From 2c8397df04c0f6fcf1dd68deaede7f7c3bfdae28 Mon Sep 17 00:00:00 2001 From: Itay Weinberger Date: Mon, 19 Jan 2015 09:14:34 +0200 Subject: [PATCH 1/3] #161 changes to support new results format. --- .travis.yml | 2 +- build/release/joola.js | 17440 ++++++++++++++++++++++---------------- src/lib/common/api.js | 5 +- src/lib/viz/Timeline.js | 32 +- src/lib/viz/index.js | 7 +- 5 files changed, 10370 insertions(+), 7116 deletions(-) diff --git a/.travis.yml b/.travis.yml index ce51aab..964c22d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ addons: sauce_connect: username: joola-io access_key: 8ac80e3d-093f-4292-aa48-95f5656b0785 - + before_script: - npm install -g grunt-cli diff --git a/build/release/joola.js b/build/release/joola.js index dd1b09a..c3c12f9 100644 --- a/build/release/joola.js +++ b/build/release/joola.js @@ -1,3 +1,6 @@ +;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0) + { + if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html + { a[key] = extenduptolevel([], b[key],levels-1,context,newobjs,a,key,true); } + else if(b[key]===null) + { a[key] = null; } + else if( b[key] instanceof Date ) + { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } + else + { a[key] = extenduptolevel({}, b[key],levels-1,context,newobjs,a,key,true); } + } + else + { a[key] = b[key]; } + } + else if(typeof a[key] === 'object' && a[key] !== null && levels>0) + { a[key] = extenduptolevel(a[key], b[key],levels-1,context,newobjs,a,key,true); } + else + { a[key] = b[key]; } + } + } + if(clean_context) {context=null;newobjs=null;} + + if(!haveaparent) + { + aparent=null; + return a; + } + if(typeof a === 'object' && !(a instanceof Array) ) + { + /*a.constructor = b.constructor; + a.prototype = b.prototype;*/ + } + return a; +} exports.extenduptolevel=extenduptolevel; + +function clone(obj) +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + if (obj instanceof Array ) + { return extend([], obj); } + else if( obj instanceof Date ) + { + var t= new obj.constructor(); + t.setTime(obj.getTime()); + return t; + } + else + { return extend({}, obj); } + } + return obj; +} exports.clone=clone; + +function cloneextend(obj,exteddata) +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + return extend(clone(obj),exteddata); + } + return obj; +} exports.cloneextend=cloneextend; + + +function cloneuptolevel(obj,level) // clone only numlevels levels other levels leave references +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + if (obj instanceof Array ) { return extenduptolevel([], obj,level); } + return extenduptolevel({}, obj,level); + } + return obj; +} exports.cloneuptolevel=cloneuptolevel; + +function foreach(object, block, context) +{ + if (object) + { + if (typeof object === "object" && object instanceof Array) + return object.forEach(object, block, context) + else //if (typeof object === "object") // or (object instanceof Function)... + { + if(object) + for (var key in object) + { + if(object.hasOwnProperty(key)) + { + if(block.call(context, object[key], key, object)===false)break; + } + } + } + } +} exports.foreach=foreach; + +/* + hasbugs and useless, yet interesting maybe developed later for dot pathed object transformation: + + { + 'foo.bar':'bluebar', + 'foo.color':'blue' + } + + transforemed to + + { + foo: + { + bar:'bluebar', + color:'blue' + } + } + + like: + + var config={}; + cloneextend.dotpath(config,{ + 'foo.bar':'bluebar', + 'foo.color':'blue' + }) + + // + function dotpath(data,dotkeys,preserve) + { + if(!preserve)preserve=false; + var create=!preserve; + if(create) if(!data) data={}; + var keys= dotkeys.split("."),value=data; + for (var i=0;i + * @license MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2013 Viacheslav Lotsmanov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * @author Feross Aboukhadijeh - * @license MIT + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -var base64 = require('base64-js') -var ieee754 = require('ieee754') - -exports.Buffer = Buffer -exports.SlowBuffer = Buffer -exports.INSPECT_MAX_BYTES = 50 -Buffer.poolSize = 8192 - /** - * If `Buffer._useTypedArrays`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (compatible down to IE6) + * Extening object that entered in first argument. + * Returns extended object or false if have no target object or incorrect type. + * If you wish to clone object, simply use that: + * deepExtend({}, yourObj_1, [yourObj_N]) - first arg is new empty object */ -Buffer._useTypedArrays = (function () { - // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, - // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding - // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support - // because we need to be able to add all the node Buffer API methods. This is an issue - // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 - try { - var buf = new ArrayBuffer(0) - var arr = new Uint8Array(buf) - arr.foo = function () { return 42 } - return 42 === arr.foo() && - typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` - } catch (e) { - return false - } -})() +var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { + if (arguments.length < 1 || typeof arguments[0] !== 'object') { + return false; + } -/** - * Class: Buffer - * ============= - * - * The Buffer constructor returns instances of `Uint8Array` that are augmented - * with function properties for all the node `Buffer` API functions. We use - * `Uint8Array` so that square bracket notation works as expected -- it returns - * a single octet. - * - * By augmenting the instances, we can avoid modifying the `Uint8Array` - * prototype. - */ -function Buffer (subject, encoding, noZero) { - if (!(this instanceof Buffer)) - return new Buffer(subject, encoding, noZero) + if (arguments.length < 2) return arguments[0]; - var type = typeof subject + var target = arguments[0]; - // Workaround: node's base64 implementation allows for non-padded strings - // while base64-js does not. - if (encoding === 'base64' && type === 'string') { - subject = stringtrim(subject) - while (subject.length % 4 !== 0) { - subject = subject + '=' - } - } + // convert arguments to array and cut off target object + var args = Array.prototype.slice.call(arguments, 1); - // Find the length - var length - if (type === 'number') - length = coerce(subject) - else if (type === 'string') - length = Buffer.byteLength(subject, encoding) - else if (type === 'object') - length = coerce(subject.length) // assume that object is array-like - else - throw new Error('First argument needs to be a number, array or string.') + var key, val, src, clone, tmpBuf; - var buf - if (Buffer._useTypedArrays) { - // Preferred: Return an augmented `Uint8Array` instance for best performance - buf = Buffer._augment(new Uint8Array(length)) - } else { - // Fallback: Return THIS instance of Buffer (created by `new`) - buf = this - buf.length = length - buf._isBuffer = true - } - - var i - if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { - // Speed optimization -- use set if we're copying from a typed array - buf._set(subject) - } else if (isArrayish(subject)) { - // Treat array-ish objects as a byte array - for (i = 0; i < length; i++) { - if (Buffer.isBuffer(subject)) - buf[i] = subject.readUInt8(i) - else - buf[i] = subject[i] - } - } else if (type === 'string') { - buf.write(subject, 0, encoding) - } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { - for (i = 0; i < length; i++) { - buf[i] = 0 - } - } + args.forEach(function (obj) { + if (typeof obj !== 'object') return; - return buf -} + for (key in obj) { + if ( ! (key in obj)) continue; -// STATIC METHODS -// ============== + src = target[key]; + val = obj[key]; -Buffer.isEncoding = function (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'raw': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} + if (val === target) continue; -Buffer.isBuffer = function (b) { - return !!(b !== null && b !== undefined && b._isBuffer) -} + if (typeof val !== 'object' || val === null) { + target[key] = val; + continue; + } else if (val instanceof Buffer) { + tmpBuf = new Buffer(val.length); + val.copy(tmpBuf); + target[key] = tmpBuf; + continue; + } else if (val instanceof Date) { + target[key] = new Date(val.getTime()); + continue; + } -Buffer.byteLength = function (str, encoding) { - var ret - str = str + '' - switch (encoding || 'utf8') { - case 'hex': - ret = str.length / 2 - break - case 'utf8': - case 'utf-8': - ret = utf8ToBytes(str).length - break - case 'ascii': - case 'binary': - case 'raw': - ret = str.length - break - case 'base64': - ret = base64ToBytes(str).length - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = str.length * 2 - break - default: - throw new Error('Unknown encoding') - } - return ret + if (typeof src !== 'object' || src === null) { + clone = (Array.isArray(val)) ? [] : {}; + target[key] = deepExtend(clone, val); + continue; + } + + if (Array.isArray(val)) { + clone = (Array.isArray(src)) ? src : []; + } else { + clone = (!Array.isArray(src)) ? src : {}; + } + + target[key] = deepExtend(clone, val); + } + }); + + return target; } -Buffer.concat = function (list, totalLength) { - assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + - 'list should be an Array.') +},{"__browserify_Buffer":49}],6:[function(require,module,exports){ +/*! + * EventEmitter2 + * https://github.com/hij1nx/EventEmitter2 + * + * Copyright (c) 2013 hij1nx + * Licensed under the MIT license. + */ +;!function(undefined) { - if (list.length === 0) { - return new Buffer(0) - } else if (list.length === 1) { - return list[0] - } + var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + var defaultMaxListeners = 10; - var i - if (typeof totalLength !== 'number') { - totalLength = 0 - for (i = 0; i < list.length; i++) { - totalLength += list[i].length + function init() { + this._events = {}; + if (this._conf) { + configure.call(this, this._conf); } } - var buf = new Buffer(totalLength) - var pos = 0 - for (i = 0; i < list.length; i++) { - var item = list[i] - item.copy(buf, pos) - pos += item.length - } - return buf -} + function configure(conf) { + if (conf) { -// BUFFER INSTANCE METHODS -// ======================= + this._conf = conf; -function _hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining + conf.delimiter && (this.delimiter = conf.delimiter); + conf.maxListeners && (this._events.maxListeners = conf.maxListeners); + conf.wildcard && (this.wildcard = conf.wildcard); + conf.newListener && (this.newListener = conf.newListener); + + if (this.wildcard) { + this.listenerTree = {}; + } } } - // must be an even number of digits - var strLen = string.length - assert(strLen % 2 === 0, 'Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; i++) { - var byte = parseInt(string.substr(i * 2, 2), 16) - assert(!isNaN(byte), 'Invalid hex string') - buf[offset + i] = byte + function EventEmitter(conf) { + this._events = {}; + this.newListener = false; + configure.call(this, conf); } - Buffer._charsWritten = i * 2 - return i -} -function _utf8Write (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(utf8ToBytes(string), buf, offset, length) - return charsWritten -} - -function _asciiWrite (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(asciiToBytes(string), buf, offset, length) - return charsWritten -} + // + // Attention, function return type now is array, always ! + // It has zero elements if no any matches found and one or more + // elements (leafs) if there are matches + // + function searchListenerTree(handlers, type, tree, i) { + if (!tree) { + return []; + } + var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, + typeLength = type.length, currentType = type[i], nextType = type[i+1]; + if (i === typeLength && tree._listeners) { + // + // If at the end of the event(s) list and the tree has listeners + // invoke those listeners. + // + if (typeof tree._listeners === 'function') { + handlers && handlers.push(tree._listeners); + return [tree]; + } else { + for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { + handlers && handlers.push(tree._listeners[leaf]); + } + return [tree]; + } + } -function _binaryWrite (buf, string, offset, length) { - return _asciiWrite(buf, string, offset, length) -} + if ((currentType === '*' || currentType === '**') || tree[currentType]) { + // + // If the event emitted is '*' at this part + // or there is a concrete match at this patch + // + if (currentType === '*') { + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); + } + } + return listeners; + } else if(currentType === '**') { + endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); + if(endReached && tree._listeners) { + // The next element has a _listeners, add it to the handlers. + listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); + } -function _base64Write (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(base64ToBytes(string), buf, offset, length) - return charsWritten -} + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + if(branch === '*' || branch === '**') { + if(tree[branch]._listeners && !endReached) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); + } + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } else if(branch === nextType) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); + } else { + // No match on this one, shift into the tree but not in the type array. + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } + } + } + return listeners; + } -function _utf16leWrite (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(utf16leToBytes(string), buf, offset, length) - return charsWritten -} + listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + } -Buffer.prototype.write = function (string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length - length = undefined + xTree = tree['*']; + if (xTree) { + // + // If the listener tree will allow any match for this part, + // then recursively explore all branches of the tree + // + searchListenerTree(handlers, type, xTree, i+1); } - } else { // legacy - var swap = encoding - encoding = offset - offset = length - length = swap - } - offset = Number(offset) || 0 - var remaining = this.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining + xxTree = tree['**']; + if(xxTree) { + if(i < typeLength) { + if(xxTree._listeners) { + // If we have a listener on a '**', it will catch all, so add its handler. + searchListenerTree(handlers, type, xxTree, typeLength); + } + + // Build arrays of matching next branches and others. + for(branch in xxTree) { + if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { + if(branch === nextType) { + // We know the next element will match, so jump twice. + searchListenerTree(handlers, type, xxTree[branch], i+2); + } else if(branch === currentType) { + // Current node matches, move into the tree. + searchListenerTree(handlers, type, xxTree[branch], i+1); + } else { + isolatedBranch = {}; + isolatedBranch[branch] = xxTree[branch]; + searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); + } + } + } + } else if(xxTree._listeners) { + // We have reached the end and still on a '**' + searchListenerTree(handlers, type, xxTree, typeLength); + } else if(xxTree['*'] && xxTree['*']._listeners) { + searchListenerTree(handlers, type, xxTree['*'], typeLength); + } } - } - encoding = String(encoding || 'utf8').toLowerCase() - var ret - switch (encoding) { - case 'hex': - ret = _hexWrite(this, string, offset, length) - break - case 'utf8': - case 'utf-8': - ret = _utf8Write(this, string, offset, length) - break - case 'ascii': - ret = _asciiWrite(this, string, offset, length) - break - case 'binary': - ret = _binaryWrite(this, string, offset, length) - break - case 'base64': - ret = _base64Write(this, string, offset, length) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = _utf16leWrite(this, string, offset, length) - break - default: - throw new Error('Unknown encoding') + return listeners; } - return ret -} -Buffer.prototype.toString = function (encoding, start, end) { - var self = this + function growListenerTree(type, listener) { - encoding = String(encoding || 'utf8').toLowerCase() - start = Number(start) || 0 - end = (end !== undefined) - ? Number(end) - : end = self.length + type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - // Fastpath empty strings - if (end === start) - return '' + // + // Looks for two consecutive '**', if so, don't add the event at all. + // + for(var i = 0, len = type.length; i+1 < len; i++) { + if(type[i] === '**' && type[i+1] === '**') { + return; + } + } - var ret - switch (encoding) { - case 'hex': - ret = _hexSlice(self, start, end) - break - case 'utf8': - case 'utf-8': - ret = _utf8Slice(self, start, end) - break - case 'ascii': - ret = _asciiSlice(self, start, end) - break - case 'binary': - ret = _binarySlice(self, start, end) - break - case 'base64': - ret = _base64Slice(self, start, end) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = _utf16leSlice(self, start, end) - break - default: - throw new Error('Unknown encoding') - } - return ret -} + var tree = this.listenerTree; + var name = type.shift(); -Buffer.prototype.toJSON = function () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} + while (name) { -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function (target, target_start, start, end) { - var source = this + if (!tree[name]) { + tree[name] = {}; + } - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (!target_start) target_start = 0 + tree = tree[name]; - // Copy 0 bytes; we're done - if (end === start) return - if (target.length === 0 || source.length === 0) return + if (type.length === 0) { - // Fatal error conditions - assert(end >= start, 'sourceEnd < sourceStart') - assert(target_start >= 0 && target_start < target.length, - 'targetStart out of bounds') - assert(start >= 0 && start < source.length, 'sourceStart out of bounds') - assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + if (!tree._listeners) { + tree._listeners = listener; + } + else if(typeof tree._listeners === 'function') { + tree._listeners = [tree._listeners, listener]; + } + else if (isArray(tree._listeners)) { - // Are we oob? - if (end > this.length) - end = this.length - if (target.length - target_start < end - start) - end = target.length - target_start + start + tree._listeners.push(listener); - var len = end - start + if (!tree._listeners.warned) { - if (len < 100 || !Buffer._useTypedArrays) { - for (var i = 0; i < len; i++) - target[i + target_start] = this[i + start] - } else { - target._set(this.subarray(start, start + len), target_start) - } -} + var m = defaultMaxListeners; -function _base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } -function _utf8Slice (buf, start, end) { - var res = '' - var tmp = '' - end = Math.min(buf.length, end) + if (m > 0 && tree._listeners.length > m) { - for (var i = start; i < end; i++) { - if (buf[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) - tmp = '' - } else { - tmp += '%' + buf[i].toString(16) + tree._listeners.warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + tree._listeners.length); + console.trace(); + } + } + } + return true; + } + name = type.shift(); } + return true; } - return res + decodeUtf8Char(tmp) -} - -function _asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; i++) - ret += String.fromCharCode(buf[i]) - return ret -} - -function _binarySlice (buf, start, end) { - return _asciiSlice(buf, start, end) -} + // By default EventEmitters will print a warning if more than + // 10 listeners are added to it. This is a useful default which + // helps finding memory leaks. + // + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. -function _hexSlice (buf, start, end) { - var len = buf.length + EventEmitter.prototype.delimiter = '.'; - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len + EventEmitter.prototype.setMaxListeners = function(n) { + this._events || init.call(this); + this._events.maxListeners = n; + if (!this._conf) this._conf = {}; + this._conf.maxListeners = n; + }; - var out = '' - for (var i = start; i < end; i++) { - out += toHex(buf[i]) - } - return out -} + EventEmitter.prototype.event = ''; -function _utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i+1] * 256) - } - return res -} + EventEmitter.prototype.once = function(event, fn) { + this.many(event, 1, fn); + return this; + }; -Buffer.prototype.slice = function (start, end) { - var len = this.length - start = clamp(start, len, 0) - end = clamp(end, len, len) + EventEmitter.prototype.many = function(event, ttl, fn) { + var self = this; - if (Buffer._useTypedArrays) { - return Buffer._augment(this.subarray(start, end)) - } else { - var sliceLen = end - start - var newBuf = new Buffer(sliceLen, undefined, true) - for (var i = 0; i < sliceLen; i++) { - newBuf[i] = this[i + start] + if (typeof fn !== 'function') { + throw new Error('many only accepts instances of Function'); } - return newBuf - } -} - -// `get` will be removed in Node 0.13+ -Buffer.prototype.get = function (offset) { - console.log('.get() is deprecated. Access using array indexes instead.') - return this.readUInt8(offset) -} - -// `set` will be removed in Node 0.13+ -Buffer.prototype.set = function (v, offset) { - console.log('.set() is deprecated. Access using array indexes instead.') - return this.writeUInt8(v, offset) -} - -Buffer.prototype.readUInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } - if (offset >= this.length) - return + function listener() { + if (--ttl === 0) { + self.off(event, listener); + } + fn.apply(this, arguments); + } - return this[offset] -} + listener._origin = fn; -function _readUInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } + this.on(event, listener); - var len = buf.length - if (offset >= len) - return + return self; + }; - var val - if (littleEndian) { - val = buf[offset] - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - } else { - val = buf[offset] << 8 - if (offset + 1 < len) - val |= buf[offset + 1] - } - return val -} + EventEmitter.prototype.emit = function() { -Buffer.prototype.readUInt16LE = function (offset, noAssert) { - return _readUInt16(this, offset, true, noAssert) -} + this._events || init.call(this); -Buffer.prototype.readUInt16BE = function (offset, noAssert) { - return _readUInt16(this, offset, false, noAssert) -} + var type = arguments[0]; -function _readUInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + if (type === 'newListener' && !this.newListener) { + if (!this._events.newListener) { return false; } + } - var len = buf.length - if (offset >= len) - return + // Loop through the *_all* functions and invoke them. + if (this._all) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + for (i = 0, l = this._all.length; i < l; i++) { + this.event = type; + this._all[i].apply(this, args); + } + } - var val - if (littleEndian) { - if (offset + 2 < len) - val = buf[offset + 2] << 16 - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - val |= buf[offset] - if (offset + 3 < len) - val = val + (buf[offset + 3] << 24 >>> 0) - } else { - if (offset + 1 < len) - val = buf[offset + 1] << 16 - if (offset + 2 < len) - val |= buf[offset + 2] << 8 - if (offset + 3 < len) - val |= buf[offset + 3] - val = val + (buf[offset] << 24 >>> 0) - } - return val -} + // If there is no 'error' event listener then throw. + if (type === 'error') { -Buffer.prototype.readUInt32LE = function (offset, noAssert) { - return _readUInt32(this, offset, true, noAssert) -} + if (!this._all && + !this._events.error && + !(this.wildcard && this.listenerTree.error)) { -Buffer.prototype.readUInt32BE = function (offset, noAssert) { - return _readUInt32(this, offset, false, noAssert) -} + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } -Buffer.prototype.readInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, - 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } + var handler; - if (offset >= this.length) - return + if(this.wildcard) { + handler = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handler, ns, this.listenerTree, 0); + } + else { + handler = this._events[type]; + } - var neg = this[offset] & 0x80 - if (neg) - return (0xff - this[offset] + 1) * -1 - else - return this[offset] -} + if (typeof handler === 'function') { + this.event = type; + if (arguments.length === 1) { + handler.call(this); + } + else if (arguments.length > 1) + switch (arguments.length) { + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + handler.apply(this, args); + } + return true; + } + else if (handler) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; -function _readInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + this.event = type; + listeners[i].apply(this, args); + } + return (listeners.length > 0) || !!this._all; + } + else { + return !!this._all; + } - var len = buf.length - if (offset >= len) - return + }; - var val = _readUInt16(buf, offset, littleEndian, true) - var neg = val & 0x8000 - if (neg) - return (0xffff - val + 1) * -1 - else - return val -} + EventEmitter.prototype.on = function(type, listener) { -Buffer.prototype.readInt16LE = function (offset, noAssert) { - return _readInt16(this, offset, true, noAssert) -} + if (typeof type === 'function') { + this.onAny(type); + return this; + } -Buffer.prototype.readInt16BE = function (offset, noAssert) { - return _readInt16(this, offset, false, noAssert) -} + if (typeof listener !== 'function') { + throw new Error('on only accepts instances of Function'); + } + this._events || init.call(this); -function _readInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); - var len = buf.length - if (offset >= len) - return + if(this.wildcard) { + growListenerTree.call(this, type, listener); + return this; + } - var val = _readUInt32(buf, offset, littleEndian, true) - var neg = val & 0x80000000 - if (neg) - return (0xffffffff - val + 1) * -1 - else - return val -} + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } + else if(typeof this._events[type] === 'function') { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + else if (isArray(this._events[type])) { + // If we've already got an array, just append. + this._events[type].push(listener); -Buffer.prototype.readInt32LE = function (offset, noAssert) { - return _readInt32(this, offset, true, noAssert) -} + // Check for listener leak + if (!this._events[type].warned) { -Buffer.prototype.readInt32BE = function (offset, noAssert) { - return _readInt32(this, offset, false, noAssert) -} + var m = defaultMaxListeners; -function _readFloat (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } - return ieee754.read(buf, offset, littleEndian, 23, 4) -} + if (m > 0 && this._events[type].length > m) { -Buffer.prototype.readFloatLE = function (offset, noAssert) { - return _readFloat(this, offset, true, noAssert) -} + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + } + return this; + }; -Buffer.prototype.readFloatBE = function (offset, noAssert) { - return _readFloat(this, offset, false, noAssert) -} + EventEmitter.prototype.onAny = function(fn) { -function _readDouble (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') - } + if (typeof fn !== 'function') { + throw new Error('onAny only accepts instances of Function'); + } - return ieee754.read(buf, offset, littleEndian, 52, 8) -} + if(!this._all) { + this._all = []; + } -Buffer.prototype.readDoubleLE = function (offset, noAssert) { - return _readDouble(this, offset, true, noAssert) -} + // Add the function to the event listener collection. + this._all.push(fn); + return this; + }; -Buffer.prototype.readDoubleBE = function (offset, noAssert) { - return _readDouble(this, offset, false, noAssert) -} + EventEmitter.prototype.addListener = EventEmitter.prototype.on; -Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'trying to write beyond buffer length') - verifuint(value, 0xff) - } + EventEmitter.prototype.off = function(type, listener) { + if (typeof listener !== 'function') { + throw new Error('removeListener only takes instances of Function'); + } - if (offset >= this.length) return + var handlers,leafs=[]; - this[offset] = value -} + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + } + else { + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events[type]) return this; + handlers = this._events[type]; + leafs.push({_listeners:handlers}); + } -function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'trying to write beyond buffer length') - verifuint(value, 0xffff) - } + for (var iLeaf=0; iLeaf= len) - return + var position = -1; - for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { - buf[offset + i] = - (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} + for (var i = 0, length = handlers.length; i < length; i++) { + if (handlers[i] === listener || + (handlers[i].listener && handlers[i].listener === listener) || + (handlers[i]._origin && handlers[i]._origin === listener)) { + position = i; + break; + } + } -Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { - _writeUInt16(this, value, offset, true, noAssert) -} + if (position < 0) { + continue; + } -Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { - _writeUInt16(this, value, offset, false, noAssert) -} + if(this.wildcard) { + leaf._listeners.splice(position, 1); + } + else { + this._events[type].splice(position, 1); + } -function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'trying to write beyond buffer length') - verifuint(value, 0xffffffff) - } + if (handlers.length === 0) { + if(this.wildcard) { + delete leaf._listeners; + } + else { + delete this._events[type]; + } + } + return this; + } + else if (handlers === listener || + (handlers.listener && handlers.listener === listener) || + (handlers._origin && handlers._origin === listener)) { + if(this.wildcard) { + delete leaf._listeners; + } + else { + delete this._events[type]; + } + } + } - var len = buf.length - if (offset >= len) - return + return this; + }; - for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { - buf[offset + i] = - (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} + EventEmitter.prototype.offAny = function(fn) { + var i = 0, l = 0, fns; + if (fn && this._all && this._all.length > 0) { + fns = this._all; + for(i = 0, l = fns.length; i < l; i++) { + if(fn === fns[i]) { + fns.splice(i, 1); + return this; + } + } + } else { + this._all = []; + } + return this; + }; -Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { - _writeUInt32(this, value, offset, true, noAssert) -} + EventEmitter.prototype.removeListener = EventEmitter.prototype.off; -Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { - _writeUInt32(this, value, offset, false, noAssert) -} + EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + !this._events || init.call(this); + return this; + } -Buffer.prototype.writeInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7f, -0x80) - } + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); - if (offset >= this.length) - return + for (var iLeaf=0; iLeaf= 0) - this.writeUInt8(value, offset, noAssert) - else - this.writeUInt8(0xff + value + 1, offset, noAssert) -} + EventEmitter.prototype.listeners = function(type) { + if(this.wildcard) { + var handlers = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handlers, ns, this.listenerTree, 0); + return handlers; + } -function _writeInt16 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fff, -0x8000) - } + this._events || init.call(this); - var len = buf.length - if (offset >= len) - return + if (!this._events[type]) this._events[type] = []; + if (!isArray(this._events[type])) { + this._events[type] = [this._events[type]]; + } + return this._events[type]; + }; - if (value >= 0) - _writeUInt16(buf, value, offset, littleEndian, noAssert) - else - _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) -} + EventEmitter.prototype.listenersAny = function() { -Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { - _writeInt16(this, value, offset, true, noAssert) -} + if(this._all) { + return this._all; + } + else { + return []; + } -Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { - _writeInt16(this, value, offset, false, noAssert) -} + }; -function _writeInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fffffff, -0x80000000) + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(function() { + return EventEmitter; + }); + } else if (typeof exports === 'object') { + // CommonJS + exports.EventEmitter2 = EventEmitter; + } + else { + // Browser global. + window.EventEmitter2 = EventEmitter; } +}(); - var len = buf.length - if (offset >= len) - return +},{}],7:[function(require,module,exports){ - if (value >= 0) - _writeUInt32(buf, value, offset, littleEndian, noAssert) - else - _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) -} -Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { - _writeInt32(this, value, offset, true, noAssert) -} +// +// The shims in this file are not fully implemented shims for the ES5 +// features, but do work for the particular usecases there is in +// the other modules. +// -Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { - _writeInt32(this, value, offset, false, noAssert) +var toString = Object.prototype.toString; +var hasOwnProperty = Object.prototype.hasOwnProperty; + +// Array.isArray is supported in IE9 +function isArray(xs) { + return toString.call(xs) === '[object Array]'; } +exports.isArray = typeof Array.isArray === 'function' ? Array.isArray : isArray; -function _writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) +// Array.prototype.indexOf is supported in IE9 +exports.indexOf = function indexOf(xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; } + return -1; +}; - var len = buf.length - if (offset >= len) - return +// Array.prototype.filter is supported in IE9 +exports.filter = function filter(xs, fn) { + if (xs.filter) return xs.filter(fn); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (fn(xs[i], i, xs)) res.push(xs[i]); + } + return res; +}; - ieee754.write(buf, value, offset, littleEndian, 23, 4) -} +// Array.prototype.forEach is supported in IE9 +exports.forEach = function forEach(xs, fn, self) { + if (xs.forEach) return xs.forEach(fn, self); + for (var i = 0; i < xs.length; i++) { + fn.call(self, xs[i], i, xs); + } +}; -Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { - _writeFloat(this, value, offset, true, noAssert) -} +// Array.prototype.map is supported in IE9 +exports.map = function map(xs, fn) { + if (xs.map) return xs.map(fn); + var out = new Array(xs.length); + for (var i = 0; i < xs.length; i++) { + out[i] = fn(xs[i], i, xs); + } + return out; +}; -Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { - _writeFloat(this, value, offset, false, noAssert) -} +// Array.prototype.reduce is supported in IE9 +exports.reduce = function reduce(array, callback, opt_initialValue) { + if (array.reduce) return array.reduce(callback, opt_initialValue); + var value, isValueSet = false; -function _writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 7 < buf.length, - 'Trying to write beyond buffer length') - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + if (2 < arguments.length) { + value = opt_initialValue; + isValueSet = true; + } + for (var i = 0, l = array.length; l > i; ++i) { + if (array.hasOwnProperty(i)) { + if (isValueSet) { + value = callback(value, array[i], i, array); + } + else { + value = array[i]; + isValueSet = true; + } + } } - var len = buf.length - if (offset >= len) - return + return value; +}; - ieee754.write(buf, value, offset, littleEndian, 52, 8) -} +// String.prototype.substr - negative index don't work in IE8 +if ('ab'.substr(-1) !== 'b') { + exports.substr = function (str, start, length) { + // did we get a negative start, calculate how much it is from the beginning of the string + if (start < 0) start = str.length + start; -Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { - _writeDouble(this, value, offset, true, noAssert) + // call the original function + return str.substr(start, length); + }; +} else { + exports.substr = function (str, start, length) { + return str.substr(start, length); + }; } -Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { - _writeDouble(this, value, offset, false, noAssert) -} +// String.prototype.trim is supported in IE9 +exports.trim = function (str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +}; -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function (value, start, end) { - if (!value) value = 0 - if (!start) start = 0 - if (!end) end = this.length +// Function.prototype.bind is supported in IE9 +exports.bind = function () { + var args = Array.prototype.slice.call(arguments); + var fn = args.shift(); + if (fn.bind) return fn.bind.apply(fn, args); + var self = args.shift(); + return function () { + fn.apply(self, args.concat([Array.prototype.slice.call(arguments)])); + }; +}; - if (typeof value === 'string') { - value = value.charCodeAt(0) +// Object.create is supported in IE9 +function create(prototype, properties) { + var object; + if (prototype === null) { + object = { '__proto__' : null }; } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); + } + return object; +} +exports.create = typeof Object.create === 'function' ? Object.create : create; - assert(typeof value === 'number' && !isNaN(value), 'value is not a number') - assert(end >= start, 'end < start') - - // Fill 0 bytes; we're done - if (end === start) return - if (this.length === 0) return - - assert(start >= 0 && start < this.length, 'start out of bounds') - assert(end >= 0 && end <= this.length, 'end out of bounds') +// Object.keys and Object.getOwnPropertyNames is supported in IE9 however +// they do show a description and number property on Error objects +function notObject(object) { + return ((typeof object != "object" && typeof object != "function") || object === null); +} - for (var i = start; i < end; i++) { - this[i] = value +function keysShim(object) { + if (notObject(object)) { + throw new TypeError("Object.keys called on a non-object"); } -} -Buffer.prototype.inspect = function () { - var out = [] - var len = this.length - for (var i = 0; i < len; i++) { - out[i] = toHex(this[i]) - if (i === exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...' - break + var result = []; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result.push(name); } } - return '' + return result; } -/** - * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. - * Added in Node 0.12. Only available in browsers that support ArrayBuffer. - */ -Buffer.prototype.toArrayBuffer = function () { - if (typeof Uint8Array !== 'undefined') { - if (Buffer._useTypedArrays) { - return (new Buffer(this)).buffer - } else { - var buf = new Uint8Array(this.length) - for (var i = 0, len = buf.length; i < len; i += 1) - buf[i] = this[i] - return buf.buffer - } - } else { - throw new Error('Buffer.toArrayBuffer not supported in this browser') - } -} - -// HELPER FUNCTIONS -// ================ - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -var BP = Buffer.prototype - -/** - * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods - */ -Buffer._augment = function (arr) { - arr._isBuffer = true - - // save reference to original Uint8Array get/set methods before overwriting - arr._get = arr.get - arr._set = arr.set - - // deprecated, will be removed in node 0.13+ - arr.get = BP.get - arr.set = BP.set - - arr.write = BP.write - arr.toString = BP.toString - arr.toLocaleString = BP.toString - arr.toJSON = BP.toJSON - arr.copy = BP.copy - arr.slice = BP.slice - arr.readUInt8 = BP.readUInt8 - arr.readUInt16LE = BP.readUInt16LE - arr.readUInt16BE = BP.readUInt16BE - arr.readUInt32LE = BP.readUInt32LE - arr.readUInt32BE = BP.readUInt32BE - arr.readInt8 = BP.readInt8 - arr.readInt16LE = BP.readInt16LE - arr.readInt16BE = BP.readInt16BE - arr.readInt32LE = BP.readInt32LE - arr.readInt32BE = BP.readInt32BE - arr.readFloatLE = BP.readFloatLE - arr.readFloatBE = BP.readFloatBE - arr.readDoubleLE = BP.readDoubleLE - arr.readDoubleBE = BP.readDoubleBE - arr.writeUInt8 = BP.writeUInt8 - arr.writeUInt16LE = BP.writeUInt16LE - arr.writeUInt16BE = BP.writeUInt16BE - arr.writeUInt32LE = BP.writeUInt32LE - arr.writeUInt32BE = BP.writeUInt32BE - arr.writeInt8 = BP.writeInt8 - arr.writeInt16LE = BP.writeInt16LE - arr.writeInt16BE = BP.writeInt16BE - arr.writeInt32LE = BP.writeInt32LE - arr.writeInt32BE = BP.writeInt32BE - arr.writeFloatLE = BP.writeFloatLE - arr.writeFloatBE = BP.writeFloatBE - arr.writeDoubleLE = BP.writeDoubleLE - arr.writeDoubleBE = BP.writeDoubleBE - arr.fill = BP.fill - arr.inspect = BP.inspect - arr.toArrayBuffer = BP.toArrayBuffer - - return arr -} +// getOwnPropertyNames is almost the same as Object.keys one key feature +// is that it returns hidden properties, since that can't be implemented, +// this feature gets reduced so it just shows the length property on arrays +function propertyShim(object) { + if (notObject(object)) { + throw new TypeError("Object.getOwnPropertyNames called on a non-object"); + } -// slice(start, end) -function clamp (index, len, defaultValue) { - if (typeof index !== 'number') return defaultValue - index = ~~index; // Coerce to integer. - if (index >= len) return len - if (index >= 0) return index - index += len - if (index >= 0) return index - return 0 + var result = keysShim(object); + if (exports.isArray(object) && exports.indexOf(object, 'length') === -1) { + result.push('length'); + } + return result; } -function coerce (length) { - // Coerce length to a number (possibly NaN), round up - // in case it's fractional (e.g. 123.456) then do a - // double negate to coerce a NaN to 0. Easy, right? - length = ~~Math.ceil(+length) - return length < 0 ? 0 : length -} +var keys = typeof Object.keys === 'function' ? Object.keys : keysShim; +var getOwnPropertyNames = typeof Object.getOwnPropertyNames === 'function' ? + Object.getOwnPropertyNames : propertyShim; -function isArray (subject) { - return (Array.isArray || function (subject) { - return Object.prototype.toString.call(subject) === '[object Array]' - })(subject) -} +if (new Error().hasOwnProperty('description')) { + var ERROR_PROPERTY_FILTER = function (obj, array) { + if (toString.call(obj) === '[object Error]') { + array = exports.filter(array, function (name) { + return name !== 'description' && name !== 'number' && name !== 'message'; + }); + } + return array; + }; -function isArrayish (subject) { - return isArray(subject) || Buffer.isBuffer(subject) || - subject && typeof subject === 'object' && - typeof subject.length === 'number' + exports.keys = function (object) { + return ERROR_PROPERTY_FILTER(object, keys(object)); + }; + exports.getOwnPropertyNames = function (object) { + return ERROR_PROPERTY_FILTER(object, getOwnPropertyNames(object)); + }; +} else { + exports.keys = keys; + exports.getOwnPropertyNames = getOwnPropertyNames; } -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) +// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements +function valueObject(value, key) { + return { value: value[key] }; } -function utf8ToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - var b = str.charCodeAt(i) - if (b <= 0x7F) - byteArray.push(str.charCodeAt(i)) - else { - var start = i - if (b >= 0xD800 && b <= 0xDFFF) i++ - var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') - for (var j = 0; j < h.length; j++) - byteArray.push(parseInt(h[j], 16)) - } +if (typeof Object.getOwnPropertyDescriptor === 'function') { + try { + Object.getOwnPropertyDescriptor({'a': 1}, 'a'); + exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + } catch (e) { + // IE8 dom element issue - use a try catch and default to valueObject + exports.getOwnPropertyDescriptor = function (value, key) { + try { + return Object.getOwnPropertyDescriptor(value, key); + } catch (e) { + return valueObject(value, key); + } + }; } - return byteArray +} else { + exports.getOwnPropertyDescriptor = valueObject; } -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} +},{}],8:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -function utf16leToBytes (str) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; i++) { - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. - return byteArray -} +module.exports = Duplex; +var util = require('util'); +var shims = require('_shims'); +var timers = require('timers'); +var Readable = require('_stream_readable'); +var Writable = require('_stream_writable'); -function base64ToBytes (str) { - return base64.toByteArray(str) -} +util.inherits(Duplex, Readable); -function blitBuffer (src, dst, offset, length) { - var pos - for (var i = 0; i < length; i++) { - if ((i + offset >= dst.length) || (i >= src.length)) - break - dst[i + offset] = src[i] - } - return i -} +shims.forEach(shims.keys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); -function decodeUtf8Char (str) { - try { - return decodeURIComponent(str) - } catch (err) { - return String.fromCharCode(0xFFFD) // UTF 8 invalid char - } -} +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); -/* - * We have to make sure that the value is a valid integer. This means that it - * is non-negative. It has no fractional component and that it does not - * exceed the maximum allowed value. - */ -function verifuint (value, max) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value >= 0, 'specified a negative value for writing an unsigned value') - assert(value <= max, 'value is larger than maximum value for type') - assert(Math.floor(value) === value, 'value has a fractional component') -} + Readable.call(this, options); + Writable.call(this, options); -function verifsint (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') - assert(Math.floor(value) === value, 'value has a fractional component') -} + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; -function verifIEEE754 (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') + this.once('end', onend); } -function assert (test, message) { - if (!test) throw new Error(message || 'Failed assertion') +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + timers.setImmediate(shims.bind(this.end, this)); } -},{"base64-js":4,"ieee754":5}],4:[function(require,module,exports){ -var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +},{"_shims":7,"_stream_readable":10,"_stream_writable":12,"timers":19,"util":21}],9:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -;(function (exports) { - 'use strict'; +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. - var Arr = (typeof Uint8Array !== 'undefined') - ? Uint8Array - : Array - - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS) - return 62 // '+' - if (code === SLASH) - return 63 // '/' - if (code < NUMBER) - return -1 //no match - if (code < NUMBER + 10) - return code - NUMBER + 26 + 26 - if (code < UPPER + 26) - return code - UPPER - if (code < LOWER + 26) - return code - LOWER + 26 - } - - function b64ToByteArray (b64) { - var i, j, l, tmp, placeHolders, arr +module.exports = PassThrough; - if (b64.length % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } +var Transform = require('_stream_transform'); +var util = require('util'); +util.inherits(PassThrough, Transform); - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - var len = b64.length - placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(b64.length * 3 / 4 - placeHolders) + Transform.call(this, options); +} - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; - var L = 0 +},{"_stream_transform":11,"util":21}],10:[function(require,module,exports){ +var process=require("__browserify_process");// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - function push (v) { - arr[L++] = v - } +module.exports = Readable; +Readable.ReadableState = ReadableState; - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) - push((tmp & 0xFF0000) >> 16) - push((tmp & 0xFF00) >> 8) - push(tmp & 0xFF) - } +var EE = require('events').EventEmitter; +var Stream = require('stream'); +var shims = require('_shims'); +var Buffer = require('buffer').Buffer; +var timers = require('timers'); +var util = require('util'); +var StringDecoder; - if (placeHolders === 2) { - tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) - push(tmp & 0xFF) - } else if (placeHolders === 1) { - tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) - push((tmp >> 8) & 0xFF) - push(tmp & 0xFF) - } +util.inherits(Readable, Stream); - return arr - } +function ReadableState(options, stream) { + options = options || {}; - function uint8ToBase64 (uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length + // 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" + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; - function encode (num) { - return lookup.charAt(num) - } + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) - } + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = false; - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1] - output += encode(temp >> 2) - output += encode((temp << 4) & 0x3F) - output += '==' - break - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) - output += encode(temp >> 10) - output += encode((temp >> 4) & 0x3F) - output += encode((temp << 2) & 0x3F) - output += '=' - break - } + // 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, becuase any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; - return output - } + // 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; - exports.toByteArray = b64ToByteArray - exports.fromByteArray = uint8ToBase64 -}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) -},{}],5:[function(require,module,exports){ -exports.read = function(buffer, offset, isLE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isLE ? (nBytes - 1) : 0, - d = isLE ? -1 : 1, - s = buffer[offset + i]; + // 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; - i += d; + // 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'; - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; +} -exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isLE ? 0 : (nBytes - 1), - d = isLE ? 1 : -1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); - value = Math.abs(value); + this._readableState = new ReadableState(options, this); - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } + // legacy + this.readable = true; - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; + Stream.call(this); +} + +// 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; + + if (typeof chunk === 'string' && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; } } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + return readableAddChunk(this, state, chunk, encoding, false); +}; - buffer[offset + i - d] |= s * 128; +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); }; -},{}],6:[function(require,module,exports){ -var Buffer = require('buffer').Buffer; -var intSize = 4; -var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); -var chrsz = 8; +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); -function toArray(buf, bigEndian) { - if ((buf.length % intSize) !== 0) { - var len = buf.length + (intSize - (buf.length % intSize)); - buf = Buffer.concat([buf, zeroBuffer], len); - } + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + state.buffer.push(chunk); + } - var arr = []; - var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; - for (var i = 0; i < buf.length; i += intSize) { - arr.push(fn.call(buf, i)); - } - return arr; -} + if (state.needReadable) + emitReadable(stream); -function toBuffer(arr, size, bigEndian) { - var buf = new Buffer(size); - var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; - for (var i = 0; i < arr.length; i++) { - fn.call(buf, arr[i], i * 4, true); + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; } - return buf; -} -function hash(buf, fn, hashSize, bigEndian) { - if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); - var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); - return toBuffer(arr, hashSize, bigEndian); + return needMoreData(state); } -module.exports = { hash: hash }; -},{"buffer":3}],7:[function(require,module,exports){ -var Buffer = require('buffer').Buffer -var sha = require('./sha') -var sha256 = require('./sha256') -var rng = require('./rng') -var md5 = require('./md5') -var algorithms = { - sha1: sha, - sha256: sha256, - md5: md5 +// if it's past the high water mark, we can push in some more. +// 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. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); } -var blocksize = 64 -var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0) -function hmac(fn, key, data) { - if(!Buffer.isBuffer(key)) key = new Buffer(key) - if(!Buffer.isBuffer(data)) data = new Buffer(data) +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; +}; - if(key.length > blocksize) { - key = fn(key) - } else if(key.length < blocksize) { - key = Buffer.concat([key, zeroBuffer], blocksize) +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; } + return n; +} - var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) - for(var i = 0; i < blocksize; i++) { - ipad[i] = key[i] ^ 0x36 - opad[i] = key[i] ^ 0x5C - } +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; - var hash = fn(Buffer.concat([ipad, data])) - return fn(Buffer.concat([opad, hash])) -} + if (state.objectMode) + return n === 0 ? 0 : 1; -function hash(alg, key) { - alg = alg || 'sha1' - var fn = algorithms[alg] - var bufs = [] - var length = 0 - if(!fn) error('algorithm:', alg, 'is not yet supported') - return { - update: function (data) { - if(!Buffer.isBuffer(data)) data = new Buffer(data) - - bufs.push(data) - length += data.length - return this - }, - digest: function (enc) { - var buf = Buffer.concat(bufs) - var r = key ? hmac(fn, key, buf) : fn(buf) - bufs = null - return enc ? r.toString(enc) : r - } + if (isNaN(n) || n === null) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; } -} -function error () { - var m = [].slice.call(arguments).join(' ') - throw new Error([ - m, - 'we accept pull requests', - 'http://github.com/dominictarr/crypto-browserify' - ].join('\n')) -} + if (n <= 0) + return 0; -exports.createHash = function (alg) { return hash(alg) } -exports.createHmac = function (alg, key) { return hash(alg, key) } -exports.randomBytes = function(size, callback) { - if (callback && callback.call) { - try { - callback.call(this, undefined, new Buffer(rng(size))) - } catch (err) { callback(err) } - } else { - return new Buffer(rng(size)) + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; } -} -function each(a, f) { - for(var i in a) - f(a[i], i) + return n; } -// the least I can do is make error messages for the rest of the node.js/crypto api. -each(['createCredentials' -, 'createCipher' -, 'createCipheriv' -, 'createDecipher' -, 'createDecipheriv' -, 'createSign' -, 'createVerify' -, 'createDiffieHellman' -, 'pbkdf2'], function (name) { - exports[name] = function () { - error('sorry,', name, 'is not implemented yet') +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + var state = this._readableState; + state.calledRead = true; + var nOrig = n; + + if (typeof n !== 'number' || 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.length >= state.highWaterMark || state.ended)) { + emitReadable(this); + return null; } -}) -},{"./md5":8,"./rng":9,"./sha":10,"./sha256":11,"buffer":3}],8:[function(require,module,exports){ -/* - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ - -var helpers = require('./helpers'); - -/* - * Perform a simple self-test to see if the VM is working - */ -function md5_vm_test() -{ - return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; -} - -/* - * Calculate the MD5 of an array of little-endian words, and a bit length - */ -function core_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return Array(a, b, c, d); - -} - -/* - * These functions implement the four basic operations the algorithm uses. - */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); -} -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); -} -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); -} -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} - -module.exports = function md5(buf) { - return helpers.hash(buf, core_md5, 16); -}; + n = howMuchToRead(n, state); -},{"./helpers":6}],9:[function(require,module,exports){ -// Original code adapted from Robert Kieffer. -// details at https://github.com/broofa/node-uuid -(function() { - var _global = this; + // 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; + } - var mathRNG, whatwgRNG; + // 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. - // NOTE: Math.random() does not guarantee "cryptographic quality" - mathRNG = function(size) { - var bytes = new Array(size); - var r; + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; - for (var i = 0, r; i < size; i++) { - if ((i & 0x03) == 0) r = Math.random() * 0x100000000; - bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; - } + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; - return bytes; - } + // 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; - if (_global.crypto && crypto.getRandomValues) { - whatwgRNG = function(size) { - var bytes = new Uint8Array(size); - crypto.getRandomValues(bytes); - return bytes; - } + if (doRead) { + 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; } - module.exports = whatwgRNG || mathRNG; + // If _read called its callback synchronously, then `reading` + // will be false, and we need to re-evaluate how much data we + // can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); -}()) + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; -},{}],10:[function(require,module,exports){ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS PUB 180-1 - * Version 2.1a Copyright Paul Johnston 2000 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ + if (ret === null) { + state.needReadable = true; + n = 0; + } -var helpers = require('./helpers'); + state.length -= n; -/* - * Calculate the SHA-1 of an array of big-endian words, and a bit length - */ -function core_sha1(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << (24 - len % 32); - x[((len + 64 >> 9) << 4) + 15] = len; + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; - var w = Array(80); - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - var e = -1009589776; + // If we happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - var olde = e; + return ret; +}; - for(var j = 0; j < 80; j++) - { - if(j < 16) w[j] = x[i + j]; - else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); - var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), - safe_add(safe_add(e, w[j]), sha1_kt(j))); - e = d; - d = c; - c = rol(b, 30); - b = a; - a = t; - } +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode && + !er) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - e = safe_add(e, olde); + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } } - return Array(a, b, c, d, e); + state.ended = true; + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(stream); } -/* - * Perform the appropriate triplet combination function for the current - * iteration - */ -function sha1_ft(t, b, c, d) -{ - if(t < 20) return (b & c) | ((~b) & d); - if(t < 40) return b ^ c ^ d; - if(t < 60) return (b & c) | (b & d) | (c & d); - return b ^ c ^ d; -} +// 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; + state.needReadable = false; + if (state.emittedReadable) + return; -/* - * Determine the appropriate additive constant for the current iteration - */ -function sha1_kt(t) -{ - return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : - (t < 60) ? -1894007588 : -899497514; + state.emittedReadable = true; + if (state.sync) + timers.setImmediate(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); } -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); +function emitReadable_(stream) { + stream.emit('readable'); } -/* - * Bitwise rotate a 32-bit number to the left. - */ -function rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} -module.exports = function sha1(buf) { - return helpers.hash(buf, core_sha1, 20, true); -}; +// 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; + timers.setImmediate(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + 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) { + this.emit('error', new Error('not implemented')); +}; + +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; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + timers.setImmediate(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function 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); + + function 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', cleanup); + + // 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 (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + // check for listeners before emit removes one-time listeners. + var errListeners = EE.listenerCount(dest, 'error'); + function onerror(er) { + unpipe(); + if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + dest.once('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() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function 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) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + timers.setImmediate(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + shims.forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // 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; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + 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; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = shims.indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + 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); + + if (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// 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() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + timers.setImmediate(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// 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 state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.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 (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + shims.forEach(events, function(ev) { + stream.on(ev, shims.bind(self.emit, self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted && state.calledRead) { + state.ended = true; + timers.setImmediate(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +},{"__browserify_process":50,"_shims":7,"buffer":23,"events":14,"stream":17,"string_decoder":18,"timers":19,"util":21}],11:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('_stream_duplex'); +var util = require('util'); +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + var ts = this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // 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; + + this.once('finish', function() { + if ('function' === typeof this._flush) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +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) { + throw new Error('not implemented'); +}; + +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 && ts.writecb && !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; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var rs = stream._readableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} + +},{"_stream_duplex":8,"util":21}],12:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; +Writable.WritableState = WritableState; + +var util = require('util'); +var Stream = require('stream'); +var timers = require('timers'); +var Buffer = require('buffer').Buffer; + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // 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() + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + 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; + + // 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; + + // 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, becuase 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.buffer = []; +} + +function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + timers.setImmediate(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + timers.setImmediate(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (typeof cb !== 'function') + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + typeof chunk === 'string') { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// 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, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + state.needDrain = !ret; + + if (state.writing) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + timers.setImmediate(function() { + cb(er); + }); + else + cb(er); + + stream.emit('error', er); +} + +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; + + 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(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + timers.setImmediate(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + 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; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // 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) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +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 (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + timers.setImmediate(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +},{"buffer":23,"stream":17,"timers":19,"util":21}],13:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// UTILITY +var util = require('util'); +var shims = require('_shims'); +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + this.message = options.message || getMessage(this); +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = shims.keys(a), + kb = shims.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; +},{"_shims":7,"util":21}],14:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var util = require('util'); + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!util.isNumber(n) || n < 0) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (util.isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + throw TypeError('Uncaught, unspecified "error" event.'); + } + return false; + } + } + + handler = this._events[type]; + + if (util.isUndefined(handler)) + return false; + + if (util.isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (util.isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!util.isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + util.isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (util.isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (util.isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!util.isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!util.isFunction(listener)) + throw TypeError('listener must be a function'); + + function g() { + this.removeListener(type, g); + listener.apply(this, arguments); + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!util.isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (util.isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (util.isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (util.isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (util.isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (util.isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; +},{"util":21}],15:[function(require,module,exports){ +var http = require('http'); + +var https = module.exports; + +for (var key in http) { + if (http.hasOwnProperty(key)) https[key] = http[key]; +}; + +https.request = function (params, cb) { + if (!params) params = {}; + params.scheme = 'https'; + return http.request.call(this, params, cb); +} +},{"http":31}],16:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Query String Utilities + +var QueryString = exports; +var util = require('util'); +var shims = require('_shims'); +var Buffer = require('buffer').Buffer; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + + +function charCode(c) { + return c.charCodeAt(0); +} + + +// a safe fast alternative to decodeURIComponent +QueryString.unescapeBuffer = function(s, decodeSpaces) { + var out = new Buffer(s.length); + var state = 'CHAR'; // states: CHAR, HEX0, HEX1 + var n, m, hexchar; + + for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) { + var c = s.charCodeAt(inIndex); + switch (state) { + case 'CHAR': + switch (c) { + case charCode('%'): + n = 0; + m = 0; + state = 'HEX0'; + break; + case charCode('+'): + if (decodeSpaces) c = charCode(' '); + // pass thru + default: + out[outIndex++] = c; + break; + } + break; + + case 'HEX0': + state = 'HEX1'; + hexchar = c; + if (charCode('0') <= c && c <= charCode('9')) { + n = c - charCode('0'); + } else if (charCode('a') <= c && c <= charCode('f')) { + n = c - charCode('a') + 10; + } else if (charCode('A') <= c && c <= charCode('F')) { + n = c - charCode('A') + 10; + } else { + out[outIndex++] = charCode('%'); + out[outIndex++] = c; + state = 'CHAR'; + break; + } + break; + + case 'HEX1': + state = 'CHAR'; + if (charCode('0') <= c && c <= charCode('9')) { + m = c - charCode('0'); + } else if (charCode('a') <= c && c <= charCode('f')) { + m = c - charCode('a') + 10; + } else if (charCode('A') <= c && c <= charCode('F')) { + m = c - charCode('A') + 10; + } else { + out[outIndex++] = charCode('%'); + out[outIndex++] = hexchar; + out[outIndex++] = c; + break; + } + out[outIndex++] = 16 * n + m; + break; + } + } + + // TODO support returning arbitrary buffers. + + return out.slice(0, outIndex - 1); +}; + + +QueryString.unescape = function(s, decodeSpaces) { + return QueryString.unescapeBuffer(s, decodeSpaces).toString(); +}; + + +QueryString.escape = function(str) { + return encodeURIComponent(str); +}; + +var stringifyPrimitive = function(v) { + if (util.isString(v)) + return v; + if (util.isBoolean(v)) + return v ? 'true' : 'false'; + if (util.isNumber(v)) + return isFinite(v) ? v : ''; + return ''; +}; + + +QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (util.isNull(obj)) { + obj = undefined; + } + + if (util.isObject(obj)) { + return shims.map(shims.keys(obj), function(k) { + var ks = QueryString.escape(stringifyPrimitive(k)) + eq; + if (util.isArray(obj[k])) { + return shims.map(obj[k], function(v) { + return ks + QueryString.escape(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + QueryString.escape(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return QueryString.escape(stringifyPrimitive(name)) + eq + + QueryString.escape(stringifyPrimitive(obj)); +}; + +// Parse a key=val string. +QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (!util.isString(qs) || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && util.isNumber(options.maxKeys)) { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; + } + + try { + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + } catch (e) { + k = QueryString.unescape(kstr, true); + v = QueryString.unescape(vstr, true); + } + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (util.isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; + } + } + + return obj; +}; +},{"_shims":7,"buffer":23,"util":21}],17:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Stream; + +var EE = require('events').EventEmitter; +var util = require('util'); + +util.inherits(Stream, EE); +Stream.Readable = require('_stream_readable'); +Stream.Writable = require('_stream_writable'); +Stream.Duplex = require('_stream_duplex'); +Stream.Transform = require('_stream_transform'); +Stream.PassThrough = require('_stream_passthrough'); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +},{"_stream_duplex":8,"_stream_passthrough":9,"_stream_readable":10,"_stream_transform":11,"_stream_writable":12,"events":14,"util":21}],18:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var Buffer = require('buffer').Buffer; + +function assertEncoding(encoding) { + if (encoding && !Buffer.isEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + this.charBuffer = new Buffer(6); + this.charReceived = 0; + this.charLength = 0; +}; + + +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + var offset = 0; + + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var i = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, offset, i); + this.charReceived += (i - offset); + offset = i; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; + + // if there are no more bytes in this buffer, just emit our char + if (i == buffer.length) return charStr; + + // otherwise cut off the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + break; + } + + var lenIncomplete = this.detectIncompleteChar(buffer); + + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); + this.charReceived = lenIncomplete; + end -= lenIncomplete; + } + + charStr += buffer.toString(this.encoding, 0, end); + + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); + return charStr.substring(0, end); + } + + // or just emit the charStr + return charStr; +}; + +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + + return i; +}; + +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 2; + this.charLength = incomplete ? 2 : 0; + return incomplete; +} + +function base64DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 3; + this.charLength = incomplete ? 3 : 0; + return incomplete; +} + +},{"buffer":23}],19:[function(require,module,exports){ +try { + // Old IE browsers that do not curry arguments + if (!setTimeout.call) { + var slicer = Array.prototype.slice; + exports.setTimeout = function(fn) { + var args = slicer.call(arguments, 1); + return setTimeout(function() { + return fn.apply(this, args); + }) + }; + + exports.setInterval = function(fn) { + var args = slicer.call(arguments, 1); + return setInterval(function() { + return fn.apply(this, args); + }); + }; + } else { + exports.setTimeout = setTimeout; + exports.setInterval = setInterval; + } + exports.clearTimeout = clearTimeout; + exports.clearInterval = clearInterval; + + if (window.setImmediate) { + exports.setImmediate = window.setImmediate; + exports.clearImmediate = window.clearImmediate; + } + + // Chrome and PhantomJS seems to depend on `this` pseudo variable being a + // `window` and throws invalid invocation exception otherwise. If this code + // runs in such JS runtime next line will throw and `catch` clause will + // exported timers functions bound to a window. + exports.setTimeout(function() {}); +} catch (_) { + function bind(f, context) { + return function () { return f.apply(context, arguments) }; + } + + if (typeof window !== 'undefined') { + exports.setTimeout = bind(setTimeout, window); + exports.setInterval = bind(setInterval, window); + exports.clearTimeout = bind(clearTimeout, window); + exports.clearInterval = bind(clearInterval, window); + if (window.setImmediate) { + exports.setImmediate = bind(window.setImmediate, window); + exports.clearImmediate = bind(window.clearImmediate, window); + } + } else { + if (typeof setTimeout !== 'undefined') { + exports.setTimeout = setTimeout; + } + if (typeof setInterval !== 'undefined') { + exports.setInterval = setInterval; + } + if (typeof clearTimeout !== 'undefined') { + exports.clearTimeout = clearTimeout; + } + if (typeof clearInterval === 'function') { + exports.clearInterval = clearInterval; + } + } +} + +exports.unref = function unref() {}; +exports.ref = function ref() {}; + +if (!exports.setImmediate) { + var currentKey = 0, queue = {}, active = false; + + exports.setImmediate = (function () { + function drain() { + active = false; + for (var key in queue) { + if (queue.hasOwnProperty(currentKey, key)) { + var fn = queue[key]; + delete queue[key]; + fn(); + } + } + } + + if (typeof window !== 'undefined' && + window.postMessage && window.addEventListener) { + window.addEventListener('message', function (ev) { + if (ev.source === window && ev.data === 'browserify-tick') { + ev.stopPropagation(); + drain(); + } + }, true); + + return function setImmediate(fn) { + var id = ++currentKey; + queue[id] = fn; + if (!active) { + active = true; + window.postMessage('browserify-tick', '*'); + } + return id; + }; + } else { + return function setImmediate(fn) { + var id = ++currentKey; + queue[id] = fn; + if (!active) { + active = true; + setTimeout(drain, 0); + } + return id; + }; + } + })(); + + exports.clearImmediate = function clearImmediate(id) { + delete queue[id]; + }; +} + +},{}],20:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var punycode = { encode : function (s) { return s } }; +var util = require('util'); +var shims = require('_shims'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && util.isObject(url) && url instanceof Url) return url; + + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!util.isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + var rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = shims.trim(rest); + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; + + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } + + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } + + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } + + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (util.isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} + +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } + + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query && + util.isObject(this.query) && + shims.keys(this.query).length) { + query = querystring.stringify(this.query); + } + + var search = this.search || (query && ('?' + query)) || ''; + + if (protocol && shims.substr(protocol, -1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} + +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} + +Url.prototype.resolveObject = function(relative) { + if (util.isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + shims.forEach(shims.keys(this), function(k) { + result[k] = this[k]; + }, this); + + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; + + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + shims.forEach(shims.keys(relative), function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); + + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + shims.forEach(shims.keys(relative), function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!util.isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } -},{"./helpers":6}],11:[function(require,module,exports){ + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); -var helpers = require('./helpers'); + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } -var safe_add = function(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -}; + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } -var S = function(X, n) { - return (X >>> n) | (X << (32 - n)); -}; + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } -var R = function(X, n) { - return (X >>> n); -}; + if (hasTrailingSlash && (shims.substr(srcPath.join('/'), -1) !== '/')) { + srcPath.push(''); + } -var Ch = function(x, y, z) { - return ((x & y) ^ ((~x) & z)); -}; + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); -var Maj = function(x, y, z) { - return ((x & y) ^ (x & z) ^ (y & z)); -}; + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } -var Sigma0256 = function(x) { - return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); -}; + mustEndAbs = mustEndAbs || (result.host && srcPath.length); -var Sigma1256 = function(x) { - return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); -}; + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } -var Gamma0256 = function(x) { - return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); -}; + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } -var Gamma1256 = function(x) { - return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); + //to support request.http + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; }; -var core_sha256 = function(m, l) { - var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); - var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); - var W = new Array(64); - var a, b, c, d, e, f, g, h, i, j; - var T1, T2; - /* append padding */ - m[l >> 5] |= 0x80 << (24 - l % 32); - m[((l + 64 >> 9) << 4) + 15] = l; - for (var i = 0; i < m.length; i += 16) { - a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; - for (var j = 0; j < 64; j++) { - if (j < 16) { - W[j] = m[j + i]; - } else { - W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); - } - T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); - T2 = safe_add(Sigma0256(a), Maj(a, b, c)); - h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); } - HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); - HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); + host = host.substr(0, host.length - port.length); } - return HASH; -}; - -module.exports = function sha256(buf) { - return helpers.hash(buf, core_sha256, 32, true); + if (host) this.hostname = host; }; - -},{"./helpers":6}],12:[function(require,module,exports){ +},{"_shims":7,"querystring":16,"util":21}],21:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -21162,5848 +24032,5715 @@ module.exports = function sha256(buf) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; - -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - - if (!this._events) - this._events = {}; +var shims = require('_shims'); - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); } + return objects.join(' '); } - handler = this._events[type]; - - if (isUndefined(handler)) - return false; - - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } - - return true; -}; - -EventEmitter.prototype.addListener = function(type, listener) { - var m; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events) - this._events = {}; - - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); - - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } - - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - if (!this._events || !this._events[type]) - return this; - - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } + return x; } - - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; } else { - list.splice(position, 1); + str += ' ' + inspect(x); } - - if (this._events.removeListener) - this.emit('removeListener', type, listener); } - - return this; + return str; }; -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; - - if (!this._events) - return this; - - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } - - listeners = this._events[type]; - - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); } - delete this._events[type]; - - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; - -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; - -function isFunction(arg) { - return typeof arg === 'function'; -} - -function isNumber(arg) { - return typeof arg === 'number'; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isUndefined(arg) { - return arg === void 0; + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); } +exports.inspect = inspect; -},{}],13:[function(require,module,exports){ -var http = module.exports; -var EventEmitter = require('events').EventEmitter; -var Request = require('./lib/request'); -var url = require('url') -http.request = function (params, cb) { - if (typeof params === 'string') { - params = url.parse(params) - } - if (!params) params = {}; - if (!params.host && !params.port) { - params.port = parseInt(window.location.port, 10); - } - if (!params.host && params.hostname) { - params.host = params.hostname; - } - - if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; - if (!params.host) { - params.host = window.location.hostname || window.location.host; - } - if (/:/.test(params.host)) { - if (!params.port) { - params.port = params.host.split(':')[1]; - } - params.host = params.host.split(':')[0]; - } - if (!params.port) params.port = params.scheme == 'https' ? 443 : 80; - - var req = new Request(new xhrHttp, params); - if (cb) req.on('response', cb); - return req; +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] }; -http.get = function (params, cb) { - params.method = 'GET'; - var req = http.request(params, cb); - req.end(); - return req; +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' }; -http.Agent = function () {}; -http.Agent.defaultMaxSockets = 4; -var xhrHttp = (function () { - if (typeof window === 'undefined') { - throw new Error('no window object present'); - } - else if (window.XMLHttpRequest) { - return window.XMLHttpRequest; - } - else if (window.ActiveXObject) { - var axs = [ - 'Msxml2.XMLHTTP.6.0', - 'Msxml2.XMLHTTP.3.0', - 'Microsoft.XMLHTTP' - ]; - for (var i = 0; i < axs.length; i++) { - try { - var ax = new(window.ActiveXObject)(axs[i]); - return function () { - if (ax) { - var ax_ = ax; - ax = null; - return ax_; - } - else { - return new(window.ActiveXObject)(axs[i]); - } - }; - } - catch (e) {} - } - throw new Error('ajax not supported in this browser') - } - else { - throw new Error('ajax not supported in this browser'); - } -})(); +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; -http.STATUS_CODES = { - 100 : 'Continue', - 101 : 'Switching Protocols', - 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 - 200 : 'OK', - 201 : 'Created', - 202 : 'Accepted', - 203 : 'Non-Authoritative Information', - 204 : 'No Content', - 205 : 'Reset Content', - 206 : 'Partial Content', - 207 : 'Multi-Status', // RFC 4918 - 300 : 'Multiple Choices', - 301 : 'Moved Permanently', - 302 : 'Moved Temporarily', - 303 : 'See Other', - 304 : 'Not Modified', - 305 : 'Use Proxy', - 307 : 'Temporary Redirect', - 400 : 'Bad Request', - 401 : 'Unauthorized', - 402 : 'Payment Required', - 403 : 'Forbidden', - 404 : 'Not Found', - 405 : 'Method Not Allowed', - 406 : 'Not Acceptable', - 407 : 'Proxy Authentication Required', - 408 : 'Request Time-out', - 409 : 'Conflict', - 410 : 'Gone', - 411 : 'Length Required', - 412 : 'Precondition Failed', - 413 : 'Request Entity Too Large', - 414 : 'Request-URI Too Large', - 415 : 'Unsupported Media Type', - 416 : 'Requested Range Not Satisfiable', - 417 : 'Expectation Failed', - 418 : 'I\'m a teapot', // RFC 2324 - 422 : 'Unprocessable Entity', // RFC 4918 - 423 : 'Locked', // RFC 4918 - 424 : 'Failed Dependency', // RFC 4918 - 425 : 'Unordered Collection', // RFC 4918 - 426 : 'Upgrade Required', // RFC 2817 - 428 : 'Precondition Required', // RFC 6585 - 429 : 'Too Many Requests', // RFC 6585 - 431 : 'Request Header Fields Too Large',// RFC 6585 - 500 : 'Internal Server Error', - 501 : 'Not Implemented', - 502 : 'Bad Gateway', - 503 : 'Service Unavailable', - 504 : 'Gateway Time-out', - 505 : 'HTTP Version Not Supported', - 506 : 'Variant Also Negotiates', // RFC 2295 - 507 : 'Insufficient Storage', // RFC 4918 - 509 : 'Bandwidth Limit Exceeded', - 510 : 'Not Extended', // RFC 2774 - 511 : 'Network Authentication Required' // RFC 6585 -}; -},{"./lib/request":14,"events":12,"url":32}],14:[function(require,module,exports){ -var Stream = require('stream'); -var Response = require('./response'); -var Base64 = require('Base64'); -var inherits = require('inherits'); + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} -var Request = module.exports = function (xhr, params) { - var self = this; - self.writable = true; - self.xhr = xhr; - self.body = []; - - self.uri = (params.scheme || 'http') + '://' - + params.host - + (params.port ? ':' + params.port : '') - + (params.path || '/') - ; - - if (typeof params.withCredentials === 'undefined') { - params.withCredentials = true; - } - try { xhr.withCredentials = params.withCredentials } - catch (e) {} - - xhr.open( - params.method || 'GET', - self.uri, - true - ); +function stylizeNoColor(str, styleType) { + return str; +} - self._headers = {}; - - if (params.headers) { - var keys = objectKeys(params.headers); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (!self.isSafeRequestHeader(key)) continue; - var value = params.headers[key]; - self.setHeader(key, value); - } - } - - if (params.auth) { - //basic auth - this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); - } - var res = new Response; - res.on('close', function () { - self.emit('close'); - }); - - res.on('ready', function () { - self.emit('response', res); - }); - - xhr.onreadystatechange = function () { - // Fix for IE9 bug - // SCRIPT575: Could not complete the operation due to error c00c023f - // It happens when a request is aborted, calling the success callback anyway with readyState === 4 - if (xhr.__aborted) return; - res.handle(xhr); - }; -}; +function arrayToHash(array) { + var hash = {}; -inherits(Request, Stream); + shims.forEach(array, function(val, idx) { + hash[val] = true; + }); -Request.prototype.setHeader = function (key, value) { - this._headers[key.toLowerCase()] = value -}; + return hash; +} -Request.prototype.getHeader = function (key) { - return this._headers[key.toLowerCase()] -}; -Request.prototype.removeHeader = function (key) { - delete this._headers[key.toLowerCase()] -}; +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } -Request.prototype.write = function (s) { - this.body.push(s); -}; + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } -Request.prototype.destroy = function (s) { - this.xhr.__aborted = true; - this.xhr.abort(); - this.emit('close'); -}; + // Look up the keys of the object. + var keys = shims.keys(value); + var visibleKeys = arrayToHash(keys); -Request.prototype.end = function (s) { - if (s !== undefined) this.body.push(s); - - var keys = objectKeys(this._headers); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var value = this._headers[key]; - if (isArray(value)) { - for (var j = 0; j < value.length; j++) { - this.xhr.setRequestHeader(key, value[j]); - } - } - else this.xhr.setRequestHeader(key, value) - } + if (ctx.showHidden) { + keys = shims.getOwnPropertyNames(value); + } - if (this.body.length === 0) { - this.xhr.send(''); - } - else if (typeof this.body[0] === 'string') { - this.xhr.send(this.body.join('')); + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); } - else if (isArray(this.body[0])) { - var body = []; - for (var i = 0; i < this.body.length; i++) { - body.push.apply(body, this.body[i]); - } - this.xhr.send(body); + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } - else if (/Array/.test(Object.prototype.toString.call(this.body[0]))) { - var len = 0; - for (var i = 0; i < this.body.length; i++) { - len += this.body[i].length; - } - var body = new(this.body[0].constructor)(len); - var k = 0; - - for (var i = 0; i < this.body.length; i++) { - var b = this.body[i]; - for (var j = 0; j < b.length; j++) { - body[k++] = b[j]; - } - } - this.xhr.send(body); + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); } - else { - var body = ''; - for (var i = 0; i < this.body.length; i++) { - body += this.body[i].toString(); - } - this.xhr.send(body); + if (isError(value)) { + return formatError(value); } -}; + } -// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html -Request.unsafeHeaders = [ - "accept-charset", - "accept-encoding", - "access-control-request-headers", - "access-control-request-method", - "connection", - "content-length", - "cookie", - "cookie2", - "content-transfer-encoding", - "date", - "expect", - "host", - "keep-alive", - "origin", - "referer", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "user-agent", - "via" -]; + var base = '', array = false, braces = ['{', '}']; -Request.prototype.isSafeRequestHeader = function (headerName) { - if (!headerName) return false; - return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; -}; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -}; + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } -var indexOf = function (xs, x) { - if (xs.indexOf) return xs.indexOf(x); - for (var i = 0; i < xs.length; i++) { - if (xs[i] === x) return i; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); } - return -1; -}; + } -},{"./response":15,"Base64":16,"inherits":18,"stream":25}],15:[function(require,module,exports){ -var Stream = require('stream'); -var util = require('util'); + ctx.seen.push(value); -var Response = module.exports = function (res) { - this.offset = 0; - this.readable = true; -}; + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } -util.inherits(Response, Stream); + ctx.seen.pop(); -var capable = { - streaming : true, - status2 : true -}; + return reduceToSingleString(output, base, braces); +} -function parseHeaders (res) { - var lines = res.getAllResponseHeaders().split(/\r?\n/); - var headers = {}; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - if (line === '') continue; - - var m = line.match(/^([^:]+):\s*(.*)/); - if (m) { - var key = m[1].toLowerCase(), value = m[2]; - - if (headers[key] !== undefined) { - - if (isArray(headers[key])) { - headers[key].push(value); - } - else { - headers[key] = [ headers[key], value ]; - } - } - else { - headers[key] = value; - } - } - else { - headers[line] = true; - } - } - return headers; + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); } -Response.prototype.getResponse = function (xhr) { - var respType = String(xhr.responseType).toLowerCase(); - if (respType === 'blob') return xhr.responseBlob || xhr.response; - if (respType === 'arraybuffer') return xhr.response; - return xhr.responseText; + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; } -Response.prototype.getHeader = function (key) { - return this.headers[key.toLowerCase()]; -}; -Response.prototype.handle = function (res) { - if (res.readyState === 2 && capable.status2) { - try { - this.statusCode = res.status; - this.headers = parseHeaders(res); - } - catch (err) { - capable.status2 = false; - } - - if (capable.status2) { - this.emit('ready'); - } - } - else if (capable.streaming && res.readyState === 3) { - try { - if (!this.statusCode) { - this.statusCode = res.status; - this.headers = parseHeaders(res); - this.emit('ready'); - } - } - catch (err) {} - - try { - this._emitData(res); - } - catch (err) { - capable.streaming = false; - } - } - else if (res.readyState === 4) { - if (!this.statusCode) { - this.statusCode = res.status; - this.emit('ready'); - } - this._emitData(res); - - if (res.error) { - this.emit('error', this.getResponse(res)); - } - else this.emit('end'); - - this.emit('close'); +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); } -}; + } -Response.prototype._emitData = function (res) { - var respBody = this.getResponse(res); - if (respBody.toString().match(/ArrayBuffer/)) { - this.emit('data', new Uint8Array(respBody, this.offset)); - this.offset = respBody.byteLength; - return; - } - if (respBody.length > this.offset) { - this.emit('data', respBody.slice(this.offset)); - this.offset = respBody.length; + shims.forEach(keys, function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); } -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -},{"stream":25,"util":34}],16:[function(require,module,exports){ -;(function () { + }); + return output; +} - var object = typeof exports != 'undefined' ? exports : this; // #8: web workers - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - function InvalidCharacterError(message) { - this.message = message; +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = shims.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } } - InvalidCharacterError.prototype = new Error; - InvalidCharacterError.prototype.name = 'InvalidCharacterError'; - // encoder - // [https://gist.github.com/999166] by [https://github.com/nignag] - object.btoa || ( - object.btoa = function (input) { - for ( - // initialize result and counter - var block, charCode, idx = 0, map = chars, output = ''; - // if the next input index does not exist: - // change the mapping table to "=" - // check if d has no fractional digits - input.charAt(idx | 0) || (map = '=', idx % 1); - // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 - output += map.charAt(63 & block >> 8 - idx % 1 * 8) - ) { - charCode = input.charCodeAt(idx += 3/4); - if (charCode > 0xFF) { - throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (shims.indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); } - block = block << 8 | charCode; + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); } - return output; - }); - - // decoder - // [https://gist.github.com/1020396] by [https://github.com/atk] - object.atob || ( - object.atob = function (input) { - input = input.replace(/=+$/, ''); - if (input.length % 4 == 1) { - throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = input.charAt(idx++); - // character found in table? initialize bit storage and add its ascii value; - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = chars.indexOf(buffer); + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } - return output; - }); + } -}()); + return name + ': ' + str; +} -},{}],17:[function(require,module,exports){ -var http = require('http'); -var https = module.exports; +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = shims.reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); -for (var key in http) { - if (http.hasOwnProperty(key)) https[key] = http[key]; -}; + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} -https.request = function (params, cb) { - if (!params) params = {}; - params.scheme = 'https'; - return http.request.call(this, params, cb); + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return shims.isArray(ar); } +exports.isArray = isArray; -},{"http":13}],18:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, 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 - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } +function isBoolean(arg) { + return typeof arg === 'boolean'; } +exports.isBoolean = isBoolean; -},{}],19:[function(require,module,exports){ -// shim for using process in browser +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; -var process = module.exports = {}; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; +function isObject(arg) { + return typeof arg === 'object' && arg; +} +exports.isObject = isObject; -function noop() {} +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; +} +exports.isError = isError; -process.binding = function (name) { - throw new Error('process.binding is not supported'); +function isFunction(arg) { + return typeof arg === 'function'; } +exports.isFunction = isFunction; -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; -},{}],20:[function(require,module,exports){ -(function (global){ -/*! http://mths.be/punycode v1.2.4 by @mathias */ -;(function(root) { +function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.binarySlice === 'function' + ; +} +exports.isBuffer = isBuffer; - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports; - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } +function objectToString(o) { + return Object.prototype.toString.call(o); +} - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - /** Temporary variable */ - key; +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; - /*--------------------------------------------------------------------------*/ - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = shims.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); +}; - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - while (length--) { - array[length] = fn(array[length]); - } - return array; - } +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; - /** - * A simple `Array#map`-like wrapper to work with domain name strings. - * @private - * @param {String} domain The domain name. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - return map(string.split(regexSeparators), fn).join('.'); - } + var keys = shims.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } +},{"_shims":7}],22:[function(require,module,exports){ +exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } + i += d; - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } + value = Math.abs(value); - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - if (index >= inputLength) { - error('invalid-input'); - } + buffer[offset + i - d] |= s * 128; +}; - digit = basicToDigit(input.charCodeAt(index++)); +},{}],23:[function(require,module,exports){ +var assert; +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } +function stringtrim(str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +} - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); +function Buffer(subject, encoding, offset) { + if(!assert) assert= require('assert'); + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; - if (digit < t) { - break; - } + // Work-around: node's base64 implementation + // allows for non-padded strings while base64-js + // does not.. + if (encoding == "base64" && typeof subject == "string") { + subject = stringtrim(subject); + while (subject.length % 4 != 0) { + subject = subject + "="; + } + } - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } + var type; - w *= baseMinusT; + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + // slicing works, with limitations (no parent tracking/update) + // check https://github.com/toots/buffer-browserify/issues/19 + for (var i = 0; i < this.length; i++) { + this[i] = subject.get(i+offset); + } + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; - } + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } - n += floor(i / out); - i %= out; + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; + } + } + } +} - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; +}; - } +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; - return ucs2encode(output); - } +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; - /** - * Converts a string of Unicode symbols to a Punycode string of ASCII-only - * symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); + case 'ascii': + case 'binary': + return str.length; - // Cache the length - inputLength = input.length; + case 'base64': + return base64ToBytes(str).length; - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; + default: + throw new Error('Unknown encoding'); + } +}; - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; - handledCPCount = basicLength = output.length; +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; - // Main encoding loop: - while (handledCPCount < inputLength) { +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } + i++; + } - delta += (m - n) * handledCPCountPlusOne; - n = m; + return res + decodeUtf8Char(tmp); +} - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; + } + } + return ''; +}; - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - ++delta; - ++n; +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; - } - return output.join(''); - } + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; - /** - * Converts a Punycode string representing a domain name to Unicode. Only the - * Punycoded parts of the domain name will be converted, i.e. it doesn't - * matter if you call it on a string that has already been converted to - * Unicode. - * @memberOf punycode - * @param {String} domain The Punycode domain name to convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(domain) { - return mapDomain(domain, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); + } + return out; +}; - /** - * Converts a Unicode string representing a domain name to Punycode. Only the - * non-ASCII parts of the domain name will be converted, i.e. it doesn't - * matter if you call it with a domain that's already in ASCII. - * @memberOf punycode - * @param {String} domain The domain name to convert, as a Unicode string. - * @returns {String} The Punycode representation of the given domain name. - */ - function toASCII(domain) { - return mapDomain(domain, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - /*--------------------------------------------------------------------------*/ +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.2.4', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; + // Fastpath empty strings + if (+end == start) { + return ''; + } - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { // in Rhino or a web browser - root.punycode = punycode; - } + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); -}(this)); + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],21:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + case 'ascii': + return this.asciiSlice(start, end); -'use strict'; + case 'binary': + return this.binarySlice(start, end); -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} + case 'base64': + return this.base64Slice(start, end); -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); - if (typeof qs !== 'string' || qs.length === 0) { - return obj; + default: + throw new Error('Unknown encoding'); } +}; - var regexp = /\+/g; - qs = qs.split(sep); - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } } - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); + } + if (length > strLen / 2) { + length = strLen / 2; } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; +}; - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; } + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); - - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; } } + encoding = String(encoding || 'utf8').toLowerCase(); - return obj; -}; - -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); -},{}],22:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); -'use strict'; + case 'ascii': + return this.asciiWrite(string, offset, length); -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; + case 'binary': + return this.binaryWrite(string, offset, length); - case 'boolean': - return v ? 'true' : 'false'; + case 'base64': + return this.base64Write(string, offset, length); - case 'number': - return isFinite(v) ? v : ''; + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); default: - return ''; + throw new Error('Unknown encoding'); } }; -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } +// slice(start, end) +function clamp(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +} - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); +Buffer.prototype.slice = function(start, end) { + var len = this.length; + start = clamp(start, len, 0); + end = clamp(end, len, len); + return new Buffer(this, end - start, +start); +}; +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; } + target_start || (target_start = 0); - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; + if (end < start) throw new Error('sourceEnd < sourceStart'); -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); } - return res; -} -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); } - return res; -}; -},{}],23:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); + } -},{"./decode":21,"./encode":22}],24:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // Are we oob? + if (end > this.length) { + end = this.length; + } -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. + if (target.length - target_start < end - start) { + end = target.length - target_start + start; + } -module.exports = Duplex; -var inherits = require('inherits'); -var setImmediate = require('process/browser.js').nextTick; -var Readable = require('./readable.js'); -var Writable = require('./writable.js'); + var temp = []; + for (var i=start; i= this.length) { + throw new Error('start out of bounds'); + } - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) - this.allowHalfOpen = false; + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); + } - this.once('end', onend); + for (var i = start; i < end; i++) { + this[i] = value; + } } -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) - return; +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; +}; - // no more data can be written. - // But allow more writes to happen in this tick. - var self = this; - setImmediate(function () { - self.end(); - }); -} +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); + } -},{"./readable.js":28,"./writable.js":30,"inherits":18,"process/browser.js":26}],25:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; + } -module.exports = Stream; + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; + } + } -var EE = require('events').EventEmitter; -var inherits = require('inherits'); + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer; +}; -inherits(Stream, EE); -Stream.Readable = require('./readable.js'); -Stream.Writable = require('./writable.js'); -Stream.Duplex = require('./duplex.js'); -Stream.Transform = require('./transform.js'); -Stream.PassThrough = require('./passthrough.js'); +Buffer.isEncoding = function(encoding) { + switch ((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; -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; + default: + return false; + } +}; +// helpers +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; +} -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) +} -function Stream() { - EE.call(this); +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; } -Stream.prototype.pipe = function(dest, options) { - var source = this; +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); +} - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); } - } - source.on('data', ondata); + return byteArray; +} - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); - dest.on('drain', ondrain); + return byteArray; +} - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; - dest.end(); + dst[i + offset] = src[i]; + i++; } + return i; +} +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char + } +} - function onclose() { - if (didOnEnd) return; - didOnEnd = true; +// read/write bit-twiddling - if (typeof dest.destroy === 'function') dest.destroy(); - } +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); } - source.on('error', onerror); - dest.on('error', onerror); + if (offset >= buffer.length) return; - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); + return buffer[offset]; +}; - source.removeListener('end', onend); - source.removeListener('close', onclose); +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - dest.removeListener('close', cleanup); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); } - source.on('end', cleanup); - source.on('close', cleanup); + if (offset >= buffer.length) return 0; - dest.on('close', cleanup); + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; + } + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; + } + } - dest.emit('pipe', source); + return val; +} - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); }; -},{"./duplex.js":24,"./passthrough.js":27,"./readable.js":28,"./transform.js":29,"./writable.js":30,"events":12,"inherits":18}],26:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); + if (offset >= buffer.length) return 0; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); + } -process.binding = function (name) { - throw new Error('process.binding is not supported'); + return val; } -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); }; -},{}],27:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. -module.exports = PassThrough; +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; -var Transform = require('./transform.js'); -var inherits = require('inherits'); -inherits(PassThrough, Transform); + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -function PassThrough(options) { - if (!(this instanceof PassThrough)) - return new PassThrough(options); + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } - Transform.call(this, options); -} + if (offset >= buffer.length) return; -PassThrough.prototype._transform = function(chunk, encoding, cb) { - cb(null, chunk); + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); + } + + return ((0xff - buffer[offset] + 1) * -1); }; -},{"./transform.js":29,"inherits":18}],28:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; -module.exports = Readable; -Readable.ReadableState = ReadableState; + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); -var EE = require('events').EventEmitter; -var Stream = require('./index.js'); -var Buffer = require('buffer').Buffer; -var setImmediate = require('process/browser.js').nextTick; -var StringDecoder; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -var inherits = require('inherits'); -inherits(Readable, Stream); + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } -function ReadableState(options, stream) { - options = options || {}; + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; + } - // 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" - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + return (0xffff - val + 1) * -1; +} - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; - this.buffer = []; - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = false; - this.ended = false; - this.endEmitted = false; - this.reading = false; +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); +}; - // In streams that never have any data, and do push(null) right away, - // the consumer can miss the 'end' event if they do some I/O before - // consuming the stream. So, we don't emit('end') until some reading - // happens. - this.calledRead = false; +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; - // 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, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - // 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; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } - // 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; + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); + } - // 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'; + return (0xffffffff - val + 1) * -1; +} - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); +}; - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); +}; - // if true, a maybeReadMore has been scheduled - this.readingMore = false; +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) - StringDecoder = require('string_decoder').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } -} - -function Readable(options) { - if (!(this instanceof Readable)) - return new Readable(options); - this._readableState = new ReadableState(options, this); + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); +} - // legacy - this.readable = true; +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); +}; - Stream.call(this); -} +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; -// 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; +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (typeof chunk === 'string' && !state.objectMode) { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = new Buffer(chunk, encoding); - encoding = ''; - } + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); } - return readableAddChunk(this, state, chunk, encoding, false); + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); }; -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function(chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); }; -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null || chunk === undefined) { - state.reading = false; - if (!state.ended) - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var e = new Error('stream.unshift() after end event'); - stream.emit('error', e); - } else { - if (state.decoder && !addToFront && !encoding) - chunk = state.decoder.write(chunk); - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) { - state.buffer.unshift(chunk); - } else { - state.reading = false; - state.buffer.push(chunk); - } +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - if (state.needReadable) - emitReadable(stream); + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); - maybeReadMore(stream, state); - } - } else if (!addToFront) { - state.reading = false; - } + assert.ok(value <= max, 'value is larger than maximum value for type'); - return needMoreData(state); + assert.ok(Math.floor(value) === value, 'value has a fractional component'); } +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); -// if it's past the high water mark, we can push in some more. -// 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. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && - (state.needReadable || - state.length < state.highWaterMark || - state.length === 0); -} + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -// backwards compatibility. -Readable.prototype.setEncoding = function(enc) { - if (!StringDecoder) - StringDecoder = require('string_decoder').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xff); + } + + if (offset < buffer.length) { + buffer[offset] = value; + } }; -// Don't raise the hwm > 128MB -var MAX_HWM = 0x800000; -function roundUpToNextPowerOf2(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 - n--; - for (var p = 1; p < 32; p <<= 1) n |= n >> p; - n++; +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffff); } - return n; + + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; + } + } -function howMuchToRead(n, state) { - if (state.length === 0 && state.ended) - return 0; +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; - if (state.objectMode) - return n === 0 ? 0 : 1; +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); +}; - if (isNaN(n) || n === null) { - // only flow one buffer at a time - if (state.flowing && state.buffer.length) - return state.buffer[0].length; - else - return state.length; - } +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - if (n <= 0) - return 0; + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - // If we're asking for more than the target buffer level, - // then raise the water mark. Bump up to the next highest - // power of 2, to prevent increasing it excessively in tiny - // amounts. - if (n > state.highWaterMark) - state.highWaterMark = roundUpToNextPowerOf2(n); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - // don't have that much. return null, unless we've ended. - if (n > state.length) { - if (!state.ended) { - state.needReadable = true; - return 0; - } else - return state.length; + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); } - return n; + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; + } } -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function(n) { - var state = this._readableState; - state.calledRead = true; - var nOrig = n; +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; - if (typeof n !== 'number' || n > 0) - state.emittedReadable = false; +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; - // 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.length >= state.highWaterMark || state.ended)) { - emitReadable(this); - return null; - } - n = howMuchToRead(n, state); +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: + * + * > -32 & 0xff + * 224 + * + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. + * + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: + * + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: + * + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. + */ - // 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; - } +/* + * A series of checks to make sure we actually have a signed 32-bit number + */ +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - // 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. + assert.ok(value <= max, 'value larger than maximum allowed value'); - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; + assert.ok(value >= min, 'value smaller than minimum allowed value'); - // if we currently have less than the highWaterMark, then also read some - if (state.length - n <= state.highWaterMark) - doRead = true; + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} - // 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; +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - if (doRead) { - 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; - } + assert.ok(value <= max, 'value larger than maximum allowed value'); - // If _read called its callback synchronously, then `reading` - // will be false, and we need to re-evaluate how much data we - // can return to the user. - if (doRead && !state.reading) - n = howMuchToRead(nOrig, state); + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} - var ret; - if (n > 0) - ret = fromList(n, state); - else - ret = null; +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; - if (ret === null) { - state.needReadable = true; - n = 0; - } + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - state.length -= n; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (state.length === 0 && !state.ended) - state.needReadable = true; + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); - // If we happened to read() exactly the remaining amount in the - // buffer, and the EOF has been seen at this point, then make sure - // that we emit 'end' on the very next tick. - if (state.ended && !state.endEmitted && state.length === 0) - endReadable(this); + verifsint(value, 0x7f, -0x80); + } - return ret; + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); + } }; -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode && - !er) { - er = new TypeError('Invalid non-string/buffer chunk'); +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); + } + + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); } - return er; } +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; -function onEofChunk(stream, state) { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; + +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fffffff, -0x80000000); } - state.ended = true; - // if we've ended and we have some data left, then emit - // 'readable' now to make sure it gets picked up. - if (state.length > 0) - emitReadable(stream); - else - endReadable(stream); + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); + } } -// 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; - state.needReadable = false; - if (state.emittedReadable) - return; +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; - state.emittedReadable = true; - if (state.sync) - setImmediate(function() { - emitReadable_(stream); - }); - else - emitReadable_(stream); -} +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; -function emitReadable_(stream) { - stream.emit('readable'); -} +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); -// 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; - setImmediate(function() { - maybeReadMore_(stream, state); - }); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); } -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && - state.length < state.highWaterMark) { - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break; - else - len = state.length; +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); +}; + +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); } - state.readingMore = false; + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); } -// 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) { - this.emit('error', new Error('not implemented')); +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); }; -Readable.prototype.pipe = function(dest, pipeOpts) { - var src = this; - var state = this._readableState; +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; - 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; +},{"./buffer_ieee754":22,"assert":13,"base64-js":24}],24:[function(require,module,exports){ +(function (exports) { + 'use strict'; - var doEnd = (!pipeOpts || pipeOpts.end !== false) && - dest !== process.stdout && - dest !== process.stderr; + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) - setImmediate(endFn); - else - src.once('end', endFn); + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; + } - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - if (readable !== src) return; - cleanup(); - } + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; - function onend() { - dest.end(); - } + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); - // 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); + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; - function 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', cleanup); + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } - // 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 (!dest._writableState || dest._writableState.needDrain) - ondrain(); - } + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - // check for listeners before emit removes one-time listeners. - var errListeners = EE.listenerCount(dest, 'error'); - function onerror(er) { - unpipe(); - if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) - dest.emit('error', er); - } - dest.once('error', onerror); + return arr; + } - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; - function unpipe() { - src.unpipe(dest); - } + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; - // tell the dest that it's being piped to - dest.emit('pipe', src); + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } - // start the flow if it hasn't been started already. - if (!state.flowing) { - // the handler that waits for readable events after all - // the data gets sucked out in flow. - // This would be easier to follow with a .once() handler - // in flow(), but that is too slow. - this.on('readable', pipeOnReadable); + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } - state.flowing = true; - setImmediate(function() { - flow(src); - }); - } + return output; + } - return dest; -}; + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); -function pipeOnDrain(src) { - return function() { - var dest = this; - var state = src._readableState; - state.awaitDrain--; - if (state.awaitDrain === 0) - flow(src); - }; -} +},{}],25:[function(require,module,exports){ +var Buffer = require('buffer').Buffer; +var intSize = 4; +var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); +var chrsz = 8; -function flow(src) { - var state = src._readableState; - var chunk; - state.awaitDrain = 0; +function toArray(buf, bigEndian) { + if ((buf.length % intSize) !== 0) { + var len = buf.length + (intSize - (buf.length % intSize)); + buf = Buffer.concat([buf, zeroBuffer], len); + } - function write(dest, i, list) { - var written = dest.write(chunk); - if (false === written) { - state.awaitDrain++; - } + var arr = []; + var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; + for (var i = 0; i < buf.length; i += intSize) { + arr.push(fn.call(buf, i)); } + return arr; +} - while (state.pipesCount && null !== (chunk = src.read())) { +function toBuffer(arr, size, bigEndian) { + var buf = new Buffer(size); + var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; + for (var i = 0; i < arr.length; i++) { + fn.call(buf, arr[i], i * 4, true); + } + return buf; +} - if (state.pipesCount === 1) - write(state.pipes, 0, null); - else - forEach(state.pipes, write); +function hash(buf, fn, hashSize, bigEndian) { + if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); + var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); + return toBuffer(arr, hashSize, bigEndian); +} - src.emit('data', chunk); +module.exports = { hash: hash }; - // if anyone needs a drain, then we have to wait for that. - if (state.awaitDrain > 0) - return; - } +},{"buffer":23}],26:[function(require,module,exports){ +var Buffer = require('buffer').Buffer +var sha = require('./sha') +var sha256 = require('./sha256') +var rng = require('./rng') +var md5 = require('./md5') - // if every destination was unpiped, either before entering this - // function, or in the while loop, then stop flowing. - // - // NB: This is a pretty rare edge case. - if (state.pipesCount === 0) { - state.flowing = false; +var algorithms = { + sha1: sha, + sha256: sha256, + md5: md5 +} - // if there were data event listeners added, then switch to old mode. - if (EE.listenerCount(src, 'data') > 0) - emitDataEvents(src); - return; +var blocksize = 64 +var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0) +function hmac(fn, key, data) { + if(!Buffer.isBuffer(key)) key = new Buffer(key) + if(!Buffer.isBuffer(data)) data = new Buffer(data) + + if(key.length > blocksize) { + key = fn(key) + } else if(key.length < blocksize) { + key = Buffer.concat([key, zeroBuffer], blocksize) } - // at this point, no one needed a drain, so we just ran out of data - // on the next readable event, start it over again. - state.ranOut = true; + var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) + for(var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } + + var hash = fn(Buffer.concat([ipad, data])) + return fn(Buffer.concat([opad, hash])) } -function pipeOnReadable() { - if (this._readableState.ranOut) { - this._readableState.ranOut = false; - flow(this); +function hash(alg, key) { + alg = alg || 'sha1' + var fn = algorithms[alg] + var bufs = [] + var length = 0 + if(!fn) error('algorithm:', alg, 'is not yet supported') + return { + update: function (data) { + if(!Buffer.isBuffer(data)) data = new Buffer(data) + + bufs.push(data) + length += data.length + return this + }, + digest: function (enc) { + var buf = Buffer.concat(bufs) + var r = key ? hmac(fn, key, buf) : fn(buf) + bufs = null + return enc ? r.toString(enc) : r + } } } +function error () { + var m = [].slice.call(arguments).join(' ') + throw new Error([ + m, + 'we accept pull requests', + 'http://github.com/dominictarr/crypto-browserify' + ].join('\n')) +} -Readable.prototype.unpipe = function(dest) { - var state = this._readableState; - - // 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; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; - if (dest) - dest.emit('unpipe', this); - return this; +exports.createHash = function (alg) { return hash(alg) } +exports.createHmac = function (alg, key) { return hash(alg, key) } +exports.randomBytes = function(size, callback) { + if (callback && callback.call) { + try { + callback.call(this, undefined, new Buffer(rng(size))) + } catch (err) { callback(err) } + } else { + return new Buffer(rng(size)) } +} - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; +function each(a, f) { + for(var i in a) + f(a[i], i) +} - for (var i = 0; i < len; i++) - dests[i].emit('unpipe', this); - return this; +// the least I can do is make error messages for the rest of the node.js/crypto api. +each(['createCredentials' +, 'createCipher' +, 'createCipheriv' +, 'createDecipher' +, 'createDecipheriv' +, 'createSign' +, 'createVerify' +, 'createDiffieHellman' +, 'pbkdf2'], function (name) { + exports[name] = function () { + error('sorry,', name, 'is not implemented yet') } +}) - // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) - return this; +},{"./md5":27,"./rng":28,"./sha":29,"./sha256":30,"buffer":23}],27:[function(require,module,exports){ +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +var helpers = require('./helpers'); + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +module.exports = function md5(buf) { + return helpers.hash(buf, core_md5, 16); +}; - state.pipes.splice(i, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) - state.pipes = state.pipes[0]; +},{"./helpers":25}],28:[function(require,module,exports){ +// Original code adapted from Robert Kieffer. +// details at https://github.com/broofa/node-uuid +(function() { + var _global = this; - dest.emit('unpipe', this); + var mathRNG, whatwgRNG; - return this; -}; + // NOTE: Math.random() does not guarantee "cryptographic quality" + mathRNG = function(size) { + var bytes = new Array(size); + var r; -// 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); + for (var i = 0, r; i < size; i++) { + if ((i & 0x03) == 0) r = Math.random() * 0x100000000; + bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; + } - if (ev === 'data' && !this._readableState.flowing) - emitDataEvents(this); + return bytes; + } - if (ev === 'readable' && this.readable) { - var state = this._readableState; - if (!state.readableListening) { - state.readableListening = true; - state.emittedReadable = false; - state.needReadable = true; - if (!state.reading) { - this.read(0); - } else if (state.length) { - emitReadable(this, state); - } + if (_global.crypto && crypto.getRandomValues) { + whatwgRNG = function(size) { + var bytes = new Uint8Array(size); + crypto.getRandomValues(bytes); + return bytes; } } - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -// 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() { - emitDataEvents(this); - this.read(0); - this.emit('resume'); -}; - -Readable.prototype.pause = function() { - emitDataEvents(this, true); - this.emit('pause'); -}; + module.exports = whatwgRNG || mathRNG; -function emitDataEvents(stream, startPaused) { - var state = stream._readableState; +}()) - if (state.flowing) { - // https://github.com/isaacs/readable-stream/issues/16 - throw new Error('Cannot switch to old mode now.'); - } +},{}],29:[function(require,module,exports){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ - var paused = startPaused || false; - var readable = false; +var helpers = require('./helpers'); - // convert to an old-style stream. - stream.readable = true; - stream.pipe = Stream.prototype.pipe; - stream.on = stream.addListener = Stream.prototype.on; +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; - stream.on('readable', function() { - readable = true; + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; - var c; - while (!paused && (null !== (c = stream.read()))) - stream.emit('data', c); + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; - if (c === null) { - readable = false; - stream._readableState.needReadable = true; + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; } - }); - - stream.pause = function() { - paused = true; - this.emit('pause'); - }; - stream.resume = function() { - paused = false; - if (readable) - setImmediate(function() { - stream.emit('readable'); - }); - else - this.read(0); - this.emit('resume'); - }; + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); - // now make it start, just in case it hadn't already. - stream.emit('readable'); } -// 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 state = this._readableState; - var paused = false; - - var self = this; - stream.on('end', function() { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) - self.push(chunk); - } - - self.push(null); - }); - - stream.on('data', function(chunk) { - if (state.decoder) - chunk = state.decoder.write(chunk); - if (!chunk || !state.objectMode && !chunk.length) - return; - - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; +} - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (typeof stream[i] === 'function' && - typeof this[i] === 'undefined') { - this[i] = function(method) { return function() { - return stream[method].apply(stream, arguments); - }}(i); - } - } +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} - // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function(ev) { - stream.on(ev, function (x) { - return self.emit.apply(self, ev, x); - }); - }); +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function(n) { - if (paused) { - paused = false; - stream.resume(); - } - }; +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} - return self; +module.exports = function sha1(buf) { + return helpers.hash(buf, core_sha1, 20, true); }; +},{"./helpers":25}],30:[function(require,module,exports){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -function fromList(n, state) { - var list = state.buffer; - var length = state.length; - var stringMode = !!state.decoder; - var objectMode = !!state.objectMode; - var ret; +var helpers = require('./helpers'); - // nothing in the list, definitely empty. - if (list.length === 0) - return null; +var safe_add = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +}; - if (length === 0) - ret = null; - else if (objectMode) - ret = list.shift(); - else if (!n || n >= length) { - // read it all, truncate the array. - if (stringMode) - ret = list.join(''); - else - ret = Buffer.concat(list, length); - list.length = 0; - } else { - // read just some of it. - if (n < list[0].length) { - // just take a part of the first list item. - // slice is the same for buffers and strings. - var buf = list[0]; - ret = buf.slice(0, n); - list[0] = buf.slice(n); - } else if (n === list[0].length) { - // first list is a perfect match - ret = list.shift(); - } else { - // complex case. - // we have enough to cover it, but it spans past the first buffer. - if (stringMode) - ret = ''; - else - ret = new Buffer(n); +var S = function(X, n) { + return (X >>> n) | (X << (32 - n)); +}; - var c = 0; - for (var i = 0, l = list.length; i < l && c < n; i++) { - var buf = list[0]; - var cpy = Math.min(n - c, buf.length); +var R = function(X, n) { + return (X >>> n); +}; - if (stringMode) - ret += buf.slice(0, cpy); - else - buf.copy(ret, c, 0, cpy); +var Ch = function(x, y, z) { + return ((x & y) ^ ((~x) & z)); +}; - if (cpy < buf.length) - list[0] = buf.slice(cpy); - else - list.shift(); +var Maj = function(x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)); +}; - c += cpy; - } - } - } +var Sigma0256 = function(x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); +}; - return ret; -} +var Sigma1256 = function(x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); +}; -function endReadable(stream) { - var state = stream._readableState; +var Gamma0256 = function(x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); +}; - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) - throw new Error('endReadable called on non-empty stream'); +var Gamma1256 = function(x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); +}; - if (!state.endEmitted && state.calledRead) { - state.ended = true; - setImmediate(function() { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); +var core_sha256 = function(m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); + var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for (var i = 0; i < m.length; i += 16) { + a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; + for (var j = 0; j < 64; j++) { + if (j < 16) { + W[j] = m[j + i]; + } else { + W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); } - }); + T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); + T2 = safe_add(Sigma0256(a), Maj(a, b, c)); + h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); + } + HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); } -} + return HASH; +}; -function forEach (xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} +module.exports = function sha256(buf) { + return helpers.hash(buf, core_sha256, 32, true); +}; -function indexOf (xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} +},{"./helpers":25}],31:[function(require,module,exports){ +var http = module.exports; +var EventEmitter = require('events').EventEmitter; +var Request = require('./lib/request'); -}).call(this,require("FWaASH")) -},{"./index.js":25,"FWaASH":19,"buffer":3,"events":12,"inherits":18,"process/browser.js":26,"string_decoder":31}],29:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +http.request = function (params, cb) { + if (!params) params = {}; + if (!params.host && !params.port) { + params.port = parseInt(window.location.port, 10); + } + if (!params.host) params.host = window.location.hostname; + if (!params.port) params.port = 80; + if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; + + var req = new Request(new xhrHttp, params); + if (cb) req.on('response', cb); + return req; +}; -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. +http.get = function (params, cb) { + params.method = 'GET'; + var req = http.request(params, cb); + req.end(); + return req; +}; -module.exports = Transform; +http.Agent = function () {}; +http.Agent.defaultMaxSockets = 4; + +var xhrHttp = (function () { + if (typeof window === 'undefined') { + throw new Error('no window object present'); + } + else if (window.XMLHttpRequest) { + return window.XMLHttpRequest; + } + else if (window.ActiveXObject) { + var axs = [ + 'Msxml2.XMLHTTP.6.0', + 'Msxml2.XMLHTTP.3.0', + 'Microsoft.XMLHTTP' + ]; + for (var i = 0; i < axs.length; i++) { + try { + var ax = new(window.ActiveXObject)(axs[i]); + return function () { + if (ax) { + var ax_ = ax; + ax = null; + return ax_; + } + else { + return new(window.ActiveXObject)(axs[i]); + } + }; + } + catch (e) {} + } + throw new Error('ajax not supported in this browser') + } + else { + throw new Error('ajax not supported in this browser'); + } +})(); -var Duplex = require('./duplex.js'); -var inherits = require('inherits'); -inherits(Transform, Duplex); +},{"./lib/request":32,"events":14}],32:[function(require,module,exports){ +var Stream = require('stream'); +var Response = require('./response'); +var concatStream = require('concat-stream'); +var Base64 = require('Base64'); +var util = require('util'); +var Request = module.exports = function (xhr, params) { + var self = this; + self.writable = true; + self.xhr = xhr; + self.body = concatStream() + + var uri = params.host + + (params.port ? ':' + params.port : '') + + (params.path || '/') + ; + + xhr.open( + params.method || 'GET', + (params.scheme || 'http') + '://' + uri, + true + ); + + if (params.headers) { + var keys = objectKeys(params.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!self.isSafeRequestHeader(key)) continue; + var value = params.headers[key]; + if (isArray(value)) { + for (var j = 0; j < value.length; j++) { + xhr.setRequestHeader(key, value[j]); + } + } + else xhr.setRequestHeader(key, value) + } + } + + if (params.auth) { + //basic auth + this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); + } -function TransformState(options, stream) { - this.afterTransform = function(er, data) { - return afterTransform(stream, er, data); - }; + var res = new Response; + res.on('close', function () { + self.emit('close'); + }); + + res.on('ready', function () { + self.emit('response', res); + }); + + xhr.onreadystatechange = function () { + res.handle(xhr); + }; +}; - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; -} +util.inherits(Request, Stream); -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; +Request.prototype.setHeader = function (key, value) { + if (isArray(value)) { + for (var i = 0; i < value.length; i++) { + this.xhr.setRequestHeader(key, value[i]); + } + } + else { + this.xhr.setRequestHeader(key, value); + } +}; - var cb = ts.writecb; +Request.prototype.write = function (s) { + this.body.write(s); +}; - if (!cb) - return stream.emit('error', new Error('no writecb in Transform class')); +Request.prototype.destroy = function (s) { + this.xhr.abort(); + this.emit('close'); +}; - ts.writechunk = null; - ts.writecb = null; +Request.prototype.end = function (s) { + if (s !== undefined) this.body.write(s); + this.body.end() + this.xhr.send(this.body.getBody()); +}; - if (data !== null && data !== undefined) - stream.push(data); +// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html +Request.unsafeHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" +]; - if (cb) - cb(er); +Request.prototype.isSafeRequestHeader = function (headerName) { + if (!headerName) return false; + return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; +}; - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +}; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; -function Transform(options) { - if (!(this instanceof Transform)) - return new Transform(options); +var indexOf = function (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (xs[i] === x) return i; + } + return -1; +}; - Duplex.call(this, options); +},{"./response":33,"Base64":34,"concat-stream":35,"stream":17,"util":21}],33:[function(require,module,exports){ +var Stream = require('stream'); +var util = require('util'); - var ts = this._transformState = new TransformState(options, this); +var Response = module.exports = function (res) { + this.offset = 0; + this.readable = true; +}; - // when the writable side finishes, then flush out anything remaining. - var stream = this; +util.inherits(Response, Stream); - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; +var capable = { + streaming : true, + status2 : 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; +function parseHeaders (res) { + var lines = res.getAllResponseHeaders().split(/\r?\n/); + var headers = {}; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line === '') continue; + + var m = line.match(/^([^:]+):\s*(.*)/); + if (m) { + var key = m[1].toLowerCase(), value = m[2]; + + if (headers[key] !== undefined) { + + if (isArray(headers[key])) { + headers[key].push(value); + } + else { + headers[key] = [ headers[key], value ]; + } + } + else { + headers[key] = value; + } + } + else { + headers[line] = true; + } + } + return headers; +} - this.once('finish', function() { - if ('function' === typeof this._flush) - this._flush(function(er) { - done(stream, er); - }); - else - done(stream); - }); +Response.prototype.getResponse = function (xhr) { + var respType = String(xhr.responseType).toLowerCase(); + if (respType === 'blob') return xhr.responseBlob || xhr.response; + if (respType === 'arraybuffer') return xhr.response; + return xhr.responseText; } -Transform.prototype.push = function(chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); +Response.prototype.getHeader = function (key) { + return this.headers[key.toLowerCase()]; }; -// 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) { - throw new Error('not implemented'); +Response.prototype.handle = function (res) { + if (res.readyState === 2 && capable.status2) { + try { + this.statusCode = res.status; + this.headers = parseHeaders(res); + } + catch (err) { + capable.status2 = false; + } + + if (capable.status2) { + this.emit('ready'); + } + } + else if (capable.streaming && res.readyState === 3) { + try { + if (!this.statusCode) { + this.statusCode = res.status; + this.headers = parseHeaders(res); + this.emit('ready'); + } + } + catch (err) {} + + try { + this._emitData(res); + } + catch (err) { + capable.streaming = false; + } + } + else if (res.readyState === 4) { + if (!this.statusCode) { + this.statusCode = res.status; + this.emit('ready'); + } + this._emitData(res); + + if (res.error) { + this.emit('error', this.getResponse(res)); + } + else this.emit('end'); + + this.emit('close'); + } }; -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); - } +Response.prototype._emitData = function (res) { + var respBody = this.getResponse(res); + if (respBody.toString().match(/ArrayBuffer/)) { + this.emit('data', new Uint8Array(respBody, this.offset)); + this.offset = respBody.byteLength; + return; + } + if (respBody.length > this.offset) { + this.emit('data', respBody.slice(this.offset)); + this.offset = respBody.length; + } }; -// 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 && ts.writecb && !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; - } +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; }; +},{"stream":17,"util":21}],34:[function(require,module,exports){ +;(function () { -function done(stream, er) { - if (er) - return stream.emit('error', er); + var + object = typeof exports != 'undefined' ? exports : this, // #8: web workers + chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', + INVALID_CHARACTER_ERR = (function () { + // fabricate a suitable error object + try { document.createElement('$'); } + catch (error) { return error; }}()); - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var rs = stream._readableState; - var ts = stream._transformState; + // encoder + // [https://gist.github.com/999166] by [https://github.com/nignag] + object.btoa || ( + object.btoa = function (input) { + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next input index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + input.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = input.charCodeAt(idx += 3/4); + if (charCode > 0xFF) throw INVALID_CHARACTER_ERR; + block = block << 8 | charCode; + } + return output; + }); - if (ws.length) - throw new Error('calling transform done when ws.length != 0'); + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + input = input.replace(/=+$/, '') + if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR; + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = input.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; + }); - if (ts.transforming) - throw new Error('calling transform done when still transforming'); +}()); - return stream.push(null); +},{}],35:[function(require,module,exports){ +var stream = require('stream') +var bops = require('bops') +var util = require('util') + +function ConcatStream(cb) { + stream.Stream.call(this) + this.writable = true + if (cb) this.cb = cb + this.body = [] + this.on('error', function(err) { + // no-op + }) } -},{"./duplex.js":24,"inherits":18}],30:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// A bit simpler than readable streams. -// Implement an async ._write(chunk, cb), and it'll handle all -// the drain event emission and buffering. - -module.exports = Writable; -Writable.WritableState = WritableState; - -var isUint8Array = typeof Uint8Array !== 'undefined' - ? function (x) { return x instanceof Uint8Array } - : function (x) { - return x && x.constructor && x.constructor.name === 'Uint8Array' - } -; -var isArrayBuffer = typeof ArrayBuffer !== 'undefined' - ? function (x) { return x instanceof ArrayBuffer } - : function (x) { - return x && x.constructor && x.constructor.name === 'ArrayBuffer' - } -; - -var inherits = require('inherits'); -var Stream = require('./index.js'); -var setImmediate = require('process/browser.js').nextTick; -var Buffer = require('buffer').Buffer; - -inherits(Writable, Stream); +util.inherits(ConcatStream, stream.Stream) -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; +ConcatStream.prototype.write = function(chunk) { + this.body.push(chunk) } -function WritableState(options, stream) { - options = options || {}; - - // 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() - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; - - 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; +ConcatStream.prototype.destroy = function() {} - // 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; +ConcatStream.prototype.arrayConcat = function(arrs) { + if (arrs.length === 0) return [] + if (arrs.length === 1) return arrs[0] + return arrs.reduce(function (a, b) { return a.concat(b) }) +} - // 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'; +ConcatStream.prototype.isArray = function(arr) { + return Array.isArray(arr) +} - // 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; +ConcatStream.prototype.getBody = function () { + if (this.body.length === 0) return + if (typeof(this.body[0]) === "string") return this.body.join('') + if (this.isArray(this.body[0])) return this.arrayConcat(this.body) + if (bops.is(this.body[0])) return bops.join(this.body) + return this.body +} - // a flag to see when we're in the middle of a write. - this.writing = false; +ConcatStream.prototype.end = function() { + if (this.cb) this.cb(this.getBody()) +} - // 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, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; +module.exports = function(cb) { + return new ConcatStream(cb) +} - // 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; +module.exports.ConcatStream = ConcatStream - // the callback that's passed to _write(chunk,cb) - this.onwrite = function(er) { - onwrite(stream, er); - }; +},{"bops":36,"stream":17,"util":21}],36:[function(require,module,exports){ +var proto = {} +module.exports = proto - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; +proto.from = require('./from.js') +proto.to = require('./to.js') +proto.is = require('./is.js') +proto.subarray = require('./subarray.js') +proto.join = require('./join.js') +proto.copy = require('./copy.js') +proto.create = require('./create.js') - // the amount that is being written when _write is called. - this.writelen = 0; +mix(require('./read.js'), proto) +mix(require('./write.js'), proto) - this.buffer = []; +function mix(from, into) { + for(var key in from) { + into[key] = from[key] + } } -function Writable(options) { - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) - return new Writable(options); - - this._writableState = new WritableState(options, this); +},{"./copy.js":39,"./create.js":40,"./from.js":41,"./is.js":42,"./join.js":43,"./read.js":45,"./subarray.js":46,"./to.js":47,"./write.js":48}],37:[function(require,module,exports){ +module.exports=require(24) +},{}],38:[function(require,module,exports){ +module.exports = to_utf8 + +var out = [] + , col = [] + , fcc = String.fromCharCode + , mask = [0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01] + , unmask = [ + 0x00 + , 0x01 + , 0x02 | 0x01 + , 0x04 | 0x02 | 0x01 + , 0x08 | 0x04 | 0x02 | 0x01 + , 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + , 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + , 0x40 | 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + ] + +function to_utf8(bytes, start, end) { + start = start === undefined ? 0 : start + end = end === undefined ? bytes.length : end + + var idx = 0 + , hi = 0x80 + , collecting = 0 + , pos + , by + + col.length = + out.length = 0 + + while(idx < bytes.length) { + by = bytes[idx] + if(!collecting && by & hi) { + pos = find_pad_position(by) + collecting += pos + if(pos < 8) { + col[col.length] = by & unmask[6 - pos] + } + } else if(collecting) { + col[col.length] = by & unmask[6] + --collecting + if(!collecting && col.length) { + out[out.length] = fcc(reduced(col, pos)) + col.length = 0 + } + } else { + out[out.length] = fcc(by) + } + ++idx + } + if(col.length && !collecting) { + out[out.length] = fcc(reduced(col, pos)) + col.length = 0 + } + return out.join('') +} - // legacy. - this.writable = true; +function find_pad_position(byt) { + for(var i = 0; i < 7; ++i) { + if(!(byt & mask[i])) { + break + } + } + return i +} - Stream.call(this); +function reduced(list) { + var out = 0 + for(var i = 0, len = list.length; i < len; ++i) { + out |= list[i] << ((len - i - 1) * 6) + } + return out } -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function() { - this.emit('error', new Error('Cannot pipe. Not readable.')); -}; +},{}],39:[function(require,module,exports){ +module.exports = copy +var slice = [].slice -function writeAfterEnd(stream, state, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - setImmediate(function() { - cb(er); - }); -} +function copy(source, target, target_start, source_start, source_end) { + target_start = arguments.length < 3 ? 0 : target_start + source_start = arguments.length < 4 ? 0 : source_start + source_end = arguments.length < 5 ? source.length : source_end -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. -function validChunk(stream, state, chunk, cb) { - var valid = true; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); - stream.emit('error', er); - setImmediate(function() { - cb(er); - }); - valid = false; + if(source_end === source_start) { + return } - return valid; -} - -Writable.prototype.write = function(chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; + if(target.length === 0 || source.length === 0) { + return } - if (!Buffer.isBuffer(chunk) && isUint8Array(chunk)) - chunk = new Buffer(chunk); - if (isArrayBuffer(chunk) && typeof Uint8Array !== 'undefined') - chunk = new Buffer(new Uint8Array(chunk)); - - if (Buffer.isBuffer(chunk)) - encoding = 'buffer'; - else if (!encoding) - encoding = state.defaultEncoding; + if(source_end > source.length) { + source_end = source.length + } - if (typeof cb !== 'function') - cb = function() {}; + if(target.length - target_start < source_end - source_start) { + source_end = target.length - target_start + start + } - if (state.ended) - writeAfterEnd(this, state, cb); - else if (validChunk(this, state, chunk, cb)) - ret = writeOrBuffer(this, state, chunk, encoding, cb); + if(source.buffer !== target.buffer) { + return fast_copy(source, target, target_start, source_start, source_end) + } + return slow_copy(source, target, target_start, source_start, source_end) +} - return ret; -}; +function fast_copy(source, target, target_start, source_start, source_end) { + var len = (source_end - source_start) + target_start -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && - state.decodeStrings !== false && - typeof chunk === 'string') { - chunk = new Buffer(chunk, encoding); + for(var i = target_start, j = source_start; + i < len; + ++i, + ++j) { + target[i] = source[j] } - return chunk; } -// 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, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - var len = state.objectMode ? 1 : chunk.length; +function slow_copy(from, to, j, i, jend) { + // the buffers could overlap. + var iend = jend + i + , tmp = new Uint8Array(slice.call(from, i, iend)) + , x = 0 - state.length += len; + for(; i < iend; ++i, ++x) { + to[j++] = tmp[x] + } +} - var ret = state.length < state.highWaterMark; - state.needDrain = !ret; +},{}],40:[function(require,module,exports){ +module.exports = function(size) { + return new Uint8Array(size) +} - if (state.writing) - state.buffer.push(new WriteReq(chunk, encoding, cb)); - else - doWrite(stream, state, len, chunk, encoding, cb); +},{}],41:[function(require,module,exports){ +module.exports = from - return ret; -} +var base64 = require('base64-js') -function doWrite(stream, state, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - stream._write(chunk, encoding, state.onwrite); - state.sync = false; +var decoders = { + hex: from_hex + , utf8: from_utf + , base64: from_base64 } -function onwriteError(stream, state, sync, er, cb) { - if (sync) - setImmediate(function() { - cb(er); - }); - else - cb(er); +function from(source, encoding) { + if(Array.isArray(source)) { + return new Uint8Array(source) + } - stream.emit('error', er); + return decoders[encoding || 'utf8'](source) } -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} +function from_hex(str) { + var size = str.length / 2 + , buf = new Uint8Array(size) + , character = '' -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; + for(var i = 0, len = str.length; i < len; ++i) { + character += str.charAt(i) - onwriteStateUpdate(state); + if(i > 0 && (i % 2) === 1) { + buf[i>>>1] = parseInt(character, 16) + character = '' + } + } - 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(stream, state); + return buf +} - if (!finished && !state.bufferProcessing && state.buffer.length) - clearBuffer(stream, state); +function from_utf(str) { + var bytes = [] + , tmp + , ch - if (sync) { - setImmediate(function() { - afterWrite(stream, state, finished, cb); - }); + for(var i = 0, len = str.length; i < len; ++i) { + ch = str.charCodeAt(i) + if(ch & 0x80) { + tmp = encodeURIComponent(str.charAt(i)).substr(1).split('%') + for(var j = 0, jlen = tmp.length; j < jlen; ++j) { + bytes[bytes.length] = parseInt(tmp[j], 16) + } } else { - afterWrite(stream, state, finished, cb); + bytes[bytes.length] = ch } } -} -function afterWrite(stream, state, finished, cb) { - if (!finished) - onwriteDrain(stream, state); - cb(); - if (finished) - finishMaybe(stream, state); + return new Uint8Array(bytes) } -// 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'); - } +function from_base64(str) { + return new Uint8Array(base64.toByteArray(str)) } +},{"base64-js":37}],42:[function(require,module,exports){ -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; +module.exports = function(buffer) { + return buffer instanceof Uint8Array; +} - for (var c = 0; c < state.buffer.length; c++) { - var entry = state.buffer[c]; - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; +},{}],43:[function(require,module,exports){ +module.exports = join - doWrite(stream, state, len, chunk, encoding, cb); +function join(targets, hint) { + if(!targets.length) { + return new Uint8Array(0) + } - // 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) { - c++; - break; + var len = hint !== undefined ? hint : get_length(targets) + , out = new Uint8Array(len) + , cur = targets[0] + , curlen = cur.length + , curidx = 0 + , curoff = 0 + , i = 0 + + while(i < len) { + if(curoff === curlen) { + curoff = 0 + ++curidx + cur = targets[curidx] + curlen = cur && cur.length + continue } + out[i++] = cur[curoff++] } - state.bufferProcessing = false; - if (c < state.buffer.length) - state.buffer = state.buffer.slice(c); - else - state.buffer.length = 0; + return out } -Writable.prototype._write = function(chunk, encoding, cb) { - cb(new Error('not implemented')); -}; - -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; +function get_length(targets) { + var size = 0 + for(var i = 0, len = targets.length; i < len; ++i) { + size += targets[i].byteLength } + return size +} - if (typeof chunk !== 'undefined' && chunk !== null) - this.write(chunk, encoding); +},{}],44:[function(require,module,exports){ +var proto + , map - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) - endWritable(this, state, cb); -}; +module.exports = proto = {} +map = typeof WeakMap === 'undefined' ? null : new WeakMap -function needFinish(stream, state) { - return (state.ending && - state.length === 0 && - !state.finished && - !state.writing); -} +proto.get = !map ? no_weakmap_get : get -function finishMaybe(stream, state) { - var need = needFinish(stream, state); - if (need) { - state.finished = true; - stream.emit('finish'); - } - return need; +function no_weakmap_get(target) { + return new DataView(target.buffer, 0) } -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) - setImmediate(cb); - else - stream.once('finish', cb); +function get(target) { + var out = map.get(target.buffer) + if(!out) { + map.set(target.buffer, out = new DataView(target.buffer, 0)) } - state.ended = true; + return out } -},{"./index.js":25,"buffer":3,"inherits":18,"process/browser.js":26}],31:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var Buffer = require('buffer').Buffer; - -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } +},{}],45:[function(require,module,exports){ +module.exports = { + readUInt8: read_uint8 + , readInt8: read_int8 + , readUInt16LE: read_uint16_le + , readUInt32LE: read_uint32_le + , readInt16LE: read_int16_le + , readInt32LE: read_int32_le + , readFloatLE: read_float_le + , readDoubleLE: read_double_le + , readUInt16BE: read_uint16_be + , readUInt32BE: read_uint32_be + , readInt16BE: read_int16_be + , readInt32BE: read_int32_be + , readFloatBE: read_float_be + , readDoubleBE: read_double_be } -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } +var map = require('./mapped.js') - this.charBuffer = new Buffer(6); - this.charReceived = 0; - this.charLength = 0; -}; +function read_uint8(target, at) { + return target[at] +} +function read_int8(target, at) { + var v = target[at]; + return v < 0x80 ? v : v - 0x100 +} -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - var offset = 0; +function read_uint16_le(target, at) { + var dv = map.get(target); + return dv.getUint16(at + target.byteOffset, true) +} - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var i = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; +function read_uint32_le(target, at) { + var dv = map.get(target); + return dv.getUint32(at + target.byteOffset, true) +} - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, offset, i); - this.charReceived += (i - offset); - offset = i; +function read_int16_le(target, at) { + var dv = map.get(target); + return dv.getInt16(at + target.byteOffset, true) +} - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } +function read_int32_le(target, at) { + var dv = map.get(target); + return dv.getInt32(at + target.byteOffset, true) +} - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); +function read_float_le(target, at) { + var dv = map.get(target); + return dv.getFloat32(at + target.byteOffset, true) +} - // lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; +function read_double_le(target, at) { + var dv = map.get(target); + return dv.getFloat64(at + target.byteOffset, true) +} - // if there are no more bytes in this buffer, just emit our char - if (i == buffer.length) return charStr; +function read_uint16_be(target, at) { + var dv = map.get(target); + return dv.getUint16(at + target.byteOffset, false) +} - // otherwise cut off the characters end from the beginning of this buffer - buffer = buffer.slice(i, buffer.length); - break; - } +function read_uint32_be(target, at) { + var dv = map.get(target); + return dv.getUint32(at + target.byteOffset, false) +} - var lenIncomplete = this.detectIncompleteChar(buffer); +function read_int16_be(target, at) { + var dv = map.get(target); + return dv.getInt16(at + target.byteOffset, false) +} - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); - this.charReceived = lenIncomplete; - end -= lenIncomplete; - } +function read_int32_be(target, at) { + var dv = map.get(target); + return dv.getInt32(at + target.byteOffset, false) +} - charStr += buffer.toString(this.encoding, 0, end); +function read_float_be(target, at) { + var dv = map.get(target); + return dv.getFloat32(at + target.byteOffset, false) +} - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); - return charStr.substring(0, end); - } +function read_double_be(target, at) { + var dv = map.get(target); + return dv.getFloat64(at + target.byteOffset, false) +} - // or just emit the charStr - return charStr; -}; +},{"./mapped.js":44}],46:[function(require,module,exports){ +module.exports = subarray -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; +function subarray(buf, from, to) { + return buf.subarray(from || 0, to || buf.length) +} - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; +},{}],47:[function(require,module,exports){ +module.exports = to - // See http://en.wikipedia.org/wiki/UTF-8#Description +var base64 = require('base64-js') + , toutf8 = require('to-utf8') - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } +var encoders = { + hex: to_hex + , utf8: to_utf + , base64: to_base64 +} - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } +function to(buf, encoding) { + return encoders[encoding || 'utf8'](buf) +} - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } +function to_hex(buf) { + var str = '' + , byt + + for(var i = 0, len = buf.length; i < len; ++i) { + byt = buf[i] + str += ((byt & 0xF0) >>> 4).toString(16) + str += (byt & 0x0F).toString(16) } - return i; -}; + return str +} -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); +function to_utf(buf) { + return toutf8(buf) +} - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } +function to_base64(buf) { + return base64.fromByteArray(buf) +} - return res; -}; -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); +},{"base64-js":37,"to-utf8":38}],48:[function(require,module,exports){ +module.exports = { + writeUInt8: write_uint8 + , writeInt8: write_int8 + , writeUInt16LE: write_uint16_le + , writeUInt32LE: write_uint32_le + , writeInt16LE: write_int16_le + , writeInt32LE: write_int32_le + , writeFloatLE: write_float_le + , writeDoubleLE: write_double_le + , writeUInt16BE: write_uint16_be + , writeUInt32BE: write_uint32_be + , writeInt16BE: write_int16_be + , writeInt32BE: write_int32_be + , writeFloatBE: write_float_be + , writeDoubleBE: write_double_be } -function utf16DetectIncompleteChar(buffer) { - var incomplete = this.charReceived = buffer.length % 2; - this.charLength = incomplete ? 2 : 0; - return incomplete; +var map = require('./mapped.js') + +function write_uint8(target, value, at) { + return target[at] = value } -function base64DetectIncompleteChar(buffer) { - var incomplete = this.charReceived = buffer.length % 3; - this.charLength = incomplete ? 3 : 0; - return incomplete; +function write_int8(target, value, at) { + return target[at] = value < 0 ? value + 0x100 : value } -},{"buffer":3}],32:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +function write_uint16_le(target, value, at) { + var dv = map.get(target); + return dv.setUint16(at + target.byteOffset, value, true) +} -var punycode = require('punycode'); +function write_uint32_le(target, value, at) { + var dv = map.get(target); + return dv.setUint32(at + target.byteOffset, value, true) +} -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; +function write_int16_le(target, value, at) { + var dv = map.get(target); + return dv.setInt16(at + target.byteOffset, value, true) +} -exports.Url = Url; +function write_int32_le(target, value, at) { + var dv = map.get(target); + return dv.setInt32(at + target.byteOffset, value, true) +} -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; +function write_float_le(target, value, at) { + var dv = map.get(target); + return dv.setFloat32(at + target.byteOffset, value, true) } -// Reference: RFC 3986, RFC 1808, RFC 2396 +function write_double_le(target, value, at) { + var dv = map.get(target); + return dv.setFloat64(at + target.byteOffset, value, true) +} -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, +function write_uint16_be(target, value, at) { + var dv = map.get(target); + return dv.setUint16(at + target.byteOffset, value, false) +} - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], +function write_uint32_be(target, value, at) { + var dv = map.get(target); + return dv.setUint32(at + target.byteOffset, value, false) +} - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), +function write_int16_be(target, value, at) { + var dv = map.get(target); + return dv.setInt16(at + target.byteOffset, value, false) +} - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = require('querystring'); +function write_int32_be(target, value, at) { + var dv = map.get(target); + return dv.setInt32(at + target.byteOffset, value, false) +} -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && isObject(url) && url instanceof Url) return url; +function write_float_be(target, value, at) { + var dv = map.get(target); + return dv.setFloat32(at + target.byteOffset, value, false) +} - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; +function write_double_be(target, value, at) { + var dv = map.get(target); + return dv.setFloat64(at + target.byteOffset, value, false) } -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); - } +},{"./mapped.js":44}],49:[function(require,module,exports){ +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; - var rest = url; + i += d; - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); - } + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { - - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. + value = Math.abs(value); - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; } - - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); + if (e + eBias >= 1) { + value += rt / c; } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); + value += rt * Math.pow(2, 1 - eBias); } - - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); + if (value * c >= 2) { + e++; + c /= 2; } - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; + } - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - // pull out port. - this.parseHost(); + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; + buffer[offset + i - d] |= s * 128; +}; - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; +},{}],"q9TxCC":[function(require,module,exports){ +var assert; +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } +function stringtrim(str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +} - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); +function Buffer(subject, encoding, offset) { + if(!assert) assert= require('assert'); + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; + + // Work-around: node's base64 implementation + // allows for non-padded strings while base64-js + // does not.. + if (encoding == "base64" && typeof subject == "string") { + subject = stringtrim(subject); + while (subject.length % 4 != 0) { + subject = subject + "="; } + } - if (!ipv6Hostname) { - // IDNA Support: Returns a puny coded representation of "domain". - // It only converts the part of the domain name that - // has non ASCII characters. I.e. it dosent matter if - // you call it with a domain that already is in ASCII. - var domainArray = this.hostname.split('.'); - var newOut = []; - for (var i = 0; i < domainArray.length; ++i) { - var s = domainArray[i]; - newOut.push(s.match(/[^A-Za-z0-9_-]/) ? - 'xn--' + punycode.encode(s) : s); - } - this.hostname = newOut.join('.'); + var type; + + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + // slicing works, with limitations (no parent tracking/update) + // check https://github.com/toots/buffer-browserify/issues/19 + for (var i = 0; i < this.length; i++) { + this[i] = subject.get(i+offset); } + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; + + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } + + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; } } } +} - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; +}; - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); - } - rest = rest.split(ae).join(esc); - } +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; + +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; + + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; + + case 'ascii': + case 'binary': + return str.length; + + case 'base64': + return base64ToBytes(str).length; + + default: + throw new Error('Unknown encoding'); } +}; +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; + +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; + +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; + +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; + +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); + + i++; } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); + + return res + decodeUtf8Char(tmp); +} + +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} + +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; + +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; + return ''; +}; + + +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); } + return out; +}; - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; + +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; + + // Fastpath empty strings + if (+end == start) { + return ''; } - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; + case 'ascii': + return this.asciiSlice(start, end); + + case 'binary': + return this.binarySlice(start, end); + + case 'base64': + return this.base64Slice(start, end); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); + + default: + throw new Error('Unknown encoding'); } +}; - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; } } - if (this.query && - isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); + } + if (length > strLen / 2) { + length = strLen / 2; } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; +}; - var search = this.search || (query && ('?' + query)) || ''; - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; + } + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } } + encoding = String(encoding || 'utf8').toLowerCase(); - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); - return protocol + host + pathname + search + hash; -}; + case 'ascii': + return this.asciiWrite(string, offset, length); -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} + case 'binary': + return this.binaryWrite(string, offset, length); -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; + case 'base64': + return this.base64Write(string, offset, length); -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); -Url.prototype.resolveObject = function(relative) { - if (isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; + default: + throw new Error('Unknown encoding'); } +}; - var result = new Url(); - Object.keys(this).forEach(function(k) { - result[k] = this[k]; - }, this); +// slice(start, end) +function clamp(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +} - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; +Buffer.prototype.slice = function(start, end) { + var len = this.length; + start = clamp(start, len, 0); + end = clamp(end, len, len); + return new Buffer(this, end - start, +start); +}; - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; } + target_start || (target_start = 0); - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - Object.keys(relative).forEach(function(k) { - if (k !== 'protocol') - result[k] = relative[k]; - }); + if (end < start) throw new Error('sourceEnd < sourceStart'); - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; - result.href = result.format(); - return result; + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); } - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - Object.keys(relative).forEach(function(k) { - result[k] = relative[k]; - }); - result.href = result.format(); - return result; - } + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); + } - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); } - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; + // Are we oob? + if (end > this.length) { + end = this.length; + } - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; - } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + if (target.length - target_start < end - start) { + end = target.length - target_start + start; } - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.href = result.format(); - return result; + var temp = []; + for (var i=start; i 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last == '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } + if (typeof value === 'string') { + value = value.charCodeAt(0); + } + if (!(typeof value === 'number') || isNaN(value)) { + throw new Error('value is not a number'); } - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } + if (end < start) throw new Error('end < start'); + + // Fill 0 bytes; we're done + if (end === start) return 0; + if (this.length == 0) return 0; + + if (start < 0 || start >= this.length) { + throw new Error('start out of bounds'); } - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); } - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); + for (var i = start; i < end; i++) { + this[i] = value; } +} - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; +}; - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); } - mustEndAbs = mustEndAbs || (result.host && srcPath.length); - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; } - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; + } } - //to support request.http - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; + return buffer; }; -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); - } - host = host.substr(0, host.length - port.length); +Buffer.isEncoding = function(encoding) { + switch ((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; } - if (host) this.hostname = host; }; -function isString(arg) { - return typeof arg === "string"; -} +// helpers -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; } -function isNull(arg) { - return arg === null; +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) } -function isNullOrUndefined(arg) { - return arg == null; + +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; } -},{"punycode":20,"querystring":23}],33:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); } -},{}],34:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); } - return objects.join(' '); + + return byteArray; +} + +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); + + return byteArray; +} + +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} + +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; + + dst[i + offset] = src[i]; + i++; } + return i; +} - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char + } +} + +// read/write bit-twiddling + +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + return buffer[offset]; +}; + +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; } } - return str; + + return val; +} + +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; + +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); + } + + return val; +} + +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; + + +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); + } + + if (offset >= buffer.length) return; + + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); + } + + return ((0xff - buffer[offset] + 1) * -1); }; +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (process.noDeprecation === true) { - return fn; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); } - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; } - return deprecated; -}; + return (0xffff - val + 1) * -1; +} +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); }; +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); + + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); + } + + return (0xffffffff - val + 1) * -1; } -exports.inspect = inspect; +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); +}; -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); }; -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); }; +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); } +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); +}; -function stylizeNoColor(str, styleType) { - return str; -} +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); +}; -function arrayToHash(array) { - var hash = {}; +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - array.forEach(function(val, idx) { - hash[val] = true; - }); + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); - return hash; + assert.ok(value <= max, 'value is larger than maximum value for type'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); } +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xff); } - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; + if (offset < buffer.length) { + buffer[offset] = value; } +}; - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); + verifuint(value, 0xffff); } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; } - var base = '', array = false, braces = ['{', '}']; +} - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); +}; + +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); } - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; } +} - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; + + +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: + * + * > -32 & 0xff + * 224 + * + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. + * + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: + * + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: + * + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. + */ + +/* + * A series of checks to make sure we actually have a signed 32-bit number + */ +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} + +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} + +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7f, -0x80); } - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); } +}; - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); } - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); } +} - ctx.seen.push(value); +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; + +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fffffff, -0x80000000); + } + + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); } +} - ctx.seen.pop(); +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; - return reduceToSingleString(output, base, braces); +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; + +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); } +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); +}; -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); +}; + +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); } +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; +},{"./buffer_ieee754":1,"assert":6,"base64-js":4}],"buffer-browserify":[function(require,module,exports){ +module.exports=require('q9TxCC'); +},{}],4:[function(require,module,exports){ +(function (exports) { + 'use strict'; + + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } + + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } + + return arr; + } + + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } + + return output; + } + + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); + +},{}],5:[function(require,module,exports){ + + +// +// The shims in this file are not fully implemented shims for the ES5 +// features, but do work for the particular usecases there is in +// the other modules. +// + +var toString = Object.prototype.toString; +var hasOwnProperty = Object.prototype.hasOwnProperty; + +// Array.isArray is supported in IE9 +function isArray(xs) { + return toString.call(xs) === '[object Array]'; } +exports.isArray = typeof Array.isArray === 'function' ? Array.isArray : isArray; +// Array.prototype.indexOf is supported in IE9 +exports.indexOf = function indexOf(xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; + } + return -1; +}; -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } +// Array.prototype.filter is supported in IE9 +exports.filter = function filter(xs, fn) { + if (xs.filter) return xs.filter(fn); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (fn(xs[i], i, xs)) res.push(xs[i]); } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} + return res; +}; +// Array.prototype.forEach is supported in IE9 +exports.forEach = function forEach(xs, fn, self) { + if (xs.forEach) return xs.forEach(fn, self); + for (var i = 0; i < xs.length; i++) { + fn.call(self, xs[i], i, xs); + } +}; -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } +// Array.prototype.map is supported in IE9 +exports.map = function map(xs, fn) { + if (xs.map) return xs.map(fn); + var out = new Array(xs.length); + for (var i = 0; i < xs.length; i++) { + out[i] = fn(xs[i], i, xs); } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; + return out; +}; + +// Array.prototype.reduce is supported in IE9 +exports.reduce = function reduce(array, callback, opt_initialValue) { + if (array.reduce) return array.reduce(callback, opt_initialValue); + var value, isValueSet = false; + + if (2 < arguments.length) { + value = opt_initialValue; + isValueSet = true; } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); + for (var i = 0, l = array.length; l > i; ++i) { + if (array.hasOwnProperty(i)) { + if (isValueSet) { + value = callback(value, array[i], i, array); } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } + else { + value = array[i]; + isValueSet = true; } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); } } - return name + ': ' + str; + return value; +}; + +// String.prototype.substr - negative index don't work in IE8 +if ('ab'.substr(-1) !== 'b') { + exports.substr = function (str, start, length) { + // did we get a negative start, calculate how much it is from the beginning of the string + if (start < 0) start = str.length + start; + + // call the original function + return str.substr(start, length); + }; +} else { + exports.substr = function (str, start, length) { + return str.substr(start, length); + }; } +// String.prototype.trim is supported in IE9 +exports.trim = function (str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +}; -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); +// Function.prototype.bind is supported in IE9 +exports.bind = function () { + var args = Array.prototype.slice.call(arguments); + var fn = args.shift(); + if (fn.bind) return fn.bind.apply(fn, args); + var self = args.shift(); + return function () { + fn.apply(self, args.concat([Array.prototype.slice.call(arguments)])); + }; +}; - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; +// Object.create is supported in IE9 +function create(prototype, properties) { + var object; + if (prototype === null) { + object = { '__proto__' : null }; + } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); } + return object; +} +exports.create = typeof Object.create === 'function' ? Object.create : create; - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +// Object.keys and Object.getOwnPropertyNames is supported in IE9 however +// they do show a description and number property on Error objects +function notObject(object) { + return ((typeof object != "object" && typeof object != "function") || object === null); } +function keysShim(object) { + if (notObject(object)) { + throw new TypeError("Object.keys called on a non-object"); + } -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); + var result = []; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result.push(name); + } + } + return result; } -exports.isArray = isArray; -function isBoolean(arg) { - return typeof arg === 'boolean'; +// getOwnPropertyNames is almost the same as Object.keys one key feature +// is that it returns hidden properties, since that can't be implemented, +// this feature gets reduced so it just shows the length property on arrays +function propertyShim(object) { + if (notObject(object)) { + throw new TypeError("Object.getOwnPropertyNames called on a non-object"); + } + + var result = keysShim(object); + if (exports.isArray(object) && exports.indexOf(object, 'length') === -1) { + result.push('length'); + } + return result; } -exports.isBoolean = isBoolean; -function isNull(arg) { - return arg === null; +var keys = typeof Object.keys === 'function' ? Object.keys : keysShim; +var getOwnPropertyNames = typeof Object.getOwnPropertyNames === 'function' ? + Object.getOwnPropertyNames : propertyShim; + +if (new Error().hasOwnProperty('description')) { + var ERROR_PROPERTY_FILTER = function (obj, array) { + if (toString.call(obj) === '[object Error]') { + array = exports.filter(array, function (name) { + return name !== 'description' && name !== 'number' && name !== 'message'; + }); + } + return array; + }; + + exports.keys = function (object) { + return ERROR_PROPERTY_FILTER(object, keys(object)); + }; + exports.getOwnPropertyNames = function (object) { + return ERROR_PROPERTY_FILTER(object, getOwnPropertyNames(object)); + }; +} else { + exports.keys = keys; + exports.getOwnPropertyNames = getOwnPropertyNames; } -exports.isNull = isNull; -function isNullOrUndefined(arg) { - return arg == null; +// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements +function valueObject(value, key) { + return { value: value[key] }; } -exports.isNullOrUndefined = isNullOrUndefined; -function isNumber(arg) { - return typeof arg === 'number'; +if (typeof Object.getOwnPropertyDescriptor === 'function') { + try { + Object.getOwnPropertyDescriptor({'a': 1}, 'a'); + exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + } catch (e) { + // IE8 dom element issue - use a try catch and default to valueObject + exports.getOwnPropertyDescriptor = function (value, key) { + try { + return Object.getOwnPropertyDescriptor(value, key); + } catch (e) { + return valueObject(value, key); + } + }; + } +} else { + exports.getOwnPropertyDescriptor = valueObject; } -exports.isNumber = isNumber; -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; +},{}],6:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// UTILITY +var util = require('util'); +var shims = require('_shims'); +var pSlice = Array.prototype.slice; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; +var assert = module.exports = ok; -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + this.message = options.message || getMessage(this); +}; -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; } -exports.isError = isError; -function isFunction(arg) { - return typeof arg === 'function'; +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } } -exports.isFunction = isFunction; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); } -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); -function objectToString(o) { - return Object.prototype.toString.call(o); -} +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); } +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); } +assert.ok = ok; +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); }; +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); } - return origin; }; -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; -}).call(this,require("FWaASH"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":33,"FWaASH":19,"inherits":18}],35:[function(require,module,exports){ -function replace(a, b) -{ - if (!b) - { - return a; - } - var key; - for (key in b) - { - if(b.hasOwnProperty(key)) - { - a[key] = b[key]; - } - } - - return a; -} exports.replace=replace; - -function add(a, b) -{ - if (!b) - { - return a; - } - var key; - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined' || a[key]===null) - { - a[key] = b[key]; - } - } - } - return a; -} exports.add=add; - - -function extend(a, b, context, newobjs, aparent, aname, haveaparent) // context is anti circular references mechanism -{ - if (a==b){ return a;} - if (!b) { return a;} - - var key, clean_context=false, return_sublevel=false,b_pos; - if(!haveaparent){ aparent={'a':a}; aname='a'; } - if(!context){clean_context=true;context=[];newobjs=[];} - b_pos=context.indexOf(b); - if( b_pos==-1 ) {context.push(b);newobjs.push([aparent, aname]);} else { return newobjs[b_pos][0][ newobjs[b_pos][1] ]; } - - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined') - { - if(typeof b[key] === 'object') - { - if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html - {a[key] = extend([], b[key],context,newobjs,a,key,true);} - else if(b[key]===null) - {a[key] = null;} - else if( b[key] instanceof Date ) - { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } - else - { a[key] = extend({}, b[key],context,newobjs,a,key,true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/ } - } - else - { a[key] = b[key]; } - } - else if(typeof a[key] === 'object' && a[key] !== null) - { a[key] = extend(a[key], b[key],context,newobjs,a,key,true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/ } - else - { a[key] = b[key]; } - } - } - if(clean_context) {context=null;newobjs=null;} - if(!haveaparent) - { - aparent=null; - return a; - } - if(typeof a === 'object' && !(a instanceof Array) ) - { - /*a.constructor = b.constructor; - a.prototype = b.prototype*/; - } - return a; -} exports.extend=extend; - -function extenduptolevel(a, b, levels, context, newobjs, aparent, aname, haveaparent) -{ - if (a==b){ return a;} - if (!b){ return a;} - - var key, clean_context=false, return_sublevel=false; - if(!haveaparent){ aparent={'a':a}; aname='a'; } - if(!context){clean_context=true;context=[];newobjs=[];} - b_pos=context.indexOf(b); - if( b_pos==-1 ) {context.push(b);newobjs.push([aparent, aname]);} else { return newobjs[b_pos][0][ newobjs[b_pos][1] ]; } - - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined') - { - if(typeof b[key] === 'object' && levels>0) - { - if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html - { a[key] = extenduptolevel([], b[key],levels-1,context,newobjs,a,key,true); } - else if(b[key]===null) - { a[key] = null; } - else if( b[key] instanceof Date ) - { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } - else - { a[key] = extenduptolevel({}, b[key],levels-1,context,newobjs,a,key,true); } - } - else - { a[key] = b[key]; } - } - else if(typeof a[key] === 'object' && a[key] !== null && levels>0) - { a[key] = extenduptolevel(a[key], b[key],levels-1,context,newobjs,a,key,true); } - else - { a[key] = b[key]; } - } - } - if(clean_context) {context=null;newobjs=null;} - - if(!haveaparent) - { - aparent=null; - return a; - } - if(typeof a === 'object' && !(a instanceof Array) ) - { - /*a.constructor = b.constructor; - a.prototype = b.prototype;*/ - } - return a; -} exports.extenduptolevel=extenduptolevel; - -function clone(obj) -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - if (obj instanceof Array ) - { return extend([], obj); } - else if( obj instanceof Date ) - { - var t= new obj.constructor(); - t.setTime(obj.getTime()); - return t; - } - else - { return extend({}, obj); } - } - return obj; -} exports.clone=clone; - -function cloneextend(obj,exteddata) -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - return extend(clone(obj),exteddata); - } - return obj; -} exports.cloneextend=cloneextend; - - -function cloneuptolevel(obj,level) // clone only numlevels levels other levels leave references -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - if (obj instanceof Array ) { return extenduptolevel([], obj,level); } - return extenduptolevel({}, obj,level); - } - return obj; -} exports.cloneuptolevel=cloneuptolevel; - -function foreach(object, block, context) -{ - if (object) - { - if (typeof object === "object" && object instanceof Array) - return object.forEach(object, block, context) - else //if (typeof object === "object") // or (object instanceof Function)... - { - if(object) - for (var key in object) - { - if(object.hasOwnProperty(key)) - { - if(block.call(context, object[key], key, object)===false)break; - } - } - } - } -} exports.foreach=foreach; - -/* - hasbugs and useless, yet interesting maybe developed later for dot pathed object transformation: - - { - 'foo.bar':'bluebar', - 'foo.color':'blue' - } - - transforemed to - - { - foo: - { - bar:'bluebar', - color:'blue' - } - } - - like: - - var config={}; - cloneextend.dotpath(config,{ - 'foo.bar':'bluebar', - 'foo.color':'blue' - }) - - // - function dotpath(data,dotkeys,preserve) - { - if(!preserve)preserve=false; - var create=!preserve; - if(create) if(!data) data={}; - var keys= dotkeys.split("."),value=data; - for (var i=0;i - * @license MIT - * - * The MIT License (MIT) - * - * Copyright (c) 2013 Viacheslav Lotsmanov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; -/** - * Extening object that entered in first argument. - * Returns extended object or false if have no target object or incorrect type. - * If you wish to clone object, simply use that: - * deepExtend({}, yourObj_1, [yourObj_N]) - first arg is new empty object - */ -var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { - if (arguments.length < 1 || typeof arguments[0] !== 'object') { - return false; - } + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } - if (arguments.length < 2) return arguments[0]; + return true; - var target = arguments[0]; + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} - // convert arguments to array and cut off target object - var args = Array.prototype.slice.call(arguments, 1); +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} - var key, val, src, clone, tmpBuf; +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = shims.keys(a), + kb = shims.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} - args.forEach(function (obj) { - if (typeof obj !== 'object') return; +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); - for (key in obj) { - if ( ! (key in obj)) continue; +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; - src = target[key]; - val = obj[key]; +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); - if (val === target) continue; +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; - if (typeof val !== 'object' || val === null) { - target[key] = val; - continue; - } else if (val instanceof Buffer) { - tmpBuf = new Buffer(val.length); - val.copy(tmpBuf); - target[key] = tmpBuf; - continue; - } else if (val instanceof Date) { - target[key] = new Date(val.getTime()); - continue; - } +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); - if (typeof src !== 'object' || src === null) { - clone = (Array.isArray(val)) ? [] : {}; - target[key] = deepExtend(clone, val); - continue; - } +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; - if (Array.isArray(val)) { - clone = (Array.isArray(src)) ? src : []; - } else { - clone = (!Array.isArray(src)) ? src : {}; - } +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } - target[key] = deepExtend(clone, val); - } - }); + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } - return target; + return false; } -}).call(this,require("buffer").Buffer) -},{"buffer":3}],37:[function(require,module,exports){ -/*! - * EventEmitter2 - * https://github.com/hij1nx/EventEmitter2 - * - * Copyright (c) 2013 hij1nx - * Licensed under the MIT license. - */ -;!function(undefined) { +function _throws(shouldThrow, block, expected, message) { + var actual; - var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { - return Object.prototype.toString.call(obj) === "[object Array]"; - }; - var defaultMaxListeners = 10; + if (util.isString(expected)) { + message = expected; + expected = null; + } - function init() { - this._events = {}; - if (this._conf) { - configure.call(this, this._conf); - } + try { + block(); + } catch (e) { + actual = e; } - function configure(conf) { - if (conf) { + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); - this._conf = conf; + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } - conf.delimiter && (this.delimiter = conf.delimiter); - conf.maxListeners && (this._events.maxListeners = conf.maxListeners); - conf.wildcard && (this.wildcard = conf.wildcard); - conf.newListener && (this.newListener = conf.newListener); + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; +},{"_shims":5,"util":7}],7:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - if (this.wildcard) { - this.listenerTree = {}; - } - } - } +var shims = require('_shims'); - function EventEmitter(conf) { - this._events = {}; - this.newListener = false; - configure.call(this, conf); +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); } - // - // Attention, function return type now is array, always ! - // It has zero elements if no any matches found and one or more - // elements (leafs) if there are matches - // - function searchListenerTree(handlers, type, tree, i) { - if (!tree) { - return []; - } - var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, - typeLength = type.length, currentType = type[i], nextType = type[i+1]; - if (i === typeLength && tree._listeners) { - // - // If at the end of the event(s) list and the tree has listeners - // invoke those listeners. - // - if (typeof tree._listeners === 'function') { - handlers && handlers.push(tree._listeners); - return [tree]; - } else { - for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { - handlers && handlers.push(tree._listeners[leaf]); + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; } - return [tree]; - } + default: + return x; } - - if ((currentType === '*' || currentType === '**') || tree[currentType]) { - // - // If the event emitted is '*' at this part - // or there is a concrete match at this patch - // - if (currentType === '*') { - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); - } - } - return listeners; - } else if(currentType === '**') { - endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); - if(endReached && tree._listeners) { - // The next element has a _listeners, add it to the handlers. - listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); - } - - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - if(branch === '*' || branch === '**') { - if(tree[branch]._listeners && !endReached) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); - } - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } else if(branch === nextType) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); - } else { - // No match on this one, shift into the tree but not in the type array. - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } - } - } - return listeners; - } - - listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); } + } + return str; +}; - xTree = tree['*']; - if (xTree) { - // - // If the listener tree will allow any match for this part, - // then recursively explore all branches of the tree - // - searchListenerTree(handlers, type, xTree, i+1); - } +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; - xxTree = tree['**']; - if(xxTree) { - if(i < typeLength) { - if(xxTree._listeners) { - // If we have a listener on a '**', it will catch all, so add its handler. - searchListenerTree(handlers, type, xxTree, typeLength); - } - // Build arrays of matching next branches and others. - for(branch in xxTree) { - if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { - if(branch === nextType) { - // We know the next element will match, so jump twice. - searchListenerTree(handlers, type, xxTree[branch], i+2); - } else if(branch === currentType) { - // Current node matches, move into the tree. - searchListenerTree(handlers, type, xxTree[branch], i+1); - } else { - isolatedBranch = {}; - isolatedBranch[branch] = xxTree[branch]; - searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); - } - } - } - } else if(xxTree._listeners) { - // We have reached the end and still on a '**' - searchListenerTree(handlers, type, xxTree, typeLength); - } else if(xxTree['*'] && xxTree['*']._listeners) { - searchListenerTree(handlers, type, xxTree['*'], typeLength); - } - } +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; - return listeners; - } +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - function growListenerTree(type, listener) { - type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; - // - // Looks for two consecutive '**', if so, don't add the event at all. - // - for(var i = 0, len = type.length; i+1 < len; i++) { - if(type[i] === '**' && type[i+1] === '**') { - return; - } - } + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} - var tree = this.listenerTree; - var name = type.shift(); - while (name) { +function stylizeNoColor(str, styleType) { + return str; +} - if (!tree[name]) { - tree[name] = {}; - } - tree = tree[name]; +function arrayToHash(array) { + var hash = {}; - if (type.length === 0) { + shims.forEach(array, function(val, idx) { + hash[val] = true; + }); - if (!tree._listeners) { - tree._listeners = listener; - } - else if(typeof tree._listeners === 'function') { - tree._listeners = [tree._listeners, listener]; - } - else if (isArray(tree._listeners)) { + return hash; +} - tree._listeners.push(listener); - if (!tree._listeners.warned) { +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } - var m = defaultMaxListeners; + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } + // Look up the keys of the object. + var keys = shims.keys(value); + var visibleKeys = arrayToHash(keys); - if (m > 0 && tree._listeners.length > m) { + if (ctx.showHidden) { + keys = shims.getOwnPropertyNames(value); + } - tree._listeners.warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - tree._listeners.length); - console.trace(); - } - } - } - return true; - } - name = type.shift(); + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); } - return true; } - // By default EventEmitters will print a warning if more than - // 10 listeners are added to it. This is a useful default which - // helps finding memory leaks. - // - // Obviously not all Emitters should be limited to 10. This function allows - // that to be increased. Set to zero for unlimited. + var base = '', array = false, braces = ['{', '}']; - EventEmitter.prototype.delimiter = '.'; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - EventEmitter.prototype.setMaxListeners = function(n) { - this._events || init.call(this); - this._events.maxListeners = n; - if (!this._conf) this._conf = {}; - this._conf.maxListeners = n; - }; + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } - EventEmitter.prototype.event = ''; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } - EventEmitter.prototype.once = function(event, fn) { - this.many(event, 1, fn); - return this; - }; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } - EventEmitter.prototype.many = function(event, ttl, fn) { - var self = this; + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } - if (typeof fn !== 'function') { - throw new Error('many only accepts instances of Function'); - } + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } - function listener() { - if (--ttl === 0) { - self.off(event, listener); - } - fn.apply(this, arguments); + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); } + } - listener._origin = fn; + ctx.seen.push(value); - this.on(event, listener); + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } - return self; - }; + ctx.seen.pop(); - EventEmitter.prototype.emit = function() { + return reduceToSingleString(output, base, braces); +} - this._events || init.call(this); - var type = arguments[0]; +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} - if (type === 'newListener' && !this.newListener) { - if (!this._events.newListener) { return false; } - } - // Loop through the *_all* functions and invoke them. - if (this._all) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - for (i = 0, l = this._all.length; i < l; i++) { - this.event = type; - this._all[i].apply(this, args); - } - } +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._all && - !this._events.error && - !(this.wildcard && this.listenerTree.error)) { +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } + shims.forEach(keys, function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); } + }); + return output; +} - var handler; - if(this.wildcard) { - handler = []; - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - searchListenerTree.call(this, handler, ns, this.listenerTree, 0); +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = shims.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); } - else { - handler = this._events[type]; + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); } + } - if (typeof handler === 'function') { - this.event = type; - if (arguments.length === 1) { - handler.call(this); + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (shims.indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); } - else if (arguments.length > 1) - switch (arguments.length) { - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - handler.apply(this, args); + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); } - return true; - } - else if (handler) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - this.event = type; - listeners[i].apply(this, args); } - return (listeners.length > 0) || !!this._all; + } else { + str = ctx.stylize('[Circular]', 'special'); } - else { - return !!this._all; + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } + } - }; + return name + ': ' + str; +} - EventEmitter.prototype.on = function(type, listener) { - if (typeof type === 'function') { - this.onAny(type); - return this; - } +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = shims.reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); - if (typeof listener !== 'function') { - throw new Error('on only accepts instances of Function'); - } - this._events || init.call(this); + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} - if(this.wildcard) { - growListenerTree.call(this, type, listener); - return this; - } - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } - else if(typeof this._events[type] === 'function') { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - else if (isArray(this._events[type])) { - // If we've already got an array, just append. - this._events[type].push(listener); +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return shims.isArray(ar); +} +exports.isArray = isArray; - // Check for listener leak - if (!this._events[type].warned) { +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; - var m = defaultMaxListeners; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; - if (m > 0 && this._events[type].length > m) { +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - } - return this; - }; +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - EventEmitter.prototype.onAny = function(fn) { +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - if (typeof fn !== 'function') { - throw new Error('onAny only accepts instances of Function'); - } +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - if(!this._all) { - this._all = []; - } +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - // Add the function to the event listener collection. - this._all.push(fn); - return this; - }; +function isObject(arg) { + return typeof arg === 'object' && arg; +} +exports.isObject = isObject; - EventEmitter.prototype.addListener = EventEmitter.prototype.on; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - EventEmitter.prototype.off = function(type, listener) { - if (typeof listener !== 'function') { - throw new Error('removeListener only takes instances of Function'); - } +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; +} +exports.isError = isError; - var handlers,leafs=[]; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); - } - else { - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events[type]) return this; - handlers = this._events[type]; - leafs.push({_listeners:handlers}); - } +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - for (var iLeaf=0; iLeaf 0) { - fns = this._all; - for(i = 0, l = fns.length; i < l; i++) { - if(fn === fns[i]) { - fns.splice(i, 1); - return this; - } - } - } else { - this._all = []; - } - return this; - }; - EventEmitter.prototype.removeListener = EventEmitter.prototype.off; +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; - EventEmitter.prototype.removeAllListeners = function(type) { - if (arguments.length === 0) { - !this._events || init.call(this); - return this; + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = shims.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true } + }); +}; - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; - for (var iLeaf=0; iLeaf 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; } - }; + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(function() { - return EventEmitter; - }); - } else if (typeof exports === 'object') { - // CommonJS - exports.EventEmitter2 = EventEmitter; - } - else { - // Browser global. - window.EventEmitter2 = EventEmitter; - } -}(); +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; -},{}],38:[function(require,module,exports){ +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +},{}],51:[function(require,module,exports){ var jQuery = require('jquery'); /*! @@ -27327,7 +30064,7 @@ $.extend( $.ui, { })( jQuery ); -},{"jquery":40}],39:[function(require,module,exports){ +},{"jquery":53}],52:[function(require,module,exports){ var jQuery = require('jquery'); require('./core'); @@ -29370,7 +32107,7 @@ $.datepicker.version = "1.10.4"; })(jQuery); -},{"./core":38,"jquery":40}],40:[function(require,module,exports){ +},{"./core":51,"jquery":53}],53:[function(require,module,exports){ /*! * jQuery JavaScript Library v2.1.3 * http://jquery.com/ @@ -38577,23 +41314,25 @@ return jQuery; })); -},{}],41:[function(require,module,exports){ -//! moment.js -//! version : 2.5.1 +},{}],54:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};//! moment.js +//! version : 2.8.4 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com (function (undefined) { - /************************************ Constants ************************************/ var moment, - VERSION = "2.5.1", - global = this, + VERSION = '2.8.4', + // the global-scope this is NOT the global object in Node.js + globalScope = typeof global !== 'undefined' ? global : this, + oldGlobalMoment, round = Math.round, + hasOwnProperty = Object.prototype.hasOwnProperty, i, YEAR = 0, @@ -38604,24 +41343,14 @@ return jQuery; SECOND = 5, MILLISECOND = 6, - // internal storage for language config files - languages = {}, - - // moment internal properties - momentProperties = { - _isAMomentObject: null, - _i : null, - _f : null, - _l : null, - _strict : null, - _isUTC : null, - _offset : null, // optional. Combine with _isUTC - _pf : null, - _lang : null // optional - }, + // internal storage for locale config files + locales = {}, + + // extra moment internal properties (plugins register props here) + momentProperties = [], // check for nodeJS - hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'), + hasModule = (typeof module !== 'undefined' && module && module.exports), // ASP.NET json date format regex aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, @@ -38632,8 +41361,8 @@ return jQuery; isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, // parsing token regexes parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 @@ -38644,6 +41373,7 @@ return jQuery; parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO separator) + parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 //strict parsing regexes @@ -38670,13 +41400,13 @@ return jQuery; // iso time formats and regexes isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], + ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], ['HH:mm', /(T| )\d\d:\d\d/], ['HH', /(T| )\d\d/] ], - // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] + // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30'] parseTimezoneChunker = /([\+\-]|\d\d)/gi, // getter and setter names @@ -38701,6 +41431,7 @@ return jQuery; w : 'week', W : 'isoWeek', M : 'month', + Q : 'quarter', y : 'year', DDD : 'dayOfYear', e : 'weekday', @@ -38720,6 +41451,15 @@ return jQuery; // format function strings formatFunctions = {}, + // default relative time thresholds + relativeTimeThresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }, + // tokens to ordinalize and pad ordinalizeTokens = 'DDD w W M D d'.split(' '), paddedTokens = 'M D H h m s w W'.split(' '), @@ -38729,10 +41469,10 @@ return jQuery; return this.month() + 1; }, MMM : function (format) { - return this.lang().monthsShort(this, format); + return this.localeData().monthsShort(this, format); }, MMMM : function (format) { - return this.lang().months(this, format); + return this.localeData().months(this, format); }, D : function () { return this.date(); @@ -38744,13 +41484,13 @@ return jQuery; return this.day(); }, dd : function (format) { - return this.lang().weekdaysMin(this, format); + return this.localeData().weekdaysMin(this, format); }, ddd : function (format) { - return this.lang().weekdaysShort(this, format); + return this.localeData().weekdaysShort(this, format); }, dddd : function (format) { - return this.lang().weekdays(this, format); + return this.localeData().weekdays(this, format); }, w : function () { return this.week(); @@ -38796,10 +41536,10 @@ return jQuery; return this.isoWeekday(); }, a : function () { - return this.lang().meridiem(this.hours(), this.minutes(), true); + return this.localeData().meridiem(this.hours(), this.minutes(), true); }, A : function () { - return this.lang().meridiem(this.hours(), this.minutes(), false); + return this.localeData().meridiem(this.hours(), this.minutes(), false); }, H : function () { return this.hours(); @@ -38827,19 +41567,19 @@ return jQuery; }, Z : function () { var a = -this.zone(), - b = "+"; + b = '+'; if (a < 0) { a = -a; - b = "-"; + b = '-'; } - return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); + return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); }, ZZ : function () { var a = -this.zone(), - b = "+"; + b = '+'; if (a < 0) { a = -a; - b = "-"; + b = '-'; } return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); }, @@ -38849,6 +41589,9 @@ return jQuery; zz : function () { return this.zoneName(); }, + x : function () { + return this.valueOf(); + }, X : function () { return this.unix(); }, @@ -38857,8 +41600,24 @@ return jQuery; } }, + deprecations = {}, + lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; + // Pick the first defined of two or three arguments. dfl comes from + // default. + function dfl(a, b, c) { + switch (arguments.length) { + case 2: return a != null ? a : b; + case 3: return a != null ? a : b != null ? b : c; + default: throw new Error('Implement me'); + } + } + + function hasOwnProp(a, b) { + return hasOwnProperty.call(a, b); + } + function defaultParsingFlags() { // We need to deep clone this object, and es5 standard is not very // helpful. @@ -38876,6 +41635,31 @@ return jQuery; }; } + function printMsg(msg) { + if (moment.suppressDeprecationWarnings === false && + typeof console !== 'undefined' && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + return extend(function () { + if (firstTime) { + printMsg(msg); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + printMsg(msg); + deprecations[name] = true; + } + } + function padToken(func, count) { return function (a) { return leftZeroFill(func.call(this, a), count); @@ -38883,7 +41667,7 @@ return jQuery; } function ordinalizeToken(func, period) { return function (a) { - return this.lang().ordinal(func.call(this, a), period); + return this.localeData().ordinal(func.call(this, a), period); }; } @@ -38902,20 +41686,23 @@ return jQuery; Constructors ************************************/ - function Language() { - + function Locale() { } // Moment prototype object - function Moment(config) { - checkOverflow(config); - extend(this, config); + function Moment(config, skipOverflow) { + if (skipOverflow !== false) { + checkOverflow(config); + } + copyConfig(this, config); + this._d = new Date(+config._d); } // Duration Constructor function Duration(duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, months = normalizedInput.month || 0, weeks = normalizedInput.week || 0, days = normalizedInput.day || 0, @@ -38937,10 +41724,13 @@ return jQuery; // which months you are are talking about, so we have to store // it separately. this._months = +months + + quarters * 3 + years * 12; this._data = {}; + this._locale = moment.localeData(); + this._bubble(); } @@ -38951,31 +41741,67 @@ return jQuery; function extend(a, b) { for (var i in b) { - if (b.hasOwnProperty(i)) { + if (hasOwnProp(b, i)) { a[i] = b[i]; } } - if (b.hasOwnProperty("toString")) { + if (hasOwnProp(b, 'toString')) { a.toString = b.toString; } - if (b.hasOwnProperty("valueOf")) { + if (hasOwnProp(b, 'valueOf')) { a.valueOf = b.valueOf; } return a; } - function cloneMoment(m) { - var result = {}, i; - for (i in m) { - if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { - result[i] = m[i]; + function copyConfig(to, from) { + var i, prop, val; + + if (typeof from._isAMomentObject !== 'undefined') { + to._isAMomentObject = from._isAMomentObject; + } + if (typeof from._i !== 'undefined') { + to._i = from._i; + } + if (typeof from._f !== 'undefined') { + to._f = from._f; + } + if (typeof from._l !== 'undefined') { + to._l = from._l; + } + if (typeof from._strict !== 'undefined') { + to._strict = from._strict; + } + if (typeof from._tzm !== 'undefined') { + to._tzm = from._tzm; + } + if (typeof from._isUTC !== 'undefined') { + to._isUTC = from._isUTC; + } + if (typeof from._offset !== 'undefined') { + to._offset = from._offset; + } + if (typeof from._pf !== 'undefined') { + to._pf = from._pf; + } + if (typeof from._locale !== 'undefined') { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i in momentProperties) { + prop = momentProperties[i]; + val = from[prop]; + if (typeof val !== 'undefined') { + to[prop] = val; + } } } - return result; + return to; } function absRound(number) { @@ -38998,35 +41824,68 @@ return jQuery; return (sign ? (forceSign ? '+' : '') : '-') + output; } - // helper function for _.addTime and _.subtractTime - function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) { + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + other = makeAs(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = moment.duration(val, period); + addOrSubtractDurationFromMoment(this, dur, direction); + return this; + }; + } + + function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, days = duration._days, - months = duration._months, - minutes, - hours; + months = duration._months; + updateOffset = updateOffset == null ? true : updateOffset; if (milliseconds) { mom._d.setTime(+mom._d + milliseconds * isAdding); } - // store the minutes and hours so we can restore them - if (days || months) { - minutes = mom.minute(); - hours = mom.hour(); - } if (days) { - mom.date(mom.date() + days * isAdding); + rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); } if (months) { - mom.month(mom.month() + months * isAdding); - } - if (milliseconds && !ignoreUpdateOffset) { - moment.updateOffset(mom); + rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); } - // restore the minutes and hours after possibly changing dst - if (days || months) { - mom.minute(minutes); - mom.hour(hours); + if (updateOffset) { + moment.updateOffset(mom, days || months); } } @@ -39036,8 +41895,8 @@ return jQuery; } function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; + return Object.prototype.toString.call(input) === '[object Date]' || + input instanceof Date; } // compare two arrays, return the number of differences @@ -39069,7 +41928,7 @@ return jQuery; prop; for (prop in inputObject) { - if (inputObject.hasOwnProperty(prop)) { + if (hasOwnProp(inputObject, prop)) { normalizedProp = normalizeUnits(prop); if (normalizedProp) { normalizedInput[normalizedProp] = inputObject[prop]; @@ -39097,7 +41956,7 @@ return jQuery; moment[field] = function (format, index) { var i, getter, - method = moment.fn._lang[field], + method = moment._locale[field], results = []; if (typeof format === 'number') { @@ -39107,7 +41966,7 @@ return jQuery; getter = function (i) { var m = moment().utc().set(setter, i); - return method.call(moment.fn._lang, m, format || ''); + return method.call(moment._locale, m, format || ''); }; if (index != null) { @@ -39141,6 +42000,10 @@ return jQuery; return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); } + function weeksInYear(year, dow, doy) { + return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; + } + function daysInYear(year) { return isLeapYear(year) ? 366 : 365; } @@ -39155,7 +42018,10 @@ return jQuery; overflow = m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : + m._a[HOUR] < 0 || m._a[HOUR] > 24 || + (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 || + m._a[SECOND] !== 0 || + m._a[MILLISECOND] !== 0)) ? HOUR : m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : @@ -39182,28 +42048,79 @@ return jQuery; if (m._strict) { m._isValid = m._isValid && m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0; + m._pf.unusedTokens.length === 0 && + m._pf.bigHour === undefined; } } return m._isValid; } - function normalizeLanguage(key) { + function normalizeLocale(key) { return key ? key.toLowerCase().replace('_', '-') : key; } + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; + } + + function loadLocale(name) { + var oldLocale = null; + if (!locales[name] && hasModule) { + try { + oldLocale = moment.locale(); + require('./locale/' + name); + // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales + moment.locale(oldLocale); + } catch (e) { } + } + return locales[name]; + } + // Return a moment from input, that is local/utc/zone equivalent to model. function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (moment.isMoment(input) || isDate(input) ? + +input : +moment(input)) - (+res); + // Use low-level api, because this fn is low-level api. + res._d.setTime(+res._d + diff); + moment.updateOffset(res, false); + return res; + } else { + return moment(input).local(); + } } /************************************ - Languages + Locale ************************************/ - extend(Language.prototype, { + extend(Locale.prototype, { set : function (config) { var prop, i; @@ -39215,50 +42132,63 @@ return jQuery; this['_' + i] = prop; } } + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _ordinalParseLenient. + this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source); }, - _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), + _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), months : function (m) { return this._months[m.month()]; }, - _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), + _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), monthsShort : function (m) { return this._monthsShort[m.month()]; }, - monthsParse : function (monthName) { + monthsParse : function (monthName, format, strict) { var i, mom, regex; if (!this._monthsParse) { this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; } for (i = 0; i < 12; i++) { // make the regex if we don't have it already - if (!this._monthsParse[i]) { - mom = moment.utc([2000, i]); + mom = moment.utc([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex - if (this._monthsParse[i].test(monthName)) { + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { return i; } } }, - _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), + _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), weekdays : function (m) { return this._weekdays[m.day()]; }, - _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), + _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), weekdaysShort : function (m) { return this._weekdaysShort[m.day()]; }, - _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), + _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), weekdaysMin : function (m) { return this._weekdaysMin[m.day()]; }, @@ -39285,11 +42215,12 @@ return jQuery; }, _longDateFormat : { - LT : "h:mm A", - L : "MM/DD/YYYY", - LL : "MMMM D YYYY", - LLL : "MMMM D YYYY LT", - LLLL : "dddd, MMMM D YYYY LT" + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY LT', + LLLL : 'dddd, MMMM D, YYYY LT' }, longDateFormat : function (key) { var output = this._longDateFormat[key]; @@ -39325,41 +42256,44 @@ return jQuery; lastWeek : '[Last] dddd [at] LT', sameElse : 'L' }, - calendar : function (key, mom) { + calendar : function (key, mom, now) { var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom) : output; + return typeof output === 'function' ? output.apply(mom, [now]) : output; }, _relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }, + relativeTime : function (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (typeof output === 'function') ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); }, + pastFuture : function (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); }, ordinal : function (number) { - return this._ordinal.replace("%d", number); + return this._ordinal.replace('%d', number); }, - _ordinal : "%d", + _ordinal : '%d', + _ordinalParse : /\d{1,2}/, preparse : function (string) { return string; @@ -39384,78 +42318,6 @@ return jQuery; } }); - // Loads a language definition into the `languages` cache. The function - // takes a key and optionally values. If not in the browser and no values - // are provided, it will load the language file module. As a convenience, - // this function also returns the language values. - function loadLang(key, values) { - values.abbr = key; - if (!languages[key]) { - languages[key] = new Language(); - } - languages[key].set(values); - return languages[key]; - } - - // Remove a language from the `languages` cache. Mostly useful in tests. - function unloadLang(key) { - delete languages[key]; - } - - // Determines which language definition to use and returns it. - // - // With no parameters, it will return the global language. If you - // pass in a language key, such as 'en', it will return the - // definition for 'en', so long as 'en' has already been loaded using - // moment.lang. - function getLangDefinition(key) { - var i = 0, j, lang, next, split, - get = function (k) { - if (!languages[k] && hasModule) { - try { - require('./lang/' + k); - } catch (e) { } - } - return languages[k]; - }; - - if (!key) { - return moment.fn._lang; - } - - if (!isArray(key)) { - //short-circuit everything else - lang = get(key); - if (lang) { - return lang; - } - key = [key]; - } - - //pick the language from the array - //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - while (i < key.length) { - split = normalizeLanguage(key[i]).split('-'); - j = split.length; - next = normalizeLanguage(key[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - lang = get(split.slice(0, j).join('-')); - if (lang) { - return lang; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return moment.fn._lang; - } - /************************************ Formatting ************************************/ @@ -39463,9 +42325,9 @@ return jQuery; function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ""); + return input.replace(/^\[|\]$/g, ''); } - return input.replace(/\\/g, ""); + return input.replace(/\\/g, ''); } function makeFormatFunction(format) { @@ -39480,7 +42342,7 @@ return jQuery; } return function (mom) { - var output = ""; + var output = ''; for (i = 0; i < length; i++) { output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; } @@ -39490,12 +42352,11 @@ return jQuery; // format date using native date object function formatMoment(m, format) { - if (!m.isValid()) { - return m.lang().invalidDate(); + return m.localeData().invalidDate(); } - format = expandFormat(format, m.lang()); + format = expandFormat(format, m.localeData()); if (!formatFunctions[format]) { formatFunctions[format] = makeFormatFunction(format); @@ -39504,11 +42365,11 @@ return jQuery; return formatFunctions[format](m); } - function expandFormat(format, lang) { + function expandFormat(format, locale) { var i = 5; function replaceLongDateFormatTokens(input) { - return lang.longDateFormat(input) || input; + return locale.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; @@ -39531,6 +42392,8 @@ return jQuery; function getParseRegexForToken(token, config) { var a, strict = config._strict; switch (token) { + case 'Q': + return parseTokenOneDigit; case 'DDDD': return parseTokenThreeDigits; case 'YYYY': @@ -39547,13 +42410,19 @@ return jQuery; case 'ggggg': return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; case 'S': - if (strict) { return parseTokenOneDigit; } + if (strict) { + return parseTokenOneDigit; + } /* falls through */ case 'SS': - if (strict) { return parseTokenTwoDigits; } + if (strict) { + return parseTokenTwoDigits; + } /* falls through */ case 'SSS': - if (strict) { return parseTokenThreeDigits; } + if (strict) { + return parseTokenThreeDigits; + } /* falls through */ case 'DDD': return parseTokenOneToThreeDigits; @@ -39565,7 +42434,9 @@ return jQuery; return parseTokenWord; case 'a': case 'A': - return getLangDefinition(config._l)._meridiemParse; + return config._locale._meridiemParse; + case 'x': + return parseTokenOffsetMs; case 'X': return parseTokenTimestampMs; case 'Z': @@ -39599,14 +42470,16 @@ return jQuery; case 'e': case 'E': return parseTokenOneOrTwoDigits; + case 'Do': + return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient; default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); + a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); return a; } } function timezoneMinutesFromString(string) { - string = string || ""; + string = string || ''; var possibleTzMatches = (string.match(parseTokenTimezone) || []), tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], @@ -39620,6 +42493,12 @@ return jQuery; var a, datePartArray = config._a; switch (token) { + // QUARTER + case 'Q': + if (input != null) { + datePartArray[MONTH] = (toInt(input) - 1) * 3; + } + break; // MONTH case 'M' : // fall through to MM case 'MM' : @@ -39629,7 +42508,7 @@ return jQuery; break; case 'MMM' : // fall through to MMMM case 'MMMM' : - a = getLangDefinition(config._l).monthsParse(input); + a = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[MONTH] = a; @@ -39644,6 +42523,12 @@ return jQuery; datePartArray[DATE] = toInt(input); } break; + case 'Do' : + if (input != null) { + datePartArray[DATE] = toInt(parseInt( + input.match(/\d{1,2}/)[0], 10)); + } + break; // DAY OF YEAR case 'DDD' : // fall through to DDDD case 'DDDD' : @@ -39654,7 +42539,7 @@ return jQuery; break; // YEAR case 'YY' : - datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + datePartArray[YEAR] = moment.parseTwoDigitYear(input); break; case 'YYYY' : case 'YYYYY' : @@ -39664,13 +42549,15 @@ return jQuery; // AM / PM case 'a' : // fall through to A case 'A' : - config._isPm = getLangDefinition(config._l).isPM(input); + config._isPm = config._locale.isPM(input); break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh + // HOUR case 'h' : // fall through to hh case 'hh' : + config._pf.bigHour = true; + /* falls through */ + case 'H' : // fall through to HH + case 'HH' : datePartArray[HOUR] = toInt(input); break; // MINUTE @@ -39690,6 +42577,10 @@ return jQuery; case 'SSSS' : datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); break; + // UNIX OFFSET (MILLISECONDS) + case 'x': + config._d = new Date(toInt(input)); + break; // UNIX TIMESTAMP WITH MS case 'X': config._d = new Date(parseFloat(input) * 1000); @@ -39700,39 +42591,93 @@ return jQuery; config._useUTC = true; config._tzm = timezoneMinutesFromString(input); break; + // WEEKDAY - human + case 'dd': + case 'ddd': + case 'dddd': + a = config._locale.weekdaysParse(input); + // if we didn't get a weekday name, mark the date as invalid + if (a != null) { + config._w = config._w || {}; + config._w['d'] = a; + } else { + config._pf.invalidWeekday = input; + } + break; + // WEEK, WEEK DAY - numeric case 'w': case 'ww': case 'W': case 'WW': case 'd': - case 'dd': - case 'ddd': - case 'dddd': case 'e': case 'E': token = token.substr(0, 1); /* falls through */ - case 'gg': case 'gggg': - case 'GG': case 'GGGG': case 'GGGGG': token = token.substr(0, 2); if (input) { config._w = config._w || {}; - config._w[token] = input; + config._w[token] = toInt(input); } break; + case 'gg': + case 'GG': + config._w = config._w || {}; + config._w[token] = moment.parseTwoDigitYear(input); } } + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); + week = dfl(w.W, 1); + weekday = dfl(w.E, 1); + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); + week = dfl(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < dow) { + ++week; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + } else { + // default to begining of week + weekday = dow; + } + } + temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); + + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } + // convert an array to a date. // the array should mirror the parameters below // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] function dateFromConfig(config) { - var i, date, input = [], currentDate, - yearToUse, fixYear, w, temp, lang, weekday, week; + var i, date, input = [], currentDate, yearToUse; if (config._d) { return; @@ -39742,39 +42687,12 @@ return jQuery; //compute day of the year from weeks and weekdays if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - fixYear = function (val) { - var int_val = parseInt(val, 10); - return val ? - (val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) : - (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); - }; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); - } - else { - lang = getLangDefinition(config._l); - weekday = w.d != null ? parseWeekday(w.d, lang) : - (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); - - week = parseInt(w.w, 10) || 1; - - //if we're parsing 'd', then the low day numbers may be next week - if (w.d != null && weekday < lang._week.dow) { - week++; - } - - temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); - } - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; + dayOfYearFromWeekInfo(config); } //if the day of the year is set, figure out what it is if (config._dayOfYear) { - yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; + yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse)) { config._pf._overflowDayOfYear = true; @@ -39799,11 +42717,25 @@ return jQuery; config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - // add the offsets to the time to be parsed so that we can have a clean array for checking isValid - input[HOUR] += toInt((config._tzm || 0) / 60); - input[MINUTE] += toInt((config._tzm || 0) % 60); + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); + // Apply timezone offset from input. The actual zone can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } } function dateFromObject(config) { @@ -39817,7 +42749,7 @@ return jQuery; config._a = [ normalizedInput.year, normalizedInput.month, - normalizedInput.day, + normalizedInput.day || normalizedInput.date, normalizedInput.hour, normalizedInput.minute, normalizedInput.second, @@ -39842,18 +42774,21 @@ return jQuery; // date from string and format string function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { + parseISO(config); + return; + } config._a = []; config._pf.empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` - var lang = getLangDefinition(config._l), - string = '' + config._i, + var string = '' + config._i, i, parsedInput, tokens, token, skipped, stringLength = string.length, totalParsedInputLength = 0; - tokens = expandFormat(config._f, lang).match(formattingTokens) || []; + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; for (i = 0; i < tokens.length; i++) { token = tokens[i]; @@ -39887,6 +42822,10 @@ return jQuery; config._pf.unusedInput.push(string); } + // clear _12h flag if hour is <= 12 + if (config._pf.bigHour === true && config._a[HOUR] <= 12) { + config._pf.bigHour = undefined; + } // handle am pm if (config._isPm && config._a[HOUR] < 12) { config._a[HOUR] += 12; @@ -39895,7 +42834,6 @@ return jQuery; if (config._isPm === false && config._a[HOUR] === 12) { config._a[HOUR] = 0; } - dateFromConfig(config); checkOverflow(config); } @@ -39928,7 +42866,10 @@ return jQuery; for (i = 0; i < config._f.length; i++) { currentScore = 0; - tempConfig = extend({}, config); + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } tempConfig._pf = defaultParsingFlags(); tempConfig._f = config._f[i]; makeDateFromStringAndFormat(tempConfig); @@ -39955,7 +42896,7 @@ return jQuery; } // date from iso format - function makeDateFromString(config) { + function parseISO(config) { var i, l, string = config._i, match = isoRegex.exec(string); @@ -39964,8 +42905,8 @@ return jQuery; config._pf.iso = true; for (i = 0, l = isoDates.length; i < l; i++) { if (isoDates[i][1].exec(string)) { - // match[5] should be "T" or undefined - config._f = isoDates[i][0] + (match[6] || " "); + // match[5] should be 'T' or undefined + config._f = isoDates[i][0] + (match[6] || ' '); break; } } @@ -39976,34 +42917,53 @@ return jQuery; } } if (string.match(parseTokenTimezone)) { - config._f += "Z"; + config._f += 'Z'; } makeDateFromStringAndFormat(config); + } else { + config._isValid = false; } - else { - config._d = new Date(string); + } + + // date from iso format or fallback + function makeDateFromString(config) { + parseISO(config); + if (config._isValid === false) { + delete config._isValid; + moment.createFromInputFallback(config); } } - function makeDateFromInput(config) { - var input = config._i, - matched = aspNetJsonRegex.exec(input); + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + function makeDateFromInput(config) { + var input = config._i, matched; if (input === undefined) { config._d = new Date(); - } else if (matched) { + } else if (isDate(input)) { + config._d = new Date(+input); + } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { config._d = new Date(+matched[1]); } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { - config._a = input.slice(0); + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); dateFromConfig(config); - } else if (isDate(input)) { - config._d = new Date(+input); } else if (typeof(input) === 'object') { dateFromObject(config); - } else { + } else if (typeof(input) === 'number') { + // from milliseconds config._d = new Date(input); + } else { + moment.createFromInputFallback(config); } } @@ -40027,13 +42987,13 @@ return jQuery; return date; } - function parseWeekday(input, language) { + function parseWeekday(input, locale) { if (typeof input === 'string') { if (!isNaN(input)) { input = parseInt(input, 10); } else { - input = language.weekdaysParse(input); + input = locale.weekdaysParse(input); if (typeof input !== 'number') { return null; } @@ -40048,29 +43008,33 @@ return jQuery; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { - return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - function relativeTime(milliseconds, withoutSuffix, lang) { - var seconds = round(Math.abs(milliseconds) / 1000), - minutes = round(seconds / 60), - hours = round(minutes / 60), - days = round(hours / 24), - years = round(days / 365), - args = seconds < 45 && ['s', seconds] || + function relativeTime(posNegDuration, withoutSuffix, locale) { + var duration = moment.duration(posNegDuration).abs(), + seconds = round(duration.as('s')), + minutes = round(duration.as('m')), + hours = round(duration.as('h')), + days = round(duration.as('d')), + months = round(duration.as('M')), + years = round(duration.as('y')), + + args = seconds < relativeTimeThresholds.s && ['s', seconds] || minutes === 1 && ['m'] || - minutes < 45 && ['mm', minutes] || + minutes < relativeTimeThresholds.m && ['mm', minutes] || hours === 1 && ['h'] || - hours < 22 && ['hh', hours] || + hours < relativeTimeThresholds.h && ['hh', hours] || days === 1 && ['d'] || - days <= 25 && ['dd', days] || - days <= 45 && ['M'] || - days < 345 && ['MM', round(days / 30)] || + days < relativeTimeThresholds.d && ['dd', days] || + months === 1 && ['M'] || + months < relativeTimeThresholds.M && ['MM', months] || years === 1 && ['y'] || ['yy', years]; + args[2] = withoutSuffix; - args[3] = milliseconds > 0; - args[4] = lang; + args[3] = +posNegDuration > 0; + args[4] = locale; return substituteTimeAgo.apply({}, args); } @@ -40101,7 +43065,7 @@ return jQuery; daysToDayOfWeek += 7; } - adjustedMoment = moment(mom).add('d', daysToDayOfWeek); + adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); return { week: Math.ceil(adjustedMoment.dayOfYear() / 7), year: adjustedMoment.year() @@ -40112,6 +43076,7 @@ return jQuery; function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + d = d === 0 ? 7 : d; weekday = weekday != null ? weekday : firstDayOfWeek; daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; @@ -40128,20 +43093,21 @@ return jQuery; function makeMoment(config) { var input = config._i, - format = config._f; + format = config._f, + res; - if (input === null) { + config._locale = config._locale || moment.localeData(config._l); + + if (input === null || (format === undefined && input === '')) { return moment.invalid({nullInput: true}); } if (typeof input === 'string') { - config._i = input = getLangDefinition().preparse(input); + config._i = input = config._locale.preparse(input); } if (moment.isMoment(input)) { - config = cloneMoment(input); - - config._d = new Date(+input._d); + return new Moment(input, true); } else if (format) { if (isArray(format)) { makeDateFromStringAndArray(config); @@ -40152,15 +43118,22 @@ return jQuery; makeDateFromInput(config); } - return new Moment(config); + res = new Moment(config); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; } - moment = function (input, format, lang, strict) { + moment = function (input, format, locale, strict) { var c; - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -40168,7 +43141,7 @@ return jQuery; c._isAMomentObject = true; c._i = input; c._f = format; - c._l = lang; + c._l = locale; c._strict = strict; c._isUTC = false; c._pf = defaultParsingFlags(); @@ -40176,13 +43149,59 @@ return jQuery; return makeMoment(c); }; + moment.suppressDeprecationWarnings = false; + + moment.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return moment(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + moment.min = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + }; + + moment.max = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + }; + // creating with utc - moment.utc = function (input, format, lang, strict) { + moment.utc = function (input, format, locale, strict) { var c; - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -40190,7 +43209,7 @@ return jQuery; c._isAMomentObject = true; c._useUTC = true; c._isUTC = true; - c._l = lang; + c._l = locale; c._i = input; c._f = format; c._strict = strict; @@ -40211,7 +43230,8 @@ return jQuery; match = null, sign, ret, - parseIso; + parseIso, + diffRes; if (moment.isDuration(input)) { duration = { @@ -40227,7 +43247,7 @@ return jQuery; duration.milliseconds = input; } } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; + sign = (match[1] === '-') ? -1 : 1; duration = { y: 0, d: toInt(match[DATE]) * sign, @@ -40237,7 +43257,7 @@ return jQuery; ms: toInt(match[MILLISECOND]) * sign }; } else if (!!(match = isoDurationRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; + sign = (match[1] === '-') ? -1 : 1; parseIso = function (inp) { // We'd normally use ~~inp for this, but unfortunately it also // converts floats to ints. @@ -40255,12 +43275,19 @@ return jQuery; s: parseIso(match[7]), w: parseIso(match[8]) }; + } else if (typeof duration === 'object' && + ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(moment(duration.from), moment(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; } ret = new Duration(duration); - if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { - ret._lang = input._lang; + if (moment.isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; } return ret; @@ -40272,42 +43299,111 @@ return jQuery; // default format moment.defaultFormat = isoFormat; + // constant that refers to the ISO standard + moment.ISO_8601 = function () {}; + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + moment.momentProperties = momentProperties; + // This function will be called whenever a moment is mutated. // It is intended to keep the offset in sync with the timezone. moment.updateOffset = function () {}; - // This function will load languages and then set the global language. If + // This function allows you to set a threshold for relative time strings + moment.relativeTimeThreshold = function (threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return relativeTimeThresholds[threshold]; + } + relativeTimeThresholds[threshold] = limit; + return true; + }; + + moment.lang = deprecate( + 'moment.lang is deprecated. Use moment.locale instead.', + function (key, value) { + return moment.locale(key, value); + } + ); + + // This function will load locale and then set the global locale. If // no arguments are passed in, it will simply return the current global - // language key. - moment.lang = function (key, values) { - var r; - if (!key) { - return moment.fn._lang._abbr; - } - if (values) { - loadLang(normalizeLanguage(key), values); - } else if (values === null) { - unloadLang(key); - key = 'en'; - } else if (!languages[key]) { - getLangDefinition(key); - } - r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); - return r._abbr; + // locale key. + moment.locale = function (key, values) { + var data; + if (key) { + if (typeof(values) !== 'undefined') { + data = moment.defineLocale(key, values); + } + else { + data = moment.localeData(key); + } + + if (data) { + moment.duration._locale = moment._locale = data; + } + } + + return moment._locale._abbr; }; - // returns language data - moment.langData = function (key) { - if (key && key._lang && key._lang._abbr) { - key = key._lang._abbr; + moment.defineLocale = function (name, values) { + if (values !== null) { + values.abbr = name; + if (!locales[name]) { + locales[name] = new Locale(); + } + locales[name].set(values); + + // backwards compat for now: also set the locale + moment.locale(name); + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } + }; + + moment.langData = deprecate( + 'moment.langData is deprecated. Use moment.localeData instead.', + function (key) { + return moment.localeData(key); + } + ); + + // returns locale data + moment.localeData = function (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return moment._locale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; } - return getLangDefinition(key); + + return chooseLocale(key); }; // compare moment object moment.isMoment = function (obj) { return obj instanceof Moment || - (obj != null && obj.hasOwnProperty('_isAMomentObject')); + (obj != null && hasOwnProp(obj, '_isAMomentObject')); }; // for typechecking Duration objects @@ -40335,8 +43431,12 @@ return jQuery; return m; }; - moment.parseZone = function (input) { - return moment(input).parseZone(); + moment.parseZone = function () { + return moment.apply(null, arguments).parseZone(); + }; + + moment.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); }; /************************************ @@ -40359,7 +43459,7 @@ return jQuery; }, toString : function () { - return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); }, toDate : function () { @@ -40369,7 +43469,12 @@ return jQuery; toISOString : function () { var m = moment(this).utc(); if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + if ('function' === typeof Date.prototype.toISOString) { + // native implementation is ~50x faster, use it when we can + return this.toDate().toISOString(); + } else { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } } else { return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } @@ -40393,7 +43498,6 @@ return jQuery; }, isDSTShifted : function () { - if (this._a) { return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; } @@ -40409,49 +43513,35 @@ return jQuery; return this._pf.overflow; }, - utc : function () { - return this.zone(0); + utc : function (keepLocalTime) { + return this.zone(0, keepLocalTime); }, - local : function () { - this.zone(0); - this._isUTC = false; + local : function (keepLocalTime) { + if (this._isUTC) { + this.zone(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.add(this._dateTzOffset(), 'm'); + } + } return this; }, format : function (inputString) { var output = formatMoment(this, inputString || moment.defaultFormat); - return this.lang().postformat(output); + return this.localeData().postformat(output); }, - add : function (input, val) { - var dur; - // switch args to support add('s', 1) and add(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, 1); - return this; - }, + add : createAdder(1, 'add'), - subtract : function (input, val) { - var dur; - // switch args to support subtract('s', 1) and subtract(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, -1); - return this; - }, + subtract : createAdder(-1, 'subtract'), diff : function (input, units, asFloat) { var that = makeAs(input, this), zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output; + diff, output, daysAdjust; units = normalizeUnits(units); @@ -40462,11 +43552,12 @@ return jQuery; output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); // adjust by taking difference in days, average number of days // and dst in the given months. - output += ((this - moment(this).startOf('month')) - - (that - moment(that).startOf('month'))) / diff; + daysAdjust = (this - moment(this).startOf('month')) - + (that - moment(that).startOf('month')); // same as above but with zones, to negate all dst - output -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; + daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4; + output += daysAdjust / diff; if (units === 'year') { output = output / 12; } @@ -40483,17 +43574,18 @@ return jQuery; }, from : function (time, withoutSuffix) { - return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); + return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); }, fromNow : function (withoutSuffix) { return this.from(moment(), withoutSuffix); }, - calendar : function () { + calendar : function (time) { // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're zone'd or not. - var sod = makeAs(moment(), this).startOf('day'), + var now = time || moment(), + sod = makeAs(now, this).startOf('day'), diff = this.diff(sod, 'days', true), format = diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : @@ -40501,7 +43593,7 @@ return jQuery; diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.lang().calendar(format, this)); + return this.format(this.localeData().calendar(format, this, moment(now))); }, isLeapYear : function () { @@ -40516,38 +43608,16 @@ return jQuery; day : function (input) { var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { - input = parseWeekday(input, this.lang()); - return this.add({ d : input - day }); + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); } else { return day; } }, - month : function (input) { - var utc = this._isUTC ? 'UTC' : '', - dayOfMonth; - - if (input != null) { - if (typeof input === 'string') { - input = this.lang().monthsParse(input); - if (typeof input !== 'number') { - return this; - } - } - - dayOfMonth = this.date(); - this.date(1); - this._d['set' + utc + 'Month'](input); - this.date(Math.min(dayOfMonth, this.daysInMonth())); + month : makeAccessor('Month', true), - moment.updateOffset(this); - return this; - } else { - return this._d['get' + utc + 'Month'](); - } - }, - - startOf: function (units) { + startOf : function (units) { units = normalizeUnits(units); // the following switch intentionally omits break keywords // to utilize falling through the cases. @@ -40555,6 +43625,7 @@ return jQuery; case 'year': this.month(0); /* falls through */ + case 'quarter': case 'month': this.date(1); /* falls through */ @@ -40581,65 +43652,124 @@ return jQuery; this.isoWeekday(1); } + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + return this; }, endOf: function (units) { units = normalizeUnits(units); - return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); + if (units === undefined || units === 'millisecond') { + return this; + } + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); }, isAfter: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) > +moment(input).startOf(units); + var inputMs; + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this > +input; + } else { + inputMs = moment.isMoment(input) ? +input : +moment(input); + return inputMs < +this.clone().startOf(units); + } }, isBefore: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) < +moment(input).startOf(units); + var inputMs; + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this < +input; + } else { + inputMs = moment.isMoment(input) ? +input : +moment(input); + return +this.clone().endOf(units) < inputMs; + } }, isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); - }, - - min: function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - }, - - max: function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; + var inputMs; + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this === +input; + } else { + inputMs = +moment(input); + return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + } }, - zone : function (input) { - var offset = this._offset || 0; + min: deprecate( + 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + } + ), + + max: deprecate( + 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + } + ), + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + zone : function (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; if (input != null) { - if (typeof input === "string") { + if (typeof input === 'string') { input = timezoneMinutesFromString(input); } if (Math.abs(input) < 16) { input = input * 60; } + if (!this._isUTC && keepLocalTime) { + localAdjust = this._dateTzOffset(); + } this._offset = input; this._isUTC = true; + if (localAdjust != null) { + this.subtract(localAdjust, 'm'); + } if (offset !== input) { - addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true); + if (!keepLocalTime || this._changeInProgress) { + addOrSubtractDurationFromMoment(this, + moment.duration(offset - input, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + moment.updateOffset(this, true); + this._changeInProgress = null; + } } } else { - return this._isUTC ? offset : this._d.getTimezoneOffset(); + return this._isUTC ? offset : this._dateTzOffset(); } return this; }, zoneAbbr : function () { - return this._isUTC ? "UTC" : ""; + return this._isUTC ? 'UTC' : ''; }, zoneName : function () { - return this._isUTC ? "Coordinated Universal Time" : ""; + return this._isUTC ? 'Coordinated Universal Time' : ''; }, parseZone : function () { @@ -40668,36 +43798,36 @@ return jQuery; dayOfYear : function (input) { var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); }, - quarter : function () { - return Math.ceil((this.month() + 1.0) / 3.0); + quarter : function (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); }, weekYear : function (input) { - var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; - return input == null ? year : this.add("y", (input - year)); + var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; + return input == null ? year : this.add((input - year), 'y'); }, isoWeekYear : function (input) { var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add("y", (input - year)); + return input == null ? year : this.add((input - year), 'y'); }, week : function (input) { - var week = this.lang().week(this); - return input == null ? week : this.add("d", (input - week) * 7); + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); }, isoWeek : function (input) { var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add("d", (input - week) * 7); + return input == null ? week : this.add((input - week) * 7, 'd'); }, weekday : function (input) { - var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; - return input == null ? weekday : this.add("d", input - weekday); + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); }, isoWeekday : function (input) { @@ -40707,6 +43837,15 @@ return jQuery; return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); }, + isoWeeksInYear : function () { + return weeksInYear(this.year(), 1, 4); + }, + + weeksInYear : function () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + }, + get : function (units) { units = normalizeUnits(units); return this[units](); @@ -40720,46 +43859,107 @@ return jQuery; return this; }, - // If passed a language key, it will set the language for this - // instance. Otherwise, it will return the language configuration + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration // variables for this instance. - lang : function (key) { + locale : function (key) { + var newLocaleData; + if (key === undefined) { - return this._lang; + return this._locale._abbr; } else { - this._lang = getLangDefinition(key); + newLocaleData = moment.localeData(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } return this; } + }, + + lang : deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ), + + localeData : function () { + return this._locale; + }, + + _dateTzOffset : function () { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return Math.round(this._d.getTimezoneOffset() / 15) * 15; } }); - // helper for adding shortcuts - function makeGetterAndSetter(name, key) { - moment.fn[name] = moment.fn[name + 's'] = function (input) { - var utc = this._isUTC ? 'UTC' : ''; - if (input != null) { - this._d['set' + utc + key](input); - moment.updateOffset(this); + function rawMonthSetter(mom, value) { + var dayOfMonth; + + // TODO: Move this out of here! + if (typeof value === 'string') { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } + + dayOfMonth = Math.min(mom.date(), + daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function rawGetter(mom, unit) { + return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); + } + + function rawSetter(mom, unit, value) { + if (unit === 'Month') { + return rawMonthSetter(mom, value); + } else { + return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + + function makeAccessor(unit, keepTime) { + return function (value) { + if (value != null) { + rawSetter(this, unit, value); + moment.updateOffset(this, keepTime); return this; } else { - return this._d['get' + utc + key](); + return rawGetter(this, unit); } }; } - // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) - for (i = 0; i < proxyGettersAndSetters.length; i ++) { - makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); - } - - // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') - makeGetterAndSetter('year', 'FullYear'); + moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); + moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); + moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); + // moment.fn.month is defined separately + moment.fn.date = makeAccessor('Date', true); + moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); + moment.fn.year = makeAccessor('FullYear', true); + moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); // add plural methods moment.fn.days = moment.fn.day; moment.fn.months = moment.fn.month; moment.fn.weeks = moment.fn.week; moment.fn.isoWeeks = moment.fn.isoWeek; + moment.fn.quarters = moment.fn.quarter; // add aliased format methods moment.fn.toJSON = moment.fn.toISOString; @@ -40769,6 +43969,17 @@ return jQuery; ************************************/ + function daysToYears (days) { + // 400 years have 146097 days (taking into account leap year rules) + return days * 400 / 146097; + } + + function yearsToDays (years) { + // years * 365 + absRound(years / 4) - + // absRound(years / 100) + absRound(years / 400); + return years * 146097 / 400; + } + extend(moment.duration.fn = Duration.prototype, { _bubble : function () { @@ -40776,7 +43987,7 @@ return jQuery; days = this._days, months = this._months, data = this._data, - seconds, minutes, hours, years; + seconds, minutes, hours, years = 0; // The following code bubbles up values, see the tests for // examples of what that means. @@ -40792,15 +44003,40 @@ return jQuery; data.hours = hours % 24; days += absRound(hours / 24); - data.days = days % 30; + // Accurately convert days to years, assume start from year 0. + years = absRound(daysToYears(days)); + days -= absRound(yearsToDays(years)); + + // 30 days to a month + // TODO (iskren): Use anchor date (like 1st Jan) to compute this. months += absRound(days / 30); - data.months = months % 12; + days %= 30; + + // 12 months -> 1 year + years += absRound(months / 12); + months %= 12; - years = absRound(months / 12); + data.days = days; + data.months = months; data.years = years; }, + abs : function () { + this._milliseconds = Math.abs(this._milliseconds); + this._days = Math.abs(this._days); + this._months = Math.abs(this._months); + + this._data.milliseconds = Math.abs(this._data.milliseconds); + this._data.seconds = Math.abs(this._data.seconds); + this._data.minutes = Math.abs(this._data.minutes); + this._data.hours = Math.abs(this._data.hours); + this._data.months = Math.abs(this._data.months); + this._data.years = Math.abs(this._data.years); + + return this; + }, + weeks : function () { return absRound(this.days() / 7); }, @@ -40813,14 +44049,13 @@ return jQuery; }, humanize : function (withSuffix) { - var difference = +this, - output = relativeTime(difference, !withSuffix, this.lang()); + var output = relativeTime(this, !withSuffix, this.localeData()); if (withSuffix) { - output = this.lang().pastFuture(difference, output); + output = this.localeData().pastFuture(+this, output); } - return this.lang().postformat(output); + return this.localeData().postformat(output); }, add : function (input, val) { @@ -40854,13 +44089,41 @@ return jQuery; }, as : function (units) { + var days, months; units = normalizeUnits(units); - return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); + + if (units === 'month' || units === 'year') { + days = this._days + this._milliseconds / 864e5; + months = this._months + daysToYears(days) * 12; + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(yearsToDays(this._months / 12)); + switch (units) { + case 'week': return days / 7 + this._milliseconds / 6048e5; + case 'day': return days + this._milliseconds / 864e5; + case 'hour': return days * 24 + this._milliseconds / 36e5; + case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; + case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } }, lang : moment.fn.lang, + locale : moment.fn.locale, - toIsoString : function () { + toIsoString : deprecate( + 'toIsoString() is deprecated. Please use toISOString() instead ' + + '(notice the capitals)', + function () { + return this.toISOString(); + } + ), + + toISOString : function () { // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js var years = Math.abs(this.years()), months = Math.abs(this.months()), @@ -40884,41 +44147,60 @@ return jQuery; (hours ? hours + 'H' : '') + (minutes ? minutes + 'M' : '') + (seconds ? seconds + 'S' : ''); + }, + + localeData : function () { + return this._locale; } }); + moment.duration.fn.toString = moment.duration.fn.toISOString; + function makeDurationGetter(name) { moment.duration.fn[name] = function () { return this._data[name]; }; } - function makeDurationAsGetter(name, factor) { - moment.duration.fn['as' + name] = function () { - return +this / factor; - }; - } - for (i in unitMillisecondFactors) { - if (unitMillisecondFactors.hasOwnProperty(i)) { - makeDurationAsGetter(i, unitMillisecondFactors[i]); + if (hasOwnProp(unitMillisecondFactors, i)) { makeDurationGetter(i.toLowerCase()); } } - makeDurationAsGetter('Weeks', 6048e5); + moment.duration.fn.asMilliseconds = function () { + return this.as('ms'); + }; + moment.duration.fn.asSeconds = function () { + return this.as('s'); + }; + moment.duration.fn.asMinutes = function () { + return this.as('m'); + }; + moment.duration.fn.asHours = function () { + return this.as('h'); + }; + moment.duration.fn.asDays = function () { + return this.as('d'); + }; + moment.duration.fn.asWeeks = function () { + return this.as('weeks'); + }; moment.duration.fn.asMonths = function () { - return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; + return this.as('M'); + }; + moment.duration.fn.asYears = function () { + return this.as('y'); }; - /************************************ - Default Lang + Default Locale ************************************/ - // Set default language, other languages will inherit from English. - moment.lang('en', { + // Set default locale, other locale will inherit from English. + moment.locale('en', { + ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -40929,61 +44211,52 @@ return jQuery; } }); - /* EMBED_LANGUAGES */ + /* EMBED_LOCALES */ /************************************ Exposing Moment ************************************/ - function makeGlobal(deprecate) { - var warned = false, local_moment = moment; + function makeGlobal(shouldDeprecate) { /*global ender:false */ if (typeof ender !== 'undefined') { return; } - // here, `this` means `window` in the browser, or `global` on the server - // add `moment` as a global object via a string identifier, - // for Closure Compiler "advanced" mode - if (deprecate) { - global.moment = function () { - if (!warned && console && console.warn) { - warned = true; - console.warn( - "Accessing Moment through the global scope is " + - "deprecated, and will be removed in an upcoming " + - "release."); - } - return local_moment.apply(null, arguments); - }; - extend(global.moment, local_moment); + oldGlobalMoment = globalScope.moment; + if (shouldDeprecate) { + globalScope.moment = deprecate( + 'Accessing Moment through the global scope is ' + + 'deprecated, and will be removed in an upcoming ' + + 'release.', + moment); } else { - global['moment'] = moment; + globalScope.moment = moment; } } // CommonJS module is defined if (hasModule) { module.exports = moment; - makeGlobal(true); - } else if (typeof define === "function" && define.amd) { - define("moment", function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal !== true) { - // If user provided noGlobal, he is aware of global - makeGlobal(module.config().noGlobal === undefined); + } else if (typeof define === 'function' && define.amd) { + define('moment', function (require, exports, module) { + if (module.config && module.config() && module.config().noGlobal === true) { + // release the global variable + globalScope.moment = oldGlobalMoment; } return moment; }); + makeGlobal(true); } else { makeGlobal(); } }).call(this); -},{}],42:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ module.exports = require('./lib/'); -},{"./lib/":43}],43:[function(require,module,exports){ +},{"./lib/":56}],56:[function(require,module,exports){ /** * Module dependencies. @@ -41072,7 +44345,7 @@ exports.connect = lookup; exports.Manager = require('./manager'); exports.Socket = require('./socket'); -},{"./manager":44,"./socket":46,"./url":47,"debug":50,"socket.io-parser":81}],44:[function(require,module,exports){ +},{"./manager":57,"./socket":59,"./url":60,"debug":63,"socket.io-parser":94}],57:[function(require,module,exports){ /** * Module dependencies. @@ -41532,7 +44805,7 @@ Manager.prototype.onreconnect = function(){ this.emitAll('reconnect', attempt); }; -},{"./on":45,"./socket":46,"./url":47,"component-bind":48,"component-emitter":49,"debug":50,"engine.io-client":51,"object-component":78,"socket.io-parser":81}],45:[function(require,module,exports){ +},{"./on":58,"./socket":59,"./url":60,"component-bind":61,"component-emitter":62,"debug":63,"engine.io-client":64,"object-component":91,"socket.io-parser":94}],58:[function(require,module,exports){ /** * Module exports. @@ -41558,7 +44831,7 @@ function on(obj, ev, fn) { }; } -},{}],46:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ /** * Module dependencies. @@ -41938,9 +45211,8 @@ Socket.prototype.disconnect = function(){ return this; }; -},{"./on":45,"component-bind":48,"component-emitter":49,"debug":50,"has-binary":75,"indexof":77,"socket.io-parser":81,"to-array":85}],47:[function(require,module,exports){ -(function (global){ - +},{"./on":58,"component-bind":61,"component-emitter":62,"debug":63,"has-binary":88,"indexof":90,"socket.io-parser":94,"to-array":98}],60:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /** * Module dependencies. */ @@ -42012,8 +45284,7 @@ function url(uri, loc){ return obj; } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"debug":50,"parseuri":79}],48:[function(require,module,exports){ +},{"debug":63,"parseuri":92}],61:[function(require,module,exports){ /** * Slice reference. */ @@ -42038,7 +45309,7 @@ module.exports = function(obj, fn){ } }; -},{}],49:[function(require,module,exports){ +},{}],62:[function(require,module,exports){ /** * Expose `Emitter`. @@ -42204,7 +45475,7 @@ Emitter.prototype.hasListeners = function(event){ return !! this.listeners(event).length; }; -},{}],50:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ /** * Expose `debug()` as the module. @@ -42343,11 +45614,11 @@ try { if (window.localStorage) debug.enable(localStorage.debug); } catch(e){} -},{}],51:[function(require,module,exports){ +},{}],64:[function(require,module,exports){ module.exports = require('./lib/'); -},{"./lib/":52}],52:[function(require,module,exports){ +},{"./lib/":65}],65:[function(require,module,exports){ module.exports = require('./socket'); @@ -42359,9 +45630,8 @@ module.exports = require('./socket'); */ module.exports.parser = require('engine.io-parser'); -},{"./socket":53,"engine.io-parser":62}],53:[function(require,module,exports){ -(function (global){ -/** +},{"./socket":66,"engine.io-parser":75}],66:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies. */ @@ -43010,8 +46280,7 @@ Socket.prototype.filterUpgrades = function (upgrades) { return filteredUpgrades; }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./transport":54,"./transports":55,"component-emitter":49,"debug":50,"engine.io-parser":62,"indexof":77,"parsejson":71,"parseqs":72,"parseuri":73}],54:[function(require,module,exports){ +},{"./transport":67,"./transports":68,"component-emitter":62,"debug":63,"engine.io-parser":75,"indexof":90,"parsejson":84,"parseqs":85,"parseuri":86}],67:[function(require,module,exports){ /** * Module dependencies. */ @@ -43163,9 +46432,8 @@ Transport.prototype.onClose = function () { this.emit('close'); }; -},{"component-emitter":49,"engine.io-parser":62}],55:[function(require,module,exports){ -(function (global){ -/** +},{"component-emitter":62,"engine.io-parser":75}],68:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies */ @@ -43219,10 +46487,8 @@ function polling(opts){ } } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling-jsonp":56,"./polling-xhr":57,"./websocket":59,"xmlhttprequest":60}],56:[function(require,module,exports){ -(function (global){ - +},{"./polling-jsonp":69,"./polling-xhr":70,"./websocket":72,"xmlhttprequest":73}],69:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /** * Module requirements. */ @@ -43455,10 +46721,8 @@ JSONPPolling.prototype.doWrite = function (data, fn) { } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling":58,"component-inherit":61}],57:[function(require,module,exports){ -(function (global){ -/** +},{"./polling":71,"component-inherit":74}],70:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module requirements. */ @@ -43810,8 +47074,7 @@ function unloadHandler() { } } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling":58,"component-emitter":49,"component-inherit":61,"debug":50,"xmlhttprequest":60}],58:[function(require,module,exports){ +},{"./polling":71,"component-emitter":62,"component-inherit":74,"debug":63,"xmlhttprequest":73}],71:[function(require,module,exports){ /** * Module dependencies. */ @@ -44058,7 +47321,7 @@ Polling.prototype.uri = function(){ return schema + '://' + this.hostname + port + this.path + query; }; -},{"../transport":54,"component-inherit":61,"debug":50,"engine.io-parser":62,"parseqs":72,"xmlhttprequest":60}],59:[function(require,module,exports){ +},{"../transport":67,"component-inherit":74,"debug":63,"engine.io-parser":75,"parseqs":85,"xmlhttprequest":73}],72:[function(require,module,exports){ /** * Module dependencies. */ @@ -44289,7 +47552,7 @@ WS.prototype.check = function(){ return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name); }; -},{"../transport":54,"component-inherit":61,"debug":50,"engine.io-parser":62,"parseqs":72,"ws":74}],60:[function(require,module,exports){ +},{"../transport":67,"component-inherit":74,"debug":63,"engine.io-parser":75,"parseqs":85,"ws":87}],73:[function(require,module,exports){ // browser shim for xmlhttprequest module var hasCORS = require('has-cors'); @@ -44327,7 +47590,7 @@ module.exports = function(opts) { } } -},{"has-cors":69}],61:[function(require,module,exports){ +},{"has-cors":82}],74:[function(require,module,exports){ module.exports = function(a, b){ var fn = function(){}; @@ -44335,9 +47598,8 @@ module.exports = function(a, b){ a.prototype = new fn; a.prototype.constructor = a; }; -},{}],62:[function(require,module,exports){ -(function (global){ -/** +},{}],75:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies. */ @@ -44904,8 +48166,7 @@ exports.decodePayloadAsBinary = function (data, binaryType, callback) { }); }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./keys":63,"after":64,"arraybuffer.slice":65,"base64-arraybuffer":66,"blob":67,"utf8":68}],63:[function(require,module,exports){ +},{"./keys":76,"after":77,"arraybuffer.slice":78,"base64-arraybuffer":79,"blob":80,"utf8":81}],76:[function(require,module,exports){ /** * Gets the keys for an object. @@ -44926,7 +48187,7 @@ module.exports = Object.keys || function keys (obj){ return arr; }; -},{}],64:[function(require,module,exports){ +},{}],77:[function(require,module,exports){ module.exports = after function after(count, callback, err_cb) { @@ -44956,7 +48217,7 @@ function after(count, callback, err_cb) { function noop() {} -},{}],65:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ /** * An abstraction for slicing an arraybuffer even when * ArrayBuffer.prototype.slice is not supported @@ -44987,7 +48248,7 @@ module.exports = function(arraybuffer, start, end) { return result.buffer; }; -},{}],66:[function(require,module,exports){ +},{}],79:[function(require,module,exports){ /* * base64-arraybuffer * https://github.com/niklasvh/base64-arraybuffer @@ -45048,9 +48309,8 @@ module.exports = function(arraybuffer, start, end) { }; })("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); -},{}],67:[function(require,module,exports){ -(function (global){ -/** +},{}],80:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Create a blob builder even when vendor prefixes exist */ @@ -45100,10 +48360,8 @@ module.exports = (function() { } })(); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],68:[function(require,module,exports){ -(function (global){ -/*! http://mths.be/utf8js v2.0.0 by @mathias */ +},{}],81:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/*! http://mths.be/utf8js v2.0.0 by @mathias */ ;(function(root) { // Detect free variables `exports` @@ -45343,8 +48601,7 @@ module.exports = (function() { }(this)); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],69:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ /** * Module dependencies. @@ -45369,7 +48626,7 @@ try { module.exports = false; } -},{"global":70}],70:[function(require,module,exports){ +},{"global":83}],83:[function(require,module,exports){ /** * Returns `this`. Execute this without a "context" (i.e. without it being @@ -45379,9 +48636,8 @@ try { module.exports = (function () { return this; })(); -},{}],71:[function(require,module,exports){ -(function (global){ -/** +},{}],84:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * JSON parse. * * @see Based on jQuery#parseJSON (MIT) and JSON2 @@ -45413,8 +48669,7 @@ module.exports = function parsejson(data) { return (new Function('return ' + data))(); } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],72:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ /** * Compiles a querystring * Returns string representation of the object @@ -45453,7 +48708,7 @@ exports.decode = function(qs){ return qry; }; -},{}],73:[function(require,module,exports){ +},{}],86:[function(require,module,exports){ /** * Parses an URI * @@ -45494,7 +48749,7 @@ module.exports = function parseuri(str) { return uri; }; -},{}],74:[function(require,module,exports){ +},{}],87:[function(require,module,exports){ /** * Module dependencies. @@ -45539,9 +48794,8 @@ function ws(uri, protocols, opts) { if (WebSocket) ws.prototype = WebSocket.prototype; -},{}],75:[function(require,module,exports){ -(function (global){ - +},{}],88:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /* * Module requirements. */ @@ -45600,13 +48854,12 @@ function hasBinary(data) { return _hasBinary(data); } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"isarray":76}],76:[function(require,module,exports){ +},{"isarray":89}],89:[function(require,module,exports){ module.exports = Array.isArray || function (arr) { return Object.prototype.toString.call(arr) == '[object Array]'; }; -},{}],77:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ var indexOf = [].indexOf; @@ -45617,7 +48870,7 @@ module.exports = function(arr, obj){ } return -1; }; -},{}],78:[function(require,module,exports){ +},{}],91:[function(require,module,exports){ /** * HOP ref. @@ -45702,7 +48955,7 @@ exports.length = function(obj){ exports.isEmpty = function(obj){ return 0 == exports.length(obj); }; -},{}],79:[function(require,module,exports){ +},{}],92:[function(require,module,exports){ /** * Parses an URI * @@ -45729,9 +48982,8 @@ module.exports = function parseuri(str) { return uri; }; -},{}],80:[function(require,module,exports){ -(function (global){ -/*global Blob,File*/ +},{}],93:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/*global Blob,File*/ /** * Module requirements @@ -45873,8 +49125,7 @@ exports.removeBlobs = function(data, callback) { } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./is-buffer":82,"isarray":83}],81:[function(require,module,exports){ +},{"./is-buffer":95,"isarray":96}],94:[function(require,module,exports){ /** * Module dependencies. @@ -46272,9 +49523,8 @@ function error(data){ }; } -},{"./binary":80,"./is-buffer":82,"component-emitter":49,"debug":50,"isarray":83,"json3":84}],82:[function(require,module,exports){ -(function (global){ - +},{"./binary":93,"./is-buffer":95,"component-emitter":62,"debug":63,"isarray":96,"json3":97}],95:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; module.exports = isBuf; /** @@ -46288,10 +49538,9 @@ function isBuf(obj) { (global.ArrayBuffer && obj instanceof ArrayBuffer); } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],83:[function(require,module,exports){ -module.exports=require(76) -},{}],84:[function(require,module,exports){ +},{}],96:[function(require,module,exports){ +module.exports=require(89) +},{}],97:[function(require,module,exports){ /*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */ ;(function (window) { // Convenience aliases. @@ -47154,7 +50403,7 @@ module.exports=require(76) } }(this)); -},{}],85:[function(require,module,exports){ +},{}],98:[function(require,module,exports){ module.exports = toArray function toArray(list, index) { @@ -47169,7 +50418,7 @@ function toArray(list, index) { return array } -},{}],86:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ var traverse = module.exports = function (obj) { return new Traverse(obj); }; @@ -47485,7 +50734,7 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { return key in obj; }; -},{}],87:[function(require,module,exports){ +},{}],100:[function(require,module,exports){ // Generated by CoffeeScript 1.7.1 (function() { var lang; @@ -47546,7 +50795,7 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{}],88:[function(require,module,exports){ +},{}],101:[function(require,module,exports){ // Generated by CoffeeScript 1.7.1 (function() { var deprecate, hasModule, makeTwix, @@ -48262,7 +51511,9 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{"./lang":87,"moment":41}],89:[function(require,module,exports){ +},{"./lang":100,"moment":102}],102:[function(require,module,exports){ +module.exports=require(54) +},{}],103:[function(require,module,exports){ // Underscore.js 1.5.2 // http://underscorejs.org // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors @@ -49540,8 +52791,8 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{}],90:[function(require,module,exports){ -module.exports={ +},{}],104:[function(require,module,exports){ +module.exports=module.exports={ "name": "joola.sdk", "preferGlobal": false, "version": "0.8.1", @@ -49574,7 +52825,6 @@ module.exports={ "dependencies": { "async": "~0.2.10", "cloneextend": "^0.0.3", - "d3": "^3.4.13", "deep-extend": "^0.2.10", "eventemitter2": "~0.4.13", "jquery": "^2.1.1", @@ -49606,7 +52856,7 @@ module.exports={ "license": "GPL-3.0" } -},{}],91:[function(require,module,exports){ +},{}],105:[function(require,module,exports){ /** * @title joola/lib/sdk/common/api * @copyright (c) Joola Smart Solutions, Ltd. @@ -49892,7 +53142,10 @@ api.getJSON = function (options, objOptions, callback) { joola.io.socket.emit(routeID, objOptions); joola.events.emit('rpc:start', 1); joola.events.emit('bandwidth', lengthInUtf8Bytes(JSON.stringify(objOptions))); - if (objOptions && (objOptions.realtime || (objOptions.options && Array.isArray(objOptions.options) && objOptions.options.length > 0 && objOptions.options[0].realtime))) { + var shouldOn = objOptions && (objOptions.realtime || (objOptions.options && Array.isArray(objOptions.options) && objOptions.options.length > 0 && objOptions.options[0].realtime)); + if (objOptions && objOptions.options && objOptions.options.realtime) + shouldOn = true; + if (shouldOn) { joola.io.socket.on(routeID + ':done', processResponse); } else { @@ -49912,7 +53165,7 @@ joola.events.on('rpc:done', function () { joola.usage = {currentCalls: 0}; joola.usage.currentCalls--; }); -},{"../index":99,"http":13,"https":17,"querystring":23,"url":32}],92:[function(require,module,exports){ +},{"../index":113,"http":31,"https":15,"querystring":16,"url":20}],106:[function(require,module,exports){ /** * joola * @@ -50032,7 +53285,7 @@ dispatch.buildstub = function (callback) { }; -},{"../../../build/temp/meta.json":1,"../index":99,"cloneextend":35}],93:[function(require,module,exports){ +},{"../../../build/temp/meta.json":1,"../index":113,"cloneextend":4}],107:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -50053,9 +53306,8 @@ _events._id = 'events'; module.exports = exports = _events; -},{"../index":99,"eventemitter2":37}],94:[function(require,module,exports){ -(function (global){ -/** +},{"../index":113,"eventemitter2":6}],108:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * @title joola * @overview the open-source data analytics framework * @copyright Joola Smart Solutions, Ltd. @@ -50081,10 +53333,8 @@ joola.timezone = function (tz) { return offset; }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../index":99}],95:[function(require,module,exports){ -(function (Buffer){ -/*jshint -W083 */ +},{"../index":113}],109:[function(require,module,exports){ +var Buffer=require("__browserify_Buffer").Buffer;/*jshint -W083 */ /** * @title joola @@ -50381,8 +53631,7 @@ common.formatDate = function (date) { return format(date, 'mmm dd, yyyy'); }; -}).call(this,require("buffer").Buffer) -},{"../index":99,"./modifiers":98,"buffer":3,"cloneextend":35,"crypto":7,"deep-extend":36,"traverse":86,"underscore":89,"util":34}],96:[function(require,module,exports){ +},{"../index":113,"./modifiers":112,"__browserify_Buffer":49,"cloneextend":4,"crypto":26,"deep-extend":5,"traverse":99,"underscore":103,"util":21}],110:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -50461,7 +53710,7 @@ logger.error = function (message, callback) { }; -},{"../index":99}],97:[function(require,module,exports){ +},{"../index":113}],111:[function(require,module,exports){ var memory = function () { this.content = {}; @@ -50496,7 +53745,7 @@ var memory = function () { }; module.exports = new memory(); -},{}],98:[function(require,module,exports){ +},{}],112:[function(require,module,exports){ /** * @title joola/lib/common/modifiers * @overview Includes different prototype modifiers used by joola @@ -50664,9 +53913,8 @@ String.prototype.commas = function () { parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); }; -},{}],99:[function(require,module,exports){ -(function (global){ -/** +},{}],113:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * @title joola * @overview the open-source data analytics framework * @copyright Joola Smart Solutions, Ltd. @@ -51007,8 +54255,7 @@ joola.on('ready', function () { var end = new Date().getTime(); }); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../../package.json":90,"./common/api":91,"./common/dispatch":92,"./common/events":93,"./common/globals":94,"./common/index":95,"./common/logger":96,"./common/memory":97,"./common/modifiers":98,"./viz/index":114,"querystring":23,"socket.io-client":42,"url":32}],100:[function(require,module,exports){ +},{"./../../package.json":104,"./common/api":105,"./common/dispatch":106,"./common/events":107,"./common/globals":108,"./common/index":109,"./common/logger":110,"./common/memory":111,"./common/modifiers":112,"./viz/index":128,"querystring":16,"socket.io-client":55,"url":20}],114:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -51631,7 +54878,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(BarTable, events.EventEmitter); -},{"../index":99,"events":12,"jquery":40,"underscore":89,"util":34}],101:[function(require,module,exports){ +},{"../index":113,"events":14,"jquery":53,"underscore":103,"util":21}],115:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -52030,7 +55277,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Canvas, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],102:[function(require,module,exports){ +},{"../index":113,"cloneextend":4,"events":14,"jquery":53,"underscore":103,"util":21}],116:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53114,7 +56361,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(DatePicker, events.EventEmitter); -},{"../index":99,"events":12,"jquery":40,"jquery-ui/datepicker":39,"underscore":89,"util":34}],103:[function(require,module,exports){ +},{"../index":113,"events":14,"jquery":53,"jquery-ui/datepicker":52,"underscore":103,"util":21}],117:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53407,7 +56654,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(DimensionPicker, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"util":34}],104:[function(require,module,exports){ +},{"../index":113,"cloneextend":4,"events":14,"jquery":53,"util":21}],118:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53524,7 +56771,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99,"jquery":40,"underscore":89}],105:[function(require,module,exports){ +},{"../index":113,"jquery":53,"underscore":103}],119:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53656,7 +56903,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99}],106:[function(require,module,exports){ +},{"../index":113}],120:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53917,7 +57164,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Metric, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],107:[function(require,module,exports){ +},{"../index":113,"cloneextend":4,"events":14,"jquery":53,"underscore":103,"util":21}],121:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54204,7 +57451,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(MetricPicker, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"util":34}],108:[function(require,module,exports){ +},{"../index":113,"cloneextend":4,"events":14,"jquery":53,"util":21}],122:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54499,7 +57746,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99,"underscore":89}],109:[function(require,module,exports){ +},{"../index":113,"underscore":103}],123:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54723,7 +57970,7 @@ Pie.template = function (options) { return html; }; -},{"../index":99,"underscore":89}],110:[function(require,module,exports){ +},{"../index":113,"underscore":103}],124:[function(require,module,exports){ /*jshint -W083 */ /** @@ -54943,7 +58190,7 @@ joola.events.on('core.init.finish', function () { }); -},{"../index":99,"underscore":89}],111:[function(require,module,exports){ +},{"../index":113,"underscore":103}],125:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -55198,7 +58445,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99}],112:[function(require,module,exports){ +},{"../index":113}],126:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -56066,7 +59313,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Table, events.EventEmitter); -},{"../index":99,"async":2,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],113:[function(require,module,exports){ +},{"../index":113,"async":3,"cloneextend":4,"events":14,"jquery":53,"underscore":103,"util":21}],127:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -56244,12 +59491,12 @@ var Timeline = module.exports = function (options, callback) { var checkExists = function (timestampDimension, documents, date) { return _.find(documents, function (document) { - if (!document.values[timestampDimension.key]) + if (!document[timestampDimension.key]) return; try { var _date = new Date(date); - var _basedate = new Date(document.values[timestampDimension.key]); + var _basedate = new Date(document[timestampDimension.key]); switch (interval) { case 'month': @@ -56275,8 +59522,8 @@ var Timeline = module.exports = function (options, callback) { var fill = function (resultRow, row, timestampDimension) { Object.keys(resultRow).forEach(function (key) { if (key !== timestampDimension.key) { - row.values[key] = 0; - row.fvalues[key] = 0; + row[key] = 0; + //row.fvalues[key] = 0; } }); }; @@ -56285,12 +59532,12 @@ var Timeline = module.exports = function (options, callback) { if (result.documents.length === 0) { result.documents.push({values: {}, fvalues: {}}); result.dimensions.forEach(function (d) { - result.documents[0].values[d.name] = null; - result.documents[0].fvalues[d.name] = null; + result.documents[0][d.name] = null; + //result.documents[0].fvalues[d.name] = null; }); result.metrics.forEach(function (m) { - result.documents[0].values[m.name] = null; - result.documents[0].fvalues[m.name] = null; + result.documents[0][m.name] = null; + //result.documents[0].fvalues[m.name] = null; }); } @@ -56308,8 +59555,8 @@ var Timeline = module.exports = function (options, callback) { interval = interval === 'ddate' ? 'day' : (interval || 'day'); if (!query.timeframe) { query.timeframe = {}; - query.timeframe.start = result.documents[result.documents.length - 1].values.timestamp; - query.timeframe.end = result.documents[0].values.timestamp; + query.timeframe.start = result.documents[result.documents.length - 1].timestamp; + query.timeframe.end = result.documents[0].timestamp; } var counter = 0; @@ -56339,9 +59586,9 @@ var Timeline = module.exports = function (options, callback) { if (!exists) { //_d.setHours(_d.getHours() + (offset * -1)); exists = {values: {}, fvalues: {}}; - exists.values[timestampDimension.key] = _d.toISOString(); - exists.fvalues[timestampDimension.key] = _d.toISOString(); - fill(result.documents[0].values, exists, timestampDimension); + exists[timestampDimension.key] = _d.toISOString(); + //exists.fvalues[timestampDimension.key] = _d.toISOString(); + fill(result.documents[0], exists, timestampDimension); } fixed.push(exists); } @@ -56380,20 +59627,20 @@ var Timeline = module.exports = function (options, callback) { if (nameBased) { series[seriesIndex].data.push({ name: x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } else { if (seriesIndex === 0) { series[seriesIndex].data.push({ x: x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } else { series[seriesIndex].data.push({ x: series[0].data[docIndex].x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } } @@ -56745,7 +59992,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Timeline, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"moment":41,"twix":88,"underscore":89,"util":34}],114:[function(require,module,exports){ +},{"../index":113,"cloneextend":4,"events":14,"jquery":53,"moment":54,"twix":101,"underscore":103,"util":21}],128:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -56942,13 +60189,14 @@ viz.fetch = function (context, query, callback) { realtime: message.query.realtime }; var key = ''; + console.log(doc); message.dimensions.forEach(function (d) { - key += doc.raw.values[d.key]; - doc.dimensions[d.key] = doc.raw.values[d.key]; + key += doc.raw[d.key]; + doc.dimensions[d.key] = doc.raw[d.key]; doc.meta[d.key] = d; }); message.metrics.forEach(function (m) { - doc.metrics[m.key] = doc.raw.values[m.key]; + doc.metrics[m.key] = doc.raw[m.key]; doc.meta[m.key] = m; }); doc.key = joola.common.hash(key); @@ -57128,4 +60376,6 @@ viz.destroy = function (self, vizOptions) { } }); });*/ -},{"../index":99,"./BarTable":100,"./Canvas":101,"./DatePicker":102,"./DimensionPicker":103,"./FilterBox":104,"./Geo":105,"./Metric":106,"./MetricPicker":107,"./MiniTable":108,"./Pie":109,"./PunchCard":110,"./Sparkline":111,"./Table":112,"./Timeline":113,"async":2,"cloneextend":35,"jquery":40,"underscore":89}]},{},[99]) \ No newline at end of file +},{"../index":113,"./BarTable":114,"./Canvas":115,"./DatePicker":116,"./DimensionPicker":117,"./FilterBox":118,"./Geo":119,"./Metric":120,"./MetricPicker":121,"./MiniTable":122,"./Pie":123,"./PunchCard":124,"./Sparkline":125,"./Table":126,"./Timeline":127,"async":3,"cloneextend":4,"jquery":53,"underscore":103}]},{},[2,113]) +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9idWlsZC90ZW1wL21ldGEuanNvbiIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9idWlsZC90ZW1wL3ZlbmRvci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvYXN5bmMvbGliL2FzeW5jLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9jbG9uZWV4dGVuZC9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZGVlcC1leHRlbmQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2V2ZW50ZW1pdHRlcjIvbGliL2V2ZW50ZW1pdHRlcjIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vX3NoaW1zLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL19zdHJlYW1fZHVwbGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vX3N0cmVhbV9yZWFkYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL2Fzc2VydC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9ldmVudHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vaHR0cHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vcXVlcnlzdHJpbmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vc3RyZWFtLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL3N0cmluZ19kZWNvZGVyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL3RpbWVycy5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi91cmwuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vdXRpbC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvbm9kZV9tb2R1bGVzL2J1ZmZlci1icm93c2VyaWZ5L2J1ZmZlcl9pZWVlNzU0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvYnVmZmVyLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9idWZmZXItYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9oZWxwZXJzLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9tZDUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ybmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEyNTYuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3JlcXVlc3QuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3Jlc3BvbnNlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvaHR0cC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9CYXNlNjQvYmFzZTY0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL25vZGVfbW9kdWxlcy90by11dGY4L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9ub2RlX21vZHVsZXMvYm9wcy90eXBlZGFycmF5L2NvcHkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvY3JlYXRlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9ub2RlX21vZHVsZXMvYm9wcy90eXBlZGFycmF5L2Zyb20uanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvaXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvam9pbi5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS9tYXBwZWQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvcmVhZC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS9zdWJhcnJheS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS90by5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS93cml0ZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2luc2VydC1tb2R1bGUtZ2xvYmFscy9idWZmZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvanF1ZXJ5LXVpL2NvcmUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2pxdWVyeS11aS9kYXRlcGlja2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9qcXVlcnkvZGlzdC9qcXVlcnkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL21vbWVudC9tb21lbnQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9tYW5hZ2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9vbi5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi91cmwuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2NvbXBvbmVudC1iaW5kL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9jb21wb25lbnQtZW1pdHRlci9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9zb2NrZXQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi94bWxodHRwcmVxdWVzdC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWluaGVyaXQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2tleXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2FmdGVyL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9hcnJheWJ1ZmZlci5zbGljZS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9ub2RlX21vZHVsZXMvYmFzZTY0LWFycmF5YnVmZmVyL2xpYi9iYXNlNjQtYXJyYXlidWZmZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2Jsb2IvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL3V0ZjgvdXRmOC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvaGFzLWNvcnMvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2hhcy1jb3JzL25vZGVfbW9kdWxlcy9nbG9iYWwvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3BhcnNlanNvbi9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvcGFyc2Vxcy9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvcGFyc2V1cmkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3dzL2xpYi9icm93c2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9pbmRleG9mL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9vYmplY3QtY29tcG9uZW50L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9wYXJzZXVyaS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaXMtYnVmZmVyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9qc29uMy9saWIvanNvbjMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3RvLWFycmF5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy90cmF2ZXJzZS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdHdpeC9iaW4vbGFuZy5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdHdpeC9iaW4vdHdpeC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3BhY2thZ2UuanNvbiIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL2NvbW1vbi9hcGkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vZGlzcGF0Y2guanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vZXZlbnRzLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvY29tbW9uL2dsb2JhbHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vbG9nZ2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvY29tbW9uL21lbW9yeS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL2NvbW1vbi9tb2RpZmllcnMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9CYXJUYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9DYW52YXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovRGF0ZVBpY2tlci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9EaW1lbnNpb25QaWNrZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovRmlsdGVyQm94LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L0dlby5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9NZXRyaWMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovTWV0cmljUGlja2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L01pbmlUYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9QaWUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovUHVuY2hDYXJkLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L1NwYXJrbGluZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9UYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9UaW1lbGluZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwNmpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzk3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3akJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9oQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwbUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzEwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ovREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyL1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4M0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFjQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMVhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeG9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzFzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1dkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25UQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3WUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDblFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMU5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsMkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNycUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzPW1vZHVsZS5leHBvcnRzPXtcInVzZXJzXCI6e1wibGlzdFwiOntcIm5hbWVcIjpcIi91c2Vycy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgdXNlcnNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiXSxcIl9wcm90b1wiOntcInVzZXJuYW1lXCI6e1wibmFtZVwiOlwidXNlcm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHVzZXJuYW1lXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkaXNwbGF5TmFtZVwiOntcIm5hbWVcIjpcImRpc3BsYXlOYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpc3BsYXluYW1lIG9mIHRoZSB1c2VyXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInBhc3N3b3JkXCI6e1wibmFtZVwiOlwicGFzc3dvcmRcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHBhc3N3b3JkXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcInJvbGVzXCI6e1wibmFtZVwiOlwicm9sZXNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHJvbGVzXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGZpbHRlclwiLFwidHlwZVwiOlwiYXJyYXlcIixcImRlZmF1bHRcIjpbXSxcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJBUElUb2tlblwiOntcIm5hbWVcIjpcIkFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBBUEkgVG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJ3b3Jrc3BhY2VcIjp7XCJuYW1lXCI6XCJ3b3Jrc3BhY2VcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIFdvcmtzcGFjZVwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJ0b2tlblwiOntcIm5hbWVcIjpcInRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBjdXJyZW50IHNlY3VyaXR5IHRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ1c2VyczpsaXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi91c2Vycy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIHVzZXJzIGJ5IHVzZXJuYW1lXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcInVzZXJuYW1lXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldEJ5VG9rZW5cIjp7XCJuYW1lXCI6XCIvdXNlcnMvZ2V0QnlUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgdXNlciBieSB0b2tlblwiLFwiaW5wdXRzXCI6W1widG9rZW5cIl0sXCJfcHJvdG9cIjp7XCJ1c2VybmFtZVwiOntcIm5hbWVcIjpcInVzZXJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyB1c2VybmFtZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGlzcGxheU5hbWVcIjp7XCJuYW1lXCI6XCJkaXNwbGF5TmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaXNwbGF5bmFtZSBvZiB0aGUgdXNlclwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJwYXNzd29yZFwiOntcIm5hbWVcIjpcInBhc3N3b3JkXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBwYXNzd29yZFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJyb2xlc1wiOntcIm5hbWVcIjpcInJvbGVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyByb2xlc1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBmaWx0ZXJcIixcInR5cGVcIjpcImFycmF5XCIsXCJkZWZhdWx0XCI6W10sXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwiQVBJVG9rZW5cIjp7XCJuYW1lXCI6XCJBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgQVBJIFRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwid29ya3NwYWNlXCI6e1wibmFtZVwiOlwid29ya3NwYWNlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBXb3Jrc3BhY2VcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgY3VycmVudCBzZWN1cml0eSB0b2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZ3Vlc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczpnZXRCeVRva2VuXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL3VzZXJzL2FkZFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgYWRkIGEgbmV3IHVzZXJcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwidXNlclwiXSxcIl9wcm90b1wiOntcInVzZXJuYW1lXCI6e1wibmFtZVwiOlwidXNlcm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHVzZXJuYW1lXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkaXNwbGF5TmFtZVwiOntcIm5hbWVcIjpcImRpc3BsYXlOYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpc3BsYXluYW1lIG9mIHRoZSB1c2VyXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInBhc3N3b3JkXCI6e1wibmFtZVwiOlwicGFzc3dvcmRcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHBhc3N3b3JkXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcInJvbGVzXCI6e1wibmFtZVwiOlwicm9sZXNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHJvbGVzXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGZpbHRlclwiLFwidHlwZVwiOlwiYXJyYXlcIixcImRlZmF1bHRcIjpbXSxcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJBUElUb2tlblwiOntcIm5hbWVcIjpcIkFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBBUEkgVG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJ3b3Jrc3BhY2VcIjp7XCJuYW1lXCI6XCJ3b3Jrc3BhY2VcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIFdvcmtzcGFjZVwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJ0b2tlblwiOntcIm5hbWVcIjpcInRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBjdXJyZW50IHNlY3VyaXR5IHRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ1c2VyczphZGRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczphZGRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJwYXRjaFwiOntcIm5hbWVcIjpcIi91c2Vycy9wYXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcGF0Y2ggYW4gZXhpc3RpbmcgdXNlclwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJ1c2VybmFtZVwiLFwidXNlclwiXSxcIl9wcm90b1wiOntcInVzZXJuYW1lXCI6e1wibmFtZVwiOlwidXNlcm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHVzZXJuYW1lXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkaXNwbGF5TmFtZVwiOntcIm5hbWVcIjpcImRpc3BsYXlOYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpc3BsYXluYW1lIG9mIHRoZSB1c2VyXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInBhc3N3b3JkXCI6e1wibmFtZVwiOlwicGFzc3dvcmRcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHBhc3N3b3JkXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcInJvbGVzXCI6e1wibmFtZVwiOlwicm9sZXNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHJvbGVzXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGZpbHRlclwiLFwidHlwZVwiOlwiYXJyYXlcIixcImRlZmF1bHRcIjpbXSxcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJBUElUb2tlblwiOntcIm5hbWVcIjpcIkFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBBUEkgVG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJ3b3Jrc3BhY2VcIjp7XCJuYW1lXCI6XCJ3b3Jrc3BhY2VcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIFdvcmtzcGFjZVwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJ0b2tlblwiOntcIm5hbWVcIjpcInRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBjdXJyZW50IHNlY3VyaXR5IHRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ1c2VyczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOnBhdGNoXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZGVsZXRlXCI6e1wibmFtZVwiOlwiL3VzZXJzL2RlbGV0ZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZGVsZXRlIGFuIGV4aXN0aW5nIHVzZXJcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwidXNlclwiXSxcIl9wcm90b1wiOm51bGwsXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ1c2VyczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJhdXRoZW50aWNhdGVcIjp7XCJuYW1lXCI6XCIvdXNlcnMvYXV0aGVudGljYXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhdXRoZW50aWNhdGUgdXNlcnNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwidXNlcm5hbWVcIixcInBhc3N3b3JkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZ3Vlc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczphdXRoZW50aWNhdGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJ2ZXJpZnlBUElUb2tlblwiOntcIm5hbWVcIjpcIi91c2Vycy92ZXJpZnlBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgdmVyaWZ5IEFQSSB0b2tlbnNcIixcImlucHV0c1wiOltcInRva2VuXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImd1ZXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6dmVyaWZ5QVBJVG9rZW5cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZW5lcmF0ZVRva2VuXCI6e1wibmFtZVwiOlwiL3VzZXJzL2dlbmVyYXRlVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJJIGdlbmVyYXRlIHRva2VucyBmb3IgdXNlcnNcIixcImlucHV0c1wiOltcInVzZXJcIl0sXCJfcHJvdG9cIjp7XCJ1c2VyXCI6e1wibmFtZVwiOlwidXNlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyIGFzc29zaWNhdGVkIHdpdGggdGhlIHRva2VuXCIsXCJ0eXBlXCI6XCJvYmplY3RcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdG9rZW4gaXRzZWxmXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiX1wiOntcIm5hbWVcIjpcIl9cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdG9rZW4gaXRzZWxmXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwidGltZXN0YW1wXCI6e1wibmFtZVwiOlwidGltZXN0YW1wXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHRva2VuIGdlbmVyYXRpb24gdGltZXN0YW1wXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwibGFzdFwiOntcIm5hbWVcIjpcImxhc3RcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdG9rZW4gbGFzdCB1c2FnZSB0aW1lc3RhbXBcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJleHBpcmVzXCI6e1wibmFtZVwiOlwiZXhwaXJlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0b2tlbiBleHBpcnkgdGltZXN0YW1wXCIsXCJ0eXBlXCI6XCJpbnRcIixcInJlcXVpcmVkXCI6dHJ1ZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1widXNlcnM6Z2VuZXJhdGVUb2tlblwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmdlbmVyYXRlVG9rZW5cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJ2YWxpZGF0ZVRva2VuXCI6e1wibmFtZVwiOlwiL3VzZXJzL3ZhbGlkYXRlVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJJIHZhbGlkYXRlIHRva2VucyBmb3IgdXNlcnNcIixcImlucHV0c1wiOltcInRva2VuXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOnZhbGlkYXRlVG9rZW5cIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2Vyczp2YWxpZGF0ZVRva2VuXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZXhwaXJlVG9rZW5cIjp7XCJuYW1lXCI6XCIvdXNlcnMvZXhwaXJlVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJJIGV4cGlyZSB0b2tlbnMgZm9yIHVzZXJzXCIsXCJpbnB1dHNcIjpbXCJ0b2tlblwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOmV4cGlyZVRva2VuXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6ZXhwaXJlVG9rZW5cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJwZXJtaXNzaW9uc1wiOntcIm5hbWVcIjpcIi91c2Vycy9wZXJtaXNzaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IHRoZSB1c2VyJ3MgcGVybWlzc2lvbnNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwidXNlclwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOnBlcm1pc3Npb25zXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6cGVybWlzc2lvbnNcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwid29ya3NwYWNlc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvd29ya3NwYWNlcy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgd29ya3NwYWNlc1wiLFwiaW5wdXRzXCI6W10sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUga2V5IG9mIHRoZSB3b3Jrc3BhY2VcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ3b3Jrc3BhY2VzOmxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ3b3Jrc3BhY2VzOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvd29ya3NwYWNlcy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIHdvcmtzcGFjZSBieSBrZXlgXCIsXCJpbnB1dHNcIjpbXCJrZXlcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUga2V5IG9mIHRoZSB3b3Jrc3BhY2VcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ3b3Jrc3BhY2VzOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIndvcmtzcGFjZXM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL3dvcmtzcGFjZXMvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgdXNlclwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wid29ya3NwYWNlczphZGRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ3b3Jrc3BhY2VzOmFkZFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInBhdGNoXCI6e1wibmFtZVwiOlwiL3dvcmtzcGFjZXMvcGF0Y2hcIixcImRlc2NyaXB0aW9uXCI6XCJJIHBhdGNoIGFuIGV4aXN0aW5nIHdvcmtzcGFjZVwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJwYXlsb2FkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wid29ya3NwYWNlczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIndvcmtzcGFjZXM6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvd29ya3NwYWNlcy9kZWxldGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGRlbGV0ZSBhbiBleGlzdGluZyB3b3Jrc3BhY2VcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIndvcmtzcGFjZXM6ZGVsZXRlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwid29ya3NwYWNlczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwicm9sZXNcIjp7XCJsaXN0XCI6e1wibmFtZVwiOlwiL3JvbGVzL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSByb2xlc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGtleSBvZiB0aGUgcm9sZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwicGVybWlzc2lvbnNcIjp7XCJuYW1lXCI6XCJwZXJtaXNzaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIkxpc3Qgb2YgcGVybWlzc2lvbnMgYXNzb3NjaWF0ZWQgd2l0aCB0aGlzIHJvbGVcIixcInJlcXVpcmVkXCI6dHJ1ZSxcImRlZmF1bHRcIjpbXSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIkxpc3Qgb2YgZmlsdGVycyBmb3IgdGhlIHNwZWNpZmllZCByb2xlXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOltdLFwicHJpdmF0ZVwiOnRydWV9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInJvbGVzOmxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJyb2xlczpsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZ2V0XCI6e1wibmFtZVwiOlwiL3JvbGVzL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgcm9sZSBieSBuYW1lYFwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJuYW1lXCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGtleSBvZiB0aGUgcm9sZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwicGVybWlzc2lvbnNcIjp7XCJuYW1lXCI6XCJwZXJtaXNzaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIkxpc3Qgb2YgcGVybWlzc2lvbnMgYXNzb3NjaWF0ZWQgd2l0aCB0aGlzIHJvbGVcIixcInJlcXVpcmVkXCI6dHJ1ZSxcImRlZmF1bHRcIjpbXSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIkxpc3Qgb2YgZmlsdGVycyBmb3IgdGhlIHNwZWNpZmllZCByb2xlXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOltdLFwicHJpdmF0ZVwiOnRydWV9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInJvbGVzOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInJvbGVzOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImFkZFwiOntcIm5hbWVcIjpcIi9yb2xlcy9hZGRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGFkZCBhIG5ldyB1c2VyXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcInJvbGVcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUga2V5IG9mIHRoZSByb2xlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJwZXJtaXNzaW9uc1wiOntcIm5hbWVcIjpcInBlcm1pc3Npb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBwZXJtaXNzaW9ucyBhc3Nvc2NpYXRlZCB3aXRoIHRoaXMgcm9sZVwiLFwicmVxdWlyZWRcIjp0cnVlLFwiZGVmYXVsdFwiOltdLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBmaWx0ZXJzIGZvciB0aGUgc3BlY2lmaWVkIHJvbGVcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6W10sXCJwcml2YXRlXCI6dHJ1ZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicm9sZXM6YWRkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicm9sZXM6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvcm9sZXMvcGF0Y2hcIixcImRlc2NyaXB0aW9uXCI6XCJJIHBhdGNoIGFuIGV4aXN0aW5nIHJvbGVcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwicm9sZVwiLFwicGF5bG9hZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInJvbGVzOnBhdGNoXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicm9sZXM6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvcm9sZXMvZGVsZXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBkZWxldGUgYW4gZXhpc3Rpbmcgcm9sZVwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJyb2xlXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicm9sZXM6ZGVsZXRlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicm9sZXM6ZGVsZXRlXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19fSxcInBlcm1pc3Npb25zXCI6e1wibGlzdFwiOntcIm5hbWVcIjpcIi9wZXJtaXNzaW9ucy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgcGVybWlzc2lvbnNcIixcImlucHV0c1wiOltdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicGVybWlzc2lvbnM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInBlcm1pc3Npb25zOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvcGVybWlzc2lvbnMvZ2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyBwZXJtaXNzaW9uIGJ5IG5hbWVgXCIsXCJpbnB1dHNcIjpbXCJuYW1lXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicGVybWlzc2lvbnM6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicGVybWlzc2lvbnM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19fSxcInN5c3RlbVwiOntcInZlcnNpb25cIjp7XCJuYW1lXCI6XCIvc3lzdGVtL3ZlcnNpb25cIixcImRlc2NyaXB0aW9uXCI6XCJJIHByaW50IG91dCB0aGUgdmVyc2lvblwiLFwidmVyYlwiOlwiR0VUXCIsXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTp2ZXJzaW9uXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOnZlcnNpb25cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJub2RlVUlEXCI6e1wibmFtZVwiOlwiL3N5c3RlbS9ub2RlVUlEXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwcmludCBvdXQgdGhlIG5vZGUgdXVpZFwiLFwidmVyYlwiOlwiR0VUXCIsXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTpub2RldWlkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOm5vZGV1aWRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJ3aG9hbWlcIjp7XCJuYW1lXCI6XCIvYXBpL3N5c3RlbS93aG9hbWlcIixcImRlc2NyaXB0aW9uXCI6XCJJIHByaW50IG91dCB0aGUgdXNlciBkZXRhaWxzXCIsXCJfcHJvdG9cIjp7XCJ1c2VybmFtZVwiOntcIm5hbWVcIjpcInVzZXJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyB1c2VybmFtZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGlzcGxheU5hbWVcIjp7XCJuYW1lXCI6XCJkaXNwbGF5TmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaXNwbGF5bmFtZSBvZiB0aGUgdXNlclwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJwYXNzd29yZFwiOntcIm5hbWVcIjpcInBhc3N3b3JkXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBwYXNzd29yZFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJyb2xlc1wiOntcIm5hbWVcIjpcInJvbGVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyByb2xlc1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBmaWx0ZXJcIixcInR5cGVcIjpcImFycmF5XCIsXCJkZWZhdWx0XCI6W10sXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwiQVBJVG9rZW5cIjp7XCJuYW1lXCI6XCJBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgQVBJIFRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwid29ya3NwYWNlXCI6e1wibmFtZVwiOlwid29ya3NwYWNlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBXb3Jrc3BhY2VcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgY3VycmVudCBzZWN1cml0eSB0b2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiaW5wdXRzXCI6W10sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJzeXN0ZW06d2hvYW1pXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOndob2FtaVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImJsYWNrbGlzdFwiOntcIm5hbWVcIjpcIi9zeXN0ZW0vYmxhY2tsaXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBibGFja2xpc3QgYW4gSVBcIixcImlucHV0c1wiOntcInJlcXVpcmVkXCI6W1wiaXBcIixcImJsYWNrbGlzdFwiXSxcIm9wdGlvbmFsXCI6W1widHRsXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTpibGFja2xpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06YmxhY2tsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwibm9kZURldGFpbHNcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL25vZGVEZXRhaWxzXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwcmludCBkZXRhaWxzIG9uIHRoaXMgbm9kZVwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXSxcIm9wdGlvbmFsXCI6W1widWlkXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTpub2RlZGV0YWlsc1wiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInN5c3RlbTpub2RlZGV0YWlsc1wiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImNvbm5lY3RlZENsaWVudHNcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL2Nvbm5lY3RlZENsaWVudHNcIixcImRlc2NyaXB0aW9uXCI6XCJJIHByaW50IGRldGFpbHMgb24gYWxsIGNvbm5lY3RlZCBjbGllbnRzIHRvIHRoaXMgbm9kZVwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXSxcIm9wdGlvbmFsXCI6W1widWlkXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTpjb25uZWN0ZWRjbGllbnRzXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOmNvbm5lY3RlZGNsaWVudHNcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJub2RlTGlzdFwiOntcIm5hbWVcIjpcIi9zeXN0ZW0vbm9kZUxpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIHJlZ2lzdGVyZWQgbm9kZXNcIixcImlucHV0c1wiOltdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOm5vZGVsaXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOm5vZGVsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicm91bmRUcmlwXCI6e1wibmFtZVwiOlwiL3N5c3RlbS9yb3VuZFRyaXBcIixcImRlc2NyaXB0aW9uXCI6XCJJIGV4ZWN1dGUgYSByb3VuZHRyaXAgb2YgYSBwYXlsb2FkIGFuZCByZXR1cm4gdGhlIHRpbWUgaW4gbXNcIixcImlucHV0c1wiOltcInN0YXJ0XCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOnJvdW5kdHJpcFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInJvdW5kdHJpcFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9LFwiX3JvdXRlXCI6bnVsbH0sXCJ0ZXJtaW5hdGVcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL3Rlcm1pbmF0ZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgdGVybWluYXRlIGEgbm9kZVwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXSxcIm9wdGlvbmFsXCI6W1widWlkXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTp0ZXJtaW5hdGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ0ZXJtaW5hdGVcIixcImxpbWl0XCI6LTEsXCJjcml0ZXJpYVwiOlwibm90bWVcIn0sXCJfcm91dGVcIjpudWxsfSxcInN0YXJ0V2ViU2VydmVyXCI6e1wibmFtZVwiOlwiL3N5c3RlbS9zdGFydFdlYlNlcnZlclwiLFwiZGVzY3JpcHRpb25cIjpcIkkgc3RhcnQgYSBXZWJTZXJ2ZXIgb24gYSBub2RlXCIsXCJpbnB1dHNcIjpbXCJub2RlXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOnN0YXJ0V2ViU2VydmVyXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3RhcnRXZWJTZXJ2ZXJcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfSxcIl9yb3V0ZVwiOm51bGx9LFwicHVyZ2VDYWNoZVwiOntcIm5hbWVcIjpcIi9zeXN0ZW0vcHVyZ2VDYWNoZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHVyZ2UgdGhlIGNhY2hlXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltdLFwib3B0aW9uYWxcIjpbXX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJzeXN0ZW06cHVyZ2VDYWNoZVwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInB1cmdlQ2FjaGVcIixcImxpbWl0XCI6LTEsXCJjcml0ZXJpYVwiOlwibm90bWVcIn0sXCJfcm91dGVcIjpudWxsfX0sXCJiZWFjb25cIjp7XCJpbnNlcnRcIjp7XCJuYW1lXCI6XCIvYmVhY29uL2luc2VydFwiLFwiZGVzY3JpcHRpb25cIjpcIlwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcImRvY3VtZW50XCJdLFwib3B0aW9uYWxcIjpbXCJvcHRpb25zXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImJlYWNvbjppbnNlcnRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJiZWFjb246aW5zZXJ0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19fSxcInF1ZXJ5XCI6e1wic3RvcFwiOntcIm5hbWVcIjpcIi9xdWVyeS9zdG9wXCIsXCJkZXNjcmlwdGlvblwiOlwiXCIsXCJpbnB1dHNcIjpbXCJxdWVyeXRva2VuXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicXVlcnk6c3RvcFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInF1ZXJ5OnN0b3BcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJmZXRjaFwiOntcIm5hbWVcIjpcIi9xdWVyeS9mZXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIlwiLFwiaW5wdXRzXCI6W1wib3B0aW9uc1wiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInF1ZXJ5OmZldGNoXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicXVlcnk6ZmV0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwiY29sbGVjdGlvbnNcIjp7XCJsaXN0XCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSBjb2xsZWN0aW9uc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBjb2xsZWN0aW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkZXNjcmlwdGlvblwiOntcIm5hbWVcIjpcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBjb2xsZWN0aW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJzdHJvbmdUeXBlZFwiOntcIm5hbWVcIjpcInN0cm9uZ1R5cGVkXCIsXCJkZXNjcmlwdGlvblwiOlwiSXMgdGhlIGNvbGxlY3Rpb24gc3Ryb25nIHR5cGVkXCIsXCJ0eXBlXCI6XCJib29sZWFuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOmZhbHNlfSxcImRpbWVuc2lvbnNcIjp7XCJuYW1lXCI6XCJkaW1lbnNpb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24ncyBkaW1lbnNpb25zXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpbXX0sXCJtZXRyaWNzXCI6e1wibmFtZVwiOlwibWV0cmljc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBjb2xsZWN0aW9uJ3MgbWV0cmljc1wiLFwidHlwZVwiOlwiYXJyYXlcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6W119fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOmxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjb2xsZWN0aW9uczpsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZ2V0XCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgY29sbGVjdGlvbiBieSBpZGBcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiaWRcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgaWQgb2YgdGhlIGNvbGxlY3Rpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGNvbGxlY3Rpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInN0cm9uZ1R5cGVkXCI6e1wibmFtZVwiOlwic3Ryb25nVHlwZWRcIixcImRlc2NyaXB0aW9uXCI6XCJJcyB0aGUgY29sbGVjdGlvbiBzdHJvbmcgdHlwZWRcIixcInR5cGVcIjpcImJvb2xlYW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6ZmFsc2V9LFwiZGltZW5zaW9uc1wiOntcIm5hbWVcIjpcImRpbWVuc2lvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbidzIGRpbWVuc2lvbnNcIixcInR5cGVcIjpcImFycmF5XCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOltdfSxcIm1ldHJpY3NcIjp7XCJuYW1lXCI6XCJtZXRyaWNzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24ncyBtZXRyaWNzXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpbXX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY29sbGVjdGlvbnM6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29sbGVjdGlvbnM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL2FkZFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgYWRkIGEgbmV3IGNvbGxlY3Rpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOmFkZFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInBhdGNoXCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL3BhdGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwYXRjaCBhbiBleGlzdGluZyBjb2xsZWN0aW9uXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcInBheWxvYWRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb2xsZWN0aW9uczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOnBhdGNoXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZGVsZXRlXCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL2RlbGV0ZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZGVsZXRlIGFuIGV4aXN0aW5nIGNvbGxlY3Rpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiaWRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb2xsZWN0aW9uczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjb2xsZWN0aW9uczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJzdGF0c1wiOntcIm5hbWVcIjpcIi9jb2xsZWN0aW9ucy9zdGF0c1wiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHJvdmlkZSBzdGF0cyBhYm91dCBhIGNvbGxlY3Rpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiaWRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb2xsZWN0aW9uczpzdGF0c1wiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOnN0YXRzXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwibWV0YWRhdGFcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvbWV0YWRhdGFcIixcImRlc2NyaXB0aW9uXCI6XCJJIHByb3ZpZGUgbWV0YWRhdGEgaW5mb3JtYXRpb24gZm9yIGEgZG9jdW1lbnRcIixcImlucHV0c1wiOntcInJlcXVpcmVkXCI6W1wid29ya3NwYWNlXCIsXCJkb2N1bWVudFwiXSxcIm9wdGlvbmFsXCI6W1wiY29sbGVjdGlvblwiXX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb2xsZWN0aW9uczptZXRhZGF0YVwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOm1ldGFkYXRhXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19fSxcImRpbWVuc2lvbnNcIjp7XCJsaXN0XCI6e1wibmFtZVwiOlwiL2RpbWVuc2lvbnMvbGlzdFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbGlzdCBhbGwgYXZhaWxhYmxlIGRpbWVuc2lvbnNcIixcImlucHV0c1wiOntcInJlcXVpcmVkXCI6W1wid29ya3NwYWNlXCJdLFwib3B0aW9uYWxcIjpbXCJjb2xsZWN0aW9uXCJdfSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBpZCBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJuYW1lXCI6e1wibmFtZVwiOlwibmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBuYW1lIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwidHlwZVwiOntcIm5hbWVcIjpcInR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdHlwZSBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJkYXRhdHlwZVwiOntcIm5hbWVcIjpcImRhdGF0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRhdGF0eXBlIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcInN0cmluZ1wifSxcImNvbGxlY3Rpb25cIjp7XCJuYW1lXCI6XCJjb2xsZWN0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24gb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImRpbWVuc2lvbnM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImRpbWVuc2lvbnM6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi9kaW1lbnNpb25zL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgZGltZW5zaW9uIGJ5IGtleWBcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwia2V5XCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJ0eXBlXCI6e1wibmFtZVwiOlwidHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0eXBlIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcImRhdGF0eXBlXCI6e1wibmFtZVwiOlwiZGF0YXR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGF0YXR5cGUgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwic3RyaW5nXCJ9LFwiY29sbGVjdGlvblwiOntcIm5hbWVcIjpcImNvbGxlY3Rpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbiBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZGltZW5zaW9uczpnZXRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJkaW1lbnNpb25zOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImFkZFwiOntcIm5hbWVcIjpcIi9kaW1lbnNpb25zL2FkZFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgYWRkIGEgbmV3IGRpbWVuc2lvblwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjb2xsZWN0aW9uXCIsXCJkaW1lbnNpb25cIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJkaW1lbnNpb25zOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImRpbWVuc2lvbnM6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvZGltZW5zaW9ucy9wYXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcGF0Y2ggYW4gZXhpc3RpbmcgZGltZW5zaW9uXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcImRpbWVuc2lvblwiLFwicGF5bG9hZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImRpbWVuc2lvbnM6cGF0Y2hcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJkaW1lbnNpb25zOnBhdGNoXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZGVsZXRlXCI6e1wibmFtZVwiOlwiL2RpbWVuc2lvbnMvZGVsZXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBkZWxldGUgYW4gZXhpc3RpbmcgZGltZW5zaW9uXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcImRpbWVuc2lvblwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImRpbWVuc2lvbnM6ZGVsZXRlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiZGltZW5zaW9uczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwibWV0cmljc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvbWV0cmljcy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgbWV0cmljc1wiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJvcHRpb25hbFwiOltcImNvbGxlY3Rpb25cIl19LFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJ0eXBlXCI6e1wibmFtZVwiOlwidHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0eXBlIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBmaWx0ZXIgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwiYXJyYXlcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJkYXRhdHlwZVwiOntcIm5hbWVcIjpcImRhdGF0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRhdGF0eXBlIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcImFnZ3JlZ2F0aW9uXCI6e1wibmFtZVwiOlwiYWdncmVnYXRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgYWdncmVnYXRpb24gb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwicHJlZml4XCI6e1wibmFtZVwiOlwicHJlZml4XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHByZWZpeCBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJzdWZmaXhcIjp7XCJuYW1lXCI6XCJzdWZmaXhcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgc3VmZml4IG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcImRlY2ltYWxzXCI6e1wibmFtZVwiOlwiZGVjaW1hbHNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHNob3dcIixcInR5cGVcIjpcImludFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjowfSxcImZvcm11bGFcIjp7XCJuYW1lXCI6XCJmb3JtdWxhXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGZvcm11bGEgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwib2JqZWN0XCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImNvbGxlY3Rpb25cIjp7XCJuYW1lXCI6XCJjb2xsZWN0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24gb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImNhdGVnb3J5XCI6e1wibmFtZVwiOlwiY2F0ZWdvcnlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY2F0ZWdvcnkgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJtZXRyaWNzOmxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJtZXRyaWNzOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvbWV0cmljcy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIG1ldHJpYyBieSBrZXlgXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcImtleVwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBpZCBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJuYW1lXCI6e1wibmFtZVwiOlwibmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBuYW1lIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwidHlwZVwiOntcIm5hbWVcIjpcInR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdHlwZSBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZmlsdGVyIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcImFycmF5XCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwiZGF0YXR5cGVcIjp7XCJuYW1lXCI6XCJkYXRhdHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkYXRhdHlwZSBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJhZ2dyZWdhdGlvblwiOntcIm5hbWVcIjpcImFnZ3JlZ2F0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGFnZ3JlZ2F0aW9uIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInByZWZpeFwiOntcIm5hbWVcIjpcInByZWZpeFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBwcmVmaXggb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwic3VmZml4XCI6e1wibmFtZVwiOlwic3VmZml4XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHN1ZmZpeCBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJkZWNpbWFsc1wiOntcIm5hbWVcIjpcImRlY2ltYWxzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB0byBzaG93XCIsXCJ0eXBlXCI6XCJpbnRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6MH0sXCJmb3JtdWxhXCI6e1wibmFtZVwiOlwiZm9ybXVsYVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBmb3JtdWxhIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcIm9iamVjdFwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJjb2xsZWN0aW9uXCI6e1wibmFtZVwiOlwiY29sbGVjdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBjb2xsZWN0aW9uIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJjYXRlZ29yeVwiOntcIm5hbWVcIjpcImNhdGVnb3J5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNhdGVnb3J5IG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wibWV0cmljczpnZXRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJtZXRyaWNzOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImFkZFwiOntcIm5hbWVcIjpcIi9tZXRyaWNzL2FkZFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgYWRkIGEgbmV3IG1ldHJpY1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjb2xsZWN0aW9uXCIsXCJtZXRyaWNcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJtZXRyaWNzOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIm1ldHJpY3M6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvbWV0cmljcy9wYXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcGF0Y2ggYW4gZXhpc3RpbmcgbWV0cmljXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcIm1ldHJpY1wiLFwicGF5bG9hZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIm1ldHJpY3M6cGF0Y2hcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJtZXRyaWNzOnBhdGNoXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZGVsZXRlXCI6e1wibmFtZVwiOlwiL21ldHJpY3MvZGVsZXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBkZWxldGUgYW4gZXhpc3RpbmcgbWV0cmljXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcIm1ldHJpY1wiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIm1ldHJpY3M6ZGVsZXRlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwibWV0cmljczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwiY29uZmlnXCI6e1wiZ2V0XCI6e1wibmFtZVwiOlwiL2NvbmZpZy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIGNvbmZpZyBieSBuYW1lYFwiLFwiaW5wdXRzXCI6W1wia2V5XCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY29uZmlnOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbmZpZzpnZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJzZXRcIjp7XCJuYW1lXCI6XCIvY29uZmlnL3NldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgc2V0IGEgbmV3IGNvbmZpZyBrZXlcIixcImlucHV0c1wiOltcImtleVwiLFwidmFsXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY29uZmlnOnNldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbmZpZzpzZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwiYWxlcnRzXCI6e30sXCJjYW52YXNlc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvY2FudmFzZXMvbGlzdFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbGlzdCBhbGwgYXZhaWxhYmxlIGNhbnZhc2VzXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgaWQgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwidmVyc2lvblwiOntcIm5hbWVcIjpcInZlcnNpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdmVyc2lvbiBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwibmFtZVwiOntcIm5hbWVcIjpcIm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbmFtZSBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkZXNjcmlwdGlvblwiOntcIm5hbWVcIjpcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInR5cGVcIjp7XCJuYW1lXCI6XCJ0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHR5cGUgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGF0ZXBpY2tlclwiOntcIm5hbWVcIjpcImRhdGVwaWNrZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGF0ZXBpY2tlciBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIn0sXCJ2aXN1YWxpemF0aW9uc1wiOntcIm5hbWVcIjpcInZpc3VhbGl6YXRpb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHZpc3VhbGl6YXRpb25zIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcImFycmF5XCJ9LFwiZGltZW5zaW9uc1wiOntcIm5hbWVcIjpcImRpbWVuc2lvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGltZW5zaW9ucyBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJhcnJheVwifSxcIm1ldHJpY3NcIjp7XCJuYW1lXCI6XCJtZXRyaWNzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG1ldHJpY3Mgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwiYXJyYXlcIn19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY2FudmFzZXM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNhbnZhc2VzOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvY2FudmFzZXMvZ2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyBjYW52YXMgYnkga2V5XCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImtleVwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBpZCBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJ2ZXJzaW9uXCI6e1wibmFtZVwiOlwidmVyc2lvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB2ZXJzaW9uIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJuYW1lXCI6e1wibmFtZVwiOlwibmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBuYW1lIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwidHlwZVwiOntcIm5hbWVcIjpcInR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdHlwZSBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkYXRlcGlja2VyXCI6e1wibmFtZVwiOlwiZGF0ZXBpY2tlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkYXRlcGlja2VyIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wifSxcInZpc3VhbGl6YXRpb25zXCI6e1wibmFtZVwiOlwidmlzdWFsaXphdGlvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdmlzdWFsaXphdGlvbnMgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwiYXJyYXlcIn0sXCJkaW1lbnNpb25zXCI6e1wibmFtZVwiOlwiZGltZW5zaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaW1lbnNpb25zIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcImFycmF5XCJ9LFwibWV0cmljc1wiOntcIm5hbWVcIjpcIm1ldHJpY3NcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbWV0cmljcyBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJhcnJheVwifX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjYW52YXNlczpnZXRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjYW52YXNlczpnZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJhZGRcIjp7XCJuYW1lXCI6XCIvY2FudmFzZXMvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgY2FudmFzXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNhbnZhc1wiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNhbnZhc2VzOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNhbnZhc2VzOmFkZFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInBhdGNoXCI6e1wibmFtZVwiOlwiL2NhbnZhc2VzL3BhdGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwYXRjaCBhbiBleGlzdGluZyBjYW52YXNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY2FudmFzXCIsXCJwYXlsb2FkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY2FudmFzZXM6cGF0Y2hcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjYW52YXNlczpwYXRjaFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImRlbGV0ZVwiOntcIm5hbWVcIjpcIi9jYW52YXNlcy9kZWxldGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGRlbGV0ZSBhbiBleGlzdGluZyBjYW52YXNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY2FudmFzXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY2FudmFzZXM6ZGVsZXRlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY2FudmFzZXM6ZGVsZXRlXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19fSxcInRlc3RcIjp7XCJ3aXRocGVybWlzc2lvblwiOntcIm5hbWVcIjpcIi90ZXN0L3dpdGhwZXJtaXNzaW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBtYWtlIHN1cmUgdGhhdCB0ZXN0cyBydW4gZmluZVwiLFwiaW5wdXRzXCI6W10sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJndWVzdFwiXX0sXCJub3Blcm1pc3Npb25cIjp7XCJuYW1lXCI6XCIvdGVzdC9ub3Blcm1pc3Npb25cIixcImRlc2NyaXB0aW9uXCI6XCJJIG1ha2Ugc3VyZSB0aGF0IHRlc3RzIHJ1biBmaW5lXCIsXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIm1hbmFnZV9zeXN0ZW1cIl19LFwiY3JlYXRldGVzdGVycm9yXCI6e1wibmFtZVwiOlwiL3Rlc3QvY3JlYXRldGVzdGVycm9yXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBtYWtlIHN1cmUgdGhhdCB0ZXN0cyBydW4gZmluZVwiLFwiaW5wdXRzXCI6W10sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXX19fSIsIi8vID09Q2xvc3VyZUNvbXBpbGVyPT1cbi8vIEBjb21waWxhdGlvbl9sZXZlbCBTSU1QTEVfT1BUSU1JWkFUSU9OU1xuXG4vKipcbiAqIEBsaWNlbnNlIEhpZ2hjaGFydHMgSlMgdjQuMC40ICgyMDE0LTA5LTAyKVxuICpcbiAqIChjKSAyMDA5LTIwMTQgVG9yc3RlaW4gSG9uc2lcbiAqXG4gKiBMaWNlbnNlOiB3d3cuaGlnaGNoYXJ0cy5jb20vbGljZW5zZVxuICovXG5cbi8vIEpTTGludCBvcHRpb25zOlxuLypnbG9iYWwgSGlnaGNoYXJ0cywgSGlnaGNoYXJ0c0FkYXB0ZXIsIGRvY3VtZW50LCB3aW5kb3csIG5hdmlnYXRvciwgc2V0SW50ZXJ2YWwsIGNsZWFySW50ZXJ2YWwsIGNsZWFyVGltZW91dCwgc2V0VGltZW91dCwgbG9jYXRpb24sIGpRdWVyeSwgJCwgY29uc29sZSwgZWFjaCwgZ3JlcCAqL1xuLypqc2xpbnQgYXNzOiB0cnVlLCBzbG9wcHk6IHRydWUsIGZvcmluOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSwgbm9tZW46IHRydWUsIHZhcnM6IHRydWUsIHJlZ2V4cDogdHJ1ZSwgbmV3Y2FwOiB0cnVlLCBicm93c2VyOiB0cnVlLCBjb250aW51ZTogdHJ1ZSwgd2hpdGU6IHRydWUgKi9cbihmdW5jdGlvbiAoKSB7XG4vLyBlbmNhcHN1bGF0ZWQgdmFyaWFibGVzXG52YXIgVU5ERUZJTkVELFxuXHRkb2MgPSBkb2N1bWVudCxcblx0d2luID0gd2luZG93LFxuXHRtYXRoID0gTWF0aCxcblx0bWF0aFJvdW5kID0gbWF0aC5yb3VuZCxcblx0bWF0aEZsb29yID0gbWF0aC5mbG9vcixcblx0bWF0aENlaWwgPSBtYXRoLmNlaWwsXG5cdG1hdGhNYXggPSBtYXRoLm1heCxcblx0bWF0aE1pbiA9IG1hdGgubWluLFxuXHRtYXRoQWJzID0gbWF0aC5hYnMsXG5cdG1hdGhDb3MgPSBtYXRoLmNvcyxcblx0bWF0aFNpbiA9IG1hdGguc2luLFxuXHRtYXRoUEkgPSBtYXRoLlBJLFxuXHRkZWcycmFkID0gbWF0aFBJICogMiAvIDM2MCxcblxuXG5cdC8vIHNvbWUgdmFyaWFibGVzXG5cdHVzZXJBZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQsXG5cdGlzT3BlcmEgPSB3aW4ub3BlcmEsXG5cdGlzSUUgPSAvbXNpZS9pLnRlc3QodXNlckFnZW50KSAmJiAhaXNPcGVyYSxcblx0ZG9jTW9kZTggPSBkb2MuZG9jdW1lbnRNb2RlID09PSA4LFxuXHRpc1dlYktpdCA9IC9BcHBsZVdlYktpdC8udGVzdCh1c2VyQWdlbnQpLFxuXHRpc0ZpcmVmb3ggPSAvRmlyZWZveC8udGVzdCh1c2VyQWdlbnQpLFxuXHRpc1RvdWNoRGV2aWNlID0gLyhNb2JpbGV8QW5kcm9pZHxXaW5kb3dzIFBob25lKS8udGVzdCh1c2VyQWdlbnQpLFxuXHRTVkdfTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuXHRoYXNTVkcgPSAhIWRvYy5jcmVhdGVFbGVtZW50TlMgJiYgISFkb2MuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgJ3N2ZycpLmNyZWF0ZVNWR1JlY3QsXG5cdGhhc0JpZGlCdWcgPSBpc0ZpcmVmb3ggJiYgcGFyc2VJbnQodXNlckFnZW50LnNwbGl0KCdGaXJlZm94LycpWzFdLCAxMCkgPCA0LCAvLyBpc3N1ZSAjMzhcblx0dXNlQ2FuVkcgPSAhaGFzU1ZHICYmICFpc0lFICYmICEhZG9jLmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpLmdldENvbnRleHQsXG5cdFJlbmRlcmVyLFxuXHRoYXNUb3VjaCxcblx0c3ltYm9sU2l6ZXMgPSB7fSxcblx0aWRDb3VudGVyID0gMCxcblx0Z2FyYmFnZUJpbixcblx0ZGVmYXVsdE9wdGlvbnMsXG5cdGRhdGVGb3JtYXQsIC8vIGZ1bmN0aW9uXG5cdGdsb2JhbEFuaW1hdGlvbixcblx0cGF0aEFuaW0sXG5cdHRpbWVVbml0cyxcblx0ZXJyb3IsXG5cdG5vb3AgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBVTkRFRklORUQ7IH0sXG5cdGNoYXJ0cyA9IFtdLFxuXHRjaGFydENvdW50ID0gMCxcblx0UFJPRFVDVCA9ICdIaWdoY2hhcnRzJyxcblx0VkVSU0lPTiA9ICc0LjAuNCcsXG5cblx0Ly8gc29tZSBjb25zdGFudHMgZm9yIGZyZXF1ZW50bHkgdXNlZCBzdHJpbmdzXG5cdERJViA9ICdkaXYnLFxuXHRBQlNPTFVURSA9ICdhYnNvbHV0ZScsXG5cdFJFTEFUSVZFID0gJ3JlbGF0aXZlJyxcblx0SElEREVOID0gJ2hpZGRlbicsXG5cdFBSRUZJWCA9ICdoaWdoY2hhcnRzLScsXG5cdFZJU0lCTEUgPSAndmlzaWJsZScsXG5cdFBYID0gJ3B4Jyxcblx0Tk9ORSA9ICdub25lJyxcblx0TSA9ICdNJyxcblx0TCA9ICdMJyxcblx0bnVtUmVnZXggPSAvXlswLTldKyQvLFxuXHROT1JNQUxfU1RBVEUgPSAnJyxcblx0SE9WRVJfU1RBVEUgPSAnaG92ZXInLFxuXHRTRUxFQ1RfU1RBVEUgPSAnc2VsZWN0Jyxcblx0XG5cdC8vIE9iamVjdCBmb3IgZXh0ZW5kaW5nIEF4aXNcblx0QXhpc1Bsb3RMaW5lT3JCYW5kRXh0ZW5zaW9uLFxuXG5cdC8vIGNvbnN0YW50cyBmb3IgYXR0cmlidXRlc1xuXHRTVFJPS0VfV0lEVEggPSAnc3Ryb2tlLXdpZHRoJyxcblxuXHQvLyB0aW1lIG1ldGhvZHMsIGNoYW5nZWQgYmFzZWQgb24gd2hldGhlciBvciBub3QgVVRDIGlzIHVzZWRcblx0RGF0ZSwgIC8vIEFsbG93IHVzaW5nIGEgZGlmZmVyZW50IERhdGUgY2xhc3Ncblx0bWFrZVRpbWUsXG5cdHRpbWV6b25lT2Zmc2V0LFxuXHRnZXRNaW51dGVzLFxuXHRnZXRIb3Vycyxcblx0Z2V0RGF5LFxuXHRnZXREYXRlLFxuXHRnZXRNb250aCxcblx0Z2V0RnVsbFllYXIsXG5cdHNldE1pbnV0ZXMsXG5cdHNldEhvdXJzLFxuXHRzZXREYXRlLFxuXHRzZXRNb250aCxcblx0c2V0RnVsbFllYXIsXG5cblxuXHQvLyBsb29rdXAgb3ZlciB0aGUgdHlwZXMgYW5kIHRoZSBhc3NvY2lhdGVkIGNsYXNzZXNcblx0c2VyaWVzVHlwZXMgPSB7fSxcblx0SGlnaGNoYXJ0cztcblxuLy8gVGhlIEhpZ2hjaGFydHMgbmFtZXNwYWNlXG5pZiAod2luLkhpZ2hjaGFydHMpIHtcblx0ZXJyb3IoMTYsIHRydWUpO1xufSBlbHNlIHtcblx0SGlnaGNoYXJ0cyA9IHdpbi5IaWdoY2hhcnRzID0ge307XG59XG4vKipcbiAqIEV4dGVuZCBhbiBvYmplY3Qgd2l0aCB0aGUgbWVtYmVycyBvZiBhbm90aGVyXG4gKiBAcGFyYW0ge09iamVjdH0gYSBUaGUgb2JqZWN0IHRvIGJlIGV4dGVuZGVkXG4gKiBAcGFyYW0ge09iamVjdH0gYiBUaGUgb2JqZWN0IHRvIGFkZCB0byB0aGUgZmlyc3Qgb25lXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZChhLCBiKSB7XG5cdHZhciBuO1xuXHRpZiAoIWEpIHtcblx0XHRhID0ge307XG5cdH1cblx0Zm9yIChuIGluIGIpIHtcblx0XHRhW25dID0gYltuXTtcblx0fVxuXHRyZXR1cm4gYTtcbn1cblx0XG4vKipcbiAqIERlZXAgbWVyZ2UgdHdvIG9yIG1vcmUgb2JqZWN0cyBhbmQgcmV0dXJuIGEgdGhpcmQgb2JqZWN0LiBJZiB0aGUgZmlyc3QgYXJndW1lbnQgaXNcbiAqIHRydWUsIHRoZSBjb250ZW50cyBvZiB0aGUgc2Vjb25kIG9iamVjdCBpcyBjb3BpZWQgaW50byB0aGUgZmlyc3Qgb2JqZWN0LlxuICogUHJldmlvdXNseSB0aGlzIGZ1bmN0aW9uIHJlZGlyZWN0ZWQgdG8galF1ZXJ5LmV4dGVuZCh0cnVlKSwgYnV0IHRoaXMgaGFkIHR3byBsaW1pdGF0aW9ucy5cbiAqIEZpcnN0LCBpdCBkZWVwIG1lcmdlZCBhcnJheXMsIHdoaWNoIGxlYWQgdG8gd29ya2Fyb3VuZHMgaW4gSGlnaGNoYXJ0cy4gU2Vjb25kLFxuICogaXQgY29waWVkIHByb3BlcnRpZXMgZnJvbSBleHRlbmRlZCBwcm90b3R5cGVzLiBcbiAqL1xuZnVuY3Rpb24gbWVyZ2UoKSB7XG5cdHZhciBpLFxuXHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0bGVuLFxuXHRcdHJldCA9IHt9LFxuXHRcdGRvQ29weSA9IGZ1bmN0aW9uIChjb3B5LCBvcmlnaW5hbCkge1xuXHRcdFx0dmFyIHZhbHVlLCBrZXk7XG5cblx0XHRcdC8vIEFuIG9iamVjdCBpcyByZXBsYWNpbmcgYSBwcmltaXRpdmVcblx0XHRcdGlmICh0eXBlb2YgY29weSAhPT0gJ29iamVjdCcpIHtcblx0XHRcdFx0Y29weSA9IHt9O1xuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKGtleSBpbiBvcmlnaW5hbCkge1xuXHRcdFx0XHRpZiAob3JpZ2luYWwuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHRcdFx0XHRcdHZhbHVlID0gb3JpZ2luYWxba2V5XTtcblxuXHRcdFx0XHRcdC8vIENvcHkgdGhlIGNvbnRlbnRzIG9mIG9iamVjdHMsIGJ1dCBub3QgYXJyYXlzIG9yIERPTSBub2Rlc1xuXHRcdFx0XHRcdGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgIT09ICdbb2JqZWN0IEFycmF5XSdcblx0XHRcdFx0XHRcdFx0JiYga2V5ICE9PSAncmVuZGVyVG8nICYmIHR5cGVvZiB2YWx1ZS5ub2RlVHlwZSAhPT0gJ251bWJlcicpIHtcblx0XHRcdFx0XHRcdGNvcHlba2V5XSA9IGRvQ29weShjb3B5W2tleV0gfHwge30sIHZhbHVlKTtcblx0XHRcdFx0XG5cdFx0XHRcdFx0Ly8gUHJpbWl0aXZlcyBhbmQgYXJyYXlzIGFyZSBjb3BpZWQgb3ZlciBkaXJlY3RseVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRjb3B5W2tleV0gPSBvcmlnaW5hbFtrZXldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGNvcHk7XG5cdFx0fTtcblxuXHQvLyBJZiBmaXJzdCBhcmd1bWVudCBpcyB0cnVlLCBjb3B5IGludG8gdGhlIGV4aXN0aW5nIG9iamVjdC4gVXNlZCBpbiBzZXRPcHRpb25zLlxuXHRpZiAoYXJnc1swXSA9PT0gdHJ1ZSkge1xuXHRcdHJldCA9IGFyZ3NbMV07XG5cdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MsIDIpO1xuXHR9XG5cblx0Ly8gRm9yIGVhY2ggYXJndW1lbnQsIGV4dGVuZCB0aGUgcmV0dXJuXG5cdGxlbiA9IGFyZ3MubGVuZ3RoO1xuXHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRyZXQgPSBkb0NvcHkocmV0LCBhcmdzW2ldKTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59XG5cbi8qKlxuICogU2hvcnRjdXQgZm9yIHBhcnNlSW50XG4gKiBAcGFyYW0ge09iamVjdH0gc1xuICogQHBhcmFtIHtOdW1iZXJ9IG1hZyBNYWduaXR1ZGVcbiAqL1xuZnVuY3Rpb24gcEludChzLCBtYWcpIHtcblx0cmV0dXJuIHBhcnNlSW50KHMsIG1hZyB8fCAxMCk7XG59XG5cbi8qKlxuICogQ2hlY2sgZm9yIHN0cmluZ1xuICogQHBhcmFtIHtPYmplY3R9IHNcbiAqL1xuZnVuY3Rpb24gaXNTdHJpbmcocykge1xuXHRyZXR1cm4gdHlwZW9mIHMgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIENoZWNrIGZvciBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3Qob2JqKSB7XG5cdHJldHVybiBvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogQ2hlY2sgZm9yIGFycmF5XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG5cdHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cblxuLyoqXG4gKiBDaGVjayBmb3IgbnVtYmVyXG4gKiBAcGFyYW0ge09iamVjdH0gblxuICovXG5mdW5jdGlvbiBpc051bWJlcihuKSB7XG5cdHJldHVybiB0eXBlb2YgbiA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIGxvZzJsaW4obnVtKSB7XG5cdHJldHVybiBtYXRoLmxvZyhudW0pIC8gbWF0aC5MTjEwO1xufVxuZnVuY3Rpb24gbGluMmxvZyhudW0pIHtcblx0cmV0dXJuIG1hdGgucG93KDEwLCBudW0pO1xufVxuXG4vKipcbiAqIFJlbW92ZSBsYXN0IG9jY3VyZW5jZSBvZiBhbiBpdGVtIGZyb20gYW4gYXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFyclxuICogQHBhcmFtIHtNaXhlZH0gaXRlbVxuICovXG5mdW5jdGlvbiBlcmFzZShhcnIsIGl0ZW0pIHtcblx0dmFyIGkgPSBhcnIubGVuZ3RoO1xuXHR3aGlsZSAoaS0tKSB7XG5cdFx0aWYgKGFycltpXSA9PT0gaXRlbSkge1xuXHRcdFx0YXJyLnNwbGljZShpLCAxKTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXHQvL3JldHVybiBhcnI7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBvYmplY3QgaXMgbm90IG51bGwgb3IgdW5kZWZpbmVkLiBMaWtlIE1vb1Rvb2xzJyAkLmRlZmluZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKi9cbmZ1bmN0aW9uIGRlZmluZWQob2JqKSB7XG5cdHJldHVybiBvYmogIT09IFVOREVGSU5FRCAmJiBvYmogIT09IG51bGw7XG59XG5cbi8qKlxuICogU2V0IG9yIGdldCBhbiBhdHRyaWJ1dGUgb3IgYW4gb2JqZWN0IG9mIGF0dHJpYnV0ZXMuIENhbid0IHVzZSBqUXVlcnkgYXR0ciBiZWNhdXNlXG4gKiBpdCBhdHRlbXB0cyB0byBzZXQgZXhwYW5kbyBwcm9wZXJ0aWVzIG9uIHRoZSBTVkcgZWxlbWVudCwgd2hpY2ggaXMgbm90IGFsbG93ZWQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGVsZW0gVGhlIERPTSBlbGVtZW50IHRvIHJlY2VpdmUgdGhlIGF0dHJpYnV0ZShzKVxuICogQHBhcmFtIHtTdHJpbmd8T2JqZWN0fSBwcm9wIFRoZSBwcm9wZXJ0eSBvciBhbiBhYmplY3Qgb2Yga2V5LXZhbHVlIHBhaXJzXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVGhlIHZhbHVlIGlmIGEgc2luZ2xlIHByb3BlcnR5IGlzIHNldFxuICovXG5mdW5jdGlvbiBhdHRyKGVsZW0sIHByb3AsIHZhbHVlKSB7XG5cdHZhciBrZXksXG5cdFx0cmV0O1xuXG5cdC8vIGlmIHRoZSBwcm9wIGlzIGEgc3RyaW5nXG5cdGlmIChpc1N0cmluZyhwcm9wKSkge1xuXHRcdC8vIHNldCB0aGUgdmFsdWVcblx0XHRpZiAoZGVmaW5lZCh2YWx1ZSkpIHtcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKHByb3AsIHZhbHVlKTtcblxuXHRcdC8vIGdldCB0aGUgdmFsdWVcblx0XHR9IGVsc2UgaWYgKGVsZW0gJiYgZWxlbS5nZXRBdHRyaWJ1dGUpIHsgLy8gZWxlbSBub3QgZGVmaW5lZCB3aGVuIHByaW50aW5nIHBpZSBkZW1vLi4uXG5cdFx0XHRyZXQgPSBlbGVtLmdldEF0dHJpYnV0ZShwcm9wKTtcblx0XHR9XG5cblx0Ly8gZWxzZSBpZiBwcm9wIGlzIGRlZmluZWQsIGl0IGlzIGEgaGFzaCBvZiBrZXkvdmFsdWUgcGFpcnNcblx0fSBlbHNlIGlmIChkZWZpbmVkKHByb3ApICYmIGlzT2JqZWN0KHByb3ApKSB7XG5cdFx0Zm9yIChrZXkgaW4gcHJvcCkge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoa2V5LCBwcm9wW2tleV0pO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gcmV0O1xufVxuLyoqXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IGlzIGFuIGFycmF5LCBhbmQgaWYgbm90LCBtYWtlIGl0IGludG8gYW4gYXJyYXkuIExpa2VcbiAqIE1vb1Rvb2xzJyAkLnNwbGF0LlxuICovXG5mdW5jdGlvbiBzcGxhdChvYmopIHtcblx0cmV0dXJuIGlzQXJyYXkob2JqKSA/IG9iaiA6IFtvYmpdO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB0aGF0IGlzIGRlZmluZWQuIExpa2UgTW9vVG9vbHMnICQucGljay5cbiAqL1xuZnVuY3Rpb24gcGljaygpIHtcblx0dmFyIGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0aSxcblx0XHRhcmcsXG5cdFx0bGVuZ3RoID0gYXJncy5sZW5ndGg7XG5cdGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuXHRcdGFyZyA9IGFyZ3NbaV07XG5cdFx0aWYgKGFyZyAhPT0gVU5ERUZJTkVEICYmIGFyZyAhPT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIGFyZztcblx0XHR9XG5cdH1cbn1cblxuLyoqXG4gKiBTZXQgQ1NTIG9uIGEgZ2l2ZW4gZWxlbWVudFxuICogQHBhcmFtIHtPYmplY3R9IGVsXG4gKiBAcGFyYW0ge09iamVjdH0gc3R5bGVzIFN0eWxlIG9iamVjdCB3aXRoIGNhbWVsIGNhc2UgcHJvcGVydHkgbmFtZXNcbiAqL1xuZnVuY3Rpb24gY3NzKGVsLCBzdHlsZXMpIHtcblx0aWYgKGlzSUUgJiYgIWhhc1NWRykgeyAvLyAjMjY4NlxuXHRcdGlmIChzdHlsZXMgJiYgc3R5bGVzLm9wYWNpdHkgIT09IFVOREVGSU5FRCkge1xuXHRcdFx0c3R5bGVzLmZpbHRlciA9ICdhbHBoYShvcGFjaXR5PScgKyAoc3R5bGVzLm9wYWNpdHkgKiAxMDApICsgJyknO1xuXHRcdH1cblx0fVxuXHRleHRlbmQoZWwuc3R5bGUsIHN0eWxlcyk7XG59XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiB0byBjcmVhdGUgZWxlbWVudCB3aXRoIGF0dHJpYnV0ZXMgYW5kIHN0eWxlc1xuICogQHBhcmFtIHtPYmplY3R9IHRhZ1xuICogQHBhcmFtIHtPYmplY3R9IGF0dHJpYnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdHlsZXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBub3BhZFxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHRhZywgYXR0cmlicywgc3R5bGVzLCBwYXJlbnQsIG5vcGFkKSB7XG5cdHZhciBlbCA9IGRvYy5jcmVhdGVFbGVtZW50KHRhZyk7XG5cdGlmIChhdHRyaWJzKSB7XG5cdFx0ZXh0ZW5kKGVsLCBhdHRyaWJzKTtcblx0fVxuXHRpZiAobm9wYWQpIHtcblx0XHRjc3MoZWwsIHtwYWRkaW5nOiAwLCBib3JkZXI6IE5PTkUsIG1hcmdpbjogMH0pO1xuXHR9XG5cdGlmIChzdHlsZXMpIHtcblx0XHRjc3MoZWwsIHN0eWxlcyk7XG5cdH1cblx0aWYgKHBhcmVudCkge1xuXHRcdHBhcmVudC5hcHBlbmRDaGlsZChlbCk7XG5cdH1cblx0cmV0dXJuIGVsO1xufVxuXG4vKipcbiAqIEV4dGVuZCBhIHByb3RvdHlwZWQgY2xhc3MgYnkgbmV3IG1lbWJlcnNcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBtZW1iZXJzXG4gKi9cbmZ1bmN0aW9uIGV4dGVuZENsYXNzKHBhcmVudCwgbWVtYmVycykge1xuXHR2YXIgb2JqZWN0ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gVU5ERUZJTkVEOyB9O1xuXHRvYmplY3QucHJvdG90eXBlID0gbmV3IHBhcmVudCgpO1xuXHRleHRlbmQob2JqZWN0LnByb3RvdHlwZSwgbWVtYmVycyk7XG5cdHJldHVybiBvYmplY3Q7XG59XG5cbi8qKlxuICogRm9ybWF0IGEgbnVtYmVyIGFuZCByZXR1cm4gYSBzdHJpbmcgYmFzZWQgb24gaW5wdXQgc2V0dGluZ3NcbiAqIEBwYXJhbSB7TnVtYmVyfSBudW1iZXIgVGhlIGlucHV0IG51bWJlciB0byBmb3JtYXRcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWNpbWFscyBUaGUgYW1vdW50IG9mIGRlY2ltYWxzXG4gKiBAcGFyYW0ge1N0cmluZ30gZGVjUG9pbnQgVGhlIGRlY2ltYWwgcG9pbnQsIGRlZmF1bHRzIHRvIHRoZSBvbmUgZ2l2ZW4gaW4gdGhlIGxhbmcgb3B0aW9uc1xuICogQHBhcmFtIHtTdHJpbmd9IHRob3VzYW5kc1NlcCBUaGUgdGhvdXNhbmRzIHNlcGFyYXRvciwgZGVmYXVsdHMgdG8gdGhlIG9uZSBnaXZlbiBpbiB0aGUgbGFuZyBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIG51bWJlckZvcm1hdChudW1iZXIsIGRlY2ltYWxzLCBkZWNQb2ludCwgdGhvdXNhbmRzU2VwKSB7XG5cdHZhciBleHRlcm5hbEZuID0gSGlnaGNoYXJ0cy5udW1iZXJGb3JtYXQsXG5cdFx0bGFuZyA9IGRlZmF1bHRPcHRpb25zLmxhbmcsXG5cdFx0Ly8gaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQvdGVjaGJsb2cvYXJ0aWNsZS9qYXZhc2NyaXB0X2VxdWl2YWxlbnRfZm9yX3BocHNfbnVtYmVyX2Zvcm1hdC9cblx0XHRuID0gK251bWJlciB8fCAwLFxuXHRcdGMgPSBkZWNpbWFscyA9PT0gLTEgP1xuXHRcdFx0KG4udG9TdHJpbmcoKS5zcGxpdCgnLicpWzFdIHx8ICcnKS5sZW5ndGggOiAvLyBwcmVzZXJ2ZSBkZWNpbWFsc1xuXHRcdFx0KGlzTmFOKGRlY2ltYWxzID0gbWF0aEFicyhkZWNpbWFscykpID8gMiA6IGRlY2ltYWxzKSxcblx0XHRkID0gZGVjUG9pbnQgPT09IHVuZGVmaW5lZCA/IGxhbmcuZGVjaW1hbFBvaW50IDogZGVjUG9pbnQsXG5cdFx0dCA9IHRob3VzYW5kc1NlcCA9PT0gdW5kZWZpbmVkID8gbGFuZy50aG91c2FuZHNTZXAgOiB0aG91c2FuZHNTZXAsXG5cdFx0cyA9IG4gPCAwID8gXCItXCIgOiBcIlwiLFxuXHRcdGkgPSBTdHJpbmcocEludChuID0gbWF0aEFicyhuKS50b0ZpeGVkKGMpKSksXG5cdFx0aiA9IGkubGVuZ3RoID4gMyA/IGkubGVuZ3RoICUgMyA6IDA7XG5cblx0cmV0dXJuIGV4dGVybmFsRm4gIT09IG51bWJlckZvcm1hdCA/IFxuXHRcdGV4dGVybmFsRm4obnVtYmVyLCBkZWNpbWFscywgZGVjUG9pbnQsIHRob3VzYW5kc1NlcCkgOlxuXHRcdChzICsgKGogPyBpLnN1YnN0cigwLCBqKSArIHQgOiBcIlwiKSArIGkuc3Vic3RyKGopLnJlcGxhY2UoLyhcXGR7M30pKD89XFxkKS9nLCBcIiQxXCIgKyB0KSArXG5cdFx0XHQoYyA/IGQgKyBtYXRoQWJzKG4gLSBpKS50b0ZpeGVkKGMpLnNsaWNlKDIpIDogXCJcIikpO1xufVxuXG4vKipcbiAqIFBhZCBhIHN0cmluZyB0byBhIGdpdmVuIGxlbmd0aCBieSBhZGRpbmcgMCB0byB0aGUgYmVnaW5uaW5nXG4gKiBAcGFyYW0ge051bWJlcn0gbnVtYmVyXG4gKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoXG4gKi9cbmZ1bmN0aW9uIHBhZChudW1iZXIsIGxlbmd0aCkge1xuXHQvLyBDcmVhdGUgYW4gYXJyYXkgb2YgdGhlIHJlbWFpbmluZyBsZW5ndGggKzEgYW5kIGpvaW4gaXQgd2l0aCAwJ3Ncblx0cmV0dXJuIG5ldyBBcnJheSgobGVuZ3RoIHx8IDIpICsgMSAtIFN0cmluZyhudW1iZXIpLmxlbmd0aCkuam9pbigwKSArIG51bWJlcjtcbn1cblxuLyoqXG4gKiBXcmFwIGEgbWV0aG9kIHdpdGggZXh0ZW5kZWQgZnVuY3Rpb25hbGl0eSwgcHJlc2VydmluZyB0aGUgb3JpZ2luYWwgZnVuY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIGNvbnRleHQgb2JqZWN0IHRoYXQgdGhlIG1ldGhvZCBiZWxvbmdzIHRvIFxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZCBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGV4dGVuZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBBIHdyYXBwZXIgZnVuY3Rpb24gY2FsbGJhY2suIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggdGhlIHNhbWUgYXJndW1lbnRzXG4gKiBhcyB0aGUgb3JpZ2luYWwgZnVuY3Rpb24sIGV4Y2VwdCB0aGF0IHRoZSBvcmlnaW5hbCBmdW5jdGlvbiBpcyB1bnNoaWZ0ZWQgYW5kIHBhc3NlZCBhcyB0aGUgZmlyc3QgXG4gKiBhcmd1bWVudC4gXG4gKi9cbmZ1bmN0aW9uIHdyYXAob2JqLCBtZXRob2QsIGZ1bmMpIHtcblx0dmFyIHByb2NlZWQgPSBvYmpbbWV0aG9kXTtcblx0b2JqW21ldGhvZF0gPSBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHRcdGFyZ3MudW5zaGlmdChwcm9jZWVkKTtcblx0XHRyZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcblx0fTtcbn1cblxuLyoqXG4gKiBCYXNlZCBvbiBodHRwOi8vd3d3LnBocC5uZXQvbWFudWFsL2VuL2Z1bmN0aW9uLnN0cmZ0aW1lLnBocFxuICogQHBhcmFtIHtTdHJpbmd9IGZvcm1hdFxuICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVzdGFtcFxuICogQHBhcmFtIHtCb29sZWFufSBjYXBpdGFsaXplXG4gKi9cbmRhdGVGb3JtYXQgPSBmdW5jdGlvbiAoZm9ybWF0LCB0aW1lc3RhbXAsIGNhcGl0YWxpemUpIHtcblx0aWYgKCFkZWZpbmVkKHRpbWVzdGFtcCkgfHwgaXNOYU4odGltZXN0YW1wKSkge1xuXHRcdHJldHVybiAnSW52YWxpZCBkYXRlJztcblx0fVxuXHRmb3JtYXQgPSBwaWNrKGZvcm1hdCwgJyVZLSVtLSVkICVIOiVNOiVTJyk7XG5cblx0dmFyIGRhdGUgPSBuZXcgRGF0ZSh0aW1lc3RhbXAgLSB0aW1lem9uZU9mZnNldCksXG5cdFx0a2V5LCAvLyB1c2VkIGluIGZvciBjb25zdHVjdCBiZWxvd1xuXHRcdC8vIGdldCB0aGUgYmFzaWMgdGltZSB2YWx1ZXNcblx0XHRob3VycyA9IGRhdGVbZ2V0SG91cnNdKCksXG5cdFx0ZGF5ID0gZGF0ZVtnZXREYXldKCksXG5cdFx0ZGF5T2ZNb250aCA9IGRhdGVbZ2V0RGF0ZV0oKSxcblx0XHRtb250aCA9IGRhdGVbZ2V0TW9udGhdKCksXG5cdFx0ZnVsbFllYXIgPSBkYXRlW2dldEZ1bGxZZWFyXSgpLFxuXHRcdGxhbmcgPSBkZWZhdWx0T3B0aW9ucy5sYW5nLFxuXHRcdGxhbmdXZWVrZGF5cyA9IGxhbmcud2Vla2RheXMsXG5cblx0XHQvLyBMaXN0IGFsbCBmb3JtYXQga2V5cy4gQ3VzdG9tIGZvcm1hdHMgY2FuIGJlIGFkZGVkIGZyb20gdGhlIG91dHNpZGUuIFxuXHRcdHJlcGxhY2VtZW50cyA9IGV4dGVuZCh7XG5cblx0XHRcdC8vIERheVxuXHRcdFx0J2EnOiBsYW5nV2Vla2RheXNbZGF5XS5zdWJzdHIoMCwgMyksIC8vIFNob3J0IHdlZWtkYXksIGxpa2UgJ01vbidcblx0XHRcdCdBJzogbGFuZ1dlZWtkYXlzW2RheV0sIC8vIExvbmcgd2Vla2RheSwgbGlrZSAnTW9uZGF5J1xuXHRcdFx0J2QnOiBwYWQoZGF5T2ZNb250aCksIC8vIFR3byBkaWdpdCBkYXkgb2YgdGhlIG1vbnRoLCAwMSB0byAzMVxuXHRcdFx0J2UnOiBkYXlPZk1vbnRoLCAvLyBEYXkgb2YgdGhlIG1vbnRoLCAxIHRocm91Z2ggMzFcblxuXHRcdFx0Ly8gV2VlayAobm9uZSBpbXBsZW1lbnRlZClcblx0XHRcdC8vJ1cnOiB3ZWVrTnVtYmVyKCksXG5cblx0XHRcdC8vIE1vbnRoXG5cdFx0XHQnYic6IGxhbmcuc2hvcnRNb250aHNbbW9udGhdLCAvLyBTaG9ydCBtb250aCwgbGlrZSAnSmFuJ1xuXHRcdFx0J0InOiBsYW5nLm1vbnRoc1ttb250aF0sIC8vIExvbmcgbW9udGgsIGxpa2UgJ0phbnVhcnknXG5cdFx0XHQnbSc6IHBhZChtb250aCArIDEpLCAvLyBUd28gZGlnaXQgbW9udGggbnVtYmVyLCAwMSB0aHJvdWdoIDEyXG5cblx0XHRcdC8vIFllYXJcblx0XHRcdCd5JzogZnVsbFllYXIudG9TdHJpbmcoKS5zdWJzdHIoMiwgMiksIC8vIFR3byBkaWdpdHMgeWVhciwgbGlrZSAwOSBmb3IgMjAwOVxuXHRcdFx0J1knOiBmdWxsWWVhciwgLy8gRm91ciBkaWdpdHMgeWVhciwgbGlrZSAyMDA5XG5cblx0XHRcdC8vIFRpbWVcblx0XHRcdCdIJzogcGFkKGhvdXJzKSwgLy8gVHdvIGRpZ2l0cyBob3VycyBpbiAyNGggZm9ybWF0LCAwMCB0aHJvdWdoIDIzXG5cdFx0XHQnSSc6IHBhZCgoaG91cnMgJSAxMikgfHwgMTIpLCAvLyBUd28gZGlnaXRzIGhvdXJzIGluIDEyaCBmb3JtYXQsIDAwIHRocm91Z2ggMTFcblx0XHRcdCdsJzogKGhvdXJzICUgMTIpIHx8IDEyLCAvLyBIb3VycyBpbiAxMmggZm9ybWF0LCAxIHRocm91Z2ggMTJcblx0XHRcdCdNJzogcGFkKGRhdGVbZ2V0TWludXRlc10oKSksIC8vIFR3byBkaWdpdHMgbWludXRlcywgMDAgdGhyb3VnaCA1OVxuXHRcdFx0J3AnOiBob3VycyA8IDEyID8gJ0FNJyA6ICdQTScsIC8vIFVwcGVyIGNhc2UgQU0gb3IgUE1cblx0XHRcdCdQJzogaG91cnMgPCAxMiA/ICdhbScgOiAncG0nLCAvLyBMb3dlciBjYXNlIEFNIG9yIFBNXG5cdFx0XHQnUyc6IHBhZChkYXRlLmdldFNlY29uZHMoKSksIC8vIFR3byBkaWdpdHMgc2Vjb25kcywgMDAgdGhyb3VnaCAgNTlcblx0XHRcdCdMJzogcGFkKG1hdGhSb3VuZCh0aW1lc3RhbXAgJSAxMDAwKSwgMykgLy8gTWlsbGlzZWNvbmRzIChuYW1pbmcgZnJvbSBSdWJ5KVxuXHRcdH0sIEhpZ2hjaGFydHMuZGF0ZUZvcm1hdHMpO1xuXG5cblx0Ly8gZG8gdGhlIHJlcGxhY2VzXG5cdGZvciAoa2V5IGluIHJlcGxhY2VtZW50cykge1xuXHRcdHdoaWxlIChmb3JtYXQuaW5kZXhPZignJScgKyBrZXkpICE9PSAtMSkgeyAvLyByZWdleCB3b3VsZCBkbyBpdCBpbiBvbmUgbGluZSwgYnV0IHRoaXMgaXMgZmFzdGVyXG5cdFx0XHRmb3JtYXQgPSBmb3JtYXQucmVwbGFjZSgnJScgKyBrZXksIHR5cGVvZiByZXBsYWNlbWVudHNba2V5XSA9PT0gJ2Z1bmN0aW9uJyA/IHJlcGxhY2VtZW50c1trZXldKHRpbWVzdGFtcCkgOiByZXBsYWNlbWVudHNba2V5XSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gT3B0aW9uYWxseSBjYXBpdGFsaXplIHRoZSBzdHJpbmcgYW5kIHJldHVyblxuXHRyZXR1cm4gY2FwaXRhbGl6ZSA/IGZvcm1hdC5zdWJzdHIoMCwgMSkudG9VcHBlckNhc2UoKSArIGZvcm1hdC5zdWJzdHIoMSkgOiBmb3JtYXQ7XG59O1xuXG4vKiogXG4gKiBGb3JtYXQgYSBzaW5nbGUgdmFyaWFibGUuIFNpbWlsYXIgdG8gc3ByaW50Ziwgd2l0aG91dCB0aGUgJSBwcmVmaXguXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdFNpbmdsZShmb3JtYXQsIHZhbCkge1xuXHR2YXIgZmxvYXRSZWdleCA9IC9mJC8sXG5cdFx0ZGVjUmVnZXggPSAvXFwuKFswLTldKS8sXG5cdFx0bGFuZyA9IGRlZmF1bHRPcHRpb25zLmxhbmcsXG5cdFx0ZGVjaW1hbHM7XG5cblx0aWYgKGZsb2F0UmVnZXgudGVzdChmb3JtYXQpKSB7IC8vIGZsb2F0XG5cdFx0ZGVjaW1hbHMgPSBmb3JtYXQubWF0Y2goZGVjUmVnZXgpO1xuXHRcdGRlY2ltYWxzID0gZGVjaW1hbHMgPyBkZWNpbWFsc1sxXSA6IC0xO1xuXHRcdGlmICh2YWwgIT09IG51bGwpIHtcblx0XHRcdHZhbCA9IG51bWJlckZvcm1hdChcblx0XHRcdFx0dmFsLFxuXHRcdFx0XHRkZWNpbWFscyxcblx0XHRcdFx0bGFuZy5kZWNpbWFsUG9pbnQsXG5cdFx0XHRcdGZvcm1hdC5pbmRleE9mKCcsJykgPiAtMSA/IGxhbmcudGhvdXNhbmRzU2VwIDogJydcblx0XHRcdCk7XG5cdFx0fVxuXHR9IGVsc2Uge1xuXHRcdHZhbCA9IGRhdGVGb3JtYXQoZm9ybWF0LCB2YWwpO1xuXHR9XG5cdHJldHVybiB2YWw7XG59XG5cbi8qKlxuICogRm9ybWF0IGEgc3RyaW5nIGFjY29yZGluZyB0byBhIHN1YnNldCBvZiB0aGUgcnVsZXMgb2YgUHl0aG9uJ3MgU3RyaW5nLmZvcm1hdCBtZXRob2QuXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdChzdHIsIGN0eCkge1xuXHR2YXIgc3BsaXR0ZXIgPSAneycsXG5cdFx0aXNJbnNpZGUgPSBmYWxzZSxcblx0XHRzZWdtZW50LFxuXHRcdHZhbHVlQW5kRm9ybWF0LFxuXHRcdHBhdGgsXG5cdFx0aSxcblx0XHRsZW4sXG5cdFx0cmV0ID0gW10sXG5cdFx0dmFsLFxuXHRcdGluZGV4O1xuXHRcblx0d2hpbGUgKChpbmRleCA9IHN0ci5pbmRleE9mKHNwbGl0dGVyKSkgIT09IC0xKSB7XG5cdFx0XG5cdFx0c2VnbWVudCA9IHN0ci5zbGljZSgwLCBpbmRleCk7XG5cdFx0aWYgKGlzSW5zaWRlKSB7IC8vIHdlJ3JlIG9uIHRoZSBjbG9zaW5nIGJyYWNrZXQgbG9va2luZyBiYWNrXG5cdFx0XHRcblx0XHRcdHZhbHVlQW5kRm9ybWF0ID0gc2VnbWVudC5zcGxpdCgnOicpO1xuXHRcdFx0cGF0aCA9IHZhbHVlQW5kRm9ybWF0LnNoaWZ0KCkuc3BsaXQoJy4nKTsgLy8gZ2V0IGZpcnN0IGFuZCBsZWF2ZSBmb3JtYXRcblx0XHRcdGxlbiA9IHBhdGgubGVuZ3RoO1xuXHRcdFx0dmFsID0gY3R4O1xuXG5cdFx0XHQvLyBBc3NpZ24gZGVlcGVyIHBhdGhzXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdFx0dmFsID0gdmFsW3BhdGhbaV1dO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3JtYXQgdGhlIHJlcGxhY2VtZW50XG5cdFx0XHRpZiAodmFsdWVBbmRGb3JtYXQubGVuZ3RoKSB7XG5cdFx0XHRcdHZhbCA9IGZvcm1hdFNpbmdsZSh2YWx1ZUFuZEZvcm1hdC5qb2luKCc6JyksIHZhbCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFB1c2ggdGhlIHJlc3VsdCBhbmQgYWR2YW5jZSB0aGUgY3Vyc29yXG5cdFx0XHRyZXQucHVzaCh2YWwpO1xuXHRcdFx0XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldC5wdXNoKHNlZ21lbnQpO1xuXHRcdFx0XG5cdFx0fVxuXHRcdHN0ciA9IHN0ci5zbGljZShpbmRleCArIDEpOyAvLyB0aGUgcmVzdFxuXHRcdGlzSW5zaWRlID0gIWlzSW5zaWRlOyAvLyB0b2dnbGVcblx0XHRzcGxpdHRlciA9IGlzSW5zaWRlID8gJ30nIDogJ3snOyAvLyBub3cgbG9vayBmb3IgbmV4dCBtYXRjaGluZyBicmFja2V0XG5cdH1cblx0cmV0LnB1c2goc3RyKTtcblx0cmV0dXJuIHJldC5qb2luKCcnKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIG1hZ25pdHVkZSBvZiBhIG51bWJlclxuICovXG5mdW5jdGlvbiBnZXRNYWduaXR1ZGUobnVtKSB7XG5cdHJldHVybiBtYXRoLnBvdygxMCwgbWF0aEZsb29yKG1hdGgubG9nKG51bSkgLyBtYXRoLkxOMTApKTtcbn1cblxuLyoqXG4gKiBUYWtlIGFuIGludGVydmFsIGFuZCBub3JtYWxpemUgaXQgdG8gbXVsdGlwbGVzIG9mIDEsIDIsIDIuNSBhbmQgNVxuICogQHBhcmFtIHtOdW1iZXJ9IGludGVydmFsXG4gKiBAcGFyYW0ge0FycmF5fSBtdWx0aXBsZXNcbiAqIEBwYXJhbSB7TnVtYmVyfSBtYWduaXR1ZGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVRpY2tJbnRlcnZhbChpbnRlcnZhbCwgbXVsdGlwbGVzLCBtYWduaXR1ZGUsIGFsbG93RGVjaW1hbHMpIHtcblx0dmFyIG5vcm1hbGl6ZWQsIGk7XG5cblx0Ly8gcm91bmQgdG8gYSB0ZW5mb2xkIG9mIDEsIDIsIDIuNSBvciA1XG5cdG1hZ25pdHVkZSA9IHBpY2sobWFnbml0dWRlLCAxKTtcblx0bm9ybWFsaXplZCA9IGludGVydmFsIC8gbWFnbml0dWRlO1xuXG5cdC8vIG11bHRpcGxlcyBmb3IgYSBsaW5lYXIgc2NhbGVcblx0aWYgKCFtdWx0aXBsZXMpIHtcblx0XHRtdWx0aXBsZXMgPSBbMSwgMiwgMi41LCA1LCAxMF07XG5cblx0XHQvLyB0aGUgYWxsb3dEZWNpbWFscyBvcHRpb25cblx0XHRpZiAoYWxsb3dEZWNpbWFscyA9PT0gZmFsc2UpIHtcblx0XHRcdGlmIChtYWduaXR1ZGUgPT09IDEpIHtcblx0XHRcdFx0bXVsdGlwbGVzID0gWzEsIDIsIDUsIDEwXTtcblx0XHRcdH0gZWxzZSBpZiAobWFnbml0dWRlIDw9IDAuMSkge1xuXHRcdFx0XHRtdWx0aXBsZXMgPSBbMSAvIG1hZ25pdHVkZV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gbm9ybWFsaXplIHRoZSBpbnRlcnZhbCB0byB0aGUgbmVhcmVzdCBtdWx0aXBsZVxuXHRmb3IgKGkgPSAwOyBpIDwgbXVsdGlwbGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0aW50ZXJ2YWwgPSBtdWx0aXBsZXNbaV07XG5cdFx0aWYgKG5vcm1hbGl6ZWQgPD0gKG11bHRpcGxlc1tpXSArIChtdWx0aXBsZXNbaSArIDFdIHx8IG11bHRpcGxlc1tpXSkpIC8gMikge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gbXVsdGlwbHkgYmFjayB0byB0aGUgY29ycmVjdCBtYWduaXR1ZGVcblx0aW50ZXJ2YWwgKj0gbWFnbml0dWRlO1xuXG5cdHJldHVybiBpbnRlcnZhbDtcbn1cblxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRoYXQgc29ydHMgYW4gb2JqZWN0IGFycmF5IGFuZCBrZWVwaW5nIHRoZSBvcmRlciBvZiBlcXVhbCBpdGVtcy5cbiAqIEVDTUEgc2NyaXB0IHN0YW5kYXJkIGRvZXMgbm90IHNwZWNpZnkgdGhlIGJlaGF2aW91ciB3aGVuIGl0ZW1zIGFyZSBlcXVhbC5cbiAqL1xuZnVuY3Rpb24gc3RhYmxlU29ydChhcnIsIHNvcnRGdW5jdGlvbikge1xuXHR2YXIgbGVuZ3RoID0gYXJyLmxlbmd0aCxcblx0XHRzb3J0VmFsdWUsXG5cdFx0aTtcblxuXHQvLyBBZGQgaW5kZXggdG8gZWFjaCBpdGVtXG5cdGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuXHRcdGFycltpXS5zc19pID0gaTsgLy8gc3RhYmxlIHNvcnQgaW5kZXhcblx0fVxuXG5cdGFyci5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0c29ydFZhbHVlID0gc29ydEZ1bmN0aW9uKGEsIGIpO1xuXHRcdHJldHVybiBzb3J0VmFsdWUgPT09IDAgPyBhLnNzX2kgLSBiLnNzX2kgOiBzb3J0VmFsdWU7XG5cdH0pO1xuXG5cdC8vIFJlbW92ZSBpbmRleCBmcm9tIGl0ZW1zXG5cdGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuXHRcdGRlbGV0ZSBhcnJbaV0uc3NfaTsgLy8gc3RhYmxlIHNvcnQgaW5kZXhcblx0fVxufVxuXG4vKipcbiAqIE5vbi1yZWN1cnNpdmUgbWV0aG9kIHRvIGZpbmQgdGhlIGxvd2VzdCBtZW1iZXIgb2YgYW4gYXJyYXkuIE1hdGgubWluIHJhaXNlcyBhIG1heGltdW1cbiAqIGNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZCBlcnJvciBpbiBDaHJvbWUgd2hlbiB0cnlpbmcgdG8gYXBwbHkgbW9yZSB0aGFuIDE1MC4wMDAgcG9pbnRzLiBUaGlzXG4gKiBtZXRob2QgaXMgc2xpZ2h0bHkgc2xvd2VyLCBidXQgc2FmZS5cbiAqL1xuZnVuY3Rpb24gYXJyYXlNaW4oZGF0YSkge1xuXHR2YXIgaSA9IGRhdGEubGVuZ3RoLFxuXHRcdG1pbiA9IGRhdGFbMF07XG5cblx0d2hpbGUgKGktLSkge1xuXHRcdGlmIChkYXRhW2ldIDwgbWluKSB7XG5cdFx0XHRtaW4gPSBkYXRhW2ldO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbWluO1xufVxuXG4vKipcbiAqIE5vbi1yZWN1cnNpdmUgbWV0aG9kIHRvIGZpbmQgdGhlIGxvd2VzdCBtZW1iZXIgb2YgYW4gYXJyYXkuIE1hdGgubWluIHJhaXNlcyBhIG1heGltdW1cbiAqIGNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZCBlcnJvciBpbiBDaHJvbWUgd2hlbiB0cnlpbmcgdG8gYXBwbHkgbW9yZSB0aGFuIDE1MC4wMDAgcG9pbnRzLiBUaGlzXG4gKiBtZXRob2QgaXMgc2xpZ2h0bHkgc2xvd2VyLCBidXQgc2FmZS5cbiAqL1xuZnVuY3Rpb24gYXJyYXlNYXgoZGF0YSkge1xuXHR2YXIgaSA9IGRhdGEubGVuZ3RoLFxuXHRcdG1heCA9IGRhdGFbMF07XG5cblx0d2hpbGUgKGktLSkge1xuXHRcdGlmIChkYXRhW2ldID4gbWF4KSB7XG5cdFx0XHRtYXggPSBkYXRhW2ldO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbWF4O1xufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRoYXQgZGVzdHJveXMgYW55IFNWR0VsZW1lbnQgb3IgVk1MRWxlbWVudCB0aGF0IGFyZSBwcm9wZXJ0aWVzIG9uIHRoZSBnaXZlbiBvYmplY3QuXG4gKiBJdCBsb29wcyBhbGwgcHJvcGVydGllcyBhbmQgaW52b2tlcyBkZXN0cm95IGlmIHRoZXJlIGlzIGEgZGVzdHJveSBtZXRob2QuIFRoZSBwcm9wZXJ0eSBpc1xuICogdGhlbiBkZWxldGUnZWQuXG4gKiBAcGFyYW0ge09iamVjdH0gVGhlIG9iamVjdCB0byBkZXN0cm95IHByb3BlcnRpZXMgb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBFeGNlcHRpb24sIGRvIG5vdCBkZXN0cm95IHRoaXMgcHJvcGVydHksIG9ubHkgZGVsZXRlIGl0LlxuICovXG5mdW5jdGlvbiBkZXN0cm95T2JqZWN0UHJvcGVydGllcyhvYmosIGV4Y2VwdCkge1xuXHR2YXIgbjtcblx0Zm9yIChuIGluIG9iaikge1xuXHRcdC8vIElmIHRoZSBvYmplY3QgaXMgbm9uLW51bGwgYW5kIGRlc3Ryb3kgaXMgZGVmaW5lZFxuXHRcdGlmIChvYmpbbl0gJiYgb2JqW25dICE9PSBleGNlcHQgJiYgb2JqW25dLmRlc3Ryb3kpIHtcblx0XHRcdC8vIEludm9rZSB0aGUgZGVzdHJveVxuXHRcdFx0b2JqW25dLmRlc3Ryb3koKTtcblx0XHR9XG5cblx0XHQvLyBEZWxldGUgdGhlIHByb3BlcnR5IGZyb20gdGhlIG9iamVjdC5cblx0XHRkZWxldGUgb2JqW25dO1xuXHR9XG59XG5cblxuLyoqXG4gKiBEaXNjYXJkIGFuIGVsZW1lbnQgYnkgbW92aW5nIGl0IHRvIHRoZSBiaW4gYW5kIGRlbGV0ZVxuICogQHBhcmFtIHtPYmplY3R9IFRoZSBIVE1MIG5vZGUgdG8gZGlzY2FyZFxuICovXG5mdW5jdGlvbiBkaXNjYXJkRWxlbWVudChlbGVtZW50KSB7XG5cdC8vIGNyZWF0ZSBhIGdhcmJhZ2UgYmluIGVsZW1lbnQsIG5vdCBwYXJ0IG9mIHRoZSBET01cblx0aWYgKCFnYXJiYWdlQmluKSB7XG5cdFx0Z2FyYmFnZUJpbiA9IGNyZWF0ZUVsZW1lbnQoRElWKTtcblx0fVxuXG5cdC8vIG1vdmUgdGhlIG5vZGUgYW5kIGVtcHR5IGJpblxuXHRpZiAoZWxlbWVudCkge1xuXHRcdGdhcmJhZ2VCaW4uYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdH1cblx0Z2FyYmFnZUJpbi5pbm5lckhUTUwgPSAnJztcbn1cblxuLyoqXG4gKiBQcm92aWRlIGVycm9yIG1lc3NhZ2VzIGZvciBkZWJ1Z2dpbmcsIHdpdGggbGlua3MgdG8gb25saW5lIGV4cGxhbmF0aW9uIFxuICovXG5lcnJvciA9IGZ1bmN0aW9uIChjb2RlLCBzdG9wKSB7XG5cdHZhciBtc2cgPSAnSGlnaGNoYXJ0cyBlcnJvciAjJyArIGNvZGUgKyAnOiB3d3cuaGlnaGNoYXJ0cy5jb20vZXJyb3JzLycgKyBjb2RlO1xuXHRpZiAoc3RvcCkge1xuXHRcdHRocm93IG1zZztcblx0fVxuXHQvLyBlbHNlIC4uLlxuXHRpZiAod2luLmNvbnNvbGUpIHtcblx0XHRjb25zb2xlLmxvZyhtc2cpO1xuXHR9XG59O1xuXG4vKipcbiAqIEZpeCBKUyByb3VuZCBvZmYgZmxvYXQgZXJyb3JzXG4gKiBAcGFyYW0ge051bWJlcn0gbnVtXG4gKi9cbmZ1bmN0aW9uIGNvcnJlY3RGbG9hdChudW0pIHtcblx0cmV0dXJuIHBhcnNlRmxvYXQoXG5cdFx0bnVtLnRvUHJlY2lzaW9uKDE0KVxuXHQpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgZ2xvYmFsIGFuaW1hdGlvbiB0byBlaXRoZXIgYSBnaXZlbiB2YWx1ZSwgb3IgZmFsbCBiYWNrIHRvIHRoZVxuICogZ2l2ZW4gY2hhcnQncyBhbmltYXRpb24gb3B0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gYW5pbWF0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gY2hhcnRcbiAqL1xuZnVuY3Rpb24gc2V0QW5pbWF0aW9uKGFuaW1hdGlvbiwgY2hhcnQpIHtcblx0Z2xvYmFsQW5pbWF0aW9uID0gcGljayhhbmltYXRpb24sIGNoYXJ0LmFuaW1hdGlvbik7XG59XG5cbi8qKlxuICogVGhlIHRpbWUgdW5pdCBsb29rdXBcbiAqL1xudGltZVVuaXRzID0ge1xuXHRtaWxsaXNlY29uZDogMSxcblx0c2Vjb25kOiAxMDAwLFxuXHRtaW51dGU6IDYwMDAwLFxuXHRob3VyOiAzNjAwMDAwLFxuXHRkYXk6IDI0ICogMzYwMDAwMCxcblx0d2VlazogNyAqIDI0ICogMzYwMDAwMCxcblx0bW9udGg6IDMxICogMjQgKiAzNjAwMDAwLFxuXHR5ZWFyOiAzMTU1Njk1MjAwMFxufTtcbi8qKlxuICogUGF0aCBpbnRlcnBvbGF0aW9uIGFsZ29yaXRobSB1c2VkIGFjcm9zcyBhZGFwdGVyc1xuICovXG5wYXRoQW5pbSA9IHtcblx0LyoqXG5cdCAqIFByZXBhcmUgc3RhcnQgYW5kIGVuZCB2YWx1ZXMgc28gdGhhdCB0aGUgcGF0aCBjYW4gYmUgYW5pbWF0ZWQgb25lIHRvIG9uZVxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGVsZW0sIGZyb21ELCB0b0QpIHtcblx0XHRmcm9tRCA9IGZyb21EIHx8ICcnO1xuXHRcdHZhciBzaGlmdCA9IGVsZW0uc2hpZnQsXG5cdFx0XHRiZXppZXIgPSBmcm9tRC5pbmRleE9mKCdDJykgPiAtMSxcblx0XHRcdG51bVBhcmFtcyA9IGJlemllciA/IDcgOiAzLFxuXHRcdFx0ZW5kTGVuZ3RoLFxuXHRcdFx0c2xpY2UsXG5cdFx0XHRpLFxuXHRcdFx0c3RhcnQgPSBmcm9tRC5zcGxpdCgnICcpLFxuXHRcdFx0ZW5kID0gW10uY29uY2F0KHRvRCksIC8vIGNvcHlcblx0XHRcdHN0YXJ0QmFzZUxpbmUsXG5cdFx0XHRlbmRCYXNlTGluZSxcblx0XHRcdHNpeGlmeSA9IGZ1bmN0aW9uIChhcnIpIHsgLy8gaW4gc3BsaW5lcyBtYWtlIG1vdmUgcG9pbnRzIGhhdmUgc2l4IHBhcmFtZXRlcnMgbGlrZSBiZXppZXIgY3VydmVzXG5cdFx0XHRcdGkgPSBhcnIubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdFx0aWYgKGFycltpXSA9PT0gTSkge1xuXHRcdFx0XHRcdFx0YXJyLnNwbGljZShpICsgMSwgMCwgYXJyW2kgKyAxXSwgYXJyW2kgKyAyXSwgYXJyW2kgKyAxXSwgYXJyW2kgKyAyXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0aWYgKGJlemllcikge1xuXHRcdFx0c2l4aWZ5KHN0YXJ0KTtcblx0XHRcdHNpeGlmeShlbmQpO1xuXHRcdH1cblxuXHRcdC8vIHB1bGwgb3V0IHRoZSBiYXNlIGxpbmVzIGJlZm9yZSBwYWRkaW5nXG5cdFx0aWYgKGVsZW0uaXNBcmVhKSB7XG5cdFx0XHRzdGFydEJhc2VMaW5lID0gc3RhcnQuc3BsaWNlKHN0YXJ0Lmxlbmd0aCAtIDYsIDYpO1xuXHRcdFx0ZW5kQmFzZUxpbmUgPSBlbmQuc3BsaWNlKGVuZC5sZW5ndGggLSA2LCA2KTtcblx0XHR9XG5cblx0XHQvLyBpZiBzaGlmdGluZyBwb2ludHMsIHByZXBlbmQgYSBkdW1teSBwb2ludCB0byB0aGUgZW5kIHBhdGhcblx0XHRpZiAoc2hpZnQgPD0gZW5kLmxlbmd0aCAvIG51bVBhcmFtcyAmJiBzdGFydC5sZW5ndGggPT09IGVuZC5sZW5ndGgpIHtcblx0XHRcdHdoaWxlIChzaGlmdC0tKSB7XG5cdFx0XHRcdGVuZCA9IFtdLmNvbmNhdChlbmQpLnNwbGljZSgwLCBudW1QYXJhbXMpLmNvbmNhdChlbmQpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlbGVtLnNoaWZ0ID0gMDsgLy8gcmVzZXQgZm9yIGZvbGxvd2luZyBhbmltYXRpb25zXG5cblx0XHQvLyBjb3B5IGFuZCBhcHBlbmQgbGFzdCBwb2ludCB1bnRpbCB0aGUgbGVuZ3RoIG1hdGNoZXMgdGhlIGVuZCBsZW5ndGhcblx0XHRpZiAoc3RhcnQubGVuZ3RoKSB7XG5cdFx0XHRlbmRMZW5ndGggPSBlbmQubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKHN0YXJ0Lmxlbmd0aCA8IGVuZExlbmd0aCkge1xuXG5cdFx0XHRcdC8vYmV6aWVyICYmIHNpeGlmeShzdGFydCk7XG5cdFx0XHRcdHNsaWNlID0gW10uY29uY2F0KHN0YXJ0KS5zcGxpY2Uoc3RhcnQubGVuZ3RoIC0gbnVtUGFyYW1zLCBudW1QYXJhbXMpO1xuXHRcdFx0XHRpZiAoYmV6aWVyKSB7IC8vIGRpc2FibGUgZmlyc3QgY29udHJvbCBwb2ludFxuXHRcdFx0XHRcdHNsaWNlW251bVBhcmFtcyAtIDZdID0gc2xpY2VbbnVtUGFyYW1zIC0gMl07XG5cdFx0XHRcdFx0c2xpY2VbbnVtUGFyYW1zIC0gNV0gPSBzbGljZVtudW1QYXJhbXMgLSAxXTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzdGFydCA9IHN0YXJ0LmNvbmNhdChzbGljZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHN0YXJ0QmFzZUxpbmUpIHsgLy8gYXBwZW5kIHRoZSBiYXNlIGxpbmVzIGZvciBhcmVhc1xuXHRcdFx0c3RhcnQgPSBzdGFydC5jb25jYXQoc3RhcnRCYXNlTGluZSk7XG5cdFx0XHRlbmQgPSBlbmQuY29uY2F0KGVuZEJhc2VMaW5lKTtcblx0XHR9XG5cdFx0cmV0dXJuIFtzdGFydCwgZW5kXTtcblx0fSxcblxuXHQvKipcblx0ICogSW50ZXJwb2xhdGUgZWFjaCB2YWx1ZSBvZiB0aGUgcGF0aCBhbmQgcmV0dXJuIHRoZSBhcnJheVxuXHQgKi9cblx0c3RlcDogZnVuY3Rpb24gKHN0YXJ0LCBlbmQsIHBvcywgY29tcGxldGUpIHtcblx0XHR2YXIgcmV0ID0gW10sXG5cdFx0XHRpID0gc3RhcnQubGVuZ3RoLFxuXHRcdFx0c3RhcnRWYWw7XG5cblx0XHRpZiAocG9zID09PSAxKSB7IC8vIGxhbmQgb24gdGhlIGZpbmFsIHBhdGggd2l0aG91dCBhZGp1c3RtZW50IHBvaW50cyBhcHBlbmRlZCBpbiB0aGUgZW5kc1xuXHRcdFx0cmV0ID0gY29tcGxldGU7XG5cblx0XHR9IGVsc2UgaWYgKGkgPT09IGVuZC5sZW5ndGggJiYgcG9zIDwgMSkge1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRzdGFydFZhbCA9IHBhcnNlRmxvYXQoc3RhcnRbaV0pO1xuXHRcdFx0XHRyZXRbaV0gPVxuXHRcdFx0XHRcdGlzTmFOKHN0YXJ0VmFsKSA/IC8vIGEgbGV0dGVyIGluc3RydWN0aW9uIGxpa2UgTSBvciBMXG5cdFx0XHRcdFx0XHRzdGFydFtpXSA6XG5cdFx0XHRcdFx0XHRwb3MgKiAocGFyc2VGbG9hdChlbmRbaV0gLSBzdGFydFZhbCkpICsgc3RhcnRWYWw7XG5cblx0XHRcdH1cblx0XHR9IGVsc2UgeyAvLyBpZiBhbmltYXRpb24gaXMgZmluaXNoZWQgb3IgbGVuZ3RoIG5vdCBtYXRjaGluZywgbGFuZCBvbiByaWdodCB2YWx1ZVxuXHRcdFx0cmV0ID0gZW5kO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9XG59O1xuXG4oZnVuY3Rpb24gKCQpIHtcblx0LyoqXG5cdCAqIFRoZSBkZWZhdWx0IEhpZ2hjaGFydHNBZGFwdGVyIGZvciBqUXVlcnlcblx0ICovXG5cdHdpbi5IaWdoY2hhcnRzQWRhcHRlciA9IHdpbi5IaWdoY2hhcnRzQWRhcHRlciB8fCAoJCAmJiB7XG5cdFx0XG5cdFx0LyoqXG5cdFx0ICogSW5pdGlhbGl6ZSB0aGUgYWRhcHRlciBieSBhcHBseWluZyBzb21lIGV4dGVuc2lvbnMgdG8galF1ZXJ5XG5cdFx0ICovXG5cdFx0aW5pdDogZnVuY3Rpb24gKHBhdGhBbmltKSB7XG5cdFx0XHRcblx0XHRcdC8vIGV4dGVuZCB0aGUgYW5pbWF0ZSBmdW5jdGlvbiB0byBhbGxvdyBTVkcgYW5pbWF0aW9uc1xuXHRcdFx0dmFyIEZ4ID0gJC5meDtcblx0XHRcdFxuXHRcdFx0Lypqc2xpbnQgdW5wYXJhbTogdHJ1ZSovLyogYWxsb3cgdW51c2VkIHBhcmFtIHggaW4gdGhpcyBmdW5jdGlvbiAqL1xuXHRcdFx0JC5leHRlbmQoJC5lYXNpbmcsIHtcblx0XHRcdFx0ZWFzZU91dFF1YWQ6IGZ1bmN0aW9uICh4LCB0LCBiLCBjLCBkKSB7XG5cdFx0XHRcdFx0cmV0dXJuIC1jICogKHQgLz0gZCkgKiAodCAtIDIpICsgYjtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHQvKmpzbGludCB1bnBhcmFtOiBmYWxzZSovXG5cdFx0XG5cdFx0XHQvLyBleHRlbmQgc29tZSBtZXRob2RzIHRvIGNoZWNrIGZvciBlbGVtLmF0dHIsIHdoaWNoIG1lYW5zIGl0IGlzIGEgSGlnaGNoYXJ0cyBTVkcgb2JqZWN0XG5cdFx0XHQkLmVhY2goWydjdXInLCAnX2RlZmF1bHQnLCAnd2lkdGgnLCAnaGVpZ2h0JywgJ29wYWNpdHknXSwgZnVuY3Rpb24gKGksIGZuKSB7XG5cdFx0XHRcdHZhciBvYmogPSBGeC5zdGVwLFxuXHRcdFx0XHRcdGJhc2U7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdC8vIEhhbmRsZSBkaWZmZXJlbnQgcGFyZW50IG9iamVjdHNcblx0XHRcdFx0aWYgKGZuID09PSAnY3VyJykge1xuXHRcdFx0XHRcdG9iaiA9IEZ4LnByb3RvdHlwZTsgLy8gJ2N1cicsIHRoZSBnZXR0ZXIsIHJlbGF0ZXMgdG8gRngucHJvdG90eXBlXG5cdFx0XHRcdFxuXHRcdFx0XHR9IGVsc2UgaWYgKGZuID09PSAnX2RlZmF1bHQnICYmICQuVHdlZW4pIHsgLy8galF1ZXJ5IDEuOCBtb2RlbFxuXHRcdFx0XHRcdG9iaiA9ICQuVHdlZW4ucHJvcEhvb2tzW2ZuXTtcblx0XHRcdFx0XHRmbiA9ICdzZXQnO1xuXHRcdFx0XHR9XG5cdFx0XG5cdFx0XHRcdC8vIE92ZXJ3cml0ZSB0aGUgbWV0aG9kXG5cdFx0XHRcdGJhc2UgPSBvYmpbZm5dO1xuXHRcdFx0XHRpZiAoYmFzZSkgeyAvLyBzdGVwLndpZHRoIGFuZCBzdGVwLmhlaWdodCBkb24ndCBleGlzdCBpbiBqUXVlcnkgPCAxLjdcblx0XHRcblx0XHRcdFx0XHQvLyBjcmVhdGUgdGhlIGV4dGVuZGVkIGZ1bmN0aW9uIHJlcGxhY2VtZW50XG5cdFx0XHRcdFx0b2JqW2ZuXSA9IGZ1bmN0aW9uIChmeCkge1xuXG5cdFx0XHRcdFx0XHR2YXIgZWxlbTtcblx0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdFx0Ly8gRngucHJvdG90eXBlLmN1ciBkb2VzIG5vdCB1c2UgZnggYXJndW1lbnRcblx0XHRcdFx0XHRcdGZ4ID0gaSA/IGZ4IDogdGhpcztcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgcnVuIGFuaW1hdGlvbnMgb24gdGV4dHVhbCBwcm9wZXJ0aWVzIGxpa2UgYWxpZ24gKCMxODIxKVxuXHRcdFx0XHRcdFx0aWYgKGZ4LnByb3AgPT09ICdhbGlnbicpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFxuXHRcdFx0XHRcdFx0Ly8gc2hvcnRjdXRcblx0XHRcdFx0XHRcdGVsZW0gPSBmeC5lbGVtO1xuXHRcdFxuXHRcdFx0XHRcdFx0Ly8gRngucHJvdG90eXBlLmN1ciByZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlLiBUaGUgb3RoZXIgb25lcyBhcmUgc2V0dGVyc1xuXHRcdFx0XHRcdFx0Ly8gYW5kIHJldHVybmluZyBhIHZhbHVlIGhhcyBubyBlZmZlY3QuXG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5hdHRyID8gLy8gaXMgU1ZHIGVsZW1lbnQgd3JhcHBlclxuXHRcdFx0XHRcdFx0XHRlbGVtLmF0dHIoZngucHJvcCwgZm4gPT09ICdjdXInID8gVU5ERUZJTkVEIDogZngubm93KSA6IC8vIGFwcGx5IHRoZSBTVkcgd3JhcHBlcidzIG1ldGhvZFxuXHRcdFx0XHRcdFx0XHRiYXNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IC8vIHVzZSBqUXVlcnkncyBidWlsdC1pbiBtZXRob2Rcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBvcGFjaXR5IGdldHRlciwgbmVlZGVkIGZvciBmYWRpbmcgb3BhY2l0eSB3aXRoIElFOSBhbmQgalF1ZXJ5IDEuMTArXG5cdFx0XHR3cmFwKCQuY3NzSG9va3Mub3BhY2l0eSwgJ2dldCcsIGZ1bmN0aW9uIChwcm9jZWVkLCBlbGVtLCBjb21wdXRlZCkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5hdHRyID8gKGVsZW0ub3BhY2l0eSB8fCAwKSA6IHByb2NlZWQuY2FsbCh0aGlzLCBlbGVtLCBjb21wdXRlZCk7XG5cdFx0XHR9KTtcblx0XHRcdFxuXHRcdFx0Ly8gRGVmaW5lIHRoZSBzZXR0ZXIgZnVuY3Rpb24gZm9yIGQgKHBhdGggZGVmaW5pdGlvbnMpXG5cdFx0XHR0aGlzLmFkZEFuaW1TZXR0ZXIoJ2QnLCBmdW5jdGlvbiAoZngpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSBmeC5lbGVtLFxuXHRcdFx0XHRcdGVuZHM7XG5cdFx0XG5cdFx0XHRcdC8vIE5vcm1hbGx5IHN0YXJ0IGFuZCBlbmQgc2hvdWxkIGJlIHNldCBpbiBzdGF0ZSA9PSAwLCBidXQgc29tZXRpbWVzLFxuXHRcdFx0XHQvLyBmb3IgcmVhc29ucyB1bmtub3duLCB0aGlzIGRvZXNuJ3QgaGFwcGVuLiBQZXJoYXBzIHN0YXRlID09IDAgaXMgc2tpcHBlZFxuXHRcdFx0XHQvLyBpbiB0aGVzZSBjYXNlc1xuXHRcdFx0XHRpZiAoIWZ4LnN0YXJ0ZWQpIHtcblx0XHRcdFx0XHRlbmRzID0gcGF0aEFuaW0uaW5pdChlbGVtLCBlbGVtLmQsIGVsZW0udG9EKTtcblx0XHRcdFx0XHRmeC5zdGFydCA9IGVuZHNbMF07XG5cdFx0XHRcdFx0ZnguZW5kID0gZW5kc1sxXTtcblx0XHRcdFx0XHRmeC5zdGFydGVkID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFxuXHRcdFx0XHQvLyBJbnRlcnBvbGF0ZSBlYWNoIHZhbHVlIG9mIHRoZSBwYXRoXG5cdFx0XHRcdGVsZW0uYXR0cignZCcsIHBhdGhBbmltLnN0ZXAoZnguc3RhcnQsIGZ4LmVuZCwgZngucG9zLCBlbGVtLnRvRCkpO1xuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdC8qKlxuXHRcdFx0ICogVXRpbGl0eSBmb3IgaXRlcmF0aW5nIG92ZXIgYW4gYXJyYXkuIFBhcmFtZXRlcnMgYXJlIHJldmVyc2VkIGNvbXBhcmVkIHRvIGpRdWVyeS5cblx0XHRcdCAqIEBwYXJhbSB7QXJyYXl9IGFyclxuXHRcdFx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5lYWNoID0gQXJyYXkucHJvdG90eXBlLmZvckVhY2ggP1xuXHRcdFx0XHRmdW5jdGlvbiAoYXJyLCBmbikgeyAvLyBtb2Rlcm4gYnJvd3NlcnNcblx0XHRcdFx0XHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChhcnIsIGZuKTtcblx0XHRcdFx0XHRcblx0XHRcdFx0fSA6IFxuXHRcdFx0XHRmdW5jdGlvbiAoYXJyLCBmbikgeyAvLyBsZWdhY3lcblx0XHRcdFx0XHR2YXIgaSwgXG5cdFx0XHRcdFx0XHRsZW4gPSBhcnIubGVuZ3RoO1xuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRcdFx0aWYgKGZuLmNhbGwoYXJyW2ldLCBhcnJbaV0sIGksIGFycikgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBSZWdpc3RlciBIaWdoY2hhcnRzIGFzIGEgcGx1Z2luIGluIHRoZSByZXNwZWN0aXZlIGZyYW1ld29ya1xuXHRcdFx0ICovXG5cdFx0XHQkLmZuLmhpZ2hjaGFydHMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHZhciBjb25zdHIgPSAnQ2hhcnQnLCAvLyBkZWZhdWx0IGNvbnN0cnVjdG9yXG5cdFx0XHRcdFx0YXJncyA9IGFyZ3VtZW50cyxcblx0XHRcdFx0XHRvcHRpb25zLFxuXHRcdFx0XHRcdHJldCxcblx0XHRcdFx0XHRjaGFydDtcblxuXHRcdFx0XHRpZiAodGhpc1swXSkge1xuXG5cdFx0XHRcdFx0aWYgKGlzU3RyaW5nKGFyZ3NbMF0pKSB7XG5cdFx0XHRcdFx0XHRjb25zdHIgPSBhcmdzWzBdO1xuXHRcdFx0XHRcdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MsIDEpOyBcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0b3B0aW9ucyA9IGFyZ3NbMF07XG5cblx0XHRcdFx0XHQvLyBDcmVhdGUgdGhlIGNoYXJ0XG5cdFx0XHRcdFx0aWYgKG9wdGlvbnMgIT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRcdFx0Lypqc2xpbnQgdW51c2VkOmZhbHNlKi9cblx0XHRcdFx0XHRcdG9wdGlvbnMuY2hhcnQgPSBvcHRpb25zLmNoYXJ0IHx8IHt9O1xuXHRcdFx0XHRcdFx0b3B0aW9ucy5jaGFydC5yZW5kZXJUbyA9IHRoaXNbMF07XG5cdFx0XHRcdFx0XHRjaGFydCA9IG5ldyBIaWdoY2hhcnRzW2NvbnN0cl0ob3B0aW9ucywgYXJnc1sxXSk7XG5cdFx0XHRcdFx0XHRyZXQgPSB0aGlzO1xuXHRcdFx0XHRcdFx0Lypqc2xpbnQgdW51c2VkOnRydWUqL1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFdoZW4gY2FsbGVkIHdpdGhvdXQgcGFyYW1ldGVycyBvciB3aXRoIHRoZSByZXR1cm4gYXJndW1lbnQsIGdldCBhIHByZWRlZmluZWQgY2hhcnRcblx0XHRcdFx0XHRpZiAob3B0aW9ucyA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdFx0XHRyZXQgPSBjaGFydHNbYXR0cih0aGlzWzBdLCAnZGF0YS1oaWdoY2hhcnRzLWNoYXJ0JyldO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH07XG5cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQWRkIGFuIGFuaW1hdGlvbiBzZXR0ZXIgZm9yIGEgc3BlY2lmaWMgcHJvcGVydHlcblx0XHQgKi9cblx0XHRhZGRBbmltU2V0dGVyOiBmdW5jdGlvbiAocHJvcCwgc2V0dGVyKSB7XG5cdFx0XHQvLyBqUXVlcnkgMS44IHN0eWxlXG5cdFx0XHRpZiAoJC5Ud2Vlbikge1xuXHRcdFx0XHQkLlR3ZWVuLnByb3BIb29rc1twcm9wXSA9IHtcblx0XHRcdFx0XHRzZXQ6IHNldHRlclxuXHRcdFx0XHR9O1xuXHRcdFx0Ly8gcHJlIDEuOFxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0JC5meC5zdGVwW3Byb3BdID0gc2V0dGVyO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0XG5cdFx0LyoqXG5cdFx0ICogRG93bmxvYWRzIGEgc2NyaXB0IGFuZCBleGVjdXRlcyBhIGNhbGxiYWNrIHdoZW4gZG9uZS5cblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gc2NyaXB0TG9jYXRpb25cblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuXHRcdCAqL1xuXHRcdGdldFNjcmlwdDogJC5nZXRTY3JpcHQsXG5cdFx0XG5cdFx0LyoqXG5cdFx0ICogUmV0dXJuIHRoZSBpbmRleCBvZiBhbiBpdGVtIGluIGFuIGFycmF5LCBvciAtMSBpZiBub3QgZm91bmRcblx0XHQgKi9cblx0XHRpbkFycmF5OiAkLmluQXJyYXksXG5cdFx0XG5cdFx0LyoqXG5cdFx0ICogQSBkaXJlY3QgbGluayB0byBqUXVlcnkgbWV0aG9kcy4gTW9vVG9vbHMgYW5kIFByb3RvdHlwZSBhZGFwdGVycyBtdXN0IGJlIGltcGxlbWVudGVkIGZvciBlYWNoIGNhc2Ugb2YgbWV0aG9kLlxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtIFRoZSBIVE1MIGVsZW1lbnRcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIFdoaWNoIG1ldGhvZCB0byBydW4gb24gdGhlIHdyYXBwZWQgZWxlbWVudFxuXHRcdCAqL1xuXHRcdGFkYXB0ZXJSdW46IGZ1bmN0aW9uIChlbGVtLCBtZXRob2QpIHtcblx0XHRcdHJldHVybiAkKGVsZW0pW21ldGhvZF0oKTtcblx0XHR9LFxuXHRcblx0XHQvKipcblx0XHQgKiBGaWx0ZXIgYW4gYXJyYXlcblx0XHQgKi9cblx0XHRncmVwOiAkLmdyZXAsXG5cdFxuXHRcdC8qKlxuXHRcdCAqIE1hcCBhbiBhcnJheVxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IGFyclxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG5cdFx0ICovXG5cdFx0bWFwOiBmdW5jdGlvbiAoYXJyLCBmbikge1xuXHRcdFx0Ly9yZXR1cm4galF1ZXJ5Lm1hcChhcnIsIGZuKTtcblx0XHRcdHZhciByZXN1bHRzID0gW10sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRsZW4gPSBhcnIubGVuZ3RoO1xuXHRcdFx0Zm9yICg7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHRyZXN1bHRzW2ldID0gZm4uY2FsbChhcnJbaV0sIGFycltpXSwgaSwgYXJyKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcblx0XHR9LFxuXHRcblx0XHQvKipcblx0XHQgKiBHZXQgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgcmVsYXRpdmUgdG8gdGhlIHRvcCBsZWZ0IG9mIHRoZSBwYWdlXG5cdFx0ICovXG5cdFx0b2Zmc2V0OiBmdW5jdGlvbiAoZWwpIHtcblx0XHRcdHJldHVybiAkKGVsKS5vZmZzZXQoKTtcblx0XHR9LFxuXHRcblx0XHQvKipcblx0XHQgKiBBZGQgYW4gZXZlbnQgbGlzdGVuZXJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZWwgQSBIVE1MIGVsZW1lbnQgb3IgY3VzdG9tIG9iamVjdFxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBUaGUgZXZlbnQgdHlwZVxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBldmVudCBoYW5kbGVyXG5cdFx0ICovXG5cdFx0YWRkRXZlbnQ6IGZ1bmN0aW9uIChlbCwgZXZlbnQsIGZuKSB7XG5cdFx0XHQkKGVsKS5iaW5kKGV2ZW50LCBmbik7XG5cdFx0fSxcblx0XG5cdFx0LyoqXG5cdFx0ICogUmVtb3ZlIGV2ZW50IGFkZGVkIHdpdGggYWRkRXZlbnRcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZWwgVGhlIG9iamVjdFxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGUgVGhlIGV2ZW50IHR5cGUuIExlYXZlIGJsYW5rIHRvIHJlbW92ZSBhbGwgZXZlbnRzLlxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXIgVGhlIGZ1bmN0aW9uIHRvIHJlbW92ZVxuXHRcdCAqL1xuXHRcdHJlbW92ZUV2ZW50OiBmdW5jdGlvbiAoZWwsIGV2ZW50VHlwZSwgaGFuZGxlcikge1xuXHRcdFx0Ly8gd29ya2Fyb3VuZCBmb3IgalF1ZXJ5IGlzc3VlIHdpdGggdW5iaW5kaW5nIGN1c3RvbSBldmVudHM6XG5cdFx0XHQvLyBodHRwOi8vZm9ydW0ualF1ZXJ5LmNvbS90b3BpYy9qYXZhc2NyaXB0LWVycm9yLXdoZW4tdW5iaW5kaW5nLWEtY3VzdG9tLWV2ZW50LXVzaW5nLWpRdWVyeS0xLTQtMlxuXHRcdFx0dmFyIGZ1bmMgPSBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lciA/ICdyZW1vdmVFdmVudExpc3RlbmVyJyA6ICdkZXRhY2hFdmVudCc7XG5cdFx0XHRpZiAoZG9jW2Z1bmNdICYmIGVsICYmICFlbFtmdW5jXSkge1xuXHRcdFx0XHRlbFtmdW5jXSA9IGZ1bmN0aW9uICgpIHt9O1xuXHRcdFx0fVxuXHRcblx0XHRcdCQoZWwpLnVuYmluZChldmVudFR5cGUsIGhhbmRsZXIpO1xuXHRcdH0sXG5cdFxuXHRcdC8qKlxuXHRcdCAqIEZpcmUgYW4gZXZlbnQgb24gYSBjdXN0b20gb2JqZWN0XG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGVsXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRBcmd1bWVudHNcblx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkZWZhdWx0RnVuY3Rpb25cblx0XHQgKi9cblx0XHRmaXJlRXZlbnQ6IGZ1bmN0aW9uIChlbCwgdHlwZSwgZXZlbnRBcmd1bWVudHMsIGRlZmF1bHRGdW5jdGlvbikge1xuXHRcdFx0dmFyIGV2ZW50ID0gJC5FdmVudCh0eXBlKSxcblx0XHRcdFx0ZGV0YWNoZWRUeXBlID0gJ2RldGFjaGVkJyArIHR5cGUsXG5cdFx0XHRcdGRlZmF1bHRQcmV2ZW50ZWQ7XG5cdFxuXHRcdFx0Ly8gUmVtb3ZlIHdhcm5pbmdzIGluIENocm9tZSB3aGVuIGFjY2Vzc2luZyByZXR1cm5WYWx1ZSAoIzI3OTApLCBsYXllclggYW5kIGxheWVyWS4gQWx0aG91Z2ggSGlnaGNoYXJ0c1xuXHRcdFx0Ly8gbmV2ZXIgdXNlcyB0aGVzZSBwcm9wZXJ0aWVzLCBDaHJvbWUgaW5jbHVkZXMgdGhlbSBpbiB0aGUgZGVmYXVsdCBjbGljayBldmVudCBhbmRcblx0XHRcdC8vIHJhaXNlcyB0aGUgd2FybmluZyB3aGVuIHRoZXkgYXJlIGNvcGllZCBvdmVyIGluIHRoZSBleHRlbmQgc3RhdGVtZW50IGJlbG93LlxuXHRcdFx0Ly9cblx0XHRcdC8vIFRvIGF2b2lkIHByb2JsZW1zIGluIElFIChzZWUgIzEwMTApIHdoZXJlIHdlIGNhbm5vdCBkZWxldGUgdGhlIHByb3BlcnRpZXMgYW5kIGF2b2lkXG5cdFx0XHQvLyB0ZXN0aW5nIGlmIHRoZXkgYXJlIHRoZXJlICh3YXJuaW5nIGluIGNocm9tZSkgdGhlIG9ubHkgb3B0aW9uIGlzIHRvIHRlc3QgaWYgcnVubmluZyBJRS5cblx0XHRcdGlmICghaXNJRSAmJiBldmVudEFyZ3VtZW50cykge1xuXHRcdFx0XHRkZWxldGUgZXZlbnRBcmd1bWVudHMubGF5ZXJYO1xuXHRcdFx0XHRkZWxldGUgZXZlbnRBcmd1bWVudHMubGF5ZXJZO1xuXHRcdFx0XHRkZWxldGUgZXZlbnRBcmd1bWVudHMucmV0dXJuVmFsdWU7XG5cdFx0XHR9XG5cdFxuXHRcdFx0ZXh0ZW5kKGV2ZW50LCBldmVudEFyZ3VtZW50cyk7XG5cdFxuXHRcdFx0Ly8gUHJldmVudCBqUXVlcnkgZnJvbSB0cmlnZ2VyaW5nIHRoZSBvYmplY3QgbWV0aG9kIHRoYXQgaXMgbmFtZWQgdGhlXG5cdFx0XHQvLyBzYW1lIGFzIHRoZSBldmVudC4gRm9yIGV4YW1wbGUsIGlmIHRoZSBldmVudCBpcyAnc2VsZWN0JywgalF1ZXJ5XG5cdFx0XHQvLyBhdHRlbXB0cyBjYWxsaW5nIGVsLnNlbGVjdCBhbmQgaXQgZ29lcyBpbnRvIGEgbG9vcC5cblx0XHRcdGlmIChlbFt0eXBlXSkge1xuXHRcdFx0XHRlbFtkZXRhY2hlZFR5cGVdID0gZWxbdHlwZV07XG5cdFx0XHRcdGVsW3R5cGVdID0gbnVsbDtcblx0XHRcdH1cblx0XG5cdFx0XHQvLyBXcmFwIHByZXZlbnREZWZhdWx0IGFuZCBzdG9wUHJvcGFnYXRpb24gaW4gdHJ5L2NhdGNoIGJsb2NrcyBpblxuXHRcdFx0Ly8gb3JkZXIgdG8gcHJldmVudCBKUyBlcnJvcnMgd2hlbiBjYW5jZWxsaW5nIGV2ZW50cyBvbiBub24tRE9NXG5cdFx0XHQvLyBvYmplY3RzLiAjNjE1LlxuXHRcdFx0Lypqc2xpbnQgdW5wYXJhbTogdHJ1ZSovXG5cdFx0XHQkLmVhY2goWydwcmV2ZW50RGVmYXVsdCcsICdzdG9wUHJvcGFnYXRpb24nXSwgZnVuY3Rpb24gKGksIGZuKSB7XG5cdFx0XHRcdHZhciBiYXNlID0gZXZlbnRbZm5dO1xuXHRcdFx0XHRldmVudFtmbl0gPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdGJhc2UuY2FsbChldmVudCk7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZSkge1xuXHRcdFx0XHRcdFx0aWYgKGZuID09PSAncHJldmVudERlZmF1bHQnKSB7XG5cdFx0XHRcdFx0XHRcdGRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH0pO1xuXHRcdFx0Lypqc2xpbnQgdW5wYXJhbTogZmFsc2UqL1xuXHRcblx0XHRcdC8vIHRyaWdnZXIgaXRcblx0XHRcdCQoZWwpLnRyaWdnZXIoZXZlbnQpO1xuXHRcblx0XHRcdC8vIGF0dGFjaCB0aGUgbWV0aG9kXG5cdFx0XHRpZiAoZWxbZGV0YWNoZWRUeXBlXSkge1xuXHRcdFx0XHRlbFt0eXBlXSA9IGVsW2RldGFjaGVkVHlwZV07XG5cdFx0XHRcdGVsW2RldGFjaGVkVHlwZV0gPSBudWxsO1xuXHRcdFx0fVxuXHRcblx0XHRcdGlmIChkZWZhdWx0RnVuY3Rpb24gJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICYmICFkZWZhdWx0UHJldmVudGVkKSB7XG5cdFx0XHRcdGRlZmF1bHRGdW5jdGlvbihldmVudCk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRcblx0XHQvKipcblx0XHQgKiBFeHRlbnNpb24gbWV0aG9kIG5lZWRlZCBmb3IgTW9vVG9vbHNcblx0XHQgKi9cblx0XHR3YXNoTW91c2VFdmVudDogZnVuY3Rpb24gKGUpIHtcblx0XHRcdHZhciByZXQgPSBlLm9yaWdpbmFsRXZlbnQgfHwgZTtcblx0XHRcdFxuXHRcdFx0Ly8gY29tcHV0ZWQgYnkgalF1ZXJ5LCBuZWVkZWQgYnkgSUU4XG5cdFx0XHRpZiAocmV0LnBhZ2VYID09PSBVTkRFRklORUQpIHsgLy8gIzEyMzZcblx0XHRcdFx0cmV0LnBhZ2VYID0gZS5wYWdlWDtcblx0XHRcdFx0cmV0LnBhZ2VZID0gZS5wYWdlWTtcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9LFxuXHRcblx0XHQvKipcblx0XHQgKiBBbmltYXRlIGEgSFRNTCBlbGVtZW50IG9yIFNWRyBlbGVtZW50IHdyYXBwZXJcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZWxcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgalF1ZXJ5LWxpa2UgYW5pbWF0aW9uIG9wdGlvbnM6IGR1cmF0aW9uLCBlYXNpbmcsIGNhbGxiYWNrXG5cdFx0ICovXG5cdFx0YW5pbWF0ZTogZnVuY3Rpb24gKGVsLCBwYXJhbXMsIG9wdGlvbnMpIHtcblx0XHRcdHZhciAkZWwgPSAkKGVsKTtcblx0XHRcdGlmICghZWwuc3R5bGUpIHtcblx0XHRcdFx0ZWwuc3R5bGUgPSB7fTsgLy8gIzE4ODFcblx0XHRcdH1cblx0XHRcdGlmIChwYXJhbXMuZCkge1xuXHRcdFx0XHRlbC50b0QgPSBwYXJhbXMuZDsgLy8ga2VlcCB0aGUgYXJyYXkgZm9ybSBmb3IgcGF0aHMsIHVzZWQgaW4gJC5meC5zdGVwLmRcblx0XHRcdFx0cGFyYW1zLmQgPSAxOyAvLyBiZWNhdXNlIGluIGpRdWVyeSwgYW5pbWF0aW5nIHRvIGFuIGFycmF5IGhhcyBhIGRpZmZlcmVudCBtZWFuaW5nXG5cdFx0XHR9XG5cdFxuXHRcdFx0JGVsLnN0b3AoKTtcblx0XHRcdGlmIChwYXJhbXMub3BhY2l0eSAhPT0gVU5ERUZJTkVEICYmIGVsLmF0dHIpIHtcblx0XHRcdFx0cGFyYW1zLm9wYWNpdHkgKz0gJ3B4JzsgLy8gZm9yY2UgalF1ZXJ5IHRvIHVzZSBzYW1lIGxvZ2ljIGFzIHdpZHRoIGFuZCBoZWlnaHQgKCMyMTYxKVxuXHRcdFx0fVxuXHRcdFx0ZWwuaGFzQW5pbSA9IDE7IC8vICMzMzQyXG5cdFx0XHQkZWwuYW5pbWF0ZShwYXJhbXMsIG9wdGlvbnMpO1xuXHRcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIFN0b3AgcnVubmluZyBhbmltYXRpb25cblx0XHQgKi9cblx0XHRzdG9wOiBmdW5jdGlvbiAoZWwpIHtcblx0XHRcdGlmIChlbC5oYXNBbmltKSB7IC8vICMzMzQyLCBtZW1vcnkgbGVhayBvbiBjYWxsaW5nICQoZWwpIGZyb20gZGVzdHJveVxuXHRcdFx0XHQkKGVsKS5zdG9wKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn0od2luLmpRdWVyeSkpO1xuXG5cbi8vIGNoZWNrIGZvciBhIGN1c3RvbSBIaWdoY2hhcnRzQWRhcHRlciBkZWZpbmVkIHByaW9yIHRvIHRoaXMgZmlsZVxudmFyIGdsb2JhbEFkYXB0ZXIgPSB3aW4uSGlnaGNoYXJ0c0FkYXB0ZXIsXG5cdGFkYXB0ZXIgPSBnbG9iYWxBZGFwdGVyIHx8IHt9O1xuXHRcbi8vIEluaXRpYWxpemUgdGhlIGFkYXB0ZXJcbmlmIChnbG9iYWxBZGFwdGVyKSB7XG5cdGdsb2JhbEFkYXB0ZXIuaW5pdC5jYWxsKGdsb2JhbEFkYXB0ZXIsIHBhdGhBbmltKTtcbn1cblxuXG4vLyBVdGlsaXR5IGZ1bmN0aW9ucy4gSWYgdGhlIEhpZ2hjaGFydHNBZGFwdGVyIGlzIG5vdCBkZWZpbmVkLCBhZGFwdGVyIGlzIGFuIGVtcHR5IG9iamVjdFxuLy8gYW5kIGFsbCB0aGUgdXRpbGl0eSBmdW5jdGlvbnMgd2lsbCBiZSBudWxsLiBJbiB0aGF0IGNhc2UgdGhleSBhcmUgcG9wdWxhdGVkIGJ5IHRoZVxuLy8gZGVmYXVsdCBhZGFwdGVycyBiZWxvdy5cbnZhciBhZGFwdGVyUnVuID0gYWRhcHRlci5hZGFwdGVyUnVuLFxuXHRnZXRTY3JpcHQgPSBhZGFwdGVyLmdldFNjcmlwdCxcblx0aW5BcnJheSA9IGFkYXB0ZXIuaW5BcnJheSxcblx0ZWFjaCA9IGFkYXB0ZXIuZWFjaCxcblx0Z3JlcCA9IGFkYXB0ZXIuZ3JlcCxcblx0b2Zmc2V0ID0gYWRhcHRlci5vZmZzZXQsXG5cdG1hcCA9IGFkYXB0ZXIubWFwLFxuXHRhZGRFdmVudCA9IGFkYXB0ZXIuYWRkRXZlbnQsXG5cdHJlbW92ZUV2ZW50ID0gYWRhcHRlci5yZW1vdmVFdmVudCxcblx0ZmlyZUV2ZW50ID0gYWRhcHRlci5maXJlRXZlbnQsXG5cdHdhc2hNb3VzZUV2ZW50ID0gYWRhcHRlci53YXNoTW91c2VFdmVudCxcblx0YW5pbWF0ZSA9IGFkYXB0ZXIuYW5pbWF0ZSxcblx0c3RvcCA9IGFkYXB0ZXIuc3RvcDtcblxuXG5cbi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqIEhhbmRsZSB0aGUgb3B0aW9ucyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhclxuXG5kZWZhdWx0TGFiZWxPcHRpb25zID0ge1xuXHRlbmFibGVkOiB0cnVlLFxuXHQvLyByb3RhdGlvbjogMCxcblx0Ly8gYWxpZ246ICdjZW50ZXInLFxuXHR4OiAwLFxuXHR5OiAxNSxcblx0Lypmb3JtYXR0ZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZTtcblx0fSwqL1xuXHRzdHlsZToge1xuXHRcdGNvbG9yOiAnIzYwNjA2MCcsXG5cdFx0Y3Vyc29yOiAnZGVmYXVsdCcsXG5cdFx0Zm9udFNpemU6ICcxMXB4J1xuXHR9XG59O1xuXG5kZWZhdWx0T3B0aW9ucyA9IHtcblx0Y29sb3JzOiBbJyM3Y2I1ZWMnLCAnIzQzNDM0OCcsICcjOTBlZDdkJywgJyNmN2EzNWMnLCBcblx0XHQgICAgJyM4MDg1ZTknLCAnI2YxNWM4MCcsICcjZTRkMzU0JywgJyM4MDg1ZTgnLCAnIzhkNDY1MycsICcjOTFlOGUxJ10sXG5cdHN5bWJvbHM6IFsnY2lyY2xlJywgJ2RpYW1vbmQnLCAnc3F1YXJlJywgJ3RyaWFuZ2xlJywgJ3RyaWFuZ2xlLWRvd24nXSxcblx0bGFuZzoge1xuXHRcdGxvYWRpbmc6ICdMb2FkaW5nLi4uJyxcblx0XHRtb250aHM6IFsnSmFudWFyeScsICdGZWJydWFyeScsICdNYXJjaCcsICdBcHJpbCcsICdNYXknLCAnSnVuZScsICdKdWx5Jyxcblx0XHRcdFx0J0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlciddLFxuXHRcdHNob3J0TW9udGhzOiBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJywgJ09jdCcsICdOb3YnLCAnRGVjJ10sXG5cdFx0d2Vla2RheXM6IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXSxcblx0XHRkZWNpbWFsUG9pbnQ6ICcuJyxcblx0XHRudW1lcmljU3ltYm9sczogWydrJywgJ00nLCAnRycsICdUJywgJ1AnLCAnRSddLCAvLyBTSSBwcmVmaXhlcyB1c2VkIGluIGF4aXMgbGFiZWxzXG5cdFx0cmVzZXRab29tOiAnUmVzZXQgem9vbScsXG5cdFx0cmVzZXRab29tVGl0bGU6ICdSZXNldCB6b29tIGxldmVsIDE6MScsXG5cdFx0dGhvdXNhbmRzU2VwOiAnLCdcblx0fSxcblx0Z2xvYmFsOiB7XG5cdFx0dXNlVVRDOiB0cnVlLFxuXHRcdC8vdGltZXpvbmVPZmZzZXQ6IDAsXG5cdFx0Y2FudmFzVG9vbHNVUkw6ICdodHRwOi8vY29kZS5oaWdoY2hhcnRzLmNvbS80LjAuNC9tb2R1bGVzL2NhbnZhcy10b29scy5qcycsXG5cdFx0Vk1MUmFkaWFsR3JhZGllbnRVUkw6ICdodHRwOi8vY29kZS5oaWdoY2hhcnRzLmNvbS80LjAuNC9nZngvdm1sLXJhZGlhbC1ncmFkaWVudC5wbmcnXG5cdH0sXG5cdGNoYXJ0OiB7XG5cdFx0Ly9hbmltYXRpb246IHRydWUsXG5cdFx0Ly9hbGlnblRpY2tzOiBmYWxzZSxcblx0XHQvL3JlZmxvdzogdHJ1ZSxcblx0XHQvL2NsYXNzTmFtZTogbnVsbCxcblx0XHQvL2V2ZW50czogeyBsb2FkLCBzZWxlY3Rpb24gfSxcblx0XHQvL21hcmdpbjogW251bGxdLFxuXHRcdC8vbWFyZ2luVG9wOiBudWxsLFxuXHRcdC8vbWFyZ2luUmlnaHQ6IG51bGwsXG5cdFx0Ly9tYXJnaW5Cb3R0b206IG51bGwsXG5cdFx0Ly9tYXJnaW5MZWZ0OiBudWxsLFxuXHRcdGJvcmRlckNvbG9yOiAnIzQ1NzJBNycsXG5cdFx0Ly9ib3JkZXJXaWR0aDogMCxcblx0XHRib3JkZXJSYWRpdXM6IDAsXG5cdFx0ZGVmYXVsdFNlcmllc1R5cGU6ICdsaW5lJyxcblx0XHRpZ25vcmVIaWRkZW5TZXJpZXM6IHRydWUsXG5cdFx0Ly9pbnZlcnRlZDogZmFsc2UsXG5cdFx0Ly9zaGFkb3c6IGZhbHNlLFxuXHRcdHNwYWNpbmc6IFsxMCwgMTAsIDE1LCAxMF0sXG5cdFx0Ly9zcGFjaW5nVG9wOiAxMCxcblx0XHQvL3NwYWNpbmdSaWdodDogMTAsXG5cdFx0Ly9zcGFjaW5nQm90dG9tOiAxNSxcblx0XHQvL3NwYWNpbmdMZWZ0OiAxMCxcblx0XHQvL3N0eWxlOiB7XG5cdFx0Ly9cdGZvbnRGYW1pbHk6ICdcIkx1Y2lkYSBHcmFuZGVcIiwgXCJMdWNpZGEgU2FucyBVbmljb2RlXCIsIFZlcmRhbmEsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWYnLCAvLyBkZWZhdWx0IGZvbnRcblx0XHQvL1x0Zm9udFNpemU6ICcxMnB4J1xuXHRcdC8vfSxcblx0XHRiYWNrZ3JvdW5kQ29sb3I6ICcjRkZGRkZGJyxcblx0XHQvL3Bsb3RCYWNrZ3JvdW5kQ29sb3I6IG51bGwsXG5cdFx0cGxvdEJvcmRlckNvbG9yOiAnI0MwQzBDMCcsXG5cdFx0Ly9wbG90Qm9yZGVyV2lkdGg6IDAsXG5cdFx0Ly9wbG90U2hhZG93OiBmYWxzZSxcblx0XHQvL3pvb21UeXBlOiAnJ1xuXHRcdHJlc2V0Wm9vbUJ1dHRvbjoge1xuXHRcdFx0dGhlbWU6IHtcblx0XHRcdFx0ekluZGV4OiAyMFxuXHRcdFx0fSxcblx0XHRcdHBvc2l0aW9uOiB7XG5cdFx0XHRcdGFsaWduOiAncmlnaHQnLFxuXHRcdFx0XHR4OiAtMTAsXG5cdFx0XHRcdC8vdmVydGljYWxBbGlnbjogJ3RvcCcsXG5cdFx0XHRcdHk6IDEwXG5cdFx0XHR9XG5cdFx0XHQvLyByZWxhdGl2ZVRvOiAncGxvdCdcblx0XHR9XG5cdH0sXG5cdHRpdGxlOiB7XG5cdFx0dGV4dDogJ0NoYXJ0IHRpdGxlJyxcblx0XHRhbGlnbjogJ2NlbnRlcicsXG5cdFx0Ly8gZmxvYXRpbmc6IGZhbHNlLFxuXHRcdG1hcmdpbjogMTUsXG5cdFx0Ly8geDogMCxcblx0XHQvLyB2ZXJ0aWNhbEFsaWduOiAndG9wJyxcblx0XHQvLyB5OiBudWxsLFxuXHRcdHN0eWxlOiB7XG5cdFx0XHRjb2xvcjogJyMzMzMzMzMnLFxuXHRcdFx0Zm9udFNpemU6ICcxOHB4J1xuXHRcdH1cblxuXHR9LFxuXHRzdWJ0aXRsZToge1xuXHRcdHRleHQ6ICcnLFxuXHRcdGFsaWduOiAnY2VudGVyJyxcblx0XHQvLyBmbG9hdGluZzogZmFsc2Vcblx0XHQvLyB4OiAwLFxuXHRcdC8vIHZlcnRpY2FsQWxpZ246ICd0b3AnLFxuXHRcdC8vIHk6IG51bGwsXG5cdFx0c3R5bGU6IHtcblx0XHRcdGNvbG9yOiAnIzU1NTU1NSdcblx0XHR9XG5cdH0sXG5cblx0cGxvdE9wdGlvbnM6IHtcblx0XHRsaW5lOiB7IC8vIGJhc2Ugc2VyaWVzIG9wdGlvbnNcblx0XHRcdGFsbG93UG9pbnRTZWxlY3Q6IGZhbHNlLFxuXHRcdFx0c2hvd0NoZWNrYm94OiBmYWxzZSxcblx0XHRcdGFuaW1hdGlvbjoge1xuXHRcdFx0XHRkdXJhdGlvbjogMTAwMFxuXHRcdFx0fSxcblx0XHRcdC8vY29ubmVjdE51bGxzOiBmYWxzZSxcblx0XHRcdC8vY3Vyc29yOiAnZGVmYXVsdCcsXG5cdFx0XHQvL2NsaXA6IHRydWUsXG5cdFx0XHQvL2Rhc2hTdHlsZTogbnVsbCxcblx0XHRcdC8vZW5hYmxlTW91c2VUcmFja2luZzogdHJ1ZSxcblx0XHRcdGV2ZW50czoge30sXG5cdFx0XHQvL2xlZ2VuZEluZGV4OiAwLFxuXHRcdFx0Ly9saW5lY2FwOiAncm91bmQnLFxuXHRcdFx0bGluZVdpZHRoOiAyLFxuXHRcdFx0Ly9zaGFkb3c6IGZhbHNlLFxuXHRcdFx0Ly8gc3RhY2tpbmc6IG51bGwsXG5cdFx0XHRtYXJrZXI6IHtcblx0XHRcdFx0Ly9lbmFibGVkOiB0cnVlLFxuXHRcdFx0XHQvL3N5bWJvbDogbnVsbCxcblx0XHRcdFx0bGluZVdpZHRoOiAwLFxuXHRcdFx0XHRyYWRpdXM6IDQsXG5cdFx0XHRcdGxpbmVDb2xvcjogJyNGRkZGRkYnLFxuXHRcdFx0XHQvL2ZpbGxDb2xvcjogbnVsbCxcblx0XHRcdFx0c3RhdGVzOiB7IC8vIHN0YXRlcyBmb3IgYSBzaW5nbGUgcG9pbnRcblx0XHRcdFx0XHRob3Zlcjoge1xuXHRcdFx0XHRcdFx0ZW5hYmxlZDogdHJ1ZSxcblx0XHRcdFx0XHRcdGxpbmVXaWR0aFBsdXM6IDEsXG5cdFx0XHRcdFx0XHRyYWRpdXNQbHVzOiAyXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRzZWxlY3Q6IHtcblx0XHRcdFx0XHRcdGZpbGxDb2xvcjogJyNGRkZGRkYnLFxuXHRcdFx0XHRcdFx0bGluZUNvbG9yOiAnIzAwMDAwMCcsXG5cdFx0XHRcdFx0XHRsaW5lV2lkdGg6IDJcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRwb2ludDoge1xuXHRcdFx0XHRldmVudHM6IHt9XG5cdFx0XHR9LFxuXHRcdFx0ZGF0YUxhYmVsczogbWVyZ2UoZGVmYXVsdExhYmVsT3B0aW9ucywge1xuXHRcdFx0XHRhbGlnbjogJ2NlbnRlcicsXG5cdFx0XHRcdC8vZGVmZXI6IHRydWUsXG5cdFx0XHRcdGVuYWJsZWQ6IGZhbHNlLFxuXHRcdFx0XHRmb3JtYXR0ZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy55ID09PSBudWxsID8gJycgOiBudW1iZXJGb3JtYXQodGhpcy55LCAtMSk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHZlcnRpY2FsQWxpZ246ICdib3R0b20nLCAvLyBhYm92ZSBzaW5ndWxhciBwb2ludFxuXHRcdFx0XHR5OiAwXG5cdFx0XHRcdC8vIGJhY2tncm91bmRDb2xvcjogdW5kZWZpbmVkLFxuXHRcdFx0XHQvLyBib3JkZXJDb2xvcjogdW5kZWZpbmVkLFxuXHRcdFx0XHQvLyBib3JkZXJSYWRpdXM6IHVuZGVmaW5lZCxcblx0XHRcdFx0Ly8gYm9yZGVyV2lkdGg6IHVuZGVmaW5lZCxcblx0XHRcdFx0Ly8gcGFkZGluZzogMyxcblx0XHRcdFx0Ly8gc2hhZG93OiBmYWxzZVxuXHRcdFx0fSksXG5cdFx0XHRjcm9wVGhyZXNob2xkOiAzMDAsIC8vIGRyYXcgcG9pbnRzIG91dHNpZGUgdGhlIHBsb3QgYXJlYSB3aGVuIHRoZSBudW1iZXIgb2YgcG9pbnRzIGlzIGxlc3MgdGhhbiB0aGlzXG5cdFx0XHRwb2ludFJhbmdlOiAwLFxuXHRcdFx0Ly9wb2ludFN0YXJ0OiAwLFxuXHRcdFx0Ly9wb2ludEludGVydmFsOiAxLFxuXHRcdFx0Ly9zaG93SW5MZWdlbmQ6IG51bGwsIC8vIGF1dG86IHRydWUgZm9yIHN0YW5kYWxvbmUgc2VyaWVzLCBmYWxzZSBmb3IgbGlua2VkIHNlcmllc1xuXHRcdFx0c3RhdGVzOiB7IC8vIHN0YXRlcyBmb3IgdGhlIGVudGlyZSBzZXJpZXNcblx0XHRcdFx0aG92ZXI6IHtcblx0XHRcdFx0XHQvL2VuYWJsZWQ6IGZhbHNlLFxuXHRcdFx0XHRcdGxpbmVXaWR0aFBsdXM6IDEsXG5cdFx0XHRcdFx0bWFya2VyOiB7XG5cdFx0XHRcdFx0XHQvLyBsaW5lV2lkdGg6IGJhc2UgKyAxLFxuXHRcdFx0XHRcdFx0Ly8gcmFkaXVzOiBiYXNlICsgMVxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0aGFsbzoge1xuXHRcdFx0XHRcdFx0c2l6ZTogMTAsXG5cdFx0XHRcdFx0XHRvcGFjaXR5OiAwLjI1XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZWxlY3Q6IHtcblx0XHRcdFx0XHRtYXJrZXI6IHt9XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRzdGlja3lUcmFja2luZzogdHJ1ZSxcblx0XHRcdC8vdG9vbHRpcDoge1xuXHRcdFx0XHQvL3BvaW50Rm9ybWF0OiAnPHNwYW4gc3R5bGU9XCJjb2xvcjp7c2VyaWVzLmNvbG9yfVwiPlxcdTI1Q0Y8L3NwYW4+IHtzZXJpZXMubmFtZX06IDxiPntwb2ludC55fTwvYj4nXG5cdFx0XHRcdC8vdmFsdWVEZWNpbWFsczogbnVsbCxcblx0XHRcdFx0Ly94RGF0ZUZvcm1hdDogJyVBLCAlYiAlZSwgJVknLFxuXHRcdFx0XHQvL3ZhbHVlUHJlZml4OiAnJyxcblx0XHRcdFx0Ly95U3VmZml4OiAnJ1x0XHRcdFx0XG5cdFx0XHQvL31cblx0XHRcdHR1cmJvVGhyZXNob2xkOiAxMDAwXG5cdFx0XHQvLyB6SW5kZXg6IG51bGxcblx0XHR9XG5cdH0sXG5cdGxhYmVsczoge1xuXHRcdC8vaXRlbXM6IFtdLFxuXHRcdHN0eWxlOiB7XG5cdFx0XHQvL2ZvbnQ6IGRlZmF1bHRGb250LFxuXHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0Y29sb3I6ICcjM0U1NzZGJ1xuXHRcdH1cblx0fSxcblx0bGVnZW5kOiB7XG5cdFx0ZW5hYmxlZDogdHJ1ZSxcblx0XHRhbGlnbjogJ2NlbnRlcicsXG5cdFx0Ly9mbG9hdGluZzogZmFsc2UsXG5cdFx0bGF5b3V0OiAnaG9yaXpvbnRhbCcsXG5cdFx0bGFiZWxGb3JtYXR0ZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRcdHJldHVybiB0aGlzLm5hbWU7XG5cdFx0fSxcblx0XHQvL2JvcmRlcldpZHRoOiAwLFxuXHRcdGJvcmRlckNvbG9yOiAnIzkwOTA5MCcsXG5cdFx0Ym9yZGVyUmFkaXVzOiAwLFxuXHRcdG5hdmlnYXRpb246IHtcblx0XHRcdC8vIGFuaW1hdGlvbjogdHJ1ZSxcblx0XHRcdGFjdGl2ZUNvbG9yOiAnIzI3NGI2ZCcsXG5cdFx0XHQvLyBhcnJvd1NpemU6IDEyXG5cdFx0XHRpbmFjdGl2ZUNvbG9yOiAnI0NDQydcblx0XHRcdC8vIHN0eWxlOiB7fSAvLyB0ZXh0IHN0eWxlc1xuXHRcdH0sXG5cdFx0Ly8gbWFyZ2luOiAyMCxcblx0XHQvLyByZXZlcnNlZDogZmFsc2UsXG5cdFx0c2hhZG93OiBmYWxzZSxcblx0XHQvLyBiYWNrZ3JvdW5kQ29sb3I6IG51bGwsXG5cdFx0LypzdHlsZToge1xuXHRcdFx0cGFkZGluZzogJzVweCdcblx0XHR9LCovXG5cdFx0aXRlbVN0eWxlOiB7XHRcdFx0XG5cdFx0XHRjb2xvcjogJyMzMzMzMzMnLFxuXHRcdFx0Zm9udFNpemU6ICcxMnB4Jyxcblx0XHRcdGZvbnRXZWlnaHQ6ICdib2xkJ1xuXHRcdH0sXG5cdFx0aXRlbUhvdmVyU3R5bGU6IHtcblx0XHRcdC8vY3Vyc29yOiAncG9pbnRlcicsIHJlbW92ZWQgYXMgb2YgIzYwMVxuXHRcdFx0Y29sb3I6ICcjMDAwJ1xuXHRcdH0sXG5cdFx0aXRlbUhpZGRlblN0eWxlOiB7XG5cdFx0XHRjb2xvcjogJyNDQ0MnXG5cdFx0fSxcblx0XHRpdGVtQ2hlY2tib3hTdHlsZToge1xuXHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0d2lkdGg6ICcxM3B4JywgLy8gZm9yIElFIHByZWNpc2lvblxuXHRcdFx0aGVpZ2h0OiAnMTNweCdcblx0XHR9LFxuXHRcdC8vIGl0ZW1XaWR0aDogdW5kZWZpbmVkLFxuXHRcdC8vIHN5bWJvbFJhZGl1czogMCxcblx0XHQvLyBzeW1ib2xXaWR0aDogMTYsXG5cdFx0c3ltYm9sUGFkZGluZzogNSxcblx0XHR2ZXJ0aWNhbEFsaWduOiAnYm90dG9tJyxcblx0XHQvLyB3aWR0aDogdW5kZWZpbmVkLFxuXHRcdHg6IDAsXG5cdFx0eTogMCxcblx0XHR0aXRsZToge1xuXHRcdFx0Ly90ZXh0OiBudWxsLFxuXHRcdFx0c3R5bGU6IHtcblx0XHRcdFx0Zm9udFdlaWdodDogJ2JvbGQnXG5cdFx0XHR9XG5cdFx0fVx0XHRcdFxuXHR9LFxuXG5cdGxvYWRpbmc6IHtcblx0XHQvLyBoaWRlRHVyYXRpb246IDEwMCxcblx0XHRsYWJlbFN0eWxlOiB7XG5cdFx0XHRmb250V2VpZ2h0OiAnYm9sZCcsXG5cdFx0XHRwb3NpdGlvbjogUkVMQVRJVkUsXG5cdFx0XHR0b3A6ICc0NSUnXG5cdFx0fSxcblx0XHQvLyBzaG93RHVyYXRpb246IDAsXG5cdFx0c3R5bGU6IHtcblx0XHRcdHBvc2l0aW9uOiBBQlNPTFVURSxcblx0XHRcdGJhY2tncm91bmRDb2xvcjogJ3doaXRlJyxcblx0XHRcdG9wYWNpdHk6IDAuNSxcblx0XHRcdHRleHRBbGlnbjogJ2NlbnRlcidcblx0XHR9XG5cdH0sXG5cblx0dG9vbHRpcDoge1xuXHRcdGVuYWJsZWQ6IHRydWUsXG5cdFx0YW5pbWF0aW9uOiBoYXNTVkcsXG5cdFx0Ly9jcm9zc2hhaXJzOiBudWxsLFxuXHRcdGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMjQ5LCAyNDksIDI0OSwgLjg1KScsXG5cdFx0Ym9yZGVyV2lkdGg6IDEsXG5cdFx0Ym9yZGVyUmFkaXVzOiAzLFxuXHRcdGRhdGVUaW1lTGFiZWxGb3JtYXRzOiB7IFxuXHRcdFx0bWlsbGlzZWNvbmQ6ICclQSwgJWIgJWUsICVIOiVNOiVTLiVMJyxcblx0XHRcdHNlY29uZDogJyVBLCAlYiAlZSwgJUg6JU06JVMnLFxuXHRcdFx0bWludXRlOiAnJUEsICViICVlLCAlSDolTScsXG5cdFx0XHRob3VyOiAnJUEsICViICVlLCAlSDolTScsXG5cdFx0XHRkYXk6ICclQSwgJWIgJWUsICVZJyxcblx0XHRcdHdlZWs6ICdXZWVrIGZyb20gJUEsICViICVlLCAlWScsXG5cdFx0XHRtb250aDogJyVCICVZJyxcblx0XHRcdHllYXI6ICclWSdcblx0XHR9LFxuXHRcdC8vZm9ybWF0dGVyOiBkZWZhdWx0Rm9ybWF0dGVyLFxuXHRcdGhlYWRlckZvcm1hdDogJzxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxMHB4XCI+e3BvaW50LmtleX08L3NwYW4+PGJyLz4nLFxuXHRcdHBvaW50Rm9ybWF0OiAnPHNwYW4gc3R5bGU9XCJjb2xvcjp7c2VyaWVzLmNvbG9yfVwiPlxcdTI1Q0Y8L3NwYW4+IHtzZXJpZXMubmFtZX06IDxiPntwb2ludC55fTwvYj48YnIvPicsXG5cdFx0c2hhZG93OiB0cnVlLFxuXHRcdC8vc2hhcGU6ICdjYWxsb3V0Jyxcblx0XHQvL3NoYXJlZDogZmFsc2UsXG5cdFx0c25hcDogaXNUb3VjaERldmljZSA/IDI1IDogMTAsXG5cdFx0c3R5bGU6IHtcblx0XHRcdGNvbG9yOiAnIzMzMzMzMycsXG5cdFx0XHRjdXJzb3I6ICdkZWZhdWx0Jyxcblx0XHRcdGZvbnRTaXplOiAnMTJweCcsXG5cdFx0XHRwYWRkaW5nOiAnOHB4Jyxcblx0XHRcdHdoaXRlU3BhY2U6ICdub3dyYXAnXG5cdFx0fVxuXHRcdC8veERhdGVGb3JtYXQ6ICclQSwgJWIgJWUsICVZJyxcblx0XHQvL3ZhbHVlRGVjaW1hbHM6IG51bGwsXG5cdFx0Ly92YWx1ZVByZWZpeDogJycsXG5cdFx0Ly92YWx1ZVN1ZmZpeDogJydcblx0fSxcblxuXHRjcmVkaXRzOiB7XG5cdFx0ZW5hYmxlZDogdHJ1ZSxcblx0XHR0ZXh0OiAnSGlnaGNoYXJ0cy5jb20nLFxuXHRcdGhyZWY6ICdodHRwOi8vd3d3LmhpZ2hjaGFydHMuY29tJyxcblx0XHRwb3NpdGlvbjoge1xuXHRcdFx0YWxpZ246ICdyaWdodCcsXG5cdFx0XHR4OiAtMTAsXG5cdFx0XHR2ZXJ0aWNhbEFsaWduOiAnYm90dG9tJyxcblx0XHRcdHk6IC01XG5cdFx0fSxcblx0XHRzdHlsZToge1xuXHRcdFx0Y3Vyc29yOiAncG9pbnRlcicsXG5cdFx0XHRjb2xvcjogJyM5MDkwOTAnLFxuXHRcdFx0Zm9udFNpemU6ICc5cHgnXG5cdFx0fVxuXHR9XG59O1xuXG5cblxuXG4vLyBTZXJpZXMgZGVmYXVsdHNcbnZhciBkZWZhdWx0UGxvdE9wdGlvbnMgPSBkZWZhdWx0T3B0aW9ucy5wbG90T3B0aW9ucyxcblx0ZGVmYXVsdFNlcmllc09wdGlvbnMgPSBkZWZhdWx0UGxvdE9wdGlvbnMubGluZTtcblxuLy8gc2V0IHRoZSBkZWZhdWx0IHRpbWUgbWV0aG9kc1xuc2V0VGltZU1ldGhvZHMoKTtcblxuXG5cbi8qKlxuICogU2V0IHRoZSB0aW1lIG1ldGhvZHMgZ2xvYmFsbHkgYmFzZWQgb24gdGhlIHVzZVVUQyBvcHRpb24uIFRpbWUgbWV0aG9kIGNhbiBiZSBlaXRoZXJcbiAqIGxvY2FsIHRpbWUgb3IgVVRDIChkZWZhdWx0KS5cbiAqL1xuZnVuY3Rpb24gc2V0VGltZU1ldGhvZHMoKSB7XG5cdHZhciB1c2VVVEMgPSBkZWZhdWx0T3B0aW9ucy5nbG9iYWwudXNlVVRDLFxuXHRcdEdFVCA9IHVzZVVUQyA/ICdnZXRVVEMnIDogJ2dldCcsXG5cdFx0U0VUID0gdXNlVVRDID8gJ3NldFVUQycgOiAnc2V0JztcblxuXG5cdERhdGUgPSBkZWZhdWx0T3B0aW9ucy5nbG9iYWwuRGF0ZSB8fCB3aW5kb3cuRGF0ZTtcblx0dGltZXpvbmVPZmZzZXQgPSAoKHVzZVVUQyAmJiBkZWZhdWx0T3B0aW9ucy5nbG9iYWwudGltZXpvbmVPZmZzZXQpIHx8IDApICogNjAwMDA7XG5cdG1ha2VUaW1lID0gdXNlVVRDID8gRGF0ZS5VVEMgOiBmdW5jdGlvbiAoeWVhciwgbW9udGgsIGRhdGUsIGhvdXJzLCBtaW51dGVzLCBzZWNvbmRzKSB7XG5cdFx0cmV0dXJuIG5ldyBEYXRlKFxuXHRcdFx0eWVhcixcblx0XHRcdG1vbnRoLFxuXHRcdFx0cGljayhkYXRlLCAxKSxcblx0XHRcdHBpY2soaG91cnMsIDApLFxuXHRcdFx0cGljayhtaW51dGVzLCAwKSxcblx0XHRcdHBpY2soc2Vjb25kcywgMClcblx0XHQpLmdldFRpbWUoKTtcblx0fTtcblx0Z2V0TWludXRlcyA9ICBHRVQgKyAnTWludXRlcyc7XG5cdGdldEhvdXJzID0gICAgR0VUICsgJ0hvdXJzJztcblx0Z2V0RGF5ID0gICAgICBHRVQgKyAnRGF5Jztcblx0Z2V0RGF0ZSA9ICAgICBHRVQgKyAnRGF0ZSc7XG5cdGdldE1vbnRoID0gICAgR0VUICsgJ01vbnRoJztcblx0Z2V0RnVsbFllYXIgPSBHRVQgKyAnRnVsbFllYXInO1xuXHRzZXRNaW51dGVzID0gIFNFVCArICdNaW51dGVzJztcblx0c2V0SG91cnMgPSAgICBTRVQgKyAnSG91cnMnO1xuXHRzZXREYXRlID0gICAgIFNFVCArICdEYXRlJztcblx0c2V0TW9udGggPSAgICBTRVQgKyAnTW9udGgnO1xuXHRzZXRGdWxsWWVhciA9IFNFVCArICdGdWxsWWVhcic7XG5cbn1cblxuLyoqXG4gKiBNZXJnZSB0aGUgZGVmYXVsdCBvcHRpb25zIHdpdGggY3VzdG9tIG9wdGlvbnMgYW5kIHJldHVybiB0aGUgbmV3IG9wdGlvbnMgc3RydWN0dXJlXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgbmV3IGN1c3RvbSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIHNldE9wdGlvbnMob3B0aW9ucykge1xuXHRcblx0Ly8gQ29weSBpbiB0aGUgZGVmYXVsdCBvcHRpb25zXG5cdGRlZmF1bHRPcHRpb25zID0gbWVyZ2UodHJ1ZSwgZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xuXHRcblx0Ly8gQXBwbHkgVVRDXG5cdHNldFRpbWVNZXRob2RzKCk7XG5cblx0cmV0dXJuIGRlZmF1bHRPcHRpb25zO1xufVxuXG4vKipcbiAqIEdldCB0aGUgdXBkYXRlZCBkZWZhdWx0IG9wdGlvbnMuIFVudGlsIDMuMC43LCBtZXJlbHkgZXhwb3NpbmcgZGVmYXVsdE9wdGlvbnMgZm9yIG91dHNpZGUgbW9kdWxlc1xuICogd2Fzbid0IGVub3VnaCBiZWNhdXNlIHRoZSBzZXRPcHRpb25zIG1ldGhvZCBjcmVhdGVkIGEgbmV3IG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZ2V0T3B0aW9ucygpIHtcblx0cmV0dXJuIGRlZmF1bHRPcHRpb25zO1xufVxuXG5cbi8qKlxuICogSGFuZGxlIGNvbG9yIG9wZXJhdGlvbnMuIFRoZSBvYmplY3QgbWV0aG9kcyBhcmUgY2hhaW5hYmxlLlxuICogQHBhcmFtIHtTdHJpbmd9IGlucHV0IFRoZSBpbnB1dCBjb2xvciBpbiBlaXRoZXIgcmJnYSBvciBoZXggZm9ybWF0XG4gKi9cbnZhciByZ2JhUmVnRXggPSAvcmdiYVxcKFxccyooWzAtOV17MSwzfSlcXHMqLFxccyooWzAtOV17MSwzfSlcXHMqLFxccyooWzAtOV17MSwzfSlcXHMqLFxccyooWzAtOV0/KD86XFwuWzAtOV0rKT8pXFxzKlxcKS8sXG5cdGhleFJlZ0V4ID0gLyMoW2EtZkEtRjAtOV17Mn0pKFthLWZBLUYwLTldezJ9KShbYS1mQS1GMC05XXsyfSkvLFxuXHRyZ2JSZWdFeCA9IC9yZ2JcXChcXHMqKFswLTldezEsM30pXFxzKixcXHMqKFswLTldezEsM30pXFxzKixcXHMqKFswLTldezEsM30pXFxzKlxcKS87XG5cbnZhciBDb2xvciA9IGZ1bmN0aW9uIChpbnB1dCkge1xuXHQvLyBkZWNsYXJlIHZhcmlhYmxlc1xuXHR2YXIgcmdiYSA9IFtdLCByZXN1bHQsIHN0b3BzO1xuXG5cdC8qKlxuXHQgKiBQYXJzZSB0aGUgaW5wdXQgY29sb3IgdG8gcmdiYSBhcnJheVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaW5wdXRcblx0ICovXG5cdGZ1bmN0aW9uIGluaXQoaW5wdXQpIHtcblxuXHRcdC8vIEdyYWRpZW50c1xuXHRcdGlmIChpbnB1dCAmJiBpbnB1dC5zdG9wcykge1xuXHRcdFx0c3RvcHMgPSBtYXAoaW5wdXQuc3RvcHMsIGZ1bmN0aW9uIChzdG9wKSB7XG5cdFx0XHRcdHJldHVybiBDb2xvcihzdG9wWzFdKTtcblx0XHRcdH0pO1xuXG5cdFx0Ly8gU29saWQgY29sb3JzXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIHJnYmFcblx0XHRcdHJlc3VsdCA9IHJnYmFSZWdFeC5leGVjKGlucHV0KTtcblx0XHRcdGlmIChyZXN1bHQpIHtcblx0XHRcdFx0cmdiYSA9IFtwSW50KHJlc3VsdFsxXSksIHBJbnQocmVzdWx0WzJdKSwgcEludChyZXN1bHRbM10pLCBwYXJzZUZsb2F0KHJlc3VsdFs0XSwgMTApXTtcblx0XHRcdH0gZWxzZSB7IFxuXHRcdFx0XHQvLyBoZXhcblx0XHRcdFx0cmVzdWx0ID0gaGV4UmVnRXguZXhlYyhpbnB1dCk7XG5cdFx0XHRcdGlmIChyZXN1bHQpIHtcblx0XHRcdFx0XHRyZ2JhID0gW3BJbnQocmVzdWx0WzFdLCAxNiksIHBJbnQocmVzdWx0WzJdLCAxNiksIHBJbnQocmVzdWx0WzNdLCAxNiksIDFdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIHJnYlxuXHRcdFx0XHRcdHJlc3VsdCA9IHJnYlJlZ0V4LmV4ZWMoaW5wdXQpO1xuXHRcdFx0XHRcdGlmIChyZXN1bHQpIHtcblx0XHRcdFx0XHRcdHJnYmEgPSBbcEludChyZXN1bHRbMV0pLCBwSW50KHJlc3VsdFsyXSksIHBJbnQocmVzdWx0WzNdKSwgMV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVx0XHRcblxuXHR9XG5cdC8qKlxuXHQgKiBSZXR1cm4gdGhlIGNvbG9yIGEgc3BlY2lmaWVkIGZvcm1hdFxuXHQgKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0XG5cdCAqL1xuXHRmdW5jdGlvbiBnZXQoZm9ybWF0KSB7XG5cdFx0dmFyIHJldDtcblxuXHRcdGlmIChzdG9wcykge1xuXHRcdFx0cmV0ID0gbWVyZ2UoaW5wdXQpO1xuXHRcdFx0cmV0LnN0b3BzID0gW10uY29uY2F0KHJldC5zdG9wcyk7XG5cdFx0XHRlYWNoKHN0b3BzLCBmdW5jdGlvbiAoc3RvcCwgaSkge1xuXHRcdFx0XHRyZXQuc3RvcHNbaV0gPSBbcmV0LnN0b3BzW2ldWzBdLCBzdG9wLmdldChmb3JtYXQpXTtcblx0XHRcdH0pO1xuXG5cdFx0Ly8gaXQncyBOYU4gaWYgZ3JhZGllbnQgY29sb3JzIG9uIGEgY29sdW1uIGNoYXJ0XG5cdFx0fSBlbHNlIGlmIChyZ2JhICYmICFpc05hTihyZ2JhWzBdKSkge1xuXHRcdFx0aWYgKGZvcm1hdCA9PT0gJ3JnYicpIHtcblx0XHRcdFx0cmV0ID0gJ3JnYignICsgcmdiYVswXSArICcsJyArIHJnYmFbMV0gKyAnLCcgKyByZ2JhWzJdICsgJyknO1xuXHRcdFx0fSBlbHNlIGlmIChmb3JtYXQgPT09ICdhJykge1xuXHRcdFx0XHRyZXQgPSByZ2JhWzNdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0ID0gJ3JnYmEoJyArIHJnYmEuam9pbignLCcpICsgJyknO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgPSBpbnB1dDtcblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fVxuXG5cdC8qKlxuXHQgKiBCcmlnaHRlbiB0aGUgY29sb3Jcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGFscGhhXG5cdCAqL1xuXHRmdW5jdGlvbiBicmlnaHRlbihhbHBoYSkge1xuXHRcdGlmIChzdG9wcykge1xuXHRcdFx0ZWFjaChzdG9wcywgZnVuY3Rpb24gKHN0b3ApIHtcblx0XHRcdFx0c3RvcC5icmlnaHRlbihhbHBoYSk7XG5cdFx0XHR9KTtcblx0XHRcblx0XHR9IGVsc2UgaWYgKGlzTnVtYmVyKGFscGhhKSAmJiBhbHBoYSAhPT0gMCkge1xuXHRcdFx0dmFyIGk7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7XG5cdFx0XHRcdHJnYmFbaV0gKz0gcEludChhbHBoYSAqIDI1NSk7XG5cblx0XHRcdFx0aWYgKHJnYmFbaV0gPCAwKSB7XG5cdFx0XHRcdFx0cmdiYVtpXSA9IDA7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHJnYmFbaV0gPiAyNTUpIHtcblx0XHRcdFx0XHRyZ2JhW2ldID0gMjU1O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cdC8qKlxuXHQgKiBTZXQgdGhlIGNvbG9yJ3Mgb3BhY2l0eSB0byBhIGdpdmVuIGFscGhhIHZhbHVlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBhbHBoYVxuXHQgKi9cblx0ZnVuY3Rpb24gc2V0T3BhY2l0eShhbHBoYSkge1xuXHRcdHJnYmFbM10gPSBhbHBoYTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8vIGluaXRpYWxpemU6IHBhcnNlIHRoZSBpbnB1dFxuXHRpbml0KGlucHV0KTtcblxuXHQvLyBwdWJsaWMgbWV0aG9kc1xuXHRyZXR1cm4ge1xuXHRcdGdldDogZ2V0LFxuXHRcdGJyaWdodGVuOiBicmlnaHRlbixcblx0XHRyZ2JhOiByZ2JhLFxuXHRcdHNldE9wYWNpdHk6IHNldE9wYWNpdHlcblx0fTtcbn07XG5cblxuLyoqXG4gKiBBIHdyYXBwZXIgb2JqZWN0IGZvciBTVkcgZWxlbWVudHNcbiAqL1xuZnVuY3Rpb24gU1ZHRWxlbWVudCgpIHt9XG5cblNWR0VsZW1lbnQucHJvdG90eXBlID0ge1xuXHRcblx0Ly8gRGVmYXVsdCBiYXNlIGZvciBhbmltYXRpb25cblx0b3BhY2l0eTogMSxcblx0Ly8gRm9yIGxhYmVscywgdGhlc2UgQ1NTIHByb3BlcnRpZXMgYXJlIGFwcGxpZWQgdG8gdGhlIDx0ZXh0PiBub2RlIGRpcmVjdGx5XG5cdHRleHRQcm9wczogWydmb250U2l6ZScsICdmb250V2VpZ2h0JywgJ2ZvbnRGYW1pbHknLCAnY29sb3InLCBcblx0XHQnbGluZUhlaWdodCcsICd3aWR0aCcsICd0ZXh0RGVjb3JhdGlvbicsICd0ZXh0U2hhZG93JywgJ0hjVGV4dFN0cm9rZSddLFxuXHRcblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdGhlIFNWRyByZW5kZXJlclxuXHQgKiBAcGFyYW0ge09iamVjdH0gcmVuZGVyZXJcblx0ICogQHBhcmFtIHtTdHJpbmd9IG5vZGVOYW1lXG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAocmVuZGVyZXIsIG5vZGVOYW1lKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzO1xuXHRcdHdyYXBwZXIuZWxlbWVudCA9IG5vZGVOYW1lID09PSAnc3BhbicgP1xuXHRcdFx0Y3JlYXRlRWxlbWVudChub2RlTmFtZSkgOlxuXHRcdFx0ZG9jLmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIG5vZGVOYW1lKTtcblx0XHR3cmFwcGVyLnJlbmRlcmVyID0gcmVuZGVyZXI7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogQW5pbWF0ZSBhIGdpdmVuIGF0dHJpYnV0ZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zIFRoZSBzYW1lIG9wdGlvbnMgYXMgaW4galF1ZXJ5IGFuaW1hdGlvblxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wbGV0ZSBGdW5jdGlvbiB0byBwZXJmb3JtIGF0IHRoZSBlbmQgb2YgYW5pbWF0aW9uXG5cdCAqL1xuXHRhbmltYXRlOiBmdW5jdGlvbiAocGFyYW1zLCBvcHRpb25zLCBjb21wbGV0ZSkge1xuXHRcdHZhciBhbmltT3B0aW9ucyA9IHBpY2sob3B0aW9ucywgZ2xvYmFsQW5pbWF0aW9uLCB0cnVlKTtcblx0XHRzdG9wKHRoaXMpOyAvLyBzdG9wIHJlZ2FyZGxlc3Mgb2YgYW5pbWF0aW9uIGFjdHVhbGx5IHJ1bm5pbmcsIG9yIHJldmVydGluZyB0byAuYXR0ciAoIzYwNylcblx0XHRpZiAoYW5pbU9wdGlvbnMpIHtcblx0XHRcdGFuaW1PcHRpb25zID0gbWVyZ2UoYW5pbU9wdGlvbnMsIHt9KTsgLy8jMjYyNVxuXHRcdFx0aWYgKGNvbXBsZXRlKSB7IC8vIGFsbG93cyB1c2luZyBhIGNhbGxiYWNrIHdpdGggdGhlIGdsb2JhbCBhbmltYXRpb24gd2l0aG91dCBvdmVyd3JpdGluZyBpdFxuXHRcdFx0XHRhbmltT3B0aW9ucy5jb21wbGV0ZSA9IGNvbXBsZXRlO1xuXHRcdFx0fVxuXHRcdFx0YW5pbWF0ZSh0aGlzLCBwYXJhbXMsIGFuaW1PcHRpb25zKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5hdHRyKHBhcmFtcyk7XG5cdFx0XHRpZiAoY29tcGxldGUpIHtcblx0XHRcdFx0Y29tcGxldGUoKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEJ1aWxkIGFuIFNWRyBncmFkaWVudCBvdXQgb2YgYSBjb21tb24gSmF2YVNjcmlwdCBjb25maWd1cmF0aW9uIG9iamVjdFxuXHQgKi9cblx0Y29sb3JHcmFkaWVudDogZnVuY3Rpb24gKGNvbG9yLCBwcm9wLCBlbGVtKSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlcixcblx0XHRcdGNvbG9yT2JqZWN0LFxuXHRcdFx0Z3JhZE5hbWUsXG5cdFx0XHRncmFkQXR0cixcblx0XHRcdGdyYWRpZW50cyxcblx0XHRcdGdyYWRpZW50T2JqZWN0LFxuXHRcdFx0c3RvcHMsXG5cdFx0XHRzdG9wQ29sb3IsXG5cdFx0XHRzdG9wT3BhY2l0eSxcblx0XHRcdHJhZGlhbFJlZmVyZW5jZSxcblx0XHRcdG4sXG5cdFx0XHRpZCxcblx0XHRcdGtleSA9IFtdO1xuXG5cdFx0Ly8gQXBwbHkgbGluZWFyIG9yIHJhZGlhbCBncmFkaWVudHNcblx0XHRpZiAoY29sb3IubGluZWFyR3JhZGllbnQpIHtcblx0XHRcdGdyYWROYW1lID0gJ2xpbmVhckdyYWRpZW50Jztcblx0XHR9IGVsc2UgaWYgKGNvbG9yLnJhZGlhbEdyYWRpZW50KSB7XG5cdFx0XHRncmFkTmFtZSA9ICdyYWRpYWxHcmFkaWVudCc7XG5cdFx0fVxuXG5cdFx0aWYgKGdyYWROYW1lKSB7XG5cdFx0XHRncmFkQXR0ciA9IGNvbG9yW2dyYWROYW1lXTtcblx0XHRcdGdyYWRpZW50cyA9IHJlbmRlcmVyLmdyYWRpZW50cztcblx0XHRcdHN0b3BzID0gY29sb3Iuc3RvcHM7XG5cdFx0XHRyYWRpYWxSZWZlcmVuY2UgPSBlbGVtLnJhZGlhbFJlZmVyZW5jZTtcblxuXHRcdFx0Ly8gS2VlcCA8IDIuMiBrb21wYXRpYmlsaXR5XG5cdFx0XHRpZiAoaXNBcnJheShncmFkQXR0cikpIHtcblx0XHRcdFx0Y29sb3JbZ3JhZE5hbWVdID0gZ3JhZEF0dHIgPSB7XG5cdFx0XHRcdFx0eDE6IGdyYWRBdHRyWzBdLFxuXHRcdFx0XHRcdHkxOiBncmFkQXR0clsxXSxcblx0XHRcdFx0XHR4MjogZ3JhZEF0dHJbMl0sXG5cdFx0XHRcdFx0eTI6IGdyYWRBdHRyWzNdLFxuXHRcdFx0XHRcdGdyYWRpZW50VW5pdHM6ICd1c2VyU3BhY2VPblVzZSdcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29ycmVjdCB0aGUgcmFkaWFsIGdyYWRpZW50IGZvciB0aGUgcmFkaWFsIHJlZmVyZW5jZSBzeXN0ZW1cblx0XHRcdGlmIChncmFkTmFtZSA9PT0gJ3JhZGlhbEdyYWRpZW50JyAmJiByYWRpYWxSZWZlcmVuY2UgJiYgIWRlZmluZWQoZ3JhZEF0dHIuZ3JhZGllbnRVbml0cykpIHtcblx0XHRcdFx0Z3JhZEF0dHIgPSBtZXJnZShncmFkQXR0ciwge1xuXHRcdFx0XHRcdGN4OiAocmFkaWFsUmVmZXJlbmNlWzBdIC0gcmFkaWFsUmVmZXJlbmNlWzJdIC8gMikgKyBncmFkQXR0ci5jeCAqIHJhZGlhbFJlZmVyZW5jZVsyXSxcblx0XHRcdFx0XHRjeTogKHJhZGlhbFJlZmVyZW5jZVsxXSAtIHJhZGlhbFJlZmVyZW5jZVsyXSAvIDIpICsgZ3JhZEF0dHIuY3kgKiByYWRpYWxSZWZlcmVuY2VbMl0sXG5cdFx0XHRcdFx0cjogZ3JhZEF0dHIuciAqIHJhZGlhbFJlZmVyZW5jZVsyXSxcblx0XHRcdFx0XHRncmFkaWVudFVuaXRzOiAndXNlclNwYWNlT25Vc2UnXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdWlsZCB0aGUgdW5pcXVlIGtleSB0byBkZXRlY3Qgd2hldGhlciB3ZSBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBlbGVtZW50ICgjMTI4Milcblx0XHRcdGZvciAobiBpbiBncmFkQXR0cikge1xuXHRcdFx0XHRpZiAobiAhPT0gJ2lkJykge1xuXHRcdFx0XHRcdGtleS5wdXNoKG4sIGdyYWRBdHRyW25dKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Zm9yIChuIGluIHN0b3BzKSB7XG5cdFx0XHRcdGtleS5wdXNoKHN0b3BzW25dKTtcblx0XHRcdH1cblx0XHRcdGtleSA9IGtleS5qb2luKCcsJyk7XG5cblx0XHRcdC8vIENoZWNrIGlmIGEgZ3JhZGllbnQgb2JqZWN0IHdpdGggdGhlIHNhbWUgY29uZmlnIG9iamVjdCBpcyBjcmVhdGVkIHdpdGhpbiB0aGlzIHJlbmRlcmVyXG5cdFx0XHRpZiAoZ3JhZGllbnRzW2tleV0pIHtcblx0XHRcdFx0aWQgPSBncmFkaWVudHNba2V5XS5hdHRyKCdpZCcpO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIFNldCB0aGUgaWQgYW5kIGNyZWF0ZSB0aGUgZWxlbWVudFxuXHRcdFx0XHRncmFkQXR0ci5pZCA9IGlkID0gUFJFRklYICsgaWRDb3VudGVyKys7XG5cdFx0XHRcdGdyYWRpZW50c1trZXldID0gZ3JhZGllbnRPYmplY3QgPSByZW5kZXJlci5jcmVhdGVFbGVtZW50KGdyYWROYW1lKVxuXHRcdFx0XHRcdC5hdHRyKGdyYWRBdHRyKVxuXHRcdFx0XHRcdC5hZGQocmVuZGVyZXIuZGVmcyk7XG5cblxuXHRcdFx0XHQvLyBUaGUgZ3JhZGllbnQgbmVlZHMgdG8ga2VlcCBhIGxpc3Qgb2Ygc3RvcHMgdG8gYmUgYWJsZSB0byBkZXN0cm95IHRoZW1cblx0XHRcdFx0Z3JhZGllbnRPYmplY3Quc3RvcHMgPSBbXTtcblx0XHRcdFx0ZWFjaChzdG9wcywgZnVuY3Rpb24gKHN0b3ApIHtcblx0XHRcdFx0XHR2YXIgc3RvcE9iamVjdDtcblx0XHRcdFx0XHRpZiAoc3RvcFsxXS5pbmRleE9mKCdyZ2JhJykgPT09IDApIHtcblx0XHRcdFx0XHRcdGNvbG9yT2JqZWN0ID0gQ29sb3Ioc3RvcFsxXSk7XG5cdFx0XHRcdFx0XHRzdG9wQ29sb3IgPSBjb2xvck9iamVjdC5nZXQoJ3JnYicpO1xuXHRcdFx0XHRcdFx0c3RvcE9wYWNpdHkgPSBjb2xvck9iamVjdC5nZXQoJ2EnKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c3RvcENvbG9yID0gc3RvcFsxXTtcblx0XHRcdFx0XHRcdHN0b3BPcGFjaXR5ID0gMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c3RvcE9iamVjdCA9IHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3N0b3AnKS5hdHRyKHtcblx0XHRcdFx0XHRcdG9mZnNldDogc3RvcFswXSxcblx0XHRcdFx0XHRcdCdzdG9wLWNvbG9yJzogc3RvcENvbG9yLFxuXHRcdFx0XHRcdFx0J3N0b3Atb3BhY2l0eSc6IHN0b3BPcGFjaXR5XG5cdFx0XHRcdFx0fSkuYWRkKGdyYWRpZW50T2JqZWN0KTtcblxuXHRcdFx0XHRcdC8vIEFkZCB0aGUgc3RvcCBlbGVtZW50IHRvIHRoZSBncmFkaWVudFxuXHRcdFx0XHRcdGdyYWRpZW50T2JqZWN0LnN0b3BzLnB1c2goc3RvcE9iamVjdCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIHJlZmVyZW5jZSB0byB0aGUgZ3JhZGllbnQgb2JqZWN0XG5cdFx0XHRlbGVtLnNldEF0dHJpYnV0ZShwcm9wLCAndXJsKCcgKyByZW5kZXJlci51cmwgKyAnIycgKyBpZCArICcpJyk7XG5cdFx0fSBcblx0fSxcblxuXHQvKipcblx0ICogU2V0IG9yIGdldCBhIGdpdmVuIGF0dHJpYnV0ZVxuXHQgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IGhhc2hcblx0ICogQHBhcmFtIHtNaXhlZHxVbmRlZmluZWR9IHZhbFxuXHQgKi9cblx0YXR0cjogZnVuY3Rpb24gKGhhc2gsIHZhbCkge1xuXHRcdHZhciBrZXksXG5cdFx0XHR2YWx1ZSxcblx0XHRcdGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsXG5cdFx0XHRoYXNTZXRTeW1ib2xTaXplLFxuXHRcdFx0cmV0ID0gdGhpcyxcblx0XHRcdHNraXBBdHRyO1xuXG5cdFx0Ly8gc2luZ2xlIGtleS12YWx1ZSBwYWlyXG5cdFx0aWYgKHR5cGVvZiBoYXNoID09PSAnc3RyaW5nJyAmJiB2YWwgIT09IFVOREVGSU5FRCkge1xuXHRcdFx0a2V5ID0gaGFzaDtcblx0XHRcdGhhc2ggPSB7fTtcblx0XHRcdGhhc2hba2V5XSA9IHZhbDtcblx0XHR9XG5cblx0XHQvLyB1c2VkIGFzIGEgZ2V0dGVyOiBmaXJzdCBhcmd1bWVudCBpcyBhIHN0cmluZywgc2Vjb25kIGlzIHVuZGVmaW5lZFxuXHRcdGlmICh0eXBlb2YgaGFzaCA9PT0gJ3N0cmluZycpIHtcblx0XHRcdHJldCA9ICh0aGlzW2hhc2ggKyAnR2V0dGVyJ10gfHwgdGhpcy5fZGVmYXVsdEdldHRlcikuY2FsbCh0aGlzLCBoYXNoLCBlbGVtZW50KTtcblx0XHRcblx0XHQvLyBzZXR0ZXJcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRmb3IgKGtleSBpbiBoYXNoKSB7XG5cdFx0XHRcdHZhbHVlID0gaGFzaFtrZXldO1xuXHRcdFx0XHRza2lwQXR0ciA9IGZhbHNlO1xuXG5cblxuXHRcdFx0XHRpZiAodGhpcy5zeW1ib2xOYW1lICYmIC9eKHh8eXx3aWR0aHxoZWlnaHR8cnxzdGFydHxlbmR8aW5uZXJSfGFuY2hvclh8YW5jaG9yWSkvLnRlc3Qoa2V5KSkge1xuXHRcdFx0XHRcdGlmICghaGFzU2V0U3ltYm9sU2l6ZSkge1xuXHRcdFx0XHRcdFx0dGhpcy5zeW1ib2xBdHRyKGhhc2gpO1xuXHRcdFx0XHRcdFx0aGFzU2V0U3ltYm9sU2l6ZSA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHNraXBBdHRyID0gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh0aGlzLnJvdGF0aW9uICYmIChrZXkgPT09ICd4JyB8fCBrZXkgPT09ICd5JykpIHtcblx0XHRcdFx0XHR0aGlzLmRvVHJhbnNmb3JtID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0aWYgKCFza2lwQXR0cikge1xuXHRcdFx0XHRcdCh0aGlzW2tleSArICdTZXR0ZXInXSB8fCB0aGlzLl9kZWZhdWx0U2V0dGVyKS5jYWxsKHRoaXMsIHZhbHVlLCBrZXksIGVsZW1lbnQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTGV0IHRoZSBzaGFkb3cgZm9sbG93IHRoZSBtYWluIGVsZW1lbnRcblx0XHRcdFx0aWYgKHRoaXMuc2hhZG93cyAmJiAvXih3aWR0aHxoZWlnaHR8dmlzaWJpbGl0eXx4fHl8ZHx0cmFuc2Zvcm18Y3h8Y3l8cikkLy50ZXN0KGtleSkpIHtcblx0XHRcdFx0XHR0aGlzLnVwZGF0ZVNoYWRvd3Moa2V5LCB2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVXBkYXRlIHRyYW5zZm9ybS4gRG8gdGhpcyBvdXRzaWRlIHRoZSBsb29wIHRvIHByZXZlbnQgcmVkdW5kYW50IHVwZGF0aW5nIGZvciBiYXRjaCBzZXR0aW5nXG5cdFx0XHQvLyBvZiBhdHRyaWJ1dGVzLlxuXHRcdFx0aWYgKHRoaXMuZG9UcmFuc2Zvcm0pIHtcblx0XHRcdFx0dGhpcy51cGRhdGVUcmFuc2Zvcm0oKTtcblx0XHRcdFx0dGhpcy5kb1RyYW5zZm9ybSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHR1cGRhdGVTaGFkb3dzOiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHRcdHZhciBzaGFkb3dzID0gdGhpcy5zaGFkb3dzLFxuXHRcdFx0aSA9IHNoYWRvd3MubGVuZ3RoO1xuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHNoYWRvd3NbaV0uc2V0QXR0cmlidXRlKFxuXHRcdFx0XHRrZXksXG5cdFx0XHRcdGtleSA9PT0gJ2hlaWdodCcgP1xuXHRcdFx0XHRcdG1hdGhNYXgodmFsdWUgLSAoc2hhZG93c1tpXS5jdXRIZWlnaHQgfHwgMCksIDApIDpcblx0XHRcdFx0XHRrZXkgPT09ICdkJyA/IHRoaXMuZCA6IHZhbHVlXG5cdFx0XHQpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQWRkIGEgY2xhc3MgbmFtZSB0byBhbiBlbGVtZW50XG5cdCAqL1xuXHRhZGRDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuXHRcdFx0Y3VycmVudENsYXNzTmFtZSA9IGF0dHIoZWxlbWVudCwgJ2NsYXNzJykgfHwgJyc7XG5cblx0XHRpZiAoY3VycmVudENsYXNzTmFtZS5pbmRleE9mKGNsYXNzTmFtZSkgPT09IC0xKSB7XG5cdFx0XHRhdHRyKGVsZW1lbnQsICdjbGFzcycsIGN1cnJlbnRDbGFzc05hbWUgKyAnICcgKyBjbGFzc05hbWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblx0LyogaGFzQ2xhc3MgYW5kIHJlbW92ZUNsYXNzIGFyZSBub3QgKHlldCkgbmVlZGVkXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG5cdFx0cmV0dXJuIGF0dHIodGhpcy5lbGVtZW50LCAnY2xhc3MnKS5pbmRleE9mKGNsYXNzTmFtZSkgIT09IC0xO1xuXHR9LFxuXHRyZW1vdmVDbGFzczogZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xuXHRcdGF0dHIodGhpcy5lbGVtZW50LCAnY2xhc3MnLCBhdHRyKHRoaXMuZWxlbWVudCwgJ2NsYXNzJykucmVwbGFjZShjbGFzc05hbWUsICcnKSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cdCovXG5cblx0LyoqXG5cdCAqIElmIG9uZSBvZiB0aGUgc3ltYm9sIHNpemUgYWZmZWN0aW5nIHBhcmFtZXRlcnMgYXJlIGNoYW5nZWQsXG5cdCAqIGNoZWNrIGFsbCB0aGUgb3RoZXJzIG9ubHkgb25jZSBmb3IgZWFjaCBjYWxsIHRvIGFuIGVsZW1lbnQnc1xuXHQgKiAuYXR0cigpIG1ldGhvZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gaGFzaFxuXHQgKi9cblx0c3ltYm9sQXR0cjogZnVuY3Rpb24gKGhhc2gpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXM7XG5cblx0XHRlYWNoKFsneCcsICd5JywgJ3InLCAnc3RhcnQnLCAnZW5kJywgJ3dpZHRoJywgJ2hlaWdodCcsICdpbm5lclInLCAnYW5jaG9yWCcsICdhbmNob3JZJ10sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdHdyYXBwZXJba2V5XSA9IHBpY2soaGFzaFtrZXldLCB3cmFwcGVyW2tleV0pO1xuXHRcdH0pO1xuXG5cdFx0d3JhcHBlci5hdHRyKHtcblx0XHRcdGQ6IHdyYXBwZXIucmVuZGVyZXIuc3ltYm9sc1t3cmFwcGVyLnN5bWJvbE5hbWVdKFxuXHRcdFx0XHR3cmFwcGVyLngsXG5cdFx0XHRcdHdyYXBwZXIueSxcblx0XHRcdFx0d3JhcHBlci53aWR0aCxcblx0XHRcdFx0d3JhcHBlci5oZWlnaHQsXG5cdFx0XHRcdHdyYXBwZXJcblx0XHRcdClcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogQXBwbHkgYSBjbGlwcGluZyBwYXRoIHRvIHRoaXMgb2JqZWN0XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpZFxuXHQgKi9cblx0Y2xpcDogZnVuY3Rpb24gKGNsaXBSZWN0KSB7XG5cdFx0cmV0dXJuIHRoaXMuYXR0cignY2xpcC1wYXRoJywgY2xpcFJlY3QgPyAndXJsKCcgKyB0aGlzLnJlbmRlcmVyLnVybCArICcjJyArIGNsaXBSZWN0LmlkICsgJyknIDogTk9ORSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZSB0aGUgY29vcmRpbmF0ZXMgbmVlZGVkIGZvciBkcmF3aW5nIGEgcmVjdGFuZ2xlIGNyaXNwbHkgYW5kIHJldHVybiB0aGVcblx0ICogY2FsY3VsYXRlZCBhdHRyaWJ1dGVzXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdHJva2VXaWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKi9cblx0Y3Jpc3A6IGZ1bmN0aW9uIChyZWN0KSB7XG5cblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHRrZXksXG5cdFx0XHRhdHRyaWJzID0ge30sXG5cdFx0XHRub3JtYWxpemVyLFxuXHRcdFx0c3Ryb2tlV2lkdGggPSByZWN0LnN0cm9rZVdpZHRoIHx8IHdyYXBwZXIuc3Ryb2tlV2lkdGggfHwgMDtcblxuXHRcdG5vcm1hbGl6ZXIgPSBtYXRoUm91bmQoc3Ryb2tlV2lkdGgpICUgMiAvIDI7IC8vIG1hdGhSb3VuZCBiZWNhdXNlIHN0cm9rZVdpZHRoIGNhbiBzb21ldGltZXMgaGF2ZSByb3VuZG9mZiBlcnJvcnNcblxuXHRcdC8vIG5vcm1hbGl6ZSBmb3IgY3Jpc3AgZWRnZXNcblx0XHRyZWN0LnggPSBtYXRoRmxvb3IocmVjdC54IHx8IHdyYXBwZXIueCB8fCAwKSArIG5vcm1hbGl6ZXI7XG5cdFx0cmVjdC55ID0gbWF0aEZsb29yKHJlY3QueSB8fCB3cmFwcGVyLnkgfHwgMCkgKyBub3JtYWxpemVyO1xuXHRcdHJlY3Qud2lkdGggPSBtYXRoRmxvb3IoKHJlY3Qud2lkdGggfHwgd3JhcHBlci53aWR0aCB8fCAwKSAtIDIgKiBub3JtYWxpemVyKTtcblx0XHRyZWN0LmhlaWdodCA9IG1hdGhGbG9vcigocmVjdC5oZWlnaHQgfHwgd3JhcHBlci5oZWlnaHQgfHwgMCkgLSAyICogbm9ybWFsaXplcik7XG5cdFx0cmVjdC5zdHJva2VXaWR0aCA9IHN0cm9rZVdpZHRoO1xuXG5cdFx0Zm9yIChrZXkgaW4gcmVjdCkge1xuXHRcdFx0aWYgKHdyYXBwZXJba2V5XSAhPT0gcmVjdFtrZXldKSB7IC8vIG9ubHkgc2V0IGF0dHJpYnV0ZSBpZiBjaGFuZ2VkXG5cdFx0XHRcdHdyYXBwZXJba2V5XSA9IGF0dHJpYnNba2V5XSA9IHJlY3Rba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gYXR0cmlicztcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHN0eWxlcyBmb3IgdGhlIGVsZW1lbnRcblx0ICogQHBhcmFtIHtPYmplY3R9IHN0eWxlc1xuXHQgKi9cblx0Y3NzOiBmdW5jdGlvbiAoc3R5bGVzKSB7XG5cdFx0dmFyIGVsZW1XcmFwcGVyID0gdGhpcyxcblx0XHRcdG9sZFN0eWxlcyA9IGVsZW1XcmFwcGVyLnN0eWxlcyxcblx0XHRcdG5ld1N0eWxlcyA9IHt9LFxuXHRcdFx0ZWxlbSA9IGVsZW1XcmFwcGVyLmVsZW1lbnQsXG5cdFx0XHR0ZXh0V2lkdGgsXG5cdFx0XHRuLFxuXHRcdFx0c2VyaWFsaXplZENzcyA9ICcnLFxuXHRcdFx0aHlwaGVuYXRlLFxuXHRcdFx0aGFzTmV3ID0gIW9sZFN0eWxlcztcblxuXHRcdC8vIGNvbnZlcnQgbGVnYWN5XG5cdFx0aWYgKHN0eWxlcyAmJiBzdHlsZXMuY29sb3IpIHtcblx0XHRcdHN0eWxlcy5maWxsID0gc3R5bGVzLmNvbG9yO1xuXHRcdH1cblxuXHRcdC8vIEZpbHRlciBvdXQgZXhpc3Rpbmcgc3R5bGVzIHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlICgjMjY0MClcblx0XHRpZiAob2xkU3R5bGVzKSB7XG5cdFx0XHRmb3IgKG4gaW4gc3R5bGVzKSB7XG5cdFx0XHRcdGlmIChzdHlsZXNbbl0gIT09IG9sZFN0eWxlc1tuXSkge1xuXHRcdFx0XHRcdG5ld1N0eWxlc1tuXSA9IHN0eWxlc1tuXTtcblx0XHRcdFx0XHRoYXNOZXcgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChoYXNOZXcpIHtcblx0XHRcdHRleHRXaWR0aCA9IGVsZW1XcmFwcGVyLnRleHRXaWR0aCA9IHN0eWxlcyAmJiBzdHlsZXMud2lkdGggJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSAndGV4dCcgJiYgcEludChzdHlsZXMud2lkdGgpO1xuXG5cdFx0XHQvLyBNZXJnZSB0aGUgbmV3IHN0eWxlcyB3aXRoIHRoZSBvbGQgb25lc1xuXHRcdFx0aWYgKG9sZFN0eWxlcykge1xuXHRcdFx0XHRzdHlsZXMgPSBleHRlbmQoXG5cdFx0XHRcdFx0b2xkU3R5bGVzLFxuXHRcdFx0XHRcdG5ld1N0eWxlc1xuXHRcdFx0XHQpO1xuXHRcdFx0fVx0XHRcblxuXHRcdFx0Ly8gc3RvcmUgb2JqZWN0XG5cdFx0XHRlbGVtV3JhcHBlci5zdHlsZXMgPSBzdHlsZXM7XG5cblx0XHRcdGlmICh0ZXh0V2lkdGggJiYgKHVzZUNhblZHIHx8ICghaGFzU1ZHICYmIGVsZW1XcmFwcGVyLnJlbmRlcmVyLmZvckV4cG9ydCkpKSB7XG5cdFx0XHRcdGRlbGV0ZSBzdHlsZXMud2lkdGg7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHNlcmlhbGl6ZSBhbmQgc2V0IHN0eWxlIGF0dHJpYnV0ZVxuXHRcdFx0aWYgKGlzSUUgJiYgIWhhc1NWRykge1xuXHRcdFx0XHRjc3MoZWxlbVdyYXBwZXIuZWxlbWVudCwgc3R5bGVzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8qanNsaW50IHVucGFyYW06IHRydWUqL1xuXHRcdFx0XHRoeXBoZW5hdGUgPSBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gJy0nICsgYi50b0xvd2VyQ2FzZSgpOyB9O1xuXHRcdFx0XHQvKmpzbGludCB1bnBhcmFtOiBmYWxzZSovXG5cdFx0XHRcdGZvciAobiBpbiBzdHlsZXMpIHtcblx0XHRcdFx0XHRzZXJpYWxpemVkQ3NzICs9IG4ucmVwbGFjZSgvKFtBLVpdKS9nLCBoeXBoZW5hdGUpICsgJzonICsgc3R5bGVzW25dICsgJzsnO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGF0dHIoZWxlbSwgJ3N0eWxlJywgc2VyaWFsaXplZENzcyk7IC8vICMxODgxXG5cdFx0XHR9XG5cblxuXHRcdFx0Ly8gcmUtYnVpbGQgdGV4dFxuXHRcdFx0aWYgKHRleHRXaWR0aCAmJiBlbGVtV3JhcHBlci5hZGRlZCkge1xuXHRcdFx0XHRlbGVtV3JhcHBlci5yZW5kZXJlci5idWlsZFRleHQoZWxlbVdyYXBwZXIpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBlbGVtV3JhcHBlcjtcblx0fSxcblxuXHQvKipcblx0ICogQWRkIGFuIGV2ZW50IGxpc3RlbmVyXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGVcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuXHQgKi9cblx0b246IGZ1bmN0aW9uIChldmVudFR5cGUsIGhhbmRsZXIpIHtcblx0XHR2YXIgc3ZnRWxlbWVudCA9IHRoaXMsXG5cdFx0XHRlbGVtZW50ID0gc3ZnRWxlbWVudC5lbGVtZW50O1xuXHRcdFxuXHRcdC8vIHRvdWNoXG5cdFx0aWYgKGhhc1RvdWNoICYmIGV2ZW50VHlwZSA9PT0gJ2NsaWNrJykge1xuXHRcdFx0ZWxlbWVudC5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZSkge1x0XHRcdFxuXHRcdFx0XHRzdmdFbGVtZW50LnRvdWNoRXZlbnRGaXJlZCA9IERhdGUubm93KCk7XHRcdFx0XHRcblx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRoYW5kbGVyLmNhbGwoZWxlbWVudCwgZSk7XG5cdFx0XHR9O1xuXHRcdFx0ZWxlbWVudC5vbmNsaWNrID0gZnVuY3Rpb24gKGUpIHtcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcblx0XHRcdFx0aWYgKHVzZXJBZ2VudC5pbmRleE9mKCdBbmRyb2lkJykgPT09IC0xIHx8IERhdGUubm93KCkgLSAoc3ZnRWxlbWVudC50b3VjaEV2ZW50RmlyZWQgfHwgMCkgPiAxMTAwKSB7IC8vICMyMjY5XG5cdFx0XHRcdFx0aGFuZGxlci5jYWxsKGVsZW1lbnQsIGUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1x0XHRcdFxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBzaW1wbGVzdCBwb3NzaWJsZSBldmVudCBtb2RlbCBmb3IgaW50ZXJuYWwgdXNlXG5cdFx0XHRlbGVtZW50WydvbicgKyBldmVudFR5cGVdID0gaGFuZGxlcjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgY29vcmRpbmF0ZXMgbmVlZGVkIHRvIGRyYXcgYSBjb25zaXN0ZW50IHJhZGlhbCBncmFkaWVudCBhY3Jvc3Ncblx0ICogcGllIHNsaWNlcyByZWdhcmRsZXNzIG9mIHBvc2l0aW9uaW5nIGluc2lkZSB0aGUgY2hhcnQuIFRoZSBmb3JtYXQgaXNcblx0ICogW2NlbnRlclgsIGNlbnRlclksIGRpYW1ldGVyXSBpbiBwaXhlbHMuXG5cdCAqL1xuXHRzZXRSYWRpYWxSZWZlcmVuY2U6IGZ1bmN0aW9uIChjb29yZGluYXRlcykge1xuXHRcdHRoaXMuZWxlbWVudC5yYWRpYWxSZWZlcmVuY2UgPSBjb29yZGluYXRlcztcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogTW92ZSBhbiBvYmplY3QgYW5kIGl0cyBjaGlsZHJlbiBieSB4IGFuZCB5IHZhbHVlc1xuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKi9cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoeCwgeSkge1xuXHRcdHJldHVybiB0aGlzLmF0dHIoe1xuXHRcdFx0dHJhbnNsYXRlWDogeCxcblx0XHRcdHRyYW5zbGF0ZVk6IHlcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogSW52ZXJ0IGEgZ3JvdXAsIHJvdGF0ZSBhbmQgZmxpcFxuXHQgKi9cblx0aW52ZXJ0OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzO1xuXHRcdHdyYXBwZXIuaW52ZXJ0ZWQgPSB0cnVlO1xuXHRcdHdyYXBwZXIudXBkYXRlVHJhbnNmb3JtKCk7XG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFByaXZhdGUgbWV0aG9kIHRvIHVwZGF0ZSB0aGUgdHJhbnNmb3JtIGF0dHJpYnV0ZSBiYXNlZCBvbiBpbnRlcm5hbFxuXHQgKiBwcm9wZXJ0aWVzXG5cdCAqL1xuXHR1cGRhdGVUcmFuc2Zvcm06IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHR0cmFuc2xhdGVYID0gd3JhcHBlci50cmFuc2xhdGVYIHx8IDAsXG5cdFx0XHR0cmFuc2xhdGVZID0gd3JhcHBlci50cmFuc2xhdGVZIHx8IDAsXG5cdFx0XHRzY2FsZVggPSB3cmFwcGVyLnNjYWxlWCxcblx0XHRcdHNjYWxlWSA9IHdyYXBwZXIuc2NhbGVZLFxuXHRcdFx0aW52ZXJ0ZWQgPSB3cmFwcGVyLmludmVydGVkLFxuXHRcdFx0cm90YXRpb24gPSB3cmFwcGVyLnJvdGF0aW9uLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHRyYW5zZm9ybTtcblxuXHRcdC8vIGZsaXBwaW5nIGFmZmVjdHMgdHJhbnNsYXRlIGFzIGFkanVzdG1lbnQgZm9yIGZsaXBwaW5nIGFyb3VuZCB0aGUgZ3JvdXAncyBheGlzXG5cdFx0aWYgKGludmVydGVkKSB7XG5cdFx0XHR0cmFuc2xhdGVYICs9IHdyYXBwZXIuYXR0cignd2lkdGgnKTtcblx0XHRcdHRyYW5zbGF0ZVkgKz0gd3JhcHBlci5hdHRyKCdoZWlnaHQnKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSB0cmFuc2xhdGUuIE5lYXJseSBhbGwgdHJhbnNmb3JtZWQgZWxlbWVudHMgaGF2ZSB0cmFuc2xhdGlvbiwgc28gaW5zdGVhZFxuXHRcdC8vIG9mIGNoZWNraW5nIGZvciB0cmFuc2xhdGUgPSAwLCBkbyBpdCBhbHdheXMgKCMxNzY3LCAjMTg0NikuXG5cdFx0dHJhbnNmb3JtID0gWyd0cmFuc2xhdGUoJyArIHRyYW5zbGF0ZVggKyAnLCcgKyB0cmFuc2xhdGVZICsgJyknXTtcblxuXHRcdC8vIGFwcGx5IHJvdGF0aW9uXG5cdFx0aWYgKGludmVydGVkKSB7XG5cdFx0XHR0cmFuc2Zvcm0ucHVzaCgncm90YXRlKDkwKSBzY2FsZSgtMSwxKScpO1xuXHRcdH0gZWxzZSBpZiAocm90YXRpb24pIHsgLy8gdGV4dCByb3RhdGlvblxuXHRcdFx0dHJhbnNmb3JtLnB1c2goJ3JvdGF0ZSgnICsgcm90YXRpb24gKyAnICcgKyAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3gnKSB8fCAwKSArICcgJyArIChlbGVtZW50LmdldEF0dHJpYnV0ZSgneScpIHx8IDApICsgJyknKTtcblx0XHR9XG5cblx0XHQvLyBhcHBseSBzY2FsZVxuXHRcdGlmIChkZWZpbmVkKHNjYWxlWCkgfHwgZGVmaW5lZChzY2FsZVkpKSB7XG5cdFx0XHR0cmFuc2Zvcm0ucHVzaCgnc2NhbGUoJyArIHBpY2soc2NhbGVYLCAxKSArICcgJyArIHBpY2soc2NhbGVZLCAxKSArICcpJyk7XG5cdFx0fVxuXG5cdFx0aWYgKHRyYW5zZm9ybS5sZW5ndGgpIHtcblx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLCB0cmFuc2Zvcm0uam9pbignICcpKTtcblx0XHR9XG5cdH0sXG5cdC8qKlxuXHQgKiBCcmluZyB0aGUgZWxlbWVudCB0byB0aGUgZnJvbnRcblx0ICovXG5cdHRvRnJvbnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblx0XHRlbGVtZW50LnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblxuXHQvKipcblx0ICogQnJlYWsgZG93biBhbGlnbm1lbnQgb3B0aW9ucyBsaWtlIGFsaWduLCB2ZXJ0aWNhbEFsaWduLCB4IGFuZCB5XG5cdCAqIHRvIHggYW5kIHkgcmVsYXRpdmUgdG8gdGhlIGNoYXJ0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gYWxpZ25PcHRpb25zXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gYWxpZ25CeVRyYW5zbGF0ZVxuXHQgKiBAcGFyYW0ge1N0cmluZ1tPYmplY3R9IGJveCBUaGUgYm94IHRvIGFsaWduIHRvLCBuZWVkcyBhIHdpZHRoIGFuZCBoZWlnaHQuIFdoZW4gdGhlXG5cdCAqICAgICAgICBib3ggaXMgYSBzdHJpbmcsIGl0IHJlZmVycyB0byBhbiBvYmplY3QgaW4gdGhlIFJlbmRlcmVyLiBGb3IgZXhhbXBsZSwgd2hlblxuXHQgKiAgICAgICAgYm94IGlzICdzcGFjaW5nQm94JywgaXQgcmVmZXJzIHRvIFJlbmRlcmVyLnNwYWNpbmdCb3ggd2hpY2ggaG9sZHMgd2lkdGgsIGhlaWdodFxuXHQgKiAgICAgICAgeCBhbmQgeSBwcm9wZXJ0aWVzLlxuXHQgKlxuXHQgKi9cblx0YWxpZ246IGZ1bmN0aW9uIChhbGlnbk9wdGlvbnMsIGFsaWduQnlUcmFuc2xhdGUsIGJveCkge1xuXHRcdHZhciBhbGlnbixcblx0XHRcdHZBbGlnbixcblx0XHRcdHgsXG5cdFx0XHR5LFxuXHRcdFx0YXR0cmlicyA9IHt9LFxuXHRcdFx0YWxpZ25Ubyxcblx0XHRcdHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlcixcblx0XHRcdGFsaWduZWRPYmplY3RzID0gcmVuZGVyZXIuYWxpZ25lZE9iamVjdHM7XG5cblx0XHQvLyBGaXJzdCBjYWxsIG9uIGluc3RhbmNpYXRlXG5cdFx0aWYgKGFsaWduT3B0aW9ucykge1xuXHRcdFx0dGhpcy5hbGlnbk9wdGlvbnMgPSBhbGlnbk9wdGlvbnM7XG5cdFx0XHR0aGlzLmFsaWduQnlUcmFuc2xhdGUgPSBhbGlnbkJ5VHJhbnNsYXRlO1xuXHRcdFx0aWYgKCFib3ggfHwgaXNTdHJpbmcoYm94KSkgeyAvLyBib3hlcyBvdGhlciB0aGFuIHJlbmRlcmVyIGhhbmRsZSB0aGlzIGludGVybmFsbHlcblx0XHRcdFx0dGhpcy5hbGlnblRvID0gYWxpZ25UbyA9IGJveCB8fCAncmVuZGVyZXInO1xuXHRcdFx0XHRlcmFzZShhbGlnbmVkT2JqZWN0cywgdGhpcyk7IC8vIHByZXZlbnQgZHVwbGljYXRlcywgbGlrZSBsZWdlbmRHcm91cCBhZnRlciByZXNpemVcblx0XHRcdFx0YWxpZ25lZE9iamVjdHMucHVzaCh0aGlzKTtcblx0XHRcdFx0Ym94ID0gbnVsbDsgLy8gcmVhc3NpZ24gaXQgYmVsb3dcblx0XHRcdH1cblxuXHRcdC8vIFdoZW4gY2FsbGVkIG9uIHJlc2l6ZSwgbm8gYXJndW1lbnRzIGFyZSBzdXBwbGllZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbGlnbk9wdGlvbnMgPSB0aGlzLmFsaWduT3B0aW9ucztcblx0XHRcdGFsaWduQnlUcmFuc2xhdGUgPSB0aGlzLmFsaWduQnlUcmFuc2xhdGU7XG5cdFx0XHRhbGlnblRvID0gdGhpcy5hbGlnblRvO1xuXHRcdH1cblxuXHRcdGJveCA9IHBpY2soYm94LCByZW5kZXJlclthbGlnblRvXSwgcmVuZGVyZXIpO1xuXG5cdFx0Ly8gQXNzaWduIHZhcmlhYmxlc1xuXHRcdGFsaWduID0gYWxpZ25PcHRpb25zLmFsaWduO1xuXHRcdHZBbGlnbiA9IGFsaWduT3B0aW9ucy52ZXJ0aWNhbEFsaWduO1xuXHRcdHggPSAoYm94LnggfHwgMCkgKyAoYWxpZ25PcHRpb25zLnggfHwgMCk7IC8vIGRlZmF1bHQ6IGxlZnQgYWxpZ25cblx0XHR5ID0gKGJveC55IHx8IDApICsgKGFsaWduT3B0aW9ucy55IHx8IDApOyAvLyBkZWZhdWx0OiB0b3AgYWxpZ25cblxuXHRcdC8vIEFsaWduXG5cdFx0aWYgKGFsaWduID09PSAncmlnaHQnIHx8IGFsaWduID09PSAnY2VudGVyJykge1xuXHRcdFx0eCArPSAoYm94LndpZHRoIC0gKGFsaWduT3B0aW9ucy53aWR0aCB8fCAwKSkgL1xuXHRcdFx0XHRcdHsgcmlnaHQ6IDEsIGNlbnRlcjogMiB9W2FsaWduXTtcblx0XHR9XG5cdFx0YXR0cmlic1thbGlnbkJ5VHJhbnNsYXRlID8gJ3RyYW5zbGF0ZVgnIDogJ3gnXSA9IG1hdGhSb3VuZCh4KTtcblxuXG5cdFx0Ly8gVmVydGljYWwgYWxpZ25cblx0XHRpZiAodkFsaWduID09PSAnYm90dG9tJyB8fCB2QWxpZ24gPT09ICdtaWRkbGUnKSB7XG5cdFx0XHR5ICs9IChib3guaGVpZ2h0IC0gKGFsaWduT3B0aW9ucy5oZWlnaHQgfHwgMCkpIC9cblx0XHRcdFx0XHQoeyBib3R0b206IDEsIG1pZGRsZTogMiB9W3ZBbGlnbl0gfHwgMSk7XG5cblx0XHR9XG5cdFx0YXR0cmlic1thbGlnbkJ5VHJhbnNsYXRlID8gJ3RyYW5zbGF0ZVknIDogJ3knXSA9IG1hdGhSb3VuZCh5KTtcblxuXHRcdC8vIEFuaW1hdGUgb25seSBpZiBhbHJlYWR5IHBsYWNlZFxuXHRcdHRoaXNbdGhpcy5wbGFjZWQgPyAnYW5pbWF0ZScgOiAnYXR0ciddKGF0dHJpYnMpO1xuXHRcdHRoaXMucGxhY2VkID0gdHJ1ZTtcblx0XHR0aGlzLmFsaWduQXR0ciA9IGF0dHJpYnM7XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBib3VuZGluZyBib3ggKHdpZHRoLCBoZWlnaHQsIHggYW5kIHkpIGZvciB0aGUgZWxlbWVudFxuXHQgKi9cblx0Z2V0QkJveDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdGJCb3ggPSB3cmFwcGVyLmJCb3gsXG5cdFx0XHRyZW5kZXJlciA9IHdyYXBwZXIucmVuZGVyZXIsXG5cdFx0XHR3aWR0aCxcblx0XHRcdGhlaWdodCxcblx0XHRcdHJvdGF0aW9uID0gd3JhcHBlci5yb3RhdGlvbixcblx0XHRcdGVsZW1lbnQgPSB3cmFwcGVyLmVsZW1lbnQsXG5cdFx0XHRzdHlsZXMgPSB3cmFwcGVyLnN0eWxlcyxcblx0XHRcdHJhZCA9IHJvdGF0aW9uICogZGVnMnJhZCxcblx0XHRcdHRleHRTdHIgPSB3cmFwcGVyLnRleHRTdHIsXG5cdFx0XHRjYWNoZUtleTtcblxuXHRcdC8vIFNpbmNlIG51bWJlcnMgYXJlIG1vbm9zcGFjZWQsIGFuZCBudW1lcmljYWwgbGFiZWxzIGFwcGVhciBhIGxvdCBpbiBhIGNoYXJ0LFxuXHRcdC8vIHdlIGFzc3VtZSB0aGF0IGEgbGFiZWwgb2YgbiBjaGFyYWN0ZXJzIGhhcyB0aGUgc2FtZSBib3VuZGluZyBib3ggYXMgb3RoZXJzIFxuXHRcdC8vIG9mIHRoZSBzYW1lIGxlbmd0aC5cblx0XHRpZiAodGV4dFN0ciA9PT0gJycgfHwgbnVtUmVnZXgudGVzdCh0ZXh0U3RyKSkge1xuXHRcdFx0Y2FjaGVLZXkgPSAnbnVtLicgKyB0ZXh0U3RyLnRvU3RyaW5nKCkubGVuZ3RoICsgKHN0eWxlcyA/ICgnfCcgKyBzdHlsZXMuZm9udFNpemUgKyAnfCcgKyBzdHlsZXMuZm9udEZhbWlseSkgOiAnJyk7XG5cblx0XHR9IC8vZWxzZSB7IC8vIFRoaXMgY29kZSBibG9jayBtYWRlIGRlbW8vd2F0ZXJmYWxsIGZhaWwsIHJlbGF0ZWQgdG8gYnVpbGRUZXh0XG5cdFx0XHQvLyBDYWNoaW5nIGFsbCBzdHJpbmdzIHJlZHVjZXMgcmVuZGVyaW5nIHRpbWUgYnkgNC01JS4gXG5cdFx0XHQvLyBUT0RPOiBDaGVjayBob3cgdGhpcyBhZmZlY3RzIHBsYWNlcyB3aGVyZSBiQm94IGlzIGZvdW5kIG9uIHRoZSBlbGVtZW50XG5cdFx0XHQvL2NhY2hlS2V5ID0gdGV4dFN0ciArIChzdHlsZXMgPyAoJ3wnICsgc3R5bGVzLmZvbnRTaXplICsgJ3wnICsgc3R5bGVzLmZvbnRGYW1pbHkpIDogJycpO1xuXHRcdC8vfVxuXHRcdGlmIChjYWNoZUtleSkge1xuXHRcdFx0YkJveCA9IHJlbmRlcmVyLmNhY2hlW2NhY2hlS2V5XTtcblx0XHR9XG5cblx0XHQvLyBObyBjYWNoZSBmb3VuZFxuXHRcdGlmICghYkJveCkge1xuXG5cdFx0XHQvLyBTVkcgZWxlbWVudHNcblx0XHRcdGlmIChlbGVtZW50Lm5hbWVzcGFjZVVSSSA9PT0gU1ZHX05TIHx8IHJlbmRlcmVyLmZvckV4cG9ydCkge1xuXHRcdFx0XHR0cnkgeyAvLyBGYWlscyBpbiBGaXJlZm94IGlmIHRoZSBjb250YWluZXIgaGFzIGRpc3BsYXk6IG5vbmUuXG5cblx0XHRcdFx0XHRiQm94ID0gZWxlbWVudC5nZXRCQm94ID9cblx0XHRcdFx0XHRcdC8vIFNWRzogdXNlIGV4dGVuZCBiZWNhdXNlIElFOSBpcyBub3QgYWxsb3dlZCB0byBjaGFuZ2Ugd2lkdGggYW5kIGhlaWdodCBpbiBjYXNlXG5cdFx0XHRcdFx0XHQvLyBvZiByb3RhdGlvbiAoYmVsb3cpXG5cdFx0XHRcdFx0XHRleHRlbmQoe30sIGVsZW1lbnQuZ2V0QkJveCgpKSA6XG5cdFx0XHRcdFx0XHQvLyBDYW52YXMgcmVuZGVyZXIgYW5kIGxlZ2FjeSBJRSBpbiBleHBvcnQgbW9kZVxuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHR3aWR0aDogZWxlbWVudC5vZmZzZXRXaWR0aCxcblx0XHRcdFx0XHRcdFx0aGVpZ2h0OiBlbGVtZW50Lm9mZnNldEhlaWdodFxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0fSBjYXRjaCAoZSkge31cblxuXHRcdFx0XHQvLyBJZiB0aGUgYkJveCBpcyBub3Qgc2V0LCB0aGUgdHJ5LWNhdGNoIGJsb2NrIGFib3ZlIGZhaWxlZC4gVGhlIG90aGVyIGNvbmRpdGlvblxuXHRcdFx0XHQvLyBpcyBmb3IgT3BlcmEgdGhhdCByZXR1cm5zIGEgd2lkdGggb2YgLUluZmluaXR5IG9uIGhpZGRlbiBlbGVtZW50cy5cblx0XHRcdFx0aWYgKCFiQm94IHx8IGJCb3gud2lkdGggPCAwKSB7XG5cdFx0XHRcdFx0YkJveCA9IHsgd2lkdGg6IDAsIGhlaWdodDogMCB9O1xuXHRcdFx0XHR9XG5cblxuXHRcdFx0Ly8gVk1MIFJlbmRlcmVyIG9yIHVzZUhUTUwgd2l0aGluIFNWR1xuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRiQm94ID0gd3JhcHBlci5odG1sR2V0QkJveCgpO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIFRydWUgU1ZHIGVsZW1lbnRzIGFzIHdlbGwgYXMgSFRNTCBlbGVtZW50cyBpbiBtb2Rlcm4gYnJvd3NlcnMgdXNpbmcgdGhlIC51c2VIVE1MIG9wdGlvblxuXHRcdFx0Ly8gbmVlZCB0byBjb21wZW5zYXRlZCBmb3Igcm90YXRpb25cblx0XHRcdGlmIChyZW5kZXJlci5pc1NWRykge1xuXHRcdFx0XHR3aWR0aCA9IGJCb3gud2lkdGg7XG5cdFx0XHRcdGhlaWdodCA9IGJCb3guaGVpZ2h0O1xuXG5cdFx0XHRcdC8vIFdvcmthcm91bmQgZm9yIHdyb25nIGJvdW5kaW5nIGJveCBpbiBJRTkgYW5kIElFMTAgKCMxMTAxLCAjMTUwNSwgIzE2NjksICMyNTY4KVxuXHRcdFx0XHRpZiAoaXNJRSAmJiBzdHlsZXMgJiYgc3R5bGVzLmZvbnRTaXplID09PSAnMTFweCcgJiYgaGVpZ2h0LnRvUHJlY2lzaW9uKDMpID09PSAnMTYuOScpIHtcblx0XHRcdFx0XHRiQm94LmhlaWdodCA9IGhlaWdodCA9IDE0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRqdXN0IGZvciByb3RhdGVkIHRleHRcblx0XHRcdFx0aWYgKHJvdGF0aW9uKSB7XG5cdFx0XHRcdFx0YkJveC53aWR0aCA9IG1hdGhBYnMoaGVpZ2h0ICogbWF0aFNpbihyYWQpKSArIG1hdGhBYnMod2lkdGggKiBtYXRoQ29zKHJhZCkpO1xuXHRcdFx0XHRcdGJCb3guaGVpZ2h0ID0gbWF0aEFicyhoZWlnaHQgKiBtYXRoQ29zKHJhZCkpICsgbWF0aEFicyh3aWR0aCAqIG1hdGhTaW4ocmFkKSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FjaGUgaXRcblx0XHRcdHdyYXBwZXIuYkJveCA9IGJCb3g7XG5cdFx0XHRpZiAoY2FjaGVLZXkpIHtcblx0XHRcdFx0cmVuZGVyZXIuY2FjaGVbY2FjaGVLZXldID0gYkJveDtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGJCb3g7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIGVsZW1lbnRcblx0ICovXG5cdHNob3c6IGZ1bmN0aW9uIChpbmhlcml0KSB7XG5cdFx0Ly8gSUU5LTExIGRvZXNuJ3QgaGFuZGxlIHZpc2liaWx0eTppbmhlcml0IHdlbGwsIHNvIHdlIHJlbW92ZSB0aGUgYXR0cmlidXRlIGluc3RlYWQgKCMyODgxKVxuXHRcdGlmIChpbmhlcml0ICYmIHRoaXMuZWxlbWVudC5uYW1lc3BhY2VVUkkgPT09IFNWR19OUykge1xuXHRcdFx0dGhpcy5lbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgndmlzaWJpbGl0eScpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmF0dHIoeyB2aXNpYmlsaXR5OiBpbmhlcml0ID8gJ2luaGVyaXQnIDogVklTSUJMRSB9KTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEhpZGUgdGhlIGVsZW1lbnRcblx0ICovXG5cdGhpZGU6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy5hdHRyKHsgdmlzaWJpbGl0eTogSElEREVOIH0pO1xuXHR9LFxuXG5cdGZhZGVPdXQ6IGZ1bmN0aW9uIChkdXJhdGlvbikge1xuXHRcdHZhciBlbGVtV3JhcHBlciA9IHRoaXM7XG5cdFx0ZWxlbVdyYXBwZXIuYW5pbWF0ZSh7XG5cdFx0XHRvcGFjaXR5OiAwXG5cdFx0fSwge1xuXHRcdFx0ZHVyYXRpb246IGR1cmF0aW9uIHx8IDE1MCxcblx0XHRcdGNvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGVsZW1XcmFwcGVyLmF0dHIoeyB5OiAtOTk5OSB9KTsgLy8gIzMwODgsIGFzc3VtaW5nIHdlJ3JlIG9ubHkgdXNpbmcgdGhpcyBmb3IgdG9vbHRpcHNcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogQWRkIHRoZSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7T2JqZWN0fFVuZGVmaW5lZH0gcGFyZW50IENhbiBiZSBhbiBlbGVtZW50LCBhbiBlbGVtZW50IHdyYXBwZXIgb3IgdW5kZWZpbmVkXG5cdCAqICAgIHRvIGFwcGVuZCB0aGUgZWxlbWVudCB0byB0aGUgcmVuZGVyZXIuYm94LlxuXHQgKi9cblx0YWRkOiBmdW5jdGlvbiAocGFyZW50KSB7XG5cblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLnJlbmRlcmVyLFxuXHRcdFx0cGFyZW50V3JhcHBlciA9IHBhcmVudCB8fCByZW5kZXJlcixcblx0XHRcdHBhcmVudE5vZGUgPSBwYXJlbnRXcmFwcGVyLmVsZW1lbnQgfHwgcmVuZGVyZXIuYm94LFxuXHRcdFx0Y2hpbGROb2Rlcyxcblx0XHRcdGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsXG5cdFx0XHR6SW5kZXggPSB0aGlzLnpJbmRleCxcblx0XHRcdG90aGVyRWxlbWVudCxcblx0XHRcdG90aGVyWkluZGV4LFxuXHRcdFx0aSxcblx0XHRcdGluc2VydGVkO1xuXG5cdFx0aWYgKHBhcmVudCkge1xuXHRcdFx0dGhpcy5wYXJlbnRHcm91cCA9IHBhcmVudDtcblx0XHR9XG5cblx0XHQvLyBtYXJrIGFzIGludmVydGVkXG5cdFx0dGhpcy5wYXJlbnRJbnZlcnRlZCA9IHBhcmVudCAmJiBwYXJlbnQuaW52ZXJ0ZWQ7XG5cblx0XHQvLyBidWlsZCBmb3JtYXR0ZWQgdGV4dFxuXHRcdGlmICh0aGlzLnRleHRTdHIgIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmVuZGVyZXIuYnVpbGRUZXh0KHRoaXMpO1xuXHRcdH1cblxuXHRcdC8vIG1hcmsgdGhlIGNvbnRhaW5lciBhcyBoYXZpbmcgeiBpbmRleGVkIGNoaWxkcmVuXG5cdFx0aWYgKHpJbmRleCkge1xuXHRcdFx0cGFyZW50V3JhcHBlci5oYW5kbGVaID0gdHJ1ZTtcblx0XHRcdHpJbmRleCA9IHBJbnQoekluZGV4KTtcblx0XHR9XG5cblx0XHQvLyBpbnNlcnQgYWNjb3JkaW5nIHRvIHRoaXMgYW5kIG90aGVyIGVsZW1lbnRzJyB6SW5kZXhcblx0XHRpZiAocGFyZW50V3JhcHBlci5oYW5kbGVaKSB7IC8vIHRoaXMgZWxlbWVudCBvciBhbnkgb2YgaXRzIHNpYmxpbmdzIGhhcyBhIHogaW5kZXhcblx0XHRcdGNoaWxkTm9kZXMgPSBwYXJlbnROb2RlLmNoaWxkTm9kZXM7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRvdGhlckVsZW1lbnQgPSBjaGlsZE5vZGVzW2ldO1xuXHRcdFx0XHRvdGhlclpJbmRleCA9IGF0dHIob3RoZXJFbGVtZW50LCAnekluZGV4Jyk7XG5cdFx0XHRcdGlmIChvdGhlckVsZW1lbnQgIT09IGVsZW1lbnQgJiYgKFxuXHRcdFx0XHRcdFx0Ly8gaW5zZXJ0IGJlZm9yZSB0aGUgZmlyc3QgZWxlbWVudCB3aXRoIGEgaGlnaGVyIHpJbmRleFxuXHRcdFx0XHRcdFx0cEludChvdGhlclpJbmRleCkgPiB6SW5kZXggfHxcblx0XHRcdFx0XHRcdC8vIGlmIG5vIHpJbmRleCBnaXZlbiwgaW5zZXJ0IGJlZm9yZSB0aGUgZmlyc3QgZWxlbWVudCB3aXRoIGEgekluZGV4XG5cdFx0XHRcdFx0XHQoIWRlZmluZWQoekluZGV4KSAmJiBkZWZpbmVkKG90aGVyWkluZGV4KSlcblxuXHRcdFx0XHRcdFx0KSkge1xuXHRcdFx0XHRcdHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIG90aGVyRWxlbWVudCk7XG5cdFx0XHRcdFx0aW5zZXJ0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gZGVmYXVsdDogYXBwZW5kIGF0IHRoZSBlbmRcblx0XHRpZiAoIWluc2VydGVkKSB7XG5cdFx0XHRwYXJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXHRcdH1cblxuXHRcdC8vIG1hcmsgYXMgYWRkZWRcblx0XHR0aGlzLmFkZGVkID0gdHJ1ZTtcblxuXHRcdC8vIGZpcmUgYW4gZXZlbnQgZm9yIGludGVybmFsIGhvb2tzXG5cdFx0aWYgKHRoaXMub25BZGQpIHtcblx0XHRcdHRoaXMub25BZGQoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogUmVtb3ZlcyBhIGNoaWxkIGVpdGhlciBieSByZW1vdmVDaGlsZCBvciBtb3ZlIHRvIGdhcmJhZ2VCaW4uXG5cdCAqIElzc3VlIDQ5MDsgaW4gVk1MIHJlbW92ZUNoaWxkIHJlc3VsdHMgaW4gT3JwaGFuZWQgbm9kZXMgYWNjb3JkaW5nIHRvIHNJRXZlLCBkaXNjYXJkRWxlbWVudCBkb2VzIG5vdC5cblx0ICovXG5cdHNhZmVSZW1vdmVDaGlsZDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcblx0XHR2YXIgcGFyZW50Tm9kZSA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblx0XHRpZiAocGFyZW50Tm9kZSkge1xuXHRcdFx0cGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbGVtZW50KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3Ryb3kgdGhlIGVsZW1lbnQgYW5kIGVsZW1lbnQgd3JhcHBlclxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdGVsZW1lbnQgPSB3cmFwcGVyLmVsZW1lbnQgfHwge30sXG5cdFx0XHRzaGFkb3dzID0gd3JhcHBlci5zaGFkb3dzLFxuXHRcdFx0cGFyZW50VG9DbGVhbiA9IHdyYXBwZXIucmVuZGVyZXIuaXNTVkcgJiYgZWxlbWVudC5ub2RlTmFtZSA9PT0gJ1NQQU4nICYmIHdyYXBwZXIucGFyZW50R3JvdXAsXG5cdFx0XHRncmFuZFBhcmVudCxcblx0XHRcdGtleSxcblx0XHRcdGk7XG5cblx0XHQvLyByZW1vdmUgZXZlbnRzXG5cdFx0ZWxlbWVudC5vbmNsaWNrID0gZWxlbWVudC5vbm1vdXNlb3V0ID0gZWxlbWVudC5vbm1vdXNlb3ZlciA9IGVsZW1lbnQub25tb3VzZW1vdmUgPSBlbGVtZW50LnBvaW50ID0gbnVsbDtcblx0XHRzdG9wKHdyYXBwZXIpOyAvLyBzdG9wIHJ1bm5pbmcgYW5pbWF0aW9uc1xuXG5cdFx0aWYgKHdyYXBwZXIuY2xpcFBhdGgpIHtcblx0XHRcdHdyYXBwZXIuY2xpcFBhdGggPSB3cmFwcGVyLmNsaXBQYXRoLmRlc3Ryb3koKTtcblx0XHR9XG5cblx0XHQvLyBEZXN0cm95IHN0b3BzIGluIGNhc2UgdGhpcyBpcyBhIGdyYWRpZW50IG9iamVjdFxuXHRcdGlmICh3cmFwcGVyLnN0b3BzKSB7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgd3JhcHBlci5zdG9wcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR3cmFwcGVyLnN0b3BzW2ldID0gd3JhcHBlci5zdG9wc1tpXS5kZXN0cm95KCk7XG5cdFx0XHR9XG5cdFx0XHR3cmFwcGVyLnN0b3BzID0gbnVsbDtcblx0XHR9XG5cblx0XHQvLyByZW1vdmUgZWxlbWVudFxuXHRcdHdyYXBwZXIuc2FmZVJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuXG5cdFx0Ly8gZGVzdHJveSBzaGFkb3dzXG5cdFx0aWYgKHNoYWRvd3MpIHtcblx0XHRcdGVhY2goc2hhZG93cywgZnVuY3Rpb24gKHNoYWRvdykge1xuXHRcdFx0XHR3cmFwcGVyLnNhZmVSZW1vdmVDaGlsZChzaGFkb3cpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gSW4gY2FzZSBvZiB1c2VIVE1MLCBjbGVhbiB1cCBlbXB0eSBjb250YWluZXJzIGVtdWxhdGluZyBTVkcgZ3JvdXBzICgjMTk2MCwgIzIzOTMsICMyNjk3KS5cblx0XHR3aGlsZSAocGFyZW50VG9DbGVhbiAmJiBwYXJlbnRUb0NsZWFuLmRpdiAmJiBwYXJlbnRUb0NsZWFuLmRpdi5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0Z3JhbmRQYXJlbnQgPSBwYXJlbnRUb0NsZWFuLnBhcmVudEdyb3VwO1xuXHRcdFx0d3JhcHBlci5zYWZlUmVtb3ZlQ2hpbGQocGFyZW50VG9DbGVhbi5kaXYpO1xuXHRcdFx0ZGVsZXRlIHBhcmVudFRvQ2xlYW4uZGl2O1xuXHRcdFx0cGFyZW50VG9DbGVhbiA9IGdyYW5kUGFyZW50O1xuXHRcdH1cblxuXHRcdC8vIHJlbW92ZSBmcm9tIGFsaWduT2JqZWN0c1xuXHRcdGlmICh3cmFwcGVyLmFsaWduVG8pIHtcblx0XHRcdGVyYXNlKHdyYXBwZXIucmVuZGVyZXIuYWxpZ25lZE9iamVjdHMsIHdyYXBwZXIpO1xuXHRcdH1cblxuXHRcdGZvciAoa2V5IGluIHdyYXBwZXIpIHtcblx0XHRcdGRlbGV0ZSB3cmFwcGVyW2tleV07XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG51bGw7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkZCBhIHNoYWRvdyB0byB0aGUgZWxlbWVudC4gTXVzdCBiZSBkb25lIGFmdGVyIHRoZSBlbGVtZW50IGlzIGFkZGVkIHRvIHRoZSBET01cblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gc2hhZG93T3B0aW9uc1xuXHQgKi9cblx0c2hhZG93OiBmdW5jdGlvbiAoc2hhZG93T3B0aW9ucywgZ3JvdXAsIGN1dE9mZikge1xuXHRcdHZhciBzaGFkb3dzID0gW10sXG5cdFx0XHRpLFxuXHRcdFx0c2hhZG93LFxuXHRcdFx0ZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcblx0XHRcdHN0cm9rZVdpZHRoLFxuXHRcdFx0c2hhZG93V2lkdGgsXG5cdFx0XHRzaGFkb3dFbGVtZW50T3BhY2l0eSxcblxuXHRcdFx0Ly8gY29tcGVuc2F0ZSBmb3IgaW52ZXJ0ZWQgcGxvdCBhcmVhXG5cdFx0XHR0cmFuc2Zvcm07XG5cblxuXHRcdGlmIChzaGFkb3dPcHRpb25zKSB7XG5cdFx0XHRzaGFkb3dXaWR0aCA9IHBpY2soc2hhZG93T3B0aW9ucy53aWR0aCwgMyk7XG5cdFx0XHRzaGFkb3dFbGVtZW50T3BhY2l0eSA9IChzaGFkb3dPcHRpb25zLm9wYWNpdHkgfHwgMC4xNSkgLyBzaGFkb3dXaWR0aDtcblx0XHRcdHRyYW5zZm9ybSA9IHRoaXMucGFyZW50SW52ZXJ0ZWQgP1xuXHRcdFx0XHQnKC0xLC0xKScgOlxuXHRcdFx0XHQnKCcgKyBwaWNrKHNoYWRvd09wdGlvbnMub2Zmc2V0WCwgMSkgKyAnLCAnICsgcGljayhzaGFkb3dPcHRpb25zLm9mZnNldFksIDEpICsgJyknO1xuXHRcdFx0Zm9yIChpID0gMTsgaSA8PSBzaGFkb3dXaWR0aDsgaSsrKSB7XG5cdFx0XHRcdHNoYWRvdyA9IGVsZW1lbnQuY2xvbmVOb2RlKDApO1xuXHRcdFx0XHRzdHJva2VXaWR0aCA9IChzaGFkb3dXaWR0aCAqIDIpICsgMSAtICgyICogaSk7XG5cdFx0XHRcdGF0dHIoc2hhZG93LCB7XG5cdFx0XHRcdFx0J2lzU2hhZG93JzogJ3RydWUnLFxuXHRcdFx0XHRcdCdzdHJva2UnOiBzaGFkb3dPcHRpb25zLmNvbG9yIHx8ICdibGFjaycsXG5cdFx0XHRcdFx0J3N0cm9rZS1vcGFjaXR5Jzogc2hhZG93RWxlbWVudE9wYWNpdHkgKiBpLFxuXHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBzdHJva2VXaWR0aCxcblx0XHRcdFx0XHQndHJhbnNmb3JtJzogJ3RyYW5zbGF0ZScgKyB0cmFuc2Zvcm0sXG5cdFx0XHRcdFx0J2ZpbGwnOiBOT05FXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRpZiAoY3V0T2ZmKSB7XG5cdFx0XHRcdFx0YXR0cihzaGFkb3csICdoZWlnaHQnLCBtYXRoTWF4KGF0dHIoc2hhZG93LCAnaGVpZ2h0JykgLSBzdHJva2VXaWR0aCwgMCkpO1xuXHRcdFx0XHRcdHNoYWRvdy5jdXRIZWlnaHQgPSBzdHJva2VXaWR0aDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChncm91cCkge1xuXHRcdFx0XHRcdGdyb3VwLmVsZW1lbnQuYXBwZW5kQ2hpbGQoc2hhZG93KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNoYWRvdywgZWxlbWVudCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRzaGFkb3dzLnB1c2goc2hhZG93KTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5zaGFkb3dzID0gc2hhZG93cztcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fSxcblxuXHR4R2V0dGVyOiBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0aWYgKHRoaXMuZWxlbWVudC5ub2RlTmFtZSA9PT0gJ2NpcmNsZScpIHtcblx0XHRcdGtleSA9IHsgeDogJ2N4JywgeTogJ2N5JyB9W2tleV0gfHwga2V5O1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5fZGVmYXVsdEdldHRlcihrZXkpO1xuXHR9LFxuXG5cdC8qKiBcblx0ICogR2V0IHRoZSBjdXJyZW50IHZhbHVlIG9mIGFuIGF0dHJpYnV0ZSBvciBwc2V1ZG8gYXR0cmlidXRlLCB1c2VkIG1haW5seVxuXHQgKiBmb3IgYW5pbWF0aW9uLlxuXHQgKi9cblx0X2RlZmF1bHRHZXR0ZXI6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHR2YXIgcmV0ID0gcGljayh0aGlzW2tleV0sIHRoaXMuZWxlbWVudCA/IHRoaXMuZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSA6IG51bGwsIDApO1xuXG5cdFx0aWYgKC9eW1xcLTAtOVxcLl0rJC8udGVzdChyZXQpKSB7IC8vIGlzIG51bWVyaWNhbFxuXHRcdFx0cmV0ID0gcGFyc2VGbG9hdChyZXQpO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cblx0ZFNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHRpZiAodmFsdWUgJiYgdmFsdWUuam9pbikgeyAvLyBqb2luIHBhdGhcblx0XHRcdHZhbHVlID0gdmFsdWUuam9pbignICcpO1xuXHRcdH1cblx0XHRpZiAoLyhOYU58IHsyfXxeJCkvLnRlc3QodmFsdWUpKSB7XG5cdFx0XHR2YWx1ZSA9ICdNIDAgMCc7XG5cdFx0fVxuXHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXG5cdFx0dGhpc1trZXldID0gdmFsdWU7XG5cdH0sXG5cdGRhc2hzdHlsZVNldHRlcjogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0dmFyIGk7XG5cdFx0dmFsdWUgPSB2YWx1ZSAmJiB2YWx1ZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmICh2YWx1ZSkge1xuXHRcdFx0dmFsdWUgPSB2YWx1ZVxuXHRcdFx0XHQucmVwbGFjZSgnc2hvcnRkYXNoZG90ZG90JywgJzMsMSwxLDEsMSwxLCcpXG5cdFx0XHRcdC5yZXBsYWNlKCdzaG9ydGRhc2hkb3QnLCAnMywxLDEsMScpXG5cdFx0XHRcdC5yZXBsYWNlKCdzaG9ydGRvdCcsICcxLDEsJylcblx0XHRcdFx0LnJlcGxhY2UoJ3Nob3J0ZGFzaCcsICczLDEsJylcblx0XHRcdFx0LnJlcGxhY2UoJ2xvbmdkYXNoJywgJzgsMywnKVxuXHRcdFx0XHQucmVwbGFjZSgvZG90L2csICcxLDMsJylcblx0XHRcdFx0LnJlcGxhY2UoJ2Rhc2gnLCAnNCwzLCcpXG5cdFx0XHRcdC5yZXBsYWNlKC8sJC8sICcnKVxuXHRcdFx0XHQuc3BsaXQoJywnKTsgLy8gZW5kaW5nIGNvbW1hXG5cblx0XHRcdGkgPSB2YWx1ZS5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdHZhbHVlW2ldID0gcEludCh2YWx1ZVtpXSkgKiB0aGlzWydzdHJva2Utd2lkdGgnXTtcblx0XHRcdH1cblx0XHRcdHZhbHVlID0gdmFsdWUuam9pbignLCcpXG5cdFx0XHRcdC5yZXBsYWNlKCdOYU4nLCAnbm9uZScpOyAvLyAjMzIyNlxuXHRcdFx0dGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnc3Ryb2tlLWRhc2hhcnJheScsIHZhbHVlKTtcblx0XHR9XG5cdH0sXG5cdGFsaWduU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHR0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCd0ZXh0LWFuY2hvcicsIHsgbGVmdDogJ3N0YXJ0JywgY2VudGVyOiAnbWlkZGxlJywgcmlnaHQ6ICdlbmQnIH1bdmFsdWVdKTtcblx0fSxcblx0b3BhY2l0eVNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHR0aGlzW2tleV0gPSB2YWx1ZTtcblx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcblx0fSxcblx0dGl0bGVTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdHZhciB0aXRsZU5vZGUgPSB0aGlzLmVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RpdGxlJylbMF07XG5cdFx0aWYgKCF0aXRsZU5vZGUpIHtcblx0XHRcdHRpdGxlTm9kZSA9IGRvYy5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAndGl0bGUnKTtcblx0XHRcdHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZCh0aXRsZU5vZGUpO1xuXHRcdH1cblx0XHR0aXRsZU5vZGUudGV4dENvbnRlbnQgPSBwaWNrKHZhbHVlLCAnJykucmVwbGFjZSgvPFtePl0qPi9nLCAnJyk7IC8vICMzMjc2XG5cdH0sXG5cdHRleHRTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdGlmICh2YWx1ZSAhPT0gdGhpcy50ZXh0U3RyKSB7XG5cdFx0XHQvLyBEZWxldGUgYkJveCBtZW1vIHdoZW4gdGhlIHRleHQgY2hhbmdlc1xuXHRcdFx0ZGVsZXRlIHRoaXMuYkJveDtcblx0XHRcblx0XHRcdHRoaXMudGV4dFN0ciA9IHZhbHVlO1xuXHRcdFx0aWYgKHRoaXMuYWRkZWQpIHtcblx0XHRcdFx0dGhpcy5yZW5kZXJlci5idWlsZFRleHQodGhpcyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRmaWxsU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcblx0XHR9IGVsc2UgaWYgKHZhbHVlKSB7XG5cdFx0XHR0aGlzLmNvbG9yR3JhZGllbnQodmFsdWUsIGtleSwgZWxlbWVudCk7XG5cdFx0fVxuXHR9LFxuXHR6SW5kZXhTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG5cdFx0dGhpc1trZXldID0gdmFsdWU7XG5cdH0sXG5cdF9kZWZhdWx0U2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHR9XG59O1xuXG4vLyBTb21lIHNoYXJlZCBzZXR0ZXJzIGFuZCBnZXR0ZXJzXG5TVkdFbGVtZW50LnByb3RvdHlwZS55R2V0dGVyID0gU1ZHRWxlbWVudC5wcm90b3R5cGUueEdldHRlcjtcblNWR0VsZW1lbnQucHJvdG90eXBlLnRyYW5zbGF0ZVhTZXR0ZXIgPSBTVkdFbGVtZW50LnByb3RvdHlwZS50cmFuc2xhdGVZU2V0dGVyID0gXG5cdFx0U1ZHRWxlbWVudC5wcm90b3R5cGUucm90YXRpb25TZXR0ZXIgPSBTVkdFbGVtZW50LnByb3RvdHlwZS52ZXJ0aWNhbEFsaWduU2V0dGVyID0gXG5cdFx0U1ZHRWxlbWVudC5wcm90b3R5cGUuc2NhbGVYU2V0dGVyID0gU1ZHRWxlbWVudC5wcm90b3R5cGUuc2NhbGVZU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0dGhpc1trZXldID0gdmFsdWU7XG5cdHRoaXMuZG9UcmFuc2Zvcm0gPSB0cnVlO1xufTtcblxuLy8gV2ViS2l0IGFuZCBCYXRpayBoYXZlIHByb2JsZW1zIHdpdGggYSBzdHJva2Utd2lkdGggb2YgemVybywgc28gaW4gdGhpcyBjYXNlIHdlIHJlbW92ZSB0aGUgXG4vLyBzdHJva2UgYXR0cmlidXRlIGFsdG9nZXRoZXIuICMxMjcwLCAjMTM2OSwgIzMwNjUsICMzMDcyLlxuU1ZHRWxlbWVudC5wcm90b3R5cGVbJ3N0cm9rZS13aWR0aFNldHRlciddID0gU1ZHRWxlbWVudC5wcm90b3R5cGUuc3Ryb2tlU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0dGhpc1trZXldID0gdmFsdWU7XG5cdC8vIE9ubHkgYXBwbHkgdGhlIHN0cm9rZSBhdHRyaWJ1dGUgaWYgdGhlIHN0cm9rZSB3aWR0aCBpcyBkZWZpbmVkIGFuZCBsYXJnZXIgdGhhbiAwXG5cdGlmICh0aGlzLnN0cm9rZSAmJiB0aGlzWydzdHJva2Utd2lkdGgnXSkge1xuXHRcdHRoaXMuc3Ryb2tlV2lkdGggPSB0aGlzWydzdHJva2Utd2lkdGgnXTtcblx0XHRTVkdFbGVtZW50LnByb3RvdHlwZS5maWxsU2V0dGVyLmNhbGwodGhpcywgdGhpcy5zdHJva2UsICdzdHJva2UnLCBlbGVtZW50KTsgLy8gdXNlIHByb3RvdHlwZSBhcyBpbnN0YW5jZSBtYXkgYmUgb3ZlcnJpZGRlblxuXHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCB0aGlzWydzdHJva2Utd2lkdGgnXSk7XG5cdFx0dGhpcy5oYXNTdHJva2UgPSB0cnVlO1xuXHR9IGVsc2UgaWYgKGtleSA9PT0gJ3N0cm9rZS13aWR0aCcgJiYgdmFsdWUgPT09IDAgJiYgdGhpcy5oYXNTdHJva2UpIHtcblx0XHRlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnc3Ryb2tlJyk7XG5cdFx0dGhpcy5oYXNTdHJva2UgPSBmYWxzZTtcblx0fVxufTtcblxuXG4vKipcbiAqIFRoZSBkZWZhdWx0IFNWRyByZW5kZXJlclxuICovXG52YXIgU1ZHUmVuZGVyZXIgPSBmdW5jdGlvbiAoKSB7XG5cdHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcblNWR1JlbmRlcmVyLnByb3RvdHlwZSA9IHtcblx0RWxlbWVudDogU1ZHRWxlbWVudCxcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgU1ZHUmVuZGVyZXJcblx0ICogQHBhcmFtIHtPYmplY3R9IGNvbnRhaW5lclxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IGZvckV4cG9ydFxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGNvbnRhaW5lciwgd2lkdGgsIGhlaWdodCwgc3R5bGUsIGZvckV4cG9ydCkge1xuXHRcdHZhciByZW5kZXJlciA9IHRoaXMsXG5cdFx0XHRsb2MgPSBsb2NhdGlvbixcblx0XHRcdGJveFdyYXBwZXIsXG5cdFx0XHRlbGVtZW50LFxuXHRcdFx0ZGVzYztcblxuXHRcdGJveFdyYXBwZXIgPSByZW5kZXJlci5jcmVhdGVFbGVtZW50KCdzdmcnKVxuXHRcdFx0LmF0dHIoe1xuXHRcdFx0XHR2ZXJzaW9uOiAnMS4xJ1xuXHRcdFx0fSlcblx0XHRcdC5jc3ModGhpcy5nZXRTdHlsZShzdHlsZSkpO1xuXHRcdGVsZW1lbnQgPSBib3hXcmFwcGVyLmVsZW1lbnQ7XG5cdFx0Y29udGFpbmVyLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXG5cdFx0Ly8gRm9yIGJyb3dzZXJzIG90aGVyIHRoYW4gSUUsIGFkZCB0aGUgbmFtZXNwYWNlIGF0dHJpYnV0ZSAoIzE5NzgpXG5cdFx0aWYgKGNvbnRhaW5lci5pbm5lckhUTUwuaW5kZXhPZigneG1sbnMnKSA9PT0gLTEpIHtcblx0XHRcdGF0dHIoZWxlbWVudCwgJ3htbG5zJywgU1ZHX05TKTtcblx0XHR9XG5cblx0XHQvLyBvYmplY3QgcHJvcGVydGllc1xuXHRcdHJlbmRlcmVyLmlzU1ZHID0gdHJ1ZTtcblx0XHRyZW5kZXJlci5ib3ggPSBlbGVtZW50O1xuXHRcdHJlbmRlcmVyLmJveFdyYXBwZXIgPSBib3hXcmFwcGVyO1xuXHRcdHJlbmRlcmVyLmFsaWduZWRPYmplY3RzID0gW107XG5cblx0XHQvLyBQYWdlIHVybCB1c2VkIGZvciBpbnRlcm5hbCByZWZlcmVuY2VzLiAjMjQsICM2NzIsICMxMDcwXG5cdFx0cmVuZGVyZXIudXJsID0gKGlzRmlyZWZveCB8fCBpc1dlYktpdCkgJiYgZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdiYXNlJykubGVuZ3RoID9cblx0XHRcdGxvYy5ocmVmXG5cdFx0XHRcdC5yZXBsYWNlKC8jLio/JC8sICcnKSAvLyByZW1vdmUgdGhlIGhhc2hcblx0XHRcdFx0LnJlcGxhY2UoLyhbXFwoJ1xcKV0pL2csICdcXFxcJDEnKSAvLyBlc2NhcGUgcGFyYW50aGVzZXMgYW5kIHF1b3Rlc1xuXHRcdFx0XHQucmVwbGFjZSgvIC9nLCAnJTIwJykgOiAvLyByZXBsYWNlIHNwYWNlcyAobmVlZGVkIGZvciBTYWZhcmkgb25seSlcblx0XHRcdCcnO1xuXG5cdFx0Ly8gQWRkIGRlc2NyaXB0aW9uXG5cdFx0ZGVzYyA9IHRoaXMuY3JlYXRlRWxlbWVudCgnZGVzYycpLmFkZCgpO1xuXHRcdGRlc2MuZWxlbWVudC5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUoJ0NyZWF0ZWQgd2l0aCAnICsgUFJPRFVDVCArICcgJyArIFZFUlNJT04pKTtcblxuXG5cdFx0cmVuZGVyZXIuZGVmcyA9IHRoaXMuY3JlYXRlRWxlbWVudCgnZGVmcycpLmFkZCgpO1xuXHRcdHJlbmRlcmVyLmZvckV4cG9ydCA9IGZvckV4cG9ydDtcblx0XHRyZW5kZXJlci5ncmFkaWVudHMgPSB7fTsgLy8gT2JqZWN0IHdoZXJlIGdyYWRpZW50IFN2Z0VsZW1lbnRzIGFyZSBzdG9yZWRcblx0XHRyZW5kZXJlci5jYWNoZSA9IHt9OyAvLyBDYWNoZSBmb3IgbnVtZXJpY2FsIGJvdW5kaW5nIGJveGVzXG5cblx0XHRyZW5kZXJlci5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcblxuXG5cblx0XHQvLyBJc3N1ZSAxMTAgd29ya2Fyb3VuZDpcblx0XHQvLyBJbiBGaXJlZm94LCBpZiBhIGRpdiBpcyBwb3NpdGlvbmVkIGJ5IHBlcmNlbnRhZ2UsIGl0cyBwaXhlbCBwb3NpdGlvbiBtYXkgbGFuZFxuXHRcdC8vIGJldHdlZW4gcGl4ZWxzLiBUaGUgY29udGFpbmVyIGl0c2VsZiBkb2Vzbid0IGRpc3BsYXkgdGhpcywgYnV0IGFuIFNWRyBlbGVtZW50XG5cdFx0Ly8gaW5zaWRlIHRoaXMgY29udGFpbmVyIHdpbGwgYmUgZHJhd24gYXQgc3VicGl4ZWwgcHJlY2lzaW9uLiBJbiBvcmRlciB0byBkcmF3XG5cdFx0Ly8gc2hhcnAgbGluZXMsIHRoaXMgbXVzdCBiZSBjb21wZW5zYXRlZCBmb3IuIFRoaXMgZG9lc24ndCBzZWVtIHRvIHdvcmsgaW5zaWRlXG5cdFx0Ly8gaWZyYW1lcyB0aG91Z2ggKGxpa2UgaW4ganNGaWRkbGUpLlxuXHRcdHZhciBzdWJQaXhlbEZpeCwgcmVjdDtcblx0XHRpZiAoaXNGaXJlZm94ICYmIGNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QpIHtcblx0XHRcdHJlbmRlcmVyLnN1YlBpeGVsRml4ID0gc3ViUGl4ZWxGaXggPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGNzcyhjb250YWluZXIsIHsgbGVmdDogMCwgdG9wOiAwIH0pO1xuXHRcdFx0XHRyZWN0ID0gY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdFx0XHRjc3MoY29udGFpbmVyLCB7XG5cdFx0XHRcdFx0bGVmdDogKG1hdGhDZWlsKHJlY3QubGVmdCkgLSByZWN0LmxlZnQpICsgUFgsXG5cdFx0XHRcdFx0dG9wOiAobWF0aENlaWwocmVjdC50b3ApIC0gcmVjdC50b3ApICsgUFhcblx0XHRcdFx0fSk7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBydW4gdGhlIGZpeCBub3dcblx0XHRcdHN1YlBpeGVsRml4KCk7XG5cblx0XHRcdC8vIHJ1biBpdCBvbiByZXNpemVcblx0XHRcdGFkZEV2ZW50KHdpbiwgJ3Jlc2l6ZScsIHN1YlBpeGVsRml4KTtcblx0XHR9XG5cdH0sXG5cblx0Z2V0U3R5bGU6IGZ1bmN0aW9uIChzdHlsZSkge1xuXHRcdHJldHVybiAodGhpcy5zdHlsZSA9IGV4dGVuZCh7XG5cdFx0XHRmb250RmFtaWx5OiAnXCJMdWNpZGEgR3JhbmRlXCIsIFwiTHVjaWRhIFNhbnMgVW5pY29kZVwiLCBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmJywgLy8gZGVmYXVsdCBmb250XG5cdFx0XHRmb250U2l6ZTogJzEycHgnXG5cdFx0fSwgc3R5bGUpKTtcblx0fSxcblxuXHQvKipcblx0ICogRGV0ZWN0IHdoZXRoZXIgdGhlIHJlbmRlcmVyIGlzIGhpZGRlbi4gVGhpcyBoYXBwZW5zIHdoZW4gb25lIG9mIHRoZSBwYXJlbnQgZWxlbWVudHNcblx0ICogaGFzIGRpc3BsYXk6IG5vbmUuICM2MDguXG5cdCAqL1xuXHRpc0hpZGRlbjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAhdGhpcy5ib3hXcmFwcGVyLmdldEJCb3goKS53aWR0aDtcblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveXMgdGhlIHJlbmRlcmVyIGFuZCBpdHMgYWxsb2NhdGVkIG1lbWJlcnMuXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcyxcblx0XHRcdHJlbmRlcmVyRGVmcyA9IHJlbmRlcmVyLmRlZnM7XG5cdFx0cmVuZGVyZXIuYm94ID0gbnVsbDtcblx0XHRyZW5kZXJlci5ib3hXcmFwcGVyID0gcmVuZGVyZXIuYm94V3JhcHBlci5kZXN0cm95KCk7XG5cblx0XHQvLyBDYWxsIGRlc3Ryb3kgb24gYWxsIGdyYWRpZW50IGVsZW1lbnRzXG5cdFx0ZGVzdHJveU9iamVjdFByb3BlcnRpZXMocmVuZGVyZXIuZ3JhZGllbnRzIHx8IHt9KTtcblx0XHRyZW5kZXJlci5ncmFkaWVudHMgPSBudWxsO1xuXG5cdFx0Ly8gRGVmcyBhcmUgbnVsbCBpbiBWTUxSZW5kZXJlclxuXHRcdC8vIE90aGVyd2lzZSwgZGVzdHJveSB0aGVtIGhlcmUuXG5cdFx0aWYgKHJlbmRlcmVyRGVmcykge1xuXHRcdFx0cmVuZGVyZXIuZGVmcyA9IHJlbmRlcmVyRGVmcy5kZXN0cm95KCk7XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHN1YiBwaXhlbCBmaXggaGFuZGxlclxuXHRcdC8vIFdlIG5lZWQgdG8gY2hlY2sgdGhhdCB0aGVyZSBpcyBhIGhhbmRsZXIsIG90aGVyd2lzZSBhbGwgZnVuY3Rpb25zIHRoYXQgYXJlIHJlZ2lzdGVyZWQgZm9yIGV2ZW50ICdyZXNpemUnIGFyZSByZW1vdmVkXG5cdFx0Ly8gU2VlIGlzc3VlICM5ODJcblx0XHRpZiAocmVuZGVyZXIuc3ViUGl4ZWxGaXgpIHtcblx0XHRcdHJlbW92ZUV2ZW50KHdpbiwgJ3Jlc2l6ZScsIHJlbmRlcmVyLnN1YlBpeGVsRml4KTtcblx0XHR9XG5cblx0XHRyZW5kZXJlci5hbGlnbmVkT2JqZWN0cyA9IG51bGw7XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIGEgd3JhcHBlciBmb3IgYW4gU1ZHIGVsZW1lbnRcblx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVOYW1lXG5cdCAqL1xuXHRjcmVhdGVFbGVtZW50OiBmdW5jdGlvbiAobm9kZU5hbWUpIHtcblx0XHR2YXIgd3JhcHBlciA9IG5ldyB0aGlzLkVsZW1lbnQoKTtcblx0XHR3cmFwcGVyLmluaXQodGhpcywgbm9kZU5hbWUpO1xuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEdW1teSBmdW5jdGlvbiBmb3IgdXNlIGluIGNhbnZhcyByZW5kZXJlclxuXHQgKi9cblx0ZHJhdzogZnVuY3Rpb24gKCkge30sXG5cblx0LyoqXG5cdCAqIFBhcnNlIGEgc2ltcGxlIEhUTUwgc3RyaW5nIGludG8gU1ZHIHRzcGFuc1xuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gdGV4dE5vZGUgVGhlIHBhcmVudCB0ZXh0IFNWRyBub2RlXG5cdCAqL1xuXHRidWlsZFRleHQ6IGZ1bmN0aW9uICh3cmFwcGVyKSB7XG5cdFx0dmFyIHRleHROb2RlID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0cmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0Zm9yRXhwb3J0ID0gcmVuZGVyZXIuZm9yRXhwb3J0LFxuXHRcdFx0dGV4dFN0ciA9IHBpY2sod3JhcHBlci50ZXh0U3RyLCAnJykudG9TdHJpbmcoKSxcblx0XHRcdGhhc01hcmt1cCA9IHRleHRTdHIuaW5kZXhPZignPCcpICE9PSAtMSxcblx0XHRcdGxpbmVzLFxuXHRcdFx0Y2hpbGROb2RlcyA9IHRleHROb2RlLmNoaWxkTm9kZXMsXG5cdFx0XHRzdHlsZVJlZ2V4LFxuXHRcdFx0aHJlZlJlZ2V4LFxuXHRcdFx0cGFyZW50WCA9IGF0dHIodGV4dE5vZGUsICd4JyksXG5cdFx0XHR0ZXh0U3R5bGVzID0gd3JhcHBlci5zdHlsZXMsXG5cdFx0XHR3aWR0aCA9IHdyYXBwZXIudGV4dFdpZHRoLFxuXHRcdFx0dGV4dExpbmVIZWlnaHQgPSB0ZXh0U3R5bGVzICYmIHRleHRTdHlsZXMubGluZUhlaWdodCxcblx0XHRcdHRleHRTdHJva2UgPSB0ZXh0U3R5bGVzICYmIHRleHRTdHlsZXMuSGNUZXh0U3Ryb2tlLFxuXHRcdFx0aSA9IGNoaWxkTm9kZXMubGVuZ3RoLFxuXHRcdFx0Z2V0TGluZUhlaWdodCA9IGZ1bmN0aW9uICh0c3Bhbikge1xuXHRcdFx0XHRyZXR1cm4gdGV4dExpbmVIZWlnaHQgPyBcblx0XHRcdFx0XHRwSW50KHRleHRMaW5lSGVpZ2h0KSA6XG5cdFx0XHRcdFx0cmVuZGVyZXIuZm9udE1ldHJpY3MoXG5cdFx0XHRcdFx0XHQvKHB4fGVtKSQvLnRlc3QodHNwYW4gJiYgdHNwYW4uc3R5bGUuZm9udFNpemUpID9cblx0XHRcdFx0XHRcdFx0dHNwYW4uc3R5bGUuZm9udFNpemUgOlxuXHRcdFx0XHRcdFx0XHQoKHRleHRTdHlsZXMgJiYgdGV4dFN0eWxlcy5mb250U2l6ZSkgfHwgcmVuZGVyZXIuc3R5bGUuZm9udFNpemUgfHwgMTIpLFxuXHRcdFx0XHRcdFx0dHNwYW5cblx0XHRcdFx0XHQpLmg7XG5cdFx0XHR9O1xuXG5cdFx0Ly8vIHJlbW92ZSBvbGQgdGV4dFxuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHRleHROb2RlLnJlbW92ZUNoaWxkKGNoaWxkTm9kZXNbaV0pO1xuXHRcdH1cblxuXHRcdC8vIFNraXAgdHNwYW5zLCBhZGQgdGV4dCBkaXJlY3RseSB0byB0ZXh0IG5vZGUuIFRoZSBmb3JjZVRTcGFuIGlzIGEgaG9vayBcblx0XHQvLyB1c2VkIGluIHRleHQgb3V0bGluZSBoYWNrLlxuXHRcdGlmICghaGFzTWFya3VwICYmICF0ZXh0U3Ryb2tlICYmIHRleHRTdHIuaW5kZXhPZignICcpID09PSAtMSkge1xuXHRcdFx0dGV4dE5vZGUuYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKHRleHRTdHIpKTtcblx0XHRcdHJldHVybjtcblxuXHRcdC8vIENvbXBsZXggc3RyaW5ncywgYWRkIG1vcmUgbG9naWNcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRzdHlsZVJlZ2V4ID0gLzwuKnN0eWxlPVwiKFteXCJdKylcIi4qPi87XG5cdFx0XHRocmVmUmVnZXggPSAvPC4qaHJlZj1cIihodHRwW15cIl0rKVwiLio+LztcblxuXHRcdFx0aWYgKHdpZHRoICYmICF3cmFwcGVyLmFkZGVkKSB7XG5cdFx0XHRcdHRoaXMuYm94LmFwcGVuZENoaWxkKHRleHROb2RlKTsgLy8gYXR0YWNoIGl0IHRvIHRoZSBET00gdG8gcmVhZCBvZmZzZXQgd2lkdGhcblx0XHRcdH1cblxuXHRcdFx0aWYgKGhhc01hcmt1cCkge1xuXHRcdFx0XHRsaW5lcyA9IHRleHRTdHJcblx0XHRcdFx0XHQucmVwbGFjZSgvPChifHN0cm9uZyk+L2csICc8c3BhbiBzdHlsZT1cImZvbnQtd2VpZ2h0OmJvbGRcIj4nKVxuXHRcdFx0XHRcdC5yZXBsYWNlKC88KGl8ZW0pPi9nLCAnPHNwYW4gc3R5bGU9XCJmb250LXN0eWxlOml0YWxpY1wiPicpXG5cdFx0XHRcdFx0LnJlcGxhY2UoLzxhL2csICc8c3BhbicpXG5cdFx0XHRcdFx0LnJlcGxhY2UoLzxcXC8oYnxzdHJvbmd8aXxlbXxhKT4vZywgJzwvc3Bhbj4nKVxuXHRcdFx0XHRcdC5zcGxpdCgvPGJyLio/Pi9nKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGluZXMgPSBbdGV4dFN0cl07XG5cdFx0XHR9XG5cblxuXHRcdFx0Ly8gcmVtb3ZlIGVtcHR5IGxpbmUgYXQgZW5kXG5cdFx0XHRpZiAobGluZXNbbGluZXMubGVuZ3RoIC0gMV0gPT09ICcnKSB7XG5cdFx0XHRcdGxpbmVzLnBvcCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRcblx0XHRcdC8vIGJ1aWxkIHRoZSBsaW5lc1xuXHRcdFx0ZWFjaChsaW5lcywgZnVuY3Rpb24gKGxpbmUsIGxpbmVObykge1xuXHRcdFx0XHR2YXIgc3BhbnMsIHNwYW5ObyA9IDA7XG5cblx0XHRcdFx0bGluZSA9IGxpbmUucmVwbGFjZSgvPHNwYW4vZywgJ3x8fDxzcGFuJykucmVwbGFjZSgvPFxcL3NwYW4+L2csICc8L3NwYW4+fHx8Jyk7XG5cdFx0XHRcdHNwYW5zID0gbGluZS5zcGxpdCgnfHx8Jyk7XG5cblx0XHRcdFx0ZWFjaChzcGFucywgZnVuY3Rpb24gKHNwYW4pIHtcblx0XHRcdFx0XHRpZiAoc3BhbiAhPT0gJycgfHwgc3BhbnMubGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdFx0XHR2YXIgYXR0cmlidXRlcyA9IHt9LFxuXHRcdFx0XHRcdFx0XHR0c3BhbiA9IGRvYy5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAndHNwYW4nKSxcblx0XHRcdFx0XHRcdFx0c3BhblN0eWxlOyAvLyAjMzkwXG5cdFx0XHRcdFx0XHRpZiAoc3R5bGVSZWdleC50ZXN0KHNwYW4pKSB7XG5cdFx0XHRcdFx0XHRcdHNwYW5TdHlsZSA9IHNwYW4ubWF0Y2goc3R5bGVSZWdleClbMV0ucmVwbGFjZSgvKDt8IHxeKWNvbG9yKFsgOl0pLywgJyQxZmlsbCQyJyk7XG5cdFx0XHRcdFx0XHRcdGF0dHIodHNwYW4sICdzdHlsZScsIHNwYW5TdHlsZSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAoaHJlZlJlZ2V4LnRlc3Qoc3BhbikgJiYgIWZvckV4cG9ydCkgeyAvLyBOb3QgZm9yIGV4cG9ydCAtICMxNTI5XG5cdFx0XHRcdFx0XHRcdGF0dHIodHNwYW4sICdvbmNsaWNrJywgJ2xvY2F0aW9uLmhyZWY9XFxcIicgKyBzcGFuLm1hdGNoKGhyZWZSZWdleClbMV0gKyAnXFxcIicpO1xuXHRcdFx0XHRcdFx0XHRjc3ModHNwYW4sIHsgY3Vyc29yOiAncG9pbnRlcicgfSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHNwYW4gPSAoc3Bhbi5yZXBsYWNlKC88KC58XFxuKSo/Pi9nLCAnJykgfHwgJyAnKVxuXHRcdFx0XHRcdFx0XHQucmVwbGFjZSgvJmx0Oy9nLCAnPCcpXG5cdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC8mZ3Q7L2csICc+Jyk7XG5cblx0XHRcdFx0XHRcdC8vIE5lc3RlZCB0YWdzIGFyZW4ndCBzdXBwb3J0ZWQsIGFuZCBjYXVzZSBjcmFzaCBpbiBTYWZhcmkgKCMxNTk2KVxuXHRcdFx0XHRcdFx0aWYgKHNwYW4gIT09ICcgJykge1xuXG5cdFx0XHRcdFx0XHRcdC8vIGFkZCB0aGUgdGV4dCBub2RlXG5cdFx0XHRcdFx0XHRcdHRzcGFuLmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZShzcGFuKSk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCFzcGFuTm8pIHsgLy8gZmlyc3Qgc3BhbiBpbiBhIGxpbmUsIGFsaWduIGl0IHRvIHRoZSBsZWZ0XG5cdFx0XHRcdFx0XHRcdFx0aWYgKGxpbmVObyAmJiBwYXJlbnRYICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhdHRyaWJ1dGVzLnggPSBwYXJlbnRYO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRhdHRyaWJ1dGVzLmR4ID0gMDsgLy8gIzE2XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyBhZGQgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHRhdHRyKHRzcGFuLCBhdHRyaWJ1dGVzKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBBcHBlbmQgaXRcblx0XHRcdFx0XHRcdFx0dGV4dE5vZGUuYXBwZW5kQ2hpbGQodHNwYW4pO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGZpcnN0IHNwYW4gb24gc3Vic2VxdWVudCBsaW5lLCBhZGQgdGhlIGxpbmUgaGVpZ2h0XG5cdFx0XHRcdFx0XHRcdGlmICghc3Bhbk5vICYmIGxpbmVObykge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gYWxsb3cgZ2V0dGluZyB0aGUgcmlnaHQgb2Zmc2V0IGhlaWdodCBpbiBleHBvcnRpbmcgaW4gSUVcblx0XHRcdFx0XHRcdFx0XHRpZiAoIWhhc1NWRyAmJiBmb3JFeHBvcnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNzcyh0c3BhbiwgeyBkaXNwbGF5OiAnYmxvY2snIH0pO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdC8vIFNldCB0aGUgbGluZSBoZWlnaHQgYmFzZWQgb24gdGhlIGZvbnQgc2l6ZSBvZiBlaXRoZXJcblx0XHRcdFx0XHRcdFx0XHQvLyB0aGUgdGV4dCBlbGVtZW50IG9yIHRoZSB0c3BhbiBlbGVtZW50XG5cdFx0XHRcdFx0XHRcdFx0YXR0cihcblx0XHRcdFx0XHRcdFx0XHRcdHRzcGFuLFxuXHRcdFx0XHRcdFx0XHRcdFx0J2R5Jyxcblx0XHRcdFx0XHRcdFx0XHRcdGdldExpbmVIZWlnaHQodHNwYW4pXG5cdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIGNoZWNrIHdpZHRoIGFuZCBhcHBseSBzb2Z0IGJyZWFrc1xuXHRcdFx0XHRcdFx0XHRpZiAod2lkdGgpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgd29yZHMgPSBzcGFuLnJlcGxhY2UoLyhbXlxcXl0pLS9nLCAnJDEtICcpLnNwbGl0KCcgJyksIC8vICMxMjczXG5cdFx0XHRcdFx0XHRcdFx0XHRoYXNXaGl0ZVNwYWNlID0gc3BhbnMubGVuZ3RoID4gMSB8fCAod29yZHMubGVuZ3RoID4gMSAmJiB0ZXh0U3R5bGVzLndoaXRlU3BhY2UgIT09ICdub3dyYXAnKSxcblx0XHRcdFx0XHRcdFx0XHRcdHRvb0xvbmcsXG5cdFx0XHRcdFx0XHRcdFx0XHRhY3R1YWxXaWR0aCxcblx0XHRcdFx0XHRcdFx0XHRcdGhjSGVpZ2h0ID0gdGV4dFN0eWxlcy5IY0hlaWdodCxcblx0XHRcdFx0XHRcdFx0XHRcdHJlc3QgPSBbXSxcblx0XHRcdFx0XHRcdFx0XHRcdGR5ID0gZ2V0TGluZUhlaWdodCh0c3BhbiksXG5cdFx0XHRcdFx0XHRcdFx0XHRzb2Z0TGluZU5vID0gMSxcblx0XHRcdFx0XHRcdFx0XHRcdGJCb3g7XG5cblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoaGFzV2hpdGVTcGFjZSAmJiAod29yZHMubGVuZ3RoIHx8IHJlc3QubGVuZ3RoKSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGVsZXRlIHdyYXBwZXIuYkJveDsgLy8gZGVsZXRlIGNhY2hlXG5cdFx0XHRcdFx0XHRcdFx0XHRiQm94ID0gd3JhcHBlci5nZXRCQm94KCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRhY3R1YWxXaWR0aCA9IGJCb3gud2lkdGg7XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIE9sZCBJRSBjYW5ub3QgbWVhc3VyZSB0aGUgYWN0dWFsV2lkdGggZm9yIFNWRyBlbGVtZW50cyAoIzIzMTQpXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIWhhc1NWRyAmJiByZW5kZXJlci5mb3JFeHBvcnQpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YWN0dWFsV2lkdGggPSByZW5kZXJlci5tZWFzdXJlU3BhbldpZHRoKHRzcGFuLmZpcnN0Q2hpbGQuZGF0YSwgd3JhcHBlci5zdHlsZXMpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHR0b29Mb25nID0gYWN0dWFsV2lkdGggPiB3aWR0aDtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICghdG9vTG9uZyB8fCB3b3Jkcy5sZW5ndGggPT09IDEpIHsgLy8gbmV3IGxpbmUgbmVlZGVkXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHdvcmRzID0gcmVzdDtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzdCA9IFtdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAod29yZHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0c29mdExpbmVObysrO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChoY0hlaWdodCAmJiBzb2Z0TGluZU5vICogZHkgPiBoY0hlaWdodCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0d29yZHMgPSBbJy4uLiddO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0d3JhcHBlci5hdHRyKCd0aXRsZScsIHdyYXBwZXIudGV4dFN0cik7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dHNwYW4gPSBkb2MuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgJ3RzcGFuJyk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhdHRyKHRzcGFuLCB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGR5OiBkeSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0eDogcGFyZW50WFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoc3BhblN0eWxlKSB7IC8vICMzOTBcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXR0cih0c3BhbiwgJ3N0eWxlJywgc3BhblN0eWxlKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRleHROb2RlLmFwcGVuZENoaWxkKHRzcGFuKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKGFjdHVhbFdpZHRoID4gd2lkdGgpIHsgLy8gYSBzaW5nbGUgd29yZCBpcyBwcmVzc2luZyBpdCBvdXRcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR3aWR0aCA9IGFjdHVhbFdpZHRoO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgeyAvLyBhcHBlbmQgdG8gZXhpc3RpbmcgbGluZSB0c3BhblxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0c3Bhbi5yZW1vdmVDaGlsZCh0c3Bhbi5maXJzdENoaWxkKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzdC51bnNoaWZ0KHdvcmRzLnBvcCgpKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdGlmICh3b3Jkcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dHNwYW4uYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKHdvcmRzLmpvaW4oJyAnKS5yZXBsYWNlKC8tIC9nLCAnLScpKSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0c3Bhbk5vKys7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIGEgYnV0dG9uIHdpdGggcHJlc2V0IHN0YXRlc1xuXHQgKiBAcGFyYW0ge1N0cmluZ30gdGV4dFxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuXHQgKiBAcGFyYW0ge09iamVjdH0gbm9ybWFsU3RhdGVcblx0ICogQHBhcmFtIHtPYmplY3R9IGhvdmVyU3RhdGVcblx0ICogQHBhcmFtIHtPYmplY3R9IHByZXNzZWRTdGF0ZVxuXHQgKi9cblx0YnV0dG9uOiBmdW5jdGlvbiAodGV4dCwgeCwgeSwgY2FsbGJhY2ssIG5vcm1hbFN0YXRlLCBob3ZlclN0YXRlLCBwcmVzc2VkU3RhdGUsIGRpc2FibGVkU3RhdGUsIHNoYXBlKSB7XG5cdFx0dmFyIGxhYmVsID0gdGhpcy5sYWJlbCh0ZXh0LCB4LCB5LCBzaGFwZSwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgJ2J1dHRvbicpLFxuXHRcdFx0Y3VyU3RhdGUgPSAwLFxuXHRcdFx0c3RhdGVPcHRpb25zLFxuXHRcdFx0c3RhdGVTdHlsZSxcblx0XHRcdG5vcm1hbFN0eWxlLFxuXHRcdFx0aG92ZXJTdHlsZSxcblx0XHRcdHByZXNzZWRTdHlsZSxcblx0XHRcdGRpc2FibGVkU3R5bGUsXG5cdFx0XHR2ZXJ0aWNhbEdyYWRpZW50ID0geyB4MTogMCwgeTE6IDAsIHgyOiAwLCB5MjogMSB9O1xuXG5cdFx0Ly8gTm9ybWFsIHN0YXRlIC0gcHJlcGFyZSB0aGUgYXR0cmlidXRlc1xuXHRcdG5vcm1hbFN0YXRlID0gbWVyZ2Uoe1xuXHRcdFx0J3N0cm9rZS13aWR0aCc6IDEsXG5cdFx0XHRzdHJva2U6ICcjQ0NDQ0NDJyxcblx0XHRcdGZpbGw6IHtcblx0XHRcdFx0bGluZWFyR3JhZGllbnQ6IHZlcnRpY2FsR3JhZGllbnQsXG5cdFx0XHRcdHN0b3BzOiBbXG5cdFx0XHRcdFx0WzAsICcjRkVGRUZFJ10sXG5cdFx0XHRcdFx0WzEsICcjRjZGNkY2J11cblx0XHRcdFx0XVxuXHRcdFx0fSxcblx0XHRcdHI6IDIsXG5cdFx0XHRwYWRkaW5nOiA1LFxuXHRcdFx0c3R5bGU6IHtcblx0XHRcdFx0Y29sb3I6ICdibGFjaydcblx0XHRcdH1cblx0XHR9LCBub3JtYWxTdGF0ZSk7XG5cdFx0bm9ybWFsU3R5bGUgPSBub3JtYWxTdGF0ZS5zdHlsZTtcblx0XHRkZWxldGUgbm9ybWFsU3RhdGUuc3R5bGU7XG5cblx0XHQvLyBIb3ZlciBzdGF0ZVxuXHRcdGhvdmVyU3RhdGUgPSBtZXJnZShub3JtYWxTdGF0ZSwge1xuXHRcdFx0c3Ryb2tlOiAnIzY4QScsXG5cdFx0XHRmaWxsOiB7XG5cdFx0XHRcdGxpbmVhckdyYWRpZW50OiB2ZXJ0aWNhbEdyYWRpZW50LFxuXHRcdFx0XHRzdG9wczogW1xuXHRcdFx0XHRcdFswLCAnI0ZGRiddLFxuXHRcdFx0XHRcdFsxLCAnI0FDRiddXG5cdFx0XHRcdF1cblx0XHRcdH1cblx0XHR9LCBob3ZlclN0YXRlKTtcblx0XHRob3ZlclN0eWxlID0gaG92ZXJTdGF0ZS5zdHlsZTtcblx0XHRkZWxldGUgaG92ZXJTdGF0ZS5zdHlsZTtcblxuXHRcdC8vIFByZXNzZWQgc3RhdGVcblx0XHRwcmVzc2VkU3RhdGUgPSBtZXJnZShub3JtYWxTdGF0ZSwge1xuXHRcdFx0c3Ryb2tlOiAnIzY4QScsXG5cdFx0XHRmaWxsOiB7XG5cdFx0XHRcdGxpbmVhckdyYWRpZW50OiB2ZXJ0aWNhbEdyYWRpZW50LFxuXHRcdFx0XHRzdG9wczogW1xuXHRcdFx0XHRcdFswLCAnIzlCRCddLFxuXHRcdFx0XHRcdFsxLCAnI0NERiddXG5cdFx0XHRcdF1cblx0XHRcdH1cblx0XHR9LCBwcmVzc2VkU3RhdGUpO1xuXHRcdHByZXNzZWRTdHlsZSA9IHByZXNzZWRTdGF0ZS5zdHlsZTtcblx0XHRkZWxldGUgcHJlc3NlZFN0YXRlLnN0eWxlO1xuXG5cdFx0Ly8gRGlzYWJsZWQgc3RhdGVcblx0XHRkaXNhYmxlZFN0YXRlID0gbWVyZ2Uobm9ybWFsU3RhdGUsIHtcblx0XHRcdHN0eWxlOiB7XG5cdFx0XHRcdGNvbG9yOiAnI0NDQydcblx0XHRcdH1cblx0XHR9LCBkaXNhYmxlZFN0YXRlKTtcblx0XHRkaXNhYmxlZFN0eWxlID0gZGlzYWJsZWRTdGF0ZS5zdHlsZTtcblx0XHRkZWxldGUgZGlzYWJsZWRTdGF0ZS5zdHlsZTtcblxuXHRcdC8vIEFkZCB0aGUgZXZlbnRzLiBJRTkgYW5kIElFMTAgbmVlZCBtb3VzZW92ZXIgYW5kIG1vdXNlb3V0IHRvIGZ1bmNpdG9uICgjNjY3KS5cblx0XHRhZGRFdmVudChsYWJlbC5lbGVtZW50LCBpc0lFID8gJ21vdXNlb3ZlcicgOiAnbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChjdXJTdGF0ZSAhPT0gMykge1xuXHRcdFx0XHRsYWJlbC5hdHRyKGhvdmVyU3RhdGUpXG5cdFx0XHRcdFx0LmNzcyhob3ZlclN0eWxlKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRhZGRFdmVudChsYWJlbC5lbGVtZW50LCBpc0lFID8gJ21vdXNlb3V0JyA6ICdtb3VzZWxlYXZlJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKGN1clN0YXRlICE9PSAzKSB7XG5cdFx0XHRcdHN0YXRlT3B0aW9ucyA9IFtub3JtYWxTdGF0ZSwgaG92ZXJTdGF0ZSwgcHJlc3NlZFN0YXRlXVtjdXJTdGF0ZV07XG5cdFx0XHRcdHN0YXRlU3R5bGUgPSBbbm9ybWFsU3R5bGUsIGhvdmVyU3R5bGUsIHByZXNzZWRTdHlsZV1bY3VyU3RhdGVdO1xuXHRcdFx0XHRsYWJlbC5hdHRyKHN0YXRlT3B0aW9ucylcblx0XHRcdFx0XHQuY3NzKHN0YXRlU3R5bGUpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0bGFiZWwuc2V0U3RhdGUgPSBmdW5jdGlvbiAoc3RhdGUpIHtcblx0XHRcdGxhYmVsLnN0YXRlID0gY3VyU3RhdGUgPSBzdGF0ZTtcblx0XHRcdGlmICghc3RhdGUpIHtcblx0XHRcdFx0bGFiZWwuYXR0cihub3JtYWxTdGF0ZSlcblx0XHRcdFx0XHQuY3NzKG5vcm1hbFN0eWxlKTtcblx0XHRcdH0gZWxzZSBpZiAoc3RhdGUgPT09IDIpIHtcblx0XHRcdFx0bGFiZWwuYXR0cihwcmVzc2VkU3RhdGUpXG5cdFx0XHRcdFx0LmNzcyhwcmVzc2VkU3R5bGUpO1xuXHRcdFx0fSBlbHNlIGlmIChzdGF0ZSA9PT0gMykge1xuXHRcdFx0XHRsYWJlbC5hdHRyKGRpc2FibGVkU3RhdGUpXG5cdFx0XHRcdFx0LmNzcyhkaXNhYmxlZFN0eWxlKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0cmV0dXJuIGxhYmVsXG5cdFx0XHQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoY3VyU3RhdGUgIT09IDMpIHtcblx0XHRcdFx0XHRjYWxsYmFjay5jYWxsKGxhYmVsKTtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5hdHRyKG5vcm1hbFN0YXRlKVxuXHRcdFx0LmNzcyhleHRlbmQoeyBjdXJzb3I6ICdkZWZhdWx0JyB9LCBub3JtYWxTdHlsZSkpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBNYWtlIGEgc3RyYWlnaHQgbGluZSBjcmlzcGVyIGJ5IG5vdCBzcGlsbGluZyBvdXQgdG8gbmVpZ2hib3VyIHBpeGVsc1xuXHQgKiBAcGFyYW0ge0FycmF5fSBwb2ludHNcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoXG5cdCAqL1xuXHRjcmlzcExpbmU6IGZ1bmN0aW9uIChwb2ludHMsIHdpZHRoKSB7XG5cdFx0Ly8gcG9pbnRzIGZvcm1hdDogW00sIDAsIDAsIEwsIDEwMCwgMF1cblx0XHQvLyBub3JtYWxpemUgdG8gYSBjcmlzcCBsaW5lXG5cdFx0aWYgKHBvaW50c1sxXSA9PT0gcG9pbnRzWzRdKSB7XG5cdFx0XHQvLyBTdWJzdHJhY3QgZHVlIHRvICMxMTI5LiBOb3cgYm90dG9tIGFuZCBsZWZ0IGF4aXMgZ3JpZGxpbmVzIGJlaGF2ZSB0aGUgc2FtZS5cblx0XHRcdHBvaW50c1sxXSA9IHBvaW50c1s0XSA9IG1hdGhSb3VuZChwb2ludHNbMV0pIC0gKHdpZHRoICUgMiAvIDIpO1xuXHRcdH1cblx0XHRpZiAocG9pbnRzWzJdID09PSBwb2ludHNbNV0pIHtcblx0XHRcdHBvaW50c1syXSA9IHBvaW50c1s1XSA9IG1hdGhSb3VuZChwb2ludHNbMl0pICsgKHdpZHRoICUgMiAvIDIpO1xuXHRcdH1cblx0XHRyZXR1cm4gcG9pbnRzO1xuXHR9LFxuXG5cblx0LyoqXG5cdCAqIERyYXcgYSBwYXRoXG5cdCAqIEBwYXJhbSB7QXJyYXl9IHBhdGggQW4gU1ZHIHBhdGggaW4gYXJyYXkgZm9ybVxuXHQgKi9cblx0cGF0aDogZnVuY3Rpb24gKHBhdGgpIHtcblx0XHR2YXIgYXR0ciA9IHtcblx0XHRcdGZpbGw6IE5PTkVcblx0XHR9O1xuXHRcdGlmIChpc0FycmF5KHBhdGgpKSB7XG5cdFx0XHRhdHRyLmQgPSBwYXRoO1xuXHRcdH0gZWxzZSBpZiAoaXNPYmplY3QocGF0aCkpIHsgLy8gYXR0cmlidXRlc1xuXHRcdFx0ZXh0ZW5kKGF0dHIsIHBhdGgpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5jcmVhdGVFbGVtZW50KCdwYXRoJykuYXR0cihhdHRyKTtcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyBhbmQgcmV0dXJuIGFuIFNWRyBjaXJjbGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggVGhlIHggcG9zaXRpb25cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHkgVGhlIHkgcG9zaXRpb25cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHIgVGhlIHJhZGl1c1xuXHQgKi9cblx0Y2lyY2xlOiBmdW5jdGlvbiAoeCwgeSwgcikge1xuXHRcdHZhciBhdHRyID0gaXNPYmplY3QoeCkgP1xuXHRcdFx0eCA6XG5cdFx0XHR7XG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHksXG5cdFx0XHRcdHI6IHJcblx0XHRcdH0sXG5cdFx0XHR3cmFwcGVyID0gdGhpcy5jcmVhdGVFbGVtZW50KCdjaXJjbGUnKTtcblxuXHRcdHdyYXBwZXIueFNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0dGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3gnLCB2YWx1ZSk7XG5cdFx0fTtcblx0XHR3cmFwcGVyLnlTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2N5JywgdmFsdWUpO1xuXHRcdH07XG5cdFx0cmV0dXJuIHdyYXBwZXIuYXR0cihhdHRyKTtcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyBhbmQgcmV0dXJuIGFuIGFyY1xuXHQgKiBAcGFyYW0ge051bWJlcn0geCBYIHBvc2l0aW9uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IFkgcG9zaXRpb25cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHIgUmFkaXVzXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBpbm5lclIgSW5uZXIgcmFkaXVzIGxpa2UgdXNlZCBpbiBkb251dCBjaGFydHNcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0IFN0YXJ0aW5nIGFuZ2xlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBlbmQgRW5kaW5nIGFuZ2xlXG5cdCAqL1xuXHRhcmM6IGZ1bmN0aW9uICh4LCB5LCByLCBpbm5lclIsIHN0YXJ0LCBlbmQpIHtcblx0XHR2YXIgYXJjO1xuXG5cdFx0aWYgKGlzT2JqZWN0KHgpKSB7XG5cdFx0XHR5ID0geC55O1xuXHRcdFx0ciA9IHgucjtcblx0XHRcdGlubmVyUiA9IHguaW5uZXJSO1xuXHRcdFx0c3RhcnQgPSB4LnN0YXJ0O1xuXHRcdFx0ZW5kID0geC5lbmQ7XG5cdFx0XHR4ID0geC54O1xuXHRcdH1cblxuXHRcdC8vIEFyY3MgYXJlIGRlZmluZWQgYXMgc3ltYm9scyBmb3IgdGhlIGFiaWxpdHkgdG8gc2V0XG5cdFx0Ly8gYXR0cmlidXRlcyBpbiBhdHRyIGFuZCBhbmltYXRlXG5cdFx0YXJjID0gdGhpcy5zeW1ib2woJ2FyYycsIHggfHwgMCwgeSB8fCAwLCByIHx8IDAsIHIgfHwgMCwge1xuXHRcdFx0aW5uZXJSOiBpbm5lclIgfHwgMCxcblx0XHRcdHN0YXJ0OiBzdGFydCB8fCAwLFxuXHRcdFx0ZW5kOiBlbmQgfHwgMFxuXHRcdH0pO1xuXHRcdGFyYy5yID0gcjsgLy8gIzk1OVxuXHRcdHJldHVybiBhcmM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIERyYXcgYW5kIHJldHVybiBhIHJlY3RhbmdsZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBMZWZ0IHBvc2l0aW9uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IFRvcCBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKiBAcGFyYW0ge051bWJlcn0gciBCb3JkZXIgY29ybmVyIHJhZGl1c1xuXHQgKiBAcGFyYW0ge051bWJlcn0gc3Ryb2tlV2lkdGggQSBzdHJva2Ugd2lkdGggY2FuIGJlIHN1cHBsaWVkIHRvIGFsbG93IGNyaXNwIGRyYXdpbmdcblx0ICovXG5cdHJlY3Q6IGZ1bmN0aW9uICh4LCB5LCB3aWR0aCwgaGVpZ2h0LCByLCBzdHJva2VXaWR0aCkge1xuXG5cdFx0ciA9IGlzT2JqZWN0KHgpID8geC5yIDogcjtcblxuXHRcdHZhciB3cmFwcGVyID0gdGhpcy5jcmVhdGVFbGVtZW50KCdyZWN0JyksXG5cdFx0XHRhdHRyaWJzID0gaXNPYmplY3QoeCkgPyB4IDogeCA9PT0gVU5ERUZJTkVEID8ge30gOiB7XG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHksXG5cdFx0XHRcdHdpZHRoOiBtYXRoTWF4KHdpZHRoLCAwKSxcblx0XHRcdFx0aGVpZ2h0OiBtYXRoTWF4KGhlaWdodCwgMClcblx0XHRcdH07XG5cblx0XHRpZiAoc3Ryb2tlV2lkdGggIT09IFVOREVGSU5FRCkge1xuXHRcdFx0YXR0cmlicy5zdHJva2VXaWR0aCA9IHN0cm9rZVdpZHRoO1xuXHRcdFx0YXR0cmlicyA9IHdyYXBwZXIuY3Jpc3AoYXR0cmlicyk7XG5cdFx0fVxuXG5cdFx0aWYgKHIpIHtcblx0XHRcdGF0dHJpYnMuciA9IHI7XG5cdFx0fVxuXG5cdFx0d3JhcHBlci5yU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRhdHRyKHRoaXMuZWxlbWVudCwge1xuXHRcdFx0XHRyeDogdmFsdWUsXG5cdFx0XHRcdHJ5OiB2YWx1ZVxuXHRcdFx0fSk7XG5cdFx0fTtcblx0XHRcblx0XHRyZXR1cm4gd3JhcHBlci5hdHRyKGF0dHJpYnMpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXNpemUgdGhlIGJveCBhbmQgcmUtYWxpZ24gYWxsIGFsaWduZWQgZWxlbWVudHNcblx0ICogQHBhcmFtIHtPYmplY3R9IHdpZHRoXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBoZWlnaHRcblx0ICogQHBhcmFtIHtCb29sZWFufSBhbmltYXRlXG5cdCAqXG5cdCAqL1xuXHRzZXRTaXplOiBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCwgYW5pbWF0ZSkge1xuXHRcdHZhciByZW5kZXJlciA9IHRoaXMsXG5cdFx0XHRhbGlnbmVkT2JqZWN0cyA9IHJlbmRlcmVyLmFsaWduZWRPYmplY3RzLFxuXHRcdFx0aSA9IGFsaWduZWRPYmplY3RzLmxlbmd0aDtcblxuXHRcdHJlbmRlcmVyLndpZHRoID0gd2lkdGg7XG5cdFx0cmVuZGVyZXIuaGVpZ2h0ID0gaGVpZ2h0O1xuXG5cdFx0cmVuZGVyZXIuYm94V3JhcHBlcltwaWNrKGFuaW1hdGUsIHRydWUpID8gJ2FuaW1hdGUnIDogJ2F0dHInXSh7XG5cdFx0XHR3aWR0aDogd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdH0pO1xuXG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0YWxpZ25lZE9iamVjdHNbaV0uYWxpZ24oKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIGdyb3VwXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBncm91cCB3aWxsIGJlIGdpdmVuIGEgY2xhc3MgbmFtZSBvZiAnaGlnaGNoYXJ0cy17bmFtZX0nLlxuXHQgKiAgICAgVGhpcyBjYW4gYmUgdXNlZCBmb3Igc3R5bGluZyBhbmQgc2NyaXB0aW5nLlxuXHQgKi9cblx0ZzogZnVuY3Rpb24gKG5hbWUpIHtcblx0XHR2YXIgZWxlbSA9IHRoaXMuY3JlYXRlRWxlbWVudCgnZycpO1xuXHRcdHJldHVybiBkZWZpbmVkKG5hbWUpID8gZWxlbS5hdHRyKHsgJ2NsYXNzJzogUFJFRklYICsgbmFtZSB9KSA6IGVsZW07XG5cdH0sXG5cblx0LyoqXG5cdCAqIERpc3BsYXkgYW4gaW1hZ2Vcblx0ICogQHBhcmFtIHtTdHJpbmd9IHNyY1xuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKi9cblx0aW1hZ2U6IGZ1bmN0aW9uIChzcmMsIHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcblx0XHR2YXIgYXR0cmlicyA9IHtcblx0XHRcdFx0cHJlc2VydmVBc3BlY3RSYXRpbzogTk9ORVxuXHRcdFx0fSxcblx0XHRcdGVsZW1XcmFwcGVyO1xuXG5cdFx0Ly8gb3B0aW9uYWwgcHJvcGVydGllc1xuXHRcdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdFx0ZXh0ZW5kKGF0dHJpYnMsIHtcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdFx0d2lkdGg6IHdpZHRoLFxuXHRcdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0ZWxlbVdyYXBwZXIgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ2ltYWdlJykuYXR0cihhdHRyaWJzKTtcblxuXHRcdC8vIHNldCB0aGUgaHJlZiBpbiB0aGUgeGxpbmsgbmFtZXNwYWNlXG5cdFx0aWYgKGVsZW1XcmFwcGVyLmVsZW1lbnQuc2V0QXR0cmlidXRlTlMpIHtcblx0XHRcdGVsZW1XcmFwcGVyLmVsZW1lbnQuc2V0QXR0cmlidXRlTlMoJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLFxuXHRcdFx0XHQnaHJlZicsIHNyYyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGNvdWxkIGJlIGV4cG9ydGluZyBpbiBJRVxuXHRcdFx0Ly8gdXNpbmcgaHJlZiB0aHJvd3MgXCJub3Qgc3VwcG9ydGVkXCIgaW4gaWU3IGFuZCB1bmRlciwgcmVxdXJpZXMgcmVnZXggc2hpbSB0byBmaXggbGF0ZXJcblx0XHRcdGVsZW1XcmFwcGVyLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdoYy1zdmctaHJlZicsIHNyYyk7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtV3JhcHBlcjtcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyBhIHN5bWJvbCBvdXQgb2YgcHJlLWRlZmluZWQgc2hhcGUgcGF0aHMgZnJvbSB0aGUgbmFtZXNwYWNlICdzeW1ib2wnIG9iamVjdC5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IHN5bWJvbFxuXHQgKiBAcGFyYW0ge09iamVjdH0geFxuXHQgKiBAcGFyYW0ge09iamVjdH0geVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcmFkaXVzXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG5cdCAqL1xuXHRzeW1ib2w6IGZ1bmN0aW9uIChzeW1ib2wsIHgsIHksIHdpZHRoLCBoZWlnaHQsIG9wdGlvbnMpIHtcblxuXHRcdHZhciBvYmosXG5cblx0XHRcdC8vIGdldCB0aGUgc3ltYm9sIGRlZmluaXRpb24gZnVuY3Rpb25cblx0XHRcdHN5bWJvbEZuID0gdGhpcy5zeW1ib2xzW3N5bWJvbF0sXG5cblx0XHRcdC8vIGNoZWNrIGlmIHRoZXJlJ3MgYSBwYXRoIGRlZmluZWQgZm9yIHRoaXMgc3ltYm9sXG5cdFx0XHRwYXRoID0gc3ltYm9sRm4gJiYgc3ltYm9sRm4oXG5cdFx0XHRcdG1hdGhSb3VuZCh4KSxcblx0XHRcdFx0bWF0aFJvdW5kKHkpLFxuXHRcdFx0XHR3aWR0aCxcblx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHRvcHRpb25zXG5cdFx0XHQpLFxuXG5cdFx0XHRpbWFnZUVsZW1lbnQsXG5cdFx0XHRpbWFnZVJlZ2V4ID0gL151cmxcXCgoLio/KVxcKSQvLFxuXHRcdFx0aW1hZ2VTcmMsXG5cdFx0XHRpbWFnZVNpemUsXG5cdFx0XHRjZW50ZXJJbWFnZTtcblxuXHRcdGlmIChwYXRoKSB7XG5cblx0XHRcdG9iaiA9IHRoaXMucGF0aChwYXRoKTtcblx0XHRcdC8vIGV4cGFuZG8gcHJvcGVydGllcyBmb3IgdXNlIGluIGFuaW1hdGUgYW5kIGF0dHJcblx0XHRcdGV4dGVuZChvYmosIHtcblx0XHRcdFx0c3ltYm9sTmFtZTogc3ltYm9sLFxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogd2lkdGgsXG5cdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHR9KTtcblx0XHRcdGlmIChvcHRpb25zKSB7XG5cdFx0XHRcdGV4dGVuZChvYmosIG9wdGlvbnMpO1xuXHRcdFx0fVxuXG5cblx0XHQvLyBpbWFnZSBzeW1ib2xzXG5cdFx0fSBlbHNlIGlmIChpbWFnZVJlZ2V4LnRlc3Qoc3ltYm9sKSkge1xuXG5cdFx0XHQvLyBPbiBpbWFnZSBsb2FkLCBzZXQgdGhlIHNpemUgYW5kIHBvc2l0aW9uXG5cdFx0XHRjZW50ZXJJbWFnZSA9IGZ1bmN0aW9uIChpbWcsIHNpemUpIHtcblx0XHRcdFx0aWYgKGltZy5lbGVtZW50KSB7IC8vIGl0IG1heSBiZSBkZXN0cm95ZWQgaW4gdGhlIG1lYW50aW1lICgjMTM5MClcblx0XHRcdFx0XHRpbWcuYXR0cih7XG5cdFx0XHRcdFx0XHR3aWR0aDogc2l6ZVswXSxcblx0XHRcdFx0XHRcdGhlaWdodDogc2l6ZVsxXVxuXHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0aWYgKCFpbWcuYWxpZ25CeVRyYW5zbGF0ZSkgeyAvLyAjMTg1XG5cdFx0XHRcdFx0XHRpbWcudHJhbnNsYXRlKFxuXHRcdFx0XHRcdFx0XHRtYXRoUm91bmQoKHdpZHRoIC0gc2l6ZVswXSkgLyAyKSwgLy8gIzEzNzhcblx0XHRcdFx0XHRcdFx0bWF0aFJvdW5kKChoZWlnaHQgLSBzaXplWzFdKSAvIDIpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdFx0aW1hZ2VTcmMgPSBzeW1ib2wubWF0Y2goaW1hZ2VSZWdleClbMV07XG5cdFx0XHRpbWFnZVNpemUgPSBzeW1ib2xTaXplc1tpbWFnZVNyY10gfHwgKG9wdGlvbnMgJiYgb3B0aW9ucy53aWR0aCAmJiBvcHRpb25zLmhlaWdodCAmJiBbb3B0aW9ucy53aWR0aCwgb3B0aW9ucy5oZWlnaHRdKTtcblxuXHRcdFx0Ly8gSXJlYXRlIHRoZSBpbWFnZSBzeW5jaHJvbm91c2x5LCBhZGQgYXR0cmlicyBhc3luY1xuXHRcdFx0b2JqID0gdGhpcy5pbWFnZShpbWFnZVNyYylcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHg6IHgsXG5cdFx0XHRcdFx0eTogeVxuXHRcdFx0XHR9KTtcblx0XHRcdG9iai5pc0ltZyA9IHRydWU7XG5cblx0XHRcdGlmIChpbWFnZVNpemUpIHtcblx0XHRcdFx0Y2VudGVySW1hZ2Uob2JqLCBpbWFnZVNpemUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gSW5pdGlhbGl6ZSBpbWFnZSB0byBiZSAwIHNpemUgc28gZXhwb3J0IHdpbGwgc3RpbGwgZnVuY3Rpb24gaWYgdGhlcmUncyBubyBjYWNoZWQgc2l6ZXMuXG5cdFx0XHRcdG9iai5hdHRyKHsgd2lkdGg6IDAsIGhlaWdodDogMCB9KTtcblxuXHRcdFx0XHQvLyBDcmVhdGUgYSBkdW1teSBKYXZhU2NyaXB0IGltYWdlIHRvIGdldCB0aGUgd2lkdGggYW5kIGhlaWdodC4gRHVlIHRvIGEgYnVnIGluIElFIDwgOCxcblx0XHRcdFx0Ly8gdGhlIGNyZWF0ZWQgZWxlbWVudCBtdXN0IGJlIGFzc2lnbmVkIHRvIGEgdmFyaWFibGUgaW4gb3JkZXIgdG8gbG9hZCAoIzI5MikuXG5cdFx0XHRcdGltYWdlRWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQoJ2ltZycsIHtcblx0XHRcdFx0XHRvbmxvYWQ6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdGNlbnRlckltYWdlKG9iaiwgc3ltYm9sU2l6ZXNbaW1hZ2VTcmNdID0gW3RoaXMud2lkdGgsIHRoaXMuaGVpZ2h0XSk7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRzcmM6IGltYWdlU3JjXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBvYmo7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFuIGV4dGVuZGFibGUgY29sbGVjdGlvbiBvZiBmdW5jdGlvbnMgZm9yIGRlZmluaW5nIHN5bWJvbCBwYXRocy5cblx0ICovXG5cdHN5bWJvbHM6IHtcblx0XHQnY2lyY2xlJzogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcblx0XHRcdHZhciBjcHcgPSAwLjE2NiAqIHc7XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRNLCB4ICsgdyAvIDIsIHksXG5cdFx0XHRcdCdDJywgeCArIHcgKyBjcHcsIHksIHggKyB3ICsgY3B3LCB5ICsgaCwgeCArIHcgLyAyLCB5ICsgaCxcblx0XHRcdFx0J0MnLCB4IC0gY3B3LCB5ICsgaCwgeCAtIGNwdywgeSwgeCArIHcgLyAyLCB5LFxuXHRcdFx0XHQnWidcblx0XHRcdF07XG5cdFx0fSxcblxuXHRcdCdzcXVhcmUnOiBmdW5jdGlvbiAoeCwgeSwgdywgaCkge1xuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0TSwgeCwgeSxcblx0XHRcdFx0TCwgeCArIHcsIHksXG5cdFx0XHRcdHggKyB3LCB5ICsgaCxcblx0XHRcdFx0eCwgeSArIGgsXG5cdFx0XHRcdCdaJ1xuXHRcdFx0XTtcblx0XHR9LFxuXG5cdFx0J3RyaWFuZ2xlJzogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcblx0XHRcdHJldHVybiBbXG5cdFx0XHRcdE0sIHggKyB3IC8gMiwgeSxcblx0XHRcdFx0TCwgeCArIHcsIHkgKyBoLFxuXHRcdFx0XHR4LCB5ICsgaCxcblx0XHRcdFx0J1onXG5cdFx0XHRdO1xuXHRcdH0sXG5cblx0XHQndHJpYW5nbGUtZG93bic6IGZ1bmN0aW9uICh4LCB5LCB3LCBoKSB7XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRNLCB4LCB5LFxuXHRcdFx0XHRMLCB4ICsgdywgeSxcblx0XHRcdFx0eCArIHcgLyAyLCB5ICsgaCxcblx0XHRcdFx0J1onXG5cdFx0XHRdO1xuXHRcdH0sXG5cdFx0J2RpYW1vbmQnOiBmdW5jdGlvbiAoeCwgeSwgdywgaCkge1xuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0TSwgeCArIHcgLyAyLCB5LFxuXHRcdFx0XHRMLCB4ICsgdywgeSArIGggLyAyLFxuXHRcdFx0XHR4ICsgdyAvIDIsIHkgKyBoLFxuXHRcdFx0XHR4LCB5ICsgaCAvIDIsXG5cdFx0XHRcdCdaJ1xuXHRcdFx0XTtcblx0XHR9LFxuXHRcdCdhcmMnOiBmdW5jdGlvbiAoeCwgeSwgdywgaCwgb3B0aW9ucykge1xuXHRcdFx0dmFyIHN0YXJ0ID0gb3B0aW9ucy5zdGFydCxcblx0XHRcdFx0cmFkaXVzID0gb3B0aW9ucy5yIHx8IHcgfHwgaCxcblx0XHRcdFx0ZW5kID0gb3B0aW9ucy5lbmQgLSAwLjAwMSwgLy8gdG8gcHJldmVudCBjb3MgYW5kIHNpbiBvZiBzdGFydCBhbmQgZW5kIGZyb20gYmVjb21pbmcgZXF1YWwgb24gMzYwIGFyY3MgKHJlbGF0ZWQ6ICMxNTYxKVxuXHRcdFx0XHRpbm5lclJhZGl1cyA9IG9wdGlvbnMuaW5uZXJSLFxuXHRcdFx0XHRvcGVuID0gb3B0aW9ucy5vcGVuLFxuXHRcdFx0XHRjb3NTdGFydCA9IG1hdGhDb3Moc3RhcnQpLFxuXHRcdFx0XHRzaW5TdGFydCA9IG1hdGhTaW4oc3RhcnQpLFxuXHRcdFx0XHRjb3NFbmQgPSBtYXRoQ29zKGVuZCksXG5cdFx0XHRcdHNpbkVuZCA9IG1hdGhTaW4oZW5kKSxcblx0XHRcdFx0bG9uZ0FyYyA9IG9wdGlvbnMuZW5kIC0gc3RhcnQgPCBtYXRoUEkgPyAwIDogMTtcblxuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0TSxcblx0XHRcdFx0eCArIHJhZGl1cyAqIGNvc1N0YXJ0LFxuXHRcdFx0XHR5ICsgcmFkaXVzICogc2luU3RhcnQsXG5cdFx0XHRcdCdBJywgLy8gYXJjVG9cblx0XHRcdFx0cmFkaXVzLCAvLyB4IHJhZGl1c1xuXHRcdFx0XHRyYWRpdXMsIC8vIHkgcmFkaXVzXG5cdFx0XHRcdDAsIC8vIHNsYW50aW5nXG5cdFx0XHRcdGxvbmdBcmMsIC8vIGxvbmcgb3Igc2hvcnQgYXJjXG5cdFx0XHRcdDEsIC8vIGNsb2Nrd2lzZVxuXHRcdFx0XHR4ICsgcmFkaXVzICogY29zRW5kLFxuXHRcdFx0XHR5ICsgcmFkaXVzICogc2luRW5kLFxuXHRcdFx0XHRvcGVuID8gTSA6IEwsXG5cdFx0XHRcdHggKyBpbm5lclJhZGl1cyAqIGNvc0VuZCxcblx0XHRcdFx0eSArIGlubmVyUmFkaXVzICogc2luRW5kLFxuXHRcdFx0XHQnQScsIC8vIGFyY1RvXG5cdFx0XHRcdGlubmVyUmFkaXVzLCAvLyB4IHJhZGl1c1xuXHRcdFx0XHRpbm5lclJhZGl1cywgLy8geSByYWRpdXNcblx0XHRcdFx0MCwgLy8gc2xhbnRpbmdcblx0XHRcdFx0bG9uZ0FyYywgLy8gbG9uZyBvciBzaG9ydCBhcmNcblx0XHRcdFx0MCwgLy8gY2xvY2t3aXNlXG5cdFx0XHRcdHggKyBpbm5lclJhZGl1cyAqIGNvc1N0YXJ0LFxuXHRcdFx0XHR5ICsgaW5uZXJSYWRpdXMgKiBzaW5TdGFydCxcblxuXHRcdFx0XHRvcGVuID8gJycgOiAnWicgLy8gY2xvc2Vcblx0XHRcdF07XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIENhbGxvdXQgc2hhcGUgdXNlZCBmb3IgZGVmYXVsdCB0b29sdGlwcywgYWxzbyB1c2VkIGZvciByb3VuZGVkIHJlY3RhbmdsZXMgaW4gVk1MXG5cdFx0ICovXG5cdFx0Y2FsbG91dDogZnVuY3Rpb24gKHgsIHksIHcsIGgsIG9wdGlvbnMpIHtcblx0XHRcdHZhciBhcnJvd0xlbmd0aCA9IDYsXG5cdFx0XHRcdGhhbGZEaXN0YW5jZSA9IDYsXG5cdFx0XHRcdHIgPSBtYXRoTWluKChvcHRpb25zICYmIG9wdGlvbnMucikgfHwgMCwgdywgaCksXG5cdFx0XHRcdHNhZmVEaXN0YW5jZSA9IHIgKyBoYWxmRGlzdGFuY2UsXG5cdFx0XHRcdGFuY2hvclggPSBvcHRpb25zICYmIG9wdGlvbnMuYW5jaG9yWCxcblx0XHRcdFx0YW5jaG9yWSA9IG9wdGlvbnMgJiYgb3B0aW9ucy5hbmNob3JZLFxuXHRcdFx0XHRwYXRoLFxuXHRcdFx0XHRub3JtYWxpemVyID0gbWF0aFJvdW5kKG9wdGlvbnMuc3Ryb2tlV2lkdGggfHwgMCkgJSAyIC8gMjsgLy8gbWF0aFJvdW5kIGJlY2F1c2Ugc3Ryb2tlV2lkdGggY2FuIHNvbWV0aW1lcyBoYXZlIHJvdW5kb2ZmIGVycm9ycztcblxuXHRcdFx0eCArPSBub3JtYWxpemVyO1xuXHRcdFx0eSArPSBub3JtYWxpemVyO1xuXHRcdFx0cGF0aCA9IFtcblx0XHRcdFx0J00nLCB4ICsgciwgeSwgXG5cdFx0XHRcdCdMJywgeCArIHcgLSByLCB5LCAvLyB0b3Agc2lkZVxuXHRcdFx0XHQnQycsIHggKyB3LCB5LCB4ICsgdywgeSwgeCArIHcsIHkgKyByLCAvLyB0b3AtcmlnaHQgY29ybmVyXG5cdFx0XHRcdCdMJywgeCArIHcsIHkgKyBoIC0gciwgLy8gcmlnaHQgc2lkZVxuXHRcdFx0XHQnQycsIHggKyB3LCB5ICsgaCwgeCArIHcsIHkgKyBoLCB4ICsgdyAtIHIsIHkgKyBoLCAvLyBib3R0b20tcmlnaHQgY29ybmVyXG5cdFx0XHRcdCdMJywgeCArIHIsIHkgKyBoLCAvLyBib3R0b20gc2lkZVxuXHRcdFx0XHQnQycsIHgsIHkgKyBoLCB4LCB5ICsgaCwgeCwgeSArIGggLSByLCAvLyBib3R0b20tbGVmdCBjb3JuZXJcblx0XHRcdFx0J0wnLCB4LCB5ICsgciwgLy8gbGVmdCBzaWRlXG5cdFx0XHRcdCdDJywgeCwgeSwgeCwgeSwgeCArIHIsIHkgLy8gdG9wLXJpZ2h0IGNvcm5lclxuXHRcdFx0XTtcblx0XHRcdFxuXHRcdFx0aWYgKGFuY2hvclggJiYgYW5jaG9yWCA+IHcgJiYgYW5jaG9yWSA+IHkgKyBzYWZlRGlzdGFuY2UgJiYgYW5jaG9yWSA8IHkgKyBoIC0gc2FmZURpc3RhbmNlKSB7IC8vIHJlcGxhY2UgcmlnaHQgc2lkZVxuXHRcdFx0XHRwYXRoLnNwbGljZSgxMywgMyxcblx0XHRcdFx0XHQnTCcsIHggKyB3LCBhbmNob3JZIC0gaGFsZkRpc3RhbmNlLCBcblx0XHRcdFx0XHR4ICsgdyArIGFycm93TGVuZ3RoLCBhbmNob3JZLFxuXHRcdFx0XHRcdHggKyB3LCBhbmNob3JZICsgaGFsZkRpc3RhbmNlLFxuXHRcdFx0XHRcdHggKyB3LCB5ICsgaCAtIHJcblx0XHRcdFx0KTtcblx0XHRcdH0gZWxzZSBpZiAoYW5jaG9yWCAmJiBhbmNob3JYIDwgMCAmJiBhbmNob3JZID4geSArIHNhZmVEaXN0YW5jZSAmJiBhbmNob3JZIDwgeSArIGggLSBzYWZlRGlzdGFuY2UpIHsgLy8gcmVwbGFjZSBsZWZ0IHNpZGVcblx0XHRcdFx0cGF0aC5zcGxpY2UoMzMsIDMsIFxuXHRcdFx0XHRcdCdMJywgeCwgYW5jaG9yWSArIGhhbGZEaXN0YW5jZSwgXG5cdFx0XHRcdFx0eCAtIGFycm93TGVuZ3RoLCBhbmNob3JZLFxuXHRcdFx0XHRcdHgsIGFuY2hvclkgLSBoYWxmRGlzdGFuY2UsXG5cdFx0XHRcdFx0eCwgeSArIHJcblx0XHRcdFx0KTtcblx0XHRcdH0gZWxzZSBpZiAoYW5jaG9yWSAmJiBhbmNob3JZID4gaCAmJiBhbmNob3JYID4geCArIHNhZmVEaXN0YW5jZSAmJiBhbmNob3JYIDwgeCArIHcgLSBzYWZlRGlzdGFuY2UpIHsgLy8gcmVwbGFjZSBib3R0b21cblx0XHRcdFx0cGF0aC5zcGxpY2UoMjMsIDMsXG5cdFx0XHRcdFx0J0wnLCBhbmNob3JYICsgaGFsZkRpc3RhbmNlLCB5ICsgaCxcblx0XHRcdFx0XHRhbmNob3JYLCB5ICsgaCArIGFycm93TGVuZ3RoLFxuXHRcdFx0XHRcdGFuY2hvclggLSBoYWxmRGlzdGFuY2UsIHkgKyBoLFxuXHRcdFx0XHRcdHggKyByLCB5ICsgaFxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIGlmIChhbmNob3JZICYmIGFuY2hvclkgPCAwICYmIGFuY2hvclggPiB4ICsgc2FmZURpc3RhbmNlICYmIGFuY2hvclggPCB4ICsgdyAtIHNhZmVEaXN0YW5jZSkgeyAvLyByZXBsYWNlIHRvcFxuXHRcdFx0XHRwYXRoLnNwbGljZSgzLCAzLFxuXHRcdFx0XHRcdCdMJywgYW5jaG9yWCAtIGhhbGZEaXN0YW5jZSwgeSxcblx0XHRcdFx0XHRhbmNob3JYLCB5IC0gYXJyb3dMZW5ndGgsXG5cdFx0XHRcdFx0YW5jaG9yWCArIGhhbGZEaXN0YW5jZSwgeSxcblx0XHRcdFx0XHR3IC0gciwgeVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHBhdGg7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZWZpbmUgYSBjbGlwcGluZyByZWN0YW5nbGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlkXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqL1xuXHRjbGlwUmVjdDogZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcblx0XHR2YXIgd3JhcHBlcixcblx0XHRcdGlkID0gUFJFRklYICsgaWRDb3VudGVyKyssXG5cblx0XHRcdGNsaXBQYXRoID0gdGhpcy5jcmVhdGVFbGVtZW50KCdjbGlwUGF0aCcpLmF0dHIoe1xuXHRcdFx0XHRpZDogaWRcblx0XHRcdH0pLmFkZCh0aGlzLmRlZnMpO1xuXG5cdFx0d3JhcHBlciA9IHRoaXMucmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0LCAwKS5hZGQoY2xpcFBhdGgpO1xuXHRcdHdyYXBwZXIuaWQgPSBpZDtcblx0XHR3cmFwcGVyLmNsaXBQYXRoID0gY2xpcFBhdGg7XG5cblx0XHRyZXR1cm4gd3JhcHBlcjtcblx0fSxcblxuXG5cdFxuXG5cblx0LyoqXG5cdCAqIEFkZCB0ZXh0IHRvIHRoZSBTVkcgb2JqZWN0XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHggTGVmdCBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge051bWJlcn0geSBUb3AgcG9zaXRpb25cblx0ICogQHBhcmFtIHtCb29sZWFufSB1c2VIVE1MIFVzZSBIVE1MIHRvIHJlbmRlciB0aGUgdGV4dFxuXHQgKi9cblx0dGV4dDogZnVuY3Rpb24gKHN0ciwgeCwgeSwgdXNlSFRNTCkge1xuXG5cdFx0Ly8gZGVjbGFyZSB2YXJpYWJsZXNcblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0ZmFrZVNWRyA9IHVzZUNhblZHIHx8ICghaGFzU1ZHICYmIHJlbmRlcmVyLmZvckV4cG9ydCksXG5cdFx0XHR3cmFwcGVyLFxuXHRcdFx0YXR0ciA9IHt9O1xuXG5cdFx0aWYgKHVzZUhUTUwgJiYgIXJlbmRlcmVyLmZvckV4cG9ydCkge1xuXHRcdFx0cmV0dXJuIHJlbmRlcmVyLmh0bWwoc3RyLCB4LCB5KTtcblx0XHR9XG5cblx0XHRhdHRyLnggPSBNYXRoLnJvdW5kKHggfHwgMCk7IC8vIFggaXMgYWx3YXlzIG5lZWRlZCBmb3IgbGluZS13cmFwIGxvZ2ljXG5cdFx0aWYgKHkpIHtcblx0XHRcdGF0dHIueSA9IE1hdGgucm91bmQoeSk7XG5cdFx0fVxuXHRcdGlmIChzdHIgfHwgc3RyID09PSAwKSB7XG5cdFx0XHRhdHRyLnRleHQgPSBzdHI7XG5cdFx0fVxuXG5cdFx0d3JhcHBlciA9IHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3RleHQnKVxuXHRcdFx0LmF0dHIoYXR0cik7XG5cblx0XHQvLyBQcmV2ZW50IHdyYXBwaW5nIGZyb20gY3JlYXRpbmcgZmFsc2Ugb2Zmc2V0V2lkdGhzIGluIGV4cG9ydCBpbiBsZWdhY3kgSUUgKCMxMDc5LCAjMTA2Mylcblx0XHRpZiAoZmFrZVNWRykge1xuXHRcdFx0d3JhcHBlci5jc3Moe1xuXHRcdFx0XHRwb3NpdGlvbjogQUJTT0xVVEVcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICghdXNlSFRNTCkge1xuXHRcdFx0d3JhcHBlci54U2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHRcdFx0dmFyIHRzcGFucyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3RzcGFuJyksXG5cdFx0XHRcdFx0dHNwYW4sXG5cdFx0XHRcdFx0cGFyZW50VmFsID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoa2V5KSxcblx0XHRcdFx0XHRpO1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgdHNwYW5zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dHNwYW4gPSB0c3BhbnNbaV07XG5cdFx0XHRcdFx0Ly8gSWYgdGhlIHggdmFsdWVzIGFyZSBlcXVhbCwgdGhlIHRzcGFuIHJlcHJlc2VudHMgYSBsaW5lYnJlYWtcblx0XHRcdFx0XHRpZiAodHNwYW4uZ2V0QXR0cmlidXRlKGtleSkgPT09IHBhcmVudFZhbCkge1xuXHRcdFx0XHRcdFx0dHNwYW4uc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcblx0XHRcdH07XG5cdFx0fVxuXHRcdFxuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBVdGlsaXR5IHRvIHJldHVybiB0aGUgYmFzZWxpbmUgb2Zmc2V0IGFuZCB0b3RhbCBsaW5lIGhlaWdodCBmcm9tIHRoZSBmb250IHNpemVcblx0ICovXG5cdGZvbnRNZXRyaWNzOiBmdW5jdGlvbiAoZm9udFNpemUsIGVsZW0pIHtcblx0XHRmb250U2l6ZSA9IGZvbnRTaXplIHx8IHRoaXMuc3R5bGUuZm9udFNpemU7XG5cdFx0aWYgKGVsZW0gJiYgd2luLmdldENvbXB1dGVkU3R5bGUpIHtcblx0XHRcdGVsZW0gPSBlbGVtLmVsZW1lbnQgfHwgZWxlbTsgLy8gU1ZHRWxlbWVudFxuXHRcdFx0Zm9udFNpemUgPSB3aW4uZ2V0Q29tcHV0ZWRTdHlsZShlbGVtLCBcIlwiKS5mb250U2l6ZTtcblx0XHR9XG5cdFx0Zm9udFNpemUgPSAvcHgvLnRlc3QoZm9udFNpemUpID8gcEludChmb250U2l6ZSkgOiAvZW0vLnRlc3QoZm9udFNpemUpID8gcGFyc2VGbG9hdChmb250U2l6ZSkgKiAxMiA6IDEyO1xuXG5cdFx0Ly8gRW1waXJpY2FsIHZhbHVlcyBmb3VuZCBieSBjb21wYXJpbmcgZm9udCBzaXplIGFuZCBib3VuZGluZyBib3ggaGVpZ2h0LlxuXHRcdC8vIEFwcGxpZXMgdG8gdGhlIGRlZmF1bHQgZm9udCBmYW1pbHkuIGh0dHA6Ly9qc2ZpZGRsZS5uZXQvaGlnaGNoYXJ0cy83eHZuNy9cblx0XHR2YXIgbGluZUhlaWdodCA9IGZvbnRTaXplIDwgMjQgPyBmb250U2l6ZSArIDQgOiBtYXRoUm91bmQoZm9udFNpemUgKiAxLjIpLFxuXHRcdFx0YmFzZWxpbmUgPSBtYXRoUm91bmQobGluZUhlaWdodCAqIDAuOCk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0aDogbGluZUhlaWdodCxcblx0XHRcdGI6IGJhc2VsaW5lLFxuXHRcdFx0ZjogZm9udFNpemVcblx0XHR9O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgYSBsYWJlbCwgYSB0ZXh0IGl0ZW0gdGhhdCBjYW4gaG9sZCBhIGNvbG9yZWQgb3IgZ3JhZGllbnQgYmFja2dyb3VuZFxuXHQgKiBhcyB3ZWxsIGFzIGEgYm9yZGVyIGFuZCBzaGFkb3cuXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICogQHBhcmFtIHtTdHJpbmd9IHNoYXBlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBhbmNob3JYIEluIGNhc2UgdGhlIHNoYXBlIGhhcyBhIHBvaW50ZXIsIGxpa2UgYSBmbGFnLCB0aGlzIGlzIHRoZVxuXHQgKiAgICBjb29yZGluYXRlcyBpdCBzaG91bGQgYmUgcGlubmVkIHRvXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBhbmNob3JZXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gYmFzZWxpbmUgV2hldGhlciB0byBwb3NpdGlvbiB0aGUgbGFiZWwgcmVsYXRpdmUgdG8gdGhlIHRleHQgYmFzZWxpbmUsXG5cdCAqICAgIGxpa2UgcmVuZGVyZXIudGV4dCwgb3IgdG8gdGhlIHVwcGVyIGJvcmRlciBvZiB0aGUgcmVjdGFuZ2xlLlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gY2xhc3NOYW1lIENsYXNzIG5hbWUgZm9yIHRoZSBncm91cFxuXHQgKi9cblx0bGFiZWw6IGZ1bmN0aW9uIChzdHIsIHgsIHksIHNoYXBlLCBhbmNob3JYLCBhbmNob3JZLCB1c2VIVE1MLCBiYXNlbGluZSwgY2xhc3NOYW1lKSB7XG5cblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0d3JhcHBlciA9IHJlbmRlcmVyLmcoY2xhc3NOYW1lKSxcblx0XHRcdHRleHQgPSByZW5kZXJlci50ZXh0KCcnLCAwLCAwLCB1c2VIVE1MKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0ekluZGV4OiAxXG5cdFx0XHRcdH0pLFxuXHRcdFx0XHQvLy5hZGQod3JhcHBlciksXG5cdFx0XHRib3gsXG5cdFx0XHRiQm94LFxuXHRcdFx0YWxpZ25GYWN0b3IgPSAwLFxuXHRcdFx0cGFkZGluZyA9IDMsXG5cdFx0XHRwYWRkaW5nTGVmdCA9IDAsXG5cdFx0XHR3aWR0aCxcblx0XHRcdGhlaWdodCxcblx0XHRcdHdyYXBwZXJYLFxuXHRcdFx0d3JhcHBlclksXG5cdFx0XHRjcmlzcEFkanVzdCA9IDAsXG5cdFx0XHRkZWZlcnJlZEF0dHIgPSB7fSxcblx0XHRcdGJhc2VsaW5lT2Zmc2V0LFxuXHRcdFx0bmVlZHNCb3g7XG5cblx0XHQvKipcblx0XHQgKiBUaGlzIGZ1bmN0aW9uIHJ1bnMgYWZ0ZXIgdGhlIGxhYmVsIGlzIGFkZGVkIHRvIHRoZSBET00gKHdoZW4gdGhlIGJvdW5kaW5nIGJveCBpc1xuXHRcdCAqIGF2YWlsYWJsZSksIGFuZCBhZnRlciB0aGUgdGV4dCBvZiB0aGUgbGFiZWwgaXMgdXBkYXRlZCB0byBkZXRlY3QgdGhlIG5ldyBib3VuZGluZ1xuXHRcdCAqIGJveCBhbmQgcmVmbGVjdCBpdCBpbiB0aGUgYm9yZGVyIGJveC5cblx0XHQgKi9cblx0XHRmdW5jdGlvbiB1cGRhdGVCb3hTaXplKCkge1xuXHRcdFx0dmFyIGJveFgsXG5cdFx0XHRcdGJveFksXG5cdFx0XHRcdHN0eWxlID0gdGV4dC5lbGVtZW50LnN0eWxlO1xuXG5cdFx0XHRiQm94ID0gKHdpZHRoID09PSB1bmRlZmluZWQgfHwgaGVpZ2h0ID09PSB1bmRlZmluZWQgfHwgd3JhcHBlci5zdHlsZXMudGV4dEFsaWduKSAmJiB0ZXh0LnRleHRTdHIgJiYgXG5cdFx0XHRcdHRleHQuZ2V0QkJveCgpO1xuXHRcdFx0d3JhcHBlci53aWR0aCA9ICh3aWR0aCB8fCBiQm94LndpZHRoIHx8IDApICsgMiAqIHBhZGRpbmcgKyBwYWRkaW5nTGVmdDtcblx0XHRcdHdyYXBwZXIuaGVpZ2h0ID0gKGhlaWdodCB8fCBiQm94LmhlaWdodCB8fCAwKSArIDIgKiBwYWRkaW5nO1xuXG5cdFx0XHQvLyB1cGRhdGUgdGhlIGxhYmVsLXNjb3BlZCB5IG9mZnNldFxuXHRcdFx0YmFzZWxpbmVPZmZzZXQgPSBwYWRkaW5nICsgcmVuZGVyZXIuZm9udE1ldHJpY3Moc3R5bGUgJiYgc3R5bGUuZm9udFNpemUsIHRleHQpLmI7XG5cblx0XHRcdFxuXHRcdFx0aWYgKG5lZWRzQm94KSB7XG5cblx0XHRcdFx0Ly8gY3JlYXRlIHRoZSBib3JkZXIgYm94IGlmIGl0IGlzIG5vdCBhbHJlYWR5IHByZXNlbnRcblx0XHRcdFx0aWYgKCFib3gpIHtcblx0XHRcdFx0XHRib3hYID0gbWF0aFJvdW5kKC1hbGlnbkZhY3RvciAqIHBhZGRpbmcpO1xuXHRcdFx0XHRcdGJveFkgPSBiYXNlbGluZSA/IC1iYXNlbGluZU9mZnNldCA6IDA7XG5cblx0XHRcdFx0XHR3cmFwcGVyLmJveCA9IGJveCA9IHNoYXBlID9cblx0XHRcdFx0XHRcdHJlbmRlcmVyLnN5bWJvbChzaGFwZSwgYm94WCwgYm94WSwgd3JhcHBlci53aWR0aCwgd3JhcHBlci5oZWlnaHQsIGRlZmVycmVkQXR0cikgOlxuXHRcdFx0XHRcdFx0cmVuZGVyZXIucmVjdChib3hYLCBib3hZLCB3cmFwcGVyLndpZHRoLCB3cmFwcGVyLmhlaWdodCwgMCwgZGVmZXJyZWRBdHRyW1NUUk9LRV9XSURUSF0pO1xuXHRcdFx0XHRcdGJveC5hdHRyKCdmaWxsJywgTk9ORSkuYWRkKHdyYXBwZXIpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gYXBwbHkgdGhlIGJveCBhdHRyaWJ1dGVzXG5cdFx0XHRcdGlmICghYm94LmlzSW1nKSB7IC8vICMxNjMwXG5cdFx0XHRcdFx0Ym94LmF0dHIoZXh0ZW5kKHtcblx0XHRcdFx0XHRcdHdpZHRoOiBtYXRoUm91bmQod3JhcHBlci53aWR0aCksXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IG1hdGhSb3VuZCh3cmFwcGVyLmhlaWdodClcblx0XHRcdFx0XHR9LCBkZWZlcnJlZEF0dHIpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkZWZlcnJlZEF0dHIgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFRoaXMgZnVuY3Rpb24gcnVucyBhZnRlciBzZXR0aW5nIHRleHQgb3IgcGFkZGluZywgYnV0IG9ubHkgaWYgcGFkZGluZyBpcyBjaGFuZ2VkXG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gdXBkYXRlVGV4dFBhZGRpbmcoKSB7XG5cdFx0XHR2YXIgc3R5bGVzID0gd3JhcHBlci5zdHlsZXMsXG5cdFx0XHRcdHRleHRBbGlnbiA9IHN0eWxlcyAmJiBzdHlsZXMudGV4dEFsaWduLFxuXHRcdFx0XHR4ID0gcGFkZGluZ0xlZnQgKyBwYWRkaW5nICogKDEgLSBhbGlnbkZhY3RvciksXG5cdFx0XHRcdHk7XG5cblx0XHRcdC8vIGRldGVybWluIHkgYmFzZWQgb24gdGhlIGJhc2VsaW5lXG5cdFx0XHR5ID0gYmFzZWxpbmUgPyAwIDogYmFzZWxpbmVPZmZzZXQ7XG5cblx0XHRcdC8vIGNvbXBlbnNhdGUgZm9yIGFsaWdubWVudFxuXHRcdFx0aWYgKGRlZmluZWQod2lkdGgpICYmIGJCb3ggJiYgKHRleHRBbGlnbiA9PT0gJ2NlbnRlcicgfHwgdGV4dEFsaWduID09PSAncmlnaHQnKSkge1xuXHRcdFx0XHR4ICs9IHsgY2VudGVyOiAwLjUsIHJpZ2h0OiAxIH1bdGV4dEFsaWduXSAqICh3aWR0aCAtIGJCb3gud2lkdGgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyB1cGRhdGUgaWYgYW55dGhpbmcgY2hhbmdlZFxuXHRcdFx0aWYgKHggIT09IHRleHQueCB8fCB5ICE9PSB0ZXh0LnkpIHtcblx0XHRcdFx0dGV4dC5hdHRyKCd4JywgeCk7XG5cdFx0XHRcdGlmICh5ICE9PSBVTkRFRklORUQpIHtcblx0XHRcdFx0XHR0ZXh0LmF0dHIoJ3knLCB5KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyByZWNvcmQgY3VycmVudCB2YWx1ZXNcblx0XHRcdHRleHQueCA9IHg7XG5cdFx0XHR0ZXh0LnkgPSB5O1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFNldCBhIGJveCBhdHRyaWJ1dGUsIG9yIGRlZmVyIGl0IGlmIHRoZSBib3ggaXMgbm90IHlldCBjcmVhdGVkXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGtleVxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZVxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGJveEF0dHIoa2V5LCB2YWx1ZSkge1xuXHRcdFx0aWYgKGJveCkge1xuXHRcdFx0XHRib3guYXR0cihrZXksIHZhbHVlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkQXR0cltrZXldID0gdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogQWZ0ZXIgdGhlIHRleHQgZWxlbWVudCBpcyBhZGRlZCwgZ2V0IHRoZSBkZXNpcmVkIHNpemUgb2YgdGhlIGJvcmRlciBib3hcblx0XHQgKiBhbmQgYWRkIGl0IGJlZm9yZSB0aGUgdGV4dCBpbiB0aGUgRE9NLlxuXHRcdCAqL1xuXHRcdHdyYXBwZXIub25BZGQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR0ZXh0LmFkZCh3cmFwcGVyKTtcblx0XHRcdHdyYXBwZXIuYXR0cih7XG5cdFx0XHRcdHRleHQ6IChzdHIgfHwgc3RyID09PSAwKSA/IHN0ciA6ICcnLCAvLyBhbGlnbm1lbnQgaXMgYXZhaWxhYmxlIG5vdyAvLyAjMzI5NTogMCBub3QgcmVuZGVyZWQgaWYgZ2l2ZW4gYXMgYSB2YWx1ZVxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5XG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKGJveCAmJiBkZWZpbmVkKGFuY2hvclgpKSB7XG5cdFx0XHRcdHdyYXBwZXIuYXR0cih7XG5cdFx0XHRcdFx0YW5jaG9yWDogYW5jaG9yWCxcblx0XHRcdFx0XHRhbmNob3JZOiBhbmNob3JZXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHQvKlxuXHRcdCAqIEFkZCBzcGVjaWZpYyBhdHRyaWJ1dGUgc2V0dGVycy5cblx0XHQgKi9cblxuXHRcdC8vIG9ubHkgY2hhbmdlIGxvY2FsIHZhcmlhYmxlc1xuXHRcdHdyYXBwZXIud2lkdGhTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdHdpZHRoID0gdmFsdWU7XG5cdFx0fTtcblx0XHR3cmFwcGVyLmhlaWdodFNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0aGVpZ2h0ID0gdmFsdWU7XG5cdFx0fTtcblx0XHR3cmFwcGVyLnBhZGRpbmdTZXR0ZXIgPSAgZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRpZiAoZGVmaW5lZCh2YWx1ZSkgJiYgdmFsdWUgIT09IHBhZGRpbmcpIHtcblx0XHRcdFx0cGFkZGluZyA9IHZhbHVlO1xuXHRcdFx0XHR1cGRhdGVUZXh0UGFkZGluZygpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0d3JhcHBlci5wYWRkaW5nTGVmdFNldHRlciA9ICBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdGlmIChkZWZpbmVkKHZhbHVlKSAmJiB2YWx1ZSAhPT0gcGFkZGluZ0xlZnQpIHtcblx0XHRcdFx0cGFkZGluZ0xlZnQgPSB2YWx1ZTtcblx0XHRcdFx0dXBkYXRlVGV4dFBhZGRpbmcoKTtcblx0XHRcdH1cblx0XHR9O1xuXG5cblx0XHQvLyBjaGFuZ2UgbG9jYWwgdmFyaWFibGUgYW5kIHByZXZlbnQgc2V0dGluZyBhdHRyaWJ1dGUgb24gdGhlIGdyb3VwXG5cdFx0d3JhcHBlci5hbGlnblNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0YWxpZ25GYWN0b3IgPSB7IGxlZnQ6IDAsIGNlbnRlcjogMC41LCByaWdodDogMSB9W3ZhbHVlXTtcblx0XHR9O1xuXG5cdFx0Ly8gYXBwbHkgdGhlc2UgdG8gdGhlIGJveCBhbmQgdGhlIHRleHQgYWxpa2Vcblx0XHR3cmFwcGVyLnRleHRTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdGlmICh2YWx1ZSAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdHRleHQudGV4dFNldHRlcih2YWx1ZSk7XG5cdFx0XHR9XG5cdFx0XHR1cGRhdGVCb3hTaXplKCk7XG5cdFx0XHR1cGRhdGVUZXh0UGFkZGluZygpO1xuXHRcdH07XG5cblx0XHQvLyBhcHBseSB0aGVzZSB0byB0aGUgYm94IGJ1dCBub3QgdG8gdGhlIHRleHRcblx0XHR3cmFwcGVyWydzdHJva2Utd2lkdGhTZXR0ZXInXSA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0XHRpZiAodmFsdWUpIHtcblx0XHRcdFx0bmVlZHNCb3ggPSB0cnVlO1xuXHRcdFx0fVxuXHRcdFx0Y3Jpc3BBZGp1c3QgPSB2YWx1ZSAlIDIgLyAyO1xuXHRcdFx0Ym94QXR0cihrZXksIHZhbHVlKTtcblx0XHR9O1xuXHRcdHdyYXBwZXIuc3Ryb2tlU2V0dGVyID0gd3JhcHBlci5maWxsU2V0dGVyID0gd3JhcHBlci5yU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHRcdGlmIChrZXkgPT09ICdmaWxsJyAmJiB2YWx1ZSkge1xuXHRcdFx0XHRuZWVkc0JveCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRib3hBdHRyKGtleSwgdmFsdWUpO1xuXHRcdH07XG5cdFx0d3JhcHBlci5hbmNob3JYU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHRcdGFuY2hvclggPSB2YWx1ZTtcblx0XHRcdGJveEF0dHIoa2V5LCB2YWx1ZSArIGNyaXNwQWRqdXN0IC0gd3JhcHBlclgpO1xuXHRcdH07XG5cdFx0d3JhcHBlci5hbmNob3JZU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHRcdGFuY2hvclkgPSB2YWx1ZTtcblx0XHRcdGJveEF0dHIoa2V5LCB2YWx1ZSAtIHdyYXBwZXJZKTtcblx0XHR9O1xuXG5cdFx0Ly8gcmVuYW1lIGF0dHJpYnV0ZXNcblx0XHR3cmFwcGVyLnhTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdHdyYXBwZXIueCA9IHZhbHVlOyAvLyBmb3IgYW5pbWF0aW9uIGdldHRlclxuXHRcdFx0aWYgKGFsaWduRmFjdG9yKSB7XG5cdFx0XHRcdHZhbHVlIC09IGFsaWduRmFjdG9yICogKCh3aWR0aCB8fCBiQm94LndpZHRoKSArIHBhZGRpbmcpO1xuXHRcdFx0fVxuXHRcdFx0d3JhcHBlclggPSBtYXRoUm91bmQodmFsdWUpO1xuXHRcdFx0d3JhcHBlci5hdHRyKCd0cmFuc2xhdGVYJywgd3JhcHBlclgpO1xuXHRcdH07XG5cdFx0d3JhcHBlci55U2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHR3cmFwcGVyWSA9IHdyYXBwZXIueSA9IG1hdGhSb3VuZCh2YWx1ZSk7XG5cdFx0XHR3cmFwcGVyLmF0dHIoJ3RyYW5zbGF0ZVknLCB3cmFwcGVyWSk7XG5cdFx0fTtcblxuXHRcdC8vIFJlZGlyZWN0IGNlcnRhaW4gbWV0aG9kcyB0byBlaXRoZXIgdGhlIGJveCBvciB0aGUgdGV4dFxuXHRcdHZhciBiYXNlQ3NzID0gd3JhcHBlci5jc3M7XG5cdFx0cmV0dXJuIGV4dGVuZCh3cmFwcGVyLCB7XG5cdFx0XHQvKipcblx0XHRcdCAqIFBpY2sgdXAgc29tZSBwcm9wZXJ0aWVzIGFuZCBhcHBseSB0aGVtIHRvIHRoZSB0ZXh0IGluc3RlYWQgb2YgdGhlIHdyYXBwZXJcblx0XHRcdCAqL1xuXHRcdFx0Y3NzOiBmdW5jdGlvbiAoc3R5bGVzKSB7XG5cdFx0XHRcdGlmIChzdHlsZXMpIHtcblx0XHRcdFx0XHR2YXIgdGV4dFN0eWxlcyA9IHt9O1xuXHRcdFx0XHRcdHN0eWxlcyA9IG1lcmdlKHN0eWxlcyk7IC8vIGNyZWF0ZSBhIGNvcHkgdG8gYXZvaWQgYWx0ZXJpbmcgdGhlIG9yaWdpbmFsIG9iamVjdCAoIzUzNylcblx0XHRcdFx0XHRlYWNoKHdyYXBwZXIudGV4dFByb3BzLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0XHRcdFx0aWYgKHN0eWxlc1twcm9wXSAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdFx0XHRcdHRleHRTdHlsZXNbcHJvcF0gPSBzdHlsZXNbcHJvcF07XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBzdHlsZXNbcHJvcF07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0dGV4dC5jc3ModGV4dFN0eWxlcyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGJhc2VDc3MuY2FsbCh3cmFwcGVyLCBzdHlsZXMpO1xuXHRcdFx0fSxcblx0XHRcdC8qKlxuXHRcdFx0ICogUmV0dXJuIHRoZSBib3VuZGluZyBib3ggb2YgdGhlIGJveCwgbm90IHRoZSBncm91cFxuXHRcdFx0ICovXG5cdFx0XHRnZXRCQm94OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0d2lkdGg6IGJCb3gud2lkdGggKyAyICogcGFkZGluZyxcblx0XHRcdFx0XHRoZWlnaHQ6IGJCb3guaGVpZ2h0ICsgMiAqIHBhZGRpbmcsXG5cdFx0XHRcdFx0eDogYkJveC54IC0gcGFkZGluZyxcblx0XHRcdFx0XHR5OiBiQm94LnkgLSBwYWRkaW5nXG5cdFx0XHRcdH07XG5cdFx0XHR9LFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBBcHBseSB0aGUgc2hhZG93IHRvIHRoZSBib3hcblx0XHRcdCAqL1xuXHRcdFx0c2hhZG93OiBmdW5jdGlvbiAoYikge1xuXHRcdFx0XHRpZiAoYm94KSB7XG5cdFx0XHRcdFx0Ym94LnNoYWRvdyhiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gd3JhcHBlcjtcblx0XHRcdH0sXG5cdFx0XHQvKipcblx0XHRcdCAqIERlc3Ryb3kgYW5kIHJlbGVhc2UgbWVtb3J5LlxuXHRcdFx0ICovXG5cdFx0XHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0Ly8gQWRkZWQgYnkgYnV0dG9uIGltcGxlbWVudGF0aW9uXG5cdFx0XHRcdHJlbW92ZUV2ZW50KHdyYXBwZXIuZWxlbWVudCwgJ21vdXNlZW50ZXInKTtcblx0XHRcdFx0cmVtb3ZlRXZlbnQod3JhcHBlci5lbGVtZW50LCAnbW91c2VsZWF2ZScpO1xuXG5cdFx0XHRcdGlmICh0ZXh0KSB7XG5cdFx0XHRcdFx0dGV4dCA9IHRleHQuZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChib3gpIHtcblx0XHRcdFx0XHRib3ggPSBib3guZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIENhbGwgYmFzZSBpbXBsZW1lbnRhdGlvbiB0byBkZXN0cm95IHRoZSByZXN0XG5cdFx0XHRcdFNWR0VsZW1lbnQucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh3cmFwcGVyKTtcblxuXHRcdFx0XHQvLyBSZWxlYXNlIGxvY2FsIHBvaW50ZXJzICgjMTI5OClcblx0XHRcdFx0d3JhcHBlciA9IHJlbmRlcmVyID0gdXBkYXRlQm94U2l6ZSA9IHVwZGF0ZVRleHRQYWRkaW5nID0gYm94QXR0ciA9IG51bGw7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn07IC8vIGVuZCBTVkdSZW5kZXJlclxuXG5cbi8vIGdlbmVyYWwgcmVuZGVyZXJcblJlbmRlcmVyID0gU1ZHUmVuZGVyZXI7XG4vLyBleHRlbmQgU3ZnRWxlbWVudCBmb3IgdXNlSFRNTCBvcHRpb25cbmV4dGVuZChTVkdFbGVtZW50LnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogQXBwbHkgQ1NTIHRvIEhUTUwgZWxlbWVudHMuIFRoaXMgaXMgdXNlZCBpbiB0ZXh0IHdpdGhpbiBTVkcgcmVuZGVyaW5nIGFuZFxuXHQgKiBieSB0aGUgVk1MIHJlbmRlcmVyXG5cdCAqL1xuXHRodG1sQ3NzOiBmdW5jdGlvbiAoc3R5bGVzKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHRleHRXaWR0aCA9IHN0eWxlcyAmJiBlbGVtZW50LnRhZ05hbWUgPT09ICdTUEFOJyAmJiBzdHlsZXMud2lkdGg7XG5cblx0XHRpZiAodGV4dFdpZHRoKSB7XG5cdFx0XHRkZWxldGUgc3R5bGVzLndpZHRoO1xuXHRcdFx0d3JhcHBlci50ZXh0V2lkdGggPSB0ZXh0V2lkdGg7XG5cdFx0XHR3cmFwcGVyLnVwZGF0ZVRyYW5zZm9ybSgpO1xuXHRcdH1cblxuXHRcdHdyYXBwZXIuc3R5bGVzID0gZXh0ZW5kKHdyYXBwZXIuc3R5bGVzLCBzdHlsZXMpO1xuXHRcdGNzcyh3cmFwcGVyLmVsZW1lbnQsIHN0eWxlcyk7XG5cblx0XHRyZXR1cm4gd3JhcHBlcjtcblx0fSxcblxuXHQvKipcblx0ICogVk1MIGFuZCB1c2VIVE1MIG1ldGhvZCBmb3IgY2FsY3VsYXRpbmcgdGhlIGJvdW5kaW5nIGJveCBiYXNlZCBvbiBvZmZzZXRzXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVmcmVzaCBXaGV0aGVyIHRvIGZvcmNlIGEgZnJlc2ggdmFsdWUgZnJvbSB0aGUgRE9NIG9yIHRvXG5cdCAqIHVzZSB0aGUgY2FjaGVkIHZhbHVlXG5cdCAqXG5cdCAqIEByZXR1cm4ge09iamVjdH0gQSBoYXNoIGNvbnRhaW5pbmcgdmFsdWVzIGZvciB4LCB5LCB3aWR0aCBhbmQgaGVpZ2h0XG5cdCAqL1xuXG5cdGh0bWxHZXRCQm94OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdGJCb3ggPSB3cmFwcGVyLmJCb3g7XG5cblx0XHQvLyBmYWtpbmcgZ2V0QkJveCBpbiBleHBvcnRlZCBTVkcgaW4gbGVnYWN5IElFXG5cdFx0aWYgKCFiQm94KSB7XG5cdFx0XHQvLyBmYWtpbmcgZ2V0QkJveCBpbiBleHBvcnRlZCBTVkcgaW4gbGVnYWN5IElFIChpcyB0aGlzIGEgZHVwbGljYXRlIG9mIHRoZSBmaXggZm9yICMxMDc5Pylcblx0XHRcdGlmIChlbGVtZW50Lm5vZGVOYW1lID09PSAndGV4dCcpIHtcblx0XHRcdFx0ZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9IEFCU09MVVRFO1xuXHRcdFx0fVxuXG5cdFx0XHRiQm94ID0gd3JhcHBlci5iQm94ID0ge1xuXHRcdFx0XHR4OiBlbGVtZW50Lm9mZnNldExlZnQsXG5cdFx0XHRcdHk6IGVsZW1lbnQub2Zmc2V0VG9wLFxuXHRcdFx0XHR3aWR0aDogZWxlbWVudC5vZmZzZXRXaWR0aCxcblx0XHRcdFx0aGVpZ2h0OiBlbGVtZW50Lm9mZnNldEhlaWdodFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYkJveDtcblx0fSxcblxuXHQvKipcblx0ICogVk1MIG92ZXJyaWRlIHByaXZhdGUgbWV0aG9kIHRvIHVwZGF0ZSBlbGVtZW50cyBiYXNlZCBvbiBpbnRlcm5hbFxuXHQgKiBwcm9wZXJ0aWVzIGJhc2VkIG9uIFNWRyB0cmFuc2Zvcm1cblx0ICovXG5cdGh0bWxVcGRhdGVUcmFuc2Zvcm06IGZ1bmN0aW9uICgpIHtcblx0XHQvLyBhbGlnbmluZyBub24gYWRkZWQgZWxlbWVudHMgaXMgZXhwZW5zaXZlXG5cdFx0aWYgKCF0aGlzLmFkZGVkKSB7XG5cdFx0XHR0aGlzLmFsaWduT25BZGQgPSB0cnVlO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdHJlbmRlcmVyID0gd3JhcHBlci5yZW5kZXJlcixcblx0XHRcdGVsZW0gPSB3cmFwcGVyLmVsZW1lbnQsXG5cdFx0XHR0cmFuc2xhdGVYID0gd3JhcHBlci50cmFuc2xhdGVYIHx8IDAsXG5cdFx0XHR0cmFuc2xhdGVZID0gd3JhcHBlci50cmFuc2xhdGVZIHx8IDAsXG5cdFx0XHR4ID0gd3JhcHBlci54IHx8IDAsXG5cdFx0XHR5ID0gd3JhcHBlci55IHx8IDAsXG5cdFx0XHRhbGlnbiA9IHdyYXBwZXIudGV4dEFsaWduIHx8ICdsZWZ0Jyxcblx0XHRcdGFsaWduQ29ycmVjdGlvbiA9IHsgbGVmdDogMCwgY2VudGVyOiAwLjUsIHJpZ2h0OiAxIH1bYWxpZ25dLFxuXHRcdFx0c2hhZG93cyA9IHdyYXBwZXIuc2hhZG93cztcblxuXHRcdC8vIGFwcGx5IHRyYW5zbGF0ZVxuXHRcdGNzcyhlbGVtLCB7XG5cdFx0XHRtYXJnaW5MZWZ0OiB0cmFuc2xhdGVYLFxuXHRcdFx0bWFyZ2luVG9wOiB0cmFuc2xhdGVZXG5cdFx0fSk7XG5cdFx0aWYgKHNoYWRvd3MpIHsgLy8gdXNlZCBpbiBsYWJlbHMvdG9vbHRpcFxuXHRcdFx0ZWFjaChzaGFkb3dzLCBmdW5jdGlvbiAoc2hhZG93KSB7XG5cdFx0XHRcdGNzcyhzaGFkb3csIHtcblx0XHRcdFx0XHRtYXJnaW5MZWZ0OiB0cmFuc2xhdGVYICsgMSxcblx0XHRcdFx0XHRtYXJnaW5Ub3A6IHRyYW5zbGF0ZVkgKyAxXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gYXBwbHkgaW52ZXJzaW9uXG5cdFx0aWYgKHdyYXBwZXIuaW52ZXJ0ZWQpIHsgLy8gd3JhcHBlciBpcyBhIGdyb3VwXG5cdFx0XHRlYWNoKGVsZW0uY2hpbGROb2RlcywgZnVuY3Rpb24gKGNoaWxkKSB7XG5cdFx0XHRcdHJlbmRlcmVyLmludmVydENoaWxkKGNoaWxkLCBlbGVtKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmIChlbGVtLnRhZ05hbWUgPT09ICdTUEFOJykge1xuXG5cdFx0XHR2YXIgd2lkdGgsXG5cdFx0XHRcdHJvdGF0aW9uID0gd3JhcHBlci5yb3RhdGlvbixcblx0XHRcdFx0YmFzZWxpbmUsXG5cdFx0XHRcdHRleHRXaWR0aCA9IHBJbnQod3JhcHBlci50ZXh0V2lkdGgpLFxuXHRcdFx0XHRjdXJyZW50VGV4dFRyYW5zZm9ybSA9IFtyb3RhdGlvbiwgYWxpZ24sIGVsZW0uaW5uZXJIVE1MLCB3cmFwcGVyLnRleHRXaWR0aF0uam9pbignLCcpO1xuXG5cdFx0XHRpZiAoY3VycmVudFRleHRUcmFuc2Zvcm0gIT09IHdyYXBwZXIuY1RUKSB7IC8vIGRvIHRoZSBjYWxjdWxhdGlvbnMgYW5kIERPTSBhY2Nlc3Mgb25seSBpZiBwcm9wZXJ0aWVzIGNoYW5nZWRcblxuXG5cdFx0XHRcdGJhc2VsaW5lID0gcmVuZGVyZXIuZm9udE1ldHJpY3MoZWxlbS5zdHlsZS5mb250U2l6ZSkuYjtcblxuXHRcdFx0XHQvLyBSZW5kZXJlciBzcGVjaWZpYyBoYW5kbGluZyBvZiBzcGFuIHJvdGF0aW9uXG5cdFx0XHRcdGlmIChkZWZpbmVkKHJvdGF0aW9uKSkge1xuXHRcdFx0XHRcdHdyYXBwZXIuc2V0U3BhblJvdGF0aW9uKHJvdGF0aW9uLCBhbGlnbkNvcnJlY3Rpb24sIGJhc2VsaW5lKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHdpZHRoID0gcGljayh3cmFwcGVyLmVsZW1XaWR0aCwgZWxlbS5vZmZzZXRXaWR0aCk7XG5cblx0XHRcdFx0Ly8gVXBkYXRlIHRleHRXaWR0aFxuXHRcdFx0XHRpZiAod2lkdGggPiB0ZXh0V2lkdGggJiYgL1sgXFwtXS8udGVzdChlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0KSkgeyAvLyAjOTgzLCAjMTI1NFxuXHRcdFx0XHRcdGNzcyhlbGVtLCB7XG5cdFx0XHRcdFx0XHR3aWR0aDogdGV4dFdpZHRoICsgUFgsXG5cdFx0XHRcdFx0XHRkaXNwbGF5OiAnYmxvY2snLFxuXHRcdFx0XHRcdFx0d2hpdGVTcGFjZTogJ25vcm1hbCdcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR3aWR0aCA9IHRleHRXaWR0aDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHdyYXBwZXIuZ2V0U3BhbkNvcnJlY3Rpb24od2lkdGgsIGJhc2VsaW5lLCBhbGlnbkNvcnJlY3Rpb24sIHJvdGF0aW9uLCBhbGlnbik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGFwcGx5IHBvc2l0aW9uIHdpdGggY29ycmVjdGlvblxuXHRcdFx0Y3NzKGVsZW0sIHtcblx0XHRcdFx0bGVmdDogKHggKyAod3JhcHBlci54Q29yciB8fCAwKSkgKyBQWCxcblx0XHRcdFx0dG9wOiAoeSArICh3cmFwcGVyLnlDb3JyIHx8IDApKSArIFBYXG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gZm9yY2UgcmVmbG93IGluIHdlYmtpdCB0byBhcHBseSB0aGUgbGVmdCBhbmQgdG9wIG9uIHVzZUhUTUwgZWxlbWVudCAoIzEyNDkpXG5cdFx0XHRpZiAoaXNXZWJLaXQpIHtcblx0XHRcdFx0YmFzZWxpbmUgPSBlbGVtLm9mZnNldEhlaWdodDsgLy8gYXNzaWduZWQgdG8gYmFzZWxpbmUgZm9yIEpTTGludCBwdXJwb3NlXG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlY29yZCBjdXJyZW50IHRleHQgdHJhbnNmb3JtXG5cdFx0XHR3cmFwcGVyLmNUVCA9IGN1cnJlbnRUZXh0VHJhbnNmb3JtO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSByb3RhdGlvbiBvZiBhbiBpbmRpdmlkdWFsIEhUTUwgc3BhblxuXHQgKi9cblx0c2V0U3BhblJvdGF0aW9uOiBmdW5jdGlvbiAocm90YXRpb24sIGFsaWduQ29ycmVjdGlvbiwgYmFzZWxpbmUpIHtcblx0XHR2YXIgcm90YXRpb25TdHlsZSA9IHt9LFxuXHRcdFx0Y3NzVHJhbnNmb3JtS2V5ID0gaXNJRSA/ICctbXMtdHJhbnNmb3JtJyA6IGlzV2ViS2l0ID8gJy13ZWJraXQtdHJhbnNmb3JtJyA6IGlzRmlyZWZveCA/ICdNb3pUcmFuc2Zvcm0nIDogaXNPcGVyYSA/ICctby10cmFuc2Zvcm0nIDogJyc7XG5cblx0XHRyb3RhdGlvblN0eWxlW2Nzc1RyYW5zZm9ybUtleV0gPSByb3RhdGlvblN0eWxlLnRyYW5zZm9ybSA9ICdyb3RhdGUoJyArIHJvdGF0aW9uICsgJ2RlZyknO1xuXHRcdHJvdGF0aW9uU3R5bGVbY3NzVHJhbnNmb3JtS2V5ICsgKGlzRmlyZWZveCA/ICdPcmlnaW4nIDogJy1vcmlnaW4nKV0gPSByb3RhdGlvblN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IChhbGlnbkNvcnJlY3Rpb24gKiAxMDApICsgJyUgJyArIGJhc2VsaW5lICsgJ3B4Jztcblx0XHRjc3ModGhpcy5lbGVtZW50LCByb3RhdGlvblN0eWxlKTtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBjb3JyZWN0aW9uIGluIFggYW5kIFkgcG9zaXRpb25pbmcgYXMgdGhlIGVsZW1lbnQgaXMgcm90YXRlZC5cblx0ICovXG5cdGdldFNwYW5Db3JyZWN0aW9uOiBmdW5jdGlvbiAod2lkdGgsIGJhc2VsaW5lLCBhbGlnbkNvcnJlY3Rpb24pIHtcblx0XHR0aGlzLnhDb3JyID0gLXdpZHRoICogYWxpZ25Db3JyZWN0aW9uO1xuXHRcdHRoaXMueUNvcnIgPSAtYmFzZWxpbmU7XG5cdH1cbn0pO1xuXG4vLyBFeHRlbmQgU3ZnUmVuZGVyZXIgZm9yIHVzZUhUTUwgb3B0aW9uLlxuZXh0ZW5kKFNWR1JlbmRlcmVyLnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogQ3JlYXRlIEhUTUwgdGV4dCBub2RlLiBUaGlzIGlzIHVzZWQgYnkgdGhlIFZNTCByZW5kZXJlciBhcyB3ZWxsIGFzIHRoZSBTVkdcblx0ICogcmVuZGVyZXIgdGhyb3VnaCB0aGUgdXNlSFRNTCBvcHRpb24uXG5cdCAqXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICovXG5cdGh0bWw6IGZ1bmN0aW9uIChzdHIsIHgsIHkpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMuY3JlYXRlRWxlbWVudCgnc3BhbicpLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHJlbmRlcmVyID0gd3JhcHBlci5yZW5kZXJlcjtcblxuXHRcdC8vIFRleHQgc2V0dGVyXG5cdFx0d3JhcHBlci50ZXh0U2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRpZiAodmFsdWUgIT09IGVsZW1lbnQuaW5uZXJIVE1MKSB7XG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmJCb3g7XG5cdFx0XHR9XG5cdFx0XHRlbGVtZW50LmlubmVySFRNTCA9IHRoaXMudGV4dFN0ciA9IHZhbHVlO1xuXHRcdH07XG5cblx0XHQvLyBWYXJpb3VzIHNldHRlcnMgd2hpY2ggcmVseSBvbiB1cGRhdGUgdHJhbnNmb3JtXG5cdFx0d3JhcHBlci54U2V0dGVyID0gd3JhcHBlci55U2V0dGVyID0gd3JhcHBlci5hbGlnblNldHRlciA9IHdyYXBwZXIucm90YXRpb25TZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0aWYgKGtleSA9PT0gJ2FsaWduJykge1xuXHRcdFx0XHRrZXkgPSAndGV4dEFsaWduJzsgLy8gRG8gbm90IG92ZXJ3cml0ZSB0aGUgU1ZHRWxlbWVudC5hbGlnbiBtZXRob2QuIFNhbWUgYXMgVk1MLlxuXHRcdFx0fVxuXHRcdFx0d3JhcHBlcltrZXldID0gdmFsdWU7XG5cdFx0XHR3cmFwcGVyLmh0bWxVcGRhdGVUcmFuc2Zvcm0oKTtcblx0XHR9O1xuXG5cdFx0Ly8gU2V0IHRoZSBkZWZhdWx0IGF0dHJpYnV0ZXNcblx0XHR3cmFwcGVyLmF0dHIoe1xuXHRcdFx0XHR0ZXh0OiBzdHIsXG5cdFx0XHRcdHg6IG1hdGhSb3VuZCh4KSxcblx0XHRcdFx0eTogbWF0aFJvdW5kKHkpXG5cdFx0XHR9KVxuXHRcdFx0LmNzcyh7XG5cdFx0XHRcdHBvc2l0aW9uOiBBQlNPTFVURSxcblx0XHRcdFx0d2hpdGVTcGFjZTogJ25vd3JhcCcsXG5cdFx0XHRcdGZvbnRGYW1pbHk6IHRoaXMuc3R5bGUuZm9udEZhbWlseSxcblx0XHRcdFx0Zm9udFNpemU6IHRoaXMuc3R5bGUuZm9udFNpemVcblx0XHRcdH0pO1xuXG5cdFx0Ly8gVXNlIHRoZSBIVE1MIHNwZWNpZmljIC5jc3MgbWV0aG9kXG5cdFx0d3JhcHBlci5jc3MgPSB3cmFwcGVyLmh0bWxDc3M7XG5cblx0XHQvLyBUaGlzIGlzIHNwZWNpZmljIGZvciBIVE1MIHdpdGhpbiBTVkdcblx0XHRpZiAocmVuZGVyZXIuaXNTVkcpIHtcblx0XHRcdHdyYXBwZXIuYWRkID0gZnVuY3Rpb24gKHN2Z0dyb3VwV3JhcHBlcikge1xuXG5cdFx0XHRcdHZhciBodG1sR3JvdXAsXG5cdFx0XHRcdFx0Y29udGFpbmVyID0gcmVuZGVyZXIuYm94LnBhcmVudE5vZGUsXG5cdFx0XHRcdFx0cGFyZW50R3JvdXAsXG5cdFx0XHRcdFx0cGFyZW50cyA9IFtdO1xuXG5cdFx0XHRcdHRoaXMucGFyZW50R3JvdXAgPSBzdmdHcm91cFdyYXBwZXI7XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIGEgbW9jayBncm91cCB0byBob2xkIHRoZSBIVE1MIGVsZW1lbnRzXG5cdFx0XHRcdGlmIChzdmdHcm91cFdyYXBwZXIpIHtcblx0XHRcdFx0XHRodG1sR3JvdXAgPSBzdmdHcm91cFdyYXBwZXIuZGl2O1xuXHRcdFx0XHRcdGlmICghaHRtbEdyb3VwKSB7XG5cblx0XHRcdFx0XHRcdC8vIFJlYWQgdGhlIHBhcmVudCBjaGFpbiBpbnRvIGFuIGFycmF5IGFuZCByZWFkIGZyb20gdG9wIGRvd25cblx0XHRcdFx0XHRcdHBhcmVudEdyb3VwID0gc3ZnR3JvdXBXcmFwcGVyO1xuXHRcdFx0XHRcdFx0d2hpbGUgKHBhcmVudEdyb3VwKSB7XG5cblx0XHRcdFx0XHRcdFx0cGFyZW50cy5wdXNoKHBhcmVudEdyb3VwKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBNb3ZlIHVwIHRvIHRoZSBuZXh0IHBhcmVudCBncm91cFxuXHRcdFx0XHRcdFx0XHRwYXJlbnRHcm91cCA9IHBhcmVudEdyb3VwLnBhcmVudEdyb3VwO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBFbnN1cmUgZHluYW1pY2FsbHkgdXBkYXRpbmcgcG9zaXRpb24gd2hlbiBhbnkgcGFyZW50IGlzIHRyYW5zbGF0ZWRcblx0XHRcdFx0XHRcdGVhY2gocGFyZW50cy5yZXZlcnNlKCksIGZ1bmN0aW9uIChwYXJlbnRHcm91cCkge1xuXHRcdFx0XHRcdFx0XHR2YXIgaHRtbEdyb3VwU3R5bGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQ3JlYXRlIGEgSFRNTCBkaXYgYW5kIGFwcGVuZCBpdCB0byB0aGUgcGFyZW50IGRpdiB0byBlbXVsYXRlXG5cdFx0XHRcdFx0XHRcdC8vIHRoZSBTVkcgZ3JvdXAgc3RydWN0dXJlXG5cdFx0XHRcdFx0XHRcdGh0bWxHcm91cCA9IHBhcmVudEdyb3VwLmRpdiA9IHBhcmVudEdyb3VwLmRpdiB8fCBjcmVhdGVFbGVtZW50KERJViwge1xuXHRcdFx0XHRcdFx0XHRcdGNsYXNzTmFtZTogYXR0cihwYXJlbnRHcm91cC5lbGVtZW50LCAnY2xhc3MnKVxuXHRcdFx0XHRcdFx0XHR9LCB7XG5cdFx0XHRcdFx0XHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0XHRcdFx0XHRcdGxlZnQ6IChwYXJlbnRHcm91cC50cmFuc2xhdGVYIHx8IDApICsgUFgsXG5cdFx0XHRcdFx0XHRcdFx0dG9wOiAocGFyZW50R3JvdXAudHJhbnNsYXRlWSB8fCAwKSArIFBYXG5cdFx0XHRcdFx0XHRcdH0sIGh0bWxHcm91cCB8fCBjb250YWluZXIpOyAvLyB0aGUgdG9wIGdyb3VwIGlzIGFwcGVuZGVkIHRvIGNvbnRhaW5lclxuXG5cdFx0XHRcdFx0XHRcdC8vIFNob3J0Y3V0XG5cdFx0XHRcdFx0XHRcdGh0bWxHcm91cFN0eWxlID0gaHRtbEdyb3VwLnN0eWxlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFNldCBsaXN0ZW5lcnMgdG8gdXBkYXRlIHRoZSBIVE1MIGRpdidzIHBvc2l0aW9uIHdoZW5ldmVyIHRoZSBTVkcgZ3JvdXBcblx0XHRcdFx0XHRcdFx0Ly8gcG9zaXRpb24gaXMgY2hhbmdlZFxuXHRcdFx0XHRcdFx0XHRleHRlbmQocGFyZW50R3JvdXAsIHtcblx0XHRcdFx0XHRcdFx0XHR0cmFuc2xhdGVYU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aHRtbEdyb3VwU3R5bGUubGVmdCA9IHZhbHVlICsgUFg7XG5cdFx0XHRcdFx0XHRcdFx0XHRwYXJlbnRHcm91cFtrZXldID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdFx0XHRwYXJlbnRHcm91cC5kb1RyYW5zZm9ybSA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHR0cmFuc2xhdGVZU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aHRtbEdyb3VwU3R5bGUudG9wID0gdmFsdWUgKyBQWDtcblx0XHRcdFx0XHRcdFx0XHRcdHBhcmVudEdyb3VwW2tleV0gPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdHBhcmVudEdyb3VwLmRvVHJhbnNmb3JtID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdHZpc2liaWxpdHlTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRodG1sR3JvdXBTdHlsZVtrZXldID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGh0bWxHcm91cCA9IGNvbnRhaW5lcjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGh0bWxHcm91cC5hcHBlbmRDaGlsZChlbGVtZW50KTtcblxuXHRcdFx0XHQvLyBTaGFyZWQgd2l0aCBWTUw6XG5cdFx0XHRcdHdyYXBwZXIuYWRkZWQgPSB0cnVlO1xuXHRcdFx0XHRpZiAod3JhcHBlci5hbGlnbk9uQWRkKSB7XG5cdFx0XHRcdFx0d3JhcHBlci5odG1sVXBkYXRlVHJhbnNmb3JtKCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gd3JhcHBlcjtcblx0XHRcdH07XG5cdFx0fVxuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9XG59KTtcblxuLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogU1RBUlQgT0YgSU5URVJORVQgRVhQTE9SRVIgPD0gOCBTUEVDSUZJQyBDT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogRm9yIGFwcGxpY2F0aW9ucyBhbmQgd2Vic2l0ZXMgdGhhdCBkb24ndCBuZWVkIElFIHN1cHBvcnQsIGxpa2UgcGxhdGZvcm0gICAgKlxuICogdGFyZ2V0ZWQgbW9iaWxlIGFwcHMgYW5kIHdlYiBhcHBzLCB0aGlzIGNvZGUgY2FuIGJlIHJlbW92ZWQuICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgVk1MUmVuZGVyZXIsIFZNTEVsZW1lbnQ7XG5pZiAoIWhhc1NWRyAmJiAhdXNlQ2FuVkcpIHtcblxuLyoqXG4gKiBUaGUgVk1MIGVsZW1lbnQgd3JhcHBlci5cbiAqL1xuVk1MRWxlbWVudCA9IHtcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSBhIG5ldyBWTUwgZWxlbWVudCB3cmFwcGVyLiBJdCBidWlsZHMgdGhlIG1hcmt1cCBhcyBhIHN0cmluZ1xuXHQgKiB0byBtaW5pbWl6ZSBET00gdHJhZmZpYy5cblx0ICogQHBhcmFtIHtPYmplY3R9IHJlbmRlcmVyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBub2RlTmFtZVxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKHJlbmRlcmVyLCBub2RlTmFtZSkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdG1hcmt1cCA9ICBbJzwnLCBub2RlTmFtZSwgJyBmaWxsZWQ9XCJmXCIgc3Ryb2tlZD1cImZcIiddLFxuXHRcdFx0c3R5bGUgPSBbJ3Bvc2l0aW9uOiAnLCBBQlNPTFVURSwgJzsnXSxcblx0XHRcdGlzRGl2ID0gbm9kZU5hbWUgPT09IERJVjtcblxuXHRcdC8vIGRpdnMgYW5kIHNoYXBlcyBuZWVkIHNpemVcblx0XHRpZiAobm9kZU5hbWUgPT09ICdzaGFwZScgfHwgaXNEaXYpIHtcblx0XHRcdHN0eWxlLnB1c2goJ2xlZnQ6MDt0b3A6MDt3aWR0aDoxcHg7aGVpZ2h0OjFweDsnKTtcblx0XHR9XG5cdFx0c3R5bGUucHVzaCgndmlzaWJpbGl0eTogJywgaXNEaXYgPyBISURERU4gOiBWSVNJQkxFKTtcblxuXHRcdG1hcmt1cC5wdXNoKCcgc3R5bGU9XCInLCBzdHlsZS5qb2luKCcnKSwgJ1wiLz4nKTtcblxuXHRcdC8vIGNyZWF0ZSBlbGVtZW50IHdpdGggZGVmYXVsdCBhdHRyaWJ1dGVzIGFuZCBzdHlsZVxuXHRcdGlmIChub2RlTmFtZSkge1xuXHRcdFx0bWFya3VwID0gaXNEaXYgfHwgbm9kZU5hbWUgPT09ICdzcGFuJyB8fCBub2RlTmFtZSA9PT0gJ2ltZycgP1xuXHRcdFx0XHRtYXJrdXAuam9pbignJylcblx0XHRcdFx0OiByZW5kZXJlci5wcmVwVk1MKG1hcmt1cCk7XG5cdFx0XHR3cmFwcGVyLmVsZW1lbnQgPSBjcmVhdGVFbGVtZW50KG1hcmt1cCk7XG5cdFx0fVxuXG5cdFx0d3JhcHBlci5yZW5kZXJlciA9IHJlbmRlcmVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgdGhlIG5vZGUgdG8gdGhlIGdpdmVuIHBhcmVudFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcGFyZW50XG5cdCAqL1xuXHRhZGQ6IGZ1bmN0aW9uIChwYXJlbnQpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHRyZW5kZXJlciA9IHdyYXBwZXIucmVuZGVyZXIsXG5cdFx0XHRlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0Ym94ID0gcmVuZGVyZXIuYm94LFxuXHRcdFx0aW52ZXJ0ZWQgPSBwYXJlbnQgJiYgcGFyZW50LmludmVydGVkLFxuXG5cdFx0XHQvLyBnZXQgdGhlIHBhcmVudCBub2RlXG5cdFx0XHRwYXJlbnROb2RlID0gcGFyZW50ID9cblx0XHRcdFx0cGFyZW50LmVsZW1lbnQgfHwgcGFyZW50IDpcblx0XHRcdFx0Ym94O1xuXG5cblx0XHQvLyBpZiB0aGUgcGFyZW50IGdyb3VwIGlzIGludmVydGVkLCBhcHBseSBpbnZlcnNpb24gb24gYWxsIGNoaWxkcmVuXG5cdFx0aWYgKGludmVydGVkKSB7IC8vIG9ubHkgb24gZ3JvdXBzXG5cdFx0XHRyZW5kZXJlci5pbnZlcnRDaGlsZChlbGVtZW50LCBwYXJlbnROb2RlKTtcblx0XHR9XG5cblx0XHQvLyBhcHBlbmQgaXRcblx0XHRwYXJlbnROb2RlLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXG5cdFx0Ly8gYWxpZ24gdGV4dCBhZnRlciBhZGRpbmcgdG8gYmUgYWJsZSB0byByZWFkIG9mZnNldFxuXHRcdHdyYXBwZXIuYWRkZWQgPSB0cnVlO1xuXHRcdGlmICh3cmFwcGVyLmFsaWduT25BZGQgJiYgIXdyYXBwZXIuZGVmZXJVcGRhdGVUcmFuc2Zvcm0pIHtcblx0XHRcdHdyYXBwZXIudXBkYXRlVHJhbnNmb3JtKCk7XG5cdFx0fVxuXG5cdFx0Ly8gZmlyZSBhbiBldmVudCBmb3IgaW50ZXJuYWwgaG9va3Ncblx0XHRpZiAod3JhcHBlci5vbkFkZCkge1xuXHRcdFx0d3JhcHBlci5vbkFkZCgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBWTUwgYWx3YXlzIHVzZXMgaHRtbFVwZGF0ZVRyYW5zZm9ybVxuXHQgKi9cblx0dXBkYXRlVHJhbnNmb3JtOiBTVkdFbGVtZW50LnByb3RvdHlwZS5odG1sVXBkYXRlVHJhbnNmb3JtLFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHJvdGF0aW9uIG9mIGEgc3BhbiB3aXRoIG9sZElFJ3MgZmlsdGVyXG5cdCAqL1xuXHRzZXRTcGFuUm90YXRpb246IGZ1bmN0aW9uICgpIHtcblx0XHQvLyBBZGp1c3QgZm9yIGFsaWdubWVudCBhbmQgcm90YXRpb24uIFJvdGF0aW9uIG9mIHVzZUhUTUwgY29udGVudCBpcyBub3QgeWV0IGltcGxlbWVudGVkXG5cdFx0Ly8gYnV0IGl0IGNhbiBwcm9iYWJseSBiZSBpbXBsZW1lbnRlZCBmb3IgRmlyZWZveCAzLjUrIG9uIHVzZXIgcmVxdWVzdC4gRkYzLjUrXG5cdFx0Ly8gaGFzIHN1cHBvcnQgZm9yIENTUzMgdHJhbnNmb3JtLiBUaGUgZ2V0QkJveCBtZXRob2QgYWxzbyBuZWVkcyB0byBiZSB1cGRhdGVkXG5cdFx0Ly8gdG8gY29tcGVuc2F0ZSBmb3IgdGhlIHJvdGF0aW9uLCBsaWtlIGl0IGN1cnJlbnRseSBkb2VzIGZvciBTVkcuXG5cdFx0Ly8gVGVzdCBjYXNlOiBodHRwOi8vanNmaWRkbGUubmV0L2hpZ2hjaGFydHMvWWJ0NDQvXG5cblx0XHR2YXIgcm90YXRpb24gPSB0aGlzLnJvdGF0aW9uLFxuXHRcdFx0Y29zdGhldGEgPSBtYXRoQ29zKHJvdGF0aW9uICogZGVnMnJhZCksXG5cdFx0XHRzaW50aGV0YSA9IG1hdGhTaW4ocm90YXRpb24gKiBkZWcycmFkKTtcblx0XHRcdFx0XHRcblx0XHRjc3ModGhpcy5lbGVtZW50LCB7XG5cdFx0XHRmaWx0ZXI6IHJvdGF0aW9uID8gWydwcm9naWQ6RFhJbWFnZVRyYW5zZm9ybS5NaWNyb3NvZnQuTWF0cml4KE0xMT0nLCBjb3N0aGV0YSxcblx0XHRcdFx0JywgTTEyPScsIC1zaW50aGV0YSwgJywgTTIxPScsIHNpbnRoZXRhLCAnLCBNMjI9JywgY29zdGhldGEsXG5cdFx0XHRcdCcsIHNpemluZ01ldGhvZD1cXCdhdXRvIGV4cGFuZFxcJyknXS5qb2luKCcnKSA6IE5PTkVcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBwb3NpdGlvbmluZyBjb3JyZWN0aW9uIGZvciB0aGUgc3BhbiBhZnRlciByb3RhdGluZy4gXG5cdCAqL1xuXHRnZXRTcGFuQ29ycmVjdGlvbjogZnVuY3Rpb24gKHdpZHRoLCBiYXNlbGluZSwgYWxpZ25Db3JyZWN0aW9uLCByb3RhdGlvbiwgYWxpZ24pIHtcblxuXHRcdHZhciBjb3N0aGV0YSA9IHJvdGF0aW9uID8gbWF0aENvcyhyb3RhdGlvbiAqIGRlZzJyYWQpIDogMSxcblx0XHRcdHNpbnRoZXRhID0gcm90YXRpb24gPyBtYXRoU2luKHJvdGF0aW9uICogZGVnMnJhZCkgOiAwLFxuXHRcdFx0aGVpZ2h0ID0gcGljayh0aGlzLmVsZW1IZWlnaHQsIHRoaXMuZWxlbWVudC5vZmZzZXRIZWlnaHQpLFxuXHRcdFx0cXVhZCxcblx0XHRcdG5vbkxlZnQgPSBhbGlnbiAmJiBhbGlnbiAhPT0gJ2xlZnQnO1xuXG5cdFx0Ly8gY29ycmVjdCB4IGFuZCB5XG5cdFx0dGhpcy54Q29yciA9IGNvc3RoZXRhIDwgMCAmJiAtd2lkdGg7XG5cdFx0dGhpcy55Q29yciA9IHNpbnRoZXRhIDwgMCAmJiAtaGVpZ2h0O1xuXG5cdFx0Ly8gY29ycmVjdCBmb3IgYmFzZWxpbmUgYW5kIGNvcm5lcnMgc3BpbGxpbmcgb3V0IGFmdGVyIHJvdGF0aW9uXG5cdFx0cXVhZCA9IGNvc3RoZXRhICogc2ludGhldGEgPCAwO1xuXHRcdHRoaXMueENvcnIgKz0gc2ludGhldGEgKiBiYXNlbGluZSAqIChxdWFkID8gMSAtIGFsaWduQ29ycmVjdGlvbiA6IGFsaWduQ29ycmVjdGlvbik7XG5cdFx0dGhpcy55Q29yciAtPSBjb3N0aGV0YSAqIGJhc2VsaW5lICogKHJvdGF0aW9uID8gKHF1YWQgPyBhbGlnbkNvcnJlY3Rpb24gOiAxIC0gYWxpZ25Db3JyZWN0aW9uKSA6IDEpO1xuXHRcdC8vIGNvcnJlY3QgZm9yIHRoZSBsZW5ndGgvaGVpZ2h0IG9mIHRoZSB0ZXh0XG5cdFx0aWYgKG5vbkxlZnQpIHtcblx0XHRcdHRoaXMueENvcnIgLT0gd2lkdGggKiBhbGlnbkNvcnJlY3Rpb24gKiAoY29zdGhldGEgPCAwID8gLTEgOiAxKTtcblx0XHRcdGlmIChyb3RhdGlvbikge1xuXHRcdFx0XHR0aGlzLnlDb3JyIC09IGhlaWdodCAqIGFsaWduQ29ycmVjdGlvbiAqIChzaW50aGV0YSA8IDAgPyAtMSA6IDEpO1xuXHRcdFx0fVxuXHRcdFx0Y3NzKHRoaXMuZWxlbWVudCwge1xuXHRcdFx0XHR0ZXh0QWxpZ246IGFsaWduXG5cdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIENvbnZlcnRzIGEgc3Vic2V0IG9mIGFuIFNWRyBwYXRoIGRlZmluaXRpb24gdG8gaXRzIFZNTCBjb3VudGVycGFydC4gVGFrZXMgYW4gYXJyYXlcblx0ICogYXMgdGhlIHBhcmFtZXRlciBhbmQgcmV0dXJucyBhIHN0cmluZy5cblx0ICovXG5cdHBhdGhUb1ZNTDogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0Ly8gY29udmVydCBwYXRoc1xuXHRcdHZhciBpID0gdmFsdWUubGVuZ3RoLFxuXHRcdFx0cGF0aCA9IFtdO1xuXG5cdFx0d2hpbGUgKGktLSkge1xuXG5cdFx0XHQvLyBNdWx0aXBseSBieSAxMCB0byBhbGxvdyBzdWJwaXhlbCBwcmVjaXNpb24uXG5cdFx0XHQvLyBTdWJzdHJhY3RpbmcgaGFsZiBhIHBpeGVsIHNlZW1zIHRvIG1ha2UgdGhlIGNvb3JkaW5hdGVzXG5cdFx0XHQvLyBhbGlnbiB3aXRoIFNWRywgYnV0IHRoaXMgaGFzbid0IGJlZW4gdGVzdGVkIHRob3JvdWdobHlcblx0XHRcdGlmIChpc051bWJlcih2YWx1ZVtpXSkpIHtcblx0XHRcdFx0cGF0aFtpXSA9IG1hdGhSb3VuZCh2YWx1ZVtpXSAqIDEwKSAtIDU7XG5cdFx0XHR9IGVsc2UgaWYgKHZhbHVlW2ldID09PSAnWicpIHsgLy8gY2xvc2UgdGhlIHBhdGhcblx0XHRcdFx0cGF0aFtpXSA9ICd4Jztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBhdGhbaV0gPSB2YWx1ZVtpXTtcblxuXHRcdFx0XHQvLyBXaGVuIHRoZSBzdGFydCBYIGFuZCBlbmQgWCBjb29yZGluYXRlcyBvZiBhbiBhcmMgYXJlIHRvbyBjbG9zZSxcblx0XHRcdFx0Ly8gdGhleSBhcmUgcm91bmRlZCB0byB0aGUgc2FtZSB2YWx1ZSBhYm92ZS4gSW4gdGhpcyBjYXNlLCBzdWJzdHJhY3Qgb3IgXG5cdFx0XHRcdC8vIGFkZCAxIGZyb20gdGhlIGVuZCBYIGFuZCBZIHBvc2l0aW9ucy4gIzE4NiwgIzc2MCwgIzEzNzEsICMxNDEwLlxuXHRcdFx0XHRpZiAodmFsdWUuaXNBcmMgJiYgKHZhbHVlW2ldID09PSAnd2EnIHx8IHZhbHVlW2ldID09PSAnYXQnKSkge1xuXHRcdFx0XHRcdC8vIFN0YXJ0IGFuZCBlbmQgWFxuXHRcdFx0XHRcdGlmIChwYXRoW2kgKyA1XSA9PT0gcGF0aFtpICsgN10pIHtcblx0XHRcdFx0XHRcdHBhdGhbaSArIDddICs9IHZhbHVlW2kgKyA3XSA+IHZhbHVlW2kgKyA1XSA/IDEgOiAtMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Ly8gU3RhcnQgYW5kIGVuZCBZXG5cdFx0XHRcdFx0aWYgKHBhdGhbaSArIDZdID09PSBwYXRoW2kgKyA4XSkge1xuXHRcdFx0XHRcdFx0cGF0aFtpICsgOF0gKz0gdmFsdWVbaSArIDhdID4gdmFsdWVbaSArIDZdID8gMSA6IC0xO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdFxuXHRcdC8vIExvb3AgdXAgYWdhaW4gdG8gaGFuZGxlIHBhdGggc2hvcnRjdXRzICgjMjEzMilcblx0XHQvKndoaWxlIChpKysgPCBwYXRoLmxlbmd0aCkge1xuXHRcdFx0aWYgKHBhdGhbaV0gPT09ICdIJykgeyAvLyBob3Jpem9udGFsIGxpbmUgdG9cblx0XHRcdFx0cGF0aFtpXSA9ICdMJztcblx0XHRcdFx0cGF0aC5zcGxpY2UoaSArIDIsIDAsIHBhdGhbaSAtIDFdKTtcblx0XHRcdH0gZWxzZSBpZiAocGF0aFtpXSA9PT0gJ1YnKSB7IC8vIHZlcnRpY2FsIGxpbmUgdG9cblx0XHRcdFx0cGF0aFtpXSA9ICdMJztcblx0XHRcdFx0cGF0aC5zcGxpY2UoaSArIDEsIDAsIHBhdGhbaSAtIDJdKTtcblx0XHRcdH1cblx0XHR9Ki9cblx0XHRyZXR1cm4gcGF0aC5qb2luKCcgJykgfHwgJ3gnO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIGVsZW1lbnQncyBjbGlwcGluZyB0byBhIHByZWRlZmluZWQgcmVjdGFuZ2xlXG5cdCAqXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpZCBUaGUgaWQgb2YgdGhlIGNsaXAgcmVjdGFuZ2xlXG5cdCAqL1xuXHRjbGlwOiBmdW5jdGlvbiAoY2xpcFJlY3QpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHRjbGlwTWVtYmVycyxcblx0XHRcdGNzc1JldDtcblxuXHRcdGlmIChjbGlwUmVjdCkge1xuXHRcdFx0Y2xpcE1lbWJlcnMgPSBjbGlwUmVjdC5tZW1iZXJzO1xuXHRcdFx0ZXJhc2UoY2xpcE1lbWJlcnMsIHdyYXBwZXIpOyAvLyBFbnN1cmUgdW5pcXVlIGxpc3Qgb2YgZWxlbWVudHMgKCMxMjU4KVxuXHRcdFx0Y2xpcE1lbWJlcnMucHVzaCh3cmFwcGVyKTtcblx0XHRcdHdyYXBwZXIuZGVzdHJveUNsaXAgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGVyYXNlKGNsaXBNZW1iZXJzLCB3cmFwcGVyKTtcblx0XHRcdH07XG5cdFx0XHRjc3NSZXQgPSBjbGlwUmVjdC5nZXRDU1Mod3JhcHBlcik7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHdyYXBwZXIuZGVzdHJveUNsaXApIHtcblx0XHRcdFx0d3JhcHBlci5kZXN0cm95Q2xpcCgpO1xuXHRcdFx0fVxuXHRcdFx0Y3NzUmV0ID0geyBjbGlwOiBkb2NNb2RlOCA/ICdpbmhlcml0JyA6ICdyZWN0KGF1dG8pJyB9OyAvLyAjMTIxNFxuXHRcdH1cblxuXHRcdHJldHVybiB3cmFwcGVyLmNzcyhjc3NSZXQpO1xuXG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCBzdHlsZXMgZm9yIHRoZSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBzdHlsZXNcblx0ICovXG5cdGNzczogU1ZHRWxlbWVudC5wcm90b3R5cGUuaHRtbENzcyxcblxuXHQvKipcblx0ICogUmVtb3ZlcyBhIGNoaWxkIGVpdGhlciBieSByZW1vdmVDaGlsZCBvciBtb3ZlIHRvIGdhcmJhZ2VCaW4uXG5cdCAqIElzc3VlIDQ5MDsgaW4gVk1MIHJlbW92ZUNoaWxkIHJlc3VsdHMgaW4gT3JwaGFuZWQgbm9kZXMgYWNjb3JkaW5nIHRvIHNJRXZlLCBkaXNjYXJkRWxlbWVudCBkb2VzIG5vdC5cblx0ICovXG5cdHNhZmVSZW1vdmVDaGlsZDogZnVuY3Rpb24gKGVsZW1lbnQpIHtcblx0XHQvLyBkaXNjYXJkRWxlbWVudCB3aWxsIGRldGFjaCB0aGUgbm9kZSBmcm9tIGl0cyBwYXJlbnQgYmVmb3JlIGF0dGFjaGluZyBpdFxuXHRcdC8vIHRvIHRoZSBnYXJiYWdlIGJpbi4gVGhlcmVmb3JlIGl0IGlzIGltcG9ydGFudCB0aGF0IHRoZSBub2RlIGlzIGF0dGFjaGVkIGFuZCBoYXZlIHBhcmVudC5cblx0XHRpZiAoZWxlbWVudC5wYXJlbnROb2RlKSB7XG5cdFx0XHRkaXNjYXJkRWxlbWVudChlbGVtZW50KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEV4dGVuZCBlbGVtZW50LmRlc3Ryb3kgYnkgcmVtb3ZpbmcgaXQgZnJvbSB0aGUgY2xpcCBtZW1iZXJzIGFycmF5XG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMuZGVzdHJveUNsaXApIHtcblx0XHRcdHRoaXMuZGVzdHJveUNsaXAoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gU1ZHRWxlbWVudC5wcm90b3R5cGUuZGVzdHJveS5hcHBseSh0aGlzKTtcblx0fSxcblxuXHQvKipcblx0ICogQWRkIGFuIGV2ZW50IGxpc3RlbmVyLiBWTUwgb3ZlcnJpZGUgZm9yIG5vcm1hbGl6aW5nIGV2ZW50IHBhcmFtZXRlcnMuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGVcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuXHQgKi9cblx0b246IGZ1bmN0aW9uIChldmVudFR5cGUsIGhhbmRsZXIpIHtcblx0XHQvLyBzaW1wbGVzdCBwb3NzaWJsZSBldmVudCBtb2RlbCBmb3IgaW50ZXJuYWwgdXNlXG5cdFx0dGhpcy5lbGVtZW50WydvbicgKyBldmVudFR5cGVdID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0dmFyIGV2dCA9IHdpbi5ldmVudDtcblx0XHRcdGV2dC50YXJnZXQgPSBldnQuc3JjRWxlbWVudDtcblx0XHRcdGhhbmRsZXIoZXZ0KTtcblx0XHR9O1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbiBzdGFja2VkIGNvbHVtbnMsIGN1dCBvZmYgdGhlIHNoYWRvd3Mgc28gdGhhdCB0aGV5IGRvbid0IG92ZXJsYXBcblx0ICovXG5cdGN1dE9mZlBhdGg6IGZ1bmN0aW9uIChwYXRoLCBsZW5ndGgpIHtcblxuXHRcdHZhciBsZW47XG5cblx0XHRwYXRoID0gcGF0aC5zcGxpdCgvWyAsXS8pO1xuXHRcdGxlbiA9IHBhdGgubGVuZ3RoO1xuXG5cdFx0aWYgKGxlbiA9PT0gOSB8fCBsZW4gPT09IDExKSB7XG5cdFx0XHRwYXRoW2xlbiAtIDRdID0gcGF0aFtsZW4gLSAyXSA9IHBJbnQocGF0aFtsZW4gLSAyXSkgLSAxMCAqIGxlbmd0aDtcblx0XHR9XG5cdFx0cmV0dXJuIHBhdGguam9pbignICcpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBcHBseSBhIGRyb3Agc2hhZG93IGJ5IGNvcHlpbmcgZWxlbWVudHMgYW5kIGdpdmluZyB0aGVtIGRpZmZlcmVudCBzdHJva2VzXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IHNoYWRvd09wdGlvbnNcblx0ICovXG5cdHNoYWRvdzogZnVuY3Rpb24gKHNoYWRvd09wdGlvbnMsIGdyb3VwLCBjdXRPZmYpIHtcblx0XHR2YXIgc2hhZG93cyA9IFtdLFxuXHRcdFx0aSxcblx0XHRcdGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsXG5cdFx0XHRyZW5kZXJlciA9IHRoaXMucmVuZGVyZXIsXG5cdFx0XHRzaGFkb3csXG5cdFx0XHRlbGVtU3R5bGUgPSBlbGVtZW50LnN0eWxlLFxuXHRcdFx0bWFya3VwLFxuXHRcdFx0cGF0aCA9IGVsZW1lbnQucGF0aCxcblx0XHRcdHN0cm9rZVdpZHRoLFxuXHRcdFx0bW9kaWZpZWRQYXRoLFxuXHRcdFx0c2hhZG93V2lkdGgsXG5cdFx0XHRzaGFkb3dFbGVtZW50T3BhY2l0eTtcblxuXHRcdC8vIHNvbWUgdGltZXMgZW1wdHkgcGF0aHMgYXJlIG5vdCBzdHJpbmdzXG5cdFx0aWYgKHBhdGggJiYgdHlwZW9mIHBhdGgudmFsdWUgIT09ICdzdHJpbmcnKSB7XG5cdFx0XHRwYXRoID0gJ3gnO1xuXHRcdH1cblx0XHRtb2RpZmllZFBhdGggPSBwYXRoO1xuXG5cdFx0aWYgKHNoYWRvd09wdGlvbnMpIHtcblx0XHRcdHNoYWRvd1dpZHRoID0gcGljayhzaGFkb3dPcHRpb25zLndpZHRoLCAzKTtcblx0XHRcdHNoYWRvd0VsZW1lbnRPcGFjaXR5ID0gKHNoYWRvd09wdGlvbnMub3BhY2l0eSB8fCAwLjE1KSAvIHNoYWRvd1dpZHRoO1xuXHRcdFx0Zm9yIChpID0gMTsgaSA8PSAzOyBpKyspIHtcblxuXHRcdFx0XHRzdHJva2VXaWR0aCA9IChzaGFkb3dXaWR0aCAqIDIpICsgMSAtICgyICogaSk7XG5cblx0XHRcdFx0Ly8gQ3V0IG9mZiBzaGFkb3dzIGZvciBzdGFja2VkIGNvbHVtbiBpdGVtc1xuXHRcdFx0XHRpZiAoY3V0T2ZmKSB7XG5cdFx0XHRcdFx0bW9kaWZpZWRQYXRoID0gdGhpcy5jdXRPZmZQYXRoKHBhdGgudmFsdWUsIHN0cm9rZVdpZHRoICsgMC41KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdG1hcmt1cCA9IFsnPHNoYXBlIGlzU2hhZG93PVwidHJ1ZVwiIHN0cm9rZXdlaWdodD1cIicsIHN0cm9rZVdpZHRoLFxuXHRcdFx0XHRcdCdcIiBmaWxsZWQ9XCJmYWxzZVwiIHBhdGg9XCInLCBtb2RpZmllZFBhdGgsXG5cdFx0XHRcdFx0J1wiIGNvb3Jkc2l6ZT1cIjEwIDEwXCIgc3R5bGU9XCInLCBlbGVtZW50LnN0eWxlLmNzc1RleHQsICdcIiAvPiddO1xuXG5cdFx0XHRcdHNoYWRvdyA9IGNyZWF0ZUVsZW1lbnQocmVuZGVyZXIucHJlcFZNTChtYXJrdXApLFxuXHRcdFx0XHRcdG51bGwsIHtcblx0XHRcdFx0XHRcdGxlZnQ6IHBJbnQoZWxlbVN0eWxlLmxlZnQpICsgcGljayhzaGFkb3dPcHRpb25zLm9mZnNldFgsIDEpLFxuXHRcdFx0XHRcdFx0dG9wOiBwSW50KGVsZW1TdHlsZS50b3ApICsgcGljayhzaGFkb3dPcHRpb25zLm9mZnNldFksIDEpXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRpZiAoY3V0T2ZmKSB7XG5cdFx0XHRcdFx0c2hhZG93LmN1dE9mZiA9IHN0cm9rZVdpZHRoICsgMTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGFwcGx5IHRoZSBvcGFjaXR5XG5cdFx0XHRcdG1hcmt1cCA9IFsnPHN0cm9rZSBjb2xvcj1cIicsIHNoYWRvd09wdGlvbnMuY29sb3IgfHwgJ2JsYWNrJywgJ1wiIG9wYWNpdHk9XCInLCBzaGFkb3dFbGVtZW50T3BhY2l0eSAqIGksICdcIi8+J107XG5cdFx0XHRcdGNyZWF0ZUVsZW1lbnQocmVuZGVyZXIucHJlcFZNTChtYXJrdXApLCBudWxsLCBudWxsLCBzaGFkb3cpO1xuXG5cblx0XHRcdFx0Ly8gaW5zZXJ0IGl0XG5cdFx0XHRcdGlmIChncm91cCkge1xuXHRcdFx0XHRcdGdyb3VwLmVsZW1lbnQuYXBwZW5kQ2hpbGQoc2hhZG93KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNoYWRvdywgZWxlbWVudCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyByZWNvcmQgaXRcblx0XHRcdFx0c2hhZG93cy5wdXNoKHNoYWRvdyk7XG5cblx0XHRcdH1cblxuXHRcdFx0dGhpcy5zaGFkb3dzID0gc2hhZG93cztcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cdHVwZGF0ZVNoYWRvd3M6IG5vb3AsIC8vIFVzZWQgaW4gU1ZHIG9ubHlcblxuXHRzZXRBdHRyOiBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuXHRcdGlmIChkb2NNb2RlOCkgeyAvLyBJRTggc2V0QXR0cmlidXRlIGJ1Z1xuXHRcdFx0dGhpcy5lbGVtZW50W2tleV0gPSB2YWx1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcblx0XHR9XG5cdH0sXG5cdGNsYXNzU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHQvLyBJRTggU3RhbmRhcmRzIG1vZGUgaGFzIHByb2JsZW1zIHJldHJpZXZpbmcgdGhlIGNsYXNzTmFtZSB1bmxlc3Mgc2V0IGxpa2UgdGhpc1xuXHRcdHRoaXMuZWxlbWVudC5jbGFzc05hbWUgPSB2YWx1ZTtcblx0fSxcblx0ZGFzaHN0eWxlU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdHZhciBzdHJva2VFbGVtID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3Ryb2tlJylbMF0gfHxcblx0XHRcdGNyZWF0ZUVsZW1lbnQodGhpcy5yZW5kZXJlci5wcmVwVk1MKFsnPHN0cm9rZS8+J10pLCBudWxsLCBudWxsLCBlbGVtZW50KTtcblx0XHRzdHJva2VFbGVtW2tleV0gPSB2YWx1ZSB8fCAnc29saWQnO1xuXHRcdHRoaXNba2V5XSA9IHZhbHVlOyAvKiBiZWNhdXNlIGNoYW5naW5nIHN0cm9rZS13aWR0aCB3aWxsIGNoYW5nZSB0aGUgZGFzaCBsZW5ndGhcblx0XHRcdGFuZCBjYXVzZSBhbiBlcGlsZXB0aWMgZWZmZWN0ICovXG5cdH0sXG5cdGRTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRzaGFkb3dzID0gdGhpcy5zaGFkb3dzO1xuXHRcdHZhbHVlID0gdmFsdWUgfHwgW107XG5cdFx0dGhpcy5kID0gdmFsdWUuam9pbiAmJiB2YWx1ZS5qb2luKCcgJyk7IC8vIHVzZWQgaW4gZ2V0dGVyIGZvciBhbmltYXRpb25cblxuXHRcdGVsZW1lbnQucGF0aCA9IHZhbHVlID0gdGhpcy5wYXRoVG9WTUwodmFsdWUpO1xuXG5cdFx0Ly8gdXBkYXRlIHNoYWRvd3Ncblx0XHRpZiAoc2hhZG93cykge1xuXHRcdFx0aSA9IHNoYWRvd3MubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRzaGFkb3dzW2ldLnBhdGggPSBzaGFkb3dzW2ldLmN1dE9mZiA/IHRoaXMuY3V0T2ZmUGF0aCh2YWx1ZSwgc2hhZG93c1tpXS5jdXRPZmYpIDogdmFsdWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuc2V0QXR0cihrZXksIHZhbHVlKTtcblx0fSxcblx0ZmlsbFNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtZW50Lm5vZGVOYW1lO1xuXHRcdGlmIChub2RlTmFtZSA9PT0gJ1NQQU4nKSB7IC8vIHRleHQgY29sb3Jcblx0XHRcdGVsZW1lbnQuc3R5bGUuY29sb3IgPSB2YWx1ZTtcblx0XHR9IGVsc2UgaWYgKG5vZGVOYW1lICE9PSAnSU1HJykgeyAvLyAjMTMzNlxuXHRcdFx0ZWxlbWVudC5maWxsZWQgPSB2YWx1ZSAhPT0gTk9ORTtcblx0XHRcdHRoaXMuc2V0QXR0cignZmlsbGNvbG9yJywgdGhpcy5yZW5kZXJlci5jb2xvcih2YWx1ZSwgZWxlbWVudCwga2V5LCB0aGlzKSk7XG5cdFx0fVxuXHR9LFxuXHRvcGFjaXR5U2V0dGVyOiBub29wLCAvLyBEb24ndCBib3RoZXIgLSBhbmltYXRpb24gaXMgdG9vIHNsb3cgYW5kIGZpbHRlcnMgaW50cm9kdWNlIGFydGlmYWN0c1xuXHRyb3RhdGlvblNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHR2YXIgc3R5bGUgPSBlbGVtZW50LnN0eWxlO1xuXHRcdHRoaXNba2V5XSA9IHN0eWxlW2tleV0gPSB2YWx1ZTsgLy8gc3R5bGUgaXMgZm9yICMxODczXG5cblx0XHQvLyBDb3JyZWN0aW9uIGZvciB0aGUgMXgxIHNpemUgb2YgdGhlIHNoYXBlIGNvbnRhaW5lci4gVXNlZCBpbiBnYXVnZSBuZWVkbGVzLlxuXHRcdHN0eWxlLmxlZnQgPSAtbWF0aFJvdW5kKG1hdGhTaW4odmFsdWUgKiBkZWcycmFkKSArIDEpICsgUFg7XG5cdFx0c3R5bGUudG9wID0gbWF0aFJvdW5kKG1hdGhDb3ModmFsdWUgKiBkZWcycmFkKSkgKyBQWDtcblx0fSxcblx0c3Ryb2tlU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdHRoaXMuc2V0QXR0cignc3Ryb2tlY29sb3InLCB0aGlzLnJlbmRlcmVyLmNvbG9yKHZhbHVlLCBlbGVtZW50LCBrZXkpKTtcblx0fSxcblx0J3N0cm9rZS13aWR0aFNldHRlcic6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0ZWxlbWVudC5zdHJva2VkID0gISF2YWx1ZTsgLy8gVk1MIFwic3Ryb2tlZFwiIGF0dHJpYnV0ZVxuXHRcdHRoaXNba2V5XSA9IHZhbHVlOyAvLyB1c2VkIGluIGdldHRlciwgaXNzdWUgIzExM1xuXHRcdGlmIChpc051bWJlcih2YWx1ZSkpIHtcblx0XHRcdHZhbHVlICs9IFBYO1xuXHRcdH1cblx0XHR0aGlzLnNldEF0dHIoJ3N0cm9rZXdlaWdodCcsIHZhbHVlKTtcblx0fSxcblx0dGl0bGVTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0dGhpcy5zZXRBdHRyKGtleSwgdmFsdWUpO1xuXHR9LFxuXHR2aXNpYmlsaXR5U2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXG5cdFx0Ly8gSGFuZGxlIGluaGVyaXRlZCB2aXNpYmlsaXR5XG5cdFx0aWYgKHZhbHVlID09PSAnaW5oZXJpdCcpIHtcblx0XHRcdHZhbHVlID0gVklTSUJMRTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gTGV0IHRoZSBzaGFkb3cgZm9sbG93IHRoZSBtYWluIGVsZW1lbnRcblx0XHRpZiAodGhpcy5zaGFkb3dzKSB7XG5cdFx0XHRlYWNoKHRoaXMuc2hhZG93cywgZnVuY3Rpb24gKHNoYWRvdykge1xuXHRcdFx0XHRzaGFkb3cuc3R5bGVba2V5XSA9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gSW5zdGVhZCBvZiB0b2dnbGluZyB0aGUgdmlzaWJpbGl0eSBDU1MgcHJvcGVydHksIG1vdmUgdGhlIGRpdiBvdXQgb2YgdGhlIHZpZXdwb3J0LlxuXHRcdC8vIFRoaXMgd29ya3MgYXJvdW5kICM2MSBhbmQgIzU4NlxuXHRcdGlmIChlbGVtZW50Lm5vZGVOYW1lID09PSAnRElWJykge1xuXHRcdFx0dmFsdWUgPSB2YWx1ZSA9PT0gSElEREVOID8gJy05OTllbScgOiAwO1xuXG5cdFx0XHQvLyBJbiBvcmRlciB0byByZWRyYXcsIElFNyBuZWVkcyB0aGUgZGl2IHRvIGJlIHZpc2libGUgd2hlbiB0dWNrZWQgYXdheVxuXHRcdFx0Ly8gb3V0c2lkZSB0aGUgdmlld3BvcnQuIFNvIHRoZSB2aXNpYmlsaXR5IGlzIGFjdHVhbGx5IG9wcG9zaXRlIG9mXG5cdFx0XHQvLyB0aGUgZXhwZWN0ZWQgdmFsdWUuIFRoaXMgYXBwbGllcyB0byB0aGUgdG9vbHRpcCBvbmx5LlxuXHRcdFx0aWYgKCFkb2NNb2RlOCkge1xuXHRcdFx0XHRlbGVtZW50LnN0eWxlW2tleV0gPSB2YWx1ZSA/IFZJU0lCTEUgOiBISURERU47XG5cdFx0XHR9XG5cdFx0XHRrZXkgPSAndG9wJztcblx0XHR9XG5cdFx0ZWxlbWVudC5zdHlsZVtrZXldID0gdmFsdWU7XG5cdH0sXG5cdHhTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0dGhpc1trZXldID0gdmFsdWU7IC8vIHVzZWQgaW4gZ2V0dGVyXG5cblx0XHRpZiAoa2V5ID09PSAneCcpIHtcblx0XHRcdGtleSA9ICdsZWZ0Jztcblx0XHR9IGVsc2UgaWYgKGtleSA9PT0gJ3knKSB7XG5cdFx0XHRrZXkgPSAndG9wJztcblx0XHR9LyogZWxzZSB7XG5cdFx0XHR2YWx1ZSA9IG1hdGhNYXgoMCwgdmFsdWUpOyAvLyBkb24ndCBzZXQgd2lkdGggb3IgaGVpZ2h0IGJlbG93IHplcm8gKCMzMTEpXG5cdFx0fSovXG5cblx0XHQvLyBjbGlwcGluZyByZWN0YW5nbGUgc3BlY2lhbFxuXHRcdGlmICh0aGlzLnVwZGF0ZUNsaXBwaW5nKSB7XG5cdFx0XHR0aGlzW2tleV0gPSB2YWx1ZTsgLy8gdGhlIGtleSBpcyBub3cgJ2xlZnQnIG9yICd0b3AnIGZvciAneCcgYW5kICd5J1xuXHRcdFx0dGhpcy51cGRhdGVDbGlwcGluZygpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBub3JtYWxcblx0XHRcdGVsZW1lbnQuc3R5bGVba2V5XSA9IHZhbHVlO1xuXHRcdH1cblx0fSxcblx0ekluZGV4U2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdGVsZW1lbnQuc3R5bGVba2V5XSA9IHZhbHVlO1xuXHR9XG59O1xuSGlnaGNoYXJ0cy5WTUxFbGVtZW50ID0gVk1MRWxlbWVudCA9IGV4dGVuZENsYXNzKFNWR0VsZW1lbnQsIFZNTEVsZW1lbnQpO1xuXG4vLyBTb21lIHNoYXJlZCBzZXR0ZXJzXG5WTUxFbGVtZW50LnByb3RvdHlwZS55U2V0dGVyID1cblx0Vk1MRWxlbWVudC5wcm90b3R5cGUud2lkdGhTZXR0ZXIgPSBcblx0Vk1MRWxlbWVudC5wcm90b3R5cGUuaGVpZ2h0U2V0dGVyID0gXG5cdFZNTEVsZW1lbnQucHJvdG90eXBlLnhTZXR0ZXI7XG5cblxuLyoqXG4gKiBUaGUgVk1MIHJlbmRlcmVyXG4gKi9cbnZhciBWTUxSZW5kZXJlckV4dGVuc2lvbiA9IHsgLy8gaW5oZXJpdCBTVkdSZW5kZXJlclxuXG5cdEVsZW1lbnQ6IFZNTEVsZW1lbnQsXG5cdGlzSUU4OiB1c2VyQWdlbnQuaW5kZXhPZignTVNJRSA4LjAnKSA+IC0xLFxuXG5cblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdGhlIFZNTFJlbmRlcmVyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBjb250YWluZXJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHRcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uIChjb250YWluZXIsIHdpZHRoLCBoZWlnaHQsIHN0eWxlKSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcyxcblx0XHRcdGJveFdyYXBwZXIsXG5cdFx0XHRib3gsXG5cdFx0XHRjc3M7XG5cblx0XHRyZW5kZXJlci5hbGlnbmVkT2JqZWN0cyA9IFtdO1xuXG5cdFx0Ym94V3JhcHBlciA9IHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoRElWKVxuXHRcdFx0LmNzcyhleHRlbmQodGhpcy5nZXRTdHlsZShzdHlsZSksIHsgcG9zaXRpb246IFJFTEFUSVZFfSkpO1xuXHRcdGJveCA9IGJveFdyYXBwZXIuZWxlbWVudDtcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQoYm94V3JhcHBlci5lbGVtZW50KTtcblxuXG5cdFx0Ly8gZ2VuZXJhdGUgdGhlIGNvbnRhaW5pbmcgYm94XG5cdFx0cmVuZGVyZXIuaXNWTUwgPSB0cnVlO1xuXHRcdHJlbmRlcmVyLmJveCA9IGJveDtcblx0XHRyZW5kZXJlci5ib3hXcmFwcGVyID0gYm94V3JhcHBlcjtcblx0XHRyZW5kZXJlci5jYWNoZSA9IHt9O1xuXG5cblx0XHRyZW5kZXJlci5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcblxuXHRcdC8vIFRoZSBvbmx5IHdheSB0byBtYWtlIElFNiBhbmQgSUU3IHByaW50IGlzIHRvIHVzZSBhIGdsb2JhbCBuYW1lc3BhY2UuIEhvd2V2ZXIsXG5cdFx0Ly8gd2l0aCBJRTggdGhlIG9ubHkgd2F5IHRvIG1ha2UgdGhlIGR5bmFtaWMgc2hhcGVzIHZpc2libGUgaW4gc2NyZWVuIGFuZCBwcmludCBtb2RlXG5cdFx0Ly8gc2VlbXMgdG8gYmUgdG8gYWRkIHRoZSB4bWxucyBhdHRyaWJ1dGUgYW5kIHRoZSBiZWhhdmlvdXIgc3R5bGUgaW5saW5lLlxuXHRcdGlmICghZG9jLm5hbWVzcGFjZXMuaGN2KSB7XG5cblx0XHRcdGRvYy5uYW1lc3BhY2VzLmFkZCgnaGN2JywgJ3VybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206dm1sJyk7XG5cblx0XHRcdC8vIFNldHVwIGRlZmF1bHQgQ1NTICgjMjE1MywgIzIzNjgsICMyMzg0KVxuXHRcdFx0Y3NzID0gJ2hjdlxcXFw6ZmlsbCwgaGN2XFxcXDpwYXRoLCBoY3ZcXFxcOnNoYXBlLCBoY3ZcXFxcOnN0cm9rZScgK1xuXHRcdFx0XHQneyBiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKTsgZGlzcGxheTogaW5saW5lLWJsb2NrOyB9ICc7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkb2MuY3JlYXRlU3R5bGVTaGVldCgpLmNzc1RleHQgPSBjc3M7XG5cdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdGRvYy5zdHlsZVNoZWV0c1swXS5jc3NUZXh0ICs9IGNzcztcblx0XHRcdH1cblxuXHRcdH1cblx0fSxcblxuXG5cdC8qKlxuXHQgKiBEZXRlY3Qgd2hldGhlciB0aGUgcmVuZGVyZXIgaXMgaGlkZGVuLiBUaGlzIGhhcHBlbnMgd2hlbiBvbmUgb2YgdGhlIHBhcmVudCBlbGVtZW50c1xuXHQgKiBoYXMgZGlzcGxheTogbm9uZVxuXHQgKi9cblx0aXNIaWRkZW46IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gIXRoaXMuYm94Lm9mZnNldFdpZHRoO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZWZpbmUgYSBjbGlwcGluZyByZWN0YW5nbGUuIEluIFZNTCBpdCBpcyBhY2NvbXBsaXNoZWQgYnkgc3RvcmluZyB0aGUgdmFsdWVzXG5cdCAqIGZvciBzZXR0aW5nIHRoZSBDU1Mgc3R5bGUgdG8gYWxsIGFzc29jaWF0ZWQgbWVtYmVycy5cblx0ICpcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHRcblx0ICovXG5cdGNsaXBSZWN0OiBmdW5jdGlvbiAoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXG5cdFx0Ly8gY3JlYXRlIGEgZHVtbXkgZWxlbWVudFxuXHRcdHZhciBjbGlwUmVjdCA9IHRoaXMuY3JlYXRlRWxlbWVudCgpLFxuXHRcdFx0aXNPYmogPSBpc09iamVjdCh4KTtcblxuXHRcdC8vIG1pbWljIGEgcmVjdGFuZ2xlIHdpdGggaXRzIHN0eWxlIG9iamVjdCBmb3IgYXV0b21hdGljIHVwZGF0aW5nIGluIGF0dHJcblx0XHRyZXR1cm4gZXh0ZW5kKGNsaXBSZWN0LCB7XG5cdFx0XHRtZW1iZXJzOiBbXSxcblx0XHRcdGxlZnQ6IChpc09iaiA/IHgueCA6IHgpICsgMSxcblx0XHRcdHRvcDogKGlzT2JqID8geC55IDogeSkgKyAxLFxuXHRcdFx0d2lkdGg6IChpc09iaiA/IHgud2lkdGggOiB3aWR0aCkgLSAxLFxuXHRcdFx0aGVpZ2h0OiAoaXNPYmogPyB4LmhlaWdodCA6IGhlaWdodCkgLSAxLFxuXHRcdFx0Z2V0Q1NTOiBmdW5jdGlvbiAod3JhcHBlcikge1xuXHRcdFx0XHR2YXIgZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdFx0XHRub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWUsXG5cdFx0XHRcdFx0aXNTaGFwZSA9IG5vZGVOYW1lID09PSAnc2hhcGUnLFxuXHRcdFx0XHRcdGludmVydGVkID0gd3JhcHBlci5pbnZlcnRlZCxcblx0XHRcdFx0XHRyZWN0ID0gdGhpcyxcblx0XHRcdFx0XHR0b3AgPSByZWN0LnRvcCAtIChpc1NoYXBlID8gZWxlbWVudC5vZmZzZXRUb3AgOiAwKSxcblx0XHRcdFx0XHRsZWZ0ID0gcmVjdC5sZWZ0LFxuXHRcdFx0XHRcdHJpZ2h0ID0gbGVmdCArIHJlY3Qud2lkdGgsXG5cdFx0XHRcdFx0Ym90dG9tID0gdG9wICsgcmVjdC5oZWlnaHQsXG5cdFx0XHRcdFx0cmV0ID0ge1xuXHRcdFx0XHRcdFx0Y2xpcDogJ3JlY3QoJyArXG5cdFx0XHRcdFx0XHRcdG1hdGhSb3VuZChpbnZlcnRlZCA/IGxlZnQgOiB0b3ApICsgJ3B4LCcgK1xuXHRcdFx0XHRcdFx0XHRtYXRoUm91bmQoaW52ZXJ0ZWQgPyBib3R0b20gOiByaWdodCkgKyAncHgsJyArXG5cdFx0XHRcdFx0XHRcdG1hdGhSb3VuZChpbnZlcnRlZCA/IHJpZ2h0IDogYm90dG9tKSArICdweCwnICtcblx0XHRcdFx0XHRcdFx0bWF0aFJvdW5kKGludmVydGVkID8gdG9wIDogbGVmdCkgKyAncHgpJ1xuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0Ly8gaXNzdWUgNzQgd29ya2Fyb3VuZFxuXHRcdFx0XHRpZiAoIWludmVydGVkICYmIGRvY01vZGU4ICYmIG5vZGVOYW1lID09PSAnRElWJykge1xuXHRcdFx0XHRcdGV4dGVuZChyZXQsIHtcblx0XHRcdFx0XHRcdHdpZHRoOiByaWdodCArIFBYLFxuXHRcdFx0XHRcdFx0aGVpZ2h0OiBib3R0b20gKyBQWFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyB1c2VkIGluIGF0dHIgYW5kIGFuaW1hdGlvbiB0byB1cGRhdGUgdGhlIGNsaXBwaW5nIG9mIGFsbCBtZW1iZXJzXG5cdFx0XHR1cGRhdGVDbGlwcGluZzogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRlYWNoKGNsaXBSZWN0Lm1lbWJlcnMsIGZ1bmN0aW9uIChtZW1iZXIpIHtcblx0XHRcdFx0XHRpZiAobWVtYmVyLmVsZW1lbnQpIHsgLy8gRGVsZXRlZCBzZXJpZXMsIGxpa2UgaW4gc3RvY2svbWVtYmVycy9zZXJpZXMtcmVtb3ZlIGRlbW8uIFNob3VsZCBiZSByZW1vdmVkIGZyb20gbWVtYmVycywgYnV0IHRoaXMgd2lsbCBkby5cblx0XHRcdFx0XHRcdG1lbWJlci5jc3MoY2xpcFJlY3QuZ2V0Q1NTKG1lbWJlcikpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0fSxcblxuXG5cdC8qKlxuXHQgKiBUYWtlIGEgY29sb3IgYW5kIHJldHVybiBpdCBpZiBpdCdzIGEgc3RyaW5nLCBtYWtlIGl0IGEgZ3JhZGllbnQgaWYgaXQncyBhXG5cdCAqIGdyYWRpZW50IGNvbmZpZ3VyYXRpb24gb2JqZWN0LCBhbmQgYXBwbHkgb3BhY2l0eS5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IGNvbG9yIFRoZSBjb2xvciBvciBjb25maWcgb2JqZWN0XG5cdCAqL1xuXHRjb2xvcjogZnVuY3Rpb24gKGNvbG9yLCBlbGVtLCBwcm9wLCB3cmFwcGVyKSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcyxcblx0XHRcdGNvbG9yT2JqZWN0LFxuXHRcdFx0cmVnZXhSZ2JhID0gL15yZ2JhLyxcblx0XHRcdG1hcmt1cCxcblx0XHRcdGZpbGxUeXBlLFxuXHRcdFx0cmV0ID0gTk9ORTtcblxuXHRcdC8vIENoZWNrIGZvciBsaW5lYXIgb3IgcmFkaWFsIGdyYWRpZW50XG5cdFx0aWYgKGNvbG9yICYmIGNvbG9yLmxpbmVhckdyYWRpZW50KSB7XG5cdFx0XHRmaWxsVHlwZSA9ICdncmFkaWVudCc7XG5cdFx0fSBlbHNlIGlmIChjb2xvciAmJiBjb2xvci5yYWRpYWxHcmFkaWVudCkge1xuXHRcdFx0ZmlsbFR5cGUgPSAncGF0dGVybic7XG5cdFx0fVxuXG5cblx0XHRpZiAoZmlsbFR5cGUpIHtcblxuXHRcdFx0dmFyIHN0b3BDb2xvcixcblx0XHRcdFx0c3RvcE9wYWNpdHksXG5cdFx0XHRcdGdyYWRpZW50ID0gY29sb3IubGluZWFyR3JhZGllbnQgfHwgY29sb3IucmFkaWFsR3JhZGllbnQsXG5cdFx0XHRcdHgxLFxuXHRcdFx0XHR5MSxcblx0XHRcdFx0eDIsXG5cdFx0XHRcdHkyLFxuXHRcdFx0XHRvcGFjaXR5MSxcblx0XHRcdFx0b3BhY2l0eTIsXG5cdFx0XHRcdGNvbG9yMSxcblx0XHRcdFx0Y29sb3IyLFxuXHRcdFx0XHRmaWxsQXR0ciA9ICcnLFxuXHRcdFx0XHRzdG9wcyA9IGNvbG9yLnN0b3BzLFxuXHRcdFx0XHRmaXJzdFN0b3AsXG5cdFx0XHRcdGxhc3RTdG9wLFxuXHRcdFx0XHRjb2xvcnMgPSBbXSxcblx0XHRcdFx0YWRkRmlsbE5vZGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0Ly8gQWRkIHRoZSBmaWxsIHN1Ym5vZGUuIFdoZW4gY29sb3JzIGF0dHJpYnV0ZSBpcyB1c2VkLCB0aGUgbWVhbmluZ3Mgb2Ygb3BhY2l0eSBhbmQgbzpvcGFjaXR5MlxuXHRcdFx0XHRcdC8vIGFyZSByZXZlcnNlZC5cblx0XHRcdFx0XHRtYXJrdXAgPSBbJzxmaWxsIGNvbG9ycz1cIicgKyBjb2xvcnMuam9pbignLCcpICsgJ1wiIG9wYWNpdHk9XCInLCBvcGFjaXR5MiwgJ1wiIG86b3BhY2l0eTI9XCInLCBvcGFjaXR5MSxcblx0XHRcdFx0XHRcdCdcIiB0eXBlPVwiJywgZmlsbFR5cGUsICdcIiAnLCBmaWxsQXR0ciwgJ2ZvY3VzPVwiMTAwJVwiIG1ldGhvZD1cImFueVwiIC8+J107XG5cdFx0XHRcdFx0Y3JlYXRlRWxlbWVudChyZW5kZXJlci5wcmVwVk1MKG1hcmt1cCksIG51bGwsIG51bGwsIGVsZW0pO1xuXHRcdFx0XHR9O1xuXG5cdFx0XHQvLyBFeHRlbmQgZnJvbSAwIHRvIDFcblx0XHRcdGZpcnN0U3RvcCA9IHN0b3BzWzBdO1xuXHRcdFx0bGFzdFN0b3AgPSBzdG9wc1tzdG9wcy5sZW5ndGggLSAxXTtcblx0XHRcdGlmIChmaXJzdFN0b3BbMF0gPiAwKSB7XG5cdFx0XHRcdHN0b3BzLnVuc2hpZnQoW1xuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0Zmlyc3RTdG9wWzFdXG5cdFx0XHRcdF0pO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGxhc3RTdG9wWzBdIDwgMSkge1xuXHRcdFx0XHRzdG9wcy5wdXNoKFtcblx0XHRcdFx0XHQxLFxuXHRcdFx0XHRcdGxhc3RTdG9wWzFdXG5cdFx0XHRcdF0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb21wdXRlIHRoZSBzdG9wc1xuXHRcdFx0ZWFjaChzdG9wcywgZnVuY3Rpb24gKHN0b3AsIGkpIHtcblx0XHRcdFx0aWYgKHJlZ2V4UmdiYS50ZXN0KHN0b3BbMV0pKSB7XG5cdFx0XHRcdFx0Y29sb3JPYmplY3QgPSBDb2xvcihzdG9wWzFdKTtcblx0XHRcdFx0XHRzdG9wQ29sb3IgPSBjb2xvck9iamVjdC5nZXQoJ3JnYicpO1xuXHRcdFx0XHRcdHN0b3BPcGFjaXR5ID0gY29sb3JPYmplY3QuZ2V0KCdhJyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3RvcENvbG9yID0gc3RvcFsxXTtcblx0XHRcdFx0XHRzdG9wT3BhY2l0eSA9IDE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBCdWlsZCB0aGUgY29sb3IgYXR0cmlidXRlXG5cdFx0XHRcdGNvbG9ycy5wdXNoKChzdG9wWzBdICogMTAwKSArICclICcgKyBzdG9wQ29sb3IpO1xuXG5cdFx0XHRcdC8vIE9ubHkgc3RhcnQgYW5kIGVuZCBvcGFjaXRpZXMgYXJlIGFsbG93ZWQsIHNvIHdlIHVzZSB0aGUgZmlyc3QgYW5kIHRoZSBsYXN0XG5cdFx0XHRcdGlmICghaSkge1xuXHRcdFx0XHRcdG9wYWNpdHkxID0gc3RvcE9wYWNpdHk7XG5cdFx0XHRcdFx0Y29sb3IyID0gc3RvcENvbG9yO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG9wYWNpdHkyID0gc3RvcE9wYWNpdHk7XG5cdFx0XHRcdFx0Y29sb3IxID0gc3RvcENvbG9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gQXBwbHkgdGhlIGdyYWRpZW50IHRvIGZpbGxzIG9ubHkuXG5cdFx0XHRpZiAocHJvcCA9PT0gJ2ZpbGwnKSB7XG5cblx0XHRcdFx0Ly8gSGFuZGxlIGxpbmVhciBncmFkaWVudCBhbmdsZVxuXHRcdFx0XHRpZiAoZmlsbFR5cGUgPT09ICdncmFkaWVudCcpIHtcblx0XHRcdFx0XHR4MSA9IGdyYWRpZW50LngxIHx8IGdyYWRpZW50WzBdIHx8IDA7XG5cdFx0XHRcdFx0eTEgPSBncmFkaWVudC55MSB8fCBncmFkaWVudFsxXSB8fCAwO1xuXHRcdFx0XHRcdHgyID0gZ3JhZGllbnQueDIgfHwgZ3JhZGllbnRbMl0gfHwgMDtcblx0XHRcdFx0XHR5MiA9IGdyYWRpZW50LnkyIHx8IGdyYWRpZW50WzNdIHx8IDA7XG5cdFx0XHRcdFx0ZmlsbEF0dHIgPSAnYW5nbGU9XCInICsgKDkwICAtIG1hdGguYXRhbihcblx0XHRcdFx0XHRcdCh5MiAtIHkxKSAvIC8vIHkgdmVjdG9yXG5cdFx0XHRcdFx0XHQoeDIgLSB4MSkgLy8geCB2ZWN0b3Jcblx0XHRcdFx0XHRcdCkgKiAxODAgLyBtYXRoUEkpICsgJ1wiJztcblxuXHRcdFx0XHRcdGFkZEZpbGxOb2RlKCk7XG5cblx0XHRcdFx0Ly8gUmFkaWFsIChjaXJjdWxhcikgZ3JhZGllbnRcblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdHZhciByID0gZ3JhZGllbnQucixcblx0XHRcdFx0XHRcdHNpemV4ID0gciAqIDIsXG5cdFx0XHRcdFx0XHRzaXpleSA9IHIgKiAyLFxuXHRcdFx0XHRcdFx0Y3ggPSBncmFkaWVudC5jeCxcblx0XHRcdFx0XHRcdGN5ID0gZ3JhZGllbnQuY3ksXG5cdFx0XHRcdFx0XHRyYWRpYWxSZWZlcmVuY2UgPSBlbGVtLnJhZGlhbFJlZmVyZW5jZSxcblx0XHRcdFx0XHRcdGJCb3gsXG5cdFx0XHRcdFx0XHRhcHBseVJhZGlhbEdyYWRpZW50ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0XHRpZiAocmFkaWFsUmVmZXJlbmNlKSB7XG5cdFx0XHRcdFx0XHRcdFx0YkJveCA9IHdyYXBwZXIuZ2V0QkJveCgpO1xuXHRcdFx0XHRcdFx0XHRcdGN4ICs9IChyYWRpYWxSZWZlcmVuY2VbMF0gLSBiQm94LngpIC8gYkJveC53aWR0aCAtIDAuNTtcblx0XHRcdFx0XHRcdFx0XHRjeSArPSAocmFkaWFsUmVmZXJlbmNlWzFdIC0gYkJveC55KSAvIGJCb3guaGVpZ2h0IC0gMC41O1xuXHRcdFx0XHRcdFx0XHRcdHNpemV4ICo9IHJhZGlhbFJlZmVyZW5jZVsyXSAvIGJCb3gud2lkdGg7XG5cdFx0XHRcdFx0XHRcdFx0c2l6ZXkgKj0gcmFkaWFsUmVmZXJlbmNlWzJdIC8gYkJveC5oZWlnaHQ7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0ZmlsbEF0dHIgPSAnc3JjPVwiJyArIGRlZmF1bHRPcHRpb25zLmdsb2JhbC5WTUxSYWRpYWxHcmFkaWVudFVSTCArICdcIiAnICtcblx0XHRcdFx0XHRcdFx0XHQnc2l6ZT1cIicgKyBzaXpleCArICcsJyArIHNpemV5ICsgJ1wiICcgK1xuXHRcdFx0XHRcdFx0XHRcdCdvcmlnaW49XCIwLjUsMC41XCIgJyArXG5cdFx0XHRcdFx0XHRcdFx0J3Bvc2l0aW9uPVwiJyArIGN4ICsgJywnICsgY3kgKyAnXCIgJyArXG5cdFx0XHRcdFx0XHRcdFx0J2NvbG9yMj1cIicgKyBjb2xvcjIgKyAnXCIgJztcblxuXHRcdFx0XHRcdFx0XHRhZGRGaWxsTm9kZSgpO1xuXHRcdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdC8vIEFwcGx5IHJhZGlhbCBncmFkaWVudFxuXHRcdFx0XHRcdGlmICh3cmFwcGVyLmFkZGVkKSB7XG5cdFx0XHRcdFx0XHRhcHBseVJhZGlhbEdyYWRpZW50KCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIFdlIG5lZWQgdG8ga25vdyB0aGUgYm91bmRpbmcgYm94IHRvIGdldCB0aGUgc2l6ZSBhbmQgcG9zaXRpb24gcmlnaHRcblx0XHRcdFx0XHRcdHdyYXBwZXIub25BZGQgPSBhcHBseVJhZGlhbEdyYWRpZW50O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFRoZSBmaWxsIGVsZW1lbnQncyBjb2xvciBhdHRyaWJ1dGUgaXMgYnJva2VuIGluIElFOCBzdGFuZGFyZHMgbW9kZSwgc28gd2Vcblx0XHRcdFx0XHQvLyBuZWVkIHRvIHNldCB0aGUgcGFyZW50IHNoYXBlJ3MgZmlsbGNvbG9yIGF0dHJpYnV0ZSBpbnN0ZWFkLlxuXHRcdFx0XHRcdHJldCA9IGNvbG9yMTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBHcmFkaWVudHMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIFZNTCBzdHJva2UsIHJldHVybiB0aGUgZmlyc3QgY29sb3IuICM3MjIuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXQgPSBzdG9wQ29sb3I7XG5cdFx0XHR9XG5cblx0XHQvLyBpZiB0aGUgY29sb3IgaXMgYW4gcmdiYSBjb2xvciwgc3BsaXQgaXQgYW5kIGFkZCBhIGZpbGwgbm9kZVxuXHRcdC8vIHRvIGhvbGQgdGhlIG9wYWNpdHkgY29tcG9uZW50XG5cdFx0fSBlbHNlIGlmIChyZWdleFJnYmEudGVzdChjb2xvcikgJiYgZWxlbS50YWdOYW1lICE9PSAnSU1HJykge1xuXG5cdFx0XHRjb2xvck9iamVjdCA9IENvbG9yKGNvbG9yKTtcblxuXHRcdFx0bWFya3VwID0gWyc8JywgcHJvcCwgJyBvcGFjaXR5PVwiJywgY29sb3JPYmplY3QuZ2V0KCdhJyksICdcIi8+J107XG5cdFx0XHRjcmVhdGVFbGVtZW50KHRoaXMucHJlcFZNTChtYXJrdXApLCBudWxsLCBudWxsLCBlbGVtKTtcblxuXHRcdFx0cmV0ID0gY29sb3JPYmplY3QuZ2V0KCdyZ2InKTtcblxuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciBwcm9wTm9kZXMgPSBlbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lKHByb3ApOyAvLyAnc3Ryb2tlJyBvciAnZmlsbCcgbm9kZVxuXHRcdFx0aWYgKHByb3BOb2Rlcy5sZW5ndGgpIHtcblx0XHRcdFx0cHJvcE5vZGVzWzBdLm9wYWNpdHkgPSAxO1xuXHRcdFx0XHRwcm9wTm9kZXNbMF0udHlwZSA9ICdzb2xpZCc7XG5cdFx0XHR9XG5cdFx0XHRyZXQgPSBjb2xvcjtcblx0XHR9XG5cblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBUYWtlIGEgVk1MIHN0cmluZyBhbmQgcHJlcGFyZSBpdCBmb3IgZWl0aGVyIElFOCBvciBJRTYvSUU3LlxuXHQgKiBAcGFyYW0ge0FycmF5fSBtYXJrdXAgQSBzdHJpbmcgYXJyYXkgb2YgdGhlIFZNTCBtYXJrdXAgdG8gcHJlcGFyZVxuXHQgKi9cblx0cHJlcFZNTDogZnVuY3Rpb24gKG1hcmt1cCkge1xuXHRcdHZhciB2bWxTdHlsZSA9ICdkaXNwbGF5OmlubGluZS1ibG9jaztiZWhhdmlvcjp1cmwoI2RlZmF1bHQjVk1MKTsnLFxuXHRcdFx0aXNJRTggPSB0aGlzLmlzSUU4O1xuXG5cdFx0bWFya3VwID0gbWFya3VwLmpvaW4oJycpO1xuXG5cdFx0aWYgKGlzSUU4KSB7IC8vIGFkZCB4bWxucyBhbmQgc3R5bGUgaW5saW5lXG5cdFx0XHRtYXJrdXAgPSBtYXJrdXAucmVwbGFjZSgnLz4nLCAnIHhtbG5zPVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWxcIiAvPicpO1xuXHRcdFx0aWYgKG1hcmt1cC5pbmRleE9mKCdzdHlsZT1cIicpID09PSAtMSkge1xuXHRcdFx0XHRtYXJrdXAgPSBtYXJrdXAucmVwbGFjZSgnLz4nLCAnIHN0eWxlPVwiJyArIHZtbFN0eWxlICsgJ1wiIC8+Jyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtYXJrdXAgPSBtYXJrdXAucmVwbGFjZSgnc3R5bGU9XCInLCAnc3R5bGU9XCInICsgdm1sU3R5bGUpO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHsgLy8gYWRkIG5hbWVzcGFjZVxuXHRcdFx0bWFya3VwID0gbWFya3VwLnJlcGxhY2UoJzwnLCAnPGhjdjonKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWFya3VwO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgcm90YXRlZCBhbmQgYWxpZ25lZCB0ZXh0XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICovXG5cdHRleHQ6IFNWR1JlbmRlcmVyLnByb3RvdHlwZS5odG1sLFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYW5kIHJldHVybiBhIHBhdGggZWxlbWVudFxuXHQgKiBAcGFyYW0ge0FycmF5fSBwYXRoXG5cdCAqL1xuXHRwYXRoOiBmdW5jdGlvbiAocGF0aCkge1xuXHRcdHZhciBhdHRyID0ge1xuXHRcdFx0Ly8gc3VicGl4ZWwgcHJlY2lzaW9uIGRvd24gdG8gMC4xICh3aWR0aCBhbmQgaGVpZ2h0ID0gMXB4KVxuXHRcdFx0Y29vcmRzaXplOiAnMTAgMTAnXG5cdFx0fTtcblx0XHRpZiAoaXNBcnJheShwYXRoKSkge1xuXHRcdFx0YXR0ci5kID0gcGF0aDtcblx0XHR9IGVsc2UgaWYgKGlzT2JqZWN0KHBhdGgpKSB7IC8vIGF0dHJpYnV0ZXNcblx0XHRcdGV4dGVuZChhdHRyLCBwYXRoKTtcblx0XHR9XG5cdFx0Ly8gY3JlYXRlIHRoZSBzaGFwZVxuXHRcdHJldHVybiB0aGlzLmNyZWF0ZUVsZW1lbnQoJ3NoYXBlJykuYXR0cihhdHRyKTtcblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIGFuZCByZXR1cm4gYSBjaXJjbGUgZWxlbWVudC4gSW4gVk1MIGNpcmNsZXMgYXJlIGltcGxlbWVudGVkIGFzXG5cdCAqIHNoYXBlcywgd2hpY2ggaXMgZmFzdGVyIHRoYW4gdjpvdmFsXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSByXG5cdCAqL1xuXHRjaXJjbGU6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG5cdFx0dmFyIGNpcmNsZSA9IHRoaXMuc3ltYm9sKCdjaXJjbGUnKTtcblx0XHRpZiAoaXNPYmplY3QoeCkpIHtcblx0XHRcdHIgPSB4LnI7XG5cdFx0XHR5ID0geC55O1xuXHRcdFx0eCA9IHgueDtcblx0XHR9XG5cdFx0Y2lyY2xlLmlzQ2lyY2xlID0gdHJ1ZTsgLy8gQ2F1c2VzIHggYW5kIHkgdG8gbWVhbiBjZW50ZXIgKCMxNjgyKVxuXHRcdGNpcmNsZS5yID0gcjtcblx0XHRyZXR1cm4gY2lyY2xlLmF0dHIoeyB4OiB4LCB5OiB5IH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYSBncm91cCB1c2luZyBhbiBvdXRlciBkaXYgYW5kIGFuIGlubmVyIHY6Z3JvdXAgdG8gYWxsb3cgcm90YXRpbmdcblx0ICogYW5kIGZsaXBwaW5nLiBBIHNpbXBsZSB2Omdyb3VwIHdvdWxkIGhhdmUgcHJvYmxlbXMgd2l0aCBwb3NpdGlvbmluZ1xuXHQgKiBjaGlsZCBIVE1MIGVsZW1lbnRzIGFuZCBDU1MgY2xpcC5cblx0ICpcblx0ICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIGdyb3VwXG5cdCAqL1xuXHRnOiBmdW5jdGlvbiAobmFtZSkge1xuXHRcdHZhciB3cmFwcGVyLFxuXHRcdFx0YXR0cmlicztcblxuXHRcdC8vIHNldCB0aGUgY2xhc3MgbmFtZVxuXHRcdGlmIChuYW1lKSB7XG5cdFx0XHRhdHRyaWJzID0geyAnY2xhc3NOYW1lJzogUFJFRklYICsgbmFtZSwgJ2NsYXNzJzogUFJFRklYICsgbmFtZSB9O1xuXHRcdH1cblxuXHRcdC8vIHRoZSBkaXYgdG8gaG9sZCBIVE1MIGFuZCBjbGlwcGluZ1xuXHRcdHdyYXBwZXIgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoRElWKS5hdHRyKGF0dHJpYnMpO1xuXG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFZNTCBvdmVycmlkZSB0byBjcmVhdGUgYSByZWd1bGFyIEhUTUwgaW1hZ2Vcblx0ICogQHBhcmFtIHtTdHJpbmd9IHNyY1xuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKi9cblx0aW1hZ2U6IGZ1bmN0aW9uIChzcmMsIHgsIHksIHdpZHRoLCBoZWlnaHQpIHtcblx0XHR2YXIgb2JqID0gdGhpcy5jcmVhdGVFbGVtZW50KCdpbWcnKVxuXHRcdFx0LmF0dHIoeyBzcmM6IHNyYyB9KTtcblxuXHRcdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdFx0b2JqLmF0dHIoe1xuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogd2lkdGgsXG5cdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvKipcblx0ICogRm9yIHJlY3RhbmdsZXMsIFZNTCB1c2VzIGEgc2hhcGUgZm9yIHJlY3QgdG8gb3ZlcmNvbWUgYnVncyBhbmQgcm90YXRpb24gcHJvYmxlbXNcblx0ICovXG5cdGNyZWF0ZUVsZW1lbnQ6IGZ1bmN0aW9uIChub2RlTmFtZSkge1xuXHRcdHJldHVybiBub2RlTmFtZSA9PT0gJ3JlY3QnID8gdGhpcy5zeW1ib2wobm9kZU5hbWUpIDogU1ZHUmVuZGVyZXIucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBub2RlTmFtZSk7XHRcblx0fSxcblxuXHQvKipcblx0ICogSW4gdGhlIFZNTCByZW5kZXJlciwgZWFjaCBjaGlsZCBvZiBhbiBpbnZlcnRlZCBkaXYgKGdyb3VwKSBpcyBpbnZlcnRlZFxuXHQgKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudFxuXHQgKiBAcGFyYW0ge09iamVjdH0gcGFyZW50Tm9kZVxuXHQgKi9cblx0aW52ZXJ0Q2hpbGQ6IGZ1bmN0aW9uIChlbGVtZW50LCBwYXJlbnROb2RlKSB7XG5cdFx0dmFyIHJlbiA9IHRoaXMsXG5cdFx0XHRwYXJlbnRTdHlsZSA9IHBhcmVudE5vZGUuc3R5bGUsXG5cdFx0XHRpbWdTdHlsZSA9IGVsZW1lbnQudGFnTmFtZSA9PT0gJ0lNRycgJiYgZWxlbWVudC5zdHlsZTsgLy8gIzExMTFcblxuXHRcdGNzcyhlbGVtZW50LCB7XG5cdFx0XHRmbGlwOiAneCcsXG5cdFx0XHRsZWZ0OiBwSW50KHBhcmVudFN0eWxlLndpZHRoKSAtIChpbWdTdHlsZSA/IHBJbnQoaW1nU3R5bGUudG9wKSA6IDEpLFxuXHRcdFx0dG9wOiBwSW50KHBhcmVudFN0eWxlLmhlaWdodCkgLSAoaW1nU3R5bGUgPyBwSW50KGltZ1N0eWxlLmxlZnQpIDogMSksXG5cdFx0XHRyb3RhdGlvbjogLTkwXG5cdFx0fSk7XG5cblx0XHQvLyBSZWN1cnNpdmVseSBpbnZlcnQgY2hpbGQgZWxlbWVudHMsIG5lZWRlZCBmb3IgbmVzdGVkIGNvbXBvc2l0ZSBzaGFwZXMgbGlrZSBib3ggcGxvdHMgYW5kIGVycm9yIGJhcnMuICMxNjgwLCAjMTgwNi5cblx0XHRlYWNoKGVsZW1lbnQuY2hpbGROb2RlcywgZnVuY3Rpb24gKGNoaWxkKSB7XG5cdFx0XHRyZW4uaW52ZXJ0Q2hpbGQoY2hpbGQsIGVsZW1lbnQpO1xuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTeW1ib2wgZGVmaW5pdGlvbnMgdGhhdCBvdmVycmlkZSB0aGUgcGFyZW50IFNWRyByZW5kZXJlcidzIHN5bWJvbHNcblx0ICpcblx0ICovXG5cdHN5bWJvbHM6IHtcblx0XHQvLyBWTUwgc3BlY2lmaWMgYXJjIGZ1bmN0aW9uXG5cdFx0YXJjOiBmdW5jdGlvbiAoeCwgeSwgdywgaCwgb3B0aW9ucykge1xuXHRcdFx0dmFyIHN0YXJ0ID0gb3B0aW9ucy5zdGFydCxcblx0XHRcdFx0ZW5kID0gb3B0aW9ucy5lbmQsXG5cdFx0XHRcdHJhZGl1cyA9IG9wdGlvbnMuciB8fCB3IHx8IGgsXG5cdFx0XHRcdGlubmVyUmFkaXVzID0gb3B0aW9ucy5pbm5lclIsXG5cdFx0XHRcdGNvc1N0YXJ0ID0gbWF0aENvcyhzdGFydCksXG5cdFx0XHRcdHNpblN0YXJ0ID0gbWF0aFNpbihzdGFydCksXG5cdFx0XHRcdGNvc0VuZCA9IG1hdGhDb3MoZW5kKSxcblx0XHRcdFx0c2luRW5kID0gbWF0aFNpbihlbmQpLFxuXHRcdFx0XHRyZXQ7XG5cblx0XHRcdGlmIChlbmQgLSBzdGFydCA9PT0gMCkgeyAvLyBubyBhbmdsZSwgZG9uJ3Qgc2hvdyBpdC5cblx0XHRcdFx0cmV0dXJuIFsneCddO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXQgPSBbXG5cdFx0XHRcdCd3YScsIC8vIGNsb2Nrd2lzZSBhcmMgdG9cblx0XHRcdFx0eCAtIHJhZGl1cywgLy8gbGVmdFxuXHRcdFx0XHR5IC0gcmFkaXVzLCAvLyB0b3Bcblx0XHRcdFx0eCArIHJhZGl1cywgLy8gcmlnaHRcblx0XHRcdFx0eSArIHJhZGl1cywgLy8gYm90dG9tXG5cdFx0XHRcdHggKyByYWRpdXMgKiBjb3NTdGFydCwgLy8gc3RhcnQgeFxuXHRcdFx0XHR5ICsgcmFkaXVzICogc2luU3RhcnQsIC8vIHN0YXJ0IHlcblx0XHRcdFx0eCArIHJhZGl1cyAqIGNvc0VuZCwgLy8gZW5kIHhcblx0XHRcdFx0eSArIHJhZGl1cyAqIHNpbkVuZCAgLy8gZW5kIHlcblx0XHRcdF07XG5cblx0XHRcdGlmIChvcHRpb25zLm9wZW4gJiYgIWlubmVyUmFkaXVzKSB7XG5cdFx0XHRcdHJldC5wdXNoKFxuXHRcdFx0XHRcdCdlJyxcblx0XHRcdFx0XHRNLFxuXHRcdFx0XHRcdHgsLy8gLSBpbm5lclJhZGl1cyxcblx0XHRcdFx0XHR5Ly8gLSBpbm5lclJhZGl1c1xuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXQucHVzaChcblx0XHRcdFx0J2F0JywgLy8gYW50aSBjbG9ja3dpc2UgYXJjIHRvXG5cdFx0XHRcdHggLSBpbm5lclJhZGl1cywgLy8gbGVmdFxuXHRcdFx0XHR5IC0gaW5uZXJSYWRpdXMsIC8vIHRvcFxuXHRcdFx0XHR4ICsgaW5uZXJSYWRpdXMsIC8vIHJpZ2h0XG5cdFx0XHRcdHkgKyBpbm5lclJhZGl1cywgLy8gYm90dG9tXG5cdFx0XHRcdHggKyBpbm5lclJhZGl1cyAqIGNvc0VuZCwgLy8gc3RhcnQgeFxuXHRcdFx0XHR5ICsgaW5uZXJSYWRpdXMgKiBzaW5FbmQsIC8vIHN0YXJ0IHlcblx0XHRcdFx0eCArIGlubmVyUmFkaXVzICogY29zU3RhcnQsIC8vIGVuZCB4XG5cdFx0XHRcdHkgKyBpbm5lclJhZGl1cyAqIHNpblN0YXJ0LCAvLyBlbmQgeVxuXHRcdFx0XHQneCcsIC8vIGZpbmlzaCBwYXRoXG5cdFx0XHRcdCdlJyAvLyBjbG9zZVxuXHRcdFx0KTtcblxuXHRcdFx0cmV0LmlzQXJjID0gdHJ1ZTtcblx0XHRcdHJldHVybiByZXQ7XG5cblx0XHR9LFxuXHRcdC8vIEFkZCBjaXJjbGUgc3ltYm9sIHBhdGguIFRoaXMgcGVyZm9ybXMgc2lnbmlmaWNhbnRseSBmYXN0ZXIgdGhhbiB2Om92YWwuXG5cdFx0Y2lyY2xlOiBmdW5jdGlvbiAoeCwgeSwgdywgaCwgd3JhcHBlcikge1xuXG5cdFx0XHRpZiAod3JhcHBlcikge1xuXHRcdFx0XHR3ID0gaCA9IDIgKiB3cmFwcGVyLnI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENlbnRlciBjb3JyZWN0aW9uLCAjMTY4MlxuXHRcdFx0aWYgKHdyYXBwZXIgJiYgd3JhcHBlci5pc0NpcmNsZSkge1xuXHRcdFx0XHR4IC09IHcgLyAyO1xuXHRcdFx0XHR5IC09IGggLyAyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXR1cm4gdGhlIHBhdGhcblx0XHRcdHJldHVybiBbXG5cdFx0XHRcdCd3YScsIC8vIGNsb2Nrd2lzZWFyY3RvXG5cdFx0XHRcdHgsIC8vIGxlZnRcblx0XHRcdFx0eSwgLy8gdG9wXG5cdFx0XHRcdHggKyB3LCAvLyByaWdodFxuXHRcdFx0XHR5ICsgaCwgLy8gYm90dG9tXG5cdFx0XHRcdHggKyB3LCAvLyBzdGFydCB4XG5cdFx0XHRcdHkgKyBoIC8gMiwgICAgIC8vIHN0YXJ0IHlcblx0XHRcdFx0eCArIHcsIC8vIGVuZCB4XG5cdFx0XHRcdHkgKyBoIC8gMiwgICAgIC8vIGVuZCB5XG5cdFx0XHRcdC8vJ3gnLCAvLyBmaW5pc2ggcGF0aFxuXHRcdFx0XHQnZScgLy8gY2xvc2Vcblx0XHRcdF07XG5cdFx0fSxcblx0XHQvKipcblx0XHQgKiBBZGQgcmVjdGFuZ2xlIHN5bWJvbCBwYXRoIHdoaWNoIGVhc2VzIHJvdGF0aW9uIGFuZCBvbWl0cyBhcmNzaXplIHByb2JsZW1zXG5cdFx0ICogY29tcGFyZWQgdG8gdGhlIGJ1aWx0LWluIFZNTCByb3VuZHJlY3Qgc2hhcGUuIFdoZW4gYm9yZGVycyBhcmUgbm90IHJvdW5kZWQsXG5cdFx0ICogdXNlIHRoZSBzaW1wbGVyIHNxdWFyZSBwYXRoLCBlbHNlIHVzZSB0aGUgY2FsbG91dCBwYXRoIHdpdGhvdXQgdGhlIGFycm93LlxuXHRcdCAqL1xuXHRcdHJlY3Q6IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCBvcHRpb25zKSB7XG5cdFx0XHRyZXR1cm4gU1ZHUmVuZGVyZXIucHJvdG90eXBlLnN5bWJvbHNbXG5cdFx0XHRcdCFkZWZpbmVkKG9wdGlvbnMpIHx8ICFvcHRpb25zLnIgPyAnc3F1YXJlJyA6ICdjYWxsb3V0J1xuXHRcdFx0XS5jYWxsKDAsIHgsIHksIHcsIGgsIG9wdGlvbnMpO1xuXHRcdH1cblx0fVxufTtcbkhpZ2hjaGFydHMuVk1MUmVuZGVyZXIgPSBWTUxSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcblx0dGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuVk1MUmVuZGVyZXIucHJvdG90eXBlID0gbWVyZ2UoU1ZHUmVuZGVyZXIucHJvdG90eXBlLCBWTUxSZW5kZXJlckV4dGVuc2lvbik7XG5cblx0Ly8gZ2VuZXJhbCByZW5kZXJlclxuXHRSZW5kZXJlciA9IFZNTFJlbmRlcmVyO1xufVxuXG4vLyBUaGlzIG1ldGhvZCBpcyB1c2VkIHdpdGggZXhwb3J0aW5nIGluIG9sZCBJRSwgd2hlbiBlbXVsYXRpbmcgU1ZHIChzZWUgIzIzMTQpXG5TVkdSZW5kZXJlci5wcm90b3R5cGUubWVhc3VyZVNwYW5XaWR0aCA9IGZ1bmN0aW9uICh0ZXh0LCBzdHlsZXMpIHtcblx0dmFyIG1lYXN1cmluZ1NwYW4gPSBkb2MuY3JlYXRlRWxlbWVudCgnc3BhbicpLFxuXHRcdG9mZnNldFdpZHRoLFxuXHR0ZXh0Tm9kZSA9IGRvYy5jcmVhdGVUZXh0Tm9kZSh0ZXh0KTtcblxuXHRtZWFzdXJpbmdTcGFuLmFwcGVuZENoaWxkKHRleHROb2RlKTtcblx0Y3NzKG1lYXN1cmluZ1NwYW4sIHN0eWxlcyk7XG5cdHRoaXMuYm94LmFwcGVuZENoaWxkKG1lYXN1cmluZ1NwYW4pO1xuXHRvZmZzZXRXaWR0aCA9IG1lYXN1cmluZ1NwYW4ub2Zmc2V0V2lkdGg7XG5cdGRpc2NhcmRFbGVtZW50KG1lYXN1cmluZ1NwYW4pOyAvLyAjMjQ2M1xuXHRyZXR1cm4gb2Zmc2V0V2lkdGg7XG59O1xuXG5cbi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIEVORCBPRiBJTlRFUk5FVCBFWFBMT1JFUiA8PSA4IFNQRUNJRklDIENPREUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIFNUQVJUIE9GIEFORFJPSUQgPCAzIFNQRUNJRklDIENPREUuIFRISVMgQ0FOIEJFIFJFTU9WRUQgSUYgWU9VJ1JFIE5PVCAgICAgICpcbiAqIFRBUkdFVElORyBUSEFUIFNZU1RFTS4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhciBDYW5WR1JlbmRlcmVyLFxuXHRDYW5WR0NvbnRyb2xsZXI7XG5cbmlmICh1c2VDYW5WRykge1xuXHQvKipcblx0ICogVGhlIENhblZHUmVuZGVyZXIgaXMgZW1wdHkgZnJvbSBzdGFydCB0byBrZWVwIHRoZSBzb3VyY2UgZm9vdHByaW50IHNtYWxsLlxuXHQgKiBXaGVuIHJlcXVlc3RlZCwgdGhlIENhblZHQ29udHJvbGxlciBkb3dubG9hZHMgdGhlIHJlc3Qgb2YgdGhlIHNvdXJjZSBwYWNrYWdlZFxuXHQgKiB0b2dldGhlciB3aXRoIHRoZSBjYW52ZyBsaWJyYXJ5LlxuXHQgKi9cblx0SGlnaGNoYXJ0cy5DYW5WR1JlbmRlcmVyID0gQ2FuVkdSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcblx0XHQvLyBPdmVycmlkZSB0aGUgZ2xvYmFsIFNWRyBuYW1lc3BhY2UgdG8gZmFrZSBTVkcvSFRNTCB0aGF0IGFjY2VwdHMgQ1NTXG5cdFx0U1ZHX05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWwnO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBTdGFydCB3aXRoIGFuIGVtcHR5IHN5bWJvbHMgb2JqZWN0LiBUaGlzIGlzIG5lZWRlZCB3aGVuIGV4cG9ydGluZyBpcyB1c2VkIChleHBvcnRpbmcuc3JjLmpzIHdpbGwgYWRkIGEgZmV3IHN5bWJvbHMpLCBidXQgXG5cdCAqIHRoZSBpbXBsZW1lbnRhdGlvbiBmcm9tIFN2Z1JlbmRlcmVyIHdpbGwgbm90IGJlIG1lcmdlZCBpbiB1bnRpbCBmaXJzdCByZW5kZXIuXG5cdCAqL1xuXHRDYW5WR1JlbmRlcmVyLnByb3RvdHlwZS5zeW1ib2xzID0ge307XG5cblx0LyoqXG5cdCAqIEhhbmRsZXMgb24gZGVtYW5kIGRvd25sb2FkIG9mIGNhbnZnIHJlbmRlcmluZyBzdXBwb3J0LlxuXHQgKi9cblx0Q2FuVkdDb250cm9sbGVyID0gKGZ1bmN0aW9uICgpIHtcblx0XHQvLyBMaXN0IG9mIHJlbmRlcmVyaW5nIGNhbGxzXG5cdFx0dmFyIGRlZmVycmVkUmVuZGVyQ2FsbHMgPSBbXTtcblxuXHRcdC8qKlxuXHRcdCAqIFdoZW4gZG93bmxvYWRlZCwgd2UgYXJlIHJlYWR5IHRvIGRyYXcgZGVmZXJyZWQgY2hhcnRzLlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIGRyYXdEZWZlcnJlZCgpIHtcblx0XHRcdHZhciBjYWxsTGVuZ3RoID0gZGVmZXJyZWRSZW5kZXJDYWxscy5sZW5ndGgsXG5cdFx0XHRcdGNhbGxJbmRleDtcblxuXHRcdFx0Ly8gRHJhdyBhbGwgcGVuZGluZyByZW5kZXIgY2FsbHNcblx0XHRcdGZvciAoY2FsbEluZGV4ID0gMDsgY2FsbEluZGV4IDwgY2FsbExlbmd0aDsgY2FsbEluZGV4KyspIHtcblx0XHRcdFx0ZGVmZXJyZWRSZW5kZXJDYWxsc1tjYWxsSW5kZXhdKCk7XG5cdFx0XHR9XG5cdFx0XHQvLyBDbGVhciB0aGUgbGlzdFxuXHRcdFx0ZGVmZXJyZWRSZW5kZXJDYWxscyA9IFtdO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRwdXNoOiBmdW5jdGlvbiAoZnVuYywgc2NyaXB0TG9jYXRpb24pIHtcblx0XHRcdFx0Ly8gT25seSBnZXQgdGhlIHNjcmlwdCBvbmNlXG5cdFx0XHRcdGlmIChkZWZlcnJlZFJlbmRlckNhbGxzLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdGdldFNjcmlwdChzY3JpcHRMb2NhdGlvbiwgZHJhd0RlZmVycmVkKTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBSZWdpc3RlciByZW5kZXIgY2FsbFxuXHRcdFx0XHRkZWZlcnJlZFJlbmRlckNhbGxzLnB1c2goZnVuYyk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSgpKTtcblxuXHRSZW5kZXJlciA9IENhblZHUmVuZGVyZXI7XG59IC8vIGVuZCBDYW5WR1JlbmRlcmVyXG5cbi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqIEVORCBPRiBBTkRST0lEIDwgMyBTUEVDSUZJQyBDT0RFICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpcbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqXG4gKiBUaGUgVGljayBjbGFzc1xuICovXG5mdW5jdGlvbiBUaWNrKGF4aXMsIHBvcywgdHlwZSwgbm9MYWJlbCkge1xuXHR0aGlzLmF4aXMgPSBheGlzO1xuXHR0aGlzLnBvcyA9IHBvcztcblx0dGhpcy50eXBlID0gdHlwZSB8fCAnJztcblx0dGhpcy5pc05ldyA9IHRydWU7XG5cblx0aWYgKCF0eXBlICYmICFub0xhYmVsKSB7XG5cdFx0dGhpcy5hZGRMYWJlbCgpO1xuXHR9XG59XG5cblRpY2sucHJvdG90eXBlID0ge1xuXHQvKipcblx0ICogV3JpdGUgdGhlIHRpY2sgbGFiZWxcblx0ICovXG5cdGFkZExhYmVsOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHRpY2sgPSB0aGlzLFxuXHRcdFx0YXhpcyA9IHRpY2suYXhpcyxcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0XHRob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHRjYXRlZ29yaWVzID0gYXhpcy5jYXRlZ29yaWVzLFxuXHRcdFx0bmFtZXMgPSBheGlzLm5hbWVzLFxuXHRcdFx0cG9zID0gdGljay5wb3MsXG5cdFx0XHRsYWJlbE9wdGlvbnMgPSBvcHRpb25zLmxhYmVscyxcblx0XHRcdHJvdGF0aW9uID0gbGFiZWxPcHRpb25zLnJvdGF0aW9uLFxuXHRcdFx0c3RyLFxuXHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMudGlja1Bvc2l0aW9ucyxcblx0XHRcdHdpZHRoID0gKGhvcml6ICYmIGNhdGVnb3JpZXMgJiZcblx0XHRcdFx0IWxhYmVsT3B0aW9ucy5zdGVwICYmICFsYWJlbE9wdGlvbnMuc3RhZ2dlckxpbmVzICYmXG5cdFx0XHRcdCFsYWJlbE9wdGlvbnMucm90YXRpb24gJiZcblx0XHRcdFx0Y2hhcnQucGxvdFdpZHRoIC8gdGlja1Bvc2l0aW9ucy5sZW5ndGgpIHx8XG5cdFx0XHRcdCghaG9yaXogJiYgKGNoYXJ0Lm1hcmdpblszXSB8fCBjaGFydC5jaGFydFdpZHRoICogMC4zMykpLCAvLyAjMTU4MCwgIzE5MzFcblx0XHRcdGlzRmlyc3QgPSBwb3MgPT09IHRpY2tQb3NpdGlvbnNbMF0sXG5cdFx0XHRpc0xhc3QgPSBwb3MgPT09IHRpY2tQb3NpdGlvbnNbdGlja1Bvc2l0aW9ucy5sZW5ndGggLSAxXSxcblx0XHRcdGNzcyxcblx0XHRcdGF0dHIsXG5cdFx0XHR2YWx1ZSA9IGNhdGVnb3JpZXMgP1xuXHRcdFx0XHRwaWNrKGNhdGVnb3JpZXNbcG9zXSwgbmFtZXNbcG9zXSwgcG9zKSA6XG5cdFx0XHRcdHBvcyxcblx0XHRcdGxhYmVsID0gdGljay5sYWJlbCxcblx0XHRcdHRpY2tQb3NpdGlvbkluZm8gPSB0aWNrUG9zaXRpb25zLmluZm8sXG5cdFx0XHRkYXRlVGltZUxhYmVsRm9ybWF0O1xuXG5cdFx0Ly8gU2V0IHRoZSBkYXRldGltZSBsYWJlbCBmb3JtYXQuIElmIGEgaGlnaGVyIHJhbmsgaXMgc2V0IGZvciB0aGlzIHBvc2l0aW9uLCB1c2UgdGhhdC4gSWYgbm90LFxuXHRcdC8vIHVzZSB0aGUgZ2VuZXJhbCBmb3JtYXQuXG5cdFx0aWYgKGF4aXMuaXNEYXRldGltZUF4aXMgJiYgdGlja1Bvc2l0aW9uSW5mbykge1xuXHRcdFx0ZGF0ZVRpbWVMYWJlbEZvcm1hdCA9IG9wdGlvbnMuZGF0ZVRpbWVMYWJlbEZvcm1hdHNbdGlja1Bvc2l0aW9uSW5mby5oaWdoZXJSYW5rc1twb3NdIHx8IHRpY2tQb3NpdGlvbkluZm8udW5pdE5hbWVdO1xuXHRcdH1cblx0XHQvLyBzZXQgcHJvcGVydGllcyBmb3IgYWNjZXNzIGluIHJlbmRlciBtZXRob2Rcblx0XHR0aWNrLmlzRmlyc3QgPSBpc0ZpcnN0O1xuXHRcdHRpY2suaXNMYXN0ID0gaXNMYXN0O1xuXG5cdFx0Ly8gZ2V0IHRoZSBzdHJpbmdcblx0XHRzdHIgPSBheGlzLmxhYmVsRm9ybWF0dGVyLmNhbGwoe1xuXHRcdFx0YXhpczogYXhpcyxcblx0XHRcdGNoYXJ0OiBjaGFydCxcblx0XHRcdGlzRmlyc3Q6IGlzRmlyc3QsXG5cdFx0XHRpc0xhc3Q6IGlzTGFzdCxcblx0XHRcdGRhdGVUaW1lTGFiZWxGb3JtYXQ6IGRhdGVUaW1lTGFiZWxGb3JtYXQsXG5cdFx0XHR2YWx1ZTogYXhpcy5pc0xvZyA/IGNvcnJlY3RGbG9hdChsaW4ybG9nKHZhbHVlKSkgOiB2YWx1ZVxuXHRcdH0pO1xuXG5cdFx0Ly8gcHJlcGFyZSBDU1Ncblx0XHRjc3MgPSB3aWR0aCAmJiB7IHdpZHRoOiBtYXRoTWF4KDEsIG1hdGhSb3VuZCh3aWR0aCAtIDIgKiAobGFiZWxPcHRpb25zLnBhZGRpbmcgfHwgMTApKSkgKyBQWCB9O1xuXHRcdFxuXHRcdC8vIGZpcnN0IGNhbGxcblx0XHRpZiAoIWRlZmluZWQobGFiZWwpKSB7XG5cdFx0XHRhdHRyID0ge1xuXHRcdFx0XHRhbGlnbjogYXhpcy5sYWJlbEFsaWduXG5cdFx0XHR9O1xuXHRcdFx0aWYgKGlzTnVtYmVyKHJvdGF0aW9uKSkge1xuXHRcdFx0XHRhdHRyLnJvdGF0aW9uID0gcm90YXRpb247XG5cdFx0XHR9XG5cdFx0XHRpZiAod2lkdGggJiYgbGFiZWxPcHRpb25zLmVsbGlwc2lzKSB7XG5cdFx0XHRcdGNzcy5IY0hlaWdodCA9IGF4aXMubGVuIC8gdGlja1Bvc2l0aW9ucy5sZW5ndGg7XG5cdFx0XHR9XG5cblx0XHRcdHRpY2subGFiZWwgPSBsYWJlbCA9XG5cdFx0XHRcdGRlZmluZWQoc3RyKSAmJiBsYWJlbE9wdGlvbnMuZW5hYmxlZCA/XG5cdFx0XHRcdFx0Y2hhcnQucmVuZGVyZXIudGV4dChcblx0XHRcdFx0XHRcdFx0c3RyLFxuXHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0XHRsYWJlbE9wdGlvbnMudXNlSFRNTFxuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0LmF0dHIoYXR0cilcblx0XHRcdFx0XHRcdC8vIHdpdGhvdXQgcG9zaXRpb24gYWJzb2x1dGUsIElFIGV4cG9ydCBzb21ldGltZXMgaXMgd3Jvbmdcblx0XHRcdFx0XHRcdC5jc3MoZXh0ZW5kKGNzcywgbGFiZWxPcHRpb25zLnN0eWxlKSlcblx0XHRcdFx0XHRcdC5hZGQoYXhpcy5sYWJlbEdyb3VwKSA6XG5cdFx0XHRcdFx0bnVsbDtcblxuXHRcdFx0Ly8gU2V0IHRoZSB0aWNrIGJhc2VsaW5lIGFuZCBjb3JyZWN0IGZvciByb3RhdGlvbiAoIzE3NjQpXG5cdFx0XHRheGlzLnRpY2tCYXNlbGluZSA9IGNoYXJ0LnJlbmRlcmVyLmZvbnRNZXRyaWNzKGxhYmVsT3B0aW9ucy5zdHlsZS5mb250U2l6ZSwgbGFiZWwpLmI7XG5cdFx0XHRpZiAocm90YXRpb24gJiYgYXhpcy5zaWRlID09PSAyKSB7XG5cdFx0XHRcdGF4aXMudGlja0Jhc2VsaW5lICo9IG1hdGhDb3Mocm90YXRpb24gKiBkZWcycmFkKTtcblx0XHRcdH1cblxuXG5cdFx0Ly8gdXBkYXRlXG5cdFx0fSBlbHNlIGlmIChsYWJlbCkge1xuXHRcdFx0bGFiZWwuYXR0cih7XG5cdFx0XHRcdFx0dGV4dDogc3RyXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jc3MoY3NzKTtcblx0XHR9XG5cdFx0dGljay55T2Zmc2V0ID0gbGFiZWwgPyBwaWNrKGxhYmVsT3B0aW9ucy55LCBheGlzLnRpY2tCYXNlbGluZSArIChheGlzLnNpZGUgPT09IDIgPyA4IDogLShsYWJlbC5nZXRCQm94KCkuaGVpZ2h0IC8gMikpKSA6IDA7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgb2Zmc2V0IGhlaWdodCBvciB3aWR0aCBvZiB0aGUgbGFiZWxcblx0ICovXG5cdGdldExhYmVsU2l6ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBsYWJlbCA9IHRoaXMubGFiZWwsXG5cdFx0XHRheGlzID0gdGhpcy5heGlzO1xuXHRcdHJldHVybiBsYWJlbCA/XG5cdFx0XHRsYWJlbC5nZXRCQm94KClbYXhpcy5ob3JpeiA/ICdoZWlnaHQnIDogJ3dpZHRoJ10gOlxuXHRcdFx0MDtcblx0fSxcblxuXHQvKipcblx0ICogRmluZCBob3cgZmFyIHRoZSBsYWJlbHMgZXh0ZW5kIHRvIHRoZSByaWdodCBhbmQgbGVmdCBvZiB0aGUgdGljaydzIHggcG9zaXRpb24uIFVzZWQgZm9yIGFudGktY29sbGlzaW9uXG5cdCAqIGRldGVjdGlvbiB3aXRoIG92ZXJmbG93IGxvZ2ljLlxuXHQgKi9cblx0Z2V0TGFiZWxTaWRlczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBiQm94ID0gdGhpcy5sYWJlbC5nZXRCQm94KCksXG5cdFx0XHRheGlzID0gdGhpcy5heGlzLFxuXHRcdFx0aG9yaXogPSBheGlzLmhvcml6LFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdGxhYmVsT3B0aW9ucyA9IG9wdGlvbnMubGFiZWxzLFxuXHRcdFx0c2l6ZSA9IGhvcml6ID8gYkJveC53aWR0aCA6IGJCb3guaGVpZ2h0LFxuXHRcdFx0bGVmdFNpZGUgPSBob3JpeiA/XG5cdFx0XHRcdGxhYmVsT3B0aW9ucy54IC0gc2l6ZSAqIHsgbGVmdDogMCwgY2VudGVyOiAwLjUsIHJpZ2h0OiAxIH1bYXhpcy5sYWJlbEFsaWduXSA6XG5cdFx0XHRcdDAsXG5cdFx0XHRyaWdodFNpZGUgPSBob3JpeiA/XG5cdFx0XHRcdHNpemUgKyBsZWZ0U2lkZSA6XG5cdFx0XHRcdHNpemU7XG5cblx0XHRyZXR1cm4gW2xlZnRTaWRlLCByaWdodFNpZGVdO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBIYW5kbGUgdGhlIGxhYmVsIG92ZXJmbG93IGJ5IGFkanVzdGluZyB0aGUgbGFiZWxzIHRvIHRoZSBsZWZ0IGFuZCByaWdodCBlZGdlLCBvclxuXHQgKiBoaWRlIHRoZW0gaWYgdGhleSBjb2xsaWRlIGludG8gdGhlIG5laWdoYm91ciBsYWJlbC5cblx0ICovXG5cdGhhbmRsZU92ZXJmbG93OiBmdW5jdGlvbiAoaW5kZXgsIHh5KSB7XG5cdFx0dmFyIHNob3cgPSB0cnVlLFxuXHRcdFx0YXhpcyA9IHRoaXMuYXhpcyxcblx0XHRcdGlzRmlyc3QgPSB0aGlzLmlzRmlyc3QsXG5cdFx0XHRpc0xhc3QgPSB0aGlzLmlzTGFzdCxcblx0XHRcdGhvcml6ID0gYXhpcy5ob3Jpeixcblx0XHRcdHB4UG9zID0gaG9yaXogPyB4eS54IDogeHkueSxcblx0XHRcdHJldmVyc2VkID0gYXhpcy5yZXZlcnNlZCxcblx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLnRpY2tQb3NpdGlvbnMsXG5cdFx0XHRzaWRlcyA9IHRoaXMuZ2V0TGFiZWxTaWRlcygpLFxuXHRcdFx0bGVmdFNpZGUgPSBzaWRlc1swXSxcblx0XHRcdHJpZ2h0U2lkZSA9IHNpZGVzWzFdLFxuXHRcdFx0YXhpc0xlZnQsXG5cdFx0XHRheGlzUmlnaHQsXG5cdFx0XHRuZWlnaGJvdXIsXG5cdFx0XHRuZWlnaGJvdXJFZGdlLFxuXHRcdFx0bGluZSA9IHRoaXMubGFiZWwubGluZSxcblx0XHRcdGxpbmVJbmRleCA9IGxpbmUgfHwgMCxcblx0XHRcdGxhYmVsRWRnZSA9IGF4aXMubGFiZWxFZGdlLFxuXHRcdFx0anVzdGlmeUxhYmVsID0gYXhpcy5qdXN0aWZ5TGFiZWxzICYmIChpc0ZpcnN0IHx8IGlzTGFzdCksXG5cdFx0XHRqdXN0aWZ5VG9QbG90O1xuXG5cdFx0Ly8gSGlkZSBpdCBpZiBpdCBub3cgb3ZlcmxhcHMgdGhlIG5laWdoYm91ciBsYWJlbFxuXHRcdGlmIChsYWJlbEVkZ2VbbGluZUluZGV4XSA9PT0gVU5ERUZJTkVEIHx8IHB4UG9zICsgbGVmdFNpZGUgPiBsYWJlbEVkZ2VbbGluZUluZGV4XSkge1xuXHRcdFx0bGFiZWxFZGdlW2xpbmVJbmRleF0gPSBweFBvcyArIHJpZ2h0U2lkZTtcblxuXHRcdH0gZWxzZSBpZiAoIWp1c3RpZnlMYWJlbCkge1xuXHRcdFx0c2hvdyA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChqdXN0aWZ5TGFiZWwpIHtcblx0XHRcdGp1c3RpZnlUb1Bsb3QgPSBheGlzLmp1c3RpZnlUb1Bsb3Q7XG5cdFx0XHRheGlzTGVmdCA9IGp1c3RpZnlUb1Bsb3QgPyBheGlzLnBvcyA6IDA7XG5cdFx0XHRheGlzUmlnaHQgPSBqdXN0aWZ5VG9QbG90ID8gYXhpc0xlZnQgKyBheGlzLmxlbiA6IGF4aXMuY2hhcnQuY2hhcnRXaWR0aDtcblxuXHRcdFx0Ly8gRmluZCB0aGUgZmlyc3RoIG5laWdoYm91ciBvbiB0aGUgc2FtZSBsaW5lXG5cdFx0XHRkbyB7XG5cdFx0XHRcdGluZGV4ICs9IChpc0ZpcnN0ID8gMSA6IC0xKTtcblx0XHRcdFx0bmVpZ2hib3VyID0gYXhpcy50aWNrc1t0aWNrUG9zaXRpb25zW2luZGV4XV07XG5cdFx0XHR9IHdoaWxlICh0aWNrUG9zaXRpb25zW2luZGV4XSAmJiAoIW5laWdoYm91ciB8fCAhbmVpZ2hib3VyLmxhYmVsIHx8IG5laWdoYm91ci5sYWJlbC5saW5lICE9PSBsaW5lKSk7IC8vICMzMDQ0XG5cblx0XHRcdG5laWdoYm91ckVkZ2UgPSBuZWlnaGJvdXIgJiYgbmVpZ2hib3VyLmxhYmVsLnh5ICYmIG5laWdoYm91ci5sYWJlbC54eS54ICsgbmVpZ2hib3VyLmdldExhYmVsU2lkZXMoKVtpc0ZpcnN0ID8gMCA6IDFdO1xuXG5cdFx0XHRpZiAoKGlzRmlyc3QgJiYgIXJldmVyc2VkKSB8fCAoaXNMYXN0ICYmIHJldmVyc2VkKSkge1xuXHRcdFx0XHQvLyBJcyB0aGUgbGFiZWwgc3BpbGxpbmcgb3V0IHRvIHRoZSBsZWZ0IG9mIHRoZSBwbG90IGFyZWE/XG5cdFx0XHRcdGlmIChweFBvcyArIGxlZnRTaWRlIDwgYXhpc0xlZnQpIHtcblxuXHRcdFx0XHRcdC8vIEFsaWduIGl0IHRvIHBsb3QgbGVmdFxuXHRcdFx0XHRcdHB4UG9zID0gYXhpc0xlZnQgLSBsZWZ0U2lkZTtcblxuXHRcdFx0XHRcdC8vIEhpZGUgaXQgaWYgaXQgbm93IG92ZXJsYXBzIHRoZSBuZWlnaGJvdXIgbGFiZWxcblx0XHRcdFx0XHRpZiAobmVpZ2hib3VyICYmIHB4UG9zICsgcmlnaHRTaWRlID4gbmVpZ2hib3VyRWRnZSkge1xuXHRcdFx0XHRcdFx0c2hvdyA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBJcyB0aGUgbGFiZWwgc3BpbGxpbmcgb3V0IHRvIHRoZSByaWdodCBvZiB0aGUgcGxvdCBhcmVhP1xuXHRcdFx0XHRpZiAocHhQb3MgKyByaWdodFNpZGUgPiBheGlzUmlnaHQpIHtcblxuXHRcdFx0XHRcdC8vIEFsaWduIGl0IHRvIHBsb3QgcmlnaHRcblx0XHRcdFx0XHRweFBvcyA9IGF4aXNSaWdodCAtIHJpZ2h0U2lkZTtcblxuXHRcdFx0XHRcdC8vIEhpZGUgaXQgaWYgaXQgbm93IG92ZXJsYXBzIHRoZSBuZWlnaGJvdXIgbGFiZWxcblx0XHRcdFx0XHRpZiAobmVpZ2hib3VyICYmIHB4UG9zICsgbGVmdFNpZGUgPCBuZWlnaGJvdXJFZGdlKSB7XG5cdFx0XHRcdFx0XHRzaG93ID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IHRoZSBtb2RpZmllZCB4IHBvc2l0aW9uIG9mIHRoZSBsYWJlbFxuXHRcdFx0eHkueCA9IHB4UG9zO1xuXHRcdH1cblx0XHRyZXR1cm4gc2hvdztcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSB4IGFuZCB5IHBvc2l0aW9uIGZvciB0aWNrcyBhbmQgbGFiZWxzXG5cdCAqL1xuXHRnZXRQb3NpdGlvbjogZnVuY3Rpb24gKGhvcml6LCBwb3MsIHRpY2ttYXJrT2Zmc2V0LCBvbGQpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMuYXhpcyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdGNIZWlnaHQgPSAob2xkICYmIGNoYXJ0Lm9sZENoYXJ0SGVpZ2h0KSB8fCBjaGFydC5jaGFydEhlaWdodDtcblxuXHRcdHJldHVybiB7XG5cdFx0XHR4OiBob3JpeiA/XG5cdFx0XHRcdGF4aXMudHJhbnNsYXRlKHBvcyArIHRpY2ttYXJrT2Zmc2V0LCBudWxsLCBudWxsLCBvbGQpICsgYXhpcy50cmFuc0IgOlxuXHRcdFx0XHRheGlzLmxlZnQgKyBheGlzLm9mZnNldCArIChheGlzLm9wcG9zaXRlID8gKChvbGQgJiYgY2hhcnQub2xkQ2hhcnRXaWR0aCkgfHwgY2hhcnQuY2hhcnRXaWR0aCkgLSBheGlzLnJpZ2h0IC0gYXhpcy5sZWZ0IDogMCksXG5cblx0XHRcdHk6IGhvcml6ID9cblx0XHRcdFx0Y0hlaWdodCAtIGF4aXMuYm90dG9tICsgYXhpcy5vZmZzZXQgLSAoYXhpcy5vcHBvc2l0ZSA/IGF4aXMuaGVpZ2h0IDogMCkgOlxuXHRcdFx0XHRjSGVpZ2h0IC0gYXhpcy50cmFuc2xhdGUocG9zICsgdGlja21hcmtPZmZzZXQsIG51bGwsIG51bGwsIG9sZCkgLSBheGlzLnRyYW5zQlxuXHRcdH07XG5cblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSB4LCB5IHBvc2l0aW9uIG9mIHRoZSB0aWNrIGxhYmVsXG5cdCAqL1xuXHRnZXRMYWJlbFBvc2l0aW9uOiBmdW5jdGlvbiAoeCwgeSwgbGFiZWwsIGhvcml6LCBsYWJlbE9wdGlvbnMsIHRpY2ttYXJrT2Zmc2V0LCBpbmRleCwgc3RlcCkge1xuXHRcdHZhciBheGlzID0gdGhpcy5heGlzLFxuXHRcdFx0dHJhbnNBID0gYXhpcy50cmFuc0EsXG5cdFx0XHRyZXZlcnNlZCA9IGF4aXMucmV2ZXJzZWQsXG5cdFx0XHRzdGFnZ2VyTGluZXMgPSBheGlzLnN0YWdnZXJMaW5lcztcblxuXHRcdHggPSB4ICsgbGFiZWxPcHRpb25zLnggLSAodGlja21hcmtPZmZzZXQgJiYgaG9yaXogP1xuXHRcdFx0dGlja21hcmtPZmZzZXQgKiB0cmFuc0EgKiAocmV2ZXJzZWQgPyAtMSA6IDEpIDogMCk7XG5cdFx0eSA9IHkgKyB0aGlzLnlPZmZzZXQgLSAodGlja21hcmtPZmZzZXQgJiYgIWhvcml6ID9cblx0XHRcdHRpY2ttYXJrT2Zmc2V0ICogdHJhbnNBICogKHJldmVyc2VkID8gMSA6IC0xKSA6IDApO1xuXG5cdFx0Ly8gQ29ycmVjdCBmb3Igc3RhZ2dlcmVkIGxhYmVsc1xuXHRcdGlmIChzdGFnZ2VyTGluZXMpIHtcblx0XHRcdGxhYmVsLmxpbmUgPSAoaW5kZXggLyAoc3RlcCB8fCAxKSAlIHN0YWdnZXJMaW5lcyk7XG5cdFx0XHR5ICs9IGxhYmVsLmxpbmUgKiAoYXhpcy5sYWJlbE9mZnNldCAvIHN0YWdnZXJMaW5lcyk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IHgsXG5cdFx0XHR5OiB5XG5cdFx0fTtcblx0fSxcblxuXHQvKipcblx0ICogRXh0ZW5kaWJsZSBtZXRob2QgdG8gcmV0dXJuIHRoZSBwYXRoIG9mIHRoZSBtYXJrZXJcblx0ICovXG5cdGdldE1hcmtQYXRoOiBmdW5jdGlvbiAoeCwgeSwgdGlja0xlbmd0aCwgdGlja1dpZHRoLCBob3JpeiwgcmVuZGVyZXIpIHtcblx0XHRyZXR1cm4gcmVuZGVyZXIuY3Jpc3BMaW5lKFtcblx0XHRcdFx0TSxcblx0XHRcdFx0eCxcblx0XHRcdFx0eSxcblx0XHRcdFx0TCxcblx0XHRcdFx0eCArIChob3JpeiA/IDAgOiAtdGlja0xlbmd0aCksXG5cdFx0XHRcdHkgKyAoaG9yaXogPyB0aWNrTGVuZ3RoIDogMClcblx0XHRcdF0sIHRpY2tXaWR0aCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFB1dCBldmVyeXRoaW5nIGluIHBsYWNlXG5cdCAqXG5cdCAqIEBwYXJhbSBpbmRleCB7TnVtYmVyfVxuXHQgKiBAcGFyYW0gb2xkIHtCb29sZWFufSBVc2Ugb2xkIGNvb3JkaW5hdGVzIHRvIHByZXBhcmUgYW4gYW5pbWF0aW9uIGludG8gbmV3IHBvc2l0aW9uXG5cdCAqL1xuXHRyZW5kZXI6IGZ1bmN0aW9uIChpbmRleCwgb2xkLCBvcGFjaXR5KSB7XG5cdFx0dmFyIHRpY2sgPSB0aGlzLFxuXHRcdFx0YXhpcyA9IHRpY2suYXhpcyxcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0aG9yaXogPSBheGlzLmhvcml6LFxuXHRcdFx0dHlwZSA9IHRpY2sudHlwZSxcblx0XHRcdGxhYmVsID0gdGljay5sYWJlbCxcblx0XHRcdHBvcyA9IHRpY2sucG9zLFxuXHRcdFx0bGFiZWxPcHRpb25zID0gb3B0aW9ucy5sYWJlbHMsXG5cdFx0XHRncmlkTGluZSA9IHRpY2suZ3JpZExpbmUsXG5cdFx0XHRncmlkUHJlZml4ID0gdHlwZSA/IHR5cGUgKyAnR3JpZCcgOiAnZ3JpZCcsXG5cdFx0XHR0aWNrUHJlZml4ID0gdHlwZSA/IHR5cGUgKyAnVGljaycgOiAndGljaycsXG5cdFx0XHRncmlkTGluZVdpZHRoID0gb3B0aW9uc1tncmlkUHJlZml4ICsgJ0xpbmVXaWR0aCddLFxuXHRcdFx0Z3JpZExpbmVDb2xvciA9IG9wdGlvbnNbZ3JpZFByZWZpeCArICdMaW5lQ29sb3InXSxcblx0XHRcdGRhc2hTdHlsZSA9IG9wdGlvbnNbZ3JpZFByZWZpeCArICdMaW5lRGFzaFN0eWxlJ10sXG5cdFx0XHR0aWNrTGVuZ3RoID0gb3B0aW9uc1t0aWNrUHJlZml4ICsgJ0xlbmd0aCddLFxuXHRcdFx0dGlja1dpZHRoID0gb3B0aW9uc1t0aWNrUHJlZml4ICsgJ1dpZHRoJ10gfHwgMCxcblx0XHRcdHRpY2tDb2xvciA9IG9wdGlvbnNbdGlja1ByZWZpeCArICdDb2xvciddLFxuXHRcdFx0dGlja1Bvc2l0aW9uID0gb3B0aW9uc1t0aWNrUHJlZml4ICsgJ1Bvc2l0aW9uJ10sXG5cdFx0XHRncmlkTGluZVBhdGgsXG5cdFx0XHRtYXJrID0gdGljay5tYXJrLFxuXHRcdFx0bWFya1BhdGgsXG5cdFx0XHRzdGVwID0gbGFiZWxPcHRpb25zLnN0ZXAsXG5cdFx0XHRhdHRyaWJzLFxuXHRcdFx0c2hvdyA9IHRydWUsXG5cdFx0XHR0aWNrbWFya09mZnNldCA9IGF4aXMudGlja21hcmtPZmZzZXQsXG5cdFx0XHR4eSA9IHRpY2suZ2V0UG9zaXRpb24oaG9yaXosIHBvcywgdGlja21hcmtPZmZzZXQsIG9sZCksXG5cdFx0XHR4ID0geHkueCxcblx0XHRcdHkgPSB4eS55LFxuXHRcdFx0cmV2ZXJzZUNyaXNwID0gKChob3JpeiAmJiB4ID09PSBheGlzLnBvcyArIGF4aXMubGVuKSB8fCAoIWhvcml6ICYmIHkgPT09IGF4aXMucG9zKSkgPyAtMSA6IDE7IC8vICMxNDgwLCAjMTY4N1xuXG5cdFx0b3BhY2l0eSA9IHBpY2sob3BhY2l0eSwgMSk7XG5cdFx0dGhpcy5pc0FjdGl2ZSA9IHRydWU7XG5cblx0XHQvLyBjcmVhdGUgdGhlIGdyaWQgbGluZVxuXHRcdGlmIChncmlkTGluZVdpZHRoKSB7XG5cdFx0XHRncmlkTGluZVBhdGggPSBheGlzLmdldFBsb3RMaW5lUGF0aChwb3MgKyB0aWNrbWFya09mZnNldCwgZ3JpZExpbmVXaWR0aCAqIHJldmVyc2VDcmlzcCwgb2xkLCB0cnVlKTtcblxuXHRcdFx0aWYgKGdyaWRMaW5lID09PSBVTkRFRklORUQpIHtcblx0XHRcdFx0YXR0cmlicyA9IHtcblx0XHRcdFx0XHRzdHJva2U6IGdyaWRMaW5lQ29sb3IsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IGdyaWRMaW5lV2lkdGhcblx0XHRcdFx0fTtcblx0XHRcdFx0aWYgKGRhc2hTdHlsZSkge1xuXHRcdFx0XHRcdGF0dHJpYnMuZGFzaHN0eWxlID0gZGFzaFN0eWxlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICghdHlwZSkge1xuXHRcdFx0XHRcdGF0dHJpYnMuekluZGV4ID0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAob2xkKSB7XG5cdFx0XHRcdFx0YXR0cmlicy5vcGFjaXR5ID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aWNrLmdyaWRMaW5lID0gZ3JpZExpbmUgPVxuXHRcdFx0XHRcdGdyaWRMaW5lV2lkdGggP1xuXHRcdFx0XHRcdFx0cmVuZGVyZXIucGF0aChncmlkTGluZVBhdGgpXG5cdFx0XHRcdFx0XHRcdC5hdHRyKGF0dHJpYnMpLmFkZChheGlzLmdyaWRHcm91cCkgOlxuXHRcdFx0XHRcdFx0bnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgdGhlIHBhcmFtZXRlciAnb2xkJyBpcyBzZXQsIHRoZSBjdXJyZW50IGNhbGwgd2lsbCBiZSBmb2xsb3dlZFxuXHRcdFx0Ly8gYnkgYW5vdGhlciBjYWxsLCB0aGVyZWZvcmUgZG8gbm90IGRvIGFueSBhbmltYXRpb25zIHRoaXMgdGltZVxuXHRcdFx0aWYgKCFvbGQgJiYgZ3JpZExpbmUgJiYgZ3JpZExpbmVQYXRoKSB7XG5cdFx0XHRcdGdyaWRMaW5lW3RpY2suaXNOZXcgPyAnYXR0cicgOiAnYW5pbWF0ZSddKHtcblx0XHRcdFx0XHRkOiBncmlkTGluZVBhdGgsXG5cdFx0XHRcdFx0b3BhY2l0eTogb3BhY2l0eVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBjcmVhdGUgdGhlIHRpY2sgbWFya1xuXHRcdGlmICh0aWNrV2lkdGggJiYgdGlja0xlbmd0aCkge1xuXG5cdFx0XHQvLyBuZWdhdGUgdGhlIGxlbmd0aFxuXHRcdFx0aWYgKHRpY2tQb3NpdGlvbiA9PT0gJ2luc2lkZScpIHtcblx0XHRcdFx0dGlja0xlbmd0aCA9IC10aWNrTGVuZ3RoO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGF4aXMub3Bwb3NpdGUpIHtcblx0XHRcdFx0dGlja0xlbmd0aCA9IC10aWNrTGVuZ3RoO1xuXHRcdFx0fVxuXG5cdFx0XHRtYXJrUGF0aCA9IHRpY2suZ2V0TWFya1BhdGgoeCwgeSwgdGlja0xlbmd0aCwgdGlja1dpZHRoICogcmV2ZXJzZUNyaXNwLCBob3JpeiwgcmVuZGVyZXIpO1xuXHRcdFx0aWYgKG1hcmspIHsgLy8gdXBkYXRpbmdcblx0XHRcdFx0bWFyay5hbmltYXRlKHtcblx0XHRcdFx0XHRkOiBtYXJrUGF0aCxcblx0XHRcdFx0XHRvcGFjaXR5OiBvcGFjaXR5XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSBlbHNlIHsgLy8gZmlyc3QgdGltZVxuXHRcdFx0XHR0aWNrLm1hcmsgPSByZW5kZXJlci5wYXRoKFxuXHRcdFx0XHRcdG1hcmtQYXRoXG5cdFx0XHRcdCkuYXR0cih7XG5cdFx0XHRcdFx0c3Ryb2tlOiB0aWNrQ29sb3IsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IHRpY2tXaWR0aCxcblx0XHRcdFx0XHRvcGFjaXR5OiBvcGFjaXR5XG5cdFx0XHRcdH0pLmFkZChheGlzLmF4aXNHcm91cCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIGxhYmVsIGlzIGNyZWF0ZWQgb24gaW5pdCAtIG5vdyBtb3ZlIGl0IGludG8gcGxhY2Vcblx0XHRpZiAobGFiZWwgJiYgIWlzTmFOKHgpKSB7XG5cdFx0XHRsYWJlbC54eSA9IHh5ID0gdGljay5nZXRMYWJlbFBvc2l0aW9uKHgsIHksIGxhYmVsLCBob3JpeiwgbGFiZWxPcHRpb25zLCB0aWNrbWFya09mZnNldCwgaW5kZXgsIHN0ZXApO1xuXG5cdFx0XHQvLyBBcHBseSBzaG93IGZpcnN0IGFuZCBzaG93IGxhc3QuIElmIHRoZSB0aWNrIGlzIGJvdGggZmlyc3QgYW5kIGxhc3QsIGl0IGlzXG5cdFx0XHQvLyBhIHNpbmdsZSBjZW50ZXJlZCB0aWNrLCBpbiB3aGljaCBjYXNlIHdlIHNob3cgdGhlIGxhYmVsIGFueXdheSAoIzIxMDApLlxuXHRcdFx0aWYgKCh0aWNrLmlzRmlyc3QgJiYgIXRpY2suaXNMYXN0ICYmICFwaWNrKG9wdGlvbnMuc2hvd0ZpcnN0TGFiZWwsIDEpKSB8fFxuXHRcdFx0XHRcdCh0aWNrLmlzTGFzdCAmJiAhdGljay5pc0ZpcnN0ICYmICFwaWNrKG9wdGlvbnMuc2hvd0xhc3RMYWJlbCwgMSkpKSB7XG5cdFx0XHRcdHNob3cgPSBmYWxzZTtcblxuXHRcdFx0Ly8gSGFuZGxlIGxhYmVsIG92ZXJmbG93IGFuZCBzaG93IG9yIGhpZGUgYWNjb3JkaW5nbHlcblx0XHRcdH0gZWxzZSBpZiAoIWF4aXMuaXNSYWRpYWwgJiYgIWxhYmVsT3B0aW9ucy5zdGVwICYmICFsYWJlbE9wdGlvbnMucm90YXRpb24gJiYgIW9sZCAmJiBvcGFjaXR5ICE9PSAwKSB7XG5cdFx0XHRcdHNob3cgPSB0aWNrLmhhbmRsZU92ZXJmbG93KGluZGV4LCB4eSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGFwcGx5IHN0ZXBcblx0XHRcdGlmIChzdGVwICYmIGluZGV4ICUgc3RlcCkge1xuXHRcdFx0XHQvLyBzaG93IHRob3NlIGluZGljZXMgZGl2aWRhYmxlIGJ5IHN0ZXBcblx0XHRcdFx0c2hvdyA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIG5ldyBwb3NpdGlvbiwgYW5kIHNob3cgb3IgaGlkZVxuXHRcdFx0aWYgKHNob3cgJiYgIWlzTmFOKHh5LnkpKSB7XG5cdFx0XHRcdHh5Lm9wYWNpdHkgPSBvcGFjaXR5O1xuXHRcdFx0XHRsYWJlbFt0aWNrLmlzTmV3ID8gJ2F0dHInIDogJ2FuaW1hdGUnXSh4eSk7XG5cdFx0XHRcdHRpY2suaXNOZXcgPSBmYWxzZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGxhYmVsLmF0dHIoJ3knLCAtOTk5OSk7IC8vICMxMzM4XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cnVjdG9yIGZvciB0aGUgdGljayBwcm90b3R5cGVcblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHRkZXN0cm95T2JqZWN0UHJvcGVydGllcyh0aGlzLCB0aGlzLmF4aXMpO1xuXHR9XG59O1xuXG4vKipcbiAqIFRoZSBvYmplY3Qgd3JhcHBlciBmb3IgcGxvdCBsaW5lcyBhbmQgcGxvdCBiYW5kc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqL1xuSGlnaGNoYXJ0cy5QbG90TGluZU9yQmFuZCA9IGZ1bmN0aW9uIChheGlzLCBvcHRpb25zKSB7XG5cdHRoaXMuYXhpcyA9IGF4aXM7XG5cblx0aWYgKG9wdGlvbnMpIHtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdHRoaXMuaWQgPSBvcHRpb25zLmlkO1xuXHR9XG59O1xuXG5IaWdoY2hhcnRzLlBsb3RMaW5lT3JCYW5kLnByb3RvdHlwZSA9IHtcblx0XG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIHBsb3QgbGluZSBvciBwbG90IGJhbmQuIElmIGl0IGlzIGFscmVhZHkgZXhpc3RpbmcsXG5cdCAqIG1vdmUgaXQuXG5cdCAqL1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcGxvdExpbmUgPSB0aGlzLFxuXHRcdFx0YXhpcyA9IHBsb3RMaW5lLmF4aXMsXG5cdFx0XHRob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHRoYWxmUG9pbnRSYW5nZSA9IChheGlzLnBvaW50UmFuZ2UgfHwgMCkgLyAyLFxuXHRcdFx0b3B0aW9ucyA9IHBsb3RMaW5lLm9wdGlvbnMsXG5cdFx0XHRvcHRpb25zTGFiZWwgPSBvcHRpb25zLmxhYmVsLFxuXHRcdFx0bGFiZWwgPSBwbG90TGluZS5sYWJlbCxcblx0XHRcdHdpZHRoID0gb3B0aW9ucy53aWR0aCxcblx0XHRcdHRvID0gb3B0aW9ucy50byxcblx0XHRcdGZyb20gPSBvcHRpb25zLmZyb20sXG5cdFx0XHRpc0JhbmQgPSBkZWZpbmVkKGZyb20pICYmIGRlZmluZWQodG8pLFxuXHRcdFx0dmFsdWUgPSBvcHRpb25zLnZhbHVlLFxuXHRcdFx0ZGFzaFN0eWxlID0gb3B0aW9ucy5kYXNoU3R5bGUsXG5cdFx0XHRzdmdFbGVtID0gcGxvdExpbmUuc3ZnRWxlbSxcblx0XHRcdHBhdGggPSBbXSxcblx0XHRcdGFkZEV2ZW50LFxuXHRcdFx0ZXZlbnRUeXBlLFxuXHRcdFx0eHMsXG5cdFx0XHR5cyxcblx0XHRcdHgsXG5cdFx0XHR5LFxuXHRcdFx0Y29sb3IgPSBvcHRpb25zLmNvbG9yLFxuXHRcdFx0ekluZGV4ID0gb3B0aW9ucy56SW5kZXgsXG5cdFx0XHRldmVudHMgPSBvcHRpb25zLmV2ZW50cyxcblx0XHRcdGF0dHJpYnMgPSB7fSxcblx0XHRcdHJlbmRlcmVyID0gYXhpcy5jaGFydC5yZW5kZXJlcjtcblxuXHRcdC8vIGxvZ2FyaXRobWljIGNvbnZlcnNpb25cblx0XHRpZiAoYXhpcy5pc0xvZykge1xuXHRcdFx0ZnJvbSA9IGxvZzJsaW4oZnJvbSk7XG5cdFx0XHR0byA9IGxvZzJsaW4odG8pO1xuXHRcdFx0dmFsdWUgPSBsb2cybGluKHZhbHVlKTtcblx0XHR9XG5cblx0XHQvLyBwbG90IGxpbmVcblx0XHRpZiAod2lkdGgpIHtcblx0XHRcdHBhdGggPSBheGlzLmdldFBsb3RMaW5lUGF0aCh2YWx1ZSwgd2lkdGgpO1xuXHRcdFx0YXR0cmlicyA9IHtcblx0XHRcdFx0c3Ryb2tlOiBjb2xvcixcblx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IHdpZHRoXG5cdFx0XHR9O1xuXHRcdFx0aWYgKGRhc2hTdHlsZSkge1xuXHRcdFx0XHRhdHRyaWJzLmRhc2hzdHlsZSA9IGRhc2hTdHlsZTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGlzQmFuZCkgeyAvLyBwbG90IGJhbmRcblx0XHRcdFxuXHRcdFx0Ly8ga2VlcCB3aXRoaW4gcGxvdCBhcmVhXG5cdFx0XHRmcm9tID0gbWF0aE1heChmcm9tLCBheGlzLm1pbiAtIGhhbGZQb2ludFJhbmdlKTtcblx0XHRcdHRvID0gbWF0aE1pbih0bywgYXhpcy5tYXggKyBoYWxmUG9pbnRSYW5nZSk7XG5cdFx0XHRcblx0XHRcdHBhdGggPSBheGlzLmdldFBsb3RCYW5kUGF0aChmcm9tLCB0bywgb3B0aW9ucyk7XG5cdFx0XHRpZiAoY29sb3IpIHtcblx0XHRcdFx0YXR0cmlicy5maWxsID0gY29sb3I7XG5cdFx0XHR9XG5cdFx0XHRpZiAob3B0aW9ucy5ib3JkZXJXaWR0aCkge1xuXHRcdFx0XHRhdHRyaWJzLnN0cm9rZSA9IG9wdGlvbnMuYm9yZGVyQ29sb3I7XG5cdFx0XHRcdGF0dHJpYnNbJ3N0cm9rZS13aWR0aCddID0gb3B0aW9ucy5ib3JkZXJXaWR0aDtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHQvLyB6SW5kZXhcblx0XHRpZiAoZGVmaW5lZCh6SW5kZXgpKSB7XG5cdFx0XHRhdHRyaWJzLnpJbmRleCA9IHpJbmRleDtcblx0XHR9XG5cblx0XHQvLyBjb21tb24gZm9yIGxpbmVzIGFuZCBiYW5kc1xuXHRcdGlmIChzdmdFbGVtKSB7XG5cdFx0XHRpZiAocGF0aCkge1xuXHRcdFx0XHRzdmdFbGVtLmFuaW1hdGUoe1xuXHRcdFx0XHRcdGQ6IHBhdGhcblx0XHRcdFx0fSwgbnVsbCwgc3ZnRWxlbS5vbkdldFBhdGgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c3ZnRWxlbS5oaWRlKCk7XG5cdFx0XHRcdHN2Z0VsZW0ub25HZXRQYXRoID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHN2Z0VsZW0uc2hvdygpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAobGFiZWwpIHtcblx0XHRcdFx0XHRwbG90TGluZS5sYWJlbCA9IGxhYmVsID0gbGFiZWwuZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChwYXRoICYmIHBhdGgubGVuZ3RoKSB7XG5cdFx0XHRwbG90TGluZS5zdmdFbGVtID0gc3ZnRWxlbSA9IHJlbmRlcmVyLnBhdGgocGF0aClcblx0XHRcdFx0LmF0dHIoYXR0cmlicykuYWRkKCk7XG5cblx0XHRcdC8vIGV2ZW50c1xuXHRcdFx0aWYgKGV2ZW50cykge1xuXHRcdFx0XHRhZGRFdmVudCA9IGZ1bmN0aW9uIChldmVudFR5cGUpIHtcblx0XHRcdFx0XHRzdmdFbGVtLm9uKGV2ZW50VHlwZSwgZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0XHRcdGV2ZW50c1tldmVudFR5cGVdLmFwcGx5KHBsb3RMaW5lLCBbZV0pO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRmb3IgKGV2ZW50VHlwZSBpbiBldmVudHMpIHtcblx0XHRcdFx0XHRhZGRFdmVudChldmVudFR5cGUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIHBsb3QgYmFuZC9saW5lIGxhYmVsXG5cdFx0aWYgKG9wdGlvbnNMYWJlbCAmJiBkZWZpbmVkKG9wdGlvbnNMYWJlbC50ZXh0KSAmJiBwYXRoICYmIHBhdGgubGVuZ3RoICYmIGF4aXMud2lkdGggPiAwICYmIGF4aXMuaGVpZ2h0ID4gMCkge1xuXHRcdFx0Ly8gYXBwbHkgZGVmYXVsdHNcblx0XHRcdG9wdGlvbnNMYWJlbCA9IG1lcmdlKHtcblx0XHRcdFx0YWxpZ246IGhvcml6ICYmIGlzQmFuZCAmJiAnY2VudGVyJyxcblx0XHRcdFx0eDogaG9yaXogPyAhaXNCYW5kICYmIDQgOiAxMCxcblx0XHRcdFx0dmVydGljYWxBbGlnbiA6ICFob3JpeiAmJiBpc0JhbmQgJiYgJ21pZGRsZScsXG5cdFx0XHRcdHk6IGhvcml6ID8gaXNCYW5kID8gMTYgOiAxMCA6IGlzQmFuZCA/IDYgOiAtNCxcblx0XHRcdFx0cm90YXRpb246IGhvcml6ICYmICFpc0JhbmQgJiYgOTBcblx0XHRcdH0sIG9wdGlvbnNMYWJlbCk7XG5cblx0XHRcdC8vIGFkZCB0aGUgU1ZHIGVsZW1lbnRcblx0XHRcdGlmICghbGFiZWwpIHtcblx0XHRcdFx0YXR0cmlicyA9IHtcblx0XHRcdFx0XHRhbGlnbjogb3B0aW9uc0xhYmVsLnRleHRBbGlnbiB8fCBvcHRpb25zTGFiZWwuYWxpZ24sXG5cdFx0XHRcdFx0cm90YXRpb246IG9wdGlvbnNMYWJlbC5yb3RhdGlvblxuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAoZGVmaW5lZCh6SW5kZXgpKSB7XG5cdFx0XHRcdFx0YXR0cmlicy56SW5kZXggPSB6SW5kZXg7XG5cdFx0XHRcdH1cblx0XHRcdFx0cGxvdExpbmUubGFiZWwgPSBsYWJlbCA9IHJlbmRlcmVyLnRleHQoXG5cdFx0XHRcdFx0XHRvcHRpb25zTGFiZWwudGV4dCxcblx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdFx0b3B0aW9uc0xhYmVsLnVzZUhUTUxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LmF0dHIoYXR0cmlicylcblx0XHRcdFx0XHQuY3NzKG9wdGlvbnNMYWJlbC5zdHlsZSlcblx0XHRcdFx0XHQuYWRkKCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGdldCB0aGUgYm91bmRpbmcgYm94IGFuZCBhbGlnbiB0aGUgbGFiZWxcblx0XHRcdC8vICMzMDAwIGNoYW5nZWQgdG8gYmV0dGVyIGhhbmRsZSBjaG9pY2UgYmV0d2VlbiBwbG90YmFuZCBvciBwbG90bGluZVxuXHRcdFx0eHMgPSBbcGF0aFsxXSwgcGF0aFs0XSwgKGlzQmFuZCA/IHBhdGhbNl0gOiBwYXRoWzFdKV07XG5cdFx0XHR5cyA9IFtwYXRoWzJdLCBwYXRoWzVdLCAoaXNCYW5kID8gcGF0aFs3XSA6IHBhdGhbMl0pXTtcblx0XHRcdHggPSBhcnJheU1pbih4cyk7XG5cdFx0XHR5ID0gYXJyYXlNaW4oeXMpO1xuXG5cdFx0XHRsYWJlbC5hbGlnbihvcHRpb25zTGFiZWwsIGZhbHNlLCB7XG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHksXG5cdFx0XHRcdHdpZHRoOiBhcnJheU1heCh4cykgLSB4LFxuXHRcdFx0XHRoZWlnaHQ6IGFycmF5TWF4KHlzKSAtIHlcblx0XHRcdH0pO1xuXHRcdFx0bGFiZWwuc2hvdygpO1xuXG5cdFx0fSBlbHNlIGlmIChsYWJlbCkgeyAvLyBtb3ZlIG91dCBvZiBzaWdodFxuXHRcdFx0bGFiZWwuaGlkZSgpO1xuXHRcdH1cblxuXHRcdC8vIGNoYWluYWJsZVxuXHRcdHJldHVybiBwbG90TGluZTtcblx0fSxcblxuXHQvKipcblx0ICogUmVtb3ZlIHRoZSBwbG90IGxpbmUgb3IgYmFuZFxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdC8vIHJlbW92ZSBpdCBmcm9tIHRoZSBsb29rdXBcblx0XHRlcmFzZSh0aGlzLmF4aXMucGxvdExpbmVzQW5kQmFuZHMsIHRoaXMpO1xuXHRcdFxuXHRcdGRlbGV0ZSB0aGlzLmF4aXM7XG5cdFx0ZGVzdHJveU9iamVjdFByb3BlcnRpZXModGhpcyk7XG5cdH1cbn07XG5cbi8qKlxuICogT2JqZWN0IHdpdGggbWVtYmVycyBmb3IgZXh0ZW5kaW5nIHRoZSBBeGlzIHByb3RvdHlwZVxuICovXG5cbkF4aXNQbG90TGluZU9yQmFuZEV4dGVuc2lvbiA9IHtcblxuXHQvKipcblx0ICogQ3JlYXRlIHRoZSBwYXRoIGZvciBhIHBsb3QgYmFuZFxuXHQgKi8gXG5cdGdldFBsb3RCYW5kUGF0aDogZnVuY3Rpb24gKGZyb20sIHRvKSB7XG5cdFx0dmFyIHRvUGF0aCA9IHRoaXMuZ2V0UGxvdExpbmVQYXRoKHRvKSxcblx0XHRcdHBhdGggPSB0aGlzLmdldFBsb3RMaW5lUGF0aChmcm9tKTtcblxuXHRcdGlmIChwYXRoICYmIHRvUGF0aCkge1xuXHRcdFx0cGF0aC5wdXNoKFxuXHRcdFx0XHR0b1BhdGhbNF0sXG5cdFx0XHRcdHRvUGF0aFs1XSxcblx0XHRcdFx0dG9QYXRoWzFdLFxuXHRcdFx0XHR0b1BhdGhbMl1cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHsgLy8gb3V0c2lkZSB0aGUgYXhpcyBhcmVhXG5cdFx0XHRwYXRoID0gbnVsbDtcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIHBhdGg7XG5cdH0sXG5cblx0YWRkUGxvdEJhbmQ6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkUGxvdEJhbmRPckxpbmUob3B0aW9ucywgJ3Bsb3RCYW5kcycpO1xuXHR9LFxuXHRcblx0YWRkUGxvdExpbmU6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkUGxvdEJhbmRPckxpbmUob3B0aW9ucywgJ3Bsb3RMaW5lcycpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgYSBwbG90IGJhbmQgb3IgcGxvdCBsaW5lIGFmdGVyIHJlbmRlciB0aW1lXG5cdCAqXG5cdCAqIEBwYXJhbSBvcHRpb25zIHtPYmplY3R9IFRoZSBwbG90QmFuZCBvciBwbG90TGluZSBjb25maWd1cmF0aW9uIG9iamVjdFxuXHQgKi9cblx0YWRkUGxvdEJhbmRPckxpbmU6IGZ1bmN0aW9uIChvcHRpb25zLCBjb2xsKSB7XG5cdFx0dmFyIG9iaiA9IG5ldyBIaWdoY2hhcnRzLlBsb3RMaW5lT3JCYW5kKHRoaXMsIG9wdGlvbnMpLnJlbmRlcigpLFxuXHRcdFx0dXNlck9wdGlvbnMgPSB0aGlzLnVzZXJPcHRpb25zO1xuXG5cdFx0aWYgKG9iaikgeyAvLyAjMjE4OVxuXHRcdFx0Ly8gQWRkIGl0IHRvIHRoZSB1c2VyIG9wdGlvbnMgZm9yIGV4cG9ydGluZyBhbmQgQXhpcy51cGRhdGVcblx0XHRcdGlmIChjb2xsKSB7XG5cdFx0XHRcdHVzZXJPcHRpb25zW2NvbGxdID0gdXNlck9wdGlvbnNbY29sbF0gfHwgW107XG5cdFx0XHRcdHVzZXJPcHRpb25zW2NvbGxdLnB1c2gob3B0aW9ucyk7IFxuXHRcdFx0fVxuXHRcdFx0dGhpcy5wbG90TGluZXNBbmRCYW5kcy5wdXNoKG9iaik7IFxuXHRcdH1cblx0XHRcblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYSBwbG90IGJhbmQgb3IgcGxvdCBsaW5lIGZyb20gdGhlIGNoYXJ0IGJ5IGlkXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpZFxuXHQgKi9cblx0cmVtb3ZlUGxvdEJhbmRPckxpbmU6IGZ1bmN0aW9uIChpZCkge1xuXHRcdHZhciBwbG90TGluZXNBbmRCYW5kcyA9IHRoaXMucGxvdExpbmVzQW5kQmFuZHMsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0dXNlck9wdGlvbnMgPSB0aGlzLnVzZXJPcHRpb25zLFxuXHRcdFx0aSA9IHBsb3RMaW5lc0FuZEJhbmRzLmxlbmd0aDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRpZiAocGxvdExpbmVzQW5kQmFuZHNbaV0uaWQgPT09IGlkKSB7XG5cdFx0XHRcdHBsb3RMaW5lc0FuZEJhbmRzW2ldLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0ZWFjaChbb3B0aW9ucy5wbG90TGluZXMgfHwgW10sIHVzZXJPcHRpb25zLnBsb3RMaW5lcyB8fCBbXSwgb3B0aW9ucy5wbG90QmFuZHMgfHwgW10sIHVzZXJPcHRpb25zLnBsb3RCYW5kcyB8fCBbXV0sIGZ1bmN0aW9uIChhcnIpIHtcblx0XHRcdGkgPSBhcnIubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRpZiAoYXJyW2ldLmlkID09PSBpZCkge1xuXHRcdFx0XHRcdGVyYXNlKGFyciwgYXJyW2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBheGlzIG9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0XG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5mdW5jdGlvbiBBeGlzKCkge1xuXHR0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuQXhpcy5wcm90b3R5cGUgPSB7XG5cblx0LyoqXG5cdCAqIERlZmF1bHQgb3B0aW9ucyBmb3IgdGhlIFggYXhpcyAtIHRoZSBZIGF4aXMgaGFzIGV4dGVuZGVkIGRlZmF1bHRzXG5cdCAqL1xuXHRkZWZhdWx0T3B0aW9uczoge1xuXHRcdC8vIGFsbG93RGVjaW1hbHM6IG51bGwsXG5cdFx0Ly8gYWx0ZXJuYXRlR3JpZENvbG9yOiBudWxsLFxuXHRcdC8vIGNhdGVnb3JpZXM6IFtdLFxuXHRcdGRhdGVUaW1lTGFiZWxGb3JtYXRzOiB7XG5cdFx0XHRtaWxsaXNlY29uZDogJyVIOiVNOiVTLiVMJyxcblx0XHRcdHNlY29uZDogJyVIOiVNOiVTJyxcblx0XHRcdG1pbnV0ZTogJyVIOiVNJyxcblx0XHRcdGhvdXI6ICclSDolTScsXG5cdFx0XHRkYXk6ICclZS4gJWInLFxuXHRcdFx0d2VlazogJyVlLiAlYicsXG5cdFx0XHRtb250aDogJyViIFxcJyV5Jyxcblx0XHRcdHllYXI6ICclWSdcblx0XHR9LFxuXHRcdGVuZE9uVGljazogZmFsc2UsXG5cdFx0Z3JpZExpbmVDb2xvcjogJyNDMEMwQzAnLFxuXHRcdC8vIGdyaWRMaW5lRGFzaFN0eWxlOiAnc29saWQnLFxuXHRcdC8vIGdyaWRMaW5lV2lkdGg6IDAsXG5cdFx0Ly8gcmV2ZXJzZWQ6IGZhbHNlLFxuXG5cdFx0bGFiZWxzOiBkZWZhdWx0TGFiZWxPcHRpb25zLFxuXHRcdFx0Ly8geyBzdGVwOiBudWxsIH0sXG5cdFx0bGluZUNvbG9yOiAnI0MwRDBFMCcsXG5cdFx0bGluZVdpZHRoOiAxLFxuXHRcdC8vbGlua2VkVG86IG51bGwsXG5cdFx0Ly9tYXg6IHVuZGVmaW5lZCxcblx0XHQvL21pbjogdW5kZWZpbmVkLFxuXHRcdG1pblBhZGRpbmc6IDAuMDEsXG5cdFx0bWF4UGFkZGluZzogMC4wMSxcblx0XHQvL21pblJhbmdlOiBudWxsLFxuXHRcdG1pbm9yR3JpZExpbmVDb2xvcjogJyNFMEUwRTAnLFxuXHRcdC8vIG1pbm9yR3JpZExpbmVEYXNoU3R5bGU6IG51bGwsXG5cdFx0bWlub3JHcmlkTGluZVdpZHRoOiAxLFxuXHRcdG1pbm9yVGlja0NvbG9yOiAnI0EwQTBBMCcsXG5cdFx0Ly9taW5vclRpY2tJbnRlcnZhbDogbnVsbCxcblx0XHRtaW5vclRpY2tMZW5ndGg6IDIsXG5cdFx0bWlub3JUaWNrUG9zaXRpb246ICdvdXRzaWRlJywgLy8gaW5zaWRlIG9yIG91dHNpZGVcblx0XHQvL21pbm9yVGlja1dpZHRoOiAwLFxuXHRcdC8vb3Bwb3NpdGU6IGZhbHNlLFxuXHRcdC8vb2Zmc2V0OiAwLFxuXHRcdC8vcGxvdEJhbmRzOiBbe1xuXHRcdC8vXHRldmVudHM6IHt9LFxuXHRcdC8vXHR6SW5kZXg6IDEsXG5cdFx0Ly9cdGxhYmVsczogeyBhbGlnbiwgeCwgdmVydGljYWxBbGlnbiwgeSwgc3R5bGUsIHJvdGF0aW9uLCB0ZXh0QWxpZ24gfVxuXHRcdC8vfV0sXG5cdFx0Ly9wbG90TGluZXM6IFt7XG5cdFx0Ly9cdGV2ZW50czoge31cblx0XHQvLyAgZGFzaFN0eWxlOiB7fVxuXHRcdC8vXHR6SW5kZXg6XG5cdFx0Ly9cdGxhYmVsczogeyBhbGlnbiwgeCwgdmVydGljYWxBbGlnbiwgeSwgc3R5bGUsIHJvdGF0aW9uLCB0ZXh0QWxpZ24gfVxuXHRcdC8vfV0sXG5cdFx0Ly9yZXZlcnNlZDogZmFsc2UsXG5cdFx0Ly8gc2hvd0ZpcnN0TGFiZWw6IHRydWUsXG5cdFx0Ly8gc2hvd0xhc3RMYWJlbDogdHJ1ZSxcblx0XHRzdGFydE9mV2VlazogMSxcblx0XHRzdGFydE9uVGljazogZmFsc2UsXG5cdFx0dGlja0NvbG9yOiAnI0MwRDBFMCcsXG5cdFx0Ly90aWNrSW50ZXJ2YWw6IG51bGwsXG5cdFx0dGlja0xlbmd0aDogMTAsXG5cdFx0dGlja21hcmtQbGFjZW1lbnQ6ICdiZXR3ZWVuJywgLy8gb24gb3IgYmV0d2VlblxuXHRcdHRpY2tQaXhlbEludGVydmFsOiAxMDAsXG5cdFx0dGlja1Bvc2l0aW9uOiAnb3V0c2lkZScsXG5cdFx0dGlja1dpZHRoOiAxLFxuXHRcdHRpdGxlOiB7XG5cdFx0XHQvL3RleHQ6IG51bGwsXG5cdFx0XHRhbGlnbjogJ21pZGRsZScsIC8vIGxvdywgbWlkZGxlIG9yIGhpZ2hcblx0XHRcdC8vbWFyZ2luOiAwIGZvciBob3Jpem9udGFsLCAxMCBmb3IgdmVydGljYWwgYXhlcyxcblx0XHRcdC8vcm90YXRpb246IDAsXG5cdFx0XHQvL3NpZGU6ICdvdXRzaWRlJyxcblx0XHRcdHN0eWxlOiB7XG5cdFx0XHRcdGNvbG9yOiAnIzcwNzA3MCdcblx0XHRcdH1cblx0XHRcdC8veDogMCxcblx0XHRcdC8veTogMFxuXHRcdH0sXG5cdFx0dHlwZTogJ2xpbmVhcicgLy8gbGluZWFyLCBsb2dhcml0aG1pYyBvciBkYXRldGltZVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGlzIG9wdGlvbnMgc2V0IGV4dGVuZHMgdGhlIGRlZmF1bHRPcHRpb25zIGZvciBZIGF4ZXNcblx0ICovXG5cdGRlZmF1bHRZQXhpc09wdGlvbnM6IHtcblx0XHRlbmRPblRpY2s6IHRydWUsXG5cdFx0Z3JpZExpbmVXaWR0aDogMSxcblx0XHR0aWNrUGl4ZWxJbnRlcnZhbDogNzIsXG5cdFx0c2hvd0xhc3RMYWJlbDogdHJ1ZSxcblx0XHRsYWJlbHM6IHtcblx0XHRcdHg6IC04LFxuXHRcdFx0eTogM1xuXHRcdH0sXG5cdFx0bGluZVdpZHRoOiAwLFxuXHRcdG1heFBhZGRpbmc6IDAuMDUsXG5cdFx0bWluUGFkZGluZzogMC4wNSxcblx0XHRzdGFydE9uVGljazogdHJ1ZSxcblx0XHR0aWNrV2lkdGg6IDAsXG5cdFx0dGl0bGU6IHtcblx0XHRcdHJvdGF0aW9uOiAyNzAsXG5cdFx0XHR0ZXh0OiAnVmFsdWVzJ1xuXHRcdH0sXG5cdFx0c3RhY2tMYWJlbHM6IHtcblx0XHRcdGVuYWJsZWQ6IGZhbHNlLFxuXHRcdFx0Ly9hbGlnbjogZHluYW1pYyxcblx0XHRcdC8veTogZHluYW1pYyxcblx0XHRcdC8veDogZHluYW1pYyxcblx0XHRcdC8vdmVydGljYWxBbGlnbjogZHluYW1pYyxcblx0XHRcdC8vdGV4dEFsaWduOiBkeW5hbWljLFxuXHRcdFx0Ly9yb3RhdGlvbjogMCxcblx0XHRcdGZvcm1hdHRlcjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRyZXR1cm4gbnVtYmVyRm9ybWF0KHRoaXMudG90YWwsIC0xKTtcblx0XHRcdH0sXG5cdFx0XHRzdHlsZTogZGVmYXVsdExhYmVsT3B0aW9ucy5zdHlsZVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogVGhlc2Ugb3B0aW9ucyBleHRlbmQgdGhlIGRlZmF1bHRPcHRpb25zIGZvciBsZWZ0IGF4ZXNcblx0ICovXG5cdGRlZmF1bHRMZWZ0QXhpc09wdGlvbnM6IHtcblx0XHRsYWJlbHM6IHtcblx0XHRcdHg6IC0xNSxcblx0XHRcdHk6IG51bGxcblx0XHR9LFxuXHRcdHRpdGxlOiB7XG5cdFx0XHRyb3RhdGlvbjogMjcwXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGVzZSBvcHRpb25zIGV4dGVuZCB0aGUgZGVmYXVsdE9wdGlvbnMgZm9yIHJpZ2h0IGF4ZXNcblx0ICovXG5cdGRlZmF1bHRSaWdodEF4aXNPcHRpb25zOiB7XG5cdFx0bGFiZWxzOiB7XG5cdFx0XHR4OiAxNSxcblx0XHRcdHk6IG51bGxcblx0XHR9LFxuXHRcdHRpdGxlOiB7XG5cdFx0XHRyb3RhdGlvbjogOTBcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRoZXNlIG9wdGlvbnMgZXh0ZW5kIHRoZSBkZWZhdWx0T3B0aW9ucyBmb3IgYm90dG9tIGF4ZXNcblx0ICovXG5cdGRlZmF1bHRCb3R0b21BeGlzT3B0aW9uczoge1xuXHRcdGxhYmVsczoge1xuXHRcdFx0eDogMCxcblx0XHRcdHk6IG51bGwgLy8gYmFzZWQgb24gZm9udCBzaXplXG5cdFx0XHQvLyBvdmVyZmxvdzogdW5kZWZpbmVkLFxuXHRcdFx0Ly8gc3RhZ2dlckxpbmVzOiBudWxsXG5cdFx0fSxcblx0XHR0aXRsZToge1xuXHRcdFx0cm90YXRpb246IDBcblx0XHR9XG5cdH0sXG5cdC8qKlxuXHQgKiBUaGVzZSBvcHRpb25zIGV4dGVuZCB0aGUgZGVmYXVsdE9wdGlvbnMgZm9yIGxlZnQgYXhlc1xuXHQgKi9cblx0ZGVmYXVsdFRvcEF4aXNPcHRpb25zOiB7XG5cdFx0bGFiZWxzOiB7XG5cdFx0XHR4OiAwLFxuXHRcdFx0eTogLTE1XG5cdFx0XHQvLyBvdmVyZmxvdzogdW5kZWZpbmVkXG5cdFx0XHQvLyBzdGFnZ2VyTGluZXM6IG51bGxcblx0XHR9LFxuXHRcdHRpdGxlOiB7XG5cdFx0XHRyb3RhdGlvbjogMFxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgYXhpc1xuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGNoYXJ0LCB1c2VyT3B0aW9ucykge1xuXG5cblx0XHR2YXIgaXNYQXhpcyA9IHVzZXJPcHRpb25zLmlzWCxcblx0XHRcdGF4aXMgPSB0aGlzO1xuXG5cdFx0Ly8gRmxhZywgaXMgdGhlIGF4aXMgaG9yaXpvbnRhbFxuXHRcdGF4aXMuaG9yaXogPSBjaGFydC5pbnZlcnRlZCA/ICFpc1hBeGlzIDogaXNYQXhpcztcblxuXHRcdC8vIEZsYWcsIGlzWEF4aXNcblx0XHRheGlzLmlzWEF4aXMgPSBpc1hBeGlzO1xuXHRcdGF4aXMuY29sbCA9IGlzWEF4aXMgPyAneEF4aXMnIDogJ3lBeGlzJztcblxuXHRcdGF4aXMub3Bwb3NpdGUgPSB1c2VyT3B0aW9ucy5vcHBvc2l0ZTsgLy8gbmVlZGVkIGluIHNldE9wdGlvbnNcblx0XHRheGlzLnNpZGUgPSB1c2VyT3B0aW9ucy5zaWRlIHx8IChheGlzLmhvcml6ID9cblx0XHRcdFx0KGF4aXMub3Bwb3NpdGUgPyAwIDogMikgOiAvLyB0b3AgOiBib3R0b21cblx0XHRcdFx0KGF4aXMub3Bwb3NpdGUgPyAxIDogMykpOyAgLy8gcmlnaHQgOiBsZWZ0XG5cblx0XHRheGlzLnNldE9wdGlvbnModXNlck9wdGlvbnMpO1xuXG5cblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdHR5cGUgPSBvcHRpb25zLnR5cGUsXG5cdFx0XHRpc0RhdGV0aW1lQXhpcyA9IHR5cGUgPT09ICdkYXRldGltZSc7XG5cblx0XHRheGlzLmxhYmVsRm9ybWF0dGVyID0gb3B0aW9ucy5sYWJlbHMuZm9ybWF0dGVyIHx8IGF4aXMuZGVmYXVsdExhYmVsRm9ybWF0dGVyOyAvLyBjYW4gYmUgb3ZlcndyaXR0ZW4gYnkgZHluYW1pYyBmb3JtYXRcblxuXG5cdFx0Ly8gRmxhZywgc3RhZ2dlciBsaW5lcyBvciBub3Rcblx0XHRheGlzLnVzZXJPcHRpb25zID0gdXNlck9wdGlvbnM7XG5cblx0XHQvL2F4aXMuYXhpc1RpdGxlTWFyZ2luID0gVU5ERUZJTkVELC8vID0gb3B0aW9ucy50aXRsZS5tYXJnaW4sXG5cdFx0YXhpcy5taW5QaXhlbFBhZGRpbmcgPSAwO1xuXHRcdC8vYXhpcy5pZ25vcmVNaW5QYWRkaW5nID0gVU5ERUZJTkVEOyAvLyBjYW4gYmUgc2V0IHRvIHRydWUgYnkgYSBjb2x1bW4gb3IgYmFyIHNlcmllc1xuXHRcdC8vYXhpcy5pZ25vcmVNYXhQYWRkaW5nID0gVU5ERUZJTkVEO1xuXG5cdFx0YXhpcy5jaGFydCA9IGNoYXJ0O1xuXHRcdGF4aXMucmV2ZXJzZWQgPSBvcHRpb25zLnJldmVyc2VkO1xuXHRcdGF4aXMuem9vbUVuYWJsZWQgPSBvcHRpb25zLnpvb21FbmFibGVkICE9PSBmYWxzZTtcblxuXHRcdC8vIEluaXRpYWwgY2F0ZWdvcmllc1xuXHRcdGF4aXMuY2F0ZWdvcmllcyA9IG9wdGlvbnMuY2F0ZWdvcmllcyB8fCB0eXBlID09PSAnY2F0ZWdvcnknO1xuXHRcdGF4aXMubmFtZXMgPSBbXTtcblxuXHRcdC8vIEVsZW1lbnRzXG5cdFx0Ly9heGlzLmF4aXNHcm91cCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMuZ3JpZEdyb3VwID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5heGlzVGl0bGUgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLmF4aXNMaW5lID0gVU5ERUZJTkVEO1xuXG5cdFx0Ly8gU2hvcnRoYW5kIHR5cGVzXG5cdFx0YXhpcy5pc0xvZyA9IHR5cGUgPT09ICdsb2dhcml0aG1pYyc7XG5cdFx0YXhpcy5pc0RhdGV0aW1lQXhpcyA9IGlzRGF0ZXRpbWVBeGlzO1xuXG5cdFx0Ly8gRmxhZywgaWYgYXhpcyBpcyBsaW5rZWQgdG8gYW5vdGhlciBheGlzXG5cdFx0YXhpcy5pc0xpbmtlZCA9IGRlZmluZWQob3B0aW9ucy5saW5rZWRUbyk7XG5cdFx0Ly8gTGlua2VkIGF4aXMuXG5cdFx0Ly9heGlzLmxpbmtlZFBhcmVudCA9IFVOREVGSU5FRDtcblxuXHRcdC8vIFRpY2sgcG9zaXRpb25zXG5cdFx0Ly9heGlzLnRpY2tQb3NpdGlvbnMgPSBVTkRFRklORUQ7IC8vIGFycmF5IGNvbnRhaW5pbmcgcHJlZGVmaW5lZCBwb3NpdGlvbnNcblx0XHQvLyBUaWNrIGludGVydmFsc1xuXHRcdC8vYXhpcy50aWNrSW50ZXJ2YWwgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLm1pbm9yVGlja0ludGVydmFsID0gVU5ERUZJTkVEO1xuXG5cdFx0YXhpcy50aWNrbWFya09mZnNldCA9IChheGlzLmNhdGVnb3JpZXMgJiYgb3B0aW9ucy50aWNrbWFya1BsYWNlbWVudCA9PT0gJ2JldHdlZW4nICYmIFxuXHRcdFx0cGljayhvcHRpb25zLnRpY2tJbnRlcnZhbCwgMSkgPT09IDEpID8gMC41IDogMDsgLy8gIzMyMDJcblxuXHRcdC8vIE1ham9yIHRpY2tzXG5cdFx0YXhpcy50aWNrcyA9IHt9O1xuXHRcdGF4aXMubGFiZWxFZGdlID0gW107XG5cdFx0Ly8gTWlub3IgdGlja3Ncblx0XHRheGlzLm1pbm9yVGlja3MgPSB7fTtcblx0XHQvL2F4aXMudGlja0Ftb3VudCA9IFVOREVGSU5FRDtcblxuXHRcdC8vIExpc3Qgb2YgcGxvdExpbmVzL0JhbmRzXG5cdFx0YXhpcy5wbG90TGluZXNBbmRCYW5kcyA9IFtdO1xuXG5cdFx0Ly8gQWx0ZXJuYXRlIGJhbmRzXG5cdFx0YXhpcy5hbHRlcm5hdGVCYW5kcyA9IHt9O1xuXG5cdFx0Ly8gQXhpcyBtZXRyaWNzXG5cdFx0Ly9heGlzLmxlZnQgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLnRvcCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMud2lkdGggPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLmhlaWdodCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMuYm90dG9tID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5yaWdodCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMudHJhbnNBID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy50cmFuc0IgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLm9sZFRyYW5zQSA9IFVOREVGSU5FRDtcblx0XHRheGlzLmxlbiA9IDA7XG5cdFx0Ly9heGlzLm9sZE1pbiA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMub2xkTWF4ID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5vbGRVc2VyTWluID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5vbGRVc2VyTWF4ID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5vbGRBeGlzTGVuZ3RoID0gVU5ERUZJTkVEO1xuXHRcdGF4aXMubWluUmFuZ2UgPSBheGlzLnVzZXJNaW5SYW5nZSA9IG9wdGlvbnMubWluUmFuZ2UgfHwgb3B0aW9ucy5tYXhab29tO1xuXHRcdGF4aXMucmFuZ2UgPSBvcHRpb25zLnJhbmdlO1xuXHRcdGF4aXMub2Zmc2V0ID0gb3B0aW9ucy5vZmZzZXQgfHwgMDtcblxuXG5cdFx0Ly8gRGljdGlvbmFyeSBmb3Igc3RhY2tzXG5cdFx0YXhpcy5zdGFja3MgPSB7fTtcblx0XHRheGlzLm9sZFN0YWNrcyA9IHt9O1xuXHRcdFxuXHRcdC8vIE1pbiBhbmQgbWF4IGluIHRoZSBkYXRhXG5cdFx0Ly9heGlzLmRhdGFNaW4gPSBVTkRFRklORUQsXG5cdFx0Ly9heGlzLmRhdGFNYXggPSBVTkRFRklORUQsXG5cblx0XHQvLyBUaGUgYXhpcyByYW5nZVxuXHRcdGF4aXMubWF4ID0gbnVsbDtcblx0XHRheGlzLm1pbiA9IG51bGw7XG5cblx0XHQvLyBVc2VyIHNldCBtaW4gYW5kIG1heFxuXHRcdC8vYXhpcy51c2VyTWluID0gVU5ERUZJTkVELFxuXHRcdC8vYXhpcy51c2VyTWF4ID0gVU5ERUZJTkVELFxuXG5cdFx0Ly8gQ3Jvc3NoYWlyIG9wdGlvbnNcblx0XHRheGlzLmNyb3NzaGFpciA9IHBpY2sob3B0aW9ucy5jcm9zc2hhaXIsIHNwbGF0KGNoYXJ0Lm9wdGlvbnMudG9vbHRpcC5jcm9zc2hhaXJzKVtpc1hBeGlzID8gMCA6IDFdLCBmYWxzZSk7XG5cdFx0Ly8gUnVuIEF4aXNcblxuXHRcdHZhciBldmVudFR5cGUsXG5cdFx0XHRldmVudHMgPSBheGlzLm9wdGlvbnMuZXZlbnRzO1xuXG5cdFx0Ly8gUmVnaXN0ZXJcblx0XHRpZiAoaW5BcnJheShheGlzLCBjaGFydC5heGVzKSA9PT0gLTEpIHsgLy8gZG9uJ3QgYWRkIGl0IGFnYWluIG9uIEF4aXMudXBkYXRlKClcblx0XHRcdGlmIChpc1hBeGlzICYmICF0aGlzLmlzQ29sb3JBeGlzKSB7IC8vICMyNzEzXG5cdFx0XHRcdGNoYXJ0LmF4ZXMuc3BsaWNlKGNoYXJ0LnhBeGlzLmxlbmd0aCwgMCwgYXhpcyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjaGFydC5heGVzLnB1c2goYXhpcyk7XG5cdFx0XHR9XG5cblx0XHRcdGNoYXJ0W2F4aXMuY29sbF0ucHVzaChheGlzKTtcblx0XHR9XG5cblx0XHRheGlzLnNlcmllcyA9IGF4aXMuc2VyaWVzIHx8IFtdOyAvLyBwb3B1bGF0ZWQgYnkgU2VyaWVzXG5cblx0XHQvLyBpbnZlcnRlZCBjaGFydHMgaGF2ZSByZXZlcnNlZCB4QXhlcyBhcyBkZWZhdWx0XG5cdFx0aWYgKGNoYXJ0LmludmVydGVkICYmIGlzWEF4aXMgJiYgYXhpcy5yZXZlcnNlZCA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRheGlzLnJldmVyc2VkID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRheGlzLnJlbW92ZVBsb3RCYW5kID0gYXhpcy5yZW1vdmVQbG90QmFuZE9yTGluZTtcblx0XHRheGlzLnJlbW92ZVBsb3RMaW5lID0gYXhpcy5yZW1vdmVQbG90QmFuZE9yTGluZTtcblxuXG5cdFx0Ly8gcmVnaXN0ZXIgZXZlbnQgbGlzdGVuZXJzXG5cdFx0Zm9yIChldmVudFR5cGUgaW4gZXZlbnRzKSB7XG5cdFx0XHRhZGRFdmVudChheGlzLCBldmVudFR5cGUsIGV2ZW50c1tldmVudFR5cGVdKTtcblx0XHR9XG5cblx0XHQvLyBleHRlbmQgbG9nYXJpdGhtaWMgYXhpc1xuXHRcdGlmIChheGlzLmlzTG9nKSB7XG5cdFx0XHRheGlzLnZhbDJsaW4gPSBsb2cybGluO1xuXHRcdFx0YXhpcy5saW4ydmFsID0gbGluMmxvZztcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIE1lcmdlIGFuZCBzZXQgb3B0aW9uc1xuXHQgKi9cblx0c2V0T3B0aW9uczogZnVuY3Rpb24gKHVzZXJPcHRpb25zKSB7XG5cdFx0dGhpcy5vcHRpb25zID0gbWVyZ2UoXG5cdFx0XHR0aGlzLmRlZmF1bHRPcHRpb25zLFxuXHRcdFx0dGhpcy5pc1hBeGlzID8ge30gOiB0aGlzLmRlZmF1bHRZQXhpc09wdGlvbnMsXG5cdFx0XHRbdGhpcy5kZWZhdWx0VG9wQXhpc09wdGlvbnMsIHRoaXMuZGVmYXVsdFJpZ2h0QXhpc09wdGlvbnMsXG5cdFx0XHRcdHRoaXMuZGVmYXVsdEJvdHRvbUF4aXNPcHRpb25zLCB0aGlzLmRlZmF1bHRMZWZ0QXhpc09wdGlvbnNdW3RoaXMuc2lkZV0sXG5cdFx0XHRtZXJnZShcblx0XHRcdFx0ZGVmYXVsdE9wdGlvbnNbdGhpcy5jb2xsXSwgLy8gaWYgc2V0IGluIHNldE9wdGlvbnMgKCMxMDUzKVxuXHRcdFx0XHR1c2VyT3B0aW9uc1xuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRoZSBkZWZhdWx0IGxhYmVsIGZvcm1hdHRlci4gVGhlIGNvbnRleHQgaXMgYSBzcGVjaWFsIGNvbmZpZyBvYmplY3QgZm9yIHRoZSBsYWJlbC5cblx0ICovXG5cdGRlZmF1bHRMYWJlbEZvcm1hdHRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcy5heGlzLFxuXHRcdFx0dmFsdWUgPSB0aGlzLnZhbHVlLFxuXHRcdFx0Y2F0ZWdvcmllcyA9IGF4aXMuY2F0ZWdvcmllcyxcblx0XHRcdGRhdGVUaW1lTGFiZWxGb3JtYXQgPSB0aGlzLmRhdGVUaW1lTGFiZWxGb3JtYXQsXG5cdFx0XHRudW1lcmljU3ltYm9scyA9IGRlZmF1bHRPcHRpb25zLmxhbmcubnVtZXJpY1N5bWJvbHMsXG5cdFx0XHRpID0gbnVtZXJpY1N5bWJvbHMgJiYgbnVtZXJpY1N5bWJvbHMubGVuZ3RoLFxuXHRcdFx0bXVsdGksXG5cdFx0XHRyZXQsXG5cdFx0XHRmb3JtYXRPcHRpb24gPSBheGlzLm9wdGlvbnMubGFiZWxzLmZvcm1hdCxcblxuXHRcdFx0Ly8gbWFrZSBzdXJlIHRoZSBzYW1lIHN5bWJvbCBpcyBhZGRlZCBmb3IgYWxsIGxhYmVscyBvbiBhIGxpbmVhciBheGlzXG5cdFx0XHRudW1lcmljU3ltYm9sRGV0ZWN0b3IgPSBheGlzLmlzTG9nID8gdmFsdWUgOiBheGlzLnRpY2tJbnRlcnZhbDtcblxuXHRcdGlmIChmb3JtYXRPcHRpb24pIHtcblx0XHRcdHJldCA9IGZvcm1hdChmb3JtYXRPcHRpb24sIHRoaXMpO1xuXG5cdFx0fSBlbHNlIGlmIChjYXRlZ29yaWVzKSB7XG5cdFx0XHRyZXQgPSB2YWx1ZTtcblxuXHRcdH0gZWxzZSBpZiAoZGF0ZVRpbWVMYWJlbEZvcm1hdCkgeyAvLyBkYXRldGltZSBheGlzXG5cdFx0XHRyZXQgPSBkYXRlRm9ybWF0KGRhdGVUaW1lTGFiZWxGb3JtYXQsIHZhbHVlKTtcblxuXHRcdH0gZWxzZSBpZiAoaSAmJiBudW1lcmljU3ltYm9sRGV0ZWN0b3IgPj0gMTAwMCkge1xuXHRcdFx0Ly8gRGVjaWRlIHdoZXRoZXIgd2Ugc2hvdWxkIGFkZCBhIG51bWVyaWMgc3ltYm9sIGxpa2UgayAodGhvdXNhbmRzKSBvciBNIChtaWxsaW9ucykuXG5cdFx0XHQvLyBJZiB3ZSBhcmUgdG8gZW5hYmxlIHRoaXMgaW4gdG9vbHRpcCBvciBvdGhlciBwbGFjZXMgYXMgd2VsbCwgd2UgY2FuIG1vdmUgdGhpc1xuXHRcdFx0Ly8gbG9naWMgdG8gdGhlIG51bWJlckZvcm1hdHRlciBhbmQgZW5hYmxlIGl0IGJ5IGEgcGFyYW1ldGVyLlxuXHRcdFx0d2hpbGUgKGktLSAmJiByZXQgPT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRtdWx0aSA9IE1hdGgucG93KDEwMDAsIGkgKyAxKTtcblx0XHRcdFx0aWYgKG51bWVyaWNTeW1ib2xEZXRlY3RvciA+PSBtdWx0aSAmJiBudW1lcmljU3ltYm9sc1tpXSAhPT0gbnVsbCkge1xuXHRcdFx0XHRcdHJldCA9IG51bWJlckZvcm1hdCh2YWx1ZSAvIG11bHRpLCAtMSkgKyBudW1lcmljU3ltYm9sc1tpXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChyZXQgPT09IFVOREVGSU5FRCkge1xuXHRcdFx0aWYgKG1hdGhBYnModmFsdWUpID49IDEwMDAwKSB7IC8vIGFkZCB0aG91c2FuZHMgc2VwYXJhdG9yc1xuXHRcdFx0XHRyZXQgPSBudW1iZXJGb3JtYXQodmFsdWUsIDApO1xuXG5cdFx0XHR9IGVsc2UgeyAvLyBzbWFsbCBudW1iZXJzXG5cdFx0XHRcdHJldCA9IG51bWJlckZvcm1hdCh2YWx1ZSwgLTEsIFVOREVGSU5FRCwgJycpOyAvLyAjMjQ2NlxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBmb3IgdGhlIHNlcmllcyBvZiBlYWNoIGF4aXNcblx0ICovXG5cdGdldFNlcmllc0V4dHJlbWVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0O1xuXG5cdFx0YXhpcy5oYXNWaXNpYmxlU2VyaWVzID0gZmFsc2U7XG5cblx0XHQvLyBSZXNldCBwcm9wZXJ0aWVzIGluIGNhc2Ugd2UncmUgcmVkcmF3aW5nICgjMzM1Mylcblx0XHRheGlzLmRhdGFNaW4gPSBheGlzLmRhdGFNYXggPSBheGlzLmlnbm9yZU1pblBhZGRpbmcgPSBheGlzLmlnbm9yZU1heFBhZGRpbmcgPSBudWxsO1xuXHRcdFxuXHRcdGlmIChheGlzLmJ1aWxkU3RhY2tzKSB7XG5cdFx0XHRheGlzLmJ1aWxkU3RhY2tzKCk7XG5cdFx0fVxuXG5cdFx0Ly8gbG9vcCB0aHJvdWdoIHRoaXMgYXhpcycgc2VyaWVzXG5cdFx0ZWFjaChheGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXG5cdFx0XHRpZiAoc2VyaWVzLnZpc2libGUgfHwgIWNoYXJ0Lm9wdGlvbnMuY2hhcnQuaWdub3JlSGlkZGVuU2VyaWVzKSB7XG5cblx0XHRcdFx0dmFyIHNlcmllc09wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdFx0XHR4RGF0YSxcblx0XHRcdFx0XHR0aHJlc2hvbGQgPSBzZXJpZXNPcHRpb25zLnRocmVzaG9sZCxcblx0XHRcdFx0XHRzZXJpZXNEYXRhTWluLFxuXHRcdFx0XHRcdHNlcmllc0RhdGFNYXg7XG5cblx0XHRcdFx0YXhpcy5oYXNWaXNpYmxlU2VyaWVzID0gdHJ1ZTtcblxuXHRcdFx0XHQvLyBWYWxpZGF0ZSB0aHJlc2hvbGQgaW4gbG9nYXJpdGhtaWMgYXhlc1xuXHRcdFx0XHRpZiAoYXhpcy5pc0xvZyAmJiB0aHJlc2hvbGQgPD0gMCkge1xuXHRcdFx0XHRcdHRocmVzaG9sZCA9IG51bGw7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBHZXQgZGF0YU1pbiBhbmQgZGF0YU1heCBmb3IgWCBheGVzXG5cdFx0XHRcdGlmIChheGlzLmlzWEF4aXMpIHtcblx0XHRcdFx0XHR4RGF0YSA9IHNlcmllcy54RGF0YTtcblx0XHRcdFx0XHRpZiAoeERhdGEubGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRheGlzLmRhdGFNaW4gPSBtYXRoTWluKHBpY2soYXhpcy5kYXRhTWluLCB4RGF0YVswXSksIGFycmF5TWluKHhEYXRhKSk7XG5cdFx0XHRcdFx0XHRheGlzLmRhdGFNYXggPSBtYXRoTWF4KHBpY2soYXhpcy5kYXRhTWF4LCB4RGF0YVswXSksIGFycmF5TWF4KHhEYXRhKSk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkYXRhTWluIGFuZCBkYXRhTWF4IGZvciBZIGF4ZXMsIGFzIHdlbGwgYXMgaGFuZGxlIHN0YWNraW5nIGFuZCBwcm9jZXNzZWQgZGF0YVxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHRoaXMgcGFydGljdWxhciBzZXJpZXMgZXh0cmVtZXNcblx0XHRcdFx0XHRzZXJpZXMuZ2V0RXh0cmVtZXMoKTtcblx0XHRcdFx0XHRzZXJpZXNEYXRhTWF4ID0gc2VyaWVzLmRhdGFNYXg7XG5cdFx0XHRcdFx0c2VyaWVzRGF0YU1pbiA9IHNlcmllcy5kYXRhTWluO1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBkYXRhTWluIGFuZCBkYXRhTWF4IHNvIGZhci4gSWYgcGVyY2VudGFnZSBpcyB1c2VkLCB0aGUgbWluIGFuZCBtYXggYXJlXG5cdFx0XHRcdFx0Ly8gYWx3YXlzIDAgYW5kIDEwMC4gSWYgc2VyaWVzRGF0YU1pbiBhbmQgc2VyaWVzRGF0YU1heCBpcyBudWxsLCB0aGVuIHNlcmllc1xuXHRcdFx0XHRcdC8vIGRvZXNuJ3QgaGF2ZSBhY3RpdmUgeSBkYXRhLCB3ZSBjb250aW51ZSB3aXRoIG51bGxzXG5cdFx0XHRcdFx0aWYgKGRlZmluZWQoc2VyaWVzRGF0YU1pbikgJiYgZGVmaW5lZChzZXJpZXNEYXRhTWF4KSkge1xuXHRcdFx0XHRcdFx0YXhpcy5kYXRhTWluID0gbWF0aE1pbihwaWNrKGF4aXMuZGF0YU1pbiwgc2VyaWVzRGF0YU1pbiksIHNlcmllc0RhdGFNaW4pO1xuXHRcdFx0XHRcdFx0YXhpcy5kYXRhTWF4ID0gbWF0aE1heChwaWNrKGF4aXMuZGF0YU1heCwgc2VyaWVzRGF0YU1heCksIHNlcmllc0RhdGFNYXgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEFkanVzdCB0byB0aHJlc2hvbGRcblx0XHRcdFx0XHRpZiAoZGVmaW5lZCh0aHJlc2hvbGQpKSB7XG5cdFx0XHRcdFx0XHRpZiAoYXhpcy5kYXRhTWluID49IHRocmVzaG9sZCkge1xuXHRcdFx0XHRcdFx0XHRheGlzLmRhdGFNaW4gPSB0aHJlc2hvbGQ7XG5cdFx0XHRcdFx0XHRcdGF4aXMuaWdub3JlTWluUGFkZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKGF4aXMuZGF0YU1heCA8IHRocmVzaG9sZCkge1xuXHRcdFx0XHRcdFx0XHRheGlzLmRhdGFNYXggPSB0aHJlc2hvbGQ7XG5cdFx0XHRcdFx0XHRcdGF4aXMuaWdub3JlTWF4UGFkZGluZyA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRyYW5zbGF0ZSBmcm9tIGF4aXMgdmFsdWUgdG8gcGl4ZWwgcG9zaXRpb24gb24gdGhlIGNoYXJ0LCBvciBiYWNrXG5cdCAqXG5cdCAqL1xuXHR0cmFuc2xhdGU6IGZ1bmN0aW9uICh2YWwsIGJhY2t3YXJkcywgY3ZzQ29vcmQsIG9sZCwgaGFuZGxlTG9nLCBwb2ludFBsYWNlbWVudCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdHNpZ24gPSAxLFxuXHRcdFx0Y3ZzT2Zmc2V0ID0gMCxcblx0XHRcdGxvY2FsQSA9IG9sZCA/IGF4aXMub2xkVHJhbnNBIDogYXhpcy50cmFuc0EsXG5cdFx0XHRsb2NhbE1pbiA9IG9sZCA/IGF4aXMub2xkTWluIDogYXhpcy5taW4sXG5cdFx0XHRyZXR1cm5WYWx1ZSxcblx0XHRcdG1pblBpeGVsUGFkZGluZyA9IGF4aXMubWluUGl4ZWxQYWRkaW5nLFxuXHRcdFx0cG9zdFRyYW5zbGF0ZSA9IChheGlzLm9wdGlvbnMub3JkaW5hbCB8fCAoYXhpcy5pc0xvZyAmJiBoYW5kbGVMb2cpKSAmJiBheGlzLmxpbjJ2YWw7XG5cblx0XHRpZiAoIWxvY2FsQSkge1xuXHRcdFx0bG9jYWxBID0gYXhpcy50cmFuc0E7XG5cdFx0fVxuXG5cdFx0Ly8gSW4gdmVydGljYWwgYXhlcywgdGhlIGNhbnZhcyBjb29yZGluYXRlcyBzdGFydCBmcm9tIDAgYXQgdGhlIHRvcCBsaWtlIGluXG5cdFx0Ly8gU1ZHLlxuXHRcdGlmIChjdnNDb29yZCkge1xuXHRcdFx0c2lnbiAqPSAtMTsgLy8gY2FudmFzIGNvb3JkaW5hdGVzIGludmVydHMgdGhlIHZhbHVlXG5cdFx0XHRjdnNPZmZzZXQgPSBheGlzLmxlbjtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgcmV2ZXJzZWQgYXhpc1xuXHRcdGlmIChheGlzLnJldmVyc2VkKSB7XG5cdFx0XHRzaWduICo9IC0xO1xuXHRcdFx0Y3ZzT2Zmc2V0IC09IHNpZ24gKiAoYXhpcy5zZWN0b3IgfHwgYXhpcy5sZW4pO1xuXHRcdH1cblxuXHRcdC8vIEZyb20gcGl4ZWxzIHRvIHZhbHVlXG5cdFx0aWYgKGJhY2t3YXJkcykgeyAvLyByZXZlcnNlIHRyYW5zbGF0aW9uXG5cblx0XHRcdHZhbCA9IHZhbCAqIHNpZ24gKyBjdnNPZmZzZXQ7XG5cdFx0XHR2YWwgLT0gbWluUGl4ZWxQYWRkaW5nO1xuXHRcdFx0cmV0dXJuVmFsdWUgPSB2YWwgLyBsb2NhbEEgKyBsb2NhbE1pbjsgLy8gZnJvbSBjaGFydCBwaXhlbCB0byB2YWx1ZVxuXHRcdFx0aWYgKHBvc3RUcmFuc2xhdGUpIHsgLy8gbG9nIGFuZCBvcmRpbmFsIGF4ZXNcblx0XHRcdFx0cmV0dXJuVmFsdWUgPSBheGlzLmxpbjJ2YWwocmV0dXJuVmFsdWUpO1xuXHRcdFx0fVxuXG5cdFx0Ly8gRnJvbSB2YWx1ZSB0byBwaXhlbHNcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKHBvc3RUcmFuc2xhdGUpIHsgLy8gbG9nIGFuZCBvcmRpbmFsIGF4ZXNcblx0XHRcdFx0dmFsID0gYXhpcy52YWwybGluKHZhbCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAocG9pbnRQbGFjZW1lbnQgPT09ICdiZXR3ZWVuJykge1xuXHRcdFx0XHRwb2ludFBsYWNlbWVudCA9IDAuNTtcblx0XHRcdH1cblx0XHRcdHJldHVyblZhbHVlID0gc2lnbiAqICh2YWwgLSBsb2NhbE1pbikgKiBsb2NhbEEgKyBjdnNPZmZzZXQgKyAoc2lnbiAqIG1pblBpeGVsUGFkZGluZykgK1xuXHRcdFx0XHQoaXNOdW1iZXIocG9pbnRQbGFjZW1lbnQpID8gbG9jYWxBICogcG9pbnRQbGFjZW1lbnQgKiBheGlzLnBvaW50UmFuZ2UgOiAwKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcmV0dXJuVmFsdWU7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFV0aWxpdHkgbWV0aG9kIHRvIHRyYW5zbGF0ZSBhbiBheGlzIHZhbHVlIHRvIHBpeGVsIHBvc2l0aW9uLlxuXHQgKiBAcGFyYW0ge051bWJlcn0gdmFsdWUgQSB2YWx1ZSBpbiB0ZXJtcyBvZiBheGlzIHVuaXRzXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcGFuZUNvb3JkaW5hdGVzIFdoZXRoZXIgdG8gcmV0dXJuIHRoZSBwaXhlbCBjb29yZGluYXRlIHJlbGF0aXZlIHRvIHRoZSBjaGFydFxuXHQgKiAgICAgICAgb3IganVzdCB0aGUgYXhpcy9wYW5lIGl0c2VsZi5cblx0ICovXG5cdHRvUGl4ZWxzOiBmdW5jdGlvbiAodmFsdWUsIHBhbmVDb29yZGluYXRlcykge1xuXHRcdHJldHVybiB0aGlzLnRyYW5zbGF0ZSh2YWx1ZSwgZmFsc2UsICF0aGlzLmhvcml6LCBudWxsLCB0cnVlKSArIChwYW5lQ29vcmRpbmF0ZXMgPyAwIDogdGhpcy5wb3MpO1xuXHR9LFxuXG5cdC8qXG5cdCAqIFV0aWxpdHkgbWV0aG9kIHRvIHRyYW5zbGF0ZSBhIHBpeGVsIHBvc2l0aW9uIGluIHRvIGFuIGF4aXMgdmFsdWVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHBpeGVsIFRoZSBwaXhlbCB2YWx1ZSBjb29yZGluYXRlXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcGFuZUNvb3JkaWFudGVzIFdoZXRoZXIgdGhlIGlucHV0IHBpeGVsIGlzIHJlbGF0aXZlIHRvIHRoZSBjaGFydCBvciBqdXN0IHRoZVxuXHQgKiAgICAgICAgYXhpcy9wYW5lIGl0c2VsZi5cblx0ICovXG5cdHRvVmFsdWU6IGZ1bmN0aW9uIChwaXhlbCwgcGFuZUNvb3JkaW5hdGVzKSB7XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNsYXRlKHBpeGVsIC0gKHBhbmVDb29yZGluYXRlcyA/IDAgOiB0aGlzLnBvcyksIHRydWUsICF0aGlzLmhvcml6LCBudWxsLCB0cnVlKTtcblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIHRoZSBwYXRoIGZvciBhIHBsb3QgbGluZSB0aGF0IGdvZXMgZnJvbSB0aGUgZ2l2ZW4gdmFsdWUgb25cblx0ICogdGhpcyBheGlzLCBhY3Jvc3MgdGhlIHBsb3QgdG8gdGhlIG9wcG9zaXRlIHNpZGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBsaW5lV2lkdGggVXNlZCBmb3IgY2FsY3VsYXRpb24gY3Jpc3AgbGluZVxuXHQgKiBAcGFyYW0ge051bWJlcl0gb2xkIFVzZSBvbGQgY29vcmRpbmF0ZXMgKGZvciByZXNpemluZyBhbmQgcmVzY2FsaW5nKVxuXHQgKi9cblx0Z2V0UGxvdExpbmVQYXRoOiBmdW5jdGlvbiAodmFsdWUsIGxpbmVXaWR0aCwgb2xkLCBmb3JjZSwgdHJhbnNsYXRlZFZhbHVlKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0YXhpc0xlZnQgPSBheGlzLmxlZnQsXG5cdFx0XHRheGlzVG9wID0gYXhpcy50b3AsXG5cdFx0XHR4MSxcblx0XHRcdHkxLFxuXHRcdFx0eDIsXG5cdFx0XHR5Mixcblx0XHRcdGNIZWlnaHQgPSAob2xkICYmIGNoYXJ0Lm9sZENoYXJ0SGVpZ2h0KSB8fCBjaGFydC5jaGFydEhlaWdodCxcblx0XHRcdGNXaWR0aCA9IChvbGQgJiYgY2hhcnQub2xkQ2hhcnRXaWR0aCkgfHwgY2hhcnQuY2hhcnRXaWR0aCxcblx0XHRcdHNraXAsXG5cdFx0XHR0cmFuc0IgPSBheGlzLnRyYW5zQjtcblxuXHRcdHRyYW5zbGF0ZWRWYWx1ZSA9IHBpY2sodHJhbnNsYXRlZFZhbHVlLCBheGlzLnRyYW5zbGF0ZSh2YWx1ZSwgbnVsbCwgbnVsbCwgb2xkKSk7XG5cdFx0eDEgPSB4MiA9IG1hdGhSb3VuZCh0cmFuc2xhdGVkVmFsdWUgKyB0cmFuc0IpO1xuXHRcdHkxID0geTIgPSBtYXRoUm91bmQoY0hlaWdodCAtIHRyYW5zbGF0ZWRWYWx1ZSAtIHRyYW5zQik7XG5cblx0XHRpZiAoaXNOYU4odHJhbnNsYXRlZFZhbHVlKSkgeyAvLyBubyBtaW4gb3IgbWF4XG5cdFx0XHRza2lwID0gdHJ1ZTtcblxuXHRcdH0gZWxzZSBpZiAoYXhpcy5ob3Jpeikge1xuXHRcdFx0eTEgPSBheGlzVG9wO1xuXHRcdFx0eTIgPSBjSGVpZ2h0IC0gYXhpcy5ib3R0b207XG5cdFx0XHRpZiAoeDEgPCBheGlzTGVmdCB8fCB4MSA+IGF4aXNMZWZ0ICsgYXhpcy53aWR0aCkge1xuXHRcdFx0XHRza2lwID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0eDEgPSBheGlzTGVmdDtcblx0XHRcdHgyID0gY1dpZHRoIC0gYXhpcy5yaWdodDtcblxuXHRcdFx0aWYgKHkxIDwgYXhpc1RvcCB8fCB5MSA+IGF4aXNUb3AgKyBheGlzLmhlaWdodCkge1xuXHRcdFx0XHRza2lwID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHNraXAgJiYgIWZvcmNlID9cblx0XHRcdG51bGwgOlxuXHRcdFx0Y2hhcnQucmVuZGVyZXIuY3Jpc3BMaW5lKFtNLCB4MSwgeTEsIEwsIHgyLCB5Ml0sIGxpbmVXaWR0aCB8fCAxKTtcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSB0aWNrIHBvc2l0aW9ucyBvZiBhIGxpbmVhciBheGlzIHRvIHJvdW5kIHZhbHVlcyBsaWtlIHdob2xlIHRlbnMgb3IgZXZlcnkgZml2ZS5cblx0ICovXG5cdGdldExpbmVhclRpY2tQb3NpdGlvbnM6IGZ1bmN0aW9uICh0aWNrSW50ZXJ2YWwsIG1pbiwgbWF4KSB7XG5cdFx0dmFyIHBvcyxcblx0XHRcdGxhc3RQb3MsXG5cdFx0XHRyb3VuZGVkTWluID0gY29ycmVjdEZsb2F0KG1hdGhGbG9vcihtaW4gLyB0aWNrSW50ZXJ2YWwpICogdGlja0ludGVydmFsKSxcblx0XHRcdHJvdW5kZWRNYXggPSBjb3JyZWN0RmxvYXQobWF0aENlaWwobWF4IC8gdGlja0ludGVydmFsKSAqIHRpY2tJbnRlcnZhbCksXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gW107XG5cblx0XHQvLyBGb3Igc2luZ2xlIHBvaW50cywgYWRkIGEgdGljayByZWdhcmRsZXNzIG9mIHRoZSByZWxhdGl2ZSBwb3NpdGlvbiAoIzI2NjIpXG5cdFx0aWYgKG1pbiA9PT0gbWF4ICYmIGlzTnVtYmVyKG1pbikpIHtcblx0XHRcdHJldHVybiBbbWluXTtcblx0XHR9XG5cblx0XHQvLyBQb3B1bGF0ZSB0aGUgaW50ZXJtZWRpYXRlIHZhbHVlc1xuXHRcdHBvcyA9IHJvdW5kZWRNaW47XG5cdFx0d2hpbGUgKHBvcyA8PSByb3VuZGVkTWF4KSB7XG5cblx0XHRcdC8vIFBsYWNlIHRoZSB0aWNrIG9uIHRoZSByb3VuZGVkIHZhbHVlXG5cdFx0XHR0aWNrUG9zaXRpb25zLnB1c2gocG9zKTtcblxuXHRcdFx0Ly8gQWx3YXlzIGFkZCB0aGUgcmF3IHRpY2tJbnRlcnZhbCwgbm90IHRoZSBjb3JyZWN0ZWQgb25lLlxuXHRcdFx0cG9zID0gY29ycmVjdEZsb2F0KHBvcyArIHRpY2tJbnRlcnZhbCk7XG5cblx0XHRcdC8vIElmIHRoZSBpbnRlcnZhbCBpcyBub3QgYmlnIGVub3VnaCBpbiB0aGUgY3VycmVudCBtaW4gLSBtYXggcmFuZ2UgdG8gYWN0dWFsbHkgaW5jcmVhc2Vcblx0XHRcdC8vIHRoZSBsb29wIHZhcmlhYmxlLCB3ZSBuZWVkIHRvIGJyZWFrIG91dCB0byBwcmV2ZW50IGVuZGxlc3MgbG9vcC4gSXNzdWUgIzYxOVxuXHRcdFx0aWYgKHBvcyA9PT0gbGFzdFBvcykge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVjb3JkIHRoZSBsYXN0IHZhbHVlXG5cdFx0XHRsYXN0UG9zID0gcG9zO1xuXHRcdH1cblx0XHRyZXR1cm4gdGlja1Bvc2l0aW9ucztcblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJuIHRoZSBtaW5vciB0aWNrIHBvc2l0aW9ucy4gRm9yIGxvZ2FyaXRobWljIGF4ZXMsIHJldXNlIHRoZSBzYW1lIGxvZ2ljXG5cdCAqIGFzIGZvciBtYWpvciB0aWNrcy5cblx0ICovXG5cdGdldE1pbm9yVGlja1Bvc2l0aW9uczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy50aWNrUG9zaXRpb25zLFxuXHRcdFx0bWlub3JUaWNrSW50ZXJ2YWwgPSBheGlzLm1pbm9yVGlja0ludGVydmFsLFxuXHRcdFx0bWlub3JUaWNrUG9zaXRpb25zID0gW10sXG5cdFx0XHRwb3MsXG5cdFx0XHRpLFxuXHRcdFx0bGVuO1xuXG5cdFx0aWYgKGF4aXMuaXNMb2cpIHtcblx0XHRcdGxlbiA9IHRpY2tQb3NpdGlvbnMubGVuZ3RoO1xuXHRcdFx0Zm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdG1pbm9yVGlja1Bvc2l0aW9ucyA9IG1pbm9yVGlja1Bvc2l0aW9ucy5jb25jYXQoXG5cdFx0XHRcdFx0YXhpcy5nZXRMb2dUaWNrUG9zaXRpb25zKG1pbm9yVGlja0ludGVydmFsLCB0aWNrUG9zaXRpb25zW2kgLSAxXSwgdGlja1Bvc2l0aW9uc1tpXSwgdHJ1ZSlcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGF4aXMuaXNEYXRldGltZUF4aXMgJiYgb3B0aW9ucy5taW5vclRpY2tJbnRlcnZhbCA9PT0gJ2F1dG8nKSB7IC8vICMxMzE0XG5cdFx0XHRtaW5vclRpY2tQb3NpdGlvbnMgPSBtaW5vclRpY2tQb3NpdGlvbnMuY29uY2F0KFxuXHRcdFx0XHRheGlzLmdldFRpbWVUaWNrcyhcblx0XHRcdFx0XHRheGlzLm5vcm1hbGl6ZVRpbWVUaWNrSW50ZXJ2YWwobWlub3JUaWNrSW50ZXJ2YWwpLFxuXHRcdFx0XHRcdGF4aXMubWluLFxuXHRcdFx0XHRcdGF4aXMubWF4LFxuXHRcdFx0XHRcdG9wdGlvbnMuc3RhcnRPZldlZWtcblx0XHRcdFx0KVxuXHRcdFx0KTtcblx0XHRcdGlmIChtaW5vclRpY2tQb3NpdGlvbnNbMF0gPCBheGlzLm1pbikge1xuXHRcdFx0XHRtaW5vclRpY2tQb3NpdGlvbnMuc2hpZnQoKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yIChwb3MgPSBheGlzLm1pbiArICh0aWNrUG9zaXRpb25zWzBdIC0gYXhpcy5taW4pICUgbWlub3JUaWNrSW50ZXJ2YWw7IHBvcyA8PSBheGlzLm1heDsgcG9zICs9IG1pbm9yVGlja0ludGVydmFsKSB7XG5cdFx0XHRcdG1pbm9yVGlja1Bvc2l0aW9ucy5wdXNoKHBvcyk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBtaW5vclRpY2tQb3NpdGlvbnM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkanVzdCB0aGUgbWluIGFuZCBtYXggZm9yIHRoZSBtaW5pbXVtIHJhbmdlLiBLZWVwIGluIG1pbmQgdGhhdCB0aGUgc2VyaWVzIGRhdGEgaXNcblx0ICogbm90IHlldCBwcm9jZXNzZWQsIHNvIHdlIGRvbid0IGhhdmUgaW5mb3JtYXRpb24gb24gZGF0YSBjcm9wcGluZyBhbmQgZ3JvdXBpbmcsIG9yXG5cdCAqIHVwZGF0ZWQgYXhpcy5wb2ludFJhbmdlIG9yIHNlcmllcy5wb2ludFJhbmdlLiBUaGUgZGF0YSBjYW4ndCBiZSBwcm9jZXNzZWQgdW50aWxcblx0ICogd2UgaGF2ZSBmaW5hbGx5IGVzdGFibGlzaGVkIG1pbiBhbmQgbWF4LlxuXHQgKi9cblx0YWRqdXN0Rm9yTWluUmFuZ2U6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gYXhpcy5vcHRpb25zLFxuXHRcdFx0bWluID0gYXhpcy5taW4sXG5cdFx0XHRtYXggPSBheGlzLm1heCxcblx0XHRcdHpvb21PZmZzZXQsXG5cdFx0XHRzcGFjZUF2YWlsYWJsZSA9IGF4aXMuZGF0YU1heCAtIGF4aXMuZGF0YU1pbiA+PSBheGlzLm1pblJhbmdlLFxuXHRcdFx0Y2xvc2VzdERhdGFSYW5nZSxcblx0XHRcdGksXG5cdFx0XHRkaXN0YW5jZSxcblx0XHRcdHhEYXRhLFxuXHRcdFx0bG9vcExlbmd0aCxcblx0XHRcdG1pbkFyZ3MsXG5cdFx0XHRtYXhBcmdzO1xuXG5cdFx0Ly8gU2V0IHRoZSBhdXRvbWF0aWMgbWluaW11bSByYW5nZSBiYXNlZCBvbiB0aGUgY2xvc2VzdCBwb2ludCBkaXN0YW5jZVxuXHRcdGlmIChheGlzLmlzWEF4aXMgJiYgYXhpcy5taW5SYW5nZSA9PT0gVU5ERUZJTkVEICYmICFheGlzLmlzTG9nKSB7XG5cblx0XHRcdGlmIChkZWZpbmVkKG9wdGlvbnMubWluKSB8fCBkZWZpbmVkKG9wdGlvbnMubWF4KSkge1xuXHRcdFx0XHRheGlzLm1pblJhbmdlID0gbnVsbDsgLy8gZG9uJ3QgZG8gdGhpcyBhZ2FpblxuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEZpbmQgdGhlIGNsb3Nlc3QgZGlzdGFuY2UgYmV0d2VlbiByYXcgZGF0YSBwb2ludHMsIGFzIG9wcG9zZWQgdG9cblx0XHRcdFx0Ly8gY2xvc2VzdFBvaW50UmFuZ2UgdGhhdCBhcHBsaWVzIHRvIHByb2Nlc3NlZCBwb2ludHMgKGNyb3BwZWQgYW5kIGdyb3VwZWQpXG5cdFx0XHRcdGVhY2goYXhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdFx0XHR4RGF0YSA9IHNlcmllcy54RGF0YTtcblx0XHRcdFx0XHRsb29wTGVuZ3RoID0gc2VyaWVzLnhJbmNyZW1lbnQgPyAxIDogeERhdGEubGVuZ3RoIC0gMTtcblx0XHRcdFx0XHRmb3IgKGkgPSBsb29wTGVuZ3RoOyBpID4gMDsgaS0tKSB7XG5cdFx0XHRcdFx0XHRkaXN0YW5jZSA9IHhEYXRhW2ldIC0geERhdGFbaSAtIDFdO1xuXHRcdFx0XHRcdFx0aWYgKGNsb3Nlc3REYXRhUmFuZ2UgPT09IFVOREVGSU5FRCB8fCBkaXN0YW5jZSA8IGNsb3Nlc3REYXRhUmFuZ2UpIHtcblx0XHRcdFx0XHRcdFx0Y2xvc2VzdERhdGFSYW5nZSA9IGRpc3RhbmNlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGF4aXMubWluUmFuZ2UgPSBtYXRoTWluKGNsb3Nlc3REYXRhUmFuZ2UgKiA1LCBheGlzLmRhdGFNYXggLSBheGlzLmRhdGFNaW4pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGlmIG1pblJhbmdlIGlzIGV4Y2VlZGVkLCBhZGp1c3Rcblx0XHRpZiAobWF4IC0gbWluIDwgYXhpcy5taW5SYW5nZSkge1xuXHRcdFx0dmFyIG1pblJhbmdlID0gYXhpcy5taW5SYW5nZTtcblx0XHRcdHpvb21PZmZzZXQgPSAobWluUmFuZ2UgLSBtYXggKyBtaW4pIC8gMjtcblxuXHRcdFx0Ly8gaWYgbWluIGFuZCBtYXggb3B0aW9ucyBoYXZlIGJlZW4gc2V0LCBkb24ndCBnbyBiZXlvbmQgaXRcblx0XHRcdG1pbkFyZ3MgPSBbbWluIC0gem9vbU9mZnNldCwgcGljayhvcHRpb25zLm1pbiwgbWluIC0gem9vbU9mZnNldCldO1xuXHRcdFx0aWYgKHNwYWNlQXZhaWxhYmxlKSB7IC8vIGlmIHNwYWNlIGlzIGF2YWlsYWJsZSwgc3RheSB3aXRoaW4gdGhlIGRhdGEgcmFuZ2Vcblx0XHRcdFx0bWluQXJnc1syXSA9IGF4aXMuZGF0YU1pbjtcblx0XHRcdH1cblx0XHRcdG1pbiA9IGFycmF5TWF4KG1pbkFyZ3MpO1xuXG5cdFx0XHRtYXhBcmdzID0gW21pbiArIG1pblJhbmdlLCBwaWNrKG9wdGlvbnMubWF4LCBtaW4gKyBtaW5SYW5nZSldO1xuXHRcdFx0aWYgKHNwYWNlQXZhaWxhYmxlKSB7IC8vIGlmIHNwYWNlIGlzIGF2YWlsYWJlLCBzdGF5IHdpdGhpbiB0aGUgZGF0YSByYW5nZVxuXHRcdFx0XHRtYXhBcmdzWzJdID0gYXhpcy5kYXRhTWF4O1xuXHRcdFx0fVxuXG5cdFx0XHRtYXggPSBhcnJheU1pbihtYXhBcmdzKTtcblxuXHRcdFx0Ly8gbm93IGlmIHRoZSBtYXggaXMgYWRqdXN0ZWQsIGFkanVzdCB0aGUgbWluIGJhY2tcblx0XHRcdGlmIChtYXggLSBtaW4gPCBtaW5SYW5nZSkge1xuXHRcdFx0XHRtaW5BcmdzWzBdID0gbWF4IC0gbWluUmFuZ2U7XG5cdFx0XHRcdG1pbkFyZ3NbMV0gPSBwaWNrKG9wdGlvbnMubWluLCBtYXggLSBtaW5SYW5nZSk7XG5cdFx0XHRcdG1pbiA9IGFycmF5TWF4KG1pbkFyZ3MpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlY29yZCBtb2RpZmllZCBleHRyZW1lc1xuXHRcdGF4aXMubWluID0gbWluO1xuXHRcdGF4aXMubWF4ID0gbWF4O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgdHJhbnNsYXRpb24gaW5mb3JtYXRpb25cblx0ICovXG5cdHNldEF4aXNUcmFuc2xhdGlvbjogZnVuY3Rpb24gKHNhdmVPbGQpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRyYW5nZSA9IGF4aXMubWF4IC0gYXhpcy5taW4sXG5cdFx0XHRwb2ludFJhbmdlID0gYXhpcy5heGlzUG9pbnRSYW5nZSB8fCAwLFxuXHRcdFx0Y2xvc2VzdFBvaW50UmFuZ2UsXG5cdFx0XHRtaW5Qb2ludE9mZnNldCA9IDAsXG5cdFx0XHRwb2ludFJhbmdlUGFkZGluZyA9IDAsXG5cdFx0XHRsaW5rZWRQYXJlbnQgPSBheGlzLmxpbmtlZFBhcmVudCxcblx0XHRcdG9yZGluYWxDb3JyZWN0aW9uLFxuXHRcdFx0aGFzQ2F0ZWdvcmllcyA9ICEhYXhpcy5jYXRlZ29yaWVzLFxuXHRcdFx0dHJhbnNBID0gYXhpcy50cmFuc0E7XG5cblx0XHQvLyBBZGp1c3QgdHJhbnNsYXRpb24gZm9yIHBhZGRpbmcuIFkgYXhpcyB3aXRoIGNhdGVnb3JpZXMgbmVlZCB0byBnbyB0aHJvdWdoIHRoZSBzYW1lICgjMTc4NCkuXG5cdFx0aWYgKGF4aXMuaXNYQXhpcyB8fCBoYXNDYXRlZ29yaWVzIHx8IHBvaW50UmFuZ2UpIHtcblx0XHRcdGlmIChsaW5rZWRQYXJlbnQpIHtcblx0XHRcdFx0bWluUG9pbnRPZmZzZXQgPSBsaW5rZWRQYXJlbnQubWluUG9pbnRPZmZzZXQ7XG5cdFx0XHRcdHBvaW50UmFuZ2VQYWRkaW5nID0gbGlua2VkUGFyZW50LnBvaW50UmFuZ2VQYWRkaW5nO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlYWNoKGF4aXMuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cdFx0XHRcdFx0dmFyIHNlcmllc1BvaW50UmFuZ2UgPSBoYXNDYXRlZ29yaWVzID8gMSA6IChheGlzLmlzWEF4aXMgPyBzZXJpZXMucG9pbnRSYW5nZSA6IChheGlzLmF4aXNQb2ludFJhbmdlIHx8IDApKSwgLy8gIzI4MDZcblx0XHRcdFx0XHRcdHBvaW50UGxhY2VtZW50ID0gc2VyaWVzLm9wdGlvbnMucG9pbnRQbGFjZW1lbnQsXG5cdFx0XHRcdFx0XHRzZXJpZXNDbG9zZXN0UG9pbnRSYW5nZSA9IHNlcmllcy5jbG9zZXN0UG9pbnRSYW5nZTtcblxuXHRcdFx0XHRcdGlmIChzZXJpZXNQb2ludFJhbmdlID4gcmFuZ2UpIHsgLy8gIzE0NDZcblx0XHRcdFx0XHRcdHNlcmllc1BvaW50UmFuZ2UgPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb2ludFJhbmdlID0gbWF0aE1heChwb2ludFJhbmdlLCBzZXJpZXNQb2ludFJhbmdlKTtcblxuXHRcdFx0XHRcdC8vIG1pblBvaW50T2Zmc2V0IGlzIHRoZSB2YWx1ZSBwYWRkaW5nIHRvIHRoZSBsZWZ0IG9mIHRoZSBheGlzIGluIG9yZGVyIHRvIG1ha2Vcblx0XHRcdFx0XHQvLyByb29tIGZvciBwb2ludHMgd2l0aCBhIHBvaW50UmFuZ2UsIHR5cGljYWxseSBjb2x1bW5zLiBXaGVuIHRoZSBwb2ludFBsYWNlbWVudCBvcHRpb25cblx0XHRcdFx0XHQvLyBpcyAnYmV0d2Vlbicgb3IgJ29uJywgdGhpcyBwYWRkaW5nIGRvZXMgbm90IGFwcGx5LlxuXHRcdFx0XHRcdG1pblBvaW50T2Zmc2V0ID0gbWF0aE1heChcblx0XHRcdFx0XHRcdG1pblBvaW50T2Zmc2V0LFxuXHRcdFx0XHRcdFx0aXNTdHJpbmcocG9pbnRQbGFjZW1lbnQpID8gMCA6IHNlcmllc1BvaW50UmFuZ2UgLyAyXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIERldGVybWluZSB0aGUgdG90YWwgcGFkZGluZyBuZWVkZWQgdG8gdGhlIGxlbmd0aCBvZiB0aGUgYXhpcyB0byBtYWtlIHJvb20gZm9yIHRoZVxuXHRcdFx0XHRcdC8vIHBvaW50UmFuZ2UuIElmIHRoZSBzZXJpZXMnIHBvaW50UGxhY2VtZW50IGlzICdvbicsIG5vIHBhZGRpbmcgaXMgYWRkZWQuXG5cdFx0XHRcdFx0cG9pbnRSYW5nZVBhZGRpbmcgPSBtYXRoTWF4KFxuXHRcdFx0XHRcdFx0cG9pbnRSYW5nZVBhZGRpbmcsXG5cdFx0XHRcdFx0XHRwb2ludFBsYWNlbWVudCA9PT0gJ29uJyA/IDAgOiBzZXJpZXNQb2ludFJhbmdlXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIFNldCB0aGUgY2xvc2VzdFBvaW50UmFuZ2Vcblx0XHRcdFx0XHRpZiAoIXNlcmllcy5ub1NoYXJlZFRvb2x0aXAgJiYgZGVmaW5lZChzZXJpZXNDbG9zZXN0UG9pbnRSYW5nZSkpIHtcblx0XHRcdFx0XHRcdGNsb3Nlc3RQb2ludFJhbmdlID0gZGVmaW5lZChjbG9zZXN0UG9pbnRSYW5nZSkgP1xuXHRcdFx0XHRcdFx0XHRtYXRoTWluKGNsb3Nlc3RQb2ludFJhbmdlLCBzZXJpZXNDbG9zZXN0UG9pbnRSYW5nZSkgOlxuXHRcdFx0XHRcdFx0XHRzZXJpZXNDbG9zZXN0UG9pbnRSYW5nZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWNvcmQgbWluUG9pbnRPZmZzZXQgYW5kIHBvaW50UmFuZ2VQYWRkaW5nXG5cdFx0XHRvcmRpbmFsQ29ycmVjdGlvbiA9IGF4aXMub3JkaW5hbFNsb3BlICYmIGNsb3Nlc3RQb2ludFJhbmdlID8gYXhpcy5vcmRpbmFsU2xvcGUgLyBjbG9zZXN0UG9pbnRSYW5nZSA6IDE7IC8vICM5ODgsICMxODUzXG5cdFx0XHRheGlzLm1pblBvaW50T2Zmc2V0ID0gbWluUG9pbnRPZmZzZXQgPSBtaW5Qb2ludE9mZnNldCAqIG9yZGluYWxDb3JyZWN0aW9uO1xuXHRcdFx0YXhpcy5wb2ludFJhbmdlUGFkZGluZyA9IHBvaW50UmFuZ2VQYWRkaW5nID0gcG9pbnRSYW5nZVBhZGRpbmcgKiBvcmRpbmFsQ29ycmVjdGlvbjtcblxuXHRcdFx0Ly8gcG9pbnRSYW5nZSBtZWFucyB0aGUgd2lkdGggcmVzZXJ2ZWQgZm9yIGVhY2ggcG9pbnQsIGxpa2UgaW4gYSBjb2x1bW4gY2hhcnRcblx0XHRcdGF4aXMucG9pbnRSYW5nZSA9IG1hdGhNaW4ocG9pbnRSYW5nZSwgcmFuZ2UpO1xuXG5cdFx0XHQvLyBjbG9zZXN0UG9pbnRSYW5nZSBtZWFucyB0aGUgY2xvc2VzdCBkaXN0YW5jZSBiZXR3ZWVuIHBvaW50cy4gSW4gY29sdW1uc1xuXHRcdFx0Ly8gaXQgaXMgbW9zdGx5IGVxdWFsIHRvIHBvaW50UmFuZ2UsIGJ1dCBpbiBsaW5lcyBwb2ludFJhbmdlIGlzIDAgd2hpbGUgY2xvc2VzdFBvaW50UmFuZ2Vcblx0XHRcdC8vIGlzIHNvbWUgb3RoZXIgdmFsdWVcblx0XHRcdGF4aXMuY2xvc2VzdFBvaW50UmFuZ2UgPSBjbG9zZXN0UG9pbnRSYW5nZTtcblx0XHR9XG5cblx0XHQvLyBTZWNvbmRhcnkgdmFsdWVzXG5cdFx0aWYgKHNhdmVPbGQpIHtcblx0XHRcdGF4aXMub2xkVHJhbnNBID0gdHJhbnNBO1xuXHRcdH1cblx0XHRheGlzLnRyYW5zbGF0aW9uU2xvcGUgPSBheGlzLnRyYW5zQSA9IHRyYW5zQSA9IGF4aXMubGVuIC8gKChyYW5nZSArIHBvaW50UmFuZ2VQYWRkaW5nKSB8fCAxKTtcblx0XHRheGlzLnRyYW5zQiA9IGF4aXMuaG9yaXogPyBheGlzLmxlZnQgOiBheGlzLmJvdHRvbTsgLy8gdHJhbnNsYXRpb24gYWRkZW5kXG5cdFx0YXhpcy5taW5QaXhlbFBhZGRpbmcgPSB0cmFuc0EgKiBtaW5Qb2ludE9mZnNldDtcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSB0aWNrIHBvc2l0aW9ucyB0byByb3VuZCB2YWx1ZXMgYW5kIG9wdGlvbmFsbHkgZXh0ZW5kIHRoZSBleHRyZW1lc1xuXHQgKiB0byB0aGUgbmVhcmVzdCB0aWNrXG5cdCAqL1xuXHRzZXRUaWNrUG9zaXRpb25zOiBmdW5jdGlvbiAoc2Vjb25kUGFzcykge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHRzdGFydE9uVGljayA9IG9wdGlvbnMuc3RhcnRPblRpY2ssXG5cdFx0XHRlbmRPblRpY2sgPSBvcHRpb25zLmVuZE9uVGljayxcblx0XHRcdGlzTG9nID0gYXhpcy5pc0xvZyxcblx0XHRcdGlzRGF0ZXRpbWVBeGlzID0gYXhpcy5pc0RhdGV0aW1lQXhpcyxcblx0XHRcdGlzWEF4aXMgPSBheGlzLmlzWEF4aXMsXG5cdFx0XHRpc0xpbmtlZCA9IGF4aXMuaXNMaW5rZWQsXG5cdFx0XHR0aWNrUG9zaXRpb25lciA9IGF4aXMub3B0aW9ucy50aWNrUG9zaXRpb25lcixcblx0XHRcdG1heFBhZGRpbmcgPSBvcHRpb25zLm1heFBhZGRpbmcsXG5cdFx0XHRtaW5QYWRkaW5nID0gb3B0aW9ucy5taW5QYWRkaW5nLFxuXHRcdFx0bGVuZ3RoLFxuXHRcdFx0bGlua2VkUGFyZW50RXh0cmVtZXMsXG5cdFx0XHR0aWNrSW50ZXJ2YWxPcHRpb24gPSBvcHRpb25zLnRpY2tJbnRlcnZhbCxcblx0XHRcdG1pblRpY2tJbnRlcnZhbE9wdGlvbiA9IG9wdGlvbnMubWluVGlja0ludGVydmFsLFxuXHRcdFx0dGlja1BpeGVsSW50ZXJ2YWxPcHRpb24gPSBvcHRpb25zLnRpY2tQaXhlbEludGVydmFsLFxuXHRcdFx0dGlja1Bvc2l0aW9ucyxcblx0XHRcdGtlZXBUd29UaWNrc09ubHksXG5cdFx0XHRjYXRlZ29yaWVzID0gYXhpcy5jYXRlZ29yaWVzO1xuXG5cdFx0Ly8gbGlua2VkIGF4aXMgZ2V0cyB0aGUgZXh0cmVtZXMgZnJvbSB0aGUgcGFyZW50IGF4aXNcblx0XHRpZiAoaXNMaW5rZWQpIHtcblx0XHRcdGF4aXMubGlua2VkUGFyZW50ID0gY2hhcnRbYXhpcy5jb2xsXVtvcHRpb25zLmxpbmtlZFRvXTtcblx0XHRcdGxpbmtlZFBhcmVudEV4dHJlbWVzID0gYXhpcy5saW5rZWRQYXJlbnQuZ2V0RXh0cmVtZXMoKTtcblx0XHRcdGF4aXMubWluID0gcGljayhsaW5rZWRQYXJlbnRFeHRyZW1lcy5taW4sIGxpbmtlZFBhcmVudEV4dHJlbWVzLmRhdGFNaW4pO1xuXHRcdFx0YXhpcy5tYXggPSBwaWNrKGxpbmtlZFBhcmVudEV4dHJlbWVzLm1heCwgbGlua2VkUGFyZW50RXh0cmVtZXMuZGF0YU1heCk7XG5cdFx0XHRpZiAob3B0aW9ucy50eXBlICE9PSBheGlzLmxpbmtlZFBhcmVudC5vcHRpb25zLnR5cGUpIHtcblx0XHRcdFx0ZXJyb3IoMTEsIDEpOyAvLyBDYW4ndCBsaW5rIGF4ZXMgb2YgZGlmZmVyZW50IHR5cGVcblx0XHRcdH1cblx0XHR9IGVsc2UgeyAvLyBpbml0aWFsIG1pbiBhbmQgbWF4IGZyb20gdGhlIGV4dHJlbWUgZGF0YSB2YWx1ZXNcblx0XHRcdGF4aXMubWluID0gcGljayhheGlzLnVzZXJNaW4sIG9wdGlvbnMubWluLCBheGlzLmRhdGFNaW4pO1xuXHRcdFx0YXhpcy5tYXggPSBwaWNrKGF4aXMudXNlck1heCwgb3B0aW9ucy5tYXgsIGF4aXMuZGF0YU1heCk7XG5cdFx0fVxuXG5cdFx0aWYgKGlzTG9nKSB7XG5cdFx0XHRpZiAoIXNlY29uZFBhc3MgJiYgbWF0aE1pbihheGlzLm1pbiwgcGljayhheGlzLmRhdGFNaW4sIGF4aXMubWluKSkgPD0gMCkgeyAvLyAjOTc4XG5cdFx0XHRcdGVycm9yKDEwLCAxKTsgLy8gQ2FuJ3QgcGxvdCBuZWdhdGl2ZSB2YWx1ZXMgb24gbG9nIGF4aXNcblx0XHRcdH1cblx0XHRcdGF4aXMubWluID0gY29ycmVjdEZsb2F0KGxvZzJsaW4oYXhpcy5taW4pKTsgLy8gY29ycmVjdEZsb2F0IGN1cmVzICM5MzRcblx0XHRcdGF4aXMubWF4ID0gY29ycmVjdEZsb2F0KGxvZzJsaW4oYXhpcy5tYXgpKTtcblx0XHR9XG5cblx0XHQvLyBoYW5kbGUgem9vbWVkIHJhbmdlXG5cdFx0aWYgKGF4aXMucmFuZ2UgJiYgZGVmaW5lZChheGlzLm1heCkpIHtcblx0XHRcdGF4aXMudXNlck1pbiA9IGF4aXMubWluID0gbWF0aE1heChheGlzLm1pbiwgYXhpcy5tYXggLSBheGlzLnJhbmdlKTsgLy8gIzYxOFxuXHRcdFx0YXhpcy51c2VyTWF4ID0gYXhpcy5tYXg7XG5cblx0XHRcdGF4aXMucmFuZ2UgPSBudWxsOyAgLy8gZG9uJ3QgdXNlIGl0IHdoZW4gcnVubmluZyBzZXRFeHRyZW1lc1xuXHRcdH1cblxuXHRcdC8vIEhvb2sgZm9yIGFkanVzdGluZyB0aGlzLm1pbiBhbmQgdGhpcy5tYXguIFVzZWQgYnkgYnViYmxlIHNlcmllcy5cblx0XHRpZiAoYXhpcy5iZWZvcmVQYWRkaW5nKSB7XG5cdFx0XHRheGlzLmJlZm9yZVBhZGRpbmcoKTtcblx0XHR9XG5cblx0XHQvLyBhZGp1c3QgbWluIGFuZCBtYXggZm9yIHRoZSBtaW5pbXVtIHJhbmdlXG5cdFx0YXhpcy5hZGp1c3RGb3JNaW5SYW5nZSgpO1xuXG5cdFx0Ly8gUGFkIHRoZSB2YWx1ZXMgdG8gZ2V0IGNsZWFyIG9mIHRoZSBjaGFydCdzIGVkZ2VzLiBUbyBhdm9pZCB0aWNrSW50ZXJ2YWwgdGFraW5nIHRoZSBwYWRkaW5nXG5cdFx0Ly8gaW50byBhY2NvdW50LCB3ZSBkbyB0aGlzIGFmdGVyIGNvbXB1dGluZyB0aWNrIGludGVydmFsICgjMTMzNykuXG5cdFx0aWYgKCFjYXRlZ29yaWVzICYmICFheGlzLmF4aXNQb2ludFJhbmdlICYmICFheGlzLnVzZVBlcmNlbnRhZ2UgJiYgIWlzTGlua2VkICYmIGRlZmluZWQoYXhpcy5taW4pICYmIGRlZmluZWQoYXhpcy5tYXgpKSB7XG5cdFx0XHRsZW5ndGggPSBheGlzLm1heCAtIGF4aXMubWluO1xuXHRcdFx0aWYgKGxlbmd0aCkge1xuXHRcdFx0XHRpZiAoIWRlZmluZWQob3B0aW9ucy5taW4pICYmICFkZWZpbmVkKGF4aXMudXNlck1pbikgJiYgbWluUGFkZGluZyAmJiAoYXhpcy5kYXRhTWluIDwgMCB8fCAhYXhpcy5pZ25vcmVNaW5QYWRkaW5nKSkge1xuXHRcdFx0XHRcdGF4aXMubWluIC09IGxlbmd0aCAqIG1pblBhZGRpbmc7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCFkZWZpbmVkKG9wdGlvbnMubWF4KSAmJiAhZGVmaW5lZChheGlzLnVzZXJNYXgpICAmJiBtYXhQYWRkaW5nICYmIChheGlzLmRhdGFNYXggPiAwIHx8ICFheGlzLmlnbm9yZU1heFBhZGRpbmcpKSB7XG5cdFx0XHRcdFx0YXhpcy5tYXggKz0gbGVuZ3RoICogbWF4UGFkZGluZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFN0YXkgd2l0aGluIGZsb29yIGFuZCBjZWlsaW5nXG5cdFx0aWYgKGlzTnVtYmVyKG9wdGlvbnMuZmxvb3IpKSB7XG5cdFx0XHRheGlzLm1pbiA9IG1hdGhNYXgoYXhpcy5taW4sIG9wdGlvbnMuZmxvb3IpO1xuXHRcdH1cblx0XHRpZiAoaXNOdW1iZXIob3B0aW9ucy5jZWlsaW5nKSkge1xuXHRcdFx0YXhpcy5tYXggPSBtYXRoTWluKGF4aXMubWF4LCBvcHRpb25zLmNlaWxpbmcpO1xuXHRcdH1cblxuXHRcdC8vIGdldCB0aWNrSW50ZXJ2YWxcblx0XHRpZiAoYXhpcy5taW4gPT09IGF4aXMubWF4IHx8IGF4aXMubWluID09PSB1bmRlZmluZWQgfHwgYXhpcy5tYXggPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSAxO1xuXHRcdH0gZWxzZSBpZiAoaXNMaW5rZWQgJiYgIXRpY2tJbnRlcnZhbE9wdGlvbiAmJlxuXHRcdFx0XHR0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbiA9PT0gYXhpcy5saW5rZWRQYXJlbnQub3B0aW9ucy50aWNrUGl4ZWxJbnRlcnZhbCkge1xuXHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBheGlzLmxpbmtlZFBhcmVudC50aWNrSW50ZXJ2YWw7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGF4aXMudGlja0ludGVydmFsID0gcGljayhcblx0XHRcdFx0dGlja0ludGVydmFsT3B0aW9uLFxuXHRcdFx0XHRjYXRlZ29yaWVzID8gLy8gZm9yIGNhdGVnb3JpZWQgYXhpcywgMSBpcyBkZWZhdWx0LCBmb3IgbGluZWFyIGF4aXMgdXNlIHRpY2tQaXhcblx0XHRcdFx0XHQxIDpcblx0XHRcdFx0XHQvLyBkb24ndCBsZXQgaXQgYmUgbW9yZSB0aGFuIHRoZSBkYXRhIHJhbmdlXG5cdFx0XHRcdFx0KGF4aXMubWF4IC0gYXhpcy5taW4pICogdGlja1BpeGVsSW50ZXJ2YWxPcHRpb24gLyBtYXRoTWF4KGF4aXMubGVuLCB0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbilcblx0XHRcdCk7XG5cdFx0XHQvLyBGb3Igc3F1aXNoZWQgYXhlcywgc2V0IG9ubHkgdHdvIHRpY2tzXG5cdFx0XHRpZiAoIWRlZmluZWQodGlja0ludGVydmFsT3B0aW9uKSAmJiBheGlzLmxlbiA8IHRpY2tQaXhlbEludGVydmFsT3B0aW9uICYmICF0aGlzLmlzUmFkaWFsICYmXG5cdFx0XHRcdFx0IXRoaXMuaXNMb2cgJiYgIWNhdGVnb3JpZXMgJiYgc3RhcnRPblRpY2sgJiYgZW5kT25UaWNrKSB7XG5cdFx0XHRcdGtlZXBUd29UaWNrc09ubHkgPSB0cnVlO1xuXHRcdFx0XHRheGlzLnRpY2tJbnRlcnZhbCAvPSA0OyAvLyB0aWNrIGV4dHJlbWVzIGNsb3NlciB0byB0aGUgcmVhbCB2YWx1ZXNcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBOb3cgd2UncmUgZmluaXNoZWQgZGV0ZWN0aW5nIG1pbiBhbmQgbWF4LCBjcm9wIGFuZCBncm91cCBzZXJpZXMgZGF0YS4gVGhpc1xuXHRcdC8vIGlzIGluIHR1cm4gbmVlZGVkIGluIG9yZGVyIHRvIGZpbmQgdGljayBwb3NpdGlvbnMgaW4gb3JkaW5hbCBheGVzLlxuXHRcdGlmIChpc1hBeGlzICYmICFzZWNvbmRQYXNzKSB7XG5cdFx0XHRlYWNoKGF4aXMuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cdFx0XHRcdHNlcmllcy5wcm9jZXNzRGF0YShheGlzLm1pbiAhPT0gYXhpcy5vbGRNaW4gfHwgYXhpcy5tYXggIT09IGF4aXMub2xkTWF4KTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdC8vIHNldCB0aGUgdHJhbnNsYXRpb24gZmFjdG9yIHVzZWQgaW4gdHJhbnNsYXRlIGZ1bmN0aW9uXG5cdFx0YXhpcy5zZXRBeGlzVHJhbnNsYXRpb24odHJ1ZSk7XG5cblx0XHQvLyBob29rIGZvciBvcmRpbmFsIGF4ZXMgYW5kIHJhZGlhbCBheGVzXG5cdFx0aWYgKGF4aXMuYmVmb3JlU2V0VGlja1Bvc2l0aW9ucykge1xuXHRcdFx0YXhpcy5iZWZvcmVTZXRUaWNrUG9zaXRpb25zKCk7XG5cdFx0fVxuXG5cdFx0Ly8gaG9vayBmb3IgZXh0ZW5zaW9ucywgdXNlZCBpbiBIaWdoc3RvY2sgb3JkaW5hbCBheGVzXG5cdFx0aWYgKGF4aXMucG9zdFByb2Nlc3NUaWNrSW50ZXJ2YWwpIHtcblx0XHRcdGF4aXMudGlja0ludGVydmFsID0gYXhpcy5wb3N0UHJvY2Vzc1RpY2tJbnRlcnZhbChheGlzLnRpY2tJbnRlcnZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gSW4gY29sdW1uLWxpa2UgY2hhcnRzLCBkb24ndCBjcmFtcCBpbiBtb3JlIHRpY2tzIHRoYW4gdGhlcmUgYXJlIHBvaW50cyAoIzE5NDMpXG5cdFx0aWYgKGF4aXMucG9pbnRSYW5nZSkge1xuXHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBtYXRoTWF4KGF4aXMucG9pbnRSYW5nZSwgYXhpcy50aWNrSW50ZXJ2YWwpO1xuXHRcdH1cblxuXHRcdC8vIEJlZm9yZSBub3JtYWxpemluZyB0aGUgdGljayBpbnRlcnZhbCwgaGFuZGxlIG1pbmltdW0gdGljayBpbnRlcnZhbC4gVGhpcyBhcHBsaWVzIG9ubHkgaWYgdGlja0ludGVydmFsIGlzIG5vdCBkZWZpbmVkLlxuXHRcdGlmICghdGlja0ludGVydmFsT3B0aW9uICYmIGF4aXMudGlja0ludGVydmFsIDwgbWluVGlja0ludGVydmFsT3B0aW9uKSB7XG5cdFx0XHRheGlzLnRpY2tJbnRlcnZhbCA9IG1pblRpY2tJbnRlcnZhbE9wdGlvbjtcblx0XHR9XG5cblx0XHQvLyBmb3IgbGluZWFyIGF4ZXMsIGdldCBtYWduaXR1ZGUgYW5kIG5vcm1hbGl6ZSB0aGUgaW50ZXJ2YWxcblx0XHRpZiAoIWlzRGF0ZXRpbWVBeGlzICYmICFpc0xvZykgeyAvLyBsaW5lYXJcblx0XHRcdGlmICghdGlja0ludGVydmFsT3B0aW9uKSB7XG5cdFx0XHRcdGF4aXMudGlja0ludGVydmFsID0gbm9ybWFsaXplVGlja0ludGVydmFsKFxuXHRcdFx0XHRcdGF4aXMudGlja0ludGVydmFsLCBcblx0XHRcdFx0XHRudWxsLCBcblx0XHRcdFx0XHRnZXRNYWduaXR1ZGUoYXhpcy50aWNrSW50ZXJ2YWwpLCBcblx0XHRcdFx0XHQvLyBJZiB0aGUgdGljayBpbnRlcnZhbCBpcyBiZXR3ZWVuIDEgYW5kIDUgYW5kIHRoZSBheGlzIG1heCBpcyBpbiB0aGUgb3JkZXIgb2Zcblx0XHRcdFx0XHQvLyB0aG91c2FuZHMsIGNoYW5jZXMgYXJlIHdlIGFyZSBkZWFsaW5nIHdpdGggeWVhcnMuIERvbid0IGFsbG93IGRlY2ltYWxzLiAjMzM2My5cblx0XHRcdFx0XHRwaWNrKG9wdGlvbnMuYWxsb3dEZWNpbWFscywgIShheGlzLnRpY2tJbnRlcnZhbCA+IDEgJiYgYXhpcy50aWNrSW50ZXJ2YWwgPCA1ICYmIGF4aXMubWF4ID4gMTAwMCAmJiBheGlzLm1heCA8IDk5OTkpKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGdldCBtaW5vclRpY2tJbnRlcnZhbFxuXHRcdGF4aXMubWlub3JUaWNrSW50ZXJ2YWwgPSBvcHRpb25zLm1pbm9yVGlja0ludGVydmFsID09PSAnYXV0bycgJiYgYXhpcy50aWNrSW50ZXJ2YWwgP1xuXHRcdFx0XHRheGlzLnRpY2tJbnRlcnZhbCAvIDUgOiBvcHRpb25zLm1pbm9yVGlja0ludGVydmFsO1xuXG5cdFx0Ly8gZmluZCB0aGUgdGljayBwb3NpdGlvbnNcblx0XHRheGlzLnRpY2tQb3NpdGlvbnMgPSB0aWNrUG9zaXRpb25zID0gb3B0aW9ucy50aWNrUG9zaXRpb25zID9cblx0XHRcdFtdLmNvbmNhdChvcHRpb25zLnRpY2tQb3NpdGlvbnMpIDogLy8gV29yayBvbiBhIGNvcHkgKCMxNTY1KVxuXHRcdFx0KHRpY2tQb3NpdGlvbmVyICYmIHRpY2tQb3NpdGlvbmVyLmFwcGx5KGF4aXMsIFtheGlzLm1pbiwgYXhpcy5tYXhdKSk7XG5cdFx0aWYgKCF0aWNrUG9zaXRpb25zKSB7XG5cblx0XHRcdC8vIFRvbyBtYW55IHRpY2tzXG5cdFx0XHRpZiAoIWF4aXMub3JkaW5hbFBvc2l0aW9ucyAmJiAoYXhpcy5tYXggLSBheGlzLm1pbikgLyBheGlzLnRpY2tJbnRlcnZhbCA+IG1hdGhNYXgoMiAqIGF4aXMubGVuLCAyMDApKSB7XG5cdFx0XHRcdGVycm9yKDE5LCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGlzRGF0ZXRpbWVBeGlzKSB7XG5cdFx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLmdldFRpbWVUaWNrcyhcblx0XHRcdFx0XHRheGlzLm5vcm1hbGl6ZVRpbWVUaWNrSW50ZXJ2YWwoYXhpcy50aWNrSW50ZXJ2YWwsIG9wdGlvbnMudW5pdHMpLFxuXHRcdFx0XHRcdGF4aXMubWluLFxuXHRcdFx0XHRcdGF4aXMubWF4LFxuXHRcdFx0XHRcdG9wdGlvbnMuc3RhcnRPZldlZWssXG5cdFx0XHRcdFx0YXhpcy5vcmRpbmFsUG9zaXRpb25zLFxuXHRcdFx0XHRcdGF4aXMuY2xvc2VzdFBvaW50UmFuZ2UsXG5cdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIGlmIChpc0xvZykge1xuXHRcdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy5nZXRMb2dUaWNrUG9zaXRpb25zKGF4aXMudGlja0ludGVydmFsLCBheGlzLm1pbiwgYXhpcy5tYXgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMuZ2V0TGluZWFyVGlja1Bvc2l0aW9ucyhheGlzLnRpY2tJbnRlcnZhbCwgYXhpcy5taW4sIGF4aXMubWF4KTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGtlZXBUd29UaWNrc09ubHkpIHtcblx0XHRcdFx0dGlja1Bvc2l0aW9ucy5zcGxpY2UoMSwgdGlja1Bvc2l0aW9ucy5sZW5ndGggLSAyKTtcblx0XHRcdH1cblxuXHRcdFx0YXhpcy50aWNrUG9zaXRpb25zID0gdGlja1Bvc2l0aW9ucztcblx0XHR9XG5cblx0XHRpZiAoIWlzTGlua2VkKSB7XG5cblx0XHRcdC8vIHJlc2V0IG1pbi9tYXggb3IgcmVtb3ZlIGV4dHJlbWVzIGJhc2VkIG9uIHN0YXJ0L2VuZCBvbiB0aWNrXG5cdFx0XHR2YXIgcm91bmRlZE1pbiA9IHRpY2tQb3NpdGlvbnNbMF0sXG5cdFx0XHRcdHJvdW5kZWRNYXggPSB0aWNrUG9zaXRpb25zW3RpY2tQb3NpdGlvbnMubGVuZ3RoIC0gMV0sXG5cdFx0XHRcdG1pblBvaW50T2Zmc2V0ID0gYXhpcy5taW5Qb2ludE9mZnNldCB8fCAwLFxuXHRcdFx0XHRzaW5nbGVQYWQ7XG5cblx0XHRcdGlmIChzdGFydE9uVGljaykge1xuXHRcdFx0XHRheGlzLm1pbiA9IHJvdW5kZWRNaW47XG5cdFx0XHR9IGVsc2UgaWYgKGF4aXMubWluIC0gbWluUG9pbnRPZmZzZXQgPiByb3VuZGVkTWluKSB7XG5cdFx0XHRcdHRpY2tQb3NpdGlvbnMuc2hpZnQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGVuZE9uVGljaykge1xuXHRcdFx0XHRheGlzLm1heCA9IHJvdW5kZWRNYXg7XG5cdFx0XHR9IGVsc2UgaWYgKGF4aXMubWF4ICsgbWluUG9pbnRPZmZzZXQgPCByb3VuZGVkTWF4KSB7XG5cdFx0XHRcdHRpY2tQb3NpdGlvbnMucG9wKCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIG5vIHRpY2sgYXJlIGxlZnQsIHNldCBvbmUgdGljayBpbiB0aGUgbWlkZGxlICgjMzE5NSkgXG5cdFx0XHRpZiAodGlja1Bvc2l0aW9ucy5sZW5ndGggPT09IDAgJiYgZGVmaW5lZChyb3VuZGVkTWluKSkge1xuXHRcdFx0XHR0aWNrUG9zaXRpb25zLnB1c2goKHJvdW5kZWRNYXggKyByb3VuZGVkTWluKSAvIDIpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXaGVuIHRoZXJlIGlzIG9ubHkgb25lIHBvaW50LCBvciBhbGwgcG9pbnRzIGhhdmUgdGhlIHNhbWUgdmFsdWUgb24gdGhpcyBheGlzLCB0aGVuIG1pblxuXHRcdFx0Ly8gYW5kIG1heCBhcmUgZXF1YWwgYW5kIHRpY2tQb3NpdGlvbnMubGVuZ3RoIGlzIDAgb3IgMS4gSW4gdGhpcyBjYXNlLCBhZGQgc29tZSBwYWRkaW5nXG5cdFx0XHQvLyBpbiBvcmRlciB0byBjZW50ZXIgdGhlIHBvaW50LCBidXQgbGVhdmUgaXQgd2l0aCBvbmUgdGljay4gIzEzMzcuXG5cdFx0XHRpZiAodGlja1Bvc2l0aW9ucy5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0c2luZ2xlUGFkID0gbWF0aEFicyhheGlzLm1heCkgPiAxMGUxMiA/IDEgOiAwLjAwMTsgLy8gVGhlIGxvd2VzdCBwb3NzaWJsZSBudW1iZXIgdG8gYXZvaWQgZXh0cmEgcGFkZGluZyBvbiBjb2x1bW5zICgjMjYxOSwgIzI4NDYpXG5cdFx0XHRcdGF4aXMubWluIC09IHNpbmdsZVBhZDtcblx0XHRcdFx0YXhpcy5tYXggKz0gc2luZ2xlUGFkO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBtYXggdGlja3Mgb2YgZWl0aGVyIHRoZSB4IGFuZCB5IGF4aXMgY29sbGVjdGlvblxuXHQgKi9cblx0c2V0TWF4VGlja3M6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRtYXhUaWNrcyA9IGNoYXJ0Lm1heFRpY2tzIHx8IHt9LFxuXHRcdFx0dGlja1Bvc2l0aW9ucyA9IHRoaXMudGlja1Bvc2l0aW9ucyxcblx0XHRcdGtleSA9IHRoaXMuX21heFRpY2tzS2V5ID0gW3RoaXMuY29sbCwgdGhpcy5wb3MsIHRoaXMubGVuXS5qb2luKCctJyk7XG5cblx0XHRpZiAoIXRoaXMuaXNMaW5rZWQgJiYgIXRoaXMuaXNEYXRldGltZUF4aXMgJiYgdGlja1Bvc2l0aW9ucyAmJiB0aWNrUG9zaXRpb25zLmxlbmd0aCA+IChtYXhUaWNrc1trZXldIHx8IDApICYmIHRoaXMub3B0aW9ucy5hbGlnblRpY2tzICE9PSBmYWxzZSkge1xuXHRcdFx0bWF4VGlja3Nba2V5XSA9IHRpY2tQb3NpdGlvbnMubGVuZ3RoO1xuXHRcdH1cblx0XHRjaGFydC5tYXhUaWNrcyA9IG1heFRpY2tzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBXaGVuIHVzaW5nIG11bHRpcGxlIGF4ZXMsIGFkanVzdCB0aGUgbnVtYmVyIG9mIHRpY2tzIHRvIG1hdGNoIHRoZSBoaWdoZXN0XG5cdCAqIG51bWJlciBvZiB0aWNrcyBpbiB0aGF0IGdyb3VwXG5cdCAqL1xuXHRhZGp1c3RUaWNrQW1vdW50OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0a2V5ID0gYXhpcy5fbWF4VGlja3NLZXksXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy50aWNrUG9zaXRpb25zLFxuXHRcdFx0bWF4VGlja3MgPSBjaGFydC5tYXhUaWNrcztcblxuXHRcdGlmIChtYXhUaWNrcyAmJiBtYXhUaWNrc1trZXldICYmICFheGlzLmlzRGF0ZXRpbWVBeGlzICYmICFheGlzLmNhdGVnb3JpZXMgJiYgIWF4aXMuaXNMaW5rZWQgJiZcblx0XHRcdFx0YXhpcy5vcHRpb25zLmFsaWduVGlja3MgIT09IGZhbHNlICYmIHRoaXMubWluICE9PSBVTkRFRklORUQpIHtcblx0XHRcdHZhciBvbGRUaWNrQW1vdW50ID0gYXhpcy50aWNrQW1vdW50LFxuXHRcdFx0XHRjYWxjdWxhdGVkVGlja0Ftb3VudCA9IHRpY2tQb3NpdGlvbnMubGVuZ3RoLFxuXHRcdFx0XHR0aWNrQW1vdW50O1xuXG5cdFx0XHQvLyBzZXQgdGhlIGF4aXMtbGV2ZWwgdGlja0Ftb3VudCB0byB1c2UgYmVsb3dcblx0XHRcdGF4aXMudGlja0Ftb3VudCA9IHRpY2tBbW91bnQgPSBtYXhUaWNrc1trZXldO1xuXG5cdFx0XHRpZiAoY2FsY3VsYXRlZFRpY2tBbW91bnQgPCB0aWNrQW1vdW50KSB7XG5cdFx0XHRcdHdoaWxlICh0aWNrUG9zaXRpb25zLmxlbmd0aCA8IHRpY2tBbW91bnQpIHtcblx0XHRcdFx0XHR0aWNrUG9zaXRpb25zLnB1c2goY29ycmVjdEZsb2F0KFxuXHRcdFx0XHRcdFx0dGlja1Bvc2l0aW9uc1t0aWNrUG9zaXRpb25zLmxlbmd0aCAtIDFdICsgYXhpcy50aWNrSW50ZXJ2YWxcblx0XHRcdFx0XHQpKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRheGlzLnRyYW5zQSAqPSAoY2FsY3VsYXRlZFRpY2tBbW91bnQgLSAxKSAvICh0aWNrQW1vdW50IC0gMSk7XG5cdFx0XHRcdGF4aXMubWF4ID0gdGlja1Bvc2l0aW9uc1t0aWNrUG9zaXRpb25zLmxlbmd0aCAtIDFdO1xuXG5cdFx0XHR9XG5cdFx0XHRpZiAoZGVmaW5lZChvbGRUaWNrQW1vdW50KSAmJiB0aWNrQW1vdW50ICE9PSBvbGRUaWNrQW1vdW50KSB7XG5cdFx0XHRcdGF4aXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHNjYWxlIGJhc2VkIG9uIGRhdGEgbWluIGFuZCBtYXgsIHVzZXIgc2V0IG1pbiBhbmQgbWF4IG9yIG9wdGlvbnNcblx0ICpcblx0ICovXG5cdHNldFNjYWxlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0c3RhY2tzID0gYXhpcy5zdGFja3MsXG5cdFx0XHR0eXBlLFxuXHRcdFx0aSxcblx0XHRcdGlzRGlydHlEYXRhLFxuXHRcdFx0aXNEaXJ0eUF4aXNMZW5ndGg7XG5cblx0XHRheGlzLm9sZE1pbiA9IGF4aXMubWluO1xuXHRcdGF4aXMub2xkTWF4ID0gYXhpcy5tYXg7XG5cdFx0YXhpcy5vbGRBeGlzTGVuZ3RoID0gYXhpcy5sZW47XG5cblx0XHQvLyBzZXQgdGhlIG5ldyBheGlzTGVuZ3RoXG5cdFx0YXhpcy5zZXRBeGlzU2l6ZSgpO1xuXHRcdC8vYXhpc0xlbmd0aCA9IGhvcml6ID8gYXhpc1dpZHRoIDogYXhpc0hlaWdodDtcblx0XHRpc0RpcnR5QXhpc0xlbmd0aCA9IGF4aXMubGVuICE9PSBheGlzLm9sZEF4aXNMZW5ndGg7XG5cblx0XHQvLyBpcyB0aGVyZSBuZXcgZGF0YT9cblx0XHRlYWNoKGF4aXMuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cdFx0XHRpZiAoc2VyaWVzLmlzRGlydHlEYXRhIHx8IHNlcmllcy5pc0RpcnR5IHx8XG5cdFx0XHRcdFx0c2VyaWVzLnhBeGlzLmlzRGlydHkpIHsgLy8gd2hlbiB4IGF4aXMgaXMgZGlydHksIHdlIG5lZWQgbmV3IGRhdGEgZXh0cmVtZXMgZm9yIHkgYXMgd2VsbFxuXHRcdFx0XHRpc0RpcnR5RGF0YSA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBkbyB3ZSByZWFsbHkgbmVlZCB0byBnbyB0aHJvdWdoIGFsbCB0aGlzP1xuXHRcdGlmIChpc0RpcnR5QXhpc0xlbmd0aCB8fCBpc0RpcnR5RGF0YSB8fCBheGlzLmlzTGlua2VkIHx8IGF4aXMuZm9yY2VSZWRyYXcgfHxcblx0XHRcdGF4aXMudXNlck1pbiAhPT0gYXhpcy5vbGRVc2VyTWluIHx8IGF4aXMudXNlck1heCAhPT0gYXhpcy5vbGRVc2VyTWF4KSB7XG5cblx0XHRcdC8vIHJlc2V0IHN0YWNrc1xuXHRcdFx0aWYgKCFheGlzLmlzWEF4aXMpIHtcblx0XHRcdFx0Zm9yICh0eXBlIGluIHN0YWNrcykge1xuXHRcdFx0XHRcdGZvciAoaSBpbiBzdGFja3NbdHlwZV0pIHtcblx0XHRcdFx0XHRcdHN0YWNrc1t0eXBlXVtpXS50b3RhbCA9IG51bGw7XG5cdFx0XHRcdFx0XHRzdGFja3NbdHlwZV1baV0uY3VtID0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0YXhpcy5mb3JjZVJlZHJhdyA9IGZhbHNlO1xuXG5cdFx0XHQvLyBnZXQgZGF0YSBleHRyZW1lcyBpZiBuZWVkZWRcblx0XHRcdGF4aXMuZ2V0U2VyaWVzRXh0cmVtZXMoKTtcblxuXHRcdFx0Ly8gZ2V0IGZpeGVkIHBvc2l0aW9ucyBiYXNlZCBvbiB0aWNrSW50ZXJ2YWxcblx0XHRcdGF4aXMuc2V0VGlja1Bvc2l0aW9ucygpO1xuXG5cdFx0XHQvLyByZWNvcmQgb2xkIHZhbHVlcyB0byBkZWNpZGUgd2hldGhlciBhIHJlc2NhbGUgaXMgbmVjZXNzYXJ5IGxhdGVyIG9uICgjNTQwKVxuXHRcdFx0YXhpcy5vbGRVc2VyTWluID0gYXhpcy51c2VyTWluO1xuXHRcdFx0YXhpcy5vbGRVc2VyTWF4ID0gYXhpcy51c2VyTWF4O1xuXG5cdFx0XHQvLyBNYXJrIGFzIGRpcnR5IGlmIGl0IGlzIG5vdCBhbHJlYWR5IHNldCB0byBkaXJ0eSBhbmQgZXh0cmVtZXMgaGF2ZSBjaGFuZ2VkLiAjNTk1LlxuXHRcdFx0aWYgKCFheGlzLmlzRGlydHkpIHtcblx0XHRcdFx0YXhpcy5pc0RpcnR5ID0gaXNEaXJ0eUF4aXNMZW5ndGggfHwgYXhpcy5taW4gIT09IGF4aXMub2xkTWluIHx8IGF4aXMubWF4ICE9PSBheGlzLm9sZE1heDtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKCFheGlzLmlzWEF4aXMpIHtcblx0XHRcdGlmIChheGlzLm9sZFN0YWNrcykge1xuXHRcdFx0XHRzdGFja3MgPSBheGlzLnN0YWNrcyA9IGF4aXMub2xkU3RhY2tzO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyByZXNldCBzdGFja3Ncblx0XHRcdGZvciAodHlwZSBpbiBzdGFja3MpIHtcblx0XHRcdFx0Zm9yIChpIGluIHN0YWNrc1t0eXBlXSkge1xuXHRcdFx0XHRcdHN0YWNrc1t0eXBlXVtpXS5jdW0gPSBzdGFja3NbdHlwZV1baV0udG90YWw7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIG1heGltdW0gdGljayBhbW91bnRcblx0XHRheGlzLnNldE1heFRpY2tzKCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgZXh0cmVtZXMgYW5kIG9wdGlvbmFsbHkgcmVkcmF3XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBuZXdNaW5cblx0ICogQHBhcmFtIHtOdW1iZXJ9IG5ld01heFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhd1xuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBhbmltYXRpb24gV2hldGhlciB0byBhcHBseSBhbmltYXRpb24sIGFuZCBvcHRpb25hbGx5IGFuaW1hdGlvblxuXHQgKiAgICBjb25maWd1cmF0aW9uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudEFyZ3VtZW50c1xuXHQgKlxuXHQgKi9cblx0c2V0RXh0cmVtZXM6IGZ1bmN0aW9uIChuZXdNaW4sIG5ld01heCwgcmVkcmF3LCBhbmltYXRpb24sIGV2ZW50QXJndW1lbnRzKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0O1xuXG5cdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpOyAvLyBkZWZhdWx0cyB0byB0cnVlXG5cblx0XHQvLyBFeHRlbmQgdGhlIGFyZ3VtZW50cyB3aXRoIG1pbiBhbmQgbWF4XG5cdFx0ZXZlbnRBcmd1bWVudHMgPSBleHRlbmQoZXZlbnRBcmd1bWVudHMsIHtcblx0XHRcdG1pbjogbmV3TWluLFxuXHRcdFx0bWF4OiBuZXdNYXhcblx0XHR9KTtcblxuXHRcdC8vIEZpcmUgdGhlIGV2ZW50XG5cdFx0ZmlyZUV2ZW50KGF4aXMsICdzZXRFeHRyZW1lcycsIGV2ZW50QXJndW1lbnRzLCBmdW5jdGlvbiAoKSB7IC8vIHRoZSBkZWZhdWx0IGV2ZW50IGhhbmRsZXJcblxuXHRcdFx0YXhpcy51c2VyTWluID0gbmV3TWluO1xuXHRcdFx0YXhpcy51c2VyTWF4ID0gbmV3TWF4O1xuXHRcdFx0YXhpcy5ldmVudEFyZ3MgPSBldmVudEFyZ3VtZW50cztcblxuXHRcdFx0Ly8gTWFyayBmb3IgcnVubmluZyBhZnRlclNldEV4dHJlbWVzXG5cdFx0XHRheGlzLmlzRGlydHlFeHRyZW1lcyA9IHRydWU7XG5cblx0XHRcdC8vIHJlZHJhd1xuXHRcdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0XHRjaGFydC5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogT3ZlcnJpZGFibGUgbWV0aG9kIGZvciB6b29taW5nIGNoYXJ0LiBQdWxsZWQgb3V0IGluIGEgc2VwYXJhdGUgbWV0aG9kIHRvIGFsbG93IG92ZXJyaWRpbmdcblx0ICogaW4gc3RvY2sgY2hhcnRzLlxuXHQgKi9cblx0em9vbTogZnVuY3Rpb24gKG5ld01pbiwgbmV3TWF4KSB7XG5cdFx0dmFyIGRhdGFNaW4gPSB0aGlzLmRhdGFNaW4sXG5cdFx0XHRkYXRhTWF4ID0gdGhpcy5kYXRhTWF4LFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblxuXHRcdC8vIFByZXZlbnQgcGluY2ggem9vbWluZyBvdXQgb2YgcmFuZ2UuIENoZWNrIGZvciBkZWZpbmVkIGlzIGZvciAjMTk0Ni4gIzE3MzQuXG5cdFx0aWYgKCF0aGlzLmFsbG93Wm9vbU91dHNpZGUpIHtcblx0XHRcdGlmIChkZWZpbmVkKGRhdGFNaW4pICYmIG5ld01pbiA8PSBtYXRoTWluKGRhdGFNaW4sIHBpY2sob3B0aW9ucy5taW4sIGRhdGFNaW4pKSkge1xuXHRcdFx0XHRuZXdNaW4gPSBVTkRFRklORUQ7XG5cdFx0XHR9XG5cdFx0XHRpZiAoZGVmaW5lZChkYXRhTWF4KSAmJiBuZXdNYXggPj0gbWF0aE1heChkYXRhTWF4LCBwaWNrKG9wdGlvbnMubWF4LCBkYXRhTWF4KSkpIHtcblx0XHRcdFx0bmV3TWF4ID0gVU5ERUZJTkVEO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEluIGZ1bGwgdmlldywgZGlzcGxheWluZyB0aGUgcmVzZXQgem9vbSBidXR0b24gaXMgbm90IHJlcXVpcmVkXG5cdFx0dGhpcy5kaXNwbGF5QnRuID0gbmV3TWluICE9PSBVTkRFRklORUQgfHwgbmV3TWF4ICE9PSBVTkRFRklORUQ7XG5cblx0XHQvLyBEbyBpdFxuXHRcdHRoaXMuc2V0RXh0cmVtZXMoXG5cdFx0XHRuZXdNaW4sXG5cdFx0XHRuZXdNYXgsXG5cdFx0XHRmYWxzZSxcblx0XHRcdFVOREVGSU5FRCxcblx0XHRcdHsgdHJpZ2dlcjogJ3pvb20nIH1cblx0XHQpO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgdGhlIGF4aXMgbWV0cmljc1xuXHQgKi9cblx0c2V0QXhpc1NpemU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdG9mZnNldExlZnQgPSBvcHRpb25zLm9mZnNldExlZnQgfHwgMCxcblx0XHRcdG9mZnNldFJpZ2h0ID0gb3B0aW9ucy5vZmZzZXRSaWdodCB8fCAwLFxuXHRcdFx0aG9yaXogPSB0aGlzLmhvcml6LFxuXHRcdFx0d2lkdGggPSBwaWNrKG9wdGlvbnMud2lkdGgsIGNoYXJ0LnBsb3RXaWR0aCAtIG9mZnNldExlZnQgKyBvZmZzZXRSaWdodCksXG5cdFx0XHRoZWlnaHQgPSBwaWNrKG9wdGlvbnMuaGVpZ2h0LCBjaGFydC5wbG90SGVpZ2h0KSxcblx0XHRcdHRvcCA9IHBpY2sob3B0aW9ucy50b3AsIGNoYXJ0LnBsb3RUb3ApLFxuXHRcdFx0bGVmdCA9IHBpY2sob3B0aW9ucy5sZWZ0LCBjaGFydC5wbG90TGVmdCArIG9mZnNldExlZnQpLFxuXHRcdFx0cGVyY2VudFJlZ2V4ID0gLyUkLztcblxuXHRcdC8vIENoZWNrIGZvciBwZXJjZW50YWdlIGJhc2VkIGlucHV0IHZhbHVlc1xuXHRcdGlmIChwZXJjZW50UmVnZXgudGVzdChoZWlnaHQpKSB7XG5cdFx0XHRoZWlnaHQgPSBwYXJzZUludChoZWlnaHQsIDEwKSAvIDEwMCAqIGNoYXJ0LnBsb3RIZWlnaHQ7XG5cdFx0fVxuXHRcdGlmIChwZXJjZW50UmVnZXgudGVzdCh0b3ApKSB7XG5cdFx0XHR0b3AgPSBwYXJzZUludCh0b3AsIDEwKSAvIDEwMCAqIGNoYXJ0LnBsb3RIZWlnaHQgKyBjaGFydC5wbG90VG9wO1xuXHRcdH1cblxuXHRcdC8vIEV4cG9zZSBiYXNpYyB2YWx1ZXMgdG8gdXNlIGluIFNlcmllcyBvYmplY3QgYW5kIG5hdmlnYXRvclxuXHRcdHRoaXMubGVmdCA9IGxlZnQ7XG5cdFx0dGhpcy50b3AgPSB0b3A7XG5cdFx0dGhpcy53aWR0aCA9IHdpZHRoO1xuXHRcdHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuXHRcdHRoaXMuYm90dG9tID0gY2hhcnQuY2hhcnRIZWlnaHQgLSBoZWlnaHQgLSB0b3A7XG5cdFx0dGhpcy5yaWdodCA9IGNoYXJ0LmNoYXJ0V2lkdGggLSB3aWR0aCAtIGxlZnQ7XG5cblx0XHQvLyBEaXJlY3Rpb24gYWdub3N0aWMgcHJvcGVydGllc1xuXHRcdHRoaXMubGVuID0gbWF0aE1heChob3JpeiA/IHdpZHRoIDogaGVpZ2h0LCAwKTsgLy8gbWF0aE1heCBmaXhlcyAjOTA1XG5cdFx0dGhpcy5wb3MgPSBob3JpeiA/IGxlZnQgOiB0b3A7IC8vIGRpc3RhbmNlIGZyb20gU1ZHIG9yaWdpblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGFjdHVhbCBheGlzIGV4dHJlbWVzXG5cdCAqL1xuXHRnZXRFeHRyZW1lczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdGlzTG9nID0gYXhpcy5pc0xvZztcblxuXHRcdHJldHVybiB7XG5cdFx0XHRtaW46IGlzTG9nID8gY29ycmVjdEZsb2F0KGxpbjJsb2coYXhpcy5taW4pKSA6IGF4aXMubWluLFxuXHRcdFx0bWF4OiBpc0xvZyA/IGNvcnJlY3RGbG9hdChsaW4ybG9nKGF4aXMubWF4KSkgOiBheGlzLm1heCxcblx0XHRcdGRhdGFNaW46IGF4aXMuZGF0YU1pbixcblx0XHRcdGRhdGFNYXg6IGF4aXMuZGF0YU1heCxcblx0XHRcdHVzZXJNaW46IGF4aXMudXNlck1pbixcblx0XHRcdHVzZXJNYXg6IGF4aXMudXNlck1heFxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgemVybyBwbGFuZSBlaXRoZXIgYmFzZWQgb24gemVybyBvciBvbiB0aGUgbWluIG9yIG1heCB2YWx1ZS5cblx0ICogVXNlZCBpbiBiYXIgYW5kIGFyZWEgcGxvdHNcblx0ICovXG5cdGdldFRocmVzaG9sZDogZnVuY3Rpb24gKHRocmVzaG9sZCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdGlzTG9nID0gYXhpcy5pc0xvZztcblxuXHRcdHZhciByZWFsTWluID0gaXNMb2cgPyBsaW4ybG9nKGF4aXMubWluKSA6IGF4aXMubWluLFxuXHRcdFx0cmVhbE1heCA9IGlzTG9nID8gbGluMmxvZyhheGlzLm1heCkgOiBheGlzLm1heDtcblxuXHRcdGlmIChyZWFsTWluID4gdGhyZXNob2xkIHx8IHRocmVzaG9sZCA9PT0gbnVsbCkge1xuXHRcdFx0dGhyZXNob2xkID0gcmVhbE1pbjtcblx0XHR9IGVsc2UgaWYgKHJlYWxNYXggPCB0aHJlc2hvbGQpIHtcblx0XHRcdHRocmVzaG9sZCA9IHJlYWxNYXg7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGF4aXMudHJhbnNsYXRlKHRocmVzaG9sZCwgMCwgMSwgMCwgMSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENvbXB1dGUgYXV0byBhbGlnbm1lbnQgZm9yIHRoZSBheGlzIGxhYmVsIGJhc2VkIG9uIHdoaWNoIHNpZGUgdGhlIGF4aXMgaXMgb25cblx0ICogYW5kIHRoZSBnaXZlbiByb3RhdGlvbiBmb3IgdGhlIGxhYmVsXG5cdCAqL1xuXHRhdXRvTGFiZWxBbGlnbjogZnVuY3Rpb24gKHJvdGF0aW9uKSB7XG5cdFx0dmFyIHJldCxcblx0XHRcdGFuZ2xlID0gKHBpY2socm90YXRpb24sIDApIC0gKHRoaXMuc2lkZSAqIDkwKSArIDcyMCkgJSAzNjA7XG5cblx0XHRpZiAoYW5nbGUgPiAxNSAmJiBhbmdsZSA8IDE2NSkge1xuXHRcdFx0cmV0ID0gJ3JpZ2h0Jztcblx0XHR9IGVsc2UgaWYgKGFuZ2xlID4gMTk1ICYmIGFuZ2xlIDwgMzQ1KSB7XG5cdFx0XHRyZXQgPSAnbGVmdCc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCA9ICdjZW50ZXInO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIHRpY2sgbGFiZWxzIHRvIGEgcHJlbGltaW5hcnkgcG9zaXRpb24gdG8gZ2V0IHRoZWlyIHNpemVzXG5cdCAqL1xuXHRnZXRPZmZzZXQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLnRpY2tQb3NpdGlvbnMsXG5cdFx0XHR0aWNrcyA9IGF4aXMudGlja3MsXG5cdFx0XHRob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHRzaWRlID0gYXhpcy5zaWRlLFxuXHRcdFx0aW52ZXJ0ZWRTaWRlID0gY2hhcnQuaW52ZXJ0ZWQgPyBbMSwgMCwgMywgMl1bc2lkZV0gOiBzaWRlLFxuXHRcdFx0aGFzRGF0YSxcblx0XHRcdHNob3dBeGlzLFxuXHRcdFx0dGl0bGVPZmZzZXQgPSAwLFxuXHRcdFx0dGl0bGVPZmZzZXRPcHRpb24sXG5cdFx0XHR0aXRsZU1hcmdpbiA9IDAsXG5cdFx0XHRheGlzVGl0bGVPcHRpb25zID0gb3B0aW9ucy50aXRsZSxcblx0XHRcdGxhYmVsT3B0aW9ucyA9IG9wdGlvbnMubGFiZWxzLFxuXHRcdFx0bGFiZWxPZmZzZXQgPSAwLCAvLyByZXNldFxuXHRcdFx0bGFiZWxPZmZzZXRQYWRkZWQsXG5cdFx0XHRheGlzT2Zmc2V0ID0gY2hhcnQuYXhpc09mZnNldCxcblx0XHRcdGNsaXBPZmZzZXQgPSBjaGFydC5jbGlwT2Zmc2V0LFxuXHRcdFx0ZGlyZWN0aW9uRmFjdG9yID0gWy0xLCAxLCAxLCAtMV1bc2lkZV0sXG5cdFx0XHRuLFxuXHRcdFx0aSxcblx0XHRcdGF1dG9TdGFnZ2VyTGluZXMgPSAxLFxuXHRcdFx0bWF4U3RhZ2dlckxpbmVzID0gcGljayhsYWJlbE9wdGlvbnMubWF4U3RhZ2dlckxpbmVzLCA1KSxcblx0XHRcdHNvcnRlZFBvc2l0aW9ucyxcblx0XHRcdGxhc3RSaWdodCxcblx0XHRcdG92ZXJsYXAsXG5cdFx0XHRwb3MsXG5cdFx0XHRiQm94LFxuXHRcdFx0eCxcblx0XHRcdHcsXG5cdFx0XHRsaW5lTm8sXG5cdFx0XHRsaW5lSGVpZ2h0Q29ycmVjdGlvbjtcblxuXHRcdC8vIEZvciByZXVzZSBpbiBBeGlzLnJlbmRlclxuXHRcdGF4aXMuaGFzRGF0YSA9IGhhc0RhdGEgPSAoYXhpcy5oYXNWaXNpYmxlU2VyaWVzIHx8IChkZWZpbmVkKGF4aXMubWluKSAmJiBkZWZpbmVkKGF4aXMubWF4KSAmJiAhIXRpY2tQb3NpdGlvbnMpKTtcblx0XHRheGlzLnNob3dBeGlzID0gc2hvd0F4aXMgPSBoYXNEYXRhIHx8IHBpY2sob3B0aW9ucy5zaG93RW1wdHksIHRydWUpO1xuXG5cdFx0Ly8gU2V0L3Jlc2V0IHN0YWdnZXJMaW5lc1xuXHRcdGF4aXMuc3RhZ2dlckxpbmVzID0gYXhpcy5ob3JpeiAmJiBsYWJlbE9wdGlvbnMuc3RhZ2dlckxpbmVzO1xuXG5cdFx0Ly8gQ3JlYXRlIHRoZSBheGlzR3JvdXAgYW5kIGdyaWRHcm91cCBlbGVtZW50cyBvbiBmaXJzdCBpdGVyYXRpb25cblx0XHRpZiAoIWF4aXMuYXhpc0dyb3VwKSB7XG5cdFx0XHRheGlzLmdyaWRHcm91cCA9IHJlbmRlcmVyLmcoJ2dyaWQnKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogb3B0aW9ucy5ncmlkWkluZGV4IHx8IDEgfSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0YXhpcy5heGlzR3JvdXAgPSByZW5kZXJlci5nKCdheGlzJylcblx0XHRcdFx0LmF0dHIoeyB6SW5kZXg6IG9wdGlvbnMuekluZGV4IHx8IDIgfSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0YXhpcy5sYWJlbEdyb3VwID0gcmVuZGVyZXIuZygnYXhpcy1sYWJlbHMnKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogbGFiZWxPcHRpb25zLnpJbmRleCB8fCA3IH0pXG5cdFx0XHRcdC5hZGRDbGFzcyhQUkVGSVggKyBheGlzLmNvbGwudG9Mb3dlckNhc2UoKSArICctbGFiZWxzJylcblx0XHRcdFx0LmFkZCgpO1xuXHRcdH1cblxuXHRcdGlmIChoYXNEYXRhIHx8IGF4aXMuaXNMaW5rZWQpIHtcblxuXHRcdFx0Ly8gU2V0IHRoZSBleHBsaWNpdCBvciBhdXRvbWF0aWMgbGFiZWwgYWxpZ25tZW50XG5cdFx0XHRheGlzLmxhYmVsQWxpZ24gPSBwaWNrKGxhYmVsT3B0aW9ucy5hbGlnbiB8fCBheGlzLmF1dG9MYWJlbEFsaWduKGxhYmVsT3B0aW9ucy5yb3RhdGlvbikpO1xuXG5cdFx0XHQvLyBHZW5lcmF0ZSB0aWNrc1xuXHRcdFx0ZWFjaCh0aWNrUG9zaXRpb25zLCBmdW5jdGlvbiAocG9zKSB7XG5cdFx0XHRcdGlmICghdGlja3NbcG9zXSkge1xuXHRcdFx0XHRcdHRpY2tzW3Bvc10gPSBuZXcgVGljayhheGlzLCBwb3MpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRpY2tzW3Bvc10uYWRkTGFiZWwoKTsgLy8gdXBkYXRlIGxhYmVscyBkZXBlbmRpbmcgb24gdGljayBpbnRlcnZhbFxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gSGFuZGxlIGF1dG9tYXRpYyBzdGFnZ2VyIGxpbmVzXG5cdFx0XHRpZiAoYXhpcy5ob3JpeiAmJiAhYXhpcy5zdGFnZ2VyTGluZXMgJiYgbWF4U3RhZ2dlckxpbmVzICYmICFsYWJlbE9wdGlvbnMucm90YXRpb24pIHtcblx0XHRcdFx0c29ydGVkUG9zaXRpb25zID0gYXhpcy5yZXZlcnNlZCA/IFtdLmNvbmNhdCh0aWNrUG9zaXRpb25zKS5yZXZlcnNlKCkgOiB0aWNrUG9zaXRpb25zO1xuXHRcdFx0XHR3aGlsZSAoYXV0b1N0YWdnZXJMaW5lcyA8IG1heFN0YWdnZXJMaW5lcykge1xuXHRcdFx0XHRcdGxhc3RSaWdodCA9IFtdO1xuXHRcdFx0XHRcdG92ZXJsYXAgPSBmYWxzZTtcblxuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBzb3J0ZWRQb3NpdGlvbnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdHBvcyA9IHNvcnRlZFBvc2l0aW9uc1tpXTtcblx0XHRcdFx0XHRcdGJCb3ggPSB0aWNrc1twb3NdLmxhYmVsICYmIHRpY2tzW3Bvc10ubGFiZWwuZ2V0QkJveCgpO1xuXHRcdFx0XHRcdFx0dyA9IGJCb3ggPyBiQm94LndpZHRoIDogMDtcblx0XHRcdFx0XHRcdGxpbmVObyA9IGkgJSBhdXRvU3RhZ2dlckxpbmVzO1xuXG5cdFx0XHRcdFx0XHRpZiAodykge1xuXHRcdFx0XHRcdFx0XHR4ID0gYXhpcy50cmFuc2xhdGUocG9zKTsgLy8gZG9uJ3QgaGFuZGxlIGxvZ1xuXHRcdFx0XHRcdFx0XHRpZiAobGFzdFJpZ2h0W2xpbmVOb10gIT09IFVOREVGSU5FRCAmJiB4IDwgbGFzdFJpZ2h0W2xpbmVOb10pIHtcblx0XHRcdFx0XHRcdFx0XHRvdmVybGFwID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRsYXN0UmlnaHRbbGluZU5vXSA9IHggKyB3O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAob3ZlcmxhcCkge1xuXHRcdFx0XHRcdFx0YXV0b1N0YWdnZXJMaW5lcysrO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoYXV0b1N0YWdnZXJMaW5lcyA+IDEpIHtcblx0XHRcdFx0XHRheGlzLnN0YWdnZXJMaW5lcyA9IGF1dG9TdGFnZ2VyTGluZXM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXG5cdFx0XHRlYWNoKHRpY2tQb3NpdGlvbnMsIGZ1bmN0aW9uIChwb3MpIHtcblx0XHRcdFx0Ly8gbGVmdCBzaWRlIG11c3QgYmUgYWxpZ246IHJpZ2h0IGFuZCByaWdodCBzaWRlIG11c3QgaGF2ZSBhbGlnbjogbGVmdCBmb3IgbGFiZWxzXG5cdFx0XHRcdGlmIChzaWRlID09PSAwIHx8IHNpZGUgPT09IDIgfHwgeyAxOiAnbGVmdCcsIDM6ICdyaWdodCcgfVtzaWRlXSA9PT0gYXhpcy5sYWJlbEFsaWduKSB7XG5cblx0XHRcdFx0XHQvLyBnZXQgdGhlIGhpZ2hlc3Qgb2Zmc2V0XG5cdFx0XHRcdFx0bGFiZWxPZmZzZXQgPSBtYXRoTWF4KFxuXHRcdFx0XHRcdFx0dGlja3NbcG9zXS5nZXRMYWJlbFNpemUoKSxcblx0XHRcdFx0XHRcdGxhYmVsT2Zmc2V0XG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGlmIChheGlzLnN0YWdnZXJMaW5lcykge1xuXHRcdFx0XHRsYWJlbE9mZnNldCAqPSBheGlzLnN0YWdnZXJMaW5lcztcblx0XHRcdFx0YXhpcy5sYWJlbE9mZnNldCA9IGxhYmVsT2Zmc2V0O1xuXHRcdFx0fVxuXG5cblx0XHR9IGVsc2UgeyAvLyBkb2Vzbid0IGhhdmUgZGF0YVxuXHRcdFx0Zm9yIChuIGluIHRpY2tzKSB7XG5cdFx0XHRcdHRpY2tzW25dLmRlc3Ryb3koKTtcblx0XHRcdFx0ZGVsZXRlIHRpY2tzW25dO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChheGlzVGl0bGVPcHRpb25zICYmIGF4aXNUaXRsZU9wdGlvbnMudGV4dCAmJiBheGlzVGl0bGVPcHRpb25zLmVuYWJsZWQgIT09IGZhbHNlKSB7XG5cdFx0XHRpZiAoIWF4aXMuYXhpc1RpdGxlKSB7XG5cdFx0XHRcdGF4aXMuYXhpc1RpdGxlID0gcmVuZGVyZXIudGV4dChcblx0XHRcdFx0XHRheGlzVGl0bGVPcHRpb25zLnRleHQsXG5cdFx0XHRcdFx0MCxcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdGF4aXNUaXRsZU9wdGlvbnMudXNlSFRNTFxuXHRcdFx0XHQpXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHR6SW5kZXg6IDcsXG5cdFx0XHRcdFx0cm90YXRpb246IGF4aXNUaXRsZU9wdGlvbnMucm90YXRpb24gfHwgMCxcblx0XHRcdFx0XHRhbGlnbjpcblx0XHRcdFx0XHRcdGF4aXNUaXRsZU9wdGlvbnMudGV4dEFsaWduIHx8XG5cdFx0XHRcdFx0XHR7IGxvdzogJ2xlZnQnLCBtaWRkbGU6ICdjZW50ZXInLCBoaWdoOiAncmlnaHQnIH1bYXhpc1RpdGxlT3B0aW9ucy5hbGlnbl1cblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZENsYXNzKFBSRUZJWCArIHRoaXMuY29sbC50b0xvd2VyQ2FzZSgpICsgJy10aXRsZScpXG5cdFx0XHRcdC5jc3MoYXhpc1RpdGxlT3B0aW9ucy5zdHlsZSlcblx0XHRcdFx0LmFkZChheGlzLmF4aXNHcm91cCk7XG5cdFx0XHRcdGF4aXMuYXhpc1RpdGxlLmlzTmV3ID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHNob3dBeGlzKSB7XG5cdFx0XHRcdHRpdGxlT2Zmc2V0ID0gYXhpcy5heGlzVGl0bGUuZ2V0QkJveCgpW2hvcml6ID8gJ2hlaWdodCcgOiAnd2lkdGgnXTtcblx0XHRcdFx0dGl0bGVPZmZzZXRPcHRpb24gPSBheGlzVGl0bGVPcHRpb25zLm9mZnNldDtcblx0XHRcdFx0dGl0bGVNYXJnaW4gPSBkZWZpbmVkKHRpdGxlT2Zmc2V0T3B0aW9uKSA/IDAgOiBwaWNrKGF4aXNUaXRsZU9wdGlvbnMubWFyZ2luLCBob3JpeiA/IDUgOiAxMCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGhpZGUgb3Igc2hvdyB0aGUgdGl0bGUgZGVwZW5kaW5nIG9uIHdoZXRoZXIgc2hvd0VtcHR5IGlzIHNldFxuXHRcdFx0YXhpcy5heGlzVGl0bGVbc2hvd0F4aXMgPyAnc2hvdycgOiAnaGlkZSddKCk7XG5cdFx0fVxuXG5cdFx0Ly8gaGFuZGxlIGF1dG9tYXRpYyBvciB1c2VyIHNldCBvZmZzZXRcblx0XHRheGlzLm9mZnNldCA9IGRpcmVjdGlvbkZhY3RvciAqIHBpY2sob3B0aW9ucy5vZmZzZXQsIGF4aXNPZmZzZXRbc2lkZV0pO1xuXG5cdFx0bGluZUhlaWdodENvcnJlY3Rpb24gPSBzaWRlID09PSAyID8gYXhpcy50aWNrQmFzZWxpbmUgOiAwO1xuXHRcdGxhYmVsT2Zmc2V0UGFkZGVkID0gbGFiZWxPZmZzZXQgKyB0aXRsZU1hcmdpbiArXG5cdFx0XHQobGFiZWxPZmZzZXQgJiYgKGRpcmVjdGlvbkZhY3RvciAqIChob3JpeiA/IHBpY2sobGFiZWxPcHRpb25zLnksIGF4aXMudGlja0Jhc2VsaW5lICsgOCkgOiBsYWJlbE9wdGlvbnMueCkgLSBsaW5lSGVpZ2h0Q29ycmVjdGlvbikpO1xuXHRcdGF4aXMuYXhpc1RpdGxlTWFyZ2luID0gcGljayh0aXRsZU9mZnNldE9wdGlvbiwgbGFiZWxPZmZzZXRQYWRkZWQpO1xuXG5cdFx0YXhpc09mZnNldFtzaWRlXSA9IG1hdGhNYXgoXG5cdFx0XHRheGlzT2Zmc2V0W3NpZGVdLFxuXHRcdFx0YXhpcy5heGlzVGl0bGVNYXJnaW4gKyB0aXRsZU9mZnNldCArIGRpcmVjdGlvbkZhY3RvciAqIGF4aXMub2Zmc2V0LFxuXHRcdFx0bGFiZWxPZmZzZXRQYWRkZWQgLy8gIzMwMjdcblx0XHQpO1xuXHRcdGNsaXBPZmZzZXRbaW52ZXJ0ZWRTaWRlXSA9IG1hdGhNYXgoY2xpcE9mZnNldFtpbnZlcnRlZFNpZGVdLCBtYXRoRmxvb3Iob3B0aW9ucy5saW5lV2lkdGggLyAyKSAqIDIpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHBhdGggZm9yIHRoZSBheGlzIGxpbmVcblx0ICovXG5cdGdldExpbmVQYXRoOiBmdW5jdGlvbiAobGluZVdpZHRoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdG9wcG9zaXRlID0gdGhpcy5vcHBvc2l0ZSxcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0LFxuXHRcdFx0aG9yaXogPSB0aGlzLmhvcml6LFxuXHRcdFx0bGluZUxlZnQgPSB0aGlzLmxlZnQgKyAob3Bwb3NpdGUgPyB0aGlzLndpZHRoIDogMCkgKyBvZmZzZXQsXG5cdFx0XHRsaW5lVG9wID0gY2hhcnQuY2hhcnRIZWlnaHQgLSB0aGlzLmJvdHRvbSAtIChvcHBvc2l0ZSA/IHRoaXMuaGVpZ2h0IDogMCkgKyBvZmZzZXQ7XG5cblx0XHRpZiAob3Bwb3NpdGUpIHtcblx0XHRcdGxpbmVXaWR0aCAqPSAtMTsgLy8gY3Jpc3BpZnkgdGhlIG90aGVyIHdheSAtICMxNDgwLCAjMTY4N1xuXHRcdH1cblxuXHRcdHJldHVybiBjaGFydC5yZW5kZXJlci5jcmlzcExpbmUoW1xuXHRcdFx0XHRNLFxuXHRcdFx0XHRob3JpeiA/XG5cdFx0XHRcdFx0dGhpcy5sZWZ0IDpcblx0XHRcdFx0XHRsaW5lTGVmdCxcblx0XHRcdFx0aG9yaXogP1xuXHRcdFx0XHRcdGxpbmVUb3AgOlxuXHRcdFx0XHRcdHRoaXMudG9wLFxuXHRcdFx0XHRMLFxuXHRcdFx0XHRob3JpeiA/XG5cdFx0XHRcdFx0Y2hhcnQuY2hhcnRXaWR0aCAtIHRoaXMucmlnaHQgOlxuXHRcdFx0XHRcdGxpbmVMZWZ0LFxuXHRcdFx0XHRob3JpeiA/XG5cdFx0XHRcdFx0bGluZVRvcCA6XG5cdFx0XHRcdFx0Y2hhcnQuY2hhcnRIZWlnaHQgLSB0aGlzLmJvdHRvbVxuXHRcdFx0XSwgbGluZVdpZHRoKTtcblx0fSxcblxuXHQvKipcblx0ICogUG9zaXRpb24gdGhlIHRpdGxlXG5cdCAqL1xuXHRnZXRUaXRsZVBvc2l0aW9uOiBmdW5jdGlvbiAoKSB7XG5cdFx0Ly8gY29tcHV0ZSBhbmNob3IgcG9pbnRzIGZvciBlYWNoIG9mIHRoZSB0aXRsZSBhbGlnbiBvcHRpb25zXG5cdFx0dmFyIGhvcml6ID0gdGhpcy5ob3Jpeixcblx0XHRcdGF4aXNMZWZ0ID0gdGhpcy5sZWZ0LFxuXHRcdFx0YXhpc1RvcCA9IHRoaXMudG9wLFxuXHRcdFx0YXhpc0xlbmd0aCA9IHRoaXMubGVuLFxuXHRcdFx0YXhpc1RpdGxlT3B0aW9ucyA9IHRoaXMub3B0aW9ucy50aXRsZSxcblx0XHRcdG1hcmdpbiA9IGhvcml6ID8gYXhpc0xlZnQgOiBheGlzVG9wLFxuXHRcdFx0b3Bwb3NpdGUgPSB0aGlzLm9wcG9zaXRlLFxuXHRcdFx0b2Zmc2V0ID0gdGhpcy5vZmZzZXQsXG5cdFx0XHRmb250U2l6ZSA9IHBJbnQoYXhpc1RpdGxlT3B0aW9ucy5zdHlsZS5mb250U2l6ZSB8fCAxMiksXG5cblx0XHRcdC8vIHRoZSBwb3NpdGlvbiBpbiB0aGUgbGVuZ3RoIGRpcmVjdGlvbiBvZiB0aGUgYXhpc1xuXHRcdFx0YWxvbmdBeGlzID0ge1xuXHRcdFx0XHRsb3c6IG1hcmdpbiArIChob3JpeiA/IDAgOiBheGlzTGVuZ3RoKSxcblx0XHRcdFx0bWlkZGxlOiBtYXJnaW4gKyBheGlzTGVuZ3RoIC8gMixcblx0XHRcdFx0aGlnaDogbWFyZ2luICsgKGhvcml6ID8gYXhpc0xlbmd0aCA6IDApXG5cdFx0XHR9W2F4aXNUaXRsZU9wdGlvbnMuYWxpZ25dLFxuXG5cdFx0XHQvLyB0aGUgcG9zaXRpb24gaW4gdGhlIHBlcnBlbmRpY3VsYXIgZGlyZWN0aW9uIG9mIHRoZSBheGlzXG5cdFx0XHRvZmZBeGlzID0gKGhvcml6ID8gYXhpc1RvcCArIHRoaXMuaGVpZ2h0IDogYXhpc0xlZnQpICtcblx0XHRcdFx0KGhvcml6ID8gMSA6IC0xKSAqIC8vIGhvcml6b250YWwgYXhpcyByZXZlcnNlcyB0aGUgbWFyZ2luXG5cdFx0XHRcdChvcHBvc2l0ZSA/IC0xIDogMSkgKiAvLyBzbyBkb2VzIG9wcG9zaXRlIGF4ZXNcblx0XHRcdFx0dGhpcy5heGlzVGl0bGVNYXJnaW4gK1xuXHRcdFx0XHQodGhpcy5zaWRlID09PSAyID8gZm9udFNpemUgOiAwKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHR4OiBob3JpeiA/XG5cdFx0XHRcdGFsb25nQXhpcyA6XG5cdFx0XHRcdG9mZkF4aXMgKyAob3Bwb3NpdGUgPyB0aGlzLndpZHRoIDogMCkgKyBvZmZzZXQgK1xuXHRcdFx0XHRcdChheGlzVGl0bGVPcHRpb25zLnggfHwgMCksIC8vIHhcblx0XHRcdHk6IGhvcml6ID9cblx0XHRcdFx0b2ZmQXhpcyAtIChvcHBvc2l0ZSA/IHRoaXMuaGVpZ2h0IDogMCkgKyBvZmZzZXQgOlxuXHRcdFx0XHRhbG9uZ0F4aXMgKyAoYXhpc1RpdGxlT3B0aW9ucy55IHx8IDApIC8vIHlcblx0XHR9O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIGF4aXNcblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdGhvcml6ID0gYXhpcy5ob3Jpeixcblx0XHRcdHJldmVyc2VkID0gYXhpcy5yZXZlcnNlZCxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRvcHRpb25zID0gYXhpcy5vcHRpb25zLFxuXHRcdFx0aXNMb2cgPSBheGlzLmlzTG9nLFxuXHRcdFx0aXNMaW5rZWQgPSBheGlzLmlzTGlua2VkLFxuXHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMudGlja1Bvc2l0aW9ucyxcblx0XHRcdHNvcnRlZFBvc2l0aW9ucyxcblx0XHRcdGF4aXNUaXRsZSA9IGF4aXMuYXhpc1RpdGxlLFx0XHRcdFxuXHRcdFx0dGlja3MgPSBheGlzLnRpY2tzLFxuXHRcdFx0bWlub3JUaWNrcyA9IGF4aXMubWlub3JUaWNrcyxcblx0XHRcdGFsdGVybmF0ZUJhbmRzID0gYXhpcy5hbHRlcm5hdGVCYW5kcyxcblx0XHRcdHN0YWNrTGFiZWxPcHRpb25zID0gb3B0aW9ucy5zdGFja0xhYmVscyxcblx0XHRcdGFsdGVybmF0ZUdyaWRDb2xvciA9IG9wdGlvbnMuYWx0ZXJuYXRlR3JpZENvbG9yLFxuXHRcdFx0dGlja21hcmtPZmZzZXQgPSBheGlzLnRpY2ttYXJrT2Zmc2V0LFxuXHRcdFx0bGluZVdpZHRoID0gb3B0aW9ucy5saW5lV2lkdGgsXG5cdFx0XHRsaW5lUGF0aCxcblx0XHRcdGhhc1JlbmRlcmVkID0gY2hhcnQuaGFzUmVuZGVyZWQsXG5cdFx0XHRzbGlkZUluVGlja3MgPSBoYXNSZW5kZXJlZCAmJiBkZWZpbmVkKGF4aXMub2xkTWluKSAmJiAhaXNOYU4oYXhpcy5vbGRNaW4pLFxuXHRcdFx0aGFzRGF0YSA9IGF4aXMuaGFzRGF0YSxcblx0XHRcdHNob3dBeGlzID0gYXhpcy5zaG93QXhpcyxcblx0XHRcdGZyb20sXG5cdFx0XHRvdmVyZmxvdyA9IG9wdGlvbnMubGFiZWxzLm92ZXJmbG93LFxuXHRcdFx0anVzdGlmeUxhYmVscyA9IGF4aXMuanVzdGlmeUxhYmVscyA9IGhvcml6ICYmIG92ZXJmbG93ICE9PSBmYWxzZSxcblx0XHRcdHRvO1xuXG5cdFx0Ly8gUmVzZXRcblx0XHRheGlzLmxhYmVsRWRnZS5sZW5ndGggPSAwO1xuXHRcdGF4aXMuanVzdGlmeVRvUGxvdCA9IG92ZXJmbG93ID09PSAnanVzdGlmeSc7XG5cblx0XHQvLyBNYXJrIGFsbCBlbGVtZW50cyBpbkFjdGl2ZSBiZWZvcmUgd2UgZ28gb3ZlciBhbmQgbWFyayB0aGUgYWN0aXZlIG9uZXNcblx0XHRlYWNoKFt0aWNrcywgbWlub3JUaWNrcywgYWx0ZXJuYXRlQmFuZHNdLCBmdW5jdGlvbiAoY29sbCkge1xuXHRcdFx0dmFyIHBvcztcblx0XHRcdGZvciAocG9zIGluIGNvbGwpIHtcblx0XHRcdFx0Y29sbFtwb3NdLmlzQWN0aXZlID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBJZiB0aGUgc2VyaWVzIGhhcyBkYXRhIGRyYXcgdGhlIHRpY2tzLiBFbHNlIG9ubHkgdGhlIGxpbmUgYW5kIHRpdGxlXG5cdFx0aWYgKGhhc0RhdGEgfHwgaXNMaW5rZWQpIHtcblxuXHRcdFx0Ly8gbWlub3IgdGlja3Ncblx0XHRcdGlmIChheGlzLm1pbm9yVGlja0ludGVydmFsICYmICFheGlzLmNhdGVnb3JpZXMpIHtcblx0XHRcdFx0ZWFjaChheGlzLmdldE1pbm9yVGlja1Bvc2l0aW9ucygpLCBmdW5jdGlvbiAocG9zKSB7XG5cdFx0XHRcdFx0aWYgKCFtaW5vclRpY2tzW3Bvc10pIHtcblx0XHRcdFx0XHRcdG1pbm9yVGlja3NbcG9zXSA9IG5ldyBUaWNrKGF4aXMsIHBvcywgJ21pbm9yJyk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gcmVuZGVyIG5ldyB0aWNrcyBpbiBvbGQgcG9zaXRpb25cblx0XHRcdFx0XHRpZiAoc2xpZGVJblRpY2tzICYmIG1pbm9yVGlja3NbcG9zXS5pc05ldykge1xuXHRcdFx0XHRcdFx0bWlub3JUaWNrc1twb3NdLnJlbmRlcihudWxsLCB0cnVlKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRtaW5vclRpY2tzW3Bvc10ucmVuZGVyKG51bGwsIGZhbHNlLCAxKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1ham9yIHRpY2tzLiBQdWxsIG91dCB0aGUgZmlyc3QgaXRlbSBhbmQgcmVuZGVyIGl0IGxhc3Qgc28gdGhhdFxuXHRcdFx0Ly8gd2UgY2FuIGdldCB0aGUgcG9zaXRpb24gb2YgdGhlIG5laWdoYm91ciBsYWJlbC4gIzgwOC5cblx0XHRcdGlmICh0aWNrUG9zaXRpb25zLmxlbmd0aCkgeyAvLyAjMTMwMFxuXHRcdFx0XHRzb3J0ZWRQb3NpdGlvbnMgPSB0aWNrUG9zaXRpb25zLnNsaWNlKCk7XG5cdFx0XHRcdGlmICgoaG9yaXogJiYgcmV2ZXJzZWQpIHx8ICghaG9yaXogJiYgIXJldmVyc2VkKSkge1xuXHRcdFx0XHRcdHNvcnRlZFBvc2l0aW9ucy5yZXZlcnNlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGp1c3RpZnlMYWJlbHMpIHtcblx0XHRcdFx0XHRzb3J0ZWRQb3NpdGlvbnMgPSBzb3J0ZWRQb3NpdGlvbnMuc2xpY2UoMSkuY29uY2F0KFtzb3J0ZWRQb3NpdGlvbnNbMF1dKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlYWNoKHNvcnRlZFBvc2l0aW9ucywgZnVuY3Rpb24gKHBvcywgaSkge1xuXG5cdFx0XHRcdFx0Ly8gUmVvcmdhbml6ZSB0aGUgaW5kaWNlc1xuXHRcdFx0XHRcdGlmIChqdXN0aWZ5TGFiZWxzKSB7XG5cdFx0XHRcdFx0XHRpID0gKGkgPT09IHNvcnRlZFBvc2l0aW9ucy5sZW5ndGggLSAxKSA/IDAgOiBpICsgMTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBsaW5rZWQgYXhlcyBuZWVkIGFuIGV4dHJhIGNoZWNrIHRvIGZpbmQgb3V0IGlmXG5cdFx0XHRcdFx0aWYgKCFpc0xpbmtlZCB8fCAocG9zID49IGF4aXMubWluICYmIHBvcyA8PSBheGlzLm1heCkpIHtcblxuXHRcdFx0XHRcdFx0aWYgKCF0aWNrc1twb3NdKSB7XG5cdFx0XHRcdFx0XHRcdHRpY2tzW3Bvc10gPSBuZXcgVGljayhheGlzLCBwb3MpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyByZW5kZXIgbmV3IHRpY2tzIGluIG9sZCBwb3NpdGlvblxuXHRcdFx0XHRcdFx0aWYgKHNsaWRlSW5UaWNrcyAmJiB0aWNrc1twb3NdLmlzTmV3KSB7XG5cdFx0XHRcdFx0XHRcdHRpY2tzW3Bvc10ucmVuZGVyKGksIHRydWUsIDAuMSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHRpY2tzW3Bvc10ucmVuZGVyKGkpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9KTtcblx0XHRcdFx0Ly8gSW4gYSBjYXRlZ29yaXplZCBheGlzLCB0aGUgdGljayBtYXJrcyBhcmUgZGlzcGxheWVkIGJldHdlZW4gbGFiZWxzLiBTb1xuXHRcdFx0XHQvLyB3ZSBuZWVkIHRvIGFkZCBhIHRpY2sgbWFyayBhbmQgZ3JpZCBsaW5lIGF0IHRoZSBsZWZ0IGVkZ2Ugb2YgdGhlIFggYXhpcy5cblx0XHRcdFx0aWYgKHRpY2ttYXJrT2Zmc2V0ICYmIGF4aXMubWluID09PSAwKSB7XG5cdFx0XHRcdFx0aWYgKCF0aWNrc1stMV0pIHtcblx0XHRcdFx0XHRcdHRpY2tzWy0xXSA9IG5ldyBUaWNrKGF4aXMsIC0xLCBudWxsLCB0cnVlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGlja3NbLTFdLnJlbmRlcigtMSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBhbHRlcm5hdGUgZ3JpZCBjb2xvclxuXHRcdFx0aWYgKGFsdGVybmF0ZUdyaWRDb2xvcikge1xuXHRcdFx0XHRlYWNoKHRpY2tQb3NpdGlvbnMsIGZ1bmN0aW9uIChwb3MsIGkpIHtcblx0XHRcdFx0XHRpZiAoaSAlIDIgPT09IDAgJiYgcG9zIDwgYXhpcy5tYXgpIHtcblx0XHRcdFx0XHRcdGlmICghYWx0ZXJuYXRlQmFuZHNbcG9zXSkge1xuXHRcdFx0XHRcdFx0XHRhbHRlcm5hdGVCYW5kc1twb3NdID0gbmV3IEhpZ2hjaGFydHMuUGxvdExpbmVPckJhbmQoYXhpcyk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRmcm9tID0gcG9zICsgdGlja21hcmtPZmZzZXQ7IC8vICM5NDlcblx0XHRcdFx0XHRcdHRvID0gdGlja1Bvc2l0aW9uc1tpICsgMV0gIT09IFVOREVGSU5FRCA/IHRpY2tQb3NpdGlvbnNbaSArIDFdICsgdGlja21hcmtPZmZzZXQgOiBheGlzLm1heDtcblx0XHRcdFx0XHRcdGFsdGVybmF0ZUJhbmRzW3Bvc10ub3B0aW9ucyA9IHtcblx0XHRcdFx0XHRcdFx0ZnJvbTogaXNMb2cgPyBsaW4ybG9nKGZyb20pIDogZnJvbSxcblx0XHRcdFx0XHRcdFx0dG86IGlzTG9nID8gbGluMmxvZyh0bykgOiB0byxcblx0XHRcdFx0XHRcdFx0Y29sb3I6IGFsdGVybmF0ZUdyaWRDb2xvclxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRcdGFsdGVybmF0ZUJhbmRzW3Bvc10ucmVuZGVyKCk7XG5cdFx0XHRcdFx0XHRhbHRlcm5hdGVCYW5kc1twb3NdLmlzQWN0aXZlID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBjdXN0b20gcGxvdCBsaW5lcyBhbmQgYmFuZHNcblx0XHRcdGlmICghYXhpcy5fYWRkZWRQbG90TEIpIHsgLy8gb25seSBmaXJzdCB0aW1lXG5cdFx0XHRcdGVhY2goKG9wdGlvbnMucGxvdExpbmVzIHx8IFtdKS5jb25jYXQob3B0aW9ucy5wbG90QmFuZHMgfHwgW10pLCBmdW5jdGlvbiAocGxvdExpbmVPcHRpb25zKSB7XG5cdFx0XHRcdFx0YXhpcy5hZGRQbG90QmFuZE9yTGluZShwbG90TGluZU9wdGlvbnMpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0YXhpcy5fYWRkZWRQbG90TEIgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0fSAvLyBlbmQgaWYgaGFzRGF0YVxuXG5cdFx0Ly8gUmVtb3ZlIGluYWN0aXZlIHRpY2tzXG5cdFx0ZWFjaChbdGlja3MsIG1pbm9yVGlja3MsIGFsdGVybmF0ZUJhbmRzXSwgZnVuY3Rpb24gKGNvbGwpIHtcblx0XHRcdHZhciBwb3MsXG5cdFx0XHRcdGksXG5cdFx0XHRcdGZvckRlc3RydWN0aW9uID0gW10sXG5cdFx0XHRcdGRlbGF5ID0gZ2xvYmFsQW5pbWF0aW9uID8gZ2xvYmFsQW5pbWF0aW9uLmR1cmF0aW9uIHx8IDUwMCA6IDAsXG5cdFx0XHRcdGRlc3Ryb3lJbmFjdGl2ZUl0ZW1zID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGkgPSBmb3JEZXN0cnVjdGlvbi5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRcdFx0Ly8gV2hlbiByZXNpemluZyByYXBpZGx5LCB0aGUgc2FtZSBpdGVtcyBtYXkgYmUgZGVzdHJveWVkIGluIGRpZmZlcmVudCB0aW1lb3V0cyxcblx0XHRcdFx0XHRcdC8vIG9yIHRoZSBtYXkgYmUgcmVhY3RpdmF0ZWRcblx0XHRcdFx0XHRcdGlmIChjb2xsW2ZvckRlc3RydWN0aW9uW2ldXSAmJiAhY29sbFtmb3JEZXN0cnVjdGlvbltpXV0uaXNBY3RpdmUpIHtcblx0XHRcdFx0XHRcdFx0Y29sbFtmb3JEZXN0cnVjdGlvbltpXV0uZGVzdHJveSgpO1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgY29sbFtmb3JEZXN0cnVjdGlvbltpXV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH07XG5cblx0XHRcdGZvciAocG9zIGluIGNvbGwpIHtcblxuXHRcdFx0XHRpZiAoIWNvbGxbcG9zXS5pc0FjdGl2ZSkge1xuXHRcdFx0XHRcdC8vIFJlbmRlciB0byB6ZXJvIG9wYWNpdHlcblx0XHRcdFx0XHRjb2xsW3Bvc10ucmVuZGVyKHBvcywgZmFsc2UsIDApO1xuXHRcdFx0XHRcdGNvbGxbcG9zXS5pc0FjdGl2ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdGZvckRlc3RydWN0aW9uLnB1c2gocG9zKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBXaGVuIHRoZSBvYmplY3RzIGFyZSBmaW5pc2hlZCBmYWRpbmcgb3V0LCBkZXN0cm95IHRoZW1cblx0XHRcdGlmIChjb2xsID09PSBhbHRlcm5hdGVCYW5kcyB8fCAhY2hhcnQuaGFzUmVuZGVyZWQgfHwgIWRlbGF5KSB7XG5cdFx0XHRcdGRlc3Ryb3lJbmFjdGl2ZUl0ZW1zKCk7XG5cdFx0XHR9IGVsc2UgaWYgKGRlbGF5KSB7XG5cdFx0XHRcdHNldFRpbWVvdXQoZGVzdHJveUluYWN0aXZlSXRlbXMsIGRlbGF5KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIFN0YXRpYyBpdGVtcy4gQXMgdGhlIGF4aXMgZ3JvdXAgaXMgY2xlYXJlZCBvbiBzdWJzZXF1ZW50IGNhbGxzXG5cdFx0Ly8gdG8gcmVuZGVyLCB0aGVzZSBpdGVtcyBhcmUgYWRkZWQgb3V0c2lkZSB0aGUgZ3JvdXAuXG5cdFx0Ly8gYXhpcyBsaW5lXG5cdFx0aWYgKGxpbmVXaWR0aCkge1xuXHRcdFx0bGluZVBhdGggPSBheGlzLmdldExpbmVQYXRoKGxpbmVXaWR0aCk7XG5cdFx0XHRpZiAoIWF4aXMuYXhpc0xpbmUpIHtcblx0XHRcdFx0YXhpcy5heGlzTGluZSA9IHJlbmRlcmVyLnBhdGgobGluZVBhdGgpXG5cdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0c3Ryb2tlOiBvcHRpb25zLmxpbmVDb2xvcixcblx0XHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBsaW5lV2lkdGgsXG5cdFx0XHRcdFx0XHR6SW5kZXg6IDdcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5hZGQoYXhpcy5heGlzR3JvdXApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YXhpcy5heGlzTGluZS5hbmltYXRlKHsgZDogbGluZVBhdGggfSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHNob3cgb3IgaGlkZSB0aGUgbGluZSBkZXBlbmRpbmcgb24gb3B0aW9ucy5zaG93RW1wdHlcblx0XHRcdGF4aXMuYXhpc0xpbmVbc2hvd0F4aXMgPyAnc2hvdycgOiAnaGlkZSddKCk7XG5cdFx0fVxuXG5cdFx0aWYgKGF4aXNUaXRsZSAmJiBzaG93QXhpcykge1xuXG5cdFx0XHRheGlzVGl0bGVbYXhpc1RpdGxlLmlzTmV3ID8gJ2F0dHInIDogJ2FuaW1hdGUnXShcblx0XHRcdFx0YXhpcy5nZXRUaXRsZVBvc2l0aW9uKClcblx0XHRcdCk7XG5cdFx0XHRheGlzVGl0bGUuaXNOZXcgPSBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBTdGFja2VkIHRvdGFsczpcblx0XHRpZiAoc3RhY2tMYWJlbE9wdGlvbnMgJiYgc3RhY2tMYWJlbE9wdGlvbnMuZW5hYmxlZCkge1xuXHRcdFx0YXhpcy5yZW5kZXJTdGFja1RvdGFscygpO1xuXHRcdH1cblx0XHQvLyBFbmQgc3RhY2tlZCB0b3RhbHNcblxuXHRcdGF4aXMuaXNEaXJ0eSA9IGZhbHNlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZWRyYXcgdGhlIGF4aXMgdG8gcmVmbGVjdCBjaGFuZ2VzIGluIHRoZSBkYXRhIG9yIGF4aXMgZXh0cmVtZXNcblx0ICovXG5cdHJlZHJhdzogZnVuY3Rpb24gKCkge1xuXHRcdFxuXHRcdC8vIHJlbmRlciB0aGUgYXhpc1xuXHRcdHRoaXMucmVuZGVyKCk7XG5cblx0XHQvLyBtb3ZlIHBsb3QgbGluZXMgYW5kIGJhbmRzXG5cdFx0ZWFjaCh0aGlzLnBsb3RMaW5lc0FuZEJhbmRzLCBmdW5jdGlvbiAocGxvdExpbmUpIHtcblx0XHRcdHBsb3RMaW5lLnJlbmRlcigpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gbWFyayBhc3NvY2lhdGVkIHNlcmllcyBhcyBkaXJ0eSBhbmQgcmVhZHkgZm9yIHJlZHJhd1xuXHRcdGVhY2godGhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdHNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHR9KTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95cyBhbiBBeGlzIGluc3RhbmNlLlxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKGtlZXBFdmVudHMpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRzdGFja3MgPSBheGlzLnN0YWNrcyxcblx0XHRcdHN0YWNrS2V5LFxuXHRcdFx0cGxvdExpbmVzQW5kQmFuZHMgPSBheGlzLnBsb3RMaW5lc0FuZEJhbmRzLFxuXHRcdFx0aTtcblxuXHRcdC8vIFJlbW92ZSB0aGUgZXZlbnRzXG5cdFx0aWYgKCFrZWVwRXZlbnRzKSB7XG5cdFx0XHRyZW1vdmVFdmVudChheGlzKTtcblx0XHR9XG5cblx0XHQvLyBEZXN0cm95IGVhY2ggc3RhY2sgdG90YWxcblx0XHRmb3IgKHN0YWNrS2V5IGluIHN0YWNrcykge1xuXHRcdFx0ZGVzdHJveU9iamVjdFByb3BlcnRpZXMoc3RhY2tzW3N0YWNrS2V5XSk7XG5cblx0XHRcdHN0YWNrc1tzdGFja0tleV0gPSBudWxsO1xuXHRcdH1cblxuXHRcdC8vIERlc3Ryb3kgY29sbGVjdGlvbnNcblx0XHRlYWNoKFtheGlzLnRpY2tzLCBheGlzLm1pbm9yVGlja3MsIGF4aXMuYWx0ZXJuYXRlQmFuZHNdLCBmdW5jdGlvbiAoY29sbCkge1xuXHRcdFx0ZGVzdHJveU9iamVjdFByb3BlcnRpZXMoY29sbCk7XG5cdFx0fSk7XG5cdFx0aSA9IHBsb3RMaW5lc0FuZEJhbmRzLmxlbmd0aDtcblx0XHR3aGlsZSAoaS0tKSB7IC8vICMxOTc1XG5cdFx0XHRwbG90TGluZXNBbmRCYW5kc1tpXS5kZXN0cm95KCk7XG5cdFx0fVxuXG5cdFx0Ly8gRGVzdHJveSBsb2NhbCB2YXJpYWJsZXNcblx0XHRlYWNoKFsnc3RhY2tUb3RhbEdyb3VwJywgJ2F4aXNMaW5lJywgJ2F4aXNUaXRsZScsICdheGlzR3JvdXAnLCAnY3Jvc3MnLCAnZ3JpZEdyb3VwJywgJ2xhYmVsR3JvdXAnXSwgZnVuY3Rpb24gKHByb3ApIHtcblx0XHRcdGlmIChheGlzW3Byb3BdKSB7XG5cdFx0XHRcdGF4aXNbcHJvcF0gPSBheGlzW3Byb3BdLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIERlc3Ryb3kgY3Jvc3NoYWlyXG5cdFx0aWYgKHRoaXMuY3Jvc3MpIHtcblx0XHRcdHRoaXMuY3Jvc3MuZGVzdHJveSgpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRHJhdyB0aGUgY3Jvc3NoYWlyXG5cdCAqL1xuXHRkcmF3Q3Jvc3NoYWlyOiBmdW5jdGlvbiAoZSwgcG9pbnQpIHtcblx0XHRpZiAoIXRoaXMuY3Jvc3NoYWlyKSB7IHJldHVybjsgfS8vIERvIG5vdCBkcmF3IGNyb3NzaGFpcnMgaWYgeW91IGRvbid0IGhhdmUgdG9vLlxuXG5cdFx0aWYgKChkZWZpbmVkKHBvaW50KSB8fCAhcGljayh0aGlzLmNyb3NzaGFpci5zbmFwLCB0cnVlKSkgPT09IGZhbHNlKSB7XG5cdFx0XHR0aGlzLmhpZGVDcm9zc2hhaXIoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgcGF0aCxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLmNyb3NzaGFpcixcblx0XHRcdGFuaW1hdGlvbiA9IG9wdGlvbnMuYW5pbWF0aW9uLFxuXHRcdFx0cG9zO1xuXG5cdFx0Ly8gR2V0IHRoZSBwYXRoXG5cdFx0aWYgKCFwaWNrKG9wdGlvbnMuc25hcCwgdHJ1ZSkpIHtcblx0XHRcdHBvcyA9ICh0aGlzLmhvcml6ID8gZS5jaGFydFggLSB0aGlzLnBvcyA6IHRoaXMubGVuIC0gZS5jaGFydFkgKyB0aGlzLnBvcyk7XG5cdFx0fSBlbHNlIGlmIChkZWZpbmVkKHBvaW50KSkge1xuXHRcdFx0Lypqc2xpbnQgZXFlcTogdHJ1ZSovXG5cdFx0XHRwb3MgPSAodGhpcy5jaGFydC5pbnZlcnRlZCAhPSB0aGlzLmhvcml6KSA/IHBvaW50LnBsb3RYIDogdGhpcy5sZW4gLSBwb2ludC5wbG90WTtcblx0XHRcdC8qanNsaW50IGVxZXE6IGZhbHNlKi9cblx0XHR9XG5cblx0XHRpZiAodGhpcy5pc1JhZGlhbCkge1xuXHRcdFx0cGF0aCA9IHRoaXMuZ2V0UGxvdExpbmVQYXRoKHRoaXMuaXNYQXhpcyA/IHBvaW50LnggOiBwaWNrKHBvaW50LnN0YWNrWSwgcG9pbnQueSkpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwYXRoID0gdGhpcy5nZXRQbG90TGluZVBhdGgobnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgcG9zKTtcblx0XHR9XG5cblx0XHRpZiAocGF0aCA9PT0gbnVsbCkge1xuXHRcdFx0dGhpcy5oaWRlQ3Jvc3NoYWlyKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRHJhdyB0aGUgY3Jvc3Ncblx0XHRpZiAodGhpcy5jcm9zcykge1xuXHRcdFx0dGhpcy5jcm9zc1xuXHRcdFx0XHQuYXR0cih7IHZpc2liaWxpdHk6IFZJU0lCTEUgfSlbYW5pbWF0aW9uID8gJ2FuaW1hdGUnIDogJ2F0dHInXSh7IGQ6IHBhdGggfSwgYW5pbWF0aW9uKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIGF0dHJpYnMgPSB7XG5cdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBvcHRpb25zLndpZHRoIHx8IDEsXG5cdFx0XHRcdHN0cm9rZTogb3B0aW9ucy5jb2xvciB8fCAnI0MwQzBDMCcsXG5cdFx0XHRcdHpJbmRleDogb3B0aW9ucy56SW5kZXggfHwgMlxuXHRcdFx0fTtcblx0XHRcdGlmIChvcHRpb25zLmRhc2hTdHlsZSkge1xuXHRcdFx0XHRhdHRyaWJzLmRhc2hzdHlsZSA9IG9wdGlvbnMuZGFzaFN0eWxlO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5jcm9zcyA9IHRoaXMuY2hhcnQucmVuZGVyZXIucGF0aChwYXRoKS5hdHRyKGF0dHJpYnMpLmFkZCgpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICpcdEhpZGUgdGhlIGNyb3NzaGFpci5cblx0ICovXG5cdGhpZGVDcm9zc2hhaXI6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAodGhpcy5jcm9zcykge1xuXHRcdFx0dGhpcy5jcm9zcy5oaWRlKCk7XG5cdFx0fVxuXHR9XG59OyAvLyBlbmQgQXhpc1xuXG5leHRlbmQoQXhpcy5wcm90b3R5cGUsIEF4aXNQbG90TGluZU9yQmFuZEV4dGVuc2lvbik7XG5cbi8qKlxuICogU2V0IHRoZSB0aWNrIHBvc2l0aW9ucyB0byBhIHRpbWUgdW5pdCB0aGF0IG1ha2VzIHNlbnNlLCBmb3IgZXhhbXBsZVxuICogb24gdGhlIGZpcnN0IG9mIGVhY2ggbW9udGggb3Igb24gZXZlcnkgTW9uZGF5LiBSZXR1cm4gYW4gYXJyYXlcbiAqIHdpdGggdGhlIHRpbWUgcG9zaXRpb25zLiBVc2VkIGluIGRhdGV0aW1lIGF4ZXMgYXMgd2VsbCBhcyBmb3IgZ3JvdXBpbmdcbiAqIGRhdGEgb24gYSBkYXRldGltZSBheGlzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBub3JtYWxpemVkSW50ZXJ2YWwgVGhlIGludGVydmFsIGluIGF4aXMgdmFsdWVzIChtcykgYW5kIHRoZSBjb3VudFxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbiBUaGUgbWluaW11bSBpbiBheGlzIHZhbHVlc1xuICogQHBhcmFtIHtOdW1iZXJ9IG1heCBUaGUgbWF4aW11bSBpbiBheGlzIHZhbHVlc1xuICogQHBhcmFtIHtOdW1iZXJ9IHN0YXJ0T2ZXZWVrXG4gKi9cbkF4aXMucHJvdG90eXBlLmdldFRpbWVUaWNrcyA9IGZ1bmN0aW9uIChub3JtYWxpemVkSW50ZXJ2YWwsIG1pbiwgbWF4LCBzdGFydE9mV2Vlaykge1xuXHR2YXIgdGlja1Bvc2l0aW9ucyA9IFtdLFxuXHRcdGksXG5cdFx0aGlnaGVyUmFua3MgPSB7fSxcblx0XHR1c2VVVEMgPSBkZWZhdWx0T3B0aW9ucy5nbG9iYWwudXNlVVRDLFxuXHRcdG1pblllYXIsIC8vIHVzZWQgaW4gbW9udGhzIGFuZCB5ZWFycyBhcyBhIGJhc2lzIGZvciBEYXRlLlVUQygpXG5cdFx0bWluRGF0ZSA9IG5ldyBEYXRlKG1pbiAtIHRpbWV6b25lT2Zmc2V0KSxcblx0XHRpbnRlcnZhbCA9IG5vcm1hbGl6ZWRJbnRlcnZhbC51bml0UmFuZ2UsXG5cdFx0Y291bnQgPSBub3JtYWxpemVkSW50ZXJ2YWwuY291bnQ7XG5cblx0aWYgKGRlZmluZWQobWluKSkgeyAvLyAjMTMwMFxuXHRcdGlmIChpbnRlcnZhbCA+PSB0aW1lVW5pdHMuc2Vjb25kKSB7IC8vIHNlY29uZFxuXHRcdFx0bWluRGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG5cdFx0XHRtaW5EYXRlLnNldFNlY29uZHMoaW50ZXJ2YWwgPj0gdGltZVVuaXRzLm1pbnV0ZSA/IDAgOlxuXHRcdFx0XHRjb3VudCAqIG1hdGhGbG9vcihtaW5EYXRlLmdldFNlY29uZHMoKSAvIGNvdW50KSk7XG5cdFx0fVxuXHRcblx0XHRpZiAoaW50ZXJ2YWwgPj0gdGltZVVuaXRzLm1pbnV0ZSkgeyAvLyBtaW51dGVcblx0XHRcdG1pbkRhdGVbc2V0TWludXRlc10oaW50ZXJ2YWwgPj0gdGltZVVuaXRzLmhvdXIgPyAwIDpcblx0XHRcdFx0Y291bnQgKiBtYXRoRmxvb3IobWluRGF0ZVtnZXRNaW51dGVzXSgpIC8gY291bnQpKTtcblx0XHR9XG5cdFxuXHRcdGlmIChpbnRlcnZhbCA+PSB0aW1lVW5pdHMuaG91cikgeyAvLyBob3VyXG5cdFx0XHRtaW5EYXRlW3NldEhvdXJzXShpbnRlcnZhbCA+PSB0aW1lVW5pdHMuZGF5ID8gMCA6XG5cdFx0XHRcdGNvdW50ICogbWF0aEZsb29yKG1pbkRhdGVbZ2V0SG91cnNdKCkgLyBjb3VudCkpO1xuXHRcdH1cblx0XG5cdFx0aWYgKGludGVydmFsID49IHRpbWVVbml0cy5kYXkpIHsgLy8gZGF5XG5cdFx0XHRtaW5EYXRlW3NldERhdGVdKGludGVydmFsID49IHRpbWVVbml0cy5tb250aCA/IDEgOlxuXHRcdFx0XHRjb3VudCAqIG1hdGhGbG9vcihtaW5EYXRlW2dldERhdGVdKCkgLyBjb3VudCkpO1xuXHRcdH1cblx0XG5cdFx0aWYgKGludGVydmFsID49IHRpbWVVbml0cy5tb250aCkgeyAvLyBtb250aFxuXHRcdFx0bWluRGF0ZVtzZXRNb250aF0oaW50ZXJ2YWwgPj0gdGltZVVuaXRzLnllYXIgPyAwIDpcblx0XHRcdFx0Y291bnQgKiBtYXRoRmxvb3IobWluRGF0ZVtnZXRNb250aF0oKSAvIGNvdW50KSk7XG5cdFx0XHRtaW5ZZWFyID0gbWluRGF0ZVtnZXRGdWxsWWVhcl0oKTtcblx0XHR9XG5cdFxuXHRcdGlmIChpbnRlcnZhbCA+PSB0aW1lVW5pdHMueWVhcikgeyAvLyB5ZWFyXG5cdFx0XHRtaW5ZZWFyIC09IG1pblllYXIgJSBjb3VudDtcblx0XHRcdG1pbkRhdGVbc2V0RnVsbFllYXJdKG1pblllYXIpO1xuXHRcdH1cblx0XG5cdFx0Ly8gd2VlayBpcyBhIHNwZWNpYWwgY2FzZSB0aGF0IHJ1bnMgb3V0c2lkZSB0aGUgaGllcmFyY2h5XG5cdFx0aWYgKGludGVydmFsID09PSB0aW1lVW5pdHMud2Vlaykge1xuXHRcdFx0Ly8gZ2V0IHN0YXJ0IG9mIGN1cnJlbnQgd2VlaywgaW5kZXBlbmRlbnQgb2YgY291bnRcblx0XHRcdG1pbkRhdGVbc2V0RGF0ZV0obWluRGF0ZVtnZXREYXRlXSgpIC0gbWluRGF0ZVtnZXREYXldKCkgK1xuXHRcdFx0XHRwaWNrKHN0YXJ0T2ZXZWVrLCAxKSk7XG5cdFx0fVxuXHRcblx0XG5cdFx0Ly8gZ2V0IHRpY2sgcG9zaXRpb25zXG5cdFx0aSA9IDE7XG5cdFx0aWYgKHRpbWV6b25lT2Zmc2V0KSB7XG5cdFx0XHRtaW5EYXRlID0gbmV3IERhdGUobWluRGF0ZS5nZXRUaW1lKCkgKyB0aW1lem9uZU9mZnNldCk7XG5cdFx0fVxuXHRcdG1pblllYXIgPSBtaW5EYXRlW2dldEZ1bGxZZWFyXSgpO1xuXHRcdHZhciB0aW1lID0gbWluRGF0ZS5nZXRUaW1lKCksXG5cdFx0XHRtaW5Nb250aCA9IG1pbkRhdGVbZ2V0TW9udGhdKCksXG5cdFx0XHRtaW5EYXRlRGF0ZSA9IG1pbkRhdGVbZ2V0RGF0ZV0oKSxcblx0XHRcdGxvY2FsVGltZXpvbmVPZmZzZXQgPSAodGltZVVuaXRzLmRheSArIFxuXHRcdFx0XHRcdCh1c2VVVEMgPyB0aW1lem9uZU9mZnNldCA6IG1pbkRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMClcblx0XHRcdFx0KSAlIHRpbWVVbml0cy5kYXk7IC8vICM5NTAsICMzMzU5XG5cdFxuXHRcdC8vIGl0ZXJhdGUgYW5kIGFkZCB0aWNrIHBvc2l0aW9ucyBhdCBhcHByb3ByaWF0ZSB2YWx1ZXNcblx0XHR3aGlsZSAodGltZSA8IG1heCkge1xuXHRcdFx0dGlja1Bvc2l0aW9ucy5wdXNoKHRpbWUpO1xuXHRcblx0XHRcdC8vIGlmIHRoZSBpbnRlcnZhbCBpcyB5ZWFycywgdXNlIERhdGUuVVRDIHRvIGluY3JlYXNlIHllYXJzXG5cdFx0XHRpZiAoaW50ZXJ2YWwgPT09IHRpbWVVbml0cy55ZWFyKSB7XG5cdFx0XHRcdHRpbWUgPSBtYWtlVGltZShtaW5ZZWFyICsgaSAqIGNvdW50LCAwKTtcblx0XG5cdFx0XHQvLyBpZiB0aGUgaW50ZXJ2YWwgaXMgbW9udGhzLCB1c2UgRGF0ZS5VVEMgdG8gaW5jcmVhc2UgbW9udGhzXG5cdFx0XHR9IGVsc2UgaWYgKGludGVydmFsID09PSB0aW1lVW5pdHMubW9udGgpIHtcblx0XHRcdFx0dGltZSA9IG1ha2VUaW1lKG1pblllYXIsIG1pbk1vbnRoICsgaSAqIGNvdW50KTtcblx0XG5cdFx0XHQvLyBpZiB3ZSdyZSB1c2luZyBnbG9iYWwgdGltZSwgdGhlIGludGVydmFsIGlzIG5vdCBmaXhlZCBhcyBpdCBqdW1wc1xuXHRcdFx0Ly8gb25lIGhvdXIgYXQgdGhlIERTVCBjcm9zc292ZXJcblx0XHRcdH0gZWxzZSBpZiAoIXVzZVVUQyAmJiAoaW50ZXJ2YWwgPT09IHRpbWVVbml0cy5kYXkgfHwgaW50ZXJ2YWwgPT09IHRpbWVVbml0cy53ZWVrKSkge1xuXHRcdFx0XHR0aW1lID0gbWFrZVRpbWUobWluWWVhciwgbWluTW9udGgsIG1pbkRhdGVEYXRlICtcblx0XHRcdFx0XHRpICogY291bnQgKiAoaW50ZXJ2YWwgPT09IHRpbWVVbml0cy5kYXkgPyAxIDogNykpO1xuXHRcblx0XHRcdC8vIGVsc2UsIHRoZSBpbnRlcnZhbCBpcyBmaXhlZCBhbmQgd2UgdXNlIHNpbXBsZSBhZGRpdGlvblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGltZSArPSBpbnRlcnZhbCAqIGNvdW50O1xuXHRcdFx0fVxuXHRcblx0XHRcdGkrKztcblx0XHR9XG5cdFxuXHRcdC8vIHB1c2ggdGhlIGxhc3QgdGltZVxuXHRcdHRpY2tQb3NpdGlvbnMucHVzaCh0aW1lKTtcblxuXG5cdFx0Ly8gbWFyayBuZXcgZGF5cyBpZiB0aGUgdGltZSBpcyBkaXZpZGlibGUgYnkgZGF5ICgjMTY0OSwgIzE3NjApXG5cdFx0ZWFjaChncmVwKHRpY2tQb3NpdGlvbnMsIGZ1bmN0aW9uICh0aW1lKSB7XG5cdFx0XHRyZXR1cm4gaW50ZXJ2YWwgPD0gdGltZVVuaXRzLmhvdXIgJiYgdGltZSAlIHRpbWVVbml0cy5kYXkgPT09IGxvY2FsVGltZXpvbmVPZmZzZXQ7XG5cdFx0fSksIGZ1bmN0aW9uICh0aW1lKSB7XG5cdFx0XHRoaWdoZXJSYW5rc1t0aW1lXSA9ICdkYXknO1xuXHRcdH0pO1xuXHR9XG5cblxuXHQvLyByZWNvcmQgaW5mb3JtYXRpb24gb24gdGhlIGNob3NlbiB1bml0IC0gZm9yIGR5bmFtaWMgbGFiZWwgZm9ybWF0dGVyXG5cdHRpY2tQb3NpdGlvbnMuaW5mbyA9IGV4dGVuZChub3JtYWxpemVkSW50ZXJ2YWwsIHtcblx0XHRoaWdoZXJSYW5rczogaGlnaGVyUmFua3MsXG5cdFx0dG90YWxSYW5nZTogaW50ZXJ2YWwgKiBjb3VudFxuXHR9KTtcblxuXHRyZXR1cm4gdGlja1Bvc2l0aW9ucztcbn07XG5cbi8qKlxuICogR2V0IGEgbm9ybWFsaXplZCB0aWNrIGludGVydmFsIGZvciBkYXRlcy4gUmV0dXJucyBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHdpdGhcbiAqIHVuaXQgcmFuZ2UgKGludGVydmFsKSwgY291bnQgYW5kIG5hbWUuIFVzZWQgdG8gcHJlcGFyZSBkYXRhIGZvciBnZXRUaW1lVGlja3MuIFxuICogUHJldmlvdXNseSB0aGlzIGxvZ2ljIHdhcyBwYXJ0IG9mIGdldFRpbWVUaWNrcywgYnV0IGFzIGdldFRpbWVUaWNrcyBub3cgcnVuc1xuICogb2Ygc2VnbWVudHMgaW4gc3RvY2sgY2hhcnRzLCB0aGUgbm9ybWFsaXppbmcgbG9naWMgd2FzIGV4dHJhY3RlZCBpbiBvcmRlciB0byBcbiAqIHByZXZlbnQgaXQgZm9yIHJ1bm5pbmcgb3ZlciBhZ2FpbiBmb3IgZWFjaCBzZWdtZW50IGhhdmluZyB0aGUgc2FtZSBpbnRlcnZhbC4gXG4gKiAjNjYyLCAjNjk3LlxuICovXG5BeGlzLnByb3RvdHlwZS5ub3JtYWxpemVUaW1lVGlja0ludGVydmFsID0gZnVuY3Rpb24gKHRpY2tJbnRlcnZhbCwgdW5pdHNPcHRpb24pIHtcblx0dmFyIHVuaXRzID0gdW5pdHNPcHRpb24gfHwgW1tcblx0XHRcdFx0J21pbGxpc2Vjb25kJywgLy8gdW5pdCBuYW1lXG5cdFx0XHRcdFsxLCAyLCA1LCAxMCwgMjAsIDI1LCA1MCwgMTAwLCAyMDAsIDUwMF0gLy8gYWxsb3dlZCBtdWx0aXBsZXNcblx0XHRcdF0sIFtcblx0XHRcdFx0J3NlY29uZCcsXG5cdFx0XHRcdFsxLCAyLCA1LCAxMCwgMTUsIDMwXVxuXHRcdFx0XSwgW1xuXHRcdFx0XHQnbWludXRlJyxcblx0XHRcdFx0WzEsIDIsIDUsIDEwLCAxNSwgMzBdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCdob3VyJyxcblx0XHRcdFx0WzEsIDIsIDMsIDQsIDYsIDgsIDEyXVxuXHRcdFx0XSwgW1xuXHRcdFx0XHQnZGF5Jyxcblx0XHRcdFx0WzEsIDJdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCd3ZWVrJyxcblx0XHRcdFx0WzEsIDJdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCdtb250aCcsXG5cdFx0XHRcdFsxLCAyLCAzLCA0LCA2XVxuXHRcdFx0XSwgW1xuXHRcdFx0XHQneWVhcicsXG5cdFx0XHRcdG51bGxcblx0XHRcdF1dLFxuXHRcdHVuaXQgPSB1bml0c1t1bml0cy5sZW5ndGggLSAxXSwgLy8gZGVmYXVsdCB1bml0IGlzIHllYXJzXG5cdFx0aW50ZXJ2YWwgPSB0aW1lVW5pdHNbdW5pdFswXV0sXG5cdFx0bXVsdGlwbGVzID0gdW5pdFsxXSxcblx0XHRjb3VudCxcblx0XHRpO1xuXHRcdFxuXHQvLyBsb29wIHRocm91Z2ggdGhlIHVuaXRzIHRvIGZpbmQgdGhlIG9uZSB0aGF0IGJlc3QgZml0cyB0aGUgdGlja0ludGVydmFsXG5cdGZvciAoaSA9IDA7IGkgPCB1bml0cy5sZW5ndGg7IGkrKykge1xuXHRcdHVuaXQgPSB1bml0c1tpXTtcblx0XHRpbnRlcnZhbCA9IHRpbWVVbml0c1t1bml0WzBdXTtcblx0XHRtdWx0aXBsZXMgPSB1bml0WzFdO1xuXG5cblx0XHRpZiAodW5pdHNbaSArIDFdKSB7XG5cdFx0XHQvLyBsZXNzVGhhbiBpcyBpbiB0aGUgbWlkZGxlIGJldHdlZW4gdGhlIGhpZ2hlc3QgbXVsdGlwbGUgYW5kIHRoZSBuZXh0IHVuaXQuXG5cdFx0XHR2YXIgbGVzc1RoYW4gPSAoaW50ZXJ2YWwgKiBtdWx0aXBsZXNbbXVsdGlwbGVzLmxlbmd0aCAtIDFdICtcblx0XHRcdFx0XHRcdHRpbWVVbml0c1t1bml0c1tpICsgMV1bMF1dKSAvIDI7XG5cblx0XHRcdC8vIGJyZWFrIGFuZCBrZWVwIHRoZSBjdXJyZW50IHVuaXRcblx0XHRcdGlmICh0aWNrSW50ZXJ2YWwgPD0gbGVzc1RoYW4pIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gcHJldmVudCAyLjUgeWVhcnMgaW50ZXJ2YWxzLCB0aG91Z2ggMjUsIDI1MCBldGMuIGFyZSBhbGxvd2VkXG5cdGlmIChpbnRlcnZhbCA9PT0gdGltZVVuaXRzLnllYXIgJiYgdGlja0ludGVydmFsIDwgNSAqIGludGVydmFsKSB7XG5cdFx0bXVsdGlwbGVzID0gWzEsIDIsIDVdO1xuXHR9XG5cblx0Ly8gZ2V0IHRoZSBjb3VudFxuXHRjb3VudCA9IG5vcm1hbGl6ZVRpY2tJbnRlcnZhbChcblx0XHR0aWNrSW50ZXJ2YWwgLyBpbnRlcnZhbCwgXG5cdFx0bXVsdGlwbGVzLFxuXHRcdHVuaXRbMF0gPT09ICd5ZWFyJyA/IG1hdGhNYXgoZ2V0TWFnbml0dWRlKHRpY2tJbnRlcnZhbCAvIGludGVydmFsKSwgMSkgOiAxIC8vICMxOTEzLCAjMjM2MFxuXHQpO1xuXHRcblx0cmV0dXJuIHtcblx0XHR1bml0UmFuZ2U6IGludGVydmFsLFxuXHRcdGNvdW50OiBjb3VudCxcblx0XHR1bml0TmFtZTogdW5pdFswXVxuXHR9O1xufTsvKipcbiAqIE1ldGhvZHMgZGVmaW5lZCBvbiB0aGUgQXhpcyBwcm90b3R5cGVcbiAqL1xuXG4vKipcbiAqIFNldCB0aGUgdGljayBwb3NpdGlvbnMgb2YgYSBsb2dhcml0aG1pYyBheGlzXG4gKi9cbkF4aXMucHJvdG90eXBlLmdldExvZ1RpY2tQb3NpdGlvbnMgPSBmdW5jdGlvbiAoaW50ZXJ2YWwsIG1pbiwgbWF4LCBtaW5vcikge1xuXHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRheGlzTGVuZ3RoID0gYXhpcy5sZW4sXG5cdFx0Ly8gU2luY2Ugd2UgdXNlIHRoaXMgbWV0aG9kIGZvciBib3RoIG1ham9yIGFuZCBtaW5vciB0aWNrcyxcblx0XHQvLyB1c2UgYSBsb2NhbCB2YXJpYWJsZSBhbmQgcmV0dXJuIHRoZSByZXN1bHRcblx0XHRwb3NpdGlvbnMgPSBbXTsgXG5cdFxuXHQvLyBSZXNldFxuXHRpZiAoIW1pbm9yKSB7XG5cdFx0YXhpcy5fbWlub3JBdXRvSW50ZXJ2YWwgPSBudWxsO1xuXHR9XG5cdFxuXHQvLyBGaXJzdCBjYXNlOiBBbGwgdGlja3MgZmFsbCBvbiB3aG9sZSBsb2dhcml0aG1zOiAxLCAxMCwgMTAwIGV0Yy5cblx0aWYgKGludGVydmFsID49IDAuNSkge1xuXHRcdGludGVydmFsID0gbWF0aFJvdW5kKGludGVydmFsKTtcblx0XHRwb3NpdGlvbnMgPSBheGlzLmdldExpbmVhclRpY2tQb3NpdGlvbnMoaW50ZXJ2YWwsIG1pbiwgbWF4KTtcblx0XHRcblx0Ly8gU2Vjb25kIGNhc2U6IFdlIG5lZWQgaW50ZXJtZWRpYXJ5IHRpY2tzLiBGb3IgZXhhbXBsZSBcblx0Ly8gMSwgMiwgNCwgNiwgOCwgMTAsIDIwLCA0MCBldGMuIFxuXHR9IGVsc2UgaWYgKGludGVydmFsID49IDAuMDgpIHtcblx0XHR2YXIgcm91bmRlZE1pbiA9IG1hdGhGbG9vcihtaW4pLFxuXHRcdFx0aW50ZXJtZWRpYXRlLFxuXHRcdFx0aSxcblx0XHRcdGosXG5cdFx0XHRsZW4sXG5cdFx0XHRwb3MsXG5cdFx0XHRsYXN0UG9zLFxuXHRcdFx0YnJlYWsyO1xuXHRcdFx0XG5cdFx0aWYgKGludGVydmFsID4gMC4zKSB7XG5cdFx0XHRpbnRlcm1lZGlhdGUgPSBbMSwgMiwgNF07XG5cdFx0fSBlbHNlIGlmIChpbnRlcnZhbCA+IDAuMTUpIHsgLy8gMC4yIGVxdWFscyBmaXZlIG1pbm9yIHRpY2tzIHBlciAxLCAxMCwgMTAwIGV0Y1xuXHRcdFx0aW50ZXJtZWRpYXRlID0gWzEsIDIsIDQsIDYsIDhdO1xuXHRcdH0gZWxzZSB7IC8vIDAuMSBlcXVhbHMgdGVuIG1pbm9yIHRpY2tzIHBlciAxLCAxMCwgMTAwIGV0Y1xuXHRcdFx0aW50ZXJtZWRpYXRlID0gWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDldO1xuXHRcdH1cblx0XHRcblx0XHRmb3IgKGkgPSByb3VuZGVkTWluOyBpIDwgbWF4ICsgMSAmJiAhYnJlYWsyOyBpKyspIHtcblx0XHRcdGxlbiA9IGludGVybWVkaWF0ZS5sZW5ndGg7XG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgbGVuICYmICFicmVhazI7IGorKykge1xuXHRcdFx0XHRwb3MgPSBsb2cybGluKGxpbjJsb2coaSkgKiBpbnRlcm1lZGlhdGVbal0pO1xuXHRcdFx0XHRpZiAocG9zID4gbWluICYmICghbWlub3IgfHwgbGFzdFBvcyA8PSBtYXgpICYmIGxhc3RQb3MgIT09IFVOREVGSU5FRCkgeyAvLyAjMTY3MCwgbGFzdFBvcyBpcyAjMzExM1xuXHRcdFx0XHRcdHBvc2l0aW9ucy5wdXNoKGxhc3RQb3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRpZiAobGFzdFBvcyA+IG1heCkge1xuXHRcdFx0XHRcdGJyZWFrMiA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0bGFzdFBvcyA9IHBvcztcblx0XHRcdH1cblx0XHR9XG5cdFx0XG5cdC8vIFRoaXJkIGNhc2U6IFdlIGFyZSBzbyBkZWVwIGluIGJldHdlZW4gd2hvbGUgbG9nYXJpdGhtaWMgdmFsdWVzIHRoYXRcblx0Ly8gd2UgbWlnaHQgYXMgd2VsbCBoYW5kbGUgdGhlIHRpY2sgcG9zaXRpb25zIGxpa2UgYSBsaW5lYXIgYXhpcy4gRm9yXG5cdC8vIGV4YW1wbGUgMS4wMSwgMS4wMiwgMS4wMywgMS4wNC5cblx0fSBlbHNlIHtcblx0XHR2YXIgcmVhbE1pbiA9IGxpbjJsb2cobWluKSxcblx0XHRcdHJlYWxNYXggPSBsaW4ybG9nKG1heCksXG5cdFx0XHR0aWNrSW50ZXJ2YWxPcHRpb24gPSBvcHRpb25zW21pbm9yID8gJ21pbm9yVGlja0ludGVydmFsJyA6ICd0aWNrSW50ZXJ2YWwnXSxcblx0XHRcdGZpbHRlcmVkVGlja0ludGVydmFsT3B0aW9uID0gdGlja0ludGVydmFsT3B0aW9uID09PSAnYXV0bycgPyBudWxsIDogdGlja0ludGVydmFsT3B0aW9uLFxuXHRcdFx0dGlja1BpeGVsSW50ZXJ2YWxPcHRpb24gPSBvcHRpb25zLnRpY2tQaXhlbEludGVydmFsIC8gKG1pbm9yID8gNSA6IDEpLFxuXHRcdFx0dG90YWxQaXhlbExlbmd0aCA9IG1pbm9yID8gYXhpc0xlbmd0aCAvIGF4aXMudGlja1Bvc2l0aW9ucy5sZW5ndGggOiBheGlzTGVuZ3RoO1xuXHRcdFxuXHRcdGludGVydmFsID0gcGljayhcblx0XHRcdGZpbHRlcmVkVGlja0ludGVydmFsT3B0aW9uLFxuXHRcdFx0YXhpcy5fbWlub3JBdXRvSW50ZXJ2YWwsXG5cdFx0XHQocmVhbE1heCAtIHJlYWxNaW4pICogdGlja1BpeGVsSW50ZXJ2YWxPcHRpb24gLyAodG90YWxQaXhlbExlbmd0aCB8fCAxKVxuXHRcdCk7XG5cdFx0XG5cdFx0aW50ZXJ2YWwgPSBub3JtYWxpemVUaWNrSW50ZXJ2YWwoXG5cdFx0XHRpbnRlcnZhbCwgXG5cdFx0XHRudWxsLCBcblx0XHRcdGdldE1hZ25pdHVkZShpbnRlcnZhbClcblx0XHQpO1xuXHRcdFxuXHRcdHBvc2l0aW9ucyA9IG1hcChheGlzLmdldExpbmVhclRpY2tQb3NpdGlvbnMoXG5cdFx0XHRpbnRlcnZhbCwgXG5cdFx0XHRyZWFsTWluLFxuXHRcdFx0cmVhbE1heFx0XG5cdFx0KSwgbG9nMmxpbik7XG5cdFx0XG5cdFx0aWYgKCFtaW5vcikge1xuXHRcdFx0YXhpcy5fbWlub3JBdXRvSW50ZXJ2YWwgPSBpbnRlcnZhbCAvIDU7XG5cdFx0fVxuXHR9XG5cdFxuXHQvLyBTZXQgdGhlIGF4aXMtbGV2ZWwgdGlja0ludGVydmFsIHZhcmlhYmxlIFxuXHRpZiAoIW1pbm9yKSB7XG5cdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBpbnRlcnZhbDtcblx0fVxuXHRyZXR1cm4gcG9zaXRpb25zO1xufTsvKipcbiAqIFRoZSB0b29sdGlwIG9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0IFRoZSBjaGFydCBpbnN0YW5jZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVG9vbHRpcCBvcHRpb25zXG4gKi9cbnZhciBUb29sdGlwID0gSGlnaGNoYXJ0cy5Ub29sdGlwID0gZnVuY3Rpb24gKCkge1xuXHR0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn07XG5cblRvb2x0aXAucHJvdG90eXBlID0ge1xuXG5cdGluaXQ6IGZ1bmN0aW9uIChjaGFydCwgb3B0aW9ucykge1xuXG5cdFx0dmFyIGJvcmRlcldpZHRoID0gb3B0aW9ucy5ib3JkZXJXaWR0aCxcblx0XHRcdHN0eWxlID0gb3B0aW9ucy5zdHlsZSxcblx0XHRcdHBhZGRpbmcgPSBwSW50KHN0eWxlLnBhZGRpbmcpO1xuXG5cdFx0Ly8gU2F2ZSB0aGUgY2hhcnQgYW5kIG9wdGlvbnNcblx0XHR0aGlzLmNoYXJ0ID0gY2hhcnQ7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuXHRcdC8vIEtlZXAgdHJhY2sgb2YgdGhlIGN1cnJlbnQgc2VyaWVzXG5cdFx0Ly90aGlzLmN1cnJlbnRTZXJpZXMgPSBVTkRFRklORUQ7XG5cblx0XHQvLyBMaXN0IG9mIGNyb3NzaGFpcnNcblx0XHR0aGlzLmNyb3NzaGFpcnMgPSBbXTtcblxuXHRcdC8vIEN1cnJlbnQgdmFsdWVzIG9mIHggYW5kIHkgd2hlbiBhbmltYXRpbmdcblx0XHR0aGlzLm5vdyA9IHsgeDogMCwgeTogMCB9O1xuXG5cdFx0Ly8gVGhlIHRvb2x0aXAgaXMgaW5pdGlhbGx5IGhpZGRlblxuXHRcdHRoaXMuaXNIaWRkZW4gPSB0cnVlO1xuXG5cblx0XHQvLyBjcmVhdGUgdGhlIGxhYmVsXG5cdFx0dGhpcy5sYWJlbCA9IGNoYXJ0LnJlbmRlcmVyLmxhYmVsKCcnLCAwLCAwLCBvcHRpb25zLnNoYXBlIHx8ICdjYWxsb3V0JywgbnVsbCwgbnVsbCwgb3B0aW9ucy51c2VIVE1MLCBudWxsLCAndG9vbHRpcCcpXG5cdFx0XHQuYXR0cih7XG5cdFx0XHRcdHBhZGRpbmc6IHBhZGRpbmcsXG5cdFx0XHRcdGZpbGw6IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yLFxuXHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogYm9yZGVyV2lkdGgsXG5cdFx0XHRcdHI6IG9wdGlvbnMuYm9yZGVyUmFkaXVzLFxuXHRcdFx0XHR6SW5kZXg6IDhcblx0XHRcdH0pXG5cdFx0XHQuY3NzKHN0eWxlKVxuXHRcdFx0LmNzcyh7IHBhZGRpbmc6IDAgfSkgLy8gUmVtb3ZlIGl0IGZyb20gVk1MLCB0aGUgcGFkZGluZyBpcyBhcHBsaWVkIGFzIGFuIGF0dHJpYnV0ZSBpbnN0ZWFkICgjMTExNylcblx0XHRcdC5hZGQoKVxuXHRcdFx0LmF0dHIoeyB5OiAtOTk5OSB9KTsgLy8gIzIzMDEsICMyNjU3XG5cblx0XHQvLyBXaGVuIHVzaW5nIGNhblZHIHRoZSBzaGFkb3cgc2hvd3MgdXAgYXMgYSBncmF5IGNpcmNsZVxuXHRcdC8vIGV2ZW4gaWYgdGhlIHRvb2x0aXAgaXMgaGlkZGVuLlxuXHRcdGlmICghdXNlQ2FuVkcpIHtcblx0XHRcdHRoaXMubGFiZWwuc2hhZG93KG9wdGlvbnMuc2hhZG93KTtcblx0XHR9XG5cblx0XHQvLyBQdWJsaWMgcHJvcGVydHkgZm9yIGdldHRpbmcgdGhlIHNoYXJlZCBzdGF0ZS5cblx0XHR0aGlzLnNoYXJlZCA9IG9wdGlvbnMuc2hhcmVkO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95IHRoZSB0b29sdGlwIGFuZCBpdHMgZWxlbWVudHMuXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0Ly8gRGVzdHJveSBhbmQgY2xlYXIgbG9jYWwgdmFyaWFibGVzXG5cdFx0aWYgKHRoaXMubGFiZWwpIHtcblx0XHRcdHRoaXMubGFiZWwgPSB0aGlzLmxhYmVsLmRlc3Ryb3koKTtcblx0XHR9XG5cdFx0Y2xlYXJUaW1lb3V0KHRoaXMuaGlkZVRpbWVyKTtcblx0XHRjbGVhclRpbWVvdXQodGhpcy50b29sdGlwVGltZW91dCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFByb3ZpZGUgYSBzb2Z0IG1vdmVtZW50IGZvciB0aGUgdG9vbHRpcFxuXHQgKlxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0bW92ZTogZnVuY3Rpb24gKHgsIHksIGFuY2hvclgsIGFuY2hvclkpIHtcblx0XHR2YXIgdG9vbHRpcCA9IHRoaXMsXG5cdFx0XHRub3cgPSB0b29sdGlwLm5vdyxcblx0XHRcdGFuaW1hdGUgPSB0b29sdGlwLm9wdGlvbnMuYW5pbWF0aW9uICE9PSBmYWxzZSAmJiAhdG9vbHRpcC5pc0hpZGRlbiAmJiBcblx0XHRcdFx0Ly8gV2hlbiB3ZSBnZXQgY2xvc2UgdG8gdGhlIHRhcmdldCBwb3NpdGlvbiwgYWJvcnQgYW5pbWF0aW9uIGFuZCBsYW5kIG9uIHRoZSByaWdodCBwbGFjZSAoIzMwNTYpXG5cdFx0XHRcdChtYXRoQWJzKHggLSBub3cueCkgPiAxIHx8IG1hdGhBYnMoeSAtIG5vdy55KSA+IDEpLFxuXHRcdFx0c2tpcEFuY2hvciA9IHRvb2x0aXAuZm9sbG93UG9pbnRlciB8fCB0b29sdGlwLmxlbiA+IDE7XG5cblx0XHQvLyBHZXQgaW50ZXJtZWRpYXRlIHZhbHVlcyBmb3IgYW5pbWF0aW9uXG5cdFx0ZXh0ZW5kKG5vdywge1xuXHRcdFx0eDogYW5pbWF0ZSA/ICgyICogbm93LnggKyB4KSAvIDMgOiB4LFxuXHRcdFx0eTogYW5pbWF0ZSA/IChub3cueSArIHkpIC8gMiA6IHksXG5cdFx0XHRhbmNob3JYOiBza2lwQW5jaG9yID8gVU5ERUZJTkVEIDogYW5pbWF0ZSA/ICgyICogbm93LmFuY2hvclggKyBhbmNob3JYKSAvIDMgOiBhbmNob3JYLFxuXHRcdFx0YW5jaG9yWTogc2tpcEFuY2hvciA/IFVOREVGSU5FRCA6IGFuaW1hdGUgPyAobm93LmFuY2hvclkgKyBhbmNob3JZKSAvIDIgOiBhbmNob3JZXG5cdFx0fSk7XG5cblx0XHQvLyBNb3ZlIHRvIHRoZSBpbnRlcm1lZGlhdGUgdmFsdWVcblx0XHR0b29sdGlwLmxhYmVsLmF0dHIobm93KTtcblxuXHRcdFxuXHRcdC8vIFJ1biBvbiBuZXh0IHRpY2sgb2YgdGhlIG1vdXNlIHRyYWNrZXJcblx0XHRpZiAoYW5pbWF0ZSkge1xuXHRcdFxuXHRcdFx0Ly8gTmV2ZXIgYWxsb3cgdHdvIHRpbWVvdXRzXG5cdFx0XHRjbGVhclRpbWVvdXQodGhpcy50b29sdGlwVGltZW91dCk7XG5cdFx0XHRcblx0XHRcdC8vIFNldCB0aGUgZml4ZWQgaW50ZXJ2YWwgdGlja2luZyBmb3IgdGhlIHNtb290aCB0b29sdGlwXG5cdFx0XHR0aGlzLnRvb2x0aXBUaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdC8vIFRoZSBpbnRlcnZhbCBmdW5jdGlvbiBtYXkgc3RpbGwgYmUgcnVubmluZyBkdXJpbmcgZGVzdHJveSwgc28gY2hlY2sgdGhhdCB0aGUgY2hhcnQgaXMgcmVhbGx5IHRoZXJlIGJlZm9yZSBjYWxsaW5nLlxuXHRcdFx0XHRpZiAodG9vbHRpcCkge1xuXHRcdFx0XHRcdHRvb2x0aXAubW92ZSh4LCB5LCBhbmNob3JYLCBhbmNob3JZKTtcblx0XHRcdFx0fVxuXHRcdFx0fSwgMzIpO1xuXHRcdFx0XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBIaWRlIHRoZSB0b29sdGlwXG5cdCAqL1xuXHRoaWRlOiBmdW5jdGlvbiAoZGVsYXkpIHtcblx0XHR2YXIgdG9vbHRpcCA9IHRoaXMsXG5cdFx0XHRob3ZlclBvaW50cztcblx0XHRcblx0XHRjbGVhclRpbWVvdXQodGhpcy5oaWRlVGltZXIpOyAvLyBkaXNhbGxvdyBkdXBsaWNhdGUgdGltZXJzICgjMTcyOCwgIzE3NjYpXG5cdFx0aWYgKCF0aGlzLmlzSGlkZGVuKSB7XG5cdFx0XHRob3ZlclBvaW50cyA9IHRoaXMuY2hhcnQuaG92ZXJQb2ludHM7XG5cblx0XHRcdHRoaXMuaGlkZVRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHRvb2x0aXAubGFiZWwuZmFkZU91dCgpO1xuXHRcdFx0XHR0b29sdGlwLmlzSGlkZGVuID0gdHJ1ZTtcblx0XHRcdH0sIHBpY2soZGVsYXksIHRoaXMub3B0aW9ucy5oaWRlRGVsYXksIDUwMCkpO1xuXG5cdFx0XHQvLyBoaWRlIHByZXZpb3VzIGhvdmVyUG9pbnRzIGFuZCBzZXQgbmV3XG5cdFx0XHRpZiAoaG92ZXJQb2ludHMpIHtcblx0XHRcdFx0ZWFjaChob3ZlclBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdFx0cG9pbnQuc2V0U3RhdGUoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuY2hhcnQuaG92ZXJQb2ludHMgPSBudWxsO1xuXHRcdH1cblx0fSxcblx0XG5cdC8qKiBcblx0ICogRXh0ZW5kYWJsZSBtZXRob2QgdG8gZ2V0IHRoZSBhbmNob3IgcG9zaXRpb24gb2YgdGhlIHRvb2x0aXBcblx0ICogZnJvbSBhIHBvaW50IG9yIHNldCBvZiBwb2ludHNcblx0ICovXG5cdGdldEFuY2hvcjogZnVuY3Rpb24gKHBvaW50cywgbW91c2VFdmVudCkge1xuXHRcdHZhciByZXQsXG5cdFx0XHRjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdFx0cGxvdFRvcCA9IGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRwbG90WCA9IDAsXG5cdFx0XHRwbG90WSA9IDAsXG5cdFx0XHR5QXhpcztcblx0XHRcblx0XHRwb2ludHMgPSBzcGxhdChwb2ludHMpO1xuXHRcdFxuXHRcdC8vIFBpZSB1c2VzIGEgc3BlY2lhbCB0b29sdGlwUG9zXG5cdFx0cmV0ID0gcG9pbnRzWzBdLnRvb2x0aXBQb3M7XG5cdFx0XG5cdFx0Ly8gV2hlbiB0b29sdGlwIGZvbGxvd3MgbW91c2UsIHJlbGF0ZSB0aGUgcG9zaXRpb24gdG8gdGhlIG1vdXNlXG5cdFx0aWYgKHRoaXMuZm9sbG93UG9pbnRlciAmJiBtb3VzZUV2ZW50KSB7XG5cdFx0XHRpZiAobW91c2VFdmVudC5jaGFydFggPT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRtb3VzZUV2ZW50ID0gY2hhcnQucG9pbnRlci5ub3JtYWxpemUobW91c2VFdmVudCk7XG5cdFx0XHR9XG5cdFx0XHRyZXQgPSBbXG5cdFx0XHRcdG1vdXNlRXZlbnQuY2hhcnRYIC0gY2hhcnQucGxvdExlZnQsXG5cdFx0XHRcdG1vdXNlRXZlbnQuY2hhcnRZIC0gcGxvdFRvcFxuXHRcdFx0XTtcblx0XHR9XG5cdFx0Ly8gV2hlbiBzaGFyZWQsIHVzZSB0aGUgYXZlcmFnZSBwb3NpdGlvblxuXHRcdGlmICghcmV0KSB7XG5cdFx0XHRlYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdHlBeGlzID0gcG9pbnQuc2VyaWVzLnlBeGlzO1xuXHRcdFx0XHRwbG90WCArPSBwb2ludC5wbG90WDtcblx0XHRcdFx0cGxvdFkgKz0gKHBvaW50LnBsb3RMb3cgPyAocG9pbnQucGxvdExvdyArIHBvaW50LnBsb3RIaWdoKSAvIDIgOiBwb2ludC5wbG90WSkgK1xuXHRcdFx0XHRcdCghaW52ZXJ0ZWQgJiYgeUF4aXMgPyB5QXhpcy50b3AgLSBwbG90VG9wIDogMCk7IC8vICMxMTUxXG5cdFx0XHR9KTtcblx0XHRcdFxuXHRcdFx0cGxvdFggLz0gcG9pbnRzLmxlbmd0aDtcblx0XHRcdHBsb3RZIC89IHBvaW50cy5sZW5ndGg7XG5cdFx0XHRcblx0XHRcdHJldCA9IFtcblx0XHRcdFx0aW52ZXJ0ZWQgPyBjaGFydC5wbG90V2lkdGggLSBwbG90WSA6IHBsb3RYLFxuXHRcdFx0XHR0aGlzLnNoYXJlZCAmJiAhaW52ZXJ0ZWQgJiYgcG9pbnRzLmxlbmd0aCA+IDEgJiYgbW91c2VFdmVudCA/IFxuXHRcdFx0XHRcdG1vdXNlRXZlbnQuY2hhcnRZIC0gcGxvdFRvcCA6IC8vIHBsYWNlIHNoYXJlZCB0b29sdGlwIG5leHQgdG8gdGhlIG1vdXNlICgjNDI0KVxuXHRcdFx0XHRcdGludmVydGVkID8gY2hhcnQucGxvdEhlaWdodCAtIHBsb3RYIDogcGxvdFlcblx0XHRcdF07XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hcChyZXQsIG1hdGhSb3VuZCk7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogUGxhY2UgdGhlIHRvb2x0aXAgaW4gYSBjaGFydCB3aXRob3V0IHNwaWxsaW5nIG92ZXJcblx0ICogYW5kIG5vdCBjb3ZlcmluZyB0aGUgcG9pbnQgaXQgc2VsZi5cblx0ICovXG5cdGdldFBvc2l0aW9uOiBmdW5jdGlvbiAoYm94V2lkdGgsIGJveEhlaWdodCwgcG9pbnQpIHtcblx0XHRcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0ZGlzdGFuY2UgPSB0aGlzLmRpc3RhbmNlLFxuXHRcdFx0cmV0ID0ge30sXG5cdFx0XHRzd2FwcGVkLFxuXHRcdFx0Zmlyc3QgPSBbJ3knLCBjaGFydC5jaGFydEhlaWdodCwgYm94SGVpZ2h0LCBwb2ludC5wbG90WSArIGNoYXJ0LnBsb3RUb3BdLFxuXHRcdFx0c2Vjb25kID0gWyd4JywgY2hhcnQuY2hhcnRXaWR0aCwgYm94V2lkdGgsIHBvaW50LnBsb3RYICsgY2hhcnQucGxvdExlZnRdLFxuXHRcdFx0Ly8gVGhlIGZhciBzaWRlIGlzIHJpZ2h0IG9yIGJvdHRvbVxuXHRcdFx0cHJlZmVyRmFyU2lkZSA9IHBvaW50LnR0QmVsb3cgfHwgKGNoYXJ0LmludmVydGVkICYmICFwb2ludC5uZWdhdGl2ZSkgfHwgKCFjaGFydC5pbnZlcnRlZCAmJiBwb2ludC5uZWdhdGl2ZSksXG5cdFx0XHQvKipcblx0XHRcdCAqIEhhbmRsZSB0aGUgcHJlZmVycmVkIGRpbWVuc2lvbi4gV2hlbiB0aGUgcHJlZmVycmVkIGRpbWVuc2lvbiBpcyB0b29sdGlwXG5cdFx0XHQgKiBvbiB0b3Agb3IgYm90dG9tIG9mIHRoZSBwb2ludCwgaXQgd2lsbCBsb29rIGZvciBzcGFjZSB0aGVyZS5cblx0XHRcdCAqL1xuXHRcdFx0Zmlyc3REaW1lbnNpb24gPSBmdW5jdGlvbiAoZGltLCBvdXRlclNpemUsIGlubmVyU2l6ZSwgcG9pbnQpIHtcblx0XHRcdFx0dmFyIHJvb21MZWZ0ID0gaW5uZXJTaXplIDwgcG9pbnQgLSBkaXN0YW5jZSxcblx0XHRcdFx0XHRyb29tUmlnaHQgPSBwb2ludCArIGRpc3RhbmNlICsgaW5uZXJTaXplIDwgb3V0ZXJTaXplLFxuXHRcdFx0XHRcdGFsaWduZWRMZWZ0ID0gcG9pbnQgLSBkaXN0YW5jZSAtIGlubmVyU2l6ZSxcblx0XHRcdFx0XHRhbGlnbmVkUmlnaHQgPSBwb2ludCArIGRpc3RhbmNlO1xuXG5cdFx0XHRcdGlmIChwcmVmZXJGYXJTaWRlICYmIHJvb21SaWdodCkge1xuXHRcdFx0XHRcdHJldFtkaW1dID0gYWxpZ25lZFJpZ2h0O1xuXHRcdFx0XHR9IGVsc2UgaWYgKCFwcmVmZXJGYXJTaWRlICYmIHJvb21MZWZ0KSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSBhbGlnbmVkTGVmdDtcblx0XHRcdFx0fSBlbHNlIGlmIChyb29tTGVmdCkge1xuXHRcdFx0XHRcdHJldFtkaW1dID0gYWxpZ25lZExlZnQ7XG5cdFx0XHRcdH0gZWxzZSBpZiAocm9vbVJpZ2h0KSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSBhbGlnbmVkUmlnaHQ7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBIYW5kbGUgdGhlIHNlY29uZGFyeSBkaW1lbnNpb24uIElmIHRoZSBwcmVmZXJyZWQgZGltZW5zaW9uIGlzIHRvb2x0aXBcblx0XHRcdCAqIG9uIHRvcCBvciBib3R0b20gb2YgdGhlIHBvaW50LCB0aGUgc2Vjb25kIGRpbWVuc2lvbiBpcyB0byBhbGlnbiB0aGUgdG9vbHRpcFxuXHRcdFx0ICogYWJvdmUgdGhlIHBvaW50LCB0cnlpbmcgdG8gYWxpZ24gY2VudGVyIGJ1dCBhbGxvd2luZyBsZWZ0IG9yIHJpZ2h0XG5cdFx0XHQgKiBhbGlnbiB3aXRoaW4gdGhlIGNoYXJ0IGJveC5cblx0XHRcdCAqL1xuXHRcdFx0c2Vjb25kRGltZW5zaW9uID0gZnVuY3Rpb24gKGRpbSwgb3V0ZXJTaXplLCBpbm5lclNpemUsIHBvaW50KSB7XG5cdFx0XHRcdC8vIFRvbyBjbG9zZSB0byB0aGUgZWRnZSwgcmV0dXJuIGZhbHNlIGFuZCBzd2FwIGRpbWVuc2lvbnNcblx0XHRcdFx0aWYgKHBvaW50IDwgZGlzdGFuY2UgfHwgcG9pbnQgPiBvdXRlclNpemUgLSBkaXN0YW5jZSkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XG5cdFx0XHRcdC8vIEFsaWduIGxlZnQvdG9wXG5cdFx0XHRcdH0gZWxzZSBpZiAocG9pbnQgPCBpbm5lclNpemUgLyAyKSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSAxO1xuXHRcdFx0XHQvLyBBbGlnbiByaWdodC9ib3R0b21cblx0XHRcdFx0fSBlbHNlIGlmIChwb2ludCA+IG91dGVyU2l6ZSAtIGlubmVyU2l6ZSAvIDIpIHtcblx0XHRcdFx0XHRyZXRbZGltXSA9IG91dGVyU2l6ZSAtIGlubmVyU2l6ZSAtIDI7XG5cdFx0XHRcdC8vIEFsaWduIGNlbnRlclxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJldFtkaW1dID0gcG9pbnQgLSBpbm5lclNpemUgLyAyO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBTd2FwIHRoZSBkaW1lbnNpb25zIFxuXHRcdFx0ICovXG5cdFx0XHRzd2FwID0gZnVuY3Rpb24gKGNvdW50KSB7XG5cdFx0XHRcdHZhciB0ZW1wID0gZmlyc3Q7XG5cdFx0XHRcdGZpcnN0ID0gc2Vjb25kO1xuXHRcdFx0XHRzZWNvbmQgPSB0ZW1wO1xuXHRcdFx0XHRzd2FwcGVkID0gY291bnQ7XG5cdFx0XHR9LFxuXHRcdFx0cnVuID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoZmlyc3REaW1lbnNpb24uYXBwbHkoMCwgZmlyc3QpICE9PSBmYWxzZSkge1xuXHRcdFx0XHRcdGlmIChzZWNvbmREaW1lbnNpb24uYXBwbHkoMCwgc2Vjb25kKSA9PT0gZmFsc2UgJiYgIXN3YXBwZWQpIHtcblx0XHRcdFx0XHRcdHN3YXAodHJ1ZSk7XG5cdFx0XHRcdFx0XHRydW4oKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoIXN3YXBwZWQpIHtcblx0XHRcdFx0XHRzd2FwKHRydWUpO1xuXHRcdFx0XHRcdHJ1bigpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJldC54ID0gcmV0LnkgPSAwO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gVW5kZXIgdGhlc2UgY29uZGl0aW9ucywgcHJlZmVyIHRoZSB0b29sdGlwIG9uIHRoZSBzaWRlIG9mIHRoZSBwb2ludFxuXHRcdGlmIChjaGFydC5pbnZlcnRlZCB8fCB0aGlzLmxlbiA+IDEpIHtcblx0XHRcdHN3YXAoKTtcblx0XHR9XG5cdFx0cnVuKCk7XG5cblx0XHRyZXR1cm4gcmV0O1xuXHRcblx0fSxcblxuXHQvKipcblx0ICogSW4gY2FzZSBubyB1c2VyIGRlZmluZWQgZm9ybWF0dGVyIGlzIGdpdmVuLCB0aGlzIHdpbGwgYmUgdXNlZC4gTm90ZSB0aGF0IHRoZSBjb250ZXh0XG5cdCAqIGhlcmUgaXMgYW4gb2JqZWN0IGhvbGRpbmcgcG9pbnQsIHNlcmllcywgeCwgeSBldGMuXG5cdCAqL1xuXHRkZWZhdWx0Rm9ybWF0dGVyOiBmdW5jdGlvbiAodG9vbHRpcCkge1xuXHRcdHZhciBpdGVtcyA9IHRoaXMucG9pbnRzIHx8IHNwbGF0KHRoaXMpLFxuXHRcdFx0c2VyaWVzID0gaXRlbXNbMF0uc2VyaWVzLFxuXHRcdFx0cztcblxuXHRcdC8vIGJ1aWxkIHRoZSBoZWFkZXJcblx0XHRzID0gW3Rvb2x0aXAudG9vbHRpcEhlYWRlckZvcm1hdHRlcihpdGVtc1swXSldO1xuXG5cdFx0Ly8gYnVpbGQgdGhlIHZhbHVlc1xuXHRcdGVhY2goaXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0XHRzZXJpZXMgPSBpdGVtLnNlcmllcztcblx0XHRcdHMucHVzaCgoc2VyaWVzLnRvb2x0aXBGb3JtYXR0ZXIgJiYgc2VyaWVzLnRvb2x0aXBGb3JtYXR0ZXIoaXRlbSkpIHx8XG5cdFx0XHRcdGl0ZW0ucG9pbnQudG9vbHRpcEZvcm1hdHRlcihzZXJpZXMudG9vbHRpcE9wdGlvbnMucG9pbnRGb3JtYXQpKTtcblx0XHR9KTtcblxuXHRcdC8vIGZvb3RlclxuXHRcdHMucHVzaCh0b29sdGlwLm9wdGlvbnMuZm9vdGVyRm9ybWF0IHx8ICcnKTtcblxuXHRcdHJldHVybiBzLmpvaW4oJycpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZWZyZXNoIHRoZSB0b29sdGlwJ3MgdGV4dCBhbmQgcG9zaXRpb24uXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwb2ludFxuXHQgKi9cblx0cmVmcmVzaDogZnVuY3Rpb24gKHBvaW50LCBtb3VzZUV2ZW50KSB7XG5cdFx0dmFyIHRvb2x0aXAgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSB0b29sdGlwLmNoYXJ0LFxuXHRcdFx0bGFiZWwgPSB0b29sdGlwLmxhYmVsLFxuXHRcdFx0b3B0aW9ucyA9IHRvb2x0aXAub3B0aW9ucyxcblx0XHRcdHgsXG5cdFx0XHR5LFxuXHRcdFx0YW5jaG9yLFxuXHRcdFx0dGV4dENvbmZpZyA9IHt9LFxuXHRcdFx0dGV4dCxcblx0XHRcdHBvaW50Q29uZmlnID0gW10sXG5cdFx0XHRmb3JtYXR0ZXIgPSBvcHRpb25zLmZvcm1hdHRlciB8fCB0b29sdGlwLmRlZmF1bHRGb3JtYXR0ZXIsXG5cdFx0XHRob3ZlclBvaW50cyA9IGNoYXJ0LmhvdmVyUG9pbnRzLFxuXHRcdFx0Ym9yZGVyQ29sb3IsXG5cdFx0XHRzaGFyZWQgPSB0b29sdGlwLnNoYXJlZCxcblx0XHRcdGN1cnJlbnRTZXJpZXM7XG5cdFx0XHRcblx0XHRjbGVhclRpbWVvdXQodGhpcy5oaWRlVGltZXIpO1xuXHRcdFxuXHRcdC8vIGdldCB0aGUgcmVmZXJlbmNlIHBvaW50IGNvb3JkaW5hdGVzIChwaWUgY2hhcnRzIHVzZSB0b29sdGlwUG9zKVxuXHRcdHRvb2x0aXAuZm9sbG93UG9pbnRlciA9IHNwbGF0KHBvaW50KVswXS5zZXJpZXMudG9vbHRpcE9wdGlvbnMuZm9sbG93UG9pbnRlcjtcblx0XHRhbmNob3IgPSB0b29sdGlwLmdldEFuY2hvcihwb2ludCwgbW91c2VFdmVudCk7XG5cdFx0eCA9IGFuY2hvclswXTtcblx0XHR5ID0gYW5jaG9yWzFdO1xuXG5cdFx0Ly8gc2hhcmVkIHRvb2x0aXAsIGFycmF5IGlzIHNlbnQgb3ZlclxuXHRcdGlmIChzaGFyZWQgJiYgIShwb2ludC5zZXJpZXMgJiYgcG9pbnQuc2VyaWVzLm5vU2hhcmVkVG9vbHRpcCkpIHtcblx0XHRcdFxuXHRcdFx0Ly8gaGlkZSBwcmV2aW91cyBob3ZlclBvaW50cyBhbmQgc2V0IG5ld1xuXHRcdFx0XG5cdFx0XHRjaGFydC5ob3ZlclBvaW50cyA9IHBvaW50O1xuXHRcdFx0aWYgKGhvdmVyUG9pbnRzKSB7XG5cdFx0XHRcdGVhY2goaG92ZXJQb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0XHRcdHBvaW50LnNldFN0YXRlKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRlYWNoKHBvaW50LCBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdFx0XHRpdGVtLnNldFN0YXRlKEhPVkVSX1NUQVRFKTtcblxuXHRcdFx0XHRwb2ludENvbmZpZy5wdXNoKGl0ZW0uZ2V0TGFiZWxDb25maWcoKSk7XG5cdFx0XHR9KTtcblxuXHRcdFx0dGV4dENvbmZpZyA9IHtcblx0XHRcdFx0eDogcG9pbnRbMF0uY2F0ZWdvcnksXG5cdFx0XHRcdHk6IHBvaW50WzBdLnlcblx0XHRcdH07XG5cdFx0XHR0ZXh0Q29uZmlnLnBvaW50cyA9IHBvaW50Q29uZmlnO1xuXHRcdFx0dGhpcy5sZW4gPSBwb2ludENvbmZpZy5sZW5ndGg7XG5cdFx0XHRwb2ludCA9IHBvaW50WzBdO1xuXG5cdFx0Ly8gc2luZ2xlIHBvaW50IHRvb2x0aXBcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGV4dENvbmZpZyA9IHBvaW50LmdldExhYmVsQ29uZmlnKCk7XG5cdFx0fVxuXHRcdHRleHQgPSBmb3JtYXR0ZXIuY2FsbCh0ZXh0Q29uZmlnLCB0b29sdGlwKTtcblxuXHRcdC8vIHJlZ2lzdGVyIHRoZSBjdXJyZW50IHNlcmllc1xuXHRcdGN1cnJlbnRTZXJpZXMgPSBwb2ludC5zZXJpZXM7XG5cdFx0dGhpcy5kaXN0YW5jZSA9IHBpY2soY3VycmVudFNlcmllcy50b29sdGlwT3B0aW9ucy5kaXN0YW5jZSwgMTYpO1xuXG5cdFx0Ly8gdXBkYXRlIHRoZSBpbm5lciBIVE1MXG5cdFx0aWYgKHRleHQgPT09IGZhbHNlKSB7XG5cdFx0XHR0aGlzLmhpZGUoKTtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBzaG93IGl0XG5cdFx0XHRpZiAodG9vbHRpcC5pc0hpZGRlbikge1xuXHRcdFx0XHRzdG9wKGxhYmVsKTtcblx0XHRcdFx0bGFiZWwuYXR0cignb3BhY2l0eScsIDEpLnNob3coKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gdXBkYXRlIHRleHRcblx0XHRcdGxhYmVsLmF0dHIoe1xuXHRcdFx0XHR0ZXh0OiB0ZXh0XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gc2V0IHRoZSBzdHJva2UgY29sb3Igb2YgdGhlIGJveFxuXHRcdFx0Ym9yZGVyQ29sb3IgPSBvcHRpb25zLmJvcmRlckNvbG9yIHx8IHBvaW50LmNvbG9yIHx8IGN1cnJlbnRTZXJpZXMuY29sb3IgfHwgJyM2MDYwNjAnO1xuXHRcdFx0bGFiZWwuYXR0cih7XG5cdFx0XHRcdHN0cm9rZTogYm9yZGVyQ29sb3Jcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHR0b29sdGlwLnVwZGF0ZVBvc2l0aW9uKHsgcGxvdFg6IHgsIHBsb3RZOiB5LCBuZWdhdGl2ZTogcG9pbnQubmVnYXRpdmUsIHR0QmVsb3c6IHBvaW50LnR0QmVsb3cgfSk7XG5cdFx0XG5cdFx0XHR0aGlzLmlzSGlkZGVuID0gZmFsc2U7XG5cdFx0fVxuXHRcdGZpcmVFdmVudChjaGFydCwgJ3Rvb2x0aXBSZWZyZXNoJywge1xuXHRcdFx0XHR0ZXh0OiB0ZXh0LFxuXHRcdFx0XHR4OiB4ICsgY2hhcnQucGxvdExlZnQsXG5cdFx0XHRcdHk6IHkgKyBjaGFydC5wbG90VG9wLFxuXHRcdFx0XHRib3JkZXJDb2xvcjogYm9yZGVyQ29sb3Jcblx0XHRcdH0pO1xuXHR9LFxuXHRcblx0LyoqXG5cdCAqIEZpbmQgdGhlIG5ldyBwb3NpdGlvbiBhbmQgcGVyZm9ybSB0aGUgbW92ZVxuXHQgKi9cblx0dXBkYXRlUG9zaXRpb246IGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRsYWJlbCA9IHRoaXMubGFiZWwsIFxuXHRcdFx0cG9zID0gKHRoaXMub3B0aW9ucy5wb3NpdGlvbmVyIHx8IHRoaXMuZ2V0UG9zaXRpb24pLmNhbGwoXG5cdFx0XHRcdHRoaXMsXG5cdFx0XHRcdGxhYmVsLndpZHRoLFxuXHRcdFx0XHRsYWJlbC5oZWlnaHQsXG5cdFx0XHRcdHBvaW50XG5cdFx0XHQpO1xuXG5cdFx0Ly8gZG8gdGhlIG1vdmVcblx0XHR0aGlzLm1vdmUoXG5cdFx0XHRtYXRoUm91bmQocG9zLngpLCBcblx0XHRcdG1hdGhSb3VuZChwb3MueSksIFxuXHRcdFx0cG9pbnQucGxvdFggKyBjaGFydC5wbG90TGVmdCwgXG5cdFx0XHRwb2ludC5wbG90WSArIGNoYXJ0LnBsb3RUb3Bcblx0XHQpO1xuXHR9LFxuXG5cblx0LyoqXG5cdCAqIEZvcm1hdCB0aGUgaGVhZGVyIG9mIHRoZSB0b29sdGlwXG5cdCAqL1xuXHR0b29sdGlwSGVhZGVyRm9ybWF0dGVyOiBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHR2YXIgc2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0dG9vbHRpcE9wdGlvbnMgPSBzZXJpZXMudG9vbHRpcE9wdGlvbnMsXG5cdFx0XHRkYXRlVGltZUxhYmVsRm9ybWF0cyA9IHRvb2x0aXBPcHRpb25zLmRhdGVUaW1lTGFiZWxGb3JtYXRzLFxuXHRcdFx0eERhdGVGb3JtYXQgPSB0b29sdGlwT3B0aW9ucy54RGF0ZUZvcm1hdCxcblx0XHRcdHhBeGlzID0gc2VyaWVzLnhBeGlzLFxuXHRcdFx0aXNEYXRlVGltZSA9IHhBeGlzICYmIHhBeGlzLm9wdGlvbnMudHlwZSA9PT0gJ2RhdGV0aW1lJyAmJiBpc051bWJlcihwb2ludC5rZXkpLFxuXHRcdFx0aGVhZGVyRm9ybWF0ID0gdG9vbHRpcE9wdGlvbnMuaGVhZGVyRm9ybWF0LFxuXHRcdFx0Y2xvc2VzdFBvaW50UmFuZ2UgPSB4QXhpcyAmJiB4QXhpcy5jbG9zZXN0UG9pbnRSYW5nZSxcblx0XHRcdG47XG5cblx0XHQvLyBHdWVzcyB0aGUgYmVzdCBkYXRlIGZvcm1hdCBiYXNlZCBvbiB0aGUgY2xvc2VzdCBwb2ludCBkaXN0YW5jZSAoIzU2OClcblx0XHRpZiAoaXNEYXRlVGltZSAmJiAheERhdGVGb3JtYXQpIHtcblx0XHRcdGlmIChjbG9zZXN0UG9pbnRSYW5nZSkge1xuXHRcdFx0XHRmb3IgKG4gaW4gdGltZVVuaXRzKSB7XG5cdFx0XHRcdFx0aWYgKHRpbWVVbml0c1tuXSA+PSBjbG9zZXN0UG9pbnRSYW5nZSB8fCBcblx0XHRcdFx0XHRcdFx0Ly8gSWYgdGhlIHBvaW50IGlzIHBsYWNlZCBldmVyeSBkYXkgYXQgMjM6NTksIHdlIG5lZWQgdG8gc2hvd1xuXHRcdFx0XHRcdFx0XHQvLyB0aGUgbWludXRlcyBhcyB3ZWxsLiBUaGlzIGxvZ2ljIG9ubHkgd29ya3MgZm9yIHRpbWUgdW5pdHMgbGVzcyB0aGFuIFxuXHRcdFx0XHRcdFx0XHQvLyBhIGRheSwgc2luY2UgYWxsIGhpZ2hlciB0aW1lIHVuaXRzIGFyZSBkaXZpZGFibGUgYnkgdGhvc2UuICMyNjM3LlxuXHRcdFx0XHRcdFx0XHQodGltZVVuaXRzW25dIDw9IHRpbWVVbml0cy5kYXkgJiYgcG9pbnQua2V5ICUgdGltZVVuaXRzW25dID4gMCkpIHtcblx0XHRcdFx0XHRcdHhEYXRlRm9ybWF0ID0gZGF0ZVRpbWVMYWJlbEZvcm1hdHNbbl07XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHhEYXRlRm9ybWF0ID0gZGF0ZVRpbWVMYWJlbEZvcm1hdHMuZGF5O1xuXHRcdFx0fVxuXG5cdFx0XHR4RGF0ZUZvcm1hdCA9IHhEYXRlRm9ybWF0IHx8IGRhdGVUaW1lTGFiZWxGb3JtYXRzLnllYXI7IC8vICMyNTQ2LCAyNTgxXG5cblx0XHR9XG5cblx0XHQvLyBJbnNlcnQgdGhlIGhlYWRlciBkYXRlIGZvcm1hdCBpZiBhbnlcblx0XHRpZiAoaXNEYXRlVGltZSAmJiB4RGF0ZUZvcm1hdCkge1xuXHRcdFx0aGVhZGVyRm9ybWF0ID0gaGVhZGVyRm9ybWF0LnJlcGxhY2UoJ3twb2ludC5rZXl9JywgJ3twb2ludC5rZXk6JyArIHhEYXRlRm9ybWF0ICsgJ30nKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZm9ybWF0KGhlYWRlckZvcm1hdCwge1xuXHRcdFx0cG9pbnQ6IHBvaW50LFxuXHRcdFx0c2VyaWVzOiBzZXJpZXNcblx0XHR9KTtcblx0fVxufTtcblxudmFyIGhvdmVyQ2hhcnRJbmRleDtcblxuLy8gR2xvYmFsIGZsYWcgZm9yIHRvdWNoIHN1cHBvcnRcbmhhc1RvdWNoID0gZG9jLmRvY3VtZW50RWxlbWVudC5vbnRvdWNoc3RhcnQgIT09IFVOREVGSU5FRDtcblxuLyoqXG4gKiBUaGUgbW91c2UgdHJhY2tlciBvYmplY3QuIEFsbCBtZXRob2RzIHN0YXJ0aW5nIHdpdGggXCJvblwiIGFyZSBwcmltYXJ5IERPTSBldmVudCBoYW5kbGVycy4gXG4gKiBTdWJzZXF1ZW50IG1ldGhvZHMgc2hvdWxkIGJlIG5hbWVkIGRpZmZlcmVudGx5IGZyb20gd2hhdCB0aGV5IGFyZSBkb2luZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjaGFydCBUaGUgQ2hhcnQgaW5zdGFuY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSByb290IG9wdGlvbnMgb2JqZWN0XG4gKi9cbnZhciBQb2ludGVyID0gSGlnaGNoYXJ0cy5Qb2ludGVyID0gZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cdHRoaXMuaW5pdChjaGFydCwgb3B0aW9ucyk7XG59O1xuXG5Qb2ludGVyLnByb3RvdHlwZSA9IHtcblx0LyoqXG5cdCAqIEluaXRpYWxpemUgUG9pbnRlclxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cdFx0XG5cdFx0dmFyIGNoYXJ0T3B0aW9ucyA9IG9wdGlvbnMuY2hhcnQsXG5cdFx0XHRjaGFydEV2ZW50cyA9IGNoYXJ0T3B0aW9ucy5ldmVudHMsXG5cdFx0XHR6b29tVHlwZSA9IHVzZUNhblZHID8gJycgOiBjaGFydE9wdGlvbnMuem9vbVR5cGUsXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdFx0em9vbVgsXG5cdFx0XHR6b29tWTtcblxuXHRcdC8vIFN0b3JlIHJlZmVyZW5jZXNcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdHRoaXMuY2hhcnQgPSBjaGFydDtcblx0XHRcblx0XHQvLyBab29tIHN0YXR1c1xuXHRcdHRoaXMuem9vbVggPSB6b29tWCA9IC94Ly50ZXN0KHpvb21UeXBlKTtcblx0XHR0aGlzLnpvb21ZID0gem9vbVkgPSAveS8udGVzdCh6b29tVHlwZSk7XG5cdFx0dGhpcy56b29tSG9yID0gKHpvb21YICYmICFpbnZlcnRlZCkgfHwgKHpvb21ZICYmIGludmVydGVkKTtcblx0XHR0aGlzLnpvb21WZXJ0ID0gKHpvb21ZICYmICFpbnZlcnRlZCkgfHwgKHpvb21YICYmIGludmVydGVkKTtcblx0XHR0aGlzLmhhc1pvb20gPSB6b29tWCB8fCB6b29tWTtcblxuXHRcdC8vIERvIHdlIG5lZWQgdG8gaGFuZGxlIGNsaWNrIG9uIGEgdG91Y2ggZGV2aWNlP1xuXHRcdHRoaXMucnVuQ2hhcnRDbGljayA9IGNoYXJ0RXZlbnRzICYmICEhY2hhcnRFdmVudHMuY2xpY2s7XG5cblx0XHR0aGlzLnBpbmNoRG93biA9IFtdO1xuXHRcdHRoaXMubGFzdFZhbGlkVG91Y2ggPSB7fTtcblxuXHRcdGlmIChIaWdoY2hhcnRzLlRvb2x0aXAgJiYgb3B0aW9ucy50b29sdGlwLmVuYWJsZWQpIHtcblx0XHRcdGNoYXJ0LnRvb2x0aXAgPSBuZXcgVG9vbHRpcChjaGFydCwgb3B0aW9ucy50b29sdGlwKTtcblx0XHRcdHRoaXMuZm9sbG93VG91Y2hNb3ZlID0gb3B0aW9ucy50b29sdGlwLmZvbGxvd1RvdWNoTW92ZTtcblx0XHR9XG5cblx0XHR0aGlzLnNldERPTUV2ZW50cygpO1xuXHR9LCBcblxuXHQvKipcblx0ICogQWRkIGNyb3NzYnJvd3NlciBzdXBwb3J0IGZvciBjaGFydFggYW5kIGNoYXJ0WVxuXHQgKiBAcGFyYW0ge09iamVjdH0gZSBUaGUgZXZlbnQgb2JqZWN0IGluIHN0YW5kYXJkIGJyb3dzZXJzXG5cdCAqL1xuXHRub3JtYWxpemU6IGZ1bmN0aW9uIChlLCBjaGFydFBvc2l0aW9uKSB7XG5cdFx0dmFyIGNoYXJ0WCxcblx0XHRcdGNoYXJ0WSxcblx0XHRcdGVQb3M7XG5cblx0XHQvLyBjb21tb24gSUUgbm9ybWFsaXppbmdcblx0XHRlID0gZSB8fCB3aW5kb3cuZXZlbnQ7XG5cblx0XHQvLyBGcmFtZXdvcmsgc3BlY2lmaWMgbm9ybWFsaXppbmcgKCMxMTY1KVxuXHRcdGUgPSB3YXNoTW91c2VFdmVudChlKTtcblxuXHRcdC8vIE1vcmUgSUUgbm9ybWFsaXppbmcsIG5lZWRzIHRvIGdvIGFmdGVyIHdhc2hNb3VzZUV2ZW50XG5cdFx0aWYgKCFlLnRhcmdldCkge1xuXHRcdFx0ZS50YXJnZXQgPSBlLnNyY0VsZW1lbnQ7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIGlPUyAoIzI3NTcpXG5cdFx0ZVBvcyA9IGUudG91Y2hlcyA/ICAoZS50b3VjaGVzLmxlbmd0aCA/IGUudG91Y2hlcy5pdGVtKDApIDogZS5jaGFuZ2VkVG91Y2hlc1swXSkgOiBlO1xuXG5cdFx0Ly8gR2V0IG1vdXNlIHBvc2l0aW9uXG5cdFx0aWYgKCFjaGFydFBvc2l0aW9uKSB7XG5cdFx0XHR0aGlzLmNoYXJ0UG9zaXRpb24gPSBjaGFydFBvc2l0aW9uID0gb2Zmc2V0KHRoaXMuY2hhcnQuY29udGFpbmVyKTtcblx0XHR9XG5cblx0XHQvLyBjaGFydFggYW5kIGNoYXJ0WVxuXHRcdGlmIChlUG9zLnBhZ2VYID09PSBVTkRFRklORUQpIHsgLy8gSUUgPCA5LiAjODg2LlxuXHRcdFx0Y2hhcnRYID0gbWF0aE1heChlLngsIGUuY2xpZW50WCAtIGNoYXJ0UG9zaXRpb24ubGVmdCk7IC8vICMyMDA1LCAjMjEyOTogdGhlIHNlY29uZCBjYXNlIGlzIFxuXHRcdFx0XHQvLyBmb3IgSUUxMCBxdWlya3MgbW9kZSB3aXRoaW4gZnJhbWVzZXRzXG5cdFx0XHRjaGFydFkgPSBlLnk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNoYXJ0WCA9IGVQb3MucGFnZVggLSBjaGFydFBvc2l0aW9uLmxlZnQ7XG5cdFx0XHRjaGFydFkgPSBlUG9zLnBhZ2VZIC0gY2hhcnRQb3NpdGlvbi50b3A7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV4dGVuZChlLCB7XG5cdFx0XHRjaGFydFg6IG1hdGhSb3VuZChjaGFydFgpLFxuXHRcdFx0Y2hhcnRZOiBtYXRoUm91bmQoY2hhcnRZKVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGNsaWNrIHBvc2l0aW9uIGluIHRlcm1zIG9mIGF4aXMgdmFsdWVzLlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gZSBBIHBvaW50ZXIgZXZlbnRcblx0ICovXG5cdGdldENvb3JkaW5hdGVzOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjb29yZGluYXRlcyA9IHtcblx0XHRcdFx0eEF4aXM6IFtdLFxuXHRcdFx0XHR5QXhpczogW11cblx0XHRcdH07XG5cblx0XHRlYWNoKHRoaXMuY2hhcnQuYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdGNvb3JkaW5hdGVzW2F4aXMuaXNYQXhpcyA/ICd4QXhpcycgOiAneUF4aXMnXS5wdXNoKHtcblx0XHRcdFx0YXhpczogYXhpcyxcblx0XHRcdFx0dmFsdWU6IGF4aXMudG9WYWx1ZShlW2F4aXMuaG9yaXogPyAnY2hhcnRYJyA6ICdjaGFydFknXSlcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdHJldHVybiBjb29yZGluYXRlcztcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBSZXR1cm4gdGhlIGluZGV4IGluIHRoZSB0b29sdGlwUG9pbnRzIGFycmF5LCBjb3JyZXNwb25kaW5nIHRvIHBpeGVsIHBvc2l0aW9uIGluIFxuXHQgKiB0aGUgcGxvdCBhcmVhLlxuXHQgKi9cblx0Z2V0SW5kZXg6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydDtcblx0XHRyZXR1cm4gY2hhcnQuaW52ZXJ0ZWQgPyBcblx0XHRcdGNoYXJ0LnBsb3RIZWlnaHQgKyBjaGFydC5wbG90VG9wIC0gZS5jaGFydFkgOiBcblx0XHRcdGUuY2hhcnRYIC0gY2hhcnQucGxvdExlZnQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFdpdGggbGluZSB0eXBlIGNoYXJ0cyB3aXRoIGEgc2luZ2xlIHRyYWNrZXIsIGdldCB0aGUgcG9pbnQgY2xvc2VzdCB0byB0aGUgbW91c2UuXG5cdCAqIFJ1biBQb2ludC5vbk1vdXNlT3ZlciBhbmQgZGlzcGxheSB0b29sdGlwIGZvciB0aGUgcG9pbnQgb3IgcG9pbnRzLlxuXHQgKi9cblx0cnVuUG9pbnRBY3Rpb25zOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBwb2ludGVyID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gcG9pbnRlci5jaGFydCxcblx0XHRcdHNlcmllcyA9IGNoYXJ0LnNlcmllcyxcblx0XHRcdHRvb2x0aXAgPSBjaGFydC50b29sdGlwLFxuXHRcdFx0Zm9sbG93UG9pbnRlcixcblx0XHRcdHBvaW50LFxuXHRcdFx0cG9pbnRzLFxuXHRcdFx0aG92ZXJQb2ludCA9IGNoYXJ0LmhvdmVyUG9pbnQsXG5cdFx0XHRob3ZlclNlcmllcyA9IGNoYXJ0LmhvdmVyU2VyaWVzLFxuXHRcdFx0aSxcblx0XHRcdGosXG5cdFx0XHRkaXN0YW5jZSA9IGNoYXJ0LmNoYXJ0V2lkdGgsXG5cdFx0XHRpbmRleCA9IHBvaW50ZXIuZ2V0SW5kZXgoZSksXG5cdFx0XHRhbmNob3I7XG5cblx0XHQvLyBzaGFyZWQgdG9vbHRpcFxuXHRcdGlmICh0b29sdGlwICYmIHBvaW50ZXIub3B0aW9ucy50b29sdGlwLnNoYXJlZCAmJiAhKGhvdmVyU2VyaWVzICYmIGhvdmVyU2VyaWVzLm5vU2hhcmVkVG9vbHRpcCkpIHtcblx0XHRcdHBvaW50cyA9IFtdO1xuXG5cdFx0XHQvLyBsb29wIG92ZXIgYWxsIHNlcmllcyBhbmQgZmluZCB0aGUgb25lcyB3aXRoIHBvaW50cyBjbG9zZXN0IHRvIHRoZSBtb3VzZVxuXHRcdFx0aSA9IHNlcmllcy5sZW5ndGg7XG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgaTsgaisrKSB7XG5cdFx0XHRcdGlmIChzZXJpZXNbal0udmlzaWJsZSAmJlxuXHRcdFx0XHRcdFx0c2VyaWVzW2pdLm9wdGlvbnMuZW5hYmxlTW91c2VUcmFja2luZyAhPT0gZmFsc2UgJiZcblx0XHRcdFx0XHRcdCFzZXJpZXNbal0ubm9TaGFyZWRUb29sdGlwICYmIHNlcmllc1tqXS5zaW5ndWxhclRvb2x0aXBzICE9PSB0cnVlICYmIHNlcmllc1tqXS50b29sdGlwUG9pbnRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdHBvaW50ID0gc2VyaWVzW2pdLnRvb2x0aXBQb2ludHNbaW5kZXhdO1xuXHRcdFx0XHRcdGlmIChwb2ludCAmJiBwb2ludC5zZXJpZXMpIHsgLy8gbm90IGEgZHVtbXkgcG9pbnQsICMxNTQ0XG5cdFx0XHRcdFx0XHRwb2ludC5fZGlzdCA9IG1hdGhBYnMoaW5kZXggLSBwb2ludC5jbGllbnRYKTtcblx0XHRcdFx0XHRcdGRpc3RhbmNlID0gbWF0aE1pbihkaXN0YW5jZSwgcG9pbnQuX2Rpc3QpO1xuXHRcdFx0XHRcdFx0cG9pbnRzLnB1c2gocG9pbnQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gcmVtb3ZlIGZ1cnRoZXN0IHBvaW50c1xuXHRcdFx0aSA9IHBvaW50cy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdGlmIChwb2ludHNbaV0uX2Rpc3QgPiBkaXN0YW5jZSkge1xuXHRcdFx0XHRcdHBvaW50cy5zcGxpY2UoaSwgMSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIHJlZnJlc2ggdGhlIHRvb2x0aXAgaWYgbmVjZXNzYXJ5XG5cdFx0XHRpZiAocG9pbnRzLmxlbmd0aCAmJiAocG9pbnRzWzBdLmNsaWVudFggIT09IHBvaW50ZXIuaG92ZXJYKSkge1xuXHRcdFx0XHR0b29sdGlwLnJlZnJlc2gocG9pbnRzLCBlKTtcblx0XHRcdFx0cG9pbnRlci5ob3ZlclggPSBwb2ludHNbMF0uY2xpZW50WDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXBhcmF0ZSB0b29sdGlwIGFuZCBnZW5lcmFsIG1vdXNlIGV2ZW50c1xuXHRcdGZvbGxvd1BvaW50ZXIgPSBob3ZlclNlcmllcyAmJiBob3ZlclNlcmllcy50b29sdGlwT3B0aW9ucy5mb2xsb3dQb2ludGVyO1xuXHRcdGlmIChob3ZlclNlcmllcyAmJiBob3ZlclNlcmllcy50cmFja2VyICYmICFmb2xsb3dQb2ludGVyKSB7IC8vICMyNTg0LCAjMjgzMFxuXG5cdFx0XHQvLyBnZXQgdGhlIHBvaW50XG5cdFx0XHRwb2ludCA9IGhvdmVyU2VyaWVzLnRvb2x0aXBQb2ludHNbaW5kZXhdO1xuXG5cdFx0XHQvLyBhIG5ldyBwb2ludCBpcyBob3ZlcmVkLCByZWZyZXNoIHRoZSB0b29sdGlwXG5cdFx0XHRpZiAocG9pbnQgJiYgcG9pbnQgIT09IGhvdmVyUG9pbnQpIHtcblxuXHRcdFx0XHQvLyB0cmlnZ2VyIHRoZSBldmVudHNcblx0XHRcdFx0cG9pbnQub25Nb3VzZU92ZXIoZSk7XG5cblx0XHRcdH1cblx0XHRcdFxuXHRcdH0gZWxzZSBpZiAodG9vbHRpcCAmJiBmb2xsb3dQb2ludGVyICYmICF0b29sdGlwLmlzSGlkZGVuKSB7XG5cdFx0XHRhbmNob3IgPSB0b29sdGlwLmdldEFuY2hvcihbe31dLCBlKTtcblx0XHRcdHRvb2x0aXAudXBkYXRlUG9zaXRpb24oeyBwbG90WDogYW5jaG9yWzBdLCBwbG90WTogYW5jaG9yWzFdIH0pO1xuXHRcdH1cblxuXHRcdC8vIFN0YXJ0IHRoZSBldmVudCBsaXN0ZW5lciB0byBwaWNrIHVwIHRoZSB0b29sdGlwIFxuXHRcdGlmICh0b29sdGlwICYmICFwb2ludGVyLl9vbkRvY3VtZW50TW91c2VNb3ZlKSB7XG5cdFx0XHRwb2ludGVyLl9vbkRvY3VtZW50TW91c2VNb3ZlID0gZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0aWYgKGNoYXJ0c1tob3ZlckNoYXJ0SW5kZXhdKSB7XG5cdFx0XHRcdFx0Y2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0ucG9pbnRlci5vbkRvY3VtZW50TW91c2VNb3ZlKGUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0YWRkRXZlbnQoZG9jLCAnbW91c2Vtb3ZlJywgcG9pbnRlci5fb25Eb2N1bWVudE1vdXNlTW92ZSk7XG5cdFx0fVxuXG5cdFx0Ly8gRHJhdyBpbmRlcGVuZGVudCBjcm9zc2hhaXJzXG5cdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0YXhpcy5kcmF3Q3Jvc3NoYWlyKGUsIHBpY2socG9pbnQsIGhvdmVyUG9pbnQpKTtcblx0XHR9KTtcblx0fSxcblxuXG5cblx0LyoqXG5cdCAqIFJlc2V0IHRoZSB0cmFja2luZyBieSBoaWRpbmcgdGhlIHRvb2x0aXAsIHRoZSBob3ZlciBzZXJpZXMgc3RhdGUgYW5kIHRoZSBob3ZlciBwb2ludFxuXHQgKiBcblx0ICogQHBhcmFtIGFsbG93TW92ZSB7Qm9vbGVhbn0gSW5zdGVhZCBvZiBkZXN0cm95aW5nIHRoZSB0b29sdGlwIGFsdG9nZXRoZXIsIGFsbG93IG1vdmluZyBpdCBpZiBwb3NzaWJsZVxuXHQgKi9cblx0cmVzZXQ6IGZ1bmN0aW9uIChhbGxvd01vdmUsIGRlbGF5KSB7XG5cdFx0dmFyIHBvaW50ZXIgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBwb2ludGVyLmNoYXJ0LFxuXHRcdFx0aG92ZXJTZXJpZXMgPSBjaGFydC5ob3ZlclNlcmllcyxcblx0XHRcdGhvdmVyUG9pbnQgPSBjaGFydC5ob3ZlclBvaW50LFxuXHRcdFx0dG9vbHRpcCA9IGNoYXJ0LnRvb2x0aXAsXG5cdFx0XHR0b29sdGlwUG9pbnRzID0gdG9vbHRpcCAmJiB0b29sdGlwLnNoYXJlZCA/IGNoYXJ0LmhvdmVyUG9pbnRzIDogaG92ZXJQb2ludDtcblx0XHRcdFxuXHRcdC8vIE5hcnJvdyBpbiBhbGxvd01vdmVcblx0XHRhbGxvd01vdmUgPSBhbGxvd01vdmUgJiYgdG9vbHRpcCAmJiB0b29sdGlwUG9pbnRzO1xuXHRcdFx0XG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIHBvaW50cyBoYXZlIG1vdmVkIG91dHNpZGUgdGhlIHBsb3QgYXJlYSwgIzEwMDNcblx0XHRpZiAoYWxsb3dNb3ZlICYmIHNwbGF0KHRvb2x0aXBQb2ludHMpWzBdLnBsb3RYID09PSBVTkRFRklORUQpIHtcblx0XHRcdGFsbG93TW92ZSA9IGZhbHNlO1xuXHRcdH1cdFxuXG5cdFx0Ly8gSnVzdCBtb3ZlIHRoZSB0b29sdGlwLCAjMzQ5XG5cdFx0aWYgKGFsbG93TW92ZSkge1xuXHRcdFx0dG9vbHRpcC5yZWZyZXNoKHRvb2x0aXBQb2ludHMpO1xuXHRcdFx0aWYgKGhvdmVyUG9pbnQpIHsgLy8gIzI1MDBcblx0XHRcdFx0aG92ZXJQb2ludC5zZXRTdGF0ZShob3ZlclBvaW50LnN0YXRlLCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdC8vIEZ1bGwgcmVzZXRcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHRpZiAoaG92ZXJQb2ludCkge1xuXHRcdFx0XHRob3ZlclBvaW50Lm9uTW91c2VPdXQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGhvdmVyU2VyaWVzKSB7XG5cdFx0XHRcdGhvdmVyU2VyaWVzLm9uTW91c2VPdXQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHRvb2x0aXApIHtcblx0XHRcdFx0dG9vbHRpcC5oaWRlKGRlbGF5KTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHBvaW50ZXIuX29uRG9jdW1lbnRNb3VzZU1vdmUpIHtcblx0XHRcdFx0cmVtb3ZlRXZlbnQoZG9jLCAnbW91c2Vtb3ZlJywgcG9pbnRlci5fb25Eb2N1bWVudE1vdXNlTW92ZSk7XG5cdFx0XHRcdHBvaW50ZXIuX29uRG9jdW1lbnRNb3VzZU1vdmUgPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZW1vdmUgY3Jvc3NoYWlyc1xuXHRcdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRheGlzLmhpZGVDcm9zc2hhaXIoKTtcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHRwb2ludGVyLmhvdmVyWCA9IG51bGw7XG5cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNjYWxlIHNlcmllcyBncm91cHMgdG8gYSBjZXJ0YWluIHNjYWxlIGFuZCB0cmFuc2xhdGlvblxuXHQgKi9cblx0c2NhbGVHcm91cHM6IGZ1bmN0aW9uIChhdHRyaWJzLCBjbGlwKSB7XG5cblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0c2VyaWVzQXR0cmlicztcblxuXHRcdC8vIFNjYWxlIGVhY2ggc2VyaWVzXG5cdFx0ZWFjaChjaGFydC5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdHNlcmllc0F0dHJpYnMgPSBhdHRyaWJzIHx8IHNlcmllcy5nZXRQbG90Qm94KCk7IC8vICMxNzAxXG5cdFx0XHRpZiAoc2VyaWVzLnhBeGlzICYmIHNlcmllcy54QXhpcy56b29tRW5hYmxlZCkge1xuXHRcdFx0XHRzZXJpZXMuZ3JvdXAuYXR0cihzZXJpZXNBdHRyaWJzKTtcblx0XHRcdFx0aWYgKHNlcmllcy5tYXJrZXJHcm91cCkge1xuXHRcdFx0XHRcdHNlcmllcy5tYXJrZXJHcm91cC5hdHRyKHNlcmllc0F0dHJpYnMpO1xuXHRcdFx0XHRcdHNlcmllcy5tYXJrZXJHcm91cC5jbGlwKGNsaXAgPyBjaGFydC5jbGlwUmVjdCA6IG51bGwpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChzZXJpZXMuZGF0YUxhYmVsc0dyb3VwKSB7XG5cdFx0XHRcdFx0c2VyaWVzLmRhdGFMYWJlbHNHcm91cC5hdHRyKHNlcmllc0F0dHJpYnMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0XG5cdFx0Ly8gQ2xpcFxuXHRcdGNoYXJ0LmNsaXBSZWN0LmF0dHIoY2xpcCB8fCBjaGFydC5jbGlwQm94KTtcblx0fSxcblxuXHQvKipcblx0ICogU3RhcnQgYSBkcmFnIG9wZXJhdGlvblxuXHQgKi9cblx0ZHJhZ1N0YXJ0OiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cblx0XHQvLyBSZWNvcmQgdGhlIHN0YXJ0IHBvc2l0aW9uXG5cdFx0Y2hhcnQubW91c2VJc0Rvd24gPSBlLnR5cGU7XG5cdFx0Y2hhcnQuY2FuY2VsQ2xpY2sgPSBmYWxzZTtcblx0XHRjaGFydC5tb3VzZURvd25YID0gdGhpcy5tb3VzZURvd25YID0gZS5jaGFydFg7XG5cdFx0Y2hhcnQubW91c2VEb3duWSA9IHRoaXMubW91c2VEb3duWSA9IGUuY2hhcnRZO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBQZXJmb3JtIGEgZHJhZyBvcGVyYXRpb24gaW4gcmVzcG9uc2UgdG8gYSBtb3VzZW1vdmUgZXZlbnQgd2hpbGUgdGhlIG1vdXNlIGlzIGRvd25cblx0ICovXG5cdGRyYWc6IGZ1bmN0aW9uIChlKSB7XG5cblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0Y2hhcnRPcHRpb25zID0gY2hhcnQub3B0aW9ucy5jaGFydCxcblx0XHRcdGNoYXJ0WCA9IGUuY2hhcnRYLFxuXHRcdFx0Y2hhcnRZID0gZS5jaGFydFksXG5cdFx0XHR6b29tSG9yID0gdGhpcy56b29tSG9yLFxuXHRcdFx0em9vbVZlcnQgPSB0aGlzLnpvb21WZXJ0LFxuXHRcdFx0cGxvdExlZnQgPSBjaGFydC5wbG90TGVmdCxcblx0XHRcdHBsb3RUb3AgPSBjaGFydC5wbG90VG9wLFxuXHRcdFx0cGxvdFdpZHRoID0gY2hhcnQucGxvdFdpZHRoLFxuXHRcdFx0cGxvdEhlaWdodCA9IGNoYXJ0LnBsb3RIZWlnaHQsXG5cdFx0XHRjbGlja2VkSW5zaWRlLFxuXHRcdFx0c2l6ZSxcblx0XHRcdG1vdXNlRG93blggPSB0aGlzLm1vdXNlRG93blgsXG5cdFx0XHRtb3VzZURvd25ZID0gdGhpcy5tb3VzZURvd25ZLFxuXHRcdFx0cGFuS2V5ID0gY2hhcnRPcHRpb25zLnBhbktleSAmJiBlW2NoYXJ0T3B0aW9ucy5wYW5LZXkgKyAnS2V5J107XG5cblx0XHQvLyBJZiB0aGUgbW91c2UgaXMgb3V0c2lkZSB0aGUgcGxvdCBhcmVhLCBhZGp1c3QgdG8gY29vb3JkaW5hdGVzXG5cdFx0Ly8gaW5zaWRlIHRvIHByZXZlbnQgdGhlIHNlbGVjdGlvbiBtYXJrZXIgZnJvbSBnb2luZyBvdXRzaWRlXG5cdFx0aWYgKGNoYXJ0WCA8IHBsb3RMZWZ0KSB7XG5cdFx0XHRjaGFydFggPSBwbG90TGVmdDtcblx0XHR9IGVsc2UgaWYgKGNoYXJ0WCA+IHBsb3RMZWZ0ICsgcGxvdFdpZHRoKSB7XG5cdFx0XHRjaGFydFggPSBwbG90TGVmdCArIHBsb3RXaWR0aDtcblx0XHR9XG5cblx0XHRpZiAoY2hhcnRZIDwgcGxvdFRvcCkge1xuXHRcdFx0Y2hhcnRZID0gcGxvdFRvcDtcblx0XHR9IGVsc2UgaWYgKGNoYXJ0WSA+IHBsb3RUb3AgKyBwbG90SGVpZ2h0KSB7XG5cdFx0XHRjaGFydFkgPSBwbG90VG9wICsgcGxvdEhlaWdodDtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gZGV0ZXJtaW5lIGlmIHRoZSBtb3VzZSBoYXMgbW92ZWQgbW9yZSB0aGFuIDEwcHhcblx0XHR0aGlzLmhhc0RyYWdnZWQgPSBNYXRoLnNxcnQoXG5cdFx0XHRNYXRoLnBvdyhtb3VzZURvd25YIC0gY2hhcnRYLCAyKSArXG5cdFx0XHRNYXRoLnBvdyhtb3VzZURvd25ZIC0gY2hhcnRZLCAyKVxuXHRcdCk7XG5cdFx0XG5cdFx0aWYgKHRoaXMuaGFzRHJhZ2dlZCA+IDEwKSB7XG5cdFx0XHRjbGlja2VkSW5zaWRlID0gY2hhcnQuaXNJbnNpZGVQbG90KG1vdXNlRG93blggLSBwbG90TGVmdCwgbW91c2VEb3duWSAtIHBsb3RUb3ApO1xuXG5cdFx0XHQvLyBtYWtlIGEgc2VsZWN0aW9uXG5cdFx0XHRpZiAoY2hhcnQuaGFzQ2FydGVzaWFuU2VyaWVzICYmICh0aGlzLnpvb21YIHx8IHRoaXMuem9vbVkpICYmIGNsaWNrZWRJbnNpZGUgJiYgIXBhbktleSkge1xuXHRcdFx0XHRpZiAoIXRoaXMuc2VsZWN0aW9uTWFya2VyKSB7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3Rpb25NYXJrZXIgPSBjaGFydC5yZW5kZXJlci5yZWN0KFxuXHRcdFx0XHRcdFx0cGxvdExlZnQsXG5cdFx0XHRcdFx0XHRwbG90VG9wLFxuXHRcdFx0XHRcdFx0em9vbUhvciA/IDEgOiBwbG90V2lkdGgsXG5cdFx0XHRcdFx0XHR6b29tVmVydCA/IDEgOiBwbG90SGVpZ2h0LFxuXHRcdFx0XHRcdFx0MFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRmaWxsOiBjaGFydE9wdGlvbnMuc2VsZWN0aW9uTWFya2VyRmlsbCB8fCAncmdiYSg2OSwxMTQsMTY3LDAuMjUpJyxcblx0XHRcdFx0XHRcdHpJbmRleDogN1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIGFkanVzdCB0aGUgd2lkdGggb2YgdGhlIHNlbGVjdGlvbiBtYXJrZXJcblx0XHRcdGlmICh0aGlzLnNlbGVjdGlvbk1hcmtlciAmJiB6b29tSG9yKSB7XG5cdFx0XHRcdHNpemUgPSBjaGFydFggLSBtb3VzZURvd25YO1xuXHRcdFx0XHR0aGlzLnNlbGVjdGlvbk1hcmtlci5hdHRyKHtcblx0XHRcdFx0XHR3aWR0aDogbWF0aEFicyhzaXplKSxcblx0XHRcdFx0XHR4OiAoc2l6ZSA+IDAgPyAwIDogc2l6ZSkgKyBtb3VzZURvd25YXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0Ly8gYWRqdXN0IHRoZSBoZWlnaHQgb2YgdGhlIHNlbGVjdGlvbiBtYXJrZXJcblx0XHRcdGlmICh0aGlzLnNlbGVjdGlvbk1hcmtlciAmJiB6b29tVmVydCkge1xuXHRcdFx0XHRzaXplID0gY2hhcnRZIC0gbW91c2VEb3duWTtcblx0XHRcdFx0dGhpcy5zZWxlY3Rpb25NYXJrZXIuYXR0cih7XG5cdFx0XHRcdFx0aGVpZ2h0OiBtYXRoQWJzKHNpemUpLFxuXHRcdFx0XHRcdHk6IChzaXplID4gMCA/IDAgOiBzaXplKSArIG1vdXNlRG93bllcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHBhbm5pbmdcblx0XHRcdGlmIChjbGlja2VkSW5zaWRlICYmICF0aGlzLnNlbGVjdGlvbk1hcmtlciAmJiBjaGFydE9wdGlvbnMucGFubmluZykge1xuXHRcdFx0XHRjaGFydC5wYW4oZSwgY2hhcnRPcHRpb25zLnBhbm5pbmcpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogT24gbW91c2UgdXAgb3IgdG91Y2ggZW5kIGFjcm9zcyB0aGUgZW50aXJlIGRvY3VtZW50LCBkcm9wIHRoZSBzZWxlY3Rpb24uXG5cdCAqL1xuXHRkcm9wOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRoYXNQaW5jaGVkID0gdGhpcy5oYXNQaW5jaGVkO1xuXG5cdFx0aWYgKHRoaXMuc2VsZWN0aW9uTWFya2VyKSB7XG5cdFx0XHR2YXIgc2VsZWN0aW9uRGF0YSA9IHtcblx0XHRcdFx0XHR4QXhpczogW10sXG5cdFx0XHRcdFx0eUF4aXM6IFtdLFxuXHRcdFx0XHRcdG9yaWdpbmFsRXZlbnQ6IGUub3JpZ2luYWxFdmVudCB8fCBlXG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNlbGVjdGlvbkJveCA9IHRoaXMuc2VsZWN0aW9uTWFya2VyLFxuXHRcdFx0XHRzZWxlY3Rpb25MZWZ0ID0gc2VsZWN0aW9uQm94LmF0dHIgPyBzZWxlY3Rpb25Cb3guYXR0cigneCcpIDogc2VsZWN0aW9uQm94LngsXG5cdFx0XHRcdHNlbGVjdGlvblRvcCA9IHNlbGVjdGlvbkJveC5hdHRyID8gc2VsZWN0aW9uQm94LmF0dHIoJ3knKSA6IHNlbGVjdGlvbkJveC55LFxuXHRcdFx0XHRzZWxlY3Rpb25XaWR0aCA9IHNlbGVjdGlvbkJveC5hdHRyID8gc2VsZWN0aW9uQm94LmF0dHIoJ3dpZHRoJykgOiBzZWxlY3Rpb25Cb3gud2lkdGgsXG5cdFx0XHRcdHNlbGVjdGlvbkhlaWdodCA9IHNlbGVjdGlvbkJveC5hdHRyID8gc2VsZWN0aW9uQm94LmF0dHIoJ2hlaWdodCcpIDogc2VsZWN0aW9uQm94LmhlaWdodCxcblx0XHRcdFx0cnVuWm9vbTtcblxuXHRcdFx0Ly8gYSBzZWxlY3Rpb24gaGFzIGJlZW4gbWFkZVxuXHRcdFx0aWYgKHRoaXMuaGFzRHJhZ2dlZCB8fCBoYXNQaW5jaGVkKSB7XG5cblx0XHRcdFx0Ly8gcmVjb3JkIGVhY2ggYXhpcycgbWluIGFuZCBtYXhcblx0XHRcdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRcdGlmIChheGlzLnpvb21FbmFibGVkKSB7XG5cdFx0XHRcdFx0XHR2YXIgaG9yaXogPSBheGlzLmhvcml6LFxuXHRcdFx0XHRcdFx0XHRtaW5QaXhlbFBhZGRpbmcgPSBlLnR5cGUgPT09ICd0b3VjaGVuZCcgPyBheGlzLm1pblBpeGVsUGFkZGluZzogMCwgLy8gIzEyMDcsICMzMDc1XG5cdFx0XHRcdFx0XHRcdHNlbGVjdGlvbk1pbiA9IGF4aXMudG9WYWx1ZSgoaG9yaXogPyBzZWxlY3Rpb25MZWZ0IDogc2VsZWN0aW9uVG9wKSArIG1pblBpeGVsUGFkZGluZyksXG5cdFx0XHRcdFx0XHRcdHNlbGVjdGlvbk1heCA9IGF4aXMudG9WYWx1ZSgoaG9yaXogPyBzZWxlY3Rpb25MZWZ0ICsgc2VsZWN0aW9uV2lkdGggOiBzZWxlY3Rpb25Ub3AgKyBzZWxlY3Rpb25IZWlnaHQpIC0gbWluUGl4ZWxQYWRkaW5nKTtcblxuXHRcdFx0XHRcdFx0aWYgKCFpc05hTihzZWxlY3Rpb25NaW4pICYmICFpc05hTihzZWxlY3Rpb25NYXgpKSB7IC8vICM4NTlcblx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uRGF0YVtheGlzLmNvbGxdLnB1c2goe1xuXHRcdFx0XHRcdFx0XHRcdGF4aXM6IGF4aXMsXG5cdFx0XHRcdFx0XHRcdFx0bWluOiBtYXRoTWluKHNlbGVjdGlvbk1pbiwgc2VsZWN0aW9uTWF4KSwgLy8gZm9yIHJldmVyc2VkIGF4ZXMsXG5cdFx0XHRcdFx0XHRcdFx0bWF4OiBtYXRoTWF4KHNlbGVjdGlvbk1pbiwgc2VsZWN0aW9uTWF4KVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0cnVuWm9vbSA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0aWYgKHJ1blpvb20pIHtcblx0XHRcdFx0XHRmaXJlRXZlbnQoY2hhcnQsICdzZWxlY3Rpb24nLCBzZWxlY3Rpb25EYXRhLCBmdW5jdGlvbiAoYXJncykgeyBcblx0XHRcdFx0XHRcdGNoYXJ0Lnpvb20oZXh0ZW5kKGFyZ3MsIGhhc1BpbmNoZWQgPyB7IGFuaW1hdGlvbjogZmFsc2UgfSA6IG51bGwpKTsgXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXHRcdFx0dGhpcy5zZWxlY3Rpb25NYXJrZXIgPSB0aGlzLnNlbGVjdGlvbk1hcmtlci5kZXN0cm95KCk7XG5cblx0XHRcdC8vIFJlc2V0IHNjYWxpbmcgcHJldmlld1xuXHRcdFx0aWYgKGhhc1BpbmNoZWQpIHtcblx0XHRcdFx0dGhpcy5zY2FsZUdyb3VwcygpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlc2V0IGFsbFxuXHRcdGlmIChjaGFydCkgeyAvLyBpdCBtYXkgYmUgZGVzdHJveWVkIG9uIG1vdXNlIHVwIC0gIzg3N1xuXHRcdFx0Y3NzKGNoYXJ0LmNvbnRhaW5lciwgeyBjdXJzb3I6IGNoYXJ0Ll9jdXJzb3IgfSk7XG5cdFx0XHRjaGFydC5jYW5jZWxDbGljayA9IHRoaXMuaGFzRHJhZ2dlZCA+IDEwOyAvLyAjMzcwXG5cdFx0XHRjaGFydC5tb3VzZUlzRG93biA9IHRoaXMuaGFzRHJhZ2dlZCA9IHRoaXMuaGFzUGluY2hlZCA9IGZhbHNlO1xuXHRcdFx0dGhpcy5waW5jaERvd24gPSBbXTtcblx0XHR9XG5cdH0sXG5cblx0b25Db250YWluZXJNb3VzZURvd246IGZ1bmN0aW9uIChlKSB7XG5cblx0XHRlID0gdGhpcy5ub3JtYWxpemUoZSk7XG5cblx0XHQvLyBpc3N1ZSAjMjk1LCBkcmFnZ2luZyBub3QgYWx3YXlzIHdvcmtpbmcgaW4gRmlyZWZveFxuXHRcdGlmIChlLnByZXZlbnREZWZhdWx0KSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHRcdFxuXHRcdHRoaXMuZHJhZ1N0YXJ0KGUpO1xuXHR9LFxuXG5cdFxuXG5cdG9uRG9jdW1lbnRNb3VzZVVwOiBmdW5jdGlvbiAoZSkge1xuXHRcdGlmIChjaGFydHNbaG92ZXJDaGFydEluZGV4XSkge1xuXHRcdFx0Y2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0ucG9pbnRlci5kcm9wKGUpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU3BlY2lhbCBoYW5kbGVyIGZvciBtb3VzZSBtb3ZlIHRoYXQgd2lsbCBoaWRlIHRoZSB0b29sdGlwIHdoZW4gdGhlIG1vdXNlIGxlYXZlcyB0aGUgcGxvdGFyZWEuXG5cdCAqIElzc3VlICMxNDkgd29ya2Fyb3VuZC4gVGhlIG1vdXNlbGVhdmUgZXZlbnQgZG9lcyBub3QgYWx3YXlzIGZpcmUuIFxuXHQgKi9cblx0b25Eb2N1bWVudE1vdXNlTW92ZTogZnVuY3Rpb24gKGUpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0Y2hhcnRQb3NpdGlvbiA9IHRoaXMuY2hhcnRQb3NpdGlvbixcblx0XHRcdGhvdmVyU2VyaWVzID0gY2hhcnQuaG92ZXJTZXJpZXM7XG5cblx0XHRlID0gdGhpcy5ub3JtYWxpemUoZSwgY2hhcnRQb3NpdGlvbik7XG5cblx0XHQvLyBJZiB3ZSdyZSBvdXRzaWRlLCBoaWRlIHRoZSB0b29sdGlwXG5cdFx0aWYgKGNoYXJ0UG9zaXRpb24gJiYgaG92ZXJTZXJpZXMgJiYgIXRoaXMuaW5DbGFzcyhlLnRhcmdldCwgJ2hpZ2hjaGFydHMtdHJhY2tlcicpICYmXG5cdFx0XHRcdCFjaGFydC5pc0luc2lkZVBsb3QoZS5jaGFydFggLSBjaGFydC5wbG90TGVmdCwgZS5jaGFydFkgLSBjaGFydC5wbG90VG9wKSkge1xuXHRcdFx0dGhpcy5yZXNldCgpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogV2hlbiBtb3VzZSBsZWF2ZXMgdGhlIGNvbnRhaW5lciwgaGlkZSB0aGUgdG9vbHRpcC5cblx0ICovXG5cdG9uQ29udGFpbmVyTW91c2VMZWF2ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IGNoYXJ0c1tob3ZlckNoYXJ0SW5kZXhdO1xuXHRcdGlmIChjaGFydCkge1xuXHRcdFx0Y2hhcnQucG9pbnRlci5yZXNldCgpO1xuXHRcdFx0Y2hhcnQucG9pbnRlci5jaGFydFBvc2l0aW9uID0gbnVsbDsgLy8gYWxzbyByZXNldCB0aGUgY2hhcnQgcG9zaXRpb24sIHVzZWQgaW4gIzE0OSBmaXhcblx0XHR9XG5cdH0sXG5cblx0Ly8gVGhlIG1vdXNlbW92ZSwgdG91Y2htb3ZlIGFuZCB0b3VjaHN0YXJ0IGV2ZW50IGhhbmRsZXJcblx0b25Db250YWluZXJNb3VzZU1vdmU6IGZ1bmN0aW9uIChlKSB7XG5cblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuXG5cdFx0aG92ZXJDaGFydEluZGV4ID0gY2hhcnQuaW5kZXg7XG5cblx0XHRlID0gdGhpcy5ub3JtYWxpemUoZSk7XHRcdFxuXHRcdGUucmV0dXJuVmFsdWUgPSBmYWxzZTsgLy8gIzIyNTEsICMzMjI0XG5cdFx0XG5cdFx0aWYgKGNoYXJ0Lm1vdXNlSXNEb3duID09PSAnbW91c2Vkb3duJykge1xuXHRcdFx0dGhpcy5kcmFnKGUpO1xuXHRcdH0gXG5cdFx0XG5cdFx0Ly8gU2hvdyB0aGUgdG9vbHRpcCBhbmQgcnVuIG1vdXNlIG92ZXIgZXZlbnRzICgjOTc3KVxuXHRcdGlmICgodGhpcy5pbkNsYXNzKGUudGFyZ2V0LCAnaGlnaGNoYXJ0cy10cmFja2VyJykgfHwgXG5cdFx0XHRcdGNoYXJ0LmlzSW5zaWRlUGxvdChlLmNoYXJ0WCAtIGNoYXJ0LnBsb3RMZWZ0LCBlLmNoYXJ0WSAtIGNoYXJ0LnBsb3RUb3ApKSAmJiAhY2hhcnQub3Blbk1lbnUpIHtcblx0XHRcdHRoaXMucnVuUG9pbnRBY3Rpb25zKGUpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogVXRpbGl0eSB0byBkZXRlY3Qgd2hldGhlciBhbiBlbGVtZW50IGhhcywgb3IgaGFzIGEgcGFyZW50IHdpdGgsIGEgc3BlY2lmaWNcblx0ICogY2xhc3MgbmFtZS4gVXNlZCBvbiBkZXRlY3Rpb24gb2YgdHJhY2tlciBvYmplY3RzIGFuZCBvbiBkZWNpZGluZyB3aGV0aGVyXG5cdCAqIGhvdmVyaW5nIHRoZSB0b29sdGlwIHNob3VsZCBjYXVzZSB0aGUgYWN0aXZlIHNlcmllcyB0byBtb3VzZSBvdXQuXG5cdCAqL1xuXHRpbkNsYXNzOiBmdW5jdGlvbiAoZWxlbWVudCwgY2xhc3NOYW1lKSB7XG5cdFx0dmFyIGVsZW1DbGFzc05hbWU7XG5cdFx0d2hpbGUgKGVsZW1lbnQpIHtcblx0XHRcdGVsZW1DbGFzc05hbWUgPSBhdHRyKGVsZW1lbnQsICdjbGFzcycpO1xuXHRcdFx0aWYgKGVsZW1DbGFzc05hbWUpIHtcblx0XHRcdFx0aWYgKGVsZW1DbGFzc05hbWUuaW5kZXhPZihjbGFzc05hbWUpICE9PSAtMSkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGVsZW1DbGFzc05hbWUuaW5kZXhPZihQUkVGSVggKyAnY29udGFpbmVyJykgIT09IC0xKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHRcdH1cdFx0XG5cdH0sXG5cblx0b25UcmFja2VyTW91c2VPdXQ6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMuY2hhcnQuaG92ZXJTZXJpZXMsXG5cdFx0XHRyZWxhdGVkVGFyZ2V0ID0gZS5yZWxhdGVkVGFyZ2V0IHx8IGUudG9FbGVtZW50LFxuXHRcdFx0cmVsYXRlZFNlcmllcyA9IHJlbGF0ZWRUYXJnZXQgJiYgcmVsYXRlZFRhcmdldC5wb2ludCAmJiByZWxhdGVkVGFyZ2V0LnBvaW50LnNlcmllczsgLy8gIzI0OTlcblx0XHRcblx0XHRpZiAoc2VyaWVzICYmICFzZXJpZXMub3B0aW9ucy5zdGlja3lUcmFja2luZyAmJiAhdGhpcy5pbkNsYXNzKHJlbGF0ZWRUYXJnZXQsIFBSRUZJWCArICd0b29sdGlwJykgJiZcblx0XHRcdFx0cmVsYXRlZFNlcmllcyAhPT0gc2VyaWVzKSB7XG5cdFx0XHRzZXJpZXMub25Nb3VzZU91dCgpO1xuXHRcdH1cblx0fSxcblxuXHRvbkNvbnRhaW5lckNsaWNrOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRob3ZlclBvaW50ID0gY2hhcnQuaG92ZXJQb2ludCwgXG5cdFx0XHRwbG90TGVmdCA9IGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0cGxvdFRvcCA9IGNoYXJ0LnBsb3RUb3A7XG5cdFx0XG5cdFx0ZSA9IHRoaXMubm9ybWFsaXplKGUpO1xuXHRcdGUuY2FuY2VsQnViYmxlID0gdHJ1ZTsgLy8gSUUgc3BlY2lmaWNcblxuXHRcdGlmICghY2hhcnQuY2FuY2VsQ2xpY2spIHtcblx0XHRcdFxuXHRcdFx0Ly8gT24gdHJhY2tlciBjbGljaywgZmlyZSB0aGUgc2VyaWVzIGFuZCBwb2ludCBldmVudHMuICM3ODMsICMxNTgzXG5cdFx0XHRpZiAoaG92ZXJQb2ludCAmJiB0aGlzLmluQ2xhc3MoZS50YXJnZXQsIFBSRUZJWCArICd0cmFja2VyJykpIHtcblxuXHRcdFx0XHQvLyB0aGUgc2VyaWVzIGNsaWNrIGV2ZW50XG5cdFx0XHRcdGZpcmVFdmVudChob3ZlclBvaW50LnNlcmllcywgJ2NsaWNrJywgZXh0ZW5kKGUsIHtcblx0XHRcdFx0XHRwb2ludDogaG92ZXJQb2ludFxuXHRcdFx0XHR9KSk7XG5cblx0XHRcdFx0Ly8gdGhlIHBvaW50IGNsaWNrIGV2ZW50XG5cdFx0XHRcdGlmIChjaGFydC5ob3ZlclBvaW50KSB7IC8vIGl0IG1heSBiZSBkZXN0cm95ZWQgKCMxODQ0KVxuXHRcdFx0XHRcdGhvdmVyUG9pbnQuZmlyZVBvaW50RXZlbnQoJ2NsaWNrJywgZSk7XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gV2hlbiBjbGlja2luZyBvdXRzaWRlIGEgdHJhY2tlciwgZmlyZSBhIGNoYXJ0IGV2ZW50XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRleHRlbmQoZSwgdGhpcy5nZXRDb29yZGluYXRlcyhlKSk7XG5cblx0XHRcdFx0Ly8gZmlyZSBhIGNsaWNrIGV2ZW50IGluIHRoZSBjaGFydFxuXHRcdFx0XHRpZiAoY2hhcnQuaXNJbnNpZGVQbG90KGUuY2hhcnRYIC0gcGxvdExlZnQsIGUuY2hhcnRZIC0gcGxvdFRvcCkpIHtcblx0XHRcdFx0XHRmaXJlRXZlbnQoY2hhcnQsICdjbGljaycsIGUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBKUyBET00gZXZlbnRzIG9uIHRoZSBjb250YWluZXIgYW5kIGRvY3VtZW50LiBUaGlzIG1ldGhvZCBzaG91bGQgY29udGFpblxuXHQgKiBhIG9uZS10by1vbmUgYXNzaWdubWVudCBiZXR3ZWVuIG1ldGhvZHMgYW5kIHRoZWlyIGhhbmRsZXJzLiBBbnkgYWR2YW5jZWQgbG9naWMgc2hvdWxkXG5cdCAqIGJlIG1vdmVkIHRvIHRoZSBoYW5kbGVyIHJlZmxlY3RpbmcgdGhlIGV2ZW50J3MgbmFtZS5cblx0ICovXG5cdHNldERPTUV2ZW50czogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHBvaW50ZXIgPSB0aGlzLFxuXHRcdFx0Y29udGFpbmVyID0gcG9pbnRlci5jaGFydC5jb250YWluZXI7XG5cblx0XHRjb250YWluZXIub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0cG9pbnRlci5vbkNvbnRhaW5lck1vdXNlRG93bihlKTtcblx0XHR9O1xuXHRcdGNvbnRhaW5lci5vbm1vdXNlbW92ZSA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRwb2ludGVyLm9uQ29udGFpbmVyTW91c2VNb3ZlKGUpO1xuXHRcdH07XG5cdFx0Y29udGFpbmVyLm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0cG9pbnRlci5vbkNvbnRhaW5lckNsaWNrKGUpO1xuXHRcdH07XG5cdFx0YWRkRXZlbnQoY29udGFpbmVyLCAnbW91c2VsZWF2ZScsIHBvaW50ZXIub25Db250YWluZXJNb3VzZUxlYXZlKTtcblx0XHRpZiAoY2hhcnRDb3VudCA9PT0gMSkge1xuXHRcdFx0YWRkRXZlbnQoZG9jLCAnbW91c2V1cCcsIHBvaW50ZXIub25Eb2N1bWVudE1vdXNlVXApO1xuXHRcdH1cblx0XHRpZiAoaGFzVG91Y2gpIHtcblx0XHRcdGNvbnRhaW5lci5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRwb2ludGVyLm9uQ29udGFpbmVyVG91Y2hTdGFydChlKTtcblx0XHRcdH07XG5cdFx0XHRjb250YWluZXIub250b3VjaG1vdmUgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRwb2ludGVyLm9uQ29udGFpbmVyVG91Y2hNb3ZlKGUpO1xuXHRcdFx0fTtcblx0XHRcdGlmIChjaGFydENvdW50ID09PSAxKSB7XG5cdFx0XHRcdGFkZEV2ZW50KGRvYywgJ3RvdWNoZW5kJywgcG9pbnRlci5vbkRvY3VtZW50VG91Y2hFbmQpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveXMgdGhlIFBvaW50ZXIgb2JqZWN0IGFuZCBkaXNjb25uZWN0cyBET00gZXZlbnRzLlxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBwcm9wO1xuXG5cdFx0cmVtb3ZlRXZlbnQodGhpcy5jaGFydC5jb250YWluZXIsICdtb3VzZWxlYXZlJywgdGhpcy5vbkNvbnRhaW5lck1vdXNlTGVhdmUpO1xuXHRcdGlmICghY2hhcnRDb3VudCkge1xuXHRcdFx0cmVtb3ZlRXZlbnQoZG9jLCAnbW91c2V1cCcsIHRoaXMub25Eb2N1bWVudE1vdXNlVXApO1xuXHRcdFx0cmVtb3ZlRXZlbnQoZG9jLCAndG91Y2hlbmQnLCB0aGlzLm9uRG9jdW1lbnRUb3VjaEVuZCk7XG5cdFx0fVxuXG5cdFx0Ly8gbWVtb3J5IGFuZCBDUFUgbGVha1xuXHRcdGNsZWFySW50ZXJ2YWwodGhpcy50b29sdGlwVGltZW91dCk7XG5cblx0XHRmb3IgKHByb3AgaW4gdGhpcykge1xuXHRcdFx0dGhpc1twcm9wXSA9IG51bGw7XG5cdFx0fVxuXHR9XG59O1xuXG5cbi8qIFN1cHBvcnQgZm9yIHRvdWNoIGRldmljZXMgKi9cbmV4dGVuZChIaWdoY2hhcnRzLlBvaW50ZXIucHJvdG90eXBlLCB7XG5cblx0LyoqXG5cdCAqIFJ1biB0cmFuc2xhdGlvbiBvcGVyYXRpb25zXG5cdCAqL1xuXHRwaW5jaFRyYW5zbGF0ZTogZnVuY3Rpb24gKHBpbmNoRG93biwgdG91Y2hlcywgdHJhbnNmb3JtLCBzZWxlY3Rpb25NYXJrZXIsIGNsaXAsIGxhc3RWYWxpZFRvdWNoKSB7XG5cdFx0aWYgKHRoaXMuem9vbUhvciB8fCB0aGlzLnBpbmNoSG9yKSB7XG5cdFx0XHR0aGlzLnBpbmNoVHJhbnNsYXRlRGlyZWN0aW9uKHRydWUsIHBpbmNoRG93biwgdG91Y2hlcywgdHJhbnNmb3JtLCBzZWxlY3Rpb25NYXJrZXIsIGNsaXAsIGxhc3RWYWxpZFRvdWNoKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMuem9vbVZlcnQgfHwgdGhpcy5waW5jaFZlcnQpIHtcblx0XHRcdHRoaXMucGluY2hUcmFuc2xhdGVEaXJlY3Rpb24oZmFsc2UsIHBpbmNoRG93biwgdG91Y2hlcywgdHJhbnNmb3JtLCBzZWxlY3Rpb25NYXJrZXIsIGNsaXAsIGxhc3RWYWxpZFRvdWNoKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJ1biB0cmFuc2xhdGlvbiBvcGVyYXRpb25zIGZvciBlYWNoIGRpcmVjdGlvbiAoaG9yaXpvbnRhbCBhbmQgdmVydGljYWwpIGluZGVwZW5kZW50bHlcblx0ICovXG5cdHBpbmNoVHJhbnNsYXRlRGlyZWN0aW9uOiBmdW5jdGlvbiAoaG9yaXosIHBpbmNoRG93biwgdG91Y2hlcywgdHJhbnNmb3JtLCBzZWxlY3Rpb25NYXJrZXIsIGNsaXAsIGxhc3RWYWxpZFRvdWNoLCBmb3JjZWRTY2FsZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHR4eSA9IGhvcml6ID8gJ3gnIDogJ3knLFxuXHRcdFx0WFkgPSBob3JpeiA/ICdYJyA6ICdZJyxcblx0XHRcdHNDaGFydFhZID0gJ2NoYXJ0JyArIFhZLFxuXHRcdFx0d2ggPSBob3JpeiA/ICd3aWR0aCcgOiAnaGVpZ2h0Jyxcblx0XHRcdHBsb3RMZWZ0VG9wID0gY2hhcnRbJ3Bsb3QnICsgKGhvcml6ID8gJ0xlZnQnIDogJ1RvcCcpXSxcblx0XHRcdHNlbGVjdGlvbldILFxuXHRcdFx0c2VsZWN0aW9uWFksXG5cdFx0XHRjbGlwWFksXG5cdFx0XHRzY2FsZSA9IGZvcmNlZFNjYWxlIHx8IDEsXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdFx0Ym91bmRzID0gY2hhcnQuYm91bmRzW2hvcml6ID8gJ2gnIDogJ3YnXSxcblx0XHRcdHNpbmdsZVRvdWNoID0gcGluY2hEb3duLmxlbmd0aCA9PT0gMSxcblx0XHRcdHRvdWNoMFN0YXJ0ID0gcGluY2hEb3duWzBdW3NDaGFydFhZXSxcblx0XHRcdHRvdWNoME5vdyA9IHRvdWNoZXNbMF1bc0NoYXJ0WFldLFxuXHRcdFx0dG91Y2gxU3RhcnQgPSAhc2luZ2xlVG91Y2ggJiYgcGluY2hEb3duWzFdW3NDaGFydFhZXSxcblx0XHRcdHRvdWNoMU5vdyA9ICFzaW5nbGVUb3VjaCAmJiB0b3VjaGVzWzFdW3NDaGFydFhZXSxcblx0XHRcdG91dE9mQm91bmRzLFxuXHRcdFx0dHJhbnNmb3JtU2NhbGUsXG5cdFx0XHRzY2FsZUtleSxcblx0XHRcdHNldFNjYWxlID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoIXNpbmdsZVRvdWNoICYmIG1hdGhBYnModG91Y2gwU3RhcnQgLSB0b3VjaDFTdGFydCkgPiAyMCkgeyAvLyBEb24ndCB6b29tIGlmIGZpbmdlcnMgYXJlIHRvbyBjbG9zZSBvbiB0aGlzIGF4aXNcblx0XHRcdFx0XHRzY2FsZSA9IGZvcmNlZFNjYWxlIHx8IG1hdGhBYnModG91Y2gwTm93IC0gdG91Y2gxTm93KSAvIG1hdGhBYnModG91Y2gwU3RhcnQgLSB0b3VjaDFTdGFydCk7IFxuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRjbGlwWFkgPSAoKHBsb3RMZWZ0VG9wIC0gdG91Y2gwTm93KSAvIHNjYWxlKSArIHRvdWNoMFN0YXJ0O1xuXHRcdFx0XHRzZWxlY3Rpb25XSCA9IGNoYXJ0WydwbG90JyArIChob3JpeiA/ICdXaWR0aCcgOiAnSGVpZ2h0JyldIC8gc2NhbGU7XG5cdFx0XHR9O1xuXG5cdFx0Ly8gU2V0IHRoZSBzY2FsZSwgZmlyc3QgcGFzc1xuXHRcdHNldFNjYWxlKCk7XG5cblx0XHRzZWxlY3Rpb25YWSA9IGNsaXBYWTsgLy8gdGhlIGNsaXAgcG9zaXRpb24gKHggb3IgeSkgaXMgYWx0ZXJlZCBpZiBvdXQgb2YgYm91bmRzLCB0aGUgc2VsZWN0aW9uIHBvc2l0aW9uIGlzIG5vdFxuXG5cdFx0Ly8gT3V0IG9mIGJvdW5kc1xuXHRcdGlmIChzZWxlY3Rpb25YWSA8IGJvdW5kcy5taW4pIHtcblx0XHRcdHNlbGVjdGlvblhZID0gYm91bmRzLm1pbjtcblx0XHRcdG91dE9mQm91bmRzID0gdHJ1ZTtcblx0XHR9IGVsc2UgaWYgKHNlbGVjdGlvblhZICsgc2VsZWN0aW9uV0ggPiBib3VuZHMubWF4KSB7XG5cdFx0XHRzZWxlY3Rpb25YWSA9IGJvdW5kcy5tYXggLSBzZWxlY3Rpb25XSDtcblx0XHRcdG91dE9mQm91bmRzID0gdHJ1ZTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gSXMgdGhlIGNoYXJ0IGRyYWdnZWQgb2ZmIGl0cyBib3VuZHMsIGRldGVybWluZWQgYnkgZGF0YU1pbiBhbmQgZGF0YU1heD9cblx0XHRpZiAob3V0T2ZCb3VuZHMpIHtcblxuXHRcdFx0Ly8gTW9kaWZ5IHRoZSB0b3VjaE5vdyBwb3NpdGlvbiBpbiBvcmRlciB0byBjcmVhdGUgYW4gZWxhc3RpYyBkcmFnIG1vdmVtZW50LiBUaGlzIGluZGljYXRlc1xuXHRcdFx0Ly8gdG8gdGhlIHVzZXIgdGhhdCB0aGUgY2hhcnQgaXMgcmVzcG9uc2l2ZSBidXQgY2FuJ3QgYmUgZHJhZ2dlZCBmdXJ0aGVyLlxuXHRcdFx0dG91Y2gwTm93IC09IDAuOCAqICh0b3VjaDBOb3cgLSBsYXN0VmFsaWRUb3VjaFt4eV1bMF0pO1xuXHRcdFx0aWYgKCFzaW5nbGVUb3VjaCkge1xuXHRcdFx0XHR0b3VjaDFOb3cgLT0gMC44ICogKHRvdWNoMU5vdyAtIGxhc3RWYWxpZFRvdWNoW3h5XVsxXSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgc2NhbGUsIHNlY29uZCBwYXNzIHRvIGFkYXB0IHRvIHRoZSBtb2RpZmllZCB0b3VjaE5vdyBwb3NpdGlvbnNcblx0XHRcdHNldFNjYWxlKCk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0bGFzdFZhbGlkVG91Y2hbeHldID0gW3RvdWNoME5vdywgdG91Y2gxTm93XTtcblx0XHR9XG5cblx0XHQvLyBTZXQgZ2VvbWV0cnkgZm9yIGNsaXBwaW5nLCBzZWxlY3Rpb24gYW5kIHRyYW5zZm9ybWF0aW9uXG5cdFx0aWYgKCFpbnZlcnRlZCkgeyAvLyBUT0RPOiBpbXBsZW1lbnQgY2xpcHBpbmcgZm9yIGludmVydGVkIGNoYXJ0c1xuXHRcdFx0Y2xpcFt4eV0gPSBjbGlwWFkgLSBwbG90TGVmdFRvcDtcblx0XHRcdGNsaXBbd2hdID0gc2VsZWN0aW9uV0g7XG5cdFx0fVxuXHRcdHNjYWxlS2V5ID0gaW52ZXJ0ZWQgPyAoaG9yaXogPyAnc2NhbGVZJyA6ICdzY2FsZVgnKSA6ICdzY2FsZScgKyBYWTtcblx0XHR0cmFuc2Zvcm1TY2FsZSA9IGludmVydGVkID8gMSAvIHNjYWxlIDogc2NhbGU7XG5cblx0XHRzZWxlY3Rpb25NYXJrZXJbd2hdID0gc2VsZWN0aW9uV0g7XG5cdFx0c2VsZWN0aW9uTWFya2VyW3h5XSA9IHNlbGVjdGlvblhZO1xuXHRcdHRyYW5zZm9ybVtzY2FsZUtleV0gPSBzY2FsZTtcblx0XHR0cmFuc2Zvcm1bJ3RyYW5zbGF0ZScgKyBYWV0gPSAodHJhbnNmb3JtU2NhbGUgKiBwbG90TGVmdFRvcCkgKyAodG91Y2gwTm93IC0gKHRyYW5zZm9ybVNjYWxlICogdG91Y2gwU3RhcnQpKTtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBIYW5kbGUgdG91Y2ggZXZlbnRzIHdpdGggdHdvIHRvdWNoZXNcblx0ICovXG5cdHBpbmNoOiBmdW5jdGlvbiAoZSkge1xuXG5cdFx0dmFyIHNlbGYgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZWxmLmNoYXJ0LFxuXHRcdFx0cGluY2hEb3duID0gc2VsZi5waW5jaERvd24sXG5cdFx0XHRmb2xsb3dUb3VjaE1vdmUgPSBzZWxmLmZvbGxvd1RvdWNoTW92ZSxcblx0XHRcdHRvdWNoZXMgPSBlLnRvdWNoZXMsXG5cdFx0XHR0b3VjaGVzTGVuZ3RoID0gdG91Y2hlcy5sZW5ndGgsXG5cdFx0XHRsYXN0VmFsaWRUb3VjaCA9IHNlbGYubGFzdFZhbGlkVG91Y2gsXG5cdFx0XHRoYXNab29tID0gc2VsZi5oYXNab29tLFxuXHRcdFx0c2VsZWN0aW9uTWFya2VyID0gc2VsZi5zZWxlY3Rpb25NYXJrZXIsXG5cdFx0XHR0cmFuc2Zvcm0gPSB7fSxcblx0XHRcdGZpcmVDbGlja0V2ZW50ID0gdG91Y2hlc0xlbmd0aCA9PT0gMSAmJiAoKHNlbGYuaW5DbGFzcyhlLnRhcmdldCwgUFJFRklYICsgJ3RyYWNrZXInKSAmJiBcblx0XHRcdFx0Y2hhcnQucnVuVHJhY2tlckNsaWNrKSB8fCBzZWxmLnJ1bkNoYXJ0Q2xpY2spLFxuXHRcdFx0Y2xpcCA9IHt9O1xuXG5cdFx0Ly8gT24gdG91Y2ggZGV2aWNlcywgb25seSBwcm9jZWVkIHRvIHRyaWdnZXIgY2xpY2sgaWYgYSBoYW5kbGVyIGlzIGRlZmluZWRcblx0XHRpZiAoKGhhc1pvb20gfHwgZm9sbG93VG91Y2hNb3ZlKSAmJiAhZmlyZUNsaWNrRXZlbnQpIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gTm9ybWFsaXplIGVhY2ggdG91Y2hcblx0XHRtYXAodG91Y2hlcywgZnVuY3Rpb24gKGUpIHtcblx0XHRcdHJldHVybiBzZWxmLm5vcm1hbGl6ZShlKTtcblx0XHR9KTtcblx0XHRcblx0XHQvLyBSZWdpc3RlciB0aGUgdG91Y2ggc3RhcnQgcG9zaXRpb25cblx0XHRpZiAoZS50eXBlID09PSAndG91Y2hzdGFydCcpIHtcblx0XHRcdGVhY2godG91Y2hlcywgZnVuY3Rpb24gKGUsIGkpIHtcblx0XHRcdFx0cGluY2hEb3duW2ldID0geyBjaGFydFg6IGUuY2hhcnRYLCBjaGFydFk6IGUuY2hhcnRZIH07XG5cdFx0XHR9KTtcblx0XHRcdGxhc3RWYWxpZFRvdWNoLnggPSBbcGluY2hEb3duWzBdLmNoYXJ0WCwgcGluY2hEb3duWzFdICYmIHBpbmNoRG93blsxXS5jaGFydFhdO1xuXHRcdFx0bGFzdFZhbGlkVG91Y2gueSA9IFtwaW5jaERvd25bMF0uY2hhcnRZLCBwaW5jaERvd25bMV0gJiYgcGluY2hEb3duWzFdLmNoYXJ0WV07XG5cblx0XHRcdC8vIElkZW50aWZ5IHRoZSBkYXRhIGJvdW5kcyBpbiBwaXhlbHNcblx0XHRcdGVhY2goY2hhcnQuYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0aWYgKGF4aXMuem9vbUVuYWJsZWQpIHtcblx0XHRcdFx0XHR2YXIgYm91bmRzID0gY2hhcnQuYm91bmRzW2F4aXMuaG9yaXogPyAnaCcgOiAndiddLFxuXHRcdFx0XHRcdFx0bWluUGl4ZWxQYWRkaW5nID0gYXhpcy5taW5QaXhlbFBhZGRpbmcsXG5cdFx0XHRcdFx0XHRtaW4gPSBheGlzLnRvUGl4ZWxzKHBpY2soYXhpcy5vcHRpb25zLm1pbiwgYXhpcy5kYXRhTWluKSksXG5cdFx0XHRcdFx0XHRtYXggPSBheGlzLnRvUGl4ZWxzKHBpY2soYXhpcy5vcHRpb25zLm1heCwgYXhpcy5kYXRhTWF4KSksXG5cdFx0XHRcdFx0XHRhYnNNaW4gPSBtYXRoTWluKG1pbiwgbWF4KSxcblx0XHRcdFx0XHRcdGFic01heCA9IG1hdGhNYXgobWluLCBtYXgpO1xuXG5cdFx0XHRcdFx0Ly8gU3RvcmUgdGhlIGJvdW5kcyBmb3IgdXNlIGluIHRoZSB0b3VjaG1vdmUgaGFuZGxlclxuXHRcdFx0XHRcdGJvdW5kcy5taW4gPSBtYXRoTWluKGF4aXMucG9zLCBhYnNNaW4gLSBtaW5QaXhlbFBhZGRpbmcpO1xuXHRcdFx0XHRcdGJvdW5kcy5tYXggPSBtYXRoTWF4KGF4aXMucG9zICsgYXhpcy5sZW4sIGFic01heCArIG1pblBpeGVsUGFkZGluZyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0c2VsZi5yZXMgPSB0cnVlOyAvLyByZXNldCBvbiBuZXh0IG1vdmVcblx0XHRcblx0XHQvLyBFdmVudCB0eXBlIGlzIHRvdWNobW92ZSwgaGFuZGxlIHBhbm5pbmcgYW5kIHBpbmNoaW5nXG5cdFx0fSBlbHNlIGlmIChwaW5jaERvd24ubGVuZ3RoKSB7IC8vIGNhbiBiZSAwIHdoZW4gcmVsZWFzaW5nLCBpZiB0b3VjaGVuZCBmaXJlcyBmaXJzdFxuXHRcdFx0XG5cblx0XHRcdC8vIFNldCB0aGUgbWFya2VyXG5cdFx0XHRpZiAoIXNlbGVjdGlvbk1hcmtlcikge1xuXHRcdFx0XHRzZWxmLnNlbGVjdGlvbk1hcmtlciA9IHNlbGVjdGlvbk1hcmtlciA9IGV4dGVuZCh7XG5cdFx0XHRcdFx0ZGVzdHJveTogbm9vcFxuXHRcdFx0XHR9LCBjaGFydC5wbG90Qm94KTtcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0c2VsZi5waW5jaFRyYW5zbGF0ZShwaW5jaERvd24sIHRvdWNoZXMsIHRyYW5zZm9ybSwgc2VsZWN0aW9uTWFya2VyLCBjbGlwLCBsYXN0VmFsaWRUb3VjaCk7XG5cblx0XHRcdHNlbGYuaGFzUGluY2hlZCA9IGhhc1pvb207XG5cblx0XHRcdC8vIFNjYWxlIGFuZCB0cmFuc2xhdGUgdGhlIGdyb3VwcyB0byBwcm92aWRlIHZpc3VhbCBmZWVkYmFjayBkdXJpbmcgcGluY2hpbmdcblx0XHRcdHNlbGYuc2NhbGVHcm91cHModHJhbnNmb3JtLCBjbGlwKTtcblx0XHRcdFxuXHRcdFx0Ly8gT3B0aW9uYWxseSBtb3ZlIHRoZSB0b29sdGlwIG9uIHRvdWNobW92ZVxuXHRcdFx0aWYgKCFoYXNab29tICYmIGZvbGxvd1RvdWNoTW92ZSAmJiB0b3VjaGVzTGVuZ3RoID09PSAxKSB7XG5cdFx0XHRcdHRoaXMucnVuUG9pbnRBY3Rpb25zKHNlbGYubm9ybWFsaXplKGUpKTtcblx0XHRcdH0gZWxzZSBpZiAoc2VsZi5yZXMpIHtcblx0XHRcdFx0c2VsZi5yZXMgPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5yZXNldChmYWxzZSwgMCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdG9uQ29udGFpbmVyVG91Y2hTdGFydDogZnVuY3Rpb24gKGUpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuXG5cdFx0aG92ZXJDaGFydEluZGV4ID0gY2hhcnQuaW5kZXg7XG5cblx0XHRpZiAoZS50b3VjaGVzLmxlbmd0aCA9PT0gMSkge1xuXG5cdFx0XHRlID0gdGhpcy5ub3JtYWxpemUoZSk7XG5cblx0XHRcdGlmIChjaGFydC5pc0luc2lkZVBsb3QoZS5jaGFydFggLSBjaGFydC5wbG90TGVmdCwgZS5jaGFydFkgLSBjaGFydC5wbG90VG9wKSkge1xuXG5cdFx0XHRcdC8vIFJ1biBtb3VzZSBldmVudHMgYW5kIGRpc3BsYXkgdG9vbHRpcCBldGNcblx0XHRcdFx0dGhpcy5ydW5Qb2ludEFjdGlvbnMoZSk7XG5cblx0XHRcdFx0dGhpcy5waW5jaChlKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gSGlkZSB0aGUgdG9vbHRpcCBvbiB0b3VjaGluZyBvdXRzaWRlIHRoZSBwbG90IGFyZWEgKCMxMjAzKVxuXHRcdFx0XHR0aGlzLnJlc2V0KCk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgaWYgKGUudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcblx0XHRcdHRoaXMucGluY2goZSk7XG5cdFx0fSAgIFxuXHR9LFxuXG5cdG9uQ29udGFpbmVyVG91Y2hNb3ZlOiBmdW5jdGlvbiAoZSkge1xuXHRcdGlmIChlLnRvdWNoZXMubGVuZ3RoID09PSAxIHx8IGUudG91Y2hlcy5sZW5ndGggPT09IDIpIHtcblx0XHRcdHRoaXMucGluY2goZSk7XG5cdFx0fVxuXHR9LFxuXG5cdG9uRG9jdW1lbnRUb3VjaEVuZDogZnVuY3Rpb24gKGUpIHtcblx0XHRpZiAoY2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0pIHtcblx0XHRcdGNoYXJ0c1tob3ZlckNoYXJ0SW5kZXhdLnBvaW50ZXIuZHJvcChlKTtcblx0XHR9XG5cdH1cblxufSk7XG5pZiAod2luLlBvaW50ZXJFdmVudCB8fCB3aW4uTVNQb2ludGVyRXZlbnQpIHtcblx0XG5cdC8vIFRoZSB0b3VjaGVzIG9iamVjdCBrZWVwcyB0cmFjayBvZiB0aGUgcG9pbnRzIGJlaW5nIHRvdWNoZWQgYXQgYWxsIHRpbWVzXG5cdHZhciB0b3VjaGVzID0ge30sXG5cdFx0aGFzUG9pbnRlckV2ZW50ID0gISF3aW4uUG9pbnRlckV2ZW50LFxuXHRcdGdldFdlYmtpdFRvdWNoZXMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIga2V5LCBmYWtlID0gW107XG5cdFx0XHRmYWtlLml0ZW0gPSBmdW5jdGlvbiAoaSkgeyByZXR1cm4gdGhpc1tpXTsgfTtcblx0XHRcdGZvciAoa2V5IGluIHRvdWNoZXMpIHtcblx0XHRcdFx0aWYgKHRvdWNoZXMuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHRcdFx0XHRcdGZha2UucHVzaCh7XG5cdFx0XHRcdFx0XHRwYWdlWDogdG91Y2hlc1trZXldLnBhZ2VYLFxuXHRcdFx0XHRcdFx0cGFnZVk6IHRvdWNoZXNba2V5XS5wYWdlWSxcblx0XHRcdFx0XHRcdHRhcmdldDogdG91Y2hlc1trZXldLnRhcmdldFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFrZTtcblx0XHR9LFxuXHRcdHRyYW5zbGF0ZU1TUG9pbnRlciA9IGZ1bmN0aW9uIChlLCBtZXRob2QsIHdrdHlwZSwgY2FsbGJhY2spIHtcblx0XHRcdHZhciBwO1xuXHRcdFx0ZSA9IGUub3JpZ2luYWxFdmVudCB8fCBlO1xuXHRcdFx0aWYgKChlLnBvaW50ZXJUeXBlID09PSAndG91Y2gnIHx8IGUucG9pbnRlclR5cGUgPT09IGUuTVNQT0lOVEVSX1RZUEVfVE9VQ0gpICYmIGNoYXJ0c1tob3ZlckNoYXJ0SW5kZXhdKSB7XG5cdFx0XHRcdGNhbGxiYWNrKGUpO1xuXHRcdFx0XHRwID0gY2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0ucG9pbnRlcjtcblx0XHRcdFx0cFttZXRob2RdKHtcblx0XHRcdFx0XHR0eXBlOiB3a3R5cGUsXG5cdFx0XHRcdFx0dGFyZ2V0OiBlLmN1cnJlbnRUYXJnZXQsXG5cdFx0XHRcdFx0cHJldmVudERlZmF1bHQ6IG5vb3AsXG5cdFx0XHRcdFx0dG91Y2hlczogZ2V0V2Via2l0VG91Y2hlcygpXG5cdFx0XHRcdH0pO1x0XHRcdFx0XG5cdFx0XHR9XG5cdFx0fTtcblxuXHQvKipcblx0ICogRXh0ZW5kIHRoZSBQb2ludGVyIHByb3RvdHlwZSB3aXRoIG1ldGhvZHMgZm9yIGVhY2ggZXZlbnQgaGFuZGxlciBhbmQgbW9yZVxuXHQgKi9cblx0ZXh0ZW5kKFBvaW50ZXIucHJvdG90eXBlLCB7XG5cdFx0b25Db250YWluZXJQb2ludGVyRG93bjogZnVuY3Rpb24gKGUpIHtcblx0XHRcdHRyYW5zbGF0ZU1TUG9pbnRlcihlLCAnb25Db250YWluZXJUb3VjaFN0YXJ0JywgJ3RvdWNoc3RhcnQnLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHR0b3VjaGVzW2UucG9pbnRlcklkXSA9IHsgcGFnZVg6IGUucGFnZVgsIHBhZ2VZOiBlLnBhZ2VZLCB0YXJnZXQ6IGUuY3VycmVudFRhcmdldCB9O1xuXHRcdFx0fSk7XG5cdFx0fSxcblx0XHRvbkNvbnRhaW5lclBvaW50ZXJNb3ZlOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0dHJhbnNsYXRlTVNQb2ludGVyKGUsICdvbkNvbnRhaW5lclRvdWNoTW92ZScsICd0b3VjaG1vdmUnLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHR0b3VjaGVzW2UucG9pbnRlcklkXSA9IHsgcGFnZVg6IGUucGFnZVgsIHBhZ2VZOiBlLnBhZ2VZIH07XG5cdFx0XHRcdGlmICghdG91Y2hlc1tlLnBvaW50ZXJJZF0udGFyZ2V0KSB7XG5cdFx0XHRcdFx0dG91Y2hlc1tlLnBvaW50ZXJJZF0udGFyZ2V0ID0gZS5jdXJyZW50VGFyZ2V0O1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9LFxuXHRcdG9uRG9jdW1lbnRQb2ludGVyVXA6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHR0cmFuc2xhdGVNU1BvaW50ZXIoZSwgJ29uQ29udGFpbmVyVG91Y2hFbmQnLCAndG91Y2hlbmQnLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRkZWxldGUgdG91Y2hlc1tlLnBvaW50ZXJJZF07XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQWRkIG9yIHJlbW92ZSB0aGUgTVMgUG9pbnRlciBzcGVjaWZpYyBldmVudHNcblx0XHQgKi9cblx0XHRiYXRjaE1TRXZlbnRzOiBmdW5jdGlvbiAoZm4pIHtcblx0XHRcdGZuKHRoaXMuY2hhcnQuY29udGFpbmVyLCBoYXNQb2ludGVyRXZlbnQgPyAncG9pbnRlcmRvd24nIDogJ01TUG9pbnRlckRvd24nLCB0aGlzLm9uQ29udGFpbmVyUG9pbnRlckRvd24pO1xuXHRcdFx0Zm4odGhpcy5jaGFydC5jb250YWluZXIsIGhhc1BvaW50ZXJFdmVudCA/ICdwb2ludGVybW92ZScgOiAnTVNQb2ludGVyTW92ZScsIHRoaXMub25Db250YWluZXJQb2ludGVyTW92ZSk7XG5cdFx0XHRmbihkb2MsIGhhc1BvaW50ZXJFdmVudCA/ICdwb2ludGVydXAnIDogJ01TUG9pbnRlclVwJywgdGhpcy5vbkRvY3VtZW50UG9pbnRlclVwKTtcblx0XHR9XG5cdH0pO1xuXG5cdC8vIERpc2FibGUgZGVmYXVsdCBJRSBhY3Rpb25zIGZvciBwaW5jaCBhbmQgc3VjaCBvbiBjaGFydCBlbGVtZW50XG5cdHdyYXAoUG9pbnRlci5wcm90b3R5cGUsICdpbml0JywgZnVuY3Rpb24gKHByb2NlZWQsIGNoYXJ0LCBvcHRpb25zKSB7XG5cdFx0cHJvY2VlZC5jYWxsKHRoaXMsIGNoYXJ0LCBvcHRpb25zKTtcblx0XHRpZiAodGhpcy5oYXNab29tIHx8IHRoaXMuZm9sbG93VG91Y2hNb3ZlKSB7XG5cdFx0XHRjc3MoY2hhcnQuY29udGFpbmVyLCB7XG5cdFx0XHRcdCctbXMtdG91Y2gtYWN0aW9uJzogTk9ORSxcblx0XHRcdFx0J3RvdWNoLWFjdGlvbic6IE5PTkVcblx0XHRcdH0pO1xuXHRcdH1cblx0fSk7XG5cblx0Ly8gQWRkIElFIHNwZWNpZmljIHRvdWNoIGV2ZW50cyB0byBjaGFydFxuXHR3cmFwKFBvaW50ZXIucHJvdG90eXBlLCAnc2V0RE9NRXZlbnRzJywgZnVuY3Rpb24gKHByb2NlZWQpIHtcblx0XHRwcm9jZWVkLmFwcGx5KHRoaXMpO1xuXHRcdGlmICh0aGlzLmhhc1pvb20gfHwgdGhpcy5mb2xsb3dUb3VjaE1vdmUpIHtcblx0XHRcdHRoaXMuYmF0Y2hNU0V2ZW50cyhhZGRFdmVudCk7XG5cdFx0fVxuXHR9KTtcblx0Ly8gRGVzdHJveSBNUyBldmVudHMgYWxzb1xuXHR3cmFwKFBvaW50ZXIucHJvdG90eXBlLCAnZGVzdHJveScsIGZ1bmN0aW9uIChwcm9jZWVkKSB7XG5cdFx0dGhpcy5iYXRjaE1TRXZlbnRzKHJlbW92ZUV2ZW50KTtcblx0XHRwcm9jZWVkLmNhbGwodGhpcyk7XG5cdH0pO1xufVxuLyoqXG4gKiBUaGUgb3ZlcnZpZXcgb2YgdGhlIGNoYXJ0J3Mgc2VyaWVzXG4gKi9cbnZhciBMZWdlbmQgPSBIaWdoY2hhcnRzLkxlZ2VuZCA9IGZ1bmN0aW9uIChjaGFydCwgb3B0aW9ucykge1xuXHR0aGlzLmluaXQoY2hhcnQsIG9wdGlvbnMpO1xufTtcblxuTGVnZW5kLnByb3RvdHlwZSA9IHtcblx0XG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBsZWdlbmRcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uIChjaGFydCwgb3B0aW9ucykge1xuXHRcdFxuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0aXRlbVN0eWxlID0gb3B0aW9ucy5pdGVtU3R5bGUsXG5cdFx0XHRwYWRkaW5nID0gcGljayhvcHRpb25zLnBhZGRpbmcsIDgpLFxuXHRcdFx0aXRlbU1hcmdpblRvcCA9IG9wdGlvbnMuaXRlbU1hcmdpblRvcCB8fCAwO1xuXHRcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG5cdFx0aWYgKCFvcHRpb25zLmVuYWJsZWQpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFxuXHRcdGxlZ2VuZC5pdGVtU3R5bGUgPSBpdGVtU3R5bGU7XG5cdFx0bGVnZW5kLml0ZW1IaWRkZW5TdHlsZSA9IG1lcmdlKGl0ZW1TdHlsZSwgb3B0aW9ucy5pdGVtSGlkZGVuU3R5bGUpO1xuXHRcdGxlZ2VuZC5pdGVtTWFyZ2luVG9wID0gaXRlbU1hcmdpblRvcDtcblx0XHRsZWdlbmQucGFkZGluZyA9IHBhZGRpbmc7XG5cdFx0bGVnZW5kLmluaXRpYWxJdGVtWCA9IHBhZGRpbmc7XG5cdFx0bGVnZW5kLmluaXRpYWxJdGVtWSA9IHBhZGRpbmcgLSA1OyAvLyA1IGlzIHRoZSBudW1iZXIgb2YgcGl4ZWxzIGFib3ZlIHRoZSB0ZXh0XG5cdFx0bGVnZW5kLm1heEl0ZW1XaWR0aCA9IDA7XG5cdFx0bGVnZW5kLmNoYXJ0ID0gY2hhcnQ7XG5cdFx0bGVnZW5kLml0ZW1IZWlnaHQgPSAwO1xuXHRcdGxlZ2VuZC5sYXN0TGluZUhlaWdodCA9IDA7XG5cdFx0bGVnZW5kLnN5bWJvbFdpZHRoID0gcGljayhvcHRpb25zLnN5bWJvbFdpZHRoLCAxNik7XG5cdFx0bGVnZW5kLnBhZ2VzID0gW107XG5cblxuXHRcdC8vIFJlbmRlciBpdFxuXHRcdGxlZ2VuZC5yZW5kZXIoKTtcblxuXHRcdC8vIG1vdmUgY2hlY2tib3hlc1xuXHRcdGFkZEV2ZW50KGxlZ2VuZC5jaGFydCwgJ2VuZFJlc2l6ZScsIGZ1bmN0aW9uICgpIHsgXG5cdFx0XHRsZWdlbmQucG9zaXRpb25DaGVja2JveGVzKCk7XG5cdFx0fSk7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBjb2xvcnMgZm9yIHRoZSBsZWdlbmQgaXRlbVxuXHQgKiBAcGFyYW0ge09iamVjdH0gaXRlbSBBIFNlcmllcyBvciBQb2ludCBpbnN0YW5jZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gdmlzaWJsZSBEaW1tZWQgb3IgY29sb3JlZFxuXHQgKi9cblx0Y29sb3JpemVJdGVtOiBmdW5jdGlvbiAoaXRlbSwgdmlzaWJsZSkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IGxlZ2VuZC5vcHRpb25zLFxuXHRcdFx0bGVnZW5kSXRlbSA9IGl0ZW0ubGVnZW5kSXRlbSxcblx0XHRcdGxlZ2VuZExpbmUgPSBpdGVtLmxlZ2VuZExpbmUsXG5cdFx0XHRsZWdlbmRTeW1ib2wgPSBpdGVtLmxlZ2VuZFN5bWJvbCxcblx0XHRcdGhpZGRlbkNvbG9yID0gbGVnZW5kLml0ZW1IaWRkZW5TdHlsZS5jb2xvcixcblx0XHRcdHRleHRDb2xvciA9IHZpc2libGUgPyBvcHRpb25zLml0ZW1TdHlsZS5jb2xvciA6IGhpZGRlbkNvbG9yLFxuXHRcdFx0c3ltYm9sQ29sb3IgPSB2aXNpYmxlID8gKGl0ZW0ubGVnZW5kQ29sb3IgfHwgaXRlbS5jb2xvciB8fCAnI0NDQycpIDogaGlkZGVuQ29sb3IsXG5cdFx0XHRtYXJrZXJPcHRpb25zID0gaXRlbS5vcHRpb25zICYmIGl0ZW0ub3B0aW9ucy5tYXJrZXIsXG5cdFx0XHRzeW1ib2xBdHRyID0geyBmaWxsOiBzeW1ib2xDb2xvciB9LFxuXHRcdFx0a2V5LFxuXHRcdFx0dmFsO1xuXHRcdFxuXHRcdGlmIChsZWdlbmRJdGVtKSB7XG5cdFx0XHRsZWdlbmRJdGVtLmNzcyh7IGZpbGw6IHRleHRDb2xvciwgY29sb3I6IHRleHRDb2xvciB9KTsgLy8gY29sb3IgZm9yICMxNTUzLCBvbGRJRVxuXHRcdH1cblx0XHRpZiAobGVnZW5kTGluZSkge1xuXHRcdFx0bGVnZW5kTGluZS5hdHRyKHsgc3Ryb2tlOiBzeW1ib2xDb2xvciB9KTtcblx0XHR9XG5cdFx0XG5cdFx0aWYgKGxlZ2VuZFN5bWJvbCkge1xuXHRcdFx0XG5cdFx0XHQvLyBBcHBseSBtYXJrZXIgb3B0aW9uc1xuXHRcdFx0aWYgKG1hcmtlck9wdGlvbnMgJiYgbGVnZW5kU3ltYm9sLmlzTWFya2VyKSB7IC8vICM1ODVcblx0XHRcdFx0c3ltYm9sQXR0ci5zdHJva2UgPSBzeW1ib2xDb2xvcjtcblx0XHRcdFx0bWFya2VyT3B0aW9ucyA9IGl0ZW0uY29udmVydEF0dHJpYnMobWFya2VyT3B0aW9ucyk7XG5cdFx0XHRcdGZvciAoa2V5IGluIG1hcmtlck9wdGlvbnMpIHtcblx0XHRcdFx0XHR2YWwgPSBtYXJrZXJPcHRpb25zW2tleV07XG5cdFx0XHRcdFx0aWYgKHZhbCAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdFx0XHRzeW1ib2xBdHRyW2tleV0gPSB2YWw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGxlZ2VuZFN5bWJvbC5hdHRyKHN5bWJvbEF0dHIpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUG9zaXRpb24gdGhlIGxlZ2VuZCBpdGVtXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIEEgU2VyaWVzIG9yIFBvaW50IGluc3RhbmNlXG5cdCAqL1xuXHRwb3NpdGlvbkl0ZW06IGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gbGVnZW5kLm9wdGlvbnMsXG5cdFx0XHRzeW1ib2xQYWRkaW5nID0gb3B0aW9ucy5zeW1ib2xQYWRkaW5nLFxuXHRcdFx0bHRyID0gIW9wdGlvbnMucnRsLFxuXHRcdFx0bGVnZW5kSXRlbVBvcyA9IGl0ZW0uX2xlZ2VuZEl0ZW1Qb3MsXG5cdFx0XHRpdGVtWCA9IGxlZ2VuZEl0ZW1Qb3NbMF0sXG5cdFx0XHRpdGVtWSA9IGxlZ2VuZEl0ZW1Qb3NbMV0sXG5cdFx0XHRjaGVja2JveCA9IGl0ZW0uY2hlY2tib3g7XG5cblx0XHRpZiAoaXRlbS5sZWdlbmRHcm91cCkge1xuXHRcdFx0aXRlbS5sZWdlbmRHcm91cC50cmFuc2xhdGUoXG5cdFx0XHRcdGx0ciA/IGl0ZW1YIDogbGVnZW5kLmxlZ2VuZFdpZHRoIC0gaXRlbVggLSAyICogc3ltYm9sUGFkZGluZyAtIDQsXG5cdFx0XHRcdGl0ZW1ZXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdGlmIChjaGVja2JveCkge1xuXHRcdFx0Y2hlY2tib3gueCA9IGl0ZW1YO1xuXHRcdFx0Y2hlY2tib3gueSA9IGl0ZW1ZO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveSBhIHNpbmdsZSBsZWdlbmQgaXRlbVxuXHQgKiBAcGFyYW0ge09iamVjdH0gaXRlbSBUaGUgc2VyaWVzIG9yIHBvaW50XG5cdCAqL1xuXHRkZXN0cm95SXRlbTogZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHR2YXIgY2hlY2tib3ggPSBpdGVtLmNoZWNrYm94O1xuXG5cdFx0Ly8gZGVzdHJveSBTVkcgZWxlbWVudHNcblx0XHRlYWNoKFsnbGVnZW5kSXRlbScsICdsZWdlbmRMaW5lJywgJ2xlZ2VuZFN5bWJvbCcsICdsZWdlbmRHcm91cCddLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoaXRlbVtrZXldKSB7XG5cdFx0XHRcdGl0ZW1ba2V5XSA9IGl0ZW1ba2V5XS5kZXN0cm95KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRpZiAoY2hlY2tib3gpIHtcblx0XHRcdGRpc2NhcmRFbGVtZW50KGl0ZW0uY2hlY2tib3gpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveXMgdGhlIGxlZ2VuZC5cblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbGVnZW5kID0gdGhpcyxcblx0XHRcdGxlZ2VuZEdyb3VwID0gbGVnZW5kLmdyb3VwLFxuXHRcdFx0Ym94ID0gbGVnZW5kLmJveDtcblxuXHRcdGlmIChib3gpIHtcblx0XHRcdGxlZ2VuZC5ib3ggPSBib3guZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdGlmIChsZWdlbmRHcm91cCkge1xuXHRcdFx0bGVnZW5kLmdyb3VwID0gbGVnZW5kR3JvdXAuZGVzdHJveSgpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUG9zaXRpb24gdGhlIGNoZWNrYm94ZXMgYWZ0ZXIgdGhlIHdpZHRoIGlzIGRldGVybWluZWRcblx0ICovXG5cdHBvc2l0aW9uQ2hlY2tib3hlczogZnVuY3Rpb24gKHNjcm9sbE9mZnNldCkge1xuXHRcdHZhciBhbGlnbkF0dHIgPSB0aGlzLmdyb3VwLmFsaWduQXR0cixcblx0XHRcdHRyYW5zbGF0ZVksXG5cdFx0XHRjbGlwSGVpZ2h0ID0gdGhpcy5jbGlwSGVpZ2h0IHx8IHRoaXMubGVnZW5kSGVpZ2h0O1xuXG5cdFx0aWYgKGFsaWduQXR0cikge1xuXHRcdFx0dHJhbnNsYXRlWSA9IGFsaWduQXR0ci50cmFuc2xhdGVZO1xuXHRcdFx0ZWFjaCh0aGlzLmFsbEl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdFx0XHR2YXIgY2hlY2tib3ggPSBpdGVtLmNoZWNrYm94LFxuXHRcdFx0XHRcdHRvcDtcblx0XHRcdFx0XG5cdFx0XHRcdGlmIChjaGVja2JveCkge1xuXHRcdFx0XHRcdHRvcCA9ICh0cmFuc2xhdGVZICsgY2hlY2tib3gueSArIChzY3JvbGxPZmZzZXQgfHwgMCkgKyAzKTtcblx0XHRcdFx0XHRjc3MoY2hlY2tib3gsIHtcblx0XHRcdFx0XHRcdGxlZnQ6IChhbGlnbkF0dHIudHJhbnNsYXRlWCArIGl0ZW0uY2hlY2tib3hPZmZzZXQgKyBjaGVja2JveC54IC0gMjApICsgUFgsXG5cdFx0XHRcdFx0XHR0b3A6IHRvcCArIFBYLFxuXHRcdFx0XHRcdFx0ZGlzcGxheTogdG9wID4gdHJhbnNsYXRlWSAtIDYgJiYgdG9wIDwgdHJhbnNsYXRlWSArIGNsaXBIZWlnaHQgLSA2ID8gJycgOiBOT05FXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblx0XG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIGxlZ2VuZCB0aXRsZSBvbiB0b3Agb2YgdGhlIGxlZ2VuZFxuXHQgKi9cblx0cmVuZGVyVGl0bGU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdHBhZGRpbmcgPSB0aGlzLnBhZGRpbmcsXG5cdFx0XHR0aXRsZU9wdGlvbnMgPSBvcHRpb25zLnRpdGxlLFxuXHRcdFx0dGl0bGVIZWlnaHQgPSAwLFxuXHRcdFx0YkJveDtcblx0XHRcblx0XHRpZiAodGl0bGVPcHRpb25zLnRleHQpIHtcblx0XHRcdGlmICghdGhpcy50aXRsZSkge1xuXHRcdFx0XHR0aGlzLnRpdGxlID0gdGhpcy5jaGFydC5yZW5kZXJlci5sYWJlbCh0aXRsZU9wdGlvbnMudGV4dCwgcGFkZGluZyAtIDMsIHBhZGRpbmcgLSA0LCBudWxsLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCAnbGVnZW5kLXRpdGxlJylcblx0XHRcdFx0XHQuYXR0cih7IHpJbmRleDogMSB9KVxuXHRcdFx0XHRcdC5jc3ModGl0bGVPcHRpb25zLnN0eWxlKVxuXHRcdFx0XHRcdC5hZGQodGhpcy5ncm91cCk7XG5cdFx0XHR9XG5cdFx0XHRiQm94ID0gdGhpcy50aXRsZS5nZXRCQm94KCk7XG5cdFx0XHR0aXRsZUhlaWdodCA9IGJCb3guaGVpZ2h0O1xuXHRcdFx0dGhpcy5vZmZzZXRXaWR0aCA9IGJCb3gud2lkdGg7IC8vICMxNzE3XG5cdFx0XHR0aGlzLmNvbnRlbnRHcm91cC5hdHRyKHsgdHJhbnNsYXRlWTogdGl0bGVIZWlnaHQgfSk7XG5cdFx0fVxuXHRcdHRoaXMudGl0bGVIZWlnaHQgPSB0aXRsZUhlaWdodDtcblx0fSxcblxuXHQvKipcblx0ICogUmVuZGVyIGEgc2luZ2xlIHNwZWNpZmljIGxlZ2VuZCBpdGVtXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIEEgc2VyaWVzIG9yIHBvaW50XG5cdCAqL1xuXHRyZW5kZXJJdGVtOiBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBsZWdlbmQuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0b3B0aW9ucyA9IGxlZ2VuZC5vcHRpb25zLFxuXHRcdFx0aG9yaXpvbnRhbCA9IG9wdGlvbnMubGF5b3V0ID09PSAnaG9yaXpvbnRhbCcsXG5cdFx0XHRzeW1ib2xXaWR0aCA9IGxlZ2VuZC5zeW1ib2xXaWR0aCxcblx0XHRcdHN5bWJvbFBhZGRpbmcgPSBvcHRpb25zLnN5bWJvbFBhZGRpbmcsXG5cdFx0XHRpdGVtU3R5bGUgPSBsZWdlbmQuaXRlbVN0eWxlLFxuXHRcdFx0aXRlbUhpZGRlblN0eWxlID0gbGVnZW5kLml0ZW1IaWRkZW5TdHlsZSxcblx0XHRcdHBhZGRpbmcgPSBsZWdlbmQucGFkZGluZyxcblx0XHRcdGl0ZW1EaXN0YW5jZSA9IGhvcml6b250YWwgPyBwaWNrKG9wdGlvbnMuaXRlbURpc3RhbmNlLCAyMCkgOiAwLFxuXHRcdFx0bHRyID0gIW9wdGlvbnMucnRsLFxuXHRcdFx0aXRlbUhlaWdodCxcblx0XHRcdHdpZHRoT3B0aW9uID0gb3B0aW9ucy53aWR0aCxcblx0XHRcdGl0ZW1NYXJnaW5Cb3R0b20gPSBvcHRpb25zLml0ZW1NYXJnaW5Cb3R0b20gfHwgMCxcblx0XHRcdGl0ZW1NYXJnaW5Ub3AgPSBsZWdlbmQuaXRlbU1hcmdpblRvcCxcblx0XHRcdGluaXRpYWxJdGVtWCA9IGxlZ2VuZC5pbml0aWFsSXRlbVgsXG5cdFx0XHRiQm94LFxuXHRcdFx0aXRlbVdpZHRoLFxuXHRcdFx0bGkgPSBpdGVtLmxlZ2VuZEl0ZW0sXG5cdFx0XHRzZXJpZXMgPSBpdGVtLnNlcmllcyAmJiBpdGVtLnNlcmllcy5kcmF3TGVnZW5kU3ltYm9sID8gaXRlbS5zZXJpZXMgOiBpdGVtLFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0c2hvd0NoZWNrYm94ID0gbGVnZW5kLmNyZWF0ZUNoZWNrYm94Rm9ySXRlbSAmJiBzZXJpZXNPcHRpb25zICYmIHNlcmllc09wdGlvbnMuc2hvd0NoZWNrYm94LFxuXHRcdFx0dXNlSFRNTCA9IG9wdGlvbnMudXNlSFRNTDtcblxuXHRcdGlmICghbGkpIHsgLy8gZ2VuZXJhdGUgaXQgb25jZSwgbGF0ZXIgbW92ZSBpdFxuXG5cdFx0XHQvLyBHZW5lcmF0ZSB0aGUgZ3JvdXAgYm94XG5cdFx0XHQvLyBBIGdyb3VwIHRvIGhvbGQgdGhlIHN5bWJvbCBhbmQgdGV4dC4gVGV4dCBpcyB0byBiZSBhcHBlbmRlZCBpbiBMZWdlbmQgY2xhc3MuXG5cdFx0XHRpdGVtLmxlZ2VuZEdyb3VwID0gcmVuZGVyZXIuZygnbGVnZW5kLWl0ZW0nKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogMSB9KVxuXHRcdFx0XHQuYWRkKGxlZ2VuZC5zY3JvbGxHcm91cCk7XG5cblx0XHRcdC8vIEdlbmVyYXRlIHRoZSBsaXN0IGl0ZW0gdGV4dCBhbmQgYWRkIGl0IHRvIHRoZSBncm91cFxuXHRcdFx0aXRlbS5sZWdlbmRJdGVtID0gbGkgPSByZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRcdG9wdGlvbnMubGFiZWxGb3JtYXQgPyBmb3JtYXQob3B0aW9ucy5sYWJlbEZvcm1hdCwgaXRlbSkgOiBvcHRpb25zLmxhYmVsRm9ybWF0dGVyLmNhbGwoaXRlbSksXG5cdFx0XHRcdFx0bHRyID8gc3ltYm9sV2lkdGggKyBzeW1ib2xQYWRkaW5nIDogLXN5bWJvbFBhZGRpbmcsXG5cdFx0XHRcdFx0bGVnZW5kLmJhc2VsaW5lIHx8IDAsXG5cdFx0XHRcdFx0dXNlSFRNTFxuXHRcdFx0XHQpXG5cdFx0XHRcdC5jc3MobWVyZ2UoaXRlbS52aXNpYmxlID8gaXRlbVN0eWxlIDogaXRlbUhpZGRlblN0eWxlKSkgLy8gbWVyZ2UgdG8gcHJldmVudCBtb2RpZnlpbmcgb3JpZ2luYWwgKCMxMDIxKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0YWxpZ246IGx0ciA/ICdsZWZ0JyA6ICdyaWdodCcsXG5cdFx0XHRcdFx0ekluZGV4OiAyXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQoaXRlbS5sZWdlbmRHcm91cCk7XG5cblx0XHRcdC8vIEdldCB0aGUgYmFzZWxpbmUgZm9yIHRoZSBmaXJzdCBpdGVtIC0gdGhlIGZvbnQgc2l6ZSBpcyBlcXVhbCBmb3IgYWxsXG5cdFx0XHRpZiAoIWxlZ2VuZC5iYXNlbGluZSkge1xuXHRcdFx0XHRsZWdlbmQuYmFzZWxpbmUgPSByZW5kZXJlci5mb250TWV0cmljcyhpdGVtU3R5bGUuZm9udFNpemUsIGxpKS5mICsgMyArIGl0ZW1NYXJnaW5Ub3A7XG5cdFx0XHRcdGxpLmF0dHIoJ3knLCBsZWdlbmQuYmFzZWxpbmUpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEcmF3IHRoZSBsZWdlbmQgc3ltYm9sIGluc2lkZSB0aGUgZ3JvdXAgYm94XG5cdFx0XHRzZXJpZXMuZHJhd0xlZ2VuZFN5bWJvbChsZWdlbmQsIGl0ZW0pO1xuXG5cdFx0XHRpZiAobGVnZW5kLnNldEl0ZW1FdmVudHMpIHtcblx0XHRcdFx0bGVnZW5kLnNldEl0ZW1FdmVudHMoaXRlbSwgbGksIHVzZUhUTUwsIGl0ZW1TdHlsZSwgaXRlbUhpZGRlblN0eWxlKTtcblx0XHRcdH1cdFx0XHRcblxuXHRcdFx0Ly8gQ29sb3JpemUgdGhlIGl0ZW1zXG5cdFx0XHRsZWdlbmQuY29sb3JpemVJdGVtKGl0ZW0sIGl0ZW0udmlzaWJsZSk7XG5cblx0XHRcdC8vIGFkZCB0aGUgSFRNTCBjaGVja2JveCBvbiB0b3Bcblx0XHRcdGlmIChzaG93Q2hlY2tib3gpIHtcblx0XHRcdFx0bGVnZW5kLmNyZWF0ZUNoZWNrYm94Rm9ySXRlbShpdGVtKTtcdFx0XHRcdFxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGNhbGN1bGF0ZSB0aGUgcG9zaXRpb25zIGZvciB0aGUgbmV4dCBsaW5lXG5cdFx0YkJveCA9IGxpLmdldEJCb3goKTtcblxuXHRcdGl0ZW1XaWR0aCA9IGl0ZW0uY2hlY2tib3hPZmZzZXQgPSBcblx0XHRcdG9wdGlvbnMuaXRlbVdpZHRoIHx8IFxuXHRcdFx0aXRlbS5sZWdlbmRJdGVtV2lkdGggfHwgXG5cdFx0XHRzeW1ib2xXaWR0aCArIHN5bWJvbFBhZGRpbmcgKyBiQm94LndpZHRoICsgaXRlbURpc3RhbmNlICsgKHNob3dDaGVja2JveCA/IDIwIDogMCk7XG5cdFx0bGVnZW5kLml0ZW1IZWlnaHQgPSBpdGVtSGVpZ2h0ID0gbWF0aFJvdW5kKGl0ZW0ubGVnZW5kSXRlbUhlaWdodCB8fCBiQm94LmhlaWdodCk7XG5cblx0XHQvLyBpZiB0aGUgaXRlbSBleGNlZWRzIHRoZSB3aWR0aCwgc3RhcnQgYSBuZXcgbGluZVxuXHRcdGlmIChob3Jpem9udGFsICYmIGxlZ2VuZC5pdGVtWCAtIGluaXRpYWxJdGVtWCArIGl0ZW1XaWR0aCA+XG5cdFx0XHRcdCh3aWR0aE9wdGlvbiB8fCAoY2hhcnQuY2hhcnRXaWR0aCAtIDIgKiBwYWRkaW5nIC0gaW5pdGlhbEl0ZW1YIC0gb3B0aW9ucy54KSkpIHtcblx0XHRcdGxlZ2VuZC5pdGVtWCA9IGluaXRpYWxJdGVtWDtcblx0XHRcdGxlZ2VuZC5pdGVtWSArPSBpdGVtTWFyZ2luVG9wICsgbGVnZW5kLmxhc3RMaW5lSGVpZ2h0ICsgaXRlbU1hcmdpbkJvdHRvbTtcblx0XHRcdGxlZ2VuZC5sYXN0TGluZUhlaWdodCA9IDA7IC8vIHJlc2V0IGZvciBuZXh0IGxpbmVcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgaXRlbSBleGNlZWRzIHRoZSBoZWlnaHQsIHN0YXJ0IGEgbmV3IGNvbHVtblxuXHRcdC8qaWYgKCFob3Jpem9udGFsICYmIGxlZ2VuZC5pdGVtWSArIG9wdGlvbnMueSArIGl0ZW1IZWlnaHQgPiBjaGFydC5jaGFydEhlaWdodCAtIHNwYWNpbmdUb3AgLSBzcGFjaW5nQm90dG9tKSB7XG5cdFx0XHRsZWdlbmQuaXRlbVkgPSBsZWdlbmQuaW5pdGlhbEl0ZW1ZO1xuXHRcdFx0bGVnZW5kLml0ZW1YICs9IGxlZ2VuZC5tYXhJdGVtV2lkdGg7XG5cdFx0XHRsZWdlbmQubWF4SXRlbVdpZHRoID0gMDtcblx0XHR9Ki9cblxuXHRcdC8vIFNldCB0aGUgZWRnZSBwb3NpdGlvbnNcblx0XHRsZWdlbmQubWF4SXRlbVdpZHRoID0gbWF0aE1heChsZWdlbmQubWF4SXRlbVdpZHRoLCBpdGVtV2lkdGgpO1xuXHRcdGxlZ2VuZC5sYXN0SXRlbVkgPSBpdGVtTWFyZ2luVG9wICsgbGVnZW5kLml0ZW1ZICsgaXRlbU1hcmdpbkJvdHRvbTtcblx0XHRsZWdlbmQubGFzdExpbmVIZWlnaHQgPSBtYXRoTWF4KGl0ZW1IZWlnaHQsIGxlZ2VuZC5sYXN0TGluZUhlaWdodCk7IC8vICM5MTVcblxuXHRcdC8vIGNhY2hlIHRoZSBwb3NpdGlvbiBvZiB0aGUgbmV3bHkgZ2VuZXJhdGVkIG9yIHJlb3JkZXJlZCBpdGVtc1xuXHRcdGl0ZW0uX2xlZ2VuZEl0ZW1Qb3MgPSBbbGVnZW5kLml0ZW1YLCBsZWdlbmQuaXRlbVldO1xuXG5cdFx0Ly8gYWR2YW5jZVxuXHRcdGlmIChob3Jpem9udGFsKSB7XG5cdFx0XHRsZWdlbmQuaXRlbVggKz0gaXRlbVdpZHRoO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGxlZ2VuZC5pdGVtWSArPSBpdGVtTWFyZ2luVG9wICsgaXRlbUhlaWdodCArIGl0ZW1NYXJnaW5Cb3R0b207XG5cdFx0XHRsZWdlbmQubGFzdExpbmVIZWlnaHQgPSBpdGVtSGVpZ2h0O1xuXHRcdH1cblxuXHRcdC8vIHRoZSB3aWR0aCBvZiB0aGUgd2lkZXN0IGl0ZW1cblx0XHRsZWdlbmQub2Zmc2V0V2lkdGggPSB3aWR0aE9wdGlvbiB8fCBtYXRoTWF4KFxuXHRcdFx0KGhvcml6b250YWwgPyBsZWdlbmQuaXRlbVggLSBpbml0aWFsSXRlbVggLSBpdGVtRGlzdGFuY2UgOiBpdGVtV2lkdGgpICsgcGFkZGluZyxcblx0XHRcdGxlZ2VuZC5vZmZzZXRXaWR0aFxuXHRcdCk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCBhbGwgaXRlbXMsIHdoaWNoIGlzIG9uZSBpdGVtIHBlciBzZXJpZXMgZm9yIG5vcm1hbCBzZXJpZXMgYW5kIG9uZSBpdGVtIHBlciBwb2ludFxuXHQgKiBmb3IgcGllIHNlcmllcy5cblx0ICovXG5cdGdldEFsbEl0ZW1zOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGFsbEl0ZW1zID0gW107XG5cdFx0ZWFjaCh0aGlzLmNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0dmFyIHNlcmllc09wdGlvbnMgPSBzZXJpZXMub3B0aW9ucztcblxuXHRcdFx0Ly8gSGFuZGxlIHNob3dJbkxlZ2VuZC4gSWYgdGhlIHNlcmllcyBpcyBsaW5rZWQgdG8gYW5vdGhlciBzZXJpZXMsIGRlZmF1bHRzIHRvIGZhbHNlLlxuXHRcdFx0aWYgKCFwaWNrKHNlcmllc09wdGlvbnMuc2hvd0luTGVnZW5kLCAhZGVmaW5lZChzZXJpZXNPcHRpb25zLmxpbmtlZFRvKSA/IFVOREVGSU5FRCA6IGZhbHNlLCB0cnVlKSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIHVzZSBwb2ludHMgb3Igc2VyaWVzIGZvciB0aGUgbGVnZW5kIGl0ZW0gZGVwZW5kaW5nIG9uIGxlZ2VuZFR5cGVcblx0XHRcdGFsbEl0ZW1zID0gYWxsSXRlbXMuY29uY2F0KFxuXHRcdFx0XHRcdHNlcmllcy5sZWdlbmRJdGVtcyB8fFxuXHRcdFx0XHRcdChzZXJpZXNPcHRpb25zLmxlZ2VuZFR5cGUgPT09ICdwb2ludCcgP1xuXHRcdFx0XHRcdFx0XHRzZXJpZXMuZGF0YSA6XG5cdFx0XHRcdFx0XHRcdHNlcmllcylcblx0XHRcdCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGFsbEl0ZW1zO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIGxlZ2VuZC4gVGhpcyBtZXRob2QgY2FuIGJlIGNhbGxlZCBib3RoIGJlZm9yZSBhbmQgYWZ0ZXJcblx0ICogY2hhcnQucmVuZGVyLiBJZiBjYWxsZWQgYWZ0ZXIsIGl0IHdpbGwgb25seSByZWFycmFuZ2UgaXRlbXMgaW5zdGVhZFxuXHQgKiBvZiBjcmVhdGluZyBuZXcgb25lcy5cblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBsZWdlbmQuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0bGVnZW5kR3JvdXAgPSBsZWdlbmQuZ3JvdXAsXG5cdFx0XHRhbGxJdGVtcyxcblx0XHRcdGRpc3BsYXksXG5cdFx0XHRsZWdlbmRXaWR0aCxcblx0XHRcdGxlZ2VuZEhlaWdodCxcblx0XHRcdGJveCA9IGxlZ2VuZC5ib3gsXG5cdFx0XHRvcHRpb25zID0gbGVnZW5kLm9wdGlvbnMsXG5cdFx0XHRwYWRkaW5nID0gbGVnZW5kLnBhZGRpbmcsXG5cdFx0XHRsZWdlbmRCb3JkZXJXaWR0aCA9IG9wdGlvbnMuYm9yZGVyV2lkdGgsXG5cdFx0XHRsZWdlbmRCYWNrZ3JvdW5kQ29sb3IgPSBvcHRpb25zLmJhY2tncm91bmRDb2xvcjtcblxuXHRcdGxlZ2VuZC5pdGVtWCA9IGxlZ2VuZC5pbml0aWFsSXRlbVg7XG5cdFx0bGVnZW5kLml0ZW1ZID0gbGVnZW5kLmluaXRpYWxJdGVtWTtcblx0XHRsZWdlbmQub2Zmc2V0V2lkdGggPSAwO1xuXHRcdGxlZ2VuZC5sYXN0SXRlbVkgPSAwO1xuXG5cdFx0aWYgKCFsZWdlbmRHcm91cCkge1xuXHRcdFx0bGVnZW5kLmdyb3VwID0gbGVnZW5kR3JvdXAgPSByZW5kZXJlci5nKCdsZWdlbmQnKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogNyB9KSBcblx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0bGVnZW5kLmNvbnRlbnRHcm91cCA9IHJlbmRlcmVyLmcoKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogMSB9KSAvLyBhYm92ZSBiYWNrZ3JvdW5kXG5cdFx0XHRcdC5hZGQobGVnZW5kR3JvdXApO1xuXHRcdFx0bGVnZW5kLnNjcm9sbEdyb3VwID0gcmVuZGVyZXIuZygpXG5cdFx0XHRcdC5hZGQobGVnZW5kLmNvbnRlbnRHcm91cCk7XG5cdFx0fVxuXHRcdFxuXHRcdGxlZ2VuZC5yZW5kZXJUaXRsZSgpO1xuXG5cdFx0Ly8gYWRkIGVhY2ggc2VyaWVzIG9yIHBvaW50XG5cdFx0YWxsSXRlbXMgPSBsZWdlbmQuZ2V0QWxsSXRlbXMoKTtcblxuXHRcdC8vIHNvcnQgYnkgbGVnZW5kSW5kZXhcblx0XHRzdGFibGVTb3J0KGFsbEl0ZW1zLCBmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0cmV0dXJuICgoYS5vcHRpb25zICYmIGEub3B0aW9ucy5sZWdlbmRJbmRleCkgfHwgMCkgLSAoKGIub3B0aW9ucyAmJiBiLm9wdGlvbnMubGVnZW5kSW5kZXgpIHx8IDApO1xuXHRcdH0pO1xuXG5cdFx0Ly8gcmV2ZXJzZWQgbGVnZW5kXG5cdFx0aWYgKG9wdGlvbnMucmV2ZXJzZWQpIHtcblx0XHRcdGFsbEl0ZW1zLnJldmVyc2UoKTtcblx0XHR9XG5cblx0XHRsZWdlbmQuYWxsSXRlbXMgPSBhbGxJdGVtcztcblx0XHRsZWdlbmQuZGlzcGxheSA9IGRpc3BsYXkgPSAhIWFsbEl0ZW1zLmxlbmd0aDtcblxuXHRcdC8vIHJlbmRlciB0aGUgaXRlbXNcblx0XHRlYWNoKGFsbEl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdFx0bGVnZW5kLnJlbmRlckl0ZW0oaXRlbSk7IFxuXHRcdH0pO1xuXG5cdFx0Ly8gRHJhdyB0aGUgYm9yZGVyXG5cdFx0bGVnZW5kV2lkdGggPSBvcHRpb25zLndpZHRoIHx8IGxlZ2VuZC5vZmZzZXRXaWR0aDtcblx0XHRsZWdlbmRIZWlnaHQgPSBsZWdlbmQubGFzdEl0ZW1ZICsgbGVnZW5kLmxhc3RMaW5lSGVpZ2h0ICsgbGVnZW5kLnRpdGxlSGVpZ2h0O1xuXHRcdFxuXHRcdFxuXHRcdGxlZ2VuZEhlaWdodCA9IGxlZ2VuZC5oYW5kbGVPdmVyZmxvdyhsZWdlbmRIZWlnaHQpO1xuXG5cdFx0aWYgKGxlZ2VuZEJvcmRlcldpZHRoIHx8IGxlZ2VuZEJhY2tncm91bmRDb2xvcikge1xuXHRcdFx0bGVnZW5kV2lkdGggKz0gcGFkZGluZztcblx0XHRcdGxlZ2VuZEhlaWdodCArPSBwYWRkaW5nO1xuXG5cdFx0XHRpZiAoIWJveCkge1xuXHRcdFx0XHRsZWdlbmQuYm94ID0gYm94ID0gcmVuZGVyZXIucmVjdChcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0bGVnZW5kV2lkdGgsXG5cdFx0XHRcdFx0bGVnZW5kSGVpZ2h0LFxuXHRcdFx0XHRcdG9wdGlvbnMuYm9yZGVyUmFkaXVzLFxuXHRcdFx0XHRcdGxlZ2VuZEJvcmRlcldpZHRoIHx8IDBcblx0XHRcdFx0KS5hdHRyKHtcblx0XHRcdFx0XHRzdHJva2U6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IGxlZ2VuZEJvcmRlcldpZHRoIHx8IDAsXG5cdFx0XHRcdFx0ZmlsbDogbGVnZW5kQmFja2dyb3VuZENvbG9yIHx8IE5PTkVcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZChsZWdlbmRHcm91cClcblx0XHRcdFx0LnNoYWRvdyhvcHRpb25zLnNoYWRvdyk7XG5cdFx0XHRcdGJveC5pc05ldyA9IHRydWU7XG5cblx0XHRcdH0gZWxzZSBpZiAobGVnZW5kV2lkdGggPiAwICYmIGxlZ2VuZEhlaWdodCA+IDApIHtcblx0XHRcdFx0Ym94W2JveC5pc05ldyA/ICdhdHRyJyA6ICdhbmltYXRlJ10oXG5cdFx0XHRcdFx0Ym94LmNyaXNwKHsgd2lkdGg6IGxlZ2VuZFdpZHRoLCBoZWlnaHQ6IGxlZ2VuZEhlaWdodCB9KVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRib3guaXNOZXcgPSBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gaGlkZSB0aGUgYm9yZGVyIGlmIG5vIGl0ZW1zXG5cdFx0XHRib3hbZGlzcGxheSA/ICdzaG93JyA6ICdoaWRlJ10oKTtcblx0XHR9XG5cdFx0XG5cdFx0bGVnZW5kLmxlZ2VuZFdpZHRoID0gbGVnZW5kV2lkdGg7XG5cdFx0bGVnZW5kLmxlZ2VuZEhlaWdodCA9IGxlZ2VuZEhlaWdodDtcblxuXHRcdC8vIE5vdyB0aGF0IHRoZSBsZWdlbmQgd2lkdGggYW5kIGhlaWdodCBhcmUgZXN0YWJsaXNoZWQsIHB1dCB0aGUgaXRlbXMgaW4gdGhlIFxuXHRcdC8vIGZpbmFsIHBvc2l0aW9uXG5cdFx0ZWFjaChhbGxJdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHRcdGxlZ2VuZC5wb3NpdGlvbkl0ZW0oaXRlbSk7XG5cdFx0fSk7XG5cblx0XHQvLyAxLnggY29tcGF0aWJpbGl0eTogcG9zaXRpb25pbmcgYmFzZWQgb24gc3R5bGVcblx0XHQvKnZhciBwcm9wcyA9IFsnbGVmdCcsICdyaWdodCcsICd0b3AnLCAnYm90dG9tJ10sXG5cdFx0XHRwcm9wLFxuXHRcdFx0aSA9IDQ7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0cHJvcCA9IHByb3BzW2ldO1xuXHRcdFx0aWYgKG9wdGlvbnMuc3R5bGVbcHJvcF0gJiYgb3B0aW9ucy5zdHlsZVtwcm9wXSAhPT0gJ2F1dG8nKSB7XG5cdFx0XHRcdG9wdGlvbnNbaSA8IDIgPyAnYWxpZ24nIDogJ3ZlcnRpY2FsQWxpZ24nXSA9IHByb3A7XG5cdFx0XHRcdG9wdGlvbnNbaSA8IDIgPyAneCcgOiAneSddID0gcEludChvcHRpb25zLnN0eWxlW3Byb3BdKSAqIChpICUgMiA/IC0xIDogMSk7XG5cdFx0XHR9XG5cdFx0fSovXG5cblx0XHRpZiAoZGlzcGxheSkge1xuXHRcdFx0bGVnZW5kR3JvdXAuYWxpZ24oZXh0ZW5kKHtcblx0XHRcdFx0d2lkdGg6IGxlZ2VuZFdpZHRoLFxuXHRcdFx0XHRoZWlnaHQ6IGxlZ2VuZEhlaWdodFxuXHRcdFx0fSwgb3B0aW9ucyksIHRydWUsICdzcGFjaW5nQm94Jyk7XG5cdFx0fVxuXG5cdFx0aWYgKCFjaGFydC5pc1Jlc2l6aW5nKSB7XG5cdFx0XHR0aGlzLnBvc2l0aW9uQ2hlY2tib3hlcygpO1xuXHRcdH1cblx0fSxcblx0XG5cdC8qKlxuXHQgKiBTZXQgdXAgdGhlIG92ZXJmbG93IGhhbmRsaW5nIGJ5IGFkZGluZyBuYXZpZ2F0aW9uIHdpdGggdXAgYW5kIGRvd24gYXJyb3dzIGJlbG93IHRoZVxuXHQgKiBsZWdlbmQuXG5cdCAqL1xuXHRoYW5kbGVPdmVyZmxvdzogZnVuY3Rpb24gKGxlZ2VuZEhlaWdodCkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRvcHRpb25zWSA9IG9wdGlvbnMueSxcblx0XHRcdGFsaWduVG9wID0gb3B0aW9ucy52ZXJ0aWNhbEFsaWduID09PSAndG9wJyxcblx0XHRcdHNwYWNlSGVpZ2h0ID0gY2hhcnQuc3BhY2luZ0JveC5oZWlnaHQgKyAoYWxpZ25Ub3AgPyAtb3B0aW9uc1kgOiBvcHRpb25zWSkgLSB0aGlzLnBhZGRpbmcsXG5cdFx0XHRtYXhIZWlnaHQgPSBvcHRpb25zLm1heEhlaWdodCxcblx0XHRcdGNsaXBIZWlnaHQsXG5cdFx0XHRjbGlwUmVjdCA9IHRoaXMuY2xpcFJlY3QsXG5cdFx0XHRuYXZPcHRpb25zID0gb3B0aW9ucy5uYXZpZ2F0aW9uLFxuXHRcdFx0YW5pbWF0aW9uID0gcGljayhuYXZPcHRpb25zLmFuaW1hdGlvbiwgdHJ1ZSksXG5cdFx0XHRhcnJvd1NpemUgPSBuYXZPcHRpb25zLmFycm93U2l6ZSB8fCAxMixcblx0XHRcdG5hdiA9IHRoaXMubmF2LFxuXHRcdFx0cGFnZXMgPSB0aGlzLnBhZ2VzLFxuXHRcdFx0bGFzdFksXG5cdFx0XHRhbGxJdGVtcyA9IHRoaXMuYWxsSXRlbXM7XG5cdFx0XHRcblx0XHQvLyBBZGp1c3QgdGhlIGhlaWdodFxuXHRcdGlmIChvcHRpb25zLmxheW91dCA9PT0gJ2hvcml6b250YWwnKSB7XG5cdFx0XHRzcGFjZUhlaWdodCAvPSAyO1xuXHRcdH1cblx0XHRpZiAobWF4SGVpZ2h0KSB7XG5cdFx0XHRzcGFjZUhlaWdodCA9IG1hdGhNaW4oc3BhY2VIZWlnaHQsIG1heEhlaWdodCk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIFJlc2V0IHRoZSBsZWdlbmQgaGVpZ2h0IGFuZCBhZGp1c3QgdGhlIGNsaXBwaW5nIHJlY3RhbmdsZVxuXHRcdHBhZ2VzLmxlbmd0aCA9IDA7XG5cdFx0aWYgKGxlZ2VuZEhlaWdodCA+IHNwYWNlSGVpZ2h0ICYmICFvcHRpb25zLnVzZUhUTUwpIHtcblxuXHRcdFx0dGhpcy5jbGlwSGVpZ2h0ID0gY2xpcEhlaWdodCA9IG1hdGhNYXgoc3BhY2VIZWlnaHQgLSAyMCAtIHRoaXMudGl0bGVIZWlnaHQgLSB0aGlzLnBhZGRpbmcsIDApO1xuXHRcdFx0dGhpcy5jdXJyZW50UGFnZSA9IHBpY2sodGhpcy5jdXJyZW50UGFnZSwgMSk7XG5cdFx0XHR0aGlzLmZ1bGxIZWlnaHQgPSBsZWdlbmRIZWlnaHQ7XG5cdFx0XHRcblx0XHRcdC8vIEZpbGwgcGFnZXMgd2l0aCBZIHBvc2l0aW9ucyBzbyB0aGF0IHRoZSB0b3Agb2YgZWFjaCBhIGxlZ2VuZCBpdGVtIGRlZmluZXNcblx0XHRcdC8vIHRoZSBzY3JvbGwgdG9wIGZvciBlYWNoIHBhZ2UgKCMyMDk4KVxuXHRcdFx0ZWFjaChhbGxJdGVtcywgZnVuY3Rpb24gKGl0ZW0sIGkpIHtcblx0XHRcdFx0dmFyIHkgPSBpdGVtLl9sZWdlbmRJdGVtUG9zWzFdLFxuXHRcdFx0XHRcdGggPSBtYXRoUm91bmQoaXRlbS5sZWdlbmRJdGVtLmdldEJCb3goKS5oZWlnaHQpLFxuXHRcdFx0XHRcdGxlbiA9IHBhZ2VzLmxlbmd0aDtcblx0XHRcdFx0XG5cdFx0XHRcdGlmICghbGVuIHx8ICh5IC0gcGFnZXNbbGVuIC0gMV0gPiBjbGlwSGVpZ2h0ICYmIChsYXN0WSB8fCB5KSAhPT0gcGFnZXNbbGVuIC0gMV0pKSB7XG5cdFx0XHRcdFx0cGFnZXMucHVzaChsYXN0WSB8fCB5KTtcblx0XHRcdFx0XHRsZW4rKztcblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0aWYgKGkgPT09IGFsbEl0ZW1zLmxlbmd0aCAtIDEgJiYgeSArIGggLSBwYWdlc1tsZW4gLSAxXSA+IGNsaXBIZWlnaHQpIHtcblx0XHRcdFx0XHRwYWdlcy5wdXNoKHkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh5ICE9PSBsYXN0WSkge1xuXHRcdFx0XHRcdGxhc3RZID0geTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIE9ubHkgYXBwbHkgY2xpcHBpbmcgaWYgbmVlZGVkLiBDbGlwcGluZyBjYXVzZXMgYmx1cnJlZCBsZWdlbmQgaW4gUERGIGV4cG9ydCAoIzE3ODcpXG5cdFx0XHRpZiAoIWNsaXBSZWN0KSB7XG5cdFx0XHRcdGNsaXBSZWN0ID0gbGVnZW5kLmNsaXBSZWN0ID0gcmVuZGVyZXIuY2xpcFJlY3QoMCwgdGhpcy5wYWRkaW5nLCA5OTk5LCAwKTtcblx0XHRcdFx0bGVnZW5kLmNvbnRlbnRHcm91cC5jbGlwKGNsaXBSZWN0KTtcblx0XHRcdH1cblx0XHRcdGNsaXBSZWN0LmF0dHIoe1xuXHRcdFx0XHRoZWlnaHQ6IGNsaXBIZWlnaHRcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHQvLyBBZGQgbmF2aWdhdGlvbiBlbGVtZW50c1xuXHRcdFx0aWYgKCFuYXYpIHtcblx0XHRcdFx0dGhpcy5uYXYgPSBuYXYgPSByZW5kZXJlci5nKCkuYXR0cih7IHpJbmRleDogMSB9KS5hZGQodGhpcy5ncm91cCk7XG5cdFx0XHRcdHRoaXMudXAgPSByZW5kZXJlci5zeW1ib2woJ3RyaWFuZ2xlJywgMCwgMCwgYXJyb3dTaXplLCBhcnJvd1NpemUpXG5cdFx0XHRcdFx0Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdGxlZ2VuZC5zY3JvbGwoLTEsIGFuaW1hdGlvbik7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuYWRkKG5hdik7XG5cdFx0XHRcdHRoaXMucGFnZXIgPSByZW5kZXJlci50ZXh0KCcnLCAxNSwgMTApXG5cdFx0XHRcdFx0LmNzcyhuYXZPcHRpb25zLnN0eWxlKVxuXHRcdFx0XHRcdC5hZGQobmF2KTtcblx0XHRcdFx0dGhpcy5kb3duID0gcmVuZGVyZXIuc3ltYm9sKCd0cmlhbmdsZS1kb3duJywgMCwgMCwgYXJyb3dTaXplLCBhcnJvd1NpemUpXG5cdFx0XHRcdFx0Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdGxlZ2VuZC5zY3JvbGwoMSwgYW5pbWF0aW9uKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5hZGQobmF2KTtcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0Ly8gU2V0IGluaXRpYWwgcG9zaXRpb25cblx0XHRcdGxlZ2VuZC5zY3JvbGwoMCk7XG5cdFx0XHRcblx0XHRcdGxlZ2VuZEhlaWdodCA9IHNwYWNlSGVpZ2h0O1xuXHRcdFx0XG5cdFx0fSBlbHNlIGlmIChuYXYpIHtcblx0XHRcdGNsaXBSZWN0LmF0dHIoe1xuXHRcdFx0XHRoZWlnaHQ6IGNoYXJ0LmNoYXJ0SGVpZ2h0XG5cdFx0XHR9KTtcblx0XHRcdG5hdi5oaWRlKCk7XG5cdFx0XHR0aGlzLnNjcm9sbEdyb3VwLmF0dHIoe1xuXHRcdFx0XHR0cmFuc2xhdGVZOiAxXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuY2xpcEhlaWdodCA9IDA7IC8vICMxMzc5XG5cdFx0fVxuXHRcdFxuXHRcdHJldHVybiBsZWdlbmRIZWlnaHQ7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogU2Nyb2xsIHRoZSBsZWdlbmQgYnkgYSBudW1iZXIgb2YgcGFnZXNcblx0ICogQHBhcmFtIHtPYmplY3R9IHNjcm9sbEJ5XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBhbmltYXRpb25cblx0ICovXG5cdHNjcm9sbDogZnVuY3Rpb24gKHNjcm9sbEJ5LCBhbmltYXRpb24pIHtcblx0XHR2YXIgcGFnZXMgPSB0aGlzLnBhZ2VzLFxuXHRcdFx0cGFnZUNvdW50ID0gcGFnZXMubGVuZ3RoLFxuXHRcdFx0Y3VycmVudFBhZ2UgPSB0aGlzLmN1cnJlbnRQYWdlICsgc2Nyb2xsQnksXG5cdFx0XHRjbGlwSGVpZ2h0ID0gdGhpcy5jbGlwSGVpZ2h0LFxuXHRcdFx0bmF2T3B0aW9ucyA9IHRoaXMub3B0aW9ucy5uYXZpZ2F0aW9uLFxuXHRcdFx0YWN0aXZlQ29sb3IgPSBuYXZPcHRpb25zLmFjdGl2ZUNvbG9yLFxuXHRcdFx0aW5hY3RpdmVDb2xvciA9IG5hdk9wdGlvbnMuaW5hY3RpdmVDb2xvcixcblx0XHRcdHBhZ2VyID0gdGhpcy5wYWdlcixcblx0XHRcdHBhZGRpbmcgPSB0aGlzLnBhZGRpbmcsXG5cdFx0XHRzY3JvbGxPZmZzZXQ7XG5cdFx0XG5cdFx0Ly8gV2hlbiByZXNpemluZyB3aGlsZSBsb29raW5nIGF0IHRoZSBsYXN0IHBhZ2Vcblx0XHRpZiAoY3VycmVudFBhZ2UgPiBwYWdlQ291bnQpIHtcblx0XHRcdGN1cnJlbnRQYWdlID0gcGFnZUNvdW50O1xuXHRcdH1cblx0XHRcblx0XHRpZiAoY3VycmVudFBhZ2UgPiAwKSB7XG5cdFx0XHRcblx0XHRcdGlmIChhbmltYXRpb24gIT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRzZXRBbmltYXRpb24oYW5pbWF0aW9uLCB0aGlzLmNoYXJ0KTtcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0dGhpcy5uYXYuYXR0cih7XG5cdFx0XHRcdHRyYW5zbGF0ZVg6IHBhZGRpbmcsXG5cdFx0XHRcdHRyYW5zbGF0ZVk6IGNsaXBIZWlnaHQgKyB0aGlzLnBhZGRpbmcgKyA3ICsgdGhpcy50aXRsZUhlaWdodCxcblx0XHRcdFx0dmlzaWJpbGl0eTogVklTSUJMRVxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnVwLmF0dHIoe1xuXHRcdFx0XHRcdGZpbGw6IGN1cnJlbnRQYWdlID09PSAxID8gaW5hY3RpdmVDb2xvciA6IGFjdGl2ZUNvbG9yXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jc3Moe1xuXHRcdFx0XHRcdGN1cnNvcjogY3VycmVudFBhZ2UgPT09IDEgPyAnZGVmYXVsdCcgOiAncG9pbnRlcidcblx0XHRcdFx0fSk7XG5cdFx0XHRwYWdlci5hdHRyKHtcblx0XHRcdFx0dGV4dDogY3VycmVudFBhZ2UgKyAnLycgKyBwYWdlQ291bnRcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5kb3duLmF0dHIoe1xuXHRcdFx0XHRcdHg6IDE4ICsgdGhpcy5wYWdlci5nZXRCQm94KCkud2lkdGgsIC8vIGFkanVzdCB0byB0ZXh0IHdpZHRoXG5cdFx0XHRcdFx0ZmlsbDogY3VycmVudFBhZ2UgPT09IHBhZ2VDb3VudCA/IGluYWN0aXZlQ29sb3IgOiBhY3RpdmVDb2xvclxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuY3NzKHtcblx0XHRcdFx0XHRjdXJzb3I6IGN1cnJlbnRQYWdlID09PSBwYWdlQ291bnQgPyAnZGVmYXVsdCcgOiAncG9pbnRlcidcblx0XHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdHNjcm9sbE9mZnNldCA9IC1wYWdlc1tjdXJyZW50UGFnZSAtIDFdICsgdGhpcy5pbml0aWFsSXRlbVk7XG5cblx0XHRcdHRoaXMuc2Nyb2xsR3JvdXAuYW5pbWF0ZSh7XG5cdFx0XHRcdHRyYW5zbGF0ZVk6IHNjcm9sbE9mZnNldFxuXHRcdFx0fSk7XHRcdFx0XG5cdFx0XHRcblx0XHRcdHRoaXMuY3VycmVudFBhZ2UgPSBjdXJyZW50UGFnZTtcblx0XHRcdHRoaXMucG9zaXRpb25DaGVja2JveGVzKHNjcm9sbE9mZnNldCk7XG5cdFx0fVxuXHRcdFx0XG5cdH1cblx0XG59O1xuXG4vKlxuICogTGVnZW5kU3ltYm9sTWl4aW5cbiAqLyBcblxudmFyIExlZ2VuZFN5bWJvbE1peGluID0gSGlnaGNoYXJ0cy5MZWdlbmRTeW1ib2xNaXhpbiA9IHtcblxuXHQvKipcblx0ICogR2V0IHRoZSBzZXJpZXMnIHN5bWJvbCBpbiB0aGUgbGVnZW5kXG5cdCAqIFxuXHQgKiBAcGFyYW0ge09iamVjdH0gbGVnZW5kIFRoZSBsZWdlbmQgb2JqZWN0XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIFRoZSBzZXJpZXMgKHRoaXMpIG9yIHBvaW50XG5cdCAqL1xuXHRkcmF3UmVjdGFuZ2xlOiBmdW5jdGlvbiAobGVnZW5kLCBpdGVtKSB7XG5cdFx0dmFyIHN5bWJvbEhlaWdodCA9IGxlZ2VuZC5vcHRpb25zLnN5bWJvbEhlaWdodCB8fCAxMjtcblx0XHRcblx0XHRpdGVtLmxlZ2VuZFN5bWJvbCA9IHRoaXMuY2hhcnQucmVuZGVyZXIucmVjdChcblx0XHRcdDAsXG5cdFx0XHRsZWdlbmQuYmFzZWxpbmUgLSA1IC0gKHN5bWJvbEhlaWdodCAvIDIpLFxuXHRcdFx0bGVnZW5kLnN5bWJvbFdpZHRoLFxuXHRcdFx0c3ltYm9sSGVpZ2h0LFxuXHRcdFx0bGVnZW5kLm9wdGlvbnMuc3ltYm9sUmFkaXVzIHx8IDBcblx0XHQpLmF0dHIoe1xuXHRcdFx0ekluZGV4OiAzXG5cdFx0fSkuYWRkKGl0ZW0ubGVnZW5kR3JvdXApO1x0XHRcblx0XHRcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBzZXJpZXMnIHN5bWJvbCBpbiB0aGUgbGVnZW5kLiBUaGlzIG1ldGhvZCBzaG91bGQgYmUgb3ZlcnJpZGFibGUgdG8gY3JlYXRlIGN1c3RvbSBcblx0ICogc3ltYm9scyB0aHJvdWdoIEhpZ2hjaGFydHMuc2VyaWVzVHlwZXNbdHlwZV0ucHJvdG90eXBlLmRyYXdMZWdlbmRTeW1ib2xzLlxuXHQgKiBcblx0ICogQHBhcmFtIHtPYmplY3R9IGxlZ2VuZCBUaGUgbGVnZW5kIG9iamVjdFxuXHQgKi9cblx0ZHJhd0xpbmVNYXJrZXI6IGZ1bmN0aW9uIChsZWdlbmQpIHtcblxuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0bWFya2VyT3B0aW9ucyA9IG9wdGlvbnMubWFya2VyLFxuXHRcdFx0cmFkaXVzLFxuXHRcdFx0bGVnZW5kT3B0aW9ucyA9IGxlZ2VuZC5vcHRpb25zLFxuXHRcdFx0bGVnZW5kU3ltYm9sLFxuXHRcdFx0c3ltYm9sV2lkdGggPSBsZWdlbmQuc3ltYm9sV2lkdGgsXG5cdFx0XHRyZW5kZXJlciA9IHRoaXMuY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRsZWdlbmRJdGVtR3JvdXAgPSB0aGlzLmxlZ2VuZEdyb3VwLFxuXHRcdFx0dmVydGljYWxDZW50ZXIgPSBsZWdlbmQuYmFzZWxpbmUgLSBtYXRoUm91bmQocmVuZGVyZXIuZm9udE1ldHJpY3MobGVnZW5kT3B0aW9ucy5pdGVtU3R5bGUuZm9udFNpemUsIHRoaXMubGVnZW5kSXRlbSkuYiAqIDAuMyksXG5cdFx0XHRhdHRyO1xuXG5cdFx0Ly8gRHJhdyB0aGUgbGluZVxuXHRcdGlmIChvcHRpb25zLmxpbmVXaWR0aCkge1xuXHRcdFx0YXR0ciA9IHtcblx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IG9wdGlvbnMubGluZVdpZHRoXG5cdFx0XHR9O1xuXHRcdFx0aWYgKG9wdGlvbnMuZGFzaFN0eWxlKSB7XG5cdFx0XHRcdGF0dHIuZGFzaHN0eWxlID0gb3B0aW9ucy5kYXNoU3R5bGU7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmxlZ2VuZExpbmUgPSByZW5kZXJlci5wYXRoKFtcblx0XHRcdFx0TSxcblx0XHRcdFx0MCxcblx0XHRcdFx0dmVydGljYWxDZW50ZXIsXG5cdFx0XHRcdEwsXG5cdFx0XHRcdHN5bWJvbFdpZHRoLFxuXHRcdFx0XHR2ZXJ0aWNhbENlbnRlclxuXHRcdFx0XSlcblx0XHRcdC5hdHRyKGF0dHIpXG5cdFx0XHQuYWRkKGxlZ2VuZEl0ZW1Hcm91cCk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIERyYXcgdGhlIG1hcmtlclxuXHRcdGlmIChtYXJrZXJPcHRpb25zICYmIG1hcmtlck9wdGlvbnMuZW5hYmxlZCAhPT0gZmFsc2UpIHtcblx0XHRcdHJhZGl1cyA9IG1hcmtlck9wdGlvbnMucmFkaXVzO1xuXHRcdFx0dGhpcy5sZWdlbmRTeW1ib2wgPSBsZWdlbmRTeW1ib2wgPSByZW5kZXJlci5zeW1ib2woXG5cdFx0XHRcdHRoaXMuc3ltYm9sLFxuXHRcdFx0XHQoc3ltYm9sV2lkdGggLyAyKSAtIHJhZGl1cyxcblx0XHRcdFx0dmVydGljYWxDZW50ZXIgLSByYWRpdXMsXG5cdFx0XHRcdDIgKiByYWRpdXMsXG5cdFx0XHRcdDIgKiByYWRpdXNcblx0XHRcdClcblx0XHRcdC5hZGQobGVnZW5kSXRlbUdyb3VwKTtcblx0XHRcdGxlZ2VuZFN5bWJvbC5pc01hcmtlciA9IHRydWU7XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBXb3JrYXJvdW5kIGZvciAjMjAzMCwgaG9yaXpvbnRhbCBsZWdlbmQgaXRlbXMgbm90IGRpc3BsYXlpbmcgaW4gSUUxMSBQcmV2aWV3LFxuLy8gYW5kIGZvciAjMjU4MCwgYSBzaW1pbGFyIGRyYXdpbmcgZmxhdyBpbiBGaXJlZm94IDI2LlxuLy8gVE9ETzogRXhwbG9yZSBpZiB0aGVyZSdzIGEgZ2VuZXJhbCBjYXVzZSBmb3IgdGhpcy4gVGhlIHByb2JsZW0gbWF5IGJlIHJlbGF0ZWQgXG4vLyB0byBuZXN0ZWQgZ3JvdXAgZWxlbWVudHMsIGFzIHRoZSBsZWdlbmQgaXRlbSB0ZXh0cyBhcmUgd2l0aGluIDQgZ3JvdXAgZWxlbWVudHMuXG5pZiAoL1RyaWRlbnRcXC83XFwuMC8udGVzdCh1c2VyQWdlbnQpIHx8IGlzRmlyZWZveCkge1xuXHR3cmFwKExlZ2VuZC5wcm90b3R5cGUsICdwb3NpdGlvbkl0ZW0nLCBmdW5jdGlvbiAocHJvY2VlZCwgaXRlbSkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0cnVuUG9zaXRpb25JdGVtID0gZnVuY3Rpb24gKCkgeyAvLyBJZiBjaGFydCBkZXN0cm95ZWQgaW4gc3luYywgdGhpcyBpcyB1bmRlZmluZWQgKCMyMDMwKVxuXHRcdFx0XHRpZiAoaXRlbS5fbGVnZW5kSXRlbVBvcykge1xuXHRcdFx0XHRcdHByb2NlZWQuY2FsbChsZWdlbmQsIGl0ZW0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gRG8gaXQgbm93LCBmb3IgZXhwb3J0IGFuZCB0byBnZXQgY2hlY2tib3ggcGxhY2VtZW50XG5cdFx0cnVuUG9zaXRpb25JdGVtKCk7XG5cdFx0XG5cdFx0Ly8gRG8gaXQgYWZ0ZXIgdG8gd29yayBhcm91bmQgdGhlIGNvcmUgaXNzdWVcblx0XHRzZXRUaW1lb3V0KHJ1blBvc2l0aW9uSXRlbSk7XG5cdH0pO1xufVxuLyoqXG4gKiBUaGUgY2hhcnQgY2xhc3NcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBGdW5jdGlvbiB0byBydW4gd2hlbiB0aGUgY2hhcnQgaGFzIGxvYWRlZFxuICovXG5mdW5jdGlvbiBDaGFydCgpIHtcblx0dGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbkNoYXJ0LnByb3RvdHlwZSA9IHtcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgY2hhcnRcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uICh1c2VyT3B0aW9ucywgY2FsbGJhY2spIHtcblxuXHRcdC8vIEhhbmRsZSByZWd1bGFyIG9wdGlvbnNcblx0XHR2YXIgb3B0aW9ucyxcblx0XHRcdHNlcmllc09wdGlvbnMgPSB1c2VyT3B0aW9ucy5zZXJpZXM7IC8vIHNraXAgbWVyZ2luZyBkYXRhIHBvaW50cyB0byBpbmNyZWFzZSBwZXJmb3JtYW5jZVxuXG5cdFx0dXNlck9wdGlvbnMuc2VyaWVzID0gbnVsbDtcblx0XHRvcHRpb25zID0gbWVyZ2UoZGVmYXVsdE9wdGlvbnMsIHVzZXJPcHRpb25zKTsgLy8gZG8gdGhlIG1lcmdlXG5cdFx0b3B0aW9ucy5zZXJpZXMgPSB1c2VyT3B0aW9ucy5zZXJpZXMgPSBzZXJpZXNPcHRpb25zOyAvLyBzZXQgYmFjayB0aGUgc2VyaWVzIGRhdGFcblx0XHR0aGlzLnVzZXJPcHRpb25zID0gdXNlck9wdGlvbnM7XG5cblx0XHR2YXIgb3B0aW9uc0NoYXJ0ID0gb3B0aW9ucy5jaGFydDtcblx0XHRcblx0XHQvLyBDcmVhdGUgbWFyZ2luICYgc3BhY2luZyBhcnJheVxuXHRcdHRoaXMubWFyZ2luID0gdGhpcy5zcGxhc2hBcnJheSgnbWFyZ2luJywgb3B0aW9uc0NoYXJ0KTtcblx0XHR0aGlzLnNwYWNpbmcgPSB0aGlzLnNwbGFzaEFycmF5KCdzcGFjaW5nJywgb3B0aW9uc0NoYXJ0KTtcblxuXHRcdHZhciBjaGFydEV2ZW50cyA9IG9wdGlvbnNDaGFydC5ldmVudHM7XG5cblx0XHQvL3RoaXMucnVuQ2hhcnRDbGljayA9IGNoYXJ0RXZlbnRzICYmICEhY2hhcnRFdmVudHMuY2xpY2s7XG5cdFx0dGhpcy5ib3VuZHMgPSB7IGg6IHt9LCB2OiB7fSB9OyAvLyBQaXhlbCBkYXRhIGJvdW5kcyBmb3IgdG91Y2ggem9vbVxuXG5cdFx0dGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuXHRcdHRoaXMuaXNSZXNpemluZyA9IDA7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblx0XHQvL2NoYXJ0VGl0bGVPcHRpb25zID0gVU5ERUZJTkVEO1xuXHRcdC8vY2hhcnRTdWJ0aXRsZU9wdGlvbnMgPSBVTkRFRklORUQ7XG5cblx0XHR0aGlzLmF4ZXMgPSBbXTtcblx0XHR0aGlzLnNlcmllcyA9IFtdO1xuXHRcdHRoaXMuaGFzQ2FydGVzaWFuU2VyaWVzID0gb3B0aW9uc0NoYXJ0LnNob3dBeGVzO1xuXHRcdC8vdGhpcy5heGlzT2Zmc2V0ID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5tYXhUaWNrcyA9IFVOREVGSU5FRDsgLy8gaGFuZGxlIHRoZSBncmVhdGVzdCBhbW91bnQgb2YgdGlja3Mgb24gZ3JvdXBlZCBheGVzXG5cdFx0Ly90aGlzLmludmVydGVkID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5sb2FkaW5nU2hvd24gPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLmNvbnRhaW5lciA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMuY2hhcnRXaWR0aCA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMuY2hhcnRIZWlnaHQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLm1hcmdpblJpZ2h0ID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5tYXJnaW5Cb3R0b20gPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLmNvbnRhaW5lcldpZHRoID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5jb250YWluZXJIZWlnaHQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLm9sZENoYXJ0V2lkdGggPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLm9sZENoYXJ0SGVpZ2h0ID0gVU5ERUZJTkVEO1xuXG5cdFx0Ly90aGlzLnJlbmRlclRvID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5yZW5kZXJUb0Nsb25lID0gVU5ERUZJTkVEO1xuXG5cdFx0Ly90aGlzLnNwYWNpbmdCb3ggPSBVTkRFRklORURcblxuXHRcdC8vdGhpcy5sZWdlbmQgPSBVTkRFRklORUQ7XG5cblx0XHQvLyBFbGVtZW50c1xuXHRcdC8vdGhpcy5jaGFydEJhY2tncm91bmQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLnBsb3RCYWNrZ3JvdW5kID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5wbG90QkdJbWFnZSA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMucGxvdEJvcmRlciA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMubG9hZGluZ0RpdiA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMubG9hZGluZ1NwYW4gPSBVTkRFRklORUQ7XG5cblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0ZXZlbnRUeXBlO1xuXG5cdFx0Ly8gQWRkIHRoZSBjaGFydCB0byB0aGUgZ2xvYmFsIGxvb2t1cFxuXHRcdGNoYXJ0LmluZGV4ID0gY2hhcnRzLmxlbmd0aDtcblx0XHRjaGFydHMucHVzaChjaGFydCk7XG5cdFx0Y2hhcnRDb3VudCsrO1xuXG5cdFx0Ly8gU2V0IHVwIGF1dG8gcmVzaXplXG5cdFx0aWYgKG9wdGlvbnNDaGFydC5yZWZsb3cgIT09IGZhbHNlKSB7XG5cdFx0XHRhZGRFdmVudChjaGFydCwgJ2xvYWQnLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGNoYXJ0LmluaXRSZWZsb3coKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdC8vIENoYXJ0IGV2ZW50IGhhbmRsZXJzXG5cdFx0aWYgKGNoYXJ0RXZlbnRzKSB7XG5cdFx0XHRmb3IgKGV2ZW50VHlwZSBpbiBjaGFydEV2ZW50cykge1xuXHRcdFx0XHRhZGRFdmVudChjaGFydCwgZXZlbnRUeXBlLCBjaGFydEV2ZW50c1tldmVudFR5cGVdKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRjaGFydC54QXhpcyA9IFtdO1xuXHRcdGNoYXJ0LnlBeGlzID0gW107XG5cblx0XHQvLyBFeHBvc2UgbWV0aG9kcyBhbmQgdmFyaWFibGVzXG5cdFx0Y2hhcnQuYW5pbWF0aW9uID0gdXNlQ2FuVkcgPyBmYWxzZSA6IHBpY2sob3B0aW9uc0NoYXJ0LmFuaW1hdGlvbiwgdHJ1ZSk7XG5cdFx0Y2hhcnQucG9pbnRDb3VudCA9IGNoYXJ0LmNvbG9yQ291bnRlciA9IGNoYXJ0LnN5bWJvbENvdW50ZXIgPSAwO1xuXG5cdFx0Y2hhcnQuZmlyc3RSZW5kZXIoKTtcblx0fSxcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSBhbiBpbmRpdmlkdWFsIHNlcmllcywgY2FsbGVkIGludGVybmFsbHkgYmVmb3JlIHJlbmRlciB0aW1lXG5cdCAqL1xuXHRpbml0U2VyaWVzOiBmdW5jdGlvbiAob3B0aW9ucykge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0dHlwZSA9IG9wdGlvbnMudHlwZSB8fCBvcHRpb25zQ2hhcnQudHlwZSB8fCBvcHRpb25zQ2hhcnQuZGVmYXVsdFNlcmllc1R5cGUsXG5cdFx0XHRzZXJpZXMsXG5cdFx0XHRjb25zdHIgPSBzZXJpZXNUeXBlc1t0eXBlXTtcblxuXHRcdC8vIE5vIHN1Y2ggc2VyaWVzIHR5cGVcblx0XHRpZiAoIWNvbnN0cikge1xuXHRcdFx0ZXJyb3IoMTcsIHRydWUpO1xuXHRcdH1cblxuXHRcdHNlcmllcyA9IG5ldyBjb25zdHIoKTtcblx0XHRzZXJpZXMuaW5pdCh0aGlzLCBvcHRpb25zKTtcblx0XHRyZXR1cm4gc2VyaWVzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDaGVjayB3aGV0aGVyIGEgZ2l2ZW4gcG9pbnQgaXMgd2l0aGluIHRoZSBwbG90IGFyZWFcblx0ICpcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHBsb3RYIFBpeGVsIHggcmVsYXRpdmUgdG8gdGhlIHBsb3QgYXJlYVxuXHQgKiBAcGFyYW0ge051bWJlcn0gcGxvdFkgUGl4ZWwgeSByZWxhdGl2ZSB0byB0aGUgcGxvdCBhcmVhXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gaW52ZXJ0ZWQgV2hldGhlciB0aGUgY2hhcnQgaXMgaW52ZXJ0ZWRcblx0ICovXG5cdGlzSW5zaWRlUGxvdDogZnVuY3Rpb24gKHBsb3RYLCBwbG90WSwgaW52ZXJ0ZWQpIHtcblx0XHR2YXIgeCA9IGludmVydGVkID8gcGxvdFkgOiBwbG90WCxcblx0XHRcdHkgPSBpbnZlcnRlZCA/IHBsb3RYIDogcGxvdFk7XG5cdFx0XHRcblx0XHRyZXR1cm4geCA+PSAwICYmXG5cdFx0XHR4IDw9IHRoaXMucGxvdFdpZHRoICYmXG5cdFx0XHR5ID49IDAgJiZcblx0XHRcdHkgPD0gdGhpcy5wbG90SGVpZ2h0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGp1c3QgYWxsIGF4ZXMgdGljayBhbW91bnRzXG5cdCAqL1xuXHRhZGp1c3RUaWNrQW1vdW50czogZnVuY3Rpb24gKCkge1xuXHRcdGlmICh0aGlzLm9wdGlvbnMuY2hhcnQuYWxpZ25UaWNrcyAhPT0gZmFsc2UpIHtcblx0XHRcdGVhY2godGhpcy5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRheGlzLmFkanVzdFRpY2tBbW91bnQoKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHR0aGlzLm1heFRpY2tzID0gbnVsbDtcblx0fSxcblxuXHQvKipcblx0ICogUmVkcmF3IGxlZ2VuZCwgYXhlcyBvciBzZXJpZXMgYmFzZWQgb24gdXBkYXRlZCBkYXRhXG5cdCAqXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IGFuaW1hdGlvbiBXaGV0aGVyIHRvIGFwcGx5IGFuaW1hdGlvbiwgYW5kIG9wdGlvbmFsbHkgYW5pbWF0aW9uXG5cdCAqICAgIGNvbmZpZ3VyYXRpb25cblx0ICovXG5cdHJlZHJhdzogZnVuY3Rpb24gKGFuaW1hdGlvbikge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRheGVzID0gY2hhcnQuYXhlcyxcblx0XHRcdHNlcmllcyA9IGNoYXJ0LnNlcmllcyxcblx0XHRcdHBvaW50ZXIgPSBjaGFydC5wb2ludGVyLFxuXHRcdFx0bGVnZW5kID0gY2hhcnQubGVnZW5kLFxuXHRcdFx0cmVkcmF3TGVnZW5kID0gY2hhcnQuaXNEaXJ0eUxlZ2VuZCxcblx0XHRcdGhhc1N0YWNrZWRTZXJpZXMsXG5cdFx0XHRoYXNEaXJ0eVN0YWNrcyxcblx0XHRcdGhhc0NhcnRlc2lhblNlcmllcyA9IGNoYXJ0Lmhhc0NhcnRlc2lhblNlcmllcyxcblx0XHRcdGlzRGlydHlCb3ggPSBjaGFydC5pc0RpcnR5Qm94LCAvLyB0b2RvOiBjaGVjayBpZiBpdCBoYXMgYWN0dWFsbHkgY2hhbmdlZD9cblx0XHRcdHNlcmllc0xlbmd0aCA9IHNlcmllcy5sZW5ndGgsXG5cdFx0XHRpID0gc2VyaWVzTGVuZ3RoLFxuXHRcdFx0c2VyaWUsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0aXNIaWRkZW5DaGFydCA9IHJlbmRlcmVyLmlzSGlkZGVuKCksXG5cdFx0XHRhZnRlclJlZHJhdyA9IFtdO1xuXHRcdFx0XG5cdFx0c2V0QW5pbWF0aW9uKGFuaW1hdGlvbiwgY2hhcnQpO1xuXHRcdFxuXHRcdGlmIChpc0hpZGRlbkNoYXJ0KSB7XG5cdFx0XHRjaGFydC5jbG9uZVJlbmRlclRvKCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWRqdXN0IHRpdGxlIGxheW91dCAocmVmbG93IG11bHRpbGluZSB0ZXh0KVxuXHRcdGNoYXJ0LmxheU91dFRpdGxlcygpO1xuXG5cdFx0Ly8gbGluayBzdGFja2VkIHNlcmllc1xuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHNlcmllID0gc2VyaWVzW2ldO1xuXG5cdFx0XHRpZiAoc2VyaWUub3B0aW9ucy5zdGFja2luZykge1xuXHRcdFx0XHRoYXNTdGFja2VkU2VyaWVzID0gdHJ1ZTtcblx0XHRcdFx0XG5cdFx0XHRcdGlmIChzZXJpZS5pc0RpcnR5KSB7XG5cdFx0XHRcdFx0aGFzRGlydHlTdGFja3MgPSB0cnVlO1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChoYXNEaXJ0eVN0YWNrcykgeyAvLyBtYXJrIG90aGVycyBhcyBkaXJ0eVxuXHRcdFx0aSA9IHNlcmllc0xlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0c2VyaWUgPSBzZXJpZXNbaV07XG5cdFx0XHRcdGlmIChzZXJpZS5vcHRpb25zLnN0YWNraW5nKSB7XG5cdFx0XHRcdFx0c2VyaWUuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBoYW5kbGUgdXBkYXRlZCBkYXRhIGluIHRoZSBzZXJpZXNcblx0XHRlYWNoKHNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRpZiAoc2VyaWUuaXNEaXJ0eSkgeyAvLyBwcmVwYXJlIHRoZSBkYXRhIHNvIGF4aXMgY2FuIHJlYWQgaXRcblx0XHRcdFx0aWYgKHNlcmllLm9wdGlvbnMubGVnZW5kVHlwZSA9PT0gJ3BvaW50Jykge1xuXHRcdFx0XHRcdHJlZHJhd0xlZ2VuZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGhhbmRsZSBhZGRlZCBvciByZW1vdmVkIHNlcmllc1xuXHRcdGlmIChyZWRyYXdMZWdlbmQgJiYgbGVnZW5kLm9wdGlvbnMuZW5hYmxlZCkgeyAvLyBzZXJpZXMgb3IgcGllIHBvaW50cyBhcmUgYWRkZWQgb3IgcmVtb3ZlZFxuXHRcdFx0Ly8gZHJhdyBsZWdlbmQgZ3JhcGhpY3Ncblx0XHRcdGxlZ2VuZC5yZW5kZXIoKTtcblxuXHRcdFx0Y2hhcnQuaXNEaXJ0eUxlZ2VuZCA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIHJlc2V0IHN0YWNrc1xuXHRcdGlmIChoYXNTdGFja2VkU2VyaWVzKSB7XG5cdFx0XHRjaGFydC5nZXRTdGFja3MoKTtcblx0XHR9XG5cblxuXHRcdGlmIChoYXNDYXJ0ZXNpYW5TZXJpZXMpIHtcblx0XHRcdGlmICghY2hhcnQuaXNSZXNpemluZykge1xuXG5cdFx0XHRcdC8vIHJlc2V0IG1heFRpY2tzXG5cdFx0XHRcdGNoYXJ0Lm1heFRpY2tzID0gbnVsbDtcblxuXHRcdFx0XHQvLyBzZXQgYXhlcyBzY2FsZXNcblx0XHRcdFx0ZWFjaChheGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRcdGF4aXMuc2V0U2NhbGUoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGNoYXJ0LmFkanVzdFRpY2tBbW91bnRzKCk7XG5cdFx0fVxuXG5cdFx0Y2hhcnQuZ2V0TWFyZ2lucygpOyAvLyAjMzA5OFxuXG5cdFx0aWYgKGhhc0NhcnRlc2lhblNlcmllcykge1xuXHRcdFx0Ly8gSWYgb25lIGF4aXMgaXMgZGlydHksIGFsbCBheGVzIG11c3QgYmUgcmVkcmF3biAoIzc5MiwgIzIxNjkpXG5cdFx0XHRlYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdGlmIChheGlzLmlzRGlydHkpIHtcblx0XHRcdFx0XHRpc0RpcnR5Qm94ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIHJlZHJhdyBheGVzXG5cdFx0XHRlYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdFxuXHRcdFx0XHQvLyBGaXJlICdhZnRlclNldEV4dHJlbWVzJyBvbmx5IGlmIGV4dHJlbWVzIGFyZSBzZXRcblx0XHRcdFx0aWYgKGF4aXMuaXNEaXJ0eUV4dHJlbWVzKSB7IC8vICM4MjFcblx0XHRcdFx0XHRheGlzLmlzRGlydHlFeHRyZW1lcyA9IGZhbHNlO1xuXHRcdFx0XHRcdGFmdGVyUmVkcmF3LnB1c2goZnVuY3Rpb24gKCkgeyAvLyBwcmV2ZW50IGEgcmVjdXJzaXZlIGNhbGwgdG8gY2hhcnQucmVkcmF3KCkgKCMxMTE5KVxuXHRcdFx0XHRcdFx0ZmlyZUV2ZW50KGF4aXMsICdhZnRlclNldEV4dHJlbWVzJywgZXh0ZW5kKGF4aXMuZXZlbnRBcmdzLCBheGlzLmdldEV4dHJlbWVzKCkpKTsgLy8gIzc0NywgIzc1MVxuXHRcdFx0XHRcdFx0ZGVsZXRlIGF4aXMuZXZlbnRBcmdzO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRpZiAoaXNEaXJ0eUJveCB8fCBoYXNTdGFja2VkU2VyaWVzKSB7XG5cdFx0XHRcdFx0YXhpcy5yZWRyYXcoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIHRoZSBwbG90IGFyZWFzIHNpemUgaGFzIGNoYW5nZWRcblx0XHRpZiAoaXNEaXJ0eUJveCkge1xuXHRcdFx0Y2hhcnQuZHJhd0NoYXJ0Qm94KCk7XG5cdFx0fVxuXG5cblx0XHQvLyByZWRyYXcgYWZmZWN0ZWQgc2VyaWVzXG5cdFx0ZWFjaChzZXJpZXMsIGZ1bmN0aW9uIChzZXJpZSkge1xuXHRcdFx0aWYgKHNlcmllLmlzRGlydHkgJiYgc2VyaWUudmlzaWJsZSAmJlxuXHRcdFx0XHRcdCghc2VyaWUuaXNDYXJ0ZXNpYW4gfHwgc2VyaWUueEF4aXMpKSB7IC8vIGlzc3VlICMxNTNcblx0XHRcdFx0c2VyaWUucmVkcmF3KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBtb3ZlIHRvb2x0aXAgb3IgcmVzZXRcblx0XHRpZiAocG9pbnRlcikge1xuXHRcdFx0cG9pbnRlci5yZXNldCh0cnVlKTtcblx0XHR9XG5cblx0XHQvLyByZWRyYXcgaWYgY2FudmFzXG5cdFx0cmVuZGVyZXIuZHJhdygpO1xuXG5cdFx0Ly8gZmlyZSB0aGUgZXZlbnRcblx0XHRmaXJlRXZlbnQoY2hhcnQsICdyZWRyYXcnKTsgLy8galF1ZXJ5IGJyZWFrcyB0aGlzIHdoZW4gY2FsbGluZyBpdCBmcm9tIGFkZEV2ZW50LiBPdmVyd3JpdGVzIGNoYXJ0LnJlZHJhd1xuXHRcdFxuXHRcdGlmIChpc0hpZGRlbkNoYXJ0KSB7XG5cdFx0XHRjaGFydC5jbG9uZVJlbmRlclRvKHRydWUpO1xuXHRcdH1cblx0XHRcblx0XHQvLyBGaXJlIGNhbGxiYWNrcyB0aGF0IGFyZSBwdXQgb24gaG9sZCB1bnRpbCBhZnRlciB0aGUgcmVkcmF3XG5cdFx0ZWFjaChhZnRlclJlZHJhdywgZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG5cdFx0XHRjYWxsYmFjay5jYWxsKCk7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCBhbiBheGlzLCBzZXJpZXMgb3IgcG9pbnQgb2JqZWN0IGJ5IGlkLlxuXHQgKiBAcGFyYW0gaWQge1N0cmluZ30gVGhlIGlkIGFzIGdpdmVuIGluIHRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnNcblx0ICovXG5cdGdldDogZnVuY3Rpb24gKGlkKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGF4ZXMgPSBjaGFydC5heGVzLFxuXHRcdFx0c2VyaWVzID0gY2hhcnQuc2VyaWVzO1xuXG5cdFx0dmFyIGksXG5cdFx0XHRqLFxuXHRcdFx0cG9pbnRzO1xuXG5cdFx0Ly8gc2VhcmNoIGF4ZXNcblx0XHRmb3IgKGkgPSAwOyBpIDwgYXhlcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGF4ZXNbaV0ub3B0aW9ucy5pZCA9PT0gaWQpIHtcblx0XHRcdFx0cmV0dXJuIGF4ZXNbaV07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gc2VhcmNoIHNlcmllc1xuXHRcdGZvciAoaSA9IDA7IGkgPCBzZXJpZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChzZXJpZXNbaV0ub3B0aW9ucy5pZCA9PT0gaWQpIHtcblx0XHRcdFx0cmV0dXJuIHNlcmllc1tpXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBzZWFyY2ggcG9pbnRzXG5cdFx0Zm9yIChpID0gMDsgaSA8IHNlcmllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0cG9pbnRzID0gc2VyaWVzW2ldLnBvaW50cyB8fCBbXTtcblx0XHRcdGZvciAoaiA9IDA7IGogPCBwb2ludHMubGVuZ3RoOyBqKyspIHtcblx0XHRcdFx0aWYgKHBvaW50c1tqXS5pZCA9PT0gaWQpIHtcblx0XHRcdFx0XHRyZXR1cm4gcG9pbnRzW2pdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBudWxsO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgdGhlIEF4aXMgaW5zdGFuY2VzIGJhc2VkIG9uIHRoZSBjb25maWcgb3B0aW9uc1xuXHQgKi9cblx0Z2V0QXhlczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0eEF4aXNPcHRpb25zID0gb3B0aW9ucy54QXhpcyA9IHNwbGF0KG9wdGlvbnMueEF4aXMgfHwge30pLFxuXHRcdFx0eUF4aXNPcHRpb25zID0gb3B0aW9ucy55QXhpcyA9IHNwbGF0KG9wdGlvbnMueUF4aXMgfHwge30pLFxuXHRcdFx0b3B0aW9uc0FycmF5LFxuXHRcdFx0YXhpcztcblxuXHRcdC8vIG1ha2Ugc3VyZSB0aGUgb3B0aW9ucyBhcmUgYXJyYXlzIGFuZCBhZGQgc29tZSBtZW1iZXJzXG5cdFx0ZWFjaCh4QXhpc09wdGlvbnMsIGZ1bmN0aW9uIChheGlzLCBpKSB7XG5cdFx0XHRheGlzLmluZGV4ID0gaTtcblx0XHRcdGF4aXMuaXNYID0gdHJ1ZTtcblx0XHR9KTtcblxuXHRcdGVhY2goeUF4aXNPcHRpb25zLCBmdW5jdGlvbiAoYXhpcywgaSkge1xuXHRcdFx0YXhpcy5pbmRleCA9IGk7XG5cdFx0fSk7XG5cblx0XHQvLyBjb25jYXRlbmF0ZSBhbGwgYXhpcyBvcHRpb25zIGludG8gb25lIGFycmF5XG5cdFx0b3B0aW9uc0FycmF5ID0geEF4aXNPcHRpb25zLmNvbmNhdCh5QXhpc09wdGlvbnMpO1xuXG5cdFx0ZWFjaChvcHRpb25zQXJyYXksIGZ1bmN0aW9uIChheGlzT3B0aW9ucykge1xuXHRcdFx0YXhpcyA9IG5ldyBBeGlzKGNoYXJ0LCBheGlzT3B0aW9ucyk7XG5cdFx0fSk7XG5cblx0XHRjaGFydC5hZGp1c3RUaWNrQW1vdW50cygpO1xuXHR9LFxuXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHBvaW50cyBmcm9tIGFsbCBzZXJpZXNcblx0ICovXG5cdGdldFNlbGVjdGVkUG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHBvaW50cyA9IFtdO1xuXHRcdGVhY2godGhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZSkge1xuXHRcdFx0cG9pbnRzID0gcG9pbnRzLmNvbmNhdChncmVwKHNlcmllLnBvaW50cyB8fCBbXSwgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdHJldHVybiBwb2ludC5zZWxlY3RlZDtcblx0XHRcdH0pKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gcG9pbnRzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBzZXJpZXNcblx0ICovXG5cdGdldFNlbGVjdGVkU2VyaWVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIGdyZXAodGhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZSkge1xuXHRcdFx0cmV0dXJuIHNlcmllLnNlbGVjdGVkO1xuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZW5lcmF0ZSBzdGFja3MgZm9yIGVhY2ggc2VyaWVzIGFuZCBjYWxjdWxhdGUgc3RhY2tzIHRvdGFsIHZhbHVlc1xuXHQgKi9cblx0Z2V0U3RhY2tzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcztcblxuXHRcdC8vIHJlc2V0IHN0YWNrcyBmb3IgZWFjaCB5QXhpc1xuXHRcdGVhY2goY2hhcnQueUF4aXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRpZiAoYXhpcy5zdGFja3MgJiYgYXhpcy5oYXNWaXNpYmxlU2VyaWVzKSB7XG5cdFx0XHRcdGF4aXMub2xkU3RhY2tzID0gYXhpcy5zdGFja3M7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0aWYgKHNlcmllcy5vcHRpb25zLnN0YWNraW5nICYmIChzZXJpZXMudmlzaWJsZSA9PT0gdHJ1ZSB8fCBjaGFydC5vcHRpb25zLmNoYXJ0Lmlnbm9yZUhpZGRlblNlcmllcyA9PT0gZmFsc2UpKSB7XG5cdFx0XHRcdHNlcmllcy5zdGFja0tleSA9IHNlcmllcy50eXBlICsgcGljayhzZXJpZXMub3B0aW9ucy5zdGFjaywgJycpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFx0XG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIHRpdGxlIGFuZCBzdWJ0aXRsZSBvZiB0aGUgY2hhcnRcblx0ICpcblx0ICogQHBhcmFtIHRpdGxlT3B0aW9ucyB7T2JqZWN0fSBOZXcgdGl0bGUgb3B0aW9uc1xuXHQgKiBAcGFyYW0gc3VidGl0bGVPcHRpb25zIHtPYmplY3R9IE5ldyBzdWJ0aXRsZSBvcHRpb25zXG5cdCAqXG5cdCAqL1xuXHRzZXRUaXRsZTogZnVuY3Rpb24gKHRpdGxlT3B0aW9ucywgc3VidGl0bGVPcHRpb25zLCByZWRyYXcpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMsXG5cdFx0XHRjaGFydFRpdGxlT3B0aW9ucyxcblx0XHRcdGNoYXJ0U3VidGl0bGVPcHRpb25zO1xuXG5cdFx0Y2hhcnRUaXRsZU9wdGlvbnMgPSBvcHRpb25zLnRpdGxlID0gbWVyZ2Uob3B0aW9ucy50aXRsZSwgdGl0bGVPcHRpb25zKTtcblx0XHRjaGFydFN1YnRpdGxlT3B0aW9ucyA9IG9wdGlvbnMuc3VidGl0bGUgPSBtZXJnZShvcHRpb25zLnN1YnRpdGxlLCBzdWJ0aXRsZU9wdGlvbnMpO1xuXG5cdFx0Ly8gYWRkIHRpdGxlIGFuZCBzdWJ0aXRsZVxuXHRcdGVhY2goW1xuXHRcdFx0Wyd0aXRsZScsIHRpdGxlT3B0aW9ucywgY2hhcnRUaXRsZU9wdGlvbnNdLFxuXHRcdFx0WydzdWJ0aXRsZScsIHN1YnRpdGxlT3B0aW9ucywgY2hhcnRTdWJ0aXRsZU9wdGlvbnNdXG5cdFx0XSwgZnVuY3Rpb24gKGFycikge1xuXHRcdFx0dmFyIG5hbWUgPSBhcnJbMF0sXG5cdFx0XHRcdHRpdGxlID0gY2hhcnRbbmFtZV0sXG5cdFx0XHRcdHRpdGxlT3B0aW9ucyA9IGFyclsxXSxcblx0XHRcdFx0Y2hhcnRUaXRsZU9wdGlvbnMgPSBhcnJbMl07XG5cblx0XHRcdGlmICh0aXRsZSAmJiB0aXRsZU9wdGlvbnMpIHtcblx0XHRcdFx0Y2hhcnRbbmFtZV0gPSB0aXRsZSA9IHRpdGxlLmRlc3Ryb3koKTsgLy8gcmVtb3ZlIG9sZFxuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHRpZiAoY2hhcnRUaXRsZU9wdGlvbnMgJiYgY2hhcnRUaXRsZU9wdGlvbnMudGV4dCAmJiAhdGl0bGUpIHtcblx0XHRcdFx0Y2hhcnRbbmFtZV0gPSBjaGFydC5yZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRcdGNoYXJ0VGl0bGVPcHRpb25zLnRleHQsXG5cdFx0XHRcdFx0MCxcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdGNoYXJ0VGl0bGVPcHRpb25zLnVzZUhUTUxcblx0XHRcdFx0KVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0YWxpZ246IGNoYXJ0VGl0bGVPcHRpb25zLmFsaWduLFxuXHRcdFx0XHRcdCdjbGFzcyc6IFBSRUZJWCArIG5hbWUsXG5cdFx0XHRcdFx0ekluZGV4OiBjaGFydFRpdGxlT3B0aW9ucy56SW5kZXggfHwgNFxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuY3NzKGNoYXJ0VGl0bGVPcHRpb25zLnN0eWxlKVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0XHR9XHRcblx0XHR9KTtcblx0XHRjaGFydC5sYXlPdXRUaXRsZXMocmVkcmF3KTtcblx0fSxcblxuXHQvKipcblx0ICogTGF5IG91dCB0aGUgY2hhcnQgdGl0bGVzIGFuZCBjYWNoZSB0aGUgZnVsbCBvZmZzZXQgaGVpZ2h0IGZvciB1c2UgaW4gZ2V0TWFyZ2luc1xuXHQgKi9cblx0bGF5T3V0VGl0bGVzOiBmdW5jdGlvbiAocmVkcmF3KSB7XG5cdFx0dmFyIHRpdGxlT2Zmc2V0ID0gMCxcblx0XHRcdHRpdGxlID0gdGhpcy50aXRsZSxcblx0XHRcdHN1YnRpdGxlID0gdGhpcy5zdWJ0aXRsZSxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHR0aXRsZU9wdGlvbnMgPSBvcHRpb25zLnRpdGxlLFxuXHRcdFx0c3VidGl0bGVPcHRpb25zID0gb3B0aW9ucy5zdWJ0aXRsZSxcblx0XHRcdHJlcXVpcmVzRGlydHlCb3gsXG5cdFx0XHRyZW5kZXJlciA9IHRoaXMucmVuZGVyZXIsXG5cdFx0XHRhdXRvV2lkdGggPSB0aGlzLnNwYWNpbmdCb3gud2lkdGggLSA0NDsgLy8gNDQgbWFrZXMgcm9vbSBmb3IgZGVmYXVsdCBjb250ZXh0IGJ1dHRvblxuXG5cdFx0aWYgKHRpdGxlKSB7XG5cdFx0XHR0aXRsZVxuXHRcdFx0XHQuY3NzKHsgd2lkdGg6ICh0aXRsZU9wdGlvbnMud2lkdGggfHwgYXV0b1dpZHRoKSArIFBYIH0pXG5cdFx0XHRcdC5hbGlnbihleHRlbmQoeyBcblx0XHRcdFx0XHR5OiByZW5kZXJlci5mb250TWV0cmljcyh0aXRsZU9wdGlvbnMuc3R5bGUuZm9udFNpemUsIHRpdGxlKS5iIC0gM1xuXHRcdFx0XHR9LCB0aXRsZU9wdGlvbnMpLCBmYWxzZSwgJ3NwYWNpbmdCb3gnKTtcblx0XHRcdFxuXHRcdFx0aWYgKCF0aXRsZU9wdGlvbnMuZmxvYXRpbmcgJiYgIXRpdGxlT3B0aW9ucy52ZXJ0aWNhbEFsaWduKSB7XG5cdFx0XHRcdHRpdGxlT2Zmc2V0ID0gdGl0bGUuZ2V0QkJveCgpLmhlaWdodDtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKHN1YnRpdGxlKSB7XG5cdFx0XHRzdWJ0aXRsZVxuXHRcdFx0XHQuY3NzKHsgd2lkdGg6IChzdWJ0aXRsZU9wdGlvbnMud2lkdGggfHwgYXV0b1dpZHRoKSArIFBYIH0pXG5cdFx0XHRcdC5hbGlnbihleHRlbmQoeyBcblx0XHRcdFx0XHR5OiB0aXRsZU9mZnNldCArICh0aXRsZU9wdGlvbnMubWFyZ2luIC0gMTMpICsgcmVuZGVyZXIuZm9udE1ldHJpY3ModGl0bGVPcHRpb25zLnN0eWxlLmZvbnRTaXplLCBzdWJ0aXRsZSkuYiBcblx0XHRcdFx0fSwgc3VidGl0bGVPcHRpb25zKSwgZmFsc2UsICdzcGFjaW5nQm94Jyk7XG5cdFx0XHRcblx0XHRcdGlmICghc3VidGl0bGVPcHRpb25zLmZsb2F0aW5nICYmICFzdWJ0aXRsZU9wdGlvbnMudmVydGljYWxBbGlnbikge1xuXHRcdFx0XHR0aXRsZU9mZnNldCA9IG1hdGhDZWlsKHRpdGxlT2Zmc2V0ICsgc3VidGl0bGUuZ2V0QkJveCgpLmhlaWdodCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmVxdWlyZXNEaXJ0eUJveCA9IHRoaXMudGl0bGVPZmZzZXQgIT09IHRpdGxlT2Zmc2V0O1x0XHRcdFx0XG5cdFx0dGhpcy50aXRsZU9mZnNldCA9IHRpdGxlT2Zmc2V0OyAvLyB1c2VkIGluIGdldE1hcmdpbnNcblxuXHRcdGlmICghdGhpcy5pc0RpcnR5Qm94ICYmIHJlcXVpcmVzRGlydHlCb3gpIHtcblx0XHRcdHRoaXMuaXNEaXJ0eUJveCA9IHJlcXVpcmVzRGlydHlCb3g7XG5cdFx0XHQvLyBSZWRyYXcgaWYgbmVjZXNzYXJ5ICgjMjcxOSwgIzI3NDQpXHRcdFxuXHRcdFx0aWYgKHRoaXMuaGFzUmVuZGVyZWQgJiYgcGljayhyZWRyYXcsIHRydWUpICYmIHRoaXMuaXNEaXJ0eUJveCkge1xuXHRcdFx0XHR0aGlzLnJlZHJhdygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogR2V0IGNoYXJ0IHdpZHRoIGFuZCBoZWlnaHQgYWNjb3JkaW5nIHRvIG9wdGlvbnMgYW5kIGNvbnRhaW5lciBzaXplXG5cdCAqL1xuXHRnZXRDaGFydFNpemU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0b3B0aW9uc0NoYXJ0ID0gY2hhcnQub3B0aW9ucy5jaGFydCxcblx0XHRcdHdpZHRoT3B0aW9uID0gb3B0aW9uc0NoYXJ0LndpZHRoLFxuXHRcdFx0aGVpZ2h0T3B0aW9uID0gb3B0aW9uc0NoYXJ0LmhlaWdodCxcblx0XHRcdHJlbmRlclRvID0gY2hhcnQucmVuZGVyVG9DbG9uZSB8fCBjaGFydC5yZW5kZXJUbztcblxuXHRcdC8vIGdldCBpbm5lciB3aWR0aCBhbmQgaGVpZ2h0IGZyb20galF1ZXJ5ICgjODI0KVxuXHRcdGlmICghZGVmaW5lZCh3aWR0aE9wdGlvbikpIHtcblx0XHRcdGNoYXJ0LmNvbnRhaW5lcldpZHRoID0gYWRhcHRlclJ1bihyZW5kZXJUbywgJ3dpZHRoJyk7XG5cdFx0fVxuXHRcdGlmICghZGVmaW5lZChoZWlnaHRPcHRpb24pKSB7XG5cdFx0XHRjaGFydC5jb250YWluZXJIZWlnaHQgPSBhZGFwdGVyUnVuKHJlbmRlclRvLCAnaGVpZ2h0Jyk7XG5cdFx0fVxuXHRcdFxuXHRcdGNoYXJ0LmNoYXJ0V2lkdGggPSBtYXRoTWF4KDAsIHdpZHRoT3B0aW9uIHx8IGNoYXJ0LmNvbnRhaW5lcldpZHRoIHx8IDYwMCk7IC8vICMxMzkzLCAxNDYwXG5cdFx0Y2hhcnQuY2hhcnRIZWlnaHQgPSBtYXRoTWF4KDAsIHBpY2soaGVpZ2h0T3B0aW9uLFxuXHRcdFx0Ly8gdGhlIG9mZnNldEhlaWdodCBvZiBhbiBlbXB0eSBjb250YWluZXIgaXMgMCBpbiBzdGFuZGFyZCBicm93c2VycywgYnV0IDE5IGluIElFNzpcblx0XHRcdGNoYXJ0LmNvbnRhaW5lckhlaWdodCA+IDE5ID8gY2hhcnQuY29udGFpbmVySGVpZ2h0IDogNDAwKSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIGNsb25lIG9mIHRoZSBjaGFydCdzIHJlbmRlclRvIGRpdiBhbmQgcGxhY2UgaXQgb3V0c2lkZSB0aGUgdmlld3BvcnQgdG8gYWxsb3dcblx0ICogc2l6ZSBjb21wdXRhdGlvbiBvbiBjaGFydC5yZW5kZXIgYW5kIGNoYXJ0LnJlZHJhd1xuXHQgKi9cblx0Y2xvbmVSZW5kZXJUbzogZnVuY3Rpb24gKHJldmVydCkge1xuXHRcdHZhciBjbG9uZSA9IHRoaXMucmVuZGVyVG9DbG9uZSxcblx0XHRcdGNvbnRhaW5lciA9IHRoaXMuY29udGFpbmVyO1xuXHRcdFxuXHRcdC8vIERlc3Ryb3kgdGhlIGNsb25lIGFuZCBicmluZyB0aGUgY29udGFpbmVyIGJhY2sgdG8gdGhlIHJlYWwgcmVuZGVyVG8gZGl2XG5cdFx0aWYgKHJldmVydCkge1xuXHRcdFx0aWYgKGNsb25lKSB7XG5cdFx0XHRcdHRoaXMucmVuZGVyVG8uYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblx0XHRcdFx0ZGlzY2FyZEVsZW1lbnQoY2xvbmUpO1xuXHRcdFx0XHRkZWxldGUgdGhpcy5yZW5kZXJUb0Nsb25lO1xuXHRcdFx0fVxuXHRcdFxuXHRcdC8vIFNldCB1cCB0aGUgY2xvbmVcblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKGNvbnRhaW5lciAmJiBjb250YWluZXIucGFyZW50Tm9kZSA9PT0gdGhpcy5yZW5kZXJUbykge1xuXHRcdFx0XHR0aGlzLnJlbmRlclRvLnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7IC8vIGRvIG5vdCBjbG9uZSB0aGlzXG5cdFx0XHR9XG5cdFx0XHR0aGlzLnJlbmRlclRvQ2xvbmUgPSBjbG9uZSA9IHRoaXMucmVuZGVyVG8uY2xvbmVOb2RlKDApO1xuXHRcdFx0Y3NzKGNsb25lLCB7XG5cdFx0XHRcdHBvc2l0aW9uOiBBQlNPTFVURSxcblx0XHRcdFx0dG9wOiAnLTk5OTlweCcsXG5cdFx0XHRcdGRpc3BsYXk6ICdibG9jaycgLy8gIzgzM1xuXHRcdFx0fSk7XG5cdFx0XHRpZiAoY2xvbmUuc3R5bGUuc2V0UHJvcGVydHkpIHsgLy8gIzI2MzFcblx0XHRcdFx0Y2xvbmUuc3R5bGUuc2V0UHJvcGVydHkoJ2Rpc3BsYXknLCAnYmxvY2snLCAnaW1wb3J0YW50Jyk7XG5cdFx0XHR9XG5cdFx0XHRkb2MuYm9keS5hcHBlbmRDaGlsZChjbG9uZSk7XG5cdFx0XHRpZiAoY29udGFpbmVyKSB7XG5cdFx0XHRcdGNsb25lLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGNvbnRhaW5pbmcgZWxlbWVudCwgZGV0ZXJtaW5lIHRoZSBzaXplIGFuZCBjcmVhdGUgdGhlIGlubmVyIGNvbnRhaW5lclxuXHQgKiBkaXYgdG8gaG9sZCB0aGUgY2hhcnRcblx0ICovXG5cdGdldENvbnRhaW5lcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRjb250YWluZXIsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0Y2hhcnRXaWR0aCxcblx0XHRcdGNoYXJ0SGVpZ2h0LFxuXHRcdFx0cmVuZGVyVG8sXG5cdFx0XHRpbmRleEF0dHJOYW1lID0gJ2RhdGEtaGlnaGNoYXJ0cy1jaGFydCcsXG5cdFx0XHRvbGRDaGFydEluZGV4LFxuXHRcdFx0Y29udGFpbmVySWQ7XG5cblx0XHRjaGFydC5yZW5kZXJUbyA9IHJlbmRlclRvID0gb3B0aW9uc0NoYXJ0LnJlbmRlclRvO1xuXHRcdGNvbnRhaW5lcklkID0gUFJFRklYICsgaWRDb3VudGVyKys7XG5cblx0XHRpZiAoaXNTdHJpbmcocmVuZGVyVG8pKSB7XG5cdFx0XHRjaGFydC5yZW5kZXJUbyA9IHJlbmRlclRvID0gZG9jLmdldEVsZW1lbnRCeUlkKHJlbmRlclRvKTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gRGlzcGxheSBhbiBlcnJvciBpZiB0aGUgcmVuZGVyVG8gaXMgd3Jvbmdcblx0XHRpZiAoIXJlbmRlclRvKSB7XG5cdFx0XHRlcnJvcigxMywgdHJ1ZSk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIElmIHRoZSBjb250YWluZXIgYWxyZWFkeSBob2xkcyBhIGNoYXJ0LCBkZXN0cm95IGl0LiBUaGUgY2hlY2sgZm9yIGhhc1JlbmRlcmVkIGlzIHRoZXJlXG5cdFx0Ly8gYmVjYXVzZSB3ZWIgcGFnZXMgdGhhdCBhcmUgc2F2ZWQgdG8gZGlzayBmcm9tIHRoZSBicm93c2VyLCB3aWxsIHByZXNlcnZlIHRoZSBkYXRhLWhpZ2hjaGFydHMtY2hhcnRcblx0XHQvLyBhdHRyaWJ1dGUgYW5kIHRoZSBTVkcgY29udGVudHMsIGJ1dCBub3QgYW4gaW50ZXJhY3RpdmUgY2hhcnQuIFNvIGluIHRoaXMgY2FzZSxcblx0XHQvLyBjaGFydHNbb2xkQ2hhcnRJbmRleF0gd2lsbCBwb2ludCB0byB0aGUgd3JvbmcgY2hhcnQgaWYgYW55ICgjMjYwOSkuXG5cdFx0b2xkQ2hhcnRJbmRleCA9IHBJbnQoYXR0cihyZW5kZXJUbywgaW5kZXhBdHRyTmFtZSkpO1xuXHRcdGlmICghaXNOYU4ob2xkQ2hhcnRJbmRleCkgJiYgY2hhcnRzW29sZENoYXJ0SW5kZXhdICYmIGNoYXJ0c1tvbGRDaGFydEluZGV4XS5oYXNSZW5kZXJlZCkge1xuXHRcdFx0Y2hhcnRzW29sZENoYXJ0SW5kZXhdLmRlc3Ryb3koKTtcblx0XHR9XHRcdFxuXHRcdFxuXHRcdC8vIE1ha2UgYSByZWZlcmVuY2UgdG8gdGhlIGNoYXJ0IGZyb20gdGhlIGRpdlxuXHRcdGF0dHIocmVuZGVyVG8sIGluZGV4QXR0ck5hbWUsIGNoYXJ0LmluZGV4KTtcblxuXHRcdC8vIHJlbW92ZSBwcmV2aW91cyBjaGFydFxuXHRcdHJlbmRlclRvLmlubmVySFRNTCA9ICcnO1xuXG5cdFx0Ly8gSWYgdGhlIGNvbnRhaW5lciBkb2Vzbid0IGhhdmUgYW4gb2Zmc2V0V2lkdGgsIGl0IGhhcyBvciBpcyBhIGNoaWxkIG9mIGEgbm9kZVxuXHRcdC8vIHRoYXQgaGFzIGRpc3BsYXk6bm9uZS4gV2UgbmVlZCB0byB0ZW1wb3JhcmlseSBtb3ZlIGl0IG91dCB0byBhIHZpc2libGVcblx0XHQvLyBzdGF0ZSB0byBkZXRlcm1pbmUgdGhlIHNpemUsIGVsc2UgdGhlIGxlZ2VuZCBhbmQgdG9vbHRpcHMgd29uJ3QgcmVuZGVyXG5cdFx0Ly8gcHJvcGVybHkuIFRoZSBhbGxvd0Nsb25lIG9wdGlvbiBpcyB1c2VkIGluIHNwYXJrbGluZXMgYXMgYSBtaWNybyBvcHRpbWl6YXRpb24sXG5cdFx0Ly8gc2F2aW5nIGFib3V0IDEtMiBtcyBlYWNoIGNoYXJ0LlxuXHRcdGlmICghb3B0aW9uc0NoYXJ0LnNraXBDbG9uZSAmJiAhcmVuZGVyVG8ub2Zmc2V0V2lkdGgpIHtcblx0XHRcdGNoYXJ0LmNsb25lUmVuZGVyVG8oKTtcblx0XHR9XG5cblx0XHQvLyBnZXQgdGhlIHdpZHRoIGFuZCBoZWlnaHRcblx0XHRjaGFydC5nZXRDaGFydFNpemUoKTtcblx0XHRjaGFydFdpZHRoID0gY2hhcnQuY2hhcnRXaWR0aDtcblx0XHRjaGFydEhlaWdodCA9IGNoYXJ0LmNoYXJ0SGVpZ2h0O1xuXG5cdFx0Ly8gY3JlYXRlIHRoZSBpbm5lciBjb250YWluZXJcblx0XHRjaGFydC5jb250YWluZXIgPSBjb250YWluZXIgPSBjcmVhdGVFbGVtZW50KERJViwge1xuXHRcdFx0XHRjbGFzc05hbWU6IFBSRUZJWCArICdjb250YWluZXInICtcblx0XHRcdFx0XHQob3B0aW9uc0NoYXJ0LmNsYXNzTmFtZSA/ICcgJyArIG9wdGlvbnNDaGFydC5jbGFzc05hbWUgOiAnJyksXG5cdFx0XHRcdGlkOiBjb250YWluZXJJZFxuXHRcdFx0fSwgZXh0ZW5kKHtcblx0XHRcdFx0cG9zaXRpb246IFJFTEFUSVZFLFxuXHRcdFx0XHRvdmVyZmxvdzogSElEREVOLCAvLyBuZWVkZWQgZm9yIGNvbnRleHQgbWVudSAoYXZvaWQgc2Nyb2xsYmFycykgYW5kXG5cdFx0XHRcdFx0Ly8gY29udGVudCBvdmVyZmxvdyBpbiBJRVxuXHRcdFx0XHR3aWR0aDogY2hhcnRXaWR0aCArIFBYLFxuXHRcdFx0XHRoZWlnaHQ6IGNoYXJ0SGVpZ2h0ICsgUFgsXG5cdFx0XHRcdHRleHRBbGlnbjogJ2xlZnQnLFxuXHRcdFx0XHRsaW5lSGVpZ2h0OiAnbm9ybWFsJywgLy8gIzQyN1xuXHRcdFx0XHR6SW5kZXg6IDAsIC8vICMxMDcyXG5cdFx0XHRcdCctd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3InOiAncmdiYSgwLDAsMCwwKSdcblx0XHRcdH0sIG9wdGlvbnNDaGFydC5zdHlsZSksXG5cdFx0XHRjaGFydC5yZW5kZXJUb0Nsb25lIHx8IHJlbmRlclRvXG5cdFx0KTtcblxuXHRcdC8vIGNhY2hlIHRoZSBjdXJzb3IgKCMxNjUwKVxuXHRcdGNoYXJ0Ll9jdXJzb3IgPSBjb250YWluZXIuc3R5bGUuY3Vyc29yO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgcmVuZGVyZXJcblx0XHRjaGFydC5yZW5kZXJlciA9XG5cdFx0XHRvcHRpb25zQ2hhcnQuZm9yRXhwb3J0ID8gLy8gZm9yY2UgU1ZHLCB1c2VkIGZvciBTVkcgZXhwb3J0XG5cdFx0XHRcdG5ldyBTVkdSZW5kZXJlcihjb250YWluZXIsIGNoYXJ0V2lkdGgsIGNoYXJ0SGVpZ2h0LCBvcHRpb25zQ2hhcnQuc3R5bGUsIHRydWUpIDpcblx0XHRcdFx0bmV3IFJlbmRlcmVyKGNvbnRhaW5lciwgY2hhcnRXaWR0aCwgY2hhcnRIZWlnaHQsIG9wdGlvbnNDaGFydC5zdHlsZSk7XG5cblx0XHRpZiAodXNlQ2FuVkcpIHtcblx0XHRcdC8vIElmIHdlIG5lZWQgY2FudmcgbGlicmFyeSwgZXh0ZW5kIGFuZCBjb25maWd1cmUgdGhlIHJlbmRlcmVyXG5cdFx0XHQvLyB0byBnZXQgdGhlIHRyYWNrZXIgZm9yIHRyYW5zbGF0aW5nIG1vdXNlIGV2ZW50c1xuXHRcdFx0Y2hhcnQucmVuZGVyZXIuY3JlYXRlKGNoYXJ0LCBjb250YWluZXIsIGNoYXJ0V2lkdGgsIGNoYXJ0SGVpZ2h0KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZSBtYXJnaW5zIGJ5IHJlbmRlcmluZyBheGlzIGxhYmVscyBpbiBhIHByZWxpbWluYXJ5IHBvc2l0aW9uLiBUaXRsZSxcblx0ICogc3VidGl0bGUgYW5kIGxlZ2VuZCBoYXZlIGFscmVhZHkgYmVlbiByZW5kZXJlZCBhdCB0aGlzIHN0YWdlLCBidXQgd2lsbCBiZVxuXHQgKiBtb3ZlZCBpbnRvIHRoZWlyIGZpbmFsIHBvc2l0aW9uc1xuXHQgKi9cblx0Z2V0TWFyZ2luczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRzcGFjaW5nID0gY2hhcnQuc3BhY2luZyxcblx0XHRcdGF4aXNPZmZzZXQsXG5cdFx0XHRsZWdlbmQgPSBjaGFydC5sZWdlbmQsXG5cdFx0XHRtYXJnaW4gPSBjaGFydC5tYXJnaW4sXG5cdFx0XHRsZWdlbmRPcHRpb25zID0gY2hhcnQub3B0aW9ucy5sZWdlbmQsXG5cdFx0XHRsZWdlbmRNYXJnaW4gPSBwaWNrKGxlZ2VuZE9wdGlvbnMubWFyZ2luLCAyMCksXG5cdFx0XHRsZWdlbmRYID0gbGVnZW5kT3B0aW9ucy54LFxuXHRcdFx0bGVnZW5kWSA9IGxlZ2VuZE9wdGlvbnMueSxcblx0XHRcdGFsaWduID0gbGVnZW5kT3B0aW9ucy5hbGlnbixcblx0XHRcdHZlcnRpY2FsQWxpZ24gPSBsZWdlbmRPcHRpb25zLnZlcnRpY2FsQWxpZ24sXG5cdFx0XHR0aXRsZU9mZnNldCA9IGNoYXJ0LnRpdGxlT2Zmc2V0O1xuXG5cdFx0Y2hhcnQucmVzZXRNYXJnaW5zKCk7XG5cdFx0YXhpc09mZnNldCA9IGNoYXJ0LmF4aXNPZmZzZXQ7XG5cblx0XHQvLyBBZGp1c3QgZm9yIHRpdGxlIGFuZCBzdWJ0aXRsZVxuXHRcdGlmICh0aXRsZU9mZnNldCAmJiAhZGVmaW5lZChtYXJnaW5bMF0pKSB7XG5cdFx0XHRjaGFydC5wbG90VG9wID0gbWF0aE1heChjaGFydC5wbG90VG9wLCB0aXRsZU9mZnNldCArIGNoYXJ0Lm9wdGlvbnMudGl0bGUubWFyZ2luICsgc3BhY2luZ1swXSk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIEFkanVzdCBmb3IgbGVnZW5kXG5cdFx0aWYgKGxlZ2VuZC5kaXNwbGF5ICYmICFsZWdlbmRPcHRpb25zLmZsb2F0aW5nKSB7XG5cdFx0XHRpZiAoYWxpZ24gPT09ICdyaWdodCcpIHsgLy8gaG9yaXpvbnRhbCBhbGlnbm1lbnQgaGFuZGxlZCBmaXJzdFxuXHRcdFx0XHRpZiAoIWRlZmluZWQobWFyZ2luWzFdKSkge1xuXHRcdFx0XHRcdGNoYXJ0Lm1hcmdpblJpZ2h0ID0gbWF0aE1heChcblx0XHRcdFx0XHRcdGNoYXJ0Lm1hcmdpblJpZ2h0LFxuXHRcdFx0XHRcdFx0bGVnZW5kLmxlZ2VuZFdpZHRoIC0gbGVnZW5kWCArIGxlZ2VuZE1hcmdpbiArIHNwYWNpbmdbMV1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2UgaWYgKGFsaWduID09PSAnbGVmdCcpIHtcblx0XHRcdFx0aWYgKCFkZWZpbmVkKG1hcmdpblszXSkpIHtcblx0XHRcdFx0XHRjaGFydC5wbG90TGVmdCA9IG1hdGhNYXgoXG5cdFx0XHRcdFx0XHRjaGFydC5wbG90TGVmdCxcblx0XHRcdFx0XHRcdGxlZ2VuZC5sZWdlbmRXaWR0aCArIGxlZ2VuZFggKyBsZWdlbmRNYXJnaW4gKyBzcGFjaW5nWzNdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKHZlcnRpY2FsQWxpZ24gPT09ICd0b3AnKSB7XG5cdFx0XHRcdGlmICghZGVmaW5lZChtYXJnaW5bMF0pKSB7XG5cdFx0XHRcdFx0Y2hhcnQucGxvdFRvcCA9IG1hdGhNYXgoXG5cdFx0XHRcdFx0XHRjaGFydC5wbG90VG9wLFxuXHRcdFx0XHRcdFx0bGVnZW5kLmxlZ2VuZEhlaWdodCArIGxlZ2VuZFkgKyBsZWdlbmRNYXJnaW4gKyBzcGFjaW5nWzBdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKHZlcnRpY2FsQWxpZ24gPT09ICdib3R0b20nKSB7XG5cdFx0XHRcdGlmICghZGVmaW5lZChtYXJnaW5bMl0pKSB7XG5cdFx0XHRcdFx0Y2hhcnQubWFyZ2luQm90dG9tID0gbWF0aE1heChcblx0XHRcdFx0XHRcdGNoYXJ0Lm1hcmdpbkJvdHRvbSxcblx0XHRcdFx0XHRcdGxlZ2VuZC5sZWdlbmRIZWlnaHQgLSBsZWdlbmRZICsgbGVnZW5kTWFyZ2luICsgc3BhY2luZ1syXVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBhZGp1c3QgZm9yIHNjcm9sbGVyXG5cdFx0aWYgKGNoYXJ0LmV4dHJhQm90dG9tTWFyZ2luKSB7XG5cdFx0XHRjaGFydC5tYXJnaW5Cb3R0b20gKz0gY2hhcnQuZXh0cmFCb3R0b21NYXJnaW47XG5cdFx0fVxuXHRcdGlmIChjaGFydC5leHRyYVRvcE1hcmdpbikge1xuXHRcdFx0Y2hhcnQucGxvdFRvcCArPSBjaGFydC5leHRyYVRvcE1hcmdpbjtcblx0XHR9XG5cblx0XHQvLyBwcmUtcmVuZGVyIGF4ZXMgdG8gZ2V0IGxhYmVscyBvZmZzZXQgd2lkdGhcblx0XHRpZiAoY2hhcnQuaGFzQ2FydGVzaWFuU2VyaWVzKSB7XG5cdFx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdGF4aXMuZ2V0T2Zmc2V0KCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0XG5cdFx0aWYgKCFkZWZpbmVkKG1hcmdpblszXSkpIHtcblx0XHRcdGNoYXJ0LnBsb3RMZWZ0ICs9IGF4aXNPZmZzZXRbM107XG5cdFx0fVxuXHRcdGlmICghZGVmaW5lZChtYXJnaW5bMF0pKSB7XG5cdFx0XHRjaGFydC5wbG90VG9wICs9IGF4aXNPZmZzZXRbMF07XG5cdFx0fVxuXHRcdGlmICghZGVmaW5lZChtYXJnaW5bMl0pKSB7XG5cdFx0XHRjaGFydC5tYXJnaW5Cb3R0b20gKz0gYXhpc09mZnNldFsyXTtcblx0XHR9XG5cdFx0aWYgKCFkZWZpbmVkKG1hcmdpblsxXSkpIHtcblx0XHRcdGNoYXJ0Lm1hcmdpblJpZ2h0ICs9IGF4aXNPZmZzZXRbMV07XG5cdFx0fVxuXG5cdFx0Y2hhcnQuc2V0Q2hhcnRTaXplKCk7XG5cblx0fSxcblxuXHQvKipcblx0ICogUmVzaXplIHRoZSBjaGFydCB0byBpdHMgY29udGFpbmVyIGlmIHNpemUgaXMgbm90IGV4cGxpY2l0bHkgc2V0XG5cdCAqL1xuXHRyZWZsb3c6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnNDaGFydCA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQsXG5cdFx0XHRyZW5kZXJUbyA9IGNoYXJ0LnJlbmRlclRvLFxuXHRcdFx0d2lkdGggPSBvcHRpb25zQ2hhcnQud2lkdGggfHwgYWRhcHRlclJ1bihyZW5kZXJUbywgJ3dpZHRoJyksXG5cdFx0XHRoZWlnaHQgPSBvcHRpb25zQ2hhcnQuaGVpZ2h0IHx8IGFkYXB0ZXJSdW4ocmVuZGVyVG8sICdoZWlnaHQnKSxcblx0XHRcdHRhcmdldCA9IGUgPyBlLnRhcmdldCA6IHdpbiwgLy8gIzgwNSAtIE1vb1Rvb2xzIGRvZXNuJ3Qgc3VwcGx5IGVcblx0XHRcdGRvUmVmbG93ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoY2hhcnQuY29udGFpbmVyKSB7IC8vIEl0IG1heSBoYXZlIGJlZW4gZGVzdHJveWVkIGluIHRoZSBtZWFudGltZSAoIzEyNTcpXG5cdFx0XHRcdFx0Y2hhcnQuc2V0U2l6ZSh3aWR0aCwgaGVpZ2h0LCBmYWxzZSk7XG5cdFx0XHRcdFx0Y2hhcnQuaGFzVXNlclNpemUgPSBudWxsO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0XG5cdFx0Ly8gV2lkdGggYW5kIGhlaWdodCBjaGVja3MgZm9yIGRpc3BsYXk6bm9uZS4gVGFyZ2V0IGlzIGRvYyBpbiBJRTggYW5kIE9wZXJhLFxuXHRcdC8vIHdpbiBpbiBGaXJlZm94LCBDaHJvbWUgYW5kIElFOS5cblx0XHRpZiAoIWNoYXJ0Lmhhc1VzZXJTaXplICYmIHdpZHRoICYmIGhlaWdodCAmJiAodGFyZ2V0ID09PSB3aW4gfHwgdGFyZ2V0ID09PSBkb2MpKSB7XG5cdFx0XHRpZiAod2lkdGggIT09IGNoYXJ0LmNvbnRhaW5lcldpZHRoIHx8IGhlaWdodCAhPT0gY2hhcnQuY29udGFpbmVySGVpZ2h0KSB7XG5cdFx0XHRcdGNsZWFyVGltZW91dChjaGFydC5yZWZsb3dUaW1lb3V0KTtcblx0XHRcdFx0aWYgKGUpIHsgLy8gQ2FsbGVkIGZyb20gd2luZG93LnJlc2l6ZVxuXHRcdFx0XHRcdGNoYXJ0LnJlZmxvd1RpbWVvdXQgPSBzZXRUaW1lb3V0KGRvUmVmbG93LCAxMDApO1xuXHRcdFx0XHR9IGVsc2UgeyAvLyBDYWxsZWQgZGlyZWN0bHkgKCMyMjI0KVxuXHRcdFx0XHRcdGRvUmVmbG93KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGNoYXJ0LmNvbnRhaW5lcldpZHRoID0gd2lkdGg7XG5cdFx0XHRjaGFydC5jb250YWluZXJIZWlnaHQgPSBoZWlnaHQ7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgdGhlIGV2ZW50IGhhbmRsZXJzIG5lY2Vzc2FyeSBmb3IgYXV0byByZXNpemluZ1xuXHQgKi9cblx0aW5pdFJlZmxvdzogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRyZWZsb3cgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRjaGFydC5yZWZsb3coZSk7XG5cdFx0XHR9O1xuXHRcdFx0XG5cdFx0XG5cdFx0YWRkRXZlbnQod2luLCAncmVzaXplJywgcmVmbG93KTtcblx0XHRhZGRFdmVudChjaGFydCwgJ2Rlc3Ryb3knLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZW1vdmVFdmVudCh3aW4sICdyZXNpemUnLCByZWZsb3cpO1xuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXNpemUgdGhlIGNoYXJ0IHRvIGEgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodFxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKiBAcGFyYW0ge09iamVjdHxCb29sZWFufSBhbmltYXRpb25cblx0ICovXG5cdHNldFNpemU6IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0LCBhbmltYXRpb24pIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0Y2hhcnRXaWR0aCxcblx0XHRcdGNoYXJ0SGVpZ2h0LFxuXHRcdFx0ZmlyZUVuZFJlc2l6ZTtcblxuXHRcdC8vIEhhbmRsZSB0aGUgaXNSZXNpemluZyBjb3VudGVyXG5cdFx0Y2hhcnQuaXNSZXNpemluZyArPSAxO1xuXHRcdGZpcmVFbmRSZXNpemUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpZiAoY2hhcnQpIHtcblx0XHRcdFx0ZmlyZUV2ZW50KGNoYXJ0LCAnZW5kUmVzaXplJywgbnVsbCwgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGNoYXJ0LmlzUmVzaXppbmcgLT0gMTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdC8vIHNldCB0aGUgYW5pbWF0aW9uIGZvciB0aGUgY3VycmVudCBwcm9jZXNzXG5cdFx0c2V0QW5pbWF0aW9uKGFuaW1hdGlvbiwgY2hhcnQpO1xuXG5cdFx0Y2hhcnQub2xkQ2hhcnRIZWlnaHQgPSBjaGFydC5jaGFydEhlaWdodDtcblx0XHRjaGFydC5vbGRDaGFydFdpZHRoID0gY2hhcnQuY2hhcnRXaWR0aDtcblx0XHRpZiAoZGVmaW5lZCh3aWR0aCkpIHtcblx0XHRcdGNoYXJ0LmNoYXJ0V2lkdGggPSBjaGFydFdpZHRoID0gbWF0aE1heCgwLCBtYXRoUm91bmQod2lkdGgpKTtcblx0XHRcdGNoYXJ0Lmhhc1VzZXJTaXplID0gISFjaGFydFdpZHRoO1xuXHRcdH1cblx0XHRpZiAoZGVmaW5lZChoZWlnaHQpKSB7XG5cdFx0XHRjaGFydC5jaGFydEhlaWdodCA9IGNoYXJ0SGVpZ2h0ID0gbWF0aE1heCgwLCBtYXRoUm91bmQoaGVpZ2h0KSk7XG5cdFx0fVxuXG5cdFx0Ly8gUmVzaXplIHRoZSBjb250YWluZXIgd2l0aCB0aGUgZ2xvYmFsIGFuaW1hdGlvbiBhcHBsaWVkIGlmIGVuYWJsZWQgKCMyNTAzKVxuXHRcdChnbG9iYWxBbmltYXRpb24gPyBhbmltYXRlIDogY3NzKShjaGFydC5jb250YWluZXIsIHtcblx0XHRcdHdpZHRoOiBjaGFydFdpZHRoICsgUFgsXG5cdFx0XHRoZWlnaHQ6IGNoYXJ0SGVpZ2h0ICsgUFhcblx0XHR9LCBnbG9iYWxBbmltYXRpb24pO1xuXG5cdFx0Y2hhcnQuc2V0Q2hhcnRTaXplKHRydWUpO1xuXHRcdGNoYXJ0LnJlbmRlcmVyLnNldFNpemUoY2hhcnRXaWR0aCwgY2hhcnRIZWlnaHQsIGFuaW1hdGlvbik7XG5cblx0XHQvLyBoYW5kbGUgYXhlc1xuXHRcdGNoYXJ0Lm1heFRpY2tzID0gbnVsbDtcblx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRheGlzLmlzRGlydHkgPSB0cnVlO1xuXHRcdFx0YXhpcy5zZXRTY2FsZSgpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gbWFrZSBzdXJlIG5vbi1jYXJ0ZXNpYW4gc2VyaWVzIGFyZSBhbHNvIGhhbmRsZWRcblx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRzZXJpZS5pc0RpcnR5ID0gdHJ1ZTtcblx0XHR9KTtcblxuXHRcdGNoYXJ0LmlzRGlydHlMZWdlbmQgPSB0cnVlOyAvLyBmb3JjZSBsZWdlbmQgcmVkcmF3XG5cdFx0Y2hhcnQuaXNEaXJ0eUJveCA9IHRydWU7IC8vIGZvcmNlIHJlZHJhdyBvZiBwbG90IGFuZCBjaGFydCBib3JkZXJcblxuXHRcdGNoYXJ0LmxheU91dFRpdGxlcygpOyAvLyAjMjg1N1xuXHRcdGNoYXJ0LmdldE1hcmdpbnMoKTtcblxuXHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXG5cblx0XHRjaGFydC5vbGRDaGFydEhlaWdodCA9IG51bGw7XG5cdFx0ZmlyZUV2ZW50KGNoYXJ0LCAncmVzaXplJyk7XG5cblx0XHQvLyBmaXJlIGVuZFJlc2l6ZSBhbmQgc2V0IGlzUmVzaXppbmcgYmFja1xuXHRcdC8vIElmIGFuaW1hdGlvbiBpcyBkaXNhYmxlZCwgZmlyZSB3aXRob3V0IGRlbGF5XG5cdFx0aWYgKGdsb2JhbEFuaW1hdGlvbiA9PT0gZmFsc2UpIHtcblx0XHRcdGZpcmVFbmRSZXNpemUoKTtcblx0XHR9IGVsc2UgeyAvLyBlbHNlIHNldCBhIHRpbWVvdXQgd2l0aCB0aGUgYW5pbWF0aW9uIGR1cmF0aW9uXG5cdFx0XHRzZXRUaW1lb3V0KGZpcmVFbmRSZXNpemUsIChnbG9iYWxBbmltYXRpb24gJiYgZ2xvYmFsQW5pbWF0aW9uLmR1cmF0aW9uKSB8fCA1MDApO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBwdWJsaWMgY2hhcnQgcHJvcGVydGllcy4gVGhpcyBpcyBkb25lIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHByZS1yZW5kZXJcblx0ICogdG8gZGV0ZXJtaW5lIG1hcmdpbiBzaXplc1xuXHQgKi9cblx0c2V0Q2hhcnRTaXplOiBmdW5jdGlvbiAoc2tpcEF4ZXMpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0aW52ZXJ0ZWQgPSBjaGFydC5pbnZlcnRlZCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRjaGFydFdpZHRoID0gY2hhcnQuY2hhcnRXaWR0aCxcblx0XHRcdGNoYXJ0SGVpZ2h0ID0gY2hhcnQuY2hhcnRIZWlnaHQsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0c3BhY2luZyA9IGNoYXJ0LnNwYWNpbmcsXG5cdFx0XHRjbGlwT2Zmc2V0ID0gY2hhcnQuY2xpcE9mZnNldCxcblx0XHRcdGNsaXBYLFxuXHRcdFx0Y2xpcFksXG5cdFx0XHRwbG90TGVmdCxcblx0XHRcdHBsb3RUb3AsXG5cdFx0XHRwbG90V2lkdGgsXG5cdFx0XHRwbG90SGVpZ2h0LFxuXHRcdFx0cGxvdEJvcmRlcldpZHRoO1xuXG5cdFx0Y2hhcnQucGxvdExlZnQgPSBwbG90TGVmdCA9IG1hdGhSb3VuZChjaGFydC5wbG90TGVmdCk7XG5cdFx0Y2hhcnQucGxvdFRvcCA9IHBsb3RUb3AgPSBtYXRoUm91bmQoY2hhcnQucGxvdFRvcCk7XG5cdFx0Y2hhcnQucGxvdFdpZHRoID0gcGxvdFdpZHRoID0gbWF0aE1heCgwLCBtYXRoUm91bmQoY2hhcnRXaWR0aCAtIHBsb3RMZWZ0IC0gY2hhcnQubWFyZ2luUmlnaHQpKTtcblx0XHRjaGFydC5wbG90SGVpZ2h0ID0gcGxvdEhlaWdodCA9IG1hdGhNYXgoMCwgbWF0aFJvdW5kKGNoYXJ0SGVpZ2h0IC0gcGxvdFRvcCAtIGNoYXJ0Lm1hcmdpbkJvdHRvbSkpO1xuXG5cdFx0Y2hhcnQucGxvdFNpemVYID0gaW52ZXJ0ZWQgPyBwbG90SGVpZ2h0IDogcGxvdFdpZHRoO1xuXHRcdGNoYXJ0LnBsb3RTaXplWSA9IGludmVydGVkID8gcGxvdFdpZHRoIDogcGxvdEhlaWdodDtcblx0XHRcblx0XHRjaGFydC5wbG90Qm9yZGVyV2lkdGggPSBvcHRpb25zQ2hhcnQucGxvdEJvcmRlcldpZHRoIHx8IDA7XG5cblx0XHQvLyBTZXQgYm94ZXMgdXNlZCBmb3IgYWxpZ25tZW50XG5cdFx0Y2hhcnQuc3BhY2luZ0JveCA9IHJlbmRlcmVyLnNwYWNpbmdCb3ggPSB7XG5cdFx0XHR4OiBzcGFjaW5nWzNdLFxuXHRcdFx0eTogc3BhY2luZ1swXSxcblx0XHRcdHdpZHRoOiBjaGFydFdpZHRoIC0gc3BhY2luZ1szXSAtIHNwYWNpbmdbMV0sXG5cdFx0XHRoZWlnaHQ6IGNoYXJ0SGVpZ2h0IC0gc3BhY2luZ1swXSAtIHNwYWNpbmdbMl1cblx0XHR9O1xuXHRcdGNoYXJ0LnBsb3RCb3ggPSByZW5kZXJlci5wbG90Qm94ID0ge1xuXHRcdFx0eDogcGxvdExlZnQsXG5cdFx0XHR5OiBwbG90VG9wLFxuXHRcdFx0d2lkdGg6IHBsb3RXaWR0aCxcblx0XHRcdGhlaWdodDogcGxvdEhlaWdodFxuXHRcdH07XG5cblx0XHRwbG90Qm9yZGVyV2lkdGggPSAyICogbWF0aEZsb29yKGNoYXJ0LnBsb3RCb3JkZXJXaWR0aCAvIDIpO1xuXHRcdGNsaXBYID0gbWF0aENlaWwobWF0aE1heChwbG90Qm9yZGVyV2lkdGgsIGNsaXBPZmZzZXRbM10pIC8gMik7XG5cdFx0Y2xpcFkgPSBtYXRoQ2VpbChtYXRoTWF4KHBsb3RCb3JkZXJXaWR0aCwgY2xpcE9mZnNldFswXSkgLyAyKTtcblx0XHRjaGFydC5jbGlwQm94ID0ge1xuXHRcdFx0eDogY2xpcFgsIFxuXHRcdFx0eTogY2xpcFksIFxuXHRcdFx0d2lkdGg6IG1hdGhGbG9vcihjaGFydC5wbG90U2l6ZVggLSBtYXRoTWF4KHBsb3RCb3JkZXJXaWR0aCwgY2xpcE9mZnNldFsxXSkgLyAyIC0gY2xpcFgpLCBcblx0XHRcdGhlaWdodDogbWF0aE1heCgwLCBtYXRoRmxvb3IoY2hhcnQucGxvdFNpemVZIC0gbWF0aE1heChwbG90Qm9yZGVyV2lkdGgsIGNsaXBPZmZzZXRbMl0pIC8gMiAtIGNsaXBZKSlcblx0XHR9O1xuXG5cdFx0aWYgKCFza2lwQXhlcykge1xuXHRcdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRheGlzLnNldEF4aXNTaXplKCk7XG5cdFx0XHRcdGF4aXMuc2V0QXhpc1RyYW5zbGF0aW9uKCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEluaXRpYWwgbWFyZ2lucyBiZWZvcmUgYXV0byBzaXplIG1hcmdpbnMgYXJlIGFwcGxpZWRcblx0ICovXG5cdHJlc2V0TWFyZ2luczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRzcGFjaW5nID0gY2hhcnQuc3BhY2luZyxcblx0XHRcdG1hcmdpbiA9IGNoYXJ0Lm1hcmdpbjtcblxuXHRcdGNoYXJ0LnBsb3RUb3AgPSBwaWNrKG1hcmdpblswXSwgc3BhY2luZ1swXSk7XG5cdFx0Y2hhcnQubWFyZ2luUmlnaHQgPSBwaWNrKG1hcmdpblsxXSwgc3BhY2luZ1sxXSk7XG5cdFx0Y2hhcnQubWFyZ2luQm90dG9tID0gcGljayhtYXJnaW5bMl0sIHNwYWNpbmdbMl0pO1xuXHRcdGNoYXJ0LnBsb3RMZWZ0ID0gcGljayhtYXJnaW5bM10sIHNwYWNpbmdbM10pO1xuXHRcdGNoYXJ0LmF4aXNPZmZzZXQgPSBbMCwgMCwgMCwgMF07IC8vIHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdFxuXHRcdGNoYXJ0LmNsaXBPZmZzZXQgPSBbMCwgMCwgMCwgMF07XG5cdH0sXG5cblx0LyoqXG5cdCAqIERyYXcgdGhlIGJvcmRlcnMgYW5kIGJhY2tncm91bmRzIGZvciBjaGFydCBhbmQgcGxvdCBhcmVhXG5cdCAqL1xuXHRkcmF3Q2hhcnRCb3g6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0b3B0aW9uc0NoYXJ0ID0gY2hhcnQub3B0aW9ucy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRjaGFydFdpZHRoID0gY2hhcnQuY2hhcnRXaWR0aCxcblx0XHRcdGNoYXJ0SGVpZ2h0ID0gY2hhcnQuY2hhcnRIZWlnaHQsXG5cdFx0XHRjaGFydEJhY2tncm91bmQgPSBjaGFydC5jaGFydEJhY2tncm91bmQsXG5cdFx0XHRwbG90QmFja2dyb3VuZCA9IGNoYXJ0LnBsb3RCYWNrZ3JvdW5kLFxuXHRcdFx0cGxvdEJvcmRlciA9IGNoYXJ0LnBsb3RCb3JkZXIsXG5cdFx0XHRwbG90QkdJbWFnZSA9IGNoYXJ0LnBsb3RCR0ltYWdlLFxuXHRcdFx0Y2hhcnRCb3JkZXJXaWR0aCA9IG9wdGlvbnNDaGFydC5ib3JkZXJXaWR0aCB8fCAwLFxuXHRcdFx0Y2hhcnRCYWNrZ3JvdW5kQ29sb3IgPSBvcHRpb25zQ2hhcnQuYmFja2dyb3VuZENvbG9yLFxuXHRcdFx0cGxvdEJhY2tncm91bmRDb2xvciA9IG9wdGlvbnNDaGFydC5wbG90QmFja2dyb3VuZENvbG9yLFxuXHRcdFx0cGxvdEJhY2tncm91bmRJbWFnZSA9IG9wdGlvbnNDaGFydC5wbG90QmFja2dyb3VuZEltYWdlLFxuXHRcdFx0cGxvdEJvcmRlcldpZHRoID0gb3B0aW9uc0NoYXJ0LnBsb3RCb3JkZXJXaWR0aCB8fCAwLFxuXHRcdFx0bWduLFxuXHRcdFx0YmdBdHRyLFxuXHRcdFx0cGxvdExlZnQgPSBjaGFydC5wbG90TGVmdCxcblx0XHRcdHBsb3RUb3AgPSBjaGFydC5wbG90VG9wLFxuXHRcdFx0cGxvdFdpZHRoID0gY2hhcnQucGxvdFdpZHRoLFxuXHRcdFx0cGxvdEhlaWdodCA9IGNoYXJ0LnBsb3RIZWlnaHQsXG5cdFx0XHRwbG90Qm94ID0gY2hhcnQucGxvdEJveCxcblx0XHRcdGNsaXBSZWN0ID0gY2hhcnQuY2xpcFJlY3QsXG5cdFx0XHRjbGlwQm94ID0gY2hhcnQuY2xpcEJveDtcblxuXHRcdC8vIENoYXJ0IGFyZWFcblx0XHRtZ24gPSBjaGFydEJvcmRlcldpZHRoICsgKG9wdGlvbnNDaGFydC5zaGFkb3cgPyA4IDogMCk7XG5cblx0XHRpZiAoY2hhcnRCb3JkZXJXaWR0aCB8fCBjaGFydEJhY2tncm91bmRDb2xvcikge1xuXHRcdFx0aWYgKCFjaGFydEJhY2tncm91bmQpIHtcblx0XHRcdFx0XG5cdFx0XHRcdGJnQXR0ciA9IHtcblx0XHRcdFx0XHRmaWxsOiBjaGFydEJhY2tncm91bmRDb2xvciB8fCBOT05FXG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmIChjaGFydEJvcmRlcldpZHRoKSB7IC8vICM5ODBcblx0XHRcdFx0XHRiZ0F0dHIuc3Ryb2tlID0gb3B0aW9uc0NoYXJ0LmJvcmRlckNvbG9yO1xuXHRcdFx0XHRcdGJnQXR0clsnc3Ryb2tlLXdpZHRoJ10gPSBjaGFydEJvcmRlcldpZHRoO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNoYXJ0LmNoYXJ0QmFja2dyb3VuZCA9IHJlbmRlcmVyLnJlY3QobWduIC8gMiwgbWduIC8gMiwgY2hhcnRXaWR0aCAtIG1nbiwgY2hhcnRIZWlnaHQgLSBtZ24sXG5cdFx0XHRcdFx0XHRvcHRpb25zQ2hhcnQuYm9yZGVyUmFkaXVzLCBjaGFydEJvcmRlcldpZHRoKVxuXHRcdFx0XHRcdC5hdHRyKGJnQXR0cilcblx0XHRcdFx0XHQuYWRkQ2xhc3MoUFJFRklYICsgJ2JhY2tncm91bmQnKVxuXHRcdFx0XHRcdC5hZGQoKVxuXHRcdFx0XHRcdC5zaGFkb3cob3B0aW9uc0NoYXJ0LnNoYWRvdyk7XG5cblx0XHRcdH0gZWxzZSB7IC8vIHJlc2l6ZVxuXHRcdFx0XHRjaGFydEJhY2tncm91bmQuYW5pbWF0ZShcblx0XHRcdFx0XHRjaGFydEJhY2tncm91bmQuY3Jpc3AoeyB3aWR0aDogY2hhcnRXaWR0aCAtIG1nbiwgaGVpZ2h0OiBjaGFydEhlaWdodCAtIG1nbiB9KVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXG5cdFx0Ly8gUGxvdCBiYWNrZ3JvdW5kXG5cdFx0aWYgKHBsb3RCYWNrZ3JvdW5kQ29sb3IpIHtcblx0XHRcdGlmICghcGxvdEJhY2tncm91bmQpIHtcblx0XHRcdFx0Y2hhcnQucGxvdEJhY2tncm91bmQgPSByZW5kZXJlci5yZWN0KHBsb3RMZWZ0LCBwbG90VG9wLCBwbG90V2lkdGgsIHBsb3RIZWlnaHQsIDApXG5cdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0ZmlsbDogcGxvdEJhY2tncm91bmRDb2xvclxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmFkZCgpXG5cdFx0XHRcdFx0LnNoYWRvdyhvcHRpb25zQ2hhcnQucGxvdFNoYWRvdyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwbG90QmFja2dyb3VuZC5hbmltYXRlKHBsb3RCb3gpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAocGxvdEJhY2tncm91bmRJbWFnZSkge1xuXHRcdFx0aWYgKCFwbG90QkdJbWFnZSkge1xuXHRcdFx0XHRjaGFydC5wbG90QkdJbWFnZSA9IHJlbmRlcmVyLmltYWdlKHBsb3RCYWNrZ3JvdW5kSW1hZ2UsIHBsb3RMZWZ0LCBwbG90VG9wLCBwbG90V2lkdGgsIHBsb3RIZWlnaHQpXG5cdFx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cGxvdEJHSW1hZ2UuYW5pbWF0ZShwbG90Qm94KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0XG5cdFx0Ly8gUGxvdCBjbGlwXG5cdFx0aWYgKCFjbGlwUmVjdCkge1xuXHRcdFx0Y2hhcnQuY2xpcFJlY3QgPSByZW5kZXJlci5jbGlwUmVjdChjbGlwQm94KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2xpcFJlY3QuYW5pbWF0ZSh7XG5cdFx0XHRcdHdpZHRoOiBjbGlwQm94LndpZHRoLFxuXHRcdFx0XHRoZWlnaHQ6IGNsaXBCb3guaGVpZ2h0XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvLyBQbG90IGFyZWEgYm9yZGVyXG5cdFx0aWYgKHBsb3RCb3JkZXJXaWR0aCkge1xuXHRcdFx0aWYgKCFwbG90Qm9yZGVyKSB7XG5cdFx0XHRcdGNoYXJ0LnBsb3RCb3JkZXIgPSByZW5kZXJlci5yZWN0KHBsb3RMZWZ0LCBwbG90VG9wLCBwbG90V2lkdGgsIHBsb3RIZWlnaHQsIDAsIC1wbG90Qm9yZGVyV2lkdGgpXG5cdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0c3Ryb2tlOiBvcHRpb25zQ2hhcnQucGxvdEJvcmRlckNvbG9yLFxuXHRcdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IHBsb3RCb3JkZXJXaWR0aCxcblx0XHRcdFx0XHRcdGZpbGw6IE5PTkUsXG5cdFx0XHRcdFx0XHR6SW5kZXg6IDFcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5hZGQoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBsb3RCb3JkZXIuYW5pbWF0ZShcblx0XHRcdFx0XHRwbG90Qm9yZGVyLmNyaXNwKHsgeDogcGxvdExlZnQsIHk6IHBsb3RUb3AsIHdpZHRoOiBwbG90V2lkdGgsIGhlaWdodDogcGxvdEhlaWdodCwgc3Ryb2tlV2lkdGg6IC1wbG90Qm9yZGVyV2lkdGggfSkgLy8jMzI4MiBwbG90Qm9yZGVyIHNob3VsZCBiZSBuZWdhdGl2ZVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHJlc2V0XG5cdFx0Y2hhcnQuaXNEaXJ0eUJveCA9IGZhbHNlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXRlY3Qgd2hldGhlciBhIGNlcnRhaW4gY2hhcnQgcHJvcGVydHkgaXMgbmVlZGVkIGJhc2VkIG9uIGluc3BlY3RpbmcgaXRzIG9wdGlvbnNcblx0ICogYW5kIHNlcmllcy4gVGhpcyBtYWlubHkgYXBwbGllcyB0byB0aGUgY2hhcnQuaW52ZXJ0IHByb3BlcnR5LCBhbmQgaW4gZXh0ZW5zaW9ucyB0byBcblx0ICogdGhlIGNoYXJ0LmFuZ3VsYXIgYW5kIGNoYXJ0LnBvbGFyIHByb3BlcnRpZXMuXG5cdCAqL1xuXHRwcm9wRnJvbVNlcmllczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0a2xhc3MsXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gY2hhcnQub3B0aW9ucy5zZXJpZXMsXG5cdFx0XHRpLFxuXHRcdFx0dmFsdWU7XG5cdFx0XHRcblx0XHRcdFxuXHRcdGVhY2goWydpbnZlcnRlZCcsICdhbmd1bGFyJywgJ3BvbGFyJ10sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFxuXHRcdFx0Ly8gVGhlIGRlZmF1bHQgc2VyaWVzIHR5cGUncyBjbGFzc1xuXHRcdFx0a2xhc3MgPSBzZXJpZXNUeXBlc1tvcHRpb25zQ2hhcnQudHlwZSB8fCBvcHRpb25zQ2hhcnQuZGVmYXVsdFNlcmllc1R5cGVdO1xuXHRcdFx0XG5cdFx0XHQvLyBHZXQgdGhlIHZhbHVlIGZyb20gYXZhaWxhYmxlIGNoYXJ0LXdpZGUgcHJvcGVydGllc1xuXHRcdFx0dmFsdWUgPSAoXG5cdFx0XHRcdGNoYXJ0W2tleV0gfHwgLy8gMS4gaXQgaXMgc2V0IGJlZm9yZVxuXHRcdFx0XHRvcHRpb25zQ2hhcnRba2V5XSB8fCAvLyAyLiBpdCBpcyBzZXQgaW4gdGhlIG9wdGlvbnNcblx0XHRcdFx0KGtsYXNzICYmIGtsYXNzLnByb3RvdHlwZVtrZXldKSAvLyAzLiBpdCdzIGRlZmF1bHQgc2VyaWVzIGNsYXNzIHJlcXVpcmVzIGl0XG5cdFx0XHQpO1xuXHRcblx0XHRcdC8vIDQuIENoZWNrIGlmIGFueSB0aGUgY2hhcnQncyBzZXJpZXMgcmVxdWlyZSBpdFxuXHRcdFx0aSA9IHNlcmllc09wdGlvbnMgJiYgc2VyaWVzT3B0aW9ucy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIXZhbHVlICYmIGktLSkge1xuXHRcdFx0XHRrbGFzcyA9IHNlcmllc1R5cGVzW3Nlcmllc09wdGlvbnNbaV0udHlwZV07XG5cdFx0XHRcdGlmIChrbGFzcyAmJiBrbGFzcy5wcm90b3R5cGVba2V5XSkge1xuXHRcdFx0XHRcdHZhbHVlID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcblx0XHRcdC8vIFNldCB0aGUgY2hhcnQgcHJvcGVydHlcblx0XHRcdGNoYXJ0W2tleV0gPSB2YWx1ZTtcdFxuXHRcdH0pO1xuXHRcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBMaW5rIHR3byBvciBtb3JlIHNlcmllcyB0b2dldGhlci4gVGhpcyBpcyBkb25lIGluaXRpYWxseSBmcm9tIENoYXJ0LnJlbmRlcixcblx0ICogYW5kIGFmdGVyIENoYXJ0LmFkZFNlcmllcyBhbmQgU2VyaWVzLnJlbW92ZS5cblx0ICovXG5cdGxpbmtTZXJpZXM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0Y2hhcnRTZXJpZXMgPSBjaGFydC5zZXJpZXM7XG5cblx0XHQvLyBSZXNldCBsaW5rc1xuXHRcdGVhY2goY2hhcnRTZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdHNlcmllcy5saW5rZWRTZXJpZXMubGVuZ3RoID0gMDtcblx0XHR9KTtcblxuXHRcdC8vIEFwcGx5IG5ldyBsaW5rc1xuXHRcdGVhY2goY2hhcnRTZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdHZhciBsaW5rZWRUbyA9IHNlcmllcy5vcHRpb25zLmxpbmtlZFRvO1xuXHRcdFx0aWYgKGlzU3RyaW5nKGxpbmtlZFRvKSkge1xuXHRcdFx0XHRpZiAobGlua2VkVG8gPT09ICc6cHJldmlvdXMnKSB7XG5cdFx0XHRcdFx0bGlua2VkVG8gPSBjaGFydC5zZXJpZXNbc2VyaWVzLmluZGV4IC0gMV07XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bGlua2VkVG8gPSBjaGFydC5nZXQobGlua2VkVG8pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChsaW5rZWRUbykge1xuXHRcdFx0XHRcdGxpbmtlZFRvLmxpbmtlZFNlcmllcy5wdXNoKHNlcmllcyk7XG5cdFx0XHRcdFx0c2VyaWVzLmxpbmtlZFBhcmVudCA9IGxpbmtlZFRvO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciBzZXJpZXMgZm9yIHRoZSBjaGFydFxuXHQgKi9cblx0cmVuZGVyU2VyaWVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0ZWFjaCh0aGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRzZXJpZS50cmFuc2xhdGUoKTtcblx0XHRcdGlmIChzZXJpZS5zZXRUb29sdGlwUG9pbnRzKSB7XG5cdFx0XHRcdHNlcmllLnNldFRvb2x0aXBQb2ludHMoKTtcblx0XHRcdH1cblx0XHRcdHNlcmllLnJlbmRlcigpO1xuXHRcdH0pO1xuXHR9LFxuXHRcdFxuXHQvKipcblx0ICogUmVuZGVyIGxhYmVscyBmb3IgdGhlIGNoYXJ0XG5cdCAqL1xuXHRyZW5kZXJMYWJlbHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0bGFiZWxzID0gY2hhcnQub3B0aW9ucy5sYWJlbHM7XG5cdFx0aWYgKGxhYmVscy5pdGVtcykge1xuXHRcdFx0ZWFjaChsYWJlbHMuaXRlbXMsIGZ1bmN0aW9uIChsYWJlbCkge1xuXHRcdFx0XHR2YXIgc3R5bGUgPSBleHRlbmQobGFiZWxzLnN0eWxlLCBsYWJlbC5zdHlsZSksXG5cdFx0XHRcdFx0eCA9IHBJbnQoc3R5bGUubGVmdCkgKyBjaGFydC5wbG90TGVmdCxcblx0XHRcdFx0XHR5ID0gcEludChzdHlsZS50b3ApICsgY2hhcnQucGxvdFRvcCArIDEyO1xuXG5cdFx0XHRcdC8vIGRlbGV0ZSB0byBwcmV2ZW50IHJld3JpdGluZyBpbiBJRVxuXHRcdFx0XHRkZWxldGUgc3R5bGUubGVmdDtcblx0XHRcdFx0ZGVsZXRlIHN0eWxlLnRvcDtcblxuXHRcdFx0XHRjaGFydC5yZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRcdGxhYmVsLmh0bWwsXG5cdFx0XHRcdFx0eCxcblx0XHRcdFx0XHR5XG5cdFx0XHRcdClcblx0XHRcdFx0LmF0dHIoeyB6SW5kZXg6IDIgfSlcblx0XHRcdFx0LmNzcyhzdHlsZSlcblx0XHRcdFx0LmFkZCgpO1xuXG5cdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciBhbGwgZ3JhcGhpY3MgZm9yIHRoZSBjaGFydFxuXHQgKi9cblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGF4ZXMgPSBjaGFydC5heGVzLFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdG9wdGlvbnMgPSBjaGFydC5vcHRpb25zO1xuXG5cdFx0Ly8gVGl0bGVcblx0XHRjaGFydC5zZXRUaXRsZSgpO1xuXG5cblx0XHQvLyBMZWdlbmRcblx0XHRjaGFydC5sZWdlbmQgPSBuZXcgTGVnZW5kKGNoYXJ0LCBvcHRpb25zLmxlZ2VuZCk7XG5cblx0XHRjaGFydC5nZXRTdGFja3MoKTsgLy8gcmVuZGVyIHN0YWNrc1xuXG5cdFx0Ly8gR2V0IG1hcmdpbnMgYnkgcHJlLXJlbmRlcmluZyBheGVzXG5cdFx0Ly8gc2V0IGF4ZXMgc2NhbGVzXG5cdFx0ZWFjaChheGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0YXhpcy5zZXRTY2FsZSgpO1xuXHRcdH0pO1xuXG5cdFx0Y2hhcnQuZ2V0TWFyZ2lucygpO1xuXG5cdFx0Y2hhcnQubWF4VGlja3MgPSBudWxsOyAvLyByZXNldCBmb3Igc2Vjb25kIHBhc3Ncblx0XHRlYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRheGlzLnNldFRpY2tQb3NpdGlvbnModHJ1ZSk7IC8vIHVwZGF0ZSB0byByZWZsZWN0IHRoZSBuZXcgbWFyZ2luc1xuXHRcdFx0YXhpcy5zZXRNYXhUaWNrcygpO1xuXHRcdH0pO1xuXHRcdGNoYXJ0LmFkanVzdFRpY2tBbW91bnRzKCk7XG5cdFx0Y2hhcnQuZ2V0TWFyZ2lucygpOyAvLyBzZWNvbmQgcGFzcyB0byBjaGVjayBmb3IgbmV3IGxhYmVsc1xuXG5cblx0XHQvLyBEcmF3IHRoZSBib3JkZXJzIGFuZCBiYWNrZ3JvdW5kc1xuXHRcdGNoYXJ0LmRyYXdDaGFydEJveCgpO1x0XHRcblxuXG5cdFx0Ly8gQXhlc1xuXHRcdGlmIChjaGFydC5oYXNDYXJ0ZXNpYW5TZXJpZXMpIHtcblx0XHRcdGVhY2goYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0YXhpcy5yZW5kZXIoKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdC8vIFRoZSBzZXJpZXNcblx0XHRpZiAoIWNoYXJ0LnNlcmllc0dyb3VwKSB7XG5cdFx0XHRjaGFydC5zZXJpZXNHcm91cCA9IHJlbmRlcmVyLmcoJ3Nlcmllcy1ncm91cCcpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiAzIH0pXG5cdFx0XHRcdC5hZGQoKTtcblx0XHR9XG5cdFx0Y2hhcnQucmVuZGVyU2VyaWVzKCk7XG5cblx0XHQvLyBMYWJlbHNcblx0XHRjaGFydC5yZW5kZXJMYWJlbHMoKTtcblxuXHRcdC8vIENyZWRpdHNcblx0XHRjaGFydC5zaG93Q3JlZGl0cyhvcHRpb25zLmNyZWRpdHMpO1xuXG5cdFx0Ly8gU2V0IGZsYWdcblx0XHRjaGFydC5oYXNSZW5kZXJlZCA9IHRydWU7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2hvdyBjaGFydCBjcmVkaXRzIGJhc2VkIG9uIGNvbmZpZyBvcHRpb25zXG5cdCAqL1xuXHRzaG93Q3JlZGl0czogZnVuY3Rpb24gKGNyZWRpdHMpIHtcblx0XHRpZiAoY3JlZGl0cy5lbmFibGVkICYmICF0aGlzLmNyZWRpdHMpIHtcblx0XHRcdHRoaXMuY3JlZGl0cyA9IHRoaXMucmVuZGVyZXIudGV4dChcblx0XHRcdFx0Y3JlZGl0cy50ZXh0LFxuXHRcdFx0XHQwLFxuXHRcdFx0XHQwXG5cdFx0XHQpXG5cdFx0XHQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoY3JlZGl0cy5ocmVmKSB7XG5cdFx0XHRcdFx0bG9jYXRpb24uaHJlZiA9IGNyZWRpdHMuaHJlZjtcblx0XHRcdFx0fVxuXHRcdFx0fSlcblx0XHRcdC5hdHRyKHtcblx0XHRcdFx0YWxpZ246IGNyZWRpdHMucG9zaXRpb24uYWxpZ24sXG5cdFx0XHRcdHpJbmRleDogOFxuXHRcdFx0fSlcblx0XHRcdC5jc3MoY3JlZGl0cy5zdHlsZSlcblx0XHRcdC5hZGQoKVxuXHRcdFx0LmFsaWduKGNyZWRpdHMucG9zaXRpb24pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQ2xlYW4gdXAgbWVtb3J5IHVzYWdlXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGF4ZXMgPSBjaGFydC5heGVzLFxuXHRcdFx0c2VyaWVzID0gY2hhcnQuc2VyaWVzLFxuXHRcdFx0Y29udGFpbmVyID0gY2hhcnQuY29udGFpbmVyLFxuXHRcdFx0aSxcblx0XHRcdHBhcmVudE5vZGUgPSBjb250YWluZXIgJiYgY29udGFpbmVyLnBhcmVudE5vZGU7XG5cdFx0XHRcblx0XHQvLyBmaXJlIHRoZSBjaGFydC5kZXN0b3kgZXZlbnRcblx0XHRmaXJlRXZlbnQoY2hhcnQsICdkZXN0cm95Jyk7XG5cdFx0XG5cdFx0Ly8gRGVsZXRlIHRoZSBjaGFydCBmcm9tIGNoYXJ0cyBsb29rdXAgYXJyYXlcblx0XHRjaGFydHNbY2hhcnQuaW5kZXhdID0gVU5ERUZJTkVEO1xuXHRcdGNoYXJ0Q291bnQtLTtcblx0XHRjaGFydC5yZW5kZXJUby5yZW1vdmVBdHRyaWJ1dGUoJ2RhdGEtaGlnaGNoYXJ0cy1jaGFydCcpO1xuXG5cdFx0Ly8gcmVtb3ZlIGV2ZW50c1xuXHRcdHJlbW92ZUV2ZW50KGNoYXJ0KTtcblxuXHRcdC8vID09PT0gRGVzdHJveSBjb2xsZWN0aW9uczpcblx0XHQvLyBEZXN0cm95IGF4ZXNcblx0XHRpID0gYXhlcy5sZW5ndGg7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0YXhlc1tpXSA9IGF4ZXNbaV0uZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdC8vIERlc3Ryb3kgZWFjaCBzZXJpZXNcblx0XHRpID0gc2VyaWVzLmxlbmd0aDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRzZXJpZXNbaV0gPSBzZXJpZXNbaV0uZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdC8vID09PT0gRGVzdHJveSBjaGFydCBwcm9wZXJ0aWVzOlxuXHRcdGVhY2goWyd0aXRsZScsICdzdWJ0aXRsZScsICdjaGFydEJhY2tncm91bmQnLCAncGxvdEJhY2tncm91bmQnLCAncGxvdEJHSW1hZ2UnLCBcblx0XHRcdFx0J3Bsb3RCb3JkZXInLCAnc2VyaWVzR3JvdXAnLCAnY2xpcFJlY3QnLCAnY3JlZGl0cycsICdwb2ludGVyJywgJ3Njcm9sbGVyJywgXG5cdFx0XHRcdCdyYW5nZVNlbGVjdG9yJywgJ2xlZ2VuZCcsICdyZXNldFpvb21CdXR0b24nLCAndG9vbHRpcCcsICdyZW5kZXJlciddLCBmdW5jdGlvbiAobmFtZSkge1xuXHRcdFx0dmFyIHByb3AgPSBjaGFydFtuYW1lXTtcblxuXHRcdFx0aWYgKHByb3AgJiYgcHJvcC5kZXN0cm95KSB7XG5cdFx0XHRcdGNoYXJ0W25hbWVdID0gcHJvcC5kZXN0cm95KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyByZW1vdmUgY29udGFpbmVyIGFuZCBhbGwgU1ZHXG5cdFx0aWYgKGNvbnRhaW5lcikgeyAvLyBjYW4gYnJlYWsgaW4gSUUgd2hlbiBkZXN0cm95ZWQgYmVmb3JlIGZpbmlzaGVkIGxvYWRpbmdcblx0XHRcdGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcblx0XHRcdHJlbW92ZUV2ZW50KGNvbnRhaW5lcik7XG5cdFx0XHRpZiAocGFyZW50Tm9kZSkge1xuXHRcdFx0XHRkaXNjYXJkRWxlbWVudChjb250YWluZXIpO1xuXHRcdFx0fVxuXG5cdFx0fVxuXG5cdFx0Ly8gY2xlYW4gaXQgYWxsIHVwXG5cdFx0Zm9yIChpIGluIGNoYXJ0KSB7XG5cdFx0XHRkZWxldGUgY2hhcnRbaV07XG5cdFx0fVxuXG5cdH0sXG5cblxuXHQvKipcblx0ICogVk1MIG5hbWVzcGFjZXMgY2FuJ3QgYmUgYWRkZWQgdW50aWwgYWZ0ZXIgY29tcGxldGUuIExpc3RlbmluZ1xuXHQgKiBmb3IgUGVyaW5pJ3MgZG9TY3JvbGwgaGFjayBpcyBub3QgZW5vdWdoLlxuXHQgKi9cblx0aXNSZWFkeVRvUmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcztcblxuXHRcdC8vIE5vdGU6IGluIHNwaXRlIG9mIEpTTGludCdzIGNvbXBsYWludHMsIHdpbiA9PSB3aW4udG9wIGlzIHJlcXVpcmVkXG5cdFx0Lypqc2xpbnQgZXFlcTogdHJ1ZSovXG5cdFx0aWYgKCghaGFzU1ZHICYmICh3aW4gPT0gd2luLnRvcCAmJiBkb2MucmVhZHlTdGF0ZSAhPT0gJ2NvbXBsZXRlJykpIHx8ICh1c2VDYW5WRyAmJiAhd2luLmNhbnZnKSkge1xuXHRcdC8qanNsaW50IGVxZXE6IGZhbHNlKi9cblx0XHRcdGlmICh1c2VDYW5WRykge1xuXHRcdFx0XHQvLyBEZWxheSByZW5kZXJpbmcgdW50aWwgY2FudmcgbGlicmFyeSBpcyBkb3dubG9hZGVkIGFuZCByZWFkeVxuXHRcdFx0XHRDYW5WR0NvbnRyb2xsZXIucHVzaChmdW5jdGlvbiAoKSB7IGNoYXJ0LmZpcnN0UmVuZGVyKCk7IH0sIGNoYXJ0Lm9wdGlvbnMuZ2xvYmFsLmNhbnZhc1Rvb2xzVVJMKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRvYy5hdHRhY2hFdmVudCgnb25yZWFkeXN0YXRlY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGRvYy5kZXRhY2hFdmVudCgnb25yZWFkeXN0YXRlY2hhbmdlJywgY2hhcnQuZmlyc3RSZW5kZXIpO1xuXHRcdFx0XHRcdGlmIChkb2MucmVhZHlTdGF0ZSA9PT0gJ2NvbXBsZXRlJykge1xuXHRcdFx0XHRcdFx0Y2hhcnQuZmlyc3RSZW5kZXIoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHQvKipcblx0ICogUHJlcGFyZSBmb3IgZmlyc3QgcmVuZGVyaW5nIGFmdGVyIGFsbCBkYXRhIGFyZSBsb2FkZWRcblx0ICovXG5cdGZpcnN0UmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBjaGFydC5vcHRpb25zLFxuXHRcdFx0Y2FsbGJhY2sgPSBjaGFydC5jYWxsYmFjaztcblxuXHRcdC8vIENoZWNrIHdoZXRoZXIgdGhlIGNoYXJ0IGlzIHJlYWR5IHRvIHJlbmRlclxuXHRcdGlmICghY2hhcnQuaXNSZWFkeVRvUmVuZGVyKCkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDcmVhdGUgdGhlIGNvbnRhaW5lclxuXHRcdGNoYXJ0LmdldENvbnRhaW5lcigpO1xuXG5cdFx0Ly8gUnVuIGFuIGVhcmx5IGV2ZW50IGFmdGVyIHRoZSBjb250YWluZXIgYW5kIHJlbmRlcmVyIGFyZSBlc3RhYmxpc2hlZFxuXHRcdGZpcmVFdmVudChjaGFydCwgJ2luaXQnKTtcblxuXHRcdFxuXHRcdGNoYXJ0LnJlc2V0TWFyZ2lucygpO1xuXHRcdGNoYXJ0LnNldENoYXJ0U2l6ZSgpO1xuXG5cdFx0Ly8gU2V0IHRoZSBjb21tb24gY2hhcnQgcHJvcGVydGllcyAobWFpbmx5IGludmVydCkgZnJvbSB0aGUgZ2l2ZW4gc2VyaWVzXG5cdFx0Y2hhcnQucHJvcEZyb21TZXJpZXMoKTtcblxuXHRcdC8vIGdldCBheGVzXG5cdFx0Y2hhcnQuZ2V0QXhlcygpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgc2VyaWVzXG5cdFx0ZWFjaChvcHRpb25zLnNlcmllcyB8fCBbXSwgZnVuY3Rpb24gKHNlcmllT3B0aW9ucykge1xuXHRcdFx0Y2hhcnQuaW5pdFNlcmllcyhzZXJpZU9wdGlvbnMpO1xuXHRcdH0pO1xuXG5cdFx0Y2hhcnQubGlua1NlcmllcygpO1xuXG5cdFx0Ly8gUnVuIGFuIGV2ZW50IGFmdGVyIGF4ZXMgYW5kIHNlcmllcyBhcmUgaW5pdGlhbGl6ZWQsIGJ1dCBiZWZvcmUgcmVuZGVyLiBBdCB0aGlzIHN0YWdlLFxuXHRcdC8vIHRoZSBzZXJpZXMgZGF0YSBpcyBpbmRleGVkIGFuZCBjYWNoZWQgaW4gdGhlIHhEYXRhIGFuZCB5RGF0YSBhcnJheXMsIHNvIHdlIGNhbiBhY2Nlc3Ncblx0XHQvLyB0aG9zZSBiZWZvcmUgcmVuZGVyaW5nLiBVc2VkIGluIEhpZ2hzdG9jay4gXG5cdFx0ZmlyZUV2ZW50KGNoYXJ0LCAnYmVmb3JlUmVuZGVyJyk7IFxuXG5cdFx0Ly8gZGVwZW5kcyBvbiBpbnZlcnRlZCBhbmQgb24gbWFyZ2lucyBiZWluZyBzZXRcblx0XHRpZiAoSGlnaGNoYXJ0cy5Qb2ludGVyKSB7XG5cdFx0XHRjaGFydC5wb2ludGVyID0gbmV3IFBvaW50ZXIoY2hhcnQsIG9wdGlvbnMpO1xuXHRcdH1cblxuXHRcdGNoYXJ0LnJlbmRlcigpO1xuXG5cdFx0Ly8gYWRkIGNhbnZhc1xuXHRcdGNoYXJ0LnJlbmRlcmVyLmRyYXcoKTtcblx0XHQvLyBydW4gY2FsbGJhY2tzXG5cdFx0aWYgKGNhbGxiYWNrKSB7XG5cdFx0XHRjYWxsYmFjay5hcHBseShjaGFydCwgW2NoYXJ0XSk7XG5cdFx0fVxuXHRcdGVhY2goY2hhcnQuY2FsbGJhY2tzLCBmdW5jdGlvbiAoZm4pIHtcblx0XHRcdGZuLmFwcGx5KGNoYXJ0LCBbY2hhcnRdKTtcblx0XHR9KTtcblx0XHRcblx0XHRcblx0XHQvLyBJZiB0aGUgY2hhcnQgd2FzIHJlbmRlcmVkIG91dHNpZGUgdGhlIHRvcCBjb250YWluZXIsIHB1dCBpdCBiYWNrIGluXG5cdFx0Y2hhcnQuY2xvbmVSZW5kZXJUbyh0cnVlKTtcblx0XHRcblx0XHRmaXJlRXZlbnQoY2hhcnQsICdsb2FkJyk7XG5cblx0fSxcblxuXHQvKipcblx0KiBDcmVhdGVzIGFycmF5cyBmb3Igc3BhY2luZyBhbmQgbWFyZ2luIGZyb20gZ2l2ZW4gb3B0aW9ucy5cblx0Ki9cblx0c3BsYXNoQXJyYXk6IGZ1bmN0aW9uICh0YXJnZXQsIG9wdGlvbnMpIHtcblx0XHR2YXIgb1ZhciA9IG9wdGlvbnNbdGFyZ2V0XSxcblx0XHRcdHRBcnJheSA9IGlzT2JqZWN0KG9WYXIpID8gb1ZhciA6IFtvVmFyLCBvVmFyLCBvVmFyLCBvVmFyXTtcblxuXHRcdHJldHVybiBbcGljayhvcHRpb25zW3RhcmdldCArICdUb3AnXSwgdEFycmF5WzBdKSxcblx0XHRcdFx0cGljayhvcHRpb25zW3RhcmdldCArICdSaWdodCddLCB0QXJyYXlbMV0pLFxuXHRcdFx0XHRwaWNrKG9wdGlvbnNbdGFyZ2V0ICsgJ0JvdHRvbSddLCB0QXJyYXlbMl0pLFxuXHRcdFx0XHRwaWNrKG9wdGlvbnNbdGFyZ2V0ICsgJ0xlZnQnXSwgdEFycmF5WzNdKV07XG5cdH1cbn07IC8vIGVuZCBDaGFydFxuXG4vLyBIb29rIGZvciBleHBvcnRpbmcgbW9kdWxlXG5DaGFydC5wcm90b3R5cGUuY2FsbGJhY2tzID0gW107XG5cbnZhciBDZW50ZXJlZFNlcmllc01peGluID0gSGlnaGNoYXJ0cy5DZW50ZXJlZFNlcmllc01peGluID0ge1xuXHQvKipcblx0ICogR2V0IHRoZSBjZW50ZXIgb2YgdGhlIHBpZSBiYXNlZCBvbiB0aGUgc2l6ZSBhbmQgY2VudGVyIG9wdGlvbnMgcmVsYXRpdmUgdG8gdGhlICBcblx0ICogcGxvdCBhcmVhLiBCb3Jyb3dlZCBieSB0aGUgcG9sYXIgYW5kIGdhdWdlIHNlcmllcyB0eXBlcy5cblx0ICovXG5cdGdldENlbnRlcjogZnVuY3Rpb24gKCkge1xuXHRcdFxuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0Y2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0c2xpY2luZ1Jvb20gPSAyICogKG9wdGlvbnMuc2xpY2VkT2Zmc2V0IHx8IDApLFxuXHRcdFx0aGFuZGxlU2xpY2luZ1Jvb20sXG5cdFx0XHRwbG90V2lkdGggPSBjaGFydC5wbG90V2lkdGggLSAyICogc2xpY2luZ1Jvb20sXG5cdFx0XHRwbG90SGVpZ2h0ID0gY2hhcnQucGxvdEhlaWdodCAtIDIgKiBzbGljaW5nUm9vbSxcblx0XHRcdGNlbnRlck9wdGlvbiA9IG9wdGlvbnMuY2VudGVyLFxuXHRcdFx0cG9zaXRpb25zID0gW3BpY2soY2VudGVyT3B0aW9uWzBdLCAnNTAlJyksIHBpY2soY2VudGVyT3B0aW9uWzFdLCAnNTAlJyksIG9wdGlvbnMuc2l6ZSB8fCAnMTAwJScsIG9wdGlvbnMuaW5uZXJTaXplIHx8IDBdLFxuXHRcdFx0c21hbGxlc3RTaXplID0gbWF0aE1pbihwbG90V2lkdGgsIHBsb3RIZWlnaHQpLFxuXHRcdFx0aXNQZXJjZW50O1xuXHRcdFxuXHRcdHJldHVybiBtYXAocG9zaXRpb25zLCBmdW5jdGlvbiAobGVuZ3RoLCBpKSB7XG5cdFx0XHRpc1BlcmNlbnQgPSAvJSQvLnRlc3QobGVuZ3RoKTtcblx0XHRcdGhhbmRsZVNsaWNpbmdSb29tID0gaSA8IDIgfHwgKGkgPT09IDIgJiYgaXNQZXJjZW50KTtcblx0XHRcdHJldHVybiAoaXNQZXJjZW50ID9cblx0XHRcdFx0Ly8gaSA9PSAwOiBjZW50ZXJYLCByZWxhdGl2ZSB0byB3aWR0aFxuXHRcdFx0XHQvLyBpID09IDE6IGNlbnRlclksIHJlbGF0aXZlIHRvIGhlaWdodFxuXHRcdFx0XHQvLyBpID09IDI6IHNpemUsIHJlbGF0aXZlIHRvIHNtYWxsZXN0U2l6ZVxuXHRcdFx0XHQvLyBpID09IDQ6IGlubmVyU2l6ZSwgcmVsYXRpdmUgdG8gc21hbGxlc3RTaXplXG5cdFx0XHRcdFtwbG90V2lkdGgsIHBsb3RIZWlnaHQsIHNtYWxsZXN0U2l6ZSwgc21hbGxlc3RTaXplXVtpXSAqXG5cdFx0XHRcdFx0cEludChsZW5ndGgpIC8gMTAwIDpcblx0XHRcdFx0bGVuZ3RoKSArIChoYW5kbGVTbGljaW5nUm9vbSA/IHNsaWNpbmdSb29tIDogMCk7XG5cdFx0fSk7XG5cdH1cbn07XG5cbi8qKlxuICogVGhlIFBvaW50IG9iamVjdCBhbmQgcHJvdG90eXBlLiBJbmhlcml0YWJsZSBhbmQgdXNlZCBhcyBiYXNlIGZvciBQaWVQb2ludFxuICovXG52YXIgUG9pbnQgPSBmdW5jdGlvbiAoKSB7fTtcblBvaW50LnByb3RvdHlwZSA9IHtcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgcG9pbnRcblx0ICogQHBhcmFtIHtPYmplY3R9IHNlcmllcyBUaGUgc2VyaWVzIG9iamVjdCBjb250YWluaW5nIHRoaXMgcG9pbnRcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIGRhdGEgaW4gZWl0aGVyIG51bWJlciwgYXJyYXkgb3Igb2JqZWN0IGZvcm1hdFxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKHNlcmllcywgb3B0aW9ucywgeCkge1xuXG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdGNvbG9ycztcblx0XHRwb2ludC5zZXJpZXMgPSBzZXJpZXM7XG5cdFx0cG9pbnQuYXBwbHlPcHRpb25zKG9wdGlvbnMsIHgpO1xuXHRcdHBvaW50LnBvaW50QXR0ciA9IHt9O1xuXG5cdFx0aWYgKHNlcmllcy5vcHRpb25zLmNvbG9yQnlQb2ludCkge1xuXHRcdFx0Y29sb3JzID0gc2VyaWVzLm9wdGlvbnMuY29sb3JzIHx8IHNlcmllcy5jaGFydC5vcHRpb25zLmNvbG9ycztcblx0XHRcdHBvaW50LmNvbG9yID0gcG9pbnQuY29sb3IgfHwgY29sb3JzW3Nlcmllcy5jb2xvckNvdW50ZXIrK107XG5cdFx0XHQvLyBsb29wIGJhY2sgdG8gemVyb1xuXHRcdFx0aWYgKHNlcmllcy5jb2xvckNvdW50ZXIgPT09IGNvbG9ycy5sZW5ndGgpIHtcblx0XHRcdFx0c2VyaWVzLmNvbG9yQ291bnRlciA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0c2VyaWVzLmNoYXJ0LnBvaW50Q291bnQrKztcblx0XHRyZXR1cm4gcG9pbnQ7XG5cdH0sXG5cdC8qKlxuXHQgKiBBcHBseSB0aGUgb3B0aW9ucyBjb250YWluaW5nIHRoZSB4IGFuZCB5IGRhdGEgYW5kIHBvc3NpYmxlIHNvbWUgZXh0cmEgcHJvcGVydGllcy5cblx0ICogVGhpcyBpcyBjYWxsZWQgb24gcG9pbnQgaW5pdCBvciBmcm9tIHBvaW50LnVwZGF0ZS5cblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcblx0ICovXG5cdGFwcGx5T3B0aW9uczogZnVuY3Rpb24gKG9wdGlvbnMsIHgpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0cG9pbnRWYWxLZXkgPSBzZXJpZXMub3B0aW9ucy5wb2ludFZhbEtleSB8fCBzZXJpZXMucG9pbnRWYWxLZXk7XG5cblx0XHRvcHRpb25zID0gUG9pbnQucHJvdG90eXBlLm9wdGlvbnNUb09iamVjdC5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG5cdFx0Ly8gY29weSBvcHRpb25zIGRpcmVjdGx5IHRvIHBvaW50XG5cdFx0ZXh0ZW5kKHBvaW50LCBvcHRpb25zKTtcblx0XHRwb2ludC5vcHRpb25zID0gcG9pbnQub3B0aW9ucyA/IGV4dGVuZChwb2ludC5vcHRpb25zLCBvcHRpb25zKSA6IG9wdGlvbnM7XG5cblx0XHQvLyBGb3IgaGlnaGVyIGRpbWVuc2lvbiBzZXJpZXMgdHlwZXMuIEZvciBpbnN0YW5jZSwgZm9yIHJhbmdlcywgcG9pbnQueSBpcyBtYXBwZWQgdG8gcG9pbnQubG93LlxuXHRcdGlmIChwb2ludFZhbEtleSkge1xuXHRcdFx0cG9pbnQueSA9IHBvaW50W3BvaW50VmFsS2V5XTtcblx0XHR9XG5cblx0XHQvLyBJZiBubyB4IGlzIHNldCBieSBub3csIGdldCBhdXRvIGluY3JlbWVudGVkIHZhbHVlLiBBbGwgcG9pbnRzIG11c3QgaGF2ZSBhblxuXHRcdC8vIHggdmFsdWUsIGhvd2V2ZXIgdGhlIHkgdmFsdWUgY2FuIGJlIG51bGwgdG8gY3JlYXRlIGEgZ2FwIGluIHRoZSBzZXJpZXNcblx0XHRpZiAocG9pbnQueCA9PT0gVU5ERUZJTkVEICYmIHNlcmllcykge1xuXHRcdFx0cG9pbnQueCA9IHggPT09IFVOREVGSU5FRCA/IHNlcmllcy5hdXRvSW5jcmVtZW50KCkgOiB4O1xuXHRcdH1cblxuXHRcdHJldHVybiBwb2ludDtcblx0fSxcblxuXHQvKipcblx0ICogVHJhbnNmb3JtIG51bWJlciBvciBhcnJheSBjb25maWdzIGludG8gb2JqZWN0c1xuXHQgKi9cblx0b3B0aW9uc1RvT2JqZWN0OiBmdW5jdGlvbiAob3B0aW9ucykge1xuXHRcdHZhciByZXQgPSB7fSxcblx0XHRcdHNlcmllcyA9IHRoaXMuc2VyaWVzLFxuXHRcdFx0cG9pbnRBcnJheU1hcCA9IHNlcmllcy5wb2ludEFycmF5TWFwIHx8IFsneSddLFxuXHRcdFx0dmFsdWVDb3VudCA9IHBvaW50QXJyYXlNYXAubGVuZ3RoLFxuXHRcdFx0Zmlyc3RJdGVtVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0aiA9IDA7XG5cblx0XHRpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdudW1iZXInIHx8IG9wdGlvbnMgPT09IG51bGwpIHtcblx0XHRcdHJldFtwb2ludEFycmF5TWFwWzBdXSA9IG9wdGlvbnM7XG5cblx0XHR9IGVsc2UgaWYgKGlzQXJyYXkob3B0aW9ucykpIHtcblx0XHRcdC8vIHdpdGggbGVhZGluZyB4IHZhbHVlXG5cdFx0XHRpZiAob3B0aW9ucy5sZW5ndGggPiB2YWx1ZUNvdW50KSB7XG5cdFx0XHRcdGZpcnN0SXRlbVR5cGUgPSB0eXBlb2Ygb3B0aW9uc1swXTtcblx0XHRcdFx0aWYgKGZpcnN0SXRlbVR5cGUgPT09ICdzdHJpbmcnKSB7XG5cdFx0XHRcdFx0cmV0Lm5hbWUgPSBvcHRpb25zWzBdO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGZpcnN0SXRlbVR5cGUgPT09ICdudW1iZXInKSB7XG5cdFx0XHRcdFx0cmV0LnggPSBvcHRpb25zWzBdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGkrKztcblx0XHRcdH1cblx0XHRcdHdoaWxlIChqIDwgdmFsdWVDb3VudCkge1xuXHRcdFx0XHRyZXRbcG9pbnRBcnJheU1hcFtqKytdXSA9IG9wdGlvbnNbaSsrXTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0Jykge1xuXHRcdFx0cmV0ID0gb3B0aW9ucztcblxuXHRcdFx0Ly8gVGhpcyBpcyB0aGUgZmFzdGVzdCB3YXkgdG8gZGV0ZWN0IGlmIHRoZXJlIGFyZSBpbmRpdmlkdWFsIHBvaW50IGRhdGFMYWJlbHMgdGhhdCBuZWVkXG5cdFx0XHQvLyB0byBiZSBjb25zaWRlcmVkIGluIGRyYXdEYXRhTGFiZWxzLiBUaGVzZSBjYW4gb25seSBvY2N1ciBpbiBvYmplY3QgY29uZmlncy5cblx0XHRcdGlmIChvcHRpb25zLmRhdGFMYWJlbHMpIHtcblx0XHRcdFx0c2VyaWVzLl9oYXNQb2ludExhYmVscyA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNhbWUgYXBwcm9hY2ggYXMgYWJvdmUgZm9yIG1hcmtlcnNcblx0XHRcdGlmIChvcHRpb25zLm1hcmtlcikge1xuXHRcdFx0XHRzZXJpZXMuX2hhc1BvaW50TWFya2VycyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3Ryb3kgYSBwb2ludCB0byBjbGVhciBtZW1vcnkuIEl0cyByZWZlcmVuY2Ugc3RpbGwgc3RheXMgaW4gc2VyaWVzLmRhdGEuXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0aG92ZXJQb2ludHMgPSBjaGFydC5ob3ZlclBvaW50cyxcblx0XHRcdHByb3A7XG5cblx0XHRjaGFydC5wb2ludENvdW50LS07XG5cblx0XHRpZiAoaG92ZXJQb2ludHMpIHtcblx0XHRcdHBvaW50LnNldFN0YXRlKCk7XG5cdFx0XHRlcmFzZShob3ZlclBvaW50cywgcG9pbnQpO1xuXHRcdFx0aWYgKCFob3ZlclBvaW50cy5sZW5ndGgpIHtcblx0XHRcdFx0Y2hhcnQuaG92ZXJQb2ludHMgPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0fVxuXHRcdGlmIChwb2ludCA9PT0gY2hhcnQuaG92ZXJQb2ludCkge1xuXHRcdFx0cG9pbnQub25Nb3VzZU91dCgpO1xuXHRcdH1cblxuXHRcdC8vIHJlbW92ZSBhbGwgZXZlbnRzXG5cdFx0aWYgKHBvaW50LmdyYXBoaWMgfHwgcG9pbnQuZGF0YUxhYmVsKSB7IC8vIHJlbW92ZUV2ZW50IGFuZCBkZXN0cm95RWxlbWVudHMgYXJlIHBlcmZvcm1hbmNlIGV4cGVuc2l2ZVxuXHRcdFx0cmVtb3ZlRXZlbnQocG9pbnQpO1xuXHRcdFx0cG9pbnQuZGVzdHJveUVsZW1lbnRzKCk7XG5cdFx0fVxuXG5cdFx0aWYgKHBvaW50LmxlZ2VuZEl0ZW0pIHsgLy8gcGllcyBoYXZlIGxlZ2VuZCBpdGVtc1xuXHRcdFx0Y2hhcnQubGVnZW5kLmRlc3Ryb3lJdGVtKHBvaW50KTtcblx0XHR9XG5cblx0XHRmb3IgKHByb3AgaW4gcG9pbnQpIHtcblx0XHRcdHBvaW50W3Byb3BdID0gbnVsbDtcblx0XHR9XG5cblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95IFNWRyBlbGVtZW50cyBhc3NvY2lhdGVkIHdpdGggdGhlIHBvaW50XG5cdCAqL1xuXHRkZXN0cm95RWxlbWVudHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0cHJvcHMgPSBbJ2dyYXBoaWMnLCAnZGF0YUxhYmVsJywgJ2RhdGFMYWJlbFVwcGVyJywgJ2dyb3VwJywgJ2Nvbm5lY3RvcicsICdzaGFkb3dHcm91cCddLFxuXHRcdFx0cHJvcCxcblx0XHRcdGkgPSA2O1xuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHByb3AgPSBwcm9wc1tpXTtcblx0XHRcdGlmIChwb2ludFtwcm9wXSkge1xuXHRcdFx0XHRwb2ludFtwcm9wXSA9IHBvaW50W3Byb3BdLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybiB0aGUgY29uZmlndXJhdGlvbiBoYXNoIG5lZWRlZCBmb3IgdGhlIGRhdGEgbGFiZWwgYW5kIHRvb2x0aXAgZm9ybWF0dGVyc1xuXHQgKi9cblx0Z2V0TGFiZWxDb25maWc6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzO1xuXHRcdHJldHVybiB7XG5cdFx0XHR4OiBwb2ludC5jYXRlZ29yeSxcblx0XHRcdHk6IHBvaW50LnksXG5cdFx0XHRrZXk6IHBvaW50Lm5hbWUgfHwgcG9pbnQuY2F0ZWdvcnksXG5cdFx0XHRzZXJpZXM6IHBvaW50LnNlcmllcyxcblx0XHRcdHBvaW50OiBwb2ludCxcblx0XHRcdHBlcmNlbnRhZ2U6IHBvaW50LnBlcmNlbnRhZ2UsXG5cdFx0XHR0b3RhbDogcG9pbnQudG90YWwgfHwgcG9pbnQuc3RhY2tUb3RhbFxuXHRcdH07XG5cdH0sXHRcblxuXHQvKipcblx0ICogRXh0ZW5kYWJsZSBtZXRob2QgZm9yIGZvcm1hdHRpbmcgZWFjaCBwb2ludCdzIHRvb2x0aXAgbGluZVxuXHQgKlxuXHQgKiBAcmV0dXJuIHtTdHJpbmd9IEEgc3RyaW5nIHRvIGJlIGNvbmNhdGVuYXRlZCBpbiB0byB0aGUgY29tbW9uIHRvb2x0aXAgdGV4dFxuXHQgKi9cblx0dG9vbHRpcEZvcm1hdHRlcjogZnVuY3Rpb24gKHBvaW50Rm9ybWF0KSB7XG5cblx0XHQvLyBJbnNlcnQgb3B0aW9ucyBmb3IgdmFsdWVEZWNpbWFscywgdmFsdWVQcmVmaXgsIGFuZCB2YWx1ZVN1ZmZpeFxuXHRcdHZhciBzZXJpZXMgPSB0aGlzLnNlcmllcyxcblx0XHRcdHNlcmllc1Rvb2x0aXBPcHRpb25zID0gc2VyaWVzLnRvb2x0aXBPcHRpb25zLFxuXHRcdFx0dmFsdWVEZWNpbWFscyA9IHBpY2soc2VyaWVzVG9vbHRpcE9wdGlvbnMudmFsdWVEZWNpbWFscywgJycpLFxuXHRcdFx0dmFsdWVQcmVmaXggPSBzZXJpZXNUb29sdGlwT3B0aW9ucy52YWx1ZVByZWZpeCB8fCAnJyxcblx0XHRcdHZhbHVlU3VmZml4ID0gc2VyaWVzVG9vbHRpcE9wdGlvbnMudmFsdWVTdWZmaXggfHwgJyc7XG5cblx0XHQvLyBMb29wIG92ZXIgdGhlIHBvaW50IGFycmF5IG1hcCBhbmQgcmVwbGFjZSB1bmZvcm1hdHRlZCB2YWx1ZXMgd2l0aCBzcHJpbnRmIGZvcm1hdHRpbmcgbWFya3VwXG5cdFx0ZWFjaChzZXJpZXMucG9pbnRBcnJheU1hcCB8fCBbJ3knXSwgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0a2V5ID0gJ3twb2ludC4nICsga2V5OyAvLyB3aXRob3V0IHRoZSBjbG9zaW5nIGJyYWNrZXRcblx0XHRcdGlmICh2YWx1ZVByZWZpeCB8fCB2YWx1ZVN1ZmZpeCkge1xuXHRcdFx0XHRwb2ludEZvcm1hdCA9IHBvaW50Rm9ybWF0LnJlcGxhY2Uoa2V5ICsgJ30nLCB2YWx1ZVByZWZpeCArIGtleSArICd9JyArIHZhbHVlU3VmZml4KTtcblx0XHRcdH1cblx0XHRcdHBvaW50Rm9ybWF0ID0gcG9pbnRGb3JtYXQucmVwbGFjZShrZXkgKyAnfScsIGtleSArICc6LC4nICsgdmFsdWVEZWNpbWFscyArICdmfScpO1xuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIGZvcm1hdChwb2ludEZvcm1hdCwge1xuXHRcdFx0cG9pbnQ6IHRoaXMsXG5cdFx0XHRzZXJpZXM6IHRoaXMuc2VyaWVzXG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEZpcmUgYW4gZXZlbnQgb24gdGhlIFBvaW50IG9iamVjdC4gTXVzdCBub3QgYmUgcmVuYW1lZCB0byBmaXJlRXZlbnQsIGFzIHRoaXNcblx0ICogY2F1c2VzIGEgbmFtZSBjbGFzaCBpbiBNb29Ub29sc1xuXHQgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRUeXBlXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudEFyZ3MgQWRkaXRpb25hbCBldmVudCBhcmd1bWVudHNcblx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZGVmYXVsdEZ1bmN0aW9uIERlZmF1bHQgZXZlbnQgaGFuZGxlclxuXHQgKi9cblx0ZmlyZVBvaW50RXZlbnQ6IGZ1bmN0aW9uIChldmVudFR5cGUsIGV2ZW50QXJncywgZGVmYXVsdEZ1bmN0aW9uKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHRoaXMuc2VyaWVzLFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zO1xuXG5cdFx0Ly8gbG9hZCBldmVudCBoYW5kbGVycyBvbiBkZW1hbmQgdG8gc2F2ZSB0aW1lIG9uIG1vdXNlb3Zlci9vdXRcblx0XHRpZiAoc2VyaWVzT3B0aW9ucy5wb2ludC5ldmVudHNbZXZlbnRUeXBlXSB8fCAocG9pbnQub3B0aW9ucyAmJiBwb2ludC5vcHRpb25zLmV2ZW50cyAmJiBwb2ludC5vcHRpb25zLmV2ZW50c1tldmVudFR5cGVdKSkge1xuXHRcdFx0dGhpcy5pbXBvcnRFdmVudHMoKTtcblx0XHR9XG5cblx0XHQvLyBhZGQgZGVmYXVsdCBoYW5kbGVyIGlmIGluIHNlbGVjdGlvbiBtb2RlXG5cdFx0aWYgKGV2ZW50VHlwZSA9PT0gJ2NsaWNrJyAmJiBzZXJpZXNPcHRpb25zLmFsbG93UG9pbnRTZWxlY3QpIHtcblx0XHRcdGRlZmF1bHRGdW5jdGlvbiA9IGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0XHQvLyBDb250cm9sIGtleSBpcyBmb3IgV2luZG93cywgbWV0YSAoPSBDbWQga2V5KSBmb3IgTWFjLCBTaGlmdCBmb3IgT3BlcmFcblx0XHRcdFx0cG9pbnQuc2VsZWN0KG51bGwsIGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSB8fCBldmVudC5zaGlmdEtleSk7XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdGZpcmVFdmVudCh0aGlzLCBldmVudFR5cGUsIGV2ZW50QXJncywgZGVmYXVsdEZ1bmN0aW9uKTtcblx0fVxufTsvKipcbiAqIEBjbGFzc0Rlc2NyaXB0aW9uIFRoZSBiYXNlIGZ1bmN0aW9uIHdoaWNoIGFsbCBvdGhlciBzZXJpZXMgdHlwZXMgaW5oZXJpdCBmcm9tLiBUaGUgZGF0YSBpbiB0aGUgc2VyaWVzIGlzIHN0b3JlZFxuICogaW4gdmFyaW91cyBhcnJheXMuXG4gKlxuICogLSBGaXJzdCwgc2VyaWVzLm9wdGlvbnMuZGF0YSBjb250YWlucyBhbGwgdGhlIG9yaWdpbmFsIGNvbmZpZyBvcHRpb25zIGZvclxuICogZWFjaCBwb2ludCB3aGV0aGVyIGFkZGVkIGJ5IG9wdGlvbnMgb3IgbWV0aG9kcyBsaWtlIHNlcmllcy5hZGRQb2ludC5cbiAqIC0gTmV4dCwgc2VyaWVzLmRhdGEgY29udGFpbnMgdGhvc2UgdmFsdWVzIGNvbnZlcnRlZCB0byBwb2ludHMsIGJ1dCBpbiBjYXNlIHRoZSBzZXJpZXMgZGF0YSBsZW5ndGhcbiAqIGV4Y2VlZHMgdGhlIGNyb3BUaHJlc2hvbGQsIG9yIGlmIHRoZSBkYXRhIGlzIGdyb3VwZWQsIHNlcmllcy5kYXRhIGRvZXNuJ3QgY29udGFpbiBhbGwgdGhlIHBvaW50cy4gSXRcbiAqIG9ubHkgY29udGFpbnMgdGhlIHBvaW50cyB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIG9uIGRlbWFuZC5cbiAqIC0gVGhlbiB0aGVyZSdzIHNlcmllcy5wb2ludHMgdGhhdCBjb250YWlucyBhbGwgY3VycmVudGx5IHZpc2libGUgcG9pbnQgb2JqZWN0cy4gSW4gY2FzZSBvZiBjcm9wcGluZyxcbiAqIHRoZSBjcm9wcGVkLWF3YXkgcG9pbnRzIGFyZSBub3QgcGFydCBvZiB0aGlzIGFycmF5LiBUaGUgc2VyaWVzLnBvaW50cyBhcnJheSBzdGFydHMgYXQgc2VyaWVzLmNyb3BTdGFydFxuICogY29tcGFyZWQgdG8gc2VyaWVzLmRhdGEgYW5kIHNlcmllcy5vcHRpb25zLmRhdGEuIElmIGhvd2V2ZXIgdGhlIHNlcmllcyBkYXRhIGlzIGdyb3VwZWQsIHRoZXNlIGNhbid0XG4gKiBiZSBjb3JyZWxhdGVkIG9uZSB0byBvbmUuXG4gKiAtIHNlcmllcy54RGF0YSBhbmQgc2VyaWVzLnByb2Nlc3NlZFhEYXRhIGNvbnRhaW4gY2xlYW4geCB2YWx1ZXMsIGVxdWl2YWxlbnQgdG8gc2VyaWVzLmRhdGEgYW5kIHNlcmllcy5wb2ludHMuXG4gKiAtIHNlcmllcy55RGF0YSBhbmQgc2VyaWVzLnByb2Nlc3NlZFlEYXRhIGNvbnRhaW4gY2xlYW4geCB2YWx1ZXMsIGVxdWl2YWxlbnQgdG8gc2VyaWVzLmRhdGEgYW5kIHNlcmllcy5wb2ludHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0XG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG52YXIgU2VyaWVzID0gZnVuY3Rpb24gKCkge307XG5cblNlcmllcy5wcm90b3R5cGUgPSB7XG5cblx0aXNDYXJ0ZXNpYW46IHRydWUsXG5cdHR5cGU6ICdsaW5lJyxcblx0cG9pbnRDbGFzczogUG9pbnQsXG5cdHNvcnRlZDogdHJ1ZSwgLy8gcmVxdWlyZXMgdGhlIGRhdGEgdG8gYmUgc29ydGVkXG5cdHJlcXVpcmVTb3J0aW5nOiB0cnVlLFxuXHRwb2ludEF0dHJUb09wdGlvbnM6IHsgLy8gbWFwcGluZyBiZXR3ZWVuIFNWRyBhdHRyaWJ1dGVzIGFuZCB0aGUgY29ycmVzcG9uZGluZyBvcHRpb25zXG5cdFx0c3Ryb2tlOiAnbGluZUNvbG9yJyxcblx0XHQnc3Ryb2tlLXdpZHRoJzogJ2xpbmVXaWR0aCcsXG5cdFx0ZmlsbDogJ2ZpbGxDb2xvcicsXG5cdFx0cjogJ3JhZGl1cydcblx0fSxcblx0YXhpc1R5cGVzOiBbJ3hBeGlzJywgJ3lBeGlzJ10sXG5cdGNvbG9yQ291bnRlcjogMCxcblx0cGFyYWxsZWxBcnJheXM6IFsneCcsICd5J10sIC8vIGVhY2ggcG9pbnQncyB4IGFuZCB5IHZhbHVlcyBhcmUgc3RvcmVkIGluIHRoaXMueERhdGEgYW5kIHRoaXMueURhdGFcblx0aW5pdDogZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRldmVudFR5cGUsXG5cdFx0XHRldmVudHMsXG5cdFx0XHRjaGFydFNlcmllcyA9IGNoYXJ0LnNlcmllcyxcblx0XHRcdHNvcnRCeUluZGV4ID0gZnVuY3Rpb24gKGEsIGIpIHtcblx0XHRcdFx0cmV0dXJuIHBpY2soYS5vcHRpb25zLmluZGV4LCBhLl9pKSAtIHBpY2soYi5vcHRpb25zLmluZGV4LCBiLl9pKTtcblx0XHRcdH07XG5cblx0XHRzZXJpZXMuY2hhcnQgPSBjaGFydDtcblx0XHRzZXJpZXMub3B0aW9ucyA9IG9wdGlvbnMgPSBzZXJpZXMuc2V0T3B0aW9ucyhvcHRpb25zKTsgLy8gbWVyZ2Ugd2l0aCBwbG90T3B0aW9uc1xuXHRcdHNlcmllcy5saW5rZWRTZXJpZXMgPSBbXTtcblxuXHRcdC8vIGJpbmQgdGhlIGF4ZXNcblx0XHRzZXJpZXMuYmluZEF4ZXMoKTtcblxuXHRcdC8vIHNldCBzb21lIHZhcmlhYmxlc1xuXHRcdGV4dGVuZChzZXJpZXMsIHtcblx0XHRcdG5hbWU6IG9wdGlvbnMubmFtZSxcblx0XHRcdHN0YXRlOiBOT1JNQUxfU1RBVEUsXG5cdFx0XHRwb2ludEF0dHI6IHt9LFxuXHRcdFx0dmlzaWJsZTogb3B0aW9ucy52aXNpYmxlICE9PSBmYWxzZSwgLy8gdHJ1ZSBieSBkZWZhdWx0XG5cdFx0XHRzZWxlY3RlZDogb3B0aW9ucy5zZWxlY3RlZCA9PT0gdHJ1ZSAvLyBmYWxzZSBieSBkZWZhdWx0XG5cdFx0fSk7XG5cblx0XHQvLyBzcGVjaWFsXG5cdFx0aWYgKHVzZUNhblZHKSB7XG5cdFx0XHRvcHRpb25zLmFuaW1hdGlvbiA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIHJlZ2lzdGVyIGV2ZW50IGxpc3RlbmVyc1xuXHRcdGV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuXHRcdGZvciAoZXZlbnRUeXBlIGluIGV2ZW50cykge1xuXHRcdFx0YWRkRXZlbnQoc2VyaWVzLCBldmVudFR5cGUsIGV2ZW50c1tldmVudFR5cGVdKTtcblx0XHR9XG5cdFx0aWYgKFxuXHRcdFx0KGV2ZW50cyAmJiBldmVudHMuY2xpY2spIHx8XG5cdFx0XHQob3B0aW9ucy5wb2ludCAmJiBvcHRpb25zLnBvaW50LmV2ZW50cyAmJiBvcHRpb25zLnBvaW50LmV2ZW50cy5jbGljaykgfHxcblx0XHRcdG9wdGlvbnMuYWxsb3dQb2ludFNlbGVjdFxuXHRcdCkge1xuXHRcdFx0Y2hhcnQucnVuVHJhY2tlckNsaWNrID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRzZXJpZXMuZ2V0Q29sb3IoKTtcblx0XHRzZXJpZXMuZ2V0U3ltYm9sKCk7XG5cblx0XHQvLyBTZXQgdGhlIGRhdGFcblx0XHRlYWNoKHNlcmllcy5wYXJhbGxlbEFycmF5cywgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0c2VyaWVzW2tleSArICdEYXRhJ10gPSBbXTtcblx0XHR9KTtcblx0XHRzZXJpZXMuc2V0RGF0YShvcHRpb25zLmRhdGEsIGZhbHNlKTtcblxuXHRcdC8vIE1hcmsgY2FydGVzaWFuXG5cdFx0aWYgKHNlcmllcy5pc0NhcnRlc2lhbikge1xuXHRcdFx0Y2hhcnQuaGFzQ2FydGVzaWFuU2VyaWVzID0gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBSZWdpc3RlciBpdCBpbiB0aGUgY2hhcnRcblx0XHRjaGFydFNlcmllcy5wdXNoKHNlcmllcyk7XG5cdFx0c2VyaWVzLl9pID0gY2hhcnRTZXJpZXMubGVuZ3RoIC0gMTtcblxuXHRcdC8vIFNvcnQgc2VyaWVzIGFjY29yZGluZyB0byBpbmRleCBvcHRpb24gKCMyNDgsICMxMTIzLCAjMjQ1Nilcblx0XHRzdGFibGVTb3J0KGNoYXJ0U2VyaWVzLCBzb3J0QnlJbmRleCk7XG5cdFx0aWYgKHRoaXMueUF4aXMpIHtcblx0XHRcdHN0YWJsZVNvcnQodGhpcy55QXhpcy5zZXJpZXMsIHNvcnRCeUluZGV4KTtcblx0XHR9XG5cblx0XHRlYWNoKGNoYXJ0U2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzLCBpKSB7XG5cdFx0XHRzZXJpZXMuaW5kZXggPSBpO1xuXHRcdFx0c2VyaWVzLm5hbWUgPSBzZXJpZXMubmFtZSB8fCAnU2VyaWVzICcgKyAoaSArIDEpO1xuXHRcdH0pO1xuXG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgeEF4aXMgYW5kIHlBeGlzIHByb3BlcnRpZXMgb2YgY2FydGVzaWFuIHNlcmllcywgYW5kIHJlZ2lzdGVyIHRoZSBzZXJpZXNcblx0ICogaW4gdGhlIGF4aXMuc2VyaWVzIGFycmF5XG5cdCAqL1xuXHRiaW5kQXhlczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRheGlzT3B0aW9ucztcblxuXHRcdGVhY2goc2VyaWVzLmF4aXNUeXBlcyB8fCBbXSwgZnVuY3Rpb24gKEFYSVMpIHsgLy8gcmVwZWF0IGZvciB4QXhpcyBhbmQgeUF4aXNcblxuXHRcdFx0ZWFjaChjaGFydFtBWElTXSwgZnVuY3Rpb24gKGF4aXMpIHsgLy8gbG9vcCB0aHJvdWdoIHRoZSBjaGFydCdzIGF4aXMgb2JqZWN0c1xuXHRcdFx0XHRheGlzT3B0aW9ucyA9IGF4aXMub3B0aW9ucztcblxuXHRcdFx0XHQvLyBhcHBseSBpZiB0aGUgc2VyaWVzIHhBeGlzIG9yIHlBeGlzIG9wdGlvbiBtYXRoY2hlcyB0aGUgbnVtYmVyIG9mIHRoZVxuXHRcdFx0XHQvLyBheGlzLCBvciBpZiB1bmRlZmluZWQsIHVzZSB0aGUgZmlyc3QgYXhpc1xuXHRcdFx0XHRpZiAoKHNlcmllc09wdGlvbnNbQVhJU10gPT09IGF4aXNPcHRpb25zLmluZGV4KSB8fFxuXHRcdFx0XHRcdFx0KHNlcmllc09wdGlvbnNbQVhJU10gIT09IFVOREVGSU5FRCAmJiBzZXJpZXNPcHRpb25zW0FYSVNdID09PSBheGlzT3B0aW9ucy5pZCkgfHxcblx0XHRcdFx0XHRcdChzZXJpZXNPcHRpb25zW0FYSVNdID09PSBVTkRFRklORUQgJiYgYXhpc09wdGlvbnMuaW5kZXggPT09IDApKSB7XG5cblx0XHRcdFx0XHQvLyByZWdpc3RlciB0aGlzIHNlcmllcyBpbiB0aGUgYXhpcy5zZXJpZXMgbG9va3VwXG5cdFx0XHRcdFx0YXhpcy5zZXJpZXMucHVzaChzZXJpZXMpO1xuXG5cdFx0XHRcdFx0Ly8gc2V0IHRoaXMgc2VyaWVzLnhBeGlzIG9yIHNlcmllcy55QXhpcyByZWZlcmVuY2Vcblx0XHRcdFx0XHRzZXJpZXNbQVhJU10gPSBheGlzO1xuXG5cdFx0XHRcdFx0Ly8gbWFyayBkaXJ0eSBmb3IgcmVkcmF3XG5cdFx0XHRcdFx0YXhpcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFRoZSBzZXJpZXMgbmVlZHMgYW4gWCBhbmQgYW4gWSBheGlzXG5cdFx0XHRpZiAoIXNlcmllc1tBWElTXSAmJiBzZXJpZXMub3B0aW9uYWxBeGlzICE9PSBBWElTKSB7XG5cdFx0XHRcdGVycm9yKDE4LCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBGb3Igc2ltcGxlIHNlcmllcyB0eXBlcyBsaWtlIGxpbmUgYW5kIGNvbHVtbiwgdGhlIGRhdGEgdmFsdWVzIGFyZSBoZWxkIGluIGFycmF5cyBsaWtlXG5cdCAqIHhEYXRhIGFuZCB5RGF0YSBmb3IgcXVpY2sgbG9va3VwIHRvIGZpbmQgZXh0cmVtZXMgYW5kIG1vcmUuIEZvciBtdWx0aWRpbWVuc2lvbmFsIHNlcmllc1xuXHQgKiBsaWtlIGJ1YmJsZSBhbmQgbWFwLCB0aGlzIGNhbiBiZSBleHRlbmRlZCB3aXRoIGFycmF5cyBsaWtlIHpEYXRhIGFuZCB2YWx1ZURhdGEgYnlcblx0ICogYWRkaW5nIHRvIHRoZSBzZXJpZXMucGFyYWxsZWxBcnJheXMgYXJyYXkuXG5cdCAqL1xuXHR1cGRhdGVQYXJhbGxlbEFycmF5czogZnVuY3Rpb24gKHBvaW50LCBpKSB7XG5cdFx0dmFyIHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRmbiA9IHR5cGVvZiBpID09PSAnbnVtYmVyJyA/XG5cdFx0XHRcdCAvLyBJbnNlcnQgdGhlIHZhbHVlIGluIHRoZSBnaXZlbiBwb3NpdGlvblxuXHRcdFx0XHRmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGtleSA9PT0gJ3knICYmIHNlcmllcy50b1lEYXRhID8gc2VyaWVzLnRvWURhdGEocG9pbnQpIDogcG9pbnRba2V5XTtcblx0XHRcdFx0XHRzZXJpZXNba2V5ICsgJ0RhdGEnXVtpXSA9IHZhbDtcblx0XHRcdFx0fSA6XG5cdFx0XHRcdC8vIEFwcGx5IHRoZSBtZXRob2Qgc3BlY2lmaWVkIGluIGkgd2l0aCB0aGUgZm9sbG93aW5nIGFyZ3VtZW50cyBhcyBhcmd1bWVudHNcblx0XHRcdFx0ZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XHRcdEFycmF5LnByb3RvdHlwZVtpXS5hcHBseShzZXJpZXNba2V5ICsgJ0RhdGEnXSwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMikpO1xuXHRcdFx0XHR9O1xuXG5cdFx0ZWFjaChzZXJpZXMucGFyYWxsZWxBcnJheXMsIGZuKTtcblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJuIGFuIGF1dG8gaW5jcmVtZW50ZWQgeCB2YWx1ZSBiYXNlZCBvbiB0aGUgcG9pbnRTdGFydCBhbmQgcG9pbnRJbnRlcnZhbCBvcHRpb25zLlxuXHQgKiBUaGlzIGlzIG9ubHkgdXNlZCBpZiBhbiB4IHZhbHVlIGlzIG5vdCBnaXZlbiBmb3IgdGhlIHBvaW50IHRoYXQgY2FsbHMgYXV0b0luY3JlbWVudC5cblx0ICovXG5cdGF1dG9JbmNyZW1lbnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdHhJbmNyZW1lbnQgPSBzZXJpZXMueEluY3JlbWVudDtcblxuXHRcdHhJbmNyZW1lbnQgPSBwaWNrKHhJbmNyZW1lbnQsIG9wdGlvbnMucG9pbnRTdGFydCwgMCk7XG5cblx0XHRzZXJpZXMucG9pbnRJbnRlcnZhbCA9IHBpY2soc2VyaWVzLnBvaW50SW50ZXJ2YWwsIG9wdGlvbnMucG9pbnRJbnRlcnZhbCwgMSk7XG5cblx0XHRzZXJpZXMueEluY3JlbWVudCA9IHhJbmNyZW1lbnQgKyBzZXJpZXMucG9pbnRJbnRlcnZhbDtcblx0XHRyZXR1cm4geEluY3JlbWVudDtcblx0fSxcblxuXHQvKipcblx0ICogRGl2aWRlIHRoZSBzZXJpZXMgZGF0YSBpbnRvIHNlZ21lbnRzIGRpdmlkZWQgYnkgbnVsbCB2YWx1ZXMuXG5cdCAqL1xuXHRnZXRTZWdtZW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0bGFzdE51bGwgPSAtMSxcblx0XHRcdHNlZ21lbnRzID0gW10sXG5cdFx0XHRpLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdHBvaW50c0xlbmd0aCA9IHBvaW50cy5sZW5ndGg7XG5cblx0XHRpZiAocG9pbnRzTGVuZ3RoKSB7IC8vIG5vIGFjdGlvbiByZXF1aXJlZCBmb3IgW11cblxuXHRcdFx0Ly8gaWYgY29ubmVjdCBudWxscywganVzdCByZW1vdmUgbnVsbCBwb2ludHNcblx0XHRcdGlmIChzZXJpZXMub3B0aW9ucy5jb25uZWN0TnVsbHMpIHtcblx0XHRcdFx0aSA9IHBvaW50c0xlbmd0aDtcblx0XHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRcdGlmIChwb2ludHNbaV0ueSA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0cG9pbnRzLnNwbGljZShpLCAxKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHBvaW50cy5sZW5ndGgpIHtcblx0XHRcdFx0XHRzZWdtZW50cyA9IFtwb2ludHNdO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIGVsc2UsIHNwbGl0IG9uIG51bGwgcG9pbnRzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50LCBpKSB7XG5cdFx0XHRcdFx0aWYgKHBvaW50LnkgPT09IG51bGwpIHtcblx0XHRcdFx0XHRcdGlmIChpID4gbGFzdE51bGwgKyAxKSB7XG5cdFx0XHRcdFx0XHRcdHNlZ21lbnRzLnB1c2gocG9pbnRzLnNsaWNlKGxhc3ROdWxsICsgMSwgaSkpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0bGFzdE51bGwgPSBpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoaSA9PT0gcG9pbnRzTGVuZ3RoIC0gMSkgeyAvLyBsYXN0IHZhbHVlXG5cdFx0XHRcdFx0XHRzZWdtZW50cy5wdXNoKHBvaW50cy5zbGljZShsYXN0TnVsbCArIDEsIGkgKyAxKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyByZWdpc3RlciBpdFxuXHRcdHNlcmllcy5zZWdtZW50cyA9IHNlZ21lbnRzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHNlcmllcyBvcHRpb25zIGJ5IG1lcmdpbmcgZnJvbSB0aGUgb3B0aW9ucyB0cmVlXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtT3B0aW9uc1xuXHQgKi9cblx0c2V0T3B0aW9uczogZnVuY3Rpb24gKGl0ZW1PcHRpb25zKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGNoYXJ0T3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMsXG5cdFx0XHRwbG90T3B0aW9ucyA9IGNoYXJ0T3B0aW9ucy5wbG90T3B0aW9ucyxcblx0XHRcdHVzZXJPcHRpb25zID0gY2hhcnQudXNlck9wdGlvbnMgfHwge30sXG5cdFx0XHR1c2VyUGxvdE9wdGlvbnMgPSB1c2VyT3B0aW9ucy5wbG90T3B0aW9ucyB8fCB7fSxcblx0XHRcdHR5cGVPcHRpb25zID0gcGxvdE9wdGlvbnNbdGhpcy50eXBlXSxcblx0XHRcdG9wdGlvbnM7XG5cblx0XHR0aGlzLnVzZXJPcHRpb25zID0gaXRlbU9wdGlvbnM7XG5cblx0XHRvcHRpb25zID0gbWVyZ2UoXG5cdFx0XHR0eXBlT3B0aW9ucyxcblx0XHRcdHBsb3RPcHRpb25zLnNlcmllcyxcblx0XHRcdGl0ZW1PcHRpb25zXG5cdFx0KTtcblxuXHRcdC8vIFRoZSB0b29sdGlwIG9wdGlvbnMgYXJlIG1lcmdlZCBiZXR3ZWVuIGdsb2JhbCBhbmQgc2VyaWVzIHNwZWNpZmljIG9wdGlvbnNcblx0XHR0aGlzLnRvb2x0aXBPcHRpb25zID0gbWVyZ2UoXG5cdFx0XHRkZWZhdWx0T3B0aW9ucy50b29sdGlwLFxuXHRcdFx0ZGVmYXVsdE9wdGlvbnMucGxvdE9wdGlvbnNbdGhpcy50eXBlXS50b29sdGlwLFxuXHRcdFx0dXNlck9wdGlvbnMudG9vbHRpcCxcblx0XHRcdHVzZXJQbG90T3B0aW9ucy5zZXJpZXMgJiYgdXNlclBsb3RPcHRpb25zLnNlcmllcy50b29sdGlwLFxuXHRcdFx0dXNlclBsb3RPcHRpb25zW3RoaXMudHlwZV0gJiYgdXNlclBsb3RPcHRpb25zW3RoaXMudHlwZV0udG9vbHRpcCxcblx0XHRcdGl0ZW1PcHRpb25zLnRvb2x0aXBcblx0XHQpO1xuXG5cdFx0Ly8gRGVsZXRlIG1hcmtlciBvYmplY3QgaWYgbm90IGFsbG93ZWQgKCMxMTI1KVxuXHRcdGlmICh0eXBlT3B0aW9ucy5tYXJrZXIgPT09IG51bGwpIHtcblx0XHRcdGRlbGV0ZSBvcHRpb25zLm1hcmtlcjtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3B0aW9ucztcblxuXHR9LFxuXG5cdGdldEN5Y2xpYzogZnVuY3Rpb24gKHByb3AsIHZhbHVlLCBkZWZhdWx0cykge1xuXHRcdHZhciBpLFxuXHRcdFx0dXNlck9wdGlvbnMgPSB0aGlzLnVzZXJPcHRpb25zLFxuXHRcdFx0aW5kZXhOYW1lID0gJ18nICsgcHJvcCArICdJbmRleCcsXG5cdFx0XHRjb3VudGVyTmFtZSA9IHByb3AgKyAnQ291bnRlcic7XG5cblx0XHRpZiAoIXZhbHVlKSB7XG5cdFx0XHRpZiAoZGVmaW5lZCh1c2VyT3B0aW9uc1tpbmRleE5hbWVdKSkgeyAvLyBhZnRlciBTZXJpZXMudXBkYXRlKClcblx0XHRcdFx0aSA9IHVzZXJPcHRpb25zW2luZGV4TmFtZV07XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR1c2VyT3B0aW9uc1tpbmRleE5hbWVdID0gaSA9IHRoaXMuY2hhcnRbY291bnRlck5hbWVdICUgZGVmYXVsdHMubGVuZ3RoO1xuXHRcdFx0XHR0aGlzLmNoYXJ0W2NvdW50ZXJOYW1lXSArPSAxO1xuXHRcdFx0fVxuXHRcdFx0dmFsdWUgPSBkZWZhdWx0c1tpXTtcblx0XHR9XG5cdFx0dGhpc1twcm9wXSA9IHZhbHVlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHNlcmllcycgY29sb3Jcblx0ICovXG5cdGdldENvbG9yOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKCF0aGlzLm9wdGlvbnMuY29sb3JCeVBvaW50KSB7XG5cdFx0XHR0aGlzLmdldEN5Y2xpYygnY29sb3InLCB0aGlzLm9wdGlvbnMuY29sb3IgfHwgZGVmYXVsdFBsb3RPcHRpb25zW3RoaXMudHlwZV0uY29sb3IsIHRoaXMuY2hhcnQub3B0aW9ucy5jb2xvcnMpO1xuXHRcdH1cblx0fSxcblx0LyoqXG5cdCAqIEdldCB0aGUgc2VyaWVzJyBzeW1ib2xcblx0ICovXG5cdGdldFN5bWJvbDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXNNYXJrZXJPcHRpb24gPSB0aGlzLm9wdGlvbnMubWFya2VyO1xuXG5cdFx0dGhpcy5nZXRDeWNsaWMoJ3N5bWJvbCcsIHNlcmllc01hcmtlck9wdGlvbi5zeW1ib2wsIHRoaXMuY2hhcnQub3B0aW9ucy5zeW1ib2xzKTtcblxuXHRcdC8vIGRvbid0IHN1YnN0cmFjdCByYWRpdXMgaW4gaW1hZ2Ugc3ltYm9scyAoIzYwNClcblx0XHRpZiAoL151cmwvLnRlc3QodGhpcy5zeW1ib2wpKSB7XG5cdFx0XHRzZXJpZXNNYXJrZXJPcHRpb24ucmFkaXVzID0gMDtcblx0XHR9XG5cdH0sXG5cblx0ZHJhd0xlZ2VuZFN5bWJvbDogTGVnZW5kU3ltYm9sTWl4aW4uZHJhd0xpbmVNYXJrZXIsXG5cblx0LyoqXG5cdCAqIFJlcGxhY2UgdGhlIHNlcmllcyBkYXRhIHdpdGggYSBuZXcgc2V0IG9mIGRhdGFcblx0ICogQHBhcmFtIHtPYmplY3R9IGRhdGFcblx0ICogQHBhcmFtIHtPYmplY3R9IHJlZHJhd1xuXHQgKi9cblx0c2V0RGF0YTogZnVuY3Rpb24gKGRhdGEsIHJlZHJhdywgYW5pbWF0aW9uLCB1cGRhdGVQb2ludHMpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9sZERhdGEgPSBzZXJpZXMucG9pbnRzLFxuXHRcdFx0b2xkRGF0YUxlbmd0aCA9IChvbGREYXRhICYmIG9sZERhdGEubGVuZ3RoKSB8fCAwLFxuXHRcdFx0ZGF0YUxlbmd0aCxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0Zmlyc3RQb2ludCA9IG51bGwsXG5cdFx0XHR4QXhpcyA9IHNlcmllcy54QXhpcyxcblx0XHRcdGhhc0NhdGVnb3JpZXMgPSB4QXhpcyAmJiAhIXhBeGlzLmNhdGVnb3JpZXMsXG5cdFx0XHR0b29sdGlwUG9pbnRzID0gc2VyaWVzLnRvb2x0aXBQb2ludHMsXG5cdFx0XHRpLFxuXHRcdFx0dHVyYm9UaHJlc2hvbGQgPSBvcHRpb25zLnR1cmJvVGhyZXNob2xkLFxuXHRcdFx0cHQsXG5cdFx0XHR4RGF0YSA9IHRoaXMueERhdGEsXG5cdFx0XHR5RGF0YSA9IHRoaXMueURhdGEsXG5cdFx0XHRwb2ludEFycmF5TWFwID0gc2VyaWVzLnBvaW50QXJyYXlNYXAsXG5cdFx0XHR2YWx1ZUNvdW50ID0gcG9pbnRBcnJheU1hcCAmJiBwb2ludEFycmF5TWFwLmxlbmd0aDtcblxuXHRcdGRhdGEgPSBkYXRhIHx8IFtdO1xuXHRcdGRhdGFMZW5ndGggPSBkYXRhLmxlbmd0aDtcblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7XG5cblx0XHQvLyBJZiB0aGUgcG9pbnQgY291bnQgaXMgdGhlIHNhbWUgYXMgaXMgd2FzLCBqdXN0IHJ1biBQb2ludC51cGRhdGUgd2hpY2ggaXNcblx0XHQvLyBjaGVhcGVyLCBhbGxvd3MgYW5pbWF0aW9uLCBhbmQga2VlcHMgcmVmZXJlbmNlcyB0byBwb2ludHMuXG5cdFx0aWYgKHVwZGF0ZVBvaW50cyAhPT0gZmFsc2UgJiYgZGF0YUxlbmd0aCAmJiBvbGREYXRhTGVuZ3RoID09PSBkYXRhTGVuZ3RoICYmICFzZXJpZXMuY3JvcHBlZCAmJiAhc2VyaWVzLmhhc0dyb3VwZWREYXRhKSB7XG5cdFx0XHRlYWNoKGRhdGEsIGZ1bmN0aW9uIChwb2ludCwgaSkge1xuXHRcdFx0XHRvbGREYXRhW2ldLnVwZGF0ZShwb2ludCwgZmFsc2UsIG51bGwsIGZhbHNlKTtcblx0XHRcdH0pO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gUmVzZXQgcHJvcGVydGllc1xuXHRcdFx0c2VyaWVzLnhJbmNyZW1lbnQgPSBudWxsO1xuXHRcdFx0c2VyaWVzLnBvaW50UmFuZ2UgPSBoYXNDYXRlZ29yaWVzID8gMSA6IG9wdGlvbnMucG9pbnRSYW5nZTtcblxuXHRcdFx0c2VyaWVzLmNvbG9yQ291bnRlciA9IDA7IC8vIGZvciBzZXJpZXMgd2l0aCBjb2xvckJ5UG9pbnQgKCMxNTQ3KVxuXHRcdFx0XG5cdFx0XHQvLyBVcGRhdGUgcGFyYWxsZWwgYXJyYXlzXG5cdFx0XHRlYWNoKHRoaXMucGFyYWxsZWxBcnJheXMsIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0c2VyaWVzW2tleSArICdEYXRhJ10ubGVuZ3RoID0gMDtcblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBJbiB0dXJibyBtb2RlLCBvbmx5IG9uZS0gb3IgdHdvZGltZW5zaW9uYWwgYXJyYXlzIG9mIG51bWJlcnMgYXJlIGFsbG93ZWQuIFRoZVxuXHRcdFx0Ly8gZmlyc3QgdmFsdWUgaXMgdGVzdGVkLCBhbmQgd2UgYXNzdW1lIHRoYXQgYWxsIHRoZSByZXN0IGFyZSBkZWZpbmVkIHRoZSBzYW1lXG5cdFx0XHQvLyB3YXkuIEFsdGhvdWdoIHRoZSAnZm9yJyBsb29wcyBhcmUgc2ltaWxhciwgdGhleSBhcmUgcmVwZWF0ZWQgaW5zaWRlIGVhY2hcblx0XHRcdC8vIGlmLWVsc2UgY29uZGl0aW9uYWwgZm9yIG1heCBwZXJmb3JtYW5jZS5cblx0XHRcdGlmICh0dXJib1RocmVzaG9sZCAmJiBkYXRhTGVuZ3RoID4gdHVyYm9UaHJlc2hvbGQpIHtcblxuXHRcdFx0XHQvLyBmaW5kIHRoZSBmaXJzdCBub24tbnVsbCBwb2ludFxuXHRcdFx0XHRpID0gMDtcblx0XHRcdFx0d2hpbGUgKGZpcnN0UG9pbnQgPT09IG51bGwgJiYgaSA8IGRhdGFMZW5ndGgpIHtcblx0XHRcdFx0XHRmaXJzdFBvaW50ID0gZGF0YVtpXTtcblx0XHRcdFx0XHRpKys7XG5cdFx0XHRcdH1cblxuXG5cdFx0XHRcdGlmIChpc051bWJlcihmaXJzdFBvaW50KSkgeyAvLyBhc3N1bWUgYWxsIHBvaW50cyBhcmUgbnVtYmVyc1xuXHRcdFx0XHRcdHZhciB4ID0gcGljayhvcHRpb25zLnBvaW50U3RhcnQsIDApLFxuXHRcdFx0XHRcdFx0cG9pbnRJbnRlcnZhbCA9IHBpY2sob3B0aW9ucy5wb2ludEludGVydmFsLCAxKTtcblxuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdHhEYXRhW2ldID0geDtcblx0XHRcdFx0XHRcdHlEYXRhW2ldID0gZGF0YVtpXTtcblx0XHRcdFx0XHRcdHggKz0gcG9pbnRJbnRlcnZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c2VyaWVzLnhJbmNyZW1lbnQgPSB4O1xuXHRcdFx0XHR9IGVsc2UgaWYgKGlzQXJyYXkoZmlyc3RQb2ludCkpIHsgLy8gYXNzdW1lIGFsbCBwb2ludHMgYXJlIGFycmF5c1xuXHRcdFx0XHRcdGlmICh2YWx1ZUNvdW50KSB7IC8vIFt4LCBsb3csIGhpZ2hdIG9yIFt4LCBvLCBoLCBsLCBjXVxuXHRcdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGRhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRwdCA9IGRhdGFbaV07XG5cdFx0XHRcdFx0XHRcdHhEYXRhW2ldID0gcHRbMF07XG5cdFx0XHRcdFx0XHRcdHlEYXRhW2ldID0gcHQuc2xpY2UoMSwgdmFsdWVDb3VudCArIDEpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSB7IC8vIFt4LCB5XVxuXHRcdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGRhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0XHRwdCA9IGRhdGFbaV07XG5cdFx0XHRcdFx0XHRcdHhEYXRhW2ldID0gcHRbMF07XG5cdFx0XHRcdFx0XHRcdHlEYXRhW2ldID0gcHRbMV07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVycm9yKDEyKTsgLy8gSGlnaGNoYXJ0cyBleHBlY3RzIGNvbmZpZ3MgdG8gYmUgbnVtYmVycyBvciBhcnJheXMgaW4gdHVyYm8gbW9kZVxuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0aWYgKGRhdGFbaV0gIT09IFVOREVGSU5FRCkgeyAvLyBzdHJheSBjb21tYXMgaW4gb2xkSUVcblx0XHRcdFx0XHRcdHB0ID0geyBzZXJpZXM6IHNlcmllcyB9O1xuXHRcdFx0XHRcdFx0c2VyaWVzLnBvaW50Q2xhc3MucHJvdG90eXBlLmFwcGx5T3B0aW9ucy5hcHBseShwdCwgW2RhdGFbaV1dKTtcblx0XHRcdFx0XHRcdHNlcmllcy51cGRhdGVQYXJhbGxlbEFycmF5cyhwdCwgaSk7XG5cdFx0XHRcdFx0XHRpZiAoaGFzQ2F0ZWdvcmllcyAmJiBwdC5uYW1lKSB7XG5cdFx0XHRcdFx0XHRcdHhBeGlzLm5hbWVzW3B0LnhdID0gcHQubmFtZTsgLy8gIzIwNDZcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yZ2V0dGluZyB0byBjYXN0IHN0cmluZ3MgdG8gbnVtYmVycyBpcyBhIGNvbW1vbiBjYXZlYXQgd2hlbiBoYW5kbGluZyBDU1Ygb3IgSlNPTlxuXHRcdFx0aWYgKGlzU3RyaW5nKHlEYXRhWzBdKSkge1xuXHRcdFx0XHRlcnJvcigxNCwgdHJ1ZSk7XG5cdFx0XHR9XG5cblx0XHRcdHNlcmllcy5kYXRhID0gW107XG5cdFx0XHRzZXJpZXMub3B0aW9ucy5kYXRhID0gZGF0YTtcblx0XHRcdC8vc2VyaWVzLnpEYXRhID0gekRhdGE7XG5cblx0XHRcdC8vIGRlc3Ryb3kgb2xkIHBvaW50c1xuXHRcdFx0aSA9IG9sZERhdGFMZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdGlmIChvbGREYXRhW2ldICYmIG9sZERhdGFbaV0uZGVzdHJveSkge1xuXHRcdFx0XHRcdG9sZERhdGFbaV0uZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAodG9vbHRpcFBvaW50cykgeyAvLyAjMjU5NFxuXHRcdFx0XHR0b29sdGlwUG9pbnRzLmxlbmd0aCA9IDA7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlc2V0IG1pblJhbmdlICgjODc4KVxuXHRcdFx0aWYgKHhBeGlzKSB7XG5cdFx0XHRcdHhBeGlzLm1pblJhbmdlID0geEF4aXMudXNlck1pblJhbmdlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyByZWRyYXdcblx0XHRcdHNlcmllcy5pc0RpcnR5ID0gc2VyaWVzLmlzRGlydHlEYXRhID0gY2hhcnQuaXNEaXJ0eUJveCA9IHRydWU7XG5cdFx0XHRhbmltYXRpb24gPSBmYWxzZTtcblx0XHR9XG5cblx0XHRpZiAocmVkcmF3KSB7XG5cdFx0XHRjaGFydC5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFByb2Nlc3MgdGhlIGRhdGEgYnkgY3JvcHBpbmcgYXdheSB1bnVzZWQgZGF0YSBwb2ludHMgaWYgdGhlIHNlcmllcyBpcyBsb25nZXJcblx0ICogdGhhbiB0aGUgY3JvcCB0aHJlc2hvbGQuIFRoaXMgc2F2ZXMgY29tcHV0aW5nIHRpbWUgZm9yIGxhZ2Ugc2VyaWVzLlxuXHQgKi9cblx0cHJvY2Vzc0RhdGE6IGZ1bmN0aW9uIChmb3JjZSkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0cHJvY2Vzc2VkWERhdGEgPSBzZXJpZXMueERhdGEsIC8vIGNvcGllZCBkdXJpbmcgc2xpY2Ugb3BlcmF0aW9uIGJlbG93XG5cdFx0XHRwcm9jZXNzZWRZRGF0YSA9IHNlcmllcy55RGF0YSxcblx0XHRcdGRhdGFMZW5ndGggPSBwcm9jZXNzZWRYRGF0YS5sZW5ndGgsXG5cdFx0XHRjcm9wcGVkRGF0YSxcblx0XHRcdGNyb3BTdGFydCA9IDAsXG5cdFx0XHRjcm9wcGVkLFxuXHRcdFx0ZGlzdGFuY2UsXG5cdFx0XHRjbG9zZXN0UG9pbnRSYW5nZSxcblx0XHRcdHhBeGlzID0gc2VyaWVzLnhBeGlzLFxuXHRcdFx0aSwgLy8gbG9vcCB2YXJpYWJsZVxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0Y3JvcFRocmVzaG9sZCA9IG9wdGlvbnMuY3JvcFRocmVzaG9sZCxcblx0XHRcdGFjdGl2ZVBvaW50Q291bnQgPSAwLFxuXHRcdFx0aXNDYXJ0ZXNpYW4gPSBzZXJpZXMuaXNDYXJ0ZXNpYW4sXG5cdFx0XHR4RXh0cmVtZXMsXG5cdFx0XHRtaW4sXG5cdFx0XHRtYXg7XG5cblx0XHQvLyBJZiB0aGUgc2VyaWVzIGRhdGEgb3IgYXhlcyBoYXZlbid0IGNoYW5nZWQsIGRvbid0IGdvIHRocm91Z2ggdGhpcy4gUmV0dXJuIGZhbHNlIHRvIHBhc3Ncblx0XHQvLyB0aGUgbWVzc2FnZSBvbiB0byBvdmVycmlkZSBtZXRob2RzIGxpa2UgaW4gZGF0YSBncm91cGluZy5cblx0XHRpZiAoaXNDYXJ0ZXNpYW4gJiYgIXNlcmllcy5pc0RpcnR5ICYmICF4QXhpcy5pc0RpcnR5ICYmICFzZXJpZXMueUF4aXMuaXNEaXJ0eSAmJiAhZm9yY2UpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRpZiAoeEF4aXMpIHtcblx0XHRcdHhFeHRyZW1lcyA9IHhBeGlzLmdldEV4dHJlbWVzKCk7IC8vIGNvcnJlY3RlZCBmb3IgbG9nIGF4aXMgKCMzMDUzKVxuXHRcdFx0bWluID0geEV4dHJlbWVzLm1pbjtcblx0XHRcdG1heCA9IHhFeHRyZW1lcy5tYXg7XG5cdFx0fVxuXG5cdFx0Ly8gb3B0aW9uYWxseSBmaWx0ZXIgb3V0IHBvaW50cyBvdXRzaWRlIHRoZSBwbG90IGFyZWFcblx0XHRpZiAoaXNDYXJ0ZXNpYW4gJiYgc2VyaWVzLnNvcnRlZCAmJiAoIWNyb3BUaHJlc2hvbGQgfHwgZGF0YUxlbmd0aCA+IGNyb3BUaHJlc2hvbGQgfHwgc2VyaWVzLmZvcmNlQ3JvcCkpIHtcblx0XHRcdFxuXHRcdFx0Ly8gaXQncyBvdXRzaWRlIGN1cnJlbnQgZXh0cmVtZXNcblx0XHRcdGlmIChwcm9jZXNzZWRYRGF0YVtkYXRhTGVuZ3RoIC0gMV0gPCBtaW4gfHwgcHJvY2Vzc2VkWERhdGFbMF0gPiBtYXgpIHtcblx0XHRcdFx0cHJvY2Vzc2VkWERhdGEgPSBbXTtcblx0XHRcdFx0cHJvY2Vzc2VkWURhdGEgPSBbXTtcblxuXHRcdFx0Ly8gb25seSBjcm9wIGlmIGl0J3MgYWN0dWFsbHkgc3BpbGxpbmcgb3V0XG5cdFx0XHR9IGVsc2UgaWYgKHByb2Nlc3NlZFhEYXRhWzBdIDwgbWluIHx8IHByb2Nlc3NlZFhEYXRhW2RhdGFMZW5ndGggLSAxXSA+IG1heCkge1xuXHRcdFx0XHRjcm9wcGVkRGF0YSA9IHRoaXMuY3JvcERhdGEoc2VyaWVzLnhEYXRhLCBzZXJpZXMueURhdGEsIG1pbiwgbWF4KTtcblx0XHRcdFx0cHJvY2Vzc2VkWERhdGEgPSBjcm9wcGVkRGF0YS54RGF0YTtcblx0XHRcdFx0cHJvY2Vzc2VkWURhdGEgPSBjcm9wcGVkRGF0YS55RGF0YTtcblx0XHRcdFx0Y3JvcFN0YXJ0ID0gY3JvcHBlZERhdGEuc3RhcnQ7XG5cdFx0XHRcdGNyb3BwZWQgPSB0cnVlO1xuXHRcdFx0XHRhY3RpdmVQb2ludENvdW50ID0gcHJvY2Vzc2VkWERhdGEubGVuZ3RoO1xuXHRcdFx0fVxuXHRcdH1cblxuXG5cdFx0Ly8gRmluZCB0aGUgY2xvc2VzdCBkaXN0YW5jZSBiZXR3ZWVuIHByb2Nlc3NlZCBwb2ludHNcblx0XHRmb3IgKGkgPSBwcm9jZXNzZWRYRGF0YS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXHRcdFx0ZGlzdGFuY2UgPSBwcm9jZXNzZWRYRGF0YVtpXSAtIHByb2Nlc3NlZFhEYXRhW2kgLSAxXTtcblx0XHRcdFxuXHRcdFx0aWYgKCFjcm9wcGVkICYmIHByb2Nlc3NlZFhEYXRhW2ldID4gbWluICYmIHByb2Nlc3NlZFhEYXRhW2ldIDwgbWF4KSB7XG5cdFx0XHRcdGFjdGl2ZVBvaW50Q291bnQrKztcblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0aWYgKGRpc3RhbmNlID4gMCAmJiAoY2xvc2VzdFBvaW50UmFuZ2UgPT09IFVOREVGSU5FRCB8fCBkaXN0YW5jZSA8IGNsb3Nlc3RQb2ludFJhbmdlKSkge1xuXHRcdFx0XHRjbG9zZXN0UG9pbnRSYW5nZSA9IGRpc3RhbmNlO1xuXG5cdFx0XHQvLyBVbnNvcnRlZCBkYXRhIGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGxpbmUgdG9vbHRpcCwgYXMgd2VsbCBhcyBkYXRhIGdyb3VwaW5nIGFuZFxuXHRcdFx0Ly8gbmF2aWdhdGlvbiBpbiBTdG9jayBjaGFydHMgKCM3MjUpIGFuZCB3aWR0aCBjYWxjdWxhdGlvbiBvZiBjb2x1bW5zICgjMTkwMClcblx0XHRcdH0gZWxzZSBpZiAoZGlzdGFuY2UgPCAwICYmIHNlcmllcy5yZXF1aXJlU29ydGluZykge1xuXHRcdFx0XHRlcnJvcigxNSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVjb3JkIHRoZSBwcm9wZXJ0aWVzXG5cdFx0c2VyaWVzLmNyb3BwZWQgPSBjcm9wcGVkOyAvLyB1bmRlZmluZWQgb3IgdHJ1ZVxuXHRcdHNlcmllcy5jcm9wU3RhcnQgPSBjcm9wU3RhcnQ7XG5cdFx0c2VyaWVzLnByb2Nlc3NlZFhEYXRhID0gcHJvY2Vzc2VkWERhdGE7XG5cdFx0c2VyaWVzLnByb2Nlc3NlZFlEYXRhID0gcHJvY2Vzc2VkWURhdGE7XG5cdFx0c2VyaWVzLmFjdGl2ZVBvaW50Q291bnQgPSBhY3RpdmVQb2ludENvdW50O1xuXG5cdFx0aWYgKG9wdGlvbnMucG9pbnRSYW5nZSA9PT0gbnVsbCkgeyAvLyBudWxsIG1lYW5zIGF1dG8sIGFzIGZvciBjb2x1bW5zLCBjYW5kbGVzdGlja3MgYW5kIE9ITENcblx0XHRcdHNlcmllcy5wb2ludFJhbmdlID0gY2xvc2VzdFBvaW50UmFuZ2UgfHwgMTtcblx0XHR9XG5cdFx0c2VyaWVzLmNsb3Nlc3RQb2ludFJhbmdlID0gY2xvc2VzdFBvaW50UmFuZ2U7XG5cblx0fSxcblxuXHQvKipcblx0ICogSXRlcmF0ZSBvdmVyIHhEYXRhIGFuZCBjcm9wIHZhbHVlcyBiZXR3ZWVuIG1pbiBhbmQgbWF4LiBSZXR1cm5zIG9iamVjdCBjb250YWluaW5nIGNyb3Agc3RhcnQvZW5kXG5cdCAqIGNyb3BwZWQgeERhdGEgd2l0aCBjb3JyZXNwb25kaW5nIHBhcnQgb2YgeURhdGEsIGRhdGFNaW4gYW5kIGRhdGFNYXggd2l0aGluIHRoZSBjcm9wcGVkIHJhbmdlXG5cdCAqL1xuXHRjcm9wRGF0YTogZnVuY3Rpb24gKHhEYXRhLCB5RGF0YSwgbWluLCBtYXgpIHtcblx0XHR2YXIgZGF0YUxlbmd0aCA9IHhEYXRhLmxlbmd0aCxcblx0XHRcdGNyb3BTdGFydCA9IDAsXG5cdFx0XHRjcm9wRW5kID0gZGF0YUxlbmd0aCxcblx0XHRcdGNyb3BTaG91bGRlciA9IHBpY2sodGhpcy5jcm9wU2hvdWxkZXIsIDEpLCAvLyBsaW5lLXR5cGUgc2VyaWVzIG5lZWQgb25lIHBvaW50IG91dHNpZGVcblx0XHRcdGk7XG5cblx0XHQvLyBpdGVyYXRlIHVwIHRvIGZpbmQgc2xpY2Ugc3RhcnRcblx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoeERhdGFbaV0gPj0gbWluKSB7XG5cdFx0XHRcdGNyb3BTdGFydCA9IG1hdGhNYXgoMCwgaSAtIGNyb3BTaG91bGRlcik7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHByb2NlZWQgdG8gZmluZCBzbGljZSBlbmRcblx0XHRmb3IgKDsgaSA8IGRhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHhEYXRhW2ldID4gbWF4KSB7XG5cdFx0XHRcdGNyb3BFbmQgPSBpICsgY3JvcFNob3VsZGVyO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0eERhdGE6IHhEYXRhLnNsaWNlKGNyb3BTdGFydCwgY3JvcEVuZCksXG5cdFx0XHR5RGF0YTogeURhdGEuc2xpY2UoY3JvcFN0YXJ0LCBjcm9wRW5kKSxcblx0XHRcdHN0YXJ0OiBjcm9wU3RhcnQsXG5cdFx0XHRlbmQ6IGNyb3BFbmRcblx0XHR9O1xuXHR9LFxuXG5cblx0LyoqXG5cdCAqIEdlbmVyYXRlIHRoZSBkYXRhIHBvaW50IGFmdGVyIHRoZSBkYXRhIGhhcyBiZWVuIHByb2Nlc3NlZCBieSBjcm9wcGluZyBhd2F5XG5cdCAqIHVudXNlZCBwb2ludHMgYW5kIG9wdGlvbmFsbHkgZ3JvdXBlZCBpbiBIaWdoY2hhcnRzIFN0b2NrLlxuXHQgKi9cblx0Z2VuZXJhdGVQb2ludHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGRhdGFPcHRpb25zID0gb3B0aW9ucy5kYXRhLFxuXHRcdFx0ZGF0YSA9IHNlcmllcy5kYXRhLFxuXHRcdFx0ZGF0YUxlbmd0aCxcblx0XHRcdHByb2Nlc3NlZFhEYXRhID0gc2VyaWVzLnByb2Nlc3NlZFhEYXRhLFxuXHRcdFx0cHJvY2Vzc2VkWURhdGEgPSBzZXJpZXMucHJvY2Vzc2VkWURhdGEsXG5cdFx0XHRwb2ludENsYXNzID0gc2VyaWVzLnBvaW50Q2xhc3MsXG5cdFx0XHRwcm9jZXNzZWREYXRhTGVuZ3RoID0gcHJvY2Vzc2VkWERhdGEubGVuZ3RoLFxuXHRcdFx0Y3JvcFN0YXJ0ID0gc2VyaWVzLmNyb3BTdGFydCB8fCAwLFxuXHRcdFx0Y3Vyc29yLFxuXHRcdFx0aGFzR3JvdXBlZERhdGEgPSBzZXJpZXMuaGFzR3JvdXBlZERhdGEsXG5cdFx0XHRwb2ludCxcblx0XHRcdHBvaW50cyA9IFtdLFxuXHRcdFx0aTtcblxuXHRcdGlmICghZGF0YSAmJiAhaGFzR3JvdXBlZERhdGEpIHtcblx0XHRcdHZhciBhcnIgPSBbXTtcblx0XHRcdGFyci5sZW5ndGggPSBkYXRhT3B0aW9ucy5sZW5ndGg7XG5cdFx0XHRkYXRhID0gc2VyaWVzLmRhdGEgPSBhcnI7XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMDsgaSA8IHByb2Nlc3NlZERhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0Y3Vyc29yID0gY3JvcFN0YXJ0ICsgaTtcblx0XHRcdGlmICghaGFzR3JvdXBlZERhdGEpIHtcblx0XHRcdFx0aWYgKGRhdGFbY3Vyc29yXSkge1xuXHRcdFx0XHRcdHBvaW50ID0gZGF0YVtjdXJzb3JdO1xuXHRcdFx0XHR9IGVsc2UgaWYgKGRhdGFPcHRpb25zW2N1cnNvcl0gIT09IFVOREVGSU5FRCkgeyAvLyAjOTcwXG5cdFx0XHRcdFx0ZGF0YVtjdXJzb3JdID0gcG9pbnQgPSAobmV3IHBvaW50Q2xhc3MoKSkuaW5pdChzZXJpZXMsIGRhdGFPcHRpb25zW2N1cnNvcl0sIHByb2Nlc3NlZFhEYXRhW2ldKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRwb2ludHNbaV0gPSBwb2ludDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIHNwbGF0IHRoZSB5IGRhdGEgaW4gY2FzZSBvZiBvaGxjIGRhdGEgYXJyYXlcblx0XHRcdFx0cG9pbnRzW2ldID0gKG5ldyBwb2ludENsYXNzKCkpLmluaXQoc2VyaWVzLCBbcHJvY2Vzc2VkWERhdGFbaV1dLmNvbmNhdChzcGxhdChwcm9jZXNzZWRZRGF0YVtpXSkpKTtcblx0XHRcdH1cblx0XHRcdHBvaW50c1tpXS5pbmRleCA9IGN1cnNvcjsgLy8gRm9yIGZhc3RlciBhY2Nlc3MgaW4gUG9pbnQudXBkYXRlXG5cdFx0fVxuXG5cdFx0Ly8gSGlkZSBjcm9wcGVkLWF3YXkgcG9pbnRzIC0gdGhpcyBvbmx5IHJ1bnMgd2hlbiB0aGUgbnVtYmVyIG9mIHBvaW50cyBpcyBhYm92ZSBjcm9wVGhyZXNob2xkLCBvciB3aGVuXG5cdFx0Ly8gc3dpdGhjaGluZyB2aWV3IGZyb20gbm9uLWdyb3VwZWQgZGF0YSB0byBncm91cGVkIGRhdGEgKCM2MzcpXG5cdFx0aWYgKGRhdGEgJiYgKHByb2Nlc3NlZERhdGFMZW5ndGggIT09IChkYXRhTGVuZ3RoID0gZGF0YS5sZW5ndGgpIHx8IGhhc0dyb3VwZWREYXRhKSkge1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGRhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAoaSA9PT0gY3JvcFN0YXJ0ICYmICFoYXNHcm91cGVkRGF0YSkgeyAvLyB3aGVuIGhhcyBncm91cGVkIGRhdGEsIGNsZWFyIGFsbCBwb2ludHNcblx0XHRcdFx0XHRpICs9IHByb2Nlc3NlZERhdGFMZW5ndGg7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGRhdGFbaV0pIHtcblx0XHRcdFx0XHRkYXRhW2ldLmRlc3Ryb3lFbGVtZW50cygpO1xuXHRcdFx0XHRcdGRhdGFbaV0ucGxvdFggPSBVTkRFRklORUQ7IC8vICMxMDAzXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRzZXJpZXMuZGF0YSA9IGRhdGE7XG5cdFx0c2VyaWVzLnBvaW50cyA9IHBvaW50cztcblx0fSxcblxuXHQvKipcblx0ICogQ2FsY3VsYXRlIFkgZXh0cmVtZXMgZm9yIHZpc2libGUgZGF0YVxuXHQgKi9cblx0Z2V0RXh0cmVtZXM6IGZ1bmN0aW9uICh5RGF0YSkge1xuXHRcdHZhciB4QXhpcyA9IHRoaXMueEF4aXMsXG5cdFx0XHR5QXhpcyA9IHRoaXMueUF4aXMsXG5cdFx0XHR4RGF0YSA9IHRoaXMucHJvY2Vzc2VkWERhdGEsXG5cdFx0XHR5RGF0YUxlbmd0aCxcblx0XHRcdGFjdGl2ZVlEYXRhID0gW10sXG5cdFx0XHRhY3RpdmVDb3VudGVyID0gMCxcblx0XHRcdHhFeHRyZW1lcyA9IHhBeGlzLmdldEV4dHJlbWVzKCksIC8vICMyMTE3LCBuZWVkIHRvIGNvbXBlbnNhdGUgZm9yIGxvZyBYIGF4aXNcblx0XHRcdHhNaW4gPSB4RXh0cmVtZXMubWluLFxuXHRcdFx0eE1heCA9IHhFeHRyZW1lcy5tYXgsXG5cdFx0XHR2YWxpZFZhbHVlLFxuXHRcdFx0d2l0aGluUmFuZ2UsXG5cdFx0XHRkYXRhTWluLFxuXHRcdFx0ZGF0YU1heCxcblx0XHRcdHgsXG5cdFx0XHR5LFxuXHRcdFx0aSxcblx0XHRcdGo7XG5cblx0XHR5RGF0YSA9IHlEYXRhIHx8IHRoaXMuc3RhY2tlZFlEYXRhIHx8IHRoaXMucHJvY2Vzc2VkWURhdGE7XG5cdFx0eURhdGFMZW5ndGggPSB5RGF0YS5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgeURhdGFMZW5ndGg7IGkrKykge1xuXG5cdFx0XHR4ID0geERhdGFbaV07XG5cdFx0XHR5ID0geURhdGFbaV07XG5cblx0XHRcdC8vIEZvciBwb2ludHMgd2l0aGluIHRoZSB2aXNpYmxlIHJhbmdlLCBpbmNsdWRpbmcgdGhlIGZpcnN0IHBvaW50IG91dHNpZGUgdGhlXG5cdFx0XHQvLyB2aXNpYmxlIHJhbmdlLCBjb25zaWRlciB5IGV4dHJlbWVzXG5cdFx0XHR2YWxpZFZhbHVlID0geSAhPT0gbnVsbCAmJiB5ICE9PSBVTkRFRklORUQgJiYgKCF5QXhpcy5pc0xvZyB8fCAoeS5sZW5ndGggfHwgeSA+IDApKTtcblx0XHRcdHdpdGhpblJhbmdlID0gdGhpcy5nZXRFeHRyZW1lc0Zyb21BbGwgfHwgdGhpcy5jcm9wcGVkIHx8ICgoeERhdGFbaSArIDFdIHx8IHgpID49IHhNaW4gJiZcblx0XHRcdFx0KHhEYXRhW2kgLSAxXSB8fCB4KSA8PSB4TWF4KTtcblxuXHRcdFx0aWYgKHZhbGlkVmFsdWUgJiYgd2l0aGluUmFuZ2UpIHtcblxuXHRcdFx0XHRqID0geS5sZW5ndGg7XG5cdFx0XHRcdGlmIChqKSB7IC8vIGFycmF5LCBsaWtlIG9obGMgb3IgcmFuZ2UgZGF0YVxuXHRcdFx0XHRcdHdoaWxlIChqLS0pIHtcblx0XHRcdFx0XHRcdGlmICh5W2pdICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0XHRcdGFjdGl2ZVlEYXRhW2FjdGl2ZUNvdW50ZXIrK10gPSB5W2pdO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRhY3RpdmVZRGF0YVthY3RpdmVDb3VudGVyKytdID0geTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHR0aGlzLmRhdGFNaW4gPSBwaWNrKGRhdGFNaW4sIGFycmF5TWluKGFjdGl2ZVlEYXRhKSk7XG5cdFx0dGhpcy5kYXRhTWF4ID0gcGljayhkYXRhTWF4LCBhcnJheU1heChhY3RpdmVZRGF0YSkpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBUcmFuc2xhdGUgZGF0YSBwb2ludHMgZnJvbSByYXcgZGF0YSB2YWx1ZXMgdG8gY2hhcnQgc3BlY2lmaWMgcG9zaXRpb25pbmcgZGF0YVxuXHQgKiBuZWVkZWQgbGF0ZXIgaW4gZHJhd1BvaW50cywgZHJhd0dyYXBoIGFuZCBkcmF3VHJhY2tlci5cblx0ICovXG5cdHRyYW5zbGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdGlmICghdGhpcy5wcm9jZXNzZWRYRGF0YSkgeyAvLyBoaWRkZW4gc2VyaWVzXG5cdFx0XHR0aGlzLnByb2Nlc3NEYXRhKCk7XG5cdFx0fVxuXHRcdHRoaXMuZ2VuZXJhdGVQb2ludHMoKTtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdHN0YWNraW5nID0gb3B0aW9ucy5zdGFja2luZyxcblx0XHRcdHhBeGlzID0gc2VyaWVzLnhBeGlzLFxuXHRcdFx0Y2F0ZWdvcmllcyA9IHhBeGlzLmNhdGVnb3JpZXMsXG5cdFx0XHR5QXhpcyA9IHNlcmllcy55QXhpcyxcblx0XHRcdHBvaW50cyA9IHNlcmllcy5wb2ludHMsXG5cdFx0XHRkYXRhTGVuZ3RoID0gcG9pbnRzLmxlbmd0aCxcblx0XHRcdGhhc01vZGlmeVZhbHVlID0gISFzZXJpZXMubW9kaWZ5VmFsdWUsXG5cdFx0XHRpLFxuXHRcdFx0cG9pbnRQbGFjZW1lbnQgPSBvcHRpb25zLnBvaW50UGxhY2VtZW50LFxuXHRcdFx0ZHluYW1pY2FsbHlQbGFjZWQgPSBwb2ludFBsYWNlbWVudCA9PT0gJ2JldHdlZW4nIHx8IGlzTnVtYmVyKHBvaW50UGxhY2VtZW50KSxcblx0XHRcdHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkO1xuXG5cdFx0Ly8gVHJhbnNsYXRlIGVhY2ggcG9pbnRcblx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgcG9pbnQgPSBwb2ludHNbaV0sXG5cdFx0XHRcdHhWYWx1ZSA9IHBvaW50LngsXG5cdFx0XHRcdHlWYWx1ZSA9IHBvaW50LnksXG5cdFx0XHRcdHlCb3R0b20gPSBwb2ludC5sb3csXG5cdFx0XHRcdHN0YWNrID0gc3RhY2tpbmcgJiYgeUF4aXMuc3RhY2tzWyhzZXJpZXMubmVnU3RhY2tzICYmIHlWYWx1ZSA8IHRocmVzaG9sZCA/ICctJyA6ICcnKSArIHNlcmllcy5zdGFja0tleV0sXG5cdFx0XHRcdHBvaW50U3RhY2ssXG5cdFx0XHRcdHN0YWNrVmFsdWVzO1xuXG5cdFx0XHQvLyBEaXNjYXJkIGRpc2FsbG93ZWQgeSB2YWx1ZXMgZm9yIGxvZyBheGVzXG5cdFx0XHRpZiAoeUF4aXMuaXNMb2cgJiYgeVZhbHVlIDw9IDApIHtcblx0XHRcdFx0cG9pbnQueSA9IHlWYWx1ZSA9IG51bGw7XG5cdFx0XHRcdGVycm9yKDEwKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gR2V0IHRoZSBwbG90WCB0cmFuc2xhdGlvblxuXHRcdFx0cG9pbnQucGxvdFggPSB4QXhpcy50cmFuc2xhdGUoeFZhbHVlLCAwLCAwLCAwLCAxLCBwb2ludFBsYWNlbWVudCwgdGhpcy50eXBlID09PSAnZmxhZ3MnKTsgLy8gTWF0aC5yb3VuZCBmaXhlcyAjNTkxXG5cblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIHRoZSBib3R0b20geSB2YWx1ZSBmb3Igc3RhY2tlZCBzZXJpZXNcblx0XHRcdGlmIChzdGFja2luZyAmJiBzZXJpZXMudmlzaWJsZSAmJiBzdGFjayAmJiBzdGFja1t4VmFsdWVdKSB7XG5cblx0XHRcdFx0cG9pbnRTdGFjayA9IHN0YWNrW3hWYWx1ZV07XG5cdFx0XHRcdHN0YWNrVmFsdWVzID0gcG9pbnRTdGFjay5wb2ludHNbc2VyaWVzLmluZGV4ICsgJywnICsgaV07XG5cdFx0XHRcdHlCb3R0b20gPSBzdGFja1ZhbHVlc1swXTtcblx0XHRcdFx0eVZhbHVlID0gc3RhY2tWYWx1ZXNbMV07XG5cblx0XHRcdFx0aWYgKHlCb3R0b20gPT09IDApIHtcblx0XHRcdFx0XHR5Qm90dG9tID0gcGljayh0aHJlc2hvbGQsIHlBeGlzLm1pbik7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHlBeGlzLmlzTG9nICYmIHlCb3R0b20gPD0gMCkgeyAvLyAjMTIwMCwgIzEyMzJcblx0XHRcdFx0XHR5Qm90dG9tID0gbnVsbDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHBvaW50LnRvdGFsID0gcG9pbnQuc3RhY2tUb3RhbCA9IHBvaW50U3RhY2sudG90YWw7XG5cdFx0XHRcdHBvaW50LnBlcmNlbnRhZ2UgPSBwb2ludFN0YWNrLnRvdGFsICYmIChwb2ludC55IC8gcG9pbnRTdGFjay50b3RhbCAqIDEwMCk7XG5cdFx0XHRcdHBvaW50LnN0YWNrWSA9IHlWYWx1ZTtcblxuXHRcdFx0XHQvLyBQbGFjZSB0aGUgc3RhY2sgbGFiZWxcblx0XHRcdFx0cG9pbnRTdGFjay5zZXRPZmZzZXQoc2VyaWVzLnBvaW50WE9mZnNldCB8fCAwLCBzZXJpZXMuYmFyVyB8fCAwKTtcblxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdHJhbnNsYXRlZCB5Qm90dG9tIG9yIHJlbW92ZSBpdFxuXHRcdFx0cG9pbnQueUJvdHRvbSA9IGRlZmluZWQoeUJvdHRvbSkgP1xuXHRcdFx0XHR5QXhpcy50cmFuc2xhdGUoeUJvdHRvbSwgMCwgMSwgMCwgMSkgOlxuXHRcdFx0XHRudWxsO1xuXG5cdFx0XHQvLyBnZW5lcmFsIGhvb2ssIHVzZWQgZm9yIEhpZ2hzdG9jayBjb21wYXJlIG1vZGVcblx0XHRcdGlmIChoYXNNb2RpZnlWYWx1ZSkge1xuXHRcdFx0XHR5VmFsdWUgPSBzZXJpZXMubW9kaWZ5VmFsdWUoeVZhbHVlLCBwb2ludCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgdGhlIHBsb3RZIHZhbHVlLCByZXNldCBpdCBmb3IgcmVkcmF3c1xuXHRcdFx0cG9pbnQucGxvdFkgPSAodHlwZW9mIHlWYWx1ZSA9PT0gJ251bWJlcicgJiYgeVZhbHVlICE9PSBJbmZpbml0eSkgP1xuXHRcdFx0XHQvL21hdGhSb3VuZCh5QXhpcy50cmFuc2xhdGUoeVZhbHVlLCAwLCAxLCAwLCAxKSAqIDEwKSAvIDEwIDogLy8gTWF0aC5yb3VuZCBmaXhlcyAjNTkxXG5cdFx0XHRcdHlBeGlzLnRyYW5zbGF0ZSh5VmFsdWUsIDAsIDEsIDAsIDEpIDpcblx0XHRcdFx0VU5ERUZJTkVEO1xuXG5cdFx0XHQvLyBTZXQgY2xpZW50IHJlbGF0ZWQgcG9zaXRpb25zIGZvciBtb3VzZSB0cmFja2luZ1xuXHRcdFx0cG9pbnQuY2xpZW50WCA9IGR5bmFtaWNhbGx5UGxhY2VkID8geEF4aXMudHJhbnNsYXRlKHhWYWx1ZSwgMCwgMCwgMCwgMSkgOiBwb2ludC5wbG90WDsgLy8gIzE1MTRcblxuXHRcdFx0cG9pbnQubmVnYXRpdmUgPSBwb2ludC55IDwgKHRocmVzaG9sZCB8fCAwKTtcblxuXHRcdFx0Ly8gc29tZSBBUEkgZGF0YVxuXHRcdFx0cG9pbnQuY2F0ZWdvcnkgPSBjYXRlZ29yaWVzICYmIGNhdGVnb3JpZXNbcG9pbnQueF0gIT09IFVOREVGSU5FRCA/XG5cdFx0XHRcdGNhdGVnb3JpZXNbcG9pbnQueF0gOiBwb2ludC54O1xuXG5cdFx0fVxuXG5cdFx0Ly8gbm93IHRoYXQgd2UgaGF2ZSB0aGUgY3JvcHBlZCBkYXRhLCBidWlsZCB0aGUgc2VnbWVudHNcblx0XHRzZXJpZXMuZ2V0U2VnbWVudHMoKTtcblx0fSxcblxuXHQvKipcblx0ICogQW5pbWF0ZSBpbiB0aGUgc2VyaWVzXG5cdCAqL1xuXHRhbmltYXRlOiBmdW5jdGlvbiAoaW5pdCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0Y2xpcFJlY3QsXG5cdFx0XHRtYXJrZXJDbGlwUmVjdCxcblx0XHRcdGFuaW1hdGlvbiA9IHNlcmllcy5vcHRpb25zLmFuaW1hdGlvbixcblx0XHRcdGNsaXBCb3ggPSBzZXJpZXMuY2xpcEJveCB8fCBjaGFydC5jbGlwQm94LFxuXHRcdFx0aW52ZXJ0ZWQgPSBjaGFydC5pbnZlcnRlZCxcblx0XHRcdHNoYXJlZENsaXBLZXk7XG5cblx0XHQvLyBBbmltYXRpb24gb3B0aW9uIGlzIHNldCB0byB0cnVlXG5cdFx0aWYgKGFuaW1hdGlvbiAmJiAhaXNPYmplY3QoYW5pbWF0aW9uKSkge1xuXHRcdFx0YW5pbWF0aW9uID0gZGVmYXVsdFBsb3RPcHRpb25zW3Nlcmllcy50eXBlXS5hbmltYXRpb247XG5cdFx0fVxuXHRcdHNoYXJlZENsaXBLZXkgPSBbJ19zaGFyZWRDbGlwJywgYW5pbWF0aW9uLmR1cmF0aW9uLCBhbmltYXRpb24uZWFzaW5nLCBjbGlwQm94LmhlaWdodF0uam9pbignLCcpO1xuXG5cdFx0Ly8gSW5pdGlhbGl6ZSB0aGUgYW5pbWF0aW9uLiBTZXQgdXAgdGhlIGNsaXBwaW5nIHJlY3RhbmdsZS5cblx0XHRpZiAoaW5pdCkge1xuXG5cdFx0XHQvLyBJZiBhIGNsaXBwaW5nIHJlY3RhbmdsZSB3aXRoIHRoZSBzYW1lIHByb3BlcnRpZXMgaXMgY3VycmVudGx5IHByZXNlbnQgaW4gdGhlIGNoYXJ0LCB1c2UgdGhhdC5cblx0XHRcdGNsaXBSZWN0ID0gY2hhcnRbc2hhcmVkQ2xpcEtleV07XG5cdFx0XHRtYXJrZXJDbGlwUmVjdCA9IGNoYXJ0W3NoYXJlZENsaXBLZXkgKyAnbSddO1xuXHRcdFx0aWYgKCFjbGlwUmVjdCkge1xuXHRcdFx0XHRjaGFydFtzaGFyZWRDbGlwS2V5XSA9IGNsaXBSZWN0ID0gcmVuZGVyZXIuY2xpcFJlY3QoXG5cdFx0XHRcdFx0ZXh0ZW5kKGNsaXBCb3gsIHsgd2lkdGg6IDAgfSlcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRjaGFydFtzaGFyZWRDbGlwS2V5ICsgJ20nXSA9IG1hcmtlckNsaXBSZWN0ID0gcmVuZGVyZXIuY2xpcFJlY3QoXG5cdFx0XHRcdFx0LTk5LCAvLyBpbmNsdWRlIHRoZSB3aWR0aCBvZiB0aGUgZmlyc3QgbWFya2VyXG5cdFx0XHRcdFx0aW52ZXJ0ZWQgPyAtY2hhcnQucGxvdExlZnQgOiAtY2hhcnQucGxvdFRvcCxcblx0XHRcdFx0XHQ5OSxcblx0XHRcdFx0XHRpbnZlcnRlZCA/IGNoYXJ0LmNoYXJ0V2lkdGggOiBjaGFydC5jaGFydEhlaWdodFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0c2VyaWVzLmdyb3VwLmNsaXAoY2xpcFJlY3QpO1xuXHRcdFx0c2VyaWVzLm1hcmtlckdyb3VwLmNsaXAobWFya2VyQ2xpcFJlY3QpO1xuXHRcdFx0c2VyaWVzLnNoYXJlZENsaXBLZXkgPSBzaGFyZWRDbGlwS2V5O1xuXG5cdFx0Ly8gUnVuIHRoZSBhbmltYXRpb25cblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2xpcFJlY3QgPSBjaGFydFtzaGFyZWRDbGlwS2V5XTtcblx0XHRcdGlmIChjbGlwUmVjdCkge1xuXHRcdFx0XHRjbGlwUmVjdC5hbmltYXRlKHtcblx0XHRcdFx0XHR3aWR0aDogY2hhcnQucGxvdFNpemVYXG5cdFx0XHRcdH0sIGFuaW1hdGlvbik7XG5cdFx0XHR9XG5cdFx0XHRpZiAoY2hhcnRbc2hhcmVkQ2xpcEtleSArICdtJ10pIHtcblx0XHRcdFx0Y2hhcnRbc2hhcmVkQ2xpcEtleSArICdtJ10uYW5pbWF0ZSh7XG5cdFx0XHRcdFx0d2lkdGg6IGNoYXJ0LnBsb3RTaXplWCArIDk5XG5cdFx0XHRcdH0sIGFuaW1hdGlvbik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERlbGV0ZSB0aGlzIGZ1bmN0aW9uIHRvIGFsbG93IGl0IG9ubHkgb25jZVxuXHRcdFx0c2VyaWVzLmFuaW1hdGUgPSBudWxsO1xuIFxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogVGhpcyBydW5zIGFmdGVyIGFuaW1hdGlvbiB0byBsYW5kIG9uIHRoZSBmaW5hbCBwbG90IGNsaXBwaW5nXG5cdCAqL1xuXHRhZnRlckFuaW1hdGU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0c2hhcmVkQ2xpcEtleSA9IHRoaXMuc2hhcmVkQ2xpcEtleSxcblx0XHRcdGdyb3VwID0gdGhpcy5ncm91cCxcblx0XHRcdGNsaXBCb3ggPSB0aGlzLmNsaXBCb3g7XG5cblx0XHRpZiAoZ3JvdXAgJiYgdGhpcy5vcHRpb25zLmNsaXAgIT09IGZhbHNlKSB7XG5cdFx0XHRpZiAoIXNoYXJlZENsaXBLZXkgfHwgIWNsaXBCb3gpIHtcblx0XHRcdFx0Z3JvdXAuY2xpcChjbGlwQm94ID8gY2hhcnQucmVuZGVyZXIuY2xpcFJlY3QoY2xpcEJveCkgOiBjaGFydC5jbGlwUmVjdCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLm1hcmtlckdyb3VwLmNsaXAoKTsgLy8gbm8gY2xpcFxuXHRcdH1cblxuXHRcdGZpcmVFdmVudCh0aGlzLCAnYWZ0ZXJBbmltYXRlJyk7XG5cblx0XHQvLyBSZW1vdmUgdGhlIHNoYXJlZCBjbGlwcGluZyByZWN0YW5jZ2xlIHdoZW4gYWxsIHNlcmllcyBhcmUgc2hvd25cblx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChzaGFyZWRDbGlwS2V5ICYmIGNoYXJ0W3NoYXJlZENsaXBLZXldKSB7XG5cdFx0XHRcdGlmICghY2xpcEJveCkge1xuXHRcdFx0XHRcdGNoYXJ0W3NoYXJlZENsaXBLZXldID0gY2hhcnRbc2hhcmVkQ2xpcEtleV0uZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChjaGFydFtzaGFyZWRDbGlwS2V5ICsgJ20nXSkge1xuXHRcdFx0XHRcdGNoYXJ0W3NoYXJlZENsaXBLZXkgKyAnbSddID0gY2hhcnRbc2hhcmVkQ2xpcEtleSArICdtJ10uZGVzdHJveSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSwgMTAwKTtcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyB0aGUgbWFya2Vyc1xuXHQgKi9cblx0ZHJhd1BvaW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0cG9pbnRBdHRyLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0cGxvdFgsXG5cdFx0XHRwbG90WSxcblx0XHRcdGksXG5cdFx0XHRwb2ludCxcblx0XHRcdHJhZGl1cyxcblx0XHRcdHN5bWJvbCxcblx0XHRcdGlzSW1hZ2UsXG5cdFx0XHRncmFwaGljLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0c2VyaWVzTWFya2VyT3B0aW9ucyA9IG9wdGlvbnMubWFya2VyLFxuXHRcdFx0c2VyaWVzUG9pbnRBdHRyID0gc2VyaWVzLnBvaW50QXR0clsnJ10sXG5cdFx0XHRwb2ludE1hcmtlck9wdGlvbnMsXG5cdFx0XHRoYXNQb2ludE1hcmtlcixcblx0XHRcdGVuYWJsZWQsXG5cdFx0XHRpc0luc2lkZSxcblx0XHRcdG1hcmtlckdyb3VwID0gc2VyaWVzLm1hcmtlckdyb3VwLFxuXHRcdFx0Z2xvYmFsbHlFbmFibGVkID0gcGljayhcblx0XHRcdFx0c2VyaWVzTWFya2VyT3B0aW9ucy5lbmFibGVkLCBcblx0XHRcdFx0IXNlcmllcy5yZXF1aXJlU29ydGluZyB8fCBzZXJpZXMuYWN0aXZlUG9pbnRDb3VudCA8ICgwLjUgKiBzZXJpZXMueEF4aXMubGVuIC8gc2VyaWVzTWFya2VyT3B0aW9ucy5yYWRpdXMpXG5cdFx0XHQpO1xuXG5cdFx0aWYgKHNlcmllc01hcmtlck9wdGlvbnMuZW5hYmxlZCAhPT0gZmFsc2UgfHwgc2VyaWVzLl9oYXNQb2ludE1hcmtlcnMpIHtcblxuXHRcdFx0aSA9IHBvaW50cy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdHBvaW50ID0gcG9pbnRzW2ldO1xuXHRcdFx0XHRwbG90WCA9IG1hdGhGbG9vcihwb2ludC5wbG90WCk7IC8vICMxODQzXG5cdFx0XHRcdHBsb3RZID0gcG9pbnQucGxvdFk7XG5cdFx0XHRcdGdyYXBoaWMgPSBwb2ludC5ncmFwaGljO1xuXHRcdFx0XHRwb2ludE1hcmtlck9wdGlvbnMgPSBwb2ludC5tYXJrZXIgfHwge307XG5cdFx0XHRcdGhhc1BvaW50TWFya2VyID0gISFwb2ludC5tYXJrZXI7XG5cdFx0XHRcdGVuYWJsZWQgPSAoZ2xvYmFsbHlFbmFibGVkICYmIHBvaW50TWFya2VyT3B0aW9ucy5lbmFibGVkID09PSBVTkRFRklORUQpIHx8IHBvaW50TWFya2VyT3B0aW9ucy5lbmFibGVkO1xuXHRcdFx0XHRpc0luc2lkZSA9IGNoYXJ0LmlzSW5zaWRlUGxvdChtYXRoUm91bmQocGxvdFgpLCBwbG90WSwgY2hhcnQuaW52ZXJ0ZWQpOyAvLyAjMTg1OFxuXG5cdFx0XHRcdC8vIG9ubHkgZHJhdyB0aGUgcG9pbnQgaWYgeSBpcyBkZWZpbmVkXG5cdFx0XHRcdGlmIChlbmFibGVkICYmIHBsb3RZICE9PSBVTkRFRklORUQgJiYgIWlzTmFOKHBsb3RZKSAmJiBwb2ludC55ICE9PSBudWxsKSB7XG5cblx0XHRcdFx0XHQvLyBzaG9ydGN1dHNcblx0XHRcdFx0XHRwb2ludEF0dHIgPSBwb2ludC5wb2ludEF0dHJbcG9pbnQuc2VsZWN0ZWQgPyBTRUxFQ1RfU1RBVEUgOiBOT1JNQUxfU1RBVEVdIHx8IHNlcmllc1BvaW50QXR0cjtcblx0XHRcdFx0XHRyYWRpdXMgPSBwb2ludEF0dHIucjtcblx0XHRcdFx0XHRzeW1ib2wgPSBwaWNrKHBvaW50TWFya2VyT3B0aW9ucy5zeW1ib2wsIHNlcmllcy5zeW1ib2wpO1xuXHRcdFx0XHRcdGlzSW1hZ2UgPSBzeW1ib2wuaW5kZXhPZigndXJsJykgPT09IDA7XG5cblx0XHRcdFx0XHRpZiAoZ3JhcGhpYykgeyAvLyB1cGRhdGVcblx0XHRcdFx0XHRcdGdyYXBoaWNbaXNJbnNpZGUgPyAnc2hvdycgOiAnaGlkZSddKHRydWUpIC8vIFNpbmNlIHRoZSBtYXJrZXIgZ3JvdXAgaXNuJ3QgY2xpcHBlZCwgZWFjaCBpbmRpdmlkdWFsIG1hcmtlciBtdXN0IGJlIHRvZ2dsZWRcblx0XHRcdFx0XHRcdFx0LmFuaW1hdGUoZXh0ZW5kKHtcblx0XHRcdFx0XHRcdFx0XHR4OiBwbG90WCAtIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0XHR5OiBwbG90WSAtIHJhZGl1c1xuXHRcdFx0XHRcdFx0XHR9LCBncmFwaGljLnN5bWJvbE5hbWUgPyB7IC8vIGRvbid0IGFwcGx5IHRvIGltYWdlIHN5bWJvbHMgIzUwN1xuXHRcdFx0XHRcdFx0XHRcdHdpZHRoOiAyICogcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRcdGhlaWdodDogMiAqIHJhZGl1c1xuXHRcdFx0XHRcdFx0XHR9IDoge30pKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGlzSW5zaWRlICYmIChyYWRpdXMgPiAwIHx8IGlzSW1hZ2UpKSB7XG5cdFx0XHRcdFx0XHRwb2ludC5ncmFwaGljID0gZ3JhcGhpYyA9IGNoYXJ0LnJlbmRlcmVyLnN5bWJvbChcblx0XHRcdFx0XHRcdFx0c3ltYm9sLFxuXHRcdFx0XHRcdFx0XHRwbG90WCAtIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0cGxvdFkgLSByYWRpdXMsXG5cdFx0XHRcdFx0XHRcdDIgKiByYWRpdXMsXG5cdFx0XHRcdFx0XHRcdDIgKiByYWRpdXMsXG5cdFx0XHRcdFx0XHRcdGhhc1BvaW50TWFya2VyID8gcG9pbnRNYXJrZXJPcHRpb25zIDogc2VyaWVzTWFya2VyT3B0aW9uc1xuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0LmF0dHIocG9pbnRBdHRyKVxuXHRcdFx0XHRcdFx0LmFkZChtYXJrZXJHcm91cCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSBpZiAoZ3JhcGhpYykge1xuXHRcdFx0XHRcdHBvaW50LmdyYXBoaWMgPSBncmFwaGljLmRlc3Ryb3koKTsgLy8gIzEyNjlcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDb252ZXJ0IHN0YXRlIHByb3BlcnRpZXMgZnJvbSBBUEkgbmFtaW5nIGNvbnZlbnRpb25zIHRvIFNWRyBhdHRyaWJ1dGVzXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIEFQSSBvcHRpb25zIG9iamVjdFxuXHQgKiBAcGFyYW0ge09iamVjdH0gYmFzZTEgU1ZHIGF0dHJpYnV0ZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBiYXNlMiBTZWNvbmQgbGV2ZWwgU1ZHIGF0dHJpYnV0ZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tXG5cdCAqL1xuXHRjb252ZXJ0QXR0cmliczogZnVuY3Rpb24gKG9wdGlvbnMsIGJhc2UxLCBiYXNlMiwgYmFzZTMpIHtcblx0XHR2YXIgY29udmVyc2lvbiA9IHRoaXMucG9pbnRBdHRyVG9PcHRpb25zLFxuXHRcdFx0YXR0cixcblx0XHRcdG9wdGlvbixcblx0XHRcdG9iaiA9IHt9O1xuXG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cdFx0YmFzZTEgPSBiYXNlMSB8fCB7fTtcblx0XHRiYXNlMiA9IGJhc2UyIHx8IHt9O1xuXHRcdGJhc2UzID0gYmFzZTMgfHwge307XG5cblx0XHRmb3IgKGF0dHIgaW4gY29udmVyc2lvbikge1xuXHRcdFx0b3B0aW9uID0gY29udmVyc2lvblthdHRyXTtcblx0XHRcdG9ialthdHRyXSA9IHBpY2sob3B0aW9uc1tvcHRpb25dLCBiYXNlMVthdHRyXSwgYmFzZTJbYXR0cl0sIGJhc2UzW2F0dHJdKTtcblx0XHR9XG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBzdGF0ZSBhdHRyaWJ1dGVzLiBFYWNoIHNlcmllcyB0eXBlIGhhcyBpdHMgb3duIHNldCBvZiBhdHRyaWJ1dGVzXG5cdCAqIHRoYXQgYXJlIGFsbG93ZWQgdG8gY2hhbmdlIG9uIGEgcG9pbnQncyBzdGF0ZSBjaGFuZ2UuIFNlcmllcyB3aWRlIGF0dHJpYnV0ZXMgYXJlIHN0b3JlZCBmb3Jcblx0ICogYWxsIHNlcmllcywgYW5kIGFkZGl0aW9uYWxseSBwb2ludCBzcGVjaWZpYyBhdHRyaWJ1dGVzIGFyZSBzdG9yZWQgZm9yIGFsbFxuXHQgKiBwb2ludHMgd2l0aCBpbmRpdmlkdWFsIG1hcmtlciBvcHRpb25zLiBJZiBzdWNoIG9wdGlvbnMgYXJlIG5vdCBkZWZpbmVkIGZvciB0aGUgcG9pbnQsXG5cdCAqIGEgcmVmZXJlbmNlIHRvIHRoZSBzZXJpZXMgd2lkZSBhdHRyaWJ1dGVzIGlzIHN0b3JlZCBpbiBwb2ludC5wb2ludEF0dHIuXG5cdCAqL1xuXHRnZXRBdHRyaWJzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRub3JtYWxPcHRpb25zID0gZGVmYXVsdFBsb3RPcHRpb25zW3Nlcmllcy50eXBlXS5tYXJrZXIgPyBzZXJpZXNPcHRpb25zLm1hcmtlciA6IHNlcmllc09wdGlvbnMsXG5cdFx0XHRzdGF0ZU9wdGlvbnMgPSBub3JtYWxPcHRpb25zLnN0YXRlcyxcblx0XHRcdHN0YXRlT3B0aW9uc0hvdmVyID0gc3RhdGVPcHRpb25zW0hPVkVSX1NUQVRFXSxcblx0XHRcdHBvaW50U3RhdGVPcHRpb25zSG92ZXIsXG5cdFx0XHRzZXJpZXNDb2xvciA9IHNlcmllcy5jb2xvcixcblx0XHRcdG5vcm1hbERlZmF1bHRzID0ge1xuXHRcdFx0XHRzdHJva2U6IHNlcmllc0NvbG9yLFxuXHRcdFx0XHRmaWxsOiBzZXJpZXNDb2xvclxuXHRcdFx0fSxcblx0XHRcdHBvaW50cyA9IHNlcmllcy5wb2ludHMgfHwgW10sIC8vICM5Mjdcblx0XHRcdGksXG5cdFx0XHRwb2ludCxcblx0XHRcdHNlcmllc1BvaW50QXR0ciA9IFtdLFxuXHRcdFx0cG9pbnRBdHRyLFxuXHRcdFx0cG9pbnRBdHRyVG9PcHRpb25zID0gc2VyaWVzLnBvaW50QXR0clRvT3B0aW9ucyxcblx0XHRcdGhhc1BvaW50U3BlY2lmaWNPcHRpb25zID0gc2VyaWVzLmhhc1BvaW50U3BlY2lmaWNPcHRpb25zLFxuXHRcdFx0bmVnYXRpdmVDb2xvciA9IHNlcmllc09wdGlvbnMubmVnYXRpdmVDb2xvcixcblx0XHRcdGRlZmF1bHRMaW5lQ29sb3IgPSBub3JtYWxPcHRpb25zLmxpbmVDb2xvcixcblx0XHRcdGRlZmF1bHRGaWxsQ29sb3IgPSBub3JtYWxPcHRpb25zLmZpbGxDb2xvcixcblx0XHRcdHR1cmJvVGhyZXNob2xkID0gc2VyaWVzT3B0aW9ucy50dXJib1RocmVzaG9sZCxcblx0XHRcdGF0dHIsXG5cdFx0XHRrZXk7XG5cblx0XHQvLyBzZXJpZXMgdHlwZSBzcGVjaWZpYyBtb2RpZmljYXRpb25zXG5cdFx0aWYgKHNlcmllc09wdGlvbnMubWFya2VyKSB7IC8vIGxpbmUsIHNwbGluZSwgYXJlYSwgYXJlYXNwbGluZSwgc2NhdHRlclxuXG5cdFx0XHQvLyBpZiBubyBob3ZlciByYWRpdXMgaXMgZ2l2ZW4sIGRlZmF1bHQgdG8gbm9ybWFsIHJhZGl1cyArIDJcblx0XHRcdHN0YXRlT3B0aW9uc0hvdmVyLnJhZGl1cyA9IHN0YXRlT3B0aW9uc0hvdmVyLnJhZGl1cyB8fCBub3JtYWxPcHRpb25zLnJhZGl1cyArIHN0YXRlT3B0aW9uc0hvdmVyLnJhZGl1c1BsdXM7XG5cdFx0XHRzdGF0ZU9wdGlvbnNIb3Zlci5saW5lV2lkdGggPSBzdGF0ZU9wdGlvbnNIb3Zlci5saW5lV2lkdGggfHwgbm9ybWFsT3B0aW9ucy5saW5lV2lkdGggKyBzdGF0ZU9wdGlvbnNIb3Zlci5saW5lV2lkdGhQbHVzO1xuXG5cdFx0fSBlbHNlIHsgLy8gY29sdW1uLCBiYXIsIHBpZVxuXG5cdFx0XHQvLyBpZiBubyBob3ZlciBjb2xvciBpcyBnaXZlbiwgYnJpZ2h0ZW4gdGhlIG5vcm1hbCBjb2xvclxuXHRcdFx0c3RhdGVPcHRpb25zSG92ZXIuY29sb3IgPSBzdGF0ZU9wdGlvbnNIb3Zlci5jb2xvciB8fFxuXHRcdFx0XHRDb2xvcihzdGF0ZU9wdGlvbnNIb3Zlci5jb2xvciB8fCBzZXJpZXNDb2xvcilcblx0XHRcdFx0XHQuYnJpZ2h0ZW4oc3RhdGVPcHRpb25zSG92ZXIuYnJpZ2h0bmVzcykuZ2V0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gZ2VuZXJhbCBwb2ludCBhdHRyaWJ1dGVzIGZvciB0aGUgc2VyaWVzIG5vcm1hbCBzdGF0ZVxuXHRcdHNlcmllc1BvaW50QXR0cltOT1JNQUxfU1RBVEVdID0gc2VyaWVzLmNvbnZlcnRBdHRyaWJzKG5vcm1hbE9wdGlvbnMsIG5vcm1hbERlZmF1bHRzKTtcblxuXHRcdC8vIEhPVkVSX1NUQVRFIGFuZCBTRUxFQ1RfU1RBVEUgc3RhdGVzIGluaGVyaXQgZnJvbSBub3JtYWwgc3RhdGUgZXhjZXB0IHRoZSBkZWZhdWx0IHJhZGl1c1xuXHRcdGVhY2goW0hPVkVSX1NUQVRFLCBTRUxFQ1RfU1RBVEVdLCBmdW5jdGlvbiAoc3RhdGUpIHtcblx0XHRcdHNlcmllc1BvaW50QXR0cltzdGF0ZV0gPVxuXHRcdFx0XHRcdHNlcmllcy5jb252ZXJ0QXR0cmlicyhzdGF0ZU9wdGlvbnNbc3RhdGVdLCBzZXJpZXNQb2ludEF0dHJbTk9STUFMX1NUQVRFXSk7XG5cdFx0fSk7XG5cblx0XHQvLyBzZXQgaXRcblx0XHRzZXJpZXMucG9pbnRBdHRyID0gc2VyaWVzUG9pbnRBdHRyO1xuXG5cblx0XHQvLyBHZW5lcmF0ZSB0aGUgcG9pbnQtc3BlY2lmaWMgYXR0cmlidXRlIGNvbGxlY3Rpb25zIGlmIHNwZWNpZmljIHBvaW50XG5cdFx0Ly8gb3B0aW9ucyBhcmUgZ2l2ZW4uIElmIG5vdCwgY3JlYXRlIGEgcmVmZXJhbmNlIHRvIHRoZSBzZXJpZXMgd2lkZSBwb2ludFxuXHRcdC8vIGF0dHJpYnV0ZXNcblx0XHRpID0gcG9pbnRzLmxlbmd0aDtcblx0XHRpZiAoIXR1cmJvVGhyZXNob2xkIHx8IGkgPCB0dXJib1RocmVzaG9sZCB8fCBoYXNQb2ludFNwZWNpZmljT3B0aW9ucykge1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRwb2ludCA9IHBvaW50c1tpXTtcblx0XHRcdFx0bm9ybWFsT3B0aW9ucyA9IChwb2ludC5vcHRpb25zICYmIHBvaW50Lm9wdGlvbnMubWFya2VyKSB8fCBwb2ludC5vcHRpb25zO1xuXHRcdFx0XHRpZiAobm9ybWFsT3B0aW9ucyAmJiBub3JtYWxPcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0bm9ybWFsT3B0aW9ucy5yYWRpdXMgPSAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHBvaW50Lm5lZ2F0aXZlICYmIG5lZ2F0aXZlQ29sb3IpIHtcblx0XHRcdFx0XHRwb2ludC5jb2xvciA9IHBvaW50LmZpbGxDb2xvciA9IG5lZ2F0aXZlQ29sb3I7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRoYXNQb2ludFNwZWNpZmljT3B0aW9ucyA9IHNlcmllc09wdGlvbnMuY29sb3JCeVBvaW50IHx8IHBvaW50LmNvbG9yOyAvLyAjODY4XG5cblx0XHRcdFx0Ly8gY2hlY2sgaWYgdGhlIHBvaW50IGhhcyBzcGVjaWZpYyB2aXN1YWwgb3B0aW9uc1xuXHRcdFx0XHRpZiAocG9pbnQub3B0aW9ucykge1xuXHRcdFx0XHRcdGZvciAoa2V5IGluIHBvaW50QXR0clRvT3B0aW9ucykge1xuXHRcdFx0XHRcdFx0aWYgKGRlZmluZWQobm9ybWFsT3B0aW9uc1twb2ludEF0dHJUb09wdGlvbnNba2V5XV0pKSB7XG5cdFx0XHRcdFx0XHRcdGhhc1BvaW50U3BlY2lmaWNPcHRpb25zID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBhIHNwZWNpZmljIG1hcmtlciBjb25maWcgb2JqZWN0IGlzIGRlZmluZWQgZm9yIHRoZSBpbmRpdmlkdWFsIHBvaW50OlxuXHRcdFx0XHQvLyBjcmVhdGUgaXQncyBvd24gYXR0cmlidXRlIGNvbGxlY3Rpb25cblx0XHRcdFx0aWYgKGhhc1BvaW50U3BlY2lmaWNPcHRpb25zKSB7XG5cdFx0XHRcdFx0bm9ybWFsT3B0aW9ucyA9IG5vcm1hbE9wdGlvbnMgfHwge307XG5cdFx0XHRcdFx0cG9pbnRBdHRyID0gW107XG5cdFx0XHRcdFx0c3RhdGVPcHRpb25zID0gbm9ybWFsT3B0aW9ucy5zdGF0ZXMgfHwge307IC8vIHJlYXNzaWduIGZvciBpbmRpdmlkdWFsIHBvaW50XG5cdFx0XHRcdFx0cG9pbnRTdGF0ZU9wdGlvbnNIb3ZlciA9IHN0YXRlT3B0aW9uc1tIT1ZFUl9TVEFURV0gPSBzdGF0ZU9wdGlvbnNbSE9WRVJfU1RBVEVdIHx8IHt9O1xuXG5cdFx0XHRcdFx0Ly8gSGFuZGxlIGNvbG9ycyBmb3IgY29sdW1uIGFuZCBwaWVzXG5cdFx0XHRcdFx0aWYgKCFzZXJpZXNPcHRpb25zLm1hcmtlcikgeyAvLyBjb2x1bW4sIGJhciwgcG9pbnRcblx0XHRcdFx0XHRcdC8vIElmIG5vIGhvdmVyIGNvbG9yIGlzIGdpdmVuLCBicmlnaHRlbiB0aGUgbm9ybWFsIGNvbG9yLiAjMTYxOSwgIzI1Nzlcblx0XHRcdFx0XHRcdHBvaW50U3RhdGVPcHRpb25zSG92ZXIuY29sb3IgPSBwb2ludFN0YXRlT3B0aW9uc0hvdmVyLmNvbG9yIHx8ICghcG9pbnQub3B0aW9ucy5jb2xvciAmJiBzdGF0ZU9wdGlvbnNIb3Zlci5jb2xvcikgfHxcblx0XHRcdFx0XHRcdFx0Q29sb3IocG9pbnQuY29sb3IpXG5cdFx0XHRcdFx0XHRcdFx0LmJyaWdodGVuKHBvaW50U3RhdGVPcHRpb25zSG92ZXIuYnJpZ2h0bmVzcyB8fCBzdGF0ZU9wdGlvbnNIb3Zlci5icmlnaHRuZXNzKVxuXHRcdFx0XHRcdFx0XHRcdC5nZXQoKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBub3JtYWwgcG9pbnQgc3RhdGUgaW5oZXJpdHMgc2VyaWVzIHdpZGUgbm9ybWFsIHN0YXRlXG5cdFx0XHRcdFx0YXR0ciA9IHsgY29sb3I6IHBvaW50LmNvbG9yIH07IC8vICM4Njhcblx0XHRcdFx0XHRpZiAoIWRlZmF1bHRGaWxsQ29sb3IpIHsgLy8gSW5kaXZpZHVhbCBwb2ludCBjb2xvciBvciBuZWdhdGl2ZSBjb2xvciBtYXJrZXJzICgjMjIxOSlcblx0XHRcdFx0XHRcdGF0dHIuZmlsbENvbG9yID0gcG9pbnQuY29sb3I7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICghZGVmYXVsdExpbmVDb2xvcikge1xuXHRcdFx0XHRcdFx0YXR0ci5saW5lQ29sb3IgPSBwb2ludC5jb2xvcjsgLy8gQnViYmxlcyB0YWtlIHBvaW50IGNvbG9yLCBsaW5lIG1hcmtlcnMgdXNlIHdoaXRlXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvaW50QXR0cltOT1JNQUxfU1RBVEVdID0gc2VyaWVzLmNvbnZlcnRBdHRyaWJzKGV4dGVuZChhdHRyLCBub3JtYWxPcHRpb25zKSwgc2VyaWVzUG9pbnRBdHRyW05PUk1BTF9TVEFURV0pO1xuXG5cdFx0XHRcdFx0Ly8gaW5oZXJpdCBmcm9tIHBvaW50IG5vcm1hbCBhbmQgc2VyaWVzIGhvdmVyXG5cdFx0XHRcdFx0cG9pbnRBdHRyW0hPVkVSX1NUQVRFXSA9IHNlcmllcy5jb252ZXJ0QXR0cmlicyhcblx0XHRcdFx0XHRcdHN0YXRlT3B0aW9uc1tIT1ZFUl9TVEFURV0sXG5cdFx0XHRcdFx0XHRzZXJpZXNQb2ludEF0dHJbSE9WRVJfU1RBVEVdLFxuXHRcdFx0XHRcdFx0cG9pbnRBdHRyW05PUk1BTF9TVEFURV1cblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gaW5oZXJpdCBmcm9tIHBvaW50IG5vcm1hbCBhbmQgc2VyaWVzIGhvdmVyXG5cdFx0XHRcdFx0cG9pbnRBdHRyW1NFTEVDVF9TVEFURV0gPSBzZXJpZXMuY29udmVydEF0dHJpYnMoXG5cdFx0XHRcdFx0XHRzdGF0ZU9wdGlvbnNbU0VMRUNUX1NUQVRFXSxcblx0XHRcdFx0XHRcdHNlcmllc1BvaW50QXR0cltTRUxFQ1RfU1RBVEVdLFxuXHRcdFx0XHRcdFx0cG9pbnRBdHRyW05PUk1BTF9TVEFURV1cblx0XHRcdFx0XHQpO1xuXG5cblx0XHRcdFx0Ly8gbm8gbWFya2VyIGNvbmZpZyBvYmplY3QgaXMgY3JlYXRlZDogY29weSBhIHJlZmVyZW5jZSB0byB0aGUgc2VyaWVzLXdpZGVcblx0XHRcdFx0Ly8gYXR0cmlidXRlIGNvbGxlY3Rpb25cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRwb2ludEF0dHIgPSBzZXJpZXNQb2ludEF0dHI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwb2ludC5wb2ludEF0dHIgPSBwb2ludEF0dHI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDbGVhciBET00gb2JqZWN0cyBhbmQgZnJlZSB1cCBtZW1vcnlcblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0aXNzdWUxMzQgPSAvQXBwbGVXZWJLaXRcXC81MzMvLnRlc3QodXNlckFnZW50KSxcblx0XHRcdGRlc3Ryb3ksXG5cdFx0XHRpLFxuXHRcdFx0ZGF0YSA9IHNlcmllcy5kYXRhIHx8IFtdLFxuXHRcdFx0cG9pbnQsXG5cdFx0XHRwcm9wLFxuXHRcdFx0YXhpcztcblxuXHRcdC8vIGFkZCBldmVudCBob29rXG5cdFx0ZmlyZUV2ZW50KHNlcmllcywgJ2Rlc3Ryb3knKTtcblxuXHRcdC8vIHJlbW92ZSBhbGwgZXZlbnRzXG5cdFx0cmVtb3ZlRXZlbnQoc2VyaWVzKTtcblxuXHRcdC8vIGVyYXNlIGZyb20gYXhlc1xuXHRcdGVhY2goc2VyaWVzLmF4aXNUeXBlcyB8fCBbXSwgZnVuY3Rpb24gKEFYSVMpIHtcblx0XHRcdGF4aXMgPSBzZXJpZXNbQVhJU107XG5cdFx0XHRpZiAoYXhpcykge1xuXHRcdFx0XHRlcmFzZShheGlzLnNlcmllcywgc2VyaWVzKTtcblx0XHRcdFx0YXhpcy5pc0RpcnR5ID0gYXhpcy5mb3JjZVJlZHJhdyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyByZW1vdmUgbGVnZW5kIGl0ZW1zXG5cdFx0aWYgKHNlcmllcy5sZWdlbmRJdGVtKSB7XG5cdFx0XHRzZXJpZXMuY2hhcnQubGVnZW5kLmRlc3Ryb3lJdGVtKHNlcmllcyk7XG5cdFx0fVxuXG5cdFx0Ly8gZGVzdHJveSBhbGwgcG9pbnRzIHdpdGggdGhlaXIgZWxlbWVudHNcblx0XHRpID0gZGF0YS5sZW5ndGg7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0cG9pbnQgPSBkYXRhW2ldO1xuXHRcdFx0aWYgKHBvaW50ICYmIHBvaW50LmRlc3Ryb3kpIHtcblx0XHRcdFx0cG9pbnQuZGVzdHJveSgpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRzZXJpZXMucG9pbnRzID0gbnVsbDtcblxuXHRcdC8vIENsZWFyIHRoZSBhbmltYXRpb24gdGltZW91dCBpZiB3ZSBhcmUgZGVzdHJveWluZyB0aGUgc2VyaWVzIGR1cmluZyBpbml0aWFsIGFuaW1hdGlvblxuXHRcdGNsZWFyVGltZW91dChzZXJpZXMuYW5pbWF0aW9uVGltZW91dCk7XG5cblx0XHQvLyBkZXN0cm95IGFsbCBTVkdFbGVtZW50cyBhc3NvY2lhdGVkIHRvIHRoZSBzZXJpZXNcblx0XHRlYWNoKFsnYXJlYScsICdncmFwaCcsICdkYXRhTGFiZWxzR3JvdXAnLCAnZ3JvdXAnLCAnbWFya2VyR3JvdXAnLCAndHJhY2tlcicsXG5cdFx0XHRcdCdncmFwaE5lZycsICdhcmVhTmVnJywgJ3Bvc0NsaXAnLCAnbmVnQ2xpcCddLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0aWYgKHNlcmllc1twcm9wXSkge1xuXG5cdFx0XHRcdC8vIGlzc3VlIDEzNCB3b3JrYXJvdW5kXG5cdFx0XHRcdGRlc3Ryb3kgPSBpc3N1ZTEzNCAmJiBwcm9wID09PSAnZ3JvdXAnID9cblx0XHRcdFx0XHQnaGlkZScgOlxuXHRcdFx0XHRcdCdkZXN0cm95JztcblxuXHRcdFx0XHRzZXJpZXNbcHJvcF1bZGVzdHJveV0oKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIHJlbW92ZSBmcm9tIGhvdmVyU2VyaWVzXG5cdFx0aWYgKGNoYXJ0LmhvdmVyU2VyaWVzID09PSBzZXJpZXMpIHtcblx0XHRcdGNoYXJ0LmhvdmVyU2VyaWVzID0gbnVsbDtcblx0XHR9XG5cdFx0ZXJhc2UoY2hhcnQuc2VyaWVzLCBzZXJpZXMpO1xuXG5cdFx0Ly8gY2xlYXIgYWxsIG1lbWJlcnNcblx0XHRmb3IgKHByb3AgaW4gc2VyaWVzKSB7XG5cdFx0XHRkZWxldGUgc2VyaWVzW3Byb3BdO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJuIHRoZSBncmFwaCBwYXRoIG9mIGEgc2VnbWVudFxuXHQgKi9cblx0Z2V0U2VnbWVudFBhdGg6IGZ1bmN0aW9uIChzZWdtZW50KSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRzZWdtZW50UGF0aCA9IFtdLFxuXHRcdFx0c3RlcCA9IHNlcmllcy5vcHRpb25zLnN0ZXA7XG5cblx0XHQvLyBidWlsZCB0aGUgc2VnbWVudCBsaW5lXG5cdFx0ZWFjaChzZWdtZW50LCBmdW5jdGlvbiAocG9pbnQsIGkpIHtcblxuXHRcdFx0dmFyIHBsb3RYID0gcG9pbnQucGxvdFgsXG5cdFx0XHRcdHBsb3RZID0gcG9pbnQucGxvdFksXG5cdFx0XHRcdGxhc3RQb2ludDtcblxuXHRcdFx0aWYgKHNlcmllcy5nZXRQb2ludFNwbGluZSkgeyAvLyBnZW5lcmF0ZSB0aGUgc3BsaW5lIGFzIGRlZmluZWQgaW4gdGhlIFNwbGluZVNlcmllcyBvYmplY3Rcblx0XHRcdFx0c2VnbWVudFBhdGgucHVzaC5hcHBseShzZWdtZW50UGF0aCwgc2VyaWVzLmdldFBvaW50U3BsaW5lKHNlZ21lbnQsIHBvaW50LCBpKSk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gbW92ZVRvIG9yIGxpbmVUb1xuXHRcdFx0XHRzZWdtZW50UGF0aC5wdXNoKGkgPyBMIDogTSk7XG5cblx0XHRcdFx0Ly8gc3RlcCBsaW5lP1xuXHRcdFx0XHRpZiAoc3RlcCAmJiBpKSB7XG5cdFx0XHRcdFx0bGFzdFBvaW50ID0gc2VnbWVudFtpIC0gMV07XG5cdFx0XHRcdFx0aWYgKHN0ZXAgPT09ICdyaWdodCcpIHtcblx0XHRcdFx0XHRcdHNlZ21lbnRQYXRoLnB1c2goXG5cdFx0XHRcdFx0XHRcdGxhc3RQb2ludC5wbG90WCxcblx0XHRcdFx0XHRcdFx0cGxvdFlcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHR9IGVsc2UgaWYgKHN0ZXAgPT09ICdjZW50ZXInKSB7XG5cdFx0XHRcdFx0XHRzZWdtZW50UGF0aC5wdXNoKFxuXHRcdFx0XHRcdFx0XHQobGFzdFBvaW50LnBsb3RYICsgcGxvdFgpIC8gMixcblx0XHRcdFx0XHRcdFx0bGFzdFBvaW50LnBsb3RZLFxuXHRcdFx0XHRcdFx0XHQobGFzdFBvaW50LnBsb3RYICsgcGxvdFgpIC8gMixcblx0XHRcdFx0XHRcdFx0cGxvdFlcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VnbWVudFBhdGgucHVzaChcblx0XHRcdFx0XHRcdFx0cGxvdFgsXG5cdFx0XHRcdFx0XHRcdGxhc3RQb2ludC5wbG90WVxuXHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBub3JtYWwgbGluZSB0byBuZXh0IHBvaW50XG5cdFx0XHRcdHNlZ21lbnRQYXRoLnB1c2goXG5cdFx0XHRcdFx0cG9pbnQucGxvdFgsXG5cdFx0XHRcdFx0cG9pbnQucGxvdFlcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdHJldHVybiBzZWdtZW50UGF0aDtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBncmFwaCBwYXRoXG5cdCAqL1xuXHRnZXRHcmFwaFBhdGg6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGdyYXBoUGF0aCA9IFtdLFxuXHRcdFx0c2VnbWVudFBhdGgsXG5cdFx0XHRzaW5nbGVQb2ludHMgPSBbXTsgLy8gdXNlZCBpbiBkcmF3VHJhY2tlclxuXG5cdFx0Ly8gRGl2aWRlIGludG8gc2VnbWVudHMgYW5kIGJ1aWxkIGdyYXBoIGFuZCBhcmVhIHBhdGhzXG5cdFx0ZWFjaChzZXJpZXMuc2VnbWVudHMsIGZ1bmN0aW9uIChzZWdtZW50KSB7XG5cblx0XHRcdHNlZ21lbnRQYXRoID0gc2VyaWVzLmdldFNlZ21lbnRQYXRoKHNlZ21lbnQpO1xuXG5cdFx0XHQvLyBhZGQgdGhlIHNlZ21lbnQgdG8gdGhlIGdyYXBoLCBvciBhIHNpbmdsZSBwb2ludCBmb3IgdHJhY2tpbmdcblx0XHRcdGlmIChzZWdtZW50Lmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0Z3JhcGhQYXRoID0gZ3JhcGhQYXRoLmNvbmNhdChzZWdtZW50UGF0aCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzaW5nbGVQb2ludHMucHVzaChzZWdtZW50WzBdKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIFJlY29yZCBpdCBmb3IgdXNlIGluIGRyYXdHcmFwaCBhbmQgZHJhd1RyYWNrZXIsIGFuZCByZXR1cm4gZ3JhcGhQYXRoXG5cdFx0c2VyaWVzLnNpbmdsZVBvaW50cyA9IHNpbmdsZVBvaW50cztcblx0XHRzZXJpZXMuZ3JhcGhQYXRoID0gZ3JhcGhQYXRoO1xuXG5cdFx0cmV0dXJuIGdyYXBoUGF0aDtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBhY3R1YWwgZ3JhcGhcblx0ICovXG5cdGRyYXdHcmFwaDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdHByb3BzID0gW1snZ3JhcGgnLCBvcHRpb25zLmxpbmVDb2xvciB8fCB0aGlzLmNvbG9yXV0sXG5cdFx0XHRsaW5lV2lkdGggPSBvcHRpb25zLmxpbmVXaWR0aCxcblx0XHRcdGRhc2hTdHlsZSA9ICBvcHRpb25zLmRhc2hTdHlsZSxcblx0XHRcdHJvdW5kQ2FwID0gb3B0aW9ucy5saW5lY2FwICE9PSAnc3F1YXJlJyxcblx0XHRcdGdyYXBoUGF0aCA9IHRoaXMuZ2V0R3JhcGhQYXRoKCksXG5cdFx0XHRuZWdhdGl2ZUNvbG9yID0gb3B0aW9ucy5uZWdhdGl2ZUNvbG9yO1xuXG5cdFx0aWYgKG5lZ2F0aXZlQ29sb3IpIHtcblx0XHRcdHByb3BzLnB1c2goWydncmFwaE5lZycsIG5lZ2F0aXZlQ29sb3JdKTtcblx0XHR9XG5cblx0XHQvLyBkcmF3IHRoZSBncmFwaFxuXHRcdGVhY2gocHJvcHMsIGZ1bmN0aW9uIChwcm9wLCBpKSB7XG5cdFx0XHR2YXIgZ3JhcGhLZXkgPSBwcm9wWzBdLFxuXHRcdFx0XHRncmFwaCA9IHNlcmllc1tncmFwaEtleV0sXG5cdFx0XHRcdGF0dHJpYnM7XG5cblx0XHRcdGlmIChncmFwaCkge1xuXHRcdFx0XHRzdG9wKGdyYXBoKTsgLy8gY2FuY2VsIHJ1bm5pbmcgYW5pbWF0aW9ucywgIzQ1OVxuXHRcdFx0XHRncmFwaC5hbmltYXRlKHsgZDogZ3JhcGhQYXRoIH0pO1xuXG5cdFx0XHR9IGVsc2UgaWYgKGxpbmVXaWR0aCAmJiBncmFwaFBhdGgubGVuZ3RoKSB7IC8vICMxNDg3XG5cdFx0XHRcdGF0dHJpYnMgPSB7XG5cdFx0XHRcdFx0c3Ryb2tlOiBwcm9wWzFdLFxuXHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBsaW5lV2lkdGgsXG5cdFx0XHRcdFx0ZmlsbDogTk9ORSxcblx0XHRcdFx0XHR6SW5kZXg6IDEgLy8gIzEwNjlcblx0XHRcdFx0fTtcblx0XHRcdFx0aWYgKGRhc2hTdHlsZSkge1xuXHRcdFx0XHRcdGF0dHJpYnMuZGFzaHN0eWxlID0gZGFzaFN0eWxlO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHJvdW5kQ2FwKSB7XG5cdFx0XHRcdFx0YXR0cmlic1snc3Ryb2tlLWxpbmVjYXAnXSA9IGF0dHJpYnNbJ3N0cm9rZS1saW5lam9pbiddID0gJ3JvdW5kJztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNlcmllc1tncmFwaEtleV0gPSBzZXJpZXMuY2hhcnQucmVuZGVyZXIucGF0aChncmFwaFBhdGgpXG5cdFx0XHRcdFx0LmF0dHIoYXR0cmlicylcblx0XHRcdFx0XHQuYWRkKHNlcmllcy5ncm91cClcblx0XHRcdFx0XHQuc2hhZG93KCFpICYmIG9wdGlvbnMuc2hhZG93KTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogQ2xpcCB0aGUgZ3JhcGhzIGludG8gdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBjb2xvdXJlZCBncmFwaHNcblx0ICovXG5cdGNsaXBOZWc6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRuZWdhdGl2ZUNvbG9yID0gb3B0aW9ucy5uZWdhdGl2ZUNvbG9yIHx8IG9wdGlvbnMubmVnYXRpdmVGaWxsQ29sb3IsXG5cdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkLFxuXHRcdFx0cG9zQXR0cixcblx0XHRcdG5lZ0F0dHIsXG5cdFx0XHRncmFwaCA9IHRoaXMuZ3JhcGgsXG5cdFx0XHRhcmVhID0gdGhpcy5hcmVhLFxuXHRcdFx0cG9zQ2xpcCA9IHRoaXMucG9zQ2xpcCxcblx0XHRcdG5lZ0NsaXAgPSB0aGlzLm5lZ0NsaXAsXG5cdFx0XHRjaGFydFdpZHRoID0gY2hhcnQuY2hhcnRXaWR0aCxcblx0XHRcdGNoYXJ0SGVpZ2h0ID0gY2hhcnQuY2hhcnRIZWlnaHQsXG5cdFx0XHRjaGFydFNpemVNYXggPSBtYXRoTWF4KGNoYXJ0V2lkdGgsIGNoYXJ0SGVpZ2h0KSxcblx0XHRcdHlBeGlzID0gdGhpcy55QXhpcyxcblx0XHRcdGFib3ZlLFxuXHRcdFx0YmVsb3c7XG5cblx0XHRpZiAobmVnYXRpdmVDb2xvciAmJiAoZ3JhcGggfHwgYXJlYSkpIHtcblx0XHRcdHRyYW5zbGF0ZWRUaHJlc2hvbGQgPSBtYXRoUm91bmQoeUF4aXMudG9QaXhlbHMob3B0aW9ucy50aHJlc2hvbGQgfHwgMCwgdHJ1ZSkpO1xuXHRcdFx0aWYgKHRyYW5zbGF0ZWRUaHJlc2hvbGQgPCAwKSB7XG5cdFx0XHRcdGNoYXJ0U2l6ZU1heCAtPSB0cmFuc2xhdGVkVGhyZXNob2xkOyAvLyAjMjUzNFxuXHRcdFx0fVxuXHRcdFx0YWJvdmUgPSB7XG5cdFx0XHRcdHg6IDAsXG5cdFx0XHRcdHk6IDAsXG5cdFx0XHRcdHdpZHRoOiBjaGFydFNpemVNYXgsXG5cdFx0XHRcdGhlaWdodDogdHJhbnNsYXRlZFRocmVzaG9sZFxuXHRcdFx0fTtcblx0XHRcdGJlbG93ID0ge1xuXHRcdFx0XHR4OiAwLFxuXHRcdFx0XHR5OiB0cmFuc2xhdGVkVGhyZXNob2xkLFxuXHRcdFx0XHR3aWR0aDogY2hhcnRTaXplTWF4LFxuXHRcdFx0XHRoZWlnaHQ6IGNoYXJ0U2l6ZU1heFxuXHRcdFx0fTtcblxuXHRcdFx0aWYgKGNoYXJ0LmludmVydGVkKSB7XG5cblx0XHRcdFx0YWJvdmUuaGVpZ2h0ID0gYmVsb3cueSA9IGNoYXJ0LnBsb3RXaWR0aCAtIHRyYW5zbGF0ZWRUaHJlc2hvbGQ7XG5cdFx0XHRcdGlmIChyZW5kZXJlci5pc1ZNTCkge1xuXHRcdFx0XHRcdGFib3ZlID0ge1xuXHRcdFx0XHRcdFx0eDogY2hhcnQucGxvdFdpZHRoIC0gdHJhbnNsYXRlZFRocmVzaG9sZCAtIGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0XHRcdFx0eTogMCxcblx0XHRcdFx0XHRcdHdpZHRoOiBjaGFydFdpZHRoLFxuXHRcdFx0XHRcdFx0aGVpZ2h0OiBjaGFydEhlaWdodFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0YmVsb3cgPSB7XG5cdFx0XHRcdFx0XHR4OiB0cmFuc2xhdGVkVGhyZXNob2xkICsgY2hhcnQucGxvdExlZnQgLSBjaGFydFdpZHRoLFxuXHRcdFx0XHRcdFx0eTogMCxcblx0XHRcdFx0XHRcdHdpZHRoOiBjaGFydC5wbG90TGVmdCArIHRyYW5zbGF0ZWRUaHJlc2hvbGQsXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IGNoYXJ0V2lkdGhcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICh5QXhpcy5yZXZlcnNlZCkge1xuXHRcdFx0XHRwb3NBdHRyID0gYmVsb3c7XG5cdFx0XHRcdG5lZ0F0dHIgPSBhYm92ZTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBvc0F0dHIgPSBhYm92ZTtcblx0XHRcdFx0bmVnQXR0ciA9IGJlbG93O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAocG9zQ2xpcCkgeyAvLyB1cGRhdGVcblx0XHRcdFx0cG9zQ2xpcC5hbmltYXRlKHBvc0F0dHIpO1xuXHRcdFx0XHRuZWdDbGlwLmFuaW1hdGUobmVnQXR0cik7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdHRoaXMucG9zQ2xpcCA9IHBvc0NsaXAgPSByZW5kZXJlci5jbGlwUmVjdChwb3NBdHRyKTtcblx0XHRcdFx0dGhpcy5uZWdDbGlwID0gbmVnQ2xpcCA9IHJlbmRlcmVyLmNsaXBSZWN0KG5lZ0F0dHIpO1xuXG5cdFx0XHRcdGlmIChncmFwaCAmJiB0aGlzLmdyYXBoTmVnKSB7XG5cdFx0XHRcdFx0Z3JhcGguY2xpcChwb3NDbGlwKTtcblx0XHRcdFx0XHR0aGlzLmdyYXBoTmVnLmNsaXAobmVnQ2xpcCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoYXJlYSkge1xuXHRcdFx0XHRcdGFyZWEuY2xpcChwb3NDbGlwKTtcblx0XHRcdFx0XHR0aGlzLmFyZWFOZWcuY2xpcChuZWdDbGlwKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSBhbmQgcGVyZm9ybSBncm91cCBpbnZlcnNpb24gb24gc2VyaWVzLmdyb3VwIGFuZCBzZXJpZXMubWFya2VyR3JvdXBcblx0ICovXG5cdGludmVydEdyb3VwczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQ7XG5cblx0XHQvLyBQaWUsIGdvIGF3YXkgKCMxNzM2KVxuXHRcdGlmICghc2VyaWVzLnhBeGlzKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQSBmaXhlZCBzaXplIGlzIG5lZWRlZCBmb3IgaW52ZXJzaW9uIHRvIHdvcmtcblx0XHRmdW5jdGlvbiBzZXRJbnZlcnQoKSB7XG5cdFx0XHR2YXIgc2l6ZSA9IHtcblx0XHRcdFx0d2lkdGg6IHNlcmllcy55QXhpcy5sZW4sXG5cdFx0XHRcdGhlaWdodDogc2VyaWVzLnhBeGlzLmxlblxuXHRcdFx0fTtcblxuXHRcdFx0ZWFjaChbJ2dyb3VwJywgJ21hcmtlckdyb3VwJ10sIGZ1bmN0aW9uIChncm91cE5hbWUpIHtcblx0XHRcdFx0aWYgKHNlcmllc1tncm91cE5hbWVdKSB7XG5cdFx0XHRcdFx0c2VyaWVzW2dyb3VwTmFtZV0uYXR0cihzaXplKS5pbnZlcnQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0YWRkRXZlbnQoY2hhcnQsICdyZXNpemUnLCBzZXRJbnZlcnQpOyAvLyBkbyBpdCBvbiByZXNpemVcblx0XHRhZGRFdmVudChzZXJpZXMsICdkZXN0cm95JywgZnVuY3Rpb24gKCkge1xuXHRcdFx0cmVtb3ZlRXZlbnQoY2hhcnQsICdyZXNpemUnLCBzZXRJbnZlcnQpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gRG8gaXQgbm93XG5cdFx0c2V0SW52ZXJ0KCk7IC8vIGRvIGl0IG5vd1xuXG5cdFx0Ly8gT24gc3Vic2VxdWVudCByZW5kZXIgYW5kIHJlZHJhdywganVzdCBkbyBzZXRJbnZlcnQgd2l0aG91dCBzZXR0aW5nIHVwIGV2ZW50cyBhZ2FpblxuXHRcdHNlcmllcy5pbnZlcnRHcm91cHMgPSBzZXRJbnZlcnQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdlbmVyYWwgYWJzdHJhY3Rpb24gZm9yIGNyZWF0aW5nIHBsb3QgZ3JvdXBzIGxpa2Ugc2VyaWVzLmdyb3VwLCBzZXJpZXMuZGF0YUxhYmVsc0dyb3VwIGFuZFxuXHQgKiBzZXJpZXMubWFya2VyR3JvdXAuIE9uIHN1YnNlcXVlbnQgY2FsbHMsIHRoZSBncm91cCB3aWxsIG9ubHkgYmUgYWRqdXN0ZWQgdG8gdGhlIHVwZGF0ZWQgcGxvdCBzaXplLlxuXHQgKi9cblx0cGxvdEdyb3VwOiBmdW5jdGlvbiAocHJvcCwgbmFtZSwgdmlzaWJpbGl0eSwgekluZGV4LCBwYXJlbnQpIHtcblx0XHR2YXIgZ3JvdXAgPSB0aGlzW3Byb3BdLFxuXHRcdFx0aXNOZXcgPSAhZ3JvdXA7XG5cblx0XHQvLyBHZW5lcmF0ZSBpdCBvbiBmaXJzdCBjYWxsXG5cdFx0aWYgKGlzTmV3KSB7XG5cdFx0XHR0aGlzW3Byb3BdID0gZ3JvdXAgPSB0aGlzLmNoYXJ0LnJlbmRlcmVyLmcobmFtZSlcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHZpc2liaWxpdHk6IHZpc2liaWxpdHksXG5cdFx0XHRcdFx0ekluZGV4OiB6SW5kZXggfHwgMC4xIC8vIElFOCBuZWVkcyB0aGlzXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQocGFyZW50KTtcblx0XHR9XG5cdFx0Ly8gUGxhY2UgaXQgb24gZmlyc3QgYW5kIHN1YnNlcXVlbnQgKHJlZHJhdykgY2FsbHNcblx0XHRncm91cFtpc05ldyA/ICdhdHRyJyA6ICdhbmltYXRlJ10odGhpcy5nZXRQbG90Qm94KCkpO1xuXHRcdHJldHVybiBncm91cDtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSB0cmFuc2xhdGlvbiBhbmQgc2NhbGUgZm9yIHRoZSBwbG90IGFyZWEgb2YgdGhpcyBzZXJpZXNcblx0ICovXG5cdGdldFBsb3RCb3g6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0eEF4aXMgPSB0aGlzLnhBeGlzLFxuXHRcdFx0eUF4aXMgPSB0aGlzLnlBeGlzO1xuXG5cdFx0Ly8gU3dhcCBheGVzIGZvciBpbnZlcnRlZCAoIzIzMzkpXG5cdFx0aWYgKGNoYXJ0LmludmVydGVkKSB7XG5cdFx0XHR4QXhpcyA9IHlBeGlzO1xuXHRcdFx0eUF4aXMgPSB0aGlzLnhBeGlzO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0dHJhbnNsYXRlWDogeEF4aXMgPyB4QXhpcy5sZWZ0IDogY2hhcnQucGxvdExlZnQsXG5cdFx0XHR0cmFuc2xhdGVZOiB5QXhpcyA/IHlBeGlzLnRvcCA6IGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRzY2FsZVg6IDEsIC8vICMxNjIzXG5cdFx0XHRzY2FsZVk6IDFcblx0XHR9O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW5kZXIgdGhlIGdyYXBoIGFuZCBtYXJrZXJzXG5cdCAqL1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0Z3JvdXAsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRhbmltYXRpb24gPSBvcHRpb25zLmFuaW1hdGlvbixcblx0XHRcdC8vIEFuaW1hdGlvbiBkb2Vzbid0IHdvcmsgaW4gSUU4IHF1aXJrcyB3aGVuIHRoZSBncm91cCBkaXYgaXMgaGlkZGVuLFxuXHRcdFx0Ly8gYW5kIGxvb2tzIGJhZCBpbiBvdGhlciBvbGRJRVxuXHRcdFx0YW5pbUR1cmF0aW9uID0gKGFuaW1hdGlvbiAmJiAhIXNlcmllcy5hbmltYXRlICYmIGNoYXJ0LnJlbmRlcmVyLmlzU1ZHICYmIHBpY2soYW5pbWF0aW9uLmR1cmF0aW9uLCA1MDApKSB8fCAwLFxuXHRcdFx0dmlzaWJpbGl0eSA9IHNlcmllcy52aXNpYmxlID8gVklTSUJMRSA6IEhJRERFTixcblx0XHRcdHpJbmRleCA9IG9wdGlvbnMuekluZGV4LFxuXHRcdFx0aGFzUmVuZGVyZWQgPSBzZXJpZXMuaGFzUmVuZGVyZWQsXG5cdFx0XHRjaGFydFNlcmllc0dyb3VwID0gY2hhcnQuc2VyaWVzR3JvdXA7XG5cblx0XHQvLyB0aGUgZ3JvdXBcblx0XHRncm91cCA9IHNlcmllcy5wbG90R3JvdXAoXG5cdFx0XHQnZ3JvdXAnLFxuXHRcdFx0J3NlcmllcycsXG5cdFx0XHR2aXNpYmlsaXR5LFxuXHRcdFx0ekluZGV4LFxuXHRcdFx0Y2hhcnRTZXJpZXNHcm91cFxuXHRcdCk7XG5cblx0XHRzZXJpZXMubWFya2VyR3JvdXAgPSBzZXJpZXMucGxvdEdyb3VwKFxuXHRcdFx0J21hcmtlckdyb3VwJyxcblx0XHRcdCdtYXJrZXJzJyxcblx0XHRcdHZpc2liaWxpdHksXG5cdFx0XHR6SW5kZXgsXG5cdFx0XHRjaGFydFNlcmllc0dyb3VwXG5cdFx0KTtcblxuXHRcdC8vIGluaXRpYXRlIHRoZSBhbmltYXRpb25cblx0XHRpZiAoYW5pbUR1cmF0aW9uKSB7XG5cdFx0XHRzZXJpZXMuYW5pbWF0ZSh0cnVlKTtcblx0XHR9XG5cblx0XHQvLyBjYWNoZSBhdHRyaWJ1dGVzIGZvciBzaGFwZXNcblx0XHRzZXJpZXMuZ2V0QXR0cmlicygpO1xuXG5cdFx0Ly8gU1ZHUmVuZGVyZXIgbmVlZHMgdG8ga25vdyB0aGlzIGJlZm9yZSBkcmF3aW5nIGVsZW1lbnRzICgjMTA4OSwgIzE3OTUpXG5cdFx0Z3JvdXAuaW52ZXJ0ZWQgPSBzZXJpZXMuaXNDYXJ0ZXNpYW4gPyBjaGFydC5pbnZlcnRlZCA6IGZhbHNlO1xuXG5cdFx0Ly8gZHJhdyB0aGUgZ3JhcGggaWYgYW55XG5cdFx0aWYgKHNlcmllcy5kcmF3R3JhcGgpIHtcblx0XHRcdHNlcmllcy5kcmF3R3JhcGgoKTtcblx0XHRcdHNlcmllcy5jbGlwTmVnKCk7XG5cdFx0fVxuXG5cdFx0ZWFjaChzZXJpZXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdGlmIChwb2ludC5yZWRyYXcpIHtcblx0XHRcdFx0cG9pbnQucmVkcmF3KCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBkcmF3IHRoZSBkYXRhIGxhYmVscyAoaW5uIHBpZXMgdGhleSBnbyBiZWZvcmUgdGhlIHBvaW50cylcblx0XHRpZiAoc2VyaWVzLmRyYXdEYXRhTGFiZWxzKSB7XG5cdFx0XHRzZXJpZXMuZHJhd0RhdGFMYWJlbHMoKTtcblx0XHR9XG5cblx0XHQvLyBkcmF3IHRoZSBwb2ludHNcblx0XHRpZiAoc2VyaWVzLnZpc2libGUpIHtcblx0XHRcdHNlcmllcy5kcmF3UG9pbnRzKCk7XG5cdFx0fVxuXG5cblx0XHQvLyBkcmF3IHRoZSBtb3VzZSB0cmFja2luZyBhcmVhXG5cdFx0aWYgKHNlcmllcy5kcmF3VHJhY2tlciAmJiBzZXJpZXMub3B0aW9ucy5lbmFibGVNb3VzZVRyYWNraW5nICE9PSBmYWxzZSkge1xuXHRcdFx0c2VyaWVzLmRyYXdUcmFja2VyKCk7XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIGludmVydGVkIHNlcmllcyBhbmQgdHJhY2tlciBncm91cHNcblx0XHRpZiAoY2hhcnQuaW52ZXJ0ZWQpIHtcblx0XHRcdHNlcmllcy5pbnZlcnRHcm91cHMoKTtcblx0XHR9XG5cblx0XHQvLyBJbml0aWFsIGNsaXBwaW5nLCBtdXN0IGJlIGRlZmluZWQgYWZ0ZXIgaW52ZXJ0aW5nIGdyb3VwcyBmb3IgVk1MXG5cdFx0aWYgKG9wdGlvbnMuY2xpcCAhPT0gZmFsc2UgJiYgIXNlcmllcy5zaGFyZWRDbGlwS2V5ICYmICFoYXNSZW5kZXJlZCkge1xuXHRcdFx0Z3JvdXAuY2xpcChjaGFydC5jbGlwUmVjdCk7XG5cdFx0fVxuXG5cdFx0Ly8gUnVuIHRoZSBhbmltYXRpb25cblx0XHRpZiAoYW5pbUR1cmF0aW9uKSB7XG5cdFx0XHRzZXJpZXMuYW5pbWF0ZSgpO1xuXHRcdH0gXG5cblx0XHQvLyBDYWxsIHRoZSBhZnRlckFuaW1hdGUgZnVuY3Rpb24gb24gYW5pbWF0aW9uIGNvbXBsZXRlIChidXQgZG9uJ3Qgb3ZlcndyaXRlIHRoZSBhbmltYXRpb24uY29tcGxldGUgb3B0aW9uXG5cdFx0Ly8gd2hpY2ggc2hvdWxkIGJlIGF2YWlsYWJsZSB0byB0aGUgdXNlcikuXG5cdFx0aWYgKCFoYXNSZW5kZXJlZCkge1xuXHRcdFx0aWYgKGFuaW1EdXJhdGlvbikge1xuXHRcdFx0XHRzZXJpZXMuYW5pbWF0aW9uVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHNlcmllcy5hZnRlckFuaW1hdGUoKTtcblx0XHRcdFx0fSwgYW5pbUR1cmF0aW9uKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlcmllcy5hZnRlckFuaW1hdGUoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRzZXJpZXMuaXNEaXJ0eSA9IHNlcmllcy5pc0RpcnR5RGF0YSA9IGZhbHNlOyAvLyBtZWFucyBkYXRhIGlzIGluIGFjY29yZGFuY2Ugd2l0aCB3aGF0IHlvdSBzZWVcblx0XHQvLyAoU2VlICMzMjIpIHNlcmllcy5pc0RpcnR5ID0gc2VyaWVzLmlzRGlydHlEYXRhID0gZmFsc2U7IC8vIG1lYW5zIGRhdGEgaXMgaW4gYWNjb3JkYW5jZSB3aXRoIHdoYXQgeW91IHNlZVxuXHRcdHNlcmllcy5oYXNSZW5kZXJlZCA9IHRydWU7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlZHJhdyB0aGUgc2VyaWVzIGFmdGVyIGFuIHVwZGF0ZSBpbiB0aGUgYXhlcy5cblx0ICovXG5cdHJlZHJhdzogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHR3YXNEaXJ0eURhdGEgPSBzZXJpZXMuaXNEaXJ0eURhdGEsIC8vIGNhY2hlIGl0IGhlcmUgYXMgaXQgaXMgc2V0IHRvIGZhbHNlIGluIHJlbmRlciwgYnV0IHVzZWQgYWZ0ZXJcblx0XHRcdGdyb3VwID0gc2VyaWVzLmdyb3VwLFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHR5QXhpcyA9IHNlcmllcy55QXhpcztcblxuXHRcdC8vIHJlcG9zaXRpb24gb24gcmVzaXplXG5cdFx0aWYgKGdyb3VwKSB7XG5cdFx0XHRpZiAoY2hhcnQuaW52ZXJ0ZWQpIHtcblx0XHRcdFx0Z3JvdXAuYXR0cih7XG5cdFx0XHRcdFx0d2lkdGg6IGNoYXJ0LnBsb3RXaWR0aCxcblx0XHRcdFx0XHRoZWlnaHQ6IGNoYXJ0LnBsb3RIZWlnaHRcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGdyb3VwLmFuaW1hdGUoe1xuXHRcdFx0XHR0cmFuc2xhdGVYOiBwaWNrKHhBeGlzICYmIHhBeGlzLmxlZnQsIGNoYXJ0LnBsb3RMZWZ0KSxcblx0XHRcdFx0dHJhbnNsYXRlWTogcGljayh5QXhpcyAmJiB5QXhpcy50b3AsIGNoYXJ0LnBsb3RUb3ApXG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRzZXJpZXMudHJhbnNsYXRlKCk7XG5cdFx0aWYgKHNlcmllcy5zZXRUb29sdGlwUG9pbnRzKSB7XG5cdFx0XHRzZXJpZXMuc2V0VG9vbHRpcFBvaW50cyh0cnVlKTtcblx0XHR9XG5cdFx0c2VyaWVzLnJlbmRlcigpO1xuXG5cdFx0aWYgKHdhc0RpcnR5RGF0YSkge1xuXHRcdFx0ZmlyZUV2ZW50KHNlcmllcywgJ3VwZGF0ZWREYXRhJyk7XG5cdFx0fVxuXHR9XG59OyAvLyBlbmQgU2VyaWVzIHByb3RvdHlwZVxuXG4vKipcbiAqIFRoZSBjbGFzcyBmb3Igc3RhY2sgaXRlbXNcbiAqL1xuZnVuY3Rpb24gU3RhY2tJdGVtKGF4aXMsIG9wdGlvbnMsIGlzTmVnYXRpdmUsIHgsIHN0YWNrT3B0aW9uKSB7XG5cdFxuXHR2YXIgaW52ZXJ0ZWQgPSBheGlzLmNoYXJ0LmludmVydGVkO1xuXG5cdHRoaXMuYXhpcyA9IGF4aXM7XG5cblx0Ly8gVGVsbHMgaWYgdGhlIHN0YWNrIGlzIG5lZ2F0aXZlXG5cdHRoaXMuaXNOZWdhdGl2ZSA9IGlzTmVnYXRpdmU7XG5cblx0Ly8gU2F2ZSB0aGUgb3B0aW9ucyB0byBiZSBhYmxlIHRvIHN0eWxlIHRoZSBsYWJlbFxuXHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG5cdC8vIFNhdmUgdGhlIHggdmFsdWUgdG8gYmUgYWJsZSB0byBwb3NpdGlvbiB0aGUgbGFiZWwgbGF0ZXJcblx0dGhpcy54ID0geDtcblxuXHQvLyBJbml0aWFsaXplIHRvdGFsIHZhbHVlXG5cdHRoaXMudG90YWwgPSBudWxsO1xuXG5cdC8vIFRoaXMgd2lsbCBrZWVwIGVhY2ggcG9pbnRzJyBleHRyZW1lcyBzdG9yZWQgYnkgc2VyaWVzLmluZGV4IGFuZCBwb2ludCBpbmRleFxuXHR0aGlzLnBvaW50cyA9IHt9O1xuXG5cdC8vIFNhdmUgdGhlIHN0YWNrIG9wdGlvbiBvbiB0aGUgc2VyaWVzIGNvbmZpZ3VyYXRpb24gb2JqZWN0LCBhbmQgd2hldGhlciB0byB0cmVhdCBpdCBhcyBwZXJjZW50XG5cdHRoaXMuc3RhY2sgPSBzdGFja09wdGlvbjtcblxuXHQvLyBUaGUgYWxpZ24gb3B0aW9ucyBhbmQgdGV4dCBhbGlnbiB2YXJpZXMgb24gd2hldGhlciB0aGUgc3RhY2sgaXMgbmVnYXRpdmUgYW5kXG5cdC8vIGlmIHRoZSBjaGFydCBpcyBpbnZlcnRlZCBvciBub3QuXG5cdC8vIEZpcnN0IHRlc3QgdGhlIHVzZXIgc3VwcGxpZWQgdmFsdWUsIHRoZW4gdXNlIHRoZSBkeW5hbWljLlxuXHR0aGlzLmFsaWduT3B0aW9ucyA9IHtcblx0XHRhbGlnbjogb3B0aW9ucy5hbGlnbiB8fCAoaW52ZXJ0ZWQgPyAoaXNOZWdhdGl2ZSA/ICdsZWZ0JyA6ICdyaWdodCcpIDogJ2NlbnRlcicpLFxuXHRcdHZlcnRpY2FsQWxpZ246IG9wdGlvbnMudmVydGljYWxBbGlnbiB8fCAoaW52ZXJ0ZWQgPyAnbWlkZGxlJyA6IChpc05lZ2F0aXZlID8gJ2JvdHRvbScgOiAndG9wJykpLFxuXHRcdHk6IHBpY2sob3B0aW9ucy55LCBpbnZlcnRlZCA/IDQgOiAoaXNOZWdhdGl2ZSA/IDE0IDogLTYpKSxcblx0XHR4OiBwaWNrKG9wdGlvbnMueCwgaW52ZXJ0ZWQgPyAoaXNOZWdhdGl2ZSA/IC02IDogNikgOiAwKVxuXHR9O1xuXG5cdHRoaXMudGV4dEFsaWduID0gb3B0aW9ucy50ZXh0QWxpZ24gfHwgKGludmVydGVkID8gKGlzTmVnYXRpdmUgPyAncmlnaHQnIDogJ2xlZnQnKSA6ICdjZW50ZXInKTtcbn1cblxuU3RhY2tJdGVtLnByb3RvdHlwZSA9IHtcblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdGRlc3Ryb3lPYmplY3RQcm9wZXJ0aWVzKHRoaXMsIHRoaXMuYXhpcyk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlcnMgdGhlIHN0YWNrIHRvdGFsIGxhYmVsIGFuZCBhZGRzIGl0IHRvIHRoZSBzdGFjayBsYWJlbCBncm91cC5cblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKGdyb3VwKSB7XG5cdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRmb3JtYXRPcHRpb24gPSBvcHRpb25zLmZvcm1hdCxcblx0XHRcdHN0ciA9IGZvcm1hdE9wdGlvbiA/XG5cdFx0XHRcdGZvcm1hdChmb3JtYXRPcHRpb24sIHRoaXMpIDogXG5cdFx0XHRcdG9wdGlvbnMuZm9ybWF0dGVyLmNhbGwodGhpcyk7ICAvLyBmb3JtYXQgdGhlIHRleHQgaW4gdGhlIGxhYmVsXG5cblx0XHQvLyBDaGFuZ2UgdGhlIHRleHQgdG8gcmVmbGVjdCB0aGUgbmV3IHRvdGFsIGFuZCBzZXQgdmlzaWJpbGl0eSB0byBoaWRkZW4gaW4gY2FzZSB0aGUgc2VyaWUgaXMgaGlkZGVuXG5cdFx0aWYgKHRoaXMubGFiZWwpIHtcblx0XHRcdHRoaXMubGFiZWwuYXR0cih7dGV4dDogc3RyLCB2aXNpYmlsaXR5OiBISURERU59KTtcblx0XHQvLyBDcmVhdGUgbmV3IGxhYmVsXG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMubGFiZWwgPVxuXHRcdFx0XHR0aGlzLmF4aXMuY2hhcnQucmVuZGVyZXIudGV4dChzdHIsIG51bGwsIG51bGwsIG9wdGlvbnMudXNlSFRNTClcdFx0Ly8gZHVtbXkgcG9zaXRpb25zLCBhY3R1YWwgcG9zaXRpb24gdXBkYXRlZCB3aXRoIHNldE9mZnNldCBtZXRob2QgaW4gY29sdW1uc2VyaWVzXG5cdFx0XHRcdFx0LmNzcyhvcHRpb25zLnN0eWxlKVx0XHRcdFx0Ly8gYXBwbHkgc3R5bGVcblx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRhbGlnbjogdGhpcy50ZXh0QWxpZ24sXHRcdFx0XHQvLyBmaXggdGhlIHRleHQtYW5jaG9yXG5cdFx0XHRcdFx0XHRyb3RhdGlvbjogb3B0aW9ucy5yb3RhdGlvbixcdC8vIHJvdGF0aW9uXG5cdFx0XHRcdFx0XHR2aXNpYmlsaXR5OiBISURERU5cdFx0XHRcdFx0Ly8gaGlkZGVuIHVudGlsIHNldE9mZnNldCBpcyBjYWxsZWRcblx0XHRcdFx0XHR9KVx0XHRcdFx0XG5cdFx0XHRcdFx0LmFkZChncm91cCk7XHRcdFx0XHRcdFx0XHQvLyBhZGQgdG8gdGhlIGxhYmVscy1ncm91cFxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0cyB0aGUgb2Zmc2V0IHRoYXQgdGhlIHN0YWNrIGhhcyBmcm9tIHRoZSB4IHZhbHVlIGFuZCByZXBvc2l0aW9ucyB0aGUgbGFiZWwuXG5cdCAqL1xuXHRzZXRPZmZzZXQ6IGZ1bmN0aW9uICh4T2Zmc2V0LCB4V2lkdGgpIHtcblx0XHR2YXIgc3RhY2tJdGVtID0gdGhpcyxcblx0XHRcdGF4aXMgPSBzdGFja0l0ZW0uYXhpcyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQsXG5cdFx0XHRuZWcgPSB0aGlzLmlzTmVnYXRpdmUsXHRcdFx0XHRcdFx0XHQvLyBzcGVjaWFsIHRyZWF0bWVudCBpcyBuZWVkZWQgZm9yIG5lZ2F0aXZlIHN0YWNrc1xuXHRcdFx0eSA9IGF4aXMudHJhbnNsYXRlKGF4aXMudXNlUGVyY2VudGFnZSA/IDEwMCA6IHRoaXMudG90YWwsIDAsIDAsIDAsIDEpLCAvLyBzdGFjayB2YWx1ZSB0cmFuc2xhdGVkIG1hcHBlZCB0byBjaGFydCBjb29yZGluYXRlc1xuXHRcdFx0eVplcm8gPSBheGlzLnRyYW5zbGF0ZSgwKSxcdFx0XHRcdFx0XHQvLyBzdGFjayBvcmlnaW5cblx0XHRcdGggPSBtYXRoQWJzKHkgLSB5WmVybyksXHRcdFx0XHRcdFx0XHQvLyBzdGFjayBoZWlnaHRcblx0XHRcdHggPSBjaGFydC54QXhpc1swXS50cmFuc2xhdGUodGhpcy54KSArIHhPZmZzZXQsXHQvLyBzdGFjayB4IHBvc2l0aW9uXG5cdFx0XHRwbG90SGVpZ2h0ID0gY2hhcnQucGxvdEhlaWdodCxcblx0XHRcdHN0YWNrQm94ID0ge1x0Ly8gdGhpcyBpcyB0aGUgYm94IGZvciB0aGUgY29tcGxldGUgc3RhY2tcblx0XHRcdFx0eDogaW52ZXJ0ZWQgPyAobmVnID8geSA6IHkgLSBoKSA6IHgsXG5cdFx0XHRcdHk6IGludmVydGVkID8gcGxvdEhlaWdodCAtIHggLSB4V2lkdGggOiAobmVnID8gKHBsb3RIZWlnaHQgLSB5IC0gaCkgOiBwbG90SGVpZ2h0IC0geSksXG5cdFx0XHRcdHdpZHRoOiBpbnZlcnRlZCA/IGggOiB4V2lkdGgsXG5cdFx0XHRcdGhlaWdodDogaW52ZXJ0ZWQgPyB4V2lkdGggOiBoXG5cdFx0XHR9LFxuXHRcdFx0bGFiZWwgPSB0aGlzLmxhYmVsLFxuXHRcdFx0YWxpZ25BdHRyO1xuXHRcdFxuXHRcdGlmIChsYWJlbCkge1xuXHRcdFx0bGFiZWwuYWxpZ24odGhpcy5hbGlnbk9wdGlvbnMsIG51bGwsIHN0YWNrQm94KTtcdC8vIGFsaWduIHRoZSBsYWJlbCB0byB0aGUgYm94XG5cdFx0XHRcdFxuXHRcdFx0Ly8gU2V0IHZpc2liaWxpdHkgKCM2NzgpXG5cdFx0XHRhbGlnbkF0dHIgPSBsYWJlbC5hbGlnbkF0dHI7XG5cdFx0XHRsYWJlbFt0aGlzLm9wdGlvbnMuY3JvcCA9PT0gZmFsc2UgfHwgY2hhcnQuaXNJbnNpZGVQbG90KGFsaWduQXR0ci54LCBhbGlnbkF0dHIueSkgPyAnc2hvdycgOiAnaGlkZSddKHRydWUpO1xuXHRcdH1cblx0fVxufTtcblxuXG4vLyBTdGFja2luZyBtZXRob2RzIGRlZmluZWQgb24gdGhlIEF4aXMgcHJvdG90eXBlXG5cbi8qKlxuICogQnVpbGQgdGhlIHN0YWNrcyBmcm9tIHRvcCBkb3duXG4gKi9cbkF4aXMucHJvdG90eXBlLmJ1aWxkU3RhY2tzID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgc2VyaWVzID0gdGhpcy5zZXJpZXMsXG5cdFx0cmV2ZXJzZWRTdGFja3MgPSBwaWNrKHRoaXMub3B0aW9ucy5yZXZlcnNlZFN0YWNrcywgdHJ1ZSksXG5cdFx0aSA9IHNlcmllcy5sZW5ndGg7XG5cdGlmICghdGhpcy5pc1hBeGlzKSB7XG5cdFx0dGhpcy51c2VQZXJjZW50YWdlID0gZmFsc2U7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0c2VyaWVzW3JldmVyc2VkU3RhY2tzID8gaSA6IHNlcmllcy5sZW5ndGggLSBpIC0gMV0uc2V0U3RhY2tlZFBvaW50cygpO1xuXHRcdH1cblx0XHQvLyBMb29wIHVwIGFnYWluIHRvIGNvbXB1dGUgcGVyY2VudCBzdGFja1xuXHRcdGlmICh0aGlzLnVzZVBlcmNlbnRhZ2UpIHtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBzZXJpZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0c2VyaWVzW2ldLnNldFBlcmNlbnRTdGFja3MoKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbkF4aXMucHJvdG90eXBlLnJlbmRlclN0YWNrVG90YWxzID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0c3RhY2tzID0gYXhpcy5zdGFja3MsXG5cdFx0c3RhY2tLZXksIFxuXHRcdG9uZVN0YWNrLCBcblx0XHRzdGFja0NhdGVnb3J5LFxuXHRcdHN0YWNrVG90YWxHcm91cCA9IGF4aXMuc3RhY2tUb3RhbEdyb3VwO1xuXG5cdC8vIENyZWF0ZSBhIHNlcGFyYXRlIGdyb3VwIGZvciB0aGUgc3RhY2sgdG90YWwgbGFiZWxzXG5cdGlmICghc3RhY2tUb3RhbEdyb3VwKSB7XG5cdFx0YXhpcy5zdGFja1RvdGFsR3JvdXAgPSBzdGFja1RvdGFsR3JvdXAgPVxuXHRcdFx0cmVuZGVyZXIuZygnc3RhY2stbGFiZWxzJylcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHZpc2liaWxpdHk6IFZJU0lCTEUsXG5cdFx0XHRcdFx0ekluZGV4OiA2XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQoKTtcblx0fVxuXG5cdC8vIHBsb3RMZWZ0L1RvcCB3aWxsIGNoYW5nZSB3aGVuIHkgYXhpcyBnZXRzIHdpZGVyIHNvIHdlIG5lZWQgdG8gdHJhbnNsYXRlIHRoZVxuXHQvLyBzdGFja1RvdGFsR3JvdXAgYXQgZXZlcnkgcmVuZGVyIGNhbGwuIFNlZSBidWcgIzUwNiBhbmQgIzUxNlxuXHRzdGFja1RvdGFsR3JvdXAudHJhbnNsYXRlKGNoYXJ0LnBsb3RMZWZ0LCBjaGFydC5wbG90VG9wKTtcblxuXHQvLyBSZW5kZXIgZWFjaCBzdGFjayB0b3RhbFxuXHRmb3IgKHN0YWNrS2V5IGluIHN0YWNrcykge1xuXHRcdG9uZVN0YWNrID0gc3RhY2tzW3N0YWNrS2V5XTtcblx0XHRmb3IgKHN0YWNrQ2F0ZWdvcnkgaW4gb25lU3RhY2spIHtcblx0XHRcdG9uZVN0YWNrW3N0YWNrQ2F0ZWdvcnldLnJlbmRlcihzdGFja1RvdGFsR3JvdXApO1xuXHRcdH1cblx0fVxufTtcblxuXG4vLyBTdGFja2luZyBtZXRob2RzIGRlZm5pZWQgZm9yIFNlcmllcyBwcm90b3R5cGVcblxuLyoqXG4gKiBBZGRzIHNlcmllcycgcG9pbnRzIHZhbHVlIHRvIGNvcnJlc3BvbmRpbmcgc3RhY2tcbiAqL1xuU2VyaWVzLnByb3RvdHlwZS5zZXRTdGFja2VkUG9pbnRzID0gZnVuY3Rpb24gKCkge1xuXHRpZiAoIXRoaXMub3B0aW9ucy5zdGFja2luZyB8fCAodGhpcy52aXNpYmxlICE9PSB0cnVlICYmIHRoaXMuY2hhcnQub3B0aW9ucy5jaGFydC5pZ25vcmVIaWRkZW5TZXJpZXMgIT09IGZhbHNlKSkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdHhEYXRhID0gc2VyaWVzLnByb2Nlc3NlZFhEYXRhLFxuXHRcdHlEYXRhID0gc2VyaWVzLnByb2Nlc3NlZFlEYXRhLFxuXHRcdHN0YWNrZWRZRGF0YSA9IFtdLFxuXHRcdHlEYXRhTGVuZ3RoID0geURhdGEubGVuZ3RoLFxuXHRcdHNlcmllc09wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHR0aHJlc2hvbGQgPSBzZXJpZXNPcHRpb25zLnRocmVzaG9sZCxcblx0XHRzdGFja09wdGlvbiA9IHNlcmllc09wdGlvbnMuc3RhY2ssXG5cdFx0c3RhY2tpbmcgPSBzZXJpZXNPcHRpb25zLnN0YWNraW5nLFxuXHRcdHN0YWNrS2V5ID0gc2VyaWVzLnN0YWNrS2V5LFxuXHRcdG5lZ0tleSA9ICctJyArIHN0YWNrS2V5LFxuXHRcdG5lZ1N0YWNrcyA9IHNlcmllcy5uZWdTdGFja3MsXG5cdFx0eUF4aXMgPSBzZXJpZXMueUF4aXMsXG5cdFx0c3RhY2tzID0geUF4aXMuc3RhY2tzLFxuXHRcdG9sZFN0YWNrcyA9IHlBeGlzLm9sZFN0YWNrcyxcblx0XHRpc05lZ2F0aXZlLFxuXHRcdHN0YWNrLFxuXHRcdG90aGVyLFxuXHRcdGtleSxcblx0XHRwb2ludEtleSxcblx0XHRpLFxuXHRcdHgsXG5cdFx0eTtcblxuXHQvLyBsb29wIG92ZXIgdGhlIG5vbi1udWxsIHkgdmFsdWVzIGFuZCByZWFkIHRoZW0gaW50byBhIGxvY2FsIGFycmF5XG5cdGZvciAoaSA9IDA7IGkgPCB5RGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0eCA9IHhEYXRhW2ldO1xuXHRcdHkgPSB5RGF0YVtpXTtcblx0XHRwb2ludEtleSA9IHNlcmllcy5pbmRleCArICcsJyArIGk7XG5cblx0XHQvLyBSZWFkIHN0YWNrZWQgdmFsdWVzIGludG8gYSBzdGFjayBiYXNlZCBvbiB0aGUgeCB2YWx1ZSxcblx0XHQvLyB0aGUgc2lnbiBvZiB5IGFuZCB0aGUgc3RhY2sga2V5LiBTdGFja2luZyBpcyBhbHNvIGhhbmRsZWQgZm9yIG51bGwgdmFsdWVzICgjNzM5KVxuXHRcdGlzTmVnYXRpdmUgPSBuZWdTdGFja3MgJiYgeSA8IHRocmVzaG9sZDtcblx0XHRrZXkgPSBpc05lZ2F0aXZlID8gbmVnS2V5IDogc3RhY2tLZXk7XG5cblx0XHQvLyBDcmVhdGUgZW1wdHkgb2JqZWN0IGZvciB0aGlzIHN0YWNrIGlmIGl0IGRvZXNuJ3QgZXhpc3QgeWV0XG5cdFx0aWYgKCFzdGFja3Nba2V5XSkge1xuXHRcdFx0c3RhY2tzW2tleV0gPSB7fTtcblx0XHR9XG5cblx0XHQvLyBJbml0aWFsaXplIFN0YWNrSXRlbSBmb3IgdGhpcyB4XG5cdFx0aWYgKCFzdGFja3Nba2V5XVt4XSkge1xuXHRcdFx0aWYgKG9sZFN0YWNrc1trZXldICYmIG9sZFN0YWNrc1trZXldW3hdKSB7XG5cdFx0XHRcdHN0YWNrc1trZXldW3hdID0gb2xkU3RhY2tzW2tleV1beF07XG5cdFx0XHRcdHN0YWNrc1trZXldW3hdLnRvdGFsID0gbnVsbDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHN0YWNrc1trZXldW3hdID0gbmV3IFN0YWNrSXRlbSh5QXhpcywgeUF4aXMub3B0aW9ucy5zdGFja0xhYmVscywgaXNOZWdhdGl2ZSwgeCwgc3RhY2tPcHRpb24pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBTdGFja0l0ZW0gZG9lc24ndCBleGlzdCwgY3JlYXRlIGl0IGZpcnN0XG5cdFx0c3RhY2sgPSBzdGFja3Nba2V5XVt4XTtcblx0XHRzdGFjay5wb2ludHNbcG9pbnRLZXldID0gW3N0YWNrLmN1bSB8fCAwXTtcblxuXHRcdC8vIEFkZCB2YWx1ZSB0byB0aGUgc3RhY2sgdG90YWxcblx0XHRpZiAoc3RhY2tpbmcgPT09ICdwZXJjZW50Jykge1xuXG5cdFx0XHQvLyBQZXJjZW50IHN0YWNrZWQgY29sdW1uLCB0b3RhbHMgYXJlIHRoZSBzYW1lIGZvciB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHN0YWNrc1xuXHRcdFx0b3RoZXIgPSBpc05lZ2F0aXZlID8gc3RhY2tLZXkgOiBuZWdLZXk7XG5cdFx0XHRpZiAobmVnU3RhY2tzICYmIHN0YWNrc1tvdGhlcl0gJiYgc3RhY2tzW290aGVyXVt4XSkge1xuXHRcdFx0XHRvdGhlciA9IHN0YWNrc1tvdGhlcl1beF07XG5cdFx0XHRcdHN0YWNrLnRvdGFsID0gb3RoZXIudG90YWwgPSBtYXRoTWF4KG90aGVyLnRvdGFsLCBzdGFjay50b3RhbCkgKyBtYXRoQWJzKHkpIHx8IDA7XG5cblx0XHRcdC8vIFBlcmNlbnQgc3RhY2tlZCBhcmVhc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c3RhY2sudG90YWwgPSBjb3JyZWN0RmxvYXQoc3RhY2sudG90YWwgKyAobWF0aEFicyh5KSB8fCAwKSk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHN0YWNrLnRvdGFsID0gY29ycmVjdEZsb2F0KHN0YWNrLnRvdGFsICsgKHkgfHwgMCkpO1xuXHRcdH1cblxuXHRcdHN0YWNrLmN1bSA9IChzdGFjay5jdW0gfHwgMCkgKyAoeSB8fCAwKTtcblxuXHRcdHN0YWNrLnBvaW50c1twb2ludEtleV0ucHVzaChzdGFjay5jdW0pO1xuXHRcdHN0YWNrZWRZRGF0YVtpXSA9IHN0YWNrLmN1bTtcblxuXHR9XG5cblx0aWYgKHN0YWNraW5nID09PSAncGVyY2VudCcpIHtcblx0XHR5QXhpcy51c2VQZXJjZW50YWdlID0gdHJ1ZTtcblx0fVxuXG5cdHRoaXMuc3RhY2tlZFlEYXRhID0gc3RhY2tlZFlEYXRhOyAvLyBUbyBiZSB1c2VkIGluIGdldEV4dHJlbWVzXG5cblx0Ly8gUmVzZXQgb2xkIHN0YWNrc1xuXHR5QXhpcy5vbGRTdGFja3MgPSB7fTtcbn07XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFsbCBzdGFja3MgYW5kIGNvbXB1dGUgdGhlIGFic29sdXRlIHZhbHVlcyB0byBwZXJjZW50XG4gKi9cblNlcmllcy5wcm90b3R5cGUuc2V0UGVyY2VudFN0YWNrcyA9IGZ1bmN0aW9uICgpIHtcblx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0c3RhY2tLZXkgPSBzZXJpZXMuc3RhY2tLZXksXG5cdFx0c3RhY2tzID0gc2VyaWVzLnlBeGlzLnN0YWNrcyxcblx0XHRwcm9jZXNzZWRYRGF0YSA9IHNlcmllcy5wcm9jZXNzZWRYRGF0YTtcblxuXHRlYWNoKFtzdGFja0tleSwgJy0nICsgc3RhY2tLZXldLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0dmFyIGkgPSBwcm9jZXNzZWRYRGF0YS5sZW5ndGgsXG5cdFx0XHR4LFxuXHRcdFx0c3RhY2ssXG5cdFx0XHRwb2ludEV4dHJlbWVzLFxuXHRcdFx0dG90YWxGYWN0b3I7XG5cblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHR4ID0gcHJvY2Vzc2VkWERhdGFbaV07XG5cdFx0XHRzdGFjayA9IHN0YWNrc1trZXldICYmIHN0YWNrc1trZXldW3hdO1xuXHRcdFx0cG9pbnRFeHRyZW1lcyA9IHN0YWNrICYmIHN0YWNrLnBvaW50c1tzZXJpZXMuaW5kZXggKyAnLCcgKyBpXTtcblx0XHRcdGlmIChwb2ludEV4dHJlbWVzKSB7XG5cdFx0XHRcdHRvdGFsRmFjdG9yID0gc3RhY2sudG90YWwgPyAxMDAgLyBzdGFjay50b3RhbCA6IDA7XG5cdFx0XHRcdHBvaW50RXh0cmVtZXNbMF0gPSBjb3JyZWN0RmxvYXQocG9pbnRFeHRyZW1lc1swXSAqIHRvdGFsRmFjdG9yKTsgLy8gWSBib3R0b20gdmFsdWVcblx0XHRcdFx0cG9pbnRFeHRyZW1lc1sxXSA9IGNvcnJlY3RGbG9hdChwb2ludEV4dHJlbWVzWzFdICogdG90YWxGYWN0b3IpOyAvLyBZIHZhbHVlXG5cdFx0XHRcdHNlcmllcy5zdGFja2VkWURhdGFbaV0gPSBwb2ludEV4dHJlbWVzWzFdO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59O1xuXG4vLyBFeHRlbmQgdGhlIENoYXJ0IHByb3RvdHlwZSBmb3IgZHluYW1pYyBtZXRob2RzXG5leHRlbmQoQ2hhcnQucHJvdG90eXBlLCB7XG5cblx0LyoqXG5cdCAqIEFkZCBhIHNlcmllcyBkeW5hbWljYWxseSBhZnRlciAgdGltZVxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgY29uZmlnIG9wdGlvbnNcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0IGFmdGVyIGFkZGluZy4gRGVmYXVsdHMgdG8gdHJ1ZS5cblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gYW5pbWF0aW9uIFdoZXRoZXIgdG8gYXBwbHkgYW5pbWF0aW9uLCBhbmQgb3B0aW9uYWxseSBhbmltYXRpb25cblx0ICogICAgY29uZmlndXJhdGlvblxuXHQgKlxuXHQgKiBAcmV0dXJuIHtPYmplY3R9IHNlcmllcyBUaGUgbmV3bHkgY3JlYXRlZCBzZXJpZXMgb2JqZWN0XG5cdCAqL1xuXHRhZGRTZXJpZXM6IGZ1bmN0aW9uIChvcHRpb25zLCByZWRyYXcsIGFuaW1hdGlvbikge1xuXHRcdHZhciBzZXJpZXMsXG5cdFx0XHRjaGFydCA9IHRoaXM7XG5cblx0XHRpZiAob3B0aW9ucykge1xuXHRcdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpOyAvLyBkZWZhdWx0cyB0byB0cnVlXG5cblx0XHRcdGZpcmVFdmVudChjaGFydCwgJ2FkZFNlcmllcycsIHsgb3B0aW9uczogb3B0aW9ucyB9LCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHNlcmllcyA9IGNoYXJ0LmluaXRTZXJpZXMob3B0aW9ucyk7XG5cblx0XHRcdFx0Y2hhcnQuaXNEaXJ0eUxlZ2VuZCA9IHRydWU7IC8vIHRoZSBzZXJpZXMgYXJyYXkgaXMgb3V0IG9mIHN5bmMgd2l0aCB0aGUgZGlzcGxheVxuXHRcdFx0XHRjaGFydC5saW5rU2VyaWVzKCk7XG5cdFx0XHRcdGlmIChyZWRyYXcpIHtcblx0XHRcdFx0XHRjaGFydC5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHNlcmllcztcblx0fSxcblxuXHQvKipcbiAgICAgKiBBZGQgYW4gYXhpcyB0byB0aGUgY2hhcnRcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgYXhpcyBvcHRpb25cbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzWCBXaGV0aGVyIGl0IGlzIGFuIFggYXhpcyBvciBhIHZhbHVlIGF4aXNcbiAgICAgKi9cblx0YWRkQXhpczogZnVuY3Rpb24gKG9wdGlvbnMsIGlzWCwgcmVkcmF3LCBhbmltYXRpb24pIHtcblx0XHR2YXIga2V5ID0gaXNYID8gJ3hBeGlzJyA6ICd5QXhpcycsXG5cdFx0XHRjaGFydE9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRheGlzO1xuXG5cdFx0Lypqc2xpbnQgdW51c2VkOiBmYWxzZSovXG5cdFx0YXhpcyA9IG5ldyBBeGlzKHRoaXMsIG1lcmdlKG9wdGlvbnMsIHtcblx0XHRcdGluZGV4OiB0aGlzW2tleV0ubGVuZ3RoLFxuXHRcdFx0aXNYOiBpc1hcblx0XHR9KSk7XG5cdFx0Lypqc2xpbnQgdW51c2VkOiB0cnVlKi9cblxuXHRcdC8vIFB1c2ggdGhlIG5ldyBheGlzIG9wdGlvbnMgdG8gdGhlIGNoYXJ0IG9wdGlvbnNcblx0XHRjaGFydE9wdGlvbnNba2V5XSA9IHNwbGF0KGNoYXJ0T3B0aW9uc1trZXldIHx8IHt9KTtcblx0XHRjaGFydE9wdGlvbnNba2V5XS5wdXNoKG9wdGlvbnMpO1xuXG5cdFx0aWYgKHBpY2socmVkcmF3LCB0cnVlKSkge1xuXHRcdFx0dGhpcy5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIERpbSB0aGUgY2hhcnQgYW5kIHNob3cgYSBsb2FkaW5nIHRleHQgb3Igc3ltYm9sXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgQW4gb3B0aW9uYWwgdGV4dCB0byBzaG93IGluIHRoZSBsb2FkaW5nIGxhYmVsIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb25lXG5cdCAqL1xuXHRzaG93TG9hZGluZzogZnVuY3Rpb24gKHN0cikge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gY2hhcnQub3B0aW9ucyxcblx0XHRcdGxvYWRpbmdEaXYgPSBjaGFydC5sb2FkaW5nRGl2LFxuXHRcdFx0bG9hZGluZ09wdGlvbnMgPSBvcHRpb25zLmxvYWRpbmcsXG5cdFx0XHRzZXRMb2FkaW5nU2l6ZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0aWYgKGxvYWRpbmdEaXYpIHtcblx0XHRcdFx0XHRjc3MobG9hZGluZ0Rpdiwge1xuXHRcdFx0XHRcdFx0bGVmdDogY2hhcnQucGxvdExlZnQgKyBQWCxcblx0XHRcdFx0XHRcdHRvcDogY2hhcnQucGxvdFRvcCArIFBYLFxuXHRcdFx0XHRcdFx0d2lkdGg6IGNoYXJ0LnBsb3RXaWR0aCArIFBYLFxuXHRcdFx0XHRcdFx0aGVpZ2h0OiBjaGFydC5wbG90SGVpZ2h0ICsgUFhcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdC8vIGNyZWF0ZSB0aGUgbGF5ZXIgYXQgdGhlIGZpcnN0IGNhbGxcblx0XHRpZiAoIWxvYWRpbmdEaXYpIHtcblx0XHRcdGNoYXJ0LmxvYWRpbmdEaXYgPSBsb2FkaW5nRGl2ID0gY3JlYXRlRWxlbWVudChESVYsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiBQUkVGSVggKyAnbG9hZGluZydcblx0XHRcdH0sIGV4dGVuZChsb2FkaW5nT3B0aW9ucy5zdHlsZSwge1xuXHRcdFx0XHR6SW5kZXg6IDEwLFxuXHRcdFx0XHRkaXNwbGF5OiBOT05FXG5cdFx0XHR9KSwgY2hhcnQuY29udGFpbmVyKTtcblxuXHRcdFx0Y2hhcnQubG9hZGluZ1NwYW4gPSBjcmVhdGVFbGVtZW50KFxuXHRcdFx0XHQnc3BhbicsXG5cdFx0XHRcdG51bGwsXG5cdFx0XHRcdGxvYWRpbmdPcHRpb25zLmxhYmVsU3R5bGUsXG5cdFx0XHRcdGxvYWRpbmdEaXZcblx0XHRcdCk7XG5cdFx0XHRhZGRFdmVudChjaGFydCwgJ3JlZHJhdycsIHNldExvYWRpbmdTaXplKTsgLy8gIzEwODBcblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgdGV4dFxuXHRcdGNoYXJ0LmxvYWRpbmdTcGFuLmlubmVySFRNTCA9IHN0ciB8fCBvcHRpb25zLmxhbmcubG9hZGluZztcblxuXHRcdC8vIHNob3cgaXRcblx0XHRpZiAoIWNoYXJ0LmxvYWRpbmdTaG93bikge1xuXHRcdFx0Y3NzKGxvYWRpbmdEaXYsIHtcblx0XHRcdFx0b3BhY2l0eTogMCxcblx0XHRcdFx0ZGlzcGxheTogJydcdFx0XHRcdFxuXHRcdFx0fSk7XG5cdFx0XHRhbmltYXRlKGxvYWRpbmdEaXYsIHtcblx0XHRcdFx0b3BhY2l0eTogbG9hZGluZ09wdGlvbnMuc3R5bGUub3BhY2l0eVxuXHRcdFx0fSwge1xuXHRcdFx0XHRkdXJhdGlvbjogbG9hZGluZ09wdGlvbnMuc2hvd0R1cmF0aW9uIHx8IDBcblx0XHRcdH0pO1xuXHRcdFx0Y2hhcnQubG9hZGluZ1Nob3duID0gdHJ1ZTtcblx0XHR9XG5cdFx0c2V0TG9hZGluZ1NpemUoKTtcblx0fSxcblxuXHQvKipcblx0ICogSGlkZSB0aGUgbG9hZGluZyBsYXllclxuXHQgKi9cblx0aGlkZUxvYWRpbmc6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdGxvYWRpbmdEaXYgPSB0aGlzLmxvYWRpbmdEaXY7XG5cblx0XHRpZiAobG9hZGluZ0Rpdikge1xuXHRcdFx0YW5pbWF0ZShsb2FkaW5nRGl2LCB7XG5cdFx0XHRcdG9wYWNpdHk6IDBcblx0XHRcdH0sIHtcblx0XHRcdFx0ZHVyYXRpb246IG9wdGlvbnMubG9hZGluZy5oaWRlRHVyYXRpb24gfHwgMTAwLFxuXHRcdFx0XHRjb21wbGV0ZTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGNzcyhsb2FkaW5nRGl2LCB7IGRpc3BsYXk6IE5PTkUgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHR0aGlzLmxvYWRpbmdTaG93biA9IGZhbHNlO1xuXHR9XG59KTtcblxuLy8gZXh0ZW5kIHRoZSBQb2ludCBwcm90b3R5cGUgZm9yIGR5bmFtaWMgbWV0aG9kc1xuZXh0ZW5kKFBvaW50LnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogVXBkYXRlIHRoZSBwb2ludCB3aXRoIG5ldyBvcHRpb25zICh0eXBpY2FsbHkgeC95IGRhdGEpIGFuZCBvcHRpb25hbGx5IHJlZHJhdyB0aGUgc2VyaWVzLlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBQb2ludCBvcHRpb25zIGFzIGRlZmluZWQgaW4gdGhlIHNlcmllcy5kYXRhIGFycmF5XG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVkcmF3IFdoZXRoZXIgdG8gcmVkcmF3IHRoZSBjaGFydCBvciB3YWl0IGZvciBhbiBleHBsaWNpdCBjYWxsXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IGFuaW1hdGlvbiBXaGV0aGVyIHRvIGFwcGx5IGFuaW1hdGlvbiwgYW5kIG9wdGlvbmFsbHkgYW5pbWF0aW9uXG5cdCAqICAgIGNvbmZpZ3VyYXRpb25cblx0ICpcblx0ICovXG5cdHVwZGF0ZTogZnVuY3Rpb24gKG9wdGlvbnMsIHJlZHJhdywgYW5pbWF0aW9uLCBydW5FdmVudCkge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRncmFwaGljID0gcG9pbnQuZ3JhcGhpYyxcblx0XHRcdGksXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHNlcmllc09wdGlvbnMgPSBzZXJpZXMub3B0aW9ucztcblxuXHRcdHJlZHJhdyA9IHBpY2socmVkcmF3LCB0cnVlKTtcblxuXHRcdGZ1bmN0aW9uIHVwZGF0ZSgpIHtcblxuXHRcdFx0cG9pbnQuYXBwbHlPcHRpb25zKG9wdGlvbnMpO1xuXG5cdFx0XHQvLyBVcGRhdGUgdmlzdWFsc1xuXHRcdFx0aWYgKGlzT2JqZWN0KG9wdGlvbnMpICYmICFpc0FycmF5KG9wdGlvbnMpKSB7XG5cdFx0XHRcdC8vIERlZmVyIHRoZSBhY3R1YWwgcmVkcmF3IHVudGlsIGdldEF0dHJpYnMgaGFzIGJlZW4gY2FsbGVkICgjMzI2MClcblx0XHRcdFx0cG9pbnQucmVkcmF3ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGlmIChncmFwaGljKSB7XG5cdFx0XHRcdFx0XHRpZiAob3B0aW9ucyAmJiBvcHRpb25zLm1hcmtlciAmJiBvcHRpb25zLm1hcmtlci5zeW1ib2wpIHtcblx0XHRcdFx0XHRcdFx0cG9pbnQuZ3JhcGhpYyA9IGdyYXBoaWMuZGVzdHJveSgpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Z3JhcGhpYy5hdHRyKHBvaW50LnBvaW50QXR0cltwb2ludC5zdGF0ZSB8fCAnJ10pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAob3B0aW9ucyAmJiBvcHRpb25zLmRhdGFMYWJlbHMgJiYgcG9pbnQuZGF0YUxhYmVsKSB7IC8vICMyNDY4XG5cdFx0XHRcdFx0XHRwb2ludC5kYXRhTGFiZWwgPSBwb2ludC5kYXRhTGFiZWwuZGVzdHJveSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb2ludC5yZWRyYXcgPSBudWxsO1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyByZWNvcmQgY2hhbmdlcyBpbiB0aGUgcGFyYWxsZWwgYXJyYXlzXG5cdFx0XHRpID0gcG9pbnQuaW5kZXg7XG5cdFx0XHRzZXJpZXMudXBkYXRlUGFyYWxsZWxBcnJheXMocG9pbnQsIGkpO1xuXG5cdFx0XHRzZXJpZXNPcHRpb25zLmRhdGFbaV0gPSBwb2ludC5vcHRpb25zO1xuXG5cdFx0XHQvLyByZWRyYXdcblx0XHRcdHNlcmllcy5pc0RpcnR5ID0gc2VyaWVzLmlzRGlydHlEYXRhID0gdHJ1ZTtcblx0XHRcdGlmICghc2VyaWVzLmZpeGVkQm94ICYmIHNlcmllcy5oYXNDYXJ0ZXNpYW5TZXJpZXMpIHsgLy8gIzE5MDYsICMyMzIwXG5cdFx0XHRcdGNoYXJ0LmlzRGlydHlCb3ggPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoc2VyaWVzT3B0aW9ucy5sZWdlbmRUeXBlID09PSAncG9pbnQnKSB7IC8vICMxODMxLCAjMTg4NVxuXHRcdFx0XHRjaGFydC5sZWdlbmQuZGVzdHJveUl0ZW0ocG9pbnQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0XHRjaGFydC5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXJlIHRoZSBldmVudCB3aXRoIGEgZGVmYXVsdCBoYW5kbGVyIG9mIGRvaW5nIHRoZSB1cGRhdGVcblx0XHRpZiAocnVuRXZlbnQgPT09IGZhbHNlKSB7IC8vIFdoZW4gY2FsbGVkIGZyb20gc2V0RGF0YVxuXHRcdFx0dXBkYXRlKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBvaW50LmZpcmVQb2ludEV2ZW50KCd1cGRhdGUnLCB7IG9wdGlvbnM6IG9wdGlvbnMgfSwgdXBkYXRlKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbW92ZSBhIHBvaW50IGFuZCBvcHRpb25hbGx5IHJlZHJhdyB0aGUgc2VyaWVzIGFuZCBpZiBuZWNlc3NhcnkgdGhlIGF4ZXNcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0IG9yIHdhaXQgZm9yIGFuIGV4cGxpY2l0IGNhbGxcblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gYW5pbWF0aW9uIFdoZXRoZXIgdG8gYXBwbHkgYW5pbWF0aW9uLCBhbmQgb3B0aW9uYWxseSBhbmltYXRpb25cblx0ICogICAgY29uZmlndXJhdGlvblxuXHQgKi9cblx0cmVtb3ZlOiBmdW5jdGlvbiAocmVkcmF3LCBhbmltYXRpb24pIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0aSxcblx0XHRcdGRhdGEgPSBzZXJpZXMuZGF0YTtcblxuXHRcdHNldEFuaW1hdGlvbihhbmltYXRpb24sIGNoYXJ0KTtcblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7XG5cblx0XHQvLyBmaXJlIHRoZSBldmVudCB3aXRoIGEgZGVmYXVsdCBoYW5kbGVyIG9mIHJlbW92aW5nIHRoZSBwb2ludFxuXHRcdHBvaW50LmZpcmVQb2ludEV2ZW50KCdyZW1vdmUnLCBudWxsLCBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdC8vIHNwbGljZSBhbGwgdGhlIHBhcmFsbGVsIGFycmF5c1xuXHRcdFx0aSA9IGluQXJyYXkocG9pbnQsIGRhdGEpO1xuXHRcdFx0aWYgKGRhdGEubGVuZ3RoID09PSBwb2ludHMubGVuZ3RoKSB7XG5cdFx0XHRcdHBvaW50cy5zcGxpY2UoaSwgMSk7XG5cdFx0XHR9XG5cdFx0XHRkYXRhLnNwbGljZShpLCAxKTtcblx0XHRcdHNlcmllcy5vcHRpb25zLmRhdGEuc3BsaWNlKGksIDEpO1xuXHRcdFx0c2VyaWVzLnVwZGF0ZVBhcmFsbGVsQXJyYXlzKHBvaW50LCAnc3BsaWNlJywgaSwgMSk7XG5cblx0XHRcdHBvaW50LmRlc3Ryb3koKTtcblxuXHRcdFx0Ly8gcmVkcmF3XG5cdFx0XHRzZXJpZXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRzZXJpZXMuaXNEaXJ0eURhdGEgPSB0cnVlO1xuXHRcdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0XHRjaGFydC5yZWRyYXcoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSk7XG5cbi8vIEV4dGVuZCB0aGUgc2VyaWVzIHByb3RvdHlwZSBmb3IgZHluYW1pYyBtZXRob2RzXG5leHRlbmQoU2VyaWVzLnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogQWRkIGEgcG9pbnQgZHluYW1pY2FsbHkgYWZ0ZXIgY2hhcnQgbG9hZCB0aW1lXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFBvaW50IG9wdGlvbnMgYXMgZ2l2ZW4gaW4gc2VyaWVzLmRhdGFcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0IG9yIHdhaXQgZm9yIGFuIGV4cGxpY2l0IGNhbGxcblx0ICogQHBhcmFtIHtCb29sZWFufSBzaGlmdCBJZiBzaGlmdCBpcyB0cnVlLCBhIHBvaW50IGlzIHNoaWZ0ZWQgb2ZmIHRoZSBzdGFydFxuXHQgKiAgICBvZiB0aGUgc2VyaWVzIGFzIG9uZSBpcyBhcHBlbmRlZCB0byB0aGUgZW5kLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBhbmltYXRpb24gV2hldGhlciB0byBhcHBseSBhbmltYXRpb24sIGFuZCBvcHRpb25hbGx5IGFuaW1hdGlvblxuXHQgKiAgICBjb25maWd1cmF0aW9uXG5cdCAqL1xuXHRhZGRQb2ludDogZnVuY3Rpb24gKG9wdGlvbnMsIHJlZHJhdywgc2hpZnQsIGFuaW1hdGlvbikge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0ZGF0YSA9IHNlcmllcy5kYXRhLFxuXHRcdFx0Z3JhcGggPSBzZXJpZXMuZ3JhcGgsXG5cdFx0XHRhcmVhID0gc2VyaWVzLmFyZWEsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdG5hbWVzID0gc2VyaWVzLnhBeGlzICYmIHNlcmllcy54QXhpcy5uYW1lcyxcblx0XHRcdGN1cnJlbnRTaGlmdCA9IChncmFwaCAmJiBncmFwaC5zaGlmdCkgfHwgMCxcblx0XHRcdGRhdGFPcHRpb25zID0gc2VyaWVzT3B0aW9ucy5kYXRhLFxuXHRcdFx0cG9pbnQsXG5cdFx0XHRpc0luVGhlTWlkZGxlLFxuXHRcdFx0eERhdGEgPSBzZXJpZXMueERhdGEsXG5cdFx0XHR4LFxuXHRcdFx0aTtcblxuXHRcdHNldEFuaW1hdGlvbihhbmltYXRpb24sIGNoYXJ0KTtcblxuXHRcdC8vIE1ha2UgZ3JhcGggYW5pbWF0ZSBzaWRld2F5c1xuXHRcdGlmIChzaGlmdCkge1xuXHRcdFx0ZWFjaChbZ3JhcGgsIGFyZWEsIHNlcmllcy5ncmFwaE5lZywgc2VyaWVzLmFyZWFOZWddLCBmdW5jdGlvbiAoc2hhcGUpIHtcblx0XHRcdFx0aWYgKHNoYXBlKSB7XG5cdFx0XHRcdFx0c2hhcGUuc2hpZnQgPSBjdXJyZW50U2hpZnQgKyAxO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKGFyZWEpIHtcblx0XHRcdGFyZWEuaXNBcmVhID0gdHJ1ZTsgLy8gbmVlZGVkIGluIGFuaW1hdGlvbiwgYm90aCB3aXRoIGFuZCB3aXRob3V0IHNoaWZ0XG5cdFx0fVxuXG5cdFx0Ly8gT3B0aW9uYWwgcmVkcmF3LCBkZWZhdWx0cyB0byB0cnVlXG5cdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpO1xuXG5cdFx0Ly8gR2V0IG9wdGlvbnMgYW5kIHB1c2ggdGhlIHBvaW50IHRvIHhEYXRhLCB5RGF0YSBhbmQgc2VyaWVzLm9wdGlvbnMuIEluIHNlcmllcy5nZW5lcmF0ZVBvaW50c1xuXHRcdC8vIHRoZSBQb2ludCBpbnN0YW5jZSB3aWxsIGJlIGNyZWF0ZWQgb24gZGVtYW5kIGFuZCBwdXNoZWQgdG8gdGhlIHNlcmllcy5kYXRhIGFycmF5LlxuXHRcdHBvaW50ID0geyBzZXJpZXM6IHNlcmllcyB9O1xuXHRcdHNlcmllcy5wb2ludENsYXNzLnByb3RvdHlwZS5hcHBseU9wdGlvbnMuYXBwbHkocG9pbnQsIFtvcHRpb25zXSk7XG5cdFx0eCA9IHBvaW50Lng7XG5cblx0XHQvLyBHZXQgdGhlIGluc2VydGlvbiBwb2ludFxuXHRcdGkgPSB4RGF0YS5sZW5ndGg7XG5cdFx0aWYgKHNlcmllcy5yZXF1aXJlU29ydGluZyAmJiB4IDwgeERhdGFbaSAtIDFdKSB7XG5cdFx0XHRpc0luVGhlTWlkZGxlID0gdHJ1ZTtcblx0XHRcdHdoaWxlIChpICYmIHhEYXRhW2kgLSAxXSA+IHgpIHtcblx0XHRcdFx0aS0tO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHNlcmllcy51cGRhdGVQYXJhbGxlbEFycmF5cyhwb2ludCwgJ3NwbGljZScsIGksIDAsIDApOyAvLyBpbnNlcnQgdW5kZWZpbmVkIGl0ZW1cblx0XHRzZXJpZXMudXBkYXRlUGFyYWxsZWxBcnJheXMocG9pbnQsIGkpOyAvLyB1cGRhdGUgaXRcblxuXHRcdGlmIChuYW1lcyAmJiBwb2ludC5uYW1lKSB7XG5cdFx0XHRuYW1lc1t4XSA9IHBvaW50Lm5hbWU7XG5cdFx0fVxuXHRcdGRhdGFPcHRpb25zLnNwbGljZShpLCAwLCBvcHRpb25zKTtcblxuXHRcdGlmIChpc0luVGhlTWlkZGxlKSB7XG5cdFx0XHRzZXJpZXMuZGF0YS5zcGxpY2UoaSwgMCwgbnVsbCk7XG5cdFx0XHRzZXJpZXMucHJvY2Vzc0RhdGEoKTtcblx0XHR9XG5cblx0XHQvLyBHZW5lcmF0ZSBwb2ludHMgdG8gYmUgYWRkZWQgdG8gdGhlIGxlZ2VuZCAoIzEzMjkpXG5cdFx0aWYgKHNlcmllc09wdGlvbnMubGVnZW5kVHlwZSA9PT0gJ3BvaW50Jykge1xuXHRcdFx0c2VyaWVzLmdlbmVyYXRlUG9pbnRzKCk7XG5cdFx0fVxuXG5cdFx0Ly8gU2hpZnQgdGhlIGZpcnN0IHBvaW50IG9mZiB0aGUgcGFyYWxsZWwgYXJyYXlzXG5cdFx0Ly8gdG9kbzogY29uc2lkZXIgc2VyaWVzLnJlbW92ZVBvaW50KGkpIG1ldGhvZFxuXHRcdGlmIChzaGlmdCkge1xuXHRcdFx0aWYgKGRhdGFbMF0gJiYgZGF0YVswXS5yZW1vdmUpIHtcblx0XHRcdFx0ZGF0YVswXS5yZW1vdmUoZmFsc2UpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGF0YS5zaGlmdCgpO1xuXHRcdFx0XHRzZXJpZXMudXBkYXRlUGFyYWxsZWxBcnJheXMocG9pbnQsICdzaGlmdCcpO1xuXG5cdFx0XHRcdGRhdGFPcHRpb25zLnNoaWZ0KCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gcmVkcmF3XG5cdFx0c2VyaWVzLmlzRGlydHkgPSB0cnVlO1xuXHRcdHNlcmllcy5pc0RpcnR5RGF0YSA9IHRydWU7XG5cdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0c2VyaWVzLmdldEF0dHJpYnMoKTsgLy8gIzE5Mzdcblx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmVtb3ZlIGEgc2VyaWVzIGFuZCBvcHRpb25hbGx5IHJlZHJhdyB0aGUgY2hhcnRcblx0ICpcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0IG9yIHdhaXQgZm9yIGFuIGV4cGxpY2l0IGNhbGxcblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gYW5pbWF0aW9uIFdoZXRoZXIgdG8gYXBwbHkgYW5pbWF0aW9uLCBhbmQgb3B0aW9uYWxseSBhbmltYXRpb25cblx0ICogICAgY29uZmlndXJhdGlvblxuXHQgKi9cblxuXHRyZW1vdmU6IGZ1bmN0aW9uIChyZWRyYXcsIGFuaW1hdGlvbikge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQ7XG5cdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpO1xuXG5cdFx0aWYgKCFzZXJpZXMuaXNSZW1vdmluZykgeyAgLyogcHJldmVudCB0cmlnZ2VyaW5nIG5hdGl2ZSBldmVudCBpbiBqUXVlcnlcblx0XHRcdFx0KGNhbGxpbmcgdGhlIHJlbW92ZSBmdW5jdGlvbiBmcm9tIHRoZSByZW1vdmUgZXZlbnQpICovXG5cdFx0XHRzZXJpZXMuaXNSZW1vdmluZyA9IHRydWU7XG5cblx0XHRcdC8vIGZpcmUgdGhlIGV2ZW50IHdpdGggYSBkZWZhdWx0IGhhbmRsZXIgb2YgcmVtb3ZpbmcgdGhlIHBvaW50XG5cdFx0XHRmaXJlRXZlbnQoc2VyaWVzLCAncmVtb3ZlJywgbnVsbCwgZnVuY3Rpb24gKCkge1xuXG5cblx0XHRcdFx0Ly8gZGVzdHJveSBlbGVtZW50c1xuXHRcdFx0XHRzZXJpZXMuZGVzdHJveSgpO1xuXG5cblx0XHRcdFx0Ly8gcmVkcmF3XG5cdFx0XHRcdGNoYXJ0LmlzRGlydHlMZWdlbmQgPSBjaGFydC5pc0RpcnR5Qm94ID0gdHJ1ZTtcblx0XHRcdFx0Y2hhcnQubGlua1NlcmllcygpO1xuXG5cdFx0XHRcdGlmIChyZWRyYXcpIHtcblx0XHRcdFx0XHRjaGFydC5yZWRyYXcoYW5pbWF0aW9uKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHR9XG5cdFx0c2VyaWVzLmlzUmVtb3ZpbmcgPSBmYWxzZTtcblx0fSxcblxuXHQvKipcblx0ICogVXBkYXRlIHRoZSBzZXJpZXMgd2l0aCBhIG5ldyBzZXQgb2Ygb3B0aW9uc1xuXHQgKi9cblx0dXBkYXRlOiBmdW5jdGlvbiAobmV3T3B0aW9ucywgcmVkcmF3KSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHQvLyBtdXN0IHVzZSB1c2VyIG9wdGlvbnMgd2hlbiBjaGFuZ2luZyB0eXBlIGJlY2F1c2UgdGhpcy5vcHRpb25zIGlzIG1lcmdlZFxuXHRcdFx0Ly8gaW4gd2l0aCB0eXBlIHNwZWNpZmljIHBsb3RPcHRpb25zXG5cdFx0XHRvbGRPcHRpb25zID0gdGhpcy51c2VyT3B0aW9ucyxcblx0XHRcdG9sZFR5cGUgPSB0aGlzLnR5cGUsXG5cdFx0XHRwcm90byA9IHNlcmllc1R5cGVzW29sZFR5cGVdLnByb3RvdHlwZSxcblx0XHRcdHByZXNlcnZlID0gWydncm91cCcsICdtYXJrZXJHcm91cCcsICdkYXRhTGFiZWxzR3JvdXAnXSxcblx0XHRcdG47XG5cblx0XHQvLyBNYWtlIHN1cmUgZ3JvdXBzIGFyZSBub3QgZGVzdHJveWVkICgjMzA5NClcblx0XHRlYWNoKHByZXNlcnZlLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0cHJlc2VydmVbcHJvcF0gPSBzZXJpZXNbcHJvcF07XG5cdFx0XHRkZWxldGUgc2VyaWVzW3Byb3BdO1xuXHRcdH0pO1xuXG5cdFx0Ly8gRG8gdGhlIG1lcmdlLCB3aXRoIHNvbWUgZm9yY2VkIG9wdGlvbnNcblx0XHRuZXdPcHRpb25zID0gbWVyZ2Uob2xkT3B0aW9ucywge1xuXHRcdFx0YW5pbWF0aW9uOiBmYWxzZSxcblx0XHRcdGluZGV4OiB0aGlzLmluZGV4LFxuXHRcdFx0cG9pbnRTdGFydDogdGhpcy54RGF0YVswXSAvLyB3aGVuIHVwZGF0aW5nIGFmdGVyIGFkZFBvaW50XG5cdFx0fSwgeyBkYXRhOiB0aGlzLm9wdGlvbnMuZGF0YSB9LCBuZXdPcHRpb25zKTtcblxuXHRcdC8vIERlc3Ryb3kgdGhlIHNlcmllcyBhbmQgcmVpbnNlcnQgbWV0aG9kcyBmcm9tIHRoZSB0eXBlIHByb3RvdHlwZVxuXHRcdHRoaXMucmVtb3ZlKGZhbHNlKTtcblx0XHRmb3IgKG4gaW4gcHJvdG8pIHsgLy8gT3ZlcndyaXRlIHNlcmllcy10eXBlIHNwZWNpZmljIG1ldGhvZHMgKCMyMjcwKVxuXHRcdFx0aWYgKHByb3RvLmhhc093blByb3BlcnR5KG4pKSB7XG5cdFx0XHRcdHRoaXNbbl0gPSBVTkRFRklORUQ7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGV4dGVuZCh0aGlzLCBzZXJpZXNUeXBlc1tuZXdPcHRpb25zLnR5cGUgfHwgb2xkVHlwZV0ucHJvdG90eXBlKTtcblxuXHRcdC8vIFJlLXJlZ2lzdGVyIGdyb3VwcyAoIzMwOTQpXG5cdFx0ZWFjaChwcmVzZXJ2ZSwgZnVuY3Rpb24gKHByb3ApIHtcblx0XHRcdHNlcmllc1twcm9wXSA9IHByZXNlcnZlW3Byb3BdO1xuXHRcdH0pO1xuXG5cblx0XHR0aGlzLmluaXQoY2hhcnQsIG5ld09wdGlvbnMpO1xuXHRcdGNoYXJ0LmxpbmtTZXJpZXMoKTsgLy8gTGlua3MgYXJlIGxvc3QgaW4gdGhpcy5yZW1vdmUgKCMzMDI4KVxuXHRcdGlmIChwaWNrKHJlZHJhdywgdHJ1ZSkpIHtcblx0XHRcdGNoYXJ0LnJlZHJhdyhmYWxzZSk7XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gRXh0ZW5kIHRoZSBBeGlzLnByb3RvdHlwZSBmb3IgZHluYW1pYyBtZXRob2RzXG5leHRlbmQoQXhpcy5wcm90b3R5cGUsIHtcblxuXHQvKipcblx0ICogVXBkYXRlIHRoZSBheGlzIHdpdGggYSBuZXcgb3B0aW9ucyBzdHJ1Y3R1cmVcblx0ICovXG5cdHVwZGF0ZTogZnVuY3Rpb24gKG5ld09wdGlvbnMsIHJlZHJhdykge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cblx0XHRuZXdPcHRpb25zID0gY2hhcnQub3B0aW9uc1t0aGlzLmNvbGxdW3RoaXMub3B0aW9ucy5pbmRleF0gPSBtZXJnZSh0aGlzLnVzZXJPcHRpb25zLCBuZXdPcHRpb25zKTtcblxuXHRcdHRoaXMuZGVzdHJveSh0cnVlKTtcblx0XHR0aGlzLl9hZGRlZFBsb3RMQiA9IFVOREVGSU5FRDsgLy8gIzE2MTEsICMyODg3XG5cblx0XHR0aGlzLmluaXQoY2hhcnQsIGV4dGVuZChuZXdPcHRpb25zLCB7IGV2ZW50czogVU5ERUZJTkVEIH0pKTtcblxuXHRcdGNoYXJ0LmlzRGlydHlCb3ggPSB0cnVlO1xuXHRcdGlmIChwaWNrKHJlZHJhdywgdHJ1ZSkpIHtcblx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcbiAgICAgKiBSZW1vdmUgdGhlIGF4aXMgZnJvbSB0aGUgY2hhcnRcbiAgICAgKi9cblx0cmVtb3ZlOiBmdW5jdGlvbiAocmVkcmF3KSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGtleSA9IHRoaXMuY29sbCwgLy8geEF4aXMgb3IgeUF4aXNcblx0XHRcdGF4aXNTZXJpZXMgPSB0aGlzLnNlcmllcyxcblx0XHRcdGkgPSBheGlzU2VyaWVzLmxlbmd0aDtcblxuXHRcdC8vIFJlbW92ZSBhc3NvY2lhdGVkIHNlcmllcyAoIzI2ODcpXG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0aWYgKGF4aXNTZXJpZXNbaV0pIHtcblx0XHRcdFx0YXhpc1Nlcmllc1tpXS5yZW1vdmUoZmFsc2UpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgYXhpc1xuXHRcdGVyYXNlKGNoYXJ0LmF4ZXMsIHRoaXMpO1xuXHRcdGVyYXNlKGNoYXJ0W2tleV0sIHRoaXMpO1xuXHRcdGNoYXJ0Lm9wdGlvbnNba2V5XS5zcGxpY2UodGhpcy5vcHRpb25zLmluZGV4LCAxKTtcblx0XHRlYWNoKGNoYXJ0W2tleV0sIGZ1bmN0aW9uIChheGlzLCBpKSB7IC8vIFJlLWluZGV4LCAjMTcwNlxuXHRcdFx0YXhpcy5vcHRpb25zLmluZGV4ID0gaTtcblx0XHR9KTtcblx0XHR0aGlzLmRlc3Ryb3koKTtcblx0XHRjaGFydC5pc0RpcnR5Qm94ID0gdHJ1ZTtcblxuXHRcdGlmIChwaWNrKHJlZHJhdywgdHJ1ZSkpIHtcblx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogVXBkYXRlIHRoZSBheGlzIHRpdGxlIGJ5IG9wdGlvbnNcblx0ICovXG5cdHNldFRpdGxlOiBmdW5jdGlvbiAobmV3VGl0bGVPcHRpb25zLCByZWRyYXcpIHtcblx0XHR0aGlzLnVwZGF0ZSh7IHRpdGxlOiBuZXdUaXRsZU9wdGlvbnMgfSwgcmVkcmF3KTtcblx0fSxcblxuXHQvKipcblx0ICogU2V0IG5ldyBheGlzIGNhdGVnb3JpZXMgYW5kIG9wdGlvbmFsbHkgcmVkcmF3XG5cdCAqIEBwYXJhbSB7QXJyYXl9IGNhdGVnb3JpZXNcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXdcblx0ICovXG5cdHNldENhdGVnb3JpZXM6IGZ1bmN0aW9uIChjYXRlZ29yaWVzLCByZWRyYXcpIHtcblx0XHR0aGlzLnVwZGF0ZSh7IGNhdGVnb3JpZXM6IGNhdGVnb3JpZXMgfSwgcmVkcmF3KTtcblx0fVxuXG59KTtcblxuXG4vKipcbiAqIExpbmVTZXJpZXMgb2JqZWN0XG4gKi9cbnZhciBMaW5lU2VyaWVzID0gZXh0ZW5kQ2xhc3MoU2VyaWVzKTtcbnNlcmllc1R5cGVzLmxpbmUgPSBMaW5lU2VyaWVzO1xuXG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBhcmVhXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5hcmVhID0gbWVyZ2UoZGVmYXVsdFNlcmllc09wdGlvbnMsIHtcblx0dGhyZXNob2xkOiAwXG5cdC8vIHRyYWNrQnlBcmVhOiBmYWxzZSxcblx0Ly8gbGluZUNvbG9yOiBudWxsLCAvLyBvdmVycmlkZXMgY29sb3IsIGJ1dCBsZXRzIGZpbGxDb2xvciBiZSB1bmFsdGVyZWRcblx0Ly8gZmlsbE9wYWNpdHk6IDAuNzUsXG5cdC8vIGZpbGxDb2xvcjogbnVsbFxufSk7XG5cbi8qKlxuICogQXJlYVNlcmllcyBvYmplY3RcbiAqL1xudmFyIEFyZWFTZXJpZXMgPSBleHRlbmRDbGFzcyhTZXJpZXMsIHtcblx0dHlwZTogJ2FyZWEnLFxuXHQvKipcblx0ICogRm9yIHN0YWNrcywgZG9uJ3Qgc3BsaXQgc2VnbWVudHMgb24gbnVsbCB2YWx1ZXMuIEluc3RlYWQsIGRyYXcgbnVsbCB2YWx1ZXMgd2l0aCBcblx0ICogbm8gbWFya2VyLiBBbHNvIGluc2VydCBkdW1teSBwb2ludHMgZm9yIGFueSBYIHBvc2l0aW9uIHRoYXQgZXhpc3RzIGluIG90aGVyIHNlcmllc1xuXHQgKiBpbiB0aGUgc3RhY2suXG5cdCAqLyBcblx0Z2V0U2VnbWVudHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdHNlZ21lbnRzID0gW10sXG5cdFx0XHRzZWdtZW50ID0gW10sXG5cdFx0XHRrZXlzID0gW10sXG5cdFx0XHR4QXhpcyA9IHRoaXMueEF4aXMsXG5cdFx0XHR5QXhpcyA9IHRoaXMueUF4aXMsXG5cdFx0XHRzdGFjayA9IHlBeGlzLnN0YWNrc1t0aGlzLnN0YWNrS2V5XSxcblx0XHRcdHBvaW50TWFwID0ge30sXG5cdFx0XHRwbG90WCxcblx0XHRcdHBsb3RZLFxuXHRcdFx0cG9pbnRzID0gdGhpcy5wb2ludHMsXG5cdFx0XHRjb25uZWN0TnVsbHMgPSB0aGlzLm9wdGlvbnMuY29ubmVjdE51bGxzLFxuXHRcdFx0aSxcblx0XHRcdHg7XG5cblx0XHRpZiAodGhpcy5vcHRpb25zLnN0YWNraW5nICYmICF0aGlzLmNyb3BwZWQpIHsgLy8gY3JvcHBlZCBjYXVzZXMgYXJ0ZWZhY3RzIGluIFN0b2NrLCBhbmQgcGVyZiBpc3N1ZVxuXHRcdFx0Ly8gQ3JlYXRlIGEgbWFwIHdoZXJlIHdlIGNhbiBxdWlja2x5IGxvb2sgdXAgdGhlIHBvaW50cyBieSB0aGVpciBYIHZhbHVlLlxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IHBvaW50cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRwb2ludE1hcFtwb2ludHNbaV0ueF0gPSBwb2ludHNbaV07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNvcnQgdGhlIGtleXMgKCMxNjUxKVxuXHRcdFx0Zm9yICh4IGluIHN0YWNrKSB7XG5cdFx0XHRcdGlmIChzdGFja1t4XS50b3RhbCAhPT0gbnVsbCkgeyAvLyBudWxsZWQgYWZ0ZXIgc3dpdGNoaW5nIGJldHdlZW4gZ3JvdXBpbmcgYW5kIG5vdCAoIzE2NTEsICMyMzM2KVxuXHRcdFx0XHRcdGtleXMucHVzaCgreCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGtleXMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYSAtIGI7XG5cdFx0XHR9KTtcblxuXHRcdFx0ZWFjaChrZXlzLCBmdW5jdGlvbiAoeCkge1xuXHRcdFx0XHR2YXIgeSA9IDAsXG5cdFx0XHRcdFx0c3RhY2tQb2ludDtcblxuXHRcdFx0XHRpZiAoY29ubmVjdE51bGxzICYmICghcG9pbnRNYXBbeF0gfHwgcG9pbnRNYXBbeF0ueSA9PT0gbnVsbCkpIHsgLy8gIzE4MzZcblx0XHRcdFx0XHRyZXR1cm47XG5cblx0XHRcdFx0Ly8gVGhlIHBvaW50IGV4aXN0cywgcHVzaCBpdCB0byB0aGUgc2VnbWVudFxuXHRcdFx0XHR9IGVsc2UgaWYgKHBvaW50TWFwW3hdKSB7XG5cdFx0XHRcdFx0c2VnbWVudC5wdXNoKHBvaW50TWFwW3hdKTtcblxuXHRcdFx0XHQvLyBUaGVyZSBpcyBubyBwb2ludCBmb3IgdGhpcyBYIHZhbHVlIGluIHRoaXMgc2VyaWVzLCBzbyB3ZSBcblx0XHRcdFx0Ly8gaW5zZXJ0IGEgZHVtbXkgcG9pbnQgaW4gb3JkZXIgZm9yIHRoZSBhcmVhcyB0byBiZSBkcmF3blxuXHRcdFx0XHQvLyBjb3JyZWN0bHkuXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHQvLyBMb29wIGRvd24gdGhlIHN0YWNrIHRvIGZpbmQgdGhlIHNlcmllcyBiZWxvdyB0aGlzIG9uZSB0aGF0IGhhc1xuXHRcdFx0XHRcdC8vIGEgdmFsdWUgKCMxOTkxKVxuXHRcdFx0XHRcdGZvciAoaSA9IHNlcmllcy5pbmRleDsgaSA8PSB5QXhpcy5zZXJpZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdHN0YWNrUG9pbnQgPSBzdGFja1t4XS5wb2ludHNbaSArICcsJyArIHhdO1xuXHRcdFx0XHRcdFx0aWYgKHN0YWNrUG9pbnQpIHtcblx0XHRcdFx0XHRcdFx0eSA9IHN0YWNrUG9pbnRbMV07XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHBsb3RYID0geEF4aXMudHJhbnNsYXRlKHgpO1xuXHRcdFx0XHRcdHBsb3RZID0geUF4aXMudG9QaXhlbHMoeSwgdHJ1ZSk7XG5cdFx0XHRcdFx0c2VnbWVudC5wdXNoKHsgXG5cdFx0XHRcdFx0XHR5OiBudWxsLCBcblx0XHRcdFx0XHRcdHBsb3RYOiBwbG90WCxcblx0XHRcdFx0XHRcdGNsaWVudFg6IHBsb3RYLCBcblx0XHRcdFx0XHRcdHBsb3RZOiBwbG90WSwgXG5cdFx0XHRcdFx0XHR5Qm90dG9tOiBwbG90WSxcblx0XHRcdFx0XHRcdG9uTW91c2VPdmVyOiBub29wXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAoc2VnbWVudC5sZW5ndGgpIHtcblx0XHRcdFx0c2VnbWVudHMucHVzaChzZWdtZW50KTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRTZXJpZXMucHJvdG90eXBlLmdldFNlZ21lbnRzLmNhbGwodGhpcyk7XG5cdFx0XHRzZWdtZW50cyA9IHRoaXMuc2VnbWVudHM7XG5cdFx0fVxuXG5cdFx0dGhpcy5zZWdtZW50cyA9IHNlZ21lbnRzO1xuXHR9LFxuXHRcblx0LyoqXG5cdCAqIEV4dGVuZCB0aGUgYmFzZSBTZXJpZXMgZ2V0U2VnbWVudFBhdGggbWV0aG9kIGJ5IGFkZGluZyB0aGUgcGF0aCBmb3IgdGhlIGFyZWEuXG5cdCAqIFRoaXMgcGF0aCBpcyBwdXNoZWQgdG8gdGhlIHNlcmllcy5hcmVhUGF0aCBwcm9wZXJ0eS5cblx0ICovXG5cdGdldFNlZ21lbnRQYXRoOiBmdW5jdGlvbiAoc2VnbWVudCkge1xuXHRcdFxuXHRcdHZhciBzZWdtZW50UGF0aCA9IFNlcmllcy5wcm90b3R5cGUuZ2V0U2VnbWVudFBhdGguY2FsbCh0aGlzLCBzZWdtZW50KSwgLy8gY2FsbCBiYXNlIG1ldGhvZFxuXHRcdFx0YXJlYVNlZ21lbnRQYXRoID0gW10uY29uY2F0KHNlZ21lbnRQYXRoKSwgLy8gd29yayBvbiBhIGNvcHkgZm9yIHRoZSBhcmVhIHBhdGhcblx0XHRcdGksXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0c2VnTGVuZ3RoID0gc2VnbWVudFBhdGgubGVuZ3RoLFxuXHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZCA9IHRoaXMueUF4aXMuZ2V0VGhyZXNob2xkKG9wdGlvbnMudGhyZXNob2xkKSwgLy8gIzIxODFcblx0XHRcdHlCb3R0b207XG5cdFx0XG5cdFx0aWYgKHNlZ0xlbmd0aCA9PT0gMykgeyAvLyBmb3IgYW5pbWF0aW9uIGZyb20gMSB0byB0d28gcG9pbnRzXG5cdFx0XHRhcmVhU2VnbWVudFBhdGgucHVzaChMLCBzZWdtZW50UGF0aFsxXSwgc2VnbWVudFBhdGhbMl0pO1xuXHRcdH1cblx0XHRpZiAob3B0aW9ucy5zdGFja2luZyAmJiAhdGhpcy5jbG9zZWRTdGFja3MpIHtcblx0XHRcdFxuXHRcdFx0Ly8gRm9sbG93IHN0YWNrIGJhY2suIFRvZG86IGltcGxlbWVudCBhcmVhc3BsaW5lLiBBIGdlbmVyYWwgc29sdXRpb24gY291bGQgYmUgdG8gXG5cdFx0XHQvLyByZXZlcnNlIHRoZSBlbnRpcmUgZ3JhcGhQYXRoIG9mIHRoZSBwcmV2aW91cyBzZXJpZXMsIHRob3VnaCBtYXkgYmUgaGFyZCB3aXRoXG5cdFx0XHQvLyBzcGxpbmVzIGFuZCB3aXRoIHNlcmllcyB3aXRoIGRpZmZlcmVudCBleHRyZW1lc1xuXHRcdFx0Zm9yIChpID0gc2VnbWVudC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuXG5cdFx0XHRcdHlCb3R0b20gPSBwaWNrKHNlZ21lbnRbaV0ueUJvdHRvbSwgdHJhbnNsYXRlZFRocmVzaG9sZCk7XG5cdFx0XHRcblx0XHRcdFx0Ly8gc3RlcCBsaW5lP1xuXHRcdFx0XHRpZiAoaSA8IHNlZ21lbnQubGVuZ3RoIC0gMSAmJiBvcHRpb25zLnN0ZXApIHtcblx0XHRcdFx0XHRhcmVhU2VnbWVudFBhdGgucHVzaChzZWdtZW50W2kgKyAxXS5wbG90WCwgeUJvdHRvbSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdGFyZWFTZWdtZW50UGF0aC5wdXNoKHNlZ21lbnRbaV0ucGxvdFgsIHlCb3R0b20pO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHsgLy8gZm9sbG93IHplcm8gbGluZSBiYWNrXG5cdFx0XHR0aGlzLmNsb3NlU2VnbWVudChhcmVhU2VnbWVudFBhdGgsIHNlZ21lbnQsIHRyYW5zbGF0ZWRUaHJlc2hvbGQpO1xuXHRcdH1cblx0XHR0aGlzLmFyZWFQYXRoID0gdGhpcy5hcmVhUGF0aC5jb25jYXQoYXJlYVNlZ21lbnRQYXRoKTtcblx0XHRyZXR1cm4gc2VnbWVudFBhdGg7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRXh0ZW5kYWJsZSBtZXRob2QgdG8gY2xvc2UgdGhlIHNlZ21lbnQgcGF0aCBvZiBhbiBhcmVhLiBUaGlzIGlzIG92ZXJyaWRkZW4gaW4gcG9sYXIgXG5cdCAqIGNoYXJ0cy5cblx0ICovXG5cdGNsb3NlU2VnbWVudDogZnVuY3Rpb24gKHBhdGgsIHNlZ21lbnQsIHRyYW5zbGF0ZWRUaHJlc2hvbGQpIHtcblx0XHRwYXRoLnB1c2goXG5cdFx0XHRMLFxuXHRcdFx0c2VnbWVudFtzZWdtZW50Lmxlbmd0aCAtIDFdLnBsb3RYLFxuXHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZCxcblx0XHRcdEwsXG5cdFx0XHRzZWdtZW50WzBdLnBsb3RYLFxuXHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZFxuXHRcdCk7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRHJhdyB0aGUgZ3JhcGggYW5kIHRoZSB1bmRlcmx5aW5nIGFyZWEuIFRoaXMgbWV0aG9kIGNhbGxzIHRoZSBTZXJpZXMgYmFzZVxuXHQgKiBmdW5jdGlvbiBhbmQgYWRkcyB0aGUgYXJlYS4gVGhlIGFyZWFQYXRoIGlzIGNhbGN1bGF0ZWQgaW4gdGhlIGdldFNlZ21lbnRQYXRoXG5cdCAqIG1ldGhvZCBjYWxsZWQgZnJvbSBTZXJpZXMucHJvdG90eXBlLmRyYXdHcmFwaC5cblx0ICovXG5cdGRyYXdHcmFwaDogZnVuY3Rpb24gKCkge1xuXHRcdFxuXHRcdC8vIERlZmluZSBvciByZXNldCBhcmVhUGF0aFxuXHRcdHRoaXMuYXJlYVBhdGggPSBbXTtcblx0XHRcblx0XHQvLyBDYWxsIHRoZSBiYXNlIG1ldGhvZFxuXHRcdFNlcmllcy5wcm90b3R5cGUuZHJhd0dyYXBoLmFwcGx5KHRoaXMpO1xuXHRcdFxuXHRcdC8vIERlZmluZSBsb2NhbCB2YXJpYWJsZXNcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGFyZWFQYXRoID0gdGhpcy5hcmVhUGF0aCxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRuZWdhdGl2ZUNvbG9yID0gb3B0aW9ucy5uZWdhdGl2ZUNvbG9yLFxuXHRcdFx0bmVnYXRpdmVGaWxsQ29sb3IgPSBvcHRpb25zLm5lZ2F0aXZlRmlsbENvbG9yLFxuXHRcdFx0cHJvcHMgPSBbWydhcmVhJywgdGhpcy5jb2xvciwgb3B0aW9ucy5maWxsQ29sb3JdXTsgLy8gYXJlYSBuYW1lLCBtYWluIGNvbG9yLCBmaWxsIGNvbG9yXG5cdFx0XG5cdFx0aWYgKG5lZ2F0aXZlQ29sb3IgfHwgbmVnYXRpdmVGaWxsQ29sb3IpIHtcblx0XHRcdHByb3BzLnB1c2goWydhcmVhTmVnJywgbmVnYXRpdmVDb2xvciwgbmVnYXRpdmVGaWxsQ29sb3JdKTtcblx0XHR9XG5cdFx0XG5cdFx0ZWFjaChwcm9wcywgZnVuY3Rpb24gKHByb3ApIHtcblx0XHRcdHZhciBhcmVhS2V5ID0gcHJvcFswXSxcblx0XHRcdFx0YXJlYSA9IHNlcmllc1thcmVhS2V5XTtcblx0XHRcdFx0XG5cdFx0XHQvLyBDcmVhdGUgb3IgdXBkYXRlIHRoZSBhcmVhXG5cdFx0XHRpZiAoYXJlYSkgeyAvLyB1cGRhdGVcblx0XHRcdFx0YXJlYS5hbmltYXRlKHsgZDogYXJlYVBhdGggfSk7XG5cdFxuXHRcdFx0fSBlbHNlIHsgLy8gY3JlYXRlXG5cdFx0XHRcdHNlcmllc1thcmVhS2V5XSA9IHNlcmllcy5jaGFydC5yZW5kZXJlci5wYXRoKGFyZWFQYXRoKVxuXHRcdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRcdGZpbGw6IHBpY2soXG5cdFx0XHRcdFx0XHRcdHByb3BbMl0sXG5cdFx0XHRcdFx0XHRcdENvbG9yKHByb3BbMV0pLnNldE9wYWNpdHkocGljayhvcHRpb25zLmZpbGxPcGFjaXR5LCAwLjc1KSkuZ2V0KClcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0XHR6SW5kZXg6IDAgLy8gIzEwNjlcblx0XHRcdFx0XHR9KS5hZGQoc2VyaWVzLmdyb3VwKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRkcmF3TGVnZW5kU3ltYm9sOiBMZWdlbmRTeW1ib2xNaXhpbi5kcmF3UmVjdGFuZ2xlXG59KTtcblxuc2VyaWVzVHlwZXMuYXJlYSA9IEFyZWFTZXJpZXM7XG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBzcGxpbmVcbiAqL1xuZGVmYXVsdFBsb3RPcHRpb25zLnNwbGluZSA9IG1lcmdlKGRlZmF1bHRTZXJpZXNPcHRpb25zKTtcblxuLyoqXG4gKiBTcGxpbmVTZXJpZXMgb2JqZWN0XG4gKi9cbnZhciBTcGxpbmVTZXJpZXMgPSBleHRlbmRDbGFzcyhTZXJpZXMsIHtcblx0dHlwZTogJ3NwbGluZScsXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgc3BsaW5lIHNlZ21lbnQgZnJvbSBhIGdpdmVuIHBvaW50J3MgcHJldmlvdXMgbmVpZ2hib3VyIHRvIHRoZSBnaXZlbiBwb2ludFxuXHQgKi9cblx0Z2V0UG9pbnRTcGxpbmU6IGZ1bmN0aW9uIChzZWdtZW50LCBwb2ludCwgaSkge1xuXHRcdHZhciBzbW9vdGhpbmcgPSAxLjUsIC8vIDEgbWVhbnMgY29udHJvbCBwb2ludHMgbWlkd2F5IGJldHdlZW4gcG9pbnRzLCAyIG1lYW5zIDEvMyBmcm9tIHRoZSBwb2ludCwgMyBpcyAxLzQgZXRjXG5cdFx0XHRkZW5vbSA9IHNtb290aGluZyArIDEsXG5cdFx0XHRwbG90WCA9IHBvaW50LnBsb3RYLFxuXHRcdFx0cGxvdFkgPSBwb2ludC5wbG90WSxcblx0XHRcdGxhc3RQb2ludCA9IHNlZ21lbnRbaSAtIDFdLFxuXHRcdFx0bmV4dFBvaW50ID0gc2VnbWVudFtpICsgMV0sXG5cdFx0XHRsZWZ0Q29udFgsXG5cdFx0XHRsZWZ0Q29udFksXG5cdFx0XHRyaWdodENvbnRYLFxuXHRcdFx0cmlnaHRDb250WSxcblx0XHRcdHJldDtcblxuXHRcdC8vIGZpbmQgY29udHJvbCBwb2ludHNcblx0XHRpZiAobGFzdFBvaW50ICYmIG5leHRQb2ludCkge1xuXHRcdFxuXHRcdFx0dmFyIGxhc3RYID0gbGFzdFBvaW50LnBsb3RYLFxuXHRcdFx0XHRsYXN0WSA9IGxhc3RQb2ludC5wbG90WSxcblx0XHRcdFx0bmV4dFggPSBuZXh0UG9pbnQucGxvdFgsXG5cdFx0XHRcdG5leHRZID0gbmV4dFBvaW50LnBsb3RZLFxuXHRcdFx0XHRjb3JyZWN0aW9uO1xuXG5cdFx0XHRsZWZ0Q29udFggPSAoc21vb3RoaW5nICogcGxvdFggKyBsYXN0WCkgLyBkZW5vbTtcblx0XHRcdGxlZnRDb250WSA9IChzbW9vdGhpbmcgKiBwbG90WSArIGxhc3RZKSAvIGRlbm9tO1xuXHRcdFx0cmlnaHRDb250WCA9IChzbW9vdGhpbmcgKiBwbG90WCArIG5leHRYKSAvIGRlbm9tO1xuXHRcdFx0cmlnaHRDb250WSA9IChzbW9vdGhpbmcgKiBwbG90WSArIG5leHRZKSAvIGRlbm9tO1xuXG5cdFx0XHQvLyBoYXZlIHRoZSB0d28gY29udHJvbCBwb2ludHMgbWFrZSBhIHN0cmFpZ2h0IGxpbmUgdGhyb3VnaCBtYWluIHBvaW50XG5cdFx0XHRjb3JyZWN0aW9uID0gKChyaWdodENvbnRZIC0gbGVmdENvbnRZKSAqIChyaWdodENvbnRYIC0gcGxvdFgpKSAvXG5cdFx0XHRcdChyaWdodENvbnRYIC0gbGVmdENvbnRYKSArIHBsb3RZIC0gcmlnaHRDb250WTtcblxuXHRcdFx0bGVmdENvbnRZICs9IGNvcnJlY3Rpb247XG5cdFx0XHRyaWdodENvbnRZICs9IGNvcnJlY3Rpb247XG5cblx0XHRcdC8vIHRvIHByZXZlbnQgZmFsc2UgZXh0cmVtZXMsIGNoZWNrIHRoYXQgY29udHJvbCBwb2ludHMgYXJlIGJldHdlZW5cblx0XHRcdC8vIG5laWdoYm91cmluZyBwb2ludHMnIHkgdmFsdWVzXG5cdFx0XHRpZiAobGVmdENvbnRZID4gbGFzdFkgJiYgbGVmdENvbnRZID4gcGxvdFkpIHtcblx0XHRcdFx0bGVmdENvbnRZID0gbWF0aE1heChsYXN0WSwgcGxvdFkpO1xuXHRcdFx0XHRyaWdodENvbnRZID0gMiAqIHBsb3RZIC0gbGVmdENvbnRZOyAvLyBtaXJyb3Igb2YgbGVmdCBjb250cm9sIHBvaW50XG5cdFx0XHR9IGVsc2UgaWYgKGxlZnRDb250WSA8IGxhc3RZICYmIGxlZnRDb250WSA8IHBsb3RZKSB7XG5cdFx0XHRcdGxlZnRDb250WSA9IG1hdGhNaW4obGFzdFksIHBsb3RZKTtcblx0XHRcdFx0cmlnaHRDb250WSA9IDIgKiBwbG90WSAtIGxlZnRDb250WTtcblx0XHRcdH1cblx0XHRcdGlmIChyaWdodENvbnRZID4gbmV4dFkgJiYgcmlnaHRDb250WSA+IHBsb3RZKSB7XG5cdFx0XHRcdHJpZ2h0Q29udFkgPSBtYXRoTWF4KG5leHRZLCBwbG90WSk7XG5cdFx0XHRcdGxlZnRDb250WSA9IDIgKiBwbG90WSAtIHJpZ2h0Q29udFk7XG5cdFx0XHR9IGVsc2UgaWYgKHJpZ2h0Q29udFkgPCBuZXh0WSAmJiByaWdodENvbnRZIDwgcGxvdFkpIHtcblx0XHRcdFx0cmlnaHRDb250WSA9IG1hdGhNaW4obmV4dFksIHBsb3RZKTtcblx0XHRcdFx0bGVmdENvbnRZID0gMiAqIHBsb3RZIC0gcmlnaHRDb250WTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcmVjb3JkIGZvciBkcmF3aW5nIGluIG5leHQgcG9pbnRcblx0XHRcdHBvaW50LnJpZ2h0Q29udFggPSByaWdodENvbnRYO1xuXHRcdFx0cG9pbnQucmlnaHRDb250WSA9IHJpZ2h0Q29udFk7XG5cblx0XHR9XG5cdFx0XG5cdFx0Ly8gVmlzdWFsaXplIGNvbnRyb2wgcG9pbnRzIGZvciBkZWJ1Z2dpbmdcblx0XHQvKlxuXHRcdGlmIChsZWZ0Q29udFgpIHtcblx0XHRcdHRoaXMuY2hhcnQucmVuZGVyZXIuY2lyY2xlKGxlZnRDb250WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIGxlZnRDb250WSArIHRoaXMuY2hhcnQucGxvdFRvcCwgMilcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHN0cm9rZTogJ3JlZCcsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IDEsXG5cdFx0XHRcdFx0ZmlsbDogJ25vbmUnXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQoKTtcblx0XHRcdHRoaXMuY2hhcnQucmVuZGVyZXIucGF0aChbJ00nLCBsZWZ0Q29udFggKyB0aGlzLmNoYXJ0LnBsb3RMZWZ0LCBsZWZ0Q29udFkgKyB0aGlzLmNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRcdCdMJywgcGxvdFggKyB0aGlzLmNoYXJ0LnBsb3RMZWZ0LCBwbG90WSArIHRoaXMuY2hhcnQucGxvdFRvcF0pXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRzdHJva2U6ICdyZWQnLFxuXHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiAxXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQoKTtcblx0XHRcdHRoaXMuY2hhcnQucmVuZGVyZXIuY2lyY2xlKHJpZ2h0Q29udFggKyB0aGlzLmNoYXJ0LnBsb3RMZWZ0LCByaWdodENvbnRZICsgdGhpcy5jaGFydC5wbG90VG9wLCAyKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0c3Ryb2tlOiAnZ3JlZW4nLFxuXHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiAxLFxuXHRcdFx0XHRcdGZpbGw6ICdub25lJ1xuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0XHR0aGlzLmNoYXJ0LnJlbmRlcmVyLnBhdGgoWydNJywgcmlnaHRDb250WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIHJpZ2h0Q29udFkgKyB0aGlzLmNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRcdCdMJywgcGxvdFggKyB0aGlzLmNoYXJ0LnBsb3RMZWZ0LCBwbG90WSArIHRoaXMuY2hhcnQucGxvdFRvcF0pXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRzdHJva2U6ICdncmVlbicsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IDFcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdH1cblx0XHQqL1xuXG5cdFx0Ly8gbW92ZVRvIG9yIGxpbmVUb1xuXHRcdGlmICghaSkge1xuXHRcdFx0cmV0ID0gW00sIHBsb3RYLCBwbG90WV07XG5cdFx0fSBlbHNlIHsgLy8gY3VydmUgZnJvbSBsYXN0IHBvaW50IHRvIHRoaXNcblx0XHRcdHJldCA9IFtcblx0XHRcdFx0J0MnLFxuXHRcdFx0XHRsYXN0UG9pbnQucmlnaHRDb250WCB8fCBsYXN0UG9pbnQucGxvdFgsXG5cdFx0XHRcdGxhc3RQb2ludC5yaWdodENvbnRZIHx8IGxhc3RQb2ludC5wbG90WSxcblx0XHRcdFx0bGVmdENvbnRYIHx8IHBsb3RYLFxuXHRcdFx0XHRsZWZ0Q29udFkgfHwgcGxvdFksXG5cdFx0XHRcdHBsb3RYLFxuXHRcdFx0XHRwbG90WVxuXHRcdFx0XTtcblx0XHRcdGxhc3RQb2ludC5yaWdodENvbnRYID0gbGFzdFBvaW50LnJpZ2h0Q29udFkgPSBudWxsOyAvLyByZXNldCBmb3IgdXBkYXRpbmcgc2VyaWVzIGxhdGVyXG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH1cbn0pO1xuc2VyaWVzVHlwZXMuc3BsaW5lID0gU3BsaW5lU2VyaWVzO1xuXG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBhcmVhc3BsaW5lXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5hcmVhc3BsaW5lID0gbWVyZ2UoZGVmYXVsdFBsb3RPcHRpb25zLmFyZWEpO1xuXG4vKipcbiAqIEFyZWFTcGxpbmVTZXJpZXMgb2JqZWN0XG4gKi9cbnZhciBhcmVhUHJvdG8gPSBBcmVhU2VyaWVzLnByb3RvdHlwZSxcblx0QXJlYVNwbGluZVNlcmllcyA9IGV4dGVuZENsYXNzKFNwbGluZVNlcmllcywge1xuXHRcdHR5cGU6ICdhcmVhc3BsaW5lJyxcblx0XHRjbG9zZWRTdGFja3M6IHRydWUsIC8vIGluc3RlYWQgb2YgZm9sbG93aW5nIHRoZSBwcmV2aW91cyBncmFwaCBiYWNrLCBmb2xsb3cgdGhlIHRocmVzaG9sZCBiYWNrXG5cdFx0XG5cdFx0Ly8gTWl4IGluIG1ldGhvZHMgZnJvbSB0aGUgYXJlYSBzZXJpZXNcblx0XHRnZXRTZWdtZW50UGF0aDogYXJlYVByb3RvLmdldFNlZ21lbnRQYXRoLFxuXHRcdGNsb3NlU2VnbWVudDogYXJlYVByb3RvLmNsb3NlU2VnbWVudCxcblx0XHRkcmF3R3JhcGg6IGFyZWFQcm90by5kcmF3R3JhcGgsXG5cdFx0ZHJhd0xlZ2VuZFN5bWJvbDogTGVnZW5kU3ltYm9sTWl4aW4uZHJhd1JlY3RhbmdsZVxuXHR9KTtcblxuc2VyaWVzVHlwZXMuYXJlYXNwbGluZSA9IEFyZWFTcGxpbmVTZXJpZXM7XG5cbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIGNvbHVtblxuICovXG5kZWZhdWx0UGxvdE9wdGlvbnMuY29sdW1uID0gbWVyZ2UoZGVmYXVsdFNlcmllc09wdGlvbnMsIHtcblx0Ym9yZGVyQ29sb3I6ICcjRkZGRkZGJyxcblx0Ly9ib3JkZXJXaWR0aDogMSxcblx0Ym9yZGVyUmFkaXVzOiAwLFxuXHQvL2NvbG9yQnlQb2ludDogdW5kZWZpbmVkLFxuXHRncm91cFBhZGRpbmc6IDAuMixcblx0Ly9ncm91cGluZzogdHJ1ZSxcblx0bWFya2VyOiBudWxsLCAvLyBwb2ludCBvcHRpb25zIGFyZSBzcGVjaWZpZWQgaW4gdGhlIGJhc2Ugb3B0aW9uc1xuXHRwb2ludFBhZGRpbmc6IDAuMSxcblx0Ly9wb2ludFdpZHRoOiBudWxsLFxuXHRtaW5Qb2ludExlbmd0aDogMCxcblx0Y3JvcFRocmVzaG9sZDogNTAsIC8vIHdoZW4gdGhlcmUgYXJlIG1vcmUgcG9pbnRzLCB0aGV5IHdpbGwgbm90IGFuaW1hdGUgb3V0IG9mIHRoZSBjaGFydCBvbiB4QXhpcy5zZXRFeHRyZW1lc1xuXHRwb2ludFJhbmdlOiBudWxsLCAvLyBudWxsIG1lYW5zIGF1dG8sIG1lYW5pbmcgMSBpbiBhIGNhdGVnb3JpemVkIGF4aXMgYW5kIGxlYXN0IGRpc3RhbmNlIGJldHdlZW4gcG9pbnRzIGlmIG5vdCBjYXRlZ29yaWVzXG5cdHN0YXRlczoge1xuXHRcdGhvdmVyOiB7XG5cdFx0XHRicmlnaHRuZXNzOiAwLjEsXG5cdFx0XHRzaGFkb3c6IGZhbHNlLFxuXHRcdFx0aGFsbzogZmFsc2Vcblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Y29sb3I6ICcjQzBDMEMwJyxcblx0XHRcdGJvcmRlckNvbG9yOiAnIzAwMDAwMCcsXG5cdFx0XHRzaGFkb3c6IGZhbHNlXG5cdFx0fVxuXHR9LFxuXHRkYXRhTGFiZWxzOiB7XG5cdFx0YWxpZ246IG51bGwsIC8vIGF1dG9cblx0XHR2ZXJ0aWNhbEFsaWduOiBudWxsLCAvLyBhdXRvXG5cdFx0eTogbnVsbFxuXHR9LFxuXHRzdGlja3lUcmFja2luZzogZmFsc2UsXG5cdHRvb2x0aXA6IHtcblx0XHRkaXN0YW5jZTogNlxuXHR9LFxuXHR0aHJlc2hvbGQ6IDBcbn0pO1xuXG4vKipcbiAqIENvbHVtblNlcmllcyBvYmplY3RcbiAqL1xudmFyIENvbHVtblNlcmllcyA9IGV4dGVuZENsYXNzKFNlcmllcywge1xuXHR0eXBlOiAnY29sdW1uJyxcblx0cG9pbnRBdHRyVG9PcHRpb25zOiB7IC8vIG1hcHBpbmcgYmV0d2VlbiBTVkcgYXR0cmlidXRlcyBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgb3B0aW9uc1xuXHRcdHN0cm9rZTogJ2JvcmRlckNvbG9yJyxcblx0XHRmaWxsOiAnY29sb3InLFxuXHRcdHI6ICdib3JkZXJSYWRpdXMnXG5cdH0sXG5cdGNyb3BTaG91bGRlcjogMCxcblx0dHJhY2tlckdyb3VwczogWydncm91cCcsICdkYXRhTGFiZWxzR3JvdXAnXSxcblx0bmVnU3RhY2tzOiB0cnVlLCAvLyB1c2Ugc2VwYXJhdGUgbmVnYXRpdmUgc3RhY2tzLCB1bmxpa2UgYXJlYSBzdGFja3Mgd2hlcmUgYSBuZWdhdGl2ZSBcblx0XHQvLyBwb2ludCBpcyBzdWJzdHJhY3RlZCBmcm9tIHByZXZpb3VzICgjMTkxMClcblx0XG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBzZXJpZXNcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uICgpIHtcblx0XHRTZXJpZXMucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQ7XG5cblx0XHQvLyBpZiB0aGUgc2VyaWVzIGlzIGFkZGVkIGR5bmFtaWNhbGx5LCBmb3JjZSByZWRyYXcgb2Ygb3RoZXJcblx0XHQvLyBzZXJpZXMgYWZmZWN0ZWQgYnkgYSBuZXcgY29sdW1uXG5cdFx0aWYgKGNoYXJ0Lmhhc1JlbmRlcmVkKSB7XG5cdFx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKG90aGVyU2VyaWVzKSB7XG5cdFx0XHRcdGlmIChvdGhlclNlcmllcy50eXBlID09PSBzZXJpZXMudHlwZSkge1xuXHRcdFx0XHRcdG90aGVyU2VyaWVzLmlzRGlydHkgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJldHVybiB0aGUgd2lkdGggYW5kIHggb2Zmc2V0IG9mIHRoZSBjb2x1bW5zIGFkanVzdGVkIGZvciBncm91cGluZywgZ3JvdXBQYWRkaW5nLCBwb2ludFBhZGRpbmcsXG5cdCAqIHBvaW50V2lkdGggZXRjLiBcblx0ICovXG5cdGdldENvbHVtbk1ldHJpY3M6IGZ1bmN0aW9uICgpIHtcblxuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHR5QXhpcyA9IHNlcmllcy55QXhpcyxcblx0XHRcdHJldmVyc2VkWEF4aXMgPSB4QXhpcy5yZXZlcnNlZCxcblx0XHRcdHN0YWNrS2V5LFxuXHRcdFx0c3RhY2tHcm91cHMgPSB7fSxcblx0XHRcdGNvbHVtbkluZGV4LFxuXHRcdFx0Y29sdW1uQ291bnQgPSAwO1xuXG5cdFx0Ly8gR2V0IHRoZSB0b3RhbCBudW1iZXIgb2YgY29sdW1uIHR5cGUgc2VyaWVzLlxuXHRcdC8vIFRoaXMgaXMgY2FsbGVkIG9uIGV2ZXJ5IHNlcmllcy4gQ29uc2lkZXIgbW92aW5nIHRoaXMgbG9naWMgdG8gYVxuXHRcdC8vIGNoYXJ0Lm9yZGVyU3RhY2tzKCkgZnVuY3Rpb24gYW5kIGNhbGwgaXQgb24gaW5pdCwgYWRkU2VyaWVzIGFuZCByZW1vdmVTZXJpZXNcblx0XHRpZiAob3B0aW9ucy5ncm91cGluZyA9PT0gZmFsc2UpIHtcblx0XHRcdGNvbHVtbkNvdW50ID0gMTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWFjaChzZXJpZXMuY2hhcnQuc2VyaWVzLCBmdW5jdGlvbiAob3RoZXJTZXJpZXMpIHtcblx0XHRcdFx0dmFyIG90aGVyT3B0aW9ucyA9IG90aGVyU2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRcdFx0b3RoZXJZQXhpcyA9IG90aGVyU2VyaWVzLnlBeGlzO1xuXHRcdFx0XHRpZiAob3RoZXJTZXJpZXMudHlwZSA9PT0gc2VyaWVzLnR5cGUgJiYgb3RoZXJTZXJpZXMudmlzaWJsZSAmJlxuXHRcdFx0XHRcdFx0eUF4aXMubGVuID09PSBvdGhlcllBeGlzLmxlbiAmJiB5QXhpcy5wb3MgPT09IG90aGVyWUF4aXMucG9zKSB7ICAvLyAjNjQyLCAjMjA4NlxuXHRcdFx0XHRcdGlmIChvdGhlck9wdGlvbnMuc3RhY2tpbmcpIHtcblx0XHRcdFx0XHRcdHN0YWNrS2V5ID0gb3RoZXJTZXJpZXMuc3RhY2tLZXk7XG5cdFx0XHRcdFx0XHRpZiAoc3RhY2tHcm91cHNbc3RhY2tLZXldID09PSBVTkRFRklORUQpIHtcblx0XHRcdFx0XHRcdFx0c3RhY2tHcm91cHNbc3RhY2tLZXldID0gY29sdW1uQ291bnQrKztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGNvbHVtbkluZGV4ID0gc3RhY2tHcm91cHNbc3RhY2tLZXldO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAob3RoZXJPcHRpb25zLmdyb3VwaW5nICE9PSBmYWxzZSkgeyAvLyAjMTE2MlxuXHRcdFx0XHRcdFx0Y29sdW1uSW5kZXggPSBjb2x1bW5Db3VudCsrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRvdGhlclNlcmllcy5jb2x1bW5JbmRleCA9IGNvbHVtbkluZGV4O1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHR2YXIgY2F0ZWdvcnlXaWR0aCA9IG1hdGhNaW4oXG5cdFx0XHRcdG1hdGhBYnMoeEF4aXMudHJhbnNBKSAqICh4QXhpcy5vcmRpbmFsU2xvcGUgfHwgb3B0aW9ucy5wb2ludFJhbmdlIHx8IHhBeGlzLmNsb3Nlc3RQb2ludFJhbmdlIHx8IHhBeGlzLnRpY2tJbnRlcnZhbCB8fCAxKSwgLy8gIzI2MTBcblx0XHRcdFx0eEF4aXMubGVuIC8vICMxNTM1XG5cdFx0XHQpLFxuXHRcdFx0Z3JvdXBQYWRkaW5nID0gY2F0ZWdvcnlXaWR0aCAqIG9wdGlvbnMuZ3JvdXBQYWRkaW5nLFxuXHRcdFx0Z3JvdXBXaWR0aCA9IGNhdGVnb3J5V2lkdGggLSAyICogZ3JvdXBQYWRkaW5nLFxuXHRcdFx0cG9pbnRPZmZzZXRXaWR0aCA9IGdyb3VwV2lkdGggLyBjb2x1bW5Db3VudCxcblx0XHRcdG9wdGlvblBvaW50V2lkdGggPSBvcHRpb25zLnBvaW50V2lkdGgsXG5cdFx0XHRwb2ludFBhZGRpbmcgPSBkZWZpbmVkKG9wdGlvblBvaW50V2lkdGgpID8gKHBvaW50T2Zmc2V0V2lkdGggLSBvcHRpb25Qb2ludFdpZHRoKSAvIDIgOlxuXHRcdFx0XHRwb2ludE9mZnNldFdpZHRoICogb3B0aW9ucy5wb2ludFBhZGRpbmcsXG5cdFx0XHRwb2ludFdpZHRoID0gcGljayhvcHRpb25Qb2ludFdpZHRoLCBwb2ludE9mZnNldFdpZHRoIC0gMiAqIHBvaW50UGFkZGluZyksIC8vIGV4YWN0IHBvaW50IHdpZHRoLCB1c2VkIGluIHBvbGFyIGNoYXJ0c1xuXHRcdFx0Y29sSW5kZXggPSAocmV2ZXJzZWRYQXhpcyA/IFxuXHRcdFx0XHRjb2x1bW5Db3VudCAtIChzZXJpZXMuY29sdW1uSW5kZXggfHwgMCkgOiAvLyAjMTI1MVxuXHRcdFx0XHRzZXJpZXMuY29sdW1uSW5kZXgpIHx8IDAsXG5cdFx0XHRwb2ludFhPZmZzZXQgPSBwb2ludFBhZGRpbmcgKyAoZ3JvdXBQYWRkaW5nICsgY29sSW5kZXggKlxuXHRcdFx0XHRwb2ludE9mZnNldFdpZHRoIC0gKGNhdGVnb3J5V2lkdGggLyAyKSkgKlxuXHRcdFx0XHQocmV2ZXJzZWRYQXhpcyA/IC0xIDogMSk7XG5cblx0XHQvLyBTYXZlIGl0IGZvciByZWFkaW5nIGluIGxpbmtlZCBzZXJpZXMgKEVycm9yIGJhcnMgcGFydGljdWxhcmx5KVxuXHRcdHJldHVybiAoc2VyaWVzLmNvbHVtbk1ldHJpY3MgPSB7IFxuXHRcdFx0d2lkdGg6IHBvaW50V2lkdGgsIFxuXHRcdFx0b2Zmc2V0OiBwb2ludFhPZmZzZXQgXG5cdFx0fSk7XG5cdFx0XHRcblx0fSxcblxuXHQvKipcblx0ICogVHJhbnNsYXRlIGVhY2ggcG9pbnQgdG8gdGhlIHBsb3QgYXJlYSBjb29yZGluYXRlIHN5c3RlbSBhbmQgZmluZCBzaGFwZSBwb3NpdGlvbnNcblx0ICovXG5cdHRyYW5zbGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRib3JkZXJXaWR0aCA9IHNlcmllcy5ib3JkZXJXaWR0aCA9IHBpY2soXG5cdFx0XHRcdG9wdGlvbnMuYm9yZGVyV2lkdGgsIFxuXHRcdFx0XHRzZXJpZXMuYWN0aXZlUG9pbnRDb3VudCA+IDAuNSAqIHNlcmllcy54QXhpcy5sZW4gPyAwIDogMVxuXHRcdFx0KSxcblx0XHRcdHlBeGlzID0gc2VyaWVzLnlBeGlzLFxuXHRcdFx0dGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQsXG5cdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkID0gc2VyaWVzLnRyYW5zbGF0ZWRUaHJlc2hvbGQgPSB5QXhpcy5nZXRUaHJlc2hvbGQodGhyZXNob2xkKSxcblx0XHRcdG1pblBvaW50TGVuZ3RoID0gcGljayhvcHRpb25zLm1pblBvaW50TGVuZ3RoLCA1KSxcblx0XHRcdG1ldHJpY3MgPSBzZXJpZXMuZ2V0Q29sdW1uTWV0cmljcygpLFxuXHRcdFx0cG9pbnRXaWR0aCA9IG1ldHJpY3Mud2lkdGgsXG5cdFx0XHRzZXJpZXNCYXJXID0gc2VyaWVzLmJhclcgPSBtYXRoTWF4KHBvaW50V2lkdGgsIDEgKyAyICogYm9yZGVyV2lkdGgpLCAvLyBwb3N0cHJvY2Vzc2VkIGZvciBib3JkZXIgd2lkdGhcblx0XHRcdHBvaW50WE9mZnNldCA9IHNlcmllcy5wb2ludFhPZmZzZXQgPSBtZXRyaWNzLm9mZnNldCxcblx0XHRcdHhDcmlzcCA9IC0oYm9yZGVyV2lkdGggJSAyID8gMC41IDogMCksXG5cdFx0XHR5Q3Jpc3AgPSBib3JkZXJXaWR0aCAlIDIgPyAwLjUgOiAxO1xuXG5cdFx0aWYgKGNoYXJ0LnJlbmRlcmVyLmlzVk1MICYmIGNoYXJ0LmludmVydGVkKSB7XG5cdFx0XHR5Q3Jpc3AgKz0gMTtcblx0XHR9XG5cblx0XHQvLyBXaGVuIHRoZSBwb2ludFBhZGRpbmcgaXMgMCwgd2Ugd2FudCB0aGUgY29sdW1ucyB0byBiZSBwYWNrZWQgdGlnaHRseSwgc28gd2UgYWxsb3cgaW5kaXZpZHVhbFxuXHRcdC8vIGNvbHVtbnMgdG8gaGF2ZSBpbmRpdmlkdWFsIHNpemVzLiBXaGVuIHBvaW50UGFkZGluZyBpcyBncmVhdGVyLCB3ZSBzdHJpdmUgZm9yIGVxdWFsLXdpZHRoXG5cdFx0Ly8gY29sdW1ucyAoIzI2OTQpLlxuXHRcdGlmIChvcHRpb25zLnBvaW50UGFkZGluZykge1xuXHRcdFx0c2VyaWVzQmFyVyA9IG1hdGhDZWlsKHNlcmllc0JhclcpO1xuXHRcdH1cblxuXHRcdFNlcmllcy5wcm90b3R5cGUudHJhbnNsYXRlLmFwcGx5KHNlcmllcyk7XG5cblx0XHQvLyBSZWNvcmQgdGhlIG5ldyB2YWx1ZXNcblx0XHRlYWNoKHNlcmllcy5wb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0dmFyIHlCb3R0b20gPSBwaWNrKHBvaW50LnlCb3R0b20sIHRyYW5zbGF0ZWRUaHJlc2hvbGQpLFxuXHRcdFx0XHRwbG90WSA9IG1hdGhNaW4obWF0aE1heCgtOTk5IC0geUJvdHRvbSwgcG9pbnQucGxvdFkpLCB5QXhpcy5sZW4gKyA5OTkgKyB5Qm90dG9tKSwgLy8gRG9uJ3QgZHJhdyB0b28gZmFyIG91dHNpZGUgcGxvdCBhcmVhICgjMTMwMywgIzIyNDEpXG5cdFx0XHRcdGJhclggPSBwb2ludC5wbG90WCArIHBvaW50WE9mZnNldCxcblx0XHRcdFx0YmFyVyA9IHNlcmllc0JhclcsXG5cdFx0XHRcdGJhclkgPSBtYXRoTWluKHBsb3RZLCB5Qm90dG9tKSxcblx0XHRcdFx0cmlnaHQsXG5cdFx0XHRcdGJvdHRvbSxcblx0XHRcdFx0ZnJvbVRvcCxcblx0XHRcdFx0YmFySCA9IG1hdGhNYXgocGxvdFksIHlCb3R0b20pIC0gYmFyWTtcblxuXHRcdFx0Ly8gSGFuZGxlIG9wdGlvbnMubWluUG9pbnRMZW5ndGhcblx0XHRcdGlmIChtYXRoQWJzKGJhckgpIDwgbWluUG9pbnRMZW5ndGgpIHtcblx0XHRcdFx0aWYgKG1pblBvaW50TGVuZ3RoKSB7XG5cdFx0XHRcdFx0YmFySCA9IG1pblBvaW50TGVuZ3RoO1xuXHRcdFx0XHRcdGJhclkgPVxuXHRcdFx0XHRcdFx0bWF0aFJvdW5kKG1hdGhBYnMoYmFyWSAtIHRyYW5zbGF0ZWRUaHJlc2hvbGQpID4gbWluUG9pbnRMZW5ndGggPyAvLyBzdGFja2VkXG5cdFx0XHRcdFx0XHRcdHlCb3R0b20gLSBtaW5Qb2ludExlbmd0aCA6IC8vIGtlZXAgcG9zaXRpb25cblx0XHRcdFx0XHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZCAtICh5QXhpcy50cmFuc2xhdGUocG9pbnQueSwgMCwgMSwgMCwgMSkgPD0gdHJhbnNsYXRlZFRocmVzaG9sZCA/IG1pblBvaW50TGVuZ3RoIDogMCkpOyAvLyB1c2UgZXhhY3QgeUF4aXMudHJhbnNsYXRpb24gKCMxNDg1KVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhY2hlIGZvciBhY2Nlc3MgaW4gcG9sYXJcblx0XHRcdHBvaW50LmJhclggPSBiYXJYO1xuXHRcdFx0cG9pbnQucG9pbnRXaWR0aCA9IHBvaW50V2lkdGg7XG5cblx0XHRcdC8vIEZpeCB0aGUgdG9vbHRpcCBvbiBjZW50ZXIgb2YgZ3JvdXBlZCBjb2x1bW5zICgjMTIxNiwgIzQyNClcblx0XHRcdHBvaW50LnRvb2x0aXBQb3MgPSBjaGFydC5pbnZlcnRlZCA/IFxuXHRcdFx0XHRbeUF4aXMubGVuIC0gcGxvdFksIHNlcmllcy54QXhpcy5sZW4gLSBiYXJYIC0gYmFyVyAvIDJdIDogXG5cdFx0XHRcdFtiYXJYICsgYmFyVyAvIDIsIHBsb3RZICsgeUF4aXMucG9zIC0gY2hhcnQucGxvdFRvcF07XG5cblx0XHRcdC8vIFJvdW5kIG9mZiB0byBvYnRhaW4gY3Jpc3AgZWRnZXMgYW5kIGF2b2lkIG92ZXJsYXBwaW5nIHdpdGggbmVpZ2hib3VycyAoIzI2OTQpXG5cdFx0XHRyaWdodCA9IG1hdGhSb3VuZChiYXJYICsgYmFyVykgKyB4Q3Jpc3A7XG5cdFx0XHRiYXJYID0gbWF0aFJvdW5kKGJhclgpICsgeENyaXNwO1xuXHRcdFx0YmFyVyA9IHJpZ2h0IC0gYmFyWDtcblxuXHRcdFx0ZnJvbVRvcCA9IG1hdGhBYnMoYmFyWSkgPCAwLjU7XG5cdFx0XHRib3R0b20gPSBtYXRoUm91bmQoYmFyWSArIGJhckgpICsgeUNyaXNwO1xuXHRcdFx0YmFyWSA9IG1hdGhSb3VuZChiYXJZKSArIHlDcmlzcDtcblx0XHRcdGJhckggPSBib3R0b20gLSBiYXJZO1xuXG5cdFx0XHQvLyBUb3AgZWRnZXMgYXJlIGV4Y2VwdGlvbnNcblx0XHRcdGlmIChmcm9tVG9wKSB7XG5cdFx0XHRcdGJhclkgLT0gMTtcblx0XHRcdFx0YmFySCArPSAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWdpc3RlciBzaGFwZSB0eXBlIGFuZCBhcmd1bWVudHMgdG8gYmUgdXNlZCBpbiBkcmF3UG9pbnRzXG5cdFx0XHRwb2ludC5zaGFwZVR5cGUgPSAncmVjdCc7XG5cdFx0XHRwb2ludC5zaGFwZUFyZ3MgPSB7XG5cdFx0XHRcdHg6IGJhclgsXG5cdFx0XHRcdHk6IGJhclksXG5cdFx0XHRcdHdpZHRoOiBiYXJXLFxuXHRcdFx0XHRoZWlnaHQ6IGJhckhcblx0XHRcdH07XG5cblx0XHR9KTtcblxuXHR9LFxuXG5cdGdldFN5bWJvbDogbm9vcCxcblx0XG5cdC8qKlxuXHQgKiBVc2UgYSBzb2xpZCByZWN0YW5nbGUgbGlrZSB0aGUgYXJlYSBzZXJpZXMgdHlwZXNcblx0ICovXG5cdGRyYXdMZWdlbmRTeW1ib2w6IExlZ2VuZFN5bWJvbE1peGluLmRyYXdSZWN0YW5nbGUsXG5cdFxuXHRcblx0LyoqXG5cdCAqIENvbHVtbnMgaGF2ZSBubyBncmFwaFxuXHQgKi9cblx0ZHJhd0dyYXBoOiBub29wLFxuXG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBjb2x1bW5zLiBGb3IgYmFycywgdGhlIHNlcmllcy5ncm91cCBpcyByb3RhdGVkLCBzbyB0aGUgc2FtZSBjb29yZGluYXRlc1xuXHQgKiBhcHBseSBmb3IgY29sdW1ucyBhbmQgYmFycy4gVGhpcyBtZXRob2QgaXMgaW5oZXJpdGVkIGJ5IHNjYXR0ZXIgc2VyaWVzLlxuXHQgKlxuXHQgKi9cblx0ZHJhd1BvaW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdGFuaW1hdGlvbkxpbWl0ID0gb3B0aW9ucy5hbmltYXRpb25MaW1pdCB8fCAyNTAsXG5cdFx0XHRzaGFwZUFyZ3MsXG5cdFx0XHRwb2ludEF0dHI7XG5cblx0XHQvLyBkcmF3IHRoZSBjb2x1bW5zXG5cdFx0ZWFjaChzZXJpZXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdHZhciBwbG90WSA9IHBvaW50LnBsb3RZLFxuXHRcdFx0XHRncmFwaGljID0gcG9pbnQuZ3JhcGhpYyxcblx0XHRcdFx0Ym9yZGVyQXR0cjtcblxuXHRcdFx0aWYgKHBsb3RZICE9PSBVTkRFRklORUQgJiYgIWlzTmFOKHBsb3RZKSAmJiBwb2ludC55ICE9PSBudWxsKSB7XG5cdFx0XHRcdHNoYXBlQXJncyA9IHBvaW50LnNoYXBlQXJncztcblxuXHRcdFx0XHRib3JkZXJBdHRyID0gZGVmaW5lZChzZXJpZXMuYm9yZGVyV2lkdGgpID8ge1xuXHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBzZXJpZXMuYm9yZGVyV2lkdGhcblx0XHRcdFx0fSA6IHt9O1xuXG5cdFx0XHRcdHBvaW50QXR0ciA9IHBvaW50LnBvaW50QXR0cltwb2ludC5zZWxlY3RlZCA/IFNFTEVDVF9TVEFURSA6IE5PUk1BTF9TVEFURV0gfHwgc2VyaWVzLnBvaW50QXR0cltOT1JNQUxfU1RBVEVdO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKGdyYXBoaWMpIHsgLy8gdXBkYXRlXG5cdFx0XHRcdFx0c3RvcChncmFwaGljKTtcblx0XHRcdFx0XHRncmFwaGljLmF0dHIoYm9yZGVyQXR0cilbY2hhcnQucG9pbnRDb3VudCA8IGFuaW1hdGlvbkxpbWl0ID8gJ2FuaW1hdGUnIDogJ2F0dHInXShtZXJnZShzaGFwZUFyZ3MpKTtcblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHBvaW50LmdyYXBoaWMgPSBncmFwaGljID0gcmVuZGVyZXJbcG9pbnQuc2hhcGVUeXBlXShzaGFwZUFyZ3MpXG5cdFx0XHRcdFx0XHQuYXR0cihwb2ludEF0dHIpXG5cdFx0XHRcdFx0XHQuYXR0cihib3JkZXJBdHRyKVxuXHRcdFx0XHRcdFx0LmFkZChzZXJpZXMuZ3JvdXApXG5cdFx0XHRcdFx0XHQuc2hhZG93KG9wdGlvbnMuc2hhZG93LCBudWxsLCBvcHRpb25zLnN0YWNraW5nICYmICFvcHRpb25zLmJvcmRlclJhZGl1cyk7XG5cdFx0XHRcdH1cblxuXHRcdFx0fSBlbHNlIGlmIChncmFwaGljKSB7XG5cdFx0XHRcdHBvaW50LmdyYXBoaWMgPSBncmFwaGljLmRlc3Ryb3koKTsgLy8gIzEyNjlcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogQW5pbWF0ZSB0aGUgY29sdW1uIGhlaWdodHMgb25lIGJ5IG9uZSBmcm9tIHplcm9cblx0ICogQHBhcmFtIHtCb29sZWFufSBpbml0IFdoZXRoZXIgdG8gaW5pdGlhbGl6ZSB0aGUgYW5pbWF0aW9uIG9yIHJ1biBpdFxuXHQgKi9cblx0YW5pbWF0ZTogZnVuY3Rpb24gKGluaXQpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdHlBeGlzID0gdGhpcy55QXhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGludmVydGVkID0gdGhpcy5jaGFydC5pbnZlcnRlZCxcblx0XHRcdGF0dHIgPSB7fSxcblx0XHRcdHRyYW5zbGF0ZWRUaHJlc2hvbGQ7XG5cblx0XHRpZiAoaGFzU1ZHKSB7IC8vIFZNTCBpcyB0b28gc2xvdyBhbnl3YXlcblx0XHRcdGlmIChpbml0KSB7XG5cdFx0XHRcdGF0dHIuc2NhbGVZID0gMC4wMDE7XG5cdFx0XHRcdHRyYW5zbGF0ZWRUaHJlc2hvbGQgPSBtYXRoTWluKHlBeGlzLnBvcyArIHlBeGlzLmxlbiwgbWF0aE1heCh5QXhpcy5wb3MsIHlBeGlzLnRvUGl4ZWxzKG9wdGlvbnMudGhyZXNob2xkKSkpO1xuXHRcdFx0XHRpZiAoaW52ZXJ0ZWQpIHtcblx0XHRcdFx0XHRhdHRyLnRyYW5zbGF0ZVggPSB0cmFuc2xhdGVkVGhyZXNob2xkIC0geUF4aXMubGVuO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGF0dHIudHJhbnNsYXRlWSA9IHRyYW5zbGF0ZWRUaHJlc2hvbGQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2VyaWVzLmdyb3VwLmF0dHIoYXR0cik7XG5cblx0XHRcdH0gZWxzZSB7IC8vIHJ1biB0aGUgYW5pbWF0aW9uXG5cdFx0XHRcdFxuXHRcdFx0XHRhdHRyLnNjYWxlWSA9IDE7XG5cdFx0XHRcdGF0dHJbaW52ZXJ0ZWQgPyAndHJhbnNsYXRlWCcgOiAndHJhbnNsYXRlWSddID0geUF4aXMucG9zO1xuXHRcdFx0XHRzZXJpZXMuZ3JvdXAuYW5pbWF0ZShhdHRyLCBzZXJpZXMub3B0aW9ucy5hbmltYXRpb24pO1xuXG5cdFx0XHRcdC8vIGRlbGV0ZSB0aGlzIGZ1bmN0aW9uIHRvIGFsbG93IGl0IG9ubHkgb25jZVxuXHRcdFx0XHRzZXJpZXMuYW5pbWF0ZSA9IG51bGw7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG5cdCAqIFJlbW92ZSB0aGlzIHNlcmllcyBmcm9tIHRoZSBjaGFydFxuXHQgKi9cblx0cmVtb3ZlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydDtcblxuXHRcdC8vIGNvbHVtbiBhbmQgYmFyIHNlcmllcyBhZmZlY3RzIG90aGVyIHNlcmllcyBvZiB0aGUgc2FtZSB0eXBlXG5cdFx0Ly8gYXMgdGhleSBhcmUgZWl0aGVyIHN0YWNrZWQgb3IgZ3JvdXBlZFxuXHRcdGlmIChjaGFydC5oYXNSZW5kZXJlZCkge1xuXHRcdFx0ZWFjaChjaGFydC5zZXJpZXMsIGZ1bmN0aW9uIChvdGhlclNlcmllcykge1xuXHRcdFx0XHRpZiAob3RoZXJTZXJpZXMudHlwZSA9PT0gc2VyaWVzLnR5cGUpIHtcblx0XHRcdFx0XHRvdGhlclNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0U2VyaWVzLnByb3RvdHlwZS5yZW1vdmUuYXBwbHkoc2VyaWVzLCBhcmd1bWVudHMpO1xuXHR9XG59KTtcbnNlcmllc1R5cGVzLmNvbHVtbiA9IENvbHVtblNlcmllcztcbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIGJhclxuICovXG5kZWZhdWx0UGxvdE9wdGlvbnMuYmFyID0gbWVyZ2UoZGVmYXVsdFBsb3RPcHRpb25zLmNvbHVtbik7XG4vKipcbiAqIFRoZSBCYXIgc2VyaWVzIGNsYXNzXG4gKi9cbnZhciBCYXJTZXJpZXMgPSBleHRlbmRDbGFzcyhDb2x1bW5TZXJpZXMsIHtcblx0dHlwZTogJ2JhcicsXG5cdGludmVydGVkOiB0cnVlXG59KTtcbnNlcmllc1R5cGVzLmJhciA9IEJhclNlcmllcztcblxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBmb3Igc2NhdHRlclxuICovXG5kZWZhdWx0UGxvdE9wdGlvbnMuc2NhdHRlciA9IG1lcmdlKGRlZmF1bHRTZXJpZXNPcHRpb25zLCB7XG5cdGxpbmVXaWR0aDogMCxcblx0dG9vbHRpcDoge1xuXHRcdGhlYWRlckZvcm1hdDogJzxzcGFuIHN0eWxlPVwiY29sb3I6e3Nlcmllcy5jb2xvcn1cIj5cXHUyNUNGPC9zcGFuPiA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZTogMTBweDtcIj4ge3Nlcmllcy5uYW1lfTwvc3Bhbj48YnIvPicsXG5cdFx0cG9pbnRGb3JtYXQ6ICd4OiA8Yj57cG9pbnQueH08L2I+PGJyLz55OiA8Yj57cG9pbnQueX08L2I+PGJyLz4nXG5cdH0sXG5cdHN0aWNreVRyYWNraW5nOiBmYWxzZVxufSk7XG5cbi8qKlxuICogVGhlIHNjYXR0ZXIgc2VyaWVzIGNsYXNzXG4gKi9cbnZhciBTY2F0dGVyU2VyaWVzID0gZXh0ZW5kQ2xhc3MoU2VyaWVzLCB7XG5cdHR5cGU6ICdzY2F0dGVyJyxcblx0c29ydGVkOiBmYWxzZSxcblx0cmVxdWlyZVNvcnRpbmc6IGZhbHNlLFxuXHRub1NoYXJlZFRvb2x0aXA6IHRydWUsXG5cdHRyYWNrZXJHcm91cHM6IFsnbWFya2VyR3JvdXAnLCAnZGF0YUxhYmVsc0dyb3VwJ10sXG5cdHRha2VPcmRpbmFsUG9zaXRpb246IGZhbHNlLCAvLyAjMjM0MlxuXHRzaW5ndWxhclRvb2x0aXBzOiB0cnVlLFxuXHRkcmF3R3JhcGg6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAodGhpcy5vcHRpb25zLmxpbmVXaWR0aCkge1xuXHRcdFx0U2VyaWVzLnByb3RvdHlwZS5kcmF3R3JhcGguY2FsbCh0aGlzKTtcblx0XHR9XG5cdH1cbn0pO1xuXG5zZXJpZXNUeXBlcy5zY2F0dGVyID0gU2NhdHRlclNlcmllcztcblxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBmb3IgcGllXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5waWUgPSBtZXJnZShkZWZhdWx0U2VyaWVzT3B0aW9ucywge1xuXHRib3JkZXJDb2xvcjogJyNGRkZGRkYnLFxuXHRib3JkZXJXaWR0aDogMSxcblx0Y2VudGVyOiBbbnVsbCwgbnVsbF0sXG5cdGNsaXA6IGZhbHNlLFxuXHRjb2xvckJ5UG9pbnQ6IHRydWUsIC8vIGFsd2F5cyB0cnVlIGZvciBwaWVzXG5cdGRhdGFMYWJlbHM6IHtcblx0XHQvLyBhbGlnbjogbnVsbCxcblx0XHQvLyBjb25uZWN0b3JXaWR0aDogMSxcblx0XHQvLyBjb25uZWN0b3JDb2xvcjogcG9pbnQuY29sb3IsXG5cdFx0Ly8gY29ubmVjdG9yUGFkZGluZzogNSxcblx0XHRkaXN0YW5jZTogMzAsXG5cdFx0ZW5hYmxlZDogdHJ1ZSxcblx0XHRmb3JtYXR0ZXI6IGZ1bmN0aW9uICgpIHsgLy8gIzI5NDVcblx0XHRcdHJldHVybiB0aGlzLnBvaW50Lm5hbWU7XG5cdFx0fVxuXHRcdC8vIHNvZnRDb25uZWN0b3I6IHRydWUsXG5cdFx0Ly95OiAwXG5cdH0sXG5cdGlnbm9yZUhpZGRlblBvaW50OiB0cnVlLFxuXHQvL2lubmVyU2l6ZTogMCxcblx0bGVnZW5kVHlwZTogJ3BvaW50Jyxcblx0bWFya2VyOiBudWxsLCAvLyBwb2ludCBvcHRpb25zIGFyZSBzcGVjaWZpZWQgaW4gdGhlIGJhc2Ugb3B0aW9uc1xuXHRzaXplOiBudWxsLFxuXHRzaG93SW5MZWdlbmQ6IGZhbHNlLFxuXHRzbGljZWRPZmZzZXQ6IDEwLFxuXHRzdGF0ZXM6IHtcblx0XHRob3Zlcjoge1xuXHRcdFx0YnJpZ2h0bmVzczogMC4xLFxuXHRcdFx0c2hhZG93OiBmYWxzZVxuXHRcdH1cblx0fSxcblx0c3RpY2t5VHJhY2tpbmc6IGZhbHNlLFxuXHR0b29sdGlwOiB7XG5cdFx0Zm9sbG93UG9pbnRlcjogdHJ1ZVxuXHR9XG59KTtcblxuLyoqXG4gKiBFeHRlbmRlZCBwb2ludCBvYmplY3QgZm9yIHBpZXNcbiAqL1xudmFyIFBpZVBvaW50ID0gZXh0ZW5kQ2xhc3MoUG9pbnQsIHtcblx0LyoqXG5cdCAqIEluaXRpYXRlIHRoZSBwaWUgc2xpY2Vcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFBvaW50LnByb3RvdHlwZS5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0dG9nZ2xlU2xpY2U7XG5cblx0XHQvLyBEaXNhbGxvdyBuZWdhdGl2ZSB2YWx1ZXMgKCMxNTMwKVxuXHRcdGlmIChwb2ludC55IDwgMCkge1xuXHRcdFx0cG9pbnQueSA9IG51bGw7XG5cdFx0fVxuXG5cdFx0Ly92aXNpYmxlOiBvcHRpb25zLnZpc2libGUgIT09IGZhbHNlLFxuXHRcdGV4dGVuZChwb2ludCwge1xuXHRcdFx0dmlzaWJsZTogcG9pbnQudmlzaWJsZSAhPT0gZmFsc2UsXG5cdFx0XHRuYW1lOiBwaWNrKHBvaW50Lm5hbWUsICdTbGljZScpXG5cdFx0fSk7XG5cblx0XHQvLyBhZGQgZXZlbnQgbGlzdGVuZXIgZm9yIHNlbGVjdFxuXHRcdHRvZ2dsZVNsaWNlID0gZnVuY3Rpb24gKGUpIHtcblx0XHRcdHBvaW50LnNsaWNlKGUudHlwZSA9PT0gJ3NlbGVjdCcpO1xuXHRcdH07XG5cdFx0YWRkRXZlbnQocG9pbnQsICdzZWxlY3QnLCB0b2dnbGVTbGljZSk7XG5cdFx0YWRkRXZlbnQocG9pbnQsICd1bnNlbGVjdCcsIHRvZ2dsZVNsaWNlKTtcblxuXHRcdHJldHVybiBwb2ludDtcblx0fSxcblxuXHQvKipcblx0ICogVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBwaWUgc2xpY2Vcblx0ICogQHBhcmFtIHtCb29sZWFufSB2aXMgV2hldGhlciB0byBzaG93IHRoZSBzbGljZSBvciBub3QuIElmIHVuZGVmaW5lZCwgdGhlXG5cdCAqICAgIHZpc2liaWxpdHkgaXMgdG9nZ2xlZFxuXHQgKi9cblx0c2V0VmlzaWJsZTogZnVuY3Rpb24gKHZpcykge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydDtcblxuXHRcdC8vIGlmIGNhbGxlZCB3aXRob3V0IGFuIGFyZ3VtZW50LCB0b2dnbGUgdmlzaWJpbGl0eVxuXHRcdHBvaW50LnZpc2libGUgPSBwb2ludC5vcHRpb25zLnZpc2libGUgPSB2aXMgPSB2aXMgPT09IFVOREVGSU5FRCA/ICFwb2ludC52aXNpYmxlIDogdmlzO1xuXHRcdHNlcmllcy5vcHRpb25zLmRhdGFbaW5BcnJheShwb2ludCwgc2VyaWVzLmRhdGEpXSA9IHBvaW50Lm9wdGlvbnM7IC8vIHVwZGF0ZSB1c2VyT3B0aW9ucy5kYXRhXG5cblx0XHQvLyBTaG93IGFuZCBoaWRlIGFzc29jaWF0ZWQgZWxlbWVudHNcblx0XHRlYWNoKFsnZ3JhcGhpYycsICdkYXRhTGFiZWwnLCAnY29ubmVjdG9yJywgJ3NoYWRvd0dyb3VwJ10sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmIChwb2ludFtrZXldKSB7XG5cdFx0XHRcdHBvaW50W2tleV1bdmlzID8gJ3Nob3cnIDogJ2hpZGUnXSh0cnVlKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGlmIChwb2ludC5sZWdlbmRJdGVtKSB7XG5cdFx0XHRjaGFydC5sZWdlbmQuY29sb3JpemVJdGVtKHBvaW50LCB2aXMpO1xuXHRcdH1cblx0XHRcblx0XHQvLyBIYW5kbGUgaWdub3JlIGhpZGRlbiBzbGljZXNcblx0XHRpZiAoIXNlcmllcy5pc0RpcnR5ICYmIHNlcmllcy5vcHRpb25zLmlnbm9yZUhpZGRlblBvaW50KSB7XG5cdFx0XHRzZXJpZXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRjaGFydC5yZWRyYXcoKTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCBvciB0b2dnbGUgd2hldGhlciB0aGUgc2xpY2UgaXMgY3V0IG91dCBmcm9tIHRoZSBwaWVcblx0ICogQHBhcmFtIHtCb29sZWFufSBzbGljZWQgV2hlbiB1bmRlZmluZWQsIHRoZSBzbGljZSBzdGF0ZSBpcyB0b2dnbGVkXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVkcmF3IFdoZXRoZXIgdG8gcmVkcmF3IHRoZSBjaGFydC4gVHJ1ZSBieSBkZWZhdWx0LlxuXHQgKi9cblx0c2xpY2U6IGZ1bmN0aW9uIChzbGljZWQsIHJlZHJhdywgYW5pbWF0aW9uKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0dHJhbnNsYXRpb247XG5cblx0XHRzZXRBbmltYXRpb24oYW5pbWF0aW9uLCBjaGFydCk7XG5cblx0XHQvLyByZWRyYXcgaXMgdHJ1ZSBieSBkZWZhdWx0XG5cdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpO1xuXG5cdFx0Ly8gaWYgY2FsbGVkIHdpdGhvdXQgYW4gYXJndW1lbnQsIHRvZ2dsZVxuXHRcdHBvaW50LnNsaWNlZCA9IHBvaW50Lm9wdGlvbnMuc2xpY2VkID0gc2xpY2VkID0gZGVmaW5lZChzbGljZWQpID8gc2xpY2VkIDogIXBvaW50LnNsaWNlZDtcblx0XHRzZXJpZXMub3B0aW9ucy5kYXRhW2luQXJyYXkocG9pbnQsIHNlcmllcy5kYXRhKV0gPSBwb2ludC5vcHRpb25zOyAvLyB1cGRhdGUgdXNlck9wdGlvbnMuZGF0YVxuXG5cdFx0dHJhbnNsYXRpb24gPSBzbGljZWQgPyBwb2ludC5zbGljZWRUcmFuc2xhdGlvbiA6IHtcblx0XHRcdHRyYW5zbGF0ZVg6IDAsXG5cdFx0XHR0cmFuc2xhdGVZOiAwXG5cdFx0fTtcblxuXHRcdHBvaW50LmdyYXBoaWMuYW5pbWF0ZSh0cmFuc2xhdGlvbik7XG5cdFx0XG5cdFx0aWYgKHBvaW50LnNoYWRvd0dyb3VwKSB7XG5cdFx0XHRwb2ludC5zaGFkb3dHcm91cC5hbmltYXRlKHRyYW5zbGF0aW9uKTtcblx0XHR9XG5cblx0fSxcblxuXHRoYWxvUGF0aDogZnVuY3Rpb24gKHNpemUpIHtcblx0XHR2YXIgc2hhcGVBcmdzID0gdGhpcy5zaGFwZUFyZ3MsXG5cdFx0XHRjaGFydCA9IHRoaXMuc2VyaWVzLmNoYXJ0O1xuXG5cdFx0cmV0dXJuIHRoaXMuc2xpY2VkIHx8ICF0aGlzLnZpc2libGUgPyBbXSA6IHRoaXMuc2VyaWVzLmNoYXJ0LnJlbmRlcmVyLnN5bWJvbHMuYXJjKGNoYXJ0LnBsb3RMZWZ0ICsgc2hhcGVBcmdzLngsIGNoYXJ0LnBsb3RUb3AgKyBzaGFwZUFyZ3MueSwgc2hhcGVBcmdzLnIgKyBzaXplLCBzaGFwZUFyZ3MuciArIHNpemUsIHtcblx0XHRcdGlubmVyUjogdGhpcy5zaGFwZUFyZ3Mucixcblx0XHRcdHN0YXJ0OiBzaGFwZUFyZ3Muc3RhcnQsXG5cdFx0XHRlbmQ6IHNoYXBlQXJncy5lbmRcblx0XHR9KTtcblx0fVxufSk7XG5cbi8qKlxuICogVGhlIFBpZSBzZXJpZXMgY2xhc3NcbiAqL1xudmFyIFBpZVNlcmllcyA9IHtcblx0dHlwZTogJ3BpZScsXG5cdGlzQ2FydGVzaWFuOiBmYWxzZSxcblx0cG9pbnRDbGFzczogUGllUG9pbnQsXG5cdHJlcXVpcmVTb3J0aW5nOiBmYWxzZSxcblx0bm9TaGFyZWRUb29sdGlwOiB0cnVlLFxuXHR0cmFja2VyR3JvdXBzOiBbJ2dyb3VwJywgJ2RhdGFMYWJlbHNHcm91cCddLFxuXHRheGlzVHlwZXM6IFtdLFxuXHRwb2ludEF0dHJUb09wdGlvbnM6IHsgLy8gbWFwcGluZyBiZXR3ZWVuIFNWRyBhdHRyaWJ1dGVzIGFuZCB0aGUgY29ycmVzcG9uZGluZyBvcHRpb25zXG5cdFx0c3Ryb2tlOiAnYm9yZGVyQ29sb3InLFxuXHRcdCdzdHJva2Utd2lkdGgnOiAnYm9yZGVyV2lkdGgnLFxuXHRcdGZpbGw6ICdjb2xvcidcblx0fSxcblx0c2luZ3VsYXJUb29sdGlwczogdHJ1ZSxcblxuXHQvKipcblx0ICogUGllcyBoYXZlIG9uZSBjb2xvciBlYWNoIHBvaW50XG5cdCAqL1xuXHRnZXRDb2xvcjogbm9vcCxcblxuXHQvKipcblx0ICogQW5pbWF0ZSB0aGUgcGllcyBpblxuXHQgKi9cblx0YW5pbWF0ZTogZnVuY3Rpb24gKGluaXQpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdHBvaW50cyA9IHNlcmllcy5wb2ludHMsXG5cdFx0XHRzdGFydEFuZ2xlUmFkID0gc2VyaWVzLnN0YXJ0QW5nbGVSYWQ7XG5cblx0XHRpZiAoIWluaXQpIHtcblx0XHRcdGVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0dmFyIGdyYXBoaWMgPSBwb2ludC5ncmFwaGljLFxuXHRcdFx0XHRcdGFyZ3MgPSBwb2ludC5zaGFwZUFyZ3M7XG5cblx0XHRcdFx0aWYgKGdyYXBoaWMpIHtcblx0XHRcdFx0XHQvLyBzdGFydCB2YWx1ZXNcblx0XHRcdFx0XHRncmFwaGljLmF0dHIoe1xuXHRcdFx0XHRcdFx0cjogc2VyaWVzLmNlbnRlclszXSAvIDIsIC8vIGFuaW1hdGUgZnJvbSBpbm5lciByYWRpdXMgKCM3NzkpXG5cdFx0XHRcdFx0XHRzdGFydDogc3RhcnRBbmdsZVJhZCxcblx0XHRcdFx0XHRcdGVuZDogc3RhcnRBbmdsZVJhZFxuXHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0Ly8gYW5pbWF0ZVxuXHRcdFx0XHRcdGdyYXBoaWMuYW5pbWF0ZSh7XG5cdFx0XHRcdFx0XHRyOiBhcmdzLnIsXG5cdFx0XHRcdFx0XHRzdGFydDogYXJncy5zdGFydCxcblx0XHRcdFx0XHRcdGVuZDogYXJncy5lbmRcblx0XHRcdFx0XHR9LCBzZXJpZXMub3B0aW9ucy5hbmltYXRpb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gZGVsZXRlIHRoaXMgZnVuY3Rpb24gdG8gYWxsb3cgaXQgb25seSBvbmNlXG5cdFx0XHRzZXJpZXMuYW5pbWF0ZSA9IG51bGw7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBFeHRlbmQgdGhlIGJhc2ljIHNldERhdGEgbWV0aG9kIGJ5IHJ1bm5pbmcgcHJvY2Vzc0RhdGEgYW5kIGdlbmVyYXRlUG9pbnRzIGltbWVkaWF0ZWx5LFxuXHQgKiBpbiBvcmRlciB0byBhY2Nlc3MgdGhlIHBvaW50cyBmcm9tIHRoZSBsZWdlbmQuXG5cdCAqL1xuXHRzZXREYXRhOiBmdW5jdGlvbiAoZGF0YSwgcmVkcmF3LCBhbmltYXRpb24sIHVwZGF0ZVBvaW50cykge1xuXHRcdFNlcmllcy5wcm90b3R5cGUuc2V0RGF0YS5jYWxsKHRoaXMsIGRhdGEsIGZhbHNlLCBhbmltYXRpb24sIHVwZGF0ZVBvaW50cyk7XG5cdFx0dGhpcy5wcm9jZXNzRGF0YSgpO1xuXHRcdHRoaXMuZ2VuZXJhdGVQb2ludHMoKTtcblx0XHRpZiAocGljayhyZWRyYXcsIHRydWUpKSB7XG5cdFx0XHR0aGlzLmNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdH0gXG5cdH0sXG5cblx0LyoqXG5cdCAqIEV4dGVuZCB0aGUgZ2VuZXJhdGVQb2ludHMgbWV0aG9kIGJ5IGFkZGluZyB0b3RhbCBhbmQgcGVyY2VudGFnZSBwcm9wZXJ0aWVzIHRvIGVhY2ggcG9pbnRcblx0ICovXG5cdGdlbmVyYXRlUG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGksXG5cdFx0XHR0b3RhbCA9IDAsXG5cdFx0XHRwb2ludHMsXG5cdFx0XHRsZW4sXG5cdFx0XHRwb2ludCxcblx0XHRcdGlnbm9yZUhpZGRlblBvaW50ID0gdGhpcy5vcHRpb25zLmlnbm9yZUhpZGRlblBvaW50O1xuXG5cdFx0U2VyaWVzLnByb3RvdHlwZS5nZW5lcmF0ZVBvaW50cy5jYWxsKHRoaXMpO1xuXG5cdFx0Ly8gUG9wdWxhdGUgbG9jYWwgdmFyc1xuXHRcdHBvaW50cyA9IHRoaXMucG9pbnRzO1xuXHRcdGxlbiA9IHBvaW50cy5sZW5ndGg7XG5cdFx0XG5cdFx0Ly8gR2V0IHRoZSB0b3RhbCBzdW1cblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdHBvaW50ID0gcG9pbnRzW2ldO1xuXHRcdFx0dG90YWwgKz0gKGlnbm9yZUhpZGRlblBvaW50ICYmICFwb2ludC52aXNpYmxlKSA/IDAgOiBwb2ludC55O1xuXHRcdH1cblx0XHR0aGlzLnRvdGFsID0gdG90YWw7XG5cblx0XHQvLyBTZXQgZWFjaCBwb2ludCdzIHByb3BlcnRpZXNcblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdHBvaW50ID0gcG9pbnRzW2ldO1xuXHRcdFx0cG9pbnQucGVyY2VudGFnZSA9IHRvdGFsID4gMCA/IChwb2ludC55IC8gdG90YWwpICogMTAwIDogMDtcblx0XHRcdHBvaW50LnRvdGFsID0gdG90YWw7XG5cdFx0fVxuXHRcdFxuXHR9LFxuXHRcblx0LyoqXG5cdCAqIERvIHRyYW5zbGF0aW9uIGZvciBwaWUgc2xpY2VzXG5cdCAqL1xuXHR0cmFuc2xhdGU6IGZ1bmN0aW9uIChwb3NpdGlvbnMpIHtcblx0XHR0aGlzLmdlbmVyYXRlUG9pbnRzKCk7XG5cdFx0XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjdW11bGF0aXZlID0gMCxcblx0XHRcdHByZWNpc2lvbiA9IDEwMDAsIC8vIGlzc3VlICMxNzJcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdHNsaWNlZE9mZnNldCA9IG9wdGlvbnMuc2xpY2VkT2Zmc2V0LFxuXHRcdFx0Y29ubmVjdG9yT2Zmc2V0ID0gc2xpY2VkT2Zmc2V0ICsgb3B0aW9ucy5ib3JkZXJXaWR0aCxcblx0XHRcdHN0YXJ0LFxuXHRcdFx0ZW5kLFxuXHRcdFx0YW5nbGUsXG5cdFx0XHRzdGFydEFuZ2xlID0gb3B0aW9ucy5zdGFydEFuZ2xlIHx8IDAsXG5cdFx0XHRzdGFydEFuZ2xlUmFkID0gc2VyaWVzLnN0YXJ0QW5nbGVSYWQgPSBtYXRoUEkgLyAxODAgKiAoc3RhcnRBbmdsZSAtIDkwKSxcblx0XHRcdGVuZEFuZ2xlUmFkID0gc2VyaWVzLmVuZEFuZ2xlUmFkID0gbWF0aFBJIC8gMTgwICogKChwaWNrKG9wdGlvbnMuZW5kQW5nbGUsIHN0YXJ0QW5nbGUgKyAzNjApKSAtIDkwKSxcblx0XHRcdGNpcmMgPSBlbmRBbmdsZVJhZCAtIHN0YXJ0QW5nbGVSYWQsIC8vMiAqIG1hdGhQSSxcblx0XHRcdHBvaW50cyA9IHNlcmllcy5wb2ludHMsXG5cdFx0XHRyYWRpdXNYLCAvLyB0aGUgeCBjb21wb25lbnQgb2YgdGhlIHJhZGl1cyB2ZWN0b3IgZm9yIGEgZ2l2ZW4gcG9pbnRcblx0XHRcdHJhZGl1c1ksXG5cdFx0XHRsYWJlbERpc3RhbmNlID0gb3B0aW9ucy5kYXRhTGFiZWxzLmRpc3RhbmNlLFxuXHRcdFx0aWdub3JlSGlkZGVuUG9pbnQgPSBvcHRpb25zLmlnbm9yZUhpZGRlblBvaW50LFxuXHRcdFx0aSxcblx0XHRcdGxlbiA9IHBvaW50cy5sZW5ndGgsXG5cdFx0XHRwb2ludDtcblxuXHRcdC8vIEdldCBwb3NpdGlvbnMgLSBlaXRoZXIgYW4gaW50ZWdlciBvciBhIHBlcmNlbnRhZ2Ugc3RyaW5nIG11c3QgYmUgZ2l2ZW4uXG5cdFx0Ly8gSWYgcG9zaXRpb25zIGFyZSBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIsIHdlJ3JlIGluIGEgcmVjdXJzaXZlIGxvb3AgZm9yIGFkanVzdGluZ1xuXHRcdC8vIHNwYWNlIGZvciBkYXRhIGxhYmVscy5cblx0XHRpZiAoIXBvc2l0aW9ucykge1xuXHRcdFx0c2VyaWVzLmNlbnRlciA9IHBvc2l0aW9ucyA9IHNlcmllcy5nZXRDZW50ZXIoKTtcblx0XHR9XG5cblx0XHQvLyB1dGlsaXR5IGZvciBnZXR0aW5nIHRoZSB4IHZhbHVlIGZyb20gYSBnaXZlbiB5LCB1c2VkIGZvciBhbnRpY29sbGlzaW9uIGxvZ2ljIGluIGRhdGEgbGFiZWxzXG5cdFx0c2VyaWVzLmdldFggPSBmdW5jdGlvbiAoeSwgbGVmdCkge1xuXG5cdFx0XHRhbmdsZSA9IG1hdGguYXNpbihtYXRoTWluKCh5IC0gcG9zaXRpb25zWzFdKSAvIChwb3NpdGlvbnNbMl0gLyAyICsgbGFiZWxEaXN0YW5jZSksIDEpKTtcblxuXHRcdFx0cmV0dXJuIHBvc2l0aW9uc1swXSArXG5cdFx0XHRcdChsZWZ0ID8gLTEgOiAxKSAqXG5cdFx0XHRcdChtYXRoQ29zKGFuZ2xlKSAqIChwb3NpdGlvbnNbMl0gLyAyICsgbGFiZWxEaXN0YW5jZSkpO1xuXHRcdH07XG5cblx0XHQvLyBDYWxjdWxhdGUgdGhlIGdlb21ldHJ5IGZvciBlYWNoIHBvaW50XG5cdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcblx0XHRcdHBvaW50ID0gcG9pbnRzW2ldO1xuXHRcdFx0XG5cdFx0XHQvLyBzZXQgc3RhcnQgYW5kIGVuZCBhbmdsZVxuXHRcdFx0c3RhcnQgPSBzdGFydEFuZ2xlUmFkICsgKGN1bXVsYXRpdmUgKiBjaXJjKTtcblx0XHRcdGlmICghaWdub3JlSGlkZGVuUG9pbnQgfHwgcG9pbnQudmlzaWJsZSkge1xuXHRcdFx0XHRjdW11bGF0aXZlICs9IHBvaW50LnBlcmNlbnRhZ2UgLyAxMDA7XG5cdFx0XHR9XG5cdFx0XHRlbmQgPSBzdGFydEFuZ2xlUmFkICsgKGN1bXVsYXRpdmUgKiBjaXJjKTtcblxuXHRcdFx0Ly8gc2V0IHRoZSBzaGFwZVxuXHRcdFx0cG9pbnQuc2hhcGVUeXBlID0gJ2FyYyc7XG5cdFx0XHRwb2ludC5zaGFwZUFyZ3MgPSB7XG5cdFx0XHRcdHg6IHBvc2l0aW9uc1swXSxcblx0XHRcdFx0eTogcG9zaXRpb25zWzFdLFxuXHRcdFx0XHRyOiBwb3NpdGlvbnNbMl0gLyAyLFxuXHRcdFx0XHRpbm5lclI6IHBvc2l0aW9uc1szXSAvIDIsXG5cdFx0XHRcdHN0YXJ0OiBtYXRoUm91bmQoc3RhcnQgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uLFxuXHRcdFx0XHRlbmQ6IG1hdGhSb3VuZChlbmQgKiBwcmVjaXNpb24pIC8gcHJlY2lzaW9uXG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBUaGUgYW5nbGUgbXVzdCBzdGF5IHdpdGhpbiAtOTAgYW5kIDI3MCAoIzI2NDUpXG5cdFx0XHRhbmdsZSA9IChlbmQgKyBzdGFydCkgLyAyO1xuXHRcdFx0aWYgKGFuZ2xlID4gMS41ICogbWF0aFBJKSB7XG5cdFx0XHRcdGFuZ2xlIC09IDIgKiBtYXRoUEk7XG5cdFx0XHR9IGVsc2UgaWYgKGFuZ2xlIDwgLW1hdGhQSSAvIDIpIHtcblx0XHRcdFx0YW5nbGUgKz0gMiAqIG1hdGhQSTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2VudGVyIGZvciB0aGUgc2xpY2VkIG91dCBzbGljZVxuXHRcdFx0cG9pbnQuc2xpY2VkVHJhbnNsYXRpb24gPSB7XG5cdFx0XHRcdHRyYW5zbGF0ZVg6IG1hdGhSb3VuZChtYXRoQ29zKGFuZ2xlKSAqIHNsaWNlZE9mZnNldCksXG5cdFx0XHRcdHRyYW5zbGF0ZVk6IG1hdGhSb3VuZChtYXRoU2luKGFuZ2xlKSAqIHNsaWNlZE9mZnNldClcblx0XHRcdH07XG5cblx0XHRcdC8vIHNldCB0aGUgYW5jaG9yIHBvaW50IGZvciB0b29sdGlwc1xuXHRcdFx0cmFkaXVzWCA9IG1hdGhDb3MoYW5nbGUpICogcG9zaXRpb25zWzJdIC8gMjtcblx0XHRcdHJhZGl1c1kgPSBtYXRoU2luKGFuZ2xlKSAqIHBvc2l0aW9uc1syXSAvIDI7XG5cdFx0XHRwb2ludC50b29sdGlwUG9zID0gW1xuXHRcdFx0XHRwb3NpdGlvbnNbMF0gKyByYWRpdXNYICogMC43LFxuXHRcdFx0XHRwb3NpdGlvbnNbMV0gKyByYWRpdXNZICogMC43XG5cdFx0XHRdO1xuXHRcdFx0XG5cdFx0XHRwb2ludC5oYWxmID0gYW5nbGUgPCAtbWF0aFBJIC8gMiB8fCBhbmdsZSA+IG1hdGhQSSAvIDIgPyAxIDogMDtcblx0XHRcdHBvaW50LmFuZ2xlID0gYW5nbGU7XG5cblx0XHRcdC8vIHNldCB0aGUgYW5jaG9yIHBvaW50IGZvciBkYXRhIGxhYmVsc1xuXHRcdFx0Y29ubmVjdG9yT2Zmc2V0ID0gbWF0aE1pbihjb25uZWN0b3JPZmZzZXQsIGxhYmVsRGlzdGFuY2UgLyAyKTsgLy8gIzE2Nzhcblx0XHRcdHBvaW50LmxhYmVsUG9zID0gW1xuXHRcdFx0XHRwb3NpdGlvbnNbMF0gKyByYWRpdXNYICsgbWF0aENvcyhhbmdsZSkgKiBsYWJlbERpc3RhbmNlLCAvLyBmaXJzdCBicmVhayBvZiBjb25uZWN0b3Jcblx0XHRcdFx0cG9zaXRpb25zWzFdICsgcmFkaXVzWSArIG1hdGhTaW4oYW5nbGUpICogbGFiZWxEaXN0YW5jZSwgLy8gYS9hXG5cdFx0XHRcdHBvc2l0aW9uc1swXSArIHJhZGl1c1ggKyBtYXRoQ29zKGFuZ2xlKSAqIGNvbm5lY3Rvck9mZnNldCwgLy8gc2Vjb25kIGJyZWFrLCByaWdodCBvdXRzaWRlIHBpZVxuXHRcdFx0XHRwb3NpdGlvbnNbMV0gKyByYWRpdXNZICsgbWF0aFNpbihhbmdsZSkgKiBjb25uZWN0b3JPZmZzZXQsIC8vIGEvYVxuXHRcdFx0XHRwb3NpdGlvbnNbMF0gKyByYWRpdXNYLCAvLyBsYW5kaW5nIHBvaW50IGZvciBjb25uZWN0b3Jcblx0XHRcdFx0cG9zaXRpb25zWzFdICsgcmFkaXVzWSwgLy8gYS9hXG5cdFx0XHRcdGxhYmVsRGlzdGFuY2UgPCAwID8gLy8gYWxpZ25tZW50XG5cdFx0XHRcdFx0J2NlbnRlcicgOlxuXHRcdFx0XHRcdHBvaW50LmhhbGYgPyAncmlnaHQnIDogJ2xlZnQnLCAvLyBhbGlnbm1lbnRcblx0XHRcdFx0YW5nbGUgLy8gY2VudGVyIGFuZ2xlXG5cdFx0XHRdO1xuXG5cdFx0fVxuXHR9LFxuXHRcblx0ZHJhd0dyYXBoOiBudWxsLFxuXG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBkYXRhIHBvaW50c1xuXHQgKi9cblx0ZHJhd1BvaW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0Z3JvdXBUcmFuc2xhdGlvbixcblx0XHRcdC8vY2VudGVyLFxuXHRcdFx0Z3JhcGhpYyxcblx0XHRcdC8vZ3JvdXAsXG5cdFx0XHRzaGFkb3cgPSBzZXJpZXMub3B0aW9ucy5zaGFkb3csXG5cdFx0XHRzaGFkb3dHcm91cCxcblx0XHRcdHNoYXBlQXJncztcblxuXHRcdGlmIChzaGFkb3cgJiYgIXNlcmllcy5zaGFkb3dHcm91cCkge1xuXHRcdFx0c2VyaWVzLnNoYWRvd0dyb3VwID0gcmVuZGVyZXIuZygnc2hhZG93Jylcblx0XHRcdFx0LmFkZChzZXJpZXMuZ3JvdXApO1xuXHRcdH1cblxuXHRcdC8vIGRyYXcgdGhlIHNsaWNlc1xuXHRcdGVhY2goc2VyaWVzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRncmFwaGljID0gcG9pbnQuZ3JhcGhpYztcblx0XHRcdHNoYXBlQXJncyA9IHBvaW50LnNoYXBlQXJncztcblx0XHRcdHNoYWRvd0dyb3VwID0gcG9pbnQuc2hhZG93R3JvdXA7XG5cblx0XHRcdC8vIHB1dCB0aGUgc2hhZG93IGJlaGluZCBhbGwgcG9pbnRzXG5cdFx0XHRpZiAoc2hhZG93ICYmICFzaGFkb3dHcm91cCkge1xuXHRcdFx0XHRzaGFkb3dHcm91cCA9IHBvaW50LnNoYWRvd0dyb3VwID0gcmVuZGVyZXIuZygnc2hhZG93Jylcblx0XHRcdFx0XHQuYWRkKHNlcmllcy5zaGFkb3dHcm91cCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGlmIHRoZSBwb2ludCBpcyBzbGljZWQsIHVzZSBzcGVjaWFsIHRyYW5zbGF0aW9uLCBlbHNlIHVzZSBwbG90IGFyZWEgdHJhc2xhdGlvblxuXHRcdFx0Z3JvdXBUcmFuc2xhdGlvbiA9IHBvaW50LnNsaWNlZCA/IHBvaW50LnNsaWNlZFRyYW5zbGF0aW9uIDoge1xuXHRcdFx0XHR0cmFuc2xhdGVYOiAwLFxuXHRcdFx0XHR0cmFuc2xhdGVZOiAwXG5cdFx0XHR9O1xuXG5cdFx0XHQvL2dyb3VwLnRyYW5zbGF0ZShncm91cFRyYW5zbGF0aW9uWzBdLCBncm91cFRyYW5zbGF0aW9uWzFdKTtcblx0XHRcdGlmIChzaGFkb3dHcm91cCkge1xuXHRcdFx0XHRzaGFkb3dHcm91cC5hdHRyKGdyb3VwVHJhbnNsYXRpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBkcmF3IHRoZSBzbGljZVxuXHRcdFx0aWYgKGdyYXBoaWMpIHtcblx0XHRcdFx0Z3JhcGhpYy5hbmltYXRlKGV4dGVuZChzaGFwZUFyZ3MsIGdyb3VwVHJhbnNsYXRpb24pKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBvaW50LmdyYXBoaWMgPSBncmFwaGljID0gcmVuZGVyZXJbcG9pbnQuc2hhcGVUeXBlXShzaGFwZUFyZ3MpXG5cdFx0XHRcdFx0LnNldFJhZGlhbFJlZmVyZW5jZShzZXJpZXMuY2VudGVyKVxuXHRcdFx0XHRcdC5hdHRyKFxuXHRcdFx0XHRcdFx0cG9pbnQucG9pbnRBdHRyW3BvaW50LnNlbGVjdGVkID8gU0VMRUNUX1NUQVRFIDogTk9STUFMX1NUQVRFXVxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuYXR0cih7IFxuXHRcdFx0XHRcdFx0J3N0cm9rZS1saW5lam9pbic6ICdyb3VuZCdcblx0XHRcdFx0XHRcdC8vekluZGV4OiAxIC8vICMyNzIyIChyZXZlcnNlZClcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5hdHRyKGdyb3VwVHJhbnNsYXRpb24pXG5cdFx0XHRcdFx0LmFkZChzZXJpZXMuZ3JvdXApXG5cdFx0XHRcdFx0LnNoYWRvdyhzaGFkb3csIHNoYWRvd0dyb3VwKTtcdFxuXHRcdFx0fVxuXG5cdFx0XHQvLyBkZXRlY3QgcG9pbnQgc3BlY2lmaWMgdmlzaWJpbGl0eSAoIzI0MzApXG5cdFx0XHRpZiAocG9pbnQudmlzaWJsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHBvaW50LnNldFZpc2libGUocG9pbnQudmlzaWJsZSk7XG5cdFx0XHR9XG5cblx0XHR9KTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBVdGlsaXR5IGZvciBzb3J0aW5nIGRhdGEgbGFiZWxzXG5cdCAqL1xuXHRzb3J0QnlBbmdsZTogZnVuY3Rpb24gKHBvaW50cywgc2lnbikge1xuXHRcdHBvaW50cy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0XHRyZXR1cm4gYS5hbmdsZSAhPT0gdW5kZWZpbmVkICYmIChiLmFuZ2xlIC0gYS5hbmdsZSkgKiBzaWduO1xuXHRcdH0pO1xuXHR9LFx0XHRcblxuXHQvKipcblx0ICogVXNlIGEgc2ltcGxlIHN5bWJvbCBmcm9tIExlZ2VuZFN5bWJvbE1peGluXG5cdCAqL1xuXHRkcmF3TGVnZW5kU3ltYm9sOiBMZWdlbmRTeW1ib2xNaXhpbi5kcmF3UmVjdGFuZ2xlLFxuXG5cdC8qKlxuXHQgKiBVc2UgdGhlIGdldENlbnRlciBtZXRob2QgZnJvbSBkcmF3TGVnZW5kU3ltYm9sXG5cdCAqL1xuXHRnZXRDZW50ZXI6IENlbnRlcmVkU2VyaWVzTWl4aW4uZ2V0Q2VudGVyLFxuXG5cdC8qKlxuXHQgKiBQaWVzIGRvbid0IGhhdmUgcG9pbnQgbWFya2VyIHN5bWJvbHNcblx0ICovXG5cdGdldFN5bWJvbDogbm9vcFxuXG59O1xuUGllU2VyaWVzID0gZXh0ZW5kQ2xhc3MoU2VyaWVzLCBQaWVTZXJpZXMpO1xuc2VyaWVzVHlwZXMucGllID0gUGllU2VyaWVzO1xuXG4vKipcbiAqIERyYXcgdGhlIGRhdGEgbGFiZWxzXG4gKi9cblNlcmllcy5wcm90b3R5cGUuZHJhd0RhdGFMYWJlbHMgPSBmdW5jdGlvbiAoKSB7XG5cblx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdGN1cnNvciA9IHNlcmllc09wdGlvbnMuY3Vyc29yLFxuXHRcdG9wdGlvbnMgPSBzZXJpZXNPcHRpb25zLmRhdGFMYWJlbHMsXG5cdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRwb2ludE9wdGlvbnMsXG5cdFx0Z2VuZXJhbE9wdGlvbnMsXG5cdFx0aGFzUmVuZGVyZWQgPSBzZXJpZXMuaGFzUmVuZGVyZWQgfHwgMCxcblx0XHRzdHIsXG5cdFx0ZGF0YUxhYmVsc0dyb3VwO1xuXG5cdGlmIChvcHRpb25zLmVuYWJsZWQgfHwgc2VyaWVzLl9oYXNQb2ludExhYmVscykge1xuXG5cdFx0Ly8gUHJvY2VzcyBkZWZhdWx0IGFsaWdubWVudCBvZiBkYXRhIGxhYmVscyBmb3IgY29sdW1uc1xuXHRcdGlmIChzZXJpZXMuZGxQcm9jZXNzT3B0aW9ucykge1xuXHRcdFx0c2VyaWVzLmRsUHJvY2Vzc09wdGlvbnMob3B0aW9ucyk7XG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIGEgc2VwYXJhdGUgZ3JvdXAgZm9yIHRoZSBkYXRhIGxhYmVscyB0byBhdm9pZCByb3RhdGlvblxuXHRcdGRhdGFMYWJlbHNHcm91cCA9IHNlcmllcy5wbG90R3JvdXAoXG5cdFx0XHQnZGF0YUxhYmVsc0dyb3VwJyxcblx0XHRcdCdkYXRhLWxhYmVscycsXG5cdFx0XHRvcHRpb25zLmRlZmVyID8gSElEREVOIDogVklTSUJMRSxcblx0XHRcdG9wdGlvbnMuekluZGV4IHx8IDZcblx0XHQpO1xuXG5cdFx0aWYgKHBpY2sob3B0aW9ucy5kZWZlciwgdHJ1ZSkpIHtcblx0XHRcdGRhdGFMYWJlbHNHcm91cC5hdHRyKHsgb3BhY2l0eTogK2hhc1JlbmRlcmVkIH0pOyAvLyAjMzMwMFxuXHRcdFx0aWYgKCFoYXNSZW5kZXJlZCkge1xuXHRcdFx0XHRhZGRFdmVudChzZXJpZXMsICdhZnRlckFuaW1hdGUnLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0aWYgKHNlcmllcy52aXNpYmxlKSB7IC8vICMzMDIzLCAjMzAyNFxuXHRcdFx0XHRcdFx0ZGF0YUxhYmVsc0dyb3VwLnNob3coKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZGF0YUxhYmVsc0dyb3VwW3Nlcmllc09wdGlvbnMuYW5pbWF0aW9uID8gJ2FuaW1hdGUnIDogJ2F0dHInXSh7IG9wYWNpdHk6IDEgfSwgeyBkdXJhdGlvbjogMjAwIH0pO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBNYWtlIHRoZSBsYWJlbHMgZm9yIGVhY2ggcG9pbnRcblx0XHRnZW5lcmFsT3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0ZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXG5cdFx0XHR2YXIgZW5hYmxlZCxcblx0XHRcdFx0ZGF0YUxhYmVsID0gcG9pbnQuZGF0YUxhYmVsLFxuXHRcdFx0XHRsYWJlbENvbmZpZyxcblx0XHRcdFx0YXR0cixcblx0XHRcdFx0bmFtZSxcblx0XHRcdFx0cm90YXRpb24sXG5cdFx0XHRcdGNvbm5lY3RvciA9IHBvaW50LmNvbm5lY3Rvcixcblx0XHRcdFx0aXNOZXcgPSB0cnVlO1xuXG5cdFx0XHQvLyBEZXRlcm1pbmUgaWYgZWFjaCBkYXRhIGxhYmVsIGlzIGVuYWJsZWRcblx0XHRcdHBvaW50T3B0aW9ucyA9IHBvaW50Lm9wdGlvbnMgJiYgcG9pbnQub3B0aW9ucy5kYXRhTGFiZWxzO1xuXHRcdFx0ZW5hYmxlZCA9IHBpY2socG9pbnRPcHRpb25zICYmIHBvaW50T3B0aW9ucy5lbmFibGVkLCBnZW5lcmFsT3B0aW9ucy5lbmFibGVkKTsgLy8gIzIyODJcblxuXG5cdFx0XHQvLyBJZiB0aGUgcG9pbnQgaXMgb3V0c2lkZSB0aGUgcGxvdCBhcmVhLCBkZXN0cm95IGl0LiAjNjc4LCAjODIwXG5cdFx0XHRpZiAoZGF0YUxhYmVsICYmICFlbmFibGVkKSB7XG5cdFx0XHRcdHBvaW50LmRhdGFMYWJlbCA9IGRhdGFMYWJlbC5kZXN0cm95KCk7XG5cblx0XHRcdC8vIEluZGl2aWR1YWwgbGFiZWxzIGFyZSBkaXNhYmxlZCBpZiB0aGUgYXJlIGV4cGxpY2l0bHkgZGlzYWJsZWRcblx0XHRcdC8vIGluIHRoZSBwb2ludCBvcHRpb25zLCBvciBpZiB0aGV5IGZhbGwgb3V0c2lkZSB0aGUgcGxvdCBhcmVhLlxuXHRcdFx0fSBlbHNlIGlmIChlbmFibGVkKSB7XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIGluZGl2aWR1YWwgb3B0aW9ucyBzdHJ1Y3R1cmUgdGhhdCBjYW4gYmUgZXh0ZW5kZWQgd2l0aG91dFxuXHRcdFx0XHQvLyBhZmZlY3Rpbmcgb3RoZXJzXG5cdFx0XHRcdG9wdGlvbnMgPSBtZXJnZShnZW5lcmFsT3B0aW9ucywgcG9pbnRPcHRpb25zKTtcblxuXHRcdFx0XHRyb3RhdGlvbiA9IG9wdGlvbnMucm90YXRpb247XG5cblx0XHRcdFx0Ly8gR2V0IHRoZSBzdHJpbmdcblx0XHRcdFx0bGFiZWxDb25maWcgPSBwb2ludC5nZXRMYWJlbENvbmZpZygpO1xuXHRcdFx0XHRzdHIgPSBvcHRpb25zLmZvcm1hdCA/XG5cdFx0XHRcdFx0Zm9ybWF0KG9wdGlvbnMuZm9ybWF0LCBsYWJlbENvbmZpZykgOlxuXHRcdFx0XHRcdG9wdGlvbnMuZm9ybWF0dGVyLmNhbGwobGFiZWxDb25maWcsIG9wdGlvbnMpO1xuXG5cdFx0XHRcdC8vIERldGVybWluZSB0aGUgY29sb3Jcblx0XHRcdFx0b3B0aW9ucy5zdHlsZS5jb2xvciA9IHBpY2sob3B0aW9ucy5jb2xvciwgb3B0aW9ucy5zdHlsZS5jb2xvciwgc2VyaWVzLmNvbG9yLCAnYmxhY2snKTtcblxuXG5cdFx0XHRcdC8vIHVwZGF0ZSBleGlzdGluZyBsYWJlbFxuXHRcdFx0XHRpZiAoZGF0YUxhYmVsKSB7XG5cblx0XHRcdFx0XHRpZiAoZGVmaW5lZChzdHIpKSB7XG5cdFx0XHRcdFx0XHRkYXRhTGFiZWxcblx0XHRcdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0XHRcdHRleHQ6IHN0clxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdGlzTmV3ID0gZmFsc2U7XG5cblx0XHRcdFx0XHR9IGVsc2UgeyAvLyAjMTQzNyAtIHRoZSBsYWJlbCBpcyBzaG93biBjb25kaXRpb25hbGx5XG5cdFx0XHRcdFx0XHRwb2ludC5kYXRhTGFiZWwgPSBkYXRhTGFiZWwgPSBkYXRhTGFiZWwuZGVzdHJveSgpO1xuXHRcdFx0XHRcdFx0aWYgKGNvbm5lY3Rvcikge1xuXHRcdFx0XHRcdFx0XHRwb2ludC5jb25uZWN0b3IgPSBjb25uZWN0b3IuZGVzdHJveSgpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBjcmVhdGUgbmV3IGxhYmVsXG5cdFx0XHRcdH0gZWxzZSBpZiAoZGVmaW5lZChzdHIpKSB7XG5cdFx0XHRcdFx0YXR0ciA9IHtcblx0XHRcdFx0XHRcdC8vYWxpZ246IGFsaWduLFxuXHRcdFx0XHRcdFx0ZmlsbDogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXG5cdFx0XHRcdFx0XHRzdHJva2U6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXG5cdFx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogb3B0aW9ucy5ib3JkZXJXaWR0aCxcblx0XHRcdFx0XHRcdHI6IG9wdGlvbnMuYm9yZGVyUmFkaXVzIHx8IDAsXG5cdFx0XHRcdFx0XHRyb3RhdGlvbjogcm90YXRpb24sXG5cdFx0XHRcdFx0XHRwYWRkaW5nOiBvcHRpb25zLnBhZGRpbmcsXG5cdFx0XHRcdFx0XHR6SW5kZXg6IDFcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdC8vIFJlbW92ZSB1bnVzZWQgYXR0cmlidXRlcyAoIzk0Nylcblx0XHRcdFx0XHRmb3IgKG5hbWUgaW4gYXR0cikge1xuXHRcdFx0XHRcdFx0aWYgKGF0dHJbbmFtZV0gPT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgYXR0cltuYW1lXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRkYXRhTGFiZWwgPSBwb2ludC5kYXRhTGFiZWwgPSBzZXJpZXMuY2hhcnQucmVuZGVyZXJbcm90YXRpb24gPyAndGV4dCcgOiAnbGFiZWwnXSggLy8gbGFiZWxzIGRvbid0IHN1cHBvcnQgcm90YXRpb25cblx0XHRcdFx0XHRcdHN0cixcblx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHQtOTk5LFxuXHRcdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0b3B0aW9ucy51c2VIVE1MXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdC5hdHRyKGF0dHIpXG5cdFx0XHRcdFx0LmNzcyhleHRlbmQob3B0aW9ucy5zdHlsZSwgY3Vyc29yICYmIHsgY3Vyc29yOiBjdXJzb3IgfSkpXG5cdFx0XHRcdFx0LmFkZChkYXRhTGFiZWxzR3JvdXApXG5cdFx0XHRcdFx0LnNoYWRvdyhvcHRpb25zLnNoYWRvdyk7XG5cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChkYXRhTGFiZWwpIHtcblx0XHRcdFx0XHQvLyBOb3cgdGhlIGRhdGEgbGFiZWwgaXMgY3JlYXRlZCBhbmQgcGxhY2VkIGF0IDAsMCwgc28gd2UgbmVlZCB0byBhbGlnbiBpdFxuXHRcdFx0XHRcdHNlcmllcy5hbGlnbkRhdGFMYWJlbChwb2ludCwgZGF0YUxhYmVsLCBvcHRpb25zLCBudWxsLCBpc05ldyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fVxufTtcblxuLyoqXG4gKiBBbGlnbiBlYWNoIGluZGl2aWR1YWwgZGF0YSBsYWJlbFxuICovXG5TZXJpZXMucHJvdG90eXBlLmFsaWduRGF0YUxhYmVsID0gZnVuY3Rpb24gKHBvaW50LCBkYXRhTGFiZWwsIG9wdGlvbnMsIGFsaWduVG8sIGlzTmV3KSB7XG5cdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0aW52ZXJ0ZWQgPSBjaGFydC5pbnZlcnRlZCxcblx0XHRwbG90WCA9IHBpY2socG9pbnQucGxvdFgsIC05OTkpLFxuXHRcdHBsb3RZID0gcGljayhwb2ludC5wbG90WSwgLTk5OSksXG5cdFx0YkJveCA9IGRhdGFMYWJlbC5nZXRCQm94KCksXG5cdFx0Ly8gTWF0aC5yb3VuZCBmb3Igcm91bmRpbmcgZXJyb3JzICgjMjY4MyksIGFsaWduVG8gdG8gYWxsb3cgY29sdW1uIGxhYmVscyAoIzI3MDApXG5cdFx0dmlzaWJsZSA9IHRoaXMudmlzaWJsZSAmJiAocG9pbnQuc2VyaWVzLmZvcmNlREwgfHwgY2hhcnQuaXNJbnNpZGVQbG90KHBsb3RYLCBtYXRoUm91bmQocGxvdFkpLCBpbnZlcnRlZCkgfHxcblx0XHRcdChhbGlnblRvICYmIGNoYXJ0LmlzSW5zaWRlUGxvdChwbG90WCwgaW52ZXJ0ZWQgPyBhbGlnblRvLnggKyAxIDogYWxpZ25Uby55ICsgYWxpZ25Uby5oZWlnaHQgLSAxLCBpbnZlcnRlZCkpKSxcblx0XHRhbGlnbkF0dHI7IC8vIHRoZSBmaW5hbCBwb3NpdGlvbjtcblxuXHRpZiAodmlzaWJsZSkge1xuXG5cdFx0Ly8gVGhlIGFsaWdubWVudCBib3ggaXMgYSBzaW5ndWxhciBwb2ludFxuXHRcdGFsaWduVG8gPSBleHRlbmQoe1xuXHRcdFx0eDogaW52ZXJ0ZWQgPyBjaGFydC5wbG90V2lkdGggLSBwbG90WSA6IHBsb3RYLFxuXHRcdFx0eTogbWF0aFJvdW5kKGludmVydGVkID8gY2hhcnQucGxvdEhlaWdodCAtIHBsb3RYIDogcGxvdFkpLFxuXHRcdFx0d2lkdGg6IDAsXG5cdFx0XHRoZWlnaHQ6IDBcblx0XHR9LCBhbGlnblRvKTtcblxuXHRcdC8vIEFkZCB0aGUgdGV4dCBzaXplIGZvciBhbGlnbm1lbnQgY2FsY3VsYXRpb25cblx0XHRleHRlbmQob3B0aW9ucywge1xuXHRcdFx0d2lkdGg6IGJCb3gud2lkdGgsXG5cdFx0XHRoZWlnaHQ6IGJCb3guaGVpZ2h0XG5cdFx0fSk7XG5cblx0XHQvLyBBbGxvdyBhIGhvb2sgZm9yIGNoYW5naW5nIGFsaWdubWVudCBpbiB0aGUgbGFzdCBtb21lbnQsIHRoZW4gZG8gdGhlIGFsaWdubWVudFxuXHRcdGlmIChvcHRpb25zLnJvdGF0aW9uKSB7IC8vIEZhbmN5IGJveCBhbGlnbm1lbnQgaXNuJ3Qgc3VwcG9ydGVkIGZvciByb3RhdGVkIHRleHRcblx0XHRcdGRhdGFMYWJlbFtpc05ldyA/ICdhdHRyJyA6ICdhbmltYXRlJ10oe1xuXHRcdFx0XHRcdHg6IGFsaWduVG8ueCArIG9wdGlvbnMueCArIGFsaWduVG8ud2lkdGggLyAyLFxuXHRcdFx0XHRcdHk6IGFsaWduVG8ueSArIG9wdGlvbnMueSArIGFsaWduVG8uaGVpZ2h0IC8gMlxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYXR0cih7IC8vICMzMDAzXG5cdFx0XHRcdFx0YWxpZ246IG9wdGlvbnMuYWxpZ25cblx0XHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGFMYWJlbC5hbGlnbihvcHRpb25zLCBudWxsLCBhbGlnblRvKTtcblx0XHRcdGFsaWduQXR0ciA9IGRhdGFMYWJlbC5hbGlnbkF0dHI7XG5cblx0XHRcdC8vIEhhbmRsZSBqdXN0aWZ5IG9yIGNyb3Bcblx0XHRcdGlmIChwaWNrKG9wdGlvbnMub3ZlcmZsb3csICdqdXN0aWZ5JykgPT09ICdqdXN0aWZ5Jykge1xuXHRcdFx0XHR0aGlzLmp1c3RpZnlEYXRhTGFiZWwoZGF0YUxhYmVsLCBvcHRpb25zLCBhbGlnbkF0dHIsIGJCb3gsIGFsaWduVG8sIGlzTmV3KTtcblxuXHRcdFx0fSBlbHNlIGlmIChwaWNrKG9wdGlvbnMuY3JvcCwgdHJ1ZSkpIHtcblx0XHRcdFx0Ly8gTm93IGNoZWNrIHRoYXQgdGhlIGRhdGEgbGFiZWwgaXMgd2l0aGluIHRoZSBwbG90IGFyZWFcblx0XHRcdFx0dmlzaWJsZSA9IGNoYXJ0LmlzSW5zaWRlUGxvdChhbGlnbkF0dHIueCwgYWxpZ25BdHRyLnkpICYmIGNoYXJ0LmlzSW5zaWRlUGxvdChhbGlnbkF0dHIueCArIGJCb3gud2lkdGgsIGFsaWduQXR0ci55ICsgYkJveC5oZWlnaHQpO1xuXG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gU2hvdyBvciBoaWRlIGJhc2VkIG9uIHRoZSBmaW5hbCBhbGlnbmVkIHBvc2l0aW9uXG5cdGlmICghdmlzaWJsZSkge1xuXHRcdGRhdGFMYWJlbC5hdHRyKHsgeTogLTk5OSB9KTtcblx0XHRkYXRhTGFiZWwucGxhY2VkID0gZmFsc2U7IC8vIGRvbid0IGFuaW1hdGUgYmFjayBpblxuXHR9XG5cbn07XG5cbi8qKlxuICogSWYgZGF0YSBsYWJlbHMgZmFsbCBwYXJ0bHkgb3V0c2lkZSB0aGUgcGxvdCBhcmVhLCBhbGlnbiB0aGVtIGJhY2sgaW4sIGluIGEgd2F5IHRoYXRcbiAqIGRvZXNuJ3QgaGlkZSB0aGUgcG9pbnQuXG4gKi9cblNlcmllcy5wcm90b3R5cGUuanVzdGlmeURhdGFMYWJlbCA9IGZ1bmN0aW9uIChkYXRhTGFiZWwsIG9wdGlvbnMsIGFsaWduQXR0ciwgYkJveCwgYWxpZ25UbywgaXNOZXcpIHtcblx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRhbGlnbiA9IG9wdGlvbnMuYWxpZ24sXG5cdFx0dmVydGljYWxBbGlnbiA9IG9wdGlvbnMudmVydGljYWxBbGlnbixcblx0XHRvZmYsXG5cdFx0anVzdGlmaWVkO1xuXG5cdC8vIE9mZiBsZWZ0XG5cdG9mZiA9IGFsaWduQXR0ci54O1xuXHRpZiAob2ZmIDwgMCkge1xuXHRcdGlmIChhbGlnbiA9PT0gJ3JpZ2h0Jykge1xuXHRcdFx0b3B0aW9ucy5hbGlnbiA9ICdsZWZ0Jztcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3B0aW9ucy54ID0gLW9mZjtcblx0XHR9XG5cdFx0anVzdGlmaWVkID0gdHJ1ZTtcblx0fVxuXG5cdC8vIE9mZiByaWdodFxuXHRvZmYgPSBhbGlnbkF0dHIueCArIGJCb3gud2lkdGg7XG5cdGlmIChvZmYgPiBjaGFydC5wbG90V2lkdGgpIHtcblx0XHRpZiAoYWxpZ24gPT09ICdsZWZ0Jykge1xuXHRcdFx0b3B0aW9ucy5hbGlnbiA9ICdyaWdodCc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9wdGlvbnMueCA9IGNoYXJ0LnBsb3RXaWR0aCAtIG9mZjtcblx0XHR9XG5cdFx0anVzdGlmaWVkID0gdHJ1ZTtcblx0fVxuXG5cdC8vIE9mZiB0b3Bcblx0b2ZmID0gYWxpZ25BdHRyLnk7XG5cdGlmIChvZmYgPCAwKSB7XG5cdFx0aWYgKHZlcnRpY2FsQWxpZ24gPT09ICdib3R0b20nKSB7XG5cdFx0XHRvcHRpb25zLnZlcnRpY2FsQWxpZ24gPSAndG9wJztcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3B0aW9ucy55ID0gLW9mZjtcblx0XHR9XG5cdFx0anVzdGlmaWVkID0gdHJ1ZTtcblx0fVxuXG5cdC8vIE9mZiBib3R0b21cblx0b2ZmID0gYWxpZ25BdHRyLnkgKyBiQm94LmhlaWdodDtcblx0aWYgKG9mZiA+IGNoYXJ0LnBsb3RIZWlnaHQpIHtcblx0XHRpZiAodmVydGljYWxBbGlnbiA9PT0gJ3RvcCcpIHtcblx0XHRcdG9wdGlvbnMudmVydGljYWxBbGlnbiA9ICdib3R0b20nO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvcHRpb25zLnkgPSBjaGFydC5wbG90SGVpZ2h0IC0gb2ZmO1xuXHRcdH1cblx0XHRqdXN0aWZpZWQgPSB0cnVlO1xuXHR9XG5cblx0aWYgKGp1c3RpZmllZCkge1xuXHRcdGRhdGFMYWJlbC5wbGFjZWQgPSAhaXNOZXc7XG5cdFx0ZGF0YUxhYmVsLmFsaWduKG9wdGlvbnMsIG51bGwsIGFsaWduVG8pO1xuXHR9XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIHRoZSBiYXNlIGRyYXdEYXRhTGFiZWxzIG1ldGhvZCBieSBwaWUgc3BlY2lmaWMgZnVuY3Rpb25hbGl0eVxuICovXG5pZiAoc2VyaWVzVHlwZXMucGllKSB7XG5cdHNlcmllc1R5cGVzLnBpZS5wcm90b3R5cGUuZHJhd0RhdGFMYWJlbHMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRkYXRhID0gc2VyaWVzLmRhdGEsXG5cdFx0XHRwb2ludCxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLmRhdGFMYWJlbHMsXG5cdFx0XHRjb25uZWN0b3JQYWRkaW5nID0gcGljayhvcHRpb25zLmNvbm5lY3RvclBhZGRpbmcsIDEwKSxcblx0XHRcdGNvbm5lY3RvcldpZHRoID0gcGljayhvcHRpb25zLmNvbm5lY3RvcldpZHRoLCAxKSxcblx0XHRcdHBsb3RXaWR0aCA9IGNoYXJ0LnBsb3RXaWR0aCxcblx0XHRcdHBsb3RIZWlnaHQgPSBjaGFydC5wbG90SGVpZ2h0LFxuXHRcdFx0Y29ubmVjdG9yLFxuXHRcdFx0Y29ubmVjdG9yUGF0aCxcblx0XHRcdHNvZnRDb25uZWN0b3IgPSBwaWNrKG9wdGlvbnMuc29mdENvbm5lY3RvciwgdHJ1ZSksXG5cdFx0XHRkaXN0YW5jZU9wdGlvbiA9IG9wdGlvbnMuZGlzdGFuY2UsXG5cdFx0XHRzZXJpZXNDZW50ZXIgPSBzZXJpZXMuY2VudGVyLFxuXHRcdFx0cmFkaXVzID0gc2VyaWVzQ2VudGVyWzJdIC8gMixcblx0XHRcdGNlbnRlclkgPSBzZXJpZXNDZW50ZXJbMV0sXG5cdFx0XHRvdXRzaWRlID0gZGlzdGFuY2VPcHRpb24gPiAwLFxuXHRcdFx0ZGF0YUxhYmVsLFxuXHRcdFx0ZGF0YUxhYmVsV2lkdGgsXG5cdFx0XHRsYWJlbFBvcyxcblx0XHRcdGxhYmVsSGVpZ2h0LFxuXHRcdFx0aGFsdmVzID0gWy8vIGRpdmlkZSB0aGUgcG9pbnRzIGludG8gcmlnaHQgYW5kIGxlZnQgaGFsdmVzIGZvciBhbnRpIGNvbGxpc2lvblxuXHRcdFx0XHRbXSwgLy8gcmlnaHRcblx0XHRcdFx0W10gIC8vIGxlZnRcblx0XHRcdF0sXG5cdFx0XHR4LFxuXHRcdFx0eSxcblx0XHRcdHZpc2liaWxpdHksXG5cdFx0XHRyYW5rQXJyLFxuXHRcdFx0aSxcblx0XHRcdGosXG5cdFx0XHRvdmVyZmxvdyA9IFswLCAwLCAwLCAwXSwgLy8gdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XG5cdFx0XHRzb3J0ID0gZnVuY3Rpb24gKGEsIGIpIHtcblx0XHRcdFx0cmV0dXJuIGIueSAtIGEueTtcblx0XHRcdH07XG5cblx0XHQvLyBnZXQgb3V0IGlmIG5vdCBlbmFibGVkXG5cdFx0aWYgKCFzZXJpZXMudmlzaWJsZSB8fCAoIW9wdGlvbnMuZW5hYmxlZCAmJiAhc2VyaWVzLl9oYXNQb2ludExhYmVscykpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBydW4gcGFyZW50IG1ldGhvZFxuXHRcdFNlcmllcy5wcm90b3R5cGUuZHJhd0RhdGFMYWJlbHMuYXBwbHkoc2VyaWVzKTtcblxuXHRcdC8vIGFycmFuZ2UgcG9pbnRzIGZvciBkZXRlY3Rpb24gY29sbGlzaW9uXG5cdFx0ZWFjaChkYXRhLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdGlmIChwb2ludC5kYXRhTGFiZWwgJiYgcG9pbnQudmlzaWJsZSkgeyAvLyAjNDA3LCAjMjUxMFxuXHRcdFx0XHRoYWx2ZXNbcG9pbnQuaGFsZl0ucHVzaChwb2ludCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvKiBMb29wIG92ZXIgdGhlIHBvaW50cyBpbiBlYWNoIGhhbGYsIHN0YXJ0aW5nIGZyb20gdGhlIHRvcCBhbmQgYm90dG9tXG5cdFx0ICogb2YgdGhlIHBpZSB0byBkZXRlY3Qgb3ZlcmxhcHBpbmcgbGFiZWxzLlxuXHRcdCAqL1xuXHRcdGkgPSAyO1xuXHRcdHdoaWxlIChpLS0pIHtcblxuXHRcdFx0dmFyIHNsb3RzID0gW10sXG5cdFx0XHRcdHNsb3RzTGVuZ3RoLFxuXHRcdFx0XHR1c2VkU2xvdHMgPSBbXSxcblx0XHRcdFx0cG9pbnRzID0gaGFsdmVzW2ldLFxuXHRcdFx0XHRwb3MsXG5cdFx0XHRcdGJvdHRvbSxcblx0XHRcdFx0bGVuZ3RoID0gcG9pbnRzLmxlbmd0aCxcblx0XHRcdFx0c2xvdEluZGV4O1xuXG5cdFx0XHRpZiAoIWxlbmd0aCkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU29ydCBieSBhbmdsZVxuXHRcdFx0c2VyaWVzLnNvcnRCeUFuZ2xlKHBvaW50cywgaSAtIDAuNSk7XG5cblx0XHRcdC8vIEFzc3VtZSBlcXVhbCBsYWJlbCBoZWlnaHRzIG9uIGVpdGhlciBoZW1pc3BoZXJlICgjMjYzMClcblx0XHRcdGogPSBsYWJlbEhlaWdodCA9IDA7XG5cdFx0XHR3aGlsZSAoIWxhYmVsSGVpZ2h0ICYmIHBvaW50c1tqXSkgeyAvLyAjMTU2OVxuXHRcdFx0XHRsYWJlbEhlaWdodCA9IHBvaW50c1tqXSAmJiBwb2ludHNbal0uZGF0YUxhYmVsICYmIChwb2ludHNbal0uZGF0YUxhYmVsLmdldEJCb3goKS5oZWlnaHQgfHwgMjEpOyAvLyAyMSBpcyBmb3IgIzk2OFxuXHRcdFx0XHRqKys7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgZG8gYW50aS1jb2xsaXNpb24gd2hlbiB3ZSBhcmUgb3V0c2lkZSB0aGUgcGllIGFuZCBoYXZlIGNvbm5lY3RvcnMgKCM4NTYpXG5cdFx0XHRpZiAoZGlzdGFuY2VPcHRpb24gPiAwKSB7XG5cblx0XHRcdFx0Ly8gQnVpbGQgdGhlIHNsb3RzXG5cdFx0XHRcdGJvdHRvbSA9IG1hdGhNaW4oY2VudGVyWSArIHJhZGl1cyArIGRpc3RhbmNlT3B0aW9uLCBjaGFydC5wbG90SGVpZ2h0KTtcblx0XHRcdFx0Zm9yIChwb3MgPSBtYXRoTWF4KDAsIGNlbnRlclkgLSByYWRpdXMgLSBkaXN0YW5jZU9wdGlvbik7IHBvcyA8PSBib3R0b207IHBvcyArPSBsYWJlbEhlaWdodCkge1xuXHRcdFx0XHRcdHNsb3RzLnB1c2gocG9zKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzbG90c0xlbmd0aCA9IHNsb3RzLmxlbmd0aDtcblxuXG5cdFx0XHRcdC8qIFZpc3VhbGl6ZSB0aGUgc2xvdHNcblx0XHRcdFx0aWYgKCFzZXJpZXMuc2xvdEVsZW1lbnRzKSB7XG5cdFx0XHRcdFx0c2VyaWVzLnNsb3RFbGVtZW50cyA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChpID09PSAxKSB7XG5cdFx0XHRcdFx0c2VyaWVzLnNsb3RFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmRlc3Ryb3koKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRzZXJpZXMuc2xvdEVsZW1lbnRzLmxlbmd0aCA9IDA7XG5cdFx0XHRcdH1cblx0XHRcdFx0XHRcblx0XHRcdFx0c2xvdHMuZm9yRWFjaChmdW5jdGlvbiAocG9zLCBubykge1xuXHRcdFx0XHRcdHZhciBzbG90WCA9IHNlcmllcy5nZXRYKHBvcywgaSkgKyBjaGFydC5wbG90TGVmdCAtIChpID8gMTAwIDogMCksXG5cdFx0XHRcdFx0XHRzbG90WSA9IHBvcyArIGNoYXJ0LnBsb3RUb3A7XG5cdFx0XHRcdFx0XG5cdFx0XHRcdFx0aWYgKCFpc05hTihzbG90WCkpIHtcblx0XHRcdFx0XHRcdHNlcmllcy5zbG90RWxlbWVudHMucHVzaChjaGFydC5yZW5kZXJlci5yZWN0KHNsb3RYLCBzbG90WSAtIDcsIDEwMCwgbGFiZWxIZWlnaHQsIDEpXG5cdFx0XHRcdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogMSxcblx0XHRcdFx0XHRcdFx0XHRzdHJva2U6ICdzaWx2ZXInLFxuXHRcdFx0XHRcdFx0XHRcdGZpbGw6ICdyZ2JhKDAsMCwyNTUsMC4xKSdcblx0XHRcdFx0XHRcdFx0fSlcblx0XHRcdFx0XHRcdFx0LmFkZCgpKTtcblx0XHRcdFx0XHRcdHNlcmllcy5zbG90RWxlbWVudHMucHVzaChjaGFydC5yZW5kZXJlci50ZXh0KCdTbG90ICcrIG5vLCBzbG90WCwgc2xvdFkgKyA0KVxuXHRcdFx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRcdFx0ZmlsbDogJ3NpbHZlcidcblx0XHRcdFx0XHRcdFx0fSkuYWRkKCkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdC8vICovXG5cblx0XHRcdFx0Ly8gaWYgdGhlcmUgYXJlIG1vcmUgdmFsdWVzIHRoYW4gYXZhaWxhYmxlIHNsb3RzLCByZW1vdmUgbG93ZXN0IHZhbHVlc1xuXHRcdFx0XHRpZiAobGVuZ3RoID4gc2xvdHNMZW5ndGgpIHtcblx0XHRcdFx0XHQvLyBjcmVhdGUgYW4gYXJyYXkgZm9yIHNvcnRpbmcgYW5kIHJhbmtpbmcgdGhlIHBvaW50cyB3aXRoaW4gZWFjaCBxdWFydGVyXG5cdFx0XHRcdFx0cmFua0FyciA9IFtdLmNvbmNhdChwb2ludHMpO1xuXHRcdFx0XHRcdHJhbmtBcnIuc29ydChzb3J0KTtcblx0XHRcdFx0XHRqID0gbGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlIChqLS0pIHtcblx0XHRcdFx0XHRcdHJhbmtBcnJbal0ucmFuayA9IGo7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGogPSBsZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKGotLSkge1xuXHRcdFx0XHRcdFx0aWYgKHBvaW50c1tqXS5yYW5rID49IHNsb3RzTGVuZ3RoKSB7XG5cdFx0XHRcdFx0XHRcdHBvaW50cy5zcGxpY2UoaiwgMSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGxlbmd0aCA9IHBvaW50cy5sZW5ndGg7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUaGUgbGFiZWwgZ29lcyB0byB0aGUgbmVhcmVzdCBvcGVuIHNsb3QsIGJ1dCBub3QgY2xvc2VyIHRvIHRoZSBlZGdlIHRoYW5cblx0XHRcdFx0Ly8gdGhlIGxhYmVsJ3MgaW5kZXguXG5cdFx0XHRcdGZvciAoaiA9IDA7IGogPCBsZW5ndGg7IGorKykge1xuXG5cdFx0XHRcdFx0cG9pbnQgPSBwb2ludHNbal07XG5cdFx0XHRcdFx0bGFiZWxQb3MgPSBwb2ludC5sYWJlbFBvcztcblxuXHRcdFx0XHRcdHZhciBjbG9zZXN0ID0gOTk5OSxcblx0XHRcdFx0XHRcdGRpc3RhbmNlLFxuXHRcdFx0XHRcdFx0c2xvdEk7XG5cblx0XHRcdFx0XHQvLyBmaW5kIHRoZSBjbG9zZXN0IHNsb3QgaW5kZXhcblx0XHRcdFx0XHRmb3IgKHNsb3RJID0gMDsgc2xvdEkgPCBzbG90c0xlbmd0aDsgc2xvdEkrKykge1xuXHRcdFx0XHRcdFx0ZGlzdGFuY2UgPSBtYXRoQWJzKHNsb3RzW3Nsb3RJXSAtIGxhYmVsUG9zWzFdKTtcblx0XHRcdFx0XHRcdGlmIChkaXN0YW5jZSA8IGNsb3Nlc3QpIHtcblx0XHRcdFx0XHRcdFx0Y2xvc2VzdCA9IGRpc3RhbmNlO1xuXHRcdFx0XHRcdFx0XHRzbG90SW5kZXggPSBzbG90STtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBpZiB0aGF0IHNsb3QgaW5kZXggaXMgY2xvc2VyIHRvIHRoZSBlZGdlcyBvZiB0aGUgc2xvdHMsIG1vdmUgaXRcblx0XHRcdFx0XHQvLyB0byB0aGUgY2xvc2VzdCBhcHByb3ByaWF0ZSBzbG90XG5cdFx0XHRcdFx0aWYgKHNsb3RJbmRleCA8IGogJiYgc2xvdHNbal0gIT09IG51bGwpIHsgLy8gY2x1c3RlciBhdCB0aGUgdG9wXG5cdFx0XHRcdFx0XHRzbG90SW5kZXggPSBqO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoc2xvdHNMZW5ndGggIDwgbGVuZ3RoIC0gaiArIHNsb3RJbmRleCAmJiBzbG90c1tqXSAhPT0gbnVsbCkgeyAvLyBjbHVzdGVyIGF0IHRoZSBib3R0b21cblx0XHRcdFx0XHRcdHNsb3RJbmRleCA9IHNsb3RzTGVuZ3RoIC0gbGVuZ3RoICsgajtcblx0XHRcdFx0XHRcdHdoaWxlIChzbG90c1tzbG90SW5kZXhdID09PSBudWxsKSB7IC8vIG1ha2Ugc3VyZSBpdCBpcyBub3QgdGFrZW5cblx0XHRcdFx0XHRcdFx0c2xvdEluZGV4Kys7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIFNsb3QgaXMgdGFrZW4sIGZpbmQgbmV4dCBmcmVlIHNsb3QgYmVsb3cuIEluIHRoZSBuZXh0IHJ1biwgdGhlIG5leHQgc2xpY2Ugd2lsbCBmaW5kIHRoZVxuXHRcdFx0XHRcdFx0Ly8gc2xvdCBhYm92ZSB0aGVzZSwgYmVjYXVzZSBpdCBpcyB0aGUgY2xvc2VzdCBvbmVcblx0XHRcdFx0XHRcdHdoaWxlIChzbG90c1tzbG90SW5kZXhdID09PSBudWxsKSB7IC8vIG1ha2Ugc3VyZSBpdCBpcyBub3QgdGFrZW5cblx0XHRcdFx0XHRcdFx0c2xvdEluZGV4Kys7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dXNlZFNsb3RzLnB1c2goeyBpOiBzbG90SW5kZXgsIHk6IHNsb3RzW3Nsb3RJbmRleF0gfSk7XG5cdFx0XHRcdFx0c2xvdHNbc2xvdEluZGV4XSA9IG51bGw7IC8vIG1hcmsgYXMgdGFrZW5cblx0XHRcdFx0fVxuXHRcdFx0XHQvLyBzb3J0IHRoZW0gaW4gb3JkZXIgdG8gZmlsbCBpbiBmcm9tIHRoZSB0b3Bcblx0XHRcdFx0dXNlZFNsb3RzLnNvcnQoc29ydCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIG5vdyB0aGUgdXNlZCBzbG90cyBhcmUgc29ydGVkLCBmaWxsIHRoZW0gdXAgc2VxdWVudGlhbGx5XG5cdFx0XHRmb3IgKGogPSAwOyBqIDwgbGVuZ3RoOyBqKyspIHtcblxuXHRcdFx0XHR2YXIgc2xvdCwgbmF0dXJhbFk7XG5cblx0XHRcdFx0cG9pbnQgPSBwb2ludHNbal07XG5cdFx0XHRcdGxhYmVsUG9zID0gcG9pbnQubGFiZWxQb3M7XG5cdFx0XHRcdGRhdGFMYWJlbCA9IHBvaW50LmRhdGFMYWJlbDtcblx0XHRcdFx0dmlzaWJpbGl0eSA9IHBvaW50LnZpc2libGUgPT09IGZhbHNlID8gSElEREVOIDogVklTSUJMRTtcblx0XHRcdFx0bmF0dXJhbFkgPSBsYWJlbFBvc1sxXTtcblxuXHRcdFx0XHRpZiAoZGlzdGFuY2VPcHRpb24gPiAwKSB7XG5cdFx0XHRcdFx0c2xvdCA9IHVzZWRTbG90cy5wb3AoKTtcblx0XHRcdFx0XHRzbG90SW5kZXggPSBzbG90Lmk7XG5cblx0XHRcdFx0XHQvLyBpZiB0aGUgc2xvdCBuZXh0IHRvIGN1cnJyZW50IHNsb3QgaXMgZnJlZSwgdGhlIHkgdmFsdWUgaXMgYWxsb3dlZFxuXHRcdFx0XHRcdC8vIHRvIGZhbGwgYmFjayB0byB0aGUgbmF0dXJhbCBwb3NpdGlvblxuXHRcdFx0XHRcdHkgPSBzbG90Lnk7XG5cdFx0XHRcdFx0aWYgKChuYXR1cmFsWSA+IHkgJiYgc2xvdHNbc2xvdEluZGV4ICsgMV0gIT09IG51bGwpIHx8XG5cdFx0XHRcdFx0XHRcdChuYXR1cmFsWSA8IHkgJiYgIHNsb3RzW3Nsb3RJbmRleCAtIDFdICE9PSBudWxsKSkge1xuXHRcdFx0XHRcdFx0eSA9IG1hdGhNaW4obWF0aE1heCgwLCBuYXR1cmFsWSksIGNoYXJ0LnBsb3RIZWlnaHQpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHkgPSBuYXR1cmFsWTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGdldCB0aGUgeCAtIHVzZSB0aGUgbmF0dXJhbCB4IHBvc2l0aW9uIGZvciBmaXJzdCBhbmQgbGFzdCBzbG90LCB0byBwcmV2ZW50IHRoZSB0b3Bcblx0XHRcdFx0Ly8gYW5kIGJvdHRvbiBzbGljZSBjb25uZWN0b3JzIGZyb20gdG91Y2hpbmcgZWFjaCBvdGhlciBvbiBlaXRoZXIgc2lkZVxuXHRcdFx0XHR4ID0gb3B0aW9ucy5qdXN0aWZ5ID9cblx0XHRcdFx0XHRzZXJpZXNDZW50ZXJbMF0gKyAoaSA/IC0xIDogMSkgKiAocmFkaXVzICsgZGlzdGFuY2VPcHRpb24pIDpcblx0XHRcdFx0XHRzZXJpZXMuZ2V0WCh5ID09PSBjZW50ZXJZIC0gcmFkaXVzIC0gZGlzdGFuY2VPcHRpb24gfHwgeSA9PT0gY2VudGVyWSArIHJhZGl1cyArIGRpc3RhbmNlT3B0aW9uID8gbmF0dXJhbFkgOiB5LCBpKTtcblxuXG5cdFx0XHRcdC8vIFJlY29yZCB0aGUgcGxhY2VtZW50IGFuZCB2aXNpYmlsaXR5XG5cdFx0XHRcdGRhdGFMYWJlbC5fYXR0ciA9IHtcblx0XHRcdFx0XHR2aXNpYmlsaXR5OiB2aXNpYmlsaXR5LFxuXHRcdFx0XHRcdGFsaWduOiBsYWJlbFBvc1s2XVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRkYXRhTGFiZWwuX3BvcyA9IHtcblx0XHRcdFx0XHR4OiB4ICsgb3B0aW9ucy54ICtcblx0XHRcdFx0XHRcdCh7IGxlZnQ6IGNvbm5lY3RvclBhZGRpbmcsIHJpZ2h0OiAtY29ubmVjdG9yUGFkZGluZyB9W2xhYmVsUG9zWzZdXSB8fCAwKSxcblx0XHRcdFx0XHR5OiB5ICsgb3B0aW9ucy55IC0gMTAgLy8gMTAgaXMgZm9yIHRoZSBiYXNlbGluZSAobGFiZWwgdnMgdGV4dClcblx0XHRcdFx0fTtcblx0XHRcdFx0ZGF0YUxhYmVsLmNvbm5YID0geDtcblx0XHRcdFx0ZGF0YUxhYmVsLmNvbm5ZID0geTtcblxuXG5cdFx0XHRcdC8vIERldGVjdCBvdmVyZmxvd2luZyBkYXRhIGxhYmVsc1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLnNpemUgPT09IG51bGwpIHtcblx0XHRcdFx0XHRkYXRhTGFiZWxXaWR0aCA9IGRhdGFMYWJlbC53aWR0aDtcblx0XHRcdFx0XHQvLyBPdmVyZmxvdyBsZWZ0XG5cdFx0XHRcdFx0aWYgKHggLSBkYXRhTGFiZWxXaWR0aCA8IGNvbm5lY3RvclBhZGRpbmcpIHtcblx0XHRcdFx0XHRcdG92ZXJmbG93WzNdID0gbWF0aE1heChtYXRoUm91bmQoZGF0YUxhYmVsV2lkdGggLSB4ICsgY29ubmVjdG9yUGFkZGluZyksIG92ZXJmbG93WzNdKTtcblxuXHRcdFx0XHRcdC8vIE92ZXJmbG93IHJpZ2h0XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh4ICsgZGF0YUxhYmVsV2lkdGggPiBwbG90V2lkdGggLSBjb25uZWN0b3JQYWRkaW5nKSB7XG5cdFx0XHRcdFx0XHRvdmVyZmxvd1sxXSA9IG1hdGhNYXgobWF0aFJvdW5kKHggKyBkYXRhTGFiZWxXaWR0aCAtIHBsb3RXaWR0aCArIGNvbm5lY3RvclBhZGRpbmcpLCBvdmVyZmxvd1sxXSk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gT3ZlcmZsb3cgdG9wXG5cdFx0XHRcdFx0aWYgKHkgLSBsYWJlbEhlaWdodCAvIDIgPCAwKSB7XG5cdFx0XHRcdFx0XHRvdmVyZmxvd1swXSA9IG1hdGhNYXgobWF0aFJvdW5kKC15ICsgbGFiZWxIZWlnaHQgLyAyKSwgb3ZlcmZsb3dbMF0pO1xuXG5cdFx0XHRcdFx0Ly8gT3ZlcmZsb3cgbGVmdFxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoeSArIGxhYmVsSGVpZ2h0IC8gMiA+IHBsb3RIZWlnaHQpIHtcblx0XHRcdFx0XHRcdG92ZXJmbG93WzJdID0gbWF0aE1heChtYXRoUm91bmQoeSArIGxhYmVsSGVpZ2h0IC8gMiAtIHBsb3RIZWlnaHQpLCBvdmVyZmxvd1syXSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9IC8vIGZvciBlYWNoIHBvaW50XG5cdFx0fSAvLyBmb3IgZWFjaCBoYWxmXG5cblx0XHQvLyBEbyBub3QgYXBwbHkgdGhlIGZpbmFsIHBsYWNlbWVudCBhbmQgZHJhdyB0aGUgY29ubmVjdG9ycyB1bnRpbCB3ZSBoYXZlIHZlcmlmaWVkXG5cdFx0Ly8gdGhhdCBsYWJlbHMgYXJlIG5vdCBzcGlsbGluZyBvdmVyLlxuXHRcdGlmIChhcnJheU1heChvdmVyZmxvdykgPT09IDAgfHwgdGhpcy52ZXJpZnlEYXRhTGFiZWxPdmVyZmxvdyhvdmVyZmxvdykpIHtcblxuXHRcdFx0Ly8gUGxhY2UgdGhlIGxhYmVscyBpbiB0aGUgZmluYWwgcG9zaXRpb25cblx0XHRcdHRoaXMucGxhY2VEYXRhTGFiZWxzKCk7XG5cblx0XHRcdC8vIERyYXcgdGhlIGNvbm5lY3RvcnNcblx0XHRcdGlmIChvdXRzaWRlICYmIGNvbm5lY3RvcldpZHRoKSB7XG5cdFx0XHRcdGVhY2godGhpcy5wb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0XHRcdGNvbm5lY3RvciA9IHBvaW50LmNvbm5lY3Rvcjtcblx0XHRcdFx0XHRsYWJlbFBvcyA9IHBvaW50LmxhYmVsUG9zO1xuXHRcdFx0XHRcdGRhdGFMYWJlbCA9IHBvaW50LmRhdGFMYWJlbDtcblxuXHRcdFx0XHRcdGlmIChkYXRhTGFiZWwgJiYgZGF0YUxhYmVsLl9wb3MpIHtcblx0XHRcdFx0XHRcdHZpc2liaWxpdHkgPSBkYXRhTGFiZWwuX2F0dHIudmlzaWJpbGl0eTtcblx0XHRcdFx0XHRcdHggPSBkYXRhTGFiZWwuY29ublg7XG5cdFx0XHRcdFx0XHR5ID0gZGF0YUxhYmVsLmNvbm5ZO1xuXHRcdFx0XHRcdFx0Y29ubmVjdG9yUGF0aCA9IHNvZnRDb25uZWN0b3IgPyBbXG5cdFx0XHRcdFx0XHRcdE0sXG5cdFx0XHRcdFx0XHRcdHggKyAobGFiZWxQb3NbNl0gPT09ICdsZWZ0JyA/IDUgOiAtNSksIHksIC8vIGVuZCBvZiB0aGUgc3RyaW5nIGF0IHRoZSBsYWJlbFxuXHRcdFx0XHRcdFx0XHQnQycsXG5cdFx0XHRcdFx0XHRcdHgsIHksIC8vIGZpcnN0IGJyZWFrLCBuZXh0IHRvIHRoZSBsYWJlbFxuXHRcdFx0XHRcdFx0XHQyICogbGFiZWxQb3NbMl0gLSBsYWJlbFBvc1s0XSwgMiAqIGxhYmVsUG9zWzNdIC0gbGFiZWxQb3NbNV0sXG5cdFx0XHRcdFx0XHRcdGxhYmVsUG9zWzJdLCBsYWJlbFBvc1szXSwgLy8gc2Vjb25kIGJyZWFrXG5cdFx0XHRcdFx0XHRcdEwsXG5cdFx0XHRcdFx0XHRcdGxhYmVsUG9zWzRdLCBsYWJlbFBvc1s1XSAvLyBiYXNlXG5cdFx0XHRcdFx0XHRdIDogW1xuXHRcdFx0XHRcdFx0XHRNLFxuXHRcdFx0XHRcdFx0XHR4ICsgKGxhYmVsUG9zWzZdID09PSAnbGVmdCcgPyA1IDogLTUpLCB5LCAvLyBlbmQgb2YgdGhlIHN0cmluZyBhdCB0aGUgbGFiZWxcblx0XHRcdFx0XHRcdFx0TCxcblx0XHRcdFx0XHRcdFx0bGFiZWxQb3NbMl0sIGxhYmVsUG9zWzNdLCAvLyBzZWNvbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0TCxcblx0XHRcdFx0XHRcdFx0bGFiZWxQb3NbNF0sIGxhYmVsUG9zWzVdIC8vIGJhc2Vcblx0XHRcdFx0XHRcdF07XG5cblx0XHRcdFx0XHRcdGlmIChjb25uZWN0b3IpIHtcblx0XHRcdFx0XHRcdFx0Y29ubmVjdG9yLmFuaW1hdGUoeyBkOiBjb25uZWN0b3JQYXRoIH0pO1xuXHRcdFx0XHRcdFx0XHRjb25uZWN0b3IuYXR0cigndmlzaWJpbGl0eScsIHZpc2liaWxpdHkpO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRwb2ludC5jb25uZWN0b3IgPSBjb25uZWN0b3IgPSBzZXJpZXMuY2hhcnQucmVuZGVyZXIucGF0aChjb25uZWN0b3JQYXRoKS5hdHRyKHtcblx0XHRcdFx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogY29ubmVjdG9yV2lkdGgsXG5cdFx0XHRcdFx0XHRcdFx0c3Ryb2tlOiBvcHRpb25zLmNvbm5lY3RvckNvbG9yIHx8IHBvaW50LmNvbG9yIHx8ICcjNjA2MDYwJyxcblx0XHRcdFx0XHRcdFx0XHR2aXNpYmlsaXR5OiB2aXNpYmlsaXR5XG5cdFx0XHRcdFx0XHRcdFx0Ly96SW5kZXg6IDAgLy8gIzI3MjIgKHJldmVyc2VkKVxuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQuYWRkKHNlcmllcy5kYXRhTGFiZWxzR3JvdXApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoY29ubmVjdG9yKSB7XG5cdFx0XHRcdFx0XHRwb2ludC5jb25uZWN0b3IgPSBjb25uZWN0b3IuZGVzdHJveSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXHQvKipcblx0ICogUGVyZm9ybSB0aGUgZmluYWwgcGxhY2VtZW50IG9mIHRoZSBkYXRhIGxhYmVscyBhZnRlciB3ZSBoYXZlIHZlcmlmaWVkIHRoYXQgdGhleVxuXHQgKiBmYWxsIHdpdGhpbiB0aGUgcGxvdCBhcmVhLlxuXHQgKi9cblx0c2VyaWVzVHlwZXMucGllLnByb3RvdHlwZS5wbGFjZURhdGFMYWJlbHMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0ZWFjaCh0aGlzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHR2YXIgZGF0YUxhYmVsID0gcG9pbnQuZGF0YUxhYmVsLFxuXHRcdFx0XHRfcG9zO1xuXG5cdFx0XHRpZiAoZGF0YUxhYmVsKSB7XG5cdFx0XHRcdF9wb3MgPSBkYXRhTGFiZWwuX3Bvcztcblx0XHRcdFx0aWYgKF9wb3MpIHtcblx0XHRcdFx0XHRkYXRhTGFiZWwuYXR0cihkYXRhTGFiZWwuX2F0dHIpO1xuXHRcdFx0XHRcdGRhdGFMYWJlbFtkYXRhTGFiZWwubW92ZWQgPyAnYW5pbWF0ZScgOiAnYXR0ciddKF9wb3MpO1xuXHRcdFx0XHRcdGRhdGFMYWJlbC5tb3ZlZCA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSBpZiAoZGF0YUxhYmVsKSB7XG5cdFx0XHRcdFx0ZGF0YUxhYmVsLmF0dHIoeyB5OiAtOTk5IH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH07XG5cblx0c2VyaWVzVHlwZXMucGllLnByb3RvdHlwZS5hbGlnbkRhdGFMYWJlbCA9ICBub29wO1xuXG5cdC8qKlxuXHQgKiBWZXJpZnkgd2hldGhlciB0aGUgZGF0YSBsYWJlbHMgYXJlIGFsbG93ZWQgdG8gZHJhdywgb3Igd2Ugc2hvdWxkIHJ1biBtb3JlIHRyYW5zbGF0aW9uIGFuZCBkYXRhXG5cdCAqIGxhYmVsIHBvc2l0aW9uaW5nIHRvIGtlZXAgdGhlbSBpbnNpZGUgdGhlIHBsb3QgYXJlYS4gUmV0dXJucyB0cnVlIHdoZW4gZGF0YSBsYWJlbHMgYXJlIHJlYWR5XG5cdCAqIHRvIGRyYXcuXG5cdCAqL1xuXHRzZXJpZXNUeXBlcy5waWUucHJvdG90eXBlLnZlcmlmeURhdGFMYWJlbE92ZXJmbG93ID0gZnVuY3Rpb24gKG92ZXJmbG93KSB7XG5cblx0XHR2YXIgY2VudGVyID0gdGhpcy5jZW50ZXIsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0Y2VudGVyT3B0aW9uID0gb3B0aW9ucy5jZW50ZXIsXG5cdFx0XHRtaW5TaXplID0gb3B0aW9ucy5taW5TaXplIHx8IDgwLFxuXHRcdFx0bmV3U2l6ZSA9IG1pblNpemUsXG5cdFx0XHRyZXQ7XG5cblx0XHQvLyBIYW5kbGUgaG9yaXpvbnRhbCBzaXplIGFuZCBjZW50ZXJcblx0XHRpZiAoY2VudGVyT3B0aW9uWzBdICE9PSBudWxsKSB7IC8vIEZpeGVkIGNlbnRlclxuXHRcdFx0bmV3U2l6ZSA9IG1hdGhNYXgoY2VudGVyWzJdIC0gbWF0aE1heChvdmVyZmxvd1sxXSwgb3ZlcmZsb3dbM10pLCBtaW5TaXplKTtcblxuXHRcdH0gZWxzZSB7IC8vIEF1dG8gY2VudGVyXG5cdFx0XHRuZXdTaXplID0gbWF0aE1heChcblx0XHRcdFx0Y2VudGVyWzJdIC0gb3ZlcmZsb3dbMV0gLSBvdmVyZmxvd1szXSwgLy8gaG9yaXpvbnRhbCBvdmVyZmxvd1xuXHRcdFx0XHRtaW5TaXplXG5cdFx0XHQpO1xuXHRcdFx0Y2VudGVyWzBdICs9IChvdmVyZmxvd1szXSAtIG92ZXJmbG93WzFdKSAvIDI7IC8vIGhvcml6b250YWwgY2VudGVyXG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIHZlcnRpY2FsIHNpemUgYW5kIGNlbnRlclxuXHRcdGlmIChjZW50ZXJPcHRpb25bMV0gIT09IG51bGwpIHsgLy8gRml4ZWQgY2VudGVyXG5cdFx0XHRuZXdTaXplID0gbWF0aE1heChtYXRoTWluKG5ld1NpemUsIGNlbnRlclsyXSAtIG1hdGhNYXgob3ZlcmZsb3dbMF0sIG92ZXJmbG93WzJdKSksIG1pblNpemUpO1xuXG5cdFx0fSBlbHNlIHsgLy8gQXV0byBjZW50ZXJcblx0XHRcdG5ld1NpemUgPSBtYXRoTWF4KFxuXHRcdFx0XHRtYXRoTWluKFxuXHRcdFx0XHRcdG5ld1NpemUsXG5cdFx0XHRcdFx0Y2VudGVyWzJdIC0gb3ZlcmZsb3dbMF0gLSBvdmVyZmxvd1syXSAvLyB2ZXJ0aWNhbCBvdmVyZmxvd1xuXHRcdFx0XHQpLFxuXHRcdFx0XHRtaW5TaXplXG5cdFx0XHQpO1xuXHRcdFx0Y2VudGVyWzFdICs9IChvdmVyZmxvd1swXSAtIG92ZXJmbG93WzJdKSAvIDI7IC8vIHZlcnRpY2FsIGNlbnRlclxuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBzaXplIG11c3QgYmUgZGVjcmVhc2VkLCB3ZSBuZWVkIHRvIHJ1biB0cmFuc2xhdGUgYW5kIGRyYXdEYXRhTGFiZWxzIGFnYWluXG5cdFx0aWYgKG5ld1NpemUgPCBjZW50ZXJbMl0pIHtcblx0XHRcdGNlbnRlclsyXSA9IG5ld1NpemU7XG5cdFx0XHR0aGlzLnRyYW5zbGF0ZShjZW50ZXIpO1xuXHRcdFx0ZWFjaCh0aGlzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdGlmIChwb2ludC5kYXRhTGFiZWwpIHtcblx0XHRcdFx0XHRwb2ludC5kYXRhTGFiZWwuX3BvcyA9IG51bGw7IC8vIHJlc2V0XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAodGhpcy5kcmF3RGF0YUxhYmVscykge1xuXHRcdFx0XHR0aGlzLmRyYXdEYXRhTGFiZWxzKCk7XG5cdFx0XHR9XG5cdFx0Ly8gRWxzZSwgcmV0dXJuIHRydWUgdG8gaW5kaWNhdGUgdGhhdCB0aGUgcGllIGFuZCBpdHMgbGFiZWxzIGlzIHdpdGhpbiB0aGUgcGxvdCBhcmVhXG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH07XG59XG5cbmlmIChzZXJpZXNUeXBlcy5jb2x1bW4pIHtcblxuXHQvKipcblx0ICogT3ZlcnJpZGUgdGhlIGJhc2ljIGRhdGEgbGFiZWwgYWxpZ25tZW50IGJ5IGFkanVzdGluZyBmb3IgdGhlIHBvc2l0aW9uIG9mIHRoZSBjb2x1bW5cblx0ICovXG5cdHNlcmllc1R5cGVzLmNvbHVtbi5wcm90b3R5cGUuYWxpZ25EYXRhTGFiZWwgPSBmdW5jdGlvbiAocG9pbnQsIGRhdGFMYWJlbCwgb3B0aW9ucywgIGFsaWduVG8sIGlzTmV3KSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQsXG5cdFx0XHRkbEJveCA9IHBvaW50LmRsQm94IHx8IHBvaW50LnNoYXBlQXJncywgLy8gZGF0YSBsYWJlbCBib3ggZm9yIGFsaWdubWVudFxuXHRcdFx0YmVsb3cgPSBwb2ludC5iZWxvdyB8fCAocG9pbnQucGxvdFkgPiBwaWNrKHRoaXMudHJhbnNsYXRlZFRocmVzaG9sZCwgY2hhcnQucGxvdFNpemVZKSksXG5cdFx0XHRpbnNpZGUgPSBwaWNrKG9wdGlvbnMuaW5zaWRlLCAhIXRoaXMub3B0aW9ucy5zdGFja2luZyk7IC8vIGRyYXcgaXQgaW5zaWRlIHRoZSBib3g/XG5cblx0XHQvLyBBbGlnbiB0byB0aGUgY29sdW1uIGl0c2VsZiwgb3IgdGhlIHRvcCBvZiBpdFxuXHRcdGlmIChkbEJveCkgeyAvLyBBcmVhIHJhbmdlIHVzZXMgdGhpcyBtZXRob2QgYnV0IG5vdCBhbGlnblRvXG5cdFx0XHRhbGlnblRvID0gbWVyZ2UoZGxCb3gpO1xuXG5cdFx0XHRpZiAoaW52ZXJ0ZWQpIHtcblx0XHRcdFx0YWxpZ25UbyA9IHtcblx0XHRcdFx0XHR4OiBjaGFydC5wbG90V2lkdGggLSBhbGlnblRvLnkgLSBhbGlnblRvLmhlaWdodCxcblx0XHRcdFx0XHR5OiBjaGFydC5wbG90SGVpZ2h0IC0gYWxpZ25Uby54IC0gYWxpZ25Uby53aWR0aCxcblx0XHRcdFx0XHR3aWR0aDogYWxpZ25Uby5oZWlnaHQsXG5cdFx0XHRcdFx0aGVpZ2h0OiBhbGlnblRvLndpZHRoXG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXB1dGUgdGhlIGFsaWdubWVudCBib3hcblx0XHRcdGlmICghaW5zaWRlKSB7XG5cdFx0XHRcdGlmIChpbnZlcnRlZCkge1xuXHRcdFx0XHRcdGFsaWduVG8ueCArPSBiZWxvdyA/IDAgOiBhbGlnblRvLndpZHRoO1xuXHRcdFx0XHRcdGFsaWduVG8ud2lkdGggPSAwO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGFsaWduVG8ueSArPSBiZWxvdyA/IGFsaWduVG8uaGVpZ2h0IDogMDtcblx0XHRcdFx0XHRhbGlnblRvLmhlaWdodCA9IDA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblxuXHRcdC8vIFdoZW4gYWxpZ25tZW50IGlzIHVuZGVmaW5lZCAodHlwaWNhbGx5IGNvbHVtbnMgYW5kIGJhcnMpLCBkaXNwbGF5IHRoZSBpbmRpdmlkdWFsXG5cdFx0Ly8gcG9pbnQgYmVsb3cgb3IgYWJvdmUgdGhlIHBvaW50IGRlcGVuZGluZyBvbiB0aGUgdGhyZXNob2xkXG5cdFx0b3B0aW9ucy5hbGlnbiA9IHBpY2soXG5cdFx0XHRvcHRpb25zLmFsaWduLFxuXHRcdFx0IWludmVydGVkIHx8IGluc2lkZSA/ICdjZW50ZXInIDogYmVsb3cgPyAncmlnaHQnIDogJ2xlZnQnXG5cdFx0KTtcblx0XHRvcHRpb25zLnZlcnRpY2FsQWxpZ24gPSBwaWNrKFxuXHRcdFx0b3B0aW9ucy52ZXJ0aWNhbEFsaWduLFxuXHRcdFx0aW52ZXJ0ZWQgfHwgaW5zaWRlID8gJ21pZGRsZScgOiBiZWxvdyA/ICd0b3AnIDogJ2JvdHRvbSdcblx0XHQpO1xuXG5cdFx0Ly8gQ2FsbCB0aGUgcGFyZW50IG1ldGhvZFxuXHRcdFNlcmllcy5wcm90b3R5cGUuYWxpZ25EYXRhTGFiZWwuY2FsbCh0aGlzLCBwb2ludCwgZGF0YUxhYmVsLCBvcHRpb25zLCBhbGlnblRvLCBpc05ldyk7XG5cdH07XG59XG5cblxuXG4vKipcbiAqIFRyYWNrZXJNaXhpbiBmb3IgcG9pbnRzIGFuZCBncmFwaHNcbiAqL1xuXG52YXIgVHJhY2tlck1peGluID0gSGlnaGNoYXJ0cy5UcmFja2VyTWl4aW4gPSB7XG5cblx0ZHJhd1RyYWNrZXJQb2ludDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRwb2ludGVyID0gY2hhcnQucG9pbnRlcixcblx0XHRcdGN1cnNvciA9IHNlcmllcy5vcHRpb25zLmN1cnNvcixcblx0XHRcdGNzcyA9IGN1cnNvciAmJiB7IGN1cnNvcjogY3Vyc29yIH0sXG5cdFx0XHRvbk1vdXNlT3ZlciA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBlLnRhcmdldCxcblx0XHRcdFx0cG9pbnQ7XG5cblx0XHRcdFx0aWYgKGNoYXJ0LmhvdmVyU2VyaWVzICE9PSBzZXJpZXMpIHtcblx0XHRcdFx0XHRzZXJpZXMub25Nb3VzZU92ZXIoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHdoaWxlICh0YXJnZXQgJiYgIXBvaW50KSB7XG5cdFx0XHRcdFx0cG9pbnQgPSB0YXJnZXQucG9pbnQ7XG5cdFx0XHRcdFx0dGFyZ2V0ID0gdGFyZ2V0LnBhcmVudE5vZGU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAocG9pbnQgIT09IFVOREVGSU5FRCAmJiBwb2ludCAhPT0gY2hhcnQuaG92ZXJQb2ludCkgeyAvLyB1bmRlZmluZWQgb24gZ3JhcGggaW4gc2NhdHRlcmNoYXJ0XG5cdFx0XHRcdFx0cG9pbnQub25Nb3VzZU92ZXIoZSk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBBZGQgcmVmZXJlbmNlIHRvIHRoZSBwb2ludFxuXHRcdGVhY2goc2VyaWVzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRpZiAocG9pbnQuZ3JhcGhpYykge1xuXHRcdFx0XHRwb2ludC5ncmFwaGljLmVsZW1lbnQucG9pbnQgPSBwb2ludDtcblx0XHRcdH1cblx0XHRcdGlmIChwb2ludC5kYXRhTGFiZWwpIHtcblx0XHRcdFx0cG9pbnQuZGF0YUxhYmVsLmVsZW1lbnQucG9pbnQgPSBwb2ludDtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEFkZCB0aGUgZXZlbnQgbGlzdGVuZXJzLCB3ZSBuZWVkIHRvIGRvIHRoaXMgb25seSBvbmNlXG5cdFx0aWYgKCFzZXJpZXMuX2hhc1RyYWNraW5nKSB7XG5cdFx0XHRlYWNoKHNlcmllcy50cmFja2VyR3JvdXBzLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdGlmIChzZXJpZXNba2V5XSkgeyAvLyB3ZSBkb24ndCBhbHdheXMgaGF2ZSBkYXRhTGFiZWxzR3JvdXBcblx0XHRcdFx0XHRzZXJpZXNba2V5XVxuXHRcdFx0XHRcdFx0LmFkZENsYXNzKFBSRUZJWCArICd0cmFja2VyJylcblx0XHRcdFx0XHRcdC5vbignbW91c2VvdmVyJywgb25Nb3VzZU92ZXIpXG5cdFx0XHRcdFx0XHQub24oJ21vdXNlb3V0JywgZnVuY3Rpb24gKGUpIHsgcG9pbnRlci5vblRyYWNrZXJNb3VzZU91dChlKTsgfSlcblx0XHRcdFx0XHRcdC5jc3MoY3NzKTtcblx0XHRcdFx0XHRpZiAoaGFzVG91Y2gpIHtcblx0XHRcdFx0XHRcdHNlcmllc1trZXldLm9uKCd0b3VjaHN0YXJ0Jywgb25Nb3VzZU92ZXIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRzZXJpZXMuX2hhc1RyYWNraW5nID0gdHJ1ZTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIERyYXcgdGhlIHRyYWNrZXIgb2JqZWN0IHRoYXQgc2l0cyBhYm92ZSBhbGwgZGF0YSBsYWJlbHMgYW5kIG1hcmtlcnMgdG9cblx0ICogdHJhY2sgbW91c2UgZXZlbnRzIG9uIHRoZSBncmFwaCBvciBwb2ludHMuIEZvciB0aGUgbGluZSB0eXBlIGNoYXJ0c1xuXHQgKiB0aGUgdHJhY2tlciB1c2VzIHRoZSBzYW1lIGdyYXBoUGF0aCwgYnV0IHdpdGggYSBncmVhdGVyIHN0cm9rZSB3aWR0aFxuXHQgKiBmb3IgYmV0dGVyIGNvbnRyb2wuXG5cdCAqL1xuXHRkcmF3VHJhY2tlckdyYXBoOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHR0cmFja0J5QXJlYSA9IG9wdGlvbnMudHJhY2tCeUFyZWEsXG5cdFx0XHR0cmFja2VyUGF0aCA9IFtdLmNvbmNhdCh0cmFja0J5QXJlYSA/IHNlcmllcy5hcmVhUGF0aCA6IHNlcmllcy5ncmFwaFBhdGgpLFxuXHRcdFx0dHJhY2tlclBhdGhMZW5ndGggPSB0cmFja2VyUGF0aC5sZW5ndGgsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHBvaW50ZXIgPSBjaGFydC5wb2ludGVyLFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdHNuYXAgPSBjaGFydC5vcHRpb25zLnRvb2x0aXAuc25hcCxcblx0XHRcdHRyYWNrZXIgPSBzZXJpZXMudHJhY2tlcixcblx0XHRcdGN1cnNvciA9IG9wdGlvbnMuY3Vyc29yLFxuXHRcdFx0Y3NzID0gY3Vyc29yICYmIHsgY3Vyc29yOiBjdXJzb3IgfSxcblx0XHRcdHNpbmdsZVBvaW50cyA9IHNlcmllcy5zaW5nbGVQb2ludHMsXG5cdFx0XHRzaW5nbGVQb2ludCxcblx0XHRcdGksXG5cdFx0XHRvbk1vdXNlT3ZlciA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0aWYgKGNoYXJ0LmhvdmVyU2VyaWVzICE9PSBzZXJpZXMpIHtcblx0XHRcdFx0XHRzZXJpZXMub25Nb3VzZU92ZXIoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdC8qXG5cdFx0XHQgKiBFbXBpcmljYWwgbG93ZXN0IHBvc3NpYmxlIG9wYWNpdGllcyBmb3IgVFJBQ0tFUl9GSUxMIGZvciBhbiBlbGVtZW50IHRvIHN0YXkgaW52aXNpYmxlIGJ1dCBjbGlja2FibGVcblx0XHRcdCAqIElFNjogMC4wMDJcblx0XHRcdCAqIElFNzogMC4wMDJcblx0XHRcdCAqIElFODogMC4wMDJcblx0XHRcdCAqIElFOTogMC4wMDAwMDAwMDAwMSAodW5saW1pdGVkKVxuXHRcdFx0ICogSUUxMDogMC4wMDAxIChleHBvcnRpbmcgb25seSlcblx0XHRcdCAqIEZGOiAwLjAwMDAwMDAwMDAxICh1bmxpbWl0ZWQpXG5cdFx0XHQgKiBDaHJvbWU6IDAuMDAwMDAxXG5cdFx0XHQgKiBTYWZhcmk6IDAuMDAwMDAxXG5cdFx0XHQgKiBPcGVyYTogMC4wMDAwMDAwMDAwMSAodW5saW1pdGVkKVxuXHRcdFx0ICovXG5cdFx0XHRUUkFDS0VSX0ZJTEwgPSAncmdiYSgxOTIsMTkyLDE5MiwnICsgKGhhc1NWRyA/IDAuMDAwMSA6IDAuMDAyKSArICcpJztcblxuXHRcdC8vIEV4dGVuZCBlbmQgcG9pbnRzLiBBIGJldHRlciB3YXkgd291bGQgYmUgdG8gdXNlIHJvdW5kIGxpbmVjYXBzLFxuXHRcdC8vIGJ1dCB0aG9zZSBhcmUgbm90IGNsaWNrYWJsZSBpbiBWTUwuXG5cdFx0aWYgKHRyYWNrZXJQYXRoTGVuZ3RoICYmICF0cmFja0J5QXJlYSkge1xuXHRcdFx0aSA9IHRyYWNrZXJQYXRoTGVuZ3RoICsgMTtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0aWYgKHRyYWNrZXJQYXRoW2ldID09PSBNKSB7IC8vIGV4dGVuZCBsZWZ0IHNpZGVcblx0XHRcdFx0XHR0cmFja2VyUGF0aC5zcGxpY2UoaSArIDEsIDAsIHRyYWNrZXJQYXRoW2kgKyAxXSAtIHNuYXAsIHRyYWNrZXJQYXRoW2kgKyAyXSwgTCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKChpICYmIHRyYWNrZXJQYXRoW2ldID09PSBNKSB8fCBpID09PSB0cmFja2VyUGF0aExlbmd0aCkgeyAvLyBleHRlbmQgcmlnaHQgc2lkZVxuXHRcdFx0XHRcdHRyYWNrZXJQYXRoLnNwbGljZShpLCAwLCBMLCB0cmFja2VyUGF0aFtpIC0gMl0gKyBzbmFwLCB0cmFja2VyUGF0aFtpIC0gMV0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaGFuZGxlIHNpbmdsZSBwb2ludHNcblx0XHRmb3IgKGkgPSAwOyBpIDwgc2luZ2xlUG9pbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRzaW5nbGVQb2ludCA9IHNpbmdsZVBvaW50c1tpXTtcblx0XHRcdHRyYWNrZXJQYXRoLnB1c2goTSwgc2luZ2xlUG9pbnQucGxvdFggLSBzbmFwLCBzaW5nbGVQb2ludC5wbG90WSxcblx0XHRcdEwsIHNpbmdsZVBvaW50LnBsb3RYICsgc25hcCwgc2luZ2xlUG9pbnQucGxvdFkpO1xuXHRcdH1cblxuXHRcdC8vIGRyYXcgdGhlIHRyYWNrZXJcblx0XHRpZiAodHJhY2tlcikge1xuXHRcdFx0dHJhY2tlci5hdHRyKHsgZDogdHJhY2tlclBhdGggfSk7XG5cdFx0fSBlbHNlIHsgLy8gY3JlYXRlXG5cblx0XHRcdHNlcmllcy50cmFja2VyID0gcmVuZGVyZXIucGF0aCh0cmFja2VyUGF0aClcblx0XHRcdC5hdHRyKHtcblx0XHRcdFx0J3N0cm9rZS1saW5lam9pbic6ICdyb3VuZCcsIC8vICMxMjI1XG5cdFx0XHRcdHZpc2liaWxpdHk6IHNlcmllcy52aXNpYmxlID8gVklTSUJMRSA6IEhJRERFTixcblx0XHRcdFx0c3Ryb2tlOiBUUkFDS0VSX0ZJTEwsXG5cdFx0XHRcdGZpbGw6IHRyYWNrQnlBcmVhID8gVFJBQ0tFUl9GSUxMIDogTk9ORSxcblx0XHRcdFx0J3N0cm9rZS13aWR0aCcgOiBvcHRpb25zLmxpbmVXaWR0aCArICh0cmFja0J5QXJlYSA/IDAgOiAyICogc25hcCksXG5cdFx0XHRcdHpJbmRleDogMlxuXHRcdFx0fSlcblx0XHRcdC5hZGQoc2VyaWVzLmdyb3VwKTtcblxuXHRcdFx0Ly8gVGhlIHRyYWNrZXIgaXMgYWRkZWQgdG8gdGhlIHNlcmllcyBncm91cCwgd2hpY2ggaXMgY2xpcHBlZCwgYnV0IGlzIGNvdmVyZWRcblx0XHRcdC8vIGJ5IHRoZSBtYXJrZXIgZ3JvdXAuIFNvIHRoZSBtYXJrZXIgZ3JvdXAgYWxzbyBuZWVkcyB0byBjYXB0dXJlIGV2ZW50cy5cblx0XHRcdGVhY2goW3Nlcmllcy50cmFja2VyLCBzZXJpZXMubWFya2VyR3JvdXBdLCBmdW5jdGlvbiAodHJhY2tlcikge1xuXHRcdFx0XHR0cmFja2VyLmFkZENsYXNzKFBSRUZJWCArICd0cmFja2VyJylcblx0XHRcdFx0XHQub24oJ21vdXNlb3ZlcicsIG9uTW91c2VPdmVyKVxuXHRcdFx0XHRcdC5vbignbW91c2VvdXQnLCBmdW5jdGlvbiAoZSkgeyBwb2ludGVyLm9uVHJhY2tlck1vdXNlT3V0KGUpOyB9KVxuXHRcdFx0XHRcdC5jc3MoY3NzKTtcblxuXHRcdFx0XHRpZiAoaGFzVG91Y2gpIHtcblx0XHRcdFx0XHR0cmFja2VyLm9uKCd0b3VjaHN0YXJ0Jywgb25Nb3VzZU92ZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cbn07XG4vKiBFbmQgVHJhY2tlck1peGluICovXG5cblxuLyoqXG4gKiBBZGQgdHJhY2tpbmcgZXZlbnQgbGlzdGVuZXIgdG8gdGhlIHNlcmllcyBncm91cCwgc28gdGhlIHBvaW50IGdyYXBoaWNzXG4gKiB0aGVtc2VsdmVzIGFjdCBhcyB0cmFja2Vyc1xuICovIFxuXG5pZiAoc2VyaWVzVHlwZXMuY29sdW1uKSB7XG5cdENvbHVtblNlcmllcy5wcm90b3R5cGUuZHJhd1RyYWNrZXIgPSBUcmFja2VyTWl4aW4uZHJhd1RyYWNrZXJQb2ludDtcdFxufVxuXG5pZiAoc2VyaWVzVHlwZXMucGllKSB7XG5cdHNlcmllc1R5cGVzLnBpZS5wcm90b3R5cGUuZHJhd1RyYWNrZXIgPSBUcmFja2VyTWl4aW4uZHJhd1RyYWNrZXJQb2ludDtcbn1cblxuaWYgKHNlcmllc1R5cGVzLnNjYXR0ZXIpIHtcblx0U2NhdHRlclNlcmllcy5wcm90b3R5cGUuZHJhd1RyYWNrZXIgPSBUcmFja2VyTWl4aW4uZHJhd1RyYWNrZXJQb2ludDtcbn1cblxuLyogXG4gKiBFeHRlbmQgTGVnZW5kIGZvciBpdGVtIGV2ZW50cyBcbiAqLyBcbmV4dGVuZChMZWdlbmQucHJvdG90eXBlLCB7XG5cblx0c2V0SXRlbUV2ZW50czogZnVuY3Rpb24gKGl0ZW0sIGxlZ2VuZEl0ZW0sIHVzZUhUTUwsIGl0ZW1TdHlsZSwgaXRlbUhpZGRlblN0eWxlKSB7XG5cdHZhciBsZWdlbmQgPSB0aGlzO1xuXHQvLyBTZXQgdGhlIGV2ZW50cyBvbiB0aGUgaXRlbSBncm91cCwgb3IgaW4gY2FzZSBvZiB1c2VIVE1MLCB0aGUgaXRlbSBpdHNlbGYgKCMxMjQ5KVxuXHQodXNlSFRNTCA/IGxlZ2VuZEl0ZW0gOiBpdGVtLmxlZ2VuZEdyb3VwKS5vbignbW91c2VvdmVyJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0aXRlbS5zZXRTdGF0ZShIT1ZFUl9TVEFURSk7XG5cdFx0XHRsZWdlbmRJdGVtLmNzcyhsZWdlbmQub3B0aW9ucy5pdGVtSG92ZXJTdHlsZSk7XG5cdFx0fSlcblx0XHQub24oJ21vdXNlb3V0JywgZnVuY3Rpb24gKCkge1xuXHRcdFx0bGVnZW5kSXRlbS5jc3MoaXRlbS52aXNpYmxlID8gaXRlbVN0eWxlIDogaXRlbUhpZGRlblN0eWxlKTtcblx0XHRcdGl0ZW0uc2V0U3RhdGUoKTtcblx0XHR9KVxuXHRcdC5vbignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcblx0XHRcdHZhciBzdHJMZWdlbmRJdGVtQ2xpY2sgPSAnbGVnZW5kSXRlbUNsaWNrJyxcblx0XHRcdFx0Zm5MZWdlbmRJdGVtQ2xpY2sgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0aXRlbS5zZXRWaXNpYmxlKCk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdFxuXHRcdFx0Ly8gUGFzcyBvdmVyIHRoZSBjbGljay90b3VjaCBldmVudC4gIzQuXG5cdFx0XHRldmVudCA9IHtcblx0XHRcdFx0YnJvd3NlckV2ZW50OiBldmVudFxuXHRcdFx0fTtcblxuXHRcdFx0Ly8gY2xpY2sgdGhlIG5hbWUgb3Igc3ltYm9sXG5cdFx0XHRpZiAoaXRlbS5maXJlUG9pbnRFdmVudCkgeyAvLyBwb2ludFxuXHRcdFx0XHRpdGVtLmZpcmVQb2ludEV2ZW50KHN0ckxlZ2VuZEl0ZW1DbGljaywgZXZlbnQsIGZuTGVnZW5kSXRlbUNsaWNrKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZpcmVFdmVudChpdGVtLCBzdHJMZWdlbmRJdGVtQ2xpY2ssIGV2ZW50LCBmbkxlZ2VuZEl0ZW1DbGljayk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0Y3JlYXRlQ2hlY2tib3hGb3JJdGVtOiBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzO1xuXG5cdFx0aXRlbS5jaGVja2JveCA9IGNyZWF0ZUVsZW1lbnQoJ2lucHV0Jywge1xuXHRcdFx0dHlwZTogJ2NoZWNrYm94Jyxcblx0XHRcdGNoZWNrZWQ6IGl0ZW0uc2VsZWN0ZWQsXG5cdFx0XHRkZWZhdWx0Q2hlY2tlZDogaXRlbS5zZWxlY3RlZCAvLyByZXF1aXJlZCBieSBJRTdcblx0XHR9LCBsZWdlbmQub3B0aW9ucy5pdGVtQ2hlY2tib3hTdHlsZSwgbGVnZW5kLmNoYXJ0LmNvbnRhaW5lcik7XG5cblx0XHRhZGRFdmVudChpdGVtLmNoZWNrYm94LCAnY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcblx0XHRcdHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG5cdFx0XHRmaXJlRXZlbnQoaXRlbSwgJ2NoZWNrYm94Q2xpY2snLCB7XG5cdFx0XHRcdFx0Y2hlY2tlZDogdGFyZ2V0LmNoZWNrZWRcblx0XHRcdFx0fSxcblx0XHRcdFx0ZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdGl0ZW0uc2VsZWN0KCk7XG5cdFx0XHRcdH1cblx0XHRcdCk7XG5cdFx0fSk7XG5cdH1cdFxufSk7XG5cbi8qIFxuICogQWRkIHBvaW50ZXIgY3Vyc29yIHRvIGxlZ2VuZCBpdGVtc3R5bGUgaW4gZGVmYXVsdE9wdGlvbnNcbiAqL1xuZGVmYXVsdE9wdGlvbnMubGVnZW5kLml0ZW1TdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG5cblxuLyogXG4gKiBFeHRlbmQgdGhlIENoYXJ0IG9iamVjdCB3aXRoIGludGVyYWN0aW9uXG4gKi9cblxuZXh0ZW5kKENoYXJ0LnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogRGlzcGxheSB0aGUgem9vbSBidXR0b25cblx0ICovXG5cdHNob3dSZXNldFpvb206IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0bGFuZyA9IGRlZmF1bHRPcHRpb25zLmxhbmcsXG5cdFx0XHRidG5PcHRpb25zID0gY2hhcnQub3B0aW9ucy5jaGFydC5yZXNldFpvb21CdXR0b24sXG5cdFx0XHR0aGVtZSA9IGJ0bk9wdGlvbnMudGhlbWUsXG5cdFx0XHRzdGF0ZXMgPSB0aGVtZS5zdGF0ZXMsXG5cdFx0XHRhbGlnblRvID0gYnRuT3B0aW9ucy5yZWxhdGl2ZVRvID09PSAnY2hhcnQnID8gbnVsbCA6ICdwbG90Qm94Jztcblx0XHRcdFxuXHRcdHRoaXMucmVzZXRab29tQnV0dG9uID0gY2hhcnQucmVuZGVyZXIuYnV0dG9uKGxhbmcucmVzZXRab29tLCBudWxsLCBudWxsLCBmdW5jdGlvbiAoKSB7IGNoYXJ0Lnpvb21PdXQoKTsgfSwgdGhlbWUsIHN0YXRlcyAmJiBzdGF0ZXMuaG92ZXIpXG5cdFx0XHQuYXR0cih7XG5cdFx0XHRcdGFsaWduOiBidG5PcHRpb25zLnBvc2l0aW9uLmFsaWduLFxuXHRcdFx0XHR0aXRsZTogbGFuZy5yZXNldFpvb21UaXRsZVxuXHRcdFx0fSlcblx0XHRcdC5hZGQoKVxuXHRcdFx0LmFsaWduKGJ0bk9wdGlvbnMucG9zaXRpb24sIGZhbHNlLCBhbGlnblRvKTtcblx0XHRcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBab29tIG91dCB0byAxOjFcblx0ICovXG5cdHpvb21PdXQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzO1xuXHRcdGZpcmVFdmVudChjaGFydCwgJ3NlbGVjdGlvbicsIHsgcmVzZXRTZWxlY3Rpb246IHRydWUgfSwgZnVuY3Rpb24gKCkgeyBcblx0XHRcdGNoYXJ0Lnpvb20oKTtcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogWm9vbSBpbnRvIGEgZ2l2ZW4gcG9ydGlvbiBvZiB0aGUgY2hhcnQgZ2l2ZW4gYnkgYXhpcyBjb29yZGluYXRlc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcblx0ICovXG5cdHpvb206IGZ1bmN0aW9uIChldmVudCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRoYXNab29tZWQsXG5cdFx0XHRwb2ludGVyID0gY2hhcnQucG9pbnRlcixcblx0XHRcdGRpc3BsYXlCdXR0b24gPSBmYWxzZSxcblx0XHRcdHJlc2V0Wm9vbUJ1dHRvbjtcblxuXHRcdC8vIElmIHpvb20gaXMgY2FsbGVkIHdpdGggbm8gYXJndW1lbnRzLCByZXNldCB0aGUgYXhlc1xuXHRcdGlmICghZXZlbnQgfHwgZXZlbnQucmVzZXRTZWxlY3Rpb24pIHtcblx0XHRcdGVhY2goY2hhcnQuYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0aGFzWm9vbWVkID0gYXhpcy56b29tKCk7XG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgeyAvLyBlbHNlLCB6b29tIGluIG9uIGFsbCBheGVzXG5cdFx0XHRlYWNoKGV2ZW50LnhBeGlzLmNvbmNhdChldmVudC55QXhpcyksIGZ1bmN0aW9uIChheGlzRGF0YSkge1xuXHRcdFx0XHR2YXIgYXhpcyA9IGF4aXNEYXRhLmF4aXMsXG5cdFx0XHRcdFx0aXNYQXhpcyA9IGF4aXMuaXNYQXhpcztcblxuXHRcdFx0XHQvLyBkb24ndCB6b29tIG1vcmUgdGhhbiBtaW5SYW5nZVxuXHRcdFx0XHRpZiAocG9pbnRlcltpc1hBeGlzID8gJ3pvb21YJyA6ICd6b29tWSddIHx8IHBvaW50ZXJbaXNYQXhpcyA/ICdwaW5jaFgnIDogJ3BpbmNoWSddKSB7XG5cdFx0XHRcdFx0aGFzWm9vbWVkID0gYXhpcy56b29tKGF4aXNEYXRhLm1pbiwgYXhpc0RhdGEubWF4KTtcblx0XHRcdFx0XHRpZiAoYXhpcy5kaXNwbGF5QnRuKSB7XG5cdFx0XHRcdFx0XHRkaXNwbGF5QnV0dG9uID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRcblx0XHQvLyBTaG93IG9yIGhpZGUgdGhlIFJlc2V0IHpvb20gYnV0dG9uXG5cdFx0cmVzZXRab29tQnV0dG9uID0gY2hhcnQucmVzZXRab29tQnV0dG9uO1xuXHRcdGlmIChkaXNwbGF5QnV0dG9uICYmICFyZXNldFpvb21CdXR0b24pIHtcblx0XHRcdGNoYXJ0LnNob3dSZXNldFpvb20oKTtcblx0XHR9IGVsc2UgaWYgKCFkaXNwbGF5QnV0dG9uICYmIGlzT2JqZWN0KHJlc2V0Wm9vbUJ1dHRvbikpIHtcblx0XHRcdGNoYXJ0LnJlc2V0Wm9vbUJ1dHRvbiA9IHJlc2V0Wm9vbUJ1dHRvbi5kZXN0cm95KCk7XG5cdFx0fVxuXHRcdFxuXG5cdFx0Ly8gUmVkcmF3XG5cdFx0aWYgKGhhc1pvb21lZCkge1xuXHRcdFx0Y2hhcnQucmVkcmF3KFxuXHRcdFx0XHRwaWNrKGNoYXJ0Lm9wdGlvbnMuY2hhcnQuYW5pbWF0aW9uLCBldmVudCAmJiBldmVudC5hbmltYXRpb24sIGNoYXJ0LnBvaW50Q291bnQgPCAxMDApIC8vIGFuaW1hdGlvblxuXHRcdFx0KTtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFBhbiB0aGUgY2hhcnQgYnkgZHJhZ2dpbmcgdGhlIG1vdXNlIGFjcm9zcyB0aGUgcGFuZS4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWRcblx0ICogb24gbW91c2UgbW92ZSwgYW5kIHRoZSBkaXN0YW5jZSB0byBwYW4gaXMgY29tcHV0ZWQgZnJvbSBjaGFydFggY29tcGFyZWQgdG9cblx0ICogdGhlIGZpcnN0IGNoYXJ0WCBwb3NpdGlvbiBpbiB0aGUgZHJhZ2dpbmcgb3BlcmF0aW9uLlxuXHQgKi9cblx0cGFuOiBmdW5jdGlvbiAoZSwgcGFubmluZykge1xuXG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGhvdmVyUG9pbnRzID0gY2hhcnQuaG92ZXJQb2ludHMsXG5cdFx0XHRkb1JlZHJhdztcblxuXHRcdC8vIHJlbW92ZSBhY3RpdmUgcG9pbnRzIGZvciBzaGFyZWQgdG9vbHRpcFxuXHRcdGlmIChob3ZlclBvaW50cykge1xuXHRcdFx0ZWFjaChob3ZlclBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdHBvaW50LnNldFN0YXRlKCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRlYWNoKHBhbm5pbmcgPT09ICd4eScgPyBbMSwgMF0gOiBbMV0sIGZ1bmN0aW9uIChpc1gpIHsgLy8geHkgaXMgdXNlZCBpbiBtYXBzXG5cdFx0XHR2YXIgbW91c2VQb3MgPSBlW2lzWCA/ICdjaGFydFgnIDogJ2NoYXJ0WSddLFxuXHRcdFx0XHRheGlzID0gY2hhcnRbaXNYID8gJ3hBeGlzJyA6ICd5QXhpcyddWzBdLFxuXHRcdFx0XHRzdGFydFBvcyA9IGNoYXJ0W2lzWCA/ICdtb3VzZURvd25YJyA6ICdtb3VzZURvd25ZJ10sXG5cdFx0XHRcdGhhbGZQb2ludFJhbmdlID0gKGF4aXMucG9pbnRSYW5nZSB8fCAwKSAvIDIsXG5cdFx0XHRcdGV4dHJlbWVzID0gYXhpcy5nZXRFeHRyZW1lcygpLFxuXHRcdFx0XHRuZXdNaW4gPSBheGlzLnRvVmFsdWUoc3RhcnRQb3MgLSBtb3VzZVBvcywgdHJ1ZSkgKyBoYWxmUG9pbnRSYW5nZSxcblx0XHRcdFx0bmV3TWF4ID0gYXhpcy50b1ZhbHVlKHN0YXJ0UG9zICsgY2hhcnRbaXNYID8gJ3Bsb3RXaWR0aCcgOiAncGxvdEhlaWdodCddIC0gbW91c2VQb3MsIHRydWUpIC0gaGFsZlBvaW50UmFuZ2U7XG5cblx0XHRcdGlmIChheGlzLnNlcmllcy5sZW5ndGggJiYgbmV3TWluID4gbWF0aE1pbihleHRyZW1lcy5kYXRhTWluLCBleHRyZW1lcy5taW4pICYmIG5ld01heCA8IG1hdGhNYXgoZXh0cmVtZXMuZGF0YU1heCwgZXh0cmVtZXMubWF4KSkge1xuXHRcdFx0XHRheGlzLnNldEV4dHJlbWVzKG5ld01pbiwgbmV3TWF4LCBmYWxzZSwgZmFsc2UsIHsgdHJpZ2dlcjogJ3BhbicgfSk7XG5cdFx0XHRcdGRvUmVkcmF3ID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0Y2hhcnRbaXNYID8gJ21vdXNlRG93blgnIDogJ21vdXNlRG93blknXSA9IG1vdXNlUG9zOyAvLyBzZXQgbmV3IHJlZmVyZW5jZSBmb3IgbmV4dCBydW5cblx0XHR9KTtcblxuXHRcdGlmIChkb1JlZHJhdykge1xuXHRcdFx0Y2hhcnQucmVkcmF3KGZhbHNlKTtcblx0XHR9XG5cdFx0Y3NzKGNoYXJ0LmNvbnRhaW5lciwgeyBjdXJzb3I6ICdtb3ZlJyB9KTtcblx0fVxufSk7XG5cbi8qXG4gKiBFeHRlbmQgdGhlIFBvaW50IG9iamVjdCB3aXRoIGludGVyYWN0aW9uXG4gKi9cbmV4dGVuZChQb2ludC5wcm90b3R5cGUsIHtcblx0LyoqXG5cdCAqIFRvZ2dsZSB0aGUgc2VsZWN0aW9uIHN0YXR1cyBvZiBhIHBvaW50XG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gc2VsZWN0ZWQgV2hldGhlciB0byBzZWxlY3Qgb3IgdW5zZWxlY3QgdGhlIHBvaW50LlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IGFjY3VtdWxhdGUgV2hldGhlciB0byBhZGQgdG8gdGhlIHByZXZpb3VzIHNlbGVjdGlvbi4gQnkgZGVmYXVsdCxcblx0ICpcdFx0IHRoaXMgaGFwcGVucyBpZiB0aGUgY29udHJvbCBrZXkgKENtZCBvbiBNYWMpIHdhcyBwcmVzc2VkIGR1cmluZyBjbGlja2luZy5cblx0ICovXG5cdHNlbGVjdDogZnVuY3Rpb24gKHNlbGVjdGVkLCBhY2N1bXVsYXRlKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0O1xuXG5cdFx0c2VsZWN0ZWQgPSBwaWNrKHNlbGVjdGVkLCAhcG9pbnQuc2VsZWN0ZWQpO1xuXG5cdFx0Ly8gZmlyZSB0aGUgZXZlbnQgd2l0aCB0aGUgZGVmYWx1dCBoYW5kbGVyXG5cdFx0cG9pbnQuZmlyZVBvaW50RXZlbnQoc2VsZWN0ZWQgPyAnc2VsZWN0JyA6ICd1bnNlbGVjdCcsIHsgYWNjdW11bGF0ZTogYWNjdW11bGF0ZSB9LCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRwb2ludC5zZWxlY3RlZCA9IHBvaW50Lm9wdGlvbnMuc2VsZWN0ZWQgPSBzZWxlY3RlZDtcblx0XHRcdHNlcmllcy5vcHRpb25zLmRhdGFbaW5BcnJheShwb2ludCwgc2VyaWVzLmRhdGEpXSA9IHBvaW50Lm9wdGlvbnM7XG5cblx0XHRcdHBvaW50LnNldFN0YXRlKHNlbGVjdGVkICYmIFNFTEVDVF9TVEFURSk7XG5cblx0XHRcdC8vIHVuc2VsZWN0IGFsbCBvdGhlciBwb2ludHMgdW5sZXNzIEN0cmwgb3IgQ21kICsgY2xpY2tcblx0XHRcdGlmICghYWNjdW11bGF0ZSkge1xuXHRcdFx0XHRlYWNoKGNoYXJ0LmdldFNlbGVjdGVkUG9pbnRzKCksIGZ1bmN0aW9uIChsb29wUG9pbnQpIHtcblx0XHRcdFx0XHRpZiAobG9vcFBvaW50LnNlbGVjdGVkICYmIGxvb3BQb2ludCAhPT0gcG9pbnQpIHtcblx0XHRcdFx0XHRcdGxvb3BQb2ludC5zZWxlY3RlZCA9IGxvb3BQb2ludC5vcHRpb25zLnNlbGVjdGVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRzZXJpZXMub3B0aW9ucy5kYXRhW2luQXJyYXkobG9vcFBvaW50LCBzZXJpZXMuZGF0YSldID0gbG9vcFBvaW50Lm9wdGlvbnM7XG5cdFx0XHRcdFx0XHRsb29wUG9pbnQuc2V0U3RhdGUoTk9STUFMX1NUQVRFKTtcblx0XHRcdFx0XHRcdFx0bG9vcFBvaW50LmZpcmVQb2ludEV2ZW50KCd1bnNlbGVjdCcpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJ1bnMgb24gbW91c2Ugb3ZlciB0aGUgcG9pbnRcblx0ICovXG5cdG9uTW91c2VPdmVyOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHRvb2x0aXAgPSBjaGFydC50b29sdGlwLFxuXHRcdFx0aG92ZXJQb2ludCA9IGNoYXJ0LmhvdmVyUG9pbnQ7XG5cblx0XHQvLyBzZXQgbm9ybWFsIHN0YXRlIHRvIHByZXZpb3VzIHNlcmllc1xuXHRcdGlmIChob3ZlclBvaW50ICYmIGhvdmVyUG9pbnQgIT09IHBvaW50KSB7XG5cdFx0XHRob3ZlclBvaW50Lm9uTW91c2VPdXQoKTtcblx0XHR9XG5cblx0XHQvLyB0cmlnZ2VyIHRoZSBldmVudFxuXHRcdHBvaW50LmZpcmVQb2ludEV2ZW50KCdtb3VzZU92ZXInKTtcblxuXHRcdC8vIHVwZGF0ZSB0aGUgdG9vbHRpcFxuXHRcdGlmICh0b29sdGlwICYmICghdG9vbHRpcC5zaGFyZWQgfHwgc2VyaWVzLm5vU2hhcmVkVG9vbHRpcCkpIHtcblx0XHRcdHRvb2x0aXAucmVmcmVzaChwb2ludCwgZSk7XG5cdFx0fVxuXG5cdFx0Ly8gaG92ZXIgdGhpc1xuXHRcdHBvaW50LnNldFN0YXRlKEhPVkVSX1NUQVRFKTtcblx0XHRjaGFydC5ob3ZlclBvaW50ID0gcG9pbnQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJ1bnMgb24gbW91c2Ugb3V0IGZyb20gdGhlIHBvaW50XG5cdCAqL1xuXHRvbk1vdXNlT3V0OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5zZXJpZXMuY2hhcnQsXG5cdFx0XHRob3ZlclBvaW50cyA9IGNoYXJ0LmhvdmVyUG9pbnRzO1xuXG5cdFx0dGhpcy5maXJlUG9pbnRFdmVudCgnbW91c2VPdXQnKTtcblxuXHRcdGlmICghaG92ZXJQb2ludHMgfHwgaW5BcnJheSh0aGlzLCBob3ZlclBvaW50cykgPT09IC0xKSB7IC8vICM4ODcsICMyMjQwXG5cdFx0XHR0aGlzLnNldFN0YXRlKCk7XG5cdFx0XHRjaGFydC5ob3ZlclBvaW50ID0gbnVsbDtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEltcG9ydCBldmVudHMgZnJvbSB0aGUgc2VyaWVzJyBhbmQgcG9pbnQncyBvcHRpb25zLiBPbmx5IGRvIGl0IG9uXG5cdCAqIGRlbWFuZCwgdG8gc2F2ZSBwcm9jZXNzaW5nIHRpbWUgb24gaG92ZXJpbmcuXG5cdCAqL1xuXHRpbXBvcnRFdmVudHM6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAoIXRoaXMuaGFzSW1wb3J0ZWRFdmVudHMpIHtcblx0XHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRcdG9wdGlvbnMgPSBtZXJnZShwb2ludC5zZXJpZXMub3B0aW9ucy5wb2ludCwgcG9pbnQub3B0aW9ucyksXG5cdFx0XHRcdGV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzLFxuXHRcdFx0XHRldmVudFR5cGU7XG5cblx0XHRcdHBvaW50LmV2ZW50cyA9IGV2ZW50cztcblxuXHRcdFx0Zm9yIChldmVudFR5cGUgaW4gZXZlbnRzKSB7XG5cdFx0XHRcdGFkZEV2ZW50KHBvaW50LCBldmVudFR5cGUsIGV2ZW50c1tldmVudFR5cGVdKTtcblx0XHRcdH1cblx0XHRcdHRoaXMuaGFzSW1wb3J0ZWRFdmVudHMgPSB0cnVlO1xuXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHBvaW50J3Mgc3RhdGVcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0YXRlXG5cdCAqL1xuXHRzZXRTdGF0ZTogZnVuY3Rpb24gKHN0YXRlLCBtb3ZlKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHBsb3RYID0gcG9pbnQucGxvdFgsXG5cdFx0XHRwbG90WSA9IHBvaW50LnBsb3RZLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0c3RhdGVPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMuc3RhdGVzLFxuXHRcdFx0bWFya2VyT3B0aW9ucyA9IGRlZmF1bHRQbG90T3B0aW9uc1tzZXJpZXMudHlwZV0ubWFya2VyICYmIHNlcmllcy5vcHRpb25zLm1hcmtlcixcblx0XHRcdG5vcm1hbERpc2FibGVkID0gbWFya2VyT3B0aW9ucyAmJiAhbWFya2VyT3B0aW9ucy5lbmFibGVkLFxuXHRcdFx0bWFya2VyU3RhdGVPcHRpb25zID0gbWFya2VyT3B0aW9ucyAmJiBtYXJrZXJPcHRpb25zLnN0YXRlc1tzdGF0ZV0sXG5cdFx0XHRzdGF0ZURpc2FibGVkID0gbWFya2VyU3RhdGVPcHRpb25zICYmIG1hcmtlclN0YXRlT3B0aW9ucy5lbmFibGVkID09PSBmYWxzZSxcblx0XHRcdHN0YXRlTWFya2VyR3JhcGhpYyA9IHNlcmllcy5zdGF0ZU1hcmtlckdyYXBoaWMsXG5cdFx0XHRwb2ludE1hcmtlciA9IHBvaW50Lm1hcmtlciB8fCB7fSxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0cmFkaXVzLFxuXHRcdFx0aGFsbyA9IHNlcmllcy5oYWxvLFxuXHRcdFx0aGFsb09wdGlvbnMsXG5cdFx0XHRuZXdTeW1ib2wsXG5cdFx0XHRwb2ludEF0dHI7XG5cblx0XHRzdGF0ZSA9IHN0YXRlIHx8IE5PUk1BTF9TVEFURTsgLy8gZW1wdHkgc3RyaW5nXG5cdFx0cG9pbnRBdHRyID0gcG9pbnQucG9pbnRBdHRyW3N0YXRlXSB8fCBzZXJpZXMucG9pbnRBdHRyW3N0YXRlXTtcblxuXHRcdGlmIChcblx0XHRcdFx0Ly8gYWxyZWFkeSBoYXMgdGhpcyBzdGF0ZVxuXHRcdFx0XHQoc3RhdGUgPT09IHBvaW50LnN0YXRlICYmICFtb3ZlKSB8fFxuXHRcdFx0XHQvLyBzZWxlY3RlZCBwb2ludHMgZG9uJ3QgcmVzcG9uZCB0byBob3ZlclxuXHRcdFx0XHQocG9pbnQuc2VsZWN0ZWQgJiYgc3RhdGUgIT09IFNFTEVDVF9TVEFURSkgfHxcblx0XHRcdFx0Ly8gc2VyaWVzJyBzdGF0ZSBvcHRpb25zIGlzIGRpc2FibGVkXG5cdFx0XHRcdChzdGF0ZU9wdGlvbnNbc3RhdGVdICYmIHN0YXRlT3B0aW9uc1tzdGF0ZV0uZW5hYmxlZCA9PT0gZmFsc2UpIHx8XG5cdFx0XHRcdC8vIGdlbmVyYWwgcG9pbnQgbWFya2VyJ3Mgc3RhdGUgb3B0aW9ucyBpcyBkaXNhYmxlZFxuXHRcdFx0XHQoc3RhdGUgJiYgKHN0YXRlRGlzYWJsZWQgfHwgKG5vcm1hbERpc2FibGVkICYmIG1hcmtlclN0YXRlT3B0aW9ucy5lbmFibGVkID09PSBmYWxzZSkpKSB8fFxuXHRcdFx0XHQvLyBpbmRpdmlkdWFsIHBvaW50IG1hcmtlcidzIHN0YXRlIG9wdGlvbnMgaXMgZGlzYWJsZWRcblx0XHRcdFx0KHN0YXRlICYmIHBvaW50TWFya2VyLnN0YXRlcyAmJiBwb2ludE1hcmtlci5zdGF0ZXNbc3RhdGVdICYmIHBvaW50TWFya2VyLnN0YXRlc1tzdGF0ZV0uZW5hYmxlZCA9PT0gZmFsc2UpIC8vICMxNjEwXG5cblx0XHRcdCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGFwcGx5IGhvdmVyIHN0eWxlcyB0byB0aGUgZXhpc3RpbmcgcG9pbnRcblx0XHRpZiAocG9pbnQuZ3JhcGhpYykge1xuXHRcdFx0cmFkaXVzID0gbWFya2VyT3B0aW9ucyAmJiBwb2ludC5ncmFwaGljLnN5bWJvbE5hbWUgJiYgcG9pbnRBdHRyLnI7XG5cdFx0XHRwb2ludC5ncmFwaGljLmF0dHIobWVyZ2UoXG5cdFx0XHRcdHBvaW50QXR0cixcblx0XHRcdFx0cmFkaXVzID8geyAvLyBuZXcgc3ltYm9sIGF0dHJpYnV0ZXMgKCM1MDcsICM2MTIpXG5cdFx0XHRcdFx0eDogcGxvdFggLSByYWRpdXMsXG5cdFx0XHRcdFx0eTogcGxvdFkgLSByYWRpdXMsXG5cdFx0XHRcdFx0d2lkdGg6IDIgKiByYWRpdXMsXG5cdFx0XHRcdFx0aGVpZ2h0OiAyICogcmFkaXVzXG5cdFx0XHRcdH0gOiB7fVxuXHRcdFx0KSk7XG5cblx0XHRcdC8vIFpvb21pbmcgaW4gZnJvbSBhIHJhbmdlIHdpdGggbm8gbWFya2VycyB0byBhIHJhbmdlIHdpdGggbWFya2Vyc1xuXHRcdFx0aWYgKHN0YXRlTWFya2VyR3JhcGhpYykge1xuXHRcdFx0XHRzdGF0ZU1hcmtlckdyYXBoaWMuaGlkZSgpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBpZiBhIGdyYXBoaWMgaXMgbm90IGFwcGxpZWQgdG8gZWFjaCBwb2ludCBpbiB0aGUgbm9ybWFsIHN0YXRlLCBjcmVhdGUgYSBzaGFyZWRcblx0XHRcdC8vIGdyYXBoaWMgZm9yIHRoZSBob3ZlciBzdGF0ZVxuXHRcdFx0aWYgKHN0YXRlICYmIG1hcmtlclN0YXRlT3B0aW9ucykge1xuXHRcdFx0XHRyYWRpdXMgPSBtYXJrZXJTdGF0ZU9wdGlvbnMucmFkaXVzO1xuXHRcdFx0XHRuZXdTeW1ib2wgPSBwb2ludE1hcmtlci5zeW1ib2wgfHwgc2VyaWVzLnN5bWJvbDtcblxuXHRcdFx0XHQvLyBJZiB0aGUgcG9pbnQgaGFzIGFub3RoZXIgc3ltYm9sIHRoYW4gdGhlIHByZXZpb3VzIG9uZSwgdGhyb3cgYXdheSB0aGVcblx0XHRcdFx0Ly8gc3RhdGUgbWFya2VyIGdyYXBoaWMgYW5kIGZvcmNlIGEgbmV3IG9uZSAoIzE0NTkpXG5cdFx0XHRcdGlmIChzdGF0ZU1hcmtlckdyYXBoaWMgJiYgc3RhdGVNYXJrZXJHcmFwaGljLmN1cnJlbnRTeW1ib2wgIT09IG5ld1N5bWJvbCkge1xuXHRcdFx0XHRcdHN0YXRlTWFya2VyR3JhcGhpYyA9IHN0YXRlTWFya2VyR3JhcGhpYy5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgYSBuZXcgc3RhdGUgbWFya2VyIGdyYXBoaWNcblx0XHRcdFx0aWYgKCFzdGF0ZU1hcmtlckdyYXBoaWMpIHtcblx0XHRcdFx0XHRpZiAobmV3U3ltYm9sKSB7XG5cdFx0XHRcdFx0XHRzZXJpZXMuc3RhdGVNYXJrZXJHcmFwaGljID0gc3RhdGVNYXJrZXJHcmFwaGljID0gY2hhcnQucmVuZGVyZXIuc3ltYm9sKFxuXHRcdFx0XHRcdFx0XHRuZXdTeW1ib2wsXG5cdFx0XHRcdFx0XHRcdHBsb3RYIC0gcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRwbG90WSAtIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0MiAqIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0MiAqIHJhZGl1c1xuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdFx0LmF0dHIocG9pbnRBdHRyKVxuXHRcdFx0XHRcdFx0LmFkZChzZXJpZXMubWFya2VyR3JvdXApO1xuXHRcdFx0XHRcdFx0c3RhdGVNYXJrZXJHcmFwaGljLmN1cnJlbnRTeW1ib2wgPSBuZXdTeW1ib2w7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE1vdmUgdGhlIGV4aXN0aW5nIGdyYXBoaWNcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdGF0ZU1hcmtlckdyYXBoaWNbbW92ZSA/ICdhbmltYXRlJyA6ICdhdHRyJ10oeyAvLyAjMTA1NFxuXHRcdFx0XHRcdFx0eDogcGxvdFggLSByYWRpdXMsXG5cdFx0XHRcdFx0XHR5OiBwbG90WSAtIHJhZGl1c1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzdGF0ZU1hcmtlckdyYXBoaWMpIHtcblx0XHRcdFx0c3RhdGVNYXJrZXJHcmFwaGljW3N0YXRlICYmIGNoYXJ0LmlzSW5zaWRlUGxvdChwbG90WCwgcGxvdFksIGNoYXJ0LmludmVydGVkKSA/ICdzaG93JyA6ICdoaWRlJ10oKTsgLy8gIzI0NTBcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTaG93IG1lIHlvdXIgaGFsb1xuXHRcdGhhbG9PcHRpb25zID0gc3RhdGVPcHRpb25zW3N0YXRlXSAmJiBzdGF0ZU9wdGlvbnNbc3RhdGVdLmhhbG87XG5cdFx0aWYgKGhhbG9PcHRpb25zICYmIGhhbG9PcHRpb25zLnNpemUpIHtcblx0XHRcdGlmICghaGFsbykge1xuXHRcdFx0XHRzZXJpZXMuaGFsbyA9IGhhbG8gPSBjaGFydC5yZW5kZXJlci5wYXRoKClcblx0XHRcdFx0XHQuYWRkKHNlcmllcy5zZXJpZXNHcm91cCk7XG5cdFx0XHR9XG5cdFx0XHRoYWxvLmF0dHIoZXh0ZW5kKHtcblx0XHRcdFx0ZmlsbDogQ29sb3IocG9pbnQuY29sb3IgfHwgc2VyaWVzLmNvbG9yKS5zZXRPcGFjaXR5KGhhbG9PcHRpb25zLm9wYWNpdHkpLmdldCgpXG5cdFx0XHR9LCBoYWxvT3B0aW9ucy5hdHRyaWJ1dGVzKSlbbW92ZSA/ICdhbmltYXRlJyA6ICdhdHRyJ10oe1xuXHRcdFx0XHRkOiBwb2ludC5oYWxvUGF0aChoYWxvT3B0aW9ucy5zaXplKVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIGlmIChoYWxvKSB7XG5cdFx0XHRoYWxvLmF0dHIoeyBkOiBbXSB9KTtcblx0XHR9XG5cblx0XHRwb2ludC5zdGF0ZSA9IHN0YXRlO1xuXHR9LFxuXG5cdGhhbG9QYXRoOiBmdW5jdGlvbiAoc2l6ZSkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0cGxvdEJveCA9IHNlcmllcy5nZXRQbG90Qm94KCksXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkO1xuXG5cdFx0cmV0dXJuIGNoYXJ0LnJlbmRlcmVyLnN5bWJvbHMuY2lyY2xlKFxuXHRcdFx0cGxvdEJveC50cmFuc2xhdGVYICsgKGludmVydGVkID8gc2VyaWVzLnlBeGlzLmxlbiAtIHRoaXMucGxvdFkgOiB0aGlzLnBsb3RYKSAtIHNpemUsIFxuXHRcdFx0cGxvdEJveC50cmFuc2xhdGVZICsgKGludmVydGVkID8gc2VyaWVzLnhBeGlzLmxlbiAtIHRoaXMucGxvdFggOiB0aGlzLnBsb3RZKSAtIHNpemUsIFxuXHRcdFx0c2l6ZSAqIDIsIFxuXHRcdFx0c2l6ZSAqIDJcblx0XHQpO1xuXHR9XG59KTtcblxuLypcbiAqIEV4dGVuZCB0aGUgU2VyaWVzIG9iamVjdCB3aXRoIGludGVyYWN0aW9uXG4gKi9cblxuZXh0ZW5kKFNlcmllcy5wcm90b3R5cGUsIHtcblx0LyoqXG5cdCAqIFNlcmllcyBtb3VzZSBvdmVyIGhhbmRsZXJcblx0ICovXG5cdG9uTW91c2VPdmVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdGhvdmVyU2VyaWVzID0gY2hhcnQuaG92ZXJTZXJpZXM7XG5cblx0XHQvLyBzZXQgbm9ybWFsIHN0YXRlIHRvIHByZXZpb3VzIHNlcmllc1xuXHRcdGlmIChob3ZlclNlcmllcyAmJiBob3ZlclNlcmllcyAhPT0gc2VyaWVzKSB7XG5cdFx0XHRob3ZlclNlcmllcy5vbk1vdXNlT3V0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gdHJpZ2dlciB0aGUgZXZlbnQsIGJ1dCB0byBzYXZlIHByb2Nlc3NpbmcgdGltZSxcblx0XHQvLyBvbmx5IGlmIGRlZmluZWRcblx0XHRpZiAoc2VyaWVzLm9wdGlvbnMuZXZlbnRzLm1vdXNlT3Zlcikge1xuXHRcdFx0ZmlyZUV2ZW50KHNlcmllcywgJ21vdXNlT3ZlcicpO1xuXHRcdH1cblxuXHRcdC8vIGhvdmVyIHRoaXNcblx0XHRzZXJpZXMuc2V0U3RhdGUoSE9WRVJfU1RBVEUpO1xuXHRcdGNoYXJ0LmhvdmVyU2VyaWVzID0gc2VyaWVzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXJpZXMgbW91c2Ugb3V0IGhhbmRsZXJcblx0ICovXG5cdG9uTW91c2VPdXQ6IGZ1bmN0aW9uICgpIHtcblx0XHQvLyB0cmlnZ2VyIHRoZSBldmVudCBvbmx5IGlmIGxpc3RlbmVycyBleGlzdFxuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHR0b29sdGlwID0gY2hhcnQudG9vbHRpcCxcblx0XHRcdGhvdmVyUG9pbnQgPSBjaGFydC5ob3ZlclBvaW50O1xuXG5cdFx0Ly8gdHJpZ2dlciBtb3VzZSBvdXQgb24gdGhlIHBvaW50LCB3aGljaCBtdXN0IGJlIGluIHRoaXMgc2VyaWVzXG5cdFx0aWYgKGhvdmVyUG9pbnQpIHtcblx0XHRcdGhvdmVyUG9pbnQub25Nb3VzZU91dCgpO1xuXHRcdH1cblxuXHRcdC8vIGZpcmUgdGhlIG1vdXNlIG91dCBldmVudFxuXHRcdGlmIChzZXJpZXMgJiYgb3B0aW9ucy5ldmVudHMubW91c2VPdXQpIHtcblx0XHRcdGZpcmVFdmVudChzZXJpZXMsICdtb3VzZU91dCcpO1xuXHRcdH1cblxuXG5cdFx0Ly8gaGlkZSB0aGUgdG9vbHRpcFxuXHRcdGlmICh0b29sdGlwICYmICFvcHRpb25zLnN0aWNreVRyYWNraW5nICYmICghdG9vbHRpcC5zaGFyZWQgfHwgc2VyaWVzLm5vU2hhcmVkVG9vbHRpcCkpIHtcblx0XHRcdHRvb2x0aXAuaGlkZSgpO1xuXHRcdH1cblxuXHRcdC8vIHNldCBub3JtYWwgc3RhdGVcblx0XHRzZXJpZXMuc2V0U3RhdGUoKTtcblx0XHRjaGFydC5ob3ZlclNlcmllcyA9IG51bGw7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgc3RhdGUgb2YgdGhlIGdyYXBoXG5cdCAqL1xuXHRzZXRTdGF0ZTogZnVuY3Rpb24gKHN0YXRlKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRncmFwaCA9IHNlcmllcy5ncmFwaCxcblx0XHRcdGdyYXBoTmVnID0gc2VyaWVzLmdyYXBoTmVnLFxuXHRcdFx0c3RhdGVPcHRpb25zID0gb3B0aW9ucy5zdGF0ZXMsXG5cdFx0XHRsaW5lV2lkdGggPSBvcHRpb25zLmxpbmVXaWR0aCxcblx0XHRcdGF0dHJpYnM7XG5cblx0XHRzdGF0ZSA9IHN0YXRlIHx8IE5PUk1BTF9TVEFURTtcblxuXHRcdGlmIChzZXJpZXMuc3RhdGUgIT09IHN0YXRlKSB7XG5cdFx0XHRzZXJpZXMuc3RhdGUgPSBzdGF0ZTtcblxuXHRcdFx0aWYgKHN0YXRlT3B0aW9uc1tzdGF0ZV0gJiYgc3RhdGVPcHRpb25zW3N0YXRlXS5lbmFibGVkID09PSBmYWxzZSkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzdGF0ZSkge1xuXHRcdFx0XHRsaW5lV2lkdGggPSBzdGF0ZU9wdGlvbnNbc3RhdGVdLmxpbmVXaWR0aCB8fCBsaW5lV2lkdGggKyAoc3RhdGVPcHRpb25zW3N0YXRlXS5saW5lV2lkdGhQbHVzIHx8IDApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoZ3JhcGggJiYgIWdyYXBoLmRhc2hzdHlsZSkgeyAvLyBob3ZlciBpcyB0dXJuZWQgb2ZmIGZvciBkYXNoZWQgbGluZXMgaW4gVk1MXG5cdFx0XHRcdGF0dHJpYnMgPSB7XG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IGxpbmVXaWR0aFxuXHRcdFx0XHR9O1xuXHRcdFx0XHQvLyB1c2UgYXR0ciBiZWNhdXNlIGFuaW1hdGUgd2lsbCBjYXVzZSBhbnkgb3RoZXIgYW5pbWF0aW9uIG9uIHRoZSBncmFwaCB0byBzdG9wXG5cdFx0XHRcdGdyYXBoLmF0dHIoYXR0cmlicyk7XG5cdFx0XHRcdGlmIChncmFwaE5lZykge1xuXHRcdFx0XHRcdGdyYXBoTmVnLmF0dHIoYXR0cmlicyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgZ3JhcGhcblx0ICpcblx0ICogQHBhcmFtIHZpcyB7Qm9vbGVhbn0gVHJ1ZSB0byBzaG93IHRoZSBzZXJpZXMsIGZhbHNlIHRvIGhpZGUuIElmIFVOREVGSU5FRCxcblx0ICpcdFx0XHRcdHRoZSB2aXNpYmlsaXR5IGlzIHRvZ2dsZWQuXG5cdCAqL1xuXHRzZXRWaXNpYmxlOiBmdW5jdGlvbiAodmlzLCByZWRyYXcpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0bGVnZW5kSXRlbSA9IHNlcmllcy5sZWdlbmRJdGVtLFxuXHRcdFx0c2hvd09ySGlkZSxcblx0XHRcdGlnbm9yZUhpZGRlblNlcmllcyA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQuaWdub3JlSGlkZGVuU2VyaWVzLFxuXHRcdFx0b2xkVmlzaWJpbGl0eSA9IHNlcmllcy52aXNpYmxlO1xuXG5cdFx0Ly8gaWYgY2FsbGVkIHdpdGhvdXQgYW4gYXJndW1lbnQsIHRvZ2dsZSB2aXNpYmlsaXR5XG5cdFx0c2VyaWVzLnZpc2libGUgPSB2aXMgPSBzZXJpZXMudXNlck9wdGlvbnMudmlzaWJsZSA9IHZpcyA9PT0gVU5ERUZJTkVEID8gIW9sZFZpc2liaWxpdHkgOiB2aXM7XG5cdFx0c2hvd09ySGlkZSA9IHZpcyA/ICdzaG93JyA6ICdoaWRlJztcblxuXHRcdC8vIHNob3cgb3IgaGlkZSBlbGVtZW50c1xuXHRcdGVhY2goWydncm91cCcsICdkYXRhTGFiZWxzR3JvdXAnLCAnbWFya2VyR3JvdXAnLCAndHJhY2tlciddLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRpZiAoc2VyaWVzW2tleV0pIHtcblx0XHRcdFx0c2VyaWVzW2tleV1bc2hvd09ySGlkZV0oKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXG5cdFx0Ly8gaGlkZSB0b29sdGlwICgjMTM2MSlcblx0XHRpZiAoY2hhcnQuaG92ZXJTZXJpZXMgPT09IHNlcmllcykge1xuXHRcdFx0c2VyaWVzLm9uTW91c2VPdXQoKTtcblx0XHR9XG5cblxuXHRcdGlmIChsZWdlbmRJdGVtKSB7XG5cdFx0XHRjaGFydC5sZWdlbmQuY29sb3JpemVJdGVtKHNlcmllcywgdmlzKTtcblx0XHR9XG5cblxuXHRcdC8vIHJlc2NhbGUgb3IgYWRhcHQgdG8gcmVzaXplZCBjaGFydFxuXHRcdHNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHQvLyBpbiBhIHN0YWNrLCBhbGwgb3RoZXIgc2VyaWVzIGFyZSBhZmZlY3RlZFxuXHRcdGlmIChzZXJpZXMub3B0aW9ucy5zdGFja2luZykge1xuXHRcdFx0ZWFjaChjaGFydC5zZXJpZXMsIGZ1bmN0aW9uIChvdGhlclNlcmllcykge1xuXHRcdFx0XHRpZiAob3RoZXJTZXJpZXMub3B0aW9ucy5zdGFja2luZyAmJiBvdGhlclNlcmllcy52aXNpYmxlKSB7XG5cdFx0XHRcdFx0b3RoZXJTZXJpZXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdC8vIHNob3cgb3IgaGlkZSBsaW5rZWQgc2VyaWVzXG5cdFx0ZWFjaChzZXJpZXMubGlua2VkU2VyaWVzLCBmdW5jdGlvbiAob3RoZXJTZXJpZXMpIHtcblx0XHRcdG90aGVyU2VyaWVzLnNldFZpc2libGUodmlzLCBmYWxzZSk7XG5cdFx0fSk7XG5cblx0XHRpZiAoaWdub3JlSGlkZGVuU2VyaWVzKSB7XG5cdFx0XHRjaGFydC5pc0RpcnR5Qm94ID0gdHJ1ZTtcblx0XHR9XG5cdFx0aWYgKHJlZHJhdyAhPT0gZmFsc2UpIHtcblx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdH1cblxuXHRcdGZpcmVFdmVudChzZXJpZXMsIHNob3dPckhpZGUpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBNZW1vcml6ZSB0b29sdGlwIHRleHRzIGFuZCBwb3NpdGlvbnNcblx0ICovXG5cdHNldFRvb2x0aXBQb2ludHM6IGZ1bmN0aW9uIChyZW5ldykge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0cG9pbnRzID0gW10sXG5cdFx0XHRwb2ludHNMZW5ndGgsXG5cdFx0XHRsb3csXG5cdFx0XHRoaWdoLFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHR4RXh0cmVtZXMgPSB4QXhpcyAmJiB4QXhpcy5nZXRFeHRyZW1lcygpLFxuXHRcdFx0YXhpc0xlbmd0aCA9IHhBeGlzID8gKHhBeGlzLnRvb2x0aXBMZW4gfHwgeEF4aXMubGVuKSA6IHNlcmllcy5jaGFydC5wbG90U2l6ZVgsIC8vIHRvb2x0aXBMZW4gYW5kIHRvb2x0aXBQb3NOYW1lIHVzZWQgaW4gcG9sYXJcblx0XHRcdHBvaW50LFxuXHRcdFx0cG9pbnRYLFxuXHRcdFx0bmV4dFBvaW50LFxuXHRcdFx0aSxcblx0XHRcdHRvb2x0aXBQb2ludHMgPSBbXTsgLy8gYSBsb29rdXAgYXJyYXkgZm9yIGVhY2ggcGl4ZWwgaW4gdGhlIHggZGltZW5zaW9uXG5cblx0XHQvLyBkb24ndCB3YXN0ZSByZXNvdXJjZXMgaWYgdHJhY2tlciBpcyBkaXNhYmxlZFxuXHRcdGlmIChzZXJpZXMub3B0aW9ucy5lbmFibGVNb3VzZVRyYWNraW5nID09PSBmYWxzZSB8fCBzZXJpZXMuc2luZ3VsYXJUb29sdGlwcykge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIHJlbmV3XG5cdFx0aWYgKHJlbmV3KSB7XG5cdFx0XHRzZXJpZXMudG9vbHRpcFBvaW50cyA9IG51bGw7XG5cdFx0fVxuXG5cdFx0Ly8gY29uY2F0IHNlZ21lbnRzIHRvIG92ZXJjb21lIG51bGwgdmFsdWVzXG5cdFx0ZWFjaChzZXJpZXMuc2VnbWVudHMgfHwgc2VyaWVzLnBvaW50cywgZnVuY3Rpb24gKHNlZ21lbnQpIHtcblx0XHRcdHBvaW50cyA9IHBvaW50cy5jb25jYXQoc2VnbWVudCk7XG5cdFx0fSk7XG5cblx0XHQvLyBSZXZlcnNlIHRoZSBwb2ludHMgaW4gY2FzZSB0aGUgWCBheGlzIGlzIHJldmVyc2VkXG5cdFx0aWYgKHhBeGlzICYmIHhBeGlzLnJldmVyc2VkKSB7XG5cdFx0XHRwb2ludHMgPSBwb2ludHMucmV2ZXJzZSgpO1xuXHRcdH1cblxuXHRcdC8vIFBvbGFyIG5lZWRzIGFkZGl0aW9uYWwgc2hhcGluZ1xuXHRcdGlmIChzZXJpZXMub3JkZXJUb29sdGlwUG9pbnRzKSB7XG5cdFx0XHRzZXJpZXMub3JkZXJUb29sdGlwUG9pbnRzKHBvaW50cyk7XG5cdFx0fVxuXG5cdFx0Ly8gQXNzaWduIGVhY2ggcGl4ZWwgcG9zaXRpb24gdG8gdGhlIG5lYXJlc3QgcG9pbnRcblx0XHRwb2ludHNMZW5ndGggPSBwb2ludHMubGVuZ3RoO1xuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW5ndGg7IGkrKykge1xuXHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHRwb2ludFggPSBwb2ludC54O1xuXHRcdFx0aWYgKHBvaW50WCA+PSB4RXh0cmVtZXMubWluICYmIHBvaW50WCA8PSB4RXh0cmVtZXMubWF4KSB7IC8vICMxMTQ5XG5cdFx0XHRcdG5leHRQb2ludCA9IHBvaW50c1tpICsgMV07XG5cblx0XHRcdFx0Ly8gU2V0IHRoaXMgcmFuZ2UncyBsb3cgdG8gdGhlIGxhc3QgcmFuZ2UncyBoaWdoIHBsdXMgb25lXG5cdFx0XHRcdGxvdyA9IGhpZ2ggPT09IFVOREVGSU5FRCA/IDAgOiBoaWdoICsgMTtcblx0XHRcdFx0Ly8gTm93IGZpbmQgdGhlIG5ldyBoaWdoXG5cdFx0XHRcdGhpZ2ggPSBwb2ludHNbaSArIDFdID9cblx0XHRcdFx0XHRtYXRoTWluKG1hdGhNYXgoMCwgbWF0aEZsb29yKCAvLyAjMjA3MFxuXHRcdFx0XHRcdFx0KHBvaW50LmNsaWVudFggKyAobmV4dFBvaW50ID8gKG5leHRQb2ludC53cmFwcGVkQ2xpZW50WCB8fCBuZXh0UG9pbnQuY2xpZW50WCkgOiBheGlzTGVuZ3RoKSkgLyAyXG5cdFx0XHRcdFx0KSksIGF4aXNMZW5ndGgpIDpcblx0XHRcdFx0XHRheGlzTGVuZ3RoO1xuXG5cdFx0XHRcdHdoaWxlIChsb3cgPj0gMCAmJiBsb3cgPD0gaGlnaCkge1xuXHRcdFx0XHRcdHRvb2x0aXBQb2ludHNbbG93KytdID0gcG9pbnQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0c2VyaWVzLnRvb2x0aXBQb2ludHMgPSB0b29sdGlwUG9pbnRzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTaG93IHRoZSBncmFwaFxuXHQgKi9cblx0c2hvdzogZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMuc2V0VmlzaWJsZSh0cnVlKTtcblx0fSxcblxuXHQvKipcblx0ICogSGlkZSB0aGUgZ3JhcGhcblx0ICovXG5cdGhpZGU6IGZ1bmN0aW9uICgpIHtcblx0XHR0aGlzLnNldFZpc2libGUoZmFsc2UpO1xuXHR9LFxuXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgc2VsZWN0ZWQgc3RhdGUgb2YgdGhlIGdyYXBoXG5cdCAqXG5cdCAqIEBwYXJhbSBzZWxlY3RlZCB7Qm9vbGVhbn0gVHJ1ZSB0byBzZWxlY3QgdGhlIHNlcmllcywgZmFsc2UgdG8gdW5zZWxlY3QuIElmXG5cdCAqXHRcdFx0XHRVTkRFRklORUQsIHRoZSBzZWxlY3Rpb24gc3RhdGUgaXMgdG9nZ2xlZC5cblx0ICovXG5cdHNlbGVjdDogZnVuY3Rpb24gKHNlbGVjdGVkKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXM7XG5cdFx0Ly8gaWYgY2FsbGVkIHdpdGhvdXQgYW4gYXJndW1lbnQsIHRvZ2dsZVxuXHRcdHNlcmllcy5zZWxlY3RlZCA9IHNlbGVjdGVkID0gKHNlbGVjdGVkID09PSBVTkRFRklORUQpID8gIXNlcmllcy5zZWxlY3RlZCA6IHNlbGVjdGVkO1xuXG5cdFx0aWYgKHNlcmllcy5jaGVja2JveCkge1xuXHRcdFx0c2VyaWVzLmNoZWNrYm94LmNoZWNrZWQgPSBzZWxlY3RlZDtcblx0XHR9XG5cblx0XHRmaXJlRXZlbnQoc2VyaWVzLCBzZWxlY3RlZCA/ICdzZWxlY3QnIDogJ3Vuc2VsZWN0Jyk7XG5cdH0sXG5cblx0ZHJhd1RyYWNrZXI6IFRyYWNrZXJNaXhpbi5kcmF3VHJhY2tlckdyYXBoXG59KTtcbi8vIGdsb2JhbCB2YXJpYWJsZXNcbmV4dGVuZChIaWdoY2hhcnRzLCB7XG5cdFxuXHQvLyBDb25zdHJ1Y3RvcnNcblx0QXhpczogQXhpcyxcblx0Q2hhcnQ6IENoYXJ0LFxuXHRDb2xvcjogQ29sb3IsXG5cdFBvaW50OiBQb2ludCxcblx0VGljazogVGljayxcdFxuXHRSZW5kZXJlcjogUmVuZGVyZXIsXG5cdFNlcmllczogU2VyaWVzLFxuXHRTVkdFbGVtZW50OiBTVkdFbGVtZW50LFxuXHRTVkdSZW5kZXJlcjogU1ZHUmVuZGVyZXIsXG5cdFxuXHQvLyBWYXJpb3VzXG5cdGFycmF5TWluOiBhcnJheU1pbixcblx0YXJyYXlNYXg6IGFycmF5TWF4LFxuXHRjaGFydHM6IGNoYXJ0cyxcblx0ZGF0ZUZvcm1hdDogZGF0ZUZvcm1hdCxcblx0Zm9ybWF0OiBmb3JtYXQsXG5cdHBhdGhBbmltOiBwYXRoQW5pbSxcblx0Z2V0T3B0aW9uczogZ2V0T3B0aW9ucyxcblx0aGFzQmlkaUJ1ZzogaGFzQmlkaUJ1Zyxcblx0aXNUb3VjaERldmljZTogaXNUb3VjaERldmljZSxcblx0bnVtYmVyRm9ybWF0OiBudW1iZXJGb3JtYXQsXG5cdHNlcmllc1R5cGVzOiBzZXJpZXNUeXBlcyxcblx0c2V0T3B0aW9uczogc2V0T3B0aW9ucyxcblx0YWRkRXZlbnQ6IGFkZEV2ZW50LFxuXHRyZW1vdmVFdmVudDogcmVtb3ZlRXZlbnQsXG5cdGNyZWF0ZUVsZW1lbnQ6IGNyZWF0ZUVsZW1lbnQsXG5cdGRpc2NhcmRFbGVtZW50OiBkaXNjYXJkRWxlbWVudCxcblx0Y3NzOiBjc3MsXG5cdGVhY2g6IGVhY2gsXG5cdGV4dGVuZDogZXh0ZW5kLFxuXHRtYXA6IG1hcCxcblx0bWVyZ2U6IG1lcmdlLFxuXHRwaWNrOiBwaWNrLFxuXHRzcGxhdDogc3BsYXQsXG5cdGV4dGVuZENsYXNzOiBleHRlbmRDbGFzcyxcblx0cEludDogcEludCxcblx0d3JhcDogd3JhcCxcblx0c3ZnOiBoYXNTVkcsXG5cdGNhbnZhczogdXNlQ2FuVkcsXG5cdHZtbDogIWhhc1NWRyAmJiAhdXNlQ2FuVkcsXG5cdHByb2R1Y3Q6IFBST0RVQ1QsXG5cdHZlcnNpb246IFZFUlNJT05cbn0pO1xuXG59KCkpO1xuXG4vKipcbiAqIEBsaWNlbnNlIEhpZ2hjaGFydHMgSlMgdjQuMC40ICgyMDE0LTA5LTAyKVxuICpcbiAqIFN0YW5kYWxvbmUgSGlnaGNoYXJ0cyBGcmFtZXdvcmtcbiAqXG4gKiBMaWNlbnNlOiBNSVQgTGljZW5zZVxuICovXG5cblxuLypnbG9iYWwgSGlnaGNoYXJ0cyAqL1xudmFyIEhpZ2hjaGFydHNBZGFwdGVyID0gKGZ1bmN0aW9uICgpIHtcblxuICB2YXIgVU5ERUZJTkVELFxuICAgIGRvYyA9IGRvY3VtZW50LFxuICAgIGVtcHR5QXJyYXkgPSBbXSxcbiAgICB0aW1lcnMgPSBbXSxcbiAgICB0aW1lcklkLFxuICAgIGFuaW1TZXR0ZXJzID0ge30sXG4gICAgRng7XG5cbiAgTWF0aC5lYXNlSW5PdXRTaW5lID0gZnVuY3Rpb24gKHQsIGIsIGMsIGQpIHtcbiAgICByZXR1cm4gLWMgLyAyICogKE1hdGguY29zKE1hdGguUEkgKiB0IC8gZCkgLSAxKSArIGI7XG4gIH07XG5cblxuXG4gIC8qKlxuICAgKiBFeHRlbmQgZ2l2ZW4gb2JqZWN0IHdpdGggY3VzdG9tIGV2ZW50c1xuICAgKi9cbiAgZnVuY3Rpb24gYXVnbWVudChvYmopIHtcbiAgICBmdW5jdGlvbiByZW1vdmVPbmVFdmVudChlbCwgdHlwZSwgZm4pIHtcbiAgICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgZm4sIGZhbHNlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBJRVJlbW92ZU9uZUV2ZW50KGVsLCB0eXBlLCBmbikge1xuICAgICAgZm4gPSBlbC5IQ1Byb3hpZWRNZXRob2RzW2ZuLnRvU3RyaW5nKCldO1xuICAgICAgZWwuZGV0YWNoRXZlbnQoJ29uJyArIHR5cGUsIGZuKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZW1vdmVBbGxFdmVudHMoZWwsIHR5cGUpIHtcbiAgICAgIHZhciBldmVudHMgPSBlbC5IQ0V2ZW50cyxcbiAgICAgICAgcmVtb3ZlLFxuICAgICAgICB0eXBlcyxcbiAgICAgICAgbGVuLFxuICAgICAgICBuO1xuXG4gICAgICBpZiAoZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICByZW1vdmUgPSByZW1vdmVPbmVFdmVudDtcbiAgICAgIH0gZWxzZSBpZiAoZWwuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgcmVtb3ZlID0gSUVSZW1vdmVPbmVFdmVudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybjsgLy8gYnJlYWsgb24gbm9uLURPTSBldmVudHNcbiAgICAgIH1cblxuXG4gICAgICBpZiAodHlwZSkge1xuICAgICAgICB0eXBlcyA9IHt9O1xuICAgICAgICB0eXBlc1t0eXBlXSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0eXBlcyA9IGV2ZW50cztcbiAgICAgIH1cblxuICAgICAgZm9yIChuIGluIHR5cGVzKSB7XG4gICAgICAgIGlmIChldmVudHNbbl0pIHtcbiAgICAgICAgICBsZW4gPSBldmVudHNbbl0ubGVuZ3RoO1xuICAgICAgICAgIHdoaWxlIChsZW4tLSkge1xuICAgICAgICAgICAgcmVtb3ZlKGVsLCBuLCBldmVudHNbbl1bbGVuXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFvYmouSENFeHRlbmRlZCkge1xuICAgICAgSGlnaGNoYXJ0cy5leHRlbmQob2JqLCB7XG4gICAgICAgIEhDRXh0ZW5kZWQ6IHRydWUsXG5cbiAgICAgICAgSENFdmVudHM6IHt9LFxuXG4gICAgICAgIGJpbmQ6IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgICAgICAgIHZhciBlbCA9IHRoaXMsXG4gICAgICAgICAgICBldmVudHMgPSB0aGlzLkhDRXZlbnRzLFxuICAgICAgICAgICAgd3JhcHBlZEZuO1xuXG4gICAgICAgICAgLy8gaGFuZGxlIERPTSBldmVudHMgaW4gbW9kZXJuIGJyb3dzZXJzXG4gICAgICAgICAgaWYgKGVsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgZm4sIGZhbHNlKTtcblxuICAgICAgICAgICAgLy8gaGFuZGxlIG9sZCBJRSBpbXBsZW1lbnRhdGlvblxuICAgICAgICAgIH0gZWxzZSBpZiAoZWwuYXR0YWNoRXZlbnQpIHtcblxuICAgICAgICAgICAgd3JhcHBlZEZuID0gZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgZS50YXJnZXQgPSBlLnNyY0VsZW1lbnQgfHwgd2luZG93OyAvLyAjMjgyMFxuICAgICAgICAgICAgICBmbi5jYWxsKGVsLCBlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGlmICghZWwuSENQcm94aWVkTWV0aG9kcykge1xuICAgICAgICAgICAgICBlbC5IQ1Byb3hpZWRNZXRob2RzID0ge307XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGxpbmsgd3JhcHBlZCBmbiB3aXRoIG9yaWdpbmFsIGZuLCBzbyB3ZSBjYW4gZ2V0IHRoaXMgaW4gcmVtb3ZlRXZlbnRcbiAgICAgICAgICAgIGVsLkhDUHJveGllZE1ldGhvZHNbZm4udG9TdHJpbmcoKV0gPSB3cmFwcGVkRm47XG5cbiAgICAgICAgICAgIGVsLmF0dGFjaEV2ZW50KCdvbicgKyBuYW1lLCB3cmFwcGVkRm4pO1xuICAgICAgICAgIH1cblxuXG4gICAgICAgICAgaWYgKGV2ZW50c1tuYW1lXSA9PT0gVU5ERUZJTkVEKSB7XG4gICAgICAgICAgICBldmVudHNbbmFtZV0gPSBbXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBldmVudHNbbmFtZV0ucHVzaChmbik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdW5iaW5kOiBmdW5jdGlvbiAobmFtZSwgZm4pIHtcbiAgICAgICAgICB2YXIgZXZlbnRzLFxuICAgICAgICAgICAgaW5kZXg7XG5cbiAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgZXZlbnRzID0gdGhpcy5IQ0V2ZW50c1tuYW1lXSB8fCBbXTtcbiAgICAgICAgICAgIGlmIChmbikge1xuICAgICAgICAgICAgICBpbmRleCA9IEhpZ2hjaGFydHNBZGFwdGVyLmluQXJyYXkoZm4sIGV2ZW50cyk7XG4gICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgdGhpcy5IQ0V2ZW50c1tuYW1lXSA9IGV2ZW50cztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAodGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlT25lRXZlbnQodGhpcywgbmFtZSwgZm4pO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgICBJRVJlbW92ZU9uZUV2ZW50KHRoaXMsIG5hbWUsIGZuKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVtb3ZlQWxsRXZlbnRzKHRoaXMsIG5hbWUpO1xuICAgICAgICAgICAgICB0aGlzLkhDRXZlbnRzW25hbWVdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlbW92ZUFsbEV2ZW50cyh0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuSENFdmVudHMgPSB7fTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgdHJpZ2dlcjogZnVuY3Rpb24gKG5hbWUsIGFyZ3MpIHtcbiAgICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5IQ0V2ZW50c1tuYW1lXSB8fCBbXSxcbiAgICAgICAgICAgIHRhcmdldCA9IHRoaXMsXG4gICAgICAgICAgICBsZW4gPSBldmVudHMubGVuZ3RoLFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIHByZXZlbnREZWZhdWx0LFxuICAgICAgICAgICAgZm47XG5cbiAgICAgICAgICAvLyBBdHRhY2ggYSBzaW1wbGUgcHJldmVudERlZmF1bHQgZnVuY3Rpb24gdG8gc2tpcCBkZWZhdWx0IGhhbmRsZXIgaWYgY2FsbGVkXG4gICAgICAgICAgcHJldmVudERlZmF1bHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhcmdzLmRlZmF1bHRQcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGZuID0gZXZlbnRzW2ldO1xuXG4gICAgICAgICAgICAvLyBhcmdzIGlzIG5ldmVyIG51bGwgaGVyZVxuICAgICAgICAgICAgaWYgKGFyZ3Muc3RvcHBlZCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFyZ3MucHJldmVudERlZmF1bHQgPSBwcmV2ZW50RGVmYXVsdDtcbiAgICAgICAgICAgIGFyZ3MudGFyZ2V0ID0gdGFyZ2V0O1xuXG4gICAgICAgICAgICAvLyBJZiB0aGUgdHlwZSBpcyBub3Qgc2V0LCB3ZSdyZSBydW5uaW5nIGEgY3VzdG9tIGV2ZW50ICgjMjI5NykuIElmIGl0IGlzIHNldCxcbiAgICAgICAgICAgIC8vIHdlJ3JlIHJ1bm5pbmcgYSBicm93c2VyIGV2ZW50LCBhbmQgc2V0dGluZyBpdCB3aWxsIGNhdXNlIGVuIGVycm9yIGluXG4gICAgICAgICAgICAvLyBJRTggKCMyNDY1KS5cbiAgICAgICAgICAgIGlmICghYXJncy50eXBlKSB7XG4gICAgICAgICAgICAgIGFyZ3MudHlwZSA9IG5hbWU7XG4gICAgICAgICAgICB9XG5cblxuXG4gICAgICAgICAgICAvLyBJZiB0aGUgZXZlbnQgaGFuZGxlciByZXR1cm4gZmFsc2UsIHByZXZlbnQgdGhlIGRlZmF1bHQgaGFuZGxlciBmcm9tIGV4ZWN1dGluZ1xuICAgICAgICAgICAgaWYgKGZuLmNhbGwodGhpcywgYXJncykgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIGFyZ3MucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG4gIH1cblxuXG4gIHJldHVybiB7XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoZSBhZGFwdGVyLiBUaGlzIGlzIHJ1biBvbmNlIGFzIEhpZ2hjaGFydHMgaXMgZmlyc3QgcnVuLlxuICAgICAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uIChwYXRoQW5pbSkge1xuXG4gICAgICAvKipcbiAgICAgICAqIENvbXBhdGliaWxpdHkgc2VjdGlvbiB0byBhZGQgc3VwcG9ydCBmb3IgbGVnYWN5IElFLiBUaGlzIGNhbiBiZSByZW1vdmVkIGlmIG9sZCBJRVxuICAgICAgICogc3VwcG9ydCBpcyBub3QgbmVlZGVkLlxuICAgICAgICovXG4gICAgICBpZiAoIWRvYy5kZWZhdWx0Vmlldykge1xuICAgICAgICB0aGlzLl9nZXRTdHlsZSA9IGZ1bmN0aW9uIChlbCwgcHJvcCkge1xuICAgICAgICAgIHZhciB2YWw7XG4gICAgICAgICAgaWYgKGVsLnN0eWxlW3Byb3BdKSB7XG4gICAgICAgICAgICByZXR1cm4gZWwuc3R5bGVbcHJvcF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChwcm9wID09PSAnb3BhY2l0eScpIHtcbiAgICAgICAgICAgICAgcHJvcCA9ICdmaWx0ZXInO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypqc2xpbnQgdW5wYXJhbTogdHJ1ZSovXG4gICAgICAgICAgICB2YWwgPSBlbC5jdXJyZW50U3R5bGVbcHJvcC5yZXBsYWNlKC9cXC0oXFx3KS9nLCBmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYi50b1VwcGVyQ2FzZSgpOyB9KV07XG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gJ2ZpbHRlcicpIHtcbiAgICAgICAgICAgICAgdmFsID0gdmFsLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgL2FscGhhXFwob3BhY2l0eT0oWzAtOV0rKVxcKS8sXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBiIC8gMTAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qanNsaW50IHVucGFyYW06IGZhbHNlKi9cbiAgICAgICAgICAgIHJldHVybiB2YWwgPT09ICcnID8gMSA6IHZhbDtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuYWRhcHRlclJ1biA9IGZ1bmN0aW9uIChlbGVtLCBtZXRob2QpIHtcbiAgICAgICAgICB2YXIgYWxpYXMgPSB7IHdpZHRoOiAnY2xpZW50V2lkdGgnLCBoZWlnaHQ6ICdjbGllbnRIZWlnaHQnIH1bbWV0aG9kXTtcblxuICAgICAgICAgIGlmIChhbGlhcykge1xuICAgICAgICAgICAgZWxlbS5zdHlsZS56b29tID0gMTtcbiAgICAgICAgICAgIHJldHVybiBlbGVtW2FsaWFzXSAtIDIgKiBwYXJzZUludChIaWdoY2hhcnRzQWRhcHRlci5fZ2V0U3R5bGUoZWxlbSwgJ3BhZGRpbmcnKSwgMTApO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFBcnJheS5wcm90b3R5cGUuZm9yRWFjaCkge1xuICAgICAgICB0aGlzLmVhY2ggPSBmdW5jdGlvbiAoYXJyLCBmbikgeyAvLyBsZWdhY3lcbiAgICAgICAgICB2YXIgaSA9IDAsXG4gICAgICAgICAgICBsZW4gPSBhcnIubGVuZ3RoO1xuICAgICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmbi5jYWxsKGFycltpXSwgYXJyW2ldLCBpLCBhcnIpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmICghQXJyYXkucHJvdG90eXBlLmluZGV4T2YpIHtcbiAgICAgICAgdGhpcy5pbkFycmF5ID0gZnVuY3Rpb24gKGl0ZW0sIGFycikge1xuICAgICAgICAgIHZhciBsZW4sXG4gICAgICAgICAgICBpID0gMDtcblxuICAgICAgICAgIGlmIChhcnIpIHtcbiAgICAgICAgICAgIGxlbiA9IGFyci5sZW5ndGg7XG5cbiAgICAgICAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgaWYgKGFycltpXSA9PT0gaXRlbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAoIUFycmF5LnByb3RvdHlwZS5maWx0ZXIpIHtcbiAgICAgICAgdGhpcy5ncmVwID0gZnVuY3Rpb24gKGVsZW1lbnRzLCBjYWxsYmFjaykge1xuICAgICAgICAgIHZhciByZXQgPSBbXSxcbiAgICAgICAgICAgIGkgPSAwLFxuICAgICAgICAgICAgbGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xuXG4gICAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCEhY2FsbGJhY2soZWxlbWVudHNbaV0sIGkpKSB7XG4gICAgICAgICAgICAgIHJldC5wdXNoKGVsZW1lbnRzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLy0tLSBFbmQgY29tcGF0aWJpbGl0eSBzZWN0aW9uIC0tLVxuXG5cbiAgICAgIC8qKlxuICAgICAgICogU3RhcnQgb2YgYW5pbWF0aW9uIHNwZWNpZmljIGNvZGVcbiAgICAgICAqL1xuICAgICAgRnggPSBmdW5jdGlvbiAoZWxlbSwgb3B0aW9ucywgcHJvcCkge1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmVsZW0gPSBlbGVtO1xuICAgICAgICB0aGlzLnByb3AgPSBwcm9wO1xuICAgICAgfTtcbiAgICAgIEZ4LnByb3RvdHlwZSA9IHtcblxuICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgc3R5bGVzLFxuICAgICAgICAgICAgcGF0aHMgPSB0aGlzLnBhdGhzLFxuICAgICAgICAgICAgZWxlbSA9IHRoaXMuZWxlbSxcbiAgICAgICAgICAgIGVsZW1lbGVtID0gZWxlbS5lbGVtZW50OyAvLyBpZiBkZXN0cm95ZWQsIGl0IGlzIG51bGxcblxuICAgICAgICAgIC8vIEFuaW1hdGlvbiBzZXR0ZXIgZGVmaW5lZCBmcm9tIG91dHNpZGVcbiAgICAgICAgICBpZiAoYW5pbVNldHRlcnNbdGhpcy5wcm9wXSkge1xuICAgICAgICAgICAgYW5pbVNldHRlcnNbdGhpcy5wcm9wXSh0aGlzKTtcblxuICAgICAgICAgICAgLy8gQW5pbWF0aW5nIGEgcGF0aCBkZWZpbml0aW9uIG9uIFNWR0VsZW1lbnRcbiAgICAgICAgICB9IGVsc2UgaWYgKHBhdGhzICYmIGVsZW1lbGVtKSB7XG4gICAgICAgICAgICBlbGVtLmF0dHIoJ2QnLCBwYXRoQW5pbS5zdGVwKHBhdGhzWzBdLCBwYXRoc1sxXSwgdGhpcy5ub3csIHRoaXMudG9EKSk7XG5cbiAgICAgICAgICAgIC8vIE90aGVyIGFuaW1hdGlvbnMgb24gU1ZHRWxlbWVudFxuICAgICAgICAgIH0gZWxzZSBpZiAoZWxlbS5hdHRyKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVsZW0pIHtcbiAgICAgICAgICAgICAgZWxlbS5hdHRyKHRoaXMucHJvcCwgdGhpcy5ub3cpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIVE1MIHN0eWxlc1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdHlsZXMgPSB7fTtcbiAgICAgICAgICAgIHN0eWxlc1t0aGlzLnByb3BdID0gdGhpcy5ub3cgKyB0aGlzLnVuaXQ7XG4gICAgICAgICAgICBIaWdoY2hhcnRzLmNzcyhlbGVtLCBzdHlsZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuc3RlcCkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCh0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfSxcbiAgICAgICAgY3VzdG9tOiBmdW5jdGlvbiAoZnJvbSwgdG8sIHVuaXQpIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICAgICAgICB0ID0gZnVuY3Rpb24gKGdvdG9FbmQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc3RlcChnb3RvRW5kKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSArbmV3IERhdGUoKTtcbiAgICAgICAgICB0aGlzLnN0YXJ0ID0gZnJvbTtcbiAgICAgICAgICB0aGlzLmVuZCA9IHRvO1xuICAgICAgICAgIHRoaXMudW5pdCA9IHVuaXQ7XG4gICAgICAgICAgdGhpcy5ub3cgPSB0aGlzLnN0YXJ0O1xuICAgICAgICAgIHRoaXMucG9zID0gdGhpcy5zdGF0ZSA9IDA7XG5cbiAgICAgICAgICB0LmVsZW0gPSB0aGlzLmVsZW07XG5cbiAgICAgICAgICBpZiAodCgpICYmIHRpbWVycy5wdXNoKHQpID09PSAxKSB7XG4gICAgICAgICAgICB0aW1lcklkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aW1lcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRpbWVyc1tpXSgpKSB7XG4gICAgICAgICAgICAgICAgICB0aW1lcnMuc3BsaWNlKGktLSwgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKCF0aW1lcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcklkKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgMTMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBzdGVwOiBmdW5jdGlvbiAoZ290b0VuZCkge1xuICAgICAgICAgIHZhciB0ID0gK25ldyBEYXRlKCksXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBkb25lLFxuICAgICAgICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcbiAgICAgICAgICAgIGVsZW0gPSB0aGlzLmVsZW0sXG4gICAgICAgICAgICBpO1xuXG4gICAgICAgICAgaWYgKGVsZW0uc3RvcEFuaW1hdGlvbiB8fCAoZWxlbS5hdHRyICYmICFlbGVtLmVsZW1lbnQpKSB7IC8vICMyNjE2LCBlbGVtZW50IGluY2x1ZGluZyBmbGFnIGlzIGRlc3Ryb3llZFxuICAgICAgICAgICAgcmV0ID0gZmFsc2U7XG5cbiAgICAgICAgICB9IGVsc2UgaWYgKGdvdG9FbmQgfHwgdCA+PSBvcHRpb25zLmR1cmF0aW9uICsgdGhpcy5zdGFydFRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMubm93ID0gdGhpcy5lbmQ7XG4gICAgICAgICAgICB0aGlzLnBvcyA9IHRoaXMuc3RhdGUgPSAxO1xuICAgICAgICAgICAgdGhpcy51cGRhdGUoKTtcblxuICAgICAgICAgICAgdGhpcy5vcHRpb25zLmN1ckFuaW1bdGhpcy5wcm9wXSA9IHRydWU7XG5cbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgZm9yIChpIGluIG9wdGlvbnMuY3VyQW5pbSkge1xuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5jdXJBbmltW2ldICE9PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmNvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5jb21wbGV0ZS5jYWxsKGVsZW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXQgPSBmYWxzZTtcblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgbiA9IHQgLSB0aGlzLnN0YXJ0VGltZTtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBuIC8gb3B0aW9ucy5kdXJhdGlvbjtcbiAgICAgICAgICAgIHRoaXMucG9zID0gb3B0aW9ucy5lYXNpbmcobiwgMCwgMSwgb3B0aW9ucy5kdXJhdGlvbik7XG4gICAgICAgICAgICB0aGlzLm5vdyA9IHRoaXMuc3RhcnQgKyAoKHRoaXMuZW5kIC0gdGhpcy5zdGFydCkgKiB0aGlzLnBvcyk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgICAgICAgICAgcmV0ID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLyoqXG4gICAgICAgKiBUaGUgYWRhcHRlciBhbmltYXRlIG1ldGhvZFxuICAgICAgICovXG4gICAgICB0aGlzLmFuaW1hdGUgPSBmdW5jdGlvbiAoZWwsIHByb3AsIG9wdCkge1xuICAgICAgICB2YXIgc3RhcnQsXG4gICAgICAgICAgdW5pdCA9ICcnLFxuICAgICAgICAgIGVuZCxcbiAgICAgICAgICBmeCxcbiAgICAgICAgICBhcmdzLFxuICAgICAgICAgIG5hbWU7XG5cbiAgICAgICAgZWwuc3RvcEFuaW1hdGlvbiA9IGZhbHNlOyAvLyByZWFkeSBmb3IgbmV3XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvcHQgIT09ICdvYmplY3QnIHx8IG9wdCA9PT0gbnVsbCkge1xuICAgICAgICAgIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgICAgICAgb3B0ID0ge1xuICAgICAgICAgICAgZHVyYXRpb246IGFyZ3NbMl0sXG4gICAgICAgICAgICBlYXNpbmc6IGFyZ3NbM10sXG4gICAgICAgICAgICBjb21wbGV0ZTogYXJnc1s0XVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBvcHQuZHVyYXRpb24gIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgb3B0LmR1cmF0aW9uID0gNDAwO1xuICAgICAgICB9XG4gICAgICAgIG9wdC5lYXNpbmcgPSBNYXRoW29wdC5lYXNpbmddIHx8IE1hdGguZWFzZUluT3V0U2luZTtcbiAgICAgICAgb3B0LmN1ckFuaW0gPSBIaWdoY2hhcnRzLmV4dGVuZCh7fSwgcHJvcCk7XG5cbiAgICAgICAgZm9yIChuYW1lIGluIHByb3ApIHtcbiAgICAgICAgICBmeCA9IG5ldyBGeChlbCwgb3B0LCBuYW1lKTtcbiAgICAgICAgICBlbmQgPSBudWxsO1xuXG4gICAgICAgICAgaWYgKG5hbWUgPT09ICdkJykge1xuICAgICAgICAgICAgZngucGF0aHMgPSBwYXRoQW5pbS5pbml0KFxuICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgZWwuZCxcbiAgICAgICAgICAgICAgcHJvcC5kXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZngudG9EID0gcHJvcC5kO1xuICAgICAgICAgICAgc3RhcnQgPSAwO1xuICAgICAgICAgICAgZW5kID0gMTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGVsLmF0dHIpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gZWwuYXR0cihuYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhcnQgPSBwYXJzZUZsb2F0KEhpZ2hjaGFydHNBZGFwdGVyLl9nZXRTdHlsZShlbCwgbmFtZSkpIHx8IDA7XG4gICAgICAgICAgICBpZiAobmFtZSAhPT0gJ29wYWNpdHknKSB7XG4gICAgICAgICAgICAgIHVuaXQgPSAncHgnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZW5kKSB7XG4gICAgICAgICAgICBlbmQgPSBwcm9wW25hbWVdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmeC5jdXN0b20oc3RhcnQsIGVuZCwgdW5pdCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB0byByZXR1cm4gQ1NTIHZhbHVlIGZvciBnaXZlbiBlbGVtZW50IGFuZCBwcm9wZXJ0eVxuICAgICAqL1xuICAgIF9nZXRTdHlsZTogZnVuY3Rpb24gKGVsLCBwcm9wKSB7XG4gICAgICByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwsIHVuZGVmaW5lZCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGFuIGFuaW1hdGlvbiBzZXR0ZXIgZm9yIGEgc3BlY2lmaWMgcHJvcGVydHlcbiAgICAgKi9cbiAgICBhZGRBbmltU2V0dGVyOiBmdW5jdGlvbiAocHJvcCwgZm4pIHtcbiAgICAgIGFuaW1TZXR0ZXJzW3Byb3BdID0gZm47XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIERvd25sb2FkcyBhIHNjcmlwdCBhbmQgZXhlY3V0ZXMgYSBjYWxsYmFjayB3aGVuIGRvbmUuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHNjcmlwdExvY2F0aW9uXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKi9cbiAgICBnZXRTY3JpcHQ6IGZ1bmN0aW9uIChzY3JpcHRMb2NhdGlvbiwgY2FsbGJhY2spIHtcbiAgICAgIC8vIFdlIGNhbm5vdCBhc3N1bWUgdGhhdCBBc3NldHMgY2xhc3MgZnJvbSBtb290b29scy1tb3JlIGlzIGF2YWlsYWJsZSBzbyBpbnN0ZWFkIGluc2VydCBhIHNjcmlwdCB0YWcgdG8gZG93bmxvYWQgc2NyaXB0LlxuICAgICAgdmFyIGhlYWQgPSBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXSxcbiAgICAgICAgc2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICBzY3JpcHQudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgICAgc2NyaXB0LnNyYyA9IHNjcmlwdExvY2F0aW9uO1xuICAgICAgc2NyaXB0Lm9ubG9hZCA9IGNhbGxiYWNrO1xuXG4gICAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgaW5kZXggb2YgYW4gaXRlbSBpbiBhbiBhcnJheSwgb3IgLTEgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgaW5BcnJheTogZnVuY3Rpb24gKGl0ZW0sIGFycikge1xuICAgICAgcmV0dXJuIGFyci5pbmRleE9mID8gYXJyLmluZGV4T2YoaXRlbSkgOiBlbXB0eUFycmF5LmluZGV4T2YuY2FsbChhcnIsIGl0ZW0pO1xuICAgIH0sXG5cblxuICAgIC8qKlxuICAgICAqIEEgZGlyZWN0IGxpbmsgdG8gYWRhcHRlciBtZXRob2RzXG4gICAgICovXG4gICAgYWRhcHRlclJ1bjogZnVuY3Rpb24gKGVsZW0sIG1ldGhvZCkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KEhpZ2hjaGFydHNBZGFwdGVyLl9nZXRTdHlsZShlbGVtLCBtZXRob2QpLCAxMCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEZpbHRlciBhbiBhcnJheVxuICAgICAqL1xuICAgIGdyZXA6IGZ1bmN0aW9uIChlbGVtZW50cywgY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiBlbXB0eUFycmF5LmZpbHRlci5jYWxsKGVsZW1lbnRzLCBjYWxsYmFjayk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIE1hcCBhbiBhcnJheVxuICAgICAqL1xuICAgIG1hcDogZnVuY3Rpb24gKGFyciwgZm4pIHtcbiAgICAgIHZhciByZXN1bHRzID0gW10sIGkgPSAwLCBsZW4gPSBhcnIubGVuZ3RoO1xuXG4gICAgICBmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHJlc3VsdHNbaV0gPSBmbi5jYWxsKGFycltpXSwgYXJyW2ldLCBpLCBhcnIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlbGVtZW50J3Mgb2Zmc2V0IHBvc2l0aW9uLCBjb3JyZWN0ZWQgYnkgb3ZlcmZsb3c6YXV0by4gTG9vc2VseSBiYXNlZCBvbiBqUXVlcnkncyBvZmZzZXQgbWV0aG9kLlxuICAgICAqL1xuICAgIG9mZnNldDogZnVuY3Rpb24gKGVsKSB7XG4gICAgICB2YXIgZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICAgICAgYm94ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogYm94LnRvcCAgKyAod2luZG93LnBhZ2VZT2Zmc2V0IHx8IGRvY0VsZW0uc2Nyb2xsVG9wKSAgLSAoZG9jRWxlbS5jbGllbnRUb3AgIHx8IDApLFxuICAgICAgICBsZWZ0OiBib3gubGVmdCArICh3aW5kb3cucGFnZVhPZmZzZXQgfHwgZG9jRWxlbS5zY3JvbGxMZWZ0KSAtIChkb2NFbGVtLmNsaWVudExlZnQgfHwgMClcbiAgICAgIH07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBldmVudCBsaXN0ZW5lclxuICAgICAqL1xuICAgIGFkZEV2ZW50OiBmdW5jdGlvbiAoZWwsIHR5cGUsIGZuKSB7XG4gICAgICBhdWdtZW50KGVsKS5iaW5kKHR5cGUsIGZuKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGV2ZW50IGFkZGVkIHdpdGggYWRkRXZlbnRcbiAgICAgKi9cbiAgICByZW1vdmVFdmVudDogZnVuY3Rpb24gKGVsLCB0eXBlLCBmbikge1xuICAgICAgYXVnbWVudChlbCkudW5iaW5kKHR5cGUsIGZuKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRmlyZSBhbiBldmVudCBvbiBhIGN1c3RvbSBvYmplY3RcbiAgICAgKi9cbiAgICBmaXJlRXZlbnQ6IGZ1bmN0aW9uIChlbCwgdHlwZSwgZXZlbnRBcmd1bWVudHMsIGRlZmF1bHRGdW5jdGlvbikge1xuICAgICAgdmFyIGU7XG5cbiAgICAgIGlmIChkb2MuY3JlYXRlRXZlbnQgJiYgKGVsLmRpc3BhdGNoRXZlbnQgfHwgZWwuZmlyZUV2ZW50KSkge1xuICAgICAgICBlID0gZG9jLmNyZWF0ZUV2ZW50KCdFdmVudHMnKTtcbiAgICAgICAgZS5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgICAgIGUudGFyZ2V0ID0gZWw7XG5cbiAgICAgICAgSGlnaGNoYXJ0cy5leHRlbmQoZSwgZXZlbnRBcmd1bWVudHMpO1xuXG4gICAgICAgIGlmIChlbC5kaXNwYXRjaEV2ZW50KSB7XG4gICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbC5maXJlRXZlbnQodHlwZSwgZSk7XG4gICAgICAgIH1cblxuICAgICAgfSBlbHNlIGlmIChlbC5IQ0V4dGVuZGVkID09PSB0cnVlKSB7XG4gICAgICAgIGV2ZW50QXJndW1lbnRzID0gZXZlbnRBcmd1bWVudHMgfHwge307XG4gICAgICAgIGVsLnRyaWdnZXIodHlwZSwgZXZlbnRBcmd1bWVudHMpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRBcmd1bWVudHMgJiYgZXZlbnRBcmd1bWVudHMuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgICBkZWZhdWx0RnVuY3Rpb24gPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAoZGVmYXVsdEZ1bmN0aW9uKSB7XG4gICAgICAgIGRlZmF1bHRGdW5jdGlvbihldmVudEFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIHdhc2hNb3VzZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuICAgICAgcmV0dXJuIGU7XG4gICAgfSxcblxuXG4gICAgLyoqXG4gICAgICogU3RvcCBydW5uaW5nIGFuaW1hdGlvblxuICAgICAqL1xuICAgIHN0b3A6IGZ1bmN0aW9uIChlbCkge1xuICAgICAgZWwuc3RvcEFuaW1hdGlvbiA9IHRydWU7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFV0aWxpdHkgZm9yIGl0ZXJhdGluZyBvdmVyIGFuIGFycmF5LiBQYXJhbWV0ZXJzIGFyZSByZXZlcnNlZCBjb21wYXJlZCB0byBqUXVlcnkuXG4gICAgICogQHBhcmFtIHtBcnJheX0gYXJyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICAgKi9cbiAgICBlYWNoOiBmdW5jdGlvbiAoYXJyLCBmbikgeyAvLyBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKGFyciwgZm4pO1xuICAgIH1cbiAgfTtcbn0oKSk7IiwidmFyIHByb2Nlc3M9cmVxdWlyZShcIl9fYnJvd3NlcmlmeV9wcm9jZXNzXCIpOy8qZ2xvYmFsIHNldEltbWVkaWF0ZTogZmFsc2UsIHNldFRpbWVvdXQ6IGZhbHNlLCBjb25zb2xlOiBmYWxzZSAqL1xuKGZ1bmN0aW9uICgpIHtcblxuICAgIHZhciBhc3luYyA9IHt9O1xuXG4gICAgLy8gZ2xvYmFsIG9uIHRoZSBzZXJ2ZXIsIHdpbmRvdyBpbiB0aGUgYnJvd3NlclxuICAgIHZhciByb290LCBwcmV2aW91c19hc3luYztcblxuICAgIHJvb3QgPSB0aGlzO1xuICAgIGlmIChyb290ICE9IG51bGwpIHtcbiAgICAgIHByZXZpb3VzX2FzeW5jID0gcm9vdC5hc3luYztcbiAgICB9XG5cbiAgICBhc3luYy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByb290LmFzeW5jID0gcHJldmlvdXNfYXN5bmM7XG4gICAgICAgIHJldHVybiBhc3luYztcbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gb25seV9vbmNlKGZuKSB7XG4gICAgICAgIHZhciBjYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgaWYgKGNhbGxlZCkgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbGJhY2sgd2FzIGFscmVhZHkgY2FsbGVkLlwiKTtcbiAgICAgICAgICAgIGNhbGxlZCA9IHRydWU7XG4gICAgICAgICAgICBmbi5hcHBseShyb290LCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8vLyBjcm9zcy1icm93c2VyIGNvbXBhdGlibGl0eSBmdW5jdGlvbnMgLy8vL1xuXG4gICAgdmFyIF9lYWNoID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IpIHtcbiAgICAgICAgaWYgKGFyci5mb3JFYWNoKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyLmZvckVhY2goaXRlcmF0b3IpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBpdGVyYXRvcihhcnJbaV0sIGksIGFycik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIF9tYXAgPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvcikge1xuICAgICAgICBpZiAoYXJyLm1hcCkge1xuICAgICAgICAgICAgcmV0dXJuIGFyci5tYXAoaXRlcmF0b3IpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByZXN1bHRzID0gW107XG4gICAgICAgIF9lYWNoKGFyciwgZnVuY3Rpb24gKHgsIGksIGEpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChpdGVyYXRvcih4LCBpLCBhKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9O1xuXG4gICAgdmFyIF9yZWR1Y2UgPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvciwgbWVtbykge1xuICAgICAgICBpZiAoYXJyLnJlZHVjZSkge1xuICAgICAgICAgICAgcmV0dXJuIGFyci5yZWR1Y2UoaXRlcmF0b3IsIG1lbW8pO1xuICAgICAgICB9XG4gICAgICAgIF9lYWNoKGFyciwgZnVuY3Rpb24gKHgsIGksIGEpIHtcbiAgICAgICAgICAgIG1lbW8gPSBpdGVyYXRvcihtZW1vLCB4LCBpLCBhKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBtZW1vO1xuICAgIH07XG5cbiAgICB2YXIgX2tleXMgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIGlmIChPYmplY3Qua2V5cykge1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGtleXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgayBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaykpIHtcbiAgICAgICAgICAgICAgICBrZXlzLnB1c2goayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGtleXM7XG4gICAgfTtcblxuICAgIC8vLy8gZXhwb3J0ZWQgYXN5bmMgbW9kdWxlIGZ1bmN0aW9ucyAvLy8vXG5cbiAgICAvLy8vIG5leHRUaWNrIGltcGxlbWVudGF0aW9uIHdpdGggYnJvd3Nlci1jb21wYXRpYmxlIGZhbGxiYWNrIC8vLy9cbiAgICBpZiAodHlwZW9mIHByb2Nlc3MgPT09ICd1bmRlZmluZWQnIHx8ICEocHJvY2Vzcy5uZXh0VGljaykpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGFzeW5jLm5leHRUaWNrID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgICAgLy8gbm90IGEgZGlyZWN0IGFsaWFzIGZvciBJRTEwIGNvbXBhdGliaWxpdHlcbiAgICAgICAgICAgICAgICBzZXRJbW1lZGlhdGUoZm4pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZSA9IGFzeW5jLm5leHRUaWNrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXN5bmMubmV4dFRpY2sgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZuLCAwKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhc3luYy5zZXRJbW1lZGlhdGUgPSBhc3luYy5uZXh0VGljaztcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgYXN5bmMubmV4dFRpY2sgPSBwcm9jZXNzLm5leHRUaWNrO1xuICAgICAgICBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgICAvLyBub3QgYSBkaXJlY3QgYWxpYXMgZm9yIElFMTAgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICBzZXRJbW1lZGlhdGUoZm4pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZSA9IGFzeW5jLm5leHRUaWNrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMuZWFjaCA9IGZ1bmN0aW9uIChhcnIsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAoIWFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb21wbGV0ZWQgPSAwO1xuICAgICAgICBfZWFjaChhcnIsIGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LCBvbmx5X29uY2UoZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZCArPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tcGxldGVkID49IGFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGFzeW5jLmZvckVhY2ggPSBhc3luYy5lYWNoO1xuXG4gICAgYXN5bmMuZWFjaFNlcmllcyA9IGZ1bmN0aW9uIChhcnIsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAoIWFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb21wbGV0ZWQgPSAwO1xuICAgICAgICB2YXIgaXRlcmF0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKGFycltjb21wbGV0ZWRdLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGVkICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21wbGV0ZWQgPj0gYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgaXRlcmF0ZSgpO1xuICAgIH07XG4gICAgYXN5bmMuZm9yRWFjaFNlcmllcyA9IGFzeW5jLmVhY2hTZXJpZXM7XG5cbiAgICBhc3luYy5lYWNoTGltaXQgPSBmdW5jdGlvbiAoYXJyLCBsaW1pdCwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBmbiA9IF9lYWNoTGltaXQobGltaXQpO1xuICAgICAgICBmbi5hcHBseShudWxsLCBbYXJyLCBpdGVyYXRvciwgY2FsbGJhY2tdKTtcbiAgICB9O1xuICAgIGFzeW5jLmZvckVhY2hMaW1pdCA9IGFzeW5jLmVhY2hMaW1pdDtcblxuICAgIHZhciBfZWFjaExpbWl0ID0gZnVuY3Rpb24gKGxpbWl0KSB7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhcnIsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgIGlmICghYXJyLmxlbmd0aCB8fCBsaW1pdCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgY29tcGxldGVkID0gMDtcbiAgICAgICAgICAgIHZhciBzdGFydGVkID0gMDtcbiAgICAgICAgICAgIHZhciBydW5uaW5nID0gMDtcblxuICAgICAgICAgICAgKGZ1bmN0aW9uIHJlcGxlbmlzaCAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRlZCA+PSBhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHdoaWxlIChydW5uaW5nIDwgbGltaXQgJiYgc3RhcnRlZCA8IGFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnRlZCArPSAxO1xuICAgICAgICAgICAgICAgICAgICBydW5uaW5nICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIGl0ZXJhdG9yKGFycltzdGFydGVkIC0gMV0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5uaW5nIC09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRlZCA+PSBhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsZW5pc2goKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH07XG4gICAgfTtcblxuXG4gICAgdmFyIGRvUGFyYWxsZWwgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBbYXN5bmMuZWFjaF0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHZhciBkb1BhcmFsbGVsTGltaXQgPSBmdW5jdGlvbihsaW1pdCwgZm4pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBbX2VhY2hMaW1pdChsaW1pdCldLmNvbmNhdChhcmdzKSk7XG4gICAgICAgIH07XG4gICAgfTtcbiAgICB2YXIgZG9TZXJpZXMgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShudWxsLCBbYXN5bmMuZWFjaFNlcmllc10uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG5cbiAgICB2YXIgX2FzeW5jTWFwID0gZnVuY3Rpb24gKGVhY2hmbiwgYXJyLCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgYXJyID0gX21hcChhcnIsIGZ1bmN0aW9uICh4LCBpKSB7XG4gICAgICAgICAgICByZXR1cm4ge2luZGV4OiBpLCB2YWx1ZTogeH07XG4gICAgICAgIH0pO1xuICAgICAgICBlYWNoZm4oYXJyLCBmdW5jdGlvbiAoeCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKHgudmFsdWUsIGZ1bmN0aW9uIChlcnIsIHYpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzW3guaW5kZXhdID0gdjtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgcmVzdWx0cyk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgYXN5bmMubWFwID0gZG9QYXJhbGxlbChfYXN5bmNNYXApO1xuICAgIGFzeW5jLm1hcFNlcmllcyA9IGRvU2VyaWVzKF9hc3luY01hcCk7XG4gICAgYXN5bmMubWFwTGltaXQgPSBmdW5jdGlvbiAoYXJyLCBsaW1pdCwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBfbWFwTGltaXQobGltaXQpKGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgdmFyIF9tYXBMaW1pdCA9IGZ1bmN0aW9uKGxpbWl0KSB7XG4gICAgICAgIHJldHVybiBkb1BhcmFsbGVsTGltaXQobGltaXQsIF9hc3luY01hcCk7XG4gICAgfTtcblxuICAgIC8vIHJlZHVjZSBvbmx5IGhhcyBhIHNlcmllcyB2ZXJzaW9uLCBhcyBkb2luZyByZWR1Y2UgaW4gcGFyYWxsZWwgd29uJ3RcbiAgICAvLyB3b3JrIGluIG1hbnkgc2l0dWF0aW9ucy5cbiAgICBhc3luYy5yZWR1Y2UgPSBmdW5jdGlvbiAoYXJyLCBtZW1vLCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgYXN5bmMuZWFjaFNlcmllcyhhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IobWVtbywgeCwgZnVuY3Rpb24gKGVyciwgdikge1xuICAgICAgICAgICAgICAgIG1lbW8gPSB2O1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBtZW1vKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyBpbmplY3QgYWxpYXNcbiAgICBhc3luYy5pbmplY3QgPSBhc3luYy5yZWR1Y2U7XG4gICAgLy8gZm9sZGwgYWxpYXNcbiAgICBhc3luYy5mb2xkbCA9IGFzeW5jLnJlZHVjZTtcblxuICAgIGFzeW5jLnJlZHVjZVJpZ2h0ID0gZnVuY3Rpb24gKGFyciwgbWVtbywgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXZlcnNlZCA9IF9tYXAoYXJyLCBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH0pLnJldmVyc2UoKTtcbiAgICAgICAgYXN5bmMucmVkdWNlKHJldmVyc2VkLCBtZW1vLCBpdGVyYXRvciwgY2FsbGJhY2spO1xuICAgIH07XG4gICAgLy8gZm9sZHIgYWxpYXNcbiAgICBhc3luYy5mb2xkciA9IGFzeW5jLnJlZHVjZVJpZ2h0O1xuXG4gICAgdmFyIF9maWx0ZXIgPSBmdW5jdGlvbiAoZWFjaGZuLCBhcnIsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgICAgICBhcnIgPSBfbWFwKGFyciwgZnVuY3Rpb24gKHgsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiB7aW5kZXg6IGksIHZhbHVlOiB4fTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVhY2hmbihhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeC52YWx1ZSwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICBpZiAodikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goeCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY2FsbGJhY2soX21hcChyZXN1bHRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgICAgICAgICB9KSwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geC52YWx1ZTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBhc3luYy5maWx0ZXIgPSBkb1BhcmFsbGVsKF9maWx0ZXIpO1xuICAgIGFzeW5jLmZpbHRlclNlcmllcyA9IGRvU2VyaWVzKF9maWx0ZXIpO1xuICAgIC8vIHNlbGVjdCBhbGlhc1xuICAgIGFzeW5jLnNlbGVjdCA9IGFzeW5jLmZpbHRlcjtcbiAgICBhc3luYy5zZWxlY3RTZXJpZXMgPSBhc3luYy5maWx0ZXJTZXJpZXM7XG5cbiAgICB2YXIgX3JlamVjdCA9IGZ1bmN0aW9uIChlYWNoZm4sIGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXN1bHRzID0gW107XG4gICAgICAgIGFyciA9IF9tYXAoYXJyLCBmdW5jdGlvbiAoeCwgaSkge1xuICAgICAgICAgICAgcmV0dXJuIHtpbmRleDogaSwgdmFsdWU6IHh9O1xuICAgICAgICB9KTtcbiAgICAgICAgZWFjaGZuKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LnZhbHVlLCBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIGlmICghdikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goeCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY2FsbGJhY2soX21hcChyZXN1bHRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYS5pbmRleCAtIGIuaW5kZXg7XG4gICAgICAgICAgICB9KSwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geC52YWx1ZTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBhc3luYy5yZWplY3QgPSBkb1BhcmFsbGVsKF9yZWplY3QpO1xuICAgIGFzeW5jLnJlamVjdFNlcmllcyA9IGRvU2VyaWVzKF9yZWplY3QpO1xuXG4gICAgdmFyIF9kZXRlY3QgPSBmdW5jdGlvbiAoZWFjaGZuLCBhcnIsIGl0ZXJhdG9yLCBtYWluX2NhbGxiYWNrKSB7XG4gICAgICAgIGVhY2hmbihhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeCwgZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgbWFpbl9jYWxsYmFjayh4KTtcbiAgICAgICAgICAgICAgICAgICAgbWFpbl9jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgbWFpbl9jYWxsYmFjaygpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGFzeW5jLmRldGVjdCA9IGRvUGFyYWxsZWwoX2RldGVjdCk7XG4gICAgYXN5bmMuZGV0ZWN0U2VyaWVzID0gZG9TZXJpZXMoX2RldGVjdCk7XG5cbiAgICBhc3luYy5zb21lID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIG1haW5fY2FsbGJhY2spIHtcbiAgICAgICAgYXN5bmMuZWFjaChhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeCwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICBpZiAodikge1xuICAgICAgICAgICAgICAgICAgICBtYWluX2NhbGxiYWNrKHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBtYWluX2NhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgbWFpbl9jYWxsYmFjayhmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8gYW55IGFsaWFzXG4gICAgYXN5bmMuYW55ID0gYXN5bmMuc29tZTtcblxuICAgIGFzeW5jLmV2ZXJ5ID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIG1haW5fY2FsbGJhY2spIHtcbiAgICAgICAgYXN5bmMuZWFjaChhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeCwgZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXYpIHtcbiAgICAgICAgICAgICAgICAgICAgbWFpbl9jYWxsYmFjayhmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIG1haW5fY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBtYWluX2NhbGxiYWNrKHRydWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIGFsbCBhbGlhc1xuICAgIGFzeW5jLmFsbCA9IGFzeW5jLmV2ZXJ5O1xuXG4gICAgYXN5bmMuc29ydEJ5ID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzeW5jLm1hcChhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeCwgZnVuY3Rpb24gKGVyciwgY3JpdGVyaWEpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCB7dmFsdWU6IHgsIGNyaXRlcmlhOiBjcml0ZXJpYX0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyLCByZXN1bHRzKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgZm4gPSBmdW5jdGlvbiAobGVmdCwgcmlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGEgPSBsZWZ0LmNyaXRlcmlhLCBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMDtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIF9tYXAocmVzdWx0cy5zb3J0KGZuKSwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHgudmFsdWU7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgYXN5bmMuYXV0byA9IGZ1bmN0aW9uICh0YXNrcywgY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgdmFyIGtleXMgPSBfa2V5cyh0YXNrcyk7XG4gICAgICAgIGlmICgha2V5cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciByZXN1bHRzID0ge307XG5cbiAgICAgICAgdmFyIGxpc3RlbmVycyA9IFtdO1xuICAgICAgICB2YXIgYWRkTGlzdGVuZXIgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgIGxpc3RlbmVycy51bnNoaWZ0KGZuKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3RlbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGlmIChsaXN0ZW5lcnNbaV0gPT09IGZuKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVycy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHZhciB0YXNrQ29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfZWFjaChsaXN0ZW5lcnMuc2xpY2UoMCksIGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBhZGRMaXN0ZW5lcihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoX2tleXMocmVzdWx0cykubGVuZ3RoID09PSBrZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIF9lYWNoKGtleXMsIGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICB2YXIgdGFzayA9ICh0YXNrc1trXSBpbnN0YW5jZW9mIEZ1bmN0aW9uKSA/IFt0YXNrc1trXV06IHRhc2tzW2tdO1xuICAgICAgICAgICAgdmFyIHRhc2tDYWxsYmFjayA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNhZmVSZXN1bHRzID0ge307XG4gICAgICAgICAgICAgICAgICAgIF9lYWNoKF9rZXlzKHJlc3VsdHMpLCBmdW5jdGlvbihya2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzYWZlUmVzdWx0c1tya2V5XSA9IHJlc3VsdHNbcmtleV07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzYWZlUmVzdWx0c1trXSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgc2FmZVJlc3VsdHMpO1xuICAgICAgICAgICAgICAgICAgICAvLyBzdG9wIHN1YnNlcXVlbnQgZXJyb3JzIGhpdHRpbmcgY2FsbGJhY2sgbXVsdGlwbGUgdGltZXNcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHNba10gPSBhcmdzO1xuICAgICAgICAgICAgICAgICAgICBhc3luYy5zZXRJbW1lZGlhdGUodGFza0NvbXBsZXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIHJlcXVpcmVzID0gdGFzay5zbGljZSgwLCBNYXRoLmFicyh0YXNrLmxlbmd0aCAtIDEpKSB8fCBbXTtcbiAgICAgICAgICAgIHZhciByZWFkeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX3JlZHVjZShyZXF1aXJlcywgZnVuY3Rpb24gKGEsIHgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChhICYmIHJlc3VsdHMuaGFzT3duUHJvcGVydHkoeCkpO1xuICAgICAgICAgICAgICAgIH0sIHRydWUpICYmICFyZXN1bHRzLmhhc093blByb3BlcnR5KGspO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChyZWFkeSgpKSB7XG4gICAgICAgICAgICAgICAgdGFza1t0YXNrLmxlbmd0aCAtIDFdKHRhc2tDYWxsYmFjaywgcmVzdWx0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWFkeSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrW3Rhc2subGVuZ3RoIC0gMV0odGFza0NhbGxiYWNrLCByZXN1bHRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgYWRkTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgYXN5bmMud2F0ZXJmYWxsID0gZnVuY3Rpb24gKHRhc2tzLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAodGFza3MuY29uc3RydWN0b3IgIT09IEFycmF5KSB7XG4gICAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgdG8gd2F0ZXJmYWxsIG11c3QgYmUgYW4gYXJyYXkgb2YgZnVuY3Rpb25zJyk7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0YXNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB3cmFwSXRlcmF0b3IgPSBmdW5jdGlvbiAoaXRlcmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaCh3cmFwSXRlcmF0b3IobmV4dCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhc3luYy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3IuYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIHdyYXBJdGVyYXRvcihhc3luYy5pdGVyYXRvcih0YXNrcykpKCk7XG4gICAgfTtcblxuICAgIHZhciBfcGFyYWxsZWwgPSBmdW5jdGlvbihlYWNoZm4sIHRhc2tzLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAodGFza3MuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XG4gICAgICAgICAgICBlYWNoZm4ubWFwKHRhc2tzLCBmdW5jdGlvbiAoZm4sIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICAgICAgICAgIGZuKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKG51bGwsIGVyciwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHRzID0ge307XG4gICAgICAgICAgICBlYWNoZm4uZWFjaChfa2V5cyh0YXNrcyksIGZ1bmN0aW9uIChrLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIHRhc2tzW2tdKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1trXSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCByZXN1bHRzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGFzeW5jLnBhcmFsbGVsID0gZnVuY3Rpb24gKHRhc2tzLCBjYWxsYmFjaykge1xuICAgICAgICBfcGFyYWxsZWwoeyBtYXA6IGFzeW5jLm1hcCwgZWFjaDogYXN5bmMuZWFjaCB9LCB0YXNrcywgY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICBhc3luYy5wYXJhbGxlbExpbWl0ID0gZnVuY3Rpb24odGFza3MsIGxpbWl0LCBjYWxsYmFjaykge1xuICAgICAgICBfcGFyYWxsZWwoeyBtYXA6IF9tYXBMaW1pdChsaW1pdCksIGVhY2g6IF9lYWNoTGltaXQobGltaXQpIH0sIHRhc2tzLCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIGFzeW5jLnNlcmllcyA9IGZ1bmN0aW9uICh0YXNrcywgY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgaWYgKHRhc2tzLmNvbnN0cnVjdG9yID09PSBBcnJheSkge1xuICAgICAgICAgICAgYXN5bmMubWFwU2VyaWVzKHRhc2tzLCBmdW5jdGlvbiAoZm4sIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICAgICAgICAgIGZuKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncyA9IGFyZ3NbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKG51bGwsIGVyciwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHRzID0ge307XG4gICAgICAgICAgICBhc3luYy5lYWNoU2VyaWVzKF9rZXlzKHRhc2tzKSwgZnVuY3Rpb24gKGssIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdGFza3Nba10oZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1swXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXN1bHRzW2tdID0gYXJncztcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgYXN5bmMuaXRlcmF0b3IgPSBmdW5jdGlvbiAodGFza3MpIHtcbiAgICAgICAgdmFyIG1ha2VDYWxsYmFjayA9IGZ1bmN0aW9uIChpbmRleCkge1xuICAgICAgICAgICAgdmFyIGZuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh0YXNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGFza3NbaW5kZXhdLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmbi5uZXh0KCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZm4ubmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGluZGV4IDwgdGFza3MubGVuZ3RoIC0gMSkgPyBtYWtlQ2FsbGJhY2soaW5kZXggKyAxKTogbnVsbDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gZm47XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtYWtlQ2FsbGJhY2soMCk7XG4gICAgfTtcblxuICAgIGFzeW5jLmFwcGx5ID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShcbiAgICAgICAgICAgICAgICBudWxsLCBhcmdzLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIF9jb25jYXQgPSBmdW5jdGlvbiAoZWFjaGZuLCBhcnIsIGZuLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgciA9IFtdO1xuICAgICAgICBlYWNoZm4oYXJyLCBmdW5jdGlvbiAoeCwgY2IpIHtcbiAgICAgICAgICAgIGZuKHgsIGZ1bmN0aW9uIChlcnIsIHkpIHtcbiAgICAgICAgICAgICAgICByID0gci5jb25jYXQoeSB8fCBbXSk7XG4gICAgICAgICAgICAgICAgY2IoZXJyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnIsIHIpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGFzeW5jLmNvbmNhdCA9IGRvUGFyYWxsZWwoX2NvbmNhdCk7XG4gICAgYXN5bmMuY29uY2F0U2VyaWVzID0gZG9TZXJpZXMoX2NvbmNhdCk7XG5cbiAgICBhc3luYy53aGlsc3QgPSBmdW5jdGlvbiAodGVzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0ZXN0KCkpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhc3luYy53aGlsc3QodGVzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBhc3luYy5kb1doaWxzdCA9IGZ1bmN0aW9uIChpdGVyYXRvciwgdGVzdCwgY2FsbGJhY2spIHtcbiAgICAgICAgaXRlcmF0b3IoZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRlc3QoKSkge1xuICAgICAgICAgICAgICAgIGFzeW5jLmRvV2hpbHN0KGl0ZXJhdG9yLCB0ZXN0LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgYXN5bmMudW50aWwgPSBmdW5jdGlvbiAodGVzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICghdGVzdCgpKSB7XG4gICAgICAgICAgICBpdGVyYXRvcihmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXN5bmMudW50aWwodGVzdCwgaXRlcmF0b3IsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBhc3luYy5kb1VudGlsID0gZnVuY3Rpb24gKGl0ZXJhdG9yLCB0ZXN0LCBjYWxsYmFjaykge1xuICAgICAgICBpdGVyYXRvcihmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRlc3QoKSkge1xuICAgICAgICAgICAgICAgIGFzeW5jLmRvVW50aWwoaXRlcmF0b3IsIHRlc3QsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBhc3luYy5xdWV1ZSA9IGZ1bmN0aW9uICh3b3JrZXIsIGNvbmN1cnJlbmN5KSB7XG4gICAgICAgIGlmIChjb25jdXJyZW5jeSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25jdXJyZW5jeSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZnVuY3Rpb24gX2luc2VydChxLCBkYXRhLCBwb3MsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgaWYoZGF0YS5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHtcbiAgICAgICAgICAgICAgZGF0YSA9IFtkYXRhXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgX2VhY2goZGF0YSwgZnVuY3Rpb24odGFzaykge1xuICAgICAgICAgICAgICB2YXIgaXRlbSA9IHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IHRhc2ssXG4gICAgICAgICAgICAgICAgICBjYWxsYmFjazogdHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nID8gY2FsbGJhY2sgOiBudWxsXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgaWYgKHBvcykge1xuICAgICAgICAgICAgICAgIHEudGFza3MudW5zaGlmdChpdGVtKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBxLnRhc2tzLnB1c2goaXRlbSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAocS5zYXR1cmF0ZWQgJiYgcS50YXNrcy5sZW5ndGggPT09IGNvbmN1cnJlbmN5KSB7XG4gICAgICAgICAgICAgICAgICBxLnNhdHVyYXRlZCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZShxLnByb2Nlc3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHdvcmtlcnMgPSAwO1xuICAgICAgICB2YXIgcSA9IHtcbiAgICAgICAgICAgIHRhc2tzOiBbXSxcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5OiBjb25jdXJyZW5jeSxcbiAgICAgICAgICAgIHNhdHVyYXRlZDogbnVsbCxcbiAgICAgICAgICAgIGVtcHR5OiBudWxsLFxuICAgICAgICAgICAgZHJhaW46IG51bGwsXG4gICAgICAgICAgICBwdXNoOiBmdW5jdGlvbiAoZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgX2luc2VydChxLCBkYXRhLCBmYWxzZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHVuc2hpZnQ6IGZ1bmN0aW9uIChkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICBfaW5zZXJ0KHEsIGRhdGEsIHRydWUsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9jZXNzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHdvcmtlcnMgPCBxLmNvbmN1cnJlbmN5ICYmIHEudGFza3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB0YXNrID0gcS50YXNrcy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocS5lbXB0eSAmJiBxLnRhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcS5lbXB0eSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHdvcmtlcnMgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5leHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JrZXJzIC09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFzay5jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2suY2FsbGJhY2suYXBwbHkodGFzaywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxLmRyYWluICYmIHEudGFza3MubGVuZ3RoICsgd29ya2VycyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHEuZHJhaW4oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHEucHJvY2VzcygpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB2YXIgY2IgPSBvbmx5X29uY2UobmV4dCk7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtlcih0YXNrLmRhdGEsIGNiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGVuZ3RoOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHEudGFza3MubGVuZ3RoO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJ1bm5pbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gd29ya2VycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHE7XG4gICAgfTtcblxuICAgIGFzeW5jLmNhcmdvID0gZnVuY3Rpb24gKHdvcmtlciwgcGF5bG9hZCkge1xuICAgICAgICB2YXIgd29ya2luZyAgICAgPSBmYWxzZSxcbiAgICAgICAgICAgIHRhc2tzICAgICAgID0gW107XG5cbiAgICAgICAgdmFyIGNhcmdvID0ge1xuICAgICAgICAgICAgdGFza3M6IHRhc2tzLFxuICAgICAgICAgICAgcGF5bG9hZDogcGF5bG9hZCxcbiAgICAgICAgICAgIHNhdHVyYXRlZDogbnVsbCxcbiAgICAgICAgICAgIGVtcHR5OiBudWxsLFxuICAgICAgICAgICAgZHJhaW46IG51bGwsXG4gICAgICAgICAgICBwdXNoOiBmdW5jdGlvbiAoZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBpZihkYXRhLmNvbnN0cnVjdG9yICE9PSBBcnJheSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhID0gW2RhdGFdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfZWFjaChkYXRhLCBmdW5jdGlvbih0YXNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhc2tzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YTogdGFzayxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyBjYWxsYmFjayA6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjYXJnby5zYXR1cmF0ZWQgJiYgdGFza3MubGVuZ3RoID09PSBwYXlsb2FkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXJnby5zYXR1cmF0ZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZShjYXJnby5wcm9jZXNzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcm9jZXNzOiBmdW5jdGlvbiBwcm9jZXNzKCkge1xuICAgICAgICAgICAgICAgIGlmICh3b3JraW5nKSByZXR1cm47XG4gICAgICAgICAgICAgICAgaWYgKHRhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBpZihjYXJnby5kcmFpbikgY2FyZ28uZHJhaW4oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciB0cyA9IHR5cGVvZiBwYXlsb2FkID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdGFza3Muc3BsaWNlKDAsIHBheWxvYWQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0YXNrcy5zcGxpY2UoMCk7XG5cbiAgICAgICAgICAgICAgICB2YXIgZHMgPSBfbWFwKHRzLCBmdW5jdGlvbiAodGFzaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFzay5kYXRhO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYoY2FyZ28uZW1wdHkpIGNhcmdvLmVtcHR5KCk7XG4gICAgICAgICAgICAgICAgd29ya2luZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgd29ya2VyKGRzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtpbmcgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICAgICAgICAgICAgX2VhY2godHMsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGF0YS5jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEuY2FsbGJhY2suYXBwbHkobnVsbCwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsZW5ndGg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFza3MubGVuZ3RoO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJ1bm5pbmc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gd29ya2luZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGNhcmdvO1xuICAgIH07XG5cbiAgICB2YXIgX2NvbnNvbGVfZm4gPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzLmNvbmNhdChbZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25zb2xlLmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbnNvbGVbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9lYWNoKGFyZ3MsIGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZVtuYW1lXSh4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfV0pKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGFzeW5jLmxvZyA9IF9jb25zb2xlX2ZuKCdsb2cnKTtcbiAgICBhc3luYy5kaXIgPSBfY29uc29sZV9mbignZGlyJyk7XG4gICAgLyphc3luYy5pbmZvID0gX2NvbnNvbGVfZm4oJ2luZm8nKTtcbiAgICBhc3luYy53YXJuID0gX2NvbnNvbGVfZm4oJ3dhcm4nKTtcbiAgICBhc3luYy5lcnJvciA9IF9jb25zb2xlX2ZuKCdlcnJvcicpOyovXG5cbiAgICBhc3luYy5tZW1vaXplID0gZnVuY3Rpb24gKGZuLCBoYXNoZXIpIHtcbiAgICAgICAgdmFyIG1lbW8gPSB7fTtcbiAgICAgICAgdmFyIHF1ZXVlcyA9IHt9O1xuICAgICAgICBoYXNoZXIgPSBoYXNoZXIgfHwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgIHJldHVybiB4O1xuICAgICAgICB9O1xuICAgICAgICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgdmFyIGtleSA9IGhhc2hlci5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgIGlmIChrZXkgaW4gbWVtbykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KG51bGwsIG1lbW9ba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChrZXkgaW4gcXVldWVzKSB7XG4gICAgICAgICAgICAgICAgcXVldWVzW2tleV0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBxdWV1ZXNba2V5XSA9IFtjYWxsYmFja107XG4gICAgICAgICAgICAgICAgZm4uYXBwbHkobnVsbCwgYXJncy5jb25jYXQoW2Z1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVtb1trZXldID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgICAgICAgICB2YXIgcSA9IHF1ZXVlc1trZXldO1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcXVldWVzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gcS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICBxW2ldLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBtZW1vaXplZC5tZW1vID0gbWVtbztcbiAgICAgICAgbWVtb2l6ZWQudW5tZW1vaXplZCA9IGZuO1xuICAgICAgICByZXR1cm4gbWVtb2l6ZWQ7XG4gICAgfTtcblxuICAgIGFzeW5jLnVubWVtb2l6ZSA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIChmbi51bm1lbW9pemVkIHx8IGZuKS5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgYXN5bmMudGltZXMgPSBmdW5jdGlvbiAoY291bnQsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgY291bnRlciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGNvdW50ZXIucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXN5bmMubWFwKGNvdW50ZXIsIGl0ZXJhdG9yLCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIGFzeW5jLnRpbWVzU2VyaWVzID0gZnVuY3Rpb24gKGNvdW50LCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGNvdW50ZXIgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBjb3VudGVyLnB1c2goaSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFzeW5jLm1hcFNlcmllcyhjb3VudGVyLCBpdGVyYXRvciwgY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICBhc3luYy5jb21wb3NlID0gZnVuY3Rpb24gKC8qIGZ1bmN0aW9ucy4uLiAqLykge1xuICAgICAgICB2YXIgZm5zID0gQXJyYXkucHJvdG90eXBlLnJldmVyc2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gYXJncy5wb3AoKTtcbiAgICAgICAgICAgIGFzeW5jLnJlZHVjZShmbnMsIGFyZ3MsIGZ1bmN0aW9uIChuZXdhcmdzLCBmbiwgY2IpIHtcbiAgICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBuZXdhcmdzLmNvbmNhdChbZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZXJyID0gYXJndW1lbnRzWzBdO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgICAgICBjYihlcnIsIG5leHRhcmdzKTtcbiAgICAgICAgICAgICAgICB9XSkpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZnVuY3Rpb24gKGVyciwgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KHRoYXQsIFtlcnJdLmNvbmNhdChyZXN1bHRzKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIF9hcHBseUVhY2ggPSBmdW5jdGlvbiAoZWFjaGZuLCBmbnMgLyphcmdzLi4uKi8pIHtcbiAgICAgICAgdmFyIGdvID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gYXJncy5wb3AoKTtcbiAgICAgICAgICAgIHJldHVybiBlYWNoZm4oZm5zLCBmdW5jdGlvbiAoZm4sIGNiKSB7XG4gICAgICAgICAgICAgICAgZm4uYXBwbHkodGhhdCwgYXJncy5jb25jYXQoW2NiXSkpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgICAgICAgICByZXR1cm4gZ28uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZ287XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGFzeW5jLmFwcGx5RWFjaCA9IGRvUGFyYWxsZWwoX2FwcGx5RWFjaCk7XG4gICAgYXN5bmMuYXBwbHlFYWNoU2VyaWVzID0gZG9TZXJpZXMoX2FwcGx5RWFjaCk7XG5cbiAgICBhc3luYy5mb3JldmVyID0gZnVuY3Rpb24gKGZuLCBjYWxsYmFjaykge1xuICAgICAgICBmdW5jdGlvbiBuZXh0KGVycikge1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm4obmV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgbmV4dCgpO1xuICAgIH07XG5cbiAgICAvLyBBTUQgLyBSZXF1aXJlSlNcbiAgICBpZiAodHlwZW9mIGRlZmluZSAhPT0gJ3VuZGVmaW5lZCcgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoW10sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBhc3luYztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIE5vZGUuanNcbiAgICBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGFzeW5jO1xuICAgIH1cbiAgICAvLyBpbmNsdWRlZCBkaXJlY3RseSB2aWEgPHNjcmlwdD4gdGFnXG4gICAgZWxzZSB7XG4gICAgICAgIHJvb3QuYXN5bmMgPSBhc3luYztcbiAgICB9XG5cbn0oKSk7XG4iLCJmdW5jdGlvbiByZXBsYWNlKGEsIGIpXHJcbntcclxuIGlmICghYilcclxuIHtcclxuICByZXR1cm4gYTtcclxuIH1cclxuIHZhciBrZXk7XHJcbiBmb3IgKGtleSBpbiBiKVxyXG4ge1xyXG4gIGlmKGIuaGFzT3duUHJvcGVydHkoa2V5KSlcclxuICB7IFxyXG4gICBhW2tleV0gPSBiW2tleV07XHJcbiAgfVxyXG4gfVxyXG4gICBcclxuIHJldHVybiBhO1xyXG59IGV4cG9ydHMucmVwbGFjZT1yZXBsYWNlO1xyXG5cclxuZnVuY3Rpb24gYWRkKGEsIGIpXHJcbntcclxuIGlmICghYilcclxuIHtcclxuICByZXR1cm4gYTtcclxuIH1cclxuIHZhciBrZXk7XHJcbiBmb3IgKGtleSBpbiBiKVxyXG4ge1xyXG4gIGlmKGIuaGFzT3duUHJvcGVydHkoa2V5KSlcclxuICB7IFxyXG4gICBpZih0eXBlb2YgYVtrZXldID09PSAndW5kZWZpbmVkJyB8fCAgYVtrZXldPT09bnVsbClcclxuICAge1xyXG4gICAgYVtrZXldID0gYltrZXldO1xyXG4gICB9XHJcbiAgfVxyXG4gfVxyXG4gcmV0dXJuIGE7XHJcbn0gZXhwb3J0cy5hZGQ9YWRkO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGV4dGVuZChhLCBiLCBjb250ZXh0LCBuZXdvYmpzLCBhcGFyZW50LCBhbmFtZSwgaGF2ZWFwYXJlbnQpIC8vIGNvbnRleHQgaXMgYW50aSBjaXJjdWxhciByZWZlcmVuY2VzIG1lY2hhbmlzbVxyXG57XHJcbiBpZiAoYT09Yil7IHJldHVybiBhO31cclxuIGlmICghYikgIHsgcmV0dXJuIGE7fVxyXG4gXHJcbiB2YXIga2V5LCBjbGVhbl9jb250ZXh0PWZhbHNlLCByZXR1cm5fc3VibGV2ZWw9ZmFsc2UsYl9wb3M7XHJcbiBpZighaGF2ZWFwYXJlbnQpeyBhcGFyZW50PXsnYSc6YX07IGFuYW1lPSdhJzsgfVxyXG4gaWYoIWNvbnRleHQpe2NsZWFuX2NvbnRleHQ9dHJ1ZTtjb250ZXh0PVtdO25ld29ianM9W107fVxyXG4gYl9wb3M9Y29udGV4dC5pbmRleE9mKGIpO1xyXG4gaWYoIGJfcG9zPT0tMSApIHtjb250ZXh0LnB1c2goYik7bmV3b2Jqcy5wdXNoKFthcGFyZW50LCBhbmFtZV0pO30gZWxzZSB7IHJldHVybiBuZXdvYmpzW2JfcG9zXVswXVsgbmV3b2Jqc1tiX3Bvc11bMV0gXTsgfVxyXG5cclxuIGZvciAoa2V5IGluIGIpXHJcbiB7XHJcbiAgIGlmKGIuaGFzT3duUHJvcGVydHkoa2V5KSlcclxuICAgeyBcclxuICAgaWYodHlwZW9mIGFba2V5XSA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgIHsgICBcclxuICAgIGlmKHR5cGVvZiBiW2tleV0gPT09ICdvYmplY3QnKVxyXG4gICAge1xyXG4gICAgIGlmKCBiW2tleV0gaW5zdGFuY2VvZiBBcnJheSApIC8vIGh0dHA6Ly9qYXZhc2NyaXB0LmNyb2NrZm9yZC5jb20vcmVtZWRpYWwuaHRtbFxyXG4gICAgICB7YVtrZXldID0gZXh0ZW5kKFtdLCBiW2tleV0sY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpO31cclxuICAgICBlbHNlIGlmKGJba2V5XT09PW51bGwpXHJcbiAgICAgIHthW2tleV0gPSBudWxsO31cclxuICAgICBlbHNlIGlmKCBiW2tleV0gaW5zdGFuY2VvZiBEYXRlIClcclxuICAgICAgeyBhW2tleV09IG5ldyBiW2tleV0uY29uc3RydWN0b3IoKTthW2tleV0uc2V0VGltZShiW2tleV0uZ2V0VGltZSgpKTsgIH1cclxuICAgICBlbHNlXHJcbiAgICAgIHsgYVtrZXldID0gZXh0ZW5kKHt9LCBiW2tleV0sY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpOyAvKmFba2V5XS5jb25zdHJ1Y3RvciA9IGJba2V5XS5jb25zdHJ1Y3RvcjsgIGFba2V5XS5wcm90b3R5cGUgPSBiW2tleV0ucHJvdG90eXBlOyovIH1cclxuICAgIH1cclxuICAgIGVsc2VcclxuICAgIHsgIGFba2V5XSA9IGJba2V5XTsgfVxyXG4gICB9XHJcbiAgIGVsc2UgaWYodHlwZW9mIGFba2V5XSA9PT0gJ29iamVjdCcgJiYgYVtrZXldICE9PSBudWxsKVxyXG4gICB7ICBhW2tleV0gPSBleHRlbmQoYVtrZXldLCBiW2tleV0sY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpOyAvKmFba2V5XS5jb25zdHJ1Y3RvciA9IGJba2V5XS5jb25zdHJ1Y3RvcjsgIGFba2V5XS5wcm90b3R5cGUgPSBiW2tleV0ucHJvdG90eXBlOyovIH1cclxuICAgZWxzZSAgXHJcbiAgIHsgIGFba2V5XSA9IGJba2V5XTsgfVxyXG4gIH1cclxuIH1cclxuIGlmKGNsZWFuX2NvbnRleHQpIHtjb250ZXh0PW51bGw7bmV3b2Jqcz1udWxsO31cclxuIGlmKCFoYXZlYXBhcmVudClcclxuIHtcclxuICBhcGFyZW50PW51bGw7XHJcbiAgcmV0dXJuIGE7XHJcbiB9XHJcbiBpZih0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgIShhIGluc3RhbmNlb2YgQXJyYXkpIClcclxuIHtcclxuICAvKmEuY29uc3RydWN0b3IgPSBiLmNvbnN0cnVjdG9yO1xyXG4gIGEucHJvdG90eXBlICAgPSBiLnByb3RvdHlwZSovO1xyXG4gfSBcclxuIHJldHVybiBhO1xyXG59IGV4cG9ydHMuZXh0ZW5kPWV4dGVuZDtcclxuXHJcbmZ1bmN0aW9uIGV4dGVuZHVwdG9sZXZlbChhLCBiLCBsZXZlbHMsIGNvbnRleHQsIG5ld29ianMsIGFwYXJlbnQsIGFuYW1lLCBoYXZlYXBhcmVudClcclxue1xyXG4gaWYgKGE9PWIpeyByZXR1cm4gYTt9XHJcbiBpZiAoIWIpeyByZXR1cm4gYTt9XHJcblxyXG4gdmFyIGtleSwgY2xlYW5fY29udGV4dD1mYWxzZSwgcmV0dXJuX3N1YmxldmVsPWZhbHNlO1xyXG4gaWYoIWhhdmVhcGFyZW50KXsgYXBhcmVudD17J2EnOmF9OyBhbmFtZT0nYSc7IH1cclxuIGlmKCFjb250ZXh0KXtjbGVhbl9jb250ZXh0PXRydWU7Y29udGV4dD1bXTtuZXdvYmpzPVtdO31cclxuIGJfcG9zPWNvbnRleHQuaW5kZXhPZihiKTtcclxuIGlmKCBiX3Bvcz09LTEgKSB7Y29udGV4dC5wdXNoKGIpO25ld29ianMucHVzaChbYXBhcmVudCwgYW5hbWVdKTt9IGVsc2UgeyByZXR1cm4gbmV3b2Jqc1tiX3Bvc11bMF1bIG5ld29ianNbYl9wb3NdWzFdIF07IH1cclxuIFxyXG4gZm9yIChrZXkgaW4gYilcclxuIHtcclxuICBpZihiLmhhc093blByb3BlcnR5KGtleSkpXHJcbiAgeyBcclxuICAgaWYodHlwZW9mIGFba2V5XSA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgIHtcclxuICAgIGlmKHR5cGVvZiBiW2tleV0gPT09ICdvYmplY3QnICYmIGxldmVscz4wKVxyXG4gICAge1xyXG4gICAgIGlmKCBiW2tleV0gaW5zdGFuY2VvZiBBcnJheSApIC8vIGh0dHA6Ly9qYXZhc2NyaXB0LmNyb2NrZm9yZC5jb20vcmVtZWRpYWwuaHRtbFxyXG4gICAgIHsgYVtrZXldID0gZXh0ZW5kdXB0b2xldmVsKFtdLCBiW2tleV0sbGV2ZWxzLTEsY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpOyB9XHJcbiAgICAgZWxzZSBpZihiW2tleV09PT1udWxsKVxyXG4gICAgIHsgYVtrZXldID0gbnVsbDsgfVxyXG4gICAgIGVsc2UgaWYoIGJba2V5XSBpbnN0YW5jZW9mIERhdGUgKVxyXG4gICAgIHsgYVtrZXldPSBuZXcgYltrZXldLmNvbnN0cnVjdG9yKCk7YVtrZXldLnNldFRpbWUoYltrZXldLmdldFRpbWUoKSk7ICB9XHJcbiAgICAgZWxzZVxyXG4gICAgIHsgYVtrZXldID0gZXh0ZW5kdXB0b2xldmVsKHt9LCBiW2tleV0sbGV2ZWxzLTEsY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpOyB9XHJcbiAgICB9XHJcbiAgICBlbHNlXHJcbiAgICB7ICBhW2tleV0gPSBiW2tleV07IH1cclxuICAgfVxyXG4gICBlbHNlIGlmKHR5cGVvZiBhW2tleV0gPT09ICdvYmplY3QnICYmIGFba2V5XSAhPT0gbnVsbCAmJiBsZXZlbHM+MClcclxuICAgeyAgYVtrZXldID0gZXh0ZW5kdXB0b2xldmVsKGFba2V5XSwgYltrZXldLGxldmVscy0xLGNvbnRleHQsbmV3b2JqcyxhLGtleSx0cnVlKTsgfVxyXG4gICBlbHNlICBcclxuICAgeyAgYVtrZXldID0gYltrZXldOyB9XHJcbiAgfVxyXG4gfVxyXG4gaWYoY2xlYW5fY29udGV4dCkge2NvbnRleHQ9bnVsbDtuZXdvYmpzPW51bGw7fVxyXG5cclxuIGlmKCFoYXZlYXBhcmVudClcclxuIHtcclxuICBhcGFyZW50PW51bGw7XHJcbiAgcmV0dXJuIGE7XHJcbiB9XHJcbiBpZih0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgIShhIGluc3RhbmNlb2YgQXJyYXkpIClcclxuIHtcclxuICAvKmEuY29uc3RydWN0b3IgPSBiLmNvbnN0cnVjdG9yO1xyXG4gIGEucHJvdG90eXBlICAgPSBiLnByb3RvdHlwZTsqL1xyXG4gfSBcclxuIHJldHVybiBhO1xyXG59IGV4cG9ydHMuZXh0ZW5kdXB0b2xldmVsPWV4dGVuZHVwdG9sZXZlbDtcclxuXHJcbmZ1bmN0aW9uIGNsb25lKG9iailcclxue1xyXG4gaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKVxyXG4ge1xyXG4gIGlmIChvYmogPT09bnVsbCApIHsgcmV0dXJuIG51bGw7IH1cclxuICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkgKVxyXG4gIHsgcmV0dXJuIGV4dGVuZChbXSwgb2JqKTsgfVxyXG4gIGVsc2UgaWYoIG9iaiBpbnN0YW5jZW9mIERhdGUgKVxyXG4gIHtcclxuICAgdmFyIHQ9IG5ldyBvYmouY29uc3RydWN0b3IoKTtcclxuICAgdC5zZXRUaW1lKG9iai5nZXRUaW1lKCkpO1xyXG4gICByZXR1cm4gdDtcclxuICB9XHJcbiAgZWxzZVxyXG4gIHsgcmV0dXJuIGV4dGVuZCh7fSwgb2JqKTsgfVxyXG4gfVxyXG4gcmV0dXJuIG9iajtcclxufSBleHBvcnRzLmNsb25lPWNsb25lO1xyXG5cclxuZnVuY3Rpb24gY2xvbmVleHRlbmQob2JqLGV4dGVkZGF0YSlcclxue1xyXG4gaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnKVxyXG4ge1xyXG4gIGlmIChvYmogPT09bnVsbCApIHsgcmV0dXJuIG51bGw7IH1cclxuICByZXR1cm4gZXh0ZW5kKGNsb25lKG9iaiksZXh0ZWRkYXRhKTtcclxuIH1cclxuIHJldHVybiBvYmo7XHJcbn0gZXhwb3J0cy5jbG9uZWV4dGVuZD1jbG9uZWV4dGVuZDtcclxuXHJcblxyXG5mdW5jdGlvbiBjbG9uZXVwdG9sZXZlbChvYmosbGV2ZWwpIC8vIGNsb25lIG9ubHkgbnVtbGV2ZWxzIGxldmVscyBvdGhlciBsZXZlbHMgbGVhdmUgcmVmZXJlbmNlc1xyXG57XHJcbiBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpXHJcbiB7XHJcbiAgaWYgKG9iaiA9PT1udWxsICkgeyByZXR1cm4gbnVsbDsgfVxyXG4gIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSApIHsgcmV0dXJuIGV4dGVuZHVwdG9sZXZlbChbXSwgb2JqLGxldmVsKTsgfVxyXG4gIHJldHVybiBleHRlbmR1cHRvbGV2ZWwoe30sIG9iaixsZXZlbCk7XHJcbiB9XHJcbiByZXR1cm4gb2JqO1xyXG59IGV4cG9ydHMuY2xvbmV1cHRvbGV2ZWw9Y2xvbmV1cHRvbGV2ZWw7XHJcblxyXG5mdW5jdGlvbiBmb3JlYWNoKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpXHJcbntcclxuIGlmIChvYmplY3QpXHJcbiB7XHJcbiAgaWYgKHR5cGVvZiBvYmplY3QgPT09IFwib2JqZWN0XCIgJiYgb2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpXHJcbiAgIHJldHVybiBvYmplY3QuZm9yRWFjaChvYmplY3QsIGJsb2NrLCBjb250ZXh0KVxyXG4gIGVsc2UgLy9pZiAodHlwZW9mIG9iamVjdCA9PT0gXCJvYmplY3RcIikgLy8gb3IgKG9iamVjdCBpbnN0YW5jZW9mIEZ1bmN0aW9uKS4uLlxyXG4gIHtcclxuICAgaWYob2JqZWN0KVxyXG4gICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KVxyXG4gICB7XHJcbiAgICBpZihvYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KSlcclxuICAgIHtcclxuICAgICBpZihibG9jay5jYWxsKGNvbnRleHQsIG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk9PT1mYWxzZSlicmVhaztcclxuICAgIH1cclxuICAgfVxyXG4gIH0gIFxyXG4gfVxyXG59IGV4cG9ydHMuZm9yZWFjaD1mb3JlYWNoO1xyXG5cclxuLypcclxuIGhhc2J1Z3MgYW5kIHVzZWxlc3MsIHlldCBpbnRlcmVzdGluZyBtYXliZSBkZXZlbG9wZWQgbGF0ZXIgZm9yIGRvdCBwYXRoZWQgb2JqZWN0IHRyYW5zZm9ybWF0aW9uOlxyXG4gXHJcbiB7XHJcbiAgJ2Zvby5iYXInOidibHVlYmFyJyxcclxuICAnZm9vLmNvbG9yJzonYmx1ZSdcclxuIH1cclxuIFxyXG4gdHJhbnNmb3JlbWVkIHRvXHJcbiBcclxuIHtcclxuICBmb286XHJcbiAge1xyXG4gICBiYXI6J2JsdWViYXInLFxyXG4gICBjb2xvcjonYmx1ZSdcclxuICB9XHJcbiB9XHJcbiBcclxuIGxpa2U6XHJcbiBcclxuIHZhciBjb25maWc9e307XHJcbiBjbG9uZWV4dGVuZC5kb3RwYXRoKGNvbmZpZyx7XHJcbiAgJ2Zvby5iYXInOidibHVlYmFyJyxcclxuICAnZm9vLmNvbG9yJzonYmx1ZSdcclxuIH0pXHJcbiBcclxuIC8vXHJcbiBmdW5jdGlvbiBkb3RwYXRoKGRhdGEsZG90a2V5cyxwcmVzZXJ2ZSlcclxuIHtcclxuICAgICAgaWYoIXByZXNlcnZlKXByZXNlcnZlPWZhbHNlO1xyXG4gICAgICB2YXIgY3JlYXRlPSFwcmVzZXJ2ZTtcclxuICAgICAgaWYoY3JlYXRlKSBpZighZGF0YSkgZGF0YT17fTtcclxuICAgICAgdmFyIGtleXM9IGRvdGtleXMuc3BsaXQoXCIuXCIpLHZhbHVlPWRhdGE7XHJcbiAgICAgIGZvciAodmFyIGk9MDtpPGtleXMubGVuZ3RoO2krKylcclxuICAgICAge1xyXG4gICAgICAgICAgaWYoIXZhbHVlW2tleXNbaV1dKSAvL3Nob3VsZCB5b3UgY3JlYXRlIG9uZT9cclxuICAgICAgICAgIHtcclxuICAgICAgICAgICAgICBpZihjcmVhdGUpXHJcbiAgICAgICAgICAgICAgICAgIHZhbHVlW2tleXNbaV1dPXt9O1xyXG4gICAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHZhbHVlID0gdmFsdWVba2V5c1tpXV07XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gfVxyXG4gKi8iLCJ2YXIgQnVmZmVyPXJlcXVpcmUoXCJfX2Jyb3dzZXJpZnlfQnVmZmVyXCIpLkJ1ZmZlcjsvKiFcbiAqIE5vZGUuSlMgbW9kdWxlIFwiRGVlcCBFeHRlbmRcIlxuICogQGRlc2NyaXB0aW9uIFJlY3Vyc2l2ZSBvYmplY3QgZXh0ZW5kaW5nLlxuICogQGF1dGhvciBWaWFjaGVzbGF2IExvdHNtYW5vdiAodW5jbGVjaHUpIDxsb3RzbWFub3Y4OUBnbWFpbC5jb20+XG4gKiBAbGljZW5zZSBNSVRcbiAqXG4gKiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMgVmlhY2hlc2xhdiBMb3RzbWFub3ZcbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mXG4gKiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluXG4gKiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvXG4gKiB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZlxuICogdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLFxuICogc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gKiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTXG4gKiBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1JcbiAqIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUlxuICogSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU5cbiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG4gKi9cblxuLyoqXG4gKiBFeHRlbmluZyBvYmplY3QgdGhhdCBlbnRlcmVkIGluIGZpcnN0IGFyZ3VtZW50LlxuICogUmV0dXJucyBleHRlbmRlZCBvYmplY3Qgb3IgZmFsc2UgaWYgaGF2ZSBubyB0YXJnZXQgb2JqZWN0IG9yIGluY29ycmVjdCB0eXBlLlxuICogSWYgeW91IHdpc2ggdG8gY2xvbmUgb2JqZWN0LCBzaW1wbHkgdXNlIHRoYXQ6XG4gKiAgZGVlcEV4dGVuZCh7fSwgeW91ck9ial8xLCBbeW91ck9ial9OXSkgLSBmaXJzdCBhcmcgaXMgbmV3IGVtcHR5IG9iamVjdFxuICovXG52YXIgZGVlcEV4dGVuZCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKC8qb2JqXzEsIFtvYmpfMl0sIFtvYmpfTl0qLykge1xuXHRpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDEgfHwgdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ29iamVjdCcpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHJldHVybiBhcmd1bWVudHNbMF07XG5cblx0dmFyIHRhcmdldCA9IGFyZ3VtZW50c1swXTtcblxuXHQvLyBjb252ZXJ0IGFyZ3VtZW50cyB0byBhcnJheSBhbmQgY3V0IG9mZiB0YXJnZXQgb2JqZWN0XG5cdHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblxuXHR2YXIga2V5LCB2YWwsIHNyYywgY2xvbmUsIHRtcEJ1ZjtcblxuXHRhcmdzLmZvckVhY2goZnVuY3Rpb24gKG9iaikge1xuXHRcdGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JykgcmV0dXJuO1xuXG5cdFx0Zm9yIChrZXkgaW4gb2JqKSB7XG5cdFx0XHRpZiAoICEgKGtleSBpbiBvYmopKSBjb250aW51ZTtcblxuXHRcdFx0c3JjID0gdGFyZ2V0W2tleV07XG5cdFx0XHR2YWwgPSBvYmpba2V5XTtcblxuXHRcdFx0aWYgKHZhbCA9PT0gdGFyZ2V0KSBjb250aW51ZTtcblxuXHRcdFx0aWYgKHR5cGVvZiB2YWwgIT09ICdvYmplY3QnIHx8IHZhbCA9PT0gbnVsbCkge1xuXHRcdFx0XHR0YXJnZXRba2V5XSA9IHZhbDtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9IGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuXHRcdFx0XHR0bXBCdWYgPSBuZXcgQnVmZmVyKHZhbC5sZW5ndGgpO1xuXHRcdFx0XHR2YWwuY29weSh0bXBCdWYpO1xuXHRcdFx0XHR0YXJnZXRba2V5XSA9IHRtcEJ1Zjtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9IGVsc2UgaWYgKHZhbCBpbnN0YW5jZW9mIERhdGUpIHtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBuZXcgRGF0ZSh2YWwuZ2V0VGltZSgpKTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmICh0eXBlb2Ygc3JjICE9PSAnb2JqZWN0JyB8fCBzcmMgPT09IG51bGwpIHtcblx0XHRcdFx0Y2xvbmUgPSAoQXJyYXkuaXNBcnJheSh2YWwpKSA/IFtdIDoge307XG5cdFx0XHRcdHRhcmdldFtrZXldID0gZGVlcEV4dGVuZChjbG9uZSwgdmFsKTtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChBcnJheS5pc0FycmF5KHZhbCkpIHtcblx0XHRcdFx0Y2xvbmUgPSAoQXJyYXkuaXNBcnJheShzcmMpKSA/IHNyYyA6IFtdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmUgPSAoIUFycmF5LmlzQXJyYXkoc3JjKSkgPyBzcmMgOiB7fTtcblx0XHRcdH1cblxuXHRcdFx0dGFyZ2V0W2tleV0gPSBkZWVwRXh0ZW5kKGNsb25lLCB2YWwpO1xuXHRcdH1cblx0fSk7XG5cblx0cmV0dXJuIHRhcmdldDtcbn1cbiIsIi8qIVxuICogRXZlbnRFbWl0dGVyMlxuICogaHR0cHM6Ly9naXRodWIuY29tL2hpajFueC9FdmVudEVtaXR0ZXIyXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEzIGhpajFueFxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG47IWZ1bmN0aW9uKHVuZGVmaW5lZCkge1xuXG4gIHZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSA/IEFycmF5LmlzQXJyYXkgOiBmdW5jdGlvbiBfaXNBcnJheShvYmopIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgPT09IFwiW29iamVjdCBBcnJheV1cIjtcbiAgfTtcbiAgdmFyIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuICBmdW5jdGlvbiBpbml0KCkge1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGlmICh0aGlzLl9jb25mKSB7XG4gICAgICBjb25maWd1cmUuY2FsbCh0aGlzLCB0aGlzLl9jb25mKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjb25maWd1cmUoY29uZikge1xuICAgIGlmIChjb25mKSB7XG5cbiAgICAgIHRoaXMuX2NvbmYgPSBjb25mO1xuXG4gICAgICBjb25mLmRlbGltaXRlciAmJiAodGhpcy5kZWxpbWl0ZXIgPSBjb25mLmRlbGltaXRlcik7XG4gICAgICBjb25mLm1heExpc3RlbmVycyAmJiAodGhpcy5fZXZlbnRzLm1heExpc3RlbmVycyA9IGNvbmYubWF4TGlzdGVuZXJzKTtcbiAgICAgIGNvbmYud2lsZGNhcmQgJiYgKHRoaXMud2lsZGNhcmQgPSBjb25mLndpbGRjYXJkKTtcbiAgICAgIGNvbmYubmV3TGlzdGVuZXIgJiYgKHRoaXMubmV3TGlzdGVuZXIgPSBjb25mLm5ld0xpc3RlbmVyKTtcblxuICAgICAgaWYgKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lclRyZWUgPSB7fTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBFdmVudEVtaXR0ZXIoY29uZikge1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHRoaXMubmV3TGlzdGVuZXIgPSBmYWxzZTtcbiAgICBjb25maWd1cmUuY2FsbCh0aGlzLCBjb25mKTtcbiAgfVxuXG4gIC8vXG4gIC8vIEF0dGVudGlvbiwgZnVuY3Rpb24gcmV0dXJuIHR5cGUgbm93IGlzIGFycmF5LCBhbHdheXMgIVxuICAvLyBJdCBoYXMgemVybyBlbGVtZW50cyBpZiBubyBhbnkgbWF0Y2hlcyBmb3VuZCBhbmQgb25lIG9yIG1vcmVcbiAgLy8gZWxlbWVudHMgKGxlYWZzKSBpZiB0aGVyZSBhcmUgbWF0Y2hlc1xuICAvL1xuICBmdW5jdGlvbiBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHRyZWUsIGkpIHtcbiAgICBpZiAoIXRyZWUpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgdmFyIGxpc3RlbmVycz1bXSwgbGVhZiwgbGVuLCBicmFuY2gsIHhUcmVlLCB4eFRyZWUsIGlzb2xhdGVkQnJhbmNoLCBlbmRSZWFjaGVkLFxuICAgICAgICB0eXBlTGVuZ3RoID0gdHlwZS5sZW5ndGgsIGN1cnJlbnRUeXBlID0gdHlwZVtpXSwgbmV4dFR5cGUgPSB0eXBlW2krMV07XG4gICAgaWYgKGkgPT09IHR5cGVMZW5ndGggJiYgdHJlZS5fbGlzdGVuZXJzKSB7XG4gICAgICAvL1xuICAgICAgLy8gSWYgYXQgdGhlIGVuZCBvZiB0aGUgZXZlbnQocykgbGlzdCBhbmQgdGhlIHRyZWUgaGFzIGxpc3RlbmVyc1xuICAgICAgLy8gaW52b2tlIHRob3NlIGxpc3RlbmVycy5cbiAgICAgIC8vXG4gICAgICBpZiAodHlwZW9mIHRyZWUuX2xpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBoYW5kbGVycyAmJiBoYW5kbGVycy5wdXNoKHRyZWUuX2xpc3RlbmVycyk7XG4gICAgICAgIHJldHVybiBbdHJlZV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGxlYWYgPSAwLCBsZW4gPSB0cmVlLl9saXN0ZW5lcnMubGVuZ3RoOyBsZWFmIDwgbGVuOyBsZWFmKyspIHtcbiAgICAgICAgICBoYW5kbGVycyAmJiBoYW5kbGVycy5wdXNoKHRyZWUuX2xpc3RlbmVyc1tsZWFmXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt0cmVlXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoKGN1cnJlbnRUeXBlID09PSAnKicgfHwgY3VycmVudFR5cGUgPT09ICcqKicpIHx8IHRyZWVbY3VycmVudFR5cGVdKSB7XG4gICAgICAvL1xuICAgICAgLy8gSWYgdGhlIGV2ZW50IGVtaXR0ZWQgaXMgJyonIGF0IHRoaXMgcGFydFxuICAgICAgLy8gb3IgdGhlcmUgaXMgYSBjb25jcmV0ZSBtYXRjaCBhdCB0aGlzIHBhdGNoXG4gICAgICAvL1xuICAgICAgaWYgKGN1cnJlbnRUeXBlID09PSAnKicpIHtcbiAgICAgICAgZm9yIChicmFuY2ggaW4gdHJlZSkge1xuICAgICAgICAgIGlmIChicmFuY2ggIT09ICdfbGlzdGVuZXJzJyAmJiB0cmVlLmhhc093blByb3BlcnR5KGJyYW5jaCkpIHtcbiAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlW2JyYW5jaF0sIGkrMSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbGlzdGVuZXJzO1xuICAgICAgfSBlbHNlIGlmKGN1cnJlbnRUeXBlID09PSAnKionKSB7XG4gICAgICAgIGVuZFJlYWNoZWQgPSAoaSsxID09PSB0eXBlTGVuZ3RoIHx8IChpKzIgPT09IHR5cGVMZW5ndGggJiYgbmV4dFR5cGUgPT09ICcqJykpO1xuICAgICAgICBpZihlbmRSZWFjaGVkICYmIHRyZWUuX2xpc3RlbmVycykge1xuICAgICAgICAgIC8vIFRoZSBuZXh0IGVsZW1lbnQgaGFzIGEgX2xpc3RlbmVycywgYWRkIGl0IHRvIHRoZSBoYW5kbGVycy5cbiAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuY29uY2F0KHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgdHJlZSwgdHlwZUxlbmd0aCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChicmFuY2ggaW4gdHJlZSkge1xuICAgICAgICAgIGlmIChicmFuY2ggIT09ICdfbGlzdGVuZXJzJyAmJiB0cmVlLmhhc093blByb3BlcnR5KGJyYW5jaCkpIHtcbiAgICAgICAgICAgIGlmKGJyYW5jaCA9PT0gJyonIHx8IGJyYW5jaCA9PT0gJyoqJykge1xuICAgICAgICAgICAgICBpZih0cmVlW2JyYW5jaF0uX2xpc3RlbmVycyAmJiAhZW5kUmVhY2hlZCkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlW2JyYW5jaF0sIHR5cGVMZW5ndGgpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuY29uY2F0KHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgdHJlZVticmFuY2hdLCBpKSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYoYnJhbmNoID09PSBuZXh0VHlwZSkge1xuICAgICAgICAgICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuY29uY2F0KHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgdHJlZVticmFuY2hdLCBpKzIpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIE5vIG1hdGNoIG9uIHRoaXMgb25lLCBzaGlmdCBpbnRvIHRoZSB0cmVlIGJ1dCBub3QgaW4gdGhlIHR5cGUgYXJyYXkuXG4gICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlW2JyYW5jaF0sIGkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxpc3RlbmVycztcbiAgICAgIH1cblxuICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmNvbmNhdChzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHRyZWVbY3VycmVudFR5cGVdLCBpKzEpKTtcbiAgICB9XG5cbiAgICB4VHJlZSA9IHRyZWVbJyonXTtcbiAgICBpZiAoeFRyZWUpIHtcbiAgICAgIC8vXG4gICAgICAvLyBJZiB0aGUgbGlzdGVuZXIgdHJlZSB3aWxsIGFsbG93IGFueSBtYXRjaCBmb3IgdGhpcyBwYXJ0LFxuICAgICAgLy8gdGhlbiByZWN1cnNpdmVseSBleHBsb3JlIGFsbCBicmFuY2hlcyBvZiB0aGUgdHJlZVxuICAgICAgLy9cbiAgICAgIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgeFRyZWUsIGkrMSk7XG4gICAgfVxuXG4gICAgeHhUcmVlID0gdHJlZVsnKionXTtcbiAgICBpZih4eFRyZWUpIHtcbiAgICAgIGlmKGkgPCB0eXBlTGVuZ3RoKSB7XG4gICAgICAgIGlmKHh4VHJlZS5fbGlzdGVuZXJzKSB7XG4gICAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIGxpc3RlbmVyIG9uIGEgJyoqJywgaXQgd2lsbCBjYXRjaCBhbGwsIHNvIGFkZCBpdHMgaGFuZGxlci5cbiAgICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHh4VHJlZSwgdHlwZUxlbmd0aCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCdWlsZCBhcnJheXMgb2YgbWF0Y2hpbmcgbmV4dCBicmFuY2hlcyBhbmQgb3RoZXJzLlxuICAgICAgICBmb3IoYnJhbmNoIGluIHh4VHJlZSkge1xuICAgICAgICAgIGlmKGJyYW5jaCAhPT0gJ19saXN0ZW5lcnMnICYmIHh4VHJlZS5oYXNPd25Qcm9wZXJ0eShicmFuY2gpKSB7XG4gICAgICAgICAgICBpZihicmFuY2ggPT09IG5leHRUeXBlKSB7XG4gICAgICAgICAgICAgIC8vIFdlIGtub3cgdGhlIG5leHQgZWxlbWVudCB3aWxsIG1hdGNoLCBzbyBqdW1wIHR3aWNlLlxuICAgICAgICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHh4VHJlZVticmFuY2hdLCBpKzIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmKGJyYW5jaCA9PT0gY3VycmVudFR5cGUpIHtcbiAgICAgICAgICAgICAgLy8gQ3VycmVudCBub2RlIG1hdGNoZXMsIG1vdmUgaW50byB0aGUgdHJlZS5cbiAgICAgICAgICAgICAgc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB4eFRyZWVbYnJhbmNoXSwgaSsxKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlzb2xhdGVkQnJhbmNoID0ge307XG4gICAgICAgICAgICAgIGlzb2xhdGVkQnJhbmNoW2JyYW5jaF0gPSB4eFRyZWVbYnJhbmNoXTtcbiAgICAgICAgICAgICAgc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB7ICcqKic6IGlzb2xhdGVkQnJhbmNoIH0sIGkrMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYoeHhUcmVlLl9saXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gV2UgaGF2ZSByZWFjaGVkIHRoZSBlbmQgYW5kIHN0aWxsIG9uIGEgJyoqJ1xuICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHh4VHJlZSwgdHlwZUxlbmd0aCk7XG4gICAgICB9IGVsc2UgaWYoeHhUcmVlWycqJ10gJiYgeHhUcmVlWycqJ10uX2xpc3RlbmVycykge1xuICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHh4VHJlZVsnKiddLCB0eXBlTGVuZ3RoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGlzdGVuZXJzO1xuICB9XG5cbiAgZnVuY3Rpb24gZ3Jvd0xpc3RlbmVyVHJlZSh0eXBlLCBsaXN0ZW5lcikge1xuXG4gICAgdHlwZSA9IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyA/IHR5cGUuc3BsaXQodGhpcy5kZWxpbWl0ZXIpIDogdHlwZS5zbGljZSgpO1xuXG4gICAgLy9cbiAgICAvLyBMb29rcyBmb3IgdHdvIGNvbnNlY3V0aXZlICcqKicsIGlmIHNvLCBkb24ndCBhZGQgdGhlIGV2ZW50IGF0IGFsbC5cbiAgICAvL1xuICAgIGZvcih2YXIgaSA9IDAsIGxlbiA9IHR5cGUubGVuZ3RoOyBpKzEgPCBsZW47IGkrKykge1xuICAgICAgaWYodHlwZVtpXSA9PT0gJyoqJyAmJiB0eXBlW2krMV0gPT09ICcqKicpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciB0cmVlID0gdGhpcy5saXN0ZW5lclRyZWU7XG4gICAgdmFyIG5hbWUgPSB0eXBlLnNoaWZ0KCk7XG5cbiAgICB3aGlsZSAobmFtZSkge1xuXG4gICAgICBpZiAoIXRyZWVbbmFtZV0pIHtcbiAgICAgICAgdHJlZVtuYW1lXSA9IHt9O1xuICAgICAgfVxuXG4gICAgICB0cmVlID0gdHJlZVtuYW1lXTtcblxuICAgICAgaWYgKHR5cGUubGVuZ3RoID09PSAwKSB7XG5cbiAgICAgICAgaWYgKCF0cmVlLl9saXN0ZW5lcnMpIHtcbiAgICAgICAgICB0cmVlLl9saXN0ZW5lcnMgPSBsaXN0ZW5lcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKHR5cGVvZiB0cmVlLl9saXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0cmVlLl9saXN0ZW5lcnMgPSBbdHJlZS5fbGlzdGVuZXJzLCBsaXN0ZW5lcl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNBcnJheSh0cmVlLl9saXN0ZW5lcnMpKSB7XG5cbiAgICAgICAgICB0cmVlLl9saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG5cbiAgICAgICAgICBpZiAoIXRyZWUuX2xpc3RlbmVycy53YXJuZWQpIHtcblxuICAgICAgICAgICAgdmFyIG0gPSBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2V2ZW50cy5tYXhMaXN0ZW5lcnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIG0gPSB0aGlzLl9ldmVudHMubWF4TGlzdGVuZXJzO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobSA+IDAgJiYgdHJlZS5fbGlzdGVuZXJzLmxlbmd0aCA+IG0pIHtcblxuICAgICAgICAgICAgICB0cmVlLl9saXN0ZW5lcnMud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZS5fbGlzdGVuZXJzLmxlbmd0aCk7XG4gICAgICAgICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBuYW1lID0gdHlwZS5zaGlmdCgpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW5cbiAgLy8gMTAgbGlzdGVuZXJzIGFyZSBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoXG4gIC8vIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuICAvL1xuICAvLyBPYnZpb3VzbHkgbm90IGFsbCBFbWl0dGVycyBzaG91bGQgYmUgbGltaXRlZCB0byAxMC4gVGhpcyBmdW5jdGlvbiBhbGxvd3NcbiAgLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5kZWxpbWl0ZXIgPSAnLic7XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbihuKSB7XG4gICAgdGhpcy5fZXZlbnRzIHx8IGluaXQuY2FsbCh0aGlzKTtcbiAgICB0aGlzLl9ldmVudHMubWF4TGlzdGVuZXJzID0gbjtcbiAgICBpZiAoIXRoaXMuX2NvbmYpIHRoaXMuX2NvbmYgPSB7fTtcbiAgICB0aGlzLl9jb25mLm1heExpc3RlbmVycyA9IG47XG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5ldmVudCA9ICcnO1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgIHRoaXMubWFueShldmVudCwgMSwgZm4pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUubWFueSA9IGZ1bmN0aW9uKGV2ZW50LCB0dGwsIGZuKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYW55IG9ubHkgYWNjZXB0cyBpbnN0YW5jZXMgb2YgRnVuY3Rpb24nKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaXN0ZW5lcigpIHtcbiAgICAgIGlmICgtLXR0bCA9PT0gMCkge1xuICAgICAgICBzZWxmLm9mZihldmVudCwgbGlzdGVuZXIpO1xuICAgICAgfVxuICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lci5fb3JpZ2luID0gZm47XG5cbiAgICB0aGlzLm9uKGV2ZW50LCBsaXN0ZW5lcik7XG5cbiAgICByZXR1cm4gc2VsZjtcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbigpIHtcblxuICAgIHRoaXMuX2V2ZW50cyB8fCBpbml0LmNhbGwodGhpcyk7XG5cbiAgICB2YXIgdHlwZSA9IGFyZ3VtZW50c1swXTtcblxuICAgIGlmICh0eXBlID09PSAnbmV3TGlzdGVuZXInICYmICF0aGlzLm5ld0xpc3RlbmVyKSB7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcikgeyByZXR1cm4gZmFsc2U7IH1cbiAgICB9XG5cbiAgICAvLyBMb29wIHRocm91Z2ggdGhlICpfYWxsKiBmdW5jdGlvbnMgYW5kIGludm9rZSB0aGVtLlxuICAgIGlmICh0aGlzLl9hbGwpIHtcbiAgICAgIHZhciBsID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGwgLSAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgbDsgaSsrKSBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgIGZvciAoaSA9IDAsIGwgPSB0aGlzLl9hbGwubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHRoaXMuZXZlbnQgPSB0eXBlO1xuICAgICAgICB0aGlzLl9hbGxbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICAgIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG5cbiAgICAgIGlmICghdGhpcy5fYWxsICYmXG4gICAgICAgICF0aGlzLl9ldmVudHMuZXJyb3IgJiZcbiAgICAgICAgISh0aGlzLndpbGRjYXJkICYmIHRoaXMubGlzdGVuZXJUcmVlLmVycm9yKSkge1xuXG4gICAgICAgIGlmIChhcmd1bWVudHNbMV0gaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHRocm93IGFyZ3VtZW50c1sxXTsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmNhdWdodCwgdW5zcGVjaWZpZWQgJ2Vycm9yJyBldmVudC5cIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBoYW5kbGVyO1xuXG4gICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgaGFuZGxlciA9IFtdO1xuICAgICAgdmFyIG5zID0gdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnID8gdHlwZS5zcGxpdCh0aGlzLmRlbGltaXRlcikgOiB0eXBlLnNsaWNlKCk7XG4gICAgICBzZWFyY2hMaXN0ZW5lclRyZWUuY2FsbCh0aGlzLCBoYW5kbGVyLCBucywgdGhpcy5saXN0ZW5lclRyZWUsIDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLmV2ZW50ID0gdHlwZTtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKVxuICAgICAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAvLyBzbG93ZXJcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobCAtIDEpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsOyBpKyspIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGVsc2UgaWYgKGhhbmRsZXIpIHtcbiAgICAgIHZhciBsID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGwgLSAxKTtcbiAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgbDsgaSsrKSBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgICAgdmFyIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gbGlzdGVuZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB0aGlzLmV2ZW50ID0gdHlwZTtcbiAgICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkgfHwgISF0aGlzLl9hbGw7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuICEhdGhpcy5fYWxsO1xuICAgIH1cblxuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuXG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLm9uQW55KHR5cGUpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvbiBvbmx5IGFjY2VwdHMgaW5zdGFuY2VzIG9mIEZ1bmN0aW9uJyk7XG4gICAgfVxuICAgIHRoaXMuX2V2ZW50cyB8fCBpbml0LmNhbGwodGhpcyk7XG5cbiAgICAvLyBUbyBhdm9pZCByZWN1cnNpb24gaW4gdGhlIGNhc2UgdGhhdCB0eXBlID09IFwibmV3TGlzdGVuZXJzXCIhIEJlZm9yZVxuICAgIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJzXCIuXG4gICAgdGhpcy5lbWl0KCduZXdMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgIGdyb3dMaXN0ZW5lclRyZWUuY2FsbCh0aGlzLCB0eXBlLCBsaXN0ZW5lcik7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkge1xuICAgICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICB9XG4gICAgZWxzZSBpZih0eXBlb2YgdGhpcy5fZXZlbnRzW3R5cGVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAvLyBBZGRpbmcgdGhlIHNlY29uZCBlbGVtZW50LCBuZWVkIHRvIGNoYW5nZSB0byBhcnJheS5cbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNBcnJheSh0aGlzLl9ldmVudHNbdHlwZV0pKSB7XG4gICAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ucHVzaChsaXN0ZW5lcik7XG5cbiAgICAgIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gICAgICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcblxuICAgICAgICB2YXIgbSA9IGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9ldmVudHMubWF4TGlzdGVuZXJzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIG0gPSB0aGlzLl9ldmVudHMubWF4TGlzdGVuZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG5cbiAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbkFueSA9IGZ1bmN0aW9uKGZuKSB7XG5cbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29uQW55IG9ubHkgYWNjZXB0cyBpbnN0YW5jZXMgb2YgRnVuY3Rpb24nKTtcbiAgICB9XG5cbiAgICBpZighdGhpcy5fYWxsKSB7XG4gICAgICB0aGlzLl9hbGwgPSBbXTtcbiAgICB9XG5cbiAgICAvLyBBZGQgdGhlIGZ1bmN0aW9uIHRvIHRoZSBldmVudCBsaXN0ZW5lciBjb2xsZWN0aW9uLlxuICAgIHRoaXMuX2FsbC5wdXNoKGZuKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbjtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdyZW1vdmVMaXN0ZW5lciBvbmx5IHRha2VzIGluc3RhbmNlcyBvZiBGdW5jdGlvbicpO1xuICAgIH1cblxuICAgIHZhciBoYW5kbGVycyxsZWFmcz1bXTtcblxuICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgIHZhciBucyA9IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyA/IHR5cGUuc3BsaXQodGhpcy5kZWxpbWl0ZXIpIDogdHlwZS5zbGljZSgpO1xuICAgICAgbGVhZnMgPSBzZWFyY2hMaXN0ZW5lclRyZWUuY2FsbCh0aGlzLCBudWxsLCBucywgdGhpcy5saXN0ZW5lclRyZWUsIDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIC8vIGRvZXMgbm90IHVzZSBsaXN0ZW5lcnMoKSwgc28gbm8gc2lkZSBlZmZlY3Qgb2YgY3JlYXRpbmcgX2V2ZW50c1t0eXBlXVxuICAgICAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pIHJldHVybiB0aGlzO1xuICAgICAgaGFuZGxlcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgICBsZWFmcy5wdXNoKHtfbGlzdGVuZXJzOmhhbmRsZXJzfSk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaUxlYWY9MDsgaUxlYWY8bGVhZnMubGVuZ3RoOyBpTGVhZisrKSB7XG4gICAgICB2YXIgbGVhZiA9IGxlYWZzW2lMZWFmXTtcbiAgICAgIGhhbmRsZXJzID0gbGVhZi5fbGlzdGVuZXJzO1xuICAgICAgaWYgKGlzQXJyYXkoaGFuZGxlcnMpKSB7XG5cbiAgICAgICAgdmFyIHBvc2l0aW9uID0gLTE7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGhhbmRsZXJzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKGhhbmRsZXJzW2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgICAgKGhhbmRsZXJzW2ldLmxpc3RlbmVyICYmIGhhbmRsZXJzW2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikgfHxcbiAgICAgICAgICAgIChoYW5kbGVyc1tpXS5fb3JpZ2luICYmIGhhbmRsZXJzW2ldLl9vcmlnaW4gPT09IGxpc3RlbmVyKSkge1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgICAgIGxlYWYuX2xpc3RlbmVycy5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGhhbmRsZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBsZWFmLl9saXN0ZW5lcnM7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChoYW5kbGVycyA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgKGhhbmRsZXJzLmxpc3RlbmVyICYmIGhhbmRsZXJzLmxpc3RlbmVyID09PSBsaXN0ZW5lcikgfHxcbiAgICAgICAgKGhhbmRsZXJzLl9vcmlnaW4gJiYgaGFuZGxlcnMuX29yaWdpbiA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgICAgICBkZWxldGUgbGVhZi5fbGlzdGVuZXJzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZkFueSA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgdmFyIGkgPSAwLCBsID0gMCwgZm5zO1xuICAgIGlmIChmbiAmJiB0aGlzLl9hbGwgJiYgdGhpcy5fYWxsLmxlbmd0aCA+IDApIHtcbiAgICAgIGZucyA9IHRoaXMuX2FsbDtcbiAgICAgIGZvcihpID0gMCwgbCA9IGZucy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgaWYoZm4gPT09IGZuc1tpXSkge1xuICAgICAgICAgIGZucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYWxsID0gW107XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZjtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgIXRoaXMuX2V2ZW50cyB8fCBpbml0LmNhbGwodGhpcyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZih0aGlzLndpbGRjYXJkKSB7XG4gICAgICB2YXIgbnMgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlLnNwbGl0KHRoaXMuZGVsaW1pdGVyKSA6IHR5cGUuc2xpY2UoKTtcbiAgICAgIHZhciBsZWFmcyA9IHNlYXJjaExpc3RlbmVyVHJlZS5jYWxsKHRoaXMsIG51bGwsIG5zLCB0aGlzLmxpc3RlbmVyVHJlZSwgMCk7XG5cbiAgICAgIGZvciAodmFyIGlMZWFmPTA7IGlMZWFmPGxlYWZzLmxlbmd0aDsgaUxlYWYrKykge1xuICAgICAgICB2YXIgbGVhZiA9IGxlYWZzW2lMZWFmXTtcbiAgICAgICAgbGVhZi5fbGlzdGVuZXJzID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkgcmV0dXJuIHRoaXM7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgICBpZih0aGlzLndpbGRjYXJkKSB7XG4gICAgICB2YXIgaGFuZGxlcnMgPSBbXTtcbiAgICAgIHZhciBucyA9IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyA/IHR5cGUuc3BsaXQodGhpcy5kZWxpbWl0ZXIpIDogdHlwZS5zbGljZSgpO1xuICAgICAgc2VhcmNoTGlzdGVuZXJUcmVlLmNhbGwodGhpcywgaGFuZGxlcnMsIG5zLCB0aGlzLmxpc3RlbmVyVHJlZSwgMCk7XG4gICAgICByZXR1cm4gaGFuZGxlcnM7XG4gICAgfVxuXG4gICAgdGhpcy5fZXZlbnRzIHx8IGluaXQuY2FsbCh0aGlzKTtcblxuICAgIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKSB0aGlzLl9ldmVudHNbdHlwZV0gPSBbXTtcbiAgICBpZiAoIWlzQXJyYXkodGhpcy5fZXZlbnRzW3R5cGVdKSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9ldmVudHNbdHlwZV07XG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnNBbnkgPSBmdW5jdGlvbigpIHtcblxuICAgIGlmKHRoaXMuX2FsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2FsbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gIH07XG5cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAvLyBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlcjtcbiAgICB9KTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpIHtcbiAgICAvLyBDb21tb25KU1xuICAgIGV4cG9ydHMuRXZlbnRFbWl0dGVyMiA9IEV2ZW50RW1pdHRlcjtcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBCcm93c2VyIGdsb2JhbC5cbiAgICB3aW5kb3cuRXZlbnRFbWl0dGVyMiA9IEV2ZW50RW1pdHRlcjtcbiAgfVxufSgpO1xuIiwiXG5cbi8vXG4vLyBUaGUgc2hpbXMgaW4gdGhpcyBmaWxlIGFyZSBub3QgZnVsbHkgaW1wbGVtZW50ZWQgc2hpbXMgZm9yIHRoZSBFUzVcbi8vIGZlYXR1cmVzLCBidXQgZG8gd29yayBmb3IgdGhlIHBhcnRpY3VsYXIgdXNlY2FzZXMgdGhlcmUgaXMgaW5cbi8vIHRoZSBvdGhlciBtb2R1bGVzLlxuLy9cblxudmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcbnZhciBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG5cbi8vIEFycmF5LmlzQXJyYXkgaXMgc3VwcG9ydGVkIGluIElFOVxuZnVuY3Rpb24gaXNBcnJheSh4cykge1xuICByZXR1cm4gdG9TdHJpbmcuY2FsbCh4cykgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5leHBvcnRzLmlzQXJyYXkgPSB0eXBlb2YgQXJyYXkuaXNBcnJheSA9PT0gJ2Z1bmN0aW9uJyA/IEFycmF5LmlzQXJyYXkgOiBpc0FycmF5O1xuXG4vLyBBcnJheS5wcm90b3R5cGUuaW5kZXhPZiBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLmluZGV4T2YgPSBmdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gIGlmICh4cy5pbmRleE9mKSByZXR1cm4geHMuaW5kZXhPZih4KTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh4ID09PSB4c1tpXSkgcmV0dXJuIGk7XG4gIH1cbiAgcmV0dXJuIC0xO1xufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLmZpbHRlciBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLmZpbHRlciA9IGZ1bmN0aW9uIGZpbHRlcih4cywgZm4pIHtcbiAgaWYgKHhzLmZpbHRlcikgcmV0dXJuIHhzLmZpbHRlcihmbik7XG4gIHZhciByZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChmbih4c1tpXSwgaSwgeHMpKSByZXMucHVzaCh4c1tpXSk7XG4gIH1cbiAgcmV0dXJuIHJlcztcbn07XG5cbi8vIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuZm9yRWFjaCA9IGZ1bmN0aW9uIGZvckVhY2goeHMsIGZuLCBzZWxmKSB7XG4gIGlmICh4cy5mb3JFYWNoKSByZXR1cm4geHMuZm9yRWFjaChmbiwgc2VsZik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICBmbi5jYWxsKHNlbGYsIHhzW2ldLCBpLCB4cyk7XG4gIH1cbn07XG5cbi8vIEFycmF5LnByb3RvdHlwZS5tYXAgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5tYXAgPSBmdW5jdGlvbiBtYXAoeHMsIGZuKSB7XG4gIGlmICh4cy5tYXApIHJldHVybiB4cy5tYXAoZm4pO1xuICB2YXIgb3V0ID0gbmV3IEFycmF5KHhzLmxlbmd0aCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICBvdXRbaV0gPSBmbih4c1tpXSwgaSwgeHMpO1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG4vLyBBcnJheS5wcm90b3R5cGUucmVkdWNlIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMucmVkdWNlID0gZnVuY3Rpb24gcmVkdWNlKGFycmF5LCBjYWxsYmFjaywgb3B0X2luaXRpYWxWYWx1ZSkge1xuICBpZiAoYXJyYXkucmVkdWNlKSByZXR1cm4gYXJyYXkucmVkdWNlKGNhbGxiYWNrLCBvcHRfaW5pdGlhbFZhbHVlKTtcbiAgdmFyIHZhbHVlLCBpc1ZhbHVlU2V0ID0gZmFsc2U7XG5cbiAgaWYgKDIgPCBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdmFsdWUgPSBvcHRfaW5pdGlhbFZhbHVlO1xuICAgIGlzVmFsdWVTZXQgPSB0cnVlO1xuICB9XG4gIGZvciAodmFyIGkgPSAwLCBsID0gYXJyYXkubGVuZ3RoOyBsID4gaTsgKytpKSB7XG4gICAgaWYgKGFycmF5Lmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICBpZiAoaXNWYWx1ZVNldCkge1xuICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrKHZhbHVlLCBhcnJheVtpXSwgaSwgYXJyYXkpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHZhbHVlID0gYXJyYXlbaV07XG4gICAgICAgIGlzVmFsdWVTZXQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbi8vIFN0cmluZy5wcm90b3R5cGUuc3Vic3RyIC0gbmVnYXRpdmUgaW5kZXggZG9uJ3Qgd29yayBpbiBJRThcbmlmICgnYWInLnN1YnN0cigtMSkgIT09ICdiJykge1xuICBleHBvcnRzLnN1YnN0ciA9IGZ1bmN0aW9uIChzdHIsIHN0YXJ0LCBsZW5ndGgpIHtcbiAgICAvLyBkaWQgd2UgZ2V0IGEgbmVnYXRpdmUgc3RhcnQsIGNhbGN1bGF0ZSBob3cgbXVjaCBpdCBpcyBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0cmluZ1xuICAgIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gc3RyLmxlbmd0aCArIHN0YXJ0O1xuXG4gICAgLy8gY2FsbCB0aGUgb3JpZ2luYWwgZnVuY3Rpb25cbiAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuZ3RoKTtcbiAgfTtcbn0gZWxzZSB7XG4gIGV4cG9ydHMuc3Vic3RyID0gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbmd0aCkge1xuICAgIHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW5ndGgpO1xuICB9O1xufVxuXG4vLyBTdHJpbmcucHJvdG90eXBlLnRyaW0gaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy50cmltID0gZnVuY3Rpb24gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpO1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbn07XG5cbi8vIEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuYmluZCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICB2YXIgZm4gPSBhcmdzLnNoaWZ0KCk7XG4gIGlmIChmbi5iaW5kKSByZXR1cm4gZm4uYmluZC5hcHBseShmbiwgYXJncyk7XG4gIHZhciBzZWxmID0gYXJncy5zaGlmdCgpO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGZuLmFwcGx5KHNlbGYsIGFyZ3MuY29uY2F0KFtBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpXSkpO1xuICB9O1xufTtcblxuLy8gT2JqZWN0LmNyZWF0ZSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5mdW5jdGlvbiBjcmVhdGUocHJvdG90eXBlLCBwcm9wZXJ0aWVzKSB7XG4gIHZhciBvYmplY3Q7XG4gIGlmIChwcm90b3R5cGUgPT09IG51bGwpIHtcbiAgICBvYmplY3QgPSB7ICdfX3Byb3RvX18nIDogbnVsbCB9O1xuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2YgcHJvdG90eXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgJ3R5cGVvZiBwcm90b3R5cGVbJyArICh0eXBlb2YgcHJvdG90eXBlKSArICddICE9IFxcJ29iamVjdFxcJydcbiAgICAgICk7XG4gICAgfVxuICAgIHZhciBUeXBlID0gZnVuY3Rpb24gKCkge307XG4gICAgVHlwZS5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gICAgb2JqZWN0ID0gbmV3IFR5cGUoKTtcbiAgICBvYmplY3QuX19wcm90b19fID0gcHJvdG90eXBlO1xuICB9XG4gIGlmICh0eXBlb2YgcHJvcGVydGllcyAhPT0gJ3VuZGVmaW5lZCcgJiYgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhvYmplY3QsIHByb3BlcnRpZXMpO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5leHBvcnRzLmNyZWF0ZSA9IHR5cGVvZiBPYmplY3QuY3JlYXRlID09PSAnZnVuY3Rpb24nID8gT2JqZWN0LmNyZWF0ZSA6IGNyZWF0ZTtcblxuLy8gT2JqZWN0LmtleXMgYW5kIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIGlzIHN1cHBvcnRlZCBpbiBJRTkgaG93ZXZlclxuLy8gdGhleSBkbyBzaG93IGEgZGVzY3JpcHRpb24gYW5kIG51bWJlciBwcm9wZXJ0eSBvbiBFcnJvciBvYmplY3RzXG5mdW5jdGlvbiBub3RPYmplY3Qob2JqZWN0KSB7XG4gIHJldHVybiAoKHR5cGVvZiBvYmplY3QgIT0gXCJvYmplY3RcIiAmJiB0eXBlb2Ygb2JqZWN0ICE9IFwiZnVuY3Rpb25cIikgfHwgb2JqZWN0ID09PSBudWxsKTtcbn1cblxuZnVuY3Rpb24ga2V5c1NoaW0ob2JqZWN0KSB7XG4gIGlmIChub3RPYmplY3Qob2JqZWN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3Qua2V5cyBjYWxsZWQgb24gYSBub24tb2JqZWN0XCIpO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBuYW1lIGluIG9iamVjdCkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgbmFtZSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKG5hbWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vLyBnZXRPd25Qcm9wZXJ0eU5hbWVzIGlzIGFsbW9zdCB0aGUgc2FtZSBhcyBPYmplY3Qua2V5cyBvbmUga2V5IGZlYXR1cmVcbi8vICBpcyB0aGF0IGl0IHJldHVybnMgaGlkZGVuIHByb3BlcnRpZXMsIHNpbmNlIHRoYXQgY2FuJ3QgYmUgaW1wbGVtZW50ZWQsXG4vLyAgdGhpcyBmZWF0dXJlIGdldHMgcmVkdWNlZCBzbyBpdCBqdXN0IHNob3dzIHRoZSBsZW5ndGggcHJvcGVydHkgb24gYXJyYXlzXG5mdW5jdGlvbiBwcm9wZXJ0eVNoaW0ob2JqZWN0KSB7XG4gIGlmIChub3RPYmplY3Qob2JqZWN0KSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyBjYWxsZWQgb24gYSBub24tb2JqZWN0XCIpO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IGtleXNTaGltKG9iamVjdCk7XG4gIGlmIChleHBvcnRzLmlzQXJyYXkob2JqZWN0KSAmJiBleHBvcnRzLmluZGV4T2Yob2JqZWN0LCAnbGVuZ3RoJykgPT09IC0xKSB7XG4gICAgcmVzdWx0LnB1c2goJ2xlbmd0aCcpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbnZhciBrZXlzID0gdHlwZW9mIE9iamVjdC5rZXlzID09PSAnZnVuY3Rpb24nID8gT2JqZWN0LmtleXMgOiBrZXlzU2hpbTtcbnZhciBnZXRPd25Qcm9wZXJ0eU5hbWVzID0gdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzID09PSAnZnVuY3Rpb24nID9cbiAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgOiBwcm9wZXJ0eVNoaW07XG5cbmlmIChuZXcgRXJyb3IoKS5oYXNPd25Qcm9wZXJ0eSgnZGVzY3JpcHRpb24nKSkge1xuICB2YXIgRVJST1JfUFJPUEVSVFlfRklMVEVSID0gZnVuY3Rpb24gKG9iaiwgYXJyYXkpIHtcbiAgICBpZiAodG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBFcnJvcl0nKSB7XG4gICAgICBhcnJheSA9IGV4cG9ydHMuZmlsdGVyKGFycmF5LCBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICByZXR1cm4gbmFtZSAhPT0gJ2Rlc2NyaXB0aW9uJyAmJiBuYW1lICE9PSAnbnVtYmVyJyAmJiBuYW1lICE9PSAnbWVzc2FnZSc7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5O1xuICB9O1xuXG4gIGV4cG9ydHMua2V5cyA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gRVJST1JfUFJPUEVSVFlfRklMVEVSKG9iamVjdCwga2V5cyhvYmplY3QpKTtcbiAgfTtcbiAgZXhwb3J0cy5nZXRPd25Qcm9wZXJ0eU5hbWVzID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBFUlJPUl9QUk9QRVJUWV9GSUxURVIob2JqZWN0LCBnZXRPd25Qcm9wZXJ0eU5hbWVzKG9iamVjdCkpO1xuICB9O1xufSBlbHNlIHtcbiAgZXhwb3J0cy5rZXlzID0ga2V5cztcbiAgZXhwb3J0cy5nZXRPd25Qcm9wZXJ0eU5hbWVzID0gZ2V0T3duUHJvcGVydHlOYW1lcztcbn1cblxuLy8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciAtIHN1cHBvcnRlZCBpbiBJRTggYnV0IG9ubHkgb24gZG9tIGVsZW1lbnRzXG5mdW5jdGlvbiB2YWx1ZU9iamVjdCh2YWx1ZSwga2V5KSB7XG4gIHJldHVybiB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG59XG5cbmlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9PT0gJ2Z1bmN0aW9uJykge1xuICB0cnkge1xuICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoeydhJzogMX0sICdhJyk7XG4gICAgZXhwb3J0cy5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gSUU4IGRvbSBlbGVtZW50IGlzc3VlIC0gdXNlIGEgdHJ5IGNhdGNoIGFuZCBkZWZhdWx0IHRvIHZhbHVlT2JqZWN0XG4gICAgZXhwb3J0cy5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZU9iamVjdCh2YWx1ZSwga2V5KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG59IGVsc2Uge1xuICBleHBvcnRzLmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IHZhbHVlT2JqZWN0O1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIGEgZHVwbGV4IHN0cmVhbSBpcyBqdXN0IGEgc3RyZWFtIHRoYXQgaXMgYm90aCByZWFkYWJsZSBhbmQgd3JpdGFibGUuXG4vLyBTaW5jZSBKUyBkb2Vzbid0IGhhdmUgbXVsdGlwbGUgcHJvdG90eXBhbCBpbmhlcml0YW5jZSwgdGhpcyBjbGFzc1xuLy8gcHJvdG90eXBhbGx5IGluaGVyaXRzIGZyb20gUmVhZGFibGUsIGFuZCB0aGVuIHBhcmFzaXRpY2FsbHkgZnJvbVxuLy8gV3JpdGFibGUuXG5cbm1vZHVsZS5leHBvcnRzID0gRHVwbGV4O1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcbnZhciB0aW1lcnMgPSByZXF1aXJlKCd0aW1lcnMnKTtcbnZhciBSZWFkYWJsZSA9IHJlcXVpcmUoJ19zdHJlYW1fcmVhZGFibGUnKTtcbnZhciBXcml0YWJsZSA9IHJlcXVpcmUoJ19zdHJlYW1fd3JpdGFibGUnKTtcblxudXRpbC5pbmhlcml0cyhEdXBsZXgsIFJlYWRhYmxlKTtcblxuc2hpbXMuZm9yRWFjaChzaGltcy5rZXlzKFdyaXRhYmxlLnByb3RvdHlwZSksIGZ1bmN0aW9uKG1ldGhvZCkge1xuICBpZiAoIUR1cGxleC5wcm90b3R5cGVbbWV0aG9kXSlcbiAgICBEdXBsZXgucHJvdG90eXBlW21ldGhvZF0gPSBXcml0YWJsZS5wcm90b3R5cGVbbWV0aG9kXTtcbn0pO1xuXG5mdW5jdGlvbiBEdXBsZXgob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRHVwbGV4KSlcbiAgICByZXR1cm4gbmV3IER1cGxleChvcHRpb25zKTtcblxuICBSZWFkYWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuICBXcml0YWJsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucmVhZGFibGUgPT09IGZhbHNlKVxuICAgIHRoaXMucmVhZGFibGUgPSBmYWxzZTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLndyaXRhYmxlID09PSBmYWxzZSlcbiAgICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgdGhpcy5hbGxvd0hhbGZPcGVuID0gdHJ1ZTtcbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5hbGxvd0hhbGZPcGVuID09PSBmYWxzZSlcbiAgICB0aGlzLmFsbG93SGFsZk9wZW4gPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2VuZCcsIG9uZW5kKTtcbn1cblxuLy8gdGhlIG5vLWhhbGYtb3BlbiBlbmZvcmNlclxuZnVuY3Rpb24gb25lbmQoKSB7XG4gIC8vIGlmIHdlIGFsbG93IGhhbGYtb3BlbiBzdGF0ZSwgb3IgaWYgdGhlIHdyaXRhYmxlIHNpZGUgZW5kZWQsXG4gIC8vIHRoZW4gd2UncmUgb2suXG4gIGlmICh0aGlzLmFsbG93SGFsZk9wZW4gfHwgdGhpcy5fd3JpdGFibGVTdGF0ZS5lbmRlZClcbiAgICByZXR1cm47XG5cbiAgLy8gbm8gbW9yZSBkYXRhIGNhbiBiZSB3cml0dGVuLlxuICAvLyBCdXQgYWxsb3cgbW9yZSB3cml0ZXMgdG8gaGFwcGVuIGluIHRoaXMgdGljay5cbiAgdGltZXJzLnNldEltbWVkaWF0ZShzaGltcy5iaW5kKHRoaXMuZW5kLCB0aGlzKSk7XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSBwYXNzdGhyb3VnaCBzdHJlYW0uXG4vLyBiYXNpY2FsbHkganVzdCB0aGUgbW9zdCBtaW5pbWFsIHNvcnQgb2YgVHJhbnNmb3JtIHN0cmVhbS5cbi8vIEV2ZXJ5IHdyaXR0ZW4gY2h1bmsgZ2V0cyBvdXRwdXQgYXMtaXMuXG5cbm1vZHVsZS5leHBvcnRzID0gUGFzc1Rocm91Z2g7XG5cbnZhciBUcmFuc2Zvcm0gPSByZXF1aXJlKCdfc3RyZWFtX3RyYW5zZm9ybScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG51dGlsLmluaGVyaXRzKFBhc3NUaHJvdWdoLCBUcmFuc2Zvcm0pO1xuXG5mdW5jdGlvbiBQYXNzVGhyb3VnaChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBQYXNzVGhyb3VnaCkpXG4gICAgcmV0dXJuIG5ldyBQYXNzVGhyb3VnaChvcHRpb25zKTtcblxuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBvcHRpb25zKTtcbn1cblxuUGFzc1Rocm91Z2gucHJvdG90eXBlLl90cmFuc2Zvcm0gPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG51bGwsIGNodW5rKTtcbn07XG4iLCJ2YXIgcHJvY2Vzcz1yZXF1aXJlKFwiX19icm93c2VyaWZ5X3Byb2Nlc3NcIik7Ly8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbm1vZHVsZS5leHBvcnRzID0gUmVhZGFibGU7XG5SZWFkYWJsZS5SZWFkYWJsZVN0YXRlID0gUmVhZGFibGVTdGF0ZTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIHNoaW1zID0gcmVxdWlyZSgnX3NoaW1zJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIHRpbWVycyA9IHJlcXVpcmUoJ3RpbWVycycpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgU3RyaW5nRGVjb2RlcjtcblxudXRpbC5pbmhlcml0cyhSZWFkYWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gUmVhZGFibGVTdGF0ZShvcHRpb25zLCBzdHJlYW0pIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gdGhlIHBvaW50IGF0IHdoaWNoIGl0IHN0b3BzIGNhbGxpbmcgX3JlYWQoKSB0byBmaWxsIHRoZSBidWZmZXJcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyBcImRvbid0IGNhbGwgX3JlYWQgcHJlZW1wdGl2ZWx5IGV2ZXJcIlxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSAoaHdtIHx8IGh3bSA9PT0gMCkgPyBod20gOiAxNiAqIDEwMjQ7XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLmJ1ZmZlciA9IFtdO1xuICB0aGlzLmxlbmd0aCA9IDA7XG4gIHRoaXMucGlwZXMgPSBudWxsO1xuICB0aGlzLnBpcGVzQ291bnQgPSAwO1xuICB0aGlzLmZsb3dpbmcgPSBmYWxzZTtcbiAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICB0aGlzLmVuZEVtaXR0ZWQgPSBmYWxzZTtcbiAgdGhpcy5yZWFkaW5nID0gZmFsc2U7XG5cbiAgLy8gSW4gc3RyZWFtcyB0aGF0IG5ldmVyIGhhdmUgYW55IGRhdGEsIGFuZCBkbyBwdXNoKG51bGwpIHJpZ2h0IGF3YXksXG4gIC8vIHRoZSBjb25zdW1lciBjYW4gbWlzcyB0aGUgJ2VuZCcgZXZlbnQgaWYgdGhleSBkbyBzb21lIEkvTyBiZWZvcmVcbiAgLy8gY29uc3VtaW5nIHRoZSBzdHJlYW0uICBTbywgd2UgZG9uJ3QgZW1pdCgnZW5kJykgdW50aWwgc29tZSByZWFkaW5nXG4gIC8vIGhhcHBlbnMuXG4gIHRoaXMuY2FsbGVkUmVhZCA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWN1YXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIHdoZW5ldmVyIHdlIHJldHVybiBudWxsLCB0aGVuIHdlIHNldCBhIGZsYWcgdG8gc2F5XG4gIC8vIHRoYXQgd2UncmUgYXdhaXRpbmcgYSAncmVhZGFibGUnIGV2ZW50IGVtaXNzaW9uLlxuICB0aGlzLm5lZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuICB0aGlzLnJlYWRhYmxlTGlzdGVuaW5nID0gZmFsc2U7XG5cblxuICAvLyBvYmplY3Qgc3RyZWFtIGZsYWcuIFVzZWQgdG8gbWFrZSByZWFkKG4pIGlnbm9yZSBuIGFuZCB0b1xuICAvLyBtYWtlIGFsbCB0aGUgYnVmZmVyIG1lcmdpbmcgYW5kIGxlbmd0aCBjaGVja3MgZ28gYXdheVxuICB0aGlzLm9iamVjdE1vZGUgPSAhIW9wdGlvbnMub2JqZWN0TW9kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyB3aGVuIHBpcGluZywgd2Ugb25seSBjYXJlIGFib3V0ICdyZWFkYWJsZScgZXZlbnRzIHRoYXQgaGFwcGVuXG4gIC8vIGFmdGVyIHJlYWQoKWluZyBhbGwgdGhlIGJ5dGVzIGFuZCBub3QgZ2V0dGluZyBhbnkgcHVzaGJhY2suXG4gIHRoaXMucmFuT3V0ID0gZmFsc2U7XG5cbiAgLy8gdGhlIG51bWJlciBvZiB3cml0ZXJzIHRoYXQgYXJlIGF3YWl0aW5nIGEgZHJhaW4gZXZlbnQgaW4gLnBpcGUoKXNcbiAgdGhpcy5hd2FpdERyYWluID0gMDtcblxuICAvLyBpZiB0cnVlLCBhIG1heWJlUmVhZE1vcmUgaGFzIGJlZW4gc2NoZWR1bGVkXG4gIHRoaXMucmVhZGluZ01vcmUgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIgPSBudWxsO1xuICB0aGlzLmVuY29kaW5nID0gbnVsbDtcbiAgaWYgKG9wdGlvbnMuZW5jb2RpbmcpIHtcbiAgICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgICBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyO1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMuZW5jb2RpbmcpO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBvcHRpb25zLmVuY29kaW5nO1xuICB9XG59XG5cbmZ1bmN0aW9uIFJlYWRhYmxlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlYWRhYmxlKSlcbiAgICByZXR1cm4gbmV3IFJlYWRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3JlYWRhYmxlU3RhdGUgPSBuZXcgUmVhZGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3lcbiAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG5cbiAgU3RyZWFtLmNhbGwodGhpcyk7XG59XG5cbi8vIE1hbnVhbGx5IHNob3ZlIHNvbWV0aGluZyBpbnRvIHRoZSByZWFkKCkgYnVmZmVyLlxuLy8gVGhpcyByZXR1cm5zIHRydWUgaWYgdGhlIGhpZ2hXYXRlck1hcmsgaGFzIG5vdCBiZWVuIGhpdCB5ZXQsXG4vLyBzaW1pbGFyIHRvIGhvdyBXcml0YWJsZS53cml0ZSgpIHJldHVybnMgdHJ1ZSBpZiB5b3Ugc2hvdWxkXG4vLyB3cml0ZSgpIHNvbWUgbW9yZS5cblJlYWRhYmxlLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycgJiYgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICBlbmNvZGluZyA9IGVuY29kaW5nIHx8IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcbiAgICBpZiAoZW5jb2RpbmcgIT09IHN0YXRlLmVuY29kaW5nKSB7XG4gICAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgICAgIGVuY29kaW5nID0gJyc7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgZmFsc2UpO1xufTtcblxuLy8gVW5zaGlmdCBzaG91bGQgKmFsd2F5cyogYmUgc29tZXRoaW5nIGRpcmVjdGx5IG91dCBvZiByZWFkKClcblJlYWRhYmxlLnByb3RvdHlwZS51bnNoaWZ0ID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgcmV0dXJuIHJlYWRhYmxlQWRkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCAnJywgdHJ1ZSk7XG59O1xuXG5mdW5jdGlvbiByZWFkYWJsZUFkZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgYWRkVG9Gcm9udCkge1xuICB2YXIgZXIgPSBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKTtcbiAgaWYgKGVyKSB7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9IGVsc2UgaWYgKGNodW5rID09PSBudWxsIHx8IGNodW5rID09PSB1bmRlZmluZWQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgaWYgKCFzdGF0ZS5lbmRlZClcbiAgICAgIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSk7XG4gIH0gZWxzZSBpZiAoc3RhdGUub2JqZWN0TW9kZSB8fCBjaHVuayAmJiBjaHVuay5sZW5ndGggPiAwKSB7XG4gICAgaWYgKHN0YXRlLmVuZGVkICYmICFhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnB1c2goKSBhZnRlciBFT0YnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUuZW5kRW1pdHRlZCAmJiBhZGRUb0Zyb250KSB7XG4gICAgICB2YXIgZSA9IG5ldyBFcnJvcignc3RyZWFtLnVuc2hpZnQoKSBhZnRlciBlbmQgZXZlbnQnKTtcbiAgICAgIHN0cmVhbS5lbWl0KCdlcnJvcicsIGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhYWRkVG9Gcm9udCAmJiAhZW5jb2RpbmcpXG4gICAgICAgIGNodW5rID0gc3RhdGUuZGVjb2Rlci53cml0ZShjaHVuayk7XG5cbiAgICAgIC8vIHVwZGF0ZSB0aGUgYnVmZmVyIGluZm8uXG4gICAgICBzdGF0ZS5sZW5ndGggKz0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG4gICAgICBpZiAoYWRkVG9Gcm9udCkge1xuICAgICAgICBzdGF0ZS5idWZmZXIudW5zaGlmdChjaHVuayk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gICAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlLm5lZWRSZWFkYWJsZSlcbiAgICAgICAgZW1pdFJlYWRhYmxlKHN0cmVhbSk7XG5cbiAgICAgIG1heWJlUmVhZE1vcmUoc3RyZWFtLCBzdGF0ZSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKCFhZGRUb0Zyb250KSB7XG4gICAgc3RhdGUucmVhZGluZyA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIG5lZWRNb3JlRGF0YShzdGF0ZSk7XG59XG5cblxuXG4vLyBpZiBpdCdzIHBhc3QgdGhlIGhpZ2ggd2F0ZXIgbWFyaywgd2UgY2FuIHB1c2ggaW4gc29tZSBtb3JlLlxuLy8gQWxzbywgaWYgd2UgaGF2ZSBubyBkYXRhIHlldCwgd2UgY2FuIHN0YW5kIHNvbWVcbi8vIG1vcmUgYnl0ZXMuICBUaGlzIGlzIHRvIHdvcmsgYXJvdW5kIGNhc2VzIHdoZXJlIGh3bT0wLFxuLy8gc3VjaCBhcyB0aGUgcmVwbC4gIEFsc28sIGlmIHRoZSBwdXNoKCkgdHJpZ2dlcmVkIGFcbi8vIHJlYWRhYmxlIGV2ZW50LCBhbmQgdGhlIHVzZXIgY2FsbGVkIHJlYWQobGFyZ2VOdW1iZXIpIHN1Y2ggdGhhdFxuLy8gbmVlZFJlYWRhYmxlIHdhcyBzZXQsIHRoZW4gd2Ugb3VnaHQgdG8gcHVzaCBtb3JlLCBzbyB0aGF0IGFub3RoZXJcbi8vICdyZWFkYWJsZScgZXZlbnQgd2lsbCBiZSB0cmlnZ2VyZWQuXG5mdW5jdGlvbiBuZWVkTW9yZURhdGEoc3RhdGUpIHtcbiAgcmV0dXJuICFzdGF0ZS5lbmRlZCAmJlxuICAgICAgICAgKHN0YXRlLm5lZWRSZWFkYWJsZSB8fFxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHxcbiAgICAgICAgICBzdGF0ZS5sZW5ndGggPT09IDApO1xufVxuXG4vLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eS5cblJlYWRhYmxlLnByb3RvdHlwZS5zZXRFbmNvZGluZyA9IGZ1bmN0aW9uKGVuYykge1xuICBpZiAoIVN0cmluZ0RlY29kZXIpXG4gICAgU3RyaW5nRGVjb2RlciA9IHJlcXVpcmUoJ3N0cmluZ19kZWNvZGVyJykuU3RyaW5nRGVjb2RlcjtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIoZW5jKTtcbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5lbmNvZGluZyA9IGVuYztcbn07XG5cbi8vIERvbid0IHJhaXNlIHRoZSBod20gPiAxMjhNQlxudmFyIE1BWF9IV00gPSAweDgwMDAwMDtcbmZ1bmN0aW9uIHJvdW5kVXBUb05leHRQb3dlck9mMihuKSB7XG4gIGlmIChuID49IE1BWF9IV00pIHtcbiAgICBuID0gTUFYX0hXTTtcbiAgfSBlbHNlIHtcbiAgICAvLyBHZXQgdGhlIG5leHQgaGlnaGVzdCBwb3dlciBvZiAyXG4gICAgbi0tO1xuICAgIGZvciAodmFyIHAgPSAxOyBwIDwgMzI7IHAgPDw9IDEpIG4gfD0gbiA+PiBwO1xuICAgIG4rKztcbiAgfVxuICByZXR1cm4gbjtcbn1cblxuZnVuY3Rpb24gaG93TXVjaFRvUmVhZChuLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLmVuZGVkKVxuICAgIHJldHVybiAwO1xuXG4gIGlmIChzdGF0ZS5vYmplY3RNb2RlKVxuICAgIHJldHVybiBuID09PSAwID8gMCA6IDE7XG5cbiAgaWYgKGlzTmFOKG4pIHx8IG4gPT09IG51bGwpIHtcbiAgICAvLyBvbmx5IGZsb3cgb25lIGJ1ZmZlciBhdCBhIHRpbWVcbiAgICBpZiAoc3RhdGUuZmxvd2luZyAmJiBzdGF0ZS5idWZmZXIubGVuZ3RoKVxuICAgICAgcmV0dXJuIHN0YXRlLmJ1ZmZlclswXS5sZW5ndGg7XG4gICAgZWxzZVxuICAgICAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuXG4gIGlmIChuIDw9IDApXG4gICAgcmV0dXJuIDA7XG5cbiAgLy8gSWYgd2UncmUgYXNraW5nIGZvciBtb3JlIHRoYW4gdGhlIHRhcmdldCBidWZmZXIgbGV2ZWwsXG4gIC8vIHRoZW4gcmFpc2UgdGhlIHdhdGVyIG1hcmsuICBCdW1wIHVwIHRvIHRoZSBuZXh0IGhpZ2hlc3RcbiAgLy8gcG93ZXIgb2YgMiwgdG8gcHJldmVudCBpbmNyZWFzaW5nIGl0IGV4Y2Vzc2l2ZWx5IGluIHRpbnlcbiAgLy8gYW1vdW50cy5cbiAgaWYgKG4gPiBzdGF0ZS5oaWdoV2F0ZXJNYXJrKVxuICAgIHN0YXRlLmhpZ2hXYXRlck1hcmsgPSByb3VuZFVwVG9OZXh0UG93ZXJPZjIobik7XG5cbiAgLy8gZG9uJ3QgaGF2ZSB0aGF0IG11Y2guICByZXR1cm4gbnVsbCwgdW5sZXNzIHdlJ3ZlIGVuZGVkLlxuICBpZiAobiA+IHN0YXRlLmxlbmd0aCkge1xuICAgIGlmICghc3RhdGUuZW5kZWQpIHtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2VcbiAgICAgIHJldHVybiBzdGF0ZS5sZW5ndGg7XG4gIH1cblxuICByZXR1cm4gbjtcbn1cblxuLy8geW91IGNhbiBvdmVycmlkZSBlaXRoZXIgdGhpcyBtZXRob2QsIG9yIHRoZSBhc3luYyBfcmVhZChuKSBiZWxvdy5cblJlYWRhYmxlLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24obikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5jYWxsZWRSZWFkID0gdHJ1ZTtcbiAgdmFyIG5PcmlnID0gbjtcblxuICBpZiAodHlwZW9mIG4gIT09ICdudW1iZXInIHx8IG4gPiAwKVxuICAgIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGlmIHdlJ3JlIGRvaW5nIHJlYWQoMCkgdG8gdHJpZ2dlciBhIHJlYWRhYmxlIGV2ZW50LCBidXQgd2VcbiAgLy8gYWxyZWFkeSBoYXZlIGEgYnVuY2ggb2YgZGF0YSBpbiB0aGUgYnVmZmVyLCB0aGVuIGp1c3QgdHJpZ2dlclxuICAvLyB0aGUgJ3JlYWRhYmxlJyBldmVudCBhbmQgbW92ZSBvbi5cbiAgaWYgKG4gPT09IDAgJiZcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSAmJlxuICAgICAgKHN0YXRlLmxlbmd0aCA+PSBzdGF0ZS5oaWdoV2F0ZXJNYXJrIHx8IHN0YXRlLmVuZGVkKSkge1xuICAgIGVtaXRSZWFkYWJsZSh0aGlzKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIG4gPSBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKTtcblxuICAvLyBpZiB3ZSd2ZSBlbmRlZCwgYW5kIHdlJ3JlIG5vdyBjbGVhciwgdGhlbiBmaW5pc2ggaXQgdXAuXG4gIGlmIChuID09PSAwICYmIHN0YXRlLmVuZGVkKSB7XG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICAgIGVuZFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gQWxsIHRoZSBhY3R1YWwgY2h1bmsgZ2VuZXJhdGlvbiBsb2dpYyBuZWVkcyB0byBiZVxuICAvLyAqYmVsb3cqIHRoZSBjYWxsIHRvIF9yZWFkLiAgVGhlIHJlYXNvbiBpcyB0aGF0IGluIGNlcnRhaW5cbiAgLy8gc3ludGhldGljIHN0cmVhbSBjYXNlcywgc3VjaCBhcyBwYXNzdGhyb3VnaCBzdHJlYW1zLCBfcmVhZFxuICAvLyBtYXkgYmUgYSBjb21wbGV0ZWx5IHN5bmNocm9ub3VzIG9wZXJhdGlvbiB3aGljaCBtYXkgY2hhbmdlXG4gIC8vIHRoZSBzdGF0ZSBvZiB0aGUgcmVhZCBidWZmZXIsIHByb3ZpZGluZyBlbm91Z2ggZGF0YSB3aGVuXG4gIC8vIGJlZm9yZSB0aGVyZSB3YXMgKm5vdCogZW5vdWdoLlxuICAvL1xuICAvLyBTbywgdGhlIHN0ZXBzIGFyZTpcbiAgLy8gMS4gRmlndXJlIG91dCB3aGF0IHRoZSBzdGF0ZSBvZiB0aGluZ3Mgd2lsbCBiZSBhZnRlciB3ZSBkb1xuICAvLyBhIHJlYWQgZnJvbSB0aGUgYnVmZmVyLlxuICAvL1xuICAvLyAyLiBJZiB0aGF0IHJlc3VsdGluZyBzdGF0ZSB3aWxsIHRyaWdnZXIgYSBfcmVhZCwgdGhlbiBjYWxsIF9yZWFkLlxuICAvLyBOb3RlIHRoYXQgdGhpcyBtYXkgYmUgYXN5bmNocm9ub3VzLCBvciBzeW5jaHJvbm91cy4gIFllcywgaXQgaXNcbiAgLy8gZGVlcGx5IHVnbHkgdG8gd3JpdGUgQVBJcyB0aGlzIHdheSwgYnV0IHRoYXQgc3RpbGwgZG9lc24ndCBtZWFuXG4gIC8vIHRoYXQgdGhlIFJlYWRhYmxlIGNsYXNzIHNob3VsZCBiZWhhdmUgaW1wcm9wZXJseSwgYXMgc3RyZWFtcyBhcmVcbiAgLy8gZGVzaWduZWQgdG8gYmUgc3luYy9hc3luYyBhZ25vc3RpYy5cbiAgLy8gVGFrZSBub3RlIGlmIHRoZSBfcmVhZCBjYWxsIGlzIHN5bmMgb3IgYXN5bmMgKGllLCBpZiB0aGUgcmVhZCBjYWxsXG4gIC8vIGhhcyByZXR1cm5lZCB5ZXQpLCBzbyB0aGF0IHdlIGtub3cgd2hldGhlciBvciBub3QgaXQncyBzYWZlIHRvIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBldGMuXG4gIC8vXG4gIC8vIDMuIEFjdHVhbGx5IHB1bGwgdGhlIHJlcXVlc3RlZCBjaHVua3Mgb3V0IG9mIHRoZSBidWZmZXIgYW5kIHJldHVybi5cblxuICAvLyBpZiB3ZSBuZWVkIGEgcmVhZGFibGUgZXZlbnQsIHRoZW4gd2UgbmVlZCB0byBkbyBzb21lIHJlYWRpbmcuXG4gIHZhciBkb1JlYWQgPSBzdGF0ZS5uZWVkUmVhZGFibGU7XG5cbiAgLy8gaWYgd2UgY3VycmVudGx5IGhhdmUgbGVzcyB0aGFuIHRoZSBoaWdoV2F0ZXJNYXJrLCB0aGVuIGFsc28gcmVhZCBzb21lXG4gIGlmIChzdGF0ZS5sZW5ndGggLSBuIDw9IHN0YXRlLmhpZ2hXYXRlck1hcmspXG4gICAgZG9SZWFkID0gdHJ1ZTtcblxuICAvLyBob3dldmVyLCBpZiB3ZSd2ZSBlbmRlZCwgdGhlbiB0aGVyZSdzIG5vIHBvaW50LCBhbmQgaWYgd2UncmUgYWxyZWFkeVxuICAvLyByZWFkaW5nLCB0aGVuIGl0J3MgdW5uZWNlc3NhcnkuXG4gIGlmIChzdGF0ZS5lbmRlZCB8fCBzdGF0ZS5yZWFkaW5nKVxuICAgIGRvUmVhZCA9IGZhbHNlO1xuXG4gIGlmIChkb1JlYWQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gdHJ1ZTtcbiAgICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIGN1cnJlbnRseSB6ZXJvLCB0aGVuIHdlICpuZWVkKiBhIHJlYWRhYmxlIGV2ZW50LlxuICAgIGlmIChzdGF0ZS5sZW5ndGggPT09IDApXG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIC8vIGNhbGwgaW50ZXJuYWwgcmVhZCBtZXRob2RcbiAgICB0aGlzLl9yZWFkKHN0YXRlLmhpZ2hXYXRlck1hcmspO1xuICAgIHN0YXRlLnN5bmMgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIElmIF9yZWFkIGNhbGxlZCBpdHMgY2FsbGJhY2sgc3luY2hyb25vdXNseSwgdGhlbiBgcmVhZGluZ2BcbiAgLy8gd2lsbCBiZSBmYWxzZSwgYW5kIHdlIG5lZWQgdG8gcmUtZXZhbHVhdGUgaG93IG11Y2ggZGF0YSB3ZVxuICAvLyBjYW4gcmV0dXJuIHRvIHRoZSB1c2VyLlxuICBpZiAoZG9SZWFkICYmICFzdGF0ZS5yZWFkaW5nKVxuICAgIG4gPSBob3dNdWNoVG9SZWFkKG5PcmlnLCBzdGF0ZSk7XG5cbiAgdmFyIHJldDtcbiAgaWYgKG4gPiAwKVxuICAgIHJldCA9IGZyb21MaXN0KG4sIHN0YXRlKTtcbiAgZWxzZVxuICAgIHJldCA9IG51bGw7XG5cbiAgaWYgKHJldCA9PT0gbnVsbCkge1xuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgbiA9IDA7XG4gIH1cblxuICBzdGF0ZS5sZW5ndGggLT0gbjtcblxuICAvLyBJZiB3ZSBoYXZlIG5vdGhpbmcgaW4gdGhlIGJ1ZmZlciwgdGhlbiB3ZSB3YW50IHRvIGtub3dcbiAgLy8gYXMgc29vbiBhcyB3ZSAqZG8qIGdldCBzb21ldGhpbmcgaW50byB0aGUgYnVmZmVyLlxuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmICFzdGF0ZS5lbmRlZClcbiAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIElmIHdlIGhhcHBlbmVkIHRvIHJlYWQoKSBleGFjdGx5IHRoZSByZW1haW5pbmcgYW1vdW50IGluIHRoZVxuICAvLyBidWZmZXIsIGFuZCB0aGUgRU9GIGhhcyBiZWVuIHNlZW4gYXQgdGhpcyBwb2ludCwgdGhlbiBtYWtlIHN1cmVcbiAgLy8gdGhhdCB3ZSBlbWl0ICdlbmQnIG9uIHRoZSB2ZXJ5IG5leHQgdGljay5cbiAgaWYgKHN0YXRlLmVuZGVkICYmICFzdGF0ZS5lbmRFbWl0dGVkICYmIHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICBlbmRSZWFkYWJsZSh0aGlzKTtcblxuICByZXR1cm4gcmV0O1xufTtcblxuZnVuY3Rpb24gY2h1bmtJbnZhbGlkKHN0YXRlLCBjaHVuaykge1xuICB2YXIgZXIgPSBudWxsO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiZcbiAgICAgICdzdHJpbmcnICE9PSB0eXBlb2YgY2h1bmsgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSAmJlxuICAgICAgIWVyKSB7XG4gICAgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gIH1cbiAgcmV0dXJuIGVyO1xufVxuXG5cbmZ1bmN0aW9uIG9uRW9mQ2h1bmsoc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUuZGVjb2RlciAmJiAhc3RhdGUuZW5kZWQpIHtcbiAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpIHtcbiAgICAgIHN0YXRlLmJ1ZmZlci5wdXNoKGNodW5rKTtcbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICB9XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkIGFuZCB3ZSBoYXZlIHNvbWUgZGF0YSBsZWZ0LCB0aGVuIGVtaXRcbiAgLy8gJ3JlYWRhYmxlJyBub3cgdG8gbWFrZSBzdXJlIGl0IGdldHMgcGlja2VkIHVwLlxuICBpZiAoc3RhdGUubGVuZ3RoID4gMClcbiAgICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcbiAgZWxzZVxuICAgIGVuZFJlYWRhYmxlKHN0cmVhbSk7XG59XG5cbi8vIERvbid0IGVtaXQgcmVhZGFibGUgcmlnaHQgYXdheSBpbiBzeW5jIG1vZGUsIGJlY2F1c2UgdGhpcyBjYW4gdHJpZ2dlclxuLy8gYW5vdGhlciByZWFkKCkgY2FsbCA9PiBzdGFjayBvdmVyZmxvdy4gIFRoaXMgd2F5LCBpdCBtaWdodCB0cmlnZ2VyXG4vLyBhIG5leHRUaWNrIHJlY3Vyc2lvbiB3YXJuaW5nLCBidXQgdGhhdCdzIG5vdCBzbyBiYWQuXG5mdW5jdGlvbiBlbWl0UmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgc3RhdGUubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIGlmIChzdGF0ZS5lbWl0dGVkUmVhZGFibGUpXG4gICAgcmV0dXJuO1xuXG4gIHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSA9IHRydWU7XG4gIGlmIChzdGF0ZS5zeW5jKVxuICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG4gICAgfSk7XG4gIGVsc2VcbiAgICBlbWl0UmVhZGFibGVfKHN0cmVhbSk7XG59XG5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZV8oc3RyZWFtKSB7XG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xufVxuXG5cbi8vIGF0IHRoaXMgcG9pbnQsIHRoZSB1c2VyIGhhcyBwcmVzdW1hYmx5IHNlZW4gdGhlICdyZWFkYWJsZScgZXZlbnQsXG4vLyBhbmQgY2FsbGVkIHJlYWQoKSB0byBjb25zdW1lIHNvbWUgZGF0YS4gIHRoYXQgbWF5IGhhdmUgdHJpZ2dlcmVkXG4vLyBpbiB0dXJuIGFub3RoZXIgX3JlYWQobikgY2FsbCwgaW4gd2hpY2ggY2FzZSByZWFkaW5nID0gdHJ1ZSBpZlxuLy8gaXQncyBpbiBwcm9ncmVzcy5cbi8vIEhvd2V2ZXIsIGlmIHdlJ3JlIG5vdCBlbmRlZCwgb3IgcmVhZGluZywgYW5kIHRoZSBsZW5ndGggPCBod20sXG4vLyB0aGVuIGdvIGFoZWFkIGFuZCB0cnkgdG8gcmVhZCBzb21lIG1vcmUgcHJlZW1wdGl2ZWx5LlxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKSB7XG4gIGlmICghc3RhdGUucmVhZGluZ01vcmUpIHtcbiAgICBzdGF0ZS5yZWFkaW5nTW9yZSA9IHRydWU7XG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIG1heWJlUmVhZE1vcmVfKHN0cmVhbSwgc3RhdGUpO1xuICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1heWJlUmVhZE1vcmVfKHN0cmVhbSwgc3RhdGUpIHtcbiAgdmFyIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgd2hpbGUgKCFzdGF0ZS5yZWFkaW5nICYmICFzdGF0ZS5mbG93aW5nICYmICFzdGF0ZS5lbmRlZCAmJlxuICAgICAgICAgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaykge1xuICAgIHN0cmVhbS5yZWFkKDApO1xuICAgIGlmIChsZW4gPT09IHN0YXRlLmxlbmd0aClcbiAgICAgIC8vIGRpZG4ndCBnZXQgYW55IGRhdGEsIHN0b3Agc3Bpbm5pbmcuXG4gICAgICBicmVhaztcbiAgICBlbHNlXG4gICAgICBsZW4gPSBzdGF0ZS5sZW5ndGg7XG4gIH1cbiAgc3RhdGUucmVhZGluZ01vcmUgPSBmYWxzZTtcbn1cblxuLy8gYWJzdHJhY3QgbWV0aG9kLiAgdG8gYmUgb3ZlcnJpZGRlbiBpbiBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbiBjbGFzc2VzLlxuLy8gY2FsbCBjYihlciwgZGF0YSkgd2hlcmUgZGF0YSBpcyA8PSBuIGluIGxlbmd0aC5cbi8vIGZvciB2aXJ0dWFsIChub24tc3RyaW5nLCBub24tYnVmZmVyKSBzdHJlYW1zLCBcImxlbmd0aFwiIGlzIHNvbWV3aGF0XG4vLyBhcmJpdHJhcnksIGFuZCBwZXJoYXBzIG5vdCB2ZXJ5IG1lYW5pbmdmdWwuXG5SZWFkYWJsZS5wcm90b3R5cGUuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgcGlwZU9wdHMpIHtcbiAgdmFyIHNyYyA9IHRoaXM7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG5cbiAgc3dpdGNoIChzdGF0ZS5waXBlc0NvdW50KSB7XG4gICAgY2FzZSAwOlxuICAgICAgc3RhdGUucGlwZXMgPSBkZXN0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxOlxuICAgICAgc3RhdGUucGlwZXMgPSBbc3RhdGUucGlwZXMsIGRlc3RdO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHN0YXRlLnBpcGVzLnB1c2goZGVzdCk7XG4gICAgICBicmVhaztcbiAgfVxuICBzdGF0ZS5waXBlc0NvdW50ICs9IDE7XG5cbiAgdmFyIGRvRW5kID0gKCFwaXBlT3B0cyB8fCBwaXBlT3B0cy5lbmQgIT09IGZhbHNlKSAmJlxuICAgICAgICAgICAgICBkZXN0ICE9PSBwcm9jZXNzLnN0ZG91dCAmJlxuICAgICAgICAgICAgICBkZXN0ICE9PSBwcm9jZXNzLnN0ZGVycjtcblxuICB2YXIgZW5kRm4gPSBkb0VuZCA/IG9uZW5kIDogY2xlYW51cDtcbiAgaWYgKHN0YXRlLmVuZEVtaXR0ZWQpXG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShlbmRGbik7XG4gIGVsc2VcbiAgICBzcmMub25jZSgnZW5kJywgZW5kRm4pO1xuXG4gIGRlc3Qub24oJ3VucGlwZScsIG9udW5waXBlKTtcbiAgZnVuY3Rpb24gb251bnBpcGUocmVhZGFibGUpIHtcbiAgICBpZiAocmVhZGFibGUgIT09IHNyYykgcmV0dXJuO1xuICAgIGNsZWFudXAoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuICAvLyB3aGVuIHRoZSBkZXN0IGRyYWlucywgaXQgcmVkdWNlcyB0aGUgYXdhaXREcmFpbiBjb3VudGVyXG4gIC8vIG9uIHRoZSBzb3VyY2UuICBUaGlzIHdvdWxkIGJlIG1vcmUgZWxlZ2FudCB3aXRoIGEgLm9uY2UoKVxuICAvLyBoYW5kbGVyIGluIGZsb3coKSwgYnV0IGFkZGluZyBhbmQgcmVtb3ZpbmcgcmVwZWF0ZWRseSBpc1xuICAvLyB0b28gc2xvdy5cbiAgdmFyIG9uZHJhaW4gPSBwaXBlT25EcmFpbihzcmMpO1xuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIGZ1bmN0aW9uIGNsZWFudXAoKSB7XG4gICAgLy8gY2xlYW51cCBldmVudCBoYW5kbGVycyBvbmNlIHRoZSBwaXBlIGlzIGJyb2tlblxuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCd1bnBpcGUnLCBvbnVucGlwZSk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBvbmVuZCk7XG4gICAgc3JjLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcblxuICAgIC8vIGlmIHRoZSByZWFkZXIgaXMgd2FpdGluZyBmb3IgYSBkcmFpbiBldmVudCBmcm9tIHRoaXNcbiAgICAvLyBzcGVjaWZpYyB3cml0ZXIsIHRoZW4gaXQgd291bGQgY2F1c2UgaXQgdG8gbmV2ZXIgc3RhcnRcbiAgICAvLyBmbG93aW5nIGFnYWluLlxuICAgIC8vIFNvLCBpZiB0aGlzIGlzIGF3YWl0aW5nIGEgZHJhaW4sIHRoZW4gd2UganVzdCBjYWxsIGl0IG5vdy5cbiAgICAvLyBJZiB3ZSBkb24ndCBrbm93LCB0aGVuIGFzc3VtZSB0aGF0IHdlIGFyZSB3YWl0aW5nIGZvciBvbmUuXG4gICAgaWYgKCFkZXN0Ll93cml0YWJsZVN0YXRlIHx8IGRlc3QuX3dyaXRhYmxlU3RhdGUubmVlZERyYWluKVxuICAgICAgb25kcmFpbigpO1xuICB9XG5cbiAgLy8gaWYgdGhlIGRlc3QgaGFzIGFuIGVycm9yLCB0aGVuIHN0b3AgcGlwaW5nIGludG8gaXQuXG4gIC8vIGhvd2V2ZXIsIGRvbid0IHN1cHByZXNzIHRoZSB0aHJvd2luZyBiZWhhdmlvciBmb3IgdGhpcy5cbiAgLy8gY2hlY2sgZm9yIGxpc3RlbmVycyBiZWZvcmUgZW1pdCByZW1vdmVzIG9uZS10aW1lIGxpc3RlbmVycy5cbiAgdmFyIGVyckxpc3RlbmVycyA9IEVFLmxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJyk7XG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXIpIHtcbiAgICB1bnBpcGUoKTtcbiAgICBpZiAoZXJyTGlzdGVuZXJzID09PSAwICYmIEVFLmxpc3RlbmVyQ291bnQoZGVzdCwgJ2Vycm9yJykgPT09IDApXG4gICAgICBkZXN0LmVtaXQoJ2Vycm9yJywgZXIpO1xuICB9XG4gIGRlc3Qub25jZSgnZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyBCb3RoIGNsb3NlIGFuZCBmaW5pc2ggc2hvdWxkIHRyaWdnZXIgdW5waXBlLCBidXQgb25seSBvbmNlLlxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIGZ1bmN0aW9uIG9uZmluaXNoKCkge1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG4gICAgdW5waXBlKCk7XG4gIH1cbiAgZGVzdC5vbmNlKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG5cbiAgZnVuY3Rpb24gdW5waXBlKCkge1xuICAgIHNyYy51bnBpcGUoZGVzdCk7XG4gIH1cblxuICAvLyB0ZWxsIHRoZSBkZXN0IHRoYXQgaXQncyBiZWluZyBwaXBlZCB0b1xuICBkZXN0LmVtaXQoJ3BpcGUnLCBzcmMpO1xuXG4gIC8vIHN0YXJ0IHRoZSBmbG93IGlmIGl0IGhhc24ndCBiZWVuIHN0YXJ0ZWQgYWxyZWFkeS5cbiAgaWYgKCFzdGF0ZS5mbG93aW5nKSB7XG4gICAgLy8gdGhlIGhhbmRsZXIgdGhhdCB3YWl0cyBmb3IgcmVhZGFibGUgZXZlbnRzIGFmdGVyIGFsbFxuICAgIC8vIHRoZSBkYXRhIGdldHMgc3Vja2VkIG91dCBpbiBmbG93LlxuICAgIC8vIFRoaXMgd291bGQgYmUgZWFzaWVyIHRvIGZvbGxvdyB3aXRoIGEgLm9uY2UoKSBoYW5kbGVyXG4gICAgLy8gaW4gZmxvdygpLCBidXQgdGhhdCBpcyB0b28gc2xvdy5cbiAgICB0aGlzLm9uKCdyZWFkYWJsZScsIHBpcGVPblJlYWRhYmxlKTtcblxuICAgIHN0YXRlLmZsb3dpbmcgPSB0cnVlO1xuICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBmbG93KHNyYyk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gZGVzdDtcbn07XG5cbmZ1bmN0aW9uIHBpcGVPbkRyYWluKHNyYykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRlc3QgPSB0aGlzO1xuICAgIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgICBzdGF0ZS5hd2FpdERyYWluLS07XG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPT09IDApXG4gICAgICBmbG93KHNyYyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGZsb3coc3JjKSB7XG4gIHZhciBzdGF0ZSA9IHNyYy5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIGNodW5rO1xuICBzdGF0ZS5hd2FpdERyYWluID0gMDtcblxuICBmdW5jdGlvbiB3cml0ZShkZXN0LCBpLCBsaXN0KSB7XG4gICAgdmFyIHdyaXR0ZW4gPSBkZXN0LndyaXRlKGNodW5rKTtcbiAgICBpZiAoZmFsc2UgPT09IHdyaXR0ZW4pIHtcbiAgICAgIHN0YXRlLmF3YWl0RHJhaW4rKztcbiAgICB9XG4gIH1cblxuICB3aGlsZSAoc3RhdGUucGlwZXNDb3VudCAmJiBudWxsICE9PSAoY2h1bmsgPSBzcmMucmVhZCgpKSkge1xuXG4gICAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpXG4gICAgICB3cml0ZShzdGF0ZS5waXBlcywgMCwgbnVsbCk7XG4gICAgZWxzZVxuICAgICAgc2hpbXMuZm9yRWFjaChzdGF0ZS5waXBlcywgd3JpdGUpO1xuXG4gICAgc3JjLmVtaXQoJ2RhdGEnLCBjaHVuayk7XG5cbiAgICAvLyBpZiBhbnlvbmUgbmVlZHMgYSBkcmFpbiwgdGhlbiB3ZSBoYXZlIHRvIHdhaXQgZm9yIHRoYXQuXG4gICAgaWYgKHN0YXRlLmF3YWl0RHJhaW4gPiAwKVxuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gaWYgZXZlcnkgZGVzdGluYXRpb24gd2FzIHVucGlwZWQsIGVpdGhlciBiZWZvcmUgZW50ZXJpbmcgdGhpc1xuICAvLyBmdW5jdGlvbiwgb3IgaW4gdGhlIHdoaWxlIGxvb3AsIHRoZW4gc3RvcCBmbG93aW5nLlxuICAvL1xuICAvLyBOQjogVGhpcyBpcyBhIHByZXR0eSByYXJlIGVkZ2UgY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApIHtcbiAgICBzdGF0ZS5mbG93aW5nID0gZmFsc2U7XG5cbiAgICAvLyBpZiB0aGVyZSB3ZXJlIGRhdGEgZXZlbnQgbGlzdGVuZXJzIGFkZGVkLCB0aGVuIHN3aXRjaCB0byBvbGQgbW9kZS5cbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudChzcmMsICdkYXRhJykgPiAwKVxuICAgICAgZW1pdERhdGFFdmVudHMoc3JjKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBhdCB0aGlzIHBvaW50LCBubyBvbmUgbmVlZGVkIGEgZHJhaW4sIHNvIHdlIGp1c3QgcmFuIG91dCBvZiBkYXRhXG4gIC8vIG9uIHRoZSBuZXh0IHJlYWRhYmxlIGV2ZW50LCBzdGFydCBpdCBvdmVyIGFnYWluLlxuICBzdGF0ZS5yYW5PdXQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBwaXBlT25SZWFkYWJsZSgpIHtcbiAgaWYgKHRoaXMuX3JlYWRhYmxlU3RhdGUucmFuT3V0KSB7XG4gICAgdGhpcy5fcmVhZGFibGVTdGF0ZS5yYW5PdXQgPSBmYWxzZTtcbiAgICBmbG93KHRoaXMpO1xuICB9XG59XG5cblxuUmVhZGFibGUucHJvdG90eXBlLnVucGlwZSA9IGZ1bmN0aW9uKGRlc3QpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBpZiB3ZSdyZSBub3QgcGlwaW5nIGFueXdoZXJlLCB0aGVuIGRvIG5vdGhpbmcuXG4gIGlmIChzdGF0ZS5waXBlc0NvdW50ID09PSAwKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIGp1c3Qgb25lIGRlc3RpbmF0aW9uLiAgbW9zdCBjb21tb24gY2FzZS5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpIHtcbiAgICAvLyBwYXNzZWQgaW4gb25lLCBidXQgaXQncyBub3QgdGhlIHJpZ2h0IG9uZS5cbiAgICBpZiAoZGVzdCAmJiBkZXN0ICE9PSBzdGF0ZS5waXBlcylcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFkZXN0KVxuICAgICAgZGVzdCA9IHN0YXRlLnBpcGVzO1xuXG4gICAgLy8gZ290IGEgbWF0Y2guXG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcGlwZU9uUmVhZGFibGUpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcbiAgICBpZiAoZGVzdClcbiAgICAgIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzbG93IGNhc2UuIG11bHRpcGxlIHBpcGUgZGVzdGluYXRpb25zLlxuXG4gIGlmICghZGVzdCkge1xuICAgIC8vIHJlbW92ZSBhbGwuXG4gICAgdmFyIGRlc3RzID0gc3RhdGUucGlwZXM7XG4gICAgdmFyIGxlbiA9IHN0YXRlLnBpcGVzQ291bnQ7XG4gICAgc3RhdGUucGlwZXMgPSBudWxsO1xuICAgIHN0YXRlLnBpcGVzQ291bnQgPSAwO1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcGlwZU9uUmVhZGFibGUpO1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspXG4gICAgICBkZXN0c1tpXS5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHRyeSB0byBmaW5kIHRoZSByaWdodCBvbmUuXG4gIHZhciBpID0gc2hpbXMuaW5kZXhPZihzdGF0ZS5waXBlcywgZGVzdCk7XG4gIGlmIChpID09PSAtMSlcbiAgICByZXR1cm4gdGhpcztcblxuICBzdGF0ZS5waXBlcy5zcGxpY2UoaSwgMSk7XG4gIHN0YXRlLnBpcGVzQ291bnQgLT0gMTtcbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDEpXG4gICAgc3RhdGUucGlwZXMgPSBzdGF0ZS5waXBlc1swXTtcblxuICBkZXN0LmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gc2V0IHVwIGRhdGEgZXZlbnRzIGlmIHRoZXkgYXJlIGFza2VkIGZvclxuLy8gRW5zdXJlIHJlYWRhYmxlIGxpc3RlbmVycyBldmVudHVhbGx5IGdldCBzb21ldGhpbmdcblJlYWRhYmxlLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKGV2LCBmbikge1xuICB2YXIgcmVzID0gU3RyZWFtLnByb3RvdHlwZS5vbi5jYWxsKHRoaXMsIGV2LCBmbik7XG5cbiAgaWYgKGV2ID09PSAnZGF0YScgJiYgIXRoaXMuX3JlYWRhYmxlU3RhdGUuZmxvd2luZylcbiAgICBlbWl0RGF0YUV2ZW50cyh0aGlzKTtcblxuICBpZiAoZXYgPT09ICdyZWFkYWJsZScgJiYgdGhpcy5yZWFkYWJsZSkge1xuICAgIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKCFzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZykge1xuICAgICAgc3RhdGUucmVhZGFibGVMaXN0ZW5pbmcgPSB0cnVlO1xuICAgICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgICAgaWYgKCFzdGF0ZS5yZWFkaW5nKSB7XG4gICAgICAgIHRoaXMucmVhZCgwKTtcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGUubGVuZ3RoKSB7XG4gICAgICAgIGVtaXRSZWFkYWJsZSh0aGlzLCBzdGF0ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn07XG5SZWFkYWJsZS5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBSZWFkYWJsZS5wcm90b3R5cGUub247XG5cbi8vIHBhdXNlKCkgYW5kIHJlc3VtZSgpIGFyZSByZW1uYW50cyBvZiB0aGUgbGVnYWN5IHJlYWRhYmxlIHN0cmVhbSBBUElcbi8vIElmIHRoZSB1c2VyIHVzZXMgdGhlbSwgdGhlbiBzd2l0Y2ggaW50byBvbGQgbW9kZS5cblJlYWRhYmxlLnByb3RvdHlwZS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgZW1pdERhdGFFdmVudHModGhpcyk7XG4gIHRoaXMucmVhZCgwKTtcbiAgdGhpcy5lbWl0KCdyZXN1bWUnKTtcbn07XG5cblJlYWRhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICBlbWl0RGF0YUV2ZW50cyh0aGlzLCB0cnVlKTtcbiAgdGhpcy5lbWl0KCdwYXVzZScpO1xufTtcblxuZnVuY3Rpb24gZW1pdERhdGFFdmVudHMoc3RyZWFtLCBzdGFydFBhdXNlZCkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgaWYgKHN0YXRlLmZsb3dpbmcpIHtcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vaXNhYWNzL3JlYWRhYmxlLXN0cmVhbS9pc3N1ZXMvMTZcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBzd2l0Y2ggdG8gb2xkIG1vZGUgbm93LicpO1xuICB9XG5cbiAgdmFyIHBhdXNlZCA9IHN0YXJ0UGF1c2VkIHx8IGZhbHNlO1xuICB2YXIgcmVhZGFibGUgPSBmYWxzZTtcblxuICAvLyBjb252ZXJ0IHRvIGFuIG9sZC1zdHlsZSBzdHJlYW0uXG4gIHN0cmVhbS5yZWFkYWJsZSA9IHRydWU7XG4gIHN0cmVhbS5waXBlID0gU3RyZWFtLnByb3RvdHlwZS5waXBlO1xuICBzdHJlYW0ub24gPSBzdHJlYW0uYWRkTGlzdGVuZXIgPSBTdHJlYW0ucHJvdG90eXBlLm9uO1xuXG4gIHN0cmVhbS5vbigncmVhZGFibGUnLCBmdW5jdGlvbigpIHtcbiAgICByZWFkYWJsZSA9IHRydWU7XG5cbiAgICB2YXIgYztcbiAgICB3aGlsZSAoIXBhdXNlZCAmJiAobnVsbCAhPT0gKGMgPSBzdHJlYW0ucmVhZCgpKSkpXG4gICAgICBzdHJlYW0uZW1pdCgnZGF0YScsIGMpO1xuXG4gICAgaWYgKGMgPT09IG51bGwpIHtcbiAgICAgIHJlYWRhYmxlID0gZmFsc2U7XG4gICAgICBzdHJlYW0uX3JlYWRhYmxlU3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIHN0cmVhbS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgIHBhdXNlZCA9IHRydWU7XG4gICAgdGhpcy5lbWl0KCdwYXVzZScpO1xuICB9O1xuXG4gIHN0cmVhbS5yZXN1bWUgPSBmdW5jdGlvbigpIHtcbiAgICBwYXVzZWQgPSBmYWxzZTtcbiAgICBpZiAocmVhZGFibGUpXG4gICAgICB0aW1lcnMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgICBzdHJlYW0uZW1pdCgncmVhZGFibGUnKTtcbiAgICAgIH0pO1xuICAgIGVsc2VcbiAgICAgIHRoaXMucmVhZCgwKTtcbiAgICB0aGlzLmVtaXQoJ3Jlc3VtZScpO1xuICB9O1xuXG4gIC8vIG5vdyBtYWtlIGl0IHN0YXJ0LCBqdXN0IGluIGNhc2UgaXQgaGFkbid0IGFscmVhZHkuXG4gIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xufVxuXG4vLyB3cmFwIGFuIG9sZC1zdHlsZSBzdHJlYW0gYXMgdGhlIGFzeW5jIGRhdGEgc291cmNlLlxuLy8gVGhpcyBpcyAqbm90KiBwYXJ0IG9mIHRoZSByZWFkYWJsZSBzdHJlYW0gaW50ZXJmYWNlLlxuLy8gSXQgaXMgYW4gdWdseSB1bmZvcnR1bmF0ZSBtZXNzIG9mIGhpc3RvcnkuXG5SZWFkYWJsZS5wcm90b3R5cGUud3JhcCA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgcGF1c2VkID0gZmFsc2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBzdHJlYW0ub24oJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFzdGF0ZS5lbmRlZCkge1xuICAgICAgdmFyIGNodW5rID0gc3RhdGUuZGVjb2Rlci5lbmQoKTtcbiAgICAgIGlmIChjaHVuayAmJiBjaHVuay5sZW5ndGgpXG4gICAgICAgIHNlbGYucHVzaChjaHVuayk7XG4gICAgfVxuXG4gICAgc2VsZi5wdXNoKG51bGwpO1xuICB9KTtcblxuICBzdHJlYW0ub24oJ2RhdGEnLCBmdW5jdGlvbihjaHVuaykge1xuICAgIGlmIChzdGF0ZS5kZWNvZGVyKVxuICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcbiAgICBpZiAoIWNodW5rIHx8ICFzdGF0ZS5vYmplY3RNb2RlICYmICFjaHVuay5sZW5ndGgpXG4gICAgICByZXR1cm47XG5cbiAgICB2YXIgcmV0ID0gc2VsZi5wdXNoKGNodW5rKTtcbiAgICBpZiAoIXJldCkge1xuICAgICAgcGF1c2VkID0gdHJ1ZTtcbiAgICAgIHN0cmVhbS5wYXVzZSgpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcHJveHkgYWxsIHRoZSBvdGhlciBtZXRob2RzLlxuICAvLyBpbXBvcnRhbnQgd2hlbiB3cmFwcGluZyBmaWx0ZXJzIGFuZCBkdXBsZXhlcy5cbiAgZm9yICh2YXIgaSBpbiBzdHJlYW0pIHtcbiAgICBpZiAodHlwZW9mIHN0cmVhbVtpXSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICB0eXBlb2YgdGhpc1tpXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXNbaV0gPSBmdW5jdGlvbihtZXRob2QpIHsgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gc3RyZWFtW21ldGhvZF0uYXBwbHkoc3RyZWFtLCBhcmd1bWVudHMpO1xuICAgICAgfX0oaSk7XG4gICAgfVxuICB9XG5cbiAgLy8gcHJveHkgY2VydGFpbiBpbXBvcnRhbnQgZXZlbnRzLlxuICB2YXIgZXZlbnRzID0gWydlcnJvcicsICdjbG9zZScsICdkZXN0cm95JywgJ3BhdXNlJywgJ3Jlc3VtZSddO1xuICBzaGltcy5mb3JFYWNoKGV2ZW50cywgZnVuY3Rpb24oZXYpIHtcbiAgICBzdHJlYW0ub24oZXYsIHNoaW1zLmJpbmQoc2VsZi5lbWl0LCBzZWxmLCBldikpO1xuICB9KTtcblxuICAvLyB3aGVuIHdlIHRyeSB0byBjb25zdW1lIHNvbWUgbW9yZSBieXRlcywgc2ltcGx5IHVucGF1c2UgdGhlXG4gIC8vIHVuZGVybHlpbmcgc3RyZWFtLlxuICBzZWxmLl9yZWFkID0gZnVuY3Rpb24obikge1xuICAgIGlmIChwYXVzZWQpIHtcbiAgICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgICAgc3RyZWFtLnJlc3VtZSgpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cblxuXG4vLyBleHBvc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzIG9ubHkuXG5SZWFkYWJsZS5fZnJvbUxpc3QgPSBmcm9tTGlzdDtcblxuLy8gUGx1Y2sgb2ZmIG4gYnl0ZXMgZnJvbSBhbiBhcnJheSBvZiBidWZmZXJzLlxuLy8gTGVuZ3RoIGlzIHRoZSBjb21iaW5lZCBsZW5ndGhzIG9mIGFsbCB0aGUgYnVmZmVycyBpbiB0aGUgbGlzdC5cbmZ1bmN0aW9uIGZyb21MaXN0KG4sIHN0YXRlKSB7XG4gIHZhciBsaXN0ID0gc3RhdGUuYnVmZmVyO1xuICB2YXIgbGVuZ3RoID0gc3RhdGUubGVuZ3RoO1xuICB2YXIgc3RyaW5nTW9kZSA9ICEhc3RhdGUuZGVjb2RlcjtcbiAgdmFyIG9iamVjdE1vZGUgPSAhIXN0YXRlLm9iamVjdE1vZGU7XG4gIHZhciByZXQ7XG5cbiAgLy8gbm90aGluZyBpbiB0aGUgbGlzdCwgZGVmaW5pdGVseSBlbXB0eS5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKVxuICAgIHJldHVybiBudWxsO1xuXG4gIGlmIChsZW5ndGggPT09IDApXG4gICAgcmV0ID0gbnVsbDtcbiAgZWxzZSBpZiAob2JqZWN0TW9kZSlcbiAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gIGVsc2UgaWYgKCFuIHx8IG4gPj0gbGVuZ3RoKSB7XG4gICAgLy8gcmVhZCBpdCBhbGwsIHRydW5jYXRlIHRoZSBhcnJheS5cbiAgICBpZiAoc3RyaW5nTW9kZSlcbiAgICAgIHJldCA9IGxpc3Quam9pbignJyk7XG4gICAgZWxzZVxuICAgICAgcmV0ID0gQnVmZmVyLmNvbmNhdChsaXN0LCBsZW5ndGgpO1xuICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgfSBlbHNlIHtcbiAgICAvLyByZWFkIGp1c3Qgc29tZSBvZiBpdC5cbiAgICBpZiAobiA8IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBqdXN0IHRha2UgYSBwYXJ0IG9mIHRoZSBmaXJzdCBsaXN0IGl0ZW0uXG4gICAgICAvLyBzbGljZSBpcyB0aGUgc2FtZSBmb3IgYnVmZmVycyBhbmQgc3RyaW5ncy5cbiAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgcmV0ID0gYnVmLnNsaWNlKDAsIG4pO1xuICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShuKTtcbiAgICB9IGVsc2UgaWYgKG4gPT09IGxpc3RbMF0ubGVuZ3RoKSB7XG4gICAgICAvLyBmaXJzdCBsaXN0IGlzIGEgcGVyZmVjdCBtYXRjaFxuICAgICAgcmV0ID0gbGlzdC5zaGlmdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjb21wbGV4IGNhc2UuXG4gICAgICAvLyB3ZSBoYXZlIGVub3VnaCB0byBjb3ZlciBpdCwgYnV0IGl0IHNwYW5zIHBhc3QgdGhlIGZpcnN0IGJ1ZmZlci5cbiAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICByZXQgPSAnJztcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0ID0gbmV3IEJ1ZmZlcihuKTtcblxuICAgICAgdmFyIGMgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0Lmxlbmd0aDsgaSA8IGwgJiYgYyA8IG47IGkrKykge1xuICAgICAgICB2YXIgYnVmID0gbGlzdFswXTtcbiAgICAgICAgdmFyIGNweSA9IE1hdGgubWluKG4gLSBjLCBidWYubGVuZ3RoKTtcblxuICAgICAgICBpZiAoc3RyaW5nTW9kZSlcbiAgICAgICAgICByZXQgKz0gYnVmLnNsaWNlKDAsIGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBidWYuY29weShyZXQsIGMsIDAsIGNweSk7XG5cbiAgICAgICAgaWYgKGNweSA8IGJ1Zi5sZW5ndGgpXG4gICAgICAgICAgbGlzdFswXSA9IGJ1Zi5zbGljZShjcHkpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuXG4gICAgICAgIGMgKz0gY3B5O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGVuZFJlYWRhYmxlKHN0cmVhbSkge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgYmVmb3JlIGNvbnN1bWluZyBhbGwgdGhlIGJ5dGVzLCB0aGVuIHRoYXQgaXMgYVxuICAvLyBidWcgaW4gbm9kZS4gIFNob3VsZCBuZXZlciBoYXBwZW4uXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKVxuICAgIHRocm93IG5ldyBFcnJvcignZW5kUmVhZGFibGUgY2FsbGVkIG9uIG5vbi1lbXB0eSBzdHJlYW0nKTtcblxuICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUuY2FsbGVkUmVhZCkge1xuICAgIHN0YXRlLmVuZGVkID0gdHJ1ZTtcbiAgICB0aW1lcnMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgLy8gQ2hlY2sgdGhhdCB3ZSBkaWRuJ3QgZ2V0IG9uZSBsYXN0IHVuc2hpZnQuXG4gICAgICBpZiAoIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHN0YXRlLmVuZEVtaXR0ZWQgPSB0cnVlO1xuICAgICAgICBzdHJlYW0ucmVhZGFibGUgPSBmYWxzZTtcbiAgICAgICAgc3RyZWFtLmVtaXQoJ2VuZCcpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSB0cmFuc2Zvcm0gc3RyZWFtIGlzIGEgcmVhZGFibGUvd3JpdGFibGUgc3RyZWFtIHdoZXJlIHlvdSBkb1xuLy8gc29tZXRoaW5nIHdpdGggdGhlIGRhdGEuICBTb21ldGltZXMgaXQncyBjYWxsZWQgYSBcImZpbHRlclwiLFxuLy8gYnV0IHRoYXQncyBub3QgYSBncmVhdCBuYW1lIGZvciBpdCwgc2luY2UgdGhhdCBpbXBsaWVzIGEgdGhpbmcgd2hlcmVcbi8vIHNvbWUgYml0cyBwYXNzIHRocm91Z2gsIGFuZCBvdGhlcnMgYXJlIHNpbXBseSBpZ25vcmVkLiAgKFRoYXQgd291bGRcbi8vIGJlIGEgdmFsaWQgZXhhbXBsZSBvZiBhIHRyYW5zZm9ybSwgb2YgY291cnNlLilcbi8vXG4vLyBXaGlsZSB0aGUgb3V0cHV0IGlzIGNhdXNhbGx5IHJlbGF0ZWQgdG8gdGhlIGlucHV0LCBpdCdzIG5vdCBhXG4vLyBuZWNlc3NhcmlseSBzeW1tZXRyaWMgb3Igc3luY2hyb25vdXMgdHJhbnNmb3JtYXRpb24uICBGb3IgZXhhbXBsZSxcbi8vIGEgemxpYiBzdHJlYW0gbWlnaHQgdGFrZSBtdWx0aXBsZSBwbGFpbi10ZXh0IHdyaXRlcygpLCBhbmQgdGhlblxuLy8gZW1pdCBhIHNpbmdsZSBjb21wcmVzc2VkIGNodW5rIHNvbWUgdGltZSBpbiB0aGUgZnV0dXJlLlxuLy9cbi8vIEhlcmUncyBob3cgdGhpcyB3b3Jrczpcbi8vXG4vLyBUaGUgVHJhbnNmb3JtIHN0cmVhbSBoYXMgYWxsIHRoZSBhc3BlY3RzIG9mIHRoZSByZWFkYWJsZSBhbmQgd3JpdGFibGVcbi8vIHN0cmVhbSBjbGFzc2VzLiAgV2hlbiB5b3Ugd3JpdGUoY2h1bmspLCB0aGF0IGNhbGxzIF93cml0ZShjaHVuayxjYilcbi8vIGludGVybmFsbHksIGFuZCByZXR1cm5zIGZhbHNlIGlmIHRoZXJlJ3MgYSBsb3Qgb2YgcGVuZGluZyB3cml0ZXNcbi8vIGJ1ZmZlcmVkIHVwLiAgV2hlbiB5b3UgY2FsbCByZWFkKCksIHRoYXQgY2FsbHMgX3JlYWQobikgdW50aWxcbi8vIHRoZXJlJ3MgZW5vdWdoIHBlbmRpbmcgcmVhZGFibGUgZGF0YSBidWZmZXJlZCB1cC5cbi8vXG4vLyBJbiBhIHRyYW5zZm9ybSBzdHJlYW0sIHRoZSB3cml0dGVuIGRhdGEgaXMgcGxhY2VkIGluIGEgYnVmZmVyLiAgV2hlblxuLy8gX3JlYWQobikgaXMgY2FsbGVkLCBpdCB0cmFuc2Zvcm1zIHRoZSBxdWV1ZWQgdXAgZGF0YSwgY2FsbGluZyB0aGVcbi8vIGJ1ZmZlcmVkIF93cml0ZSBjYidzIGFzIGl0IGNvbnN1bWVzIGNodW5rcy4gIElmIGNvbnN1bWluZyBhIHNpbmdsZVxuLy8gd3JpdHRlbiBjaHVuayB3b3VsZCByZXN1bHQgaW4gbXVsdGlwbGUgb3V0cHV0IGNodW5rcywgdGhlbiB0aGUgZmlyc3Rcbi8vIG91dHB1dHRlZCBiaXQgY2FsbHMgdGhlIHJlYWRjYiwgYW5kIHN1YnNlcXVlbnQgY2h1bmtzIGp1c3QgZ28gaW50b1xuLy8gdGhlIHJlYWQgYnVmZmVyLCBhbmQgd2lsbCBjYXVzZSBpdCB0byBlbWl0ICdyZWFkYWJsZScgaWYgbmVjZXNzYXJ5LlxuLy9cbi8vIFRoaXMgd2F5LCBiYWNrLXByZXNzdXJlIGlzIGFjdHVhbGx5IGRldGVybWluZWQgYnkgdGhlIHJlYWRpbmcgc2lkZSxcbi8vIHNpbmNlIF9yZWFkIGhhcyB0byBiZSBjYWxsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZyBhIG5ldyBjaHVuay4gIEhvd2V2ZXIsXG4vLyBhIHBhdGhvbG9naWNhbCBpbmZsYXRlIHR5cGUgb2YgdHJhbnNmb3JtIGNhbiBjYXVzZSBleGNlc3NpdmUgYnVmZmVyaW5nXG4vLyBoZXJlLiAgRm9yIGV4YW1wbGUsIGltYWdpbmUgYSBzdHJlYW0gd2hlcmUgZXZlcnkgYnl0ZSBvZiBpbnB1dCBpc1xuLy8gaW50ZXJwcmV0ZWQgYXMgYW4gaW50ZWdlciBmcm9tIDAtMjU1LCBhbmQgdGhlbiByZXN1bHRzIGluIHRoYXQgbWFueVxuLy8gYnl0ZXMgb2Ygb3V0cHV0LiAgV3JpdGluZyB0aGUgNCBieXRlcyB7ZmYsZmYsZmYsZmZ9IHdvdWxkIHJlc3VsdCBpblxuLy8gMWtiIG9mIGRhdGEgYmVpbmcgb3V0cHV0LiAgSW4gdGhpcyBjYXNlLCB5b3UgY291bGQgd3JpdGUgYSB2ZXJ5IHNtYWxsXG4vLyBhbW91bnQgb2YgaW5wdXQsIGFuZCBlbmQgdXAgd2l0aCBhIHZlcnkgbGFyZ2UgYW1vdW50IG9mIG91dHB1dC4gIEluXG4vLyBzdWNoIGEgcGF0aG9sb2dpY2FsIGluZmxhdGluZyBtZWNoYW5pc20sIHRoZXJlJ2QgYmUgbm8gd2F5IHRvIHRlbGxcbi8vIHRoZSBzeXN0ZW0gdG8gc3RvcCBkb2luZyB0aGUgdHJhbnNmb3JtLiAgQSBzaW5nbGUgNE1CIHdyaXRlIGNvdWxkXG4vLyBjYXVzZSB0aGUgc3lzdGVtIHRvIHJ1biBvdXQgb2YgbWVtb3J5LlxuLy9cbi8vIEhvd2V2ZXIsIGV2ZW4gaW4gc3VjaCBhIHBhdGhvbG9naWNhbCBjYXNlLCBvbmx5IGEgc2luZ2xlIHdyaXR0ZW4gY2h1bmtcbi8vIHdvdWxkIGJlIGNvbnN1bWVkLCBhbmQgdGhlbiB0aGUgcmVzdCB3b3VsZCB3YWl0ICh1bi10cmFuc2Zvcm1lZCkgdW50aWxcbi8vIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm1lZCBjaHVuayB3ZXJlIGNvbnN1bWVkLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zZm9ybTtcblxudmFyIER1cGxleCA9IHJlcXVpcmUoJ19zdHJlYW1fZHVwbGV4Jyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnV0aWwuaW5oZXJpdHMoVHJhbnNmb3JtLCBEdXBsZXgpO1xuXG5cbmZ1bmN0aW9uIFRyYW5zZm9ybVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICB0aGlzLmFmdGVyVHJhbnNmb3JtID0gZnVuY3Rpb24oZXIsIGRhdGEpIHtcbiAgICByZXR1cm4gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSk7XG4gIH07XG5cbiAgdGhpcy5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHRoaXMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG4gIHRoaXMud3JpdGVjaHVuayA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGFmdGVyVHJhbnNmb3JtKHN0cmVhbSwgZXIsIGRhdGEpIHtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMudHJhbnNmb3JtaW5nID0gZmFsc2U7XG5cbiAgdmFyIGNiID0gdHMud3JpdGVjYjtcblxuICBpZiAoIWNiKVxuICAgIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBuZXcgRXJyb3IoJ25vIHdyaXRlY2IgaW4gVHJhbnNmb3JtIGNsYXNzJykpO1xuXG4gIHRzLndyaXRlY2h1bmsgPSBudWxsO1xuICB0cy53cml0ZWNiID0gbnVsbDtcblxuICBpZiAoZGF0YSAhPT0gbnVsbCAmJiBkYXRhICE9PSB1bmRlZmluZWQpXG4gICAgc3RyZWFtLnB1c2goZGF0YSk7XG5cbiAgaWYgKGNiKVxuICAgIGNiKGVyKTtcblxuICB2YXIgcnMgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHJzLnJlYWRpbmcgPSBmYWxzZTtcbiAgaWYgKHJzLm5lZWRSZWFkYWJsZSB8fCBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgc3RyZWFtLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59XG5cblxuZnVuY3Rpb24gVHJhbnNmb3JtKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFRyYW5zZm9ybSkpXG4gICAgcmV0dXJuIG5ldyBUcmFuc2Zvcm0ob3B0aW9ucyk7XG5cbiAgRHVwbGV4LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGUgPSBuZXcgVHJhbnNmb3JtU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gd2hlbiB0aGUgd3JpdGFibGUgc2lkZSBmaW5pc2hlcywgdGhlbiBmbHVzaCBvdXQgYW55dGhpbmcgcmVtYWluaW5nLlxuICB2YXIgc3RyZWFtID0gdGhpcztcblxuICAvLyBzdGFydCBvdXQgYXNraW5nIGZvciBhIHJlYWRhYmxlIGV2ZW50IG9uY2UgZGF0YSBpcyB0cmFuc2Zvcm1lZC5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuXG4gIC8vIHdlIGhhdmUgaW1wbGVtZW50ZWQgdGhlIF9yZWFkIG1ldGhvZCwgYW5kIGRvbmUgdGhlIG90aGVyIHRoaW5nc1xuICAvLyB0aGF0IFJlYWRhYmxlIHdhbnRzIGJlZm9yZSB0aGUgZmlyc3QgX3JlYWQgY2FsbCwgc28gdW5zZXQgdGhlXG4gIC8vIHN5bmMgZ3VhcmQgZmxhZy5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZS5zeW5jID0gZmFsc2U7XG5cbiAgdGhpcy5vbmNlKCdmaW5pc2gnLCBmdW5jdGlvbigpIHtcbiAgICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHRoaXMuX2ZsdXNoKVxuICAgICAgdGhpcy5fZmx1c2goZnVuY3Rpb24oZXIpIHtcbiAgICAgICAgZG9uZShzdHJlYW0sIGVyKTtcbiAgICAgIH0pO1xuICAgIGVsc2VcbiAgICAgIGRvbmUoc3RyZWFtKTtcbiAgfSk7XG59XG5cblRyYW5zZm9ybS5wcm90b3R5cGUucHVzaCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZykge1xuICB0aGlzLl90cmFuc2Zvcm1TdGF0ZS5uZWVkVHJhbnNmb3JtID0gZmFsc2U7XG4gIHJldHVybiBEdXBsZXgucHJvdG90eXBlLnB1c2guY2FsbCh0aGlzLCBjaHVuaywgZW5jb2RpbmcpO1xufTtcblxuLy8gVGhpcyBpcyB0aGUgcGFydCB3aGVyZSB5b3UgZG8gc3R1ZmYhXG4vLyBvdmVycmlkZSB0aGlzIGZ1bmN0aW9uIGluIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyAnY2h1bmsnIGlzIGFuIGlucHV0IGNodW5rLlxuLy9cbi8vIENhbGwgYHB1c2gobmV3Q2h1bmspYCB0byBwYXNzIGFsb25nIHRyYW5zZm9ybWVkIG91dHB1dFxuLy8gdG8gdGhlIHJlYWRhYmxlIHNpZGUuICBZb3UgbWF5IGNhbGwgJ3B1c2gnIHplcm8gb3IgbW9yZSB0aW1lcy5cbi8vXG4vLyBDYWxsIGBjYihlcnIpYCB3aGVuIHlvdSBhcmUgZG9uZSB3aXRoIHRoaXMgY2h1bmsuICBJZiB5b3UgcGFzc1xuLy8gYW4gZXJyb3IsIHRoZW4gdGhhdCdsbCBwdXQgdGhlIGh1cnQgb24gdGhlIHdob2xlIG9wZXJhdGlvbi4gIElmIHlvdVxuLy8gbmV2ZXIgY2FsbCBjYigpLCB0aGVuIHlvdSdsbCBuZXZlciBnZXQgYW5vdGhlciBjaHVuay5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKTtcbn07XG5cblRyYW5zZm9ybS5wcm90b3R5cGUuX3dyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcbiAgdHMud3JpdGVjYiA9IGNiO1xuICB0cy53cml0ZWNodW5rID0gY2h1bms7XG4gIHRzLndyaXRlZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgaWYgKCF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB2YXIgcnMgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICAgIGlmICh0cy5uZWVkVHJhbnNmb3JtIHx8XG4gICAgICAgIHJzLm5lZWRSZWFkYWJsZSB8fFxuICAgICAgICBycy5sZW5ndGggPCBycy5oaWdoV2F0ZXJNYXJrKVxuICAgICAgdGhpcy5fcmVhZChycy5oaWdoV2F0ZXJNYXJrKTtcbiAgfVxufTtcblxuLy8gRG9lc24ndCBtYXR0ZXIgd2hhdCB0aGUgYXJncyBhcmUgaGVyZS5cbi8vIF90cmFuc2Zvcm0gZG9lcyBhbGwgdGhlIHdvcmsuXG4vLyBUaGF0IHdlIGdvdCBoZXJlIG1lYW5zIHRoYXQgdGhlIHJlYWRhYmxlIHNpZGUgd2FudHMgbW9yZSBkYXRhLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdmFyIHRzID0gdGhpcy5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHRzLndyaXRlY2h1bmsgJiYgdHMud3JpdGVjYiAmJiAhdHMudHJhbnNmb3JtaW5nKSB7XG4gICAgdHMudHJhbnNmb3JtaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl90cmFuc2Zvcm0odHMud3JpdGVjaHVuaywgdHMud3JpdGVlbmNvZGluZywgdHMuYWZ0ZXJUcmFuc2Zvcm0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG1hcmsgdGhhdCB3ZSBuZWVkIGEgdHJhbnNmb3JtLCBzbyB0aGF0IGFueSBkYXRhIHRoYXQgY29tZXMgaW5cbiAgICAvLyB3aWxsIGdldCBwcm9jZXNzZWQsIG5vdyB0aGF0IHdlJ3ZlIGFza2VkIGZvciBpdC5cbiAgICB0cy5uZWVkVHJhbnNmb3JtID0gdHJ1ZTtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBkb25lKHN0cmVhbSwgZXIpIHtcbiAgaWYgKGVyKVxuICAgIHJldHVybiBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG5cbiAgLy8gaWYgdGhlcmUncyBub3RoaW5nIGluIHRoZSB3cml0ZSBidWZmZXIsIHRoZW4gdGhhdCBtZWFuc1xuICAvLyB0aGF0IG5vdGhpbmcgbW9yZSB3aWxsIGV2ZXIgYmUgcHJvdmlkZWRcbiAgdmFyIHdzID0gc3RyZWFtLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcnMgPSBzdHJlYW0uX3JlYWRhYmxlU3RhdGU7XG4gIHZhciB0cyA9IHN0cmVhbS5fdHJhbnNmb3JtU3RhdGU7XG5cbiAgaWYgKHdzLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiB3cy5sZW5ndGggIT0gMCcpO1xuXG4gIGlmICh0cy50cmFuc2Zvcm1pbmcpXG4gICAgdGhyb3cgbmV3IEVycm9yKCdjYWxsaW5nIHRyYW5zZm9ybSBkb25lIHdoZW4gc3RpbGwgdHJhbnNmb3JtaW5nJyk7XG5cbiAgcmV0dXJuIHN0cmVhbS5wdXNoKG51bGwpO1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIEEgYml0IHNpbXBsZXIgdGhhbiByZWFkYWJsZSBzdHJlYW1zLlxuLy8gSW1wbGVtZW50IGFuIGFzeW5jIC5fd3JpdGUoY2h1bmssIGNiKSwgYW5kIGl0J2xsIGhhbmRsZSBhbGxcbi8vIHRoZSBkcmFpbiBldmVudCBlbWlzc2lvbiBhbmQgYnVmZmVyaW5nLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFdyaXRhYmxlO1xuV3JpdGFibGUuV3JpdGFibGVTdGF0ZSA9IFdyaXRhYmxlU3RhdGU7XG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIHRpbWVycyA9IHJlcXVpcmUoJ3RpbWVycycpO1xudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxudXRpbC5pbmhlcml0cyhXcml0YWJsZSwgU3RyZWFtKTtcblxuZnVuY3Rpb24gV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aGlzLmNodW5rID0gY2h1bms7XG4gIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZztcbiAgdGhpcy5jYWxsYmFjayA9IGNiO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggd3JpdGUoKSBzdGFydHMgcmV0dXJuaW5nIGZhbHNlXG4gIC8vIE5vdGU6IDAgaXMgYSB2YWxpZCB2YWx1ZSwgbWVhbnMgdGhhdCB3ZSBhbHdheXMgcmV0dXJuIGZhbHNlIGlmXG4gIC8vIHRoZSBlbnRpcmUgYnVmZmVyIGlzIG5vdCBmbHVzaGVkIGltbWVkaWF0ZWx5IG9uIHdyaXRlKClcbiAgdmFyIGh3bSA9IG9wdGlvbnMuaGlnaFdhdGVyTWFyaztcbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gKGh3bSB8fCBod20gPT09IDApID8gaHdtIDogMTYgKiAxMDI0O1xuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZyB0byBpbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGlzIHN0cmVhbVxuICAvLyBjb250YWlucyBidWZmZXJzIG9yIG9iamVjdHMuXG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIC8vIGNhc3QgdG8gaW50cy5cbiAgdGhpcy5oaWdoV2F0ZXJNYXJrID0gfn50aGlzLmhpZ2hXYXRlck1hcms7XG5cbiAgdGhpcy5uZWVkRHJhaW4gPSBmYWxzZTtcbiAgLy8gYXQgdGhlIHN0YXJ0IG9mIGNhbGxpbmcgZW5kKClcbiAgdGhpcy5lbmRpbmcgPSBmYWxzZTtcbiAgLy8gd2hlbiBlbmQoKSBoYXMgYmVlbiBjYWxsZWQsIGFuZCByZXR1cm5lZFxuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIC8vIHdoZW4gJ2ZpbmlzaCcgaXMgZW1pdHRlZFxuICB0aGlzLmZpbmlzaGVkID0gZmFsc2U7XG5cbiAgLy8gc2hvdWxkIHdlIGRlY29kZSBzdHJpbmdzIGludG8gYnVmZmVycyBiZWZvcmUgcGFzc2luZyB0byBfd3JpdGU/XG4gIC8vIHRoaXMgaXMgaGVyZSBzbyB0aGF0IHNvbWUgbm9kZS1jb3JlIHN0cmVhbXMgY2FuIG9wdGltaXplIHN0cmluZ1xuICAvLyBoYW5kbGluZyBhdCBhIGxvd2VyIGxldmVsLlxuICB2YXIgbm9EZWNvZGUgPSBvcHRpb25zLmRlY29kZVN0cmluZ3MgPT09IGZhbHNlO1xuICB0aGlzLmRlY29kZVN0cmluZ3MgPSAhbm9EZWNvZGU7XG5cbiAgLy8gQ3J5cHRvIGlzIGtpbmQgb2Ygb2xkIGFuZCBjcnVzdHkuICBIaXN0b3JpY2FsbHksIGl0cyBkZWZhdWx0IHN0cmluZ1xuICAvLyBlbmNvZGluZyBpcyAnYmluYXJ5JyBzbyB3ZSBoYXZlIHRvIG1ha2UgdGhpcyBjb25maWd1cmFibGUuXG4gIC8vIEV2ZXJ5dGhpbmcgZWxzZSBpbiB0aGUgdW5pdmVyc2UgdXNlcyAndXRmOCcsIHRob3VnaC5cbiAgdGhpcy5kZWZhdWx0RW5jb2RpbmcgPSBvcHRpb25zLmRlZmF1bHRFbmNvZGluZyB8fCAndXRmOCc7XG5cbiAgLy8gbm90IGFuIGFjdHVhbCBidWZmZXIgd2Uga2VlcCB0cmFjayBvZiwgYnV0IGEgbWVhc3VyZW1lbnRcbiAgLy8gb2YgaG93IG11Y2ggd2UncmUgd2FpdGluZyB0byBnZXQgcHVzaGVkIHRvIHNvbWUgdW5kZXJseWluZ1xuICAvLyBzb2NrZXQgb3IgZmlsZS5cbiAgdGhpcy5sZW5ndGggPSAwO1xuXG4gIC8vIGEgZmxhZyB0byBzZWUgd2hlbiB3ZSdyZSBpbiB0aGUgbWlkZGxlIG9mIGEgd3JpdGUuXG4gIHRoaXMud3JpdGluZyA9IGZhbHNlO1xuXG4gIC8vIGEgZmxhZyB0byBiZSBhYmxlIHRvIHRlbGwgaWYgdGhlIG9ud3JpdGUgY2IgaXMgY2FsbGVkIGltbWVkaWF0ZWx5LFxuICAvLyBvciBvbiBhIGxhdGVyIHRpY2suICBXZSBzZXQgdGhpcyB0byB0cnVlIGF0IGZpcnN0LCBiZWN1YXNlIGFueVxuICAvLyBhY3Rpb25zIHRoYXQgc2hvdWxkbid0IGhhcHBlbiB1bnRpbCBcImxhdGVyXCIgc2hvdWxkIGdlbmVyYWxseSBhbHNvXG4gIC8vIG5vdCBoYXBwZW4gYmVmb3JlIHRoZSBmaXJzdCB3cml0ZSBjYWxsLlxuICB0aGlzLnN5bmMgPSB0cnVlO1xuXG4gIC8vIGEgZmxhZyB0byBrbm93IGlmIHdlJ3JlIHByb2Nlc3NpbmcgcHJldmlvdXNseSBidWZmZXJlZCBpdGVtcywgd2hpY2hcbiAgLy8gbWF5IGNhbGwgdGhlIF93cml0ZSgpIGNhbGxiYWNrIGluIHRoZSBzYW1lIHRpY2ssIHNvIHRoYXQgd2UgZG9uJ3RcbiAgLy8gZW5kIHVwIGluIGFuIG92ZXJsYXBwZWQgb253cml0ZSBzaXR1YXRpb24uXG4gIHRoaXMuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0J3MgcGFzc2VkIHRvIF93cml0ZShjaHVuayxjYilcbiAgdGhpcy5vbndyaXRlID0gZnVuY3Rpb24oZXIpIHtcbiAgICBvbndyaXRlKHN0cmVhbSwgZXIpO1xuICB9O1xuXG4gIC8vIHRoZSBjYWxsYmFjayB0aGF0IHRoZSB1c2VyIHN1cHBsaWVzIHRvIHdyaXRlKGNodW5rLGVuY29kaW5nLGNiKVxuICB0aGlzLndyaXRlY2IgPSBudWxsO1xuXG4gIC8vIHRoZSBhbW91bnQgdGhhdCBpcyBiZWluZyB3cml0dGVuIHdoZW4gX3dyaXRlIGlzIGNhbGxlZC5cbiAgdGhpcy53cml0ZWxlbiA9IDA7XG5cbiAgdGhpcy5idWZmZXIgPSBbXTtcbn1cblxuZnVuY3Rpb24gV3JpdGFibGUob3B0aW9ucykge1xuICAvLyBXcml0YWJsZSBjdG9yIGlzIGFwcGxpZWQgdG8gRHVwbGV4ZXMsIHRob3VnaCB0aGV5J3JlIG5vdFxuICAvLyBpbnN0YW5jZW9mIFdyaXRhYmxlLCB0aGV5J3JlIGluc3RhbmNlb2YgUmVhZGFibGUuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBXcml0YWJsZSkgJiYgISh0aGlzIGluc3RhbmNlb2YgU3RyZWFtLkR1cGxleCkpXG4gICAgcmV0dXJuIG5ldyBXcml0YWJsZShvcHRpb25zKTtcblxuICB0aGlzLl93cml0YWJsZVN0YXRlID0gbmV3IFdyaXRhYmxlU3RhdGUob3B0aW9ucywgdGhpcyk7XG5cbiAgLy8gbGVnYWN5LlxuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gT3RoZXJ3aXNlIHBlb3BsZSBjYW4gcGlwZSBXcml0YWJsZSBzdHJlYW1zLCB3aGljaCBpcyBqdXN0IHdyb25nLlxuV3JpdGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignQ2Fubm90IHBpcGUuIE5vdCByZWFkYWJsZS4nKSk7XG59O1xuXG5cbmZ1bmN0aW9uIHdyaXRlQWZ0ZXJFbmQoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgdmFyIGVyID0gbmV3IEVycm9yKCd3cml0ZSBhZnRlciBlbmQnKTtcbiAgLy8gVE9ETzogZGVmZXIgZXJyb3IgZXZlbnRzIGNvbnNpc3RlbnRseSBldmVyeXdoZXJlLCBub3QganVzdCB0aGUgY2JcbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICB0aW1lcnMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgIGNiKGVyKTtcbiAgfSk7XG59XG5cbi8vIElmIHdlIGdldCBzb21ldGhpbmcgdGhhdCBpcyBub3QgYSBidWZmZXIsIHN0cmluZywgbnVsbCwgb3IgdW5kZWZpbmVkLFxuLy8gYW5kIHdlJ3JlIG5vdCBpbiBvYmplY3RNb2RlLCB0aGVuIHRoYXQncyBhbiBlcnJvci5cbi8vIE90aGVyd2lzZSBzdHJlYW0gY2h1bmtzIGFyZSBhbGwgY29uc2lkZXJlZCB0byBiZSBvZiBsZW5ndGg9MSwgYW5kIHRoZVxuLy8gd2F0ZXJtYXJrcyBkZXRlcm1pbmUgaG93IG1hbnkgb2JqZWN0cyB0byBrZWVwIGluIHRoZSBidWZmZXIsIHJhdGhlciB0aGFuXG4vLyBob3cgbWFueSBieXRlcyBvciBjaGFyYWN0ZXJzLlxuZnVuY3Rpb24gdmFsaWRDaHVuayhzdHJlYW0sIHN0YXRlLCBjaHVuaywgY2IpIHtcbiAgdmFyIHZhbGlkID0gdHJ1ZTtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoY2h1bmspICYmXG4gICAgICAnc3RyaW5nJyAhPT0gdHlwZW9mIGNodW5rICYmXG4gICAgICBjaHVuayAhPT0gbnVsbCAmJlxuICAgICAgY2h1bmsgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgIXN0YXRlLm9iamVjdE1vZGUpIHtcbiAgICB2YXIgZXIgPSBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIG5vbi1zdHJpbmcvYnVmZmVyIGNodW5rJyk7XG4gICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xuICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBjYihlcik7XG4gICAgfSk7XG4gICAgdmFsaWQgPSBmYWxzZTtcbiAgfVxuICByZXR1cm4gdmFsaWQ7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHJldCA9IGZhbHNlO1xuXG4gIGlmICh0eXBlb2YgZW5jb2RpbmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gbnVsbDtcbiAgfVxuXG4gIGlmIChCdWZmZXIuaXNCdWZmZXIoY2h1bmspKVxuICAgIGVuY29kaW5nID0gJ2J1ZmZlcic7XG4gIGVsc2UgaWYgKCFlbmNvZGluZylcbiAgICBlbmNvZGluZyA9IHN0YXRlLmRlZmF1bHRFbmNvZGluZztcblxuICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKVxuICAgIGNiID0gZnVuY3Rpb24oKSB7fTtcblxuICBpZiAoc3RhdGUuZW5kZWQpXG4gICAgd3JpdGVBZnRlckVuZCh0aGlzLCBzdGF0ZSwgY2IpO1xuICBlbHNlIGlmICh2YWxpZENodW5rKHRoaXMsIHN0YXRlLCBjaHVuaywgY2IpKVxuICAgIHJldCA9IHdyaXRlT3JCdWZmZXIodGhpcywgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKSB7XG4gIGlmICghc3RhdGUub2JqZWN0TW9kZSAmJlxuICAgICAgc3RhdGUuZGVjb2RlU3RyaW5ncyAhPT0gZmFsc2UgJiZcbiAgICAgIHR5cGVvZiBjaHVuayA9PT0gJ3N0cmluZycpIHtcbiAgICBjaHVuayA9IG5ldyBCdWZmZXIoY2h1bmssIGVuY29kaW5nKTtcbiAgfVxuICByZXR1cm4gY2h1bms7XG59XG5cbi8vIGlmIHdlJ3JlIGFscmVhZHkgd3JpdGluZyBzb21ldGhpbmcsIHRoZW4ganVzdCBwdXQgdGhpc1xuLy8gaW4gdGhlIHF1ZXVlLCBhbmQgd2FpdCBvdXIgdHVybi4gIE90aGVyd2lzZSwgY2FsbCBfd3JpdGVcbi8vIElmIHdlIHJldHVybiBmYWxzZSwgdGhlbiB3ZSBuZWVkIGEgZHJhaW4gZXZlbnQsIHNvIHNldCB0aGF0IGZsYWcuXG5mdW5jdGlvbiB3cml0ZU9yQnVmZmVyKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2h1bmsgPSBkZWNvZGVDaHVuayhzdGF0ZSwgY2h1bmssIGVuY29kaW5nKTtcbiAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gIHN0YXRlLmxlbmd0aCArPSBsZW47XG5cbiAgdmFyIHJldCA9IHN0YXRlLmxlbmd0aCA8IHN0YXRlLmhpZ2hXYXRlck1hcms7XG4gIHN0YXRlLm5lZWREcmFpbiA9ICFyZXQ7XG5cbiAgaWYgKHN0YXRlLndyaXRpbmcpXG4gICAgc3RhdGUuYnVmZmVyLnB1c2gobmV3IFdyaXRlUmVxKGNodW5rLCBlbmNvZGluZywgY2IpKTtcbiAgZWxzZVxuICAgIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKTtcblxuICByZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBzdGF0ZS53cml0ZWxlbiA9IGxlbjtcbiAgc3RhdGUud3JpdGVjYiA9IGNiO1xuICBzdGF0ZS53cml0aW5nID0gdHJ1ZTtcbiAgc3RhdGUuc3luYyA9IHRydWU7XG4gIHN0cmVhbS5fd3JpdGUoY2h1bmssIGVuY29kaW5nLCBzdGF0ZS5vbndyaXRlKTtcbiAgc3RhdGUuc3luYyA9IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKSB7XG4gIGlmIChzeW5jKVxuICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICBjYihlcik7XG4gICAgfSk7XG4gIGVsc2VcbiAgICBjYihlcik7XG5cbiAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXIpO1xufVxuXG5mdW5jdGlvbiBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpIHtcbiAgc3RhdGUud3JpdGluZyA9IGZhbHNlO1xuICBzdGF0ZS53cml0ZWNiID0gbnVsbDtcbiAgc3RhdGUubGVuZ3RoIC09IHN0YXRlLndyaXRlbGVuO1xuICBzdGF0ZS53cml0ZWxlbiA9IDA7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGUoc3RyZWFtLCBlcikge1xuICB2YXIgc3RhdGUgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBzeW5jID0gc3RhdGUuc3luYztcbiAgdmFyIGNiID0gc3RhdGUud3JpdGVjYjtcblxuICBvbndyaXRlU3RhdGVVcGRhdGUoc3RhdGUpO1xuXG4gIGlmIChlcilcbiAgICBvbndyaXRlRXJyb3Ioc3RyZWFtLCBzdGF0ZSwgc3luYywgZXIsIGNiKTtcbiAgZWxzZSB7XG4gICAgLy8gQ2hlY2sgaWYgd2UncmUgYWN0dWFsbHkgcmVhZHkgdG8gZmluaXNoLCBidXQgZG9uJ3QgZW1pdCB5ZXRcbiAgICB2YXIgZmluaXNoZWQgPSBuZWVkRmluaXNoKHN0cmVhbSwgc3RhdGUpO1xuXG4gICAgaWYgKCFmaW5pc2hlZCAmJiAhc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyAmJiBzdGF0ZS5idWZmZXIubGVuZ3RoKVxuICAgICAgY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSk7XG5cbiAgICBpZiAoc3luYykge1xuICAgICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFmdGVyV3JpdGUoc3RyZWFtLCBzdGF0ZSwgZmluaXNoZWQsIGNiKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpIHtcbiAgaWYgKCFmaW5pc2hlZClcbiAgICBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSk7XG4gIGNiKCk7XG4gIGlmIChmaW5pc2hlZClcbiAgICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbn1cblxuLy8gTXVzdCBmb3JjZSBjYWxsYmFjayB0byBiZSBjYWxsZWQgb24gbmV4dFRpY2ssIHNvIHRoYXQgd2UgZG9uJ3Rcbi8vIGVtaXQgJ2RyYWluJyBiZWZvcmUgdGhlIHdyaXRlKCkgY29uc3VtZXIgZ2V0cyB0aGUgJ2ZhbHNlJyByZXR1cm5cbi8vIHZhbHVlLCBhbmQgaGFzIGEgY2hhbmNlIHRvIGF0dGFjaCBhICdkcmFpbicgbGlzdGVuZXIuXG5mdW5jdGlvbiBvbndyaXRlRHJhaW4oc3RyZWFtLCBzdGF0ZSkge1xuICBpZiAoc3RhdGUubGVuZ3RoID09PSAwICYmIHN0YXRlLm5lZWREcmFpbikge1xuICAgIHN0YXRlLm5lZWREcmFpbiA9IGZhbHNlO1xuICAgIHN0cmVhbS5lbWl0KCdkcmFpbicpO1xuICB9XG59XG5cblxuLy8gaWYgdGhlcmUncyBzb21ldGhpbmcgaW4gdGhlIGJ1ZmZlciB3YWl0aW5nLCB0aGVuIHByb2Nlc3MgaXRcbmZ1bmN0aW9uIGNsZWFyQnVmZmVyKHN0cmVhbSwgc3RhdGUpIHtcbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IHRydWU7XG5cbiAgZm9yICh2YXIgYyA9IDA7IGMgPCBzdGF0ZS5idWZmZXIubGVuZ3RoOyBjKyspIHtcbiAgICB2YXIgZW50cnkgPSBzdGF0ZS5idWZmZXJbY107XG4gICAgdmFyIGNodW5rID0gZW50cnkuY2h1bms7XG4gICAgdmFyIGVuY29kaW5nID0gZW50cnkuZW5jb2Rpbmc7XG4gICAgdmFyIGNiID0gZW50cnkuY2FsbGJhY2s7XG4gICAgdmFyIGxlbiA9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gICAgLy8gaWYgd2UgZGlkbid0IGNhbGwgdGhlIG9ud3JpdGUgaW1tZWRpYXRlbHksIHRoZW5cbiAgICAvLyBpdCBtZWFucyB0aGF0IHdlIG5lZWQgdG8gd2FpdCB1bnRpbCBpdCBkb2VzLlxuICAgIC8vIGFsc28sIHRoYXQgbWVhbnMgdGhhdCB0aGUgY2h1bmsgYW5kIGNiIGFyZSBjdXJyZW50bHlcbiAgICAvLyBiZWluZyBwcm9jZXNzZWQsIHNvIG1vdmUgdGhlIGJ1ZmZlciBjb3VudGVyIHBhc3QgdGhlbS5cbiAgICBpZiAoc3RhdGUud3JpdGluZykge1xuICAgICAgYysrO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgc3RhdGUuYnVmZmVyUHJvY2Vzc2luZyA9IGZhbHNlO1xuICBpZiAoYyA8IHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgc3RhdGUuYnVmZmVyID0gc3RhdGUuYnVmZmVyLnNsaWNlKGMpO1xuICBlbHNlXG4gICAgc3RhdGUuYnVmZmVyLmxlbmd0aCA9IDA7XG59XG5cbldyaXRhYmxlLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIGNiKG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuV3JpdGFibGUucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fd3JpdGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBjaHVuaztcbiAgICBjaHVuayA9IG51bGw7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBjaHVuayAhPT0gJ3VuZGVmaW5lZCcgJiYgY2h1bmsgIT09IG51bGwpXG4gICAgdGhpcy53cml0ZShjaHVuaywgZW5jb2RpbmcpO1xuXG4gIC8vIGlnbm9yZSB1bm5lY2Vzc2FyeSBlbmQoKSBjYWxscy5cbiAgaWYgKCFzdGF0ZS5lbmRpbmcgJiYgIXN0YXRlLmZpbmlzaGVkKVxuICAgIGVuZFdyaXRhYmxlKHRoaXMsIHN0YXRlLCBjYik7XG59O1xuXG5cbmZ1bmN0aW9uIG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSkge1xuICByZXR1cm4gKHN0YXRlLmVuZGluZyAmJlxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICAgICFzdGF0ZS5maW5pc2hlZCAmJlxuICAgICAgICAgICFzdGF0ZS53cml0aW5nKTtcbn1cblxuZnVuY3Rpb24gZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbmVlZCA9IG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChuZWVkKSB7XG4gICAgc3RhdGUuZmluaXNoZWQgPSB0cnVlO1xuICAgIHN0cmVhbS5lbWl0KCdmaW5pc2gnKTtcbiAgfVxuICByZXR1cm4gbmVlZDtcbn1cblxuZnVuY3Rpb24gZW5kV3JpdGFibGUoc3RyZWFtLCBzdGF0ZSwgY2IpIHtcbiAgc3RhdGUuZW5kaW5nID0gdHJ1ZTtcbiAgZmluaXNoTWF5YmUoc3RyZWFtLCBzdGF0ZSk7XG4gIGlmIChjYikge1xuICAgIGlmIChzdGF0ZS5maW5pc2hlZClcbiAgICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoY2IpO1xuICAgIGVsc2VcbiAgICAgIHN0cmVhbS5vbmNlKCdmaW5pc2gnLCBjYik7XG4gIH1cbiAgc3RhdGUuZW5kZWQgPSB0cnVlO1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIFVUSUxJVFlcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHNoaW1zID0gcmVxdWlyZSgnX3NoaW1zJyk7XG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlIHx8IGdldE1lc3NhZ2UodGhpcyk7XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gcmVwbGFjZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAodXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gJycgKyB2YWx1ZTtcbiAgfVxuICBpZiAodXRpbC5pc051bWJlcih2YWx1ZSkgJiYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIGlmICh1dGlsLmlzRnVuY3Rpb24odmFsdWUpIHx8IHV0aWwuaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHMpKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5hY3R1YWwsIHJlcGxhY2VyKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuZXhwZWN0ZWQsIHJlcGxhY2VyKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0J1ZmZlcihhY3R1YWwpICYmIHV0aWwuaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFjdHVhbFtpXSAhPT0gZXhwZWN0ZWRbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNPYmplY3QoYWN0dWFsKSAmJiAhdXRpbC5pc09iamVjdChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIpIHtcbiAgaWYgKHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYSkgfHwgdXRpbC5pc051bGxPclVuZGVmaW5lZChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIpO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gc2hpbXMua2V5cyhhKSxcbiAgICAgICAga2IgPSBzaGltcy5rZXlzKGIpLFxuICAgICAgICBrZXksIGk7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh1dGlsLmlzU3RyaW5nKGV4cGVjdGVkKSkge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBhY3R1YWwgPSBlO1xuICB9XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoIXNob3VsZFRocm93ICYmIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbZmFsc2VdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB7dGhyb3cgZXJyO319OyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCF1dGlsLmlzTnVtYmVyKG4pIHx8IG4gPCAwKVxuICAgIHRocm93IFR5cGVFcnJvcignbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcbiAgICBpZiAoIXRoaXMuX2V2ZW50cy5lcnJvciB8fFxuICAgICAgICAodXRpbC5pc09iamVjdCh0aGlzLl9ldmVudHMuZXJyb3IpICYmICF0aGlzLl9ldmVudHMuZXJyb3IubGVuZ3RoKSkge1xuICAgICAgZXIgPSBhcmd1bWVudHNbMV07XG4gICAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkICdlcnJvcicgZXZlbnRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFR5cGVFcnJvcignVW5jYXVnaHQsIHVuc3BlY2lmaWVkIFwiZXJyb3JcIiBldmVudC4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVyID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmICh1dGlsLmlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAodXRpbC5pc0Z1bmN0aW9uKGhhbmRsZXIpKSB7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgICBjYXNlIDE6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBzbG93ZXJcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodXRpbC5pc09iamVjdChoYW5kbGVyKSkge1xuICAgIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcblxuICAgIGxpc3RlbmVycyA9IGhhbmRsZXIuc2xpY2UoKTtcbiAgICBsZW4gPSBsaXN0ZW5lcnMubGVuZ3RoO1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGxpc3RlbmVyc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBtO1xuXG4gIGlmICghdXRpbC5pc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgdXRpbC5pc0Z1bmN0aW9uKGxpc3RlbmVyLmxpc3RlbmVyKSA/XG4gICAgICAgICAgICAgIGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIC8vIE9wdGltaXplIHRoZSBjYXNlIG9mIG9uZSBsaXN0ZW5lci4gRG9uJ3QgbmVlZCB0aGUgZXh0cmEgYXJyYXkgb2JqZWN0LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICBlbHNlIGlmICh1dGlsLmlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgLy8gSWYgd2UndmUgYWxyZWFkeSBnb3QgYW4gYXJyYXksIGp1c3QgYXBwZW5kLlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcbiAgZWxzZVxuICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFt0aGlzLl9ldmVudHNbdHlwZV0sIGxpc3RlbmVyXTtcblxuICAvLyBDaGVjayBmb3IgbGlzdGVuZXIgbGVha1xuICBpZiAodXRpbC5pc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgdmFyIG07XG4gICAgaWYgKCF1dGlsLmlzVW5kZWZpbmVkKHRoaXMuX21heExpc3RlbmVycykpIHtcbiAgICAgIG0gPSB0aGlzLl9tYXhMaXN0ZW5lcnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBFdmVudEVtaXR0ZXIuZGVmYXVsdE1heExpc3RlbmVycztcbiAgICB9XG5cbiAgICBpZiAobSAmJiBtID4gMCAmJiB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoID4gbSkge1xuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICdVc2UgZW1pdHRlci5zZXRNYXhMaXN0ZW5lcnMoKSB0byBpbmNyZWFzZSBsaW1pdC4nLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbdHlwZV0ubGVuZ3RoKTtcbiAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBmdW5jdGlvbiBnKCkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgZyk7XG4gICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIGcubGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgdGhpcy5vbih0eXBlLCBnKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGVtaXRzIGEgJ3JlbW92ZUxpc3RlbmVyJyBldmVudCBpZmYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIGxpc3QsIHBvc2l0aW9uLCBsZW5ndGgsIGk7XG5cbiAgaWYgKCF1dGlsLmlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICh1dGlsLmlzRnVuY3Rpb24obGlzdC5saXN0ZW5lcikgJiYgbGlzdC5saXN0ZW5lciA9PT0gbGlzdGVuZXIpKSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcblxuICB9IGVsc2UgaWYgKHV0aWwuaXNPYmplY3QobGlzdCkpIHtcbiAgICBmb3IgKGkgPSBsZW5ndGg7IGktLSA+IDA7KSB7XG4gICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHxcbiAgICAgICAgICAobGlzdFtpXS5saXN0ZW5lciAmJiBsaXN0W2ldLmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocG9zaXRpb24gPCAwKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICAgIGxpc3QubGVuZ3RoID0gMDtcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpc3Quc3BsaWNlKHBvc2l0aW9uLCAxKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgdGhpcy5lbWl0KCdyZW1vdmVMaXN0ZW5lcicsIHR5cGUsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBrZXksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICByZXR1cm4gdGhpcztcblxuICAvLyBub3QgbGlzdGVuaW5nIGZvciByZW1vdmVMaXN0ZW5lciwgbm8gbmVlZCB0byBlbWl0XG4gIGlmICghdGhpcy5fZXZlbnRzLnJlbW92ZUxpc3RlbmVyKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApXG4gICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICBlbHNlIGlmICh0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZW1pdCByZW1vdmVMaXN0ZW5lciBmb3IgYWxsIGxpc3RlbmVycyBvbiBhbGwgZXZlbnRzXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgZm9yIChrZXkgaW4gdGhpcy5fZXZlbnRzKSB7XG4gICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKGtleSk7XG4gICAgfVxuICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuXG4gIGlmICh1dGlsLmlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAodXRpbC5pc0Z1bmN0aW9uKHRoaXMuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gW3RoaXMuX2V2ZW50c1t0eXBlXV07XG4gIGVsc2VcbiAgICByZXQgPSB0aGlzLl9ldmVudHNbdHlwZV0uc2xpY2UoKTtcbiAgcmV0dXJuIHJldDtcbn07XG5cbkV2ZW50RW1pdHRlci5saXN0ZW5lckNvdW50ID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIWVtaXR0ZXIuX2V2ZW50cyB8fCAhZW1pdHRlci5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IDA7XG4gIGVsc2UgaWYgKHV0aWwuaXNGdW5jdGlvbihlbWl0dGVyLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IDE7XG4gIGVsc2VcbiAgICByZXQgPSBlbWl0dGVyLl9ldmVudHNbdHlwZV0ubGVuZ3RoO1xuICByZXR1cm4gcmV0O1xufTsiLCJ2YXIgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcblxudmFyIGh0dHBzID0gbW9kdWxlLmV4cG9ydHM7XG5cbmZvciAodmFyIGtleSBpbiBodHRwKSB7XG4gICAgaWYgKGh0dHAuaGFzT3duUHJvcGVydHkoa2V5KSkgaHR0cHNba2V5XSA9IGh0dHBba2V5XTtcbn07XG5cbmh0dHBzLnJlcXVlc3QgPSBmdW5jdGlvbiAocGFyYW1zLCBjYikge1xuICAgIGlmICghcGFyYW1zKSBwYXJhbXMgPSB7fTtcbiAgICBwYXJhbXMuc2NoZW1lID0gJ2h0dHBzJztcbiAgICByZXR1cm4gaHR0cC5yZXF1ZXN0LmNhbGwodGhpcywgcGFyYW1zLCBjYik7XG59IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIFF1ZXJ5IFN0cmluZyBVdGlsaXRpZXNcblxudmFyIFF1ZXJ5U3RyaW5nID0gZXhwb3J0cztcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHNoaW1zID0gcmVxdWlyZSgnX3NoaW1zJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG4vLyBJZiBvYmouaGFzT3duUHJvcGVydHkgaGFzIGJlZW4gb3ZlcnJpZGRlbiwgdGhlbiBjYWxsaW5nXG4vLyBvYmouaGFzT3duUHJvcGVydHkocHJvcCkgd2lsbCBicmVhay5cbi8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2pveWVudC9ub2RlL2lzc3Vlcy8xNzA3XG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG5cbmZ1bmN0aW9uIGNoYXJDb2RlKGMpIHtcbiAgcmV0dXJuIGMuY2hhckNvZGVBdCgwKTtcbn1cblxuXG4vLyBhIHNhZmUgZmFzdCBhbHRlcm5hdGl2ZSB0byBkZWNvZGVVUklDb21wb25lbnRcblF1ZXJ5U3RyaW5nLnVuZXNjYXBlQnVmZmVyID0gZnVuY3Rpb24ocywgZGVjb2RlU3BhY2VzKSB7XG4gIHZhciBvdXQgPSBuZXcgQnVmZmVyKHMubGVuZ3RoKTtcbiAgdmFyIHN0YXRlID0gJ0NIQVInOyAvLyBzdGF0ZXM6IENIQVIsIEhFWDAsIEhFWDFcbiAgdmFyIG4sIG0sIGhleGNoYXI7XG5cbiAgZm9yICh2YXIgaW5JbmRleCA9IDAsIG91dEluZGV4ID0gMDsgaW5JbmRleCA8PSBzLmxlbmd0aDsgaW5JbmRleCsrKSB7XG4gICAgdmFyIGMgPSBzLmNoYXJDb2RlQXQoaW5JbmRleCk7XG4gICAgc3dpdGNoIChzdGF0ZSkge1xuICAgICAgY2FzZSAnQ0hBUic6XG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgY2hhckNvZGUoJyUnKTpcbiAgICAgICAgICAgIG4gPSAwO1xuICAgICAgICAgICAgbSA9IDA7XG4gICAgICAgICAgICBzdGF0ZSA9ICdIRVgwJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgY2hhckNvZGUoJysnKTpcbiAgICAgICAgICAgIGlmIChkZWNvZGVTcGFjZXMpIGMgPSBjaGFyQ29kZSgnICcpO1xuICAgICAgICAgICAgLy8gcGFzcyB0aHJ1XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IGM7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnSEVYMCc6XG4gICAgICAgIHN0YXRlID0gJ0hFWDEnO1xuICAgICAgICBoZXhjaGFyID0gYztcbiAgICAgICAgaWYgKGNoYXJDb2RlKCcwJykgPD0gYyAmJiBjIDw9IGNoYXJDb2RlKCc5JykpIHtcbiAgICAgICAgICBuID0gYyAtIGNoYXJDb2RlKCcwJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUoJ2EnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJ2YnKSkge1xuICAgICAgICAgIG4gPSBjIC0gY2hhckNvZGUoJ2EnKSArIDEwO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXJDb2RlKCdBJykgPD0gYyAmJiBjIDw9IGNoYXJDb2RlKCdGJykpIHtcbiAgICAgICAgICBuID0gYyAtIGNoYXJDb2RlKCdBJykgKyAxMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXRbb3V0SW5kZXgrK10gPSBjaGFyQ29kZSgnJScpO1xuICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IGM7XG4gICAgICAgICAgc3RhdGUgPSAnQ0hBUic7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0hFWDEnOlxuICAgICAgICBzdGF0ZSA9ICdDSEFSJztcbiAgICAgICAgaWYgKGNoYXJDb2RlKCcwJykgPD0gYyAmJiBjIDw9IGNoYXJDb2RlKCc5JykpIHtcbiAgICAgICAgICBtID0gYyAtIGNoYXJDb2RlKCcwJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUoJ2EnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJ2YnKSkge1xuICAgICAgICAgIG0gPSBjIC0gY2hhckNvZGUoJ2EnKSArIDEwO1xuICAgICAgICB9IGVsc2UgaWYgKGNoYXJDb2RlKCdBJykgPD0gYyAmJiBjIDw9IGNoYXJDb2RlKCdGJykpIHtcbiAgICAgICAgICBtID0gYyAtIGNoYXJDb2RlKCdBJykgKyAxMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXRbb3V0SW5kZXgrK10gPSBjaGFyQ29kZSgnJScpO1xuICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IGhleGNoYXI7XG4gICAgICAgICAgb3V0W291dEluZGV4KytdID0gYztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBvdXRbb3V0SW5kZXgrK10gPSAxNiAqIG4gKyBtO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyBUT0RPIHN1cHBvcnQgcmV0dXJuaW5nIGFyYml0cmFyeSBidWZmZXJzLlxuXG4gIHJldHVybiBvdXQuc2xpY2UoMCwgb3V0SW5kZXggLSAxKTtcbn07XG5cblxuUXVlcnlTdHJpbmcudW5lc2NhcGUgPSBmdW5jdGlvbihzLCBkZWNvZGVTcGFjZXMpIHtcbiAgcmV0dXJuIFF1ZXJ5U3RyaW5nLnVuZXNjYXBlQnVmZmVyKHMsIGRlY29kZVNwYWNlcykudG9TdHJpbmcoKTtcbn07XG5cblxuUXVlcnlTdHJpbmcuZXNjYXBlID0gZnVuY3Rpb24oc3RyKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyKTtcbn07XG5cbnZhciBzdHJpbmdpZnlQcmltaXRpdmUgPSBmdW5jdGlvbih2KSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHYpKVxuICAgIHJldHVybiB2O1xuICBpZiAodXRpbC5pc0Jvb2xlYW4odikpXG4gICAgcmV0dXJuIHYgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICBpZiAodXRpbC5pc051bWJlcih2KSlcbiAgICByZXR1cm4gaXNGaW5pdGUodikgPyB2IDogJyc7XG4gIHJldHVybiAnJztcbn07XG5cblxuUXVlcnlTdHJpbmcuc3RyaW5naWZ5ID0gUXVlcnlTdHJpbmcuZW5jb2RlID0gZnVuY3Rpb24ob2JqLCBzZXAsIGVxLCBuYW1lKSB7XG4gIHNlcCA9IHNlcCB8fCAnJic7XG4gIGVxID0gZXEgfHwgJz0nO1xuICBpZiAodXRpbC5pc051bGwob2JqKSkge1xuICAgIG9iaiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICh1dGlsLmlzT2JqZWN0KG9iaikpIHtcbiAgICByZXR1cm4gc2hpbXMubWFwKHNoaW1zLmtleXMob2JqKSwgZnVuY3Rpb24oaykge1xuICAgICAgdmFyIGtzID0gUXVlcnlTdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShrKSkgKyBlcTtcbiAgICAgIGlmICh1dGlsLmlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgICByZXR1cm4gc2hpbXMubWFwKG9ialtrXSwgZnVuY3Rpb24odikge1xuICAgICAgICAgIHJldHVybiBrcyArIFF1ZXJ5U3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUodikpO1xuICAgICAgICB9KS5qb2luKHNlcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ga3MgKyBRdWVyeVN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKG9ialtrXSkpO1xuICAgICAgfVxuICAgIH0pLmpvaW4oc2VwKTtcblxuICB9XG5cbiAgaWYgKCFuYW1lKSByZXR1cm4gJyc7XG4gIHJldHVybiBRdWVyeVN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKG5hbWUpKSArIGVxICtcbiAgICAgICAgIFF1ZXJ5U3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUob2JqKSk7XG59O1xuXG4vLyBQYXJzZSBhIGtleT12YWwgc3RyaW5nLlxuUXVlcnlTdHJpbmcucGFyc2UgPSBRdWVyeVN0cmluZy5kZWNvZGUgPSBmdW5jdGlvbihxcywgc2VwLCBlcSwgb3B0aW9ucykge1xuICBzZXAgPSBzZXAgfHwgJyYnO1xuICBlcSA9IGVxIHx8ICc9JztcbiAgdmFyIG9iaiA9IHt9O1xuXG4gIGlmICghdXRpbC5pc1N0cmluZyhxcykgfHwgcXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHZhciByZWdleHAgPSAvXFwrL2c7XG4gIHFzID0gcXMuc3BsaXQoc2VwKTtcblxuICB2YXIgbWF4S2V5cyA9IDEwMDA7XG4gIGlmIChvcHRpb25zICYmIHV0aWwuaXNOdW1iZXIob3B0aW9ucy5tYXhLZXlzKSkge1xuICAgIG1heEtleXMgPSBvcHRpb25zLm1heEtleXM7XG4gIH1cblxuICB2YXIgbGVuID0gcXMubGVuZ3RoO1xuICAvLyBtYXhLZXlzIDw9IDAgbWVhbnMgdGhhdCB3ZSBzaG91bGQgbm90IGxpbWl0IGtleXMgY291bnRcbiAgaWYgKG1heEtleXMgPiAwICYmIGxlbiA+IG1heEtleXMpIHtcbiAgICBsZW4gPSBtYXhLZXlzO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgIHZhciB4ID0gcXNbaV0ucmVwbGFjZShyZWdleHAsICclMjAnKSxcbiAgICAgICAgaWR4ID0geC5pbmRleE9mKGVxKSxcbiAgICAgICAga3N0ciwgdnN0ciwgaywgdjtcblxuICAgIGlmIChpZHggPj0gMCkge1xuICAgICAga3N0ciA9IHguc3Vic3RyKDAsIGlkeCk7XG4gICAgICB2c3RyID0geC5zdWJzdHIoaWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGtzdHIgPSB4O1xuICAgICAgdnN0ciA9ICcnO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBrID0gZGVjb2RlVVJJQ29tcG9uZW50KGtzdHIpO1xuICAgICAgdiA9IGRlY29kZVVSSUNvbXBvbmVudCh2c3RyKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBrID0gUXVlcnlTdHJpbmcudW5lc2NhcGUoa3N0ciwgdHJ1ZSk7XG4gICAgICB2ID0gUXVlcnlTdHJpbmcudW5lc2NhcGUodnN0ciwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgaWYgKCFoYXNPd25Qcm9wZXJ0eShvYmosIGspKSB7XG4gICAgICBvYmpba10gPSB2O1xuICAgIH0gZWxzZSBpZiAodXRpbC5pc0FycmF5KG9ialtrXSkpIHtcbiAgICAgIG9ialtrXS5wdXNoKHYpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvYmpba10gPSBbb2JqW2tdLCB2XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqO1xufTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBTdHJlYW07XG5cbnZhciBFRSA9IHJlcXVpcmUoJ2V2ZW50cycpLkV2ZW50RW1pdHRlcjtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG51dGlsLmluaGVyaXRzKFN0cmVhbSwgRUUpO1xuU3RyZWFtLlJlYWRhYmxlID0gcmVxdWlyZSgnX3N0cmVhbV9yZWFkYWJsZScpO1xuU3RyZWFtLldyaXRhYmxlID0gcmVxdWlyZSgnX3N0cmVhbV93cml0YWJsZScpO1xuU3RyZWFtLkR1cGxleCA9IHJlcXVpcmUoJ19zdHJlYW1fZHVwbGV4Jyk7XG5TdHJlYW0uVHJhbnNmb3JtID0gcmVxdWlyZSgnX3N0cmVhbV90cmFuc2Zvcm0nKTtcblN0cmVhbS5QYXNzVGhyb3VnaCA9IHJlcXVpcmUoJ19zdHJlYW1fcGFzc3Rocm91Z2gnKTtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC40LnhcblN0cmVhbS5TdHJlYW0gPSBTdHJlYW07XG5cblxuXG4vLyBvbGQtc3R5bGUgc3RyZWFtcy4gIE5vdGUgdGhhdCB0aGUgcGlwZSBtZXRob2QgKHRoZSBvbmx5IHJlbGV2YW50XG4vLyBwYXJ0IG9mIHRoaXMgY2xhc3MpIGlzIG92ZXJyaWRkZW4gaW4gdGhlIFJlYWRhYmxlIGNsYXNzLlxuXG5mdW5jdGlvbiBTdHJlYW0oKSB7XG4gIEVFLmNhbGwodGhpcyk7XG59XG5cblN0cmVhbS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKGRlc3QsIG9wdGlvbnMpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gb25kYXRhKGNodW5rKSB7XG4gICAgaWYgKGRlc3Qud3JpdGFibGUpIHtcbiAgICAgIGlmIChmYWxzZSA9PT0gZGVzdC53cml0ZShjaHVuaykgJiYgc291cmNlLnBhdXNlKSB7XG4gICAgICAgIHNvdXJjZS5wYXVzZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZGF0YScsIG9uZGF0YSk7XG5cbiAgZnVuY3Rpb24gb25kcmFpbigpIHtcbiAgICBpZiAoc291cmNlLnJlYWRhYmxlICYmIHNvdXJjZS5yZXN1bWUpIHtcbiAgICAgIHNvdXJjZS5yZXN1bWUoKTtcbiAgICB9XG4gIH1cblxuICBkZXN0Lm9uKCdkcmFpbicsIG9uZHJhaW4pO1xuXG4gIC8vIElmIHRoZSAnZW5kJyBvcHRpb24gaXMgbm90IHN1cHBsaWVkLCBkZXN0LmVuZCgpIHdpbGwgYmUgY2FsbGVkIHdoZW5cbiAgLy8gc291cmNlIGdldHMgdGhlICdlbmQnIG9yICdjbG9zZScgZXZlbnRzLiAgT25seSBkZXN0LmVuZCgpIG9uY2UuXG4gIGlmICghZGVzdC5faXNTdGRpbyAmJiAoIW9wdGlvbnMgfHwgb3B0aW9ucy5lbmQgIT09IGZhbHNlKSkge1xuICAgIHNvdXJjZS5vbignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5vbignY2xvc2UnLCBvbmNsb3NlKTtcbiAgfVxuXG4gIHZhciBkaWRPbkVuZCA9IGZhbHNlO1xuICBmdW5jdGlvbiBvbmVuZCgpIHtcbiAgICBpZiAoZGlkT25FbmQpIHJldHVybjtcbiAgICBkaWRPbkVuZCA9IHRydWU7XG5cbiAgICBkZXN0LmVuZCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgZGVzdC5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSBkZXN0LmRlc3Ryb3koKTtcbiAgfVxuXG4gIC8vIGRvbid0IGxlYXZlIGRhbmdsaW5nIHBpcGVzIHdoZW4gdGhlcmUgYXJlIGVycm9ycy5cbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIGNsZWFudXAoKTtcbiAgICBpZiAoRUUubGlzdGVuZXJDb3VudCh0aGlzLCAnZXJyb3InKSA9PT0gMCkge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCBzdHJlYW0gZXJyb3IgaW4gcGlwZS5cbiAgICB9XG4gIH1cblxuICBzb3VyY2Uub24oJ2Vycm9yJywgb25lcnJvcik7XG4gIGRlc3Qub24oJ2Vycm9yJywgb25lcnJvcik7XG5cbiAgLy8gcmVtb3ZlIGFsbCB0aGUgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZC5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2RhdGEnLCBvbmRhdGEpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ2RyYWluJywgb25kcmFpbik7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgb25jbG9zZSk7XG5cbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgY2xlYW51cCk7XG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBjbGVhbnVwKTtcbiAgfVxuXG4gIHNvdXJjZS5vbignZW5kJywgY2xlYW51cCk7XG4gIHNvdXJjZS5vbignY2xvc2UnLCBjbGVhbnVwKTtcblxuICBkZXN0Lm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3QuZW1pdCgncGlwZScsIHNvdXJjZSk7XG5cbiAgLy8gQWxsb3cgZm9yIHVuaXgtbGlrZSB1c2FnZTogQS5waXBlKEIpLnBpcGUoQylcbiAgcmV0dXJuIGRlc3Q7XG59O1xuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbmZ1bmN0aW9uIGFzc2VydEVuY29kaW5nKGVuY29kaW5nKSB7XG4gIGlmIChlbmNvZGluZyAmJiAhQnVmZmVyLmlzRW5jb2RpbmcoZW5jb2RpbmcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpO1xuICB9XG59XG5cbnZhciBTdHJpbmdEZWNvZGVyID0gZXhwb3J0cy5TdHJpbmdEZWNvZGVyID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgdGhpcy5lbmNvZGluZyA9IChlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWy1fXS8sICcnKTtcbiAgYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpO1xuICBzd2l0Y2ggKHRoaXMuZW5jb2RpbmcpIHtcbiAgICBjYXNlICd1dGY4JzpcbiAgICAgIC8vIENFU1UtOCByZXByZXNlbnRzIGVhY2ggb2YgU3Vycm9nYXRlIFBhaXIgYnkgMy1ieXRlc1xuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgLy8gVVRGLTE2IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAyLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAyO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IHV0ZjE2RGV0ZWN0SW5jb21wbGV0ZUNoYXI7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgLy8gQmFzZS02NCBzdG9yZXMgMyBieXRlcyBpbiA0IGNoYXJzLCBhbmQgcGFkcyB0aGUgcmVtYWluZGVyLlxuICAgICAgdGhpcy5zdXJyb2dhdGVTaXplID0gMztcbiAgICAgIHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aGlzLndyaXRlID0gcGFzc1Rocm91Z2hXcml0ZTtcbiAgICAgIHJldHVybjtcbiAgfVxuXG4gIHRoaXMuY2hhckJ1ZmZlciA9IG5ldyBCdWZmZXIoNik7XG4gIHRoaXMuY2hhclJlY2VpdmVkID0gMDtcbiAgdGhpcy5jaGFyTGVuZ3RoID0gMDtcbn07XG5cblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIGNoYXJTdHIgPSAnJztcbiAgdmFyIG9mZnNldCA9IDA7XG5cbiAgLy8gaWYgb3VyIGxhc3Qgd3JpdGUgZW5kZWQgd2l0aCBhbiBpbmNvbXBsZXRlIG11bHRpYnl0ZSBjaGFyYWN0ZXJcbiAgd2hpbGUgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGRldGVybWluZSBob3cgbWFueSByZW1haW5pbmcgYnl0ZXMgdGhpcyBidWZmZXIgaGFzIHRvIG9mZmVyIGZvciB0aGlzIGNoYXJcbiAgICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IHRoaXMuY2hhckxlbmd0aCAtIHRoaXMuY2hhclJlY2VpdmVkKSA/XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQgOlxuICAgICAgICAgICAgICAgIGJ1ZmZlci5sZW5ndGg7XG5cbiAgICAvLyBhZGQgdGhlIG5ldyBieXRlcyB0byB0aGUgY2hhciBidWZmZXJcbiAgICBidWZmZXIuY29weSh0aGlzLmNoYXJCdWZmZXIsIHRoaXMuY2hhclJlY2VpdmVkLCBvZmZzZXQsIGkpO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IChpIC0gb2Zmc2V0KTtcbiAgICBvZmZzZXQgPSBpO1xuXG4gICAgaWYgKHRoaXMuY2hhclJlY2VpdmVkIDwgdGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgICAvLyBzdGlsbCBub3QgZW5vdWdoIGNoYXJzIGluIHRoaXMgYnVmZmVyPyB3YWl0IGZvciBtb3JlIC4uLlxuICAgICAgcmV0dXJuICcnO1xuICAgIH1cblxuICAgIC8vIGdldCB0aGUgY2hhcmFjdGVyIHRoYXQgd2FzIHNwbGl0XG4gICAgY2hhclN0ciA9IHRoaXMuY2hhckJ1ZmZlci5zbGljZSgwLCB0aGlzLmNoYXJMZW5ndGgpLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xuXG4gICAgLy8gbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoY2hhclN0ci5sZW5ndGggLSAxKTtcbiAgICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoICs9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICAgIGNoYXJTdHIgPSAnJztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IHRoaXMuY2hhckxlbmd0aCA9IDA7XG5cbiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gbW9yZSBieXRlcyBpbiB0aGlzIGJ1ZmZlciwganVzdCBlbWl0IG91ciBjaGFyXG4gICAgaWYgKGkgPT0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuIGNoYXJTdHI7XG5cbiAgICAvLyBvdGhlcndpc2UgY3V0IG9mZiB0aGUgY2hhcmFjdGVycyBlbmQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgYnVmZmVyXG4gICAgYnVmZmVyID0gYnVmZmVyLnNsaWNlKGksIGJ1ZmZlci5sZW5ndGgpO1xuICAgIGJyZWFrO1xuICB9XG5cbiAgdmFyIGxlbkluY29tcGxldGUgPSB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcik7XG5cbiAgdmFyIGVuZCA9IGJ1ZmZlci5sZW5ndGg7XG4gIGlmICh0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAvLyBidWZmZXIgdGhlIGluY29tcGxldGUgY2hhcmFjdGVyIGJ5dGVzIHdlIGdvdFxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgMCwgYnVmZmVyLmxlbmd0aCAtIGxlbkluY29tcGxldGUsIGVuZCk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgPSBsZW5JbmNvbXBsZXRlO1xuICAgIGVuZCAtPSBsZW5JbmNvbXBsZXRlO1xuICB9XG5cbiAgY2hhclN0ciArPSBidWZmZXIudG9TdHJpbmcodGhpcy5lbmNvZGluZywgMCwgZW5kKTtcblxuICB2YXIgZW5kID0gY2hhclN0ci5sZW5ndGggLSAxO1xuICB2YXIgY2hhckNvZGUgPSBjaGFyU3RyLmNoYXJDb2RlQXQoZW5kKTtcbiAgLy8gbGVhZCBzdXJyb2dhdGUgKEQ4MDAtREJGRikgaXMgYWxzbyB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXJcbiAgaWYgKGNoYXJDb2RlID49IDB4RDgwMCAmJiBjaGFyQ29kZSA8PSAweERCRkYpIHtcbiAgICB2YXIgc2l6ZSA9IHRoaXMuc3Vycm9nYXRlU2l6ZTtcbiAgICB0aGlzLmNoYXJMZW5ndGggKz0gc2l6ZTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCArPSBzaXplO1xuICAgIHRoaXMuY2hhckJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgc2l6ZSwgMCwgc2l6ZSk7XG4gICAgdGhpcy5jaGFyQnVmZmVyLndyaXRlKGNoYXJTdHIuY2hhckF0KGNoYXJTdHIubGVuZ3RoIC0gMSksIHRoaXMuZW5jb2RpbmcpO1xuICAgIHJldHVybiBjaGFyU3RyLnN1YnN0cmluZygwLCBlbmQpO1xuICB9XG5cbiAgLy8gb3IganVzdCBlbWl0IHRoZSBjaGFyU3RyXG4gIHJldHVybiBjaGFyU3RyO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZGV0ZWN0SW5jb21wbGV0ZUNoYXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IGJ5dGVzIHdlIGhhdmUgdG8gY2hlY2sgYXQgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlclxuICB2YXIgaSA9IChidWZmZXIubGVuZ3RoID49IDMpID8gMyA6IGJ1ZmZlci5sZW5ndGg7XG5cbiAgLy8gRmlndXJlIG91dCBpZiBvbmUgb2YgdGhlIGxhc3QgaSBieXRlcyBvZiBvdXIgYnVmZmVyIGFubm91bmNlcyBhblxuICAvLyBpbmNvbXBsZXRlIGNoYXIuXG4gIGZvciAoOyBpID4gMDsgaS0tKSB7XG4gICAgdmFyIGMgPSBidWZmZXJbYnVmZmVyLmxlbmd0aCAtIGldO1xuXG4gICAgLy8gU2VlIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvVVRGLTgjRGVzY3JpcHRpb25cblxuICAgIC8vIDExMFhYWFhYXG4gICAgaWYgKGkgPT0gMSAmJiBjID4+IDUgPT0gMHgwNikge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMjtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTBYWFhYXG4gICAgaWYgKGkgPD0gMiAmJiBjID4+IDQgPT0gMHgwRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gMztcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIDExMTEwWFhYXG4gICAgaWYgKGkgPD0gMyAmJiBjID4+IDMgPT0gMHgxRSkge1xuICAgICAgdGhpcy5jaGFyTGVuZ3RoID0gNDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpO1xufTtcblxuU3RyaW5nRGVjb2Rlci5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gIHZhciByZXMgPSAnJztcbiAgaWYgKGJ1ZmZlciAmJiBidWZmZXIubGVuZ3RoKVxuICAgIHJlcyA9IHRoaXMud3JpdGUoYnVmZmVyKTtcblxuICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQpIHtcbiAgICB2YXIgY3IgPSB0aGlzLmNoYXJSZWNlaXZlZDtcbiAgICB2YXIgYnVmID0gdGhpcy5jaGFyQnVmZmVyO1xuICAgIHZhciBlbmMgPSB0aGlzLmVuY29kaW5nO1xuICAgIHJlcyArPSBidWYuc2xpY2UoMCwgY3IpLnRvU3RyaW5nKGVuYyk7XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblxuZnVuY3Rpb24gcGFzc1Rocm91Z2hXcml0ZShidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nKTtcbn1cblxuZnVuY3Rpb24gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdmFyIGluY29tcGxldGUgPSB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAyO1xuICB0aGlzLmNoYXJMZW5ndGggPSBpbmNvbXBsZXRlID8gMiA6IDA7XG4gIHJldHVybiBpbmNvbXBsZXRlO1xufVxuXG5mdW5jdGlvbiBiYXNlNjREZXRlY3RJbmNvbXBsZXRlQ2hhcihidWZmZXIpIHtcbiAgdmFyIGluY29tcGxldGUgPSB0aGlzLmNoYXJSZWNlaXZlZCA9IGJ1ZmZlci5sZW5ndGggJSAzO1xuICB0aGlzLmNoYXJMZW5ndGggPSBpbmNvbXBsZXRlID8gMyA6IDA7XG4gIHJldHVybiBpbmNvbXBsZXRlO1xufVxuIiwidHJ5IHtcbiAgICAvLyBPbGQgSUUgYnJvd3NlcnMgdGhhdCBkbyBub3QgY3VycnkgYXJndW1lbnRzXG4gICAgaWYgKCFzZXRUaW1lb3V0LmNhbGwpIHtcbiAgICAgICAgdmFyIHNsaWNlciA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbiAgICAgICAgZXhwb3J0cy5zZXRUaW1lb3V0ID0gZnVuY3Rpb24oZm4pIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gc2xpY2VyLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH07XG5cbiAgICAgICAgZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGZ1bmN0aW9uKGZuKSB7XG4gICAgICAgICAgICB2YXIgYXJncyA9IHNsaWNlci5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZXhwb3J0cy5zZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgICAgZXhwb3J0cy5zZXRJbnRlcnZhbCA9IHNldEludGVydmFsO1xuICAgIH1cbiAgICBleHBvcnRzLmNsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICBleHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBjbGVhckludGVydmFsO1xuXG4gICAgaWYgKHdpbmRvdy5zZXRJbW1lZGlhdGUpIHtcbiAgICAgIGV4cG9ydHMuc2V0SW1tZWRpYXRlID0gd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICAgIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSB3aW5kb3cuY2xlYXJJbW1lZGlhdGU7XG4gICAgfVxuXG4gICAgLy8gQ2hyb21lIGFuZCBQaGFudG9tSlMgc2VlbXMgdG8gZGVwZW5kIG9uIGB0aGlzYCBwc2V1ZG8gdmFyaWFibGUgYmVpbmcgYVxuICAgIC8vIGB3aW5kb3dgIGFuZCB0aHJvd3MgaW52YWxpZCBpbnZvY2F0aW9uIGV4Y2VwdGlvbiBvdGhlcndpc2UuIElmIHRoaXMgY29kZVxuICAgIC8vIHJ1bnMgaW4gc3VjaCBKUyBydW50aW1lIG5leHQgbGluZSB3aWxsIHRocm93IGFuZCBgY2F0Y2hgIGNsYXVzZSB3aWxsXG4gICAgLy8gZXhwb3J0ZWQgdGltZXJzIGZ1bmN0aW9ucyBib3VuZCB0byBhIHdpbmRvdy5cbiAgICBleHBvcnRzLnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7fSk7XG59IGNhdGNoIChfKSB7XG4gICAgZnVuY3Rpb24gYmluZChmLCBjb250ZXh0KSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7IHJldHVybiBmLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cykgfTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGV4cG9ydHMuc2V0VGltZW91dCA9IGJpbmQoc2V0VGltZW91dCwgd2luZG93KTtcbiAgICAgIGV4cG9ydHMuc2V0SW50ZXJ2YWwgPSBiaW5kKHNldEludGVydmFsLCB3aW5kb3cpO1xuICAgICAgZXhwb3J0cy5jbGVhclRpbWVvdXQgPSBiaW5kKGNsZWFyVGltZW91dCwgd2luZG93KTtcbiAgICAgIGV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGJpbmQoY2xlYXJJbnRlcnZhbCwgd2luZG93KTtcbiAgICAgIGlmICh3aW5kb3cuc2V0SW1tZWRpYXRlKSB7XG4gICAgICAgIGV4cG9ydHMuc2V0SW1tZWRpYXRlID0gYmluZCh3aW5kb3cuc2V0SW1tZWRpYXRlLCB3aW5kb3cpO1xuICAgICAgICBleHBvcnRzLmNsZWFySW1tZWRpYXRlID0gYmluZCh3aW5kb3cuY2xlYXJJbW1lZGlhdGUsIHdpbmRvdyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0eXBlb2Ygc2V0VGltZW91dCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZXhwb3J0cy5zZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygc2V0SW50ZXJ2YWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGV4cG9ydHMuc2V0SW50ZXJ2YWwgPSBzZXRJbnRlcnZhbDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgY2xlYXJUaW1lb3V0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzLmNsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgY2xlYXJJbnRlcnZhbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBleHBvcnRzLmNsZWFySW50ZXJ2YWwgPSBjbGVhckludGVydmFsO1xuICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0cy51bnJlZiA9IGZ1bmN0aW9uIHVucmVmKCkge307XG5leHBvcnRzLnJlZiA9IGZ1bmN0aW9uIHJlZigpIHt9O1xuXG5pZiAoIWV4cG9ydHMuc2V0SW1tZWRpYXRlKSB7XG4gIHZhciBjdXJyZW50S2V5ID0gMCwgcXVldWUgPSB7fSwgYWN0aXZlID0gZmFsc2U7XG5cbiAgZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgZnVuY3Rpb24gZHJhaW4oKSB7XG4gICAgICAgIGFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICBmb3IgKHZhciBrZXkgaW4gcXVldWUpIHtcbiAgICAgICAgICBpZiAocXVldWUuaGFzT3duUHJvcGVydHkoY3VycmVudEtleSwga2V5KSkge1xuICAgICAgICAgICAgdmFyIGZuID0gcXVldWVba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBxdWV1ZVtrZXldO1xuICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgaWYgKGV2LnNvdXJjZSA9PT0gd2luZG93ICYmIGV2LmRhdGEgPT09ICdicm93c2VyaWZ5LXRpY2snKSB7XG4gICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGRyYWluKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKSB7XG4gICAgICAgICAgdmFyIGlkID0gKytjdXJyZW50S2V5O1xuICAgICAgICAgIHF1ZXVlW2lkXSA9IGZuO1xuICAgICAgICAgIGlmICghYWN0aXZlKSB7XG4gICAgICAgICAgICBhY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdicm93c2VyaWZ5LXRpY2snLCAnKicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaWQ7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gc2V0SW1tZWRpYXRlKGZuKSB7XG4gICAgICAgICAgdmFyIGlkID0gKytjdXJyZW50S2V5O1xuICAgICAgICAgIHF1ZXVlW2lkXSA9IGZuO1xuICAgICAgICAgIGlmICghYWN0aXZlKSB7XG4gICAgICAgICAgICBhY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgc2V0VGltZW91dChkcmFpbiwgMCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpZDtcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgfSkoKTtcblxuICBleHBvcnRzLmNsZWFySW1tZWRpYXRlID0gZnVuY3Rpb24gY2xlYXJJbW1lZGlhdGUoaWQpIHtcbiAgICBkZWxldGUgcXVldWVbaWRdO1xuICB9O1xufVxuIiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBwdW55Y29kZSA9IHsgZW5jb2RlIDogZnVuY3Rpb24gKHMpIHsgcmV0dXJuIHMgfSB9O1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcblxuZXhwb3J0cy5wYXJzZSA9IHVybFBhcnNlO1xuZXhwb3J0cy5yZXNvbHZlID0gdXJsUmVzb2x2ZTtcbmV4cG9ydHMucmVzb2x2ZU9iamVjdCA9IHVybFJlc29sdmVPYmplY3Q7XG5leHBvcnRzLmZvcm1hdCA9IHVybEZvcm1hdDtcblxuZXhwb3J0cy5VcmwgPSBVcmw7XG5cbmZ1bmN0aW9uIFVybCgpIHtcbiAgdGhpcy5wcm90b2NvbCA9IG51bGw7XG4gIHRoaXMuc2xhc2hlcyA9IG51bGw7XG4gIHRoaXMuYXV0aCA9IG51bGw7XG4gIHRoaXMuaG9zdCA9IG51bGw7XG4gIHRoaXMucG9ydCA9IG51bGw7XG4gIHRoaXMuaG9zdG5hbWUgPSBudWxsO1xuICB0aGlzLmhhc2ggPSBudWxsO1xuICB0aGlzLnNlYXJjaCA9IG51bGw7XG4gIHRoaXMucXVlcnkgPSBudWxsO1xuICB0aGlzLnBhdGhuYW1lID0gbnVsbDtcbiAgdGhpcy5wYXRoID0gbnVsbDtcbiAgdGhpcy5ocmVmID0gbnVsbDtcbn1cblxuLy8gUmVmZXJlbmNlOiBSRkMgMzk4NiwgUkZDIDE4MDgsIFJGQyAyMzk2XG5cbi8vIGRlZmluZSB0aGVzZSBoZXJlIHNvIGF0IGxlYXN0IHRoZXkgb25seSBoYXZlIHRvIGJlXG4vLyBjb21waWxlZCBvbmNlIG9uIHRoZSBmaXJzdCBtb2R1bGUgbG9hZC5cbnZhciBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pLFxuICAgIHBvcnRQYXR0ZXJuID0gLzpbMC05XSokLyxcblxuICAgIC8vIFJGQyAyMzk2OiBjaGFyYWN0ZXJzIHJlc2VydmVkIGZvciBkZWxpbWl0aW5nIFVSTHMuXG4gICAgLy8gV2UgYWN0dWFsbHkganVzdCBhdXRvLWVzY2FwZSB0aGVzZS5cbiAgICBkZWxpbXMgPSBbJzwnLCAnPicsICdcIicsICdgJywgJyAnLCAnXFxyJywgJ1xcbicsICdcXHQnXSxcblxuICAgIC8vIFJGQyAyMzk2OiBjaGFyYWN0ZXJzIG5vdCBhbGxvd2VkIGZvciB2YXJpb3VzIHJlYXNvbnMuXG4gICAgdW53aXNlID0gWyd7JywgJ30nLCAnfCcsICdcXFxcJywgJ14nLCAnYCddLmNvbmNhdChkZWxpbXMpLFxuXG4gICAgLy8gQWxsb3dlZCBieSBSRkNzLCBidXQgY2F1c2Ugb2YgWFNTIGF0dGFja3MuICBBbHdheXMgZXNjYXBlIHRoZXNlLlxuICAgIGF1dG9Fc2NhcGUgPSBbJ1xcJyddLmNvbmNhdCh1bndpc2UpLFxuICAgIC8vIENoYXJhY3RlcnMgdGhhdCBhcmUgbmV2ZXIgZXZlciBhbGxvd2VkIGluIGEgaG9zdG5hbWUuXG4gICAgLy8gTm90ZSB0aGF0IGFueSBpbnZhbGlkIGNoYXJzIGFyZSBhbHNvIGhhbmRsZWQsIGJ1dCB0aGVzZVxuICAgIC8vIGFyZSB0aGUgb25lcyB0aGF0IGFyZSAqZXhwZWN0ZWQqIHRvIGJlIHNlZW4sIHNvIHdlIGZhc3QtcGF0aFxuICAgIC8vIHRoZW0uXG4gICAgbm9uSG9zdENoYXJzID0gWyclJywgJy8nLCAnPycsICc7JywgJyMnXS5jb25jYXQoYXV0b0VzY2FwZSksXG4gICAgaG9zdEVuZGluZ0NoYXJzID0gWycvJywgJz8nLCAnIyddLFxuICAgIGhvc3RuYW1lTWF4TGVuID0gMjU1LFxuICAgIGhvc3RuYW1lUGFydFBhdHRlcm4gPSAvXlthLXowLTlBLVpfLV17MCw2M30kLyxcbiAgICBob3N0bmFtZVBhcnRTdGFydCA9IC9eKFthLXowLTlBLVpfLV17MCw2M30pKC4qKSQvLFxuICAgIC8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuICAgIHVuc2FmZVByb3RvY29sID0ge1xuICAgICAgJ2phdmFzY3JpcHQnOiB0cnVlLFxuICAgICAgJ2phdmFzY3JpcHQ6JzogdHJ1ZVxuICAgIH0sXG4gICAgLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuICAgIGhvc3RsZXNzUHJvdG9jb2wgPSB7XG4gICAgICAnamF2YXNjcmlwdCc6IHRydWUsXG4gICAgICAnamF2YXNjcmlwdDonOiB0cnVlXG4gICAgfSxcbiAgICAvLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbiAgICBzbGFzaGVkUHJvdG9jb2wgPSB7XG4gICAgICAnaHR0cCc6IHRydWUsXG4gICAgICAnaHR0cHMnOiB0cnVlLFxuICAgICAgJ2Z0cCc6IHRydWUsXG4gICAgICAnZ29waGVyJzogdHJ1ZSxcbiAgICAgICdmaWxlJzogdHJ1ZSxcbiAgICAgICdodHRwOic6IHRydWUsXG4gICAgICAnaHR0cHM6JzogdHJ1ZSxcbiAgICAgICdmdHA6JzogdHJ1ZSxcbiAgICAgICdnb3BoZXI6JzogdHJ1ZSxcbiAgICAgICdmaWxlOic6IHRydWVcbiAgICB9LFxuICAgIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKTtcblxuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsICYmIHV0aWwuaXNPYmplY3QodXJsKSAmJiB1cmwgaW5zdGFuY2VvZiBVcmwpIHJldHVybiB1cmw7XG5cbiAgdmFyIHUgPSBuZXcgVXJsO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuVXJsLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpIHtcbiAgaWYgKCF1dGlsLmlzU3RyaW5nKHVybCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFyYW1ldGVyICd1cmwnIG11c3QgYmUgYSBzdHJpbmcsIG5vdCBcIiArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgdmFyIHJlc3QgPSB1cmw7XG5cbiAgLy8gdHJpbSBiZWZvcmUgcHJvY2VlZGluZy5cbiAgLy8gVGhpcyBpcyB0byBzdXBwb3J0IHBhcnNlIHN0dWZmIGxpa2UgXCIgIGh0dHA6Ly9mb28uY29tICBcXG5cIlxuICByZXN0ID0gc2hpbXMudHJpbShyZXN0KTtcblxuICB2YXIgcHJvdG8gPSBwcm90b2NvbFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgaWYgKHByb3RvKSB7XG4gICAgcHJvdG8gPSBwcm90b1swXTtcbiAgICB2YXIgbG93ZXJQcm90byA9IHByb3RvLnRvTG93ZXJDYXNlKCk7XG4gICAgdGhpcy5wcm90b2NvbCA9IGxvd2VyUHJvdG87XG4gICAgcmVzdCA9IHJlc3Quc3Vic3RyKHByb3RvLmxlbmd0aCk7XG4gIH1cblxuICAvLyBmaWd1cmUgb3V0IGlmIGl0J3MgZ290IGEgaG9zdFxuICAvLyB1c2VyQHNlcnZlciBpcyAqYWx3YXlzKiBpbnRlcnByZXRlZCBhcyBhIGhvc3RuYW1lLCBhbmQgdXJsXG4gIC8vIHJlc29sdXRpb24gd2lsbCB0cmVhdCAvL2Zvby9iYXIgYXMgaG9zdD1mb28scGF0aD1iYXIgYmVjYXVzZSB0aGF0J3NcbiAgLy8gaG93IHRoZSBicm93c2VyIHJlc29sdmVzIHJlbGF0aXZlIFVSTHMuXG4gIGlmIChzbGFzaGVzRGVub3RlSG9zdCB8fCBwcm90byB8fCByZXN0Lm1hdGNoKC9eXFwvXFwvW15AXFwvXStAW15AXFwvXSsvKSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5zdWJzdHIoMCwgMikgPT09ICcvLyc7XG4gICAgaWYgKHNsYXNoZXMgJiYgIShwcm90byAmJiBob3N0bGVzc1Byb3RvY29sW3Byb3RvXSkpIHtcbiAgICAgIHJlc3QgPSByZXN0LnN1YnN0cigyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJlxuICAgICAgKHNsYXNoZXMgfHwgKHByb3RvICYmICFzbGFzaGVkUHJvdG9jb2xbcHJvdG9dKSkpIHtcblxuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YyBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgLy8gZmluZCB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgYW55IGhvc3RFbmRpbmdDaGFyc1xuICAgIHZhciBob3N0RW5kID0gLTE7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBob3N0RW5kaW5nQ2hhcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBoZWMgPSByZXN0LmluZGV4T2YoaG9zdEVuZGluZ0NoYXJzW2ldKTtcbiAgICAgIGlmIChoZWMgIT09IC0xICYmIChob3N0RW5kID09PSAtMSB8fCBoZWMgPCBob3N0RW5kKSlcbiAgICAgICAgaG9zdEVuZCA9IGhlYztcbiAgICB9XG5cbiAgICAvLyBhdCB0aGlzIHBvaW50LCBlaXRoZXIgd2UgaGF2ZSBhbiBleHBsaWNpdCBwb2ludCB3aGVyZSB0aGVcbiAgICAvLyBhdXRoIHBvcnRpb24gY2Fubm90IGdvIHBhc3QsIG9yIHRoZSBsYXN0IEAgY2hhciBpcyB0aGUgZGVjaWRlci5cbiAgICB2YXIgYXV0aCwgYXRTaWduO1xuICAgIGlmIChob3N0RW5kID09PSAtMSkge1xuICAgICAgLy8gYXRTaWduIGNhbiBiZSBhbnl3aGVyZS5cbiAgICAgIGF0U2lnbiA9IHJlc3QubGFzdEluZGV4T2YoJ0AnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYXRTaWduIG11c3QgYmUgaW4gYXV0aCBwb3J0aW9uLlxuICAgICAgLy8gaHR0cDovL2FAYi9jQGQgPT4gaG9zdDpiIGF1dGg6YSBwYXRoOi9jQGRcbiAgICAgIGF0U2lnbiA9IHJlc3QubGFzdEluZGV4T2YoJ0AnLCBob3N0RW5kKTtcbiAgICB9XG5cbiAgICAvLyBOb3cgd2UgaGF2ZSBhIHBvcnRpb24gd2hpY2ggaXMgZGVmaW5pdGVseSB0aGUgYXV0aC5cbiAgICAvLyBQdWxsIHRoYXQgb2ZmLlxuICAgIGlmIChhdFNpZ24gIT09IC0xKSB7XG4gICAgICBhdXRoID0gcmVzdC5zbGljZSgwLCBhdFNpZ24pO1xuICAgICAgcmVzdCA9IHJlc3Quc2xpY2UoYXRTaWduICsgMSk7XG4gICAgICB0aGlzLmF1dGggPSBkZWNvZGVVUklDb21wb25lbnQoYXV0aCk7XG4gICAgfVxuXG4gICAgLy8gdGhlIGhvc3QgaXMgdGhlIHJlbWFpbmluZyB0byB0aGUgbGVmdCBvZiB0aGUgZmlyc3Qgbm9uLWhvc3QgY2hhclxuICAgIGhvc3RFbmQgPSAtMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vbkhvc3RDaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhlYyA9IHJlc3QuaW5kZXhPZihub25Ib3N0Q2hhcnNbaV0pO1xuICAgICAgaWYgKGhlYyAhPT0gLTEgJiYgKGhvc3RFbmQgPT09IC0xIHx8IGhlYyA8IGhvc3RFbmQpKVxuICAgICAgICBob3N0RW5kID0gaGVjO1xuICAgIH1cbiAgICAvLyBpZiB3ZSBzdGlsbCBoYXZlIG5vdCBoaXQgaXQsIHRoZW4gdGhlIGVudGlyZSB0aGluZyBpcyBhIGhvc3QuXG4gICAgaWYgKGhvc3RFbmQgPT09IC0xKVxuICAgICAgaG9zdEVuZCA9IHJlc3QubGVuZ3RoO1xuXG4gICAgdGhpcy5ob3N0ID0gcmVzdC5zbGljZSgwLCBob3N0RW5kKTtcbiAgICByZXN0ID0gcmVzdC5zbGljZShob3N0RW5kKTtcblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcblxuICAgIC8vIGlmIGhvc3RuYW1lIGJlZ2lucyB3aXRoIFsgYW5kIGVuZHMgd2l0aCBdXG4gICAgLy8gYXNzdW1lIHRoYXQgaXQncyBhbiBJUHY2IGFkZHJlc3MuXG4gICAgdmFyIGlwdjZIb3N0bmFtZSA9IHRoaXMuaG9zdG5hbWVbMF0gPT09ICdbJyAmJlxuICAgICAgICB0aGlzLmhvc3RuYW1lW3RoaXMuaG9zdG5hbWUubGVuZ3RoIC0gMV0gPT09ICddJztcblxuICAgIC8vIHZhbGlkYXRlIGEgbGl0dGxlLlxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICB2YXIgaG9zdHBhcnRzID0gdGhpcy5ob3N0bmFtZS5zcGxpdCgvXFwuLyk7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGhvc3RwYXJ0cy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgdmFyIHBhcnQgPSBob3N0cGFydHNbaV07XG4gICAgICAgIGlmICghcGFydCkgY29udGludWU7XG4gICAgICAgIGlmICghcGFydC5tYXRjaChob3N0bmFtZVBhcnRQYXR0ZXJuKSkge1xuICAgICAgICAgIHZhciBuZXdwYXJ0ID0gJyc7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGsgPSBwYXJ0Lmxlbmd0aDsgaiA8IGs7IGorKykge1xuICAgICAgICAgICAgaWYgKHBhcnQuY2hhckNvZGVBdChqKSA+IDEyNykge1xuICAgICAgICAgICAgICAvLyB3ZSByZXBsYWNlIG5vbi1BU0NJSSBjaGFyIHdpdGggYSB0ZW1wb3JhcnkgcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0aGlzIHRvIG1ha2Ugc3VyZSBzaXplIG9mIGhvc3RuYW1lIGlzIG5vdFxuICAgICAgICAgICAgICAvLyBicm9rZW4gYnkgcmVwbGFjaW5nIG5vbi1BU0NJSSBieSBub3RoaW5nXG4gICAgICAgICAgICAgIG5ld3BhcnQgKz0gJ3gnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbmV3cGFydCArPSBwYXJ0W2pdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyB3ZSB0ZXN0IGFnYWluIHdpdGggQVNDSUkgY2hhciBvbmx5XG4gICAgICAgICAgaWYgKCFuZXdwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFBhdHRlcm4pKSB7XG4gICAgICAgICAgICB2YXIgdmFsaWRQYXJ0cyA9IGhvc3RwYXJ0cy5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgIHZhciBub3RIb3N0ID0gaG9zdHBhcnRzLnNsaWNlKGkgKyAxKTtcbiAgICAgICAgICAgIHZhciBiaXQgPSBwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFN0YXJ0KTtcbiAgICAgICAgICAgIGlmIChiaXQpIHtcbiAgICAgICAgICAgICAgdmFsaWRQYXJ0cy5wdXNoKGJpdFsxXSk7XG4gICAgICAgICAgICAgIG5vdEhvc3QudW5zaGlmdChiaXRbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vdEhvc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc3QgPSAnLycgKyBub3RIb3N0LmpvaW4oJy4nKSArIHJlc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmhvc3RuYW1lID0gdmFsaWRQYXJ0cy5qb2luKCcuJyk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5ob3N0bmFtZS5sZW5ndGggPiBob3N0bmFtZU1heExlbikge1xuICAgICAgdGhpcy5ob3N0bmFtZSA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBob3N0bmFtZXMgYXJlIGFsd2F5cyBsb3dlciBjYXNlLlxuICAgICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICB9XG5cbiAgICBpZiAoIWlwdjZIb3N0bmFtZSkge1xuICAgICAgLy8gSUROQSBTdXBwb3J0OiBSZXR1cm5zIGEgcHVueSBjb2RlZCByZXByZXNlbnRhdGlvbiBvZiBcImRvbWFpblwiLlxuICAgICAgLy8gSXQgb25seSBjb252ZXJ0cyB0aGUgcGFydCBvZiB0aGUgZG9tYWluIG5hbWUgdGhhdFxuICAgICAgLy8gaGFzIG5vbiBBU0NJSSBjaGFyYWN0ZXJzLiBJLmUuIGl0IGRvc2VudCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIGluIEFTQ0lJLlxuICAgICAgdmFyIGRvbWFpbkFycmF5ID0gdGhpcy5ob3N0bmFtZS5zcGxpdCgnLicpO1xuICAgICAgdmFyIG5ld091dCA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb21haW5BcnJheS5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgcyA9IGRvbWFpbkFycmF5W2ldO1xuICAgICAgICBuZXdPdXQucHVzaChzLm1hdGNoKC9bXkEtWmEtejAtOV8tXS8pID9cbiAgICAgICAgICAgICd4bi0tJyArIHB1bnljb2RlLmVuY29kZShzKSA6IHMpO1xuICAgICAgfVxuICAgICAgdGhpcy5ob3N0bmFtZSA9IG5ld091dC5qb2luKCcuJyk7XG4gICAgfVxuXG4gICAgdmFyIHAgPSB0aGlzLnBvcnQgPyAnOicgKyB0aGlzLnBvcnQgOiAnJztcbiAgICB2YXIgaCA9IHRoaXMuaG9zdG5hbWUgfHwgJyc7XG4gICAgdGhpcy5ob3N0ID0gaCArIHA7XG4gICAgdGhpcy5ocmVmICs9IHRoaXMuaG9zdDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnN1YnN0cigxLCB0aGlzLmhvc3RuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgaWYgKHJlc3RbMF0gIT09ICcvJykge1xuICAgICAgICByZXN0ID0gJy8nICsgcmVzdDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBub3cgcmVzdCBpcyBzZXQgdG8gdGhlIHBvc3QtaG9zdCBzdHVmZi5cbiAgLy8gY2hvcCBvZmYgYW55IGRlbGltIGNoYXJzLlxuICBpZiAoIXVuc2FmZVByb3RvY29sW2xvd2VyUHJvdG9dKSB7XG5cbiAgICAvLyBGaXJzdCwgbWFrZSAxMDAlIHN1cmUgdGhhdCBhbnkgXCJhdXRvRXNjYXBlXCIgY2hhcnMgZ2V0XG4gICAgLy8gZXNjYXBlZCwgZXZlbiBpZiBlbmNvZGVVUklDb21wb25lbnQgZG9lc24ndCB0aGluayB0aGV5XG4gICAgLy8gbmVlZCB0byBiZS5cbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IGF1dG9Fc2NhcGUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICB2YXIgYWUgPSBhdXRvRXNjYXBlW2ldO1xuICAgICAgdmFyIGVzYyA9IGVuY29kZVVSSUNvbXBvbmVudChhZSk7XG4gICAgICBpZiAoZXNjID09PSBhZSkge1xuICAgICAgICBlc2MgPSBlc2NhcGUoYWUpO1xuICAgICAgfVxuICAgICAgcmVzdCA9IHJlc3Quc3BsaXQoYWUpLmpvaW4oZXNjKTtcbiAgICB9XG4gIH1cblxuXG4gIC8vIGNob3Agb2ZmIGZyb20gdGhlIHRhaWwgZmlyc3QuXG4gIHZhciBoYXNoID0gcmVzdC5pbmRleE9mKCcjJyk7XG4gIGlmIChoYXNoICE9PSAtMSkge1xuICAgIC8vIGdvdCBhIGZyYWdtZW50IHN0cmluZy5cbiAgICB0aGlzLmhhc2ggPSByZXN0LnN1YnN0cihoYXNoKTtcbiAgICByZXN0ID0gcmVzdC5zbGljZSgwLCBoYXNoKTtcbiAgfVxuICB2YXIgcW0gPSByZXN0LmluZGV4T2YoJz8nKTtcbiAgaWYgKHFtICE9PSAtMSkge1xuICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zdWJzdHIocW0pO1xuICAgIHRoaXMucXVlcnkgPSByZXN0LnN1YnN0cihxbSArIDEpO1xuICAgIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5xdWVyeSk7XG4gICAgfVxuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIHFtKTtcbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuICBpZiAocmVzdCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiZcbiAgICAgIHRoaXMuaG9zdG5hbWUgJiYgIXRoaXMucGF0aG5hbWUpIHtcbiAgICB0aGlzLnBhdGhuYW1lID0gJy8nO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIHZhciBwID0gdGhpcy5wYXRobmFtZSB8fCAnJztcbiAgICB2YXIgcyA9IHRoaXMuc2VhcmNoIHx8ICcnO1xuICAgIHRoaXMucGF0aCA9IHAgKyBzO1xuICB9XG5cbiAgLy8gZmluYWxseSwgcmVjb25zdHJ1Y3QgdGhlIGhyZWYgYmFzZWQgb24gd2hhdCBoYXMgYmVlbiB2YWxpZGF0ZWQuXG4gIHRoaXMuaHJlZiA9IHRoaXMuZm9ybWF0KCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuZnVuY3Rpb24gdXJsRm9ybWF0KG9iaikge1xuICAvLyBlbnN1cmUgaXQncyBhbiBvYmplY3QsIGFuZCBub3QgYSBzdHJpbmcgdXJsLlxuICAvLyBJZiBpdCdzIGFuIG9iaiwgdGhpcyBpcyBhIG5vLW9wLlxuICAvLyB0aGlzIHdheSwgeW91IGNhbiBjYWxsIHVybF9mb3JtYXQoKSBvbiBzdHJpbmdzXG4gIC8vIHRvIGNsZWFuIHVwIHBvdGVudGlhbGx5IHdvbmt5IHVybHMuXG4gIGlmICh1dGlsLmlzU3RyaW5nKG9iaikpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG4gIHJldHVybiBvYmouZm9ybWF0KCk7XG59XG5cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhdXRoID0gdGhpcy5hdXRoIHx8ICcnO1xuICBpZiAoYXV0aCkge1xuICAgIGF1dGggPSBlbmNvZGVVUklDb21wb25lbnQoYXV0aCk7XG4gICAgYXV0aCA9IGF1dGgucmVwbGFjZSgvJTNBL2ksICc6Jyk7XG4gICAgYXV0aCArPSAnQCc7XG4gIH1cblxuICB2YXIgcHJvdG9jb2wgPSB0aGlzLnByb3RvY29sIHx8ICcnLFxuICAgICAgcGF0aG5hbWUgPSB0aGlzLnBhdGhuYW1lIHx8ICcnLFxuICAgICAgaGFzaCA9IHRoaXMuaGFzaCB8fCAnJyxcbiAgICAgIGhvc3QgPSBmYWxzZSxcbiAgICAgIHF1ZXJ5ID0gJyc7XG5cbiAgaWYgKHRoaXMuaG9zdCkge1xuICAgIGhvc3QgPSBhdXRoICsgdGhpcy5ob3N0O1xuICB9IGVsc2UgaWYgKHRoaXMuaG9zdG5hbWUpIHtcbiAgICBob3N0ID0gYXV0aCArICh0aGlzLmhvc3RuYW1lLmluZGV4T2YoJzonKSA9PT0gLTEgP1xuICAgICAgICB0aGlzLmhvc3RuYW1lIDpcbiAgICAgICAgJ1snICsgdGhpcy5ob3N0bmFtZSArICddJyk7XG4gICAgaWYgKHRoaXMucG9ydCkge1xuICAgICAgaG9zdCArPSAnOicgKyB0aGlzLnBvcnQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKHRoaXMucXVlcnkgJiZcbiAgICAgIHV0aWwuaXNPYmplY3QodGhpcy5xdWVyeSkgJiZcbiAgICAgIHNoaW1zLmtleXModGhpcy5xdWVyeSkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG4gIH1cblxuICB2YXIgc2VhcmNoID0gdGhpcy5zZWFyY2ggfHwgKHF1ZXJ5ICYmICgnPycgKyBxdWVyeSkpIHx8ICcnO1xuXG4gIGlmIChwcm90b2NvbCAmJiBzaGltcy5zdWJzdHIocHJvdG9jb2wsIC0xKSAhPT0gJzonKSBwcm90b2NvbCArPSAnOic7XG5cbiAgLy8gb25seSB0aGUgc2xhc2hlZFByb3RvY29scyBnZXQgdGhlIC8vLiAgTm90IG1haWx0bzosIHhtcHA6LCBldGMuXG4gIC8vIHVubGVzcyB0aGV5IGhhZCB0aGVtIHRvIGJlZ2luIHdpdGguXG4gIGlmICh0aGlzLnNsYXNoZXMgfHxcbiAgICAgICghcHJvdG9jb2wgfHwgc2xhc2hlZFByb3RvY29sW3Byb3RvY29sXSkgJiYgaG9zdCAhPT0gZmFsc2UpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckF0KDApICE9PSAnLycpIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJBdCgwKSAhPT0gJyMnKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckF0KDApICE9PSAnPycpIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICBwYXRobmFtZSA9IHBhdGhuYW1lLnJlcGxhY2UoL1s/I10vZywgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KG1hdGNoKTtcbiAgfSk7XG4gIHNlYXJjaCA9IHNlYXJjaC5yZXBsYWNlKCcjJywgJyUyMycpO1xuXG4gIHJldHVybiBwcm90b2NvbCArIGhvc3QgKyBwYXRobmFtZSArIHNlYXJjaCArIGhhc2g7XG59O1xuXG5mdW5jdGlvbiB1cmxSZXNvbHZlKHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmUocmVsYXRpdmUpO1xufVxuXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbihyZWxhdGl2ZSkge1xuICByZXR1cm4gdGhpcy5yZXNvbHZlT2JqZWN0KHVybFBhcnNlKHJlbGF0aXZlLCBmYWxzZSwgdHJ1ZSkpLmZvcm1hdCgpO1xufTtcblxuZnVuY3Rpb24gdXJsUmVzb2x2ZU9iamVjdChzb3VyY2UsIHJlbGF0aXZlKSB7XG4gIGlmICghc291cmNlKSByZXR1cm4gcmVsYXRpdmU7XG4gIHJldHVybiB1cmxQYXJzZShzb3VyY2UsIGZhbHNlLCB0cnVlKS5yZXNvbHZlT2JqZWN0KHJlbGF0aXZlKTtcbn1cblxuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24ocmVsYXRpdmUpIHtcbiAgaWYgKHV0aWwuaXNTdHJpbmcocmVsYXRpdmUpKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHNoaW1zLmZvckVhY2goc2hpbXMua2V5cyh0aGlzKSwgZnVuY3Rpb24oaykge1xuICAgIHJlc3VsdFtrXSA9IHRoaXNba107XG4gIH0sIHRoaXMpO1xuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgc2hpbXMuZm9yRWFjaChzaGltcy5rZXlzKHJlbGF0aXZlKSwgZnVuY3Rpb24oaykge1xuICAgICAgaWYgKGsgIT09ICdwcm90b2NvbCcpXG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgIH0pO1xuXG4gICAgLy91cmxQYXJzZSBhcHBlbmRzIHRyYWlsaW5nIC8gdG8gdXJscyBsaWtlIGh0dHA6Ly93d3cuZXhhbXBsZS5jb21cbiAgICBpZiAoc2xhc2hlZFByb3RvY29sW3Jlc3VsdC5wcm90b2NvbF0gJiZcbiAgICAgICAgcmVzdWx0Lmhvc3RuYW1lICYmICFyZXN1bHQucGF0aG5hbWUpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gcmVzdWx0LnBhdGhuYW1lID0gJy8nO1xuICAgIH1cblxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBpZiAocmVsYXRpdmUucHJvdG9jb2wgJiYgcmVsYXRpdmUucHJvdG9jb2wgIT09IHJlc3VsdC5wcm90b2NvbCkge1xuICAgIC8vIGlmIGl0J3MgYSBrbm93biB1cmwgcHJvdG9jb2wsIHRoZW4gY2hhbmdpbmdcbiAgICAvLyB0aGUgcHJvdG9jb2wgZG9lcyB3ZWlyZCB0aGluZ3NcbiAgICAvLyBmaXJzdCwgaWYgaXQncyBub3QgZmlsZTosIHRoZW4gd2UgTVVTVCBoYXZlIGEgaG9zdCxcbiAgICAvLyBhbmQgaWYgdGhlcmUgd2FzIGEgcGF0aFxuICAgIC8vIHRvIGJlZ2luIHdpdGgsIHRoZW4gd2UgTVVTVCBoYXZlIGEgcGF0aC5cbiAgICAvLyBpZiBpdCBpcyBmaWxlOiwgdGhlbiB0aGUgaG9zdCBpcyBkcm9wcGVkLFxuICAgIC8vIGJlY2F1c2UgdGhhdCdzIGtub3duIHRvIGJlIGhvc3RsZXNzLlxuICAgIC8vIGFueXRoaW5nIGVsc2UgaXMgYXNzdW1lZCB0byBiZSBhYnNvbHV0ZS5cbiAgICBpZiAoIXNsYXNoZWRQcm90b2NvbFtyZWxhdGl2ZS5wcm90b2NvbF0pIHtcbiAgICAgIHNoaW1zLmZvckVhY2goc2hpbXMua2V5cyhyZWxhdGl2ZSksIGZ1bmN0aW9uKGspIHtcbiAgICAgICAgcmVzdWx0W2tdID0gcmVsYXRpdmVba107XG4gICAgICB9KTtcbiAgICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICByZXN1bHQucHJvdG9jb2wgPSByZWxhdGl2ZS5wcm90b2NvbDtcbiAgICBpZiAoIXJlbGF0aXZlLmhvc3QgJiYgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIgcmVsUGF0aCA9IChyZWxhdGl2ZS5wYXRobmFtZSB8fCAnJykuc3BsaXQoJy8nKTtcbiAgICAgIHdoaWxlIChyZWxQYXRoLmxlbmd0aCAmJiAhKHJlbGF0aXZlLmhvc3QgPSByZWxQYXRoLnNoaWZ0KCkpKTtcbiAgICAgIGlmICghcmVsYXRpdmUuaG9zdCkgcmVsYXRpdmUuaG9zdCA9ICcnO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0bmFtZSkgcmVsYXRpdmUuaG9zdG5hbWUgPSAnJztcbiAgICAgIGlmIChyZWxQYXRoWzBdICE9PSAnJykgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIGlmIChyZWxQYXRoLmxlbmd0aCA8IDIpIHJlbFBhdGgudW5zaGlmdCgnJyk7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxQYXRoLmpvaW4oJy8nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0LnBhdGhuYW1lID0gcmVsYXRpdmUucGF0aG5hbWU7XG4gICAgfVxuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgcmVzdWx0Lmhvc3QgPSByZWxhdGl2ZS5ob3N0IHx8ICcnO1xuICAgIHJlc3VsdC5hdXRoID0gcmVsYXRpdmUuYXV0aDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSByZWxhdGl2ZS5ob3N0bmFtZSB8fCByZWxhdGl2ZS5ob3N0O1xuICAgIHJlc3VsdC5wb3J0ID0gcmVsYXRpdmUucG9ydDtcbiAgICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmIChyZXN1bHQucGF0aG5hbWUgfHwgcmVzdWx0LnNlYXJjaCkge1xuICAgICAgdmFyIHAgPSByZXN1bHQucGF0aG5hbWUgfHwgJyc7XG4gICAgICB2YXIgcyA9IHJlc3VsdC5zZWFyY2ggfHwgJyc7XG4gICAgICByZXN1bHQucGF0aCA9IHAgKyBzO1xuICAgIH1cbiAgICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHZhciBpc1NvdXJjZUFicyA9IChyZXN1bHQucGF0aG5hbWUgJiYgcmVzdWx0LnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nKSxcbiAgICAgIGlzUmVsQWJzID0gKFxuICAgICAgICAgIHJlbGF0aXZlLmhvc3QgfHxcbiAgICAgICAgICByZWxhdGl2ZS5wYXRobmFtZSAmJiByZWxhdGl2ZS5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJ1xuICAgICAgKSxcbiAgICAgIG11c3RFbmRBYnMgPSAoaXNSZWxBYnMgfHwgaXNTb3VyY2VBYnMgfHxcbiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdC5ob3N0ICYmIHJlbGF0aXZlLnBhdGhuYW1lKSksXG4gICAgICByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicyxcbiAgICAgIHNyY1BhdGggPSByZXN1bHQucGF0aG5hbWUgJiYgcmVzdWx0LnBhdGhuYW1lLnNwbGl0KCcvJykgfHwgW10sXG4gICAgICByZWxQYXRoID0gcmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICAgIHBzeWNob3RpYyA9IHJlc3VsdC5wcm90b2NvbCAmJiAhc2xhc2hlZFByb3RvY29sW3Jlc3VsdC5wcm90b2NvbF07XG5cbiAgLy8gaWYgdGhlIHVybCBpcyBhIG5vbi1zbGFzaGVkIHVybCwgdGhlbiByZWxhdGl2ZVxuICAvLyBsaW5rcyBsaWtlIC4uLy4uIHNob3VsZCBiZSBhYmxlXG4gIC8vIHRvIGNyYXdsIHVwIHRvIHRoZSBob3N0bmFtZSwgYXMgd2VsbC4gIFRoaXMgaXMgc3RyYW5nZS5cbiAgLy8gcmVzdWx0LnByb3RvY29sIGhhcyBhbHJlYWR5IGJlZW4gc2V0IGJ5IG5vdy5cbiAgLy8gTGF0ZXIgb24sIHB1dCB0aGUgZmlyc3QgcGF0aCBwYXJ0IGludG8gdGhlIGhvc3QgZmllbGQuXG4gIGlmIChwc3ljaG90aWMpIHtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSAnJztcbiAgICByZXN1bHQucG9ydCA9IG51bGw7XG4gICAgaWYgKHJlc3VsdC5ob3N0KSB7XG4gICAgICBpZiAoc3JjUGF0aFswXSA9PT0gJycpIHNyY1BhdGhbMF0gPSByZXN1bHQuaG9zdDtcbiAgICAgIGVsc2Ugc3JjUGF0aC51bnNoaWZ0KHJlc3VsdC5ob3N0KTtcbiAgICB9XG4gICAgcmVzdWx0Lmhvc3QgPSAnJztcbiAgICBpZiAocmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAgIHJlbGF0aXZlLmhvc3RuYW1lID0gbnVsbDtcbiAgICAgIHJlbGF0aXZlLnBvcnQgPSBudWxsO1xuICAgICAgaWYgKHJlbGF0aXZlLmhvc3QpIHtcbiAgICAgICAgaWYgKHJlbFBhdGhbMF0gPT09ICcnKSByZWxQYXRoWzBdID0gcmVsYXRpdmUuaG9zdDtcbiAgICAgICAgZWxzZSByZWxQYXRoLnVuc2hpZnQocmVsYXRpdmUuaG9zdCk7XG4gICAgICB9XG4gICAgICByZWxhdGl2ZS5ob3N0ID0gbnVsbDtcbiAgICB9XG4gICAgbXVzdEVuZEFicyA9IG11c3RFbmRBYnMgJiYgKHJlbFBhdGhbMF0gPT09ICcnIHx8IHNyY1BhdGhbMF0gPT09ICcnKTtcbiAgfVxuXG4gIGlmIChpc1JlbEFicykge1xuICAgIC8vIGl0J3MgYWJzb2x1dGUuXG4gICAgcmVzdWx0Lmhvc3QgPSAocmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJykgP1xuICAgICAgICAgICAgICAgICAgcmVsYXRpdmUuaG9zdCA6IHJlc3VsdC5ob3N0O1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IChyZWxhdGl2ZS5ob3N0bmFtZSB8fCByZWxhdGl2ZS5ob3N0bmFtZSA9PT0gJycpID9cbiAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZS5ob3N0bmFtZSA6IHJlc3VsdC5ob3N0bmFtZTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIHNyY1BhdGggPSByZWxQYXRoO1xuICAgIC8vIGZhbGwgdGhyb3VnaCB0byB0aGUgZG90LWhhbmRsaW5nIGJlbG93LlxuICB9IGVsc2UgaWYgKHJlbFBhdGgubGVuZ3RoKSB7XG4gICAgLy8gaXQncyByZWxhdGl2ZVxuICAgIC8vIHRocm93IGF3YXkgdGhlIGV4aXN0aW5nIGZpbGUsIGFuZCB0YWtlIHRoZSBuZXcgcGF0aCBpbnN0ZWFkLlxuICAgIGlmICghc3JjUGF0aCkgc3JjUGF0aCA9IFtdO1xuICAgIHNyY1BhdGgucG9wKCk7XG4gICAgc3JjUGF0aCA9IHNyY1BhdGguY29uY2F0KHJlbFBhdGgpO1xuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNOdWxsT3JVbmRlZmluZWQocmVsYXRpdmUuc2VhcmNoKSkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2NhdGlvbmFseSB0aGUgYXV0aCBjYW4gZ2V0IHN0dWNrIG9ubHkgaW4gaG9zdFxuICAgICAgLy90aGlzIGVzcGVjaWFseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAgIC8vdXJsLnJlc29sdmVPYmplY3QoJ21haWx0bzpsb2NhbDFAZG9tYWluMScsICdsb2NhbDJAZG9tYWluMicpXG4gICAgICB2YXIgYXV0aEluSG9zdCA9IHJlc3VsdC5ob3N0ICYmIHJlc3VsdC5ob3N0LmluZGV4T2YoJ0AnKSA+IDAgP1xuICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuaG9zdC5zcGxpdCgnQCcpIDogZmFsc2U7XG4gICAgICBpZiAoYXV0aEluSG9zdCkge1xuICAgICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgICAgcmVzdWx0Lmhvc3QgPSByZXN1bHQuaG9zdG5hbWUgPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmICghdXRpbC5pc051bGwocmVzdWx0LnBhdGhuYW1lKSB8fCAhdXRpbC5pc051bGwocmVzdWx0LnNlYXJjaCkpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAgIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID0gKFxuICAgICAgKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QpICYmIChsYXN0ID09PSAnLicgfHwgbGFzdCA9PT0gJy4uJykgfHxcbiAgICAgIGxhc3QgPT09ICcnKTtcblxuICAvLyBzdHJpcCBzaW5nbGUgZG90cywgcmVzb2x2ZSBkb3VibGUgZG90cyB0byBwYXJlbnQgZGlyXG4gIC8vIGlmIHRoZSBwYXRoIHRyaWVzIHRvIGdvIGFib3ZlIHRoZSByb290LCBgdXBgIGVuZHMgdXAgPiAwXG4gIHZhciB1cCA9IDA7XG4gIGZvciAodmFyIGkgPSBzcmNQYXRoLmxlbmd0aDsgaSA+PSAwOyBpLS0pIHtcbiAgICBsYXN0ID0gc3JjUGF0aFtpXTtcbiAgICBpZiAobGFzdCA9PSAnLicpIHtcbiAgICAgIHNyY1BhdGguc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSBpZiAobGFzdCA9PT0gJy4uJykge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cCsrO1xuICAgIH0gZWxzZSBpZiAodXApIHtcbiAgICAgIHNyY1BhdGguc3BsaWNlKGksIDEpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmXG4gICAgICAoIXNyY1BhdGhbMF0gfHwgc3JjUGF0aFswXS5jaGFyQXQoMCkgIT09ICcvJykpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKGhhc1RyYWlsaW5nU2xhc2ggJiYgKHNoaW1zLnN1YnN0cihzcmNQYXRoLmpvaW4oJy8nKSwgLTEpICE9PSAnLycpKSB7XG4gICAgc3JjUGF0aC5wdXNoKCcnKTtcbiAgfVxuXG4gIHZhciBpc0Fic29sdXRlID0gc3JjUGF0aFswXSA9PT0gJycgfHxcbiAgICAgIChzcmNQYXRoWzBdICYmIHNyY1BhdGhbMF0uY2hhckF0KDApID09PSAnLycpO1xuXG4gIC8vIHB1dCB0aGUgaG9zdCBiYWNrXG4gIGlmIChwc3ljaG90aWMpIHtcbiAgICByZXN1bHQuaG9zdG5hbWUgPSByZXN1bHQuaG9zdCA9IGlzQWJzb2x1dGUgPyAnJyA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNQYXRoLmxlbmd0aCA/IHNyY1BhdGguc2hpZnQoKSA6ICcnO1xuICAgIC8vb2NjYXRpb25hbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgIC8vdXJsLnJlc29sdmVPYmplY3QoJ21haWx0bzpsb2NhbDFAZG9tYWluMScsICdsb2NhbDJAZG9tYWluMicpXG4gICAgdmFyIGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID9cbiAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5ob3N0LnNwbGl0KCdAJykgOiBmYWxzZTtcbiAgICBpZiAoYXV0aEluSG9zdCkge1xuICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICByZXN1bHQuaG9zdCA9IHJlc3VsdC5ob3N0bmFtZSA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICB9XG4gIH1cblxuICBtdXN0RW5kQWJzID0gbXVzdEVuZEFicyB8fCAocmVzdWx0Lmhvc3QgJiYgc3JjUGF0aC5sZW5ndGgpO1xuXG4gIGlmIChtdXN0RW5kQWJzICYmICFpc0Fic29sdXRlKSB7XG4gICAgc3JjUGF0aC51bnNoaWZ0KCcnKTtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIHJlc3VsdC5wYXRoID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQucGF0aG5hbWUgPSBzcmNQYXRoLmpvaW4oJy8nKTtcbiAgfVxuXG4gIC8vdG8gc3VwcG9ydCByZXF1ZXN0Lmh0dHBcbiAgaWYgKCF1dGlsLmlzTnVsbChyZXN1bHQucGF0aG5hbWUpIHx8ICF1dGlsLmlzTnVsbChyZXN1bHQuc2VhcmNoKSkge1xuICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuVXJsLnByb3RvdHlwZS5wYXJzZUhvc3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGhvc3QgPSB0aGlzLmhvc3Q7XG4gIHZhciBwb3J0ID0gcG9ydFBhdHRlcm4uZXhlYyhob3N0KTtcbiAgaWYgKHBvcnQpIHtcbiAgICBwb3J0ID0gcG9ydFswXTtcbiAgICBpZiAocG9ydCAhPT0gJzonKSB7XG4gICAgICB0aGlzLnBvcnQgPSBwb3J0LnN1YnN0cigxKTtcbiAgICB9XG4gICAgaG9zdCA9IGhvc3Quc3Vic3RyKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBzaGltcyA9IHJlcXVpcmUoJ19zaGltcycpO1xuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIHNoaW1zLmZvckVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBzaGltcy5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IHNoaW1zLmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG5cbiAgc2hpbXMuZm9yRWFjaChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBzaGltcy5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoc2hpbXMuaW5kZXhPZihjdHguc2VlbiwgZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IHNoaW1zLnJlZHVjZShvdXRwdXQsIGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBzaGltcy5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZztcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJiBvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJztcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmZ1bmN0aW9uIGlzQnVmZmVyKGFyZykge1xuICByZXR1cm4gYXJnICYmIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnXG4gICAgJiYgdHlwZW9mIGFyZy5jb3B5ID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5maWxsID09PSAnZnVuY3Rpb24nXG4gICAgJiYgdHlwZW9mIGFyZy5iaW5hcnlTbGljZSA9PT0gJ2Z1bmN0aW9uJ1xuICA7XG59XG5leHBvcnRzLmlzQnVmZmVyID0gaXNCdWZmZXI7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IGZ1bmN0aW9uKGN0b3IsIHN1cGVyQ3Rvcikge1xuICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvcjtcbiAgY3Rvci5wcm90b3R5cGUgPSBzaGltcy5jcmVhdGUoc3VwZXJDdG9yLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY3RvcixcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xufTtcblxuZXhwb3J0cy5fZXh0ZW5kID0gZnVuY3Rpb24ob3JpZ2luLCBhZGQpIHtcbiAgLy8gRG9uJ3QgZG8gYW55dGhpbmcgaWYgYWRkIGlzbid0IGFuIG9iamVjdFxuICBpZiAoIWFkZCB8fCAhaXNPYmplY3QoYWRkKSkgcmV0dXJuIG9yaWdpbjtcblxuICB2YXIga2V5cyA9IHNoaW1zLmtleXMoYWRkKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSkge1xuICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgfVxuICByZXR1cm4gb3JpZ2luO1xufTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkob2JqLCBwcm9wKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBwcm9wKTtcbn1cbiIsImV4cG9ydHMucmVhZElFRUU3NTQgPSBmdW5jdGlvbihidWZmZXIsIG9mZnNldCwgaXNCRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIG5CaXRzID0gLTcsXG4gICAgICBpID0gaXNCRSA/IDAgOiAobkJ5dGVzIC0gMSksXG4gICAgICBkID0gaXNCRSA/IDEgOiAtMSxcbiAgICAgIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV07XG5cbiAgaSArPSBkO1xuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBzID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gZUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIGUgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXM7XG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XG59O1xuXG5leHBvcnRzLndyaXRlSUVFRTc1NCA9IGZ1bmN0aW9uKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKSxcbiAgICAgIGkgPSBpc0JFID8gKG5CeXRlcyAtIDEpIDogMCxcbiAgICAgIGQgPSBpc0JFID8gLTEgOiAxLFxuICAgICAgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMDtcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCk7XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyODtcbn07XG4iLCJ2YXIgYXNzZXJ0O1xuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXI7XG5leHBvcnRzLlNsb3dCdWZmZXIgPSBCdWZmZXI7XG5CdWZmZXIucG9vbFNpemUgPSA4MTkyO1xuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwO1xuXG5mdW5jdGlvbiBzdHJpbmd0cmltKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpO1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbn1cblxuZnVuY3Rpb24gQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nLCBvZmZzZXQpIHtcbiAgaWYoIWFzc2VydCkgYXNzZXJ0PSByZXF1aXJlKCdhc3NlcnQnKTtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgb2Zmc2V0KTtcbiAgfVxuICB0aGlzLnBhcmVudCA9IHRoaXM7XG4gIHRoaXMub2Zmc2V0ID0gMDtcblxuICAvLyBXb3JrLWFyb3VuZDogbm9kZSdzIGJhc2U2NCBpbXBsZW1lbnRhdGlvblxuICAvLyBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgc3RyaW5ncyB3aGlsZSBiYXNlNjQtanNcbiAgLy8gZG9lcyBub3QuLlxuICBpZiAoZW5jb2RpbmcgPT0gXCJiYXNlNjRcIiAmJiB0eXBlb2Ygc3ViamVjdCA9PSBcInN0cmluZ1wiKSB7XG4gICAgc3ViamVjdCA9IHN0cmluZ3RyaW0oc3ViamVjdCk7XG4gICAgd2hpbGUgKHN1YmplY3QubGVuZ3RoICUgNCAhPSAwKSB7XG4gICAgICBzdWJqZWN0ID0gc3ViamVjdCArIFwiPVwiOyBcbiAgICB9XG4gIH1cblxuICB2YXIgdHlwZTtcblxuICAvLyBBcmUgd2Ugc2xpY2luZz9cbiAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdudW1iZXInKSB7XG4gICAgdGhpcy5sZW5ndGggPSBjb2VyY2UoZW5jb2RpbmcpO1xuICAgIC8vIHNsaWNpbmcgd29ya3MsIHdpdGggbGltaXRhdGlvbnMgKG5vIHBhcmVudCB0cmFja2luZy91cGRhdGUpXG4gICAgLy8gY2hlY2sgaHR0cHM6Ly9naXRodWIuY29tL3Rvb3RzL2J1ZmZlci1icm93c2VyaWZ5L2lzc3Vlcy8xOVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzW2ldID0gc3ViamVjdC5nZXQoaStvZmZzZXQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBGaW5kIHRoZSBsZW5ndGhcbiAgICBzd2l0Y2ggKHR5cGUgPSB0eXBlb2Ygc3ViamVjdCkge1xuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgdGhpcy5sZW5ndGggPSBjb2VyY2Uoc3ViamVjdCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICB0aGlzLmxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHN1YmplY3QsIGVuY29kaW5nKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ29iamVjdCc6IC8vIEFzc3VtZSBvYmplY3QgaXMgYW4gYXJyYXlcbiAgICAgICAgdGhpcy5sZW5ndGggPSBjb2VyY2Uoc3ViamVjdC5sZW5ndGgpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCBuZWVkcyB0byBiZSBhIG51bWJlciwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnYXJyYXkgb3Igc3RyaW5nLicpO1xuICAgIH1cblxuICAgIC8vIFRyZWF0IGFycmF5LWlzaCBvYmplY3RzIGFzIGEgYnl0ZSBhcnJheS5cbiAgICBpZiAoaXNBcnJheUlzaChzdWJqZWN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzdWJqZWN0IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgICAgdGhpc1tpXSA9IHN1YmplY3QucmVhZFVJbnQ4KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXNbaV0gPSBzdWJqZWN0W2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBXZSBhcmUgYSBzdHJpbmdcbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy53cml0ZShzdWJqZWN0LCAwLCBlbmNvZGluZyk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldChpKSB7XG4gIGlmIChpIDwgMCB8fCBpID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ29vYicpO1xuICByZXR1cm4gdGhpc1tpXTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gc2V0KGksIHYpIHtcbiAgaWYgKGkgPCAwIHx8IGkgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignb29iJyk7XG4gIHJldHVybiB0aGlzW2ldID0gdjtcbn07XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gKHN0ciwgZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChlbmNvZGluZyB8fCBcInV0ZjhcIikge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXR1cm4gc3RyLmxlbmd0aCAvIDI7XG5cbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyKS5sZW5ndGg7XG5cbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldHVybiBzdHIubGVuZ3RoO1xuXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cikubGVuZ3RoO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpO1xuICB9XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnV0ZjhXcml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBieXRlcywgcG9zO1xuICByZXR1cm4gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSAgYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcpLCB0aGlzLCBvZmZzZXQsIGxlbmd0aCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLmFzY2lpV3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgYnl0ZXMsIHBvcztcbiAgcmV0dXJuIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIHRoaXMsIG9mZnNldCwgbGVuZ3RoKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmluYXJ5V3JpdGUgPSBCdWZmZXIucHJvdG90eXBlLmFzY2lpV3JpdGU7XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmFzZTY0V3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgYnl0ZXMsIHBvcztcbiAgcmV0dXJuIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIHRoaXMsIG9mZnNldCwgbGVuZ3RoKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmFzZTY0U2xpY2UgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICByZXR1cm4gcmVxdWlyZShcImJhc2U2NC1qc1wiKS5mcm9tQnl0ZUFycmF5KGJ5dGVzKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUudXRmOFNsaWNlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgdmFyIHJlcyA9IFwiXCI7XG4gIHZhciB0bXAgPSBcIlwiO1xuICB2YXIgaSA9IDA7XG4gIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgaWYgKGJ5dGVzW2ldIDw9IDB4N0YpIHtcbiAgICAgIHJlcyArPSBkZWNvZGVVdGY4Q2hhcih0bXApICsgU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gICAgICB0bXAgPSBcIlwiO1xuICAgIH0gZWxzZVxuICAgICAgdG1wICs9IFwiJVwiICsgYnl0ZXNbaV0udG9TdHJpbmcoMTYpO1xuXG4gICAgaSsrO1xuICB9XG5cbiAgcmV0dXJuIHJlcyArIGRlY29kZVV0ZjhDaGFyKHRtcCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuYXNjaWlTbGljZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGJ5dGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHZhciByZXQgPSBcIlwiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKVxuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKTtcbiAgcmV0dXJuIHJldDtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5iaW5hcnlTbGljZSA9IEJ1ZmZlci5wcm90b3R5cGUuYXNjaWlTbGljZTtcblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBvdXQgPSBbXSxcbiAgICAgIGxlbiA9IHRoaXMubGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gdG9IZXgodGhpc1tpXSk7XG4gICAgaWYgKGkgPT0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUykge1xuICAgICAgb3V0W2kgKyAxXSA9ICcuLi4nO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgb3V0LmpvaW4oJyAnKSArICc+Jztcbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS5oZXhTbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoO1xuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDA7XG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW47XG5cbiAgdmFyIG91dCA9ICcnO1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleCh0aGlzW2ldKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpO1xuICBzdGFydCA9ICtzdGFydCB8fCAwO1xuICBpZiAodHlwZW9mIGVuZCA9PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5sZW5ndGg7XG5cbiAgLy8gRmFzdHBhdGggZW1wdHkgc3RyaW5nc1xuICBpZiAoK2VuZCA9PSBzdGFydCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0dXJuIHRoaXMuaGV4U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXR1cm4gdGhpcy51dGY4U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXR1cm4gdGhpcy5hc2NpaVNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldHVybiB0aGlzLmJpbmFyeVNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldHVybiB0aGlzLmJhc2U2NFNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgICAgcmV0dXJuIHRoaXMudWNzMlNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpO1xuICB9XG59O1xuXG5cbkJ1ZmZlci5wcm90b3R5cGUuaGV4V3JpdGUgPSBmdW5jdGlvbihzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9ICtvZmZzZXQgfHwgMDtcbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0O1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSArbGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aDtcbiAgaWYgKHN0ckxlbiAlIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpO1xuICB9XG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMjtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGJ5dGUgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpO1xuICAgIGlmIChpc05hTihieXRlKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKTtcbiAgICB0aGlzW29mZnNldCArIGldID0gYnl0ZTtcbiAgfVxuICBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9IGkgKiAyO1xuICByZXR1cm4gaTtcbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIFN1cHBvcnQgYm90aCAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpXG4gIC8vIGFuZCB0aGUgbGVnYWN5IChzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBpZiAoIWlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoO1xuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSBlbHNlIHsgIC8vIGxlZ2FjeVxuICAgIHZhciBzd2FwID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXQ7XG4gICAgb2Zmc2V0ID0gbGVuZ3RoO1xuICAgIGxlbmd0aCA9IHN3YXA7XG4gIH1cblxuICBvZmZzZXQgPSArb2Zmc2V0IHx8IDA7XG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gK2xlbmd0aDtcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gICAgfVxuICB9XG4gIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKTtcblxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldHVybiB0aGlzLmhleFdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0dXJuIHRoaXMudXRmOFdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0dXJuIHRoaXMuYXNjaWlXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnlXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXR1cm4gdGhpcy5iYXNlNjRXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIHJldHVybiB0aGlzLnVjczJXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKTtcbiAgfVxufTtcblxuLy8gc2xpY2Uoc3RhcnQsIGVuZClcbmZ1bmN0aW9uIGNsYW1wKGluZGV4LCBsZW4sIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodHlwZW9mIGluZGV4ICE9PSAnbnVtYmVyJykgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgaW5kZXggPSB+fmluZGV4OyAgLy8gQ29lcmNlIHRvIGludGVnZXIuXG4gIGlmIChpbmRleCA+PSBsZW4pIHJldHVybiBsZW47XG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXg7XG4gIGluZGV4ICs9IGxlbjtcbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleDtcbiAgcmV0dXJuIDA7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aDtcbiAgc3RhcnQgPSBjbGFtcChzdGFydCwgbGVuLCAwKTtcbiAgZW5kID0gY2xhbXAoZW5kLCBsZW4sIGxlbik7XG4gIHJldHVybiBuZXcgQnVmZmVyKHRoaXMsIGVuZCAtIHN0YXJ0LCArc3RhcnQpO1xufTtcblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24odGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG4gIHN0YXJ0IHx8IChzdGFydCA9IDApO1xuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgaXNOYU4oZW5kKSkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoO1xuICB9XG4gIHRhcmdldF9zdGFydCB8fCAodGFyZ2V0X3N0YXJ0ID0gMCk7XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUVuZCA8IHNvdXJjZVN0YXJ0Jyk7XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMDtcbiAgaWYgKHRhcmdldC5sZW5ndGggPT0gMCB8fCBzb3VyY2UubGVuZ3RoID09IDApIHJldHVybiAwO1xuXG4gIGlmICh0YXJnZXRfc3RhcnQgPCAwIHx8IHRhcmdldF9zdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIGlmIChlbmQgPCAwIHx8IGVuZCA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0ICsgc3RhcnQ7XG4gIH1cblxuICB2YXIgdGVtcCA9IFtdO1xuICBmb3IgKHZhciBpPXN0YXJ0OyBpPGVuZDsgaSsrKSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiB0aGlzW2ldICE9PSAndW5kZWZpbmVkJywgXCJjb3B5aW5nIHVuZGVmaW5lZCBidWZmZXIgYnl0ZXMhXCIpO1xuICAgIHRlbXAucHVzaCh0aGlzW2ldKTtcbiAgfVxuXG4gIGZvciAodmFyIGk9dGFyZ2V0X3N0YXJ0OyBpPHRhcmdldF9zdGFydCt0ZW1wLmxlbmd0aDsgaSsrKSB7XG4gICAgdGFyZ2V0W2ldID0gdGVtcFtpLXRhcmdldF9zdGFydF07XG4gIH1cbn07XG5cbi8vIGZpbGwodmFsdWUsIHN0YXJ0PTAsIGVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICB2YWx1ZSB8fCAodmFsdWUgPSAwKTtcbiAgc3RhcnQgfHwgKHN0YXJ0ID0gMCk7XG4gIGVuZCB8fCAoZW5kID0gdGhpcy5sZW5ndGgpO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApO1xuICB9XG4gIGlmICghKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHx8IGlzTmFOKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcigndmFsdWUgaXMgbm90IGEgbnVtYmVyJyk7XG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIHRocm93IG5ldyBFcnJvcignZW5kIDwgc3RhcnQnKTtcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwO1xuICBpZiAodGhpcy5sZW5ndGggPT0gMCkgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RhcnQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHRoaXNbaV0gPSB2YWx1ZTtcbiAgfVxufVxuXG4vLyBTdGF0aWMgbWV0aG9kc1xuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIoYikge1xuICByZXR1cm4gYiBpbnN0YW5jZW9mIEJ1ZmZlciB8fCBiIGluc3RhbmNlb2YgQnVmZmVyO1xufTtcblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIChsaXN0LCB0b3RhbExlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVc2FnZTogQnVmZmVyLmNvbmNhdChsaXN0LCBbdG90YWxMZW5ndGhdKVxcbiBcXFxuICAgICAgbGlzdCBzaG91bGQgYmUgYW4gQXJyYXkuXCIpO1xuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMCk7XG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdG90YWxMZW5ndGggIT09ICdudW1iZXInKSB7XG4gICAgdG90YWxMZW5ndGggPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGJ1ZiA9IGxpc3RbaV07XG4gICAgICB0b3RhbExlbmd0aCArPSBidWYubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRvdGFsTGVuZ3RoKTtcbiAgdmFyIHBvcyA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBidWYgPSBsaXN0W2ldO1xuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKTtcbiAgICBwb3MgKz0gYnVmLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gYnVmZmVyO1xufTtcblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICBzd2l0Y2ggKChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIGhlbHBlcnNcblxuZnVuY3Rpb24gY29lcmNlKGxlbmd0aCkge1xuICAvLyBDb2VyY2UgbGVuZ3RoIHRvIGEgbnVtYmVyIChwb3NzaWJseSBOYU4pLCByb3VuZCB1cFxuICAvLyBpbiBjYXNlIGl0J3MgZnJhY3Rpb25hbCAoZS5nLiAxMjMuNDU2KSB0aGVuIGRvIGFcbiAgLy8gZG91YmxlIG5lZ2F0ZSB0byBjb2VyY2UgYSBOYU4gdG8gMC4gRWFzeSwgcmlnaHQ/XG4gIGxlbmd0aCA9IH5+TWF0aC5jZWlsKCtsZW5ndGgpO1xuICByZXR1cm4gbGVuZ3RoIDwgMCA/IDAgOiBsZW5ndGg7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkoc3ViamVjdCkge1xuICByZXR1cm4gKEFycmF5LmlzQXJyYXkgfHxcbiAgICBmdW5jdGlvbihzdWJqZWN0KXtcbiAgICAgIHJldHVybiB7fS50b1N0cmluZy5hcHBseShzdWJqZWN0KSA9PSAnW29iamVjdCBBcnJheV0nXG4gICAgfSlcbiAgICAoc3ViamVjdClcbn1cblxuZnVuY3Rpb24gaXNBcnJheUlzaChzdWJqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5KHN1YmplY3QpIHx8IEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSB8fFxuICAgICAgICAgc3ViamVjdCAmJiB0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIHR5cGVvZiBzdWJqZWN0Lmxlbmd0aCA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIHRvSGV4KG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpO1xuICByZXR1cm4gbi50b1N0cmluZygxNik7XG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKVxuICAgIGlmIChzdHIuY2hhckNvZGVBdChpKSA8PSAweDdGKVxuICAgICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIGggPSBlbmNvZGVVUklDb21wb25lbnQoc3RyLmNoYXJBdChpKSkuc3Vic3RyKDEpLnNwbGl0KCclJyk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGgubGVuZ3RoOyBqKyspXG4gICAgICAgIGJ5dGVBcnJheS5wdXNoKHBhcnNlSW50KGhbal0sIDE2KSk7XG4gICAgfVxuXG4gIHJldHVybiBieXRlQXJyYXk7XG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyhzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrIClcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaCggc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGICk7XG5cbiAgcmV0dXJuIGJ5dGVBcnJheTtcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyhzdHIpIHtcbiAgcmV0dXJuIHJlcXVpcmUoXCJiYXNlNjQtanNcIikudG9CeXRlQXJyYXkoc3RyKTtcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlcihzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIHBvcywgaSA9IDA7XG4gIHdoaWxlIChpIDwgbGVuZ3RoKSB7XG4gICAgaWYgKChpK29mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSlcbiAgICAgIGJyZWFrO1xuXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldO1xuICAgIGkrKztcbiAgfVxuICByZXR1cm4gaTtcbn1cblxuZnVuY3Rpb24gZGVjb2RlVXRmOENoYXIoc3RyKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgweEZGRkQpOyAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuXG4vLyByZWFkL3dyaXRlIGJpdC10d2lkZGxpbmdcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHJldHVybiBidWZmZXJbb2Zmc2V0XTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRVSW50MTYoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgdmFsID0gMDtcblxuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuIDA7XG5cbiAgaWYgKGlzQmlnRW5kaWFuKSB7XG4gICAgdmFsID0gYnVmZmVyW29mZnNldF0gPDwgODtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgMV07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhbCA9IGJ1ZmZlcltvZmZzZXRdO1xuICAgIGlmIChvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAxXSA8PCA4O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB2YWw7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkVUludDMyKGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIHZhbCA9IDA7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gMDtcblxuICBpZiAoaXNCaWdFbmRpYW4pIHtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSBidWZmZXJbb2Zmc2V0ICsgMV0gPDwgMTY7XG4gICAgaWYgKG9mZnNldCArIDIgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAyXSA8PCA4O1xuICAgIGlmIChvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgM107XG4gICAgdmFsID0gdmFsICsgKGJ1ZmZlcltvZmZzZXRdIDw8IDI0ID4+PiAwKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSBidWZmZXJbb2Zmc2V0ICsgMl0gPDwgMTY7XG4gICAgaWYgKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAxXSA8PCA4O1xuICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0XTtcbiAgICBpZiAob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSB2YWwgKyAoYnVmZmVyW29mZnNldCArIDNdIDw8IDI0ID4+PiAwKTtcbiAgfVxuXG4gIHJldHVybiB2YWw7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5cbi8qXG4gKiBTaWduZWQgaW50ZWdlciB0eXBlcywgeWF5IHRlYW0hIEEgcmVtaW5kZXIgb24gaG93IHR3bydzIGNvbXBsZW1lbnQgYWN0dWFsbHlcbiAqIHdvcmtzLiBUaGUgZmlyc3QgYml0IGlzIHRoZSBzaWduZWQgYml0LCBpLmUuIHRlbGxzIHVzIHdoZXRoZXIgb3Igbm90IHRoZVxuICogbnVtYmVyIHNob3VsZCBiZSBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gSWYgdGhlIHR3bydzIGNvbXBsZW1lbnQgdmFsdWUgaXNcbiAqIHBvc2l0aXZlLCB0aGVuIHdlJ3JlIGRvbmUsIGFzIGl0J3MgZXF1aXZhbGVudCB0byB0aGUgdW5zaWduZWQgcmVwcmVzZW50YXRpb24uXG4gKlxuICogTm93IGlmIHRoZSBudW1iZXIgaXMgcG9zaXRpdmUsIHlvdSdyZSBwcmV0dHkgbXVjaCBkb25lLCB5b3UgY2FuIGp1c3QgbGV2ZXJhZ2VcbiAqIHRoZSB1bnNpZ25lZCB0cmFuc2xhdGlvbnMgYW5kIHJldHVybiB0aG9zZS4gVW5mb3J0dW5hdGVseSwgbmVnYXRpdmUgbnVtYmVyc1xuICogYXJlbid0IHF1aXRlIHRoYXQgc3RyYWlnaHRmb3J3YXJkLlxuICpcbiAqIEF0IGZpcnN0IGdsYW5jZSwgb25lIG1pZ2h0IGJlIGluY2xpbmVkIHRvIHVzZSB0aGUgdHJhZGl0aW9uYWwgZm9ybXVsYSB0b1xuICogdHJhbnNsYXRlIGJpbmFyeSBudW1iZXJzIGJldHdlZW4gdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSB2YWx1ZXMgaW4gdHdvJ3NcbiAqIGNvbXBsZW1lbnQuIChUaG91Z2ggaXQgZG9lc24ndCBxdWl0ZSB3b3JrIGZvciB0aGUgbW9zdCBuZWdhdGl2ZSB2YWx1ZSlcbiAqIE1haW5seTpcbiAqICAtIGludmVydCBhbGwgdGhlIGJpdHNcbiAqICAtIGFkZCBvbmUgdG8gdGhlIHJlc3VsdFxuICpcbiAqIE9mIGNvdXJzZSwgdGhpcyBkb2Vzbid0IHF1aXRlIHdvcmsgaW4gSmF2YXNjcmlwdC4gVGFrZSBmb3IgZXhhbXBsZSB0aGUgdmFsdWVcbiAqIG9mIC0xMjguIFRoaXMgY291bGQgYmUgcmVwcmVzZW50ZWQgaW4gMTYgYml0cyAoYmlnLWVuZGlhbikgYXMgMHhmZjgwLiBCdXQgb2ZcbiAqIGNvdXJzZSwgSmF2YXNjcmlwdCB3aWxsIGRvIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogPiB+MHhmZjgwXG4gKiAtNjU0MDlcbiAqXG4gKiBXaG9oIHRoZXJlLCBKYXZhc2NyaXB0LCB0aGF0J3Mgbm90IHF1aXRlIHJpZ2h0LiBCdXQgd2FpdCwgYWNjb3JkaW5nIHRvXG4gKiBKYXZhc2NyaXB0IHRoYXQncyBwZXJmZWN0bHkgY29ycmVjdC4gV2hlbiBKYXZhc2NyaXB0IGVuZHMgdXAgc2VlaW5nIHRoZVxuICogY29uc3RhbnQgMHhmZjgwLCBpdCBoYXMgbm8gbm90aW9uIHRoYXQgaXQgaXMgYWN0dWFsbHkgYSBzaWduZWQgbnVtYmVyLiBJdFxuICogYXNzdW1lcyB0aGF0IHdlJ3ZlIGlucHV0IHRoZSB1bnNpZ25lZCB2YWx1ZSAweGZmODAuIFRodXMsIHdoZW4gaXQgZG9lcyB0aGVcbiAqIGJpbmFyeSBuZWdhdGlvbiwgaXQgY2FzdHMgaXQgaW50byBhIHNpZ25lZCB2YWx1ZSwgKHBvc2l0aXZlIDB4ZmY4MCkuIFRoZW5cbiAqIHdoZW4geW91IHBlcmZvcm0gYmluYXJ5IG5lZ2F0aW9uIG9uIHRoYXQsIGl0IHR1cm5zIGl0IGludG8gYSBuZWdhdGl2ZSBudW1iZXIuXG4gKlxuICogSW5zdGVhZCwgd2UncmUgZ29pbmcgdG8gaGF2ZSB0byB1c2UgdGhlIGZvbGxvd2luZyBnZW5lcmFsIGZvcm11bGEsIHRoYXQgd29ya3NcbiAqIGluIGEgcmF0aGVyIEphdmFzY3JpcHQgZnJpZW5kbHkgd2F5LiBJJ20gZ2xhZCB3ZSBkb24ndCBzdXBwb3J0IHRoaXMga2luZCBvZlxuICogd2VpcmQgbnVtYmVyaW5nIHNjaGVtZSBpbiB0aGUga2VybmVsLlxuICpcbiAqIChCSVQtTUFYIC0gKHVuc2lnbmVkKXZhbCArIDEpICogLTFcbiAqXG4gKiBUaGUgYXN0dXRlIG9ic2VydmVyLCBtYXkgdGhpbmsgdGhhdCB0aGlzIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3IgOC1iaXQgbnVtYmVyc1xuICogKHJlYWxseSBpdCBpc24ndCBuZWNlc3NhcnkgZm9yIHRoZW0pLiBIb3dldmVyLCB3aGVuIHlvdSBnZXQgMTYtYml0IG51bWJlcnMsXG4gKiB5b3UgZG8uIExldCdzIGdvIGJhY2sgdG8gb3VyIHByaW9yIGV4YW1wbGUgYW5kIHNlZSBob3cgdGhpcyB3aWxsIGxvb2s6XG4gKlxuICogKDB4ZmZmZiAtIDB4ZmY4MCArIDEpICogLTFcbiAqICgweDAwN2YgKyAxKSAqIC0xXG4gKiAoMHgwMDgwKSAqIC0xXG4gKi9cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuICB2YXIgbmVnO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuO1xuXG4gIG5lZyA9IGJ1ZmZlcltvZmZzZXRdICYgMHg4MDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gKGJ1ZmZlcltvZmZzZXRdKTtcbiAgfVxuXG4gIHJldHVybiAoKDB4ZmYgLSBidWZmZXJbb2Zmc2V0XSArIDEpICogLTEpO1xufTtcblxuZnVuY3Rpb24gcmVhZEludDE2KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIG5lZywgdmFsO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIHZhbCA9IHJlYWRVSW50MTYoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIG5lZyA9IHZhbCAmIDB4ODAwMDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgcmV0dXJuICgweGZmZmYgLSB2YWwgKyAxKSAqIC0xO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkSW50MzIoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgbmVnLCB2YWw7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgdmFsID0gcmVhZFVJbnQzMihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgbmVnID0gdmFsICYgMHg4MDAwMDAwMDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gKHZhbCk7XG4gIH1cblxuICByZXR1cm4gKDB4ZmZmZmZmZmYgLSB2YWwgKyAxKSAqIC0xO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkRmxvYXQoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS5yZWFkSUVFRTc1NChidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICAyMywgNCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkRmxvYXQodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHJlYWREb3VibGUoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgNyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS5yZWFkSUVFRTc1NChidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICA1MiwgOCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZERvdWJsZSh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWREb3VibGUodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5cbi8qXG4gKiBXZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB2YWx1ZSBpcyBhIHZhbGlkIGludGVnZXIuIFRoaXMgbWVhbnMgdGhhdCBpdCBpc1xuICogbm9uLW5lZ2F0aXZlLiBJdCBoYXMgbm8gZnJhY3Rpb25hbCBjb21wb25lbnQgYW5kIHRoYXQgaXQgZG9lcyBub3QgZXhjZWVkIHRoZVxuICogbWF4aW11bSBhbGxvd2VkIHZhbHVlLlxuICpcbiAqICAgICAgdmFsdWUgICAgICAgICAgIFRoZSBudW1iZXIgdG8gY2hlY2sgZm9yIHZhbGlkaXR5XG4gKlxuICogICAgICBtYXggICAgICAgICAgICAgVGhlIG1heGltdW0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdmVyaWZ1aW50KHZhbHVlLCBtYXgpIHtcbiAgYXNzZXJ0Lm9rKHR5cGVvZiAodmFsdWUpID09ICdudW1iZXInLFxuICAgICAgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKTtcblxuICBhc3NlcnQub2sodmFsdWUgPj0gMCxcbiAgICAgICdzcGVjaWZpZWQgYSBuZWdhdGl2ZSB2YWx1ZSBmb3Igd3JpdGluZyBhbiB1bnNpZ25lZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBpcyBsYXJnZXIgdGhhbiBtYXhpbXVtIHZhbHVlIGZvciB0eXBlJyk7XG5cbiAgYXNzZXJ0Lm9rKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSwgJ3ZhbHVlIGhhcyBhIGZyYWN0aW9uYWwgY29tcG9uZW50Jyk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZik7XG4gIH1cblxuICBpZiAob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCkge1xuICAgIGJ1ZmZlcltvZmZzZXRdID0gdmFsdWU7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHdyaXRlVUludDE2KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmKTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTWF0aC5taW4oYnVmZmVyLmxlbmd0aCAtIG9mZnNldCwgMik7IGkrKykge1xuICAgIGJ1ZmZlcltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGlzQmlnRW5kaWFuID8gMSAtIGkgOiBpKSkpKSA+Pj5cbiAgICAgICAgICAgIChpc0JpZ0VuZGlhbiA/IDEgLSBpIDogaSkgKiA4O1xuICB9XG5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlVUludDMyKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmZmZmZik7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IE1hdGgubWluKGJ1ZmZlci5sZW5ndGggLSBvZmZzZXQsIDQpOyBpKyspIHtcbiAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgPj4+IChpc0JpZ0VuZGlhbiA/IDMgLSBpIDogaSkgKiA4KSAmIDB4ZmY7XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cblxuLypcbiAqIFdlIG5vdyBtb3ZlIG9udG8gb3VyIGZyaWVuZHMgaW4gdGhlIHNpZ25lZCBudW1iZXIgY2F0ZWdvcnkuIFVubGlrZSB1bnNpZ25lZFxuICogbnVtYmVycywgd2UncmUgZ29pbmcgdG8gaGF2ZSB0byB3b3JyeSBhIGJpdCBtb3JlIGFib3V0IGhvdyB3ZSBwdXQgdmFsdWVzIGludG9cbiAqIGFycmF5cy4gU2luY2Ugd2UgYXJlIG9ubHkgd29ycnlpbmcgYWJvdXQgc2lnbmVkIDMyLWJpdCB2YWx1ZXMsIHdlJ3JlIGluXG4gKiBzbGlnaHRseSBiZXR0ZXIgc2hhcGUuIFVuZm9ydHVuYXRlbHksIHdlIHJlYWxseSBjYW4ndCBkbyBvdXIgZmF2b3JpdGUgYmluYXJ5XG4gKiAmIGluIHRoaXMgc3lzdGVtLiBJdCByZWFsbHkgc2VlbXMgdG8gZG8gdGhlIHdyb25nIHRoaW5nLiBGb3IgZXhhbXBsZTpcbiAqXG4gKiA+IC0zMiAmIDB4ZmZcbiAqIDIyNFxuICpcbiAqIFdoYXQncyBoYXBwZW5pbmcgYWJvdmUgaXMgcmVhbGx5OiAweGUwICYgMHhmZiA9IDB4ZTAuIEhvd2V2ZXIsIHRoZSByZXN1bHRzIG9mXG4gKiB0aGlzIGFyZW4ndCB0cmVhdGVkIGFzIGEgc2lnbmVkIG51bWJlci4gVWx0aW1hdGVseSBhIGJhZCB0aGluZy5cbiAqXG4gKiBXaGF0IHdlJ3JlIGdvaW5nIHRvIHdhbnQgdG8gZG8gaXMgYmFzaWNhbGx5IGNyZWF0ZSB0aGUgdW5zaWduZWQgZXF1aXZhbGVudCBvZlxuICogb3VyIHJlcHJlc2VudGF0aW9uIGFuZCBwYXNzIHRoYXQgb2ZmIHRvIHRoZSB3dWludCogZnVuY3Rpb25zLiBUbyBkbyB0aGF0XG4gKiB3ZSdyZSBnb2luZyB0byBkbyB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlmIHRoZSB2YWx1ZSBpcyBwb3NpdGl2ZVxuICogICAgICB3ZSBjYW4gcGFzcyBpdCBkaXJlY3RseSBvZmYgdG8gdGhlIGVxdWl2YWxlbnQgd3VpbnRcbiAqICAtIGlmIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZVxuICogICAgICB3ZSBkbyB0aGUgZm9sbG93aW5nIGNvbXB1dGF0aW9uOlxuICogICAgICAgICBtYiArIHZhbCArIDEsIHdoZXJlXG4gKiAgICAgICAgIG1iICAgaXMgdGhlIG1heGltdW0gdW5zaWduZWQgdmFsdWUgaW4gdGhhdCBieXRlIHNpemVcbiAqICAgICAgICAgdmFsICBpcyB0aGUgSmF2YXNjcmlwdCBuZWdhdGl2ZSBpbnRlZ2VyXG4gKlxuICpcbiAqIEFzIGEgY29uY3JldGUgdmFsdWUsIHRha2UgLTEyOC4gSW4gc2lnbmVkIDE2IGJpdHMgdGhpcyB3b3VsZCBiZSAweGZmODAuIElmXG4gKiB5b3UgZG8gb3V0IHRoZSBjb21wdXRhdGlvbnM6XG4gKlxuICogMHhmZmZmIC0gMTI4ICsgMVxuICogMHhmZmZmIC0gMTI3XG4gKiAweGZmODBcbiAqXG4gKiBZb3UgY2FuIHRoZW4gZW5jb2RlIHRoaXMgdmFsdWUgYXMgdGhlIHNpZ25lZCB2ZXJzaW9uLiBUaGlzIGlzIHJlYWxseSByYXRoZXJcbiAqIGhhY2t5LCBidXQgaXQgc2hvdWxkIHdvcmsgYW5kIGdldCB0aGUgam9iIGRvbmUgd2hpY2ggaXMgb3VyIGdvYWwgaGVyZS5cbiAqL1xuXG4vKlxuICogQSBzZXJpZXMgb2YgY2hlY2tzIHRvIG1ha2Ugc3VyZSB3ZSBhY3R1YWxseSBoYXZlIGEgc2lnbmVkIDMyLWJpdCBudW1iZXJcbiAqL1xuZnVuY3Rpb24gdmVyaWZzaW50KHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQub2sodHlwZW9mICh2YWx1ZSkgPT0gJ251bWJlcicsXG4gICAgICAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKTtcblxuICBhc3NlcnQub2sodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayhNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpO1xufVxuXG5mdW5jdGlvbiB2ZXJpZklFRUU3NTQodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydC5vayh0eXBlb2YgKHZhbHVlKSA9PSAnbnVtYmVyJyxcbiAgICAgICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGxhcmdlciB0aGFuIG1heGltdW0gYWxsb3dlZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA+PSBtaW4sICd2YWx1ZSBzbWFsbGVyIHRoYW4gbWluaW11bSBhbGxvd2VkIHZhbHVlJyk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFyIGJ1ZmZlciA9IHRoaXM7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmLCAtMHg4MCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICBidWZmZXIud3JpdGVVSW50OCgweGZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIG5vQXNzZXJ0KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gd3JpdGVJbnQxNihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZiwgLTB4ODAwMCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIHdyaXRlVUludDE2KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICB3cml0ZVVJbnQxNihidWZmZXIsIDB4ZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlSW50MzIoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIHdyaXRlVUludDMyKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICB3cml0ZVVJbnQzMihidWZmZXIsIDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZsb2F0KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLndyaXRlSUVFRTc1NChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgMjMsIDQpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZURvdWJsZShidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDcgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLndyaXRlSUVFRTc1NChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgNTIsIDgpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcbiIsIihmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuXHRmdW5jdGlvbiBiNjRUb0J5dGVBcnJheShiNjQpIHtcblx0XHR2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFycjtcblx0XG5cdFx0aWYgKGI2NC5sZW5ndGggJSA0ID4gMCkge1xuXHRcdFx0dGhyb3cgJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnO1xuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHRwbGFjZUhvbGRlcnMgPSBiNjQuaW5kZXhPZignPScpO1xuXHRcdHBsYWNlSG9sZGVycyA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gcGxhY2VIb2xkZXJzIDogMDtcblxuXHRcdC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuXHRcdGFyciA9IFtdOy8vbmV3IFVpbnQ4QXJyYXkoYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKTtcblxuXHRcdC8vIGlmIHRoZXJlIGFyZSBwbGFjZWhvbGRlcnMsIG9ubHkgZ2V0IHVwIHRvIHRoZSBsYXN0IGNvbXBsZXRlIDQgY2hhcnNcblx0XHRsID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSA0IDogYjY0Lmxlbmd0aDtcblxuXHRcdGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcblx0XHRcdHRtcCA9IChsb29rdXAuaW5kZXhPZihiNjRbaV0pIDw8IDE4KSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDFdKSA8PCAxMikgfCAobG9va3VwLmluZGV4T2YoYjY0W2kgKyAyXSkgPDwgNikgfCBsb29rdXAuaW5kZXhPZihiNjRbaSArIDNdKTtcblx0XHRcdGFyci5wdXNoKCh0bXAgJiAweEZGMDAwMCkgPj4gMTYpO1xuXHRcdFx0YXJyLnB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOCk7XG5cdFx0XHRhcnIucHVzaCh0bXAgJiAweEZGKTtcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAobG9va3VwLmluZGV4T2YoYjY0W2ldKSA8PCAyKSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDFdKSA+PiA0KTtcblx0XHRcdGFyci5wdXNoKHRtcCAmIDB4RkYpO1xuXHRcdH0gZWxzZSBpZiAocGxhY2VIb2xkZXJzID09PSAxKSB7XG5cdFx0XHR0bXAgPSAobG9va3VwLmluZGV4T2YoYjY0W2ldKSA8PCAxMCkgfCAobG9va3VwLmluZGV4T2YoYjY0W2kgKyAxXSkgPDwgNCkgfCAobG9va3VwLmluZGV4T2YoYjY0W2kgKyAyXSkgPj4gMik7XG5cdFx0XHRhcnIucHVzaCgodG1wID4+IDgpICYgMHhGRik7XG5cdFx0XHRhcnIucHVzaCh0bXAgJiAweEZGKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyO1xuXHR9XG5cblx0ZnVuY3Rpb24gdWludDhUb0Jhc2U2NCh1aW50OCkge1xuXHRcdHZhciBpLFxuXHRcdFx0ZXh0cmFCeXRlcyA9IHVpbnQ4Lmxlbmd0aCAlIDMsIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG5cdFx0XHRvdXRwdXQgPSBcIlwiLFxuXHRcdFx0dGVtcCwgbGVuZ3RoO1xuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgMHgzRl0gKyBsb29rdXBbbnVtID4+IDEyICYgMHgzRl0gKyBsb29rdXBbbnVtID4+IDYgJiAweDNGXSArIGxvb2t1cFtudW0gJiAweDNGXTtcblx0XHR9O1xuXG5cdFx0Ly8gZ28gdGhyb3VnaCB0aGUgYXJyYXkgZXZlcnkgdGhyZWUgYnl0ZXMsIHdlJ2xsIGRlYWwgd2l0aCB0cmFpbGluZyBzdHVmZiBsYXRlclxuXHRcdGZvciAoaSA9IDAsIGxlbmd0aCA9IHVpbnQ4Lmxlbmd0aCAtIGV4dHJhQnl0ZXM7IGkgPCBsZW5ndGg7IGkgKz0gMykge1xuXHRcdFx0dGVtcCA9ICh1aW50OFtpXSA8PCAxNikgKyAodWludDhbaSArIDFdIDw8IDgpICsgKHVpbnQ4W2kgKyAyXSk7XG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApO1xuXHRcdH1cblxuXHRcdC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcblx0XHRzd2l0Y2ggKGV4dHJhQnl0ZXMpIHtcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0dGVtcCA9IHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwW3RlbXAgPj4gMl07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbKHRlbXAgPDwgNCkgJiAweDNGXTtcblx0XHRcdFx0b3V0cHV0ICs9ICc9PSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFt0ZW1wID4+IDEwXTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFsodGVtcCA+PiA0KSAmIDB4M0ZdO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwWyh0ZW1wIDw8IDIpICYgMHgzRl07XG5cdFx0XHRcdG91dHB1dCArPSAnPSc7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cblxuXHRtb2R1bGUuZXhwb3J0cy50b0J5dGVBcnJheSA9IGI2NFRvQnl0ZUFycmF5O1xuXHRtb2R1bGUuZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gdWludDhUb0Jhc2U2NDtcbn0oKSk7XG4iLCJ2YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xudmFyIGludFNpemUgPSA0O1xudmFyIHplcm9CdWZmZXIgPSBuZXcgQnVmZmVyKGludFNpemUpOyB6ZXJvQnVmZmVyLmZpbGwoMCk7XG52YXIgY2hyc3ogPSA4O1xuXG5mdW5jdGlvbiB0b0FycmF5KGJ1ZiwgYmlnRW5kaWFuKSB7XG4gIGlmICgoYnVmLmxlbmd0aCAlIGludFNpemUpICE9PSAwKSB7XG4gICAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGggKyAoaW50U2l6ZSAtIChidWYubGVuZ3RoICUgaW50U2l6ZSkpO1xuICAgIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoW2J1ZiwgemVyb0J1ZmZlcl0sIGxlbik7XG4gIH1cblxuICB2YXIgYXJyID0gW107XG4gIHZhciBmbiA9IGJpZ0VuZGlhbiA/IGJ1Zi5yZWFkSW50MzJCRSA6IGJ1Zi5yZWFkSW50MzJMRTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBidWYubGVuZ3RoOyBpICs9IGludFNpemUpIHtcbiAgICBhcnIucHVzaChmbi5jYWxsKGJ1ZiwgaSkpO1xuICB9XG4gIHJldHVybiBhcnI7XG59XG5cbmZ1bmN0aW9uIHRvQnVmZmVyKGFyciwgc2l6ZSwgYmlnRW5kaWFuKSB7XG4gIHZhciBidWYgPSBuZXcgQnVmZmVyKHNpemUpO1xuICB2YXIgZm4gPSBiaWdFbmRpYW4gPyBidWYud3JpdGVJbnQzMkJFIDogYnVmLndyaXRlSW50MzJMRTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBmbi5jYWxsKGJ1ZiwgYXJyW2ldLCBpICogNCwgdHJ1ZSk7XG4gIH1cbiAgcmV0dXJuIGJ1Zjtcbn1cblxuZnVuY3Rpb24gaGFzaChidWYsIGZuLCBoYXNoU2l6ZSwgYmlnRW5kaWFuKSB7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGJ1ZikpIGJ1ZiA9IG5ldyBCdWZmZXIoYnVmKTtcbiAgdmFyIGFyciA9IGZuKHRvQXJyYXkoYnVmLCBiaWdFbmRpYW4pLCBidWYubGVuZ3RoICogY2hyc3opO1xuICByZXR1cm4gdG9CdWZmZXIoYXJyLCBoYXNoU2l6ZSwgYmlnRW5kaWFuKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7IGhhc2g6IGhhc2ggfTtcbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXJcbnZhciBzaGEgPSByZXF1aXJlKCcuL3NoYScpXG52YXIgc2hhMjU2ID0gcmVxdWlyZSgnLi9zaGEyNTYnKVxudmFyIHJuZyA9IHJlcXVpcmUoJy4vcm5nJylcbnZhciBtZDUgPSByZXF1aXJlKCcuL21kNScpXG5cbnZhciBhbGdvcml0aG1zID0ge1xuICBzaGExOiBzaGEsXG4gIHNoYTI1Njogc2hhMjU2LFxuICBtZDU6IG1kNVxufVxuXG52YXIgYmxvY2tzaXplID0gNjRcbnZhciB6ZXJvQnVmZmVyID0gbmV3IEJ1ZmZlcihibG9ja3NpemUpOyB6ZXJvQnVmZmVyLmZpbGwoMClcbmZ1bmN0aW9uIGhtYWMoZm4sIGtleSwgZGF0YSkge1xuICBpZighQnVmZmVyLmlzQnVmZmVyKGtleSkpIGtleSA9IG5ldyBCdWZmZXIoa2V5KVxuICBpZighQnVmZmVyLmlzQnVmZmVyKGRhdGEpKSBkYXRhID0gbmV3IEJ1ZmZlcihkYXRhKVxuXG4gIGlmKGtleS5sZW5ndGggPiBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBmbihrZXkpXG4gIH0gZWxzZSBpZihrZXkubGVuZ3RoIDwgYmxvY2tzaXplKSB7XG4gICAga2V5ID0gQnVmZmVyLmNvbmNhdChba2V5LCB6ZXJvQnVmZmVyXSwgYmxvY2tzaXplKVxuICB9XG5cbiAgdmFyIGlwYWQgPSBuZXcgQnVmZmVyKGJsb2Nrc2l6ZSksIG9wYWQgPSBuZXcgQnVmZmVyKGJsb2Nrc2l6ZSlcbiAgZm9yKHZhciBpID0gMDsgaSA8IGJsb2Nrc2l6ZTsgaSsrKSB7XG4gICAgaXBhZFtpXSA9IGtleVtpXSBeIDB4MzZcbiAgICBvcGFkW2ldID0ga2V5W2ldIF4gMHg1Q1xuICB9XG5cbiAgdmFyIGhhc2ggPSBmbihCdWZmZXIuY29uY2F0KFtpcGFkLCBkYXRhXSkpXG4gIHJldHVybiBmbihCdWZmZXIuY29uY2F0KFtvcGFkLCBoYXNoXSkpXG59XG5cbmZ1bmN0aW9uIGhhc2goYWxnLCBrZXkpIHtcbiAgYWxnID0gYWxnIHx8ICdzaGExJ1xuICB2YXIgZm4gPSBhbGdvcml0aG1zW2FsZ11cbiAgdmFyIGJ1ZnMgPSBbXVxuICB2YXIgbGVuZ3RoID0gMFxuICBpZighZm4pIGVycm9yKCdhbGdvcml0aG06JywgYWxnLCAnaXMgbm90IHlldCBzdXBwb3J0ZWQnKVxuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGlmKCFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEpXG4gICAgICAgIFxuICAgICAgYnVmcy5wdXNoKGRhdGEpXG4gICAgICBsZW5ndGggKz0gZGF0YS5sZW5ndGhcbiAgICAgIHJldHVybiB0aGlzXG4gICAgfSxcbiAgICBkaWdlc3Q6IGZ1bmN0aW9uIChlbmMpIHtcbiAgICAgIHZhciBidWYgPSBCdWZmZXIuY29uY2F0KGJ1ZnMpXG4gICAgICB2YXIgciA9IGtleSA/IGhtYWMoZm4sIGtleSwgYnVmKSA6IGZuKGJ1ZilcbiAgICAgIGJ1ZnMgPSBudWxsXG4gICAgICByZXR1cm4gZW5jID8gci50b1N0cmluZyhlbmMpIDogclxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBlcnJvciAoKSB7XG4gIHZhciBtID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpLmpvaW4oJyAnKVxuICB0aHJvdyBuZXcgRXJyb3IoW1xuICAgIG0sXG4gICAgJ3dlIGFjY2VwdCBwdWxsIHJlcXVlc3RzJyxcbiAgICAnaHR0cDovL2dpdGh1Yi5jb20vZG9taW5pY3RhcnIvY3J5cHRvLWJyb3dzZXJpZnknXG4gICAgXS5qb2luKCdcXG4nKSlcbn1cblxuZXhwb3J0cy5jcmVhdGVIYXNoID0gZnVuY3Rpb24gKGFsZykgeyByZXR1cm4gaGFzaChhbGcpIH1cbmV4cG9ydHMuY3JlYXRlSG1hYyA9IGZ1bmN0aW9uIChhbGcsIGtleSkgeyByZXR1cm4gaGFzaChhbGcsIGtleSkgfVxuZXhwb3J0cy5yYW5kb21CeXRlcyA9IGZ1bmN0aW9uKHNpemUsIGNhbGxiYWNrKSB7XG4gIGlmIChjYWxsYmFjayAmJiBjYWxsYmFjay5jYWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNhbGxiYWNrLmNhbGwodGhpcywgdW5kZWZpbmVkLCBuZXcgQnVmZmVyKHJuZyhzaXplKSkpXG4gICAgfSBjYXRjaCAoZXJyKSB7IGNhbGxiYWNrKGVycikgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKHJuZyhzaXplKSlcbiAgfVxufVxuXG5mdW5jdGlvbiBlYWNoKGEsIGYpIHtcbiAgZm9yKHZhciBpIGluIGEpXG4gICAgZihhW2ldLCBpKVxufVxuXG4vLyB0aGUgbGVhc3QgSSBjYW4gZG8gaXMgbWFrZSBlcnJvciBtZXNzYWdlcyBmb3IgdGhlIHJlc3Qgb2YgdGhlIG5vZGUuanMvY3J5cHRvIGFwaS5cbmVhY2goWydjcmVhdGVDcmVkZW50aWFscydcbiwgJ2NyZWF0ZUNpcGhlcidcbiwgJ2NyZWF0ZUNpcGhlcml2J1xuLCAnY3JlYXRlRGVjaXBoZXInXG4sICdjcmVhdGVEZWNpcGhlcml2J1xuLCAnY3JlYXRlU2lnbidcbiwgJ2NyZWF0ZVZlcmlmeSdcbiwgJ2NyZWF0ZURpZmZpZUhlbGxtYW4nXG4sICdwYmtkZjInXSwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgZXhwb3J0c1tuYW1lXSA9IGZ1bmN0aW9uICgpIHtcbiAgICBlcnJvcignc29ycnksJywgbmFtZSwgJ2lzIG5vdCBpbXBsZW1lbnRlZCB5ZXQnKVxuICB9XG59KVxuIiwiLypcclxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBSU0EgRGF0YSBTZWN1cml0eSwgSW5jLiBNRDUgTWVzc2FnZVxyXG4gKiBEaWdlc3QgQWxnb3JpdGhtLCBhcyBkZWZpbmVkIGluIFJGQyAxMzIxLlxyXG4gKiBWZXJzaW9uIDIuMSBDb3B5cmlnaHQgKEMpIFBhdWwgSm9obnN0b24gMTk5OSAtIDIwMDIuXHJcbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcclxuICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlXHJcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBtb3JlIGluZm8uXHJcbiAqL1xyXG5cclxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcclxuXHJcbi8qXHJcbiAqIFBlcmZvcm0gYSBzaW1wbGUgc2VsZi10ZXN0IHRvIHNlZSBpZiB0aGUgVk0gaXMgd29ya2luZ1xyXG4gKi9cclxuZnVuY3Rpb24gbWQ1X3ZtX3Rlc3QoKVxyXG57XHJcbiAgcmV0dXJuIGhleF9tZDUoXCJhYmNcIikgPT0gXCI5MDAxNTA5ODNjZDI0ZmIwZDY5NjNmN2QyOGUxN2Y3MlwiO1xyXG59XHJcblxyXG4vKlxyXG4gKiBDYWxjdWxhdGUgdGhlIE1ENSBvZiBhbiBhcnJheSBvZiBsaXR0bGUtZW5kaWFuIHdvcmRzLCBhbmQgYSBiaXQgbGVuZ3RoXHJcbiAqL1xyXG5mdW5jdGlvbiBjb3JlX21kNSh4LCBsZW4pXHJcbntcclxuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xyXG4gIHhbbGVuID4+IDVdIHw9IDB4ODAgPDwgKChsZW4pICUgMzIpO1xyXG4gIHhbKCgobGVuICsgNjQpID4+PiA5KSA8PCA0KSArIDE0XSA9IGxlbjtcclxuXHJcbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcclxuICB2YXIgYiA9IC0yNzE3MzM4Nzk7XHJcbiAgdmFyIGMgPSAtMTczMjU4NDE5NDtcclxuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XHJcblxyXG4gIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgaSArPSAxNilcclxuICB7XHJcbiAgICB2YXIgb2xkYSA9IGE7XHJcbiAgICB2YXIgb2xkYiA9IGI7XHJcbiAgICB2YXIgb2xkYyA9IGM7XHJcbiAgICB2YXIgb2xkZCA9IGQ7XHJcblxyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDBdLCA3ICwgLTY4MDg3NjkzNik7XHJcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgMV0sIDEyLCAtMzg5NTY0NTg2KTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKyAyXSwgMTcsICA2MDYxMDU4MTkpO1xyXG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krIDNdLCAyMiwgLTEwNDQ1MjUzMzApO1xyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDRdLCA3ICwgLTE3NjQxODg5Nyk7XHJcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgNV0sIDEyLCAgMTIwMDA4MDQyNik7XHJcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsgNl0sIDE3LCAtMTQ3MzIzMTM0MSk7XHJcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsgN10sIDIyLCAtNDU3MDU5ODMpO1xyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krIDhdLCA3ICwgIDE3NzAwMzU0MTYpO1xyXG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krIDldLCAxMiwgLTE5NTg0MTQ0MTcpO1xyXG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krMTBdLCAxNywgLTQyMDYzKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKzExXSwgMjIsIC0xOTkwNDA0MTYyKTtcclxuICAgIGEgPSBtZDVfZmYoYSwgYiwgYywgZCwgeFtpKzEyXSwgNyAsICAxODA0NjAzNjgyKTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKzEzXSwgMTIsIC00MDM0MTEwMSk7XHJcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE3LCAtMTUwMjAwMjI5MCk7XHJcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsxNV0sIDIyLCAgMTIzNjUzNTMyOSk7XHJcblxyXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDFdLCA1ICwgLTE2NTc5NjUxMCk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgNl0sIDkgLCAtMTA2OTUwMTYzMik7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxMV0sIDE0LCAgNjQzNzE3NzEzKTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyAwXSwgMjAsIC0zNzM4OTczMDIpO1xyXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDVdLCA1ICwgLTcwMTU1ODY5MSk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxMF0sIDkgLCAgMzgwMTYwODMpO1xyXG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krMTVdLCAxNCwgLTY2MDQ3ODMzNSk7XHJcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsgNF0sIDIwLCAtNDA1NTM3ODQ4KTtcclxuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKyA5XSwgNSAsICA1Njg0NDY0MzgpO1xyXG4gICAgZCA9IG1kNV9nZyhkLCBhLCBiLCBjLCB4W2krMTRdLCA5ICwgLTEwMTk4MDM2OTApO1xyXG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krIDNdLCAxNCwgLTE4NzM2Mzk2MSk7XHJcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsgOF0sIDIwLCAgMTE2MzUzMTUwMSk7XHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsxM10sIDUgLCAtMTQ0NDY4MTQ2Nyk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsgMl0sIDkgLCAtNTE0MDM3ODQpO1xyXG4gICAgYyA9IG1kNV9nZyhjLCBkLCBhLCBiLCB4W2krIDddLCAxNCwgIDE3MzUzMjg0NzMpO1xyXG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krMTJdLCAyMCwgLTE5MjY2MDc3MzQpO1xyXG5cclxuICAgIGEgPSBtZDVfaGgoYSwgYiwgYywgZCwgeFtpKyA1XSwgNCAsIC0zNzg1NTgpO1xyXG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDhdLCAxMSwgLTIwMjI1NzQ0NjMpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krMTFdLCAxNiwgIDE4MzkwMzA1NjIpO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krMTRdLCAyMywgLTM1MzA5NTU2KTtcclxuICAgIGEgPSBtZDVfaGgoYSwgYiwgYywgZCwgeFtpKyAxXSwgNCAsIC0xNTMwOTkyMDYwKTtcclxuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyA0XSwgMTEsICAxMjcyODkzMzUzKTtcclxuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKyA3XSwgMTYsIC0xNTU0OTc2MzIpO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krMTBdLCAyMywgLTEwOTQ3MzA2NDApO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krMTNdLCA0ICwgIDY4MTI3OTE3NCk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgMF0sIDExLCAtMzU4NTM3MjIyKTtcclxuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKyAzXSwgMTYsIC03MjI1MjE5NzkpO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDZdLCAyMywgIDc2MDI5MTg5KTtcclxuICAgIGEgPSBtZDVfaGgoYSwgYiwgYywgZCwgeFtpKyA5XSwgNCAsIC02NDAzNjQ0ODcpO1xyXG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krMTJdLCAxMSwgLTQyMTgxNTgzNSk7XHJcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE2LCAgNTMwNzQyNTIwKTtcclxuICAgIGIgPSBtZDVfaGgoYiwgYywgZCwgYSwgeFtpKyAyXSwgMjMsIC05OTUzMzg2NTEpO1xyXG5cclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyAwXSwgNiAsIC0xOTg2MzA4NDQpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDddLCAxMCwgIDExMjY4OTE0MTUpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krMTRdLCAxNSwgLTE0MTYzNTQ5MDUpO1xyXG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDVdLCAyMSwgLTU3NDM0MDU1KTtcclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKzEyXSwgNiAsICAxNzAwNDg1NTcxKTtcclxuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKyAzXSwgMTAsIC0xODk0OTg2NjA2KTtcclxuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKzEwXSwgMTUsIC0xMDUxNTIzKTtcclxuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKyAxXSwgMjEsIC0yMDU0OTIyNzk5KTtcclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyA4XSwgNiAsICAxODczMzEzMzU5KTtcclxuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKzE1XSwgMTAsIC0zMDYxMTc0NCk7XHJcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsgNl0sIDE1LCAtMTU2MDE5ODM4MCk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsxM10sIDIxLCAgMTMwOTE1MTY0OSk7XHJcbiAgICBhID0gbWQ1X2lpKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDYgLCAtMTQ1NTIzMDcwKTtcclxuICAgIGQgPSBtZDVfaWkoZCwgYSwgYiwgYywgeFtpKzExXSwgMTAsIC0xMTIwMjEwMzc5KTtcclxuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyAyXSwgMTUsICA3MTg3ODcyNTkpO1xyXG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDldLCAyMSwgLTM0MzQ4NTU1MSk7XHJcblxyXG4gICAgYSA9IHNhZmVfYWRkKGEsIG9sZGEpO1xyXG4gICAgYiA9IHNhZmVfYWRkKGIsIG9sZGIpO1xyXG4gICAgYyA9IHNhZmVfYWRkKGMsIG9sZGMpO1xyXG4gICAgZCA9IHNhZmVfYWRkKGQsIG9sZGQpO1xyXG4gIH1cclxuICByZXR1cm4gQXJyYXkoYSwgYiwgYywgZCk7XHJcblxyXG59XHJcblxyXG4vKlxyXG4gKiBUaGVzZSBmdW5jdGlvbnMgaW1wbGVtZW50IHRoZSBmb3VyIGJhc2ljIG9wZXJhdGlvbnMgdGhlIGFsZ29yaXRobSB1c2VzLlxyXG4gKi9cclxuZnVuY3Rpb24gbWQ1X2NtbihxLCBhLCBiLCB4LCBzLCB0KVxyXG57XHJcbiAgcmV0dXJuIHNhZmVfYWRkKGJpdF9yb2woc2FmZV9hZGQoc2FmZV9hZGQoYSwgcSksIHNhZmVfYWRkKHgsIHQpKSwgcyksYik7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2ZmKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbigoYiAmIGMpIHwgKCh+YikgJiBkKSwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2dnKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbigoYiAmIGQpIHwgKGMgJiAofmQpKSwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2hoKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbihiIF4gYyBeIGQsIGEsIGIsIHgsIHMsIHQpO1xyXG59XHJcbmZ1bmN0aW9uIG1kNV9paShhLCBiLCBjLCBkLCB4LCBzLCB0KVxyXG57XHJcbiAgcmV0dXJuIG1kNV9jbW4oYyBeIChiIHwgKH5kKSksIGEsIGIsIHgsIHMsIHQpO1xyXG59XHJcblxyXG4vKlxyXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XHJcbiAqIHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXHJcbiAqL1xyXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxyXG57XHJcbiAgdmFyIGxzdyA9ICh4ICYgMHhGRkZGKSArICh5ICYgMHhGRkZGKTtcclxuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XHJcbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XHJcbn1cclxuXHJcbi8qXHJcbiAqIEJpdHdpc2Ugcm90YXRlIGEgMzItYml0IG51bWJlciB0byB0aGUgbGVmdC5cclxuICovXHJcbmZ1bmN0aW9uIGJpdF9yb2wobnVtLCBjbnQpXHJcbntcclxuICByZXR1cm4gKG51bSA8PCBjbnQpIHwgKG51bSA+Pj4gKDMyIC0gY250KSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gbWQ1KGJ1Zikge1xyXG4gIHJldHVybiBoZWxwZXJzLmhhc2goYnVmLCBjb3JlX21kNSwgMTYpO1xyXG59O1xyXG4iLCIvLyBPcmlnaW5hbCBjb2RlIGFkYXB0ZWQgZnJvbSBSb2JlcnQgS2llZmZlci5cbi8vIGRldGFpbHMgYXQgaHR0cHM6Ly9naXRodWIuY29tL2Jyb29mYS9ub2RlLXV1aWRcbihmdW5jdGlvbigpIHtcbiAgdmFyIF9nbG9iYWwgPSB0aGlzO1xuXG4gIHZhciBtYXRoUk5HLCB3aGF0d2dSTkc7XG5cbiAgLy8gTk9URTogTWF0aC5yYW5kb20oKSBkb2VzIG5vdCBndWFyYW50ZWUgXCJjcnlwdG9ncmFwaGljIHF1YWxpdHlcIlxuICBtYXRoUk5HID0gZnVuY3Rpb24oc2l6ZSkge1xuICAgIHZhciBieXRlcyA9IG5ldyBBcnJheShzaXplKTtcbiAgICB2YXIgcjtcblxuICAgIGZvciAodmFyIGkgPSAwLCByOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgICBpZiAoKGkgJiAweDAzKSA9PSAwKSByID0gTWF0aC5yYW5kb20oKSAqIDB4MTAwMDAwMDAwO1xuICAgICAgYnl0ZXNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG5cbiAgaWYgKF9nbG9iYWwuY3J5cHRvICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHtcbiAgICB3aGF0d2dSTkcgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShzaXplKTtcbiAgICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYnl0ZXMpO1xuICAgICAgcmV0dXJuIGJ5dGVzO1xuICAgIH1cbiAgfVxuXG4gIG1vZHVsZS5leHBvcnRzID0gd2hhdHdnUk5HIHx8IG1hdGhSTkc7XG5cbn0oKSlcbiIsIi8qXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFNlY3VyZSBIYXNoIEFsZ29yaXRobSwgU0hBLTEsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgUFVCIDE4MC0xXG4gKiBWZXJzaW9uIDIuMWEgQ29weXJpZ2h0IFBhdWwgSm9obnN0b24gMjAwMCAtIDIwMDIuXG4gKiBPdGhlciBjb250cmlidXRvcnM6IEdyZWcgSG9sdCwgQW5kcmV3IEtlcGVydCwgWWRuYXIsIExvc3RpbmV0XG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcbiAqIFNlZSBodHRwOi8vcGFqaG9tZS5vcmcudWsvY3J5cHQvbWQ1IGZvciBkZXRhaWxzLlxuICovXG5cbnZhciBoZWxwZXJzID0gcmVxdWlyZSgnLi9oZWxwZXJzJyk7XG5cbi8qXG4gKiBDYWxjdWxhdGUgdGhlIFNIQS0xIG9mIGFuIGFycmF5IG9mIGJpZy1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcbiAqL1xuZnVuY3Rpb24gY29yZV9zaGExKHgsIGxlbilcbntcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsZW4gJSAzMik7XG4gIHhbKChsZW4gKyA2NCA+PiA5KSA8PCA0KSArIDE1XSA9IGxlbjtcblxuICB2YXIgdyA9IEFycmF5KDgwKTtcbiAgdmFyIGEgPSAgMTczMjU4NDE5MztcbiAgdmFyIGIgPSAtMjcxNzMzODc5O1xuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xuICB2YXIgZCA9ICAyNzE3MzM4Nzg7XG4gIHZhciBlID0gLTEwMDk1ODk3NzY7XG5cbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxuICB7XG4gICAgdmFyIG9sZGEgPSBhO1xuICAgIHZhciBvbGRiID0gYjtcbiAgICB2YXIgb2xkYyA9IGM7XG4gICAgdmFyIG9sZGQgPSBkO1xuICAgIHZhciBvbGRlID0gZTtcblxuICAgIGZvcih2YXIgaiA9IDA7IGogPCA4MDsgaisrKVxuICAgIHtcbiAgICAgIGlmKGogPCAxNikgd1tqXSA9IHhbaSArIGpdO1xuICAgICAgZWxzZSB3W2pdID0gcm9sKHdbai0zXSBeIHdbai04XSBeIHdbai0xNF0gXiB3W2otMTZdLCAxKTtcbiAgICAgIHZhciB0ID0gc2FmZV9hZGQoc2FmZV9hZGQocm9sKGEsIDUpLCBzaGExX2Z0KGosIGIsIGMsIGQpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgc2FmZV9hZGQoc2FmZV9hZGQoZSwgd1tqXSksIHNoYTFfa3QoaikpKTtcbiAgICAgIGUgPSBkO1xuICAgICAgZCA9IGM7XG4gICAgICBjID0gcm9sKGIsIDMwKTtcbiAgICAgIGIgPSBhO1xuICAgICAgYSA9IHQ7XG4gICAgfVxuXG4gICAgYSA9IHNhZmVfYWRkKGEsIG9sZGEpO1xuICAgIGIgPSBzYWZlX2FkZChiLCBvbGRiKTtcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XG4gICAgZCA9IHNhZmVfYWRkKGQsIG9sZGQpO1xuICAgIGUgPSBzYWZlX2FkZChlLCBvbGRlKTtcbiAgfVxuICByZXR1cm4gQXJyYXkoYSwgYiwgYywgZCwgZSk7XG5cbn1cblxuLypcbiAqIFBlcmZvcm0gdGhlIGFwcHJvcHJpYXRlIHRyaXBsZXQgY29tYmluYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjdXJyZW50XG4gKiBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9mdCh0LCBiLCBjLCBkKVxue1xuICBpZih0IDwgMjApIHJldHVybiAoYiAmIGMpIHwgKCh+YikgJiBkKTtcbiAgaWYodCA8IDQwKSByZXR1cm4gYiBeIGMgXiBkO1xuICBpZih0IDwgNjApIHJldHVybiAoYiAmIGMpIHwgKGIgJiBkKSB8IChjICYgZCk7XG4gIHJldHVybiBiIF4gYyBeIGQ7XG59XG5cbi8qXG4gKiBEZXRlcm1pbmUgdGhlIGFwcHJvcHJpYXRlIGFkZGl0aXZlIGNvbnN0YW50IGZvciB0aGUgY3VycmVudCBpdGVyYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hhMV9rdCh0KVxue1xuICByZXR1cm4gKHQgPCAyMCkgPyAgMTUxODUwMDI0OSA6ICh0IDwgNDApID8gIDE4NTk3NzUzOTMgOlxuICAgICAgICAgKHQgPCA2MCkgPyAtMTg5NDAwNzU4OCA6IC04OTk0OTc1MTQ7XG59XG5cbi8qXG4gKiBBZGQgaW50ZWdlcnMsIHdyYXBwaW5nIGF0IDJeMzIuIFRoaXMgdXNlcyAxNi1iaXQgb3BlcmF0aW9ucyBpbnRlcm5hbGx5XG4gKiB0byB3b3JrIGFyb3VuZCBidWdzIGluIHNvbWUgSlMgaW50ZXJwcmV0ZXJzLlxuICovXG5mdW5jdGlvbiBzYWZlX2FkZCh4LCB5KVxue1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufVxuXG4vKlxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxuICovXG5mdW5jdGlvbiByb2wobnVtLCBjbnQpXG57XG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaGExKGJ1Zikge1xuICByZXR1cm4gaGVscGVycy5oYXNoKGJ1ZiwgY29yZV9zaGExLCAyMCwgdHJ1ZSk7XG59O1xuIiwiXG4vKipcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMjU2LCBhcyBkZWZpbmVkXG4gKiBpbiBGSVBTIDE4MC0yXG4gKiBWZXJzaW9uIDIuMi1iZXRhIENvcHlyaWdodCBBbmdlbCBNYXJpbiwgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwOS5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqXG4gKi9cblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxudmFyIHNhZmVfYWRkID0gZnVuY3Rpb24oeCwgeSkge1xuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xuICB2YXIgbXN3ID0gKHggPj4gMTYpICsgKHkgPj4gMTYpICsgKGxzdyA+PiAxNik7XG4gIHJldHVybiAobXN3IDw8IDE2KSB8IChsc3cgJiAweEZGRkYpO1xufTtcblxudmFyIFMgPSBmdW5jdGlvbihYLCBuKSB7XG4gIHJldHVybiAoWCA+Pj4gbikgfCAoWCA8PCAoMzIgLSBuKSk7XG59O1xuXG52YXIgUiA9IGZ1bmN0aW9uKFgsIG4pIHtcbiAgcmV0dXJuIChYID4+PiBuKTtcbn07XG5cbnZhciBDaCA9IGZ1bmN0aW9uKHgsIHksIHopIHtcbiAgcmV0dXJuICgoeCAmIHkpIF4gKCh+eCkgJiB6KSk7XG59O1xuXG52YXIgTWFqID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICByZXR1cm4gKCh4ICYgeSkgXiAoeCAmIHopIF4gKHkgJiB6KSk7XG59O1xuXG52YXIgU2lnbWEwMjU2ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gKFMoeCwgMikgXiBTKHgsIDEzKSBeIFMoeCwgMjIpKTtcbn07XG5cbnZhciBTaWdtYTEyNTYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAoUyh4LCA2KSBeIFMoeCwgMTEpIF4gUyh4LCAyNSkpO1xufTtcblxudmFyIEdhbW1hMDI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDcpIF4gUyh4LCAxOCkgXiBSKHgsIDMpKTtcbn07XG5cbnZhciBHYW1tYTEyNTYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAoUyh4LCAxNykgXiBTKHgsIDE5KSBeIFIoeCwgMTApKTtcbn07XG5cbnZhciBjb3JlX3NoYTI1NiA9IGZ1bmN0aW9uKG0sIGwpIHtcbiAgdmFyIEsgPSBuZXcgQXJyYXkoMHg0MjhBMkY5OCwweDcxMzc0NDkxLDB4QjVDMEZCQ0YsMHhFOUI1REJBNSwweDM5NTZDMjVCLDB4NTlGMTExRjEsMHg5MjNGODJBNCwweEFCMUM1RUQ1LDB4RDgwN0FBOTgsMHgxMjgzNUIwMSwweDI0MzE4NUJFLDB4NTUwQzdEQzMsMHg3MkJFNUQ3NCwweDgwREVCMUZFLDB4OUJEQzA2QTcsMHhDMTlCRjE3NCwweEU0OUI2OUMxLDB4RUZCRTQ3ODYsMHhGQzE5REM2LDB4MjQwQ0ExQ0MsMHgyREU5MkM2RiwweDRBNzQ4NEFBLDB4NUNCMEE5REMsMHg3NkY5ODhEQSwweDk4M0U1MTUyLDB4QTgzMUM2NkQsMHhCMDAzMjdDOCwweEJGNTk3RkM3LDB4QzZFMDBCRjMsMHhENUE3OTE0NywweDZDQTYzNTEsMHgxNDI5Mjk2NywweDI3QjcwQTg1LDB4MkUxQjIxMzgsMHg0RDJDNkRGQywweDUzMzgwRDEzLDB4NjUwQTczNTQsMHg3NjZBMEFCQiwweDgxQzJDOTJFLDB4OTI3MjJDODUsMHhBMkJGRThBMSwweEE4MUE2NjRCLDB4QzI0QjhCNzAsMHhDNzZDNTFBMywweEQxOTJFODE5LDB4RDY5OTA2MjQsMHhGNDBFMzU4NSwweDEwNkFBMDcwLDB4MTlBNEMxMTYsMHgxRTM3NkMwOCwweDI3NDg3NzRDLDB4MzRCMEJDQjUsMHgzOTFDMENCMywweDRFRDhBQTRBLDB4NUI5Q0NBNEYsMHg2ODJFNkZGMywweDc0OEY4MkVFLDB4NzhBNTYzNkYsMHg4NEM4NzgxNCwweDhDQzcwMjA4LDB4OTBCRUZGRkEsMHhBNDUwNkNFQiwweEJFRjlBM0Y3LDB4QzY3MTc4RjIpO1xuICB2YXIgSEFTSCA9IG5ldyBBcnJheSgweDZBMDlFNjY3LCAweEJCNjdBRTg1LCAweDNDNkVGMzcyLCAweEE1NEZGNTNBLCAweDUxMEU1MjdGLCAweDlCMDU2ODhDLCAweDFGODNEOUFCLCAweDVCRTBDRDE5KTtcbiAgICB2YXIgVyA9IG5ldyBBcnJheSg2NCk7XG4gICAgdmFyIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGgsIGksIGo7XG4gICAgdmFyIFQxLCBUMjtcbiAgLyogYXBwZW5kIHBhZGRpbmcgKi9cbiAgbVtsID4+IDVdIHw9IDB4ODAgPDwgKDI0IC0gbCAlIDMyKTtcbiAgbVsoKGwgKyA2NCA+PiA5KSA8PCA0KSArIDE1XSA9IGw7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbS5sZW5ndGg7IGkgKz0gMTYpIHtcbiAgICBhID0gSEFTSFswXTsgYiA9IEhBU0hbMV07IGMgPSBIQVNIWzJdOyBkID0gSEFTSFszXTsgZSA9IEhBU0hbNF07IGYgPSBIQVNIWzVdOyBnID0gSEFTSFs2XTsgaCA9IEhBU0hbN107XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCA2NDsgaisrKSB7XG4gICAgICBpZiAoaiA8IDE2KSB7XG4gICAgICAgIFdbal0gPSBtW2ogKyBpXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIFdbal0gPSBzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChHYW1tYTEyNTYoV1tqIC0gMl0pLCBXW2ogLSA3XSksIEdhbW1hMDI1NihXW2ogLSAxNV0pKSwgV1tqIC0gMTZdKTtcbiAgICAgIH1cbiAgICAgIFQxID0gc2FmZV9hZGQoc2FmZV9hZGQoc2FmZV9hZGQoc2FmZV9hZGQoaCwgU2lnbWExMjU2KGUpKSwgQ2goZSwgZiwgZykpLCBLW2pdKSwgV1tqXSk7XG4gICAgICBUMiA9IHNhZmVfYWRkKFNpZ21hMDI1NihhKSwgTWFqKGEsIGIsIGMpKTtcbiAgICAgIGggPSBnOyBnID0gZjsgZiA9IGU7IGUgPSBzYWZlX2FkZChkLCBUMSk7IGQgPSBjOyBjID0gYjsgYiA9IGE7IGEgPSBzYWZlX2FkZChUMSwgVDIpO1xuICAgIH1cbiAgICBIQVNIWzBdID0gc2FmZV9hZGQoYSwgSEFTSFswXSk7IEhBU0hbMV0gPSBzYWZlX2FkZChiLCBIQVNIWzFdKTsgSEFTSFsyXSA9IHNhZmVfYWRkKGMsIEhBU0hbMl0pOyBIQVNIWzNdID0gc2FmZV9hZGQoZCwgSEFTSFszXSk7XG4gICAgSEFTSFs0XSA9IHNhZmVfYWRkKGUsIEhBU0hbNF0pOyBIQVNIWzVdID0gc2FmZV9hZGQoZiwgSEFTSFs1XSk7IEhBU0hbNl0gPSBzYWZlX2FkZChnLCBIQVNIWzZdKTsgSEFTSFs3XSA9IHNhZmVfYWRkKGgsIEhBU0hbN10pO1xuICB9XG4gIHJldHVybiBIQVNIO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzaGEyNTYoYnVmKSB7XG4gIHJldHVybiBoZWxwZXJzLmhhc2goYnVmLCBjb3JlX3NoYTI1NiwgMzIsIHRydWUpO1xufTtcbiIsInZhciBodHRwID0gbW9kdWxlLmV4cG9ydHM7XG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIFJlcXVlc3QgPSByZXF1aXJlKCcuL2xpYi9yZXF1ZXN0Jyk7XG5cbmh0dHAucmVxdWVzdCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gICAgaWYgKCFwYXJhbXMpIHBhcmFtcyA9IHt9O1xuICAgIGlmICghcGFyYW1zLmhvc3QgJiYgIXBhcmFtcy5wb3J0KSB7XG4gICAgICAgIHBhcmFtcy5wb3J0ID0gcGFyc2VJbnQod2luZG93LmxvY2F0aW9uLnBvcnQsIDEwKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuaG9zdCkgcGFyYW1zLmhvc3QgPSB3aW5kb3cubG9jYXRpb24uaG9zdG5hbWU7XG4gICAgaWYgKCFwYXJhbXMucG9ydCkgcGFyYW1zLnBvcnQgPSA4MDtcbiAgICBpZiAoIXBhcmFtcy5zY2hlbWUpIHBhcmFtcy5zY2hlbWUgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wuc3BsaXQoJzonKVswXTtcbiAgICBcbiAgICB2YXIgcmVxID0gbmV3IFJlcXVlc3QobmV3IHhockh0dHAsIHBhcmFtcyk7XG4gICAgaWYgKGNiKSByZXEub24oJ3Jlc3BvbnNlJywgY2IpO1xuICAgIHJldHVybiByZXE7XG59O1xuXG5odHRwLmdldCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gICAgcGFyYW1zLm1ldGhvZCA9ICdHRVQnO1xuICAgIHZhciByZXEgPSBodHRwLnJlcXVlc3QocGFyYW1zLCBjYik7XG4gICAgcmVxLmVuZCgpO1xuICAgIHJldHVybiByZXE7XG59O1xuXG5odHRwLkFnZW50ID0gZnVuY3Rpb24gKCkge307XG5odHRwLkFnZW50LmRlZmF1bHRNYXhTb2NrZXRzID0gNDtcblxudmFyIHhockh0dHAgPSAoZnVuY3Rpb24gKCkge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHdpbmRvdyBvYmplY3QgcHJlc2VudCcpO1xuICAgIH1cbiAgICBlbHNlIGlmICh3aW5kb3cuWE1MSHR0cFJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5YTUxIdHRwUmVxdWVzdDtcbiAgICB9XG4gICAgZWxzZSBpZiAod2luZG93LkFjdGl2ZVhPYmplY3QpIHtcbiAgICAgICAgdmFyIGF4cyA9IFtcbiAgICAgICAgICAgICdNc3htbDIuWE1MSFRUUC42LjAnLFxuICAgICAgICAgICAgJ01zeG1sMi5YTUxIVFRQLjMuMCcsXG4gICAgICAgICAgICAnTWljcm9zb2Z0LlhNTEhUVFAnXG4gICAgICAgIF07XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBheCA9IG5ldyh3aW5kb3cuQWN0aXZlWE9iamVjdCkoYXhzW2ldKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBheF8gPSBheDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF4ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBheF87XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3KHdpbmRvdy5BY3RpdmVYT2JqZWN0KShheHNbaV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7fVxuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWpheCBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FqYXggbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKTtcbiAgICB9XG59KSgpO1xuIiwidmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIFJlc3BvbnNlID0gcmVxdWlyZSgnLi9yZXNwb25zZScpO1xudmFyIGNvbmNhdFN0cmVhbSA9IHJlcXVpcmUoJ2NvbmNhdC1zdHJlYW0nKTtcbnZhciBCYXNlNjQgPSByZXF1aXJlKCdCYXNlNjQnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG52YXIgUmVxdWVzdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHhociwgcGFyYW1zKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgIHNlbGYueGhyID0geGhyO1xuICAgIHNlbGYuYm9keSA9IGNvbmNhdFN0cmVhbSgpXG4gICAgXG4gICAgdmFyIHVyaSA9IHBhcmFtcy5ob3N0XG4gICAgICAgICsgKHBhcmFtcy5wb3J0ID8gJzonICsgcGFyYW1zLnBvcnQgOiAnJylcbiAgICAgICAgKyAocGFyYW1zLnBhdGggfHwgJy8nKVxuICAgIDtcbiAgICBcbiAgICB4aHIub3BlbihcbiAgICAgICAgcGFyYW1zLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgICAgKHBhcmFtcy5zY2hlbWUgfHwgJ2h0dHAnKSArICc6Ly8nICsgdXJpLFxuICAgICAgICB0cnVlXG4gICAgKTtcbiAgICBcbiAgICBpZiAocGFyYW1zLmhlYWRlcnMpIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKHBhcmFtcy5oZWFkZXJzKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICAgIGlmICghc2VsZi5pc1NhZmVSZXF1ZXN0SGVhZGVyKGtleSkpIGNvbnRpbnVlO1xuICAgICAgICAgICAgdmFyIHZhbHVlID0gcGFyYW1zLmhlYWRlcnNba2V5XTtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdmFsdWUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZVtqXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKVxuICAgICAgICB9XG4gICAgfVxuICAgIFxuICAgIGlmIChwYXJhbXMuYXV0aCkge1xuICAgICAgICAvL2Jhc2ljIGF1dGhcbiAgICAgICAgdGhpcy5zZXRIZWFkZXIoJ0F1dGhvcml6YXRpb24nLCAnQmFzaWMgJyArIEJhc2U2NC5idG9hKHBhcmFtcy5hdXRoKSk7XG4gICAgfVxuXG4gICAgdmFyIHJlcyA9IG5ldyBSZXNwb25zZTtcbiAgICByZXMub24oJ2Nsb3NlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLmVtaXQoJ2Nsb3NlJyk7XG4gICAgfSk7XG4gICAgXG4gICAgcmVzLm9uKCdyZWFkeScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5lbWl0KCdyZXNwb25zZScsIHJlcyk7XG4gICAgfSk7XG4gICAgXG4gICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmVzLmhhbmRsZSh4aHIpO1xuICAgIH07XG59O1xuXG51dGlsLmluaGVyaXRzKFJlcXVlc3QsIFN0cmVhbSk7XG5cblJlcXVlc3QucHJvdG90eXBlLnNldEhlYWRlciA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRoaXMueGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZVtpXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRoaXMueGhyLnNldFJlcXVlc3RIZWFkZXIoa2V5LCB2YWx1ZSk7XG4gICAgfVxufTtcblxuUmVxdWVzdC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocykge1xuICAgIHRoaXMuYm9keS53cml0ZShzKTtcbn07XG5cblJlcXVlc3QucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbiAocykge1xuICAgIHRoaXMueGhyLmFib3J0KCk7XG4gICAgdGhpcy5lbWl0KCdjbG9zZScpO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24gKHMpIHtcbiAgICBpZiAocyAhPT0gdW5kZWZpbmVkKSB0aGlzLmJvZHkud3JpdGUocyk7XG4gICAgdGhpcy5ib2R5LmVuZCgpXG4gICAgdGhpcy54aHIuc2VuZCh0aGlzLmJvZHkuZ2V0Qm9keSgpKTtcbn07XG5cbi8vIFRha2VuIGZyb20gaHR0cDovL2R4ci5tb3ppbGxhLm9yZy9tb3ppbGxhL21vemlsbGEtY2VudHJhbC9jb250ZW50L2Jhc2Uvc3JjL25zWE1MSHR0cFJlcXVlc3QuY3BwLmh0bWxcblJlcXVlc3QudW5zYWZlSGVhZGVycyA9IFtcbiAgICBcImFjY2VwdC1jaGFyc2V0XCIsXG4gICAgXCJhY2NlcHQtZW5jb2RpbmdcIixcbiAgICBcImFjY2Vzcy1jb250cm9sLXJlcXVlc3QtaGVhZGVyc1wiLFxuICAgIFwiYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1tZXRob2RcIixcbiAgICBcImNvbm5lY3Rpb25cIixcbiAgICBcImNvbnRlbnQtbGVuZ3RoXCIsXG4gICAgXCJjb29raWVcIixcbiAgICBcImNvb2tpZTJcIixcbiAgICBcImNvbnRlbnQtdHJhbnNmZXItZW5jb2RpbmdcIixcbiAgICBcImRhdGVcIixcbiAgICBcImV4cGVjdFwiLFxuICAgIFwiaG9zdFwiLFxuICAgIFwia2VlcC1hbGl2ZVwiLFxuICAgIFwib3JpZ2luXCIsXG4gICAgXCJyZWZlcmVyXCIsXG4gICAgXCJ0ZVwiLFxuICAgIFwidHJhaWxlclwiLFxuICAgIFwidHJhbnNmZXItZW5jb2RpbmdcIixcbiAgICBcInVwZ3JhZGVcIixcbiAgICBcInVzZXItYWdlbnRcIixcbiAgICBcInZpYVwiXG5dO1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5pc1NhZmVSZXF1ZXN0SGVhZGVyID0gZnVuY3Rpb24gKGhlYWRlck5hbWUpIHtcbiAgICBpZiAoIWhlYWRlck5hbWUpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gaW5kZXhPZihSZXF1ZXN0LnVuc2FmZUhlYWRlcnMsIGhlYWRlck5hbWUudG9Mb3dlckNhc2UoKSkgPT09IC0xO1xufTtcblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSBrZXlzLnB1c2goa2V5KTtcbiAgICByZXR1cm4ga2V5cztcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG5cbnZhciBpbmRleE9mID0gZnVuY3Rpb24gKHhzLCB4KSB7XG4gICAgaWYgKHhzLmluZGV4T2YpIHJldHVybiB4cy5pbmRleE9mKHgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHhzW2ldID09PSB4KSByZXR1cm4gaTtcbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufTtcbiIsInZhciBTdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG52YXIgUmVzcG9uc2UgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgICB0aGlzLm9mZnNldCA9IDA7XG4gICAgdGhpcy5yZWFkYWJsZSA9IHRydWU7XG59O1xuXG51dGlsLmluaGVyaXRzKFJlc3BvbnNlLCBTdHJlYW0pO1xuXG52YXIgY2FwYWJsZSA9IHtcbiAgICBzdHJlYW1pbmcgOiB0cnVlLFxuICAgIHN0YXR1czIgOiB0cnVlXG59O1xuXG5mdW5jdGlvbiBwYXJzZUhlYWRlcnMgKHJlcykge1xuICAgIHZhciBsaW5lcyA9IHJlcy5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKS5zcGxpdCgvXFxyP1xcbi8pO1xuICAgIHZhciBoZWFkZXJzID0ge307XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbGluZSA9IGxpbmVzW2ldO1xuICAgICAgICBpZiAobGluZSA9PT0gJycpIGNvbnRpbnVlO1xuICAgICAgICBcbiAgICAgICAgdmFyIG0gPSBsaW5lLm1hdGNoKC9eKFteOl0rKTpcXHMqKC4qKS8pO1xuICAgICAgICBpZiAobSkge1xuICAgICAgICAgICAgdmFyIGtleSA9IG1bMV0udG9Mb3dlckNhc2UoKSwgdmFsdWUgPSBtWzJdO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoaGVhZGVyc1trZXldICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KGhlYWRlcnNba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyc1trZXldLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyc1trZXldID0gWyBoZWFkZXJzW2tleV0sIHZhbHVlIF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaGVhZGVyc1trZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoZWFkZXJzW2xpbmVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaGVhZGVycztcbn1cblxuUmVzcG9uc2UucHJvdG90eXBlLmdldFJlc3BvbnNlID0gZnVuY3Rpb24gKHhocikge1xuICAgIHZhciByZXNwVHlwZSA9IFN0cmluZyh4aHIucmVzcG9uc2VUeXBlKS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChyZXNwVHlwZSA9PT0gJ2Jsb2InKSByZXR1cm4geGhyLnJlc3BvbnNlQmxvYiB8fCB4aHIucmVzcG9uc2U7XG4gICAgaWYgKHJlc3BUeXBlID09PSAnYXJyYXlidWZmZXInKSByZXR1cm4geGhyLnJlc3BvbnNlO1xuICAgIHJldHVybiB4aHIucmVzcG9uc2VUZXh0O1xufVxuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0SGVhZGVyID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmhlYWRlcnNba2V5LnRvTG93ZXJDYXNlKCldO1xufTtcblxuUmVzcG9uc2UucHJvdG90eXBlLmhhbmRsZSA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgICBpZiAocmVzLnJlYWR5U3RhdGUgPT09IDIgJiYgY2FwYWJsZS5zdGF0dXMyKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLnN0YXR1c0NvZGUgPSByZXMuc3RhdHVzO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHJlcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY2FwYWJsZS5zdGF0dXMyID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmIChjYXBhYmxlLnN0YXR1czIpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChjYXBhYmxlLnN0cmVhbWluZyAmJiByZXMucmVhZHlTdGF0ZSA9PT0gMykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXR1c0NvZGUgPSByZXMuc3RhdHVzO1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhZGVycyA9IHBhcnNlSGVhZGVycyhyZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7fVxuICAgICAgICBcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuX2VtaXREYXRhKHJlcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY2FwYWJsZS5zdHJlYW1pbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChyZXMucmVhZHlTdGF0ZSA9PT0gNCkge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdHVzQ29kZSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0dXNDb2RlID0gcmVzLnN0YXR1cztcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9lbWl0RGF0YShyZXMpO1xuICAgICAgICBcbiAgICAgICAgaWYgKHJlcy5lcnJvcikge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIHRoaXMuZ2V0UmVzcG9uc2UocmVzKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB0aGlzLmVtaXQoJ2VuZCcpO1xuICAgICAgICBcbiAgICAgICAgdGhpcy5lbWl0KCdjbG9zZScpO1xuICAgIH1cbn07XG5cblJlc3BvbnNlLnByb3RvdHlwZS5fZW1pdERhdGEgPSBmdW5jdGlvbiAocmVzKSB7XG4gICAgdmFyIHJlc3BCb2R5ID0gdGhpcy5nZXRSZXNwb25zZShyZXMpO1xuICAgIGlmIChyZXNwQm9keS50b1N0cmluZygpLm1hdGNoKC9BcnJheUJ1ZmZlci8pKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIG5ldyBVaW50OEFycmF5KHJlc3BCb2R5LCB0aGlzLm9mZnNldCkpO1xuICAgICAgICB0aGlzLm9mZnNldCA9IHJlc3BCb2R5LmJ5dGVMZW5ndGg7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHJlc3BCb2R5Lmxlbmd0aCA+IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHJlc3BCb2R5LnNsaWNlKHRoaXMub2Zmc2V0KSk7XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gcmVzcEJvZHkubGVuZ3RoO1xuICAgIH1cbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoeHMpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn07XG4iLCI7KGZ1bmN0aW9uICgpIHtcblxuICB2YXJcbiAgICBvYmplY3QgPSB0eXBlb2YgZXhwb3J0cyAhPSAndW5kZWZpbmVkJyA/IGV4cG9ydHMgOiB0aGlzLCAvLyAjODogd2ViIHdvcmtlcnNcbiAgICBjaGFycyA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPScsXG4gICAgSU5WQUxJRF9DSEFSQUNURVJfRVJSID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGZhYnJpY2F0ZSBhIHN1aXRhYmxlIGVycm9yIG9iamVjdFxuICAgICAgdHJ5IHsgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnJCcpOyB9XG4gICAgICBjYXRjaCAoZXJyb3IpIHsgcmV0dXJuIGVycm9yOyB9fSgpKTtcblxuICAvLyBlbmNvZGVyXG4gIC8vIFtodHRwczovL2dpc3QuZ2l0aHViLmNvbS85OTkxNjZdIGJ5IFtodHRwczovL2dpdGh1Yi5jb20vbmlnbmFnXVxuICBvYmplY3QuYnRvYSB8fCAoXG4gIG9iamVjdC5idG9hID0gZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgZm9yIChcbiAgICAgIC8vIGluaXRpYWxpemUgcmVzdWx0IGFuZCBjb3VudGVyXG4gICAgICB2YXIgYmxvY2ssIGNoYXJDb2RlLCBpZHggPSAwLCBtYXAgPSBjaGFycywgb3V0cHV0ID0gJyc7XG4gICAgICAvLyBpZiB0aGUgbmV4dCBpbnB1dCBpbmRleCBkb2VzIG5vdCBleGlzdDpcbiAgICAgIC8vICAgY2hhbmdlIHRoZSBtYXBwaW5nIHRhYmxlIHRvIFwiPVwiXG4gICAgICAvLyAgIGNoZWNrIGlmIGQgaGFzIG5vIGZyYWN0aW9uYWwgZGlnaXRzXG4gICAgICBpbnB1dC5jaGFyQXQoaWR4IHwgMCkgfHwgKG1hcCA9ICc9JywgaWR4ICUgMSk7XG4gICAgICAvLyBcIjggLSBpZHggJSAxICogOFwiIGdlbmVyYXRlcyB0aGUgc2VxdWVuY2UgMiwgNCwgNiwgOFxuICAgICAgb3V0cHV0ICs9IG1hcC5jaGFyQXQoNjMgJiBibG9jayA+PiA4IC0gaWR4ICUgMSAqIDgpXG4gICAgKSB7XG4gICAgICBjaGFyQ29kZSA9IGlucHV0LmNoYXJDb2RlQXQoaWR4ICs9IDMvNCk7XG4gICAgICBpZiAoY2hhckNvZGUgPiAweEZGKSB0aHJvdyBJTlZBTElEX0NIQVJBQ1RFUl9FUlI7XG4gICAgICBibG9jayA9IGJsb2NrIDw8IDggfCBjaGFyQ29kZTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfSk7XG5cbiAgLy8gZGVjb2RlclxuICAvLyBbaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vMTAyMDM5Nl0gYnkgW2h0dHBzOi8vZ2l0aHViLmNvbS9hdGtdXG4gIG9iamVjdC5hdG9iIHx8IChcbiAgb2JqZWN0LmF0b2IgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoLz0rJC8sICcnKVxuICAgIGlmIChpbnB1dC5sZW5ndGggJSA0ID09IDEpIHRocm93IElOVkFMSURfQ0hBUkFDVEVSX0VSUjtcbiAgICBmb3IgKFxuICAgICAgLy8gaW5pdGlhbGl6ZSByZXN1bHQgYW5kIGNvdW50ZXJzXG4gICAgICB2YXIgYmMgPSAwLCBicywgYnVmZmVyLCBpZHggPSAwLCBvdXRwdXQgPSAnJztcbiAgICAgIC8vIGdldCBuZXh0IGNoYXJhY3RlclxuICAgICAgYnVmZmVyID0gaW5wdXQuY2hhckF0KGlkeCsrKTtcbiAgICAgIC8vIGNoYXJhY3RlciBmb3VuZCBpbiB0YWJsZT8gaW5pdGlhbGl6ZSBiaXQgc3RvcmFnZSBhbmQgYWRkIGl0cyBhc2NpaSB2YWx1ZTtcbiAgICAgIH5idWZmZXIgJiYgKGJzID0gYmMgJSA0ID8gYnMgKiA2NCArIGJ1ZmZlciA6IGJ1ZmZlcixcbiAgICAgICAgLy8gYW5kIGlmIG5vdCBmaXJzdCBvZiBlYWNoIDQgY2hhcmFjdGVycyxcbiAgICAgICAgLy8gY29udmVydCB0aGUgZmlyc3QgOCBiaXRzIHRvIG9uZSBhc2NpaSBjaGFyYWN0ZXJcbiAgICAgICAgYmMrKyAlIDQpID8gb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoMjU1ICYgYnMgPj4gKC0yICogYmMgJiA2KSkgOiAwXG4gICAgKSB7XG4gICAgICAvLyB0cnkgdG8gZmluZCBjaGFyYWN0ZXIgaW4gdGFibGUgKDAtNjMsIG5vdCBmb3VuZCA9PiAtMSlcbiAgICAgIGJ1ZmZlciA9IGNoYXJzLmluZGV4T2YoYnVmZmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfSk7XG5cbn0oKSk7XG4iLCJ2YXIgc3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJylcbnZhciBib3BzID0gcmVxdWlyZSgnYm9wcycpXG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKVxuXG5mdW5jdGlvbiBDb25jYXRTdHJlYW0oY2IpIHtcbiAgc3RyZWFtLlN0cmVhbS5jYWxsKHRoaXMpXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlXG4gIGlmIChjYikgdGhpcy5jYiA9IGNiXG4gIHRoaXMuYm9keSA9IFtdXG4gIHRoaXMub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKSB7XG4gICAgLy8gbm8tb3BcbiAgfSlcbn1cblxudXRpbC5pbmhlcml0cyhDb25jYXRTdHJlYW0sIHN0cmVhbS5TdHJlYW0pXG5cbkNvbmNhdFN0cmVhbS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihjaHVuaykge1xuICB0aGlzLmJvZHkucHVzaChjaHVuaylcbn1cblxuQ29uY2F0U3RyZWFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7fVxuXG5Db25jYXRTdHJlYW0ucHJvdG90eXBlLmFycmF5Q29uY2F0ID0gZnVuY3Rpb24oYXJycykge1xuICBpZiAoYXJycy5sZW5ndGggPT09IDApIHJldHVybiBbXVxuICBpZiAoYXJycy5sZW5ndGggPT09IDEpIHJldHVybiBhcnJzWzBdXG4gIHJldHVybiBhcnJzLnJlZHVjZShmdW5jdGlvbiAoYSwgYikgeyByZXR1cm4gYS5jb25jYXQoYikgfSlcbn1cblxuQ29uY2F0U3RyZWFtLnByb3RvdHlwZS5pc0FycmF5ID0gZnVuY3Rpb24oYXJyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFycilcbn1cblxuQ29uY2F0U3RyZWFtLnByb3RvdHlwZS5nZXRCb2R5ID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5ib2R5Lmxlbmd0aCA9PT0gMCkgcmV0dXJuXG4gIGlmICh0eXBlb2YodGhpcy5ib2R5WzBdKSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHRoaXMuYm9keS5qb2luKCcnKVxuICBpZiAodGhpcy5pc0FycmF5KHRoaXMuYm9keVswXSkpIHJldHVybiB0aGlzLmFycmF5Q29uY2F0KHRoaXMuYm9keSlcbiAgaWYgKGJvcHMuaXModGhpcy5ib2R5WzBdKSkgcmV0dXJuIGJvcHMuam9pbih0aGlzLmJvZHkpXG4gIHJldHVybiB0aGlzLmJvZHlcbn1cblxuQ29uY2F0U3RyZWFtLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuY2IpIHRoaXMuY2IodGhpcy5nZXRCb2R5KCkpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oY2IpIHtcbiAgcmV0dXJuIG5ldyBDb25jYXRTdHJlYW0oY2IpXG59XG5cbm1vZHVsZS5leHBvcnRzLkNvbmNhdFN0cmVhbSA9IENvbmNhdFN0cmVhbVxuIiwidmFyIHByb3RvID0ge31cbm1vZHVsZS5leHBvcnRzID0gcHJvdG9cblxucHJvdG8uZnJvbSA9IHJlcXVpcmUoJy4vZnJvbS5qcycpXG5wcm90by50byA9IHJlcXVpcmUoJy4vdG8uanMnKVxucHJvdG8uaXMgPSByZXF1aXJlKCcuL2lzLmpzJylcbnByb3RvLnN1YmFycmF5ID0gcmVxdWlyZSgnLi9zdWJhcnJheS5qcycpXG5wcm90by5qb2luID0gcmVxdWlyZSgnLi9qb2luLmpzJylcbnByb3RvLmNvcHkgPSByZXF1aXJlKCcuL2NvcHkuanMnKVxucHJvdG8uY3JlYXRlID0gcmVxdWlyZSgnLi9jcmVhdGUuanMnKVxuXG5taXgocmVxdWlyZSgnLi9yZWFkLmpzJyksIHByb3RvKVxubWl4KHJlcXVpcmUoJy4vd3JpdGUuanMnKSwgcHJvdG8pXG5cbmZ1bmN0aW9uIG1peChmcm9tLCBpbnRvKSB7XG4gIGZvcih2YXIga2V5IGluIGZyb20pIHtcbiAgICBpbnRvW2tleV0gPSBmcm9tW2tleV1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSB0b191dGY4XG5cbnZhciBvdXQgPSBbXVxuICAsIGNvbCA9IFtdXG4gICwgZmNjID0gU3RyaW5nLmZyb21DaGFyQ29kZVxuICAsIG1hc2sgPSBbMHg0MCwgMHgyMCwgMHgxMCwgMHgwOCwgMHgwNCwgMHgwMiwgMHgwMV1cbiAgLCB1bm1hc2sgPSBbXG4gICAgICAweDAwXG4gICAgLCAweDAxXG4gICAgLCAweDAyIHwgMHgwMVxuICAgICwgMHgwNCB8IDB4MDIgfCAweDAxXG4gICAgLCAweDA4IHwgMHgwNCB8IDB4MDIgfCAweDAxXG4gICAgLCAweDEwIHwgMHgwOCB8IDB4MDQgfCAweDAyIHwgMHgwMVxuICAgICwgMHgyMCB8IDB4MTAgfCAweDA4IHwgMHgwNCB8IDB4MDIgfCAweDAxXG4gICAgLCAweDQwIHwgMHgyMCB8IDB4MTAgfCAweDA4IHwgMHgwNCB8IDB4MDIgfCAweDAxXG4gIF1cblxuZnVuY3Rpb24gdG9fdXRmOChieXRlcywgc3RhcnQsIGVuZCkge1xuICBzdGFydCA9IHN0YXJ0ID09PSB1bmRlZmluZWQgPyAwIDogc3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBieXRlcy5sZW5ndGggOiBlbmRcblxuICB2YXIgaWR4ID0gMFxuICAgICwgaGkgPSAweDgwXG4gICAgLCBjb2xsZWN0aW5nID0gMFxuICAgICwgcG9zXG4gICAgLCBieVxuXG4gIGNvbC5sZW5ndGggPVxuICBvdXQubGVuZ3RoID0gMFxuXG4gIHdoaWxlKGlkeCA8IGJ5dGVzLmxlbmd0aCkge1xuICAgIGJ5ID0gYnl0ZXNbaWR4XVxuICAgIGlmKCFjb2xsZWN0aW5nICYmIGJ5ICYgaGkpIHtcbiAgICAgIHBvcyA9IGZpbmRfcGFkX3Bvc2l0aW9uKGJ5KVxuICAgICAgY29sbGVjdGluZyArPSBwb3NcbiAgICAgIGlmKHBvcyA8IDgpIHtcbiAgICAgICAgY29sW2NvbC5sZW5ndGhdID0gYnkgJiB1bm1hc2tbNiAtIHBvc11cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYoY29sbGVjdGluZykge1xuICAgICAgY29sW2NvbC5sZW5ndGhdID0gYnkgJiB1bm1hc2tbNl1cbiAgICAgIC0tY29sbGVjdGluZ1xuICAgICAgaWYoIWNvbGxlY3RpbmcgJiYgY29sLmxlbmd0aCkge1xuICAgICAgICBvdXRbb3V0Lmxlbmd0aF0gPSBmY2MocmVkdWNlZChjb2wsIHBvcykpXG4gICAgICAgIGNvbC5sZW5ndGggPSAwXG4gICAgICB9XG4gICAgfSBlbHNlIHsgXG4gICAgICBvdXRbb3V0Lmxlbmd0aF0gPSBmY2MoYnkpXG4gICAgfVxuICAgICsraWR4XG4gIH1cbiAgaWYoY29sLmxlbmd0aCAmJiAhY29sbGVjdGluZykge1xuICAgIG91dFtvdXQubGVuZ3RoXSA9IGZjYyhyZWR1Y2VkKGNvbCwgcG9zKSlcbiAgICBjb2wubGVuZ3RoID0gMFxuICB9XG4gIHJldHVybiBvdXQuam9pbignJylcbn1cblxuZnVuY3Rpb24gZmluZF9wYWRfcG9zaXRpb24oYnl0KSB7XG4gIGZvcih2YXIgaSA9IDA7IGkgPCA3OyArK2kpIHtcbiAgICBpZighKGJ5dCAmIG1hc2tbaV0pKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiByZWR1Y2VkKGxpc3QpIHtcbiAgdmFyIG91dCA9IDBcbiAgZm9yKHZhciBpID0gMCwgbGVuID0gbGlzdC5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIG91dCB8PSBsaXN0W2ldIDw8ICgobGVuIC0gaSAtIDEpICogNilcbiAgfVxuICByZXR1cm4gb3V0XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGNvcHlcblxudmFyIHNsaWNlID0gW10uc2xpY2VcblxuZnVuY3Rpb24gY29weShzb3VyY2UsIHRhcmdldCwgdGFyZ2V0X3N0YXJ0LCBzb3VyY2Vfc3RhcnQsIHNvdXJjZV9lbmQpIHtcbiAgdGFyZ2V0X3N0YXJ0ID0gYXJndW1lbnRzLmxlbmd0aCA8IDMgPyAwIDogdGFyZ2V0X3N0YXJ0XG4gIHNvdXJjZV9zdGFydCA9IGFyZ3VtZW50cy5sZW5ndGggPCA0ID8gMCA6IHNvdXJjZV9zdGFydFxuICBzb3VyY2VfZW5kID0gYXJndW1lbnRzLmxlbmd0aCA8IDUgPyBzb3VyY2UubGVuZ3RoIDogc291cmNlX2VuZFxuXG4gIGlmKHNvdXJjZV9lbmQgPT09IHNvdXJjZV9zdGFydCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgaWYodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCBzb3VyY2UubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBpZihzb3VyY2VfZW5kID4gc291cmNlLmxlbmd0aCkge1xuICAgIHNvdXJjZV9lbmQgPSBzb3VyY2UubGVuZ3RoXG4gIH1cblxuICBpZih0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0IDwgc291cmNlX2VuZCAtIHNvdXJjZV9zdGFydCkge1xuICAgIHNvdXJjZV9lbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0ICsgc3RhcnRcbiAgfVxuXG4gIGlmKHNvdXJjZS5idWZmZXIgIT09IHRhcmdldC5idWZmZXIpIHtcbiAgICByZXR1cm4gZmFzdF9jb3B5KHNvdXJjZSwgdGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHNvdXJjZV9zdGFydCwgc291cmNlX2VuZClcbiAgfVxuICByZXR1cm4gc2xvd19jb3B5KHNvdXJjZSwgdGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHNvdXJjZV9zdGFydCwgc291cmNlX2VuZClcbn1cblxuZnVuY3Rpb24gZmFzdF9jb3B5KHNvdXJjZSwgdGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHNvdXJjZV9zdGFydCwgc291cmNlX2VuZCkge1xuICB2YXIgbGVuID0gKHNvdXJjZV9lbmQgLSBzb3VyY2Vfc3RhcnQpICsgdGFyZ2V0X3N0YXJ0XG5cbiAgZm9yKHZhciBpID0gdGFyZ2V0X3N0YXJ0LCBqID0gc291cmNlX3N0YXJ0O1xuICAgICAgaSA8IGxlbjtcbiAgICAgICsraSxcbiAgICAgICsraikge1xuICAgIHRhcmdldFtpXSA9IHNvdXJjZVtqXVxuICB9XG59XG5cbmZ1bmN0aW9uIHNsb3dfY29weShmcm9tLCB0bywgaiwgaSwgamVuZCkge1xuICAvLyB0aGUgYnVmZmVycyBjb3VsZCBvdmVybGFwLlxuICB2YXIgaWVuZCA9IGplbmQgKyBpXG4gICAgLCB0bXAgPSBuZXcgVWludDhBcnJheShzbGljZS5jYWxsKGZyb20sIGksIGllbmQpKVxuICAgICwgeCA9IDBcblxuICBmb3IoOyBpIDwgaWVuZDsgKytpLCArK3gpIHtcbiAgICB0b1tqKytdID0gdG1wW3hdXG4gIH1cbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2l6ZSkge1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc2l6ZSlcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gZnJvbVxuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcblxudmFyIGRlY29kZXJzID0ge1xuICAgIGhleDogZnJvbV9oZXhcbiAgLCB1dGY4OiBmcm9tX3V0ZlxuICAsIGJhc2U2NDogZnJvbV9iYXNlNjRcbn1cblxuZnVuY3Rpb24gZnJvbShzb3VyY2UsIGVuY29kaW5nKSB7XG4gIGlmKEFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheShzb3VyY2UpXG4gIH1cblxuICByZXR1cm4gZGVjb2RlcnNbZW5jb2RpbmcgfHwgJ3V0ZjgnXShzb3VyY2UpXG59XG5cbmZ1bmN0aW9uIGZyb21faGV4KHN0cikge1xuICB2YXIgc2l6ZSA9IHN0ci5sZW5ndGggLyAyXG4gICAgLCBidWYgPSBuZXcgVWludDhBcnJheShzaXplKVxuICAgICwgY2hhcmFjdGVyID0gJydcblxuICBmb3IodmFyIGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBjaGFyYWN0ZXIgKz0gc3RyLmNoYXJBdChpKVxuXG4gICAgaWYoaSA+IDAgJiYgKGkgJSAyKSA9PT0gMSkge1xuICAgICAgYnVmW2k+Pj4xXSA9IHBhcnNlSW50KGNoYXJhY3RlciwgMTYpXG4gICAgICBjaGFyYWN0ZXIgPSAnJyBcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYnVmIFxufVxuXG5mdW5jdGlvbiBmcm9tX3V0ZihzdHIpIHtcbiAgdmFyIGJ5dGVzID0gW11cbiAgICAsIHRtcFxuICAgICwgY2hcblxuICBmb3IodmFyIGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBjaCA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaWYoY2ggJiAweDgwKSB7XG4gICAgICB0bXAgPSBlbmNvZGVVUklDb21wb25lbnQoc3RyLmNoYXJBdChpKSkuc3Vic3RyKDEpLnNwbGl0KCclJylcbiAgICAgIGZvcih2YXIgaiA9IDAsIGpsZW4gPSB0bXAubGVuZ3RoOyBqIDwgamxlbjsgKytqKSB7XG4gICAgICAgIGJ5dGVzW2J5dGVzLmxlbmd0aF0gPSBwYXJzZUludCh0bXBbal0sIDE2KVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBieXRlc1tieXRlcy5sZW5ndGhdID0gY2ggXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJ5dGVzKVxufVxuXG5mdW5jdGlvbiBmcm9tX2Jhc2U2NChzdHIpIHtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGJhc2U2NC50b0J5dGVBcnJheShzdHIpKSBcbn1cbiIsIlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgcmV0dXJuIGJ1ZmZlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk7XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGpvaW5cblxuZnVuY3Rpb24gam9pbih0YXJnZXRzLCBoaW50KSB7XG4gIGlmKCF0YXJnZXRzLmxlbmd0aCkge1xuICAgIHJldHVybiBuZXcgVWludDhBcnJheSgwKVxuICB9XG5cbiAgdmFyIGxlbiA9IGhpbnQgIT09IHVuZGVmaW5lZCA/IGhpbnQgOiBnZXRfbGVuZ3RoKHRhcmdldHMpXG4gICAgLCBvdXQgPSBuZXcgVWludDhBcnJheShsZW4pXG4gICAgLCBjdXIgPSB0YXJnZXRzWzBdXG4gICAgLCBjdXJsZW4gPSBjdXIubGVuZ3RoXG4gICAgLCBjdXJpZHggPSAwXG4gICAgLCBjdXJvZmYgPSAwXG4gICAgLCBpID0gMFxuXG4gIHdoaWxlKGkgPCBsZW4pIHtcbiAgICBpZihjdXJvZmYgPT09IGN1cmxlbikge1xuICAgICAgY3Vyb2ZmID0gMFxuICAgICAgKytjdXJpZHhcbiAgICAgIGN1ciA9IHRhcmdldHNbY3VyaWR4XVxuICAgICAgY3VybGVuID0gY3VyICYmIGN1ci5sZW5ndGhcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIG91dFtpKytdID0gY3VyW2N1cm9mZisrXSBcbiAgfVxuXG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gZ2V0X2xlbmd0aCh0YXJnZXRzKSB7XG4gIHZhciBzaXplID0gMFxuICBmb3IodmFyIGkgPSAwLCBsZW4gPSB0YXJnZXRzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgc2l6ZSArPSB0YXJnZXRzW2ldLmJ5dGVMZW5ndGhcbiAgfVxuICByZXR1cm4gc2l6ZVxufVxuIiwidmFyIHByb3RvXG4gICwgbWFwXG5cbm1vZHVsZS5leHBvcnRzID0gcHJvdG8gPSB7fVxuXG5tYXAgPSB0eXBlb2YgV2Vha01hcCA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogbmV3IFdlYWtNYXBcblxucHJvdG8uZ2V0ID0gIW1hcCA/IG5vX3dlYWttYXBfZ2V0IDogZ2V0XG5cbmZ1bmN0aW9uIG5vX3dlYWttYXBfZ2V0KHRhcmdldCkge1xuICByZXR1cm4gbmV3IERhdGFWaWV3KHRhcmdldC5idWZmZXIsIDApXG59XG5cbmZ1bmN0aW9uIGdldCh0YXJnZXQpIHtcbiAgdmFyIG91dCA9IG1hcC5nZXQodGFyZ2V0LmJ1ZmZlcilcbiAgaWYoIW91dCkge1xuICAgIG1hcC5zZXQodGFyZ2V0LmJ1ZmZlciwgb3V0ID0gbmV3IERhdGFWaWV3KHRhcmdldC5idWZmZXIsIDApKVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICAgIHJlYWRVSW50ODogICAgICByZWFkX3VpbnQ4XG4gICwgcmVhZEludDg6ICAgICAgIHJlYWRfaW50OFxuICAsIHJlYWRVSW50MTZMRTogICByZWFkX3VpbnQxNl9sZVxuICAsIHJlYWRVSW50MzJMRTogICByZWFkX3VpbnQzMl9sZVxuICAsIHJlYWRJbnQxNkxFOiAgICByZWFkX2ludDE2X2xlXG4gICwgcmVhZEludDMyTEU6ICAgIHJlYWRfaW50MzJfbGVcbiAgLCByZWFkRmxvYXRMRTogICAgcmVhZF9mbG9hdF9sZVxuICAsIHJlYWREb3VibGVMRTogICByZWFkX2RvdWJsZV9sZVxuICAsIHJlYWRVSW50MTZCRTogICByZWFkX3VpbnQxNl9iZVxuICAsIHJlYWRVSW50MzJCRTogICByZWFkX3VpbnQzMl9iZVxuICAsIHJlYWRJbnQxNkJFOiAgICByZWFkX2ludDE2X2JlXG4gICwgcmVhZEludDMyQkU6ICAgIHJlYWRfaW50MzJfYmVcbiAgLCByZWFkRmxvYXRCRTogICAgcmVhZF9mbG9hdF9iZVxuICAsIHJlYWREb3VibGVCRTogICByZWFkX2RvdWJsZV9iZVxufVxuXG52YXIgbWFwID0gcmVxdWlyZSgnLi9tYXBwZWQuanMnKVxuXG5mdW5jdGlvbiByZWFkX3VpbnQ4KHRhcmdldCwgYXQpIHtcbiAgcmV0dXJuIHRhcmdldFthdF1cbn1cblxuZnVuY3Rpb24gcmVhZF9pbnQ4KHRhcmdldCwgYXQpIHtcbiAgdmFyIHYgPSB0YXJnZXRbYXRdO1xuICByZXR1cm4gdiA8IDB4ODAgPyB2IDogdiAtIDB4MTAwXG59XG5cbmZ1bmN0aW9uIHJlYWRfdWludDE2X2xlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0VWludDE2KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHJlYWRfdWludDMyX2xlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0VWludDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHJlYWRfaW50MTZfbGUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRJbnQxNihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB0cnVlKVxufVxuXG5mdW5jdGlvbiByZWFkX2ludDMyX2xlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0SW50MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gcmVhZF9mbG9hdF9sZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEZsb2F0MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gcmVhZF9kb3VibGVfbGUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRGbG9hdDY0KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHJlYWRfdWludDE2X2JlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0VWludDE2KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiByZWFkX3VpbnQzMl9iZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldFVpbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gcmVhZF9pbnQxNl9iZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEludDE2KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiByZWFkX2ludDMyX2JlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0SW50MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHJlYWRfZmxvYXRfYmUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRGbG9hdDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiByZWFkX2RvdWJsZV9iZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEZsb2F0NjQoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgZmFsc2UpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHN1YmFycmF5XG5cbmZ1bmN0aW9uIHN1YmFycmF5KGJ1ZiwgZnJvbSwgdG8pIHtcbiAgcmV0dXJuIGJ1Zi5zdWJhcnJheShmcm9tIHx8IDAsIHRvIHx8IGJ1Zi5sZW5ndGgpXG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHRvXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxuICAsIHRvdXRmOCA9IHJlcXVpcmUoJ3RvLXV0ZjgnKVxuXG52YXIgZW5jb2RlcnMgPSB7XG4gICAgaGV4OiB0b19oZXhcbiAgLCB1dGY4OiB0b191dGZcbiAgLCBiYXNlNjQ6IHRvX2Jhc2U2NFxufVxuXG5mdW5jdGlvbiB0byhidWYsIGVuY29kaW5nKSB7XG4gIHJldHVybiBlbmNvZGVyc1tlbmNvZGluZyB8fCAndXRmOCddKGJ1Zilcbn1cblxuZnVuY3Rpb24gdG9faGV4KGJ1Zikge1xuICB2YXIgc3RyID0gJydcbiAgICAsIGJ5dFxuXG4gIGZvcih2YXIgaSA9IDAsIGxlbiA9IGJ1Zi5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIGJ5dCA9IGJ1ZltpXVxuICAgIHN0ciArPSAoKGJ5dCAmIDB4RjApID4+PiA0KS50b1N0cmluZygxNilcbiAgICBzdHIgKz0gKGJ5dCAmIDB4MEYpLnRvU3RyaW5nKDE2KVxuICB9XG5cbiAgcmV0dXJuIHN0clxufVxuXG5mdW5jdGlvbiB0b191dGYoYnVmKSB7XG4gIHJldHVybiB0b3V0ZjgoYnVmKVxufVxuXG5mdW5jdGlvbiB0b19iYXNlNjQoYnVmKSB7XG4gIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG59XG5cbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICAgIHdyaXRlVUludDg6ICAgICAgd3JpdGVfdWludDhcbiAgLCB3cml0ZUludDg6ICAgICAgIHdyaXRlX2ludDhcbiAgLCB3cml0ZVVJbnQxNkxFOiAgIHdyaXRlX3VpbnQxNl9sZVxuICAsIHdyaXRlVUludDMyTEU6ICAgd3JpdGVfdWludDMyX2xlXG4gICwgd3JpdGVJbnQxNkxFOiAgICB3cml0ZV9pbnQxNl9sZVxuICAsIHdyaXRlSW50MzJMRTogICAgd3JpdGVfaW50MzJfbGVcbiAgLCB3cml0ZUZsb2F0TEU6ICAgIHdyaXRlX2Zsb2F0X2xlXG4gICwgd3JpdGVEb3VibGVMRTogICB3cml0ZV9kb3VibGVfbGVcbiAgLCB3cml0ZVVJbnQxNkJFOiAgIHdyaXRlX3VpbnQxNl9iZVxuICAsIHdyaXRlVUludDMyQkU6ICAgd3JpdGVfdWludDMyX2JlXG4gICwgd3JpdGVJbnQxNkJFOiAgICB3cml0ZV9pbnQxNl9iZVxuICAsIHdyaXRlSW50MzJCRTogICAgd3JpdGVfaW50MzJfYmVcbiAgLCB3cml0ZUZsb2F0QkU6ICAgIHdyaXRlX2Zsb2F0X2JlXG4gICwgd3JpdGVEb3VibGVCRTogICB3cml0ZV9kb3VibGVfYmVcbn1cblxudmFyIG1hcCA9IHJlcXVpcmUoJy4vbWFwcGVkLmpzJylcblxuZnVuY3Rpb24gd3JpdGVfdWludDgodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgcmV0dXJuIHRhcmdldFthdF0gPSB2YWx1ZVxufVxuXG5mdW5jdGlvbiB3cml0ZV9pbnQ4KHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHJldHVybiB0YXJnZXRbYXRdID0gdmFsdWUgPCAwID8gdmFsdWUgKyAweDEwMCA6IHZhbHVlXG59XG5cbmZ1bmN0aW9uIHdyaXRlX3VpbnQxNl9sZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRVaW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX3VpbnQzMl9sZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRVaW50MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2ludDE2X2xlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldEludDE2KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCB0cnVlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9pbnQzMl9sZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRJbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfZmxvYXRfbGUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0RmxvYXQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfZG91YmxlX2xlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldEZsb2F0NjQoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX3VpbnQxNl9iZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRVaW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV91aW50MzJfYmUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0VWludDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfaW50MTZfYmUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0SW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9pbnQzMl9iZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRJbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2Zsb2F0X2JlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldEZsb2F0MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9kb3VibGVfYmUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0RmxvYXQ2NChhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgZmFsc2UpXG59XG4iLCJyZXF1aXJlPShmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbmV4cG9ydHMucmVhZElFRUU3NTQgPSBmdW5jdGlvbihidWZmZXIsIG9mZnNldCwgaXNCRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIG5CaXRzID0gLTcsXG4gICAgICBpID0gaXNCRSA/IDAgOiAobkJ5dGVzIC0gMSksXG4gICAgICBkID0gaXNCRSA/IDEgOiAtMSxcbiAgICAgIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV07XG5cbiAgaSArPSBkO1xuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBzID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gZUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIGUgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXM7XG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XG59O1xuXG5leHBvcnRzLndyaXRlSUVFRTc1NCA9IGZ1bmN0aW9uKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLCBjLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIHJ0ID0gKG1MZW4gPT09IDIzID8gTWF0aC5wb3coMiwgLTI0KSAtIE1hdGgucG93KDIsIC03NykgOiAwKSxcbiAgICAgIGkgPSBpc0JFID8gKG5CeXRlcyAtIDEpIDogMCxcbiAgICAgIGQgPSBpc0JFID8gLTEgOiAxLFxuICAgICAgcyA9IHZhbHVlIDwgMCB8fCAodmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCkgPyAxIDogMDtcblxuICB2YWx1ZSA9IE1hdGguYWJzKHZhbHVlKTtcblxuICBpZiAoaXNOYU4odmFsdWUpIHx8IHZhbHVlID09PSBJbmZpbml0eSkge1xuICAgIG0gPSBpc05hTih2YWx1ZSkgPyAxIDogMDtcbiAgICBlID0gZU1heDtcbiAgfSBlbHNlIHtcbiAgICBlID0gTWF0aC5mbG9vcihNYXRoLmxvZyh2YWx1ZSkgLyBNYXRoLkxOMik7XG4gICAgaWYgKHZhbHVlICogKGMgPSBNYXRoLnBvdygyLCAtZSkpIDwgMSkge1xuICAgICAgZS0tO1xuICAgICAgYyAqPSAyO1xuICAgIH1cbiAgICBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIHZhbHVlICs9IHJ0IC8gYztcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgKz0gcnQgKiBNYXRoLnBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZSArIGVCaWFzID49IGVNYXgpIHtcbiAgICAgIG0gPSAwO1xuICAgICAgZSA9IGVNYXg7XG4gICAgfSBlbHNlIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgbSA9ICh2YWx1ZSAqIGMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IGUgKyBlQmlhcztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IHZhbHVlICogTWF0aC5wb3coMiwgZUJpYXMgLSAxKSAqIE1hdGgucG93KDIsIG1MZW4pO1xuICAgICAgZSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IG1MZW4gPj0gODsgYnVmZmVyW29mZnNldCArIGldID0gbSAmIDB4ZmYsIGkgKz0gZCwgbSAvPSAyNTYsIG1MZW4gLT0gOCk7XG5cbiAgZSA9IChlIDw8IG1MZW4pIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltvZmZzZXQgKyBpXSA9IGUgJiAweGZmLCBpICs9IGQsIGUgLz0gMjU2LCBlTGVuIC09IDgpO1xuXG4gIGJ1ZmZlcltvZmZzZXQgKyBpIC0gZF0gfD0gcyAqIDEyODtcbn07XG5cbn0se31dLFwicTlUeENDXCI6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xudmFyIGFzc2VydDtcbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyO1xuZXhwb3J0cy5TbG93QnVmZmVyID0gQnVmZmVyO1xuQnVmZmVyLnBvb2xTaXplID0gODE5MjtcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MDtcblxuZnVuY3Rpb24gc3RyaW5ndHJpbShzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKTtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XG59XG5cbmZ1bmN0aW9uIEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgb2Zmc2V0KSB7XG4gIGlmKCFhc3NlcnQpIGFzc2VydD0gcmVxdWlyZSgnYXNzZXJ0Jyk7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBCdWZmZXIpKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG9mZnNldCk7XG4gIH1cbiAgdGhpcy5wYXJlbnQgPSB0aGlzO1xuICB0aGlzLm9mZnNldCA9IDA7XG5cbiAgLy8gV29yay1hcm91bmQ6IG5vZGUncyBiYXNlNjQgaW1wbGVtZW50YXRpb25cbiAgLy8gYWxsb3dzIGZvciBub24tcGFkZGVkIHN0cmluZ3Mgd2hpbGUgYmFzZTY0LWpzXG4gIC8vIGRvZXMgbm90Li5cbiAgaWYgKGVuY29kaW5nID09IFwiYmFzZTY0XCIgJiYgdHlwZW9mIHN1YmplY3QgPT0gXCJzdHJpbmdcIikge1xuICAgIHN1YmplY3QgPSBzdHJpbmd0cmltKHN1YmplY3QpO1xuICAgIHdoaWxlIChzdWJqZWN0Lmxlbmd0aCAlIDQgIT0gMCkge1xuICAgICAgc3ViamVjdCA9IHN1YmplY3QgKyBcIj1cIjsgXG4gICAgfVxuICB9XG5cbiAgdmFyIHR5cGU7XG5cbiAgLy8gQXJlIHdlIHNsaWNpbmc/XG4gIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnbnVtYmVyJykge1xuICAgIHRoaXMubGVuZ3RoID0gY29lcmNlKGVuY29kaW5nKTtcbiAgICAvLyBzbGljaW5nIHdvcmtzLCB3aXRoIGxpbWl0YXRpb25zIChubyBwYXJlbnQgdHJhY2tpbmcvdXBkYXRlKVxuICAgIC8vIGNoZWNrIGh0dHBzOi8vZ2l0aHViLmNvbS90b290cy9idWZmZXItYnJvd3NlcmlmeS9pc3N1ZXMvMTlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1tpXSA9IHN1YmplY3QuZ2V0KGkrb2Zmc2V0KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gRmluZCB0aGUgbGVuZ3RoXG4gICAgc3dpdGNoICh0eXBlID0gdHlwZW9mIHN1YmplY3QpIHtcbiAgICAgIGNhc2UgJ251bWJlcic6XG4gICAgICAgIHRoaXMubGVuZ3RoID0gY29lcmNlKHN1YmplY3QpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgdGhpcy5sZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzdWJqZWN0LCBlbmNvZGluZyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdvYmplY3QnOiAvLyBBc3N1bWUgb2JqZWN0IGlzIGFuIGFycmF5XG4gICAgICAgIHRoaXMubGVuZ3RoID0gY29lcmNlKHN1YmplY3QubGVuZ3RoKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgbmVlZHMgdG8gYmUgYSBudW1iZXIsICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FycmF5IG9yIHN0cmluZy4nKTtcbiAgICB9XG5cbiAgICAvLyBUcmVhdCBhcnJheS1pc2ggb2JqZWN0cyBhcyBhIGJ5dGUgYXJyYXkuXG4gICAgaWYgKGlzQXJyYXlJc2goc3ViamVjdCkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc3ViamVjdCBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgICAgIHRoaXNbaV0gPSBzdWJqZWN0LnJlYWRVSW50OChpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzW2ldID0gc3ViamVjdFtpXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PSAnc3RyaW5nJykge1xuICAgICAgLy8gV2UgYXJlIGEgc3RyaW5nXG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMud3JpdGUoc3ViamVjdCwgMCwgZW5jb2RpbmcpO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzW2ldID0gMDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiBnZXQoaSkge1xuICBpZiAoaSA8IDAgfHwgaSA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdvb2InKTtcbiAgcmV0dXJuIHRoaXNbaV07XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIHNldChpLCB2KSB7XG4gIGlmIChpIDwgMCB8fCBpID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ29vYicpO1xuICByZXR1cm4gdGhpc1tpXSA9IHY7XG59O1xuXG5CdWZmZXIuYnl0ZUxlbmd0aCA9IGZ1bmN0aW9uIChzdHIsIGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoZW5jb2RpbmcgfHwgXCJ1dGY4XCIpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0dXJuIHN0ci5sZW5ndGggLyAyO1xuXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0dXJuIHV0ZjhUb0J5dGVzKHN0cikubGVuZ3RoO1xuXG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXR1cm4gc3RyLmxlbmd0aDtcblxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXR1cm4gYmFzZTY0VG9CeXRlcyhzdHIpLmxlbmd0aDtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKTtcbiAgfVxufTtcblxuQnVmZmVyLnByb3RvdHlwZS51dGY4V3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgYnl0ZXMsIHBvcztcbiAgcmV0dXJuIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gIGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nKSwgdGhpcywgb2Zmc2V0LCBsZW5ndGgpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5hc2NpaVdyaXRlID0gZnVuY3Rpb24gKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGJ5dGVzLCBwb3M7XG4gIHJldHVybiBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9ICBibGl0QnVmZmVyKGFzY2lpVG9CeXRlcyhzdHJpbmcpLCB0aGlzLCBvZmZzZXQsIGxlbmd0aCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLmJpbmFyeVdyaXRlID0gQnVmZmVyLnByb3RvdHlwZS5hc2NpaVdyaXRlO1xuXG5CdWZmZXIucHJvdG90eXBlLmJhc2U2NFdyaXRlID0gZnVuY3Rpb24gKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGJ5dGVzLCBwb3M7XG4gIHJldHVybiBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9IGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCB0aGlzLCBvZmZzZXQsIGxlbmd0aCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLmJhc2U2NFNsaWNlID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGJ5dGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cylcbiAgcmV0dXJuIHJlcXVpcmUoXCJiYXNlNjQtanNcIikuZnJvbUJ5dGVBcnJheShieXRlcyk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnV0ZjhTbGljZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGJ5dGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHZhciByZXMgPSBcIlwiO1xuICB2YXIgdG1wID0gXCJcIjtcbiAgdmFyIGkgPSAwO1xuICB3aGlsZSAoaSA8IGJ5dGVzLmxlbmd0aCkge1xuICAgIGlmIChieXRlc1tpXSA8PSAweDdGKSB7XG4gICAgICByZXMgKz0gZGVjb2RlVXRmOENoYXIodG1wKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICAgICAgdG1wID0gXCJcIjtcbiAgICB9IGVsc2VcbiAgICAgIHRtcCArPSBcIiVcIiArIGJ5dGVzW2ldLnRvU3RyaW5nKDE2KTtcblxuICAgIGkrKztcbiAgfVxuXG4gIHJldHVybiByZXMgKyBkZWNvZGVVdGY4Q2hhcih0bXApO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmFzY2lpU2xpY2UgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBieXRlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB2YXIgcmV0ID0gXCJcIjtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkrKylcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gIHJldHVybiByZXQ7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmluYXJ5U2xpY2UgPSBCdWZmZXIucHJvdG90eXBlLmFzY2lpU2xpY2U7XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgb3V0ID0gW10sXG4gICAgICBsZW4gPSB0aGlzLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG91dFtpXSA9IHRvSGV4KHRoaXNbaV0pO1xuICAgIGlmIChpID09IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMpIHtcbiAgICAgIG91dFtpICsgMV0gPSAnLi4uJztcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIG91dC5qb2luKCcgJykgKyAnPic7XG59O1xuXG5cbkJ1ZmZlci5wcm90b3R5cGUuaGV4U2xpY2UgPSBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aDtcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwO1xuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuO1xuXG4gIHZhciBvdXQgPSAnJztcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgodGhpc1tpXSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uKGVuY29kaW5nLCBzdGFydCwgZW5kKSB7XG4gIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKTtcbiAgc3RhcnQgPSArc3RhcnQgfHwgMDtcbiAgaWYgKHR5cGVvZiBlbmQgPT0gJ3VuZGVmaW5lZCcpIGVuZCA9IHRoaXMubGVuZ3RoO1xuXG4gIC8vIEZhc3RwYXRoIGVtcHR5IHN0cmluZ3NcbiAgaWYgKCtlbmQgPT0gc3RhcnQpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cblxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldHVybiB0aGlzLmhleFNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0dXJuIHRoaXMudXRmOFNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0dXJuIHRoaXMuYXNjaWlTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnlTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXR1cm4gdGhpcy5iYXNlNjRTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIHJldHVybiB0aGlzLnVjczJTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKTtcbiAgfVxufTtcblxuXG5CdWZmZXIucHJvdG90eXBlLmhleFdyaXRlID0gZnVuY3Rpb24oc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSArb2Zmc2V0IHx8IDA7XG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gK2xlbmd0aDtcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGg7XG4gIGlmIChzdHJMZW4gJSAyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKTtcbiAgfVxuICBpZiAobGVuZ3RoID4gc3RyTGVuIC8gMikge1xuICAgIGxlbmd0aCA9IHN0ckxlbiAvIDI7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgIHZhciBieXRlID0gcGFyc2VJbnQoc3RyaW5nLnN1YnN0cihpICogMiwgMiksIDE2KTtcbiAgICBpZiAoaXNOYU4oYnl0ZSkpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJyk7XG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9IGJ5dGU7XG4gIH1cbiAgQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSBpICogMjtcbiAgcmV0dXJuIGk7XG59O1xuXG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBTdXBwb3J0IGJvdGggKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKVxuICAvLyBhbmQgdGhlIGxlZ2FjeSAoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpXG4gIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aDtcbiAgICAgIGxlbmd0aCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0gZWxzZSB7ICAvLyBsZWdhY3lcbiAgICB2YXIgc3dhcCA9IGVuY29kaW5nO1xuICAgIGVuY29kaW5nID0gb2Zmc2V0O1xuICAgIG9mZnNldCA9IGxlbmd0aDtcbiAgICBsZW5ndGggPSBzd2FwO1xuICB9XG5cbiAgb2Zmc2V0ID0gK29mZnNldCB8fCAwO1xuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXQ7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nO1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9ICtsZW5ndGg7XG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nO1xuICAgIH1cbiAgfVxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCk7XG5cbiAgc3dpdGNoIChlbmNvZGluZykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXR1cm4gdGhpcy5oZXhXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldHVybiB0aGlzLnV0ZjhXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldHVybiB0aGlzLmFzY2lpV3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBjYXNlICdiaW5hcnknOlxuICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5V3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0dXJuIHRoaXMuYmFzZTY0V3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgICByZXR1cm4gdGhpcy51Y3MyV3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJyk7XG4gIH1cbn07XG5cbi8vIHNsaWNlKHN0YXJ0LCBlbmQpXG5mdW5jdGlvbiBjbGFtcChpbmRleCwgbGVuLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gIGluZGV4ID0gfn5pbmRleDsgIC8vIENvZXJjZSB0byBpbnRlZ2VyLlxuICBpZiAoaW5kZXggPj0gbGVuKSByZXR1cm4gbGVuO1xuICBpZiAoaW5kZXggPj0gMCkgcmV0dXJuIGluZGV4O1xuICBpbmRleCArPSBsZW47XG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXg7XG4gIHJldHVybiAwO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGg7XG4gIHN0YXJ0ID0gY2xhbXAoc3RhcnQsIGxlbiwgMCk7XG4gIGVuZCA9IGNsYW1wKGVuZCwgbGVuLCBsZW4pO1xuICByZXR1cm4gbmV3IEJ1ZmZlcih0aGlzLCBlbmQgLSBzdGFydCwgK3N0YXJ0KTtcbn07XG5cbi8vIGNvcHkodGFyZ2V0QnVmZmVyLCB0YXJnZXRTdGFydD0wLCBzb3VyY2VTdGFydD0wLCBzb3VyY2VFbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKHRhcmdldCwgdGFyZ2V0X3N0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzO1xuICBzdGFydCB8fCAoc3RhcnQgPSAwKTtcbiAgaWYgKGVuZCA9PT0gdW5kZWZpbmVkIHx8IGlzTmFOKGVuZCkpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aDtcbiAgfVxuICB0YXJnZXRfc3RhcnQgfHwgKHRhcmdldF9zdGFydCA9IDApO1xuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VFbmQgPCBzb3VyY2VTdGFydCcpO1xuXG4gIC8vIENvcHkgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDA7XG4gIGlmICh0YXJnZXQubGVuZ3RoID09IDAgfHwgc291cmNlLmxlbmd0aCA9PSAwKSByZXR1cm4gMDtcblxuICBpZiAodGFyZ2V0X3N0YXJ0IDwgMCB8fCB0YXJnZXRfc3RhcnQgPj0gdGFyZ2V0Lmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcigndGFyZ2V0U3RhcnQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGg7XG4gIH1cblxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCA8IGVuZCAtIHN0YXJ0KSB7XG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCArIHN0YXJ0O1xuICB9XG5cbiAgdmFyIHRlbXAgPSBbXTtcbiAgZm9yICh2YXIgaT1zdGFydDsgaTxlbmQ7IGkrKykge1xuICAgIGFzc2VydC5vayh0eXBlb2YgdGhpc1tpXSAhPT0gJ3VuZGVmaW5lZCcsIFwiY29weWluZyB1bmRlZmluZWQgYnVmZmVyIGJ5dGVzIVwiKTtcbiAgICB0ZW1wLnB1c2godGhpc1tpXSk7XG4gIH1cblxuICBmb3IgKHZhciBpPXRhcmdldF9zdGFydDsgaTx0YXJnZXRfc3RhcnQrdGVtcC5sZW5ndGg7IGkrKykge1xuICAgIHRhcmdldFtpXSA9IHRlbXBbaS10YXJnZXRfc3RhcnRdO1xuICB9XG59O1xuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uIGZpbGwodmFsdWUsIHN0YXJ0LCBlbmQpIHtcbiAgdmFsdWUgfHwgKHZhbHVlID0gMCk7XG4gIHN0YXJ0IHx8IChzdGFydCA9IDApO1xuICBlbmQgfHwgKGVuZCA9IHRoaXMubGVuZ3RoKTtcblxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHZhbHVlID0gdmFsdWUuY2hhckNvZGVBdCgwKTtcbiAgfVxuICBpZiAoISh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB8fCBpc05hTih2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbHVlIGlzIG5vdCBhIG51bWJlcicpO1xuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgRXJyb3IoJ2VuZCA8IHN0YXJ0Jyk7XG5cbiAgLy8gRmlsbCAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMDtcbiAgaWYgKHRoaXMubGVuZ3RoID09IDApIHJldHVybiAwO1xuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0YXJ0IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIGlmIChlbmQgPCAwIHx8IGVuZCA+IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICB0aGlzW2ldID0gdmFsdWU7XG4gIH1cbn1cblxuLy8gU3RhdGljIG1ldGhvZHNcbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIGlzQnVmZmVyKGIpIHtcbiAgcmV0dXJuIGIgaW5zdGFuY2VvZiBCdWZmZXIgfHwgYiBpbnN0YW5jZW9mIEJ1ZmZlcjtcbn07XG5cbkJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbiAobGlzdCwgdG90YWxMZW5ndGgpIHtcbiAgaWYgKCFpc0FycmF5KGxpc3QpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVXNhZ2U6IEJ1ZmZlci5jb25jYXQobGlzdCwgW3RvdGFsTGVuZ3RoXSlcXG4gXFxcbiAgICAgIGxpc3Qgc2hvdWxkIGJlIGFuIEFycmF5LlwiKTtcbiAgfVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApO1xuICB9IGVsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIGxpc3RbMF07XG4gIH1cblxuICBpZiAodHlwZW9mIHRvdGFsTGVuZ3RoICE9PSAnbnVtYmVyJykge1xuICAgIHRvdGFsTGVuZ3RoID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBidWYgPSBsaXN0W2ldO1xuICAgICAgdG90YWxMZW5ndGggKz0gYnVmLmxlbmd0aDtcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmZmVyID0gbmV3IEJ1ZmZlcih0b3RhbExlbmd0aCk7XG4gIHZhciBwb3MgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnVmID0gbGlzdFtpXTtcbiAgICBidWYuY29weShidWZmZXIsIHBvcyk7XG4gICAgcG9zICs9IGJ1Zi5sZW5ndGg7XG4gIH1cbiAgcmV0dXJuIGJ1ZmZlcjtcbn07XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24oZW5jb2RpbmcpIHtcbiAgc3dpdGNoICgoZW5jb2RpbmcgKyAnJykudG9Mb3dlckNhc2UoKSkge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICBjYXNlICdyYXcnOlxuICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG4vLyBoZWxwZXJzXG5cbmZ1bmN0aW9uIGNvZXJjZShsZW5ndGgpIHtcbiAgLy8gQ29lcmNlIGxlbmd0aCB0byBhIG51bWJlciAocG9zc2libHkgTmFOKSwgcm91bmQgdXBcbiAgLy8gaW4gY2FzZSBpdCdzIGZyYWN0aW9uYWwgKGUuZy4gMTIzLjQ1NikgdGhlbiBkbyBhXG4gIC8vIGRvdWJsZSBuZWdhdGUgdG8gY29lcmNlIGEgTmFOIHRvIDAuIEVhc3ksIHJpZ2h0P1xuICBsZW5ndGggPSB+fk1hdGguY2VpbCgrbGVuZ3RoKTtcbiAgcmV0dXJuIGxlbmd0aCA8IDAgPyAwIDogbGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBpc0FycmF5KHN1YmplY3QpIHtcbiAgcmV0dXJuIChBcnJheS5pc0FycmF5IHx8XG4gICAgZnVuY3Rpb24oc3ViamVjdCl7XG4gICAgICByZXR1cm4ge30udG9TdHJpbmcuYXBwbHkoc3ViamVjdCkgPT0gJ1tvYmplY3QgQXJyYXldJ1xuICAgIH0pXG4gICAgKHN1YmplY3QpXG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlJc2goc3ViamVjdCkge1xuICByZXR1cm4gaXNBcnJheShzdWJqZWN0KSB8fCBCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkgfHxcbiAgICAgICAgIHN1YmplY3QgJiYgdHlwZW9mIHN1YmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICAgICB0eXBlb2Ygc3ViamVjdC5sZW5ndGggPT09ICdudW1iZXInO1xufVxuXG5mdW5jdGlvbiB0b0hleChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KTtcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpO1xufVxuXG5mdW5jdGlvbiB1dGY4VG9CeXRlcyhzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKylcbiAgICBpZiAoc3RyLmNoYXJDb2RlQXQoaSkgPD0gMHg3RilcbiAgICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKTtcbiAgICBlbHNlIHtcbiAgICAgIHZhciBoID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0ci5jaGFyQXQoaSkpLnN1YnN0cigxKS5zcGxpdCgnJScpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBoLmxlbmd0aDsgaisrKVxuICAgICAgICBieXRlQXJyYXkucHVzaChwYXJzZUludChoW2pdLCAxNikpO1xuICAgIH1cblxuICByZXR1cm4gYnl0ZUFycmF5O1xufVxuXG5mdW5jdGlvbiBhc2NpaVRvQnl0ZXMoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKyApXG4gICAgLy8gTm9kZSdzIGNvZGUgc2VlbXMgdG8gYmUgZG9pbmcgdGhpcyBhbmQgbm90ICYgMHg3Ri4uXG4gICAgYnl0ZUFycmF5LnB1c2goIHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRiApO1xuXG4gIHJldHVybiBieXRlQXJyYXk7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMoc3RyKSB7XG4gIHJldHVybiByZXF1aXJlKFwiYmFzZTY0LWpzXCIpLnRvQnl0ZUFycmF5KHN0cik7XG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIoc3JjLCBkc3QsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBwb3MsIGkgPSAwO1xuICB3aGlsZSAoaSA8IGxlbmd0aCkge1xuICAgIGlmICgoaStvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpXG4gICAgICBicmVhaztcblxuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXTtcbiAgICBpKys7XG4gIH1cbiAgcmV0dXJuIGk7XG59XG5cbmZ1bmN0aW9uIGRlY29kZVV0ZjhDaGFyKHN0cikge1xuICB0cnkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRkZEKTsgLy8gVVRGIDggaW52YWxpZCBjaGFyXG4gIH1cbn1cblxuLy8gcmVhZC93cml0ZSBiaXQtdHdpZGRsaW5nXG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YXIgYnVmZmVyID0gdGhpcztcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICBpZiAob2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHJldHVybjtcblxuICByZXR1cm4gYnVmZmVyW29mZnNldF07XG59O1xuXG5mdW5jdGlvbiByZWFkVUludDE2KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIHZhbCA9IDA7XG5cblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICBpZiAob2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHJldHVybiAwO1xuXG4gIGlmIChpc0JpZ0VuZGlhbikge1xuICAgIHZhbCA9IGJ1ZmZlcltvZmZzZXRdIDw8IDg7XG4gICAgaWYgKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICB2YWwgfD0gYnVmZmVyW29mZnNldCArIDFdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB2YWwgPSBidWZmZXJbb2Zmc2V0XTtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgMV0gPDwgODtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkVUludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gcmVhZFVJbnQzMihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhciB2YWwgPSAwO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuIDA7XG5cbiAgaWYgKGlzQmlnRW5kaWFuKSB7XG4gICAgaWYgKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsID0gYnVmZmVyW29mZnNldCArIDFdIDw8IDE2O1xuICAgIGlmIChvZmZzZXQgKyAyIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgMl0gPDwgODtcbiAgICBpZiAob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgfD0gYnVmZmVyW29mZnNldCArIDNdO1xuICAgIHZhbCA9IHZhbCArIChidWZmZXJbb2Zmc2V0XSA8PCAyNCA+Pj4gMCk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKG9mZnNldCArIDIgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsID0gYnVmZmVyW29mZnNldCArIDJdIDw8IDE2O1xuICAgIGlmIChvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgMV0gPDwgODtcbiAgICB2YWwgfD0gYnVmZmVyW29mZnNldF07XG4gICAgaWYgKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsID0gdmFsICsgKGJ1ZmZlcltvZmZzZXQgKyAzXSA8PCAyNCA+Pj4gMCk7XG4gIH1cblxuICByZXR1cm4gdmFsO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyQkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkVUludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuXG4vKlxuICogU2lnbmVkIGludGVnZXIgdHlwZXMsIHlheSB0ZWFtISBBIHJlbWluZGVyIG9uIGhvdyB0d28ncyBjb21wbGVtZW50IGFjdHVhbGx5XG4gKiB3b3Jrcy4gVGhlIGZpcnN0IGJpdCBpcyB0aGUgc2lnbmVkIGJpdCwgaS5lLiB0ZWxscyB1cyB3aGV0aGVyIG9yIG5vdCB0aGVcbiAqIG51bWJlciBzaG91bGQgYmUgcG9zaXRpdmUgb3IgbmVnYXRpdmUuIElmIHRoZSB0d28ncyBjb21wbGVtZW50IHZhbHVlIGlzXG4gKiBwb3NpdGl2ZSwgdGhlbiB3ZSdyZSBkb25lLCBhcyBpdCdzIGVxdWl2YWxlbnQgdG8gdGhlIHVuc2lnbmVkIHJlcHJlc2VudGF0aW9uLlxuICpcbiAqIE5vdyBpZiB0aGUgbnVtYmVyIGlzIHBvc2l0aXZlLCB5b3UncmUgcHJldHR5IG11Y2ggZG9uZSwgeW91IGNhbiBqdXN0IGxldmVyYWdlXG4gKiB0aGUgdW5zaWduZWQgdHJhbnNsYXRpb25zIGFuZCByZXR1cm4gdGhvc2UuIFVuZm9ydHVuYXRlbHksIG5lZ2F0aXZlIG51bWJlcnNcbiAqIGFyZW4ndCBxdWl0ZSB0aGF0IHN0cmFpZ2h0Zm9yd2FyZC5cbiAqXG4gKiBBdCBmaXJzdCBnbGFuY2UsIG9uZSBtaWdodCBiZSBpbmNsaW5lZCB0byB1c2UgdGhlIHRyYWRpdGlvbmFsIGZvcm11bGEgdG9cbiAqIHRyYW5zbGF0ZSBiaW5hcnkgbnVtYmVycyBiZXR3ZWVuIHRoZSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgdmFsdWVzIGluIHR3bydzXG4gKiBjb21wbGVtZW50LiAoVGhvdWdoIGl0IGRvZXNuJ3QgcXVpdGUgd29yayBmb3IgdGhlIG1vc3QgbmVnYXRpdmUgdmFsdWUpXG4gKiBNYWlubHk6XG4gKiAgLSBpbnZlcnQgYWxsIHRoZSBiaXRzXG4gKiAgLSBhZGQgb25lIHRvIHRoZSByZXN1bHRcbiAqXG4gKiBPZiBjb3Vyc2UsIHRoaXMgZG9lc24ndCBxdWl0ZSB3b3JrIGluIEphdmFzY3JpcHQuIFRha2UgZm9yIGV4YW1wbGUgdGhlIHZhbHVlXG4gKiBvZiAtMTI4LiBUaGlzIGNvdWxkIGJlIHJlcHJlc2VudGVkIGluIDE2IGJpdHMgKGJpZy1lbmRpYW4pIGFzIDB4ZmY4MC4gQnV0IG9mXG4gKiBjb3Vyc2UsIEphdmFzY3JpcHQgd2lsbCBkbyB0aGUgZm9sbG93aW5nOlxuICpcbiAqID4gfjB4ZmY4MFxuICogLTY1NDA5XG4gKlxuICogV2hvaCB0aGVyZSwgSmF2YXNjcmlwdCwgdGhhdCdzIG5vdCBxdWl0ZSByaWdodC4gQnV0IHdhaXQsIGFjY29yZGluZyB0b1xuICogSmF2YXNjcmlwdCB0aGF0J3MgcGVyZmVjdGx5IGNvcnJlY3QuIFdoZW4gSmF2YXNjcmlwdCBlbmRzIHVwIHNlZWluZyB0aGVcbiAqIGNvbnN0YW50IDB4ZmY4MCwgaXQgaGFzIG5vIG5vdGlvbiB0aGF0IGl0IGlzIGFjdHVhbGx5IGEgc2lnbmVkIG51bWJlci4gSXRcbiAqIGFzc3VtZXMgdGhhdCB3ZSd2ZSBpbnB1dCB0aGUgdW5zaWduZWQgdmFsdWUgMHhmZjgwLiBUaHVzLCB3aGVuIGl0IGRvZXMgdGhlXG4gKiBiaW5hcnkgbmVnYXRpb24sIGl0IGNhc3RzIGl0IGludG8gYSBzaWduZWQgdmFsdWUsIChwb3NpdGl2ZSAweGZmODApLiBUaGVuXG4gKiB3aGVuIHlvdSBwZXJmb3JtIGJpbmFyeSBuZWdhdGlvbiBvbiB0aGF0LCBpdCB0dXJucyBpdCBpbnRvIGEgbmVnYXRpdmUgbnVtYmVyLlxuICpcbiAqIEluc3RlYWQsIHdlJ3JlIGdvaW5nIHRvIGhhdmUgdG8gdXNlIHRoZSBmb2xsb3dpbmcgZ2VuZXJhbCBmb3JtdWxhLCB0aGF0IHdvcmtzXG4gKiBpbiBhIHJhdGhlciBKYXZhc2NyaXB0IGZyaWVuZGx5IHdheS4gSSdtIGdsYWQgd2UgZG9uJ3Qgc3VwcG9ydCB0aGlzIGtpbmQgb2ZcbiAqIHdlaXJkIG51bWJlcmluZyBzY2hlbWUgaW4gdGhlIGtlcm5lbC5cbiAqXG4gKiAoQklULU1BWCAtICh1bnNpZ25lZCl2YWwgKyAxKSAqIC0xXG4gKlxuICogVGhlIGFzdHV0ZSBvYnNlcnZlciwgbWF5IHRoaW5rIHRoYXQgdGhpcyBkb2Vzbid0IG1ha2Ugc2Vuc2UgZm9yIDgtYml0IG51bWJlcnNcbiAqIChyZWFsbHkgaXQgaXNuJ3QgbmVjZXNzYXJ5IGZvciB0aGVtKS4gSG93ZXZlciwgd2hlbiB5b3UgZ2V0IDE2LWJpdCBudW1iZXJzLFxuICogeW91IGRvLiBMZXQncyBnbyBiYWNrIHRvIG91ciBwcmlvciBleGFtcGxlIGFuZCBzZWUgaG93IHRoaXMgd2lsbCBsb29rOlxuICpcbiAqICgweGZmZmYgLSAweGZmODAgKyAxKSAqIC0xXG4gKiAoMHgwMDdmICsgMSkgKiAtMVxuICogKDB4MDA4MCkgKiAtMVxuICovXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YXIgYnVmZmVyID0gdGhpcztcbiAgdmFyIG5lZztcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICBpZiAob2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHJldHVybjtcblxuICBuZWcgPSBidWZmZXJbb2Zmc2V0XSAmIDB4ODA7XG4gIGlmICghbmVnKSB7XG4gICAgcmV0dXJuIChidWZmZXJbb2Zmc2V0XSk7XG4gIH1cblxuICByZXR1cm4gKCgweGZmIC0gYnVmZmVyW29mZnNldF0gKyAxKSAqIC0xKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRJbnQxNihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhciBuZWcsIHZhbDtcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICB2YWwgPSByZWFkVUludDE2KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICBuZWcgPSB2YWwgJiAweDgwMDA7XG4gIGlmICghbmVnKSB7XG4gICAgcmV0dXJuIHZhbDtcbiAgfVxuXG4gIHJldHVybiAoMHhmZmZmIC0gdmFsICsgMSkgKiAtMTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gcmVhZEludDMyKGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIG5lZywgdmFsO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIHZhbCA9IHJlYWRVSW50MzIoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIG5lZyA9IHZhbCAmIDB4ODAwMDAwMDA7XG4gIGlmICghbmVnKSB7XG4gICAgcmV0dXJuICh2YWwpO1xuICB9XG5cbiAgcmV0dXJuICgweGZmZmZmZmZmIC0gdmFsICsgMSkgKiAtMTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gcmVhZEZsb2F0KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIHJldHVybiByZXF1aXJlKCcuL2J1ZmZlcl9pZWVlNzU0JykucmVhZElFRUU3NTQoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgMjMsIDQpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdExFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkRmxvYXQodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkRG91YmxlKGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDcgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIHJldHVybiByZXF1aXJlKCcuL2J1ZmZlcl9pZWVlNzU0JykucmVhZElFRUU3NTQoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgNTIsIDgpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWREb3VibGUodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuXG4vKlxuICogV2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgdmFsdWUgaXMgYSB2YWxpZCBpbnRlZ2VyLiBUaGlzIG1lYW5zIHRoYXQgaXQgaXNcbiAqIG5vbi1uZWdhdGl2ZS4gSXQgaGFzIG5vIGZyYWN0aW9uYWwgY29tcG9uZW50IGFuZCB0aGF0IGl0IGRvZXMgbm90IGV4Y2VlZCB0aGVcbiAqIG1heGltdW0gYWxsb3dlZCB2YWx1ZS5cbiAqXG4gKiAgICAgIHZhbHVlICAgICAgICAgICBUaGUgbnVtYmVyIHRvIGNoZWNrIGZvciB2YWxpZGl0eVxuICpcbiAqICAgICAgbWF4ICAgICAgICAgICAgIFRoZSBtYXhpbXVtIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHZlcmlmdWludCh2YWx1ZSwgbWF4KSB7XG4gIGFzc2VydC5vayh0eXBlb2YgKHZhbHVlKSA9PSAnbnVtYmVyJyxcbiAgICAgICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlID49IDAsXG4gICAgICAnc3BlY2lmaWVkIGEgbmVnYXRpdmUgdmFsdWUgZm9yIHdyaXRpbmcgYW4gdW5zaWduZWQgdmFsdWUnKTtcblxuICBhc3NlcnQub2sodmFsdWUgPD0gbWF4LCAndmFsdWUgaXMgbGFyZ2VyIHRoYW4gbWF4aW11bSB2YWx1ZSBmb3IgdHlwZScpO1xuXG4gIGFzc2VydC5vayhNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDggPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YXIgYnVmZmVyID0gdGhpcztcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmYpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICBidWZmZXJbb2Zmc2V0XSA9IHZhbHVlO1xuICB9XG59O1xuXG5mdW5jdGlvbiB3cml0ZVVJbnQxNihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZik7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IE1hdGgubWluKGJ1ZmZlci5sZW5ndGggLSBvZmZzZXQsIDIpOyBpKyspIHtcbiAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChpc0JpZ0VuZGlhbiA/IDEgLSBpIDogaSkpKSkgPj4+XG4gICAgICAgICAgICAoaXNCaWdFbmRpYW4gPyAxIC0gaSA6IGkpICogODtcbiAgfVxuXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZVVJbnQzMihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZmZmZmYpO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBNYXRoLm1pbihidWZmZXIubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSsrKSB7XG4gICAgYnVmZmVyW29mZnNldCArIGldID1cbiAgICAgICAgKHZhbHVlID4+PiAoaXNCaWdFbmRpYW4gPyAzIC0gaSA6IGkpICogOCkgJiAweGZmO1xuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyQkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5cbi8qXG4gKiBXZSBub3cgbW92ZSBvbnRvIG91ciBmcmllbmRzIGluIHRoZSBzaWduZWQgbnVtYmVyIGNhdGVnb3J5LiBVbmxpa2UgdW5zaWduZWRcbiAqIG51bWJlcnMsIHdlJ3JlIGdvaW5nIHRvIGhhdmUgdG8gd29ycnkgYSBiaXQgbW9yZSBhYm91dCBob3cgd2UgcHV0IHZhbHVlcyBpbnRvXG4gKiBhcnJheXMuIFNpbmNlIHdlIGFyZSBvbmx5IHdvcnJ5aW5nIGFib3V0IHNpZ25lZCAzMi1iaXQgdmFsdWVzLCB3ZSdyZSBpblxuICogc2xpZ2h0bHkgYmV0dGVyIHNoYXBlLiBVbmZvcnR1bmF0ZWx5LCB3ZSByZWFsbHkgY2FuJ3QgZG8gb3VyIGZhdm9yaXRlIGJpbmFyeVxuICogJiBpbiB0aGlzIHN5c3RlbS4gSXQgcmVhbGx5IHNlZW1zIHRvIGRvIHRoZSB3cm9uZyB0aGluZy4gRm9yIGV4YW1wbGU6XG4gKlxuICogPiAtMzIgJiAweGZmXG4gKiAyMjRcbiAqXG4gKiBXaGF0J3MgaGFwcGVuaW5nIGFib3ZlIGlzIHJlYWxseTogMHhlMCAmIDB4ZmYgPSAweGUwLiBIb3dldmVyLCB0aGUgcmVzdWx0cyBvZlxuICogdGhpcyBhcmVuJ3QgdHJlYXRlZCBhcyBhIHNpZ25lZCBudW1iZXIuIFVsdGltYXRlbHkgYSBiYWQgdGhpbmcuXG4gKlxuICogV2hhdCB3ZSdyZSBnb2luZyB0byB3YW50IHRvIGRvIGlzIGJhc2ljYWxseSBjcmVhdGUgdGhlIHVuc2lnbmVkIGVxdWl2YWxlbnQgb2ZcbiAqIG91ciByZXByZXNlbnRhdGlvbiBhbmQgcGFzcyB0aGF0IG9mZiB0byB0aGUgd3VpbnQqIGZ1bmN0aW9ucy4gVG8gZG8gdGhhdFxuICogd2UncmUgZ29pbmcgdG8gZG8gdGhlIGZvbGxvd2luZzpcbiAqXG4gKiAgLSBpZiB0aGUgdmFsdWUgaXMgcG9zaXRpdmVcbiAqICAgICAgd2UgY2FuIHBhc3MgaXQgZGlyZWN0bHkgb2ZmIHRvIHRoZSBlcXVpdmFsZW50IHd1aW50XG4gKiAgLSBpZiB0aGUgdmFsdWUgaXMgbmVnYXRpdmVcbiAqICAgICAgd2UgZG8gdGhlIGZvbGxvd2luZyBjb21wdXRhdGlvbjpcbiAqICAgICAgICAgbWIgKyB2YWwgKyAxLCB3aGVyZVxuICogICAgICAgICBtYiAgIGlzIHRoZSBtYXhpbXVtIHVuc2lnbmVkIHZhbHVlIGluIHRoYXQgYnl0ZSBzaXplXG4gKiAgICAgICAgIHZhbCAgaXMgdGhlIEphdmFzY3JpcHQgbmVnYXRpdmUgaW50ZWdlclxuICpcbiAqXG4gKiBBcyBhIGNvbmNyZXRlIHZhbHVlLCB0YWtlIC0xMjguIEluIHNpZ25lZCAxNiBiaXRzIHRoaXMgd291bGQgYmUgMHhmZjgwLiBJZlxuICogeW91IGRvIG91dCB0aGUgY29tcHV0YXRpb25zOlxuICpcbiAqIDB4ZmZmZiAtIDEyOCArIDFcbiAqIDB4ZmZmZiAtIDEyN1xuICogMHhmZjgwXG4gKlxuICogWW91IGNhbiB0aGVuIGVuY29kZSB0aGlzIHZhbHVlIGFzIHRoZSBzaWduZWQgdmVyc2lvbi4gVGhpcyBpcyByZWFsbHkgcmF0aGVyXG4gKiBoYWNreSwgYnV0IGl0IHNob3VsZCB3b3JrIGFuZCBnZXQgdGhlIGpvYiBkb25lIHdoaWNoIGlzIG91ciBnb2FsIGhlcmUuXG4gKi9cblxuLypcbiAqIEEgc2VyaWVzIG9mIGNoZWNrcyB0byBtYWtlIHN1cmUgd2UgYWN0dWFsbHkgaGF2ZSBhIHNpZ25lZCAzMi1iaXQgbnVtYmVyXG4gKi9cbmZ1bmN0aW9uIHZlcmlmc2ludCh2YWx1ZSwgbWF4LCBtaW4pIHtcbiAgYXNzZXJ0Lm9rKHR5cGVvZiAodmFsdWUpID09ICdudW1iZXInLFxuICAgICAgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKTtcblxuICBhc3NlcnQub2sodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKTtcblxuICBhc3NlcnQub2soTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKTtcbn1cblxuZnVuY3Rpb24gdmVyaWZJRUVFNzU0KHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQub2sodHlwZW9mICh2YWx1ZSkgPT0gJ251bWJlcicsXG4gICAgICAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKTtcblxuICBhc3NlcnQub2sodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZiwgLTB4ODApO1xuICB9XG5cbiAgaWYgKHZhbHVlID49IDApIHtcbiAgICBidWZmZXIud3JpdGVVSW50OCh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCk7XG4gIH0gZWxzZSB7XG4gICAgYnVmZmVyLndyaXRlVUludDgoMHhmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBub0Fzc2VydCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHdyaXRlSW50MTYoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmYsIC0weDgwMDApO1xuICB9XG5cbiAgaWYgKHZhbHVlID49IDApIHtcbiAgICB3cml0ZVVJbnQxNihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIH0gZWxzZSB7XG4gICAgd3JpdGVVSW50MTYoYnVmZmVyLCAweGZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUludDMyKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApO1xuICB9XG5cbiAgaWYgKHZhbHVlID49IDApIHtcbiAgICB3cml0ZVVJbnQzMihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIH0gZWxzZSB7XG4gICAgd3JpdGVVSW50MzIoYnVmZmVyLCAweGZmZmZmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVGbG9hdChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KTtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS53cml0ZUlFRUU3NTQoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbixcbiAgICAgIDIzLCA0KTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0TEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVEb3VibGUoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyA3IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KTtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS53cml0ZUlFRUU3NTQoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbixcbiAgICAgIDUyLCA4KTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbn0se1wiLi9idWZmZXJfaWVlZTc1NFwiOjEsXCJhc3NlcnRcIjo2LFwiYmFzZTY0LWpzXCI6NH1dLFwiYnVmZmVyLWJyb3dzZXJpZnlcIjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5tb2R1bGUuZXhwb3J0cz1yZXF1aXJlKCdxOVR4Q0MnKTtcbn0se31dLDQ6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG5cdGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5KGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyO1xuXHRcblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyAnSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCc7XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHBsYWNlSG9sZGVycyA9IGI2NC5pbmRleE9mKCc9Jyk7XG5cdFx0cGxhY2VIb2xkZXJzID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSBwbGFjZUhvbGRlcnMgOiAwO1xuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gW107Ly9uZXcgVWludDhBcnJheShiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpO1xuXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuXHRcdGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoO1xuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGxvb2t1cC5pbmRleE9mKGI2NFtpXSkgPDwgMTgpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMV0pIDw8IDEyKSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDJdKSA8PCA2KSB8IGxvb2t1cC5pbmRleE9mKGI2NFtpICsgM10pO1xuXHRcdFx0YXJyLnB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNik7XG5cdFx0XHRhcnIucHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KTtcblx0XHRcdGFyci5wdXNoKHRtcCAmIDB4RkYpO1xuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChsb29rdXAuaW5kZXhPZihiNjRbaV0pIDw8IDIpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMV0pID4+IDQpO1xuXHRcdFx0YXJyLnB1c2godG1wICYgMHhGRik7XG5cdFx0fSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcblx0XHRcdHRtcCA9IChsb29rdXAuaW5kZXhPZihiNjRbaV0pIDw8IDEwKSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDFdKSA8PCA0KSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDJdKSA+PiAyKTtcblx0XHRcdGFyci5wdXNoKCh0bXAgPj4gOCkgJiAweEZGKTtcblx0XHRcdGFyci5wdXNoKHRtcCAmIDB4RkYpO1xuXHRcdH1cblxuXHRcdHJldHVybiBhcnI7XG5cdH1cblxuXHRmdW5jdGlvbiB1aW50OFRvQmFzZTY0KHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGg7XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICsgbG9va3VwW251bSAmIDB4M0ZdO1xuXHRcdH07XG5cblx0XHQvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG5cdFx0Zm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG5cdFx0XHR0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKTtcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcCk7XG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbdGVtcCA+PiAyXTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFsodGVtcCA8PCA0KSAmIDB4M0ZdO1xuXHRcdFx0XHRvdXRwdXQgKz0gJz09Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwW3RlbXAgPj4gMTBdO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwWyh0ZW1wID4+IDQpICYgMHgzRl07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbKHRlbXAgPDwgMikgJiAweDNGXTtcblx0XHRcdFx0b3V0cHV0ICs9ICc9Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdG1vZHVsZS5leHBvcnRzLnRvQnl0ZUFycmF5ID0gYjY0VG9CeXRlQXJyYXk7XG5cdG1vZHVsZS5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0O1xufSgpKTtcblxufSx7fV0sNTpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG5cblxuLy9cbi8vIFRoZSBzaGltcyBpbiB0aGlzIGZpbGUgYXJlIG5vdCBmdWxseSBpbXBsZW1lbnRlZCBzaGltcyBmb3IgdGhlIEVTNVxuLy8gZmVhdHVyZXMsIGJ1dCBkbyB3b3JrIGZvciB0aGUgcGFydGljdWxhciB1c2VjYXNlcyB0aGVyZSBpcyBpblxuLy8gdGhlIG90aGVyIG1vZHVsZXMuXG4vL1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLy8gQXJyYXkuaXNBcnJheSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5mdW5jdGlvbiBpc0FycmF5KHhzKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IHR5cGVvZiBBcnJheS5pc0FycmF5ID09PSAnZnVuY3Rpb24nID8gQXJyYXkuaXNBcnJheSA6IGlzQXJyYXk7XG5cbi8vIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgaWYgKHhzLmluZGV4T2YpIHJldHVybiB4cy5pbmRleE9mKHgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHggPT09IHhzW2ldKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59O1xuXG4vLyBBcnJheS5wcm90b3R5cGUuZmlsdGVyIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuZmlsdGVyID0gZnVuY3Rpb24gZmlsdGVyKHhzLCBmbikge1xuICBpZiAoeHMuZmlsdGVyKSByZXR1cm4geHMuZmlsdGVyKGZuKTtcbiAgdmFyIHJlcyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZuKHhzW2ldLCBpLCB4cykpIHJlcy5wdXNoKHhzW2ldKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLmZvckVhY2ggaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaCh4cywgZm4sIHNlbGYpIHtcbiAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuLCBzZWxmKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIGZuLmNhbGwoc2VsZiwgeHNbaV0sIGksIHhzKTtcbiAgfVxufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLm1hcCBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLm1hcCA9IGZ1bmN0aW9uIG1hcCh4cywgZm4pIHtcbiAgaWYgKHhzLm1hcCkgcmV0dXJuIHhzLm1hcChmbik7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoeHMubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIG91dFtpXSA9IGZuKHhzW2ldLCBpLCB4cyk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cbi8vIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5yZWR1Y2UgPSBmdW5jdGlvbiByZWR1Y2UoYXJyYXksIGNhbGxiYWNrLCBvcHRfaW5pdGlhbFZhbHVlKSB7XG4gIGlmIChhcnJheS5yZWR1Y2UpIHJldHVybiBhcnJheS5yZWR1Y2UoY2FsbGJhY2ssIG9wdF9pbml0aWFsVmFsdWUpO1xuICB2YXIgdmFsdWUsIGlzVmFsdWVTZXQgPSBmYWxzZTtcblxuICBpZiAoMiA8IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICB2YWx1ZSA9IG9wdF9pbml0aWFsVmFsdWU7XG4gICAgaXNWYWx1ZVNldCA9IHRydWU7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcnJheS5sZW5ndGg7IGwgPiBpOyArK2kpIHtcbiAgICBpZiAoYXJyYXkuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIGlmIChpc1ZhbHVlU2V0KSB7XG4gICAgICAgIHZhbHVlID0gY2FsbGJhY2sodmFsdWUsIGFycmF5W2ldLCBpLCBhcnJheSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBhcnJheVtpXTtcbiAgICAgICAgaXNWYWx1ZVNldCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuLy8gU3RyaW5nLnByb3RvdHlwZS5zdWJzdHIgLSBuZWdhdGl2ZSBpbmRleCBkb24ndCB3b3JrIGluIElFOFxuaWYgKCdhYicuc3Vic3RyKC0xKSAhPT0gJ2InKSB7XG4gIGV4cG9ydHMuc3Vic3RyID0gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbmd0aCkge1xuICAgIC8vIGRpZCB3ZSBnZXQgYSBuZWdhdGl2ZSBzdGFydCwgY2FsY3VsYXRlIGhvdyBtdWNoIGl0IGlzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSBzdHIubGVuZ3RoICsgc3RhcnQ7XG5cbiAgICAvLyBjYWxsIHRoZSBvcmlnaW5hbCBmdW5jdGlvblxuICAgIHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW5ndGgpO1xuICB9O1xufSBlbHNlIHtcbiAgZXhwb3J0cy5zdWJzdHIgPSBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHN0ci5zdWJzdHIoc3RhcnQsIGxlbmd0aCk7XG4gIH07XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUudHJpbSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLnRyaW0gPSBmdW5jdGlvbiAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKCk7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xufTtcblxuLy8gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5iaW5kID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gIHZhciBmbiA9IGFyZ3Muc2hpZnQoKTtcbiAgaWYgKGZuLmJpbmQpIHJldHVybiBmbi5iaW5kLmFwcGx5KGZuLCBhcmdzKTtcbiAgdmFyIHNlbGYgPSBhcmdzLnNoaWZ0KCk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgZm4uYXBwbHkoc2VsZiwgYXJncy5jb25jYXQoW0FycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyldKSk7XG4gIH07XG59O1xuXG4vLyBPYmplY3QuY3JlYXRlIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmZ1bmN0aW9uIGNyZWF0ZShwcm90b3R5cGUsIHByb3BlcnRpZXMpIHtcbiAgdmFyIG9iamVjdDtcbiAgaWYgKHByb3RvdHlwZSA9PT0gbnVsbCkge1xuICAgIG9iamVjdCA9IHsgJ19fcHJvdG9fXycgOiBudWxsIH07XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBwcm90b3R5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAndHlwZW9mIHByb3RvdHlwZVsnICsgKHR5cGVvZiBwcm90b3R5cGUpICsgJ10gIT0gXFwnb2JqZWN0XFwnJ1xuICAgICAgKTtcbiAgICB9XG4gICAgdmFyIFR5cGUgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICBvYmplY3QgPSBuZXcgVHlwZSgpO1xuICAgIG9iamVjdC5fX3Byb3RvX18gPSBwcm90b3R5cGU7XG4gIH1cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAndW5kZWZpbmVkJyAmJiBPYmplY3QuZGVmaW5lUHJvcGVydGllcykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG9iamVjdCwgcHJvcGVydGllcyk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cbmV4cG9ydHMuY3JlYXRlID0gdHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicgPyBPYmplY3QuY3JlYXRlIDogY3JlYXRlO1xuXG4vLyBPYmplY3Qua2V5cyBhbmQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgaXMgc3VwcG9ydGVkIGluIElFOSBob3dldmVyXG4vLyB0aGV5IGRvIHNob3cgYSBkZXNjcmlwdGlvbiBhbmQgbnVtYmVyIHByb3BlcnR5IG9uIEVycm9yIG9iamVjdHNcbmZ1bmN0aW9uIG5vdE9iamVjdChvYmplY3QpIHtcbiAgcmV0dXJuICgodHlwZW9mIG9iamVjdCAhPSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmplY3QgIT0gXCJmdW5jdGlvblwiKSB8fCBvYmplY3QgPT09IG51bGwpO1xufVxuXG5mdW5jdGlvbiBrZXlzU2hpbShvYmplY3QpIHtcbiAgaWYgKG5vdE9iamVjdChvYmplY3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdC5rZXlzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvciAodmFyIG5hbWUgaW4gb2JqZWN0KSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBuYW1lKSkge1xuICAgICAgcmVzdWx0LnB1c2gobmFtZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIGdldE93blByb3BlcnR5TmFtZXMgaXMgYWxtb3N0IHRoZSBzYW1lIGFzIE9iamVjdC5rZXlzIG9uZSBrZXkgZmVhdHVyZVxuLy8gIGlzIHRoYXQgaXQgcmV0dXJucyBoaWRkZW4gcHJvcGVydGllcywgc2luY2UgdGhhdCBjYW4ndCBiZSBpbXBsZW1lbnRlZCxcbi8vICB0aGlzIGZlYXR1cmUgZ2V0cyByZWR1Y2VkIHNvIGl0IGp1c3Qgc2hvd3MgdGhlIGxlbmd0aCBwcm9wZXJ0eSBvbiBhcnJheXNcbmZ1bmN0aW9uIHByb3BlcnR5U2hpbShvYmplY3QpIHtcbiAgaWYgKG5vdE9iamVjdChvYmplY3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0ga2V5c1NoaW0ob2JqZWN0KTtcbiAgaWYgKGV4cG9ydHMuaXNBcnJheShvYmplY3QpICYmIGV4cG9ydHMuaW5kZXhPZihvYmplY3QsICdsZW5ndGgnKSA9PT0gLTEpIHtcbiAgICByZXN1bHQucHVzaCgnbGVuZ3RoJyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxudmFyIGtleXMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgPyBPYmplY3Qua2V5cyA6IGtleXNTaGltO1xudmFyIGdldE93blByb3BlcnR5TmFtZXMgPSB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgPT09ICdmdW5jdGlvbicgP1xuICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA6IHByb3BlcnR5U2hpbTtcblxuaWYgKG5ldyBFcnJvcigpLmhhc093blByb3BlcnR5KCdkZXNjcmlwdGlvbicpKSB7XG4gIHZhciBFUlJPUl9QUk9QRVJUWV9GSUxURVIgPSBmdW5jdGlvbiAob2JqLCBhcnJheSkge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEVycm9yXScpIHtcbiAgICAgIGFycmF5ID0gZXhwb3J0cy5maWx0ZXIoYXJyYXksIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiBuYW1lICE9PSAnZGVzY3JpcHRpb24nICYmIG5hbWUgIT09ICdudW1iZXInICYmIG5hbWUgIT09ICdtZXNzYWdlJztcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH07XG5cbiAgZXhwb3J0cy5rZXlzID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBFUlJPUl9QUk9QRVJUWV9GSUxURVIob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICB9O1xuICBleHBvcnRzLmdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIEVSUk9SX1BST1BFUlRZX0ZJTFRFUihvYmplY3QsIGdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KSk7XG4gIH07XG59IGVsc2Uge1xuICBleHBvcnRzLmtleXMgPSBrZXlzO1xuICBleHBvcnRzLmdldE93blByb3BlcnR5TmFtZXMgPSBnZXRPd25Qcm9wZXJ0eU5hbWVzO1xufVxuXG4vLyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIC0gc3VwcG9ydGVkIGluIElFOCBidXQgb25seSBvbiBkb20gZWxlbWVudHNcbmZ1bmN0aW9uIHZhbHVlT2JqZWN0KHZhbHVlLCBrZXkpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbn1cblxuaWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih7J2EnOiAxfSwgJ2EnKTtcbiAgICBleHBvcnRzLmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJRTggZG9tIGVsZW1lbnQgaXNzdWUgLSB1c2UgYSB0cnkgY2F0Y2ggYW5kIGRlZmF1bHQgdG8gdmFsdWVPYmplY3RcbiAgICBleHBvcnRzLmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlT2JqZWN0KHZhbHVlLCBrZXkpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn0gZWxzZSB7XG4gIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gdmFsdWVPYmplY3Q7XG59XG5cbn0se31dLDY6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbi8vIFVUSUxJVFlcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudmFyIHNoaW1zID0gcmVxdWlyZSgnX3NoaW1zJyk7XG52YXIgcFNsaWNlID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgdGhpcy5tZXNzYWdlID0gb3B0aW9ucy5tZXNzYWdlIHx8IGdldE1lc3NhZ2UodGhpcyk7XG59O1xuXG4vLyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IgaW5zdGFuY2VvZiBFcnJvclxudXRpbC5pbmhlcml0cyhhc3NlcnQuQXNzZXJ0aW9uRXJyb3IsIEVycm9yKTtcblxuZnVuY3Rpb24gcmVwbGFjZXIoa2V5LCB2YWx1ZSkge1xuICBpZiAodXRpbC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gJycgKyB2YWx1ZTtcbiAgfVxuICBpZiAodXRpbC5pc051bWJlcih2YWx1ZSkgJiYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIGlmICh1dGlsLmlzRnVuY3Rpb24odmFsdWUpIHx8IHV0aWwuaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cnVuY2F0ZShzLCBuKSB7XG4gIGlmICh1dGlsLmlzU3RyaW5nKHMpKSB7XG4gICAgcmV0dXJuIHMubGVuZ3RoIDwgbiA/IHMgOiBzLnNsaWNlKDAsIG4pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2Uoc2VsZikge1xuICByZXR1cm4gdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5hY3R1YWwsIHJlcGxhY2VyKSwgMTI4KSArICcgJyArXG4gICAgICAgICBzZWxmLm9wZXJhdG9yICsgJyAnICtcbiAgICAgICAgIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuZXhwZWN0ZWQsIHJlcGxhY2VyKSwgMTI4KTtcbn1cblxuLy8gQXQgcHJlc2VudCBvbmx5IHRoZSB0aHJlZSBrZXlzIG1lbnRpb25lZCBhYm92ZSBhcmUgdXNlZCBhbmRcbi8vIHVuZGVyc3Rvb2QgYnkgdGhlIHNwZWMuIEltcGxlbWVudGF0aW9ucyBvciBzdWIgbW9kdWxlcyBjYW4gcGFzc1xuLy8gb3RoZXIga2V5cyB0byB0aGUgQXNzZXJ0aW9uRXJyb3IncyBjb25zdHJ1Y3RvciAtIHRoZXkgd2lsbCBiZVxuLy8gaWdub3JlZC5cblxuLy8gMy4gQWxsIG9mIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zIG11c3QgdGhyb3cgYW4gQXNzZXJ0aW9uRXJyb3Jcbi8vIHdoZW4gYSBjb3JyZXNwb25kaW5nIGNvbmRpdGlvbiBpcyBub3QgbWV0LCB3aXRoIGEgbWVzc2FnZSB0aGF0XG4vLyBtYXkgYmUgdW5kZWZpbmVkIGlmIG5vdCBwcm92aWRlZC4gIEFsbCBhc3NlcnRpb24gbWV0aG9kcyBwcm92aWRlXG4vLyBib3RoIHRoZSBhY3R1YWwgYW5kIGV4cGVjdGVkIHZhbHVlcyB0byB0aGUgYXNzZXJ0aW9uIGVycm9yIGZvclxuLy8gZGlzcGxheSBwdXJwb3Nlcy5cblxuZnVuY3Rpb24gZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCBvcGVyYXRvciwgc3RhY2tTdGFydEZ1bmN0aW9uKSB7XG4gIHRocm93IG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3Ioe1xuICAgIG1lc3NhZ2U6IG1lc3NhZ2UsXG4gICAgYWN0dWFsOiBhY3R1YWwsXG4gICAgZXhwZWN0ZWQ6IGV4cGVjdGVkLFxuICAgIG9wZXJhdG9yOiBvcGVyYXRvcixcbiAgICBzdGFja1N0YXJ0RnVuY3Rpb246IHN0YWNrU3RhcnRGdW5jdGlvblxuICB9KTtcbn1cblxuLy8gRVhURU5TSU9OISBhbGxvd3MgZm9yIHdlbGwgYmVoYXZlZCBlcnJvcnMgZGVmaW5lZCBlbHNld2hlcmUuXG5hc3NlcnQuZmFpbCA9IGZhaWw7XG5cbi8vIDQuIFB1cmUgYXNzZXJ0aW9uIHRlc3RzIHdoZXRoZXIgYSB2YWx1ZSBpcyB0cnV0aHksIGFzIGRldGVybWluZWRcbi8vIGJ5ICEhZ3VhcmQuXG4vLyBhc3NlcnQub2soZ3VhcmQsIG1lc3NhZ2Vfb3B0KTtcbi8vIFRoaXMgc3RhdGVtZW50IGlzIGVxdWl2YWxlbnQgdG8gYXNzZXJ0LmVxdWFsKHRydWUsICEhZ3VhcmQsXG4vLyBtZXNzYWdlX29wdCk7LiBUbyB0ZXN0IHN0cmljdGx5IGZvciB0aGUgdmFsdWUgdHJ1ZSwgdXNlXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwodHJ1ZSwgZ3VhcmQsIG1lc3NhZ2Vfb3B0KTsuXG5cbmZ1bmN0aW9uIG9rKHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICghdmFsdWUpIGZhaWwodmFsdWUsIHRydWUsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5vayk7XG59XG5hc3NlcnQub2sgPSBvaztcblxuLy8gNS4gVGhlIGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzaGFsbG93LCBjb2VyY2l2ZSBlcXVhbGl0eSB3aXRoXG4vLyA9PS5cbi8vIGFzc2VydC5lcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5lcXVhbCA9IGZ1bmN0aW9uIGVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPSBleHBlY3RlZCkgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQuZXF1YWwpO1xufTtcblxuLy8gNi4gVGhlIG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHdoZXRoZXIgdHdvIG9iamVjdHMgYXJlIG5vdCBlcXVhbFxuLy8gd2l0aCAhPSBhc3NlcnQubm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RXF1YWwgPSBmdW5jdGlvbiBub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPScsIGFzc2VydC5ub3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDcuIFRoZSBlcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgYSBkZWVwIGVxdWFsaXR5IHJlbGF0aW9uLlxuLy8gYXNzZXJ0LmRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5kZWVwRXF1YWwgPSBmdW5jdGlvbiBkZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoIV9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdkZWVwRXF1YWwnLCBhc3NlcnQuZGVlcEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIC8vIDcuMS4gQWxsIGlkZW50aWNhbCB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGFzIGRldGVybWluZWQgYnkgPT09LlxuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0J1ZmZlcihhY3R1YWwpICYmIHV0aWwuaXNCdWZmZXIoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKGFjdHVhbC5sZW5ndGggIT0gZXhwZWN0ZWQubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFjdHVhbC5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFjdHVhbFtpXSAhPT0gZXhwZWN0ZWRbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcblxuICAvLyA3LjIuIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIERhdGUgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIERhdGUgb2JqZWN0IHRoYXQgcmVmZXJzIHRvIHRoZSBzYW1lIHRpbWUuXG4gIH0gZWxzZSBpZiAodXRpbC5pc0RhdGUoYWN0dWFsKSAmJiB1dGlsLmlzRGF0ZShleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLmdldFRpbWUoKSA9PT0gZXhwZWN0ZWQuZ2V0VGltZSgpO1xuXG4gIC8vIDcuMyBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBSZWdFeHAgb2JqZWN0LCB0aGUgYWN0dWFsIHZhbHVlIGlzXG4gIC8vIGVxdWl2YWxlbnQgaWYgaXQgaXMgYWxzbyBhIFJlZ0V4cCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBzb3VyY2UgYW5kXG4gIC8vIHByb3BlcnRpZXMgKGBnbG9iYWxgLCBgbXVsdGlsaW5lYCwgYGxhc3RJbmRleGAsIGBpZ25vcmVDYXNlYCkuXG4gIH0gZWxzZSBpZiAodXRpbC5pc1JlZ0V4cChhY3R1YWwpICYmIHV0aWwuaXNSZWdFeHAoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5zb3VyY2UgPT09IGV4cGVjdGVkLnNvdXJjZSAmJlxuICAgICAgICAgICBhY3R1YWwuZ2xvYmFsID09PSBleHBlY3RlZC5nbG9iYWwgJiZcbiAgICAgICAgICAgYWN0dWFsLm11bHRpbGluZSA9PT0gZXhwZWN0ZWQubXVsdGlsaW5lICYmXG4gICAgICAgICAgIGFjdHVhbC5sYXN0SW5kZXggPT09IGV4cGVjdGVkLmxhc3RJbmRleCAmJlxuICAgICAgICAgICBhY3R1YWwuaWdub3JlQ2FzZSA9PT0gZXhwZWN0ZWQuaWdub3JlQ2FzZTtcblxuICAvLyA3LjQuIE90aGVyIHBhaXJzIHRoYXQgZG8gbm90IGJvdGggcGFzcyB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCcsXG4gIC8vIGVxdWl2YWxlbmNlIGlzIGRldGVybWluZWQgYnkgPT0uXG4gIH0gZWxzZSBpZiAoIXV0aWwuaXNPYmplY3QoYWN0dWFsKSAmJiAhdXRpbC5pc09iamVjdChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsID09IGV4cGVjdGVkO1xuXG4gIC8vIDcuNSBGb3IgYWxsIG90aGVyIE9iamVjdCBwYWlycywgaW5jbHVkaW5nIEFycmF5IG9iamVjdHMsIGVxdWl2YWxlbmNlIGlzXG4gIC8vIGRldGVybWluZWQgYnkgaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChhcyB2ZXJpZmllZFxuICAvLyB3aXRoIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCksIHRoZSBzYW1lIHNldCBvZiBrZXlzXG4gIC8vIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLCBlcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnlcbiAgLy8gY29ycmVzcG9uZGluZyBrZXksIGFuZCBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuIE5vdGU6IHRoaXNcbiAgLy8gYWNjb3VudHMgZm9yIGJvdGggbmFtZWQgYW5kIGluZGV4ZWQgcHJvcGVydGllcyBvbiBBcnJheXMuXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iakVxdWl2KGFjdHVhbCwgZXhwZWN0ZWQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKG9iamVjdCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iamVjdCkgPT0gJ1tvYmplY3QgQXJndW1lbnRzXSc7XG59XG5cbmZ1bmN0aW9uIG9iakVxdWl2KGEsIGIpIHtcbiAgaWYgKHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYSkgfHwgdXRpbC5pc051bGxPclVuZGVmaW5lZChiKSlcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS5cbiAgaWYgKGEucHJvdG90eXBlICE9PSBiLnByb3RvdHlwZSkgcmV0dXJuIGZhbHNlO1xuICAvL35+fkkndmUgbWFuYWdlZCB0byBicmVhayBPYmplY3Qua2V5cyB0aHJvdWdoIHNjcmV3eSBhcmd1bWVudHMgcGFzc2luZy5cbiAgLy8gICBDb252ZXJ0aW5nIHRvIGFycmF5IHNvbHZlcyB0aGUgcHJvYmxlbS5cbiAgaWYgKGlzQXJndW1lbnRzKGEpKSB7XG4gICAgaWYgKCFpc0FyZ3VtZW50cyhiKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhID0gcFNsaWNlLmNhbGwoYSk7XG4gICAgYiA9IHBTbGljZS5jYWxsKGIpO1xuICAgIHJldHVybiBfZGVlcEVxdWFsKGEsIGIpO1xuICB9XG4gIHRyeSB7XG4gICAgdmFyIGthID0gc2hpbXMua2V5cyhhKSxcbiAgICAgICAga2IgPSBzaGltcy5rZXlzKGIpLFxuICAgICAgICBrZXksIGk7XG4gIH0gY2F0Y2ggKGUpIHsvL2hhcHBlbnMgd2hlbiBvbmUgaXMgYSBzdHJpbmcgbGl0ZXJhbCBhbmQgdGhlIG90aGVyIGlzbid0XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoa2V5cyBpbmNvcnBvcmF0ZXNcbiAgLy8gaGFzT3duUHJvcGVydHkpXG4gIGlmIChrYS5sZW5ndGggIT0ga2IubGVuZ3RoKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy90aGUgc2FtZSBzZXQgb2Yga2V5cyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSxcbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG4gIC8vfn5+Y2hlYXAga2V5IHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pXG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy9lcXVpdmFsZW50IHZhbHVlcyBmb3IgZXZlcnkgY29ycmVzcG9uZGluZyBrZXksIGFuZFxuICAvL35+fnBvc3NpYmx5IGV4cGVuc2l2ZSBkZWVwIHRlc3RcbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBrZXkgPSBrYVtpXTtcbiAgICBpZiAoIV9kZWVwRXF1YWwoYVtrZXldLCBiW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIDguIFRoZSBub24tZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGZvciBhbnkgZGVlcCBpbmVxdWFsaXR5LlxuLy8gYXNzZXJ0Lm5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3REZWVwRXF1YWwgPSBmdW5jdGlvbiBub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ25vdERlZXBFcXVhbCcsIGFzc2VydC5ub3REZWVwRXF1YWwpO1xuICB9XG59O1xuXG4vLyA5LiBUaGUgc3RyaWN0IGVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBzdHJpY3QgZXF1YWxpdHksIGFzIGRldGVybWluZWQgYnkgPT09LlxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnN0cmljdEVxdWFsID0gZnVuY3Rpb24gc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09PScsIGFzc2VydC5zdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDEwLiBUaGUgc3RyaWN0IG5vbi1lcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgZm9yIHN0cmljdCBpbmVxdWFsaXR5LCBhc1xuLy8gZGV0ZXJtaW5lZCBieSAhPT0uICBhc3NlcnQubm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90U3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT09JywgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkge1xuICBpZiAoIWFjdHVhbCB8fCAhZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGV4cGVjdGVkKSA9PSAnW29iamVjdCBSZWdFeHBdJykge1xuICAgIHJldHVybiBleHBlY3RlZC50ZXN0KGFjdHVhbCk7XG4gIH0gZWxzZSBpZiAoYWN0dWFsIGluc3RhbmNlb2YgZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChleHBlY3RlZC5jYWxsKHt9LCBhY3R1YWwpID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIF90aHJvd3Moc2hvdWxkVGhyb3csIGJsb2NrLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICB2YXIgYWN0dWFsO1xuXG4gIGlmICh1dGlsLmlzU3RyaW5nKGV4cGVjdGVkKSkge1xuICAgIG1lc3NhZ2UgPSBleHBlY3RlZDtcbiAgICBleHBlY3RlZCA9IG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGJsb2NrKCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBhY3R1YWwgPSBlO1xuICB9XG5cbiAgbWVzc2FnZSA9IChleHBlY3RlZCAmJiBleHBlY3RlZC5uYW1lID8gJyAoJyArIGV4cGVjdGVkLm5hbWUgKyAnKS4nIDogJy4nKSArXG4gICAgICAgICAgICAobWVzc2FnZSA/ICcgJyArIG1lc3NhZ2UgOiAnLicpO1xuXG4gIGlmIChzaG91bGRUaHJvdyAmJiAhYWN0dWFsKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnTWlzc2luZyBleHBlY3RlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoIXNob3VsZFRocm93ICYmIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCAnR290IHVud2FudGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICgoc2hvdWxkVGhyb3cgJiYgYWN0dWFsICYmIGV4cGVjdGVkICYmXG4gICAgICAhZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHx8ICghc2hvdWxkVGhyb3cgJiYgYWN0dWFsKSkge1xuICAgIHRocm93IGFjdHVhbDtcbiAgfVxufVxuXG4vLyAxMS4gRXhwZWN0ZWQgdG8gdGhyb3cgYW4gZXJyb3I6XG4vLyBhc3NlcnQudGhyb3dzKGJsb2NrLCBFcnJvcl9vcHQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LnRocm93cyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9lcnJvciwgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFt0cnVlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuLy8gRVhURU5TSU9OISBUaGlzIGlzIGFubm95aW5nIHRvIHdyaXRlIG91dHNpZGUgdGhpcyBtb2R1bGUuXG5hc3NlcnQuZG9lc05vdFRocm93ID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbZmFsc2VdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG5hc3NlcnQuaWZFcnJvciA9IGZ1bmN0aW9uKGVycikgeyBpZiAoZXJyKSB7dGhyb3cgZXJyO319O1xufSx7XCJfc2hpbXNcIjo1LFwidXRpbFwiOjd9XSw3OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcblxudmFyIGZvcm1hdFJlZ0V4cCA9IC8lW3NkaiVdL2c7XG5leHBvcnRzLmZvcm1hdCA9IGZ1bmN0aW9uKGYpIHtcbiAgaWYgKCFpc1N0cmluZyhmKSkge1xuICAgIHZhciBvYmplY3RzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIG9iamVjdHMucHVzaChpbnNwZWN0KGFyZ3VtZW50c1tpXSkpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0cy5qb2luKCcgJyk7XG4gIH1cblxuICB2YXIgaSA9IDE7XG4gIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICB2YXIgbGVuID0gYXJncy5sZW5ndGg7XG4gIHZhciBzdHIgPSBTdHJpbmcoZikucmVwbGFjZShmb3JtYXRSZWdFeHAsIGZ1bmN0aW9uKHgpIHtcbiAgICBpZiAoeCA9PT0gJyUlJykgcmV0dXJuICclJztcbiAgICBpZiAoaSA+PSBsZW4pIHJldHVybiB4O1xuICAgIHN3aXRjaCAoeCkge1xuICAgICAgY2FzZSAnJXMnOiByZXR1cm4gU3RyaW5nKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclZCc6IHJldHVybiBOdW1iZXIoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVqJzpcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoYXJnc1tpKytdKTtcbiAgICAgICAgfSBjYXRjaCAoXykge1xuICAgICAgICAgIHJldHVybiAnW0NpcmN1bGFyXSc7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgfSk7XG4gIGZvciAodmFyIHggPSBhcmdzW2ldOyBpIDwgbGVuOyB4ID0gYXJnc1srK2ldKSB7XG4gICAgaWYgKGlzTnVsbCh4KSB8fCAhaXNPYmplY3QoeCkpIHtcbiAgICAgIHN0ciArPSAnICcgKyB4O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgKz0gJyAnICsgaW5zcGVjdCh4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn07XG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBzaGltcy5mb3JFYWNoKGFycmF5LCBmdW5jdGlvbih2YWwsIGlkeCkge1xuICAgIGhhc2hbdmFsXSA9IHRydWU7XG4gIH0pO1xuXG4gIHJldHVybiBoYXNoO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFZhbHVlKGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcykge1xuICAvLyBQcm92aWRlIGEgaG9vayBmb3IgdXNlci1zcGVjaWZpZWQgaW5zcGVjdCBmdW5jdGlvbnMuXG4gIC8vIENoZWNrIHRoYXQgdmFsdWUgaXMgYW4gb2JqZWN0IHdpdGggYW4gaW5zcGVjdCBmdW5jdGlvbiBvbiBpdFxuICBpZiAoY3R4LmN1c3RvbUluc3BlY3QgJiZcbiAgICAgIHZhbHVlICYmXG4gICAgICBpc0Z1bmN0aW9uKHZhbHVlLmluc3BlY3QpICYmXG4gICAgICAvLyBGaWx0ZXIgb3V0IHRoZSB1dGlsIG1vZHVsZSwgaXQncyBpbnNwZWN0IGZ1bmN0aW9uIGlzIHNwZWNpYWxcbiAgICAgIHZhbHVlLmluc3BlY3QgIT09IGV4cG9ydHMuaW5zcGVjdCAmJlxuICAgICAgLy8gQWxzbyBmaWx0ZXIgb3V0IGFueSBwcm90b3R5cGUgb2JqZWN0cyB1c2luZyB0aGUgY2lyY3VsYXIgY2hlY2suXG4gICAgICAhKHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLnByb3RvdHlwZSA9PT0gdmFsdWUpKSB7XG4gICAgdmFyIHJldCA9IHZhbHVlLmluc3BlY3QocmVjdXJzZVRpbWVzKTtcbiAgICBpZiAoIWlzU3RyaW5nKHJldCkpIHtcbiAgICAgIHJldCA9IGZvcm1hdFZhbHVlKGN0eCwgcmV0LCByZWN1cnNlVGltZXMpO1xuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLy8gUHJpbWl0aXZlIHR5cGVzIGNhbm5vdCBoYXZlIHByb3BlcnRpZXNcbiAgdmFyIHByaW1pdGl2ZSA9IGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKTtcbiAgaWYgKHByaW1pdGl2ZSkge1xuICAgIHJldHVybiBwcmltaXRpdmU7XG4gIH1cblxuICAvLyBMb29rIHVwIHRoZSBrZXlzIG9mIHRoZSBvYmplY3QuXG4gIHZhciBrZXlzID0gc2hpbXMua2V5cyh2YWx1ZSk7XG4gIHZhciB2aXNpYmxlS2V5cyA9IGFycmF5VG9IYXNoKGtleXMpO1xuXG4gIGlmIChjdHguc2hvd0hpZGRlbikge1xuICAgIGtleXMgPSBzaGltcy5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIFNvbWUgdHlwZSBvZiBvYmplY3Qgd2l0aG91dCBwcm9wZXJ0aWVzIGNhbiBiZSBzaG9ydGN1dHRlZC5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgICB2YXIgbmFtZSA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbRnVuY3Rpb24nICsgbmFtZSArICddJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShEYXRlLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ2RhdGUnKTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBiYXNlID0gJycsIGFycmF5ID0gZmFsc2UsIGJyYWNlcyA9IFsneycsICd9J107XG5cbiAgLy8gTWFrZSBBcnJheSBzYXkgdGhhdCB0aGV5IGFyZSBBcnJheVxuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBhcnJheSA9IHRydWU7XG4gICAgYnJhY2VzID0gWydbJywgJ10nXTtcbiAgfVxuXG4gIC8vIE1ha2UgZnVuY3Rpb25zIHNheSB0aGF0IHRoZXkgYXJlIGZ1bmN0aW9uc1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICB2YXIgbiA9IHZhbHVlLm5hbWUgPyAnOiAnICsgdmFsdWUubmFtZSA6ICcnO1xuICAgIGJhc2UgPSAnIFtGdW5jdGlvbicgKyBuICsgJ10nO1xuICB9XG5cbiAgLy8gTWFrZSBSZWdFeHBzIHNheSB0aGF0IHRoZXkgYXJlIFJlZ0V4cHNcbiAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBkYXRlcyB3aXRoIHByb3BlcnRpZXMgZmlyc3Qgc2F5IHRoZSBkYXRlXG4gIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIERhdGUucHJvdG90eXBlLnRvVVRDU3RyaW5nLmNhbGwodmFsdWUpO1xuICB9XG5cbiAgLy8gTWFrZSBlcnJvciB3aXRoIG1lc3NhZ2UgZmlyc3Qgc2F5IHRoZSBlcnJvclxuICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgaWYgKGtleXMubGVuZ3RoID09PSAwICYmICghYXJyYXkgfHwgdmFsdWUubGVuZ3RoID09IDApKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyBicmFjZXNbMV07XG4gIH1cblxuICBpZiAocmVjdXJzZVRpbWVzIDwgMCkge1xuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW09iamVjdF0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGN0eC5zZWVuLnB1c2godmFsdWUpO1xuXG4gIHZhciBvdXRwdXQ7XG4gIGlmIChhcnJheSkge1xuICAgIG91dHB1dCA9IGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IGtleXMubWFwKGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpO1xuICAgIH0pO1xuICB9XG5cbiAgY3R4LnNlZW4ucG9wKCk7XG5cbiAgcmV0dXJuIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSkge1xuICBpZiAoaXNVbmRlZmluZWQodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgndW5kZWZpbmVkJywgJ3VuZGVmaW5lZCcpO1xuICBpZiAoaXNTdHJpbmcodmFsdWUpKSB7XG4gICAgdmFyIHNpbXBsZSA9ICdcXCcnICsgSlNPTi5zdHJpbmdpZnkodmFsdWUpLnJlcGxhY2UoL15cInxcIiQvZywgJycpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpICsgJ1xcJyc7XG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKHNpbXBsZSwgJ3N0cmluZycpO1xuICB9XG4gIGlmIChpc051bWJlcih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdudW1iZXInKTtcbiAgaWYgKGlzQm9vbGVhbih2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCcnICsgdmFsdWUsICdib29sZWFuJyk7XG4gIC8vIEZvciBzb21lIHJlYXNvbiB0eXBlb2YgbnVsbCBpcyBcIm9iamVjdFwiLCBzbyBzcGVjaWFsIGNhc2UgaGVyZS5cbiAgaWYgKGlzTnVsbCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCdudWxsJywgJ251bGwnKTtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRFcnJvcih2YWx1ZSkge1xuICByZXR1cm4gJ1snICsgRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpICsgJ10nO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEFycmF5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleXMpIHtcbiAgdmFyIG91dHB1dCA9IFtdO1xuICBmb3IgKHZhciBpID0gMCwgbCA9IHZhbHVlLmxlbmd0aDsgaSA8IGw7ICsraSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh2YWx1ZSwgU3RyaW5nKGkpKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBTdHJpbmcoaSksIHRydWUpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0LnB1c2goJycpO1xuICAgIH1cbiAgfVxuXG4gIHNoaW1zLmZvckVhY2goa2V5cywgZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIGtleSwgdHJ1ZSkpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSkge1xuICB2YXIgbmFtZSwgc3RyLCBkZXNjO1xuICBkZXNjID0gc2hpbXMuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghaGFzT3duUHJvcGVydHkodmlzaWJsZUtleXMsIGtleSkpIHtcbiAgICBuYW1lID0gJ1snICsga2V5ICsgJ10nO1xuICB9XG4gIGlmICghc3RyKSB7XG4gICAgaWYgKHNoaW1zLmluZGV4T2YoY3R4LnNlZW4sIGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBzaGltcy5yZWR1Y2Uob3V0cHV0LCBmdW5jdGlvbihwcmV2LCBjdXIpIHtcbiAgICBudW1MaW5lc0VzdCsrO1xuICAgIGlmIChjdXIuaW5kZXhPZignXFxuJykgPj0gMCkgbnVtTGluZXNFc3QrKztcbiAgICByZXR1cm4gcHJldiArIGN1ci5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZywgJycpLmxlbmd0aCArIDE7XG4gIH0sIDApO1xuXG4gIGlmIChsZW5ndGggPiA2MCkge1xuICAgIHJldHVybiBicmFjZXNbMF0gK1xuICAgICAgICAgICAoYmFzZSA9PT0gJycgPyAnJyA6IGJhc2UgKyAnXFxuICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgb3V0cHV0LmpvaW4oJyxcXG4gICcpICtcbiAgICAgICAgICAgJyAnICtcbiAgICAgICAgICAgYnJhY2VzWzFdO1xuICB9XG5cbiAgcmV0dXJuIGJyYWNlc1swXSArIGJhc2UgKyAnICcgKyBvdXRwdXQuam9pbignLCAnKSArICcgJyArIGJyYWNlc1sxXTtcbn1cblxuXG4vLyBOT1RFOiBUaGVzZSB0eXBlIGNoZWNraW5nIGZ1bmN0aW9ucyBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBgaW5zdGFuY2VvZmBcbi8vIGJlY2F1c2UgaXQgaXMgZnJhZ2lsZSBhbmQgY2FuIGJlIGVhc2lseSBmYWtlZCB3aXRoIGBPYmplY3QuY3JlYXRlKClgLlxuZnVuY3Rpb24gaXNBcnJheShhcikge1xuICByZXR1cm4gc2hpbXMuaXNBcnJheShhcik7XG59XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuXG5mdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnYm9vbGVhbic7XG59XG5leHBvcnRzLmlzQm9vbGVhbiA9IGlzQm9vbGVhbjtcblxuZnVuY3Rpb24gaXNOdWxsKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGwgPSBpc051bGw7XG5cbmZ1bmN0aW9uIGlzTnVsbE9yVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbE9yVW5kZWZpbmVkID0gaXNOdWxsT3JVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XG59XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5cbmZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N0cmluZyc7XG59XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5cbmZ1bmN0aW9uIGlzU3ltYm9sKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCc7XG59XG5leHBvcnRzLmlzU3ltYm9sID0gaXNTeW1ib2w7XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5leHBvcnRzLmlzVW5kZWZpbmVkID0gaXNVbmRlZmluZWQ7XG5cbmZ1bmN0aW9uIGlzUmVnRXhwKHJlKSB7XG4gIHJldHVybiBpc09iamVjdChyZSkgJiYgb2JqZWN0VG9TdHJpbmcocmUpID09PSAnW29iamVjdCBSZWdFeHBdJztcbn1cbmV4cG9ydHMuaXNSZWdFeHAgPSBpc1JlZ0V4cDtcblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmc7XG59XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5cbmZ1bmN0aW9uIGlzRGF0ZShkKSB7XG4gIHJldHVybiBpc09iamVjdChkKSAmJiBvYmplY3RUb1N0cmluZyhkKSA9PT0gJ1tvYmplY3QgRGF0ZV0nO1xufVxuZXhwb3J0cy5pc0RhdGUgPSBpc0RhdGU7XG5cbmZ1bmN0aW9uIGlzRXJyb3IoZSkge1xuICByZXR1cm4gaXNPYmplY3QoZSkgJiYgb2JqZWN0VG9TdHJpbmcoZSkgPT09ICdbb2JqZWN0IEVycm9yXSc7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5mdW5jdGlvbiBpc0J1ZmZlcihhcmcpIHtcbiAgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIEJ1ZmZlcjtcbn1cbmV4cG9ydHMuaXNCdWZmZXIgPSBpc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gZnVuY3Rpb24oY3Rvciwgc3VwZXJDdG9yKSB7XG4gIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuICBjdG9yLnByb3RvdHlwZSA9IHNoaW1zLmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG59O1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gc2hpbXMua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG59LHtcIl9zaGltc1wiOjV9XX0se30sW10pXG47O21vZHVsZS5leHBvcnRzPXJlcXVpcmUoXCJidWZmZXItYnJvd3NlcmlmeVwiKVxuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuUG9zdCA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnBvc3RNZXNzYWdlICYmIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyXG4gICAgO1xuXG4gICAgaWYgKGNhblNldEltbWVkaWF0ZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGYpIHsgcmV0dXJuIHdpbmRvdy5zZXRJbW1lZGlhdGUoZikgfTtcbiAgICB9XG5cbiAgICBpZiAoY2FuUG9zdCkge1xuICAgICAgICB2YXIgcXVldWUgPSBbXTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBldi5zb3VyY2U7XG4gICAgICAgICAgICBpZiAoKHNvdXJjZSA9PT0gd2luZG93IHx8IHNvdXJjZSA9PT0gbnVsbCkgJiYgZXYuZGF0YSA9PT0gJ3Byb2Nlc3MtdGljaycpIHtcbiAgICAgICAgICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICBpZiAocXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdHJ1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgICAgICBxdWV1ZS5wdXNoKGZuKTtcbiAgICAgICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZSgncHJvY2Vzcy10aWNrJywgJyonKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcbn0pKCk7XG5cbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuIiwidmFyIGpRdWVyeSA9IHJlcXVpcmUoJ2pxdWVyeScpO1xuXG4vKiFcbiAqIGpRdWVyeSBVSSBDb3JlIDEuMTAuNFxuICogaHR0cDovL2pxdWVyeXVpLmNvbVxuICpcbiAqIENvcHlyaWdodCAyMDE0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBodHRwOi8vYXBpLmpxdWVyeXVpLmNvbS9jYXRlZ29yeS91aS1jb3JlL1xuICovXG4oZnVuY3Rpb24oICQsIHVuZGVmaW5lZCApIHtcblxudmFyIHV1aWQgPSAwLFxuXHRydW5pcXVlSWQgPSAvXnVpLWlkLVxcZCskLztcblxuLy8gJC51aSBtaWdodCBleGlzdCBmcm9tIGNvbXBvbmVudHMgd2l0aCBubyBkZXBlbmRlbmNpZXMsIGUuZy4sICQudWkucG9zaXRpb25cbiQudWkgPSAkLnVpIHx8IHt9O1xuXG4kLmV4dGVuZCggJC51aSwge1xuXHR2ZXJzaW9uOiBcIjEuMTAuNFwiLFxuXG5cdGtleUNvZGU6IHtcblx0XHRCQUNLU1BBQ0U6IDgsXG5cdFx0Q09NTUE6IDE4OCxcblx0XHRERUxFVEU6IDQ2LFxuXHRcdERPV046IDQwLFxuXHRcdEVORDogMzUsXG5cdFx0RU5URVI6IDEzLFxuXHRcdEVTQ0FQRTogMjcsXG5cdFx0SE9NRTogMzYsXG5cdFx0TEVGVDogMzcsXG5cdFx0TlVNUEFEX0FERDogMTA3LFxuXHRcdE5VTVBBRF9ERUNJTUFMOiAxMTAsXG5cdFx0TlVNUEFEX0RJVklERTogMTExLFxuXHRcdE5VTVBBRF9FTlRFUjogMTA4LFxuXHRcdE5VTVBBRF9NVUxUSVBMWTogMTA2LFxuXHRcdE5VTVBBRF9TVUJUUkFDVDogMTA5LFxuXHRcdFBBR0VfRE9XTjogMzQsXG5cdFx0UEFHRV9VUDogMzMsXG5cdFx0UEVSSU9EOiAxOTAsXG5cdFx0UklHSFQ6IDM5LFxuXHRcdFNQQUNFOiAzMixcblx0XHRUQUI6IDksXG5cdFx0VVA6IDM4XG5cdH1cbn0pO1xuXG4vLyBwbHVnaW5zXG4kLmZuLmV4dGVuZCh7XG5cdGZvY3VzOiAoZnVuY3Rpb24oIG9yaWcgKSB7XG5cdFx0cmV0dXJuIGZ1bmN0aW9uKCBkZWxheSwgZm4gKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIGRlbGF5ID09PSBcIm51bWJlclwiID9cblx0XHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHZhciBlbGVtID0gdGhpcztcblx0XHRcdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0JCggZWxlbSApLmZvY3VzKCk7XG5cdFx0XHRcdFx0XHRpZiAoIGZuICkge1xuXHRcdFx0XHRcdFx0XHRmbi5jYWxsKCBlbGVtICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSwgZGVsYXkgKTtcblx0XHRcdFx0fSkgOlxuXHRcdFx0XHRvcmlnLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHR9O1xuXHR9KSggJC5mbi5mb2N1cyApLFxuXG5cdHNjcm9sbFBhcmVudDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHNjcm9sbFBhcmVudDtcblx0XHRpZiAoKCQudWkuaWUgJiYgKC8oc3RhdGljfHJlbGF0aXZlKS8pLnRlc3QodGhpcy5jc3MoXCJwb3NpdGlvblwiKSkpIHx8ICgvYWJzb2x1dGUvKS50ZXN0KHRoaXMuY3NzKFwicG9zaXRpb25cIikpKSB7XG5cdFx0XHRzY3JvbGxQYXJlbnQgPSB0aGlzLnBhcmVudHMoKS5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAoLyhyZWxhdGl2ZXxhYnNvbHV0ZXxmaXhlZCkvKS50ZXN0KCQuY3NzKHRoaXMsXCJwb3NpdGlvblwiKSkgJiYgKC8oYXV0b3xzY3JvbGwpLykudGVzdCgkLmNzcyh0aGlzLFwib3ZlcmZsb3dcIikrJC5jc3ModGhpcyxcIm92ZXJmbG93LXlcIikrJC5jc3ModGhpcyxcIm92ZXJmbG93LXhcIikpO1xuXHRcdFx0fSkuZXEoMCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNjcm9sbFBhcmVudCA9IHRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICgvKGF1dG98c2Nyb2xsKS8pLnRlc3QoJC5jc3ModGhpcyxcIm92ZXJmbG93XCIpKyQuY3NzKHRoaXMsXCJvdmVyZmxvdy15XCIpKyQuY3NzKHRoaXMsXCJvdmVyZmxvdy14XCIpKTtcblx0XHRcdH0pLmVxKDApO1xuXHRcdH1cblxuXHRcdHJldHVybiAoL2ZpeGVkLykudGVzdCh0aGlzLmNzcyhcInBvc2l0aW9uXCIpKSB8fCAhc2Nyb2xsUGFyZW50Lmxlbmd0aCA/ICQoZG9jdW1lbnQpIDogc2Nyb2xsUGFyZW50O1xuXHR9LFxuXG5cdHpJbmRleDogZnVuY3Rpb24oIHpJbmRleCApIHtcblx0XHRpZiAoIHpJbmRleCAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuY3NzKCBcInpJbmRleFwiLCB6SW5kZXggKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xuXHRcdFx0dmFyIGVsZW0gPSAkKCB0aGlzWyAwIF0gKSwgcG9zaXRpb24sIHZhbHVlO1xuXHRcdFx0d2hpbGUgKCBlbGVtLmxlbmd0aCAmJiBlbGVtWyAwIF0gIT09IGRvY3VtZW50ICkge1xuXHRcdFx0XHQvLyBJZ25vcmUgei1pbmRleCBpZiBwb3NpdGlvbiBpcyBzZXQgdG8gYSB2YWx1ZSB3aGVyZSB6LWluZGV4IGlzIGlnbm9yZWQgYnkgdGhlIGJyb3dzZXJcblx0XHRcdFx0Ly8gVGhpcyBtYWtlcyBiZWhhdmlvciBvZiB0aGlzIGZ1bmN0aW9uIGNvbnNpc3RlbnQgYWNyb3NzIGJyb3dzZXJzXG5cdFx0XHRcdC8vIFdlYktpdCBhbHdheXMgcmV0dXJucyBhdXRvIGlmIHRoZSBlbGVtZW50IGlzIHBvc2l0aW9uZWRcblx0XHRcdFx0cG9zaXRpb24gPSBlbGVtLmNzcyggXCJwb3NpdGlvblwiICk7XG5cdFx0XHRcdGlmICggcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJyZWxhdGl2ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSB7XG5cdFx0XHRcdFx0Ly8gSUUgcmV0dXJucyAwIHdoZW4gekluZGV4IGlzIG5vdCBzcGVjaWZpZWRcblx0XHRcdFx0XHQvLyBvdGhlciBicm93c2VycyByZXR1cm4gYSBzdHJpbmdcblx0XHRcdFx0XHQvLyB3ZSBpZ25vcmUgdGhlIGNhc2Ugb2YgbmVzdGVkIGVsZW1lbnRzIHdpdGggYW4gZXhwbGljaXQgdmFsdWUgb2YgMFxuXHRcdFx0XHRcdC8vIDxkaXYgc3R5bGU9XCJ6LWluZGV4OiAtMTA7XCI+PGRpdiBzdHlsZT1cInotaW5kZXg6IDA7XCI+PC9kaXY+PC9kaXY+XG5cdFx0XHRcdFx0dmFsdWUgPSBwYXJzZUludCggZWxlbS5jc3MoIFwiekluZGV4XCIgKSwgMTAgKTtcblx0XHRcdFx0XHRpZiAoICFpc05hTiggdmFsdWUgKSAmJiB2YWx1ZSAhPT0gMCApIHtcblx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxlbSA9IGVsZW0ucGFyZW50KCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0dW5pcXVlSWQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICF0aGlzLmlkICkge1xuXHRcdFx0XHR0aGlzLmlkID0gXCJ1aS1pZC1cIiArICgrK3V1aWQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdHJlbW92ZVVuaXF1ZUlkOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBydW5pcXVlSWQudGVzdCggdGhpcy5pZCApICkge1xuXHRcdFx0XHQkKCB0aGlzICkucmVtb3ZlQXR0ciggXCJpZFwiICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG4vLyBzZWxlY3RvcnNcbmZ1bmN0aW9uIGZvY3VzYWJsZSggZWxlbWVudCwgaXNUYWJJbmRleE5vdE5hTiApIHtcblx0dmFyIG1hcCwgbWFwTmFtZSwgaW1nLFxuXHRcdG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRpZiAoIFwiYXJlYVwiID09PSBub2RlTmFtZSApIHtcblx0XHRtYXAgPSBlbGVtZW50LnBhcmVudE5vZGU7XG5cdFx0bWFwTmFtZSA9IG1hcC5uYW1lO1xuXHRcdGlmICggIWVsZW1lbnQuaHJlZiB8fCAhbWFwTmFtZSB8fCBtYXAubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJtYXBcIiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aW1nID0gJCggXCJpbWdbdXNlbWFwPSNcIiArIG1hcE5hbWUgKyBcIl1cIiApWzBdO1xuXHRcdHJldHVybiAhIWltZyAmJiB2aXNpYmxlKCBpbWcgKTtcblx0fVxuXHRyZXR1cm4gKCAvaW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbnxvYmplY3QvLnRlc3QoIG5vZGVOYW1lICkgP1xuXHRcdCFlbGVtZW50LmRpc2FibGVkIDpcblx0XHRcImFcIiA9PT0gbm9kZU5hbWUgP1xuXHRcdFx0ZWxlbWVudC5ocmVmIHx8IGlzVGFiSW5kZXhOb3ROYU4gOlxuXHRcdFx0aXNUYWJJbmRleE5vdE5hTikgJiZcblx0XHQvLyB0aGUgZWxlbWVudCBhbmQgYWxsIG9mIGl0cyBhbmNlc3RvcnMgbXVzdCBiZSB2aXNpYmxlXG5cdFx0dmlzaWJsZSggZWxlbWVudCApO1xufVxuXG5mdW5jdGlvbiB2aXNpYmxlKCBlbGVtZW50ICkge1xuXHRyZXR1cm4gJC5leHByLmZpbHRlcnMudmlzaWJsZSggZWxlbWVudCApICYmXG5cdFx0ISQoIGVsZW1lbnQgKS5wYXJlbnRzKCkuYWRkQmFjaygpLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiAkLmNzcyggdGhpcywgXCJ2aXNpYmlsaXR5XCIgKSA9PT0gXCJoaWRkZW5cIjtcblx0XHR9KS5sZW5ndGg7XG59XG5cbiQuZXh0ZW5kKCAkLmV4cHJbIFwiOlwiIF0sIHtcblx0ZGF0YTogJC5leHByLmNyZWF0ZVBzZXVkbyA/XG5cdFx0JC5leHByLmNyZWF0ZVBzZXVkbyhmdW5jdGlvbiggZGF0YU5hbWUgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAhISQuZGF0YSggZWxlbSwgZGF0YU5hbWUgKTtcblx0XHRcdH07XG5cdFx0fSkgOlxuXHRcdC8vIHN1cHBvcnQ6IGpRdWVyeSA8MS44XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGksIG1hdGNoICkge1xuXHRcdFx0cmV0dXJuICEhJC5kYXRhKCBlbGVtLCBtYXRjaFsgMyBdICk7XG5cdFx0fSxcblxuXHRmb2N1c2FibGU6IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRcdHJldHVybiBmb2N1c2FibGUoIGVsZW1lbnQsICFpc05hTiggJC5hdHRyKCBlbGVtZW50LCBcInRhYmluZGV4XCIgKSApICk7XG5cdH0sXG5cblx0dGFiYmFibGU6IGZ1bmN0aW9uKCBlbGVtZW50ICkge1xuXHRcdHZhciB0YWJJbmRleCA9ICQuYXR0ciggZWxlbWVudCwgXCJ0YWJpbmRleFwiICksXG5cdFx0XHRpc1RhYkluZGV4TmFOID0gaXNOYU4oIHRhYkluZGV4ICk7XG5cdFx0cmV0dXJuICggaXNUYWJJbmRleE5hTiB8fCB0YWJJbmRleCA+PSAwICkgJiYgZm9jdXNhYmxlKCBlbGVtZW50LCAhaXNUYWJJbmRleE5hTiApO1xuXHR9XG59KTtcblxuLy8gc3VwcG9ydDogalF1ZXJ5IDwxLjhcbmlmICggISQoIFwiPGE+XCIgKS5vdXRlcldpZHRoKCAxICkuanF1ZXJ5ICkge1xuXHQkLmVhY2goIFsgXCJXaWR0aFwiLCBcIkhlaWdodFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHRcdHZhciBzaWRlID0gbmFtZSA9PT0gXCJXaWR0aFwiID8gWyBcIkxlZnRcIiwgXCJSaWdodFwiIF0gOiBbIFwiVG9wXCIsIFwiQm90dG9tXCIgXSxcblx0XHRcdHR5cGUgPSBuYW1lLnRvTG93ZXJDYXNlKCksXG5cdFx0XHRvcmlnID0ge1xuXHRcdFx0XHRpbm5lcldpZHRoOiAkLmZuLmlubmVyV2lkdGgsXG5cdFx0XHRcdGlubmVySGVpZ2h0OiAkLmZuLmlubmVySGVpZ2h0LFxuXHRcdFx0XHRvdXRlcldpZHRoOiAkLmZuLm91dGVyV2lkdGgsXG5cdFx0XHRcdG91dGVySGVpZ2h0OiAkLmZuLm91dGVySGVpZ2h0XG5cdFx0XHR9O1xuXG5cdFx0ZnVuY3Rpb24gcmVkdWNlKCBlbGVtLCBzaXplLCBib3JkZXIsIG1hcmdpbiApIHtcblx0XHRcdCQuZWFjaCggc2lkZSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNpemUgLT0gcGFyc2VGbG9hdCggJC5jc3MoIGVsZW0sIFwicGFkZGluZ1wiICsgdGhpcyApICkgfHwgMDtcblx0XHRcdFx0aWYgKCBib3JkZXIgKSB7XG5cdFx0XHRcdFx0c2l6ZSAtPSBwYXJzZUZsb2F0KCAkLmNzcyggZWxlbSwgXCJib3JkZXJcIiArIHRoaXMgKyBcIldpZHRoXCIgKSApIHx8IDA7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBtYXJnaW4gKSB7XG5cdFx0XHRcdFx0c2l6ZSAtPSBwYXJzZUZsb2F0KCAkLmNzcyggZWxlbSwgXCJtYXJnaW5cIiArIHRoaXMgKSApIHx8IDA7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHNpemU7XG5cdFx0fVxuXG5cdFx0JC5mblsgXCJpbm5lclwiICsgbmFtZSBdID0gZnVuY3Rpb24oIHNpemUgKSB7XG5cdFx0XHRpZiAoIHNpemUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIG9yaWdbIFwiaW5uZXJcIiArIG5hbWUgXS5jYWxsKCB0aGlzICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5jc3MoIHR5cGUsIHJlZHVjZSggdGhpcywgc2l6ZSApICsgXCJweFwiICk7XG5cdFx0XHR9KTtcblx0XHR9O1xuXG5cdFx0JC5mblsgXCJvdXRlclwiICsgbmFtZV0gPSBmdW5jdGlvbiggc2l6ZSwgbWFyZ2luICkge1xuXHRcdFx0aWYgKCB0eXBlb2Ygc2l6ZSAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0cmV0dXJuIG9yaWdbIFwib3V0ZXJcIiArIG5hbWUgXS5jYWxsKCB0aGlzLCBzaXplICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCQoIHRoaXMpLmNzcyggdHlwZSwgcmVkdWNlKCB0aGlzLCBzaXplLCB0cnVlLCBtYXJnaW4gKSArIFwicHhcIiApO1xuXHRcdFx0fSk7XG5cdFx0fTtcblx0fSk7XG59XG5cbi8vIHN1cHBvcnQ6IGpRdWVyeSA8MS44XG5pZiAoICEkLmZuLmFkZEJhY2sgKSB7XG5cdCQuZm4uYWRkQmFjayA9IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH07XG59XG5cbi8vIHN1cHBvcnQ6IGpRdWVyeSAxLjYuMSwgMS42LjIgKGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0Lzk0MTMpXG5pZiAoICQoIFwiPGE+XCIgKS5kYXRhKCBcImEtYlwiLCBcImFcIiApLnJlbW92ZURhdGEoIFwiYS1iXCIgKS5kYXRhKCBcImEtYlwiICkgKSB7XG5cdCQuZm4ucmVtb3ZlRGF0YSA9IChmdW5jdGlvbiggcmVtb3ZlRGF0YSApIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oIGtleSApIHtcblx0XHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHJlbW92ZURhdGEuY2FsbCggdGhpcywgJC5jYW1lbENhc2UoIGtleSApICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gcmVtb3ZlRGF0YS5jYWxsKCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSkoICQuZm4ucmVtb3ZlRGF0YSApO1xufVxuXG5cblxuXG5cbi8vIGRlcHJlY2F0ZWRcbiQudWkuaWUgPSAhIS9tc2llIFtcXHcuXSsvLmV4ZWMoIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKSApO1xuXG4kLnN1cHBvcnQuc2VsZWN0c3RhcnQgPSBcIm9uc2VsZWN0c3RhcnRcIiBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG4kLmZuLmV4dGVuZCh7XG5cdGRpc2FibGVTZWxlY3Rpb246IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmJpbmQoICggJC5zdXBwb3J0LnNlbGVjdHN0YXJ0ID8gXCJzZWxlY3RzdGFydFwiIDogXCJtb3VzZWRvd25cIiApICtcblx0XHRcdFwiLnVpLWRpc2FibGVTZWxlY3Rpb25cIiwgZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0fSk7XG5cdH0sXG5cblx0ZW5hYmxlU2VsZWN0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy51bmJpbmQoIFwiLnVpLWRpc2FibGVTZWxlY3Rpb25cIiApO1xuXHR9XG59KTtcblxuJC5leHRlbmQoICQudWksIHtcblx0Ly8gJC51aS5wbHVnaW4gaXMgZGVwcmVjYXRlZC4gVXNlICQud2lkZ2V0KCkgZXh0ZW5zaW9ucyBpbnN0ZWFkLlxuXHRwbHVnaW46IHtcblx0XHRhZGQ6IGZ1bmN0aW9uKCBtb2R1bGUsIG9wdGlvbiwgc2V0ICkge1xuXHRcdFx0dmFyIGksXG5cdFx0XHRcdHByb3RvID0gJC51aVsgbW9kdWxlIF0ucHJvdG90eXBlO1xuXHRcdFx0Zm9yICggaSBpbiBzZXQgKSB7XG5cdFx0XHRcdHByb3RvLnBsdWdpbnNbIGkgXSA9IHByb3RvLnBsdWdpbnNbIGkgXSB8fCBbXTtcblx0XHRcdFx0cHJvdG8ucGx1Z2luc1sgaSBdLnB1c2goIFsgb3B0aW9uLCBzZXRbIGkgXSBdICk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRjYWxsOiBmdW5jdGlvbiggaW5zdGFuY2UsIG5hbWUsIGFyZ3MgKSB7XG5cdFx0XHR2YXIgaSxcblx0XHRcdFx0c2V0ID0gaW5zdGFuY2UucGx1Z2luc1sgbmFtZSBdO1xuXHRcdFx0aWYgKCAhc2V0IHx8ICFpbnN0YW5jZS5lbGVtZW50WyAwIF0ucGFyZW50Tm9kZSB8fCBpbnN0YW5jZS5lbGVtZW50WyAwIF0ucGFyZW50Tm9kZS5ub2RlVHlwZSA9PT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggaW5zdGFuY2Uub3B0aW9uc1sgc2V0WyBpIF1bIDAgXSBdICkge1xuXHRcdFx0XHRcdHNldFsgaSBdWyAxIF0uYXBwbHkoIGluc3RhbmNlLmVsZW1lbnQsIGFyZ3MgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvLyBvbmx5IHVzZWQgYnkgcmVzaXphYmxlXG5cdGhhc1Njcm9sbDogZnVuY3Rpb24oIGVsLCBhICkge1xuXG5cdFx0Ly9JZiBvdmVyZmxvdyBpcyBoaWRkZW4sIHRoZSBlbGVtZW50IG1pZ2h0IGhhdmUgZXh0cmEgY29udGVudCwgYnV0IHRoZSB1c2VyIHdhbnRzIHRvIGhpZGUgaXRcblx0XHRpZiAoICQoIGVsICkuY3NzKCBcIm92ZXJmbG93XCIgKSA9PT0gXCJoaWRkZW5cIikge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHZhciBzY3JvbGwgPSAoIGEgJiYgYSA9PT0gXCJsZWZ0XCIgKSA/IFwic2Nyb2xsTGVmdFwiIDogXCJzY3JvbGxUb3BcIixcblx0XHRcdGhhcyA9IGZhbHNlO1xuXG5cdFx0aWYgKCBlbFsgc2Nyb2xsIF0gPiAwICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gVE9ETzogZGV0ZXJtaW5lIHdoaWNoIGNhc2VzIGFjdHVhbGx5IGNhdXNlIHRoaXMgdG8gaGFwcGVuXG5cdFx0Ly8gaWYgdGhlIGVsZW1lbnQgZG9lc24ndCBoYXZlIHRoZSBzY3JvbGwgc2V0LCBzZWUgaWYgaXQncyBwb3NzaWJsZSB0b1xuXHRcdC8vIHNldCB0aGUgc2Nyb2xsXG5cdFx0ZWxbIHNjcm9sbCBdID0gMTtcblx0XHRoYXMgPSAoIGVsWyBzY3JvbGwgXSA+IDAgKTtcblx0XHRlbFsgc2Nyb2xsIF0gPSAwO1xuXHRcdHJldHVybiBoYXM7XG5cdH1cbn0pO1xuXG59KSggalF1ZXJ5ICk7XG4iLCJ2YXIgalF1ZXJ5ID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5yZXF1aXJlKCcuL2NvcmUnKTtcblxuLyohXG4gKiBqUXVlcnkgVUkgRGF0ZXBpY2tlciAxLjEwLjRcbiAqIGh0dHA6Ly9qcXVlcnl1aS5jb21cbiAqXG4gKiBDb3B5cmlnaHQgMjAxNCBqUXVlcnkgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogaHR0cDovL2FwaS5qcXVlcnl1aS5jb20vZGF0ZXBpY2tlci9cbiAqXG4gKiBEZXBlbmRzOlxuICpcdGpxdWVyeS51aS5jb3JlLmpzXG4gKi9cbihmdW5jdGlvbiggJCwgdW5kZWZpbmVkICkge1xuXG4kLmV4dGVuZCgkLnVpLCB7IGRhdGVwaWNrZXI6IHsgdmVyc2lvbjogXCIxLjEwLjRcIiB9IH0pO1xuXG52YXIgUFJPUF9OQU1FID0gXCJkYXRlcGlja2VyXCIsXG5cdGluc3RBY3RpdmU7XG5cbi8qIERhdGUgcGlja2VyIG1hbmFnZXIuXG4gICBVc2UgdGhlIHNpbmdsZXRvbiBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzLCAkLmRhdGVwaWNrZXIsIHRvIGludGVyYWN0IHdpdGggdGhlIGRhdGUgcGlja2VyLlxuICAgU2V0dGluZ3MgZm9yIChncm91cHMgb2YpIGRhdGUgcGlja2VycyBhcmUgbWFpbnRhaW5lZCBpbiBhbiBpbnN0YW5jZSBvYmplY3QsXG4gICBhbGxvd2luZyBtdWx0aXBsZSBkaWZmZXJlbnQgc2V0dGluZ3Mgb24gdGhlIHNhbWUgcGFnZS4gKi9cblxuZnVuY3Rpb24gRGF0ZXBpY2tlcigpIHtcblx0dGhpcy5fY3VySW5zdCA9IG51bGw7IC8vIFRoZSBjdXJyZW50IGluc3RhbmNlIGluIHVzZVxuXHR0aGlzLl9rZXlFdmVudCA9IGZhbHNlOyAvLyBJZiB0aGUgbGFzdCBldmVudCB3YXMgYSBrZXkgZXZlbnRcblx0dGhpcy5fZGlzYWJsZWRJbnB1dHMgPSBbXTsgLy8gTGlzdCBvZiBkYXRlIHBpY2tlciBpbnB1dHMgdGhhdCBoYXZlIGJlZW4gZGlzYWJsZWRcblx0dGhpcy5fZGF0ZXBpY2tlclNob3dpbmcgPSBmYWxzZTsgLy8gVHJ1ZSBpZiB0aGUgcG9wdXAgcGlja2VyIGlzIHNob3dpbmcgLCBmYWxzZSBpZiBub3Rcblx0dGhpcy5faW5EaWFsb2cgPSBmYWxzZTsgLy8gVHJ1ZSBpZiBzaG93aW5nIHdpdGhpbiBhIFwiZGlhbG9nXCIsIGZhbHNlIGlmIG5vdFxuXHR0aGlzLl9tYWluRGl2SWQgPSBcInVpLWRhdGVwaWNrZXItZGl2XCI7IC8vIFRoZSBJRCBvZiB0aGUgbWFpbiBkYXRlcGlja2VyIGRpdmlzaW9uXG5cdHRoaXMuX2lubGluZUNsYXNzID0gXCJ1aS1kYXRlcGlja2VyLWlubGluZVwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgaW5saW5lIG1hcmtlciBjbGFzc1xuXHR0aGlzLl9hcHBlbmRDbGFzcyA9IFwidWktZGF0ZXBpY2tlci1hcHBlbmRcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIGFwcGVuZCBtYXJrZXIgY2xhc3Ncblx0dGhpcy5fdHJpZ2dlckNsYXNzID0gXCJ1aS1kYXRlcGlja2VyLXRyaWdnZXJcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2RpYWxvZ0NsYXNzID0gXCJ1aS1kYXRlcGlja2VyLWRpYWxvZ1wiOyAvLyBUaGUgbmFtZSBvZiB0aGUgZGlhbG9nIG1hcmtlciBjbGFzc1xuXHR0aGlzLl9kaXNhYmxlQ2xhc3MgPSBcInVpLWRhdGVwaWNrZXItZGlzYWJsZWRcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIGRpc2FibGVkIGNvdmVyaW5nIG1hcmtlciBjbGFzc1xuXHR0aGlzLl91bnNlbGVjdGFibGVDbGFzcyA9IFwidWktZGF0ZXBpY2tlci11bnNlbGVjdGFibGVcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIHVuc2VsZWN0YWJsZSBjZWxsIG1hcmtlciBjbGFzc1xuXHR0aGlzLl9jdXJyZW50Q2xhc3MgPSBcInVpLWRhdGVwaWNrZXItY3VycmVudC1kYXlcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIGN1cnJlbnQgZGF5IG1hcmtlciBjbGFzc1xuXHR0aGlzLl9kYXlPdmVyQ2xhc3MgPSBcInVpLWRhdGVwaWNrZXItZGF5cy1jZWxsLW92ZXJcIjsgLy8gVGhlIG5hbWUgb2YgdGhlIGRheSBob3ZlciBtYXJrZXIgY2xhc3Ncblx0dGhpcy5yZWdpb25hbCA9IFtdOyAvLyBBdmFpbGFibGUgcmVnaW9uYWwgc2V0dGluZ3MsIGluZGV4ZWQgYnkgbGFuZ3VhZ2UgY29kZVxuXHR0aGlzLnJlZ2lvbmFsW1wiXCJdID0geyAvLyBEZWZhdWx0IHJlZ2lvbmFsIHNldHRpbmdzXG5cdFx0Y2xvc2VUZXh0OiBcIkRvbmVcIiwgLy8gRGlzcGxheSB0ZXh0IGZvciBjbG9zZSBsaW5rXG5cdFx0cHJldlRleHQ6IFwiUHJldlwiLCAvLyBEaXNwbGF5IHRleHQgZm9yIHByZXZpb3VzIG1vbnRoIGxpbmtcblx0XHRuZXh0VGV4dDogXCJOZXh0XCIsIC8vIERpc3BsYXkgdGV4dCBmb3IgbmV4dCBtb250aCBsaW5rXG5cdFx0Y3VycmVudFRleHQ6IFwiVG9kYXlcIiwgLy8gRGlzcGxheSB0ZXh0IGZvciBjdXJyZW50IG1vbnRoIGxpbmtcblx0XHRtb250aE5hbWVzOiBbXCJKYW51YXJ5XCIsXCJGZWJydWFyeVwiLFwiTWFyY2hcIixcIkFwcmlsXCIsXCJNYXlcIixcIkp1bmVcIixcblx0XHRcdFwiSnVseVwiLFwiQXVndXN0XCIsXCJTZXB0ZW1iZXJcIixcIk9jdG9iZXJcIixcIk5vdmVtYmVyXCIsXCJEZWNlbWJlclwiXSwgLy8gTmFtZXMgb2YgbW9udGhzIGZvciBkcm9wLWRvd24gYW5kIGZvcm1hdHRpbmdcblx0XHRtb250aE5hbWVzU2hvcnQ6IFtcIkphblwiLCBcIkZlYlwiLCBcIk1hclwiLCBcIkFwclwiLCBcIk1heVwiLCBcIkp1blwiLCBcIkp1bFwiLCBcIkF1Z1wiLCBcIlNlcFwiLCBcIk9jdFwiLCBcIk5vdlwiLCBcIkRlY1wiXSwgLy8gRm9yIGZvcm1hdHRpbmdcblx0XHRkYXlOYW1lczogW1wiU3VuZGF5XCIsIFwiTW9uZGF5XCIsIFwiVHVlc2RheVwiLCBcIldlZG5lc2RheVwiLCBcIlRodXJzZGF5XCIsIFwiRnJpZGF5XCIsIFwiU2F0dXJkYXlcIl0sIC8vIEZvciBmb3JtYXR0aW5nXG5cdFx0ZGF5TmFtZXNTaG9ydDogW1wiU3VuXCIsIFwiTW9uXCIsIFwiVHVlXCIsIFwiV2VkXCIsIFwiVGh1XCIsIFwiRnJpXCIsIFwiU2F0XCJdLCAvLyBGb3IgZm9ybWF0dGluZ1xuXHRcdGRheU5hbWVzTWluOiBbXCJTdVwiLFwiTW9cIixcIlR1XCIsXCJXZVwiLFwiVGhcIixcIkZyXCIsXCJTYVwiXSwgLy8gQ29sdW1uIGhlYWRpbmdzIGZvciBkYXlzIHN0YXJ0aW5nIGF0IFN1bmRheVxuXHRcdHdlZWtIZWFkZXI6IFwiV2tcIiwgLy8gQ29sdW1uIGhlYWRlciBmb3Igd2VlayBvZiB0aGUgeWVhclxuXHRcdGRhdGVGb3JtYXQ6IFwibW0vZGQveXlcIiwgLy8gU2VlIGZvcm1hdCBvcHRpb25zIG9uIHBhcnNlRGF0ZVxuXHRcdGZpcnN0RGF5OiAwLCAvLyBUaGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLCBTdW4gPSAwLCBNb24gPSAxLCAuLi5cblx0XHRpc1JUTDogZmFsc2UsIC8vIFRydWUgaWYgcmlnaHQtdG8tbGVmdCBsYW5ndWFnZSwgZmFsc2UgaWYgbGVmdC10by1yaWdodFxuXHRcdHNob3dNb250aEFmdGVyWWVhcjogZmFsc2UsIC8vIFRydWUgaWYgdGhlIHllYXIgc2VsZWN0IHByZWNlZGVzIG1vbnRoLCBmYWxzZSBmb3IgbW9udGggdGhlbiB5ZWFyXG5cdFx0eWVhclN1ZmZpeDogXCJcIiAvLyBBZGRpdGlvbmFsIHRleHQgdG8gYXBwZW5kIHRvIHRoZSB5ZWFyIGluIHRoZSBtb250aCBoZWFkZXJzXG5cdH07XG5cdHRoaXMuX2RlZmF1bHRzID0geyAvLyBHbG9iYWwgZGVmYXVsdHMgZm9yIGFsbCB0aGUgZGF0ZSBwaWNrZXIgaW5zdGFuY2VzXG5cdFx0c2hvd09uOiBcImZvY3VzXCIsIC8vIFwiZm9jdXNcIiBmb3IgcG9wdXAgb24gZm9jdXMsXG5cdFx0XHQvLyBcImJ1dHRvblwiIGZvciB0cmlnZ2VyIGJ1dHRvbiwgb3IgXCJib3RoXCIgZm9yIGVpdGhlclxuXHRcdHNob3dBbmltOiBcImZhZGVJblwiLCAvLyBOYW1lIG9mIGpRdWVyeSBhbmltYXRpb24gZm9yIHBvcHVwXG5cdFx0c2hvd09wdGlvbnM6IHt9LCAvLyBPcHRpb25zIGZvciBlbmhhbmNlZCBhbmltYXRpb25zXG5cdFx0ZGVmYXVsdERhdGU6IG51bGwsIC8vIFVzZWQgd2hlbiBmaWVsZCBpcyBibGFuazogYWN0dWFsIGRhdGUsXG5cdFx0XHQvLyArLy1udW1iZXIgZm9yIG9mZnNldCBmcm9tIHRvZGF5LCBudWxsIGZvciB0b2RheVxuXHRcdGFwcGVuZFRleHQ6IFwiXCIsIC8vIERpc3BsYXkgdGV4dCBmb2xsb3dpbmcgdGhlIGlucHV0IGJveCwgZS5nLiBzaG93aW5nIHRoZSBmb3JtYXRcblx0XHRidXR0b25UZXh0OiBcIi4uLlwiLCAvLyBUZXh0IGZvciB0cmlnZ2VyIGJ1dHRvblxuXHRcdGJ1dHRvbkltYWdlOiBcIlwiLCAvLyBVUkwgZm9yIHRyaWdnZXIgYnV0dG9uIGltYWdlXG5cdFx0YnV0dG9uSW1hZ2VPbmx5OiBmYWxzZSwgLy8gVHJ1ZSBpZiB0aGUgaW1hZ2UgYXBwZWFycyBhbG9uZSwgZmFsc2UgaWYgaXQgYXBwZWFycyBvbiBhIGJ1dHRvblxuXHRcdGhpZGVJZk5vUHJldk5leHQ6IGZhbHNlLCAvLyBUcnVlIHRvIGhpZGUgbmV4dC9wcmV2aW91cyBtb250aCBsaW5rc1xuXHRcdFx0Ly8gaWYgbm90IGFwcGxpY2FibGUsIGZhbHNlIHRvIGp1c3QgZGlzYWJsZSB0aGVtXG5cdFx0bmF2aWdhdGlvbkFzRGF0ZUZvcm1hdDogZmFsc2UsIC8vIFRydWUgaWYgZGF0ZSBmb3JtYXR0aW5nIGFwcGxpZWQgdG8gcHJldi90b2RheS9uZXh0IGxpbmtzXG5cdFx0Z290b0N1cnJlbnQ6IGZhbHNlLCAvLyBUcnVlIGlmIHRvZGF5IGxpbmsgZ29lcyBiYWNrIHRvIGN1cnJlbnQgc2VsZWN0aW9uIGluc3RlYWRcblx0XHRjaGFuZ2VNb250aDogZmFsc2UsIC8vIFRydWUgaWYgbW9udGggY2FuIGJlIHNlbGVjdGVkIGRpcmVjdGx5LCBmYWxzZSBpZiBvbmx5IHByZXYvbmV4dFxuXHRcdGNoYW5nZVllYXI6IGZhbHNlLCAvLyBUcnVlIGlmIHllYXIgY2FuIGJlIHNlbGVjdGVkIGRpcmVjdGx5LCBmYWxzZSBpZiBvbmx5IHByZXYvbmV4dFxuXHRcdHllYXJSYW5nZTogXCJjLTEwOmMrMTBcIiwgLy8gUmFuZ2Ugb2YgeWVhcnMgdG8gZGlzcGxheSBpbiBkcm9wLWRvd24sXG5cdFx0XHQvLyBlaXRoZXIgcmVsYXRpdmUgdG8gdG9kYXkncyB5ZWFyICgtbm46K25uKSwgcmVsYXRpdmUgdG8gY3VycmVudGx5IGRpc3BsYXllZCB5ZWFyXG5cdFx0XHQvLyAoYy1ubjpjK25uKSwgYWJzb2x1dGUgKG5ubm46bm5ubiksIG9yIGEgY29tYmluYXRpb24gb2YgdGhlIGFib3ZlIChubm5uOi1uKVxuXHRcdHNob3dPdGhlck1vbnRoczogZmFsc2UsIC8vIFRydWUgdG8gc2hvdyBkYXRlcyBpbiBvdGhlciBtb250aHMsIGZhbHNlIHRvIGxlYXZlIGJsYW5rXG5cdFx0c2VsZWN0T3RoZXJNb250aHM6IGZhbHNlLCAvLyBUcnVlIHRvIGFsbG93IHNlbGVjdGlvbiBvZiBkYXRlcyBpbiBvdGhlciBtb250aHMsIGZhbHNlIGZvciB1bnNlbGVjdGFibGVcblx0XHRzaG93V2VlazogZmFsc2UsIC8vIFRydWUgdG8gc2hvdyB3ZWVrIG9mIHRoZSB5ZWFyLCBmYWxzZSB0byBub3Qgc2hvdyBpdFxuXHRcdGNhbGN1bGF0ZVdlZWs6IHRoaXMuaXNvODYwMVdlZWssIC8vIEhvdyB0byBjYWxjdWxhdGUgdGhlIHdlZWsgb2YgdGhlIHllYXIsXG5cdFx0XHQvLyB0YWtlcyBhIERhdGUgYW5kIHJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgd2VlayBmb3IgaXRcblx0XHRzaG9ydFllYXJDdXRvZmY6IFwiKzEwXCIsIC8vIFNob3J0IHllYXIgdmFsdWVzIDwgdGhpcyBhcmUgaW4gdGhlIGN1cnJlbnQgY2VudHVyeSxcblx0XHRcdC8vID4gdGhpcyBhcmUgaW4gdGhlIHByZXZpb3VzIGNlbnR1cnksXG5cdFx0XHQvLyBzdHJpbmcgdmFsdWUgc3RhcnRpbmcgd2l0aCBcIitcIiBmb3IgY3VycmVudCB5ZWFyICsgdmFsdWVcblx0XHRtaW5EYXRlOiBudWxsLCAvLyBUaGUgZWFybGllc3Qgc2VsZWN0YWJsZSBkYXRlLCBvciBudWxsIGZvciBubyBsaW1pdFxuXHRcdG1heERhdGU6IG51bGwsIC8vIFRoZSBsYXRlc3Qgc2VsZWN0YWJsZSBkYXRlLCBvciBudWxsIGZvciBubyBsaW1pdFxuXHRcdGR1cmF0aW9uOiBcImZhc3RcIiwgLy8gRHVyYXRpb24gb2YgZGlzcGxheS9jbG9zdXJlXG5cdFx0YmVmb3JlU2hvd0RheTogbnVsbCwgLy8gRnVuY3Rpb24gdGhhdCB0YWtlcyBhIGRhdGUgYW5kIHJldHVybnMgYW4gYXJyYXkgd2l0aFxuXHRcdFx0Ly8gWzBdID0gdHJ1ZSBpZiBzZWxlY3RhYmxlLCBmYWxzZSBpZiBub3QsIFsxXSA9IGN1c3RvbSBDU1MgY2xhc3MgbmFtZShzKSBvciBcIlwiLFxuXHRcdFx0Ly8gWzJdID0gY2VsbCB0aXRsZSAob3B0aW9uYWwpLCBlLmcuICQuZGF0ZXBpY2tlci5ub1dlZWtlbmRzXG5cdFx0YmVmb3JlU2hvdzogbnVsbCwgLy8gRnVuY3Rpb24gdGhhdCB0YWtlcyBhbiBpbnB1dCBmaWVsZCBhbmRcblx0XHRcdC8vIHJldHVybnMgYSBzZXQgb2YgY3VzdG9tIHNldHRpbmdzIGZvciB0aGUgZGF0ZSBwaWNrZXJcblx0XHRvblNlbGVjdDogbnVsbCwgLy8gRGVmaW5lIGEgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiBhIGRhdGUgaXMgc2VsZWN0ZWRcblx0XHRvbkNoYW5nZU1vbnRoWWVhcjogbnVsbCwgLy8gRGVmaW5lIGEgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiB0aGUgbW9udGggb3IgeWVhciBpcyBjaGFuZ2VkXG5cdFx0b25DbG9zZTogbnVsbCwgLy8gRGVmaW5lIGEgY2FsbGJhY2sgZnVuY3Rpb24gd2hlbiB0aGUgZGF0ZXBpY2tlciBpcyBjbG9zZWRcblx0XHRudW1iZXJPZk1vbnRoczogMSwgLy8gTnVtYmVyIG9mIG1vbnRocyB0byBzaG93IGF0IGEgdGltZVxuXHRcdHNob3dDdXJyZW50QXRQb3M6IDAsIC8vIFRoZSBwb3NpdGlvbiBpbiBtdWx0aXBlIG1vbnRocyBhdCB3aGljaCB0byBzaG93IHRoZSBjdXJyZW50IG1vbnRoIChzdGFydGluZyBhdCAwKVxuXHRcdHN0ZXBNb250aHM6IDEsIC8vIE51bWJlciBvZiBtb250aHMgdG8gc3RlcCBiYWNrL2ZvcndhcmRcblx0XHRzdGVwQmlnTW9udGhzOiAxMiwgLy8gTnVtYmVyIG9mIG1vbnRocyB0byBzdGVwIGJhY2svZm9yd2FyZCBmb3IgdGhlIGJpZyBsaW5rc1xuXHRcdGFsdEZpZWxkOiBcIlwiLCAvLyBTZWxlY3RvciBmb3IgYW4gYWx0ZXJuYXRlIGZpZWxkIHRvIHN0b3JlIHNlbGVjdGVkIGRhdGVzIGludG9cblx0XHRhbHRGb3JtYXQ6IFwiXCIsIC8vIFRoZSBkYXRlIGZvcm1hdCB0byB1c2UgZm9yIHRoZSBhbHRlcm5hdGUgZmllbGRcblx0XHRjb25zdHJhaW5JbnB1dDogdHJ1ZSwgLy8gVGhlIGlucHV0IGlzIGNvbnN0cmFpbmVkIGJ5IHRoZSBjdXJyZW50IGRhdGUgZm9ybWF0XG5cdFx0c2hvd0J1dHRvblBhbmVsOiBmYWxzZSwgLy8gVHJ1ZSB0byBzaG93IGJ1dHRvbiBwYW5lbCwgZmFsc2UgdG8gbm90IHNob3cgaXRcblx0XHRhdXRvU2l6ZTogZmFsc2UsIC8vIFRydWUgdG8gc2l6ZSB0aGUgaW5wdXQgZm9yIHRoZSBkYXRlIGZvcm1hdCwgZmFsc2UgdG8gbGVhdmUgYXMgaXNcblx0XHRkaXNhYmxlZDogZmFsc2UgLy8gVGhlIGluaXRpYWwgZGlzYWJsZWQgc3RhdGVcblx0fTtcblx0JC5leHRlbmQodGhpcy5fZGVmYXVsdHMsIHRoaXMucmVnaW9uYWxbXCJcIl0pO1xuXHR0aGlzLmRwRGl2ID0gYmluZEhvdmVyKCQoXCI8ZGl2IGlkPSdcIiArIHRoaXMuX21haW5EaXZJZCArIFwiJyBjbGFzcz0ndWktZGF0ZXBpY2tlciB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktaGVscGVyLWNsZWFyZml4IHVpLWNvcm5lci1hbGwnPjwvZGl2PlwiKSk7XG59XG5cbiQuZXh0ZW5kKERhdGVwaWNrZXIucHJvdG90eXBlLCB7XG5cdC8qIENsYXNzIG5hbWUgYWRkZWQgdG8gZWxlbWVudHMgdG8gaW5kaWNhdGUgYWxyZWFkeSBjb25maWd1cmVkIHdpdGggYSBkYXRlIHBpY2tlci4gKi9cblx0bWFya2VyQ2xhc3NOYW1lOiBcImhhc0RhdGVwaWNrZXJcIixcblxuXHQvL0tlZXAgdHJhY2sgb2YgdGhlIG1heGltdW0gbnVtYmVyIG9mIHJvd3MgZGlzcGxheWVkIChzZWUgIzcwNDMpXG5cdG1heFJvd3M6IDQsXG5cblx0Ly8gVE9ETyByZW5hbWUgdG8gXCJ3aWRnZXRcIiB3aGVuIHN3aXRjaGluZyB0byB3aWRnZXQgZmFjdG9yeVxuXHRfd2lkZ2V0RGF0ZXBpY2tlcjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZHBEaXY7XG5cdH0sXG5cblx0LyogT3ZlcnJpZGUgdGhlIGRlZmF1bHQgc2V0dGluZ3MgZm9yIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGRhdGUgcGlja2VyLlxuXHQgKiBAcGFyYW0gIHNldHRpbmdzICBvYmplY3QgLSB0aGUgbmV3IHNldHRpbmdzIHRvIHVzZSBhcyBkZWZhdWx0cyAoYW5vbnltb3VzIG9iamVjdClcblx0ICogQHJldHVybiB0aGUgbWFuYWdlciBvYmplY3Rcblx0ICovXG5cdHNldERlZmF1bHRzOiBmdW5jdGlvbihzZXR0aW5ncykge1xuXHRcdGV4dGVuZFJlbW92ZSh0aGlzLl9kZWZhdWx0cywgc2V0dGluZ3MgfHwge30pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdC8qIEF0dGFjaCB0aGUgZGF0ZSBwaWNrZXIgdG8gYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldFx0ZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKiBAcGFyYW0gIHNldHRpbmdzICBvYmplY3QgLSB0aGUgbmV3IHNldHRpbmdzIHRvIHVzZSBmb3IgdGhpcyBkYXRlIHBpY2tlciBpbnN0YW5jZSAoYW5vbnltb3VzKVxuXHQgKi9cblx0X2F0dGFjaERhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgc2V0dGluZ3MpIHtcblx0XHR2YXIgbm9kZU5hbWUsIGlubGluZSwgaW5zdDtcblx0XHRub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlubGluZSA9IChub2RlTmFtZSA9PT0gXCJkaXZcIiB8fCBub2RlTmFtZSA9PT0gXCJzcGFuXCIpO1xuXHRcdGlmICghdGFyZ2V0LmlkKSB7XG5cdFx0XHR0aGlzLnV1aWQgKz0gMTtcblx0XHRcdHRhcmdldC5pZCA9IFwiZHBcIiArIHRoaXMudXVpZDtcblx0XHR9XG5cdFx0aW5zdCA9IHRoaXMuX25ld0luc3QoJCh0YXJnZXQpLCBpbmxpbmUpO1xuXHRcdGluc3Quc2V0dGluZ3MgPSAkLmV4dGVuZCh7fSwgc2V0dGluZ3MgfHwge30pO1xuXHRcdGlmIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiKSB7XG5cdFx0XHR0aGlzLl9jb25uZWN0RGF0ZXBpY2tlcih0YXJnZXQsIGluc3QpO1xuXHRcdH0gZWxzZSBpZiAoaW5saW5lKSB7XG5cdFx0XHR0aGlzLl9pbmxpbmVEYXRlcGlja2VyKHRhcmdldCwgaW5zdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvYmplY3QuICovXG5cdF9uZXdJbnN0OiBmdW5jdGlvbih0YXJnZXQsIGlubGluZSkge1xuXHRcdHZhciBpZCA9IHRhcmdldFswXS5pZC5yZXBsYWNlKC8oW15BLVphLXowLTlfXFwtXSkvZywgXCJcXFxcXFxcXCQxXCIpOyAvLyBlc2NhcGUgalF1ZXJ5IG1ldGEgY2hhcnNcblx0XHRyZXR1cm4ge2lkOiBpZCwgaW5wdXQ6IHRhcmdldCwgLy8gYXNzb2NpYXRlZCB0YXJnZXRcblx0XHRcdHNlbGVjdGVkRGF5OiAwLCBzZWxlY3RlZE1vbnRoOiAwLCBzZWxlY3RlZFllYXI6IDAsIC8vIGN1cnJlbnQgc2VsZWN0aW9uXG5cdFx0XHRkcmF3TW9udGg6IDAsIGRyYXdZZWFyOiAwLCAvLyBtb250aCBiZWluZyBkcmF3blxuXHRcdFx0aW5saW5lOiBpbmxpbmUsIC8vIGlzIGRhdGVwaWNrZXIgaW5saW5lIG9yIG5vdFxuXHRcdFx0ZHBEaXY6ICghaW5saW5lID8gdGhpcy5kcERpdiA6IC8vIHByZXNlbnRhdGlvbiBkaXZcblx0XHRcdGJpbmRIb3ZlcigkKFwiPGRpdiBjbGFzcz0nXCIgKyB0aGlzLl9pbmxpbmVDbGFzcyArIFwiIHVpLWRhdGVwaWNrZXIgdWktd2lkZ2V0IHVpLXdpZGdldC1jb250ZW50IHVpLWhlbHBlci1jbGVhcmZpeCB1aS1jb3JuZXItYWxsJz48L2Rpdj5cIikpKX07XG5cdH0sXG5cblx0LyogQXR0YWNoIHRoZSBkYXRlIHBpY2tlciB0byBhbiBpbnB1dCBmaWVsZC4gKi9cblx0X2Nvbm5lY3REYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQsIGluc3QpIHtcblx0XHR2YXIgaW5wdXQgPSAkKHRhcmdldCk7XG5cdFx0aW5zdC5hcHBlbmQgPSAkKFtdKTtcblx0XHRpbnN0LnRyaWdnZXIgPSAkKFtdKTtcblx0XHRpZiAoaW5wdXQuaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuX2F0dGFjaG1lbnRzKGlucHV0LCBpbnN0KTtcblx0XHRpbnB1dC5hZGRDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkua2V5ZG93bih0aGlzLl9kb0tleURvd24pLlxuXHRcdFx0a2V5cHJlc3ModGhpcy5fZG9LZXlQcmVzcykua2V5dXAodGhpcy5fZG9LZXlVcCk7XG5cdFx0dGhpcy5fYXV0b1NpemUoaW5zdCk7XG5cdFx0JC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FLCBpbnN0KTtcblx0XHQvL0lmIGRpc2FibGVkIG9wdGlvbiBpcyB0cnVlLCBkaXNhYmxlIHRoZSBkYXRlcGlja2VyIG9uY2UgaXQgaGFzIGJlZW4gYXR0YWNoZWQgdG8gdGhlIGlucHV0IChzZWUgdGlja2V0ICM1NjY1KVxuXHRcdGlmKCBpbnN0LnNldHRpbmdzLmRpc2FibGVkICkge1xuXHRcdFx0dGhpcy5fZGlzYWJsZURhdGVwaWNrZXIoIHRhcmdldCApO1xuXHRcdH1cblx0fSxcblxuXHQvKiBNYWtlIGF0dGFjaG1lbnRzIGJhc2VkIG9uIHNldHRpbmdzLiAqL1xuXHRfYXR0YWNobWVudHM6IGZ1bmN0aW9uKGlucHV0LCBpbnN0KSB7XG5cdFx0dmFyIHNob3dPbiwgYnV0dG9uVGV4dCwgYnV0dG9uSW1hZ2UsXG5cdFx0XHRhcHBlbmRUZXh0ID0gdGhpcy5fZ2V0KGluc3QsIFwiYXBwZW5kVGV4dFwiKSxcblx0XHRcdGlzUlRMID0gdGhpcy5fZ2V0KGluc3QsIFwiaXNSVExcIik7XG5cblx0XHRpZiAoaW5zdC5hcHBlbmQpIHtcblx0XHRcdGluc3QuYXBwZW5kLnJlbW92ZSgpO1xuXHRcdH1cblx0XHRpZiAoYXBwZW5kVGV4dCkge1xuXHRcdFx0aW5zdC5hcHBlbmQgPSAkKFwiPHNwYW4gY2xhc3M9J1wiICsgdGhpcy5fYXBwZW5kQ2xhc3MgKyBcIic+XCIgKyBhcHBlbmRUZXh0ICsgXCI8L3NwYW4+XCIpO1xuXHRcdFx0aW5wdXRbaXNSVEwgPyBcImJlZm9yZVwiIDogXCJhZnRlclwiXShpbnN0LmFwcGVuZCk7XG5cdFx0fVxuXG5cdFx0aW5wdXQudW5iaW5kKFwiZm9jdXNcIiwgdGhpcy5fc2hvd0RhdGVwaWNrZXIpO1xuXG5cdFx0aWYgKGluc3QudHJpZ2dlcikge1xuXHRcdFx0aW5zdC50cmlnZ2VyLnJlbW92ZSgpO1xuXHRcdH1cblxuXHRcdHNob3dPbiA9IHRoaXMuX2dldChpbnN0LCBcInNob3dPblwiKTtcblx0XHRpZiAoc2hvd09uID09PSBcImZvY3VzXCIgfHwgc2hvd09uID09PSBcImJvdGhcIikgeyAvLyBwb3AtdXAgZGF0ZSBwaWNrZXIgd2hlbiBpbiB0aGUgbWFya2VkIGZpZWxkXG5cdFx0XHRpbnB1dC5mb2N1cyh0aGlzLl9zaG93RGF0ZXBpY2tlcik7XG5cdFx0fVxuXHRcdGlmIChzaG93T24gPT09IFwiYnV0dG9uXCIgfHwgc2hvd09uID09PSBcImJvdGhcIikgeyAvLyBwb3AtdXAgZGF0ZSBwaWNrZXIgd2hlbiBidXR0b24gY2xpY2tlZFxuXHRcdFx0YnV0dG9uVGV4dCA9IHRoaXMuX2dldChpbnN0LCBcImJ1dHRvblRleHRcIik7XG5cdFx0XHRidXR0b25JbWFnZSA9IHRoaXMuX2dldChpbnN0LCBcImJ1dHRvbkltYWdlXCIpO1xuXHRcdFx0aW5zdC50cmlnZ2VyID0gJCh0aGlzLl9nZXQoaW5zdCwgXCJidXR0b25JbWFnZU9ubHlcIikgP1xuXHRcdFx0XHQkKFwiPGltZy8+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuXG5cdFx0XHRcdFx0YXR0cih7IHNyYzogYnV0dG9uSW1hZ2UsIGFsdDogYnV0dG9uVGV4dCwgdGl0bGU6IGJ1dHRvblRleHQgfSkgOlxuXHRcdFx0XHQkKFwiPGJ1dHRvbiB0eXBlPSdidXR0b24nPjwvYnV0dG9uPlwiKS5hZGRDbGFzcyh0aGlzLl90cmlnZ2VyQ2xhc3MpLlxuXHRcdFx0XHRcdGh0bWwoIWJ1dHRvbkltYWdlID8gYnV0dG9uVGV4dCA6ICQoXCI8aW1nLz5cIikuYXR0cihcblx0XHRcdFx0XHR7IHNyYzpidXR0b25JbWFnZSwgYWx0OmJ1dHRvblRleHQsIHRpdGxlOmJ1dHRvblRleHQgfSkpKTtcblx0XHRcdGlucHV0W2lzUlRMID8gXCJiZWZvcmVcIiA6IFwiYWZ0ZXJcIl0oaW5zdC50cmlnZ2VyKTtcblx0XHRcdGluc3QudHJpZ2dlci5jbGljayhmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgJiYgJC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgPT09IGlucHV0WzBdKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKCQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgJiYgJC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgIT09IGlucHV0WzBdKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIoaW5wdXRbMF0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2hvd0RhdGVwaWNrZXIoaW5wdXRbMF0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKiBBcHBseSB0aGUgbWF4aW11bSBsZW5ndGggZm9yIHRoZSBkYXRlIGZvcm1hdC4gKi9cblx0X2F1dG9TaXplOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0aWYgKHRoaXMuX2dldChpbnN0LCBcImF1dG9TaXplXCIpICYmICFpbnN0LmlubGluZSkge1xuXHRcdFx0dmFyIGZpbmRNYXgsIG1heCwgbWF4SSwgaSxcblx0XHRcdFx0ZGF0ZSA9IG5ldyBEYXRlKDIwMDksIDEyIC0gMSwgMjApLCAvLyBFbnN1cmUgZG91YmxlIGRpZ2l0c1xuXHRcdFx0XHRkYXRlRm9ybWF0ID0gdGhpcy5fZ2V0KGluc3QsIFwiZGF0ZUZvcm1hdFwiKTtcblxuXHRcdFx0aWYgKGRhdGVGb3JtYXQubWF0Y2goL1tETV0vKSkge1xuXHRcdFx0XHRmaW5kTWF4ID0gZnVuY3Rpb24obmFtZXMpIHtcblx0XHRcdFx0XHRtYXggPSAwO1xuXHRcdFx0XHRcdG1heEkgPSAwO1xuXHRcdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBuYW1lcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0aWYgKG5hbWVzW2ldLmxlbmd0aCA+IG1heCkge1xuXHRcdFx0XHRcdFx0XHRtYXggPSBuYW1lc1tpXS5sZW5ndGg7XG5cdFx0XHRcdFx0XHRcdG1heEkgPSBpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gbWF4STtcblx0XHRcdFx0fTtcblx0XHRcdFx0ZGF0ZS5zZXRNb250aChmaW5kTWF4KHRoaXMuX2dldChpbnN0LCAoZGF0ZUZvcm1hdC5tYXRjaCgvTU0vKSA/XG5cdFx0XHRcdFx0XCJtb250aE5hbWVzXCIgOiBcIm1vbnRoTmFtZXNTaG9ydFwiKSkpKTtcblx0XHRcdFx0ZGF0ZS5zZXREYXRlKGZpbmRNYXgodGhpcy5fZ2V0KGluc3QsIChkYXRlRm9ybWF0Lm1hdGNoKC9ERC8pID9cblx0XHRcdFx0XHRcImRheU5hbWVzXCIgOiBcImRheU5hbWVzU2hvcnRcIikpKSArIDIwIC0gZGF0ZS5nZXREYXkoKSk7XG5cdFx0XHR9XG5cdFx0XHRpbnN0LmlucHV0LmF0dHIoXCJzaXplXCIsIHRoaXMuX2Zvcm1hdERhdGUoaW5zdCwgZGF0ZSkubGVuZ3RoKTtcblx0XHR9XG5cdH0sXG5cblx0LyogQXR0YWNoIGFuIGlubGluZSBkYXRlIHBpY2tlciB0byBhIGRpdi4gKi9cblx0X2lubGluZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgaW5zdCkge1xuXHRcdHZhciBkaXZTcGFuID0gJCh0YXJnZXQpO1xuXHRcdGlmIChkaXZTcGFuLmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRkaXZTcGFuLmFkZENsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5hcHBlbmQoaW5zdC5kcERpdik7XG5cdFx0JC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FLCBpbnN0KTtcblx0XHR0aGlzLl9zZXREYXRlKGluc3QsIHRoaXMuX2dldERlZmF1bHREYXRlKGluc3QpLCB0cnVlKTtcblx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblx0XHQvL0lmIGRpc2FibGVkIG9wdGlvbiBpcyB0cnVlLCBkaXNhYmxlIHRoZSBkYXRlcGlja2VyIGJlZm9yZSBzaG93aW5nIGl0IChzZWUgdGlja2V0ICM1NjY1KVxuXHRcdGlmKCBpbnN0LnNldHRpbmdzLmRpc2FibGVkICkge1xuXHRcdFx0dGhpcy5fZGlzYWJsZURhdGVwaWNrZXIoIHRhcmdldCApO1xuXHRcdH1cblx0XHQvLyBTZXQgZGlzcGxheTpibG9jayBpbiBwbGFjZSBvZiBpbnN0LmRwRGl2LnNob3coKSB3aGljaCB3b24ndCB3b3JrIG9uIGRpc2Nvbm5lY3RlZCBlbGVtZW50c1xuXHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeXVpLmNvbS90aWNrZXQvNzU1MiAtIEEgRGF0ZXBpY2tlciBjcmVhdGVkIG9uIGEgZGV0YWNoZWQgZGl2IGhhcyB6ZXJvIGhlaWdodFxuXHRcdGluc3QuZHBEaXYuY3NzKCBcImRpc3BsYXlcIiwgXCJibG9ja1wiICk7XG5cdH0sXG5cblx0LyogUG9wLXVwIHRoZSBkYXRlIHBpY2tlciBpbiBhIFwiZGlhbG9nXCIgYm94LlxuXHQgKiBAcGFyYW0gIGlucHV0IGVsZW1lbnQgLSBpZ25vcmVkXG5cdCAqIEBwYXJhbSAgZGF0ZVx0c3RyaW5nIG9yIERhdGUgLSB0aGUgaW5pdGlhbCBkYXRlIHRvIGRpc3BsYXlcblx0ICogQHBhcmFtICBvblNlbGVjdCAgZnVuY3Rpb24gLSB0aGUgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIGEgZGF0ZSBpcyBzZWxlY3RlZFxuXHQgKiBAcGFyYW0gIHNldHRpbmdzICBvYmplY3QgLSB1cGRhdGUgdGhlIGRpYWxvZyBkYXRlIHBpY2tlciBpbnN0YW5jZSdzIHNldHRpbmdzIChhbm9ueW1vdXMgb2JqZWN0KVxuXHQgKiBAcGFyYW0gIHBvcyBpbnRbMl0gLSBjb29yZGluYXRlcyBmb3IgdGhlIGRpYWxvZydzIHBvc2l0aW9uIHdpdGhpbiB0aGUgc2NyZWVuIG9yXG5cdCAqXHRcdFx0XHRcdGV2ZW50IC0gd2l0aCB4L3kgY29vcmRpbmF0ZXMgb3Jcblx0ICpcdFx0XHRcdFx0bGVhdmUgZW1wdHkgZm9yIGRlZmF1bHQgKHNjcmVlbiBjZW50cmUpXG5cdCAqIEByZXR1cm4gdGhlIG1hbmFnZXIgb2JqZWN0XG5cdCAqL1xuXHRfZGlhbG9nRGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5wdXQsIGRhdGUsIG9uU2VsZWN0LCBzZXR0aW5ncywgcG9zKSB7XG5cdFx0dmFyIGlkLCBicm93c2VyV2lkdGgsIGJyb3dzZXJIZWlnaHQsIHNjcm9sbFgsIHNjcm9sbFksXG5cdFx0XHRpbnN0ID0gdGhpcy5fZGlhbG9nSW5zdDsgLy8gaW50ZXJuYWwgaW5zdGFuY2VcblxuXHRcdGlmICghaW5zdCkge1xuXHRcdFx0dGhpcy51dWlkICs9IDE7XG5cdFx0XHRpZCA9IFwiZHBcIiArIHRoaXMudXVpZDtcblx0XHRcdHRoaXMuX2RpYWxvZ0lucHV0ID0gJChcIjxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nXCIgKyBpZCArXG5cdFx0XHRcdFwiJyBzdHlsZT0ncG9zaXRpb246IGFic29sdXRlOyB0b3A6IC0xMDBweDsgd2lkdGg6IDBweDsnLz5cIik7XG5cdFx0XHR0aGlzLl9kaWFsb2dJbnB1dC5rZXlkb3duKHRoaXMuX2RvS2V5RG93bik7XG5cdFx0XHQkKFwiYm9keVwiKS5hcHBlbmQodGhpcy5fZGlhbG9nSW5wdXQpO1xuXHRcdFx0aW5zdCA9IHRoaXMuX2RpYWxvZ0luc3QgPSB0aGlzLl9uZXdJbnN0KHRoaXMuX2RpYWxvZ0lucHV0LCBmYWxzZSk7XG5cdFx0XHRpbnN0LnNldHRpbmdzID0ge307XG5cdFx0XHQkLmRhdGEodGhpcy5fZGlhbG9nSW5wdXRbMF0sIFBST1BfTkFNRSwgaW5zdCk7XG5cdFx0fVxuXHRcdGV4dGVuZFJlbW92ZShpbnN0LnNldHRpbmdzLCBzZXR0aW5ncyB8fCB7fSk7XG5cdFx0ZGF0ZSA9IChkYXRlICYmIGRhdGUuY29uc3RydWN0b3IgPT09IERhdGUgPyB0aGlzLl9mb3JtYXREYXRlKGluc3QsIGRhdGUpIDogZGF0ZSk7XG5cdFx0dGhpcy5fZGlhbG9nSW5wdXQudmFsKGRhdGUpO1xuXG5cdFx0dGhpcy5fcG9zID0gKHBvcyA/IChwb3MubGVuZ3RoID8gcG9zIDogW3Bvcy5wYWdlWCwgcG9zLnBhZ2VZXSkgOiBudWxsKTtcblx0XHRpZiAoIXRoaXMuX3Bvcykge1xuXHRcdFx0YnJvd3NlcldpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuXHRcdFx0YnJvd3NlckhlaWdodCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG5cdFx0XHRzY3JvbGxYID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbExlZnQgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0O1xuXHRcdFx0c2Nyb2xsWSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3A7XG5cdFx0XHR0aGlzLl9wb3MgPSAvLyBzaG91bGQgdXNlIGFjdHVhbCB3aWR0aC9oZWlnaHQgYmVsb3dcblx0XHRcdFx0Wyhicm93c2VyV2lkdGggLyAyKSAtIDEwMCArIHNjcm9sbFgsIChicm93c2VySGVpZ2h0IC8gMikgLSAxNTAgKyBzY3JvbGxZXTtcblx0XHR9XG5cblx0XHQvLyBtb3ZlIGlucHV0IG9uIHNjcmVlbiBmb3IgZm9jdXMsIGJ1dCBoaWRkZW4gYmVoaW5kIGRpYWxvZ1xuXHRcdHRoaXMuX2RpYWxvZ0lucHV0LmNzcyhcImxlZnRcIiwgKHRoaXMuX3Bvc1swXSArIDIwKSArIFwicHhcIikuY3NzKFwidG9wXCIsIHRoaXMuX3Bvc1sxXSArIFwicHhcIik7XG5cdFx0aW5zdC5zZXR0aW5ncy5vblNlbGVjdCA9IG9uU2VsZWN0O1xuXHRcdHRoaXMuX2luRGlhbG9nID0gdHJ1ZTtcblx0XHR0aGlzLmRwRGl2LmFkZENsYXNzKHRoaXMuX2RpYWxvZ0NsYXNzKTtcblx0XHR0aGlzLl9zaG93RGF0ZXBpY2tlcih0aGlzLl9kaWFsb2dJbnB1dFswXSk7XG5cdFx0aWYgKCQuYmxvY2tVSSkge1xuXHRcdFx0JC5ibG9ja1VJKHRoaXMuZHBEaXYpO1xuXHRcdH1cblx0XHQkLmRhdGEodGhpcy5fZGlhbG9nSW5wdXRbMF0sIFBST1BfTkFNRSwgaW5zdCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyogRGV0YWNoIGEgZGF0ZXBpY2tlciBmcm9tIGl0cyBjb250cm9sLlxuXHQgKiBAcGFyYW0gIHRhcmdldFx0ZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKi9cblx0X2Rlc3Ryb3lEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgbm9kZU5hbWUsXG5cdFx0XHQkdGFyZ2V0ID0gJCh0YXJnZXQpLFxuXHRcdFx0aW5zdCA9ICQuZGF0YSh0YXJnZXQsIFBST1BfTkFNRSk7XG5cblx0XHRpZiAoISR0YXJnZXQuaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bm9kZU5hbWUgPSB0YXJnZXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHQkLnJlbW92ZURhdGEodGFyZ2V0LCBQUk9QX05BTUUpO1xuXHRcdGlmIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiKSB7XG5cdFx0XHRpbnN0LmFwcGVuZC5yZW1vdmUoKTtcblx0XHRcdGluc3QudHJpZ2dlci5yZW1vdmUoKTtcblx0XHRcdCR0YXJnZXQucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLlxuXHRcdFx0XHR1bmJpbmQoXCJmb2N1c1wiLCB0aGlzLl9zaG93RGF0ZXBpY2tlcikuXG5cdFx0XHRcdHVuYmluZChcImtleWRvd25cIiwgdGhpcy5fZG9LZXlEb3duKS5cblx0XHRcdFx0dW5iaW5kKFwia2V5cHJlc3NcIiwgdGhpcy5fZG9LZXlQcmVzcykuXG5cdFx0XHRcdHVuYmluZChcImtleXVwXCIsIHRoaXMuX2RvS2V5VXApO1xuXHRcdH0gZWxzZSBpZiAobm9kZU5hbWUgPT09IFwiZGl2XCIgfHwgbm9kZU5hbWUgPT09IFwic3BhblwiKSB7XG5cdFx0XHQkdGFyZ2V0LnJlbW92ZUNsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5lbXB0eSgpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBFbmFibGUgdGhlIGRhdGUgcGlja2VyIHRvIGEgalF1ZXJ5IHNlbGVjdGlvbi5cblx0ICogQHBhcmFtICB0YXJnZXRcdGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW5cblx0ICovXG5cdF9lbmFibGVEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgbm9kZU5hbWUsIGlubGluZSxcblx0XHRcdCR0YXJnZXQgPSAkKHRhcmdldCksXG5cdFx0XHRpbnN0ID0gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblxuXHRcdGlmICghJHRhcmdldC5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiKSB7XG5cdFx0XHR0YXJnZXQuZGlzYWJsZWQgPSBmYWxzZTtcblx0XHRcdGluc3QudHJpZ2dlci5maWx0ZXIoXCJidXR0b25cIikuXG5cdFx0XHRcdGVhY2goZnVuY3Rpb24oKSB7IHRoaXMuZGlzYWJsZWQgPSBmYWxzZTsgfSkuZW5kKCkuXG5cdFx0XHRcdGZpbHRlcihcImltZ1wiKS5jc3Moe29wYWNpdHk6IFwiMS4wXCIsIGN1cnNvcjogXCJcIn0pO1xuXHRcdH0gZWxzZSBpZiAobm9kZU5hbWUgPT09IFwiZGl2XCIgfHwgbm9kZU5hbWUgPT09IFwic3BhblwiKSB7XG5cdFx0XHRpbmxpbmUgPSAkdGFyZ2V0LmNoaWxkcmVuKFwiLlwiICsgdGhpcy5faW5saW5lQ2xhc3MpO1xuXHRcdFx0aW5saW5lLmNoaWxkcmVuKCkucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1kaXNhYmxlZFwiKTtcblx0XHRcdGlubGluZS5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXItbW9udGgsIHNlbGVjdC51aS1kYXRlcGlja2VyLXllYXJcIikuXG5cdFx0XHRcdHByb3AoXCJkaXNhYmxlZFwiLCBmYWxzZSk7XG5cdFx0fVxuXHRcdHRoaXMuX2Rpc2FibGVkSW5wdXRzID0gJC5tYXAodGhpcy5fZGlzYWJsZWRJbnB1dHMsXG5cdFx0XHRmdW5jdGlvbih2YWx1ZSkgeyByZXR1cm4gKHZhbHVlID09PSB0YXJnZXQgPyBudWxsIDogdmFsdWUpOyB9KTsgLy8gZGVsZXRlIGVudHJ5XG5cdH0sXG5cblx0LyogRGlzYWJsZSB0aGUgZGF0ZSBwaWNrZXIgdG8gYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldFx0ZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKi9cblx0X2Rpc2FibGVEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgbm9kZU5hbWUsIGlubGluZSxcblx0XHRcdCR0YXJnZXQgPSAkKHRhcmdldCksXG5cdFx0XHRpbnN0ID0gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblxuXHRcdGlmICghJHRhcmdldC5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdGlmIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiKSB7XG5cdFx0XHR0YXJnZXQuZGlzYWJsZWQgPSB0cnVlO1xuXHRcdFx0aW5zdC50cmlnZ2VyLmZpbHRlcihcImJ1dHRvblwiKS5cblx0XHRcdFx0ZWFjaChmdW5jdGlvbigpIHsgdGhpcy5kaXNhYmxlZCA9IHRydWU7IH0pLmVuZCgpLlxuXHRcdFx0XHRmaWx0ZXIoXCJpbWdcIikuY3NzKHtvcGFjaXR5OiBcIjAuNVwiLCBjdXJzb3I6IFwiZGVmYXVsdFwifSk7XG5cdFx0fSBlbHNlIGlmIChub2RlTmFtZSA9PT0gXCJkaXZcIiB8fCBub2RlTmFtZSA9PT0gXCJzcGFuXCIpIHtcblx0XHRcdGlubGluZSA9ICR0YXJnZXQuY2hpbGRyZW4oXCIuXCIgKyB0aGlzLl9pbmxpbmVDbGFzcyk7XG5cdFx0XHRpbmxpbmUuY2hpbGRyZW4oKS5hZGRDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIpO1xuXHRcdFx0aW5saW5lLmZpbmQoXCJzZWxlY3QudWktZGF0ZXBpY2tlci1tb250aCwgc2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhclwiKS5cblx0XHRcdFx0cHJvcChcImRpc2FibGVkXCIsIHRydWUpO1xuXHRcdH1cblx0XHR0aGlzLl9kaXNhYmxlZElucHV0cyA9ICQubWFwKHRoaXMuX2Rpc2FibGVkSW5wdXRzLFxuXHRcdFx0ZnVuY3Rpb24odmFsdWUpIHsgcmV0dXJuICh2YWx1ZSA9PT0gdGFyZ2V0ID8gbnVsbCA6IHZhbHVlKTsgfSk7IC8vIGRlbGV0ZSBlbnRyeVxuXHRcdHRoaXMuX2Rpc2FibGVkSW5wdXRzW3RoaXMuX2Rpc2FibGVkSW5wdXRzLmxlbmd0aF0gPSB0YXJnZXQ7XG5cdH0sXG5cblx0LyogSXMgdGhlIGZpcnN0IGZpZWxkIGluIGEgalF1ZXJ5IGNvbGxlY3Rpb24gZGlzYWJsZWQgYXMgYSBkYXRlcGlja2VyP1xuXHQgKiBAcGFyYW0gIHRhcmdldFx0ZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKiBAcmV0dXJuIGJvb2xlYW4gLSB0cnVlIGlmIGRpc2FibGVkLCBmYWxzZSBpZiBlbmFibGVkXG5cdCAqL1xuXHRfaXNEaXNhYmxlZERhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdGlmICghdGFyZ2V0KSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fZGlzYWJsZWRJbnB1dHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9kaXNhYmxlZElucHV0c1tpXSA9PT0gdGFyZ2V0KSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0sXG5cblx0LyogUmV0cmlldmUgdGhlIGluc3RhbmNlIGRhdGEgZm9yIHRoZSB0YXJnZXQgY29udHJvbC5cblx0ICogQHBhcmFtICB0YXJnZXQgIGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW5cblx0ICogQHJldHVybiAgb2JqZWN0IC0gdGhlIGFzc29jaWF0ZWQgaW5zdGFuY2UgZGF0YVxuXHQgKiBAdGhyb3dzICBlcnJvciBpZiBhIGpRdWVyeSBwcm9ibGVtIGdldHRpbmcgZGF0YVxuXHQgKi9cblx0X2dldEluc3Q6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblx0XHR9XG5cdFx0Y2F0Y2ggKGVycikge1xuXHRcdFx0dGhyb3cgXCJNaXNzaW5nIGluc3RhbmNlIGRhdGEgZm9yIHRoaXMgZGF0ZXBpY2tlclwiO1xuXHRcdH1cblx0fSxcblxuXHQvKiBVcGRhdGUgb3IgcmV0cmlldmUgdGhlIHNldHRpbmdzIGZvciBhIGRhdGUgcGlja2VyIGF0dGFjaGVkIHRvIGFuIGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldCAgZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKiBAcGFyYW0gIG5hbWVcdG9iamVjdCAtIHRoZSBuZXcgc2V0dGluZ3MgdG8gdXBkYXRlIG9yXG5cdCAqXHRcdFx0XHRzdHJpbmcgLSB0aGUgbmFtZSBvZiB0aGUgc2V0dGluZyB0byBjaGFuZ2Ugb3IgcmV0cmlldmUsXG5cdCAqXHRcdFx0XHR3aGVuIHJldHJpZXZpbmcgYWxzbyBcImFsbFwiIGZvciBhbGwgaW5zdGFuY2Ugc2V0dGluZ3Mgb3Jcblx0ICpcdFx0XHRcdFwiZGVmYXVsdHNcIiBmb3IgYWxsIGdsb2JhbCBkZWZhdWx0c1xuXHQgKiBAcGFyYW0gIHZhbHVlICAgYW55IC0gdGhlIG5ldyB2YWx1ZSBmb3IgdGhlIHNldHRpbmdcblx0ICpcdFx0XHRcdChvbWl0IGlmIGFib3ZlIGlzIGFuIG9iamVjdCBvciB0byByZXRyaWV2ZSBhIHZhbHVlKVxuXHQgKi9cblx0X29wdGlvbkRhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgdmFsdWUpIHtcblx0XHR2YXIgc2V0dGluZ3MsIGRhdGUsIG1pbkRhdGUsIG1heERhdGUsXG5cdFx0XHRpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXQpO1xuXG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiYgdHlwZW9mIG5hbWUgPT09IFwic3RyaW5nXCIpIHtcblx0XHRcdHJldHVybiAobmFtZSA9PT0gXCJkZWZhdWx0c1wiID8gJC5leHRlbmQoe30sICQuZGF0ZXBpY2tlci5fZGVmYXVsdHMpIDpcblx0XHRcdFx0KGluc3QgPyAobmFtZSA9PT0gXCJhbGxcIiA/ICQuZXh0ZW5kKHt9LCBpbnN0LnNldHRpbmdzKSA6XG5cdFx0XHRcdHRoaXMuX2dldChpbnN0LCBuYW1lKSkgOiBudWxsKSk7XG5cdFx0fVxuXG5cdFx0c2V0dGluZ3MgPSBuYW1lIHx8IHt9O1xuXHRcdGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0c2V0dGluZ3MgPSB7fTtcblx0XHRcdHNldHRpbmdzW25hbWVdID0gdmFsdWU7XG5cdFx0fVxuXG5cdFx0aWYgKGluc3QpIHtcblx0XHRcdGlmICh0aGlzLl9jdXJJbnN0ID09PSBpbnN0KSB7XG5cdFx0XHRcdHRoaXMuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHR9XG5cblx0XHRcdGRhdGUgPSB0aGlzLl9nZXREYXRlRGF0ZXBpY2tlcih0YXJnZXQsIHRydWUpO1xuXHRcdFx0bWluRGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgXCJtaW5cIik7XG5cdFx0XHRtYXhEYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1heFwiKTtcblx0XHRcdGV4dGVuZFJlbW92ZShpbnN0LnNldHRpbmdzLCBzZXR0aW5ncyk7XG5cdFx0XHQvLyByZWZvcm1hdCB0aGUgb2xkIG1pbkRhdGUvbWF4RGF0ZSB2YWx1ZXMgaWYgZGF0ZUZvcm1hdCBjaGFuZ2VzIGFuZCBhIG5ldyBtaW5EYXRlL21heERhdGUgaXNuJ3QgcHJvdmlkZWRcblx0XHRcdGlmIChtaW5EYXRlICE9PSBudWxsICYmIHNldHRpbmdzLmRhdGVGb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBzZXR0aW5ncy5taW5EYXRlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0aW5zdC5zZXR0aW5ncy5taW5EYXRlID0gdGhpcy5fZm9ybWF0RGF0ZShpbnN0LCBtaW5EYXRlKTtcblx0XHRcdH1cblx0XHRcdGlmIChtYXhEYXRlICE9PSBudWxsICYmIHNldHRpbmdzLmRhdGVGb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBzZXR0aW5ncy5tYXhEYXRlID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0aW5zdC5zZXR0aW5ncy5tYXhEYXRlID0gdGhpcy5fZm9ybWF0RGF0ZShpbnN0LCBtYXhEYXRlKTtcblx0XHRcdH1cblx0XHRcdGlmICggXCJkaXNhYmxlZFwiIGluIHNldHRpbmdzICkge1xuXHRcdFx0XHRpZiAoIHNldHRpbmdzLmRpc2FibGVkICkge1xuXHRcdFx0XHRcdHRoaXMuX2Rpc2FibGVEYXRlcGlja2VyKHRhcmdldCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5fZW5hYmxlRGF0ZXBpY2tlcih0YXJnZXQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9hdHRhY2htZW50cygkKHRhcmdldCksIGluc3QpO1xuXHRcdFx0dGhpcy5fYXV0b1NpemUoaW5zdCk7XG5cdFx0XHR0aGlzLl9zZXREYXRlKGluc3QsIGRhdGUpO1xuXHRcdFx0dGhpcy5fdXBkYXRlQWx0ZXJuYXRlKGluc3QpO1xuXHRcdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gY2hhbmdlIG1ldGhvZCBkZXByZWNhdGVkXG5cdF9jaGFuZ2VEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQsIG5hbWUsIHZhbHVlKSB7XG5cdFx0dGhpcy5fb3B0aW9uRGF0ZXBpY2tlcih0YXJnZXQsIG5hbWUsIHZhbHVlKTtcblx0fSxcblxuXHQvKiBSZWRyYXcgdGhlIGRhdGUgcGlja2VyIGF0dGFjaGVkIHRvIGFuIGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldCAgZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKi9cblx0X3JlZnJlc2hEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQpIHtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0KTtcblx0XHRpZiAoaW5zdCkge1xuXHRcdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0LyogU2V0IHRoZSBkYXRlcyBmb3IgYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldCBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqIEBwYXJhbSAgZGF0ZVx0RGF0ZSAtIHRoZSBuZXcgZGF0ZVxuXHQgKi9cblx0X3NldERhdGVEYXRlcGlja2VyOiBmdW5jdGlvbih0YXJnZXQsIGRhdGUpIHtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0KTtcblx0XHRpZiAoaW5zdCkge1xuXHRcdFx0dGhpcy5fc2V0RGF0ZShpbnN0LCBkYXRlKTtcblx0XHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0XHR0aGlzLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEdldCB0aGUgZGF0ZShzKSBmb3IgdGhlIGZpcnN0IGVudHJ5IGluIGEgalF1ZXJ5IHNlbGVjdGlvbi5cblx0ICogQHBhcmFtICB0YXJnZXQgZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKiBAcGFyYW0gIG5vRGVmYXVsdCBib29sZWFuIC0gdHJ1ZSBpZiBubyBkZWZhdWx0IGRhdGUgaXMgdG8gYmUgdXNlZFxuXHQgKiBAcmV0dXJuIERhdGUgLSB0aGUgY3VycmVudCBkYXRlXG5cdCAqL1xuXHRfZ2V0RGF0ZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgbm9EZWZhdWx0KSB7XG5cdFx0dmFyIGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldCk7XG5cdFx0aWYgKGluc3QgJiYgIWluc3QuaW5saW5lKSB7XG5cdFx0XHR0aGlzLl9zZXREYXRlRnJvbUZpZWxkKGluc3QsIG5vRGVmYXVsdCk7XG5cdFx0fVxuXHRcdHJldHVybiAoaW5zdCA/IHRoaXMuX2dldERhdGUoaW5zdCkgOiBudWxsKTtcblx0fSxcblxuXHQvKiBIYW5kbGUga2V5c3Ryb2tlcy4gKi9cblx0X2RvS2V5RG93bjogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgb25TZWxlY3QsIGRhdGVTdHIsIHNlbCxcblx0XHRcdGluc3QgPSAkLmRhdGVwaWNrZXIuX2dldEluc3QoZXZlbnQudGFyZ2V0KSxcblx0XHRcdGhhbmRsZWQgPSB0cnVlLFxuXHRcdFx0aXNSVEwgPSBpbnN0LmRwRGl2LmlzKFwiLnVpLWRhdGVwaWNrZXItcnRsXCIpO1xuXG5cdFx0aW5zdC5fa2V5RXZlbnQgPSB0cnVlO1xuXHRcdGlmICgkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nKSB7XG5cdFx0XHRzd2l0Y2ggKGV2ZW50LmtleUNvZGUpIHtcblx0XHRcdFx0Y2FzZSA5OiAkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gaGlkZSBvbiB0YWIgb3V0XG5cdFx0XHRcdGNhc2UgMTM6IHNlbCA9ICQoXCJ0ZC5cIiArICQuZGF0ZXBpY2tlci5fZGF5T3ZlckNsYXNzICsgXCI6bm90KC5cIiArXG5cdFx0XHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2N1cnJlbnRDbGFzcyArIFwiKVwiLCBpbnN0LmRwRGl2KTtcblx0XHRcdFx0XHRcdGlmIChzZWxbMF0pIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9zZWxlY3REYXkoZXZlbnQudGFyZ2V0LCBpbnN0LnNlbGVjdGVkTW9udGgsIGluc3Quc2VsZWN0ZWRZZWFyLCBzZWxbMF0pO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRvblNlbGVjdCA9ICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwib25TZWxlY3RcIik7XG5cdFx0XHRcdFx0XHRpZiAob25TZWxlY3QpIHtcblx0XHRcdFx0XHRcdFx0ZGF0ZVN0ciA9ICQuZGF0ZXBpY2tlci5fZm9ybWF0RGF0ZShpbnN0KTtcblxuXHRcdFx0XHRcdFx0XHQvLyB0cmlnZ2VyIGN1c3RvbSBjYWxsYmFja1xuXHRcdFx0XHRcdFx0XHRvblNlbGVjdC5hcHBseSgoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXRbMF0gOiBudWxsKSwgW2RhdGVTdHIsIGluc3RdKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlOyAvLyBkb24ndCBzdWJtaXQgdGhlIGZvcm1cblx0XHRcdFx0Y2FzZSAyNzogJC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIGhpZGUgb24gZXNjYXBlXG5cdFx0XHRcdGNhc2UgMzM6ICQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChldmVudC5jdHJsS2V5ID9cblx0XHRcdFx0XHRcdFx0LSQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic3RlcEJpZ01vbnRoc1wiKSA6XG5cdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInN0ZXBNb250aHNcIikpLCBcIk1cIik7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gcHJldmlvdXMgbW9udGgveWVhciBvbiBwYWdlIHVwLysgY3RybFxuXHRcdFx0XHRjYXNlIDM0OiAkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoZXZlbnQuY3RybEtleSA/XG5cdFx0XHRcdFx0XHRcdCskLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInN0ZXBCaWdNb250aHNcIikgOlxuXHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwTW9udGhzXCIpKSwgXCJNXCIpO1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIG5leHQgbW9udGgveWVhciBvbiBwYWdlIGRvd24vKyBjdHJsXG5cdFx0XHRcdGNhc2UgMzU6IGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9jbGVhckRhdGUoZXZlbnQudGFyZ2V0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gY2xlYXIgb24gY3RybCBvciBjb21tYW5kICtlbmRcblx0XHRcdFx0Y2FzZSAzNjogaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkge1xuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2dvdG9Ub2RheShldmVudC50YXJnZXQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBjdXJyZW50IG9uIGN0cmwgb3IgY29tbWFuZCAraG9tZVxuXHRcdFx0XHRjYXNlIDM3OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChpc1JUTCA/ICsxIDogLTEpLCBcIkRcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0Ly8gLTEgZGF5IG9uIGN0cmwgb3IgY29tbWFuZCArbGVmdFxuXHRcdFx0XHRcdFx0aWYgKGV2ZW50Lm9yaWdpbmFsRXZlbnQuYWx0S2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChldmVudC5jdHJsS2V5ID9cblx0XHRcdFx0XHRcdFx0XHQtJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwQmlnTW9udGhzXCIpIDpcblx0XHRcdFx0XHRcdFx0XHQtJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwTW9udGhzXCIpKSwgXCJNXCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gbmV4dCBtb250aC95ZWFyIG9uIGFsdCArbGVmdCBvbiBNYWNcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDM4OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIC03LCBcIkRcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIC0xIHdlZWsgb24gY3RybCBvciBjb21tYW5kICt1cFxuXHRcdFx0XHRjYXNlIDM5OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChpc1JUTCA/IC0xIDogKzEpLCBcIkRcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0Ly8gKzEgZGF5IG9uIGN0cmwgb3IgY29tbWFuZCArcmlnaHRcblx0XHRcdFx0XHRcdGlmIChldmVudC5vcmlnaW5hbEV2ZW50LmFsdEtleSkge1xuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCAoZXZlbnQuY3RybEtleSA/XG5cdFx0XHRcdFx0XHRcdFx0KyQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic3RlcEJpZ01vbnRoc1wiKSA6XG5cdFx0XHRcdFx0XHRcdFx0KyQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic3RlcE1vbnRoc1wiKSksIFwiTVwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdC8vIG5leHQgbW9udGgveWVhciBvbiBhbHQgK3JpZ2h0XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0Y2FzZSA0MDogaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkge1xuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2FkanVzdERhdGUoZXZlbnQudGFyZ2V0LCArNywgXCJEXCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyArMSB3ZWVrIG9uIGN0cmwgb3IgY29tbWFuZCArZG93blxuXHRcdFx0XHRkZWZhdWx0OiBoYW5kbGVkID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIGlmIChldmVudC5rZXlDb2RlID09PSAzNiAmJiBldmVudC5jdHJsS2V5KSB7IC8vIGRpc3BsYXkgdGhlIGRhdGUgcGlja2VyIG9uIGN0cmwraG9tZVxuXHRcdFx0JC5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcih0aGlzKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aGFuZGxlZCA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChoYW5kbGVkKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEZpbHRlciBlbnRlcmVkIGNoYXJhY3RlcnMgLSBiYXNlZCBvbiBkYXRlIGZvcm1hdC4gKi9cblx0X2RvS2V5UHJlc3M6IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIGNoYXJzLCBjaHIsXG5cdFx0XHRpbnN0ID0gJC5kYXRlcGlja2VyLl9nZXRJbnN0KGV2ZW50LnRhcmdldCk7XG5cblx0XHRpZiAoJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJjb25zdHJhaW5JbnB1dFwiKSkge1xuXHRcdFx0Y2hhcnMgPSAkLmRhdGVwaWNrZXIuX3Bvc3NpYmxlQ2hhcnMoJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpKTtcblx0XHRcdGNociA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZXZlbnQuY2hhckNvZGUgPT0gbnVsbCA/IGV2ZW50LmtleUNvZGUgOiBldmVudC5jaGFyQ29kZSk7XG5cdFx0XHRyZXR1cm4gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IChjaHIgPCBcIiBcIiB8fCAhY2hhcnMgfHwgY2hhcnMuaW5kZXhPZihjaHIpID4gLTEpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBTeW5jaHJvbmlzZSBtYW51YWwgZW50cnkgYW5kIGZpZWxkL2FsdGVybmF0ZSBmaWVsZC4gKi9cblx0X2RvS2V5VXA6IGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0dmFyIGRhdGUsXG5cdFx0XHRpbnN0ID0gJC5kYXRlcGlja2VyLl9nZXRJbnN0KGV2ZW50LnRhcmdldCk7XG5cblx0XHRpZiAoaW5zdC5pbnB1dC52YWwoKSAhPT0gaW5zdC5sYXN0VmFsKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkYXRlID0gJC5kYXRlcGlja2VyLnBhcnNlRGF0ZSgkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcImRhdGVGb3JtYXRcIiksXG5cdFx0XHRcdFx0KGluc3QuaW5wdXQgPyBpbnN0LmlucHV0LnZhbCgpIDogbnVsbCksXG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpO1xuXG5cdFx0XHRcdGlmIChkYXRlKSB7IC8vIG9ubHkgaWYgdmFsaWRcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3NldERhdGVGcm9tRmllbGQoaW5zdCk7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRjYXRjaCAoZXJyKSB7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9LFxuXG5cdC8qIFBvcC11cCB0aGUgZGF0ZSBwaWNrZXIgZm9yIGEgZ2l2ZW4gaW5wdXQgZmllbGQuXG5cdCAqIElmIGZhbHNlIHJldHVybmVkIGZyb20gYmVmb3JlU2hvdyBldmVudCBoYW5kbGVyIGRvIG5vdCBzaG93LlxuXHQgKiBAcGFyYW0gIGlucHV0ICBlbGVtZW50IC0gdGhlIGlucHV0IGZpZWxkIGF0dGFjaGVkIHRvIHRoZSBkYXRlIHBpY2tlciBvclxuXHQgKlx0XHRcdFx0XHRldmVudCAtIGlmIHRyaWdnZXJlZCBieSBmb2N1c1xuXHQgKi9cblx0X3Nob3dEYXRlcGlja2VyOiBmdW5jdGlvbihpbnB1dCkge1xuXHRcdGlucHV0ID0gaW5wdXQudGFyZ2V0IHx8IGlucHV0O1xuXHRcdGlmIChpbnB1dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSBcImlucHV0XCIpIHsgLy8gZmluZCBmcm9tIGJ1dHRvbi9pbWFnZSB0cmlnZ2VyXG5cdFx0XHRpbnB1dCA9ICQoXCJpbnB1dFwiLCBpbnB1dC5wYXJlbnROb2RlKVswXTtcblx0XHR9XG5cblx0XHRpZiAoJC5kYXRlcGlja2VyLl9pc0Rpc2FibGVkRGF0ZXBpY2tlcihpbnB1dCkgfHwgJC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgPT09IGlucHV0KSB7IC8vIGFscmVhZHkgaGVyZVxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBpbnN0LCBiZWZvcmVTaG93LCBiZWZvcmVTaG93U2V0dGluZ3MsIGlzRml4ZWQsXG5cdFx0XHRvZmZzZXQsIHNob3dBbmltLCBkdXJhdGlvbjtcblxuXHRcdGluc3QgPSAkLmRhdGVwaWNrZXIuX2dldEluc3QoaW5wdXQpO1xuXHRcdGlmICgkLmRhdGVwaWNrZXIuX2N1ckluc3QgJiYgJC5kYXRlcGlja2VyLl9jdXJJbnN0ICE9PSBpbnN0KSB7XG5cdFx0XHQkLmRhdGVwaWNrZXIuX2N1ckluc3QuZHBEaXYuc3RvcCh0cnVlLCB0cnVlKTtcblx0XHRcdGlmICggaW5zdCAmJiAkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICkge1xuXHRcdFx0XHQkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCAkLmRhdGVwaWNrZXIuX2N1ckluc3QuaW5wdXRbMF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRiZWZvcmVTaG93ID0gJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJiZWZvcmVTaG93XCIpO1xuXHRcdGJlZm9yZVNob3dTZXR0aW5ncyA9IGJlZm9yZVNob3cgPyBiZWZvcmVTaG93LmFwcGx5KGlucHV0LCBbaW5wdXQsIGluc3RdKSA6IHt9O1xuXHRcdGlmKGJlZm9yZVNob3dTZXR0aW5ncyA9PT0gZmFsc2Upe1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHRleHRlbmRSZW1vdmUoaW5zdC5zZXR0aW5ncywgYmVmb3JlU2hvd1NldHRpbmdzKTtcblxuXHRcdGluc3QubGFzdFZhbCA9IG51bGw7XG5cdFx0JC5kYXRlcGlja2VyLl9sYXN0SW5wdXQgPSBpbnB1dDtcblx0XHQkLmRhdGVwaWNrZXIuX3NldERhdGVGcm9tRmllbGQoaW5zdCk7XG5cblx0XHRpZiAoJC5kYXRlcGlja2VyLl9pbkRpYWxvZykgeyAvLyBoaWRlIGN1cnNvclxuXHRcdFx0aW5wdXQudmFsdWUgPSBcIlwiO1xuXHRcdH1cblx0XHRpZiAoISQuZGF0ZXBpY2tlci5fcG9zKSB7IC8vIHBvc2l0aW9uIGJlbG93IGlucHV0XG5cdFx0XHQkLmRhdGVwaWNrZXIuX3BvcyA9ICQuZGF0ZXBpY2tlci5fZmluZFBvcyhpbnB1dCk7XG5cdFx0XHQkLmRhdGVwaWNrZXIuX3Bvc1sxXSArPSBpbnB1dC5vZmZzZXRIZWlnaHQ7IC8vIGFkZCB0aGUgaGVpZ2h0XG5cdFx0fVxuXG5cdFx0aXNGaXhlZCA9IGZhbHNlO1xuXHRcdCQoaW5wdXQpLnBhcmVudHMoKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aXNGaXhlZCB8PSAkKHRoaXMpLmNzcyhcInBvc2l0aW9uXCIpID09PSBcImZpeGVkXCI7XG5cdFx0XHRyZXR1cm4gIWlzRml4ZWQ7XG5cdFx0fSk7XG5cblx0XHRvZmZzZXQgPSB7bGVmdDogJC5kYXRlcGlja2VyLl9wb3NbMF0sIHRvcDogJC5kYXRlcGlja2VyLl9wb3NbMV19O1xuXHRcdCQuZGF0ZXBpY2tlci5fcG9zID0gbnVsbDtcblx0XHQvL3RvIGF2b2lkIGZsYXNoZXMgb24gRmlyZWZveFxuXHRcdGluc3QuZHBEaXYuZW1wdHkoKTtcblx0XHQvLyBkZXRlcm1pbmUgc2l6aW5nIG9mZnNjcmVlblxuXHRcdGluc3QuZHBEaXYuY3NzKHtwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCBkaXNwbGF5OiBcImJsb2NrXCIsIHRvcDogXCItMTAwMHB4XCJ9KTtcblx0XHQkLmRhdGVwaWNrZXIuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0Ly8gZml4IHdpZHRoIGZvciBkeW5hbWljIG51bWJlciBvZiBkYXRlIHBpY2tlcnNcblx0XHQvLyBhbmQgYWRqdXN0IHBvc2l0aW9uIGJlZm9yZSBzaG93aW5nXG5cdFx0b2Zmc2V0ID0gJC5kYXRlcGlja2VyLl9jaGVja09mZnNldChpbnN0LCBvZmZzZXQsIGlzRml4ZWQpO1xuXHRcdGluc3QuZHBEaXYuY3NzKHtwb3NpdGlvbjogKCQuZGF0ZXBpY2tlci5faW5EaWFsb2cgJiYgJC5ibG9ja1VJID9cblx0XHRcdFwic3RhdGljXCIgOiAoaXNGaXhlZCA/IFwiZml4ZWRcIiA6IFwiYWJzb2x1dGVcIikpLCBkaXNwbGF5OiBcIm5vbmVcIixcblx0XHRcdGxlZnQ6IG9mZnNldC5sZWZ0ICsgXCJweFwiLCB0b3A6IG9mZnNldC50b3AgKyBcInB4XCJ9KTtcblxuXHRcdGlmICghaW5zdC5pbmxpbmUpIHtcblx0XHRcdHNob3dBbmltID0gJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzaG93QW5pbVwiKTtcblx0XHRcdGR1cmF0aW9uID0gJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJkdXJhdGlvblwiKTtcblx0XHRcdGluc3QuZHBEaXYuekluZGV4KCQoaW5wdXQpLnpJbmRleCgpKzEpO1xuXHRcdFx0JC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyA9IHRydWU7XG5cblx0XHRcdGlmICggJC5lZmZlY3RzICYmICQuZWZmZWN0cy5lZmZlY3RbIHNob3dBbmltIF0gKSB7XG5cdFx0XHRcdGluc3QuZHBEaXYuc2hvdyhzaG93QW5pbSwgJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzaG93T3B0aW9uc1wiKSwgZHVyYXRpb24pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aW5zdC5kcERpdltzaG93QW5pbSB8fCBcInNob3dcIl0oc2hvd0FuaW0gPyBkdXJhdGlvbiA6IG51bGwpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoICQuZGF0ZXBpY2tlci5fc2hvdWxkRm9jdXNJbnB1dCggaW5zdCApICkge1xuXHRcdFx0XHRpbnN0LmlucHV0LmZvY3VzKCk7XG5cdFx0XHR9XG5cblx0XHRcdCQuZGF0ZXBpY2tlci5fY3VySW5zdCA9IGluc3Q7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEdlbmVyYXRlIHRoZSBkYXRlIHBpY2tlciBjb250ZW50LiAqL1xuXHRfdXBkYXRlRGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHRoaXMubWF4Um93cyA9IDQ7IC8vUmVzZXQgdGhlIG1heCBudW1iZXIgb2Ygcm93cyBiZWluZyBkaXNwbGF5ZWQgKHNlZSAjNzA0Mylcblx0XHRpbnN0QWN0aXZlID0gaW5zdDsgLy8gZm9yIGRlbGVnYXRlIGhvdmVyIGV2ZW50c1xuXHRcdGluc3QuZHBEaXYuZW1wdHkoKS5hcHBlbmQodGhpcy5fZ2VuZXJhdGVIVE1MKGluc3QpKTtcblx0XHR0aGlzLl9hdHRhY2hIYW5kbGVycyhpbnN0KTtcblx0XHRpbnN0LmRwRGl2LmZpbmQoXCIuXCIgKyB0aGlzLl9kYXlPdmVyQ2xhc3MgKyBcIiBhXCIpLm1vdXNlb3ZlcigpO1xuXG5cdFx0dmFyIG9yaWd5ZWFyc2h0bWwsXG5cdFx0XHRudW1Nb250aHMgPSB0aGlzLl9nZXROdW1iZXJPZk1vbnRocyhpbnN0KSxcblx0XHRcdGNvbHMgPSBudW1Nb250aHNbMV0sXG5cdFx0XHR3aWR0aCA9IDE3O1xuXG5cdFx0aW5zdC5kcERpdi5yZW1vdmVDbGFzcyhcInVpLWRhdGVwaWNrZXItbXVsdGktMiB1aS1kYXRlcGlja2VyLW11bHRpLTMgdWktZGF0ZXBpY2tlci1tdWx0aS00XCIpLndpZHRoKFwiXCIpO1xuXHRcdGlmIChjb2xzID4gMSkge1xuXHRcdFx0aW5zdC5kcERpdi5hZGRDbGFzcyhcInVpLWRhdGVwaWNrZXItbXVsdGktXCIgKyBjb2xzKS5jc3MoXCJ3aWR0aFwiLCAod2lkdGggKiBjb2xzKSArIFwiZW1cIik7XG5cdFx0fVxuXHRcdGluc3QuZHBEaXZbKG51bU1vbnRoc1swXSAhPT0gMSB8fCBudW1Nb250aHNbMV0gIT09IDEgPyBcImFkZFwiIDogXCJyZW1vdmVcIikgK1xuXHRcdFx0XCJDbGFzc1wiXShcInVpLWRhdGVwaWNrZXItbXVsdGlcIik7XG5cdFx0aW5zdC5kcERpdlsodGhpcy5fZ2V0KGluc3QsIFwiaXNSVExcIikgPyBcImFkZFwiIDogXCJyZW1vdmVcIikgK1xuXHRcdFx0XCJDbGFzc1wiXShcInVpLWRhdGVwaWNrZXItcnRsXCIpO1xuXG5cdFx0aWYgKGluc3QgPT09ICQuZGF0ZXBpY2tlci5fY3VySW5zdCAmJiAkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICYmICQuZGF0ZXBpY2tlci5fc2hvdWxkRm9jdXNJbnB1dCggaW5zdCApICkge1xuXHRcdFx0aW5zdC5pbnB1dC5mb2N1cygpO1xuXHRcdH1cblxuXHRcdC8vIGRlZmZlcmVkIHJlbmRlciBvZiB0aGUgeWVhcnMgc2VsZWN0ICh0byBhdm9pZCBmbGFzaGVzIG9uIEZpcmVmb3gpXG5cdFx0aWYoIGluc3QueWVhcnNodG1sICl7XG5cdFx0XHRvcmlneWVhcnNodG1sID0gaW5zdC55ZWFyc2h0bWw7XG5cdFx0XHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG5cdFx0XHRcdC8vYXNzdXJlIHRoYXQgaW5zdC55ZWFyc2h0bWwgZGlkbid0IGNoYW5nZS5cblx0XHRcdFx0aWYoIG9yaWd5ZWFyc2h0bWwgPT09IGluc3QueWVhcnNodG1sICYmIGluc3QueWVhcnNodG1sICl7XG5cdFx0XHRcdFx0aW5zdC5kcERpdi5maW5kKFwic2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhcjpmaXJzdFwiKS5yZXBsYWNlV2l0aChpbnN0LnllYXJzaHRtbCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0b3JpZ3llYXJzaHRtbCA9IGluc3QueWVhcnNodG1sID0gbnVsbDtcblx0XHRcdH0sIDApO1xuXHRcdH1cblx0fSxcblxuXHQvLyAjNjY5NCAtIGRvbid0IGZvY3VzIHRoZSBpbnB1dCBpZiBpdCdzIGFscmVhZHkgZm9jdXNlZFxuXHQvLyB0aGlzIGJyZWFrcyB0aGUgY2hhbmdlIGV2ZW50IGluIElFXG5cdC8vIFN1cHBvcnQ6IElFIGFuZCBqUXVlcnkgPDEuOVxuXHRfc2hvdWxkRm9jdXNJbnB1dDogZnVuY3Rpb24oIGluc3QgKSB7XG5cdFx0cmV0dXJuIGluc3QuaW5wdXQgJiYgaW5zdC5pbnB1dC5pcyggXCI6dmlzaWJsZVwiICkgJiYgIWluc3QuaW5wdXQuaXMoIFwiOmRpc2FibGVkXCIgKSAmJiAhaW5zdC5pbnB1dC5pcyggXCI6Zm9jdXNcIiApO1xuXHR9LFxuXG5cdC8qIENoZWNrIHBvc2l0aW9uaW5nIHRvIHJlbWFpbiBvbiBzY3JlZW4uICovXG5cdF9jaGVja09mZnNldDogZnVuY3Rpb24oaW5zdCwgb2Zmc2V0LCBpc0ZpeGVkKSB7XG5cdFx0dmFyIGRwV2lkdGggPSBpbnN0LmRwRGl2Lm91dGVyV2lkdGgoKSxcblx0XHRcdGRwSGVpZ2h0ID0gaW5zdC5kcERpdi5vdXRlckhlaWdodCgpLFxuXHRcdFx0aW5wdXRXaWR0aCA9IGluc3QuaW5wdXQgPyBpbnN0LmlucHV0Lm91dGVyV2lkdGgoKSA6IDAsXG5cdFx0XHRpbnB1dEhlaWdodCA9IGluc3QuaW5wdXQgPyBpbnN0LmlucHV0Lm91dGVySGVpZ2h0KCkgOiAwLFxuXHRcdFx0dmlld1dpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoICsgKGlzRml4ZWQgPyAwIDogJChkb2N1bWVudCkuc2Nyb2xsTGVmdCgpKSxcblx0XHRcdHZpZXdIZWlnaHQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0ICsgKGlzRml4ZWQgPyAwIDogJChkb2N1bWVudCkuc2Nyb2xsVG9wKCkpO1xuXG5cdFx0b2Zmc2V0LmxlZnQgLT0gKHRoaXMuX2dldChpbnN0LCBcImlzUlRMXCIpID8gKGRwV2lkdGggLSBpbnB1dFdpZHRoKSA6IDApO1xuXHRcdG9mZnNldC5sZWZ0IC09IChpc0ZpeGVkICYmIG9mZnNldC5sZWZ0ID09PSBpbnN0LmlucHV0Lm9mZnNldCgpLmxlZnQpID8gJChkb2N1bWVudCkuc2Nyb2xsTGVmdCgpIDogMDtcblx0XHRvZmZzZXQudG9wIC09IChpc0ZpeGVkICYmIG9mZnNldC50b3AgPT09IChpbnN0LmlucHV0Lm9mZnNldCgpLnRvcCArIGlucHV0SGVpZ2h0KSkgPyAkKGRvY3VtZW50KS5zY3JvbGxUb3AoKSA6IDA7XG5cblx0XHQvLyBub3cgY2hlY2sgaWYgZGF0ZXBpY2tlciBpcyBzaG93aW5nIG91dHNpZGUgd2luZG93IHZpZXdwb3J0IC0gbW92ZSB0byBhIGJldHRlciBwbGFjZSBpZiBzby5cblx0XHRvZmZzZXQubGVmdCAtPSBNYXRoLm1pbihvZmZzZXQubGVmdCwgKG9mZnNldC5sZWZ0ICsgZHBXaWR0aCA+IHZpZXdXaWR0aCAmJiB2aWV3V2lkdGggPiBkcFdpZHRoKSA/XG5cdFx0XHRNYXRoLmFicyhvZmZzZXQubGVmdCArIGRwV2lkdGggLSB2aWV3V2lkdGgpIDogMCk7XG5cdFx0b2Zmc2V0LnRvcCAtPSBNYXRoLm1pbihvZmZzZXQudG9wLCAob2Zmc2V0LnRvcCArIGRwSGVpZ2h0ID4gdmlld0hlaWdodCAmJiB2aWV3SGVpZ2h0ID4gZHBIZWlnaHQpID9cblx0XHRcdE1hdGguYWJzKGRwSGVpZ2h0ICsgaW5wdXRIZWlnaHQpIDogMCk7XG5cblx0XHRyZXR1cm4gb2Zmc2V0O1xuXHR9LFxuXG5cdC8qIEZpbmQgYW4gb2JqZWN0J3MgcG9zaXRpb24gb24gdGhlIHNjcmVlbi4gKi9cblx0X2ZpbmRQb3M6IGZ1bmN0aW9uKG9iaikge1xuXHRcdHZhciBwb3NpdGlvbixcblx0XHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KG9iaiksXG5cdFx0XHRpc1JUTCA9IHRoaXMuX2dldChpbnN0LCBcImlzUlRMXCIpO1xuXG5cdFx0d2hpbGUgKG9iaiAmJiAob2JqLnR5cGUgPT09IFwiaGlkZGVuXCIgfHwgb2JqLm5vZGVUeXBlICE9PSAxIHx8ICQuZXhwci5maWx0ZXJzLmhpZGRlbihvYmopKSkge1xuXHRcdFx0b2JqID0gb2JqW2lzUlRMID8gXCJwcmV2aW91c1NpYmxpbmdcIiA6IFwibmV4dFNpYmxpbmdcIl07XG5cdFx0fVxuXG5cdFx0cG9zaXRpb24gPSAkKG9iaikub2Zmc2V0KCk7XG5cdFx0cmV0dXJuIFtwb3NpdGlvbi5sZWZ0LCBwb3NpdGlvbi50b3BdO1xuXHR9LFxuXG5cdC8qIEhpZGUgdGhlIGRhdGUgcGlja2VyIGZyb20gdmlldy5cblx0ICogQHBhcmFtICBpbnB1dCAgZWxlbWVudCAtIHRoZSBpbnB1dCBmaWVsZCBhdHRhY2hlZCB0byB0aGUgZGF0ZSBwaWNrZXJcblx0ICovXG5cdF9oaWRlRGF0ZXBpY2tlcjogZnVuY3Rpb24oaW5wdXQpIHtcblx0XHR2YXIgc2hvd0FuaW0sIGR1cmF0aW9uLCBwb3N0UHJvY2Vzcywgb25DbG9zZSxcblx0XHRcdGluc3QgPSB0aGlzLl9jdXJJbnN0O1xuXG5cdFx0aWYgKCFpbnN0IHx8IChpbnB1dCAmJiBpbnN0ICE9PSAkLmRhdGEoaW5wdXQsIFBST1BfTkFNRSkpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX2RhdGVwaWNrZXJTaG93aW5nKSB7XG5cdFx0XHRzaG93QW5pbSA9IHRoaXMuX2dldChpbnN0LCBcInNob3dBbmltXCIpO1xuXHRcdFx0ZHVyYXRpb24gPSB0aGlzLl9nZXQoaW5zdCwgXCJkdXJhdGlvblwiKTtcblx0XHRcdHBvc3RQcm9jZXNzID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCQuZGF0ZXBpY2tlci5fdGlkeURpYWxvZyhpbnN0KTtcblx0XHRcdH07XG5cblx0XHRcdC8vIERFUFJFQ0FURUQ6IGFmdGVyIEJDIGZvciAxLjgueCAkLmVmZmVjdHNbIHNob3dBbmltIF0gaXMgbm90IG5lZWRlZFxuXHRcdFx0aWYgKCAkLmVmZmVjdHMgJiYgKCAkLmVmZmVjdHMuZWZmZWN0WyBzaG93QW5pbSBdIHx8ICQuZWZmZWN0c1sgc2hvd0FuaW0gXSApICkge1xuXHRcdFx0XHRpbnN0LmRwRGl2LmhpZGUoc2hvd0FuaW0sICQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic2hvd09wdGlvbnNcIiksIGR1cmF0aW9uLCBwb3N0UHJvY2Vzcyk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpbnN0LmRwRGl2WyhzaG93QW5pbSA9PT0gXCJzbGlkZURvd25cIiA/IFwic2xpZGVVcFwiIDpcblx0XHRcdFx0XHQoc2hvd0FuaW0gPT09IFwiZmFkZUluXCIgPyBcImZhZGVPdXRcIiA6IFwiaGlkZVwiKSldKChzaG93QW5pbSA/IGR1cmF0aW9uIDogbnVsbCksIHBvc3RQcm9jZXNzKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCFzaG93QW5pbSkge1xuXHRcdFx0XHRwb3N0UHJvY2VzcygpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5fZGF0ZXBpY2tlclNob3dpbmcgPSBmYWxzZTtcblxuXHRcdFx0b25DbG9zZSA9IHRoaXMuX2dldChpbnN0LCBcIm9uQ2xvc2VcIik7XG5cdFx0XHRpZiAob25DbG9zZSkge1xuXHRcdFx0XHRvbkNsb3NlLmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLCBbKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0LnZhbCgpIDogXCJcIiksIGluc3RdKTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5fbGFzdElucHV0ID0gbnVsbDtcblx0XHRcdGlmICh0aGlzLl9pbkRpYWxvZykge1xuXHRcdFx0XHR0aGlzLl9kaWFsb2dJbnB1dC5jc3MoeyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCBsZWZ0OiBcIjBcIiwgdG9wOiBcIi0xMDBweFwiIH0pO1xuXHRcdFx0XHRpZiAoJC5ibG9ja1VJKSB7XG5cdFx0XHRcdFx0JC51bmJsb2NrVUkoKTtcblx0XHRcdFx0XHQkKFwiYm9keVwiKS5hcHBlbmQodGhpcy5kcERpdik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMuX2luRGlhbG9nID0gZmFsc2U7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFRpZHkgdXAgYWZ0ZXIgYSBkaWFsb2cgZGlzcGxheS4gKi9cblx0X3RpZHlEaWFsb2c6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHRpbnN0LmRwRGl2LnJlbW92ZUNsYXNzKHRoaXMuX2RpYWxvZ0NsYXNzKS51bmJpbmQoXCIudWktZGF0ZXBpY2tlci1jYWxlbmRhclwiKTtcblx0fSxcblxuXHQvKiBDbG9zZSBkYXRlIHBpY2tlciBpZiBjbGlja2VkIGVsc2V3aGVyZS4gKi9cblx0X2NoZWNrRXh0ZXJuYWxDbGljazogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRpZiAoISQuZGF0ZXBpY2tlci5fY3VySW5zdCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciAkdGFyZ2V0ID0gJChldmVudC50YXJnZXQpLFxuXHRcdFx0aW5zdCA9ICQuZGF0ZXBpY2tlci5fZ2V0SW5zdCgkdGFyZ2V0WzBdKTtcblxuXHRcdGlmICggKCAoICR0YXJnZXRbMF0uaWQgIT09ICQuZGF0ZXBpY2tlci5fbWFpbkRpdklkICYmXG5cdFx0XHRcdCR0YXJnZXQucGFyZW50cyhcIiNcIiArICQuZGF0ZXBpY2tlci5fbWFpbkRpdklkKS5sZW5ndGggPT09IDAgJiZcblx0XHRcdFx0ISR0YXJnZXQuaGFzQ2xhc3MoJC5kYXRlcGlja2VyLm1hcmtlckNsYXNzTmFtZSkgJiZcblx0XHRcdFx0ISR0YXJnZXQuY2xvc2VzdChcIi5cIiArICQuZGF0ZXBpY2tlci5fdHJpZ2dlckNsYXNzKS5sZW5ndGggJiZcblx0XHRcdFx0JC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyAmJiAhKCQuZGF0ZXBpY2tlci5faW5EaWFsb2cgJiYgJC5ibG9ja1VJKSApICkgfHxcblx0XHRcdCggJHRhcmdldC5oYXNDbGFzcygkLmRhdGVwaWNrZXIubWFya2VyQ2xhc3NOYW1lKSAmJiAkLmRhdGVwaWNrZXIuX2N1ckluc3QgIT09IGluc3QgKSApIHtcblx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBBZGp1c3Qgb25lIG9mIHRoZSBkYXRlIHN1Yi1maWVsZHMuICovXG5cdF9hZGp1c3REYXRlOiBmdW5jdGlvbihpZCwgb2Zmc2V0LCBwZXJpb2QpIHtcblx0XHR2YXIgdGFyZ2V0ID0gJChpZCksXG5cdFx0XHRpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXRbMF0pO1xuXG5cdFx0aWYgKHRoaXMuX2lzRGlzYWJsZWREYXRlcGlja2VyKHRhcmdldFswXSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5fYWRqdXN0SW5zdERhdGUoaW5zdCwgb2Zmc2V0ICtcblx0XHRcdChwZXJpb2QgPT09IFwiTVwiID8gdGhpcy5fZ2V0KGluc3QsIFwic2hvd0N1cnJlbnRBdFBvc1wiKSA6IDApLCAvLyB1bmRvIHBvc2l0aW9uaW5nXG5cdFx0XHRwZXJpb2QpO1xuXHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdH0sXG5cblx0LyogQWN0aW9uIGZvciBjdXJyZW50IGxpbmsuICovXG5cdF9nb3RvVG9kYXk6IGZ1bmN0aW9uKGlkKSB7XG5cdFx0dmFyIGRhdGUsXG5cdFx0XHR0YXJnZXQgPSAkKGlkKSxcblx0XHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cblx0XHRpZiAodGhpcy5fZ2V0KGluc3QsIFwiZ290b0N1cnJlbnRcIikgJiYgaW5zdC5jdXJyZW50RGF5KSB7XG5cdFx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gaW5zdC5jdXJyZW50RGF5O1xuXHRcdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBpbnN0LmN1cnJlbnRNb250aDtcblx0XHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGluc3QuY3VycmVudFllYXI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGUgPSBuZXcgRGF0ZSgpO1xuXHRcdFx0aW5zdC5zZWxlY3RlZERheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBkYXRlLmdldE1vbnRoKCk7XG5cdFx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0fVxuXHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0XHR0aGlzLl9hZGp1c3REYXRlKHRhcmdldCk7XG5cdH0sXG5cblx0LyogQWN0aW9uIGZvciBzZWxlY3RpbmcgYSBuZXcgbW9udGgveWVhci4gKi9cblx0X3NlbGVjdE1vbnRoWWVhcjogZnVuY3Rpb24oaWQsIHNlbGVjdCwgcGVyaW9kKSB7XG5cdFx0dmFyIHRhcmdldCA9ICQoaWQpLFxuXHRcdFx0aW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblxuXHRcdGluc3RbXCJzZWxlY3RlZFwiICsgKHBlcmlvZCA9PT0gXCJNXCIgPyBcIk1vbnRoXCIgOiBcIlllYXJcIildID1cblx0XHRpbnN0W1wiZHJhd1wiICsgKHBlcmlvZCA9PT0gXCJNXCIgPyBcIk1vbnRoXCIgOiBcIlllYXJcIildID1cblx0XHRcdHBhcnNlSW50KHNlbGVjdC5vcHRpb25zW3NlbGVjdC5zZWxlY3RlZEluZGV4XS52YWx1ZSwxMCk7XG5cblx0XHR0aGlzLl9ub3RpZnlDaGFuZ2UoaW5zdCk7XG5cdFx0dGhpcy5fYWRqdXN0RGF0ZSh0YXJnZXQpO1xuXHR9LFxuXG5cdC8qIEFjdGlvbiBmb3Igc2VsZWN0aW5nIGEgZGF5LiAqL1xuXHRfc2VsZWN0RGF5OiBmdW5jdGlvbihpZCwgbW9udGgsIHllYXIsIHRkKSB7XG5cdFx0dmFyIGluc3QsXG5cdFx0XHR0YXJnZXQgPSAkKGlkKTtcblxuXHRcdGlmICgkKHRkKS5oYXNDbGFzcyh0aGlzLl91bnNlbGVjdGFibGVDbGFzcykgfHwgdGhpcy5faXNEaXNhYmxlZERhdGVwaWNrZXIodGFyZ2V0WzBdKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cdFx0aW5zdC5zZWxlY3RlZERheSA9IGluc3QuY3VycmVudERheSA9ICQoXCJhXCIsIHRkKS5odG1sKCk7XG5cdFx0aW5zdC5zZWxlY3RlZE1vbnRoID0gaW5zdC5jdXJyZW50TW9udGggPSBtb250aDtcblx0XHRpbnN0LnNlbGVjdGVkWWVhciA9IGluc3QuY3VycmVudFllYXIgPSB5ZWFyO1xuXHRcdHRoaXMuX3NlbGVjdERhdGUoaWQsIHRoaXMuX2Zvcm1hdERhdGUoaW5zdCxcblx0XHRcdGluc3QuY3VycmVudERheSwgaW5zdC5jdXJyZW50TW9udGgsIGluc3QuY3VycmVudFllYXIpKTtcblx0fSxcblxuXHQvKiBFcmFzZSB0aGUgaW5wdXQgZmllbGQgYW5kIGhpZGUgdGhlIGRhdGUgcGlja2VyLiAqL1xuXHRfY2xlYXJEYXRlOiBmdW5jdGlvbihpZCkge1xuXHRcdHZhciB0YXJnZXQgPSAkKGlkKTtcblx0XHR0aGlzLl9zZWxlY3REYXRlKHRhcmdldCwgXCJcIik7XG5cdH0sXG5cblx0LyogVXBkYXRlIHRoZSBpbnB1dCBmaWVsZCB3aXRoIHRoZSBzZWxlY3RlZCBkYXRlLiAqL1xuXHRfc2VsZWN0RGF0ZTogZnVuY3Rpb24oaWQsIGRhdGVTdHIpIHtcblx0XHR2YXIgb25TZWxlY3QsXG5cdFx0XHR0YXJnZXQgPSAkKGlkKSxcblx0XHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cblx0XHRkYXRlU3RyID0gKGRhdGVTdHIgIT0gbnVsbCA/IGRhdGVTdHIgOiB0aGlzLl9mb3JtYXREYXRlKGluc3QpKTtcblx0XHRpZiAoaW5zdC5pbnB1dCkge1xuXHRcdFx0aW5zdC5pbnB1dC52YWwoZGF0ZVN0cik7XG5cdFx0fVxuXHRcdHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblxuXHRcdG9uU2VsZWN0ID0gdGhpcy5fZ2V0KGluc3QsIFwib25TZWxlY3RcIik7XG5cdFx0aWYgKG9uU2VsZWN0KSB7XG5cdFx0XHRvblNlbGVjdC5hcHBseSgoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXRbMF0gOiBudWxsKSwgW2RhdGVTdHIsIGluc3RdKTsgIC8vIHRyaWdnZXIgY3VzdG9tIGNhbGxiYWNrXG5cdFx0fSBlbHNlIGlmIChpbnN0LmlucHV0KSB7XG5cdFx0XHRpbnN0LmlucHV0LnRyaWdnZXIoXCJjaGFuZ2VcIik7IC8vIGZpcmUgdGhlIGNoYW5nZSBldmVudFxuXHRcdH1cblxuXHRcdGlmIChpbnN0LmlubGluZSl7XG5cdFx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0dGhpcy5fbGFzdElucHV0ID0gaW5zdC5pbnB1dFswXTtcblx0XHRcdGlmICh0eXBlb2YoaW5zdC5pbnB1dFswXSkgIT09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0aW5zdC5pbnB1dC5mb2N1cygpOyAvLyByZXN0b3JlIGZvY3VzXG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9sYXN0SW5wdXQgPSBudWxsO1xuXHRcdH1cblx0fSxcblxuXHQvKiBVcGRhdGUgYW55IGFsdGVybmF0ZSBmaWVsZCB0byBzeW5jaHJvbmlzZSB3aXRoIHRoZSBtYWluIGZpZWxkLiAqL1xuXHRfdXBkYXRlQWx0ZXJuYXRlOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIGFsdEZvcm1hdCwgZGF0ZSwgZGF0ZVN0cixcblx0XHRcdGFsdEZpZWxkID0gdGhpcy5fZ2V0KGluc3QsIFwiYWx0RmllbGRcIik7XG5cblx0XHRpZiAoYWx0RmllbGQpIHsgLy8gdXBkYXRlIGFsdGVybmF0ZSBmaWVsZCB0b29cblx0XHRcdGFsdEZvcm1hdCA9IHRoaXMuX2dldChpbnN0LCBcImFsdEZvcm1hdFwiKSB8fCB0aGlzLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpO1xuXHRcdFx0ZGF0ZSA9IHRoaXMuX2dldERhdGUoaW5zdCk7XG5cdFx0XHRkYXRlU3RyID0gdGhpcy5mb3JtYXREYXRlKGFsdEZvcm1hdCwgZGF0ZSwgdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpKTtcblx0XHRcdCQoYWx0RmllbGQpLmVhY2goZnVuY3Rpb24oKSB7ICQodGhpcykudmFsKGRhdGVTdHIpOyB9KTtcblx0XHR9XG5cdH0sXG5cblx0LyogU2V0IGFzIGJlZm9yZVNob3dEYXkgZnVuY3Rpb24gdG8gcHJldmVudCBzZWxlY3Rpb24gb2Ygd2Vla2VuZHMuXG5cdCAqIEBwYXJhbSAgZGF0ZSAgRGF0ZSAtIHRoZSBkYXRlIHRvIGN1c3RvbWlzZVxuXHQgKiBAcmV0dXJuIFtib29sZWFuLCBzdHJpbmddIC0gaXMgdGhpcyBkYXRlIHNlbGVjdGFibGU/LCB3aGF0IGlzIGl0cyBDU1MgY2xhc3M/XG5cdCAqL1xuXHRub1dlZWtlbmRzOiBmdW5jdGlvbihkYXRlKSB7XG5cdFx0dmFyIGRheSA9IGRhdGUuZ2V0RGF5KCk7XG5cdFx0cmV0dXJuIFsoZGF5ID4gMCAmJiBkYXkgPCA2KSwgXCJcIl07XG5cdH0sXG5cblx0LyogU2V0IGFzIGNhbGN1bGF0ZVdlZWsgdG8gZGV0ZXJtaW5lIHRoZSB3ZWVrIG9mIHRoZSB5ZWFyIGJhc2VkIG9uIHRoZSBJU08gODYwMSBkZWZpbml0aW9uLlxuXHQgKiBAcGFyYW0gIGRhdGUgIERhdGUgLSB0aGUgZGF0ZSB0byBnZXQgdGhlIHdlZWsgZm9yXG5cdCAqIEByZXR1cm4gIG51bWJlciAtIHRoZSBudW1iZXIgb2YgdGhlIHdlZWsgd2l0aGluIHRoZSB5ZWFyIHRoYXQgY29udGFpbnMgdGhpcyBkYXRlXG5cdCAqL1xuXHRpc284NjAxV2VlazogZnVuY3Rpb24oZGF0ZSkge1xuXHRcdHZhciB0aW1lLFxuXHRcdFx0Y2hlY2tEYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpO1xuXG5cdFx0Ly8gRmluZCBUaHVyc2RheSBvZiB0aGlzIHdlZWsgc3RhcnRpbmcgb24gTW9uZGF5XG5cdFx0Y2hlY2tEYXRlLnNldERhdGUoY2hlY2tEYXRlLmdldERhdGUoKSArIDQgLSAoY2hlY2tEYXRlLmdldERheSgpIHx8IDcpKTtcblxuXHRcdHRpbWUgPSBjaGVja0RhdGUuZ2V0VGltZSgpO1xuXHRcdGNoZWNrRGF0ZS5zZXRNb250aCgwKTsgLy8gQ29tcGFyZSB3aXRoIEphbiAxXG5cdFx0Y2hlY2tEYXRlLnNldERhdGUoMSk7XG5cdFx0cmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yb3VuZCgodGltZSAtIGNoZWNrRGF0ZSkgLyA4NjQwMDAwMCkgLyA3KSArIDE7XG5cdH0sXG5cblx0LyogUGFyc2UgYSBzdHJpbmcgdmFsdWUgaW50byBhIGRhdGUgb2JqZWN0LlxuXHQgKiBTZWUgZm9ybWF0RGF0ZSBiZWxvdyBmb3IgdGhlIHBvc3NpYmxlIGZvcm1hdHMuXG5cdCAqXG5cdCAqIEBwYXJhbSAgZm9ybWF0IHN0cmluZyAtIHRoZSBleHBlY3RlZCBmb3JtYXQgb2YgdGhlIGRhdGVcblx0ICogQHBhcmFtICB2YWx1ZSBzdHJpbmcgLSB0aGUgZGF0ZSBpbiB0aGUgYWJvdmUgZm9ybWF0XG5cdCAqIEBwYXJhbSAgc2V0dGluZ3MgT2JqZWN0IC0gYXR0cmlidXRlcyBpbmNsdWRlOlxuXHQgKlx0XHRcdFx0XHRzaG9ydFllYXJDdXRvZmYgIG51bWJlciAtIHRoZSBjdXRvZmYgeWVhciBmb3IgZGV0ZXJtaW5pbmcgdGhlIGNlbnR1cnkgKG9wdGlvbmFsKVxuXHQgKlx0XHRcdFx0XHRkYXlOYW1lc1Nob3J0XHRzdHJpbmdbN10gLSBhYmJyZXZpYXRlZCBuYW1lcyBvZiB0aGUgZGF5cyBmcm9tIFN1bmRheSAob3B0aW9uYWwpXG5cdCAqXHRcdFx0XHRcdGRheU5hbWVzXHRcdHN0cmluZ1s3XSAtIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0bW9udGhOYW1lc1Nob3J0IHN0cmluZ1sxMl0gLSBhYmJyZXZpYXRlZCBuYW1lcyBvZiB0aGUgbW9udGhzIChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0bW9udGhOYW1lc1x0XHRzdHJpbmdbMTJdIC0gbmFtZXMgb2YgdGhlIG1vbnRocyAob3B0aW9uYWwpXG5cdCAqIEByZXR1cm4gIERhdGUgLSB0aGUgZXh0cmFjdGVkIGRhdGUgdmFsdWUgb3IgbnVsbCBpZiB2YWx1ZSBpcyBibGFua1xuXHQgKi9cblx0cGFyc2VEYXRlOiBmdW5jdGlvbiAoZm9ybWF0LCB2YWx1ZSwgc2V0dGluZ3MpIHtcblx0XHRpZiAoZm9ybWF0ID09IG51bGwgfHwgdmFsdWUgPT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgXCJJbnZhbGlkIGFyZ3VtZW50c1wiO1xuXHRcdH1cblxuXHRcdHZhbHVlID0gKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiA/IHZhbHVlLnRvU3RyaW5nKCkgOiB2YWx1ZSArIFwiXCIpO1xuXHRcdGlmICh2YWx1ZSA9PT0gXCJcIikge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0dmFyIGlGb3JtYXQsIGRpbSwgZXh0cmEsXG5cdFx0XHRpVmFsdWUgPSAwLFxuXHRcdFx0c2hvcnRZZWFyQ3V0b2ZmVGVtcCA9IChzZXR0aW5ncyA/IHNldHRpbmdzLnNob3J0WWVhckN1dG9mZiA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLnNob3J0WWVhckN1dG9mZixcblx0XHRcdHNob3J0WWVhckN1dG9mZiA9ICh0eXBlb2Ygc2hvcnRZZWFyQ3V0b2ZmVGVtcCAhPT0gXCJzdHJpbmdcIiA/IHNob3J0WWVhckN1dG9mZlRlbXAgOlxuXHRcdFx0XHRuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgJSAxMDAgKyBwYXJzZUludChzaG9ydFllYXJDdXRvZmZUZW1wLCAxMCkpLFxuXHRcdFx0ZGF5TmFtZXNTaG9ydCA9IChzZXR0aW5ncyA/IHNldHRpbmdzLmRheU5hbWVzU2hvcnQgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5kYXlOYW1lc1Nob3J0LFxuXHRcdFx0ZGF5TmFtZXMgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5kYXlOYW1lcyA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzLFxuXHRcdFx0bW9udGhOYW1lc1Nob3J0ID0gKHNldHRpbmdzID8gc2V0dGluZ3MubW9udGhOYW1lc1Nob3J0IDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMubW9udGhOYW1lc1Nob3J0LFxuXHRcdFx0bW9udGhOYW1lcyA9IChzZXR0aW5ncyA/IHNldHRpbmdzLm1vbnRoTmFtZXMgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzLFxuXHRcdFx0eWVhciA9IC0xLFxuXHRcdFx0bW9udGggPSAtMSxcblx0XHRcdGRheSA9IC0xLFxuXHRcdFx0ZG95ID0gLTEsXG5cdFx0XHRsaXRlcmFsID0gZmFsc2UsXG5cdFx0XHRkYXRlLFxuXHRcdFx0Ly8gQ2hlY2sgd2hldGhlciBhIGZvcm1hdCBjaGFyYWN0ZXIgaXMgZG91YmxlZFxuXHRcdFx0bG9va0FoZWFkID0gZnVuY3Rpb24obWF0Y2gpIHtcblx0XHRcdFx0dmFyIG1hdGNoZXMgPSAoaUZvcm1hdCArIDEgPCBmb3JtYXQubGVuZ3RoICYmIGZvcm1hdC5jaGFyQXQoaUZvcm1hdCArIDEpID09PSBtYXRjaCk7XG5cdFx0XHRcdGlmIChtYXRjaGVzKSB7XG5cdFx0XHRcdFx0aUZvcm1hdCsrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBtYXRjaGVzO1xuXHRcdFx0fSxcblx0XHRcdC8vIEV4dHJhY3QgYSBudW1iZXIgZnJvbSB0aGUgc3RyaW5nIHZhbHVlXG5cdFx0XHRnZXROdW1iZXIgPSBmdW5jdGlvbihtYXRjaCkge1xuXHRcdFx0XHR2YXIgaXNEb3VibGVkID0gbG9va0FoZWFkKG1hdGNoKSxcblx0XHRcdFx0XHRzaXplID0gKG1hdGNoID09PSBcIkBcIiA/IDE0IDogKG1hdGNoID09PSBcIiFcIiA/IDIwIDpcblx0XHRcdFx0XHQobWF0Y2ggPT09IFwieVwiICYmIGlzRG91YmxlZCA/IDQgOiAobWF0Y2ggPT09IFwib1wiID8gMyA6IDIpKSkpLFxuXHRcdFx0XHRcdGRpZ2l0cyA9IG5ldyBSZWdFeHAoXCJeXFxcXGR7MSxcIiArIHNpemUgKyBcIn1cIiksXG5cdFx0XHRcdFx0bnVtID0gdmFsdWUuc3Vic3RyaW5nKGlWYWx1ZSkubWF0Y2goZGlnaXRzKTtcblx0XHRcdFx0aWYgKCFudW0pIHtcblx0XHRcdFx0XHR0aHJvdyBcIk1pc3NpbmcgbnVtYmVyIGF0IHBvc2l0aW9uIFwiICsgaVZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlWYWx1ZSArPSBudW1bMF0ubGVuZ3RoO1xuXHRcdFx0XHRyZXR1cm4gcGFyc2VJbnQobnVtWzBdLCAxMCk7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gRXh0cmFjdCBhIG5hbWUgZnJvbSB0aGUgc3RyaW5nIHZhbHVlIGFuZCBjb252ZXJ0IHRvIGFuIGluZGV4XG5cdFx0XHRnZXROYW1lID0gZnVuY3Rpb24obWF0Y2gsIHNob3J0TmFtZXMsIGxvbmdOYW1lcykge1xuXHRcdFx0XHR2YXIgaW5kZXggPSAtMSxcblx0XHRcdFx0XHRuYW1lcyA9ICQubWFwKGxvb2tBaGVhZChtYXRjaCkgPyBsb25nTmFtZXMgOiBzaG9ydE5hbWVzLCBmdW5jdGlvbiAodiwgaykge1xuXHRcdFx0XHRcdFx0cmV0dXJuIFsgW2ssIHZdIF07XG5cdFx0XHRcdFx0fSkuc29ydChmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0XHRcdFx0cmV0dXJuIC0oYVsxXS5sZW5ndGggLSBiWzFdLmxlbmd0aCk7XG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0JC5lYWNoKG5hbWVzLCBmdW5jdGlvbiAoaSwgcGFpcikge1xuXHRcdFx0XHRcdHZhciBuYW1lID0gcGFpclsxXTtcblx0XHRcdFx0XHRpZiAodmFsdWUuc3Vic3RyKGlWYWx1ZSwgbmFtZS5sZW5ndGgpLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKSkge1xuXHRcdFx0XHRcdFx0aW5kZXggPSBwYWlyWzBdO1xuXHRcdFx0XHRcdFx0aVZhbHVlICs9IG5hbWUubGVuZ3RoO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGlmIChpbmRleCAhPT0gLTEpIHtcblx0XHRcdFx0XHRyZXR1cm4gaW5kZXggKyAxO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRocm93IFwiVW5rbm93biBuYW1lIGF0IHBvc2l0aW9uIFwiICsgaVZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ29uZmlybSB0aGF0IGEgbGl0ZXJhbCBjaGFyYWN0ZXIgbWF0Y2hlcyB0aGUgc3RyaW5nIHZhbHVlXG5cdFx0XHRjaGVja0xpdGVyYWwgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKHZhbHVlLmNoYXJBdChpVmFsdWUpICE9PSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpKSB7XG5cdFx0XHRcdFx0dGhyb3cgXCJVbmV4cGVjdGVkIGxpdGVyYWwgYXQgcG9zaXRpb24gXCIgKyBpVmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0aVZhbHVlKys7XG5cdFx0XHR9O1xuXG5cdFx0Zm9yIChpRm9ybWF0ID0gMDsgaUZvcm1hdCA8IGZvcm1hdC5sZW5ndGg7IGlGb3JtYXQrKykge1xuXHRcdFx0aWYgKGxpdGVyYWwpIHtcblx0XHRcdFx0aWYgKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkgPT09IFwiJ1wiICYmICFsb29rQWhlYWQoXCInXCIpKSB7XG5cdFx0XHRcdFx0bGl0ZXJhbCA9IGZhbHNlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNoZWNrTGl0ZXJhbCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzd2l0Y2ggKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkpIHtcblx0XHRcdFx0XHRjYXNlIFwiZFwiOlxuXHRcdFx0XHRcdFx0ZGF5ID0gZ2V0TnVtYmVyKFwiZFwiKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJEXCI6XG5cdFx0XHRcdFx0XHRnZXROYW1lKFwiRFwiLCBkYXlOYW1lc1Nob3J0LCBkYXlOYW1lcyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwib1wiOlxuXHRcdFx0XHRcdFx0ZG95ID0gZ2V0TnVtYmVyKFwib1wiKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJtXCI6XG5cdFx0XHRcdFx0XHRtb250aCA9IGdldE51bWJlcihcIm1cIik7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwiTVwiOlxuXHRcdFx0XHRcdFx0bW9udGggPSBnZXROYW1lKFwiTVwiLCBtb250aE5hbWVzU2hvcnQsIG1vbnRoTmFtZXMpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcInlcIjpcblx0XHRcdFx0XHRcdHllYXIgPSBnZXROdW1iZXIoXCJ5XCIpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIkBcIjpcblx0XHRcdFx0XHRcdGRhdGUgPSBuZXcgRGF0ZShnZXROdW1iZXIoXCJAXCIpKTtcblx0XHRcdFx0XHRcdHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0XHRcdFx0XHRtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7XG5cdFx0XHRcdFx0XHRkYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCIhXCI6XG5cdFx0XHRcdFx0XHRkYXRlID0gbmV3IERhdGUoKGdldE51bWJlcihcIiFcIikgLSB0aGlzLl90aWNrc1RvMTk3MCkgLyAxMDAwMCk7XG5cdFx0XHRcdFx0XHR5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuXHRcdFx0XHRcdFx0bW9udGggPSBkYXRlLmdldE1vbnRoKCkgKyAxO1xuXHRcdFx0XHRcdFx0ZGF5ID0gZGF0ZS5nZXREYXRlKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwiJ1wiOlxuXHRcdFx0XHRcdFx0aWYgKGxvb2tBaGVhZChcIidcIikpe1xuXHRcdFx0XHRcdFx0XHRjaGVja0xpdGVyYWwoKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGxpdGVyYWwgPSB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdGNoZWNrTGl0ZXJhbCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGlWYWx1ZSA8IHZhbHVlLmxlbmd0aCl7XG5cdFx0XHRleHRyYSA9IHZhbHVlLnN1YnN0cihpVmFsdWUpO1xuXHRcdFx0aWYgKCEvXlxccysvLnRlc3QoZXh0cmEpKSB7XG5cdFx0XHRcdHRocm93IFwiRXh0cmEvdW5wYXJzZWQgY2hhcmFjdGVycyBmb3VuZCBpbiBkYXRlOiBcIiArIGV4dHJhO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICh5ZWFyID09PSAtMSkge1xuXHRcdFx0eWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0XHR9IGVsc2UgaWYgKHllYXIgPCAxMDApIHtcblx0XHRcdHllYXIgKz0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpIC0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpICUgMTAwICtcblx0XHRcdFx0KHllYXIgPD0gc2hvcnRZZWFyQ3V0b2ZmID8gMCA6IC0xMDApO1xuXHRcdH1cblxuXHRcdGlmIChkb3kgPiAtMSkge1xuXHRcdFx0bW9udGggPSAxO1xuXHRcdFx0ZGF5ID0gZG95O1xuXHRcdFx0ZG8ge1xuXHRcdFx0XHRkaW0gPSB0aGlzLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCAtIDEpO1xuXHRcdFx0XHRpZiAoZGF5IDw9IGRpbSkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG1vbnRoKys7XG5cdFx0XHRcdGRheSAtPSBkaW07XG5cdFx0XHR9IHdoaWxlICh0cnVlKTtcblx0XHR9XG5cblx0XHRkYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoeWVhciwgbW9udGggLSAxLCBkYXkpKTtcblx0XHRpZiAoZGF0ZS5nZXRGdWxsWWVhcigpICE9PSB5ZWFyIHx8IGRhdGUuZ2V0TW9udGgoKSArIDEgIT09IG1vbnRoIHx8IGRhdGUuZ2V0RGF0ZSgpICE9PSBkYXkpIHtcblx0XHRcdHRocm93IFwiSW52YWxpZCBkYXRlXCI7IC8vIEUuZy4gMzEvMDIvMDBcblx0XHR9XG5cdFx0cmV0dXJuIGRhdGU7XG5cdH0sXG5cblx0LyogU3RhbmRhcmQgZGF0ZSBmb3JtYXRzLiAqL1xuXHRBVE9NOiBcInl5LW1tLWRkXCIsIC8vIFJGQyAzMzM5IChJU08gODYwMSlcblx0Q09PS0lFOiBcIkQsIGRkIE0geXlcIixcblx0SVNPXzg2MDE6IFwieXktbW0tZGRcIixcblx0UkZDXzgyMjogXCJELCBkIE0geVwiLFxuXHRSRkNfODUwOiBcIkRELCBkZC1NLXlcIixcblx0UkZDXzEwMzY6IFwiRCwgZCBNIHlcIixcblx0UkZDXzExMjM6IFwiRCwgZCBNIHl5XCIsXG5cdFJGQ18yODIyOiBcIkQsIGQgTSB5eVwiLFxuXHRSU1M6IFwiRCwgZCBNIHlcIiwgLy8gUkZDIDgyMlxuXHRUSUNLUzogXCIhXCIsXG5cdFRJTUVTVEFNUDogXCJAXCIsXG5cdFczQzogXCJ5eS1tbS1kZFwiLCAvLyBJU08gODYwMVxuXG5cdF90aWNrc1RvMTk3MDogKCgoMTk3MCAtIDEpICogMzY1ICsgTWF0aC5mbG9vcigxOTcwIC8gNCkgLSBNYXRoLmZsb29yKDE5NzAgLyAxMDApICtcblx0XHRNYXRoLmZsb29yKDE5NzAgLyA0MDApKSAqIDI0ICogNjAgKiA2MCAqIDEwMDAwMDAwKSxcblxuXHQvKiBGb3JtYXQgYSBkYXRlIG9iamVjdCBpbnRvIGEgc3RyaW5nIHZhbHVlLlxuXHQgKiBUaGUgZm9ybWF0IGNhbiBiZSBjb21iaW5hdGlvbnMgb2YgdGhlIGZvbGxvd2luZzpcblx0ICogZCAgLSBkYXkgb2YgbW9udGggKG5vIGxlYWRpbmcgemVybylcblx0ICogZGQgLSBkYXkgb2YgbW9udGggKHR3byBkaWdpdClcblx0ICogbyAgLSBkYXkgb2YgeWVhciAobm8gbGVhZGluZyB6ZXJvcylcblx0ICogb28gLSBkYXkgb2YgeWVhciAodGhyZWUgZGlnaXQpXG5cdCAqIEQgIC0gZGF5IG5hbWUgc2hvcnRcblx0ICogREQgLSBkYXkgbmFtZSBsb25nXG5cdCAqIG0gIC0gbW9udGggb2YgeWVhciAobm8gbGVhZGluZyB6ZXJvKVxuXHQgKiBtbSAtIG1vbnRoIG9mIHllYXIgKHR3byBkaWdpdClcblx0ICogTSAgLSBtb250aCBuYW1lIHNob3J0XG5cdCAqIE1NIC0gbW9udGggbmFtZSBsb25nXG5cdCAqIHkgIC0geWVhciAodHdvIGRpZ2l0KVxuXHQgKiB5eSAtIHllYXIgKGZvdXIgZGlnaXQpXG5cdCAqIEAgLSBVbml4IHRpbWVzdGFtcCAobXMgc2luY2UgMDEvMDEvMTk3MClcblx0ICogISAtIFdpbmRvd3MgdGlja3MgKDEwMG5zIHNpbmNlIDAxLzAxLzAwMDEpXG5cdCAqIFwiLi4uXCIgLSBsaXRlcmFsIHRleHRcblx0ICogJycgLSBzaW5nbGUgcXVvdGVcblx0ICpcblx0ICogQHBhcmFtICBmb3JtYXQgc3RyaW5nIC0gdGhlIGRlc2lyZWQgZm9ybWF0IG9mIHRoZSBkYXRlXG5cdCAqIEBwYXJhbSAgZGF0ZSBEYXRlIC0gdGhlIGRhdGUgdmFsdWUgdG8gZm9ybWF0XG5cdCAqIEBwYXJhbSAgc2V0dGluZ3MgT2JqZWN0IC0gYXR0cmlidXRlcyBpbmNsdWRlOlxuXHQgKlx0XHRcdFx0XHRkYXlOYW1lc1Nob3J0XHRzdHJpbmdbN10gLSBhYmJyZXZpYXRlZCBuYW1lcyBvZiB0aGUgZGF5cyBmcm9tIFN1bmRheSAob3B0aW9uYWwpXG5cdCAqXHRcdFx0XHRcdGRheU5hbWVzXHRcdHN0cmluZ1s3XSAtIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0bW9udGhOYW1lc1Nob3J0IHN0cmluZ1sxMl0gLSBhYmJyZXZpYXRlZCBuYW1lcyBvZiB0aGUgbW9udGhzIChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0bW9udGhOYW1lc1x0XHRzdHJpbmdbMTJdIC0gbmFtZXMgb2YgdGhlIG1vbnRocyAob3B0aW9uYWwpXG5cdCAqIEByZXR1cm4gIHN0cmluZyAtIHRoZSBkYXRlIGluIHRoZSBhYm92ZSBmb3JtYXRcblx0ICovXG5cdGZvcm1hdERhdGU6IGZ1bmN0aW9uIChmb3JtYXQsIGRhdGUsIHNldHRpbmdzKSB7XG5cdFx0aWYgKCFkYXRlKSB7XG5cdFx0XHRyZXR1cm4gXCJcIjtcblx0XHR9XG5cblx0XHR2YXIgaUZvcm1hdCxcblx0XHRcdGRheU5hbWVzU2hvcnQgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5kYXlOYW1lc1Nob3J0IDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMuZGF5TmFtZXNTaG9ydCxcblx0XHRcdGRheU5hbWVzID0gKHNldHRpbmdzID8gc2V0dGluZ3MuZGF5TmFtZXMgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5kYXlOYW1lcyxcblx0XHRcdG1vbnRoTmFtZXNTaG9ydCA9IChzZXR0aW5ncyA/IHNldHRpbmdzLm1vbnRoTmFtZXNTaG9ydCA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXNTaG9ydCxcblx0XHRcdG1vbnRoTmFtZXMgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5tb250aE5hbWVzIDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMubW9udGhOYW1lcyxcblx0XHRcdC8vIENoZWNrIHdoZXRoZXIgYSBmb3JtYXQgY2hhcmFjdGVyIGlzIGRvdWJsZWRcblx0XHRcdGxvb2tBaGVhZCA9IGZ1bmN0aW9uKG1hdGNoKSB7XG5cdFx0XHRcdHZhciBtYXRjaGVzID0gKGlGb3JtYXQgKyAxIDwgZm9ybWF0Lmxlbmd0aCAmJiBmb3JtYXQuY2hhckF0KGlGb3JtYXQgKyAxKSA9PT0gbWF0Y2gpO1xuXHRcdFx0XHRpZiAobWF0Y2hlcykge1xuXHRcdFx0XHRcdGlGb3JtYXQrKztcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gbWF0Y2hlcztcblx0XHRcdH0sXG5cdFx0XHQvLyBGb3JtYXQgYSBudW1iZXIsIHdpdGggbGVhZGluZyB6ZXJvIGlmIG5lY2Vzc2FyeVxuXHRcdFx0Zm9ybWF0TnVtYmVyID0gZnVuY3Rpb24obWF0Y2gsIHZhbHVlLCBsZW4pIHtcblx0XHRcdFx0dmFyIG51bSA9IFwiXCIgKyB2YWx1ZTtcblx0XHRcdFx0aWYgKGxvb2tBaGVhZChtYXRjaCkpIHtcblx0XHRcdFx0XHR3aGlsZSAobnVtLmxlbmd0aCA8IGxlbikge1xuXHRcdFx0XHRcdFx0bnVtID0gXCIwXCIgKyBudW07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBudW07XG5cdFx0XHR9LFxuXHRcdFx0Ly8gRm9ybWF0IGEgbmFtZSwgc2hvcnQgb3IgbG9uZyBhcyByZXF1ZXN0ZWRcblx0XHRcdGZvcm1hdE5hbWUgPSBmdW5jdGlvbihtYXRjaCwgdmFsdWUsIHNob3J0TmFtZXMsIGxvbmdOYW1lcykge1xuXHRcdFx0XHRyZXR1cm4gKGxvb2tBaGVhZChtYXRjaCkgPyBsb25nTmFtZXNbdmFsdWVdIDogc2hvcnROYW1lc1t2YWx1ZV0pO1xuXHRcdFx0fSxcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHRsaXRlcmFsID0gZmFsc2U7XG5cblx0XHRpZiAoZGF0ZSkge1xuXHRcdFx0Zm9yIChpRm9ybWF0ID0gMDsgaUZvcm1hdCA8IGZvcm1hdC5sZW5ndGg7IGlGb3JtYXQrKykge1xuXHRcdFx0XHRpZiAobGl0ZXJhbCkge1xuXHRcdFx0XHRcdGlmIChmb3JtYXQuY2hhckF0KGlGb3JtYXQpID09PSBcIidcIiAmJiAhbG9va0FoZWFkKFwiJ1wiKSkge1xuXHRcdFx0XHRcdFx0bGl0ZXJhbCA9IGZhbHNlO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0LmNoYXJBdChpRm9ybWF0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3dpdGNoIChmb3JtYXQuY2hhckF0KGlGb3JtYXQpKSB7XG5cdFx0XHRcdFx0XHRjYXNlIFwiZFwiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TnVtYmVyKFwiZFwiLCBkYXRlLmdldERhdGUoKSwgMik7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIkRcIjpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IGZvcm1hdE5hbWUoXCJEXCIsIGRhdGUuZ2V0RGF5KCksIGRheU5hbWVzU2hvcnQsIGRheU5hbWVzKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwib1wiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TnVtYmVyKFwib1wiLFxuXHRcdFx0XHRcdFx0XHRcdE1hdGgucm91bmQoKG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSkuZ2V0VGltZSgpIC0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCAwLCAwKS5nZXRUaW1lKCkpIC8gODY0MDAwMDApLCAzKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwibVwiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TnVtYmVyKFwibVwiLCBkYXRlLmdldE1vbnRoKCkgKyAxLCAyKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwiTVwiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TmFtZShcIk1cIiwgZGF0ZS5nZXRNb250aCgpLCBtb250aE5hbWVzU2hvcnQsIG1vbnRoTmFtZXMpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJ5XCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSAobG9va0FoZWFkKFwieVwiKSA/IGRhdGUuZ2V0RnVsbFllYXIoKSA6XG5cdFx0XHRcdFx0XHRcdFx0KGRhdGUuZ2V0WWVhcigpICUgMTAwIDwgMTAgPyBcIjBcIiA6IFwiXCIpICsgZGF0ZS5nZXRZZWFyKCkgJSAxMDApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJAXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBkYXRlLmdldFRpbWUoKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwiIVwiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZGF0ZS5nZXRUaW1lKCkgKiAxMDAwMCArIHRoaXMuX3RpY2tzVG8xOTcwO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCInXCI6XG5cdFx0XHRcdFx0XHRcdGlmIChsb29rQWhlYWQoXCInXCIpKSB7XG5cdFx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IFwiJ1wiO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGxpdGVyYWwgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IGZvcm1hdC5jaGFyQXQoaUZvcm1hdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH0sXG5cblx0LyogRXh0cmFjdCBhbGwgcG9zc2libGUgY2hhcmFjdGVycyBmcm9tIHRoZSBkYXRlIGZvcm1hdC4gKi9cblx0X3Bvc3NpYmxlQ2hhcnM6IGZ1bmN0aW9uIChmb3JtYXQpIHtcblx0XHR2YXIgaUZvcm1hdCxcblx0XHRcdGNoYXJzID0gXCJcIixcblx0XHRcdGxpdGVyYWwgPSBmYWxzZSxcblx0XHRcdC8vIENoZWNrIHdoZXRoZXIgYSBmb3JtYXQgY2hhcmFjdGVyIGlzIGRvdWJsZWRcblx0XHRcdGxvb2tBaGVhZCA9IGZ1bmN0aW9uKG1hdGNoKSB7XG5cdFx0XHRcdHZhciBtYXRjaGVzID0gKGlGb3JtYXQgKyAxIDwgZm9ybWF0Lmxlbmd0aCAmJiBmb3JtYXQuY2hhckF0KGlGb3JtYXQgKyAxKSA9PT0gbWF0Y2gpO1xuXHRcdFx0XHRpZiAobWF0Y2hlcykge1xuXHRcdFx0XHRcdGlGb3JtYXQrKztcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gbWF0Y2hlcztcblx0XHRcdH07XG5cblx0XHRmb3IgKGlGb3JtYXQgPSAwOyBpRm9ybWF0IDwgZm9ybWF0Lmxlbmd0aDsgaUZvcm1hdCsrKSB7XG5cdFx0XHRpZiAobGl0ZXJhbCkge1xuXHRcdFx0XHRpZiAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSA9PT0gXCInXCIgJiYgIWxvb2tBaGVhZChcIidcIikpIHtcblx0XHRcdFx0XHRsaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y2hhcnMgKz0gZm9ybWF0LmNoYXJBdChpRm9ybWF0KTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c3dpdGNoIChmb3JtYXQuY2hhckF0KGlGb3JtYXQpKSB7XG5cdFx0XHRcdFx0Y2FzZSBcImRcIjogY2FzZSBcIm1cIjogY2FzZSBcInlcIjogY2FzZSBcIkBcIjpcblx0XHRcdFx0XHRcdGNoYXJzICs9IFwiMDEyMzQ1Njc4OVwiO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIkRcIjogY2FzZSBcIk1cIjpcblx0XHRcdFx0XHRcdHJldHVybiBudWxsOyAvLyBBY2NlcHQgYW55dGhpbmdcblx0XHRcdFx0XHRjYXNlIFwiJ1wiOlxuXHRcdFx0XHRcdFx0aWYgKGxvb2tBaGVhZChcIidcIikpIHtcblx0XHRcdFx0XHRcdFx0Y2hhcnMgKz0gXCInXCI7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRsaXRlcmFsID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0XHRjaGFycyArPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBjaGFycztcblx0fSxcblxuXHQvKiBHZXQgYSBzZXR0aW5nIHZhbHVlLCBkZWZhdWx0aW5nIGlmIG5lY2Vzc2FyeS4gKi9cblx0X2dldDogZnVuY3Rpb24oaW5zdCwgbmFtZSkge1xuXHRcdHJldHVybiBpbnN0LnNldHRpbmdzW25hbWVdICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0aW5zdC5zZXR0aW5nc1tuYW1lXSA6IHRoaXMuX2RlZmF1bHRzW25hbWVdO1xuXHR9LFxuXG5cdC8qIFBhcnNlIGV4aXN0aW5nIGRhdGUgYW5kIGluaXRpYWxpc2UgZGF0ZSBwaWNrZXIuICovXG5cdF9zZXREYXRlRnJvbUZpZWxkOiBmdW5jdGlvbihpbnN0LCBub0RlZmF1bHQpIHtcblx0XHRpZiAoaW5zdC5pbnB1dC52YWwoKSA9PT0gaW5zdC5sYXN0VmFsKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIGRhdGVGb3JtYXQgPSB0aGlzLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpLFxuXHRcdFx0ZGF0ZXMgPSBpbnN0Lmxhc3RWYWwgPSBpbnN0LmlucHV0ID8gaW5zdC5pbnB1dC52YWwoKSA6IG51bGwsXG5cdFx0XHRkZWZhdWx0RGF0ZSA9IHRoaXMuX2dldERlZmF1bHREYXRlKGluc3QpLFxuXHRcdFx0ZGF0ZSA9IGRlZmF1bHREYXRlLFxuXHRcdFx0c2V0dGluZ3MgPSB0aGlzLl9nZXRGb3JtYXRDb25maWcoaW5zdCk7XG5cblx0XHR0cnkge1xuXHRcdFx0ZGF0ZSA9IHRoaXMucGFyc2VEYXRlKGRhdGVGb3JtYXQsIGRhdGVzLCBzZXR0aW5ncykgfHwgZGVmYXVsdERhdGU7XG5cdFx0fSBjYXRjaCAoZXZlbnQpIHtcblx0XHRcdGRhdGVzID0gKG5vRGVmYXVsdCA/IFwiXCIgOiBkYXRlcyk7XG5cdFx0fVxuXHRcdGluc3Quc2VsZWN0ZWREYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTtcblx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0aW5zdC5jdXJyZW50RGF5ID0gKGRhdGVzID8gZGF0ZS5nZXREYXRlKCkgOiAwKTtcblx0XHRpbnN0LmN1cnJlbnRNb250aCA9IChkYXRlcyA/IGRhdGUuZ2V0TW9udGgoKSA6IDApO1xuXHRcdGluc3QuY3VycmVudFllYXIgPSAoZGF0ZXMgPyBkYXRlLmdldEZ1bGxZZWFyKCkgOiAwKTtcblx0XHR0aGlzLl9hZGp1c3RJbnN0RGF0ZShpbnN0KTtcblx0fSxcblxuXHQvKiBSZXRyaWV2ZSB0aGUgZGVmYXVsdCBkYXRlIHNob3duIG9uIG9wZW5pbmcuICovXG5cdF9nZXREZWZhdWx0RGF0ZTogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHJldHVybiB0aGlzLl9yZXN0cmljdE1pbk1heChpbnN0LFxuXHRcdFx0dGhpcy5fZGV0ZXJtaW5lRGF0ZShpbnN0LCB0aGlzLl9nZXQoaW5zdCwgXCJkZWZhdWx0RGF0ZVwiKSwgbmV3IERhdGUoKSkpO1xuXHR9LFxuXG5cdC8qIEEgZGF0ZSBtYXkgYmUgc3BlY2lmaWVkIGFzIGFuIGV4YWN0IHZhbHVlIG9yIGEgcmVsYXRpdmUgb25lLiAqL1xuXHRfZGV0ZXJtaW5lRGF0ZTogZnVuY3Rpb24oaW5zdCwgZGF0ZSwgZGVmYXVsdERhdGUpIHtcblx0XHR2YXIgb2Zmc2V0TnVtZXJpYyA9IGZ1bmN0aW9uKG9mZnNldCkge1xuXHRcdFx0XHR2YXIgZGF0ZSA9IG5ldyBEYXRlKCk7XG5cdFx0XHRcdGRhdGUuc2V0RGF0ZShkYXRlLmdldERhdGUoKSArIG9mZnNldCk7XG5cdFx0XHRcdHJldHVybiBkYXRlO1xuXHRcdFx0fSxcblx0XHRcdG9mZnNldFN0cmluZyA9IGZ1bmN0aW9uKG9mZnNldCkge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHJldHVybiAkLmRhdGVwaWNrZXIucGFyc2VEYXRlKCQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwiZGF0ZUZvcm1hdFwiKSxcblx0XHRcdFx0XHRcdG9mZnNldCwgJC5kYXRlcGlja2VyLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0Ly8gSWdub3JlXG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgZGF0ZSA9IChvZmZzZXQudG9Mb3dlckNhc2UoKS5tYXRjaCgvXmMvKSA/XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9nZXREYXRlKGluc3QpIDogbnVsbCkgfHwgbmV3IERhdGUoKSxcblx0XHRcdFx0XHR5ZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpLFxuXHRcdFx0XHRcdG1vbnRoID0gZGF0ZS5nZXRNb250aCgpLFxuXHRcdFx0XHRcdGRheSA9IGRhdGUuZ2V0RGF0ZSgpLFxuXHRcdFx0XHRcdHBhdHRlcm4gPSAvKFsrXFwtXT9bMC05XSspXFxzKihkfER8d3xXfG18TXx5fFkpPy9nLFxuXHRcdFx0XHRcdG1hdGNoZXMgPSBwYXR0ZXJuLmV4ZWMob2Zmc2V0KTtcblxuXHRcdFx0XHR3aGlsZSAobWF0Y2hlcykge1xuXHRcdFx0XHRcdHN3aXRjaCAobWF0Y2hlc1syXSB8fCBcImRcIikge1xuXHRcdFx0XHRcdFx0Y2FzZSBcImRcIiA6IGNhc2UgXCJEXCIgOlxuXHRcdFx0XHRcdFx0XHRkYXkgKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCk7IGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIndcIiA6IGNhc2UgXCJXXCIgOlxuXHRcdFx0XHRcdFx0XHRkYXkgKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCkgKiA3OyBicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJtXCIgOiBjYXNlIFwiTVwiIDpcblx0XHRcdFx0XHRcdFx0bW9udGggKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCk7XG5cdFx0XHRcdFx0XHRcdGRheSA9IE1hdGgubWluKGRheSwgJC5kYXRlcGlja2VyLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCkpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJ5XCI6IGNhc2UgXCJZXCIgOlxuXHRcdFx0XHRcdFx0XHR5ZWFyICs9IHBhcnNlSW50KG1hdGNoZXNbMV0sMTApO1xuXHRcdFx0XHRcdFx0XHRkYXkgPSBNYXRoLm1pbihkYXksICQuZGF0ZXBpY2tlci5fZ2V0RGF5c0luTW9udGgoeWVhciwgbW9udGgpKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG1hdGNoZXMgPSBwYXR0ZXJuLmV4ZWMob2Zmc2V0KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGgsIGRheSk7XG5cdFx0XHR9LFxuXHRcdFx0bmV3RGF0ZSA9IChkYXRlID09IG51bGwgfHwgZGF0ZSA9PT0gXCJcIiA/IGRlZmF1bHREYXRlIDogKHR5cGVvZiBkYXRlID09PSBcInN0cmluZ1wiID8gb2Zmc2V0U3RyaW5nKGRhdGUpIDpcblx0XHRcdFx0KHR5cGVvZiBkYXRlID09PSBcIm51bWJlclwiID8gKGlzTmFOKGRhdGUpID8gZGVmYXVsdERhdGUgOiBvZmZzZXROdW1lcmljKGRhdGUpKSA6IG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpKSkpKTtcblxuXHRcdG5ld0RhdGUgPSAobmV3RGF0ZSAmJiBuZXdEYXRlLnRvU3RyaW5nKCkgPT09IFwiSW52YWxpZCBEYXRlXCIgPyBkZWZhdWx0RGF0ZSA6IG5ld0RhdGUpO1xuXHRcdGlmIChuZXdEYXRlKSB7XG5cdFx0XHRuZXdEYXRlLnNldEhvdXJzKDApO1xuXHRcdFx0bmV3RGF0ZS5zZXRNaW51dGVzKDApO1xuXHRcdFx0bmV3RGF0ZS5zZXRTZWNvbmRzKDApO1xuXHRcdFx0bmV3RGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXdEYXRlKTtcblx0fSxcblxuXHQvKiBIYW5kbGUgc3dpdGNoIHRvL2Zyb20gZGF5bGlnaHQgc2F2aW5nLlxuXHQgKiBIb3VycyBtYXkgYmUgbm9uLXplcm8gb24gZGF5bGlnaHQgc2F2aW5nIGN1dC1vdmVyOlxuXHQgKiA+IDEyIHdoZW4gbWlkbmlnaHQgY2hhbmdlb3ZlciwgYnV0IHRoZW4gY2Fubm90IGdlbmVyYXRlXG5cdCAqIG1pZG5pZ2h0IGRhdGV0aW1lLCBzbyBqdW1wIHRvIDFBTSwgb3RoZXJ3aXNlIHJlc2V0LlxuXHQgKiBAcGFyYW0gIGRhdGUgIChEYXRlKSB0aGUgZGF0ZSB0byBjaGVja1xuXHQgKiBAcmV0dXJuICAoRGF0ZSkgdGhlIGNvcnJlY3RlZCBkYXRlXG5cdCAqL1xuXHRfZGF5bGlnaHRTYXZpbmdBZGp1c3Q6IGZ1bmN0aW9uKGRhdGUpIHtcblx0XHRpZiAoIWRhdGUpIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRkYXRlLnNldEhvdXJzKGRhdGUuZ2V0SG91cnMoKSA+IDEyID8gZGF0ZS5nZXRIb3VycygpICsgMiA6IDApO1xuXHRcdHJldHVybiBkYXRlO1xuXHR9LFxuXG5cdC8qIFNldCB0aGUgZGF0ZShzKSBkaXJlY3RseS4gKi9cblx0X3NldERhdGU6IGZ1bmN0aW9uKGluc3QsIGRhdGUsIG5vQ2hhbmdlKSB7XG5cdFx0dmFyIGNsZWFyID0gIWRhdGUsXG5cdFx0XHRvcmlnTW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGgsXG5cdFx0XHRvcmlnWWVhciA9IGluc3Quc2VsZWN0ZWRZZWFyLFxuXHRcdFx0bmV3RGF0ZSA9IHRoaXMuX3Jlc3RyaWN0TWluTWF4KGluc3QsIHRoaXMuX2RldGVybWluZURhdGUoaW5zdCwgZGF0ZSwgbmV3IERhdGUoKSkpO1xuXG5cdFx0aW5zdC5zZWxlY3RlZERheSA9IGluc3QuY3VycmVudERheSA9IG5ld0RhdGUuZ2V0RGF0ZSgpO1xuXHRcdGluc3QuZHJhd01vbnRoID0gaW5zdC5zZWxlY3RlZE1vbnRoID0gaW5zdC5jdXJyZW50TW9udGggPSBuZXdEYXRlLmdldE1vbnRoKCk7XG5cdFx0aW5zdC5kcmF3WWVhciA9IGluc3Quc2VsZWN0ZWRZZWFyID0gaW5zdC5jdXJyZW50WWVhciA9IG5ld0RhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRpZiAoKG9yaWdNb250aCAhPT0gaW5zdC5zZWxlY3RlZE1vbnRoIHx8IG9yaWdZZWFyICE9PSBpbnN0LnNlbGVjdGVkWWVhcikgJiYgIW5vQ2hhbmdlKSB7XG5cdFx0XHR0aGlzLl9ub3RpZnlDaGFuZ2UoaW5zdCk7XG5cdFx0fVxuXHRcdHRoaXMuX2FkanVzdEluc3REYXRlKGluc3QpO1xuXHRcdGlmIChpbnN0LmlucHV0KSB7XG5cdFx0XHRpbnN0LmlucHV0LnZhbChjbGVhciA/IFwiXCIgOiB0aGlzLl9mb3JtYXREYXRlKGluc3QpKTtcblx0XHR9XG5cdH0sXG5cblx0LyogUmV0cmlldmUgdGhlIGRhdGUocykgZGlyZWN0bHkuICovXG5cdF9nZXREYXRlOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIHN0YXJ0RGF0ZSA9ICghaW5zdC5jdXJyZW50WWVhciB8fCAoaW5zdC5pbnB1dCAmJiBpbnN0LmlucHV0LnZhbCgpID09PSBcIlwiKSA/IG51bGwgOlxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoXG5cdFx0XHRpbnN0LmN1cnJlbnRZZWFyLCBpbnN0LmN1cnJlbnRNb250aCwgaW5zdC5jdXJyZW50RGF5KSkpO1xuXHRcdFx0cmV0dXJuIHN0YXJ0RGF0ZTtcblx0fSxcblxuXHQvKiBBdHRhY2ggdGhlIG9ueHh4IGhhbmRsZXJzLiAgVGhlc2UgYXJlIGRlY2xhcmVkIHN0YXRpY2FsbHkgc29cblx0ICogdGhleSB3b3JrIHdpdGggc3RhdGljIGNvZGUgdHJhbnNmb3JtZXJzIGxpa2UgQ2FqYS5cblx0ICovXG5cdF9hdHRhY2hIYW5kbGVyczogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBzdGVwTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsIFwic3RlcE1vbnRoc1wiKSxcblx0XHRcdGlkID0gXCIjXCIgKyBpbnN0LmlkLnJlcGxhY2UoIC9cXFxcXFxcXC9nLCBcIlxcXFxcIiApO1xuXHRcdGluc3QuZHBEaXYuZmluZChcIltkYXRhLWhhbmRsZXJdXCIpLm1hcChmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgaGFuZGxlciA9IHtcblx0XHRcdFx0cHJldjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShpZCwgLXN0ZXBNb250aHMsIFwiTVwiKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0bmV4dDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShpZCwgK3N0ZXBNb250aHMsIFwiTVwiKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0aGlkZTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0dG9kYXk6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2dvdG9Ub2RheShpZCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNlbGVjdERheTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2VsZWN0RGF5KGlkLCArdGhpcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLW1vbnRoXCIpLCArdGhpcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLXllYXJcIiksIHRoaXMpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0TW9udGg6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3NlbGVjdE1vbnRoWWVhcihpZCwgdGhpcywgXCJNXCIpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0WWVhcjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2VsZWN0TW9udGhZZWFyKGlkLCB0aGlzLCBcIllcIik7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0JCh0aGlzKS5iaW5kKHRoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS1ldmVudFwiKSwgaGFuZGxlclt0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEtaGFuZGxlclwiKV0pO1xuXHRcdH0pO1xuXHR9LFxuXG5cdC8qIEdlbmVyYXRlIHRoZSBIVE1MIGZvciB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgZGF0ZSBwaWNrZXIuICovXG5cdF9nZW5lcmF0ZUhUTUw6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgbWF4RHJhdywgcHJldlRleHQsIHByZXYsIG5leHRUZXh0LCBuZXh0LCBjdXJyZW50VGV4dCwgZ290b0RhdGUsXG5cdFx0XHRjb250cm9scywgYnV0dG9uUGFuZWwsIGZpcnN0RGF5LCBzaG93V2VlaywgZGF5TmFtZXMsIGRheU5hbWVzTWluLFxuXHRcdFx0bW9udGhOYW1lcywgbW9udGhOYW1lc1Nob3J0LCBiZWZvcmVTaG93RGF5LCBzaG93T3RoZXJNb250aHMsXG5cdFx0XHRzZWxlY3RPdGhlck1vbnRocywgZGVmYXVsdERhdGUsIGh0bWwsIGRvdywgcm93LCBncm91cCwgY29sLCBzZWxlY3RlZERhdGUsXG5cdFx0XHRjb3JuZXJDbGFzcywgY2FsZW5kZXIsIHRoZWFkLCBkYXksIGRheXNJbk1vbnRoLCBsZWFkRGF5cywgY3VyUm93cywgbnVtUm93cyxcblx0XHRcdHByaW50RGF0ZSwgZFJvdywgdGJvZHksIGRheVNldHRpbmdzLCBvdGhlck1vbnRoLCB1bnNlbGVjdGFibGUsXG5cdFx0XHR0ZW1wRGF0ZSA9IG5ldyBEYXRlKCksXG5cdFx0XHR0b2RheSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KFxuXHRcdFx0XHRuZXcgRGF0ZSh0ZW1wRGF0ZS5nZXRGdWxsWWVhcigpLCB0ZW1wRGF0ZS5nZXRNb250aCgpLCB0ZW1wRGF0ZS5nZXREYXRlKCkpKSwgLy8gY2xlYXIgdGltZVxuXHRcdFx0aXNSVEwgPSB0aGlzLl9nZXQoaW5zdCwgXCJpc1JUTFwiKSxcblx0XHRcdHNob3dCdXR0b25QYW5lbCA9IHRoaXMuX2dldChpbnN0LCBcInNob3dCdXR0b25QYW5lbFwiKSxcblx0XHRcdGhpZGVJZk5vUHJldk5leHQgPSB0aGlzLl9nZXQoaW5zdCwgXCJoaWRlSWZOb1ByZXZOZXh0XCIpLFxuXHRcdFx0bmF2aWdhdGlvbkFzRGF0ZUZvcm1hdCA9IHRoaXMuX2dldChpbnN0LCBcIm5hdmlnYXRpb25Bc0RhdGVGb3JtYXRcIiksXG5cdFx0XHRudW1Nb250aHMgPSB0aGlzLl9nZXROdW1iZXJPZk1vbnRocyhpbnN0KSxcblx0XHRcdHNob3dDdXJyZW50QXRQb3MgPSB0aGlzLl9nZXQoaW5zdCwgXCJzaG93Q3VycmVudEF0UG9zXCIpLFxuXHRcdFx0c3RlcE1vbnRocyA9IHRoaXMuX2dldChpbnN0LCBcInN0ZXBNb250aHNcIiksXG5cdFx0XHRpc011bHRpTW9udGggPSAobnVtTW9udGhzWzBdICE9PSAxIHx8IG51bU1vbnRoc1sxXSAhPT0gMSksXG5cdFx0XHRjdXJyZW50RGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KCghaW5zdC5jdXJyZW50RGF5ID8gbmV3IERhdGUoOTk5OSwgOSwgOSkgOlxuXHRcdFx0XHRuZXcgRGF0ZShpbnN0LmN1cnJlbnRZZWFyLCBpbnN0LmN1cnJlbnRNb250aCwgaW5zdC5jdXJyZW50RGF5KSkpLFxuXHRcdFx0bWluRGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgXCJtaW5cIiksXG5cdFx0XHRtYXhEYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1heFwiKSxcblx0XHRcdGRyYXdNb250aCA9IGluc3QuZHJhd01vbnRoIC0gc2hvd0N1cnJlbnRBdFBvcyxcblx0XHRcdGRyYXdZZWFyID0gaW5zdC5kcmF3WWVhcjtcblxuXHRcdGlmIChkcmF3TW9udGggPCAwKSB7XG5cdFx0XHRkcmF3TW9udGggKz0gMTI7XG5cdFx0XHRkcmF3WWVhci0tO1xuXHRcdH1cblx0XHRpZiAobWF4RGF0ZSkge1xuXHRcdFx0bWF4RHJhdyA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKG1heERhdGUuZ2V0RnVsbFllYXIoKSxcblx0XHRcdFx0bWF4RGF0ZS5nZXRNb250aCgpIC0gKG51bU1vbnRoc1swXSAqIG51bU1vbnRoc1sxXSkgKyAxLCBtYXhEYXRlLmdldERhdGUoKSkpO1xuXHRcdFx0bWF4RHJhdyA9IChtaW5EYXRlICYmIG1heERyYXcgPCBtaW5EYXRlID8gbWluRGF0ZSA6IG1heERyYXcpO1xuXHRcdFx0d2hpbGUgKHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGRyYXdZZWFyLCBkcmF3TW9udGgsIDEpKSA+IG1heERyYXcpIHtcblx0XHRcdFx0ZHJhd01vbnRoLS07XG5cdFx0XHRcdGlmIChkcmF3TW9udGggPCAwKSB7XG5cdFx0XHRcdFx0ZHJhd01vbnRoID0gMTE7XG5cdFx0XHRcdFx0ZHJhd1llYXItLTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRpbnN0LmRyYXdNb250aCA9IGRyYXdNb250aDtcblx0XHRpbnN0LmRyYXdZZWFyID0gZHJhd1llYXI7XG5cblx0XHRwcmV2VGV4dCA9IHRoaXMuX2dldChpbnN0LCBcInByZXZUZXh0XCIpO1xuXHRcdHByZXZUZXh0ID0gKCFuYXZpZ2F0aW9uQXNEYXRlRm9ybWF0ID8gcHJldlRleHQgOiB0aGlzLmZvcm1hdERhdGUocHJldlRleHQsXG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoIC0gc3RlcE1vbnRocywgMSkpLFxuXHRcdFx0dGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpKSk7XG5cblx0XHRwcmV2ID0gKHRoaXMuX2NhbkFkanVzdE1vbnRoKGluc3QsIC0xLCBkcmF3WWVhciwgZHJhd01vbnRoKSA/XG5cdFx0XHRcIjxhIGNsYXNzPSd1aS1kYXRlcGlja2VyLXByZXYgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSdwcmV2JyBkYXRhLWV2ZW50PSdjbGljaydcIiArXG5cdFx0XHRcIiB0aXRsZT0nXCIgKyBwcmV2VGV4dCArIFwiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIiArICggaXNSVEwgPyBcImVcIiA6IFwid1wiKSArIFwiJz5cIiArIHByZXZUZXh0ICsgXCI8L3NwYW4+PC9hPlwiIDpcblx0XHRcdChoaWRlSWZOb1ByZXZOZXh0ID8gXCJcIiA6IFwiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItcHJldiB1aS1jb3JuZXItYWxsIHVpLXN0YXRlLWRpc2FibGVkJyB0aXRsZT0nXCIrIHByZXZUZXh0ICtcIic+PHNwYW4gY2xhc3M9J3VpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtXCIgKyAoIGlzUlRMID8gXCJlXCIgOiBcIndcIikgKyBcIic+XCIgKyBwcmV2VGV4dCArIFwiPC9zcGFuPjwvYT5cIikpO1xuXG5cdFx0bmV4dFRleHQgPSB0aGlzLl9nZXQoaW5zdCwgXCJuZXh0VGV4dFwiKTtcblx0XHRuZXh0VGV4dCA9ICghbmF2aWdhdGlvbkFzRGF0ZUZvcm1hdCA/IG5leHRUZXh0IDogdGhpcy5mb3JtYXREYXRlKG5leHRUZXh0LFxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZHJhd1llYXIsIGRyYXdNb250aCArIHN0ZXBNb250aHMsIDEpKSxcblx0XHRcdHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSkpO1xuXG5cdFx0bmV4dCA9ICh0aGlzLl9jYW5BZGp1c3RNb250aChpbnN0LCArMSwgZHJhd1llYXIsIGRyYXdNb250aCkgP1xuXHRcdFx0XCI8YSBjbGFzcz0ndWktZGF0ZXBpY2tlci1uZXh0IHVpLWNvcm5lci1hbGwnIGRhdGEtaGFuZGxlcj0nbmV4dCcgZGF0YS1ldmVudD0nY2xpY2snXCIgK1xuXHRcdFx0XCIgdGl0bGU9J1wiICsgbmV4dFRleHQgKyBcIic+PHNwYW4gY2xhc3M9J3VpLWljb24gdWktaWNvbi1jaXJjbGUtdHJpYW5nbGUtXCIgKyAoIGlzUlRMID8gXCJ3XCIgOiBcImVcIikgKyBcIic+XCIgKyBuZXh0VGV4dCArIFwiPC9zcGFuPjwvYT5cIiA6XG5cdFx0XHQoaGlkZUlmTm9QcmV2TmV4dCA/IFwiXCIgOiBcIjxhIGNsYXNzPSd1aS1kYXRlcGlja2VyLW5leHQgdWktY29ybmVyLWFsbCB1aS1zdGF0ZS1kaXNhYmxlZCcgdGl0bGU9J1wiKyBuZXh0VGV4dCArIFwiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIiArICggaXNSVEwgPyBcIndcIiA6IFwiZVwiKSArIFwiJz5cIiArIG5leHRUZXh0ICsgXCI8L3NwYW4+PC9hPlwiKSk7XG5cblx0XHRjdXJyZW50VGV4dCA9IHRoaXMuX2dldChpbnN0LCBcImN1cnJlbnRUZXh0XCIpO1xuXHRcdGdvdG9EYXRlID0gKHRoaXMuX2dldChpbnN0LCBcImdvdG9DdXJyZW50XCIpICYmIGluc3QuY3VycmVudERheSA/IGN1cnJlbnREYXRlIDogdG9kYXkpO1xuXHRcdGN1cnJlbnRUZXh0ID0gKCFuYXZpZ2F0aW9uQXNEYXRlRm9ybWF0ID8gY3VycmVudFRleHQgOlxuXHRcdFx0dGhpcy5mb3JtYXREYXRlKGN1cnJlbnRUZXh0LCBnb3RvRGF0ZSwgdGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpKSk7XG5cblx0XHRjb250cm9scyA9ICghaW5zdC5pbmxpbmUgPyBcIjxidXR0b24gdHlwZT0nYnV0dG9uJyBjbGFzcz0ndWktZGF0ZXBpY2tlci1jbG9zZSB1aS1zdGF0ZS1kZWZhdWx0IHVpLXByaW9yaXR5LXByaW1hcnkgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSdoaWRlJyBkYXRhLWV2ZW50PSdjbGljayc+XCIgK1xuXHRcdFx0dGhpcy5fZ2V0KGluc3QsIFwiY2xvc2VUZXh0XCIpICsgXCI8L2J1dHRvbj5cIiA6IFwiXCIpO1xuXG5cdFx0YnV0dG9uUGFuZWwgPSAoc2hvd0J1dHRvblBhbmVsKSA/IFwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1idXR0b25wYW5lIHVpLXdpZGdldC1jb250ZW50Jz5cIiArIChpc1JUTCA/IGNvbnRyb2xzIDogXCJcIikgK1xuXHRcdFx0KHRoaXMuX2lzSW5SYW5nZShpbnN0LCBnb3RvRGF0ZSkgPyBcIjxidXR0b24gdHlwZT0nYnV0dG9uJyBjbGFzcz0ndWktZGF0ZXBpY2tlci1jdXJyZW50IHVpLXN0YXRlLWRlZmF1bHQgdWktcHJpb3JpdHktc2Vjb25kYXJ5IHVpLWNvcm5lci1hbGwnIGRhdGEtaGFuZGxlcj0ndG9kYXknIGRhdGEtZXZlbnQ9J2NsaWNrJ1wiICtcblx0XHRcdFwiPlwiICsgY3VycmVudFRleHQgKyBcIjwvYnV0dG9uPlwiIDogXCJcIikgKyAoaXNSVEwgPyBcIlwiIDogY29udHJvbHMpICsgXCI8L2Rpdj5cIiA6IFwiXCI7XG5cblx0XHRmaXJzdERheSA9IHBhcnNlSW50KHRoaXMuX2dldChpbnN0LCBcImZpcnN0RGF5XCIpLDEwKTtcblx0XHRmaXJzdERheSA9IChpc05hTihmaXJzdERheSkgPyAwIDogZmlyc3REYXkpO1xuXG5cdFx0c2hvd1dlZWsgPSB0aGlzLl9nZXQoaW5zdCwgXCJzaG93V2Vla1wiKTtcblx0XHRkYXlOYW1lcyA9IHRoaXMuX2dldChpbnN0LCBcImRheU5hbWVzXCIpO1xuXHRcdGRheU5hbWVzTWluID0gdGhpcy5fZ2V0KGluc3QsIFwiZGF5TmFtZXNNaW5cIik7XG5cdFx0bW9udGhOYW1lcyA9IHRoaXMuX2dldChpbnN0LCBcIm1vbnRoTmFtZXNcIik7XG5cdFx0bW9udGhOYW1lc1Nob3J0ID0gdGhpcy5fZ2V0KGluc3QsIFwibW9udGhOYW1lc1Nob3J0XCIpO1xuXHRcdGJlZm9yZVNob3dEYXkgPSB0aGlzLl9nZXQoaW5zdCwgXCJiZWZvcmVTaG93RGF5XCIpO1xuXHRcdHNob3dPdGhlck1vbnRocyA9IHRoaXMuX2dldChpbnN0LCBcInNob3dPdGhlck1vbnRoc1wiKTtcblx0XHRzZWxlY3RPdGhlck1vbnRocyA9IHRoaXMuX2dldChpbnN0LCBcInNlbGVjdE90aGVyTW9udGhzXCIpO1xuXHRcdGRlZmF1bHREYXRlID0gdGhpcy5fZ2V0RGVmYXVsdERhdGUoaW5zdCk7XG5cdFx0aHRtbCA9IFwiXCI7XG5cdFx0ZG93O1xuXHRcdGZvciAocm93ID0gMDsgcm93IDwgbnVtTW9udGhzWzBdOyByb3crKykge1xuXHRcdFx0Z3JvdXAgPSBcIlwiO1xuXHRcdFx0dGhpcy5tYXhSb3dzID0gNDtcblx0XHRcdGZvciAoY29sID0gMDsgY29sIDwgbnVtTW9udGhzWzFdOyBjb2wrKykge1xuXHRcdFx0XHRzZWxlY3RlZERhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoLCBpbnN0LnNlbGVjdGVkRGF5KSk7XG5cdFx0XHRcdGNvcm5lckNsYXNzID0gXCIgdWktY29ybmVyLWFsbFwiO1xuXHRcdFx0XHRjYWxlbmRlciA9IFwiXCI7XG5cdFx0XHRcdGlmIChpc011bHRpTW9udGgpIHtcblx0XHRcdFx0XHRjYWxlbmRlciArPSBcIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItZ3JvdXBcIjtcblx0XHRcdFx0XHRpZiAobnVtTW9udGhzWzFdID4gMSkge1xuXHRcdFx0XHRcdFx0c3dpdGNoIChjb2wpIHtcblx0XHRcdFx0XHRcdFx0Y2FzZSAwOiBjYWxlbmRlciArPSBcIiB1aS1kYXRlcGlja2VyLWdyb3VwLWZpcnN0XCI7XG5cdFx0XHRcdFx0XHRcdFx0Y29ybmVyQ2xhc3MgPSBcIiB1aS1jb3JuZXItXCIgKyAoaXNSVEwgPyBcInJpZ2h0XCIgOiBcImxlZnRcIik7IGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRjYXNlIG51bU1vbnRoc1sxXS0xOiBjYWxlbmRlciArPSBcIiB1aS1kYXRlcGlja2VyLWdyb3VwLWxhc3RcIjtcblx0XHRcdFx0XHRcdFx0XHRjb3JuZXJDbGFzcyA9IFwiIHVpLWNvcm5lci1cIiArIChpc1JUTCA/IFwibGVmdFwiIDogXCJyaWdodFwiKTsgYnJlYWs7XG5cdFx0XHRcdFx0XHRcdGRlZmF1bHQ6IGNhbGVuZGVyICs9IFwiIHVpLWRhdGVwaWNrZXItZ3JvdXAtbWlkZGxlXCI7IGNvcm5lckNsYXNzID0gXCJcIjsgYnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhbGVuZGVyICs9IFwiJz5cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRjYWxlbmRlciArPSBcIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItaGVhZGVyIHVpLXdpZGdldC1oZWFkZXIgdWktaGVscGVyLWNsZWFyZml4XCIgKyBjb3JuZXJDbGFzcyArIFwiJz5cIiArXG5cdFx0XHRcdFx0KC9hbGx8bGVmdC8udGVzdChjb3JuZXJDbGFzcykgJiYgcm93ID09PSAwID8gKGlzUlRMID8gbmV4dCA6IHByZXYpIDogXCJcIikgK1xuXHRcdFx0XHRcdCgvYWxsfHJpZ2h0Ly50ZXN0KGNvcm5lckNsYXNzKSAmJiByb3cgPT09IDAgPyAoaXNSVEwgPyBwcmV2IDogbmV4dCkgOiBcIlwiKSArXG5cdFx0XHRcdFx0dGhpcy5fZ2VuZXJhdGVNb250aFllYXJIZWFkZXIoaW5zdCwgZHJhd01vbnRoLCBkcmF3WWVhciwgbWluRGF0ZSwgbWF4RGF0ZSxcblx0XHRcdFx0XHRyb3cgPiAwIHx8IGNvbCA+IDAsIG1vbnRoTmFtZXMsIG1vbnRoTmFtZXNTaG9ydCkgKyAvLyBkcmF3IG1vbnRoIGhlYWRlcnNcblx0XHRcdFx0XHRcIjwvZGl2Pjx0YWJsZSBjbGFzcz0ndWktZGF0ZXBpY2tlci1jYWxlbmRhcic+PHRoZWFkPlwiICtcblx0XHRcdFx0XHRcIjx0cj5cIjtcblx0XHRcdFx0dGhlYWQgPSAoc2hvd1dlZWsgPyBcIjx0aCBjbGFzcz0ndWktZGF0ZXBpY2tlci13ZWVrLWNvbCc+XCIgKyB0aGlzLl9nZXQoaW5zdCwgXCJ3ZWVrSGVhZGVyXCIpICsgXCI8L3RoPlwiIDogXCJcIik7XG5cdFx0XHRcdGZvciAoZG93ID0gMDsgZG93IDwgNzsgZG93KyspIHsgLy8gZGF5cyBvZiB0aGUgd2Vla1xuXHRcdFx0XHRcdGRheSA9IChkb3cgKyBmaXJzdERheSkgJSA3O1xuXHRcdFx0XHRcdHRoZWFkICs9IFwiPHRoXCIgKyAoKGRvdyArIGZpcnN0RGF5ICsgNikgJSA3ID49IDUgPyBcIiBjbGFzcz0ndWktZGF0ZXBpY2tlci13ZWVrLWVuZCdcIiA6IFwiXCIpICsgXCI+XCIgK1xuXHRcdFx0XHRcdFx0XCI8c3BhbiB0aXRsZT0nXCIgKyBkYXlOYW1lc1tkYXldICsgXCInPlwiICsgZGF5TmFtZXNNaW5bZGF5XSArIFwiPC9zcGFuPjwvdGg+XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2FsZW5kZXIgKz0gdGhlYWQgKyBcIjwvdHI+PC90aGVhZD48dGJvZHk+XCI7XG5cdFx0XHRcdGRheXNJbk1vbnRoID0gdGhpcy5fZ2V0RGF5c0luTW9udGgoZHJhd1llYXIsIGRyYXdNb250aCk7XG5cdFx0XHRcdGlmIChkcmF3WWVhciA9PT0gaW5zdC5zZWxlY3RlZFllYXIgJiYgZHJhd01vbnRoID09PSBpbnN0LnNlbGVjdGVkTW9udGgpIHtcblx0XHRcdFx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gTWF0aC5taW4oaW5zdC5zZWxlY3RlZERheSwgZGF5c0luTW9udGgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxlYWREYXlzID0gKHRoaXMuX2dldEZpcnN0RGF5T2ZNb250aChkcmF3WWVhciwgZHJhd01vbnRoKSAtIGZpcnN0RGF5ICsgNykgJSA3O1xuXHRcdFx0XHRjdXJSb3dzID0gTWF0aC5jZWlsKChsZWFkRGF5cyArIGRheXNJbk1vbnRoKSAvIDcpOyAvLyBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiByb3dzIHRvIGdlbmVyYXRlXG5cdFx0XHRcdG51bVJvd3MgPSAoaXNNdWx0aU1vbnRoID8gdGhpcy5tYXhSb3dzID4gY3VyUm93cyA/IHRoaXMubWF4Um93cyA6IGN1clJvd3MgOiBjdXJSb3dzKTsgLy9JZiBtdWx0aXBsZSBtb250aHMsIHVzZSB0aGUgaGlnaGVyIG51bWJlciBvZiByb3dzIChzZWUgIzcwNDMpXG5cdFx0XHRcdHRoaXMubWF4Um93cyA9IG51bVJvd3M7XG5cdFx0XHRcdHByaW50RGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGRyYXdZZWFyLCBkcmF3TW9udGgsIDEgLSBsZWFkRGF5cykpO1xuXHRcdFx0XHRmb3IgKGRSb3cgPSAwOyBkUm93IDwgbnVtUm93czsgZFJvdysrKSB7IC8vIGNyZWF0ZSBkYXRlIHBpY2tlciByb3dzXG5cdFx0XHRcdFx0Y2FsZW5kZXIgKz0gXCI8dHI+XCI7XG5cdFx0XHRcdFx0dGJvZHkgPSAoIXNob3dXZWVrID8gXCJcIiA6IFwiPHRkIGNsYXNzPSd1aS1kYXRlcGlja2VyLXdlZWstY29sJz5cIiArXG5cdFx0XHRcdFx0XHR0aGlzLl9nZXQoaW5zdCwgXCJjYWxjdWxhdGVXZWVrXCIpKHByaW50RGF0ZSkgKyBcIjwvdGQ+XCIpO1xuXHRcdFx0XHRcdGZvciAoZG93ID0gMDsgZG93IDwgNzsgZG93KyspIHsgLy8gY3JlYXRlIGRhdGUgcGlja2VyIGRheXNcblx0XHRcdFx0XHRcdGRheVNldHRpbmdzID0gKGJlZm9yZVNob3dEYXkgP1xuXHRcdFx0XHRcdFx0XHRiZWZvcmVTaG93RGF5LmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLCBbcHJpbnREYXRlXSkgOiBbdHJ1ZSwgXCJcIl0pO1xuXHRcdFx0XHRcdFx0b3RoZXJNb250aCA9IChwcmludERhdGUuZ2V0TW9udGgoKSAhPT0gZHJhd01vbnRoKTtcblx0XHRcdFx0XHRcdHVuc2VsZWN0YWJsZSA9IChvdGhlck1vbnRoICYmICFzZWxlY3RPdGhlck1vbnRocykgfHwgIWRheVNldHRpbmdzWzBdIHx8XG5cdFx0XHRcdFx0XHRcdChtaW5EYXRlICYmIHByaW50RGF0ZSA8IG1pbkRhdGUpIHx8IChtYXhEYXRlICYmIHByaW50RGF0ZSA+IG1heERhdGUpO1xuXHRcdFx0XHRcdFx0dGJvZHkgKz0gXCI8dGQgY2xhc3M9J1wiICtcblx0XHRcdFx0XHRcdFx0KChkb3cgKyBmaXJzdERheSArIDYpICUgNyA+PSA1ID8gXCIgdWktZGF0ZXBpY2tlci13ZWVrLWVuZFwiIDogXCJcIikgKyAvLyBoaWdobGlnaHQgd2Vla2VuZHNcblx0XHRcdFx0XHRcdFx0KG90aGVyTW9udGggPyBcIiB1aS1kYXRlcGlja2VyLW90aGVyLW1vbnRoXCIgOiBcIlwiKSArIC8vIGhpZ2hsaWdodCBkYXlzIGZyb20gb3RoZXIgbW9udGhzXG5cdFx0XHRcdFx0XHRcdCgocHJpbnREYXRlLmdldFRpbWUoKSA9PT0gc2VsZWN0ZWREYXRlLmdldFRpbWUoKSAmJiBkcmF3TW9udGggPT09IGluc3Quc2VsZWN0ZWRNb250aCAmJiBpbnN0Ll9rZXlFdmVudCkgfHwgLy8gdXNlciBwcmVzc2VkIGtleVxuXHRcdFx0XHRcdFx0XHQoZGVmYXVsdERhdGUuZ2V0VGltZSgpID09PSBwcmludERhdGUuZ2V0VGltZSgpICYmIGRlZmF1bHREYXRlLmdldFRpbWUoKSA9PT0gc2VsZWN0ZWREYXRlLmdldFRpbWUoKSkgP1xuXHRcdFx0XHRcdFx0XHQvLyBvciBkZWZhdWx0RGF0ZSBpcyBjdXJyZW50IHByaW50ZWREYXRlIGFuZCBkZWZhdWx0RGF0ZSBpcyBzZWxlY3RlZERhdGVcblx0XHRcdFx0XHRcdFx0XCIgXCIgKyB0aGlzLl9kYXlPdmVyQ2xhc3MgOiBcIlwiKSArIC8vIGhpZ2hsaWdodCBzZWxlY3RlZCBkYXlcblx0XHRcdFx0XHRcdFx0KHVuc2VsZWN0YWJsZSA/IFwiIFwiICsgdGhpcy5fdW5zZWxlY3RhYmxlQ2xhc3MgKyBcIiB1aS1zdGF0ZS1kaXNhYmxlZFwiOiBcIlwiKSArICAvLyBoaWdobGlnaHQgdW5zZWxlY3RhYmxlIGRheXNcblx0XHRcdFx0XHRcdFx0KG90aGVyTW9udGggJiYgIXNob3dPdGhlck1vbnRocyA/IFwiXCIgOiBcIiBcIiArIGRheVNldHRpbmdzWzFdICsgLy8gaGlnaGxpZ2h0IGN1c3RvbSBkYXRlc1xuXHRcdFx0XHRcdFx0XHQocHJpbnREYXRlLmdldFRpbWUoKSA9PT0gY3VycmVudERhdGUuZ2V0VGltZSgpID8gXCIgXCIgKyB0aGlzLl9jdXJyZW50Q2xhc3MgOiBcIlwiKSArIC8vIGhpZ2hsaWdodCBzZWxlY3RlZCBkYXlcblx0XHRcdFx0XHRcdFx0KHByaW50RGF0ZS5nZXRUaW1lKCkgPT09IHRvZGF5LmdldFRpbWUoKSA/IFwiIHVpLWRhdGVwaWNrZXItdG9kYXlcIiA6IFwiXCIpKSArIFwiJ1wiICsgLy8gaGlnaGxpZ2h0IHRvZGF5IChpZiBkaWZmZXJlbnQpXG5cdFx0XHRcdFx0XHRcdCgoIW90aGVyTW9udGggfHwgc2hvd090aGVyTW9udGhzKSAmJiBkYXlTZXR0aW5nc1syXSA/IFwiIHRpdGxlPSdcIiArIGRheVNldHRpbmdzWzJdLnJlcGxhY2UoLycvZywgXCImIzM5O1wiKSArIFwiJ1wiIDogXCJcIikgKyAvLyBjZWxsIHRpdGxlXG5cdFx0XHRcdFx0XHRcdCh1bnNlbGVjdGFibGUgPyBcIlwiIDogXCIgZGF0YS1oYW5kbGVyPSdzZWxlY3REYXknIGRhdGEtZXZlbnQ9J2NsaWNrJyBkYXRhLW1vbnRoPSdcIiArIHByaW50RGF0ZS5nZXRNb250aCgpICsgXCInIGRhdGEteWVhcj0nXCIgKyBwcmludERhdGUuZ2V0RnVsbFllYXIoKSArIFwiJ1wiKSArIFwiPlwiICsgLy8gYWN0aW9uc1xuXHRcdFx0XHRcdFx0XHQob3RoZXJNb250aCAmJiAhc2hvd090aGVyTW9udGhzID8gXCImI3hhMDtcIiA6IC8vIGRpc3BsYXkgZm9yIG90aGVyIG1vbnRoc1xuXHRcdFx0XHRcdFx0XHQodW5zZWxlY3RhYmxlID8gXCI8c3BhbiBjbGFzcz0ndWktc3RhdGUtZGVmYXVsdCc+XCIgKyBwcmludERhdGUuZ2V0RGF0ZSgpICsgXCI8L3NwYW4+XCIgOiBcIjxhIGNsYXNzPSd1aS1zdGF0ZS1kZWZhdWx0XCIgK1xuXHRcdFx0XHRcdFx0XHQocHJpbnREYXRlLmdldFRpbWUoKSA9PT0gdG9kYXkuZ2V0VGltZSgpID8gXCIgdWktc3RhdGUtaGlnaGxpZ2h0XCIgOiBcIlwiKSArXG5cdFx0XHRcdFx0XHRcdChwcmludERhdGUuZ2V0VGltZSgpID09PSBjdXJyZW50RGF0ZS5nZXRUaW1lKCkgPyBcIiB1aS1zdGF0ZS1hY3RpdmVcIiA6IFwiXCIpICsgLy8gaGlnaGxpZ2h0IHNlbGVjdGVkIGRheVxuXHRcdFx0XHRcdFx0XHQob3RoZXJNb250aCA/IFwiIHVpLXByaW9yaXR5LXNlY29uZGFyeVwiIDogXCJcIikgKyAvLyBkaXN0aW5ndWlzaCBkYXRlcyBmcm9tIG90aGVyIG1vbnRoc1xuXHRcdFx0XHRcdFx0XHRcIicgaHJlZj0nIyc+XCIgKyBwcmludERhdGUuZ2V0RGF0ZSgpICsgXCI8L2E+XCIpKSArIFwiPC90ZD5cIjsgLy8gZGlzcGxheSBzZWxlY3RhYmxlIGRhdGVcblx0XHRcdFx0XHRcdHByaW50RGF0ZS5zZXREYXRlKHByaW50RGF0ZS5nZXREYXRlKCkgKyAxKTtcblx0XHRcdFx0XHRcdHByaW50RGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KHByaW50RGF0ZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNhbGVuZGVyICs9IHRib2R5ICsgXCI8L3RyPlwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRyYXdNb250aCsrO1xuXHRcdFx0XHRpZiAoZHJhd01vbnRoID4gMTEpIHtcblx0XHRcdFx0XHRkcmF3TW9udGggPSAwO1xuXHRcdFx0XHRcdGRyYXdZZWFyKys7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2FsZW5kZXIgKz0gXCI8L3Rib2R5PjwvdGFibGU+XCIgKyAoaXNNdWx0aU1vbnRoID8gXCI8L2Rpdj5cIiArXG5cdFx0XHRcdFx0XHRcdCgobnVtTW9udGhzWzBdID4gMCAmJiBjb2wgPT09IG51bU1vbnRoc1sxXS0xKSA/IFwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1yb3ctYnJlYWsnPjwvZGl2PlwiIDogXCJcIikgOiBcIlwiKTtcblx0XHRcdFx0Z3JvdXAgKz0gY2FsZW5kZXI7XG5cdFx0XHR9XG5cdFx0XHRodG1sICs9IGdyb3VwO1xuXHRcdH1cblx0XHRodG1sICs9IGJ1dHRvblBhbmVsO1xuXHRcdGluc3QuX2tleUV2ZW50ID0gZmFsc2U7XG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0LyogR2VuZXJhdGUgdGhlIG1vbnRoIGFuZCB5ZWFyIGhlYWRlci4gKi9cblx0X2dlbmVyYXRlTW9udGhZZWFySGVhZGVyOiBmdW5jdGlvbihpbnN0LCBkcmF3TW9udGgsIGRyYXdZZWFyLCBtaW5EYXRlLCBtYXhEYXRlLFxuXHRcdFx0c2Vjb25kYXJ5LCBtb250aE5hbWVzLCBtb250aE5hbWVzU2hvcnQpIHtcblxuXHRcdHZhciBpbk1pblllYXIsIGluTWF4WWVhciwgbW9udGgsIHllYXJzLCB0aGlzWWVhciwgZGV0ZXJtaW5lWWVhciwgeWVhciwgZW5kWWVhcixcblx0XHRcdGNoYW5nZU1vbnRoID0gdGhpcy5fZ2V0KGluc3QsIFwiY2hhbmdlTW9udGhcIiksXG5cdFx0XHRjaGFuZ2VZZWFyID0gdGhpcy5fZ2V0KGluc3QsIFwiY2hhbmdlWWVhclwiKSxcblx0XHRcdHNob3dNb250aEFmdGVyWWVhciA9IHRoaXMuX2dldChpbnN0LCBcInNob3dNb250aEFmdGVyWWVhclwiKSxcblx0XHRcdGh0bWwgPSBcIjxkaXYgY2xhc3M9J3VpLWRhdGVwaWNrZXItdGl0bGUnPlwiLFxuXHRcdFx0bW9udGhIdG1sID0gXCJcIjtcblxuXHRcdC8vIG1vbnRoIHNlbGVjdGlvblxuXHRcdGlmIChzZWNvbmRhcnkgfHwgIWNoYW5nZU1vbnRoKSB7XG5cdFx0XHRtb250aEh0bWwgKz0gXCI8c3BhbiBjbGFzcz0ndWktZGF0ZXBpY2tlci1tb250aCc+XCIgKyBtb250aE5hbWVzW2RyYXdNb250aF0gKyBcIjwvc3Bhbj5cIjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0aW5NaW5ZZWFyID0gKG1pbkRhdGUgJiYgbWluRGF0ZS5nZXRGdWxsWWVhcigpID09PSBkcmF3WWVhcik7XG5cdFx0XHRpbk1heFllYXIgPSAobWF4RGF0ZSAmJiBtYXhEYXRlLmdldEZ1bGxZZWFyKCkgPT09IGRyYXdZZWFyKTtcblx0XHRcdG1vbnRoSHRtbCArPSBcIjxzZWxlY3QgY2xhc3M9J3VpLWRhdGVwaWNrZXItbW9udGgnIGRhdGEtaGFuZGxlcj0nc2VsZWN0TW9udGgnIGRhdGEtZXZlbnQ9J2NoYW5nZSc+XCI7XG5cdFx0XHRmb3IgKCBtb250aCA9IDA7IG1vbnRoIDwgMTI7IG1vbnRoKyspIHtcblx0XHRcdFx0aWYgKCghaW5NaW5ZZWFyIHx8IG1vbnRoID49IG1pbkRhdGUuZ2V0TW9udGgoKSkgJiYgKCFpbk1heFllYXIgfHwgbW9udGggPD0gbWF4RGF0ZS5nZXRNb250aCgpKSkge1xuXHRcdFx0XHRcdG1vbnRoSHRtbCArPSBcIjxvcHRpb24gdmFsdWU9J1wiICsgbW9udGggKyBcIidcIiArXG5cdFx0XHRcdFx0XHQobW9udGggPT09IGRyYXdNb250aCA/IFwiIHNlbGVjdGVkPSdzZWxlY3RlZCdcIiA6IFwiXCIpICtcblx0XHRcdFx0XHRcdFwiPlwiICsgbW9udGhOYW1lc1Nob3J0W21vbnRoXSArIFwiPC9vcHRpb24+XCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG1vbnRoSHRtbCArPSBcIjwvc2VsZWN0PlwiO1xuXHRcdH1cblxuXHRcdGlmICghc2hvd01vbnRoQWZ0ZXJZZWFyKSB7XG5cdFx0XHRodG1sICs9IG1vbnRoSHRtbCArIChzZWNvbmRhcnkgfHwgIShjaGFuZ2VNb250aCAmJiBjaGFuZ2VZZWFyKSA/IFwiJiN4YTA7XCIgOiBcIlwiKTtcblx0XHR9XG5cblx0XHQvLyB5ZWFyIHNlbGVjdGlvblxuXHRcdGlmICggIWluc3QueWVhcnNodG1sICkge1xuXHRcdFx0aW5zdC55ZWFyc2h0bWwgPSBcIlwiO1xuXHRcdFx0aWYgKHNlY29uZGFyeSB8fCAhY2hhbmdlWWVhcikge1xuXHRcdFx0XHRodG1sICs9IFwiPHNwYW4gY2xhc3M9J3VpLWRhdGVwaWNrZXIteWVhcic+XCIgKyBkcmF3WWVhciArIFwiPC9zcGFuPlwiO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gZGV0ZXJtaW5lIHJhbmdlIG9mIHllYXJzIHRvIGRpc3BsYXlcblx0XHRcdFx0eWVhcnMgPSB0aGlzLl9nZXQoaW5zdCwgXCJ5ZWFyUmFuZ2VcIikuc3BsaXQoXCI6XCIpO1xuXHRcdFx0XHR0aGlzWWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0XHRcdFx0ZGV0ZXJtaW5lWWVhciA9IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0XHRcdFx0dmFyIHllYXIgPSAodmFsdWUubWF0Y2goL2NbK1xcLV0uKi8pID8gZHJhd1llYXIgKyBwYXJzZUludCh2YWx1ZS5zdWJzdHJpbmcoMSksIDEwKSA6XG5cdFx0XHRcdFx0XHQodmFsdWUubWF0Y2goL1srXFwtXS4qLykgPyB0aGlzWWVhciArIHBhcnNlSW50KHZhbHVlLCAxMCkgOlxuXHRcdFx0XHRcdFx0cGFyc2VJbnQodmFsdWUsIDEwKSkpO1xuXHRcdFx0XHRcdHJldHVybiAoaXNOYU4oeWVhcikgPyB0aGlzWWVhciA6IHllYXIpO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHR5ZWFyID0gZGV0ZXJtaW5lWWVhcih5ZWFyc1swXSk7XG5cdFx0XHRcdGVuZFllYXIgPSBNYXRoLm1heCh5ZWFyLCBkZXRlcm1pbmVZZWFyKHllYXJzWzFdIHx8IFwiXCIpKTtcblx0XHRcdFx0eWVhciA9IChtaW5EYXRlID8gTWF0aC5tYXgoeWVhciwgbWluRGF0ZS5nZXRGdWxsWWVhcigpKSA6IHllYXIpO1xuXHRcdFx0XHRlbmRZZWFyID0gKG1heERhdGUgPyBNYXRoLm1pbihlbmRZZWFyLCBtYXhEYXRlLmdldEZ1bGxZZWFyKCkpIDogZW5kWWVhcik7XG5cdFx0XHRcdGluc3QueWVhcnNodG1sICs9IFwiPHNlbGVjdCBjbGFzcz0ndWktZGF0ZXBpY2tlci15ZWFyJyBkYXRhLWhhbmRsZXI9J3NlbGVjdFllYXInIGRhdGEtZXZlbnQ9J2NoYW5nZSc+XCI7XG5cdFx0XHRcdGZvciAoOyB5ZWFyIDw9IGVuZFllYXI7IHllYXIrKykge1xuXHRcdFx0XHRcdGluc3QueWVhcnNodG1sICs9IFwiPG9wdGlvbiB2YWx1ZT0nXCIgKyB5ZWFyICsgXCInXCIgK1xuXHRcdFx0XHRcdFx0KHllYXIgPT09IGRyYXdZZWFyID8gXCIgc2VsZWN0ZWQ9J3NlbGVjdGVkJ1wiIDogXCJcIikgK1xuXHRcdFx0XHRcdFx0XCI+XCIgKyB5ZWFyICsgXCI8L29wdGlvbj5cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpbnN0LnllYXJzaHRtbCArPSBcIjwvc2VsZWN0PlwiO1xuXG5cdFx0XHRcdGh0bWwgKz0gaW5zdC55ZWFyc2h0bWw7XG5cdFx0XHRcdGluc3QueWVhcnNodG1sID0gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRodG1sICs9IHRoaXMuX2dldChpbnN0LCBcInllYXJTdWZmaXhcIik7XG5cdFx0aWYgKHNob3dNb250aEFmdGVyWWVhcikge1xuXHRcdFx0aHRtbCArPSAoc2Vjb25kYXJ5IHx8ICEoY2hhbmdlTW9udGggJiYgY2hhbmdlWWVhcikgPyBcIiYjeGEwO1wiIDogXCJcIikgKyBtb250aEh0bWw7XG5cdFx0fVxuXHRcdGh0bWwgKz0gXCI8L2Rpdj5cIjsgLy8gQ2xvc2UgZGF0ZXBpY2tlcl9oZWFkZXJcblx0XHRyZXR1cm4gaHRtbDtcblx0fSxcblxuXHQvKiBBZGp1c3Qgb25lIG9mIHRoZSBkYXRlIHN1Yi1maWVsZHMuICovXG5cdF9hZGp1c3RJbnN0RGF0ZTogZnVuY3Rpb24oaW5zdCwgb2Zmc2V0LCBwZXJpb2QpIHtcblx0XHR2YXIgeWVhciA9IGluc3QuZHJhd1llYXIgKyAocGVyaW9kID09PSBcIllcIiA/IG9mZnNldCA6IDApLFxuXHRcdFx0bW9udGggPSBpbnN0LmRyYXdNb250aCArIChwZXJpb2QgPT09IFwiTVwiID8gb2Zmc2V0IDogMCksXG5cdFx0XHRkYXkgPSBNYXRoLm1pbihpbnN0LnNlbGVjdGVkRGF5LCB0aGlzLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCkpICsgKHBlcmlvZCA9PT0gXCJEXCIgPyBvZmZzZXQgOiAwKSxcblx0XHRcdGRhdGUgPSB0aGlzLl9yZXN0cmljdE1pbk1heChpbnN0LCB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KSkpO1xuXG5cdFx0aW5zdC5zZWxlY3RlZERheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdGluc3QuZHJhd01vbnRoID0gaW5zdC5zZWxlY3RlZE1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuXHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRpZiAocGVyaW9kID09PSBcIk1cIiB8fCBwZXJpb2QgPT09IFwiWVwiKSB7XG5cdFx0XHR0aGlzLl9ub3RpZnlDaGFuZ2UoaW5zdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEVuc3VyZSBhIGRhdGUgaXMgd2l0aGluIGFueSBtaW4vbWF4IGJvdW5kcy4gKi9cblx0X3Jlc3RyaWN0TWluTWF4OiBmdW5jdGlvbihpbnN0LCBkYXRlKSB7XG5cdFx0dmFyIG1pbkRhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsIFwibWluXCIpLFxuXHRcdFx0bWF4RGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgXCJtYXhcIiksXG5cdFx0XHRuZXdEYXRlID0gKG1pbkRhdGUgJiYgZGF0ZSA8IG1pbkRhdGUgPyBtaW5EYXRlIDogZGF0ZSk7XG5cdFx0cmV0dXJuIChtYXhEYXRlICYmIG5ld0RhdGUgPiBtYXhEYXRlID8gbWF4RGF0ZSA6IG5ld0RhdGUpO1xuXHR9LFxuXG5cdC8qIE5vdGlmeSBjaGFuZ2Ugb2YgbW9udGgveWVhci4gKi9cblx0X25vdGlmeUNoYW5nZTogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBvbkNoYW5nZSA9IHRoaXMuX2dldChpbnN0LCBcIm9uQ2hhbmdlTW9udGhZZWFyXCIpO1xuXHRcdGlmIChvbkNoYW5nZSkge1xuXHRcdFx0b25DaGFuZ2UuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksXG5cdFx0XHRcdFtpbnN0LnNlbGVjdGVkWWVhciwgaW5zdC5zZWxlY3RlZE1vbnRoICsgMSwgaW5zdF0pO1xuXHRcdH1cblx0fSxcblxuXHQvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBtb250aHMgdG8gc2hvdy4gKi9cblx0X2dldE51bWJlck9mTW9udGhzOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIG51bU1vbnRocyA9IHRoaXMuX2dldChpbnN0LCBcIm51bWJlck9mTW9udGhzXCIpO1xuXHRcdHJldHVybiAobnVtTW9udGhzID09IG51bGwgPyBbMSwgMV0gOiAodHlwZW9mIG51bU1vbnRocyA9PT0gXCJudW1iZXJcIiA/IFsxLCBudW1Nb250aHNdIDogbnVtTW9udGhzKSk7XG5cdH0sXG5cblx0LyogRGV0ZXJtaW5lIHRoZSBjdXJyZW50IG1heGltdW0gZGF0ZSAtIGVuc3VyZSBubyB0aW1lIGNvbXBvbmVudHMgYXJlIHNldC4gKi9cblx0X2dldE1pbk1heERhdGU6IGZ1bmN0aW9uKGluc3QsIG1pbk1heCkge1xuXHRcdHJldHVybiB0aGlzLl9kZXRlcm1pbmVEYXRlKGluc3QsIHRoaXMuX2dldChpbnN0LCBtaW5NYXggKyBcIkRhdGVcIiksIG51bGwpO1xuXHR9LFxuXG5cdC8qIEZpbmQgdGhlIG51bWJlciBvZiBkYXlzIGluIGEgZ2l2ZW4gbW9udGguICovXG5cdF9nZXREYXlzSW5Nb250aDogZnVuY3Rpb24oeWVhciwgbW9udGgpIHtcblx0XHRyZXR1cm4gMzIgLSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMzIpKS5nZXREYXRlKCk7XG5cdH0sXG5cblx0LyogRmluZCB0aGUgZGF5IG9mIHRoZSB3ZWVrIG9mIHRoZSBmaXJzdCBvZiBhIG1vbnRoLiAqL1xuXHRfZ2V0Rmlyc3REYXlPZk1vbnRoOiBmdW5jdGlvbih5ZWFyLCBtb250aCkge1xuXHRcdHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSkuZ2V0RGF5KCk7XG5cdH0sXG5cblx0LyogRGV0ZXJtaW5lcyBpZiB3ZSBzaG91bGQgYWxsb3cgYSBcIm5leHQvcHJldlwiIG1vbnRoIGRpc3BsYXkgY2hhbmdlLiAqL1xuXHRfY2FuQWRqdXN0TW9udGg6IGZ1bmN0aW9uKGluc3QsIG9mZnNldCwgY3VyWWVhciwgY3VyTW9udGgpIHtcblx0XHR2YXIgbnVtTW9udGhzID0gdGhpcy5fZ2V0TnVtYmVyT2ZNb250aHMoaW5zdCksXG5cdFx0XHRkYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoY3VyWWVhcixcblx0XHRcdGN1ck1vbnRoICsgKG9mZnNldCA8IDAgPyBvZmZzZXQgOiBudW1Nb250aHNbMF0gKiBudW1Nb250aHNbMV0pLCAxKSk7XG5cblx0XHRpZiAob2Zmc2V0IDwgMCkge1xuXHRcdFx0ZGF0ZS5zZXREYXRlKHRoaXMuX2dldERheXNJbk1vbnRoKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpKSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLl9pc0luUmFuZ2UoaW5zdCwgZGF0ZSk7XG5cdH0sXG5cblx0LyogSXMgdGhlIGdpdmVuIGRhdGUgaW4gdGhlIGFjY2VwdGVkIHJhbmdlPyAqL1xuXHRfaXNJblJhbmdlOiBmdW5jdGlvbihpbnN0LCBkYXRlKSB7XG5cdFx0dmFyIHllYXJTcGxpdCwgY3VycmVudFllYXIsXG5cdFx0XHRtaW5EYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1pblwiKSxcblx0XHRcdG1heERhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsIFwibWF4XCIpLFxuXHRcdFx0bWluWWVhciA9IG51bGwsXG5cdFx0XHRtYXhZZWFyID0gbnVsbCxcblx0XHRcdHllYXJzID0gdGhpcy5fZ2V0KGluc3QsIFwieWVhclJhbmdlXCIpO1xuXHRcdFx0aWYgKHllYXJzKXtcblx0XHRcdFx0eWVhclNwbGl0ID0geWVhcnMuc3BsaXQoXCI6XCIpO1xuXHRcdFx0XHRjdXJyZW50WWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcblx0XHRcdFx0bWluWWVhciA9IHBhcnNlSW50KHllYXJTcGxpdFswXSwgMTApO1xuXHRcdFx0XHRtYXhZZWFyID0gcGFyc2VJbnQoeWVhclNwbGl0WzFdLCAxMCk7XG5cdFx0XHRcdGlmICggeWVhclNwbGl0WzBdLm1hdGNoKC9bK1xcLV0uKi8pICkge1xuXHRcdFx0XHRcdG1pblllYXIgKz0gY3VycmVudFllYXI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCB5ZWFyU3BsaXRbMV0ubWF0Y2goL1srXFwtXS4qLykgKSB7XG5cdFx0XHRcdFx0bWF4WWVhciArPSBjdXJyZW50WWVhcjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0cmV0dXJuICgoIW1pbkRhdGUgfHwgZGF0ZS5nZXRUaW1lKCkgPj0gbWluRGF0ZS5nZXRUaW1lKCkpICYmXG5cdFx0XHQoIW1heERhdGUgfHwgZGF0ZS5nZXRUaW1lKCkgPD0gbWF4RGF0ZS5nZXRUaW1lKCkpICYmXG5cdFx0XHQoIW1pblllYXIgfHwgZGF0ZS5nZXRGdWxsWWVhcigpID49IG1pblllYXIpICYmXG5cdFx0XHQoIW1heFllYXIgfHwgZGF0ZS5nZXRGdWxsWWVhcigpIDw9IG1heFllYXIpKTtcblx0fSxcblxuXHQvKiBQcm92aWRlIHRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzIGZvciBmb3JtYXR0aW5nL3BhcnNpbmcuICovXG5cdF9nZXRGb3JtYXRDb25maWc6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgc2hvcnRZZWFyQ3V0b2ZmID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvcnRZZWFyQ3V0b2ZmXCIpO1xuXHRcdHNob3J0WWVhckN1dG9mZiA9ICh0eXBlb2Ygc2hvcnRZZWFyQ3V0b2ZmICE9PSBcInN0cmluZ1wiID8gc2hvcnRZZWFyQ3V0b2ZmIDpcblx0XHRcdG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKSAlIDEwMCArIHBhcnNlSW50KHNob3J0WWVhckN1dG9mZiwgMTApKTtcblx0XHRyZXR1cm4ge3Nob3J0WWVhckN1dG9mZjogc2hvcnRZZWFyQ3V0b2ZmLFxuXHRcdFx0ZGF5TmFtZXNTaG9ydDogdGhpcy5fZ2V0KGluc3QsIFwiZGF5TmFtZXNTaG9ydFwiKSwgZGF5TmFtZXM6IHRoaXMuX2dldChpbnN0LCBcImRheU5hbWVzXCIpLFxuXHRcdFx0bW9udGhOYW1lc1Nob3J0OiB0aGlzLl9nZXQoaW5zdCwgXCJtb250aE5hbWVzU2hvcnRcIiksIG1vbnRoTmFtZXM6IHRoaXMuX2dldChpbnN0LCBcIm1vbnRoTmFtZXNcIil9O1xuXHR9LFxuXG5cdC8qIEZvcm1hdCB0aGUgZ2l2ZW4gZGF0ZSBmb3IgZGlzcGxheS4gKi9cblx0X2Zvcm1hdERhdGU6IGZ1bmN0aW9uKGluc3QsIGRheSwgbW9udGgsIHllYXIpIHtcblx0XHRpZiAoIWRheSkge1xuXHRcdFx0aW5zdC5jdXJyZW50RGF5ID0gaW5zdC5zZWxlY3RlZERheTtcblx0XHRcdGluc3QuY3VycmVudE1vbnRoID0gaW5zdC5zZWxlY3RlZE1vbnRoO1xuXHRcdFx0aW5zdC5jdXJyZW50WWVhciA9IGluc3Quc2VsZWN0ZWRZZWFyO1xuXHRcdH1cblx0XHR2YXIgZGF0ZSA9IChkYXkgPyAodHlwZW9mIGRheSA9PT0gXCJvYmplY3RcIiA/IGRheSA6XG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KSkpIDpcblx0XHRcdHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGluc3QuY3VycmVudFllYXIsIGluc3QuY3VycmVudE1vbnRoLCBpbnN0LmN1cnJlbnREYXkpKSk7XG5cdFx0cmV0dXJuIHRoaXMuZm9ybWF0RGF0ZSh0aGlzLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpLCBkYXRlLCB0aGlzLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpO1xuXHR9XG59KTtcblxuLypcbiAqIEJpbmQgaG92ZXIgZXZlbnRzIGZvciBkYXRlcGlja2VyIGVsZW1lbnRzLlxuICogRG9uZSB2aWEgZGVsZWdhdGUgc28gdGhlIGJpbmRpbmcgb25seSBvY2N1cnMgb25jZSBpbiB0aGUgbGlmZXRpbWUgb2YgdGhlIHBhcmVudCBkaXYuXG4gKiBHbG9iYWwgaW5zdEFjdGl2ZSwgc2V0IGJ5IF91cGRhdGVEYXRlcGlja2VyIGFsbG93cyB0aGUgaGFuZGxlcnMgdG8gZmluZCB0aGVpciB3YXkgYmFjayB0byB0aGUgYWN0aXZlIHBpY2tlci5cbiAqL1xuZnVuY3Rpb24gYmluZEhvdmVyKGRwRGl2KSB7XG5cdHZhciBzZWxlY3RvciA9IFwiYnV0dG9uLCAudWktZGF0ZXBpY2tlci1wcmV2LCAudWktZGF0ZXBpY2tlci1uZXh0LCAudWktZGF0ZXBpY2tlci1jYWxlbmRhciB0ZCBhXCI7XG5cdHJldHVybiBkcERpdi5kZWxlZ2F0ZShzZWxlY3RvciwgXCJtb3VzZW91dFwiLCBmdW5jdGlvbigpIHtcblx0XHRcdCQodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKTtcblx0XHRcdGlmICh0aGlzLmNsYXNzTmFtZS5pbmRleE9mKFwidWktZGF0ZXBpY2tlci1wcmV2XCIpICE9PSAtMSkge1xuXHRcdFx0XHQkKHRoaXMpLnJlbW92ZUNsYXNzKFwidWktZGF0ZXBpY2tlci1wcmV2LWhvdmVyXCIpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLW5leHRcIikgIT09IC0xKSB7XG5cdFx0XHRcdCQodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLW5leHQtaG92ZXJcIik7XG5cdFx0XHR9XG5cdFx0fSlcblx0XHQuZGVsZWdhdGUoc2VsZWN0b3IsIFwibW91c2VvdmVyXCIsIGZ1bmN0aW9uKCl7XG5cdFx0XHRpZiAoISQuZGF0ZXBpY2tlci5faXNEaXNhYmxlZERhdGVwaWNrZXIoIGluc3RBY3RpdmUuaW5saW5lID8gZHBEaXYucGFyZW50KClbMF0gOiBpbnN0QWN0aXZlLmlucHV0WzBdKSkge1xuXHRcdFx0XHQkKHRoaXMpLnBhcmVudHMoXCIudWktZGF0ZXBpY2tlci1jYWxlbmRhclwiKS5maW5kKFwiYVwiKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWhvdmVyXCIpO1xuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKFwidWktc3RhdGUtaG92ZXJcIik7XG5cdFx0XHRcdGlmICh0aGlzLmNsYXNzTmFtZS5pbmRleE9mKFwidWktZGF0ZXBpY2tlci1wcmV2XCIpICE9PSAtMSkge1xuXHRcdFx0XHRcdCQodGhpcykuYWRkQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLXByZXYtaG92ZXJcIik7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLW5leHRcIikgIT09IC0xKSB7XG5cdFx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcyhcInVpLWRhdGVwaWNrZXItbmV4dC1ob3ZlclwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xufVxuXG4vKiBqUXVlcnkgZXh0ZW5kIG5vdyBpZ25vcmVzIG51bGxzISAqL1xuZnVuY3Rpb24gZXh0ZW5kUmVtb3ZlKHRhcmdldCwgcHJvcHMpIHtcblx0JC5leHRlbmQodGFyZ2V0LCBwcm9wcyk7XG5cdGZvciAodmFyIG5hbWUgaW4gcHJvcHMpIHtcblx0XHRpZiAocHJvcHNbbmFtZV0gPT0gbnVsbCkge1xuXHRcdFx0dGFyZ2V0W25hbWVdID0gcHJvcHNbbmFtZV07XG5cdFx0fVxuXHR9XG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbi8qIEludm9rZSB0aGUgZGF0ZXBpY2tlciBmdW5jdGlvbmFsaXR5LlxuICAgQHBhcmFtICBvcHRpb25zICBzdHJpbmcgLSBhIGNvbW1hbmQsIG9wdGlvbmFsbHkgZm9sbG93ZWQgYnkgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIG9yXG5cdFx0XHRcdFx0T2JqZWN0IC0gc2V0dGluZ3MgZm9yIGF0dGFjaGluZyBuZXcgZGF0ZXBpY2tlciBmdW5jdGlvbmFsaXR5XG4gICBAcmV0dXJuICBqUXVlcnkgb2JqZWN0ICovXG4kLmZuLmRhdGVwaWNrZXIgPSBmdW5jdGlvbihvcHRpb25zKXtcblxuXHQvKiBWZXJpZnkgYW4gZW1wdHkgY29sbGVjdGlvbiB3YXNuJ3QgcGFzc2VkIC0gRml4ZXMgIzY5NzYgKi9cblx0aWYgKCAhdGhpcy5sZW5ndGggKSB7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKiBJbml0aWFsaXNlIHRoZSBkYXRlIHBpY2tlci4gKi9cblx0aWYgKCEkLmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWQpIHtcblx0XHQkKGRvY3VtZW50KS5tb3VzZWRvd24oJC5kYXRlcGlja2VyLl9jaGVja0V4dGVybmFsQ2xpY2spO1xuXHRcdCQuZGF0ZXBpY2tlci5pbml0aWFsaXplZCA9IHRydWU7XG5cdH1cblxuXHQvKiBBcHBlbmQgZGF0ZXBpY2tlciBtYWluIGNvbnRhaW5lciB0byBib2R5IGlmIG5vdCBleGlzdC4gKi9cblx0aWYgKCQoXCIjXCIrJC5kYXRlcGlja2VyLl9tYWluRGl2SWQpLmxlbmd0aCA9PT0gMCkge1xuXHRcdCQoXCJib2R5XCIpLmFwcGVuZCgkLmRhdGVwaWNrZXIuZHBEaXYpO1xuXHR9XG5cblx0dmFyIG90aGVyQXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cdGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIiAmJiAob3B0aW9ucyA9PT0gXCJpc0Rpc2FibGVkXCIgfHwgb3B0aW9ucyA9PT0gXCJnZXREYXRlXCIgfHwgb3B0aW9ucyA9PT0gXCJ3aWRnZXRcIikpIHtcblx0XHRyZXR1cm4gJC5kYXRlcGlja2VyW1wiX1wiICsgb3B0aW9ucyArIFwiRGF0ZXBpY2tlclwiXS5cblx0XHRcdGFwcGx5KCQuZGF0ZXBpY2tlciwgW3RoaXNbMF1dLmNvbmNhdChvdGhlckFyZ3MpKTtcblx0fVxuXHRpZiAob3B0aW9ucyA9PT0gXCJvcHRpb25cIiAmJiBhcmd1bWVudHMubGVuZ3RoID09PSAyICYmIHR5cGVvZiBhcmd1bWVudHNbMV0gPT09IFwic3RyaW5nXCIpIHtcblx0XHRyZXR1cm4gJC5kYXRlcGlja2VyW1wiX1wiICsgb3B0aW9ucyArIFwiRGF0ZXBpY2tlclwiXS5cblx0XHRcdGFwcGx5KCQuZGF0ZXBpY2tlciwgW3RoaXNbMF1dLmNvbmNhdChvdGhlckFyZ3MpKTtcblx0fVxuXHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cblx0XHRcdCQuZGF0ZXBpY2tlcltcIl9cIiArIG9wdGlvbnMgKyBcIkRhdGVwaWNrZXJcIl0uXG5cdFx0XHRcdGFwcGx5KCQuZGF0ZXBpY2tlciwgW3RoaXNdLmNvbmNhdChvdGhlckFyZ3MpKSA6XG5cdFx0XHQkLmRhdGVwaWNrZXIuX2F0dGFjaERhdGVwaWNrZXIodGhpcywgb3B0aW9ucyk7XG5cdH0pO1xufTtcblxuJC5kYXRlcGlja2VyID0gbmV3IERhdGVwaWNrZXIoKTsgLy8gc2luZ2xldG9uIGluc3RhbmNlXG4kLmRhdGVwaWNrZXIuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiQuZGF0ZXBpY2tlci51dWlkID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4kLmRhdGVwaWNrZXIudmVyc2lvbiA9IFwiMS4xMC40XCI7XG5cbn0pKGpRdWVyeSk7XG4iLCIvKiFcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjIuMS4zXG4gKiBodHRwOi8vanF1ZXJ5LmNvbS9cbiAqXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMDUsIDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNC0xMi0xOFQxNToxMVpcbiAqL1xuXG4oZnVuY3Rpb24oIGdsb2JhbCwgZmFjdG9yeSApIHtcblxuXHRpZiAoIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiICkge1xuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2Bcblx0XHQvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LlxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC5cblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cblx0XHRtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG5cdFx0XHRmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6XG5cdFx0XHRmdW5jdGlvbiggdyApIHtcblx0XHRcdFx0aWYgKCAhdy5kb2N1bWVudCApIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhY3RvcnkoIHcgKTtcblx0XHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0ZmFjdG9yeSggZ2xvYmFsICk7XG5cdH1cblxuLy8gUGFzcyB0aGlzIGlmIHdpbmRvdyBpcyBub3QgZGVmaW5lZCB5ZXRcbn0odHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKCB3aW5kb3csIG5vR2xvYmFsICkge1xuXG4vLyBTdXBwb3J0OiBGaXJlZm94IDE4K1xuLy8gQ2FuJ3QgYmUgaW4gc3RyaWN0IG1vZGUsIHNldmVyYWwgbGlicyBpbmNsdWRpbmcgQVNQLk5FVCB0cmFjZVxuLy8gdGhlIHN0YWNrIHZpYSBhcmd1bWVudHMuY2FsbGVyLmNhbGxlZSBhbmQgRmlyZWZveCBkaWVzIGlmXG4vLyB5b3UgdHJ5IHRvIHRyYWNlIHRocm91Z2ggXCJ1c2Ugc3RyaWN0XCIgY2FsbCBjaGFpbnMuICgjMTMzMzUpXG4vL1xuXG52YXIgYXJyID0gW107XG5cbnZhciBzbGljZSA9IGFyci5zbGljZTtcblxudmFyIGNvbmNhdCA9IGFyci5jb25jYXQ7XG5cbnZhciBwdXNoID0gYXJyLnB1c2g7XG5cbnZhciBpbmRleE9mID0gYXJyLmluZGV4T2Y7XG5cbnZhciBjbGFzczJ0eXBlID0ge307XG5cbnZhciB0b1N0cmluZyA9IGNsYXNzMnR5cGUudG9TdHJpbmc7XG5cbnZhciBoYXNPd24gPSBjbGFzczJ0eXBlLmhhc093blByb3BlcnR5O1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG5cblxudmFyXG5cdC8vIFVzZSB0aGUgY29ycmVjdCBkb2N1bWVudCBhY2NvcmRpbmdseSB3aXRoIHdpbmRvdyBhcmd1bWVudCAoc2FuZGJveClcblx0ZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQsXG5cblx0dmVyc2lvbiA9IFwiMi4xLjNcIixcblxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxuXHRqUXVlcnkgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0Ly8gVGhlIGpRdWVyeSBvYmplY3QgaXMgYWN0dWFsbHkganVzdCB0aGUgaW5pdCBjb25zdHJ1Y3RvciAnZW5oYW5jZWQnXG5cdFx0Ly8gTmVlZCBpbml0IGlmIGpRdWVyeSBpcyBjYWxsZWQgKGp1c3QgYWxsb3cgZXJyb3IgdG8gYmUgdGhyb3duIGlmIG5vdCBpbmNsdWRlZClcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xuXHR9LFxuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4xXG5cdC8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxuXHRydHJpbSA9IC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZyxcblxuXHQvLyBNYXRjaGVzIGRhc2hlZCBzdHJpbmcgZm9yIGNhbWVsaXppbmdcblx0cm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFtcXGRhLXpdKS9naSxcblxuXHQvLyBVc2VkIGJ5IGpRdWVyeS5jYW1lbENhc2UgYXMgY2FsbGJhY2sgdG8gcmVwbGFjZSgpXG5cdGZjYW1lbENhc2UgPSBmdW5jdGlvbiggYWxsLCBsZXR0ZXIgKSB7XG5cdFx0cmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xuXHR9O1xuXG5qUXVlcnkuZm4gPSBqUXVlcnkucHJvdG90eXBlID0ge1xuXHQvLyBUaGUgY3VycmVudCB2ZXJzaW9uIG9mIGpRdWVyeSBiZWluZyB1c2VkXG5cdGpxdWVyeTogdmVyc2lvbixcblxuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LFxuXG5cdC8vIFN0YXJ0IHdpdGggYW4gZW1wdHkgc2VsZWN0b3Jcblx0c2VsZWN0b3I6IFwiXCIsXG5cblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXG5cdGxlbmd0aDogMCxcblxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIEdldCB0aGUgTnRoIGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQgT1Jcblx0Ly8gR2V0IHRoZSB3aG9sZSBtYXRjaGVkIGVsZW1lbnQgc2V0IGFzIGEgY2xlYW4gYXJyYXlcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xuXHRcdHJldHVybiBudW0gIT0gbnVsbCA/XG5cblx0XHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcblx0XHRcdCggbnVtIDwgMCA/IHRoaXNbIG51bSArIHRoaXMubGVuZ3RoIF0gOiB0aGlzWyBudW0gXSApIDpcblxuXHRcdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxuXHRcdFx0c2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2tcblx0Ly8gKHJldHVybmluZyB0aGUgbmV3IG1hdGNoZWQgZWxlbWVudCBzZXQpXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xuXG5cdFx0Ly8gQnVpbGQgYSBuZXcgalF1ZXJ5IG1hdGNoZWQgZWxlbWVudCBzZXRcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XG5cblx0XHQvLyBBZGQgdGhlIG9sZCBvYmplY3Qgb250byB0aGUgc3RhY2sgKGFzIGEgcmVmZXJlbmNlKVxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcblx0XHRyZXQuY29udGV4dCA9IHRoaXMuY29udGV4dDtcblxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvLyBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgc2V0LlxuXHQvLyAoWW91IGNhbiBzZWVkIHRoZSBhcmd1bWVudHMgd2l0aCBhbiBhcnJheSBvZiBhcmdzLCBidXQgdGhpcyBpc1xuXHQvLyBvbmx5IHVzZWQgaW50ZXJuYWxseS4pXG5cdGVhY2g6IGZ1bmN0aW9uKCBjYWxsYmFjaywgYXJncyApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmVhY2goIHRoaXMsIGNhbGxiYWNrLCBhcmdzICk7XG5cdH0sXG5cblx0bWFwOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkubWFwKHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcblx0XHR9KSk7XG5cdH0sXG5cblx0c2xpY2U6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggc2xpY2UuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApICk7XG5cdH0sXG5cblx0Zmlyc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAwICk7XG5cdH0sXG5cblx0bGFzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIC0xICk7XG5cdH0sXG5cblx0ZXE6IGZ1bmN0aW9uKCBpICkge1xuXHRcdHZhciBsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdGogPSAraSArICggaSA8IDAgPyBsZW4gOiAwICk7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqID49IDAgJiYgaiA8IGxlbiA/IFsgdGhpc1tqXSBdIDogW10gKTtcblx0fSxcblxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcihudWxsKTtcblx0fSxcblxuXHQvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxuXHRwdXNoOiBwdXNoLFxuXHRzb3J0OiBhcnIuc29ydCxcblx0c3BsaWNlOiBhcnIuc3BsaWNlXG59O1xuXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgb3B0aW9ucywgbmFtZSwgc3JjLCBjb3B5LCBjb3B5SXNBcnJheSwgY2xvbmUsXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWzBdIHx8IHt9LFxuXHRcdGkgPSAxLFxuXHRcdGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG5cdFx0ZGVlcCA9IGZhbHNlO1xuXG5cdC8vIEhhbmRsZSBhIGRlZXAgY29weSBzaXR1YXRpb25cblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRkZWVwID0gdGFyZ2V0O1xuXG5cdFx0Ly8gU2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgaSBdIHx8IHt9O1xuXHRcdGkrKztcblx0fVxuXG5cdC8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KVxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKHRhcmdldCkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBFeHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHQvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXG5cdFx0aWYgKCAob3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdKSAhPSBudWxsICkge1xuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbIG5hbWUgXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0galF1ZXJ5LmlzQXJyYXkoY29weSkpICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSApIHtcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBqUXVlcnkuaXNBcnJheShzcmMpID8gc3JjIDogW107XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmMgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdGlzRnVuY3Rpb246IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKG9iaikgPT09IFwiZnVuY3Rpb25cIjtcblx0fSxcblxuXHRpc0FycmF5OiBBcnJheS5pc0FycmF5LFxuXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7XG5cdH0sXG5cblx0aXNOdW1lcmljOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzIChudWxsfHRydWV8ZmFsc2V8XCJcIilcblx0XHQvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzIChcIjB4Li4uXCIpXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXG5cdFx0Ly8gYWRkaW5nIDEgY29ycmVjdHMgbG9zcyBvZiBwcmVjaXNpb24gZnJvbSBwYXJzZUZsb2F0ICgjMTUxMDApXG5cdFx0cmV0dXJuICFqUXVlcnkuaXNBcnJheSggb2JqICkgJiYgKG9iaiAtIHBhcnNlRmxvYXQoIG9iaiApICsgMSkgPj0gMDtcblx0fSxcblxuXHRpc1BsYWluT2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8vIE5vdCBwbGFpbiBvYmplY3RzOlxuXHRcdC8vIC0gQW55IG9iamVjdCBvciB2YWx1ZSB3aG9zZSBpbnRlcm5hbCBbW0NsYXNzXV0gcHJvcGVydHkgaXMgbm90IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQvLyAtIERPTSBub2Rlc1xuXHRcdC8vIC0gd2luZG93XG5cdFx0aWYgKCBqUXVlcnkudHlwZSggb2JqICkgIT09IFwib2JqZWN0XCIgfHwgb2JqLm5vZGVUeXBlIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcblx0XHRcdFx0IWhhc093bi5jYWxsKCBvYmouY29uc3RydWN0b3IucHJvdG90eXBlLCBcImlzUHJvdG90eXBlT2ZcIiApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBmdW5jdGlvbiBoYXNuJ3QgcmV0dXJuZWQgYWxyZWFkeSwgd2UncmUgY29uZmlkZW50IHRoYXRcblx0XHQvLyB8b2JqfCBpcyBhIHBsYWluIG9iamVjdCwgY3JlYXRlZCBieSB7fSBvciBjb25zdHJ1Y3RlZCB3aXRoIG5ldyBPYmplY3Rcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHRpc0VtcHR5T2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBuYW1lO1xuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHR0eXBlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcblx0XHR9XG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjAsIGlPUzw2IChmdW5jdGlvbmlzaCBSZWdFeHApXG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwob2JqKSBdIHx8IFwib2JqZWN0XCIgOlxuXHRcdFx0dHlwZW9mIG9iajtcblx0fSxcblxuXHQvLyBFdmFsdWF0ZXMgYSBzY3JpcHQgaW4gYSBnbG9iYWwgY29udGV4dFxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSApIHtcblx0XHR2YXIgc2NyaXB0LFxuXHRcdFx0aW5kaXJlY3QgPSBldmFsO1xuXG5cdFx0Y29kZSA9IGpRdWVyeS50cmltKCBjb2RlICk7XG5cblx0XHRpZiAoIGNvZGUgKSB7XG5cdFx0XHQvLyBJZiB0aGUgY29kZSBpbmNsdWRlcyBhIHZhbGlkLCBwcm9sb2d1ZSBwb3NpdGlvblxuXHRcdFx0Ly8gc3RyaWN0IG1vZGUgcHJhZ21hLCBleGVjdXRlIGNvZGUgYnkgaW5qZWN0aW5nIGFcblx0XHRcdC8vIHNjcmlwdCB0YWcgaW50byB0aGUgZG9jdW1lbnQuXG5cdFx0XHRpZiAoIGNvZGUuaW5kZXhPZihcInVzZSBzdHJpY3RcIikgPT09IDEgKSB7XG5cdFx0XHRcdHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIik7XG5cdFx0XHRcdHNjcmlwdC50ZXh0ID0gY29kZTtcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0ICkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggc2NyaXB0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gT3RoZXJ3aXNlLCBhdm9pZCB0aGUgRE9NIG5vZGUgY3JlYXRpb24sIGluc2VydGlvblxuXHRcdFx0Ly8gYW5kIHJlbW92YWwgYnkgdXNpbmcgYW4gaW5kaXJlY3QgZ2xvYmFsIGV2YWxcblx0XHRcdFx0aW5kaXJlY3QoIGNvZGUgKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gQ29udmVydCBkYXNoZWQgdG8gY2FtZWxDYXNlOyB1c2VkIGJ5IHRoZSBjc3MgYW5kIGRhdGEgbW9kdWxlc1xuXHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdC8vIE1pY3Jvc29mdCBmb3Jnb3QgdG8gaHVtcCB0aGVpciB2ZW5kb3IgcHJlZml4ICgjOTU3Milcblx0Y2FtZWxDYXNlOiBmdW5jdGlvbiggc3RyaW5nICkge1xuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xuXHR9LFxuXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fSxcblxuXHQvLyBhcmdzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrLCBhcmdzICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHRcdGlzQXJyYXkgPSBpc0FycmF5bGlrZSggb2JqICk7XG5cblx0XHRpZiAoIGFyZ3MgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suYXBwbHkoIG9ialsgaSBdLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5hcHBseSggb2JqWyBpIF0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBIHNwZWNpYWwsIGZhc3QsIGNhc2UgZm9yIHRoZSBtb3N0IGNvbW1vbiB1c2Ugb2YgZWFjaFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMVxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcdFwiXCIgOlxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5bGlrZSggT2JqZWN0KGFycikgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHRyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7XG5cdH0sXG5cblx0bWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkge1xuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcblx0XHRcdGogPSAwLFxuXHRcdFx0aSA9IGZpcnN0Lmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqIF07XG5cdFx0fVxuXG5cdFx0Zmlyc3QubGVuZ3RoID0gaTtcblxuXHRcdHJldHVybiBmaXJzdDtcblx0fSxcblxuXHRncmVwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBpbnZlcnQgKSB7XG5cdFx0dmFyIGNhbGxiYWNrSW52ZXJzZSxcblx0XHRcdG1hdGNoZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIG9ubHkgc2F2aW5nIHRoZSBpdGVtc1xuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG5cdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRjYWxsYmFja0ludmVyc2UgPSAhY2FsbGJhY2soIGVsZW1zWyBpIF0sIGkgKTtcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBlbGVtc1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZXM7XG5cdH0sXG5cblx0Ly8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0aXNBcnJheSA9IGlzQXJyYXlsaWtlKCBlbGVtcyApLFxuXHRcdFx0cmV0ID0gW107XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xuXHRcdGlmICggaXNBcnJheSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEdvIHRocm91Z2ggZXZlcnkga2V5IG9uIHRoZSBvYmplY3QsXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRyZXR1cm4gY29uY2F0LmFwcGx5KCBbXSwgcmV0ICk7XG5cdH0sXG5cblx0Ly8gQSBnbG9iYWwgR1VJRCBjb3VudGVyIGZvciBvYmplY3RzXG5cdGd1aWQ6IDEsXG5cblx0Ly8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG5cdC8vIGFyZ3VtZW50cy5cblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0XHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdFx0Y29udGV4dCA9IGZuO1xuXHRcdFx0Zm4gPSB0bXA7XG5cdFx0fVxuXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0XHQvLyB0aGlzIHRocm93cyBhIFR5cGVFcnJvciwgYnV0IHdlIHdpbGwganVzdCByZXR1cm4gdW5kZWZpbmVkLlxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCBmbiApICkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBTaW11bGF0ZWQgYmluZFxuXHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0XHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XG5cdFx0fTtcblxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRcdHByb3h5Lmd1aWQgPSBmbi5ndWlkID0gZm4uZ3VpZCB8fCBqUXVlcnkuZ3VpZCsrO1xuXG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9LFxuXG5cdG5vdzogRGF0ZS5ub3csXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0pO1xuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvclwiLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oaSwgbmFtZSkge1xuXHRjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbn0pO1xuXG5mdW5jdGlvbiBpc0FycmF5bGlrZSggb2JqICkge1xuXHR2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHR0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xuXG5cdGlmICggdHlwZSA9PT0gXCJmdW5jdGlvblwiIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBvYmoubm9kZVR5cGUgPT09IDEgJiYgbGVuZ3RoICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcblx0XHR0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKCBsZW5ndGggLSAxICkgaW4gb2JqO1xufVxudmFyIFNpenpsZSA9XG4vKiFcbiAqIFNpenpsZSBDU1MgU2VsZWN0b3IgRW5naW5lIHYyLjIuMC1wcmVcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMDgsIDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNC0xMi0xNlxuICovXG4oZnVuY3Rpb24oIHdpbmRvdyApIHtcblxudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0c29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0Ly8gR2VuZXJhbC1wdXJwb3NlIGNvbnN0YW50c1xuXHRNQVhfTkVHQVRJVkUgPSAxIDw8IDMxLFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcblx0YXJyID0gW10sXG5cdHBvcCA9IGFyci5wb3AsXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXG5cdHB1c2ggPSBhcnIucHVzaCxcblx0c2xpY2UgPSBhcnIuc2xpY2UsXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxuXHQvLyBodHRwOi8vanNwZXJmLmNvbS90aG9yLWluZGV4b2YtdnMtZm9yLzVcblx0aW5kZXhPZiA9IGZ1bmN0aW9uKCBsaXN0LCBlbGVtICkge1xuXHRcdHZhciBpID0gMCxcblx0XHRcdGxlbiA9IGxpc3QubGVuZ3RoO1xuXHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0aWYgKCBsaXN0W2ldID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBXaGl0ZXNwYWNlIGNoYXJhY3RlcnMgaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2Vcblx0d2hpdGVzcGFjZSA9IFwiW1xcXFx4MjBcXFxcdFxcXFxyXFxcXG5cXFxcZl1cIixcblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zeW50YXgvI2NoYXJhY3RlcnNcblx0Y2hhcmFjdGVyRW5jb2RpbmcgPSBcIig/OlxcXFxcXFxcLnxbXFxcXHctXXxbXlxcXFx4MDAtXFxcXHhhMF0pK1wiLFxuXG5cdC8vIExvb3NlbHkgbW9kZWxlZCBvbiBDU1MgaWRlbnRpZmllciBjaGFyYWN0ZXJzXG5cdC8vIEFuIHVucXVvdGVkIHZhbHVlIHNob3VsZCBiZSBhIENTUyBpZGVudGlmaWVyIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdC8vIFByb3BlciBzeW50YXg6IGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCN2YWx1ZS1kZWYtaWRlbnRpZmllclxuXHRpZGVudGlmaWVyID0gY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidyNcIiApLFxuXG5cdC8vIEF0dHJpYnV0ZSBzZWxlY3RvcnM6IGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpKD86XCIgKyB3aGl0ZXNwYWNlICtcblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcblx0XHRcIiooPzonKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCJ8KFwiICsgaWRlbnRpZmllciArIFwiKSl8KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XCIqXFxcXF1cIixcblxuXHRwc2V1ZG9zID0gXCI6KFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIikoPzpcXFxcKChcIiArXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcblx0XHQvLyAxLiBxdW90ZWQgKGNhcHR1cmUgMzsgY2FwdHVyZSA0IG9yIGNhcHR1cmUgNSlcblx0XHRcIignKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCIpfFwiICtcblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcblx0XHRcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXCgpW1xcXFxdXXxcIiArIGF0dHJpYnV0ZXMgKyBcIikqKXxcIiArXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCIrXCIsIFwiZ1wiICksXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICsgd2hpdGVzcGFjZSArIFwiKyRcIiwgXCJnXCIgKSxcblxuXHRyY29tbWEgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiosXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmNvbWJpbmF0b3JzID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFs+K35dfFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgd2hpdGVzcGFjZSArIFwiKlwiICksXG5cblx0cmF0dHJpYnV0ZVF1b3RlcyA9IG5ldyBSZWdFeHAoIFwiPVwiICsgd2hpdGVzcGFjZSArIFwiKihbXlxcXFxdJ1xcXCJdKj8pXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXF1cIiwgXCJnXCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpXCIgKSxcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiVEFHXCI6IG5ldyBSZWdFeHAoIFwiXihcIiArIGNoYXJhY3RlckVuY29kaW5nLnJlcGxhY2UoIFwid1wiLCBcIncqXCIgKSArIFwiKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cdFx0Ly8gRm9yIHVzZSBpbiBsaWJyYXJpZXMgaW1wbGVtZW50aW5nIC5pcygpXG5cdFx0Ly8gV2UgdXNlIHRoaXMgZm9yIFBPUyBtYXRjaGluZyBpbiBgc2VsZWN0YFxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXHRyZXNjYXBlID0gLyd8XFxcXC9nLFxuXG5cdC8vIENTUyBlc2NhcGVzIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXChbXFxcXGRhLWZdezEsNn1cIiArIHdoaXRlc3BhY2UgKyBcIj98KFwiICsgd2hpdGVzcGFjZSArIFwiKXwuKVwiLCBcImlnXCIgKSxcblx0ZnVuZXNjYXBlID0gZnVuY3Rpb24oIF8sIGVzY2FwZWQsIGVzY2FwZWRXaGl0ZXNwYWNlICkge1xuXHRcdHZhciBoaWdoID0gXCIweFwiICsgZXNjYXBlZCAtIDB4MTAwMDA7XG5cdFx0Ly8gTmFOIG1lYW5zIG5vbi1jb2RlcG9pbnRcblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI0XG5cdFx0Ly8gV29ya2Fyb3VuZCBlcnJvbmVvdXMgbnVtZXJpYyBpbnRlcnByZXRhdGlvbiBvZiArXCIweFwiXG5cdFx0cmV0dXJuIGhpZ2ggIT09IGhpZ2ggfHwgZXNjYXBlZFdoaXRlc3BhY2UgP1xuXHRcdFx0ZXNjYXBlZCA6XG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdC8vIEJNUCBjb2RlcG9pbnRcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCArIDB4MTAwMDAgKSA6XG5cdFx0XHRcdC8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKVxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fSxcblxuXHQvLyBVc2VkIGZvciBpZnJhbWVzXG5cdC8vIFNlZSBzZXREb2N1bWVudCgpXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxuXHQvLyBlcnJvciBpbiBJRVxuXHR1bmxvYWRIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG5cdFx0c2V0RG9jdW1lbnQoKTtcblx0fTtcblxuLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0IClcbnRyeSB7XG5cdHB1c2guYXBwbHkoXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXG5cdC8vIERldGVjdCBzaWxlbnRseSBmYWlsaW5nIHB1c2guYXBwbHlcblx0YXJyWyBwcmVmZXJyZWREb2MuY2hpbGROb2Rlcy5sZW5ndGggXS5ub2RlVHlwZTtcbn0gY2F0Y2ggKCBlICkge1xuXHRwdXNoID0geyBhcHBseTogYXJyLmxlbmd0aCA/XG5cblx0XHQvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHB1c2hfbmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoZWxzKSApO1xuXHRcdH0gOlxuXG5cdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHR2YXIgaiA9IHRhcmdldC5sZW5ndGgsXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0Ly8gQ2FuJ3QgdHJ1c3QgTm9kZUxpc3QubGVuZ3RoXG5cdFx0XHR3aGlsZSAoICh0YXJnZXRbaisrXSA9IGVsc1tpKytdKSApIHt9XG5cdFx0XHR0YXJnZXQubGVuZ3RoID0gaiAtIDE7XG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBTaXp6bGUoIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgbWF0Y2gsIGVsZW0sIG0sIG5vZGVUeXBlLFxuXHRcdC8vIFFTQSB2YXJzXG5cdFx0aSwgZ3JvdXBzLCBvbGQsIG5pZCwgbmV3Q29udGV4dCwgbmV3U2VsZWN0b3I7XG5cblx0aWYgKCAoIGNvbnRleHQgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IHByZWZlcnJlZERvYyApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cblx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXHRub2RlVHlwZSA9IGNvbnRleHQubm9kZVR5cGU7XG5cblx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgfHwgIXNlbGVjdG9yIHx8XG5cdFx0bm9kZVR5cGUgIT09IDEgJiYgbm9kZVR5cGUgIT09IDkgJiYgbm9kZVR5cGUgIT09IDExICkge1xuXG5cdFx0cmV0dXJuIHJlc3VsdHM7XG5cdH1cblxuXHRpZiAoICFzZWVkICYmIGRvY3VtZW50SXNIVE1MICkge1xuXG5cdFx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyB3aGVuIHBvc3NpYmxlIChlLmcuLCBub3QgdW5kZXIgRG9jdW1lbnRGcmFnbWVudClcblx0XHRpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIiNJRFwiKVxuXHRcdFx0aWYgKCAobSA9IG1hdGNoWzFdKSApIHtcblx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggbSApO1xuXHRcdFx0XHRcdC8vIENoZWNrIHBhcmVudE5vZGUgdG8gY2F0Y2ggd2hlbiBCbGFja2JlcnJ5IDQuNiByZXR1cm5zXG5cdFx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAoalF1ZXJ5ICM2OTYzKVxuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgSUUsIE9wZXJhLCBhbmQgV2Via2l0IHJldHVybiBpdGVtc1xuXHRcdFx0XHRcdFx0Ly8gYnkgbmFtZSBpbnN0ZWFkIG9mIElEXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIENvbnRleHQgaXMgbm90IGEgZG9jdW1lbnRcblx0XHRcdFx0XHRpZiAoIGNvbnRleHQub3duZXJEb2N1bWVudCAmJiAoZWxlbSA9IGNvbnRleHQub3duZXJEb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbSApKSAmJlxuXHRcdFx0XHRcdFx0Y29udGFpbnMoIGNvbnRleHQsIGVsZW0gKSAmJiBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIlRBR1wiKVxuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbMl0gKSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHNlbGVjdG9yICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdC8vIFNwZWVkLXVwOiBTaXp6bGUoXCIuQ0xBU1NcIilcblx0XHRcdH0gZWxzZSBpZiAoIChtID0gbWF0Y2hbM10pICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBtICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUVNBIHBhdGhcblx0XHRpZiAoIHN1cHBvcnQucXNhICYmICghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7XG5cdFx0XHRuaWQgPSBvbGQgPSBleHBhbmRvO1xuXHRcdFx0bmV3Q29udGV4dCA9IGNvbnRleHQ7XG5cdFx0XHRuZXdTZWxlY3RvciA9IG5vZGVUeXBlICE9PSAxICYmIHNlbGVjdG9yO1xuXG5cdFx0XHQvLyBxU0Egd29ya3Mgc3RyYW5nZWx5IG9uIEVsZW1lbnQtcm9vdGVkIHF1ZXJpZXNcblx0XHRcdC8vIFdlIGNhbiB3b3JrIGFyb3VuZCB0aGlzIGJ5IHNwZWNpZnlpbmcgYW4gZXh0cmEgSUQgb24gdGhlIHJvb3Rcblx0XHRcdC8vIGFuZCB3b3JraW5nIHVwIGZyb20gdGhlcmUgKFRoYW5rcyB0byBBbmRyZXcgRHVwb250IGZvciB0aGUgdGVjaG5pcXVlKVxuXHRcdFx0Ly8gSUUgOCBkb2Vzbid0IHdvcmsgb24gb2JqZWN0IGVsZW1lbnRzXG5cdFx0XHRpZiAoIG5vZGVUeXBlID09PSAxICYmIGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJvYmplY3RcIiApIHtcblx0XHRcdFx0Z3JvdXBzID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cblx0XHRcdFx0aWYgKCAob2xkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoXCJpZFwiKSkgKSB7XG5cdFx0XHRcdFx0bmlkID0gb2xkLnJlcGxhY2UoIHJlc2NhcGUsIFwiXFxcXCQmXCIgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCBuaWQgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRuaWQgPSBcIltpZD0nXCIgKyBuaWQgKyBcIiddIFwiO1xuXG5cdFx0XHRcdGkgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRncm91cHNbaV0gPSBuaWQgKyB0b1NlbGVjdG9yKCBncm91cHNbaV0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRuZXdDb250ZXh0ID0gcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dDtcblx0XHRcdFx0bmV3U2VsZWN0b3IgPSBncm91cHMuam9pbihcIixcIik7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggbmV3U2VsZWN0b3IgKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cyxcblx0XHRcdFx0XHRcdG5ld0NvbnRleHQucXVlcnlTZWxlY3RvckFsbCggbmV3U2VsZWN0b3IgKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH0gY2F0Y2gocXNhRXJyb3IpIHtcblx0XHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0XHRpZiAoICFvbGQgKSB7XG5cdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZShcImlkXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFsbCBvdGhlcnNcblx0cmV0dXJuIHNlbGVjdCggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGtleS12YWx1ZSBjYWNoZXMgb2YgbGltaXRlZCBzaXplXG4gKiBAcmV0dXJucyB7RnVuY3Rpb24oc3RyaW5nLCBPYmplY3QpfSBSZXR1cm5zIHRoZSBPYmplY3QgZGF0YSBhZnRlciBzdG9yaW5nIGl0IG9uIGl0c2VsZiB3aXRoXG4gKlx0cHJvcGVydHkgbmFtZSB0aGUgKHNwYWNlLXN1ZmZpeGVkKSBzdHJpbmcgYW5kIChpZiB0aGUgY2FjaGUgaXMgbGFyZ2VyIHRoYW4gRXhwci5jYWNoZUxlbmd0aClcbiAqXHRkZWxldGluZyB0aGUgb2xkZXN0IGVudHJ5XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNhY2hlKCkge1xuXHR2YXIga2V5cyA9IFtdO1xuXG5cdGZ1bmN0aW9uIGNhY2hlKCBrZXksIHZhbHVlICkge1xuXHRcdC8vIFVzZSAoa2V5ICsgXCIgXCIpIHRvIGF2b2lkIGNvbGxpc2lvbiB3aXRoIG5hdGl2ZSBwcm90b3R5cGUgcHJvcGVydGllcyAoc2VlIElzc3VlICMxNTcpXG5cdFx0aWYgKCBrZXlzLnB1c2goIGtleSArIFwiIFwiICkgPiBFeHByLmNhY2hlTGVuZ3RoICkge1xuXHRcdFx0Ly8gT25seSBrZWVwIHRoZSBtb3N0IHJlY2VudCBlbnRyaWVzXG5cdFx0XHRkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdO1xuXHRcdH1cblx0XHRyZXR1cm4gKGNhY2hlWyBrZXkgKyBcIiBcIiBdID0gdmFsdWUpO1xuXHR9XG5cdHJldHVybiBjYWNoZTtcbn1cblxuLyoqXG4gKiBNYXJrIGEgZnVuY3Rpb24gZm9yIHNwZWNpYWwgdXNlIGJ5IFNpenpsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIG1hcmtcbiAqL1xuZnVuY3Rpb24gbWFya0Z1bmN0aW9uKCBmbiApIHtcblx0Zm5bIGV4cGFuZG8gXSA9IHRydWU7XG5cdHJldHVybiBmbjtcbn1cblxuLyoqXG4gKiBTdXBwb3J0IHRlc3RpbmcgdXNpbmcgYW4gZWxlbWVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gUGFzc2VkIHRoZSBjcmVhdGVkIGRpdiBhbmQgZXhwZWN0cyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG5cdHRyeSB7XG5cdFx0cmV0dXJuICEhZm4oIGRpdiApO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9IGZpbmFsbHkge1xuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZGl2LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRkaXYucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggZGl2ICk7XG5cdFx0fVxuXHRcdC8vIHJlbGVhc2UgbWVtb3J5IGluIElFXG5cdFx0ZGl2ID0gbnVsbDtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgdGhlIHNhbWUgaGFuZGxlciBmb3IgYWxsIG9mIHRoZSBzcGVjaWZpZWQgYXR0cnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBhdHRycyBQaXBlLXNlcGFyYXRlZCBsaXN0IG9mIGF0dHJpYnV0ZXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXIgVGhlIG1ldGhvZCB0aGF0IHdpbGwgYmUgYXBwbGllZFxuICovXG5mdW5jdGlvbiBhZGRIYW5kbGUoIGF0dHJzLCBoYW5kbGVyICkge1xuXHR2YXIgYXJyID0gYXR0cnMuc3BsaXQoXCJ8XCIpLFxuXHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cblx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0RXhwci5hdHRySGFuZGxlWyBhcnJbaV0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0KCB+Yi5zb3VyY2VJbmRleCB8fCBNQVhfTkVHQVRJVkUgKSAtXG5cdFx0XHQoIH5hLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApO1xuXG5cdC8vIFVzZSBJRSBzb3VyY2VJbmRleCBpZiBhdmFpbGFibGUgb24gYm90aCBub2Rlc1xuXHRpZiAoIGRpZmYgKSB7XG5cdFx0cmV0dXJuIGRpZmY7XG5cdH1cblxuXHQvLyBDaGVjayBpZiBiIGZvbGxvd3MgYVxuXHRpZiAoIGN1ciApIHtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIubmV4dFNpYmxpbmcpICkge1xuXHRcdFx0aWYgKCBjdXIgPT09IGIgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gYSA/IDEgOiAtMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGlucHV0IHR5cGVzXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbnB1dFBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgYnV0dG9uc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQnV0dG9uUHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIChuYW1lID09PSBcImlucHV0XCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIikgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgcG9zaXRpb25hbHNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZuICkge1xuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcblx0XHRhcmd1bWVudCA9ICthcmd1bWVudDtcblx0XHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0dmFyIGosXG5cdFx0XHRcdG1hdGNoSW5kZXhlcyA9IGZuKCBbXSwgc2VlZC5sZW5ndGgsIGFyZ3VtZW50ICksXG5cdFx0XHRcdGkgPSBtYXRjaEluZGV4ZXMubGVuZ3RoO1xuXG5cdFx0XHQvLyBNYXRjaCBlbGVtZW50cyBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4ZXNcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoIHNlZWRbIChqID0gbWF0Y2hJbmRleGVzW2ldKSBdICkge1xuXHRcdFx0XHRcdHNlZWRbal0gPSAhKG1hdGNoZXNbal0gPSBzZWVkW2pdKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dFxuICogQHJldHVybnMge0VsZW1lbnR8T2JqZWN0fEJvb2xlYW59IFRoZSBpbnB1dCBub2RlIGlmIGFjY2VwdGFibGUsIG90aGVyd2lzZSBhIGZhbHN5IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkge1xuXHRyZXR1cm4gY29udGV4dCAmJiB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdC8vIGRvY3VtZW50RWxlbWVudCBpcyB2ZXJpZmllZCBmb3IgY2FzZXMgd2hlcmUgaXQgZG9lc24ndCB5ZXQgZXhpc3Rcblx0Ly8gKHN1Y2ggYXMgbG9hZGluZyBpZnJhbWVzIGluIElFIC0gIzQ4MzMpXG5cdHZhciBkb2N1bWVudEVsZW1lbnQgPSBlbGVtICYmIChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSkuZG9jdW1lbnRFbGVtZW50O1xuXHRyZXR1cm4gZG9jdW1lbnRFbGVtZW50ID8gZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSBcIkhUTUxcIiA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKi9cbnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7XG5cdHZhciBoYXNDb21wYXJlLCBwYXJlbnQsXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xuXG5cdC8vIElmIG5vIGRvY3VtZW50IGFuZCBkb2N1bWVudEVsZW1lbnQgaXMgYXZhaWxhYmxlLCByZXR1cm5cblx0aWYgKCBkb2MgPT09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHQvLyBTZXQgb3VyIGRvY3VtZW50XG5cdGRvY3VtZW50ID0gZG9jO1xuXHRkb2NFbGVtID0gZG9jLmRvY3VtZW50RWxlbWVudDtcblx0cGFyZW50ID0gZG9jLmRlZmF1bHRWaWV3O1xuXG5cdC8vIFN1cHBvcnQ6IElFPjhcblx0Ly8gSWYgaWZyYW1lIGRvY3VtZW50IGlzIGFzc2lnbmVkIHRvIFwiZG9jdW1lbnRcIiB2YXJpYWJsZSBhbmQgaWYgaWZyYW1lIGhhcyBiZWVuIHJlbG9hZGVkLFxuXHQvLyBJRSB3aWxsIHRocm93IFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIGFjY2Vzc2luZyBcImRvY3VtZW50XCIgdmFyaWFibGUsIHNlZSBqUXVlcnkgIzEzOTM2XG5cdC8vIElFNi04IGRvIG5vdCBzdXBwb3J0IHRoZSBkZWZhdWx0VmlldyBwcm9wZXJ0eSBzbyBwYXJlbnQgd2lsbCBiZSB1bmRlZmluZWRcblx0aWYgKCBwYXJlbnQgJiYgcGFyZW50ICE9PSBwYXJlbnQudG9wICkge1xuXHRcdC8vIElFMTEgZG9lcyBub3QgaGF2ZSBhdHRhY2hFdmVudCwgc28gYWxsIG11c3Qgc3VmZmVyXG5cdFx0aWYgKCBwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdHBhcmVudC5hZGRFdmVudExpc3RlbmVyKCBcInVubG9hZFwiLCB1bmxvYWRIYW5kbGVyLCBmYWxzZSApO1xuXHRcdH0gZWxzZSBpZiAoIHBhcmVudC5hdHRhY2hFdmVudCApIHtcblx0XHRcdHBhcmVudC5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCB1bmxvYWRIYW5kbGVyICk7XG5cdFx0fVxuXHR9XG5cblx0LyogU3VwcG9ydCB0ZXN0c1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2MgKTtcblxuXHQvKiBBdHRyaWJ1dGVzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBTdXBwb3J0OiBJRTw4XG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xuXHQvLyAoZXhjZXB0aW5nIElFOCBib29sZWFucylcblx0c3VwcG9ydC5hdHRyaWJ1dGVzID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmNsYXNzTmFtZSA9IFwiaVwiO1xuXHRcdHJldHVybiAhZGl2LmdldEF0dHJpYnV0ZShcImNsYXNzTmFtZVwiKTtcblx0fSk7XG5cblx0LyogZ2V0RWxlbWVudChzKUJ5KlxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpIHJldHVybnMgb25seSBlbGVtZW50c1xuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlQ29tbWVudChcIlwiKSApO1xuXHRcdHJldHVybiAhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKS5sZW5ndGg7XG5cdH0pO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDlcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gcm5hdGl2ZS50ZXN0KCBkb2MuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDEwXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRCeUlkIHJldHVybnMgZWxlbWVudHMgYnkgbmFtZVxuXHQvLyBUaGUgYnJva2VuIGdldEVsZW1lbnRCeUlkIG1ldGhvZHMgZG9uJ3QgcGljayB1cCBwcm9ncmFtYXRpY2FsbHktc2V0IG5hbWVzLFxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3Rcblx0c3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZGl2ICkuaWQgPSBleHBhbmRvO1xuXHRcdHJldHVybiAhZG9jLmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2MuZ2V0RWxlbWVudHNCeU5hbWUoIGV4cGFuZG8gKS5sZW5ndGg7XG5cdH0pO1xuXG5cdC8vIElEIGZpbmQgYW5kIGZpbHRlclxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbmRbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblx0XHRcdFx0Ly8gQ2hlY2sgcGFyZW50Tm9kZSB0byBjYXRjaCB3aGVuIEJsYWNrYmVycnkgNC42IHJldHVybnNcblx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAjNjk2M1xuXHRcdFx0XHRyZXR1cm4gbSAmJiBtLnBhcmVudE5vZGUgPyBbIG0gXSA6IFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJpZFwiKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdC8vIFN1cHBvcnQ6IElFNi83XG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxuXHRcdGRlbGV0ZSBFeHByLmZpbmRbXCJJRFwiXTtcblxuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSAgZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9XG5cblx0Ly8gVGFnXG5cdEV4cHIuZmluZFtcIlRBR1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cblx0XHRcdFx0cmVzdWx0cyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXG5cdFx0XHRpZiAoIHRhZyA9PT0gXCIqXCIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSByZXN1bHRzW2krK10pICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdHRtcC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRtcDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kW1wiQ0xBU1NcIl0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZnVuY3Rpb24oIGNsYXNzTmFtZSwgY29udGV4dCApIHtcblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggY2xhc3NOYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3Jcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcblxuXHQvLyBtYXRjaGVzU2VsZWN0b3IoOmFjdGl2ZSkgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKElFOS9PcGVyYSAxMS41KVxuXHRyYnVnZ3lNYXRjaGVzID0gW107XG5cblx0Ly8gcVNhKDpmb2N1cykgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKENocm9tZSAyMSlcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXG5cdC8vIHdoZW5ldmVyIGBkb2N1bWVudC5hY3RpdmVFbGVtZW50YCBpcyBhY2Nlc3NlZCBvbiBhbiBpZnJhbWVcblx0Ly8gU28sIHdlIGFsbG93IDpmb2N1cyB0byBwYXNzIHRocm91Z2ggUVNBIGFsbCB0aGUgdGltZSB0byBhdm9pZCB0aGUgSUUgZXJyb3Jcblx0Ly8gU2VlIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2MucXVlcnlTZWxlY3RvckFsbCApKSApIHtcblx0XHQvLyBCdWlsZCBRU0EgcmVnZXhcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBTZWxlY3QgaXMgc2V0IHRvIGVtcHR5IHN0cmluZyBvbiBwdXJwb3NlXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcblx0XHRcdC8vIHNldHRpbmcgYSBib29sZWFuIGNvbnRlbnQgYXR0cmlidXRlLFxuXHRcdFx0Ly8gc2luY2UgaXRzIHByZXNlbmNlIHNob3VsZCBiZSBlbm91Z2hcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XG5cdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBkaXYgKS5pbm5lckhUTUwgPSBcIjxhIGlkPSdcIiArIGV4cGFuZG8gKyBcIic+PC9hPlwiICtcblx0XHRcdFx0XCI8c2VsZWN0IGlkPSdcIiArIGV4cGFuZG8gKyBcIi1cXGZdJyBtc2FsbG93Y2FwdHVyZT0nJz5cIiArXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LCBPcGVyYSAxMS0xMi4xNlxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxuXHRcdFx0Ly8gVGhlIHRlc3QgYXR0cmlidXRlIG11c3QgYmUgdW5rbm93biBpbiBPcGVyYSBidXQgXCJzYWZlXCIgZm9yIFdpblJUXG5cdFx0XHQvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvaGg0NjUzODguYXNweCNhdHRyaWJ1dGVfc2VjdGlvblxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIlttc2FsbG93Y2FwdHVyZV49JyddXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiWypeJF09XCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86Jyd8XFxcIlxcXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgYW5kIFwidmFsdWVcIiBhcmUgbm90IHRyZWF0ZWQgY29ycmVjdGx5XG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWU8MjksIEFuZHJvaWQ8NC4yKywgU2FmYXJpPDcuMCssIGlPUzw3LjArLCBQaGFudG9tSlM8MS45LjcrXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJbaWR+PVwiICsgZXhwYW5kbyArIFwiLV1cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCJ+PVwiKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gV2Via2l0L09wZXJhIC0gOmNoZWNrZWQgc2hvdWxkIHJldHVybiBzZWxlY3RlZCBvcHRpb24gZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6Y2hlY2tlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwiOmNoZWNrZWRcIik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA4KywgaU9TIDgrXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXG5cdFx0XHQvLyBJbi1wYWdlIGBzZWxlY3RvciNpZCBzaWJpbmctY29tYmluYXRvciBzZWxlY3RvcmAgZmFpbHNcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKCBcImEjXCIgKyBleHBhbmRvICsgXCIrKlwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIi4jLitbK35dXCIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBTdXBwb3J0OiBXaW5kb3dzIDggTmF0aXZlIEFwcHNcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxuXHRcdFx0dmFyIGlucHV0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwiaGlkZGVuXCIgKTtcblx0XHRcdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKS5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcIkRcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEVuZm9yY2UgY2FzZS1zZW5zaXRpdml0eSBvZiBuYW1lIGF0dHJpYnV0ZVxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIltuYW1lPWRdXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiOmVuYWJsZWRcIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXG5cdFx0XHRkaXYucXVlcnlTZWxlY3RvckFsbChcIiosOnhcIik7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaChcIiwuKjpcIik7XG5cdFx0fSk7XG5cdH1cblxuXHRpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcblx0XHRkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvcikgKSkgKSB7XG5cblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIENoZWNrIHRvIHNlZSBpZiBpdCdzIHBvc3NpYmxlIHRvIGRvIG1hdGNoZXNTZWxlY3RvclxuXHRcdFx0Ly8gb24gYSBkaXNjb25uZWN0ZWQgbm9kZSAoSUUgOSlcblx0XHRcdHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggPSBtYXRjaGVzLmNhbGwoIGRpdiwgXCJkaXZcIiApO1xuXG5cdFx0XHQvLyBUaGlzIHNob3VsZCBmYWlsIHdpdGggYW4gZXhjZXB0aW9uXG5cdFx0XHQvLyBHZWNrbyBkb2VzIG5vdCBlcnJvciwgcmV0dXJucyBmYWxzZSBpbnN0ZWFkXG5cdFx0XHRtYXRjaGVzLmNhbGwoIGRpdiwgXCJbcyE9JyddOnhcIiApO1xuXHRcdFx0cmJ1Z2d5TWF0Y2hlcy5wdXNoKCBcIiE9XCIsIHBzZXVkb3MgKTtcblx0XHR9KTtcblx0fVxuXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oXCJ8XCIpICk7XG5cdHJidWdneU1hdGNoZXMgPSByYnVnZ3lNYXRjaGVzLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lNYXRjaGVzLmpvaW4oXCJ8XCIpICk7XG5cblx0LyogQ29udGFpbnNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXHRoYXNDb21wYXJlID0gcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICk7XG5cblx0Ly8gRWxlbWVudCBjb250YWlucyBhbm90aGVyXG5cdC8vIFB1cnBvc2VmdWxseSBkb2VzIG5vdCBpbXBsZW1lbnQgaW5jbHVzaXZlIGRlc2NlbmRlbnRcblx0Ly8gQXMgaW4sIGFuIGVsZW1lbnQgZG9lcyBub3QgY29udGFpbiBpdHNlbGZcblx0Y29udGFpbnMgPSBoYXNDb21wYXJlIHx8IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb250YWlucyApID9cblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdHZhciBhZG93biA9IGEubm9kZVR5cGUgPT09IDkgPyBhLmRvY3VtZW50RWxlbWVudCA6IGEsXG5cdFx0XHRcdGJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlO1xuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXG5cdFx0XHRcdGFkb3duLmNvbnRhaW5zID9cblx0XHRcdFx0XHRhZG93bi5jb250YWlucyggYnVwICkgOlxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxuXHRcdFx0KSk7XG5cdFx0fSA6XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHRpZiAoIGIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGIgPSBiLnBhcmVudE5vZGUpICkge1xuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cblx0LyogU29ydGluZ1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gRG9jdW1lbnQgb3JkZXIgc29ydGluZ1xuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXG5cdFx0dmFyIGNvbXBhcmUgPSAhYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAtICFiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uO1xuXHRcdGlmICggY29tcGFyZSApIHtcblx0XHRcdHJldHVybiBjb21wYXJlO1xuXHRcdH1cblxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09PSAoIGIub3duZXJEb2N1bWVudCB8fCBiICkgP1xuXHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYiApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHdlIGtub3cgdGhleSBhcmUgZGlzY29ubmVjdGVkXG5cdFx0XHQxO1xuXG5cdFx0Ly8gRGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0aWYgKCBjb21wYXJlICYgMSB8fFxuXHRcdFx0KCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkge1xuXG5cdFx0XHQvLyBDaG9vc2UgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyByZWxhdGVkIHRvIG91ciBwcmVmZXJyZWQgZG9jdW1lbnRcblx0XHRcdGlmICggYSA9PT0gZG9jIHx8IGEub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYSkgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHRcdGlmICggYiA9PT0gZG9jIHx8IGIub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYikgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxuXHRcdFx0cmV0dXJuIHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF1cCA9IGEucGFyZW50Tm9kZSxcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcblx0XHRcdGFwID0gWyBhIF0sXG5cdFx0XHRicCA9IFsgYiBdO1xuXG5cdFx0Ly8gUGFyZW50bGVzcyBub2RlcyBhcmUgZWl0aGVyIGRvY3VtZW50cyBvciBkaXNjb25uZWN0ZWRcblx0XHRpZiAoICFhdXAgfHwgIWJ1cCApIHtcblx0XHRcdHJldHVybiBhID09PSBkb2MgPyAtMSA6XG5cdFx0XHRcdGIgPT09IGRvYyA/IDEgOlxuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHQvLyBJZiB0aGUgbm9kZXMgYXJlIHNpYmxpbmdzLCB3ZSBjYW4gZG8gYSBxdWljayBjaGVja1xuXHRcdH0gZWxzZSBpZiAoIGF1cCA9PT0gYnVwICkge1xuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cdFx0Y3VyID0gYjtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRicC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cblx0XHQvLyBXYWxrIGRvd24gdGhlIHRyZWUgbG9va2luZyBmb3IgYSBkaXNjcmVwYW5jeVxuXHRcdHdoaWxlICggYXBbaV0gPT09IGJwW2ldICkge1xuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdHJldHVybiBpID9cblx0XHRcdC8vIERvIGEgc2libGluZyBjaGVjayBpZiB0aGUgbm9kZXMgaGF2ZSBhIGNvbW1vbiBhbmNlc3RvclxuXHRcdFx0c2libGluZ0NoZWNrKCBhcFtpXSwgYnBbaV0gKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSBub2RlcyBpbiBvdXIgZG9jdW1lbnQgc29ydCBmaXJzdFxuXHRcdFx0YXBbaV0gPT09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcblx0XHRcdDA7XG5cdH07XG5cblx0cmV0dXJuIGRvYztcbn07XG5cblNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xufTtcblxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHQvLyBNYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGUgc2VsZWN0b3JzIGFyZSBxdW90ZWRcblx0ZXhwciA9IGV4cHIucmVwbGFjZSggcmF0dHJpYnV0ZVF1b3RlcywgXCI9JyQxJ11cIiApO1xuXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcblx0XHQoICFyYnVnZ3lNYXRjaGVzIHx8ICFyYnVnZ3lNYXRjaGVzLnRlc3QoIGV4cHIgKSApICYmXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xuXG5cdFx0dHJ5IHtcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcblxuXHRcdFx0Ly8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxuXHRcdFx0XHRcdC8vIEFzIHdlbGwsIGRpc2Nvbm5lY3RlZCBub2RlcyBhcmUgc2FpZCB0byBiZSBpbiBhIGRvY3VtZW50XG5cdFx0XHRcdFx0Ly8gZnJhZ21lbnQgaW4gSUUgOVxuXHRcdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoZSkge31cblx0fVxuXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XG59O1xuXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0dmFyIGZuID0gRXhwci5hdHRySGFuZGxlWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSxcblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/XG5cdFx0dmFsIDpcblx0XHRzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWRvY3VtZW50SXNIVE1MID9cblx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgOlxuXHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG59O1xuXG5TaXp6bGUuZXJyb3IgPSBmdW5jdGlvbiggbXNnICkge1xuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcbn07XG5cbi8qKlxuICogRG9jdW1lbnQgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlc1xuICogQHBhcmFtIHtBcnJheUxpa2V9IHJlc3VsdHNcbiAqL1xuU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbiggcmVzdWx0cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxuXHRcdGogPSAwLFxuXHRcdGkgPSAwO1xuXG5cdC8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2Vcblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRpZiAoIGVsZW0gPT09IHJlc3VsdHNbIGkgXSApIHtcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdHJlc3VsdHMuc3BsaWNlKCBkdXBsaWNhdGVzWyBqIF0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDbGVhciBpbnB1dCBhZnRlciBzb3J0aW5nIHRvIHJlbGVhc2Ugb2JqZWN0c1xuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcblx0c29ydElucHV0ID0gbnVsbDtcblxuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdGV4dCB2YWx1ZSBvZiBhbiBhcnJheSBvZiBET00gbm9kZXNcbiAqIEBwYXJhbSB7QXJyYXl8RWxlbWVudH0gZWxlbVxuICovXG5nZXRUZXh0ID0gU2l6emxlLmdldFRleHQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0dmFyIG5vZGUsXG5cdFx0cmV0ID0gXCJcIixcblx0XHRpID0gMCxcblx0XHRub2RlVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0aWYgKCAhbm9kZVR5cGUgKSB7XG5cdFx0Ly8gSWYgbm8gbm9kZVR5cGUsIHRoaXMgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXlcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcblx0XHRcdC8vIERvIG5vdCB0cmF2ZXJzZSBjb21tZW50IG5vZGVzXG5cdFx0XHRyZXQgKz0gZ2V0VGV4dCggbm9kZSApO1xuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDkgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXHRcdC8vIFVzZSB0ZXh0Q29udGVudCBmb3IgZWxlbWVudHNcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxuXHRcdGlmICggdHlwZW9mIGVsZW0udGV4dENvbnRlbnQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS50ZXh0Q29udGVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gVHJhdmVyc2UgaXRzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVWYWx1ZTtcblx0fVxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcblxuXHRyZXR1cm4gcmV0O1xufTtcblxuRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0Ly8gTW92ZSB0aGUgZ2l2ZW4gdmFsdWUgdG8gbWF0Y2hbM10gd2hldGhlciBxdW90ZWQgb3IgdW5xdW90ZWRcblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsyXSA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0LyogbWF0Y2hlcyBmcm9tIG1hdGNoRXhwcltcIkNISUxEXCJdXG5cdFx0XHRcdDEgdHlwZSAob25seXxudGh8Li4uKVxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdDMgYXJndW1lbnQgKGV2ZW58b2RkfFxcZCp8XFxkKm4oWystXVxcZCspP3wuLi4pXG5cdFx0XHRcdDQgeG4tY29tcG9uZW50IG9mIHhuK3kgYXJndW1lbnQgKFsrLV0/XFxkKm58KVxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDYgeCBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NyBzaWduIG9mIHktY29tcG9uZW50XG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxuXHRcdFx0Ki9cblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsxXS5zbGljZSggMCwgMyApID09PSBcIm50aFwiICkge1xuXHRcdFx0XHQvLyBudGgtKiByZXF1aXJlcyBhcmd1bWVudFxuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBudW1lcmljIHggYW5kIHkgcGFyYW1ldGVycyBmb3IgRXhwci5maWx0ZXIuQ0hJTERcblx0XHRcdFx0Ly8gcmVtZW1iZXIgdGhhdCBmYWxzZS90cnVlIGNhc3QgcmVzcGVjdGl2ZWx5IHRvIDAvMVxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xuXHRcdFx0XHRtYXRjaFs1XSA9ICsoICggbWF0Y2hbN10gKyBtYXRjaFs4XSApIHx8IG1hdGNoWzNdID09PSBcIm9kZFwiICk7XG5cblx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHR2YXIgZXhjZXNzLFxuXHRcdFx0XHR1bnF1b3RlZCA9ICFtYXRjaFs2XSAmJiBtYXRjaFsyXTtcblxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbXCJDSElMRFwiXS50ZXN0KCBtYXRjaFswXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdG1hdGNoWzJdID0gbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIjtcblxuXHRcdFx0Ly8gU3RyaXAgZXhjZXNzIGNoYXJhY3RlcnMgZnJvbSB1bnF1b3RlZCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxuXHRcdFx0XHQvLyBHZXQgZXhjZXNzIGZyb20gdG9rZW5pemUgKHJlY3Vyc2l2ZWx5KVxuXHRcdFx0XHQoZXhjZXNzID0gdG9rZW5pemUoIHVucXVvdGVkLCB0cnVlICkpICYmXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xuXHRcdFx0XHQoZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoKSApIHtcblxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxuXHRcdFx0XHRtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdFx0bWF0Y2hbMl0gPSB1bnF1b3RlZC5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHVybiBvbmx5IGNhcHR1cmVzIG5lZWRlZCBieSB0aGUgcHNldWRvIGZpbHRlciBtZXRob2QgKHR5cGUgYW5kIGFyZ3VtZW50KVxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XG5cdFx0fVxuXHR9LFxuXG5cdGZpbHRlcjoge1xuXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBub2RlTmFtZVNlbGVjdG9yLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBub2RlTmFtZVNlbGVjdG9yID09PSBcIipcIiA/XG5cdFx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbm9kZU5hbWU7XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcblx0XHRcdHZhciBwYXR0ZXJuID0gY2xhc3NDYWNoZVsgY2xhc3NOYW1lICsgXCIgXCIgXTtcblxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcblx0XHRcdFx0KHBhdHRlcm4gPSBuZXcgUmVnRXhwKCBcIihefFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgY2xhc3NOYW1lICsgXCIoXCIgKyB3aGl0ZXNwYWNlICsgXCJ8JClcIiApKSAmJlxuXHRcdFx0XHRjbGFzc0NhY2hlKCBjbGFzc05hbWUsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoIHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSB8fCBcIlwiICk7XG5cdFx0XHRcdH0pO1xuXHRcdH0sXG5cblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG5hbWUsIG9wZXJhdG9yLCBjaGVjayApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdFx0aWYgKCByZXN1bHQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiIT1cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoICFvcGVyYXRvciApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJlc3VsdCArPSBcIlwiO1xuXG5cdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCI9XCIgPyByZXN1bHQgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIhPVwiID8gcmVzdWx0ICE9PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiXj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID09PSAwIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIqPVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiJD1cIiA/IGNoZWNrICYmIHJlc3VsdC5zbGljZSggLWNoZWNrLmxlbmd0aCApID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifj1cIiA/ICggXCIgXCIgKyByZXN1bHQucmVwbGFjZSggcndoaXRlc3BhY2UsIFwiIFwiICkgKyBcIiBcIiApLmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifD1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgfHwgcmVzdWx0LnNsaWNlKCAwLCBjaGVjay5sZW5ndGggKyAxICkgPT09IGNoZWNrICsgXCItXCIgOlxuXHRcdFx0XHRcdGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggdHlwZSwgd2hhdCwgYXJndW1lbnQsIGZpcnN0LCBsYXN0ICkge1xuXHRcdFx0dmFyIHNpbXBsZSA9IHR5cGUuc2xpY2UoIDAsIDMgKSAhPT0gXCJudGhcIixcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxuXHRcdFx0XHRvZlR5cGUgPSB3aGF0ID09PSBcIm9mLXR5cGVcIjtcblxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xuXG5cdFx0XHRcdC8vIFNob3J0Y3V0IGZvciA6bnRoLSoobilcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuICEhZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0XHR9IDpcblxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBjYWNoZSwgb3V0ZXJDYWNoZSwgbm9kZSwgZGlmZiwgbm9kZUluZGV4LCBzdGFydCxcblx0XHRcdFx0XHRcdGRpciA9IHNpbXBsZSAhPT0gZm9yd2FyZCA/IFwibmV4dFNpYmxpbmdcIiA6IFwicHJldmlvdXNTaWJsaW5nXCIsXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXG5cdFx0XHRcdFx0XHRuYW1lID0gb2ZUeXBlICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcblx0XHRcdFx0XHRcdHVzZUNhY2hlID0gIXhtbCAmJiAhb2ZUeXBlO1xuXG5cdFx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIDooZmlyc3R8bGFzdHxvbmx5KS0oY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0XHRcdGlmICggc2ltcGxlICkge1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gbm9kZVsgZGlyIF0pICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBvZlR5cGUgPyBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdC8vIFJldmVyc2UgZGlyZWN0aW9uIGZvciA6b25seS0qIChpZiB3ZSBoYXZlbid0IHlldCBkb25lIHNvKVxuXHRcdFx0XHRcdFx0XHRcdHN0YXJ0ID0gZGlyID0gdHlwZSA9PT0gXCJvbmx5XCIgJiYgIXN0YXJ0ICYmIFwibmV4dFNpYmxpbmdcIjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0c3RhcnQgPSBbIGZvcndhcmQgPyBwYXJlbnQuZmlyc3RDaGlsZCA6IHBhcmVudC5sYXN0Q2hpbGQgXTtcblxuXHRcdFx0XHRcdFx0Ly8gbm9uLXhtbCA6bnRoLWNoaWxkKC4uLikgc3RvcmVzIGNhY2hlIGRhdGEgb24gYHBhcmVudGBcblx0XHRcdFx0XHRcdGlmICggZm9yd2FyZCAmJiB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0Ly8gU2VlayBgZWxlbWAgZnJvbSBhIHByZXZpb3VzbHktY2FjaGVkIGluZGV4XG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBwYXJlbnRbIGV4cGFuZG8gXSB8fCAocGFyZW50WyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRcdGNhY2hlID0gb3V0ZXJDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVswXSA9PT0gZGlycnVucyAmJiBjYWNoZVsxXTtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IGNhY2hlWzBdID09PSBkaXJydW5zICYmIGNhY2hlWzJdO1xuXHRcdFx0XHRcdFx0XHRub2RlID0gbm9kZUluZGV4ICYmIHBhcmVudC5jaGlsZE5vZGVzWyBub2RlSW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFdoZW4gZm91bmQsIGNhY2hlIGluZGV4ZXMgb24gYHBhcmVudGAgYW5kIGJyZWFrXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLm5vZGVUeXBlID09PSAxICYmICsrZGlmZiAmJiBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBub2RlSW5kZXgsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBVc2UgcHJldmlvdXNseS1jYWNoZWQgZWxlbWVudCBpbmRleCBpZiBhdmFpbGFibGVcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHVzZUNhY2hlICYmIChjYWNoZSA9IChlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KSlbIHR5cGUgXSkgJiYgY2FjaGVbMF0gPT09IGRpcnJ1bnMgKSB7XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBjYWNoZVsxXTtcblxuXHRcdFx0XHRcdFx0Ly8geG1sIDpudGgtY2hpbGQoLi4uKSBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBVc2UgdGhlIHNhbWUgbG9vcCBhcyBhYm92ZSB0byBzZWVrIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCAoIG9mVHlwZSA/IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6IG5vZGUubm9kZVR5cGUgPT09IDEgKSAmJiArK2RpZmYgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBDYWNoZSB0aGUgaW5kZXggb2YgZWFjaCBlbmNvdW50ZXJlZCBlbGVtZW50XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQobm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSkpWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgdGhlIG9mZnNldCwgdGhlbiBjaGVjayBhZ2FpbnN0IGN5Y2xlIHNpemVcblx0XHRcdFx0XHRcdGRpZmYgLT0gbGFzdDtcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIHBzZXVkbywgYXJndW1lbnQgKSB7XG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jcHNldWRvLWNsYXNzZXNcblx0XHRcdC8vIFByaW9yaXRpemUgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBjYXNlIGN1c3RvbSBwc2V1ZG9zIGFyZSBhZGRlZCB3aXRoIHVwcGVyY2FzZSBsZXR0ZXJzXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdC8vIFRoZSB1c2VyIG1heSB1c2UgY3JlYXRlUHNldWRvIHRvIGluZGljYXRlIHRoYXRcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXG5cdFx0XHQvLyBqdXN0IGFzIFNpenpsZSBkb2VzXG5cdFx0XHRpZiAoIGZuWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdC8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlXG5cdFx0XHQvLyB0byBhdm9pZCB0cmVhdGluZyBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXG5cdFx0XHR2YXIgaW5wdXQgPSBbXSxcblx0XHRcdFx0cmVzdWx0cyA9IFtdLFxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XG5cblx0XHRcdHJldHVybiBtYXRjaGVyWyBleHBhbmRvIF0gP1xuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0XHRcdHVubWF0Y2hlZCA9IG1hdGNoZXIoIHNlZWQsIG51bGwsIHhtbCwgW10gKSxcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcblxuXHRcdFx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIHVubWF0Y2hlZCBieSBgbWF0Y2hlcmBcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkW2ldID0gIShtYXRjaGVzW2ldID0gZWxlbSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0XHRcdGlucHV0WzBdID0gbnVsbDtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHR0ZXh0ID0gdGV4dC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KGxhbmcgfHwgXCJcIikgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoXCJ4bWw6bGFuZ1wiKSB8fCBlbGVtLmdldEF0dHJpYnV0ZShcImxhbmdcIikpICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIE1pc2NlbGxhbmVvdXNcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBoYXNoID0gd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdFx0cmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkO1xuXHRcdH0sXG5cblx0XHRcInJvb3RcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcblx0XHR9LFxuXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmICghZG9jdW1lbnQuaGFzRm9jdXMgfHwgZG9jdW1lbnQuaGFzRm9jdXMoKSkgJiYgISEoZWxlbS50eXBlIHx8IGVsZW0uaHJlZiB8fCB+ZWxlbS50YWJJbmRleCk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdFwiZW5hYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZTtcblx0XHR9LFxuXG5cdFx0XCJkaXNhYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHRcImNoZWNrZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBJbiBDU1MzLCA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIGJvdGggY2hlY2tlZCBhbmQgc2VsZWN0ZWQgZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gKG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgISFlbGVtLmNoZWNrZWQpIHx8IChub2RlTmFtZSA9PT0gXCJvcHRpb25cIiAmJiAhIWVsZW0uc2VsZWN0ZWQpO1xuXHRcdH0sXG5cblx0XHRcInNlbGVjdGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxuXHRcdFx0Ly8gb3B0aW9ucyBpbiBTYWZhcmkgd29yayBwcm9wZXJseVxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG9cblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcblx0XHRcdC8vICAgYnV0IG5vdCBieSBvdGhlcnMgKGNvbW1lbnQ6IDg7IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb246IDc7IGV0Yy4pXG5cdFx0XHQvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRcInBhcmVudFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcblx0XHR9LFxuXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDhcblx0XHRcdFx0Ly8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sIFwic2VhcmNoXCIpIGFwcGVhciB3aXRoIGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XG5cdFx0fSxcblxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9KSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSlcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zW1wibnRoXCJdID0gRXhwci5wc2V1ZG9zW1wiZXFcIl07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cdFx0XHRcdC8vIERvbid0IGNvbnN1bWUgdHJhaWxpbmcgY29tbWFzIGFzIHZhbGlkXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2Vcblx0XHRcdFx0dHlwZTogbWF0Y2hbMF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0pO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGaWx0ZXJzXG5cdFx0Zm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHtcblx0XHRcdGlmICggKG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSkgJiYgKCFwcmVGaWx0ZXJzWyB0eXBlIF0gfHxcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XG5cdFx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXHRcdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XG59O1xuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zW2ldLnZhbHVlO1xuXHR9XG5cdHJldHVybiBzZWxlY3Rvcjtcbn1cblxuZnVuY3Rpb24gYWRkQ29tYmluYXRvciggbWF0Y2hlciwgY29tYmluYXRvciwgYmFzZSApIHtcblx0dmFyIGRpciA9IGNvbWJpbmF0b3IuZGlyLFxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGRpciA9PT0gXCJwYXJlbnROb2RlXCIsXG5cdFx0ZG9uZU5hbWUgPSBkb25lKys7XG5cblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xuXHRcdC8vIENoZWNrIGFnYWluc3QgY2xvc2VzdCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IDpcblxuXHRcdC8vIENoZWNrIGFnYWluc3QgYWxsIGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50c1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgb2xkQ2FjaGUsIG91dGVyQ2FjaGUsXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xuXG5cdFx0XHQvLyBXZSBjYW4ndCBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gWE1MIG5vZGVzLCBzbyB0aGV5IGRvbid0IGJlbmVmaXQgZnJvbSBkaXIgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8IChlbGVtWyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IG91dGVyQ2FjaGVbIGRpciBdKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyBkaXIgXSA9IG5ld0NhY2hlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEEgbWF0Y2ggbWVhbnMgd2UncmUgZG9uZTsgYSBmYWlsIG1lYW5zIHdlIGhhdmUgdG8ga2VlcCBjaGVja2luZ1xuXHRcdFx0XHRcdFx0XHRpZiAoIChuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcbn1cblxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xuXHRyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggIW1hdGNoZXJzW2ldKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWzBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRpZiAoICFmaWx0ZXIgfHwgZmlsdGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0aWYgKCBtYXBwZWQgKSB7XG5cdFx0XHRcdFx0bWFwLnB1c2goIGkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBuZXdVbm1hdGNoZWQ7XG59XG5cbmZ1bmN0aW9uIHNldE1hdGNoZXIoIHByZUZpbHRlciwgc2VsZWN0b3IsIG1hdGNoZXIsIHBvc3RGaWx0ZXIsIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApIHtcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTtcblx0fVxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmluZGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICk7XG5cdH1cblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxuXHRcdFx0ZWxlbXMgPSBzZWVkIHx8IG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yIHx8IFwiKlwiLCBjb250ZXh0Lm5vZGVUeXBlID8gWyBjb250ZXh0IF0gOiBjb250ZXh0LCBbXSApLFxuXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cblx0XHRcdG1hdGNoZXJJbiA9IHByZUZpbHRlciAmJiAoIHNlZWQgfHwgIXNlbGVjdG9yICkgP1xuXHRcdFx0XHRjb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdGVsZW1zLFxuXG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlciA/XG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHQvLyBGaW5kIHByaW1hcnkgbWF0Y2hlc1xuXHRcdGlmICggbWF0Y2hlciApIHtcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHQvLyBVbi1tYXRjaCBmYWlsaW5nIGVsZW1lbnRzIGJ5IG1vdmluZyB0aGVtIGJhY2sgdG8gbWF0Y2hlckluXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoZWxlbSA9IHRlbXBbaV0pICkge1xuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggc2VlZCApIHtcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XG5cdFx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0XHQvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHNcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaFxuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goIChtYXRjaGVySW5baV0gPSBlbGVtKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCAobWF0Y2hlck91dCA9IFtdKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBNb3ZlIG1hdGNoZWQgZWxlbWVudHMgZnJvbSBzZWVkIHRvIHJlc3VsdHMgdG8ga2VlcCB0aGVtIHN5bmNocm9uaXplZFxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSAmJlxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZiggc2VlZCwgZWxlbSApIDogcHJlTWFwW2ldKSA+IC0xICkge1xuXG5cdFx0XHRcdFx0XHRzZWVkW3RlbXBdID0gIShyZXN1bHRzW3RlbXBdID0gZWxlbSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBZGQgZWxlbWVudHMgdG8gcmVzdWx0cywgdGhyb3VnaCBwb3N0RmluZGVyIGlmIGRlZmluZWRcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlck91dCA9IGNvbmRlbnNlKFxuXHRcdFx0XHRtYXRjaGVyT3V0ID09PSByZXN1bHRzID9cblx0XHRcdFx0XHRtYXRjaGVyT3V0LnNwbGljZSggcHJlZXhpc3RpbmcsIG1hdGNoZXJPdXQubGVuZ3RoICkgOlxuXHRcdFx0XHRcdG1hdGNoZXJPdXRcblx0XHRcdCk7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIHJlc3VsdHMsIG1hdGNoZXJPdXQsIHhtbCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgbWF0Y2hlck91dCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMgKSB7XG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRsZWFkaW5nUmVsYXRpdmUgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbMF0udHlwZSBdLFxuXHRcdGltcGxpY2l0UmVsYXRpdmUgPSBsZWFkaW5nUmVsYXRpdmUgfHwgRXhwci5yZWxhdGl2ZVtcIiBcIl0sXG5cdFx0aSA9IGxlYWRpbmdSZWxhdGl2ZSA/IDEgOiAwLFxuXG5cdFx0Ly8gVGhlIGZvdW5kYXRpb25hbCBtYXRjaGVyIGVuc3VyZXMgdGhhdCBlbGVtZW50cyBhcmUgcmVhY2hhYmxlIGZyb20gdG9wLWxldmVsIGNvbnRleHQocylcblx0XHRtYXRjaENvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBjaGVja0NvbnRleHQ7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoQW55Q29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGluZGV4T2YoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIHJldCA9ICggIWxlYWRpbmdSZWxhdGl2ZSAmJiAoIHhtbCB8fCBjb250ZXh0ICE9PSBvdXRlcm1vc3RDb250ZXh0ICkgKSB8fCAoXG5cdFx0XHRcdChjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/XG5cdFx0XHRcdFx0bWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdFx0bWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApO1xuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRjaGVja0NvbnRleHQgPSBudWxsO1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9IF07XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksIG1hdGNoZXIpIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zW2ldLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zW2ldLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHQvLyBGaW5kIHRoZSBuZXh0IHJlbGF0aXZlIG9wZXJhdG9yIChpZiBhbnkpIGZvciBwcm9wZXIgaGFuZGxpbmdcblx0XHRcdFx0aiA9ICsraTtcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyB0b2tlbnNbal0udHlwZSBdICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBzZXRNYXRjaGVyKFxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxuXHRcdFx0XHRcdGkgPiAxICYmIHRvU2VsZWN0b3IoXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGUgcHJlY2VkaW5nIHRva2VuIHdhcyBhIGRlc2NlbmRhbnQgY29tYmluYXRvciwgaW5zZXJ0IGFuIGltcGxpY2l0IGFueS1lbGVtZW50IGAqYFxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSlcblx0XHRcdFx0XHQpLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSxcblx0XHRcdFx0XHRtYXRjaGVyLFxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgbWF0Y2hlckZyb21Ub2tlbnMoICh0b2tlbnMgPSB0b2tlbnMuc2xpY2UoIGogKSkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIHRvU2VsZWN0b3IoIHRva2VucyApXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRtYXRjaGVycy5wdXNoKCBtYXRjaGVyICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XG5cdHZhciBieVNldCA9IHNldE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0YnlFbGVtZW50ID0gZWxlbWVudE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xuXHRcdFx0dmFyIGVsZW0sIGosIG1hdGNoZXIsXG5cdFx0XHRcdG1hdGNoZWRDb3VudCA9IDAsXG5cdFx0XHRcdGkgPSBcIjBcIixcblx0XHRcdFx0dW5tYXRjaGVkID0gc2VlZCAmJiBbXSxcblx0XHRcdFx0c2V0TWF0Y2hlZCA9IFtdLFxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcblx0XHRcdFx0Ly8gV2UgbXVzdCBhbHdheXMgaGF2ZSBlaXRoZXIgc2VlZCBlbGVtZW50cyBvciBvdXRlcm1vc3QgY29udGV4dFxuXHRcdFx0XHRlbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFtcIlRBR1wiXSggXCIqXCIsIG91dGVybW9zdCApLFxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxuXHRcdFx0XHRkaXJydW5zVW5pcXVlID0gKGRpcnJ1bnMgKz0gY29udGV4dEJhY2t1cCA9PSBudWxsID8gMSA6IE1hdGgucmFuZG9tKCkgfHwgMC4xKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHQgIT09IGRvY3VtZW50ICYmIGNvbnRleHQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBlbGVtZW50cyBwYXNzaW5nIGVsZW1lbnRNYXRjaGVycyBkaXJlY3RseSB0byByZXN1bHRzXG5cdFx0XHQvLyBLZWVwIGBpYCBhIHN0cmluZyBpZiB0aGVyZSBhcmUgbm8gZWxlbWVudHMgc28gYG1hdGNoZWRDb3VudGAgd2lsbCBiZSBcIjAwXCIgYmVsb3dcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUcmFjayB1bm1hdGNoZWQgZWxlbWVudHMgZm9yIHNldCBmaWx0ZXJzXG5cdFx0XHRcdGlmICggYnlTZXQgKSB7XG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSAhbWF0Y2hlciAmJiBlbGVtKSApIHtcblx0XHRcdFx0XHRcdG1hdGNoZWRDb3VudC0tO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIExlbmd0aGVuIHRoZSBhcnJheSBmb3IgZXZlcnkgZWxlbWVudCwgbWF0Y2hlZCBvciBub3Rcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBcHBseSBzZXQgZmlsdGVycyB0byB1bm1hdGNoZWQgZWxlbWVudHNcblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xuXHRcdFx0aWYgKCBieVNldCAmJiBpICE9PSBtYXRjaGVkQ291bnQgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gc2V0TWF0Y2hlcnNbaisrXSkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFtpXSA9IHBvcC5jYWxsKCByZXN1bHRzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xuXHRcdFx0XHRcdHNldE1hdGNoZWQgPSBjb25kZW5zZSggc2V0TWF0Y2hlZCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRkIG1hdGNoZXMgdG8gcmVzdWx0c1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZXRNYXRjaGVkICk7XG5cblx0XHRcdFx0Ly8gU2VlZGxlc3Mgc2V0IG1hdGNoZXMgc3VjY2VlZGluZyBtdWx0aXBsZSBzdWNjZXNzZnVsIG1hdGNoZXJzIHN0aXB1bGF0ZSBzb3J0aW5nXG5cdFx0XHRcdGlmICggb3V0ZXJtb3N0ICYmICFzZWVkICYmIHNldE1hdGNoZWQubGVuZ3RoID4gMCAmJlxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xuXG5cdFx0XHRcdFx0U2l6emxlLnVuaXF1ZVNvcnQoIHJlc3VsdHMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XG5cdFx0fTtcblxuXHRyZXR1cm4gYnlTZXQgP1xuXHRcdG1hcmtGdW5jdGlvbiggc3VwZXJNYXRjaGVyICkgOlxuXHRcdHN1cGVyTWF0Y2hlcjtcbn1cblxuY29tcGlsZSA9IFNpenpsZS5jb21waWxlID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBtYXRjaCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0dmFyIGksXG5cdFx0c2V0TWF0Y2hlcnMgPSBbXSxcblx0XHRlbGVtZW50TWF0Y2hlcnMgPSBbXSxcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCAhY2FjaGVkICkge1xuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxuXHRcdGlmICggIW1hdGNoICkge1xuXHRcdFx0bWF0Y2ggPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblx0XHR9XG5cdFx0aSA9IG1hdGNoLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFtpXSApO1xuXHRcdFx0aWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0c2V0TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FjaGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZSggc2VsZWN0b3IsIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApICk7XG5cblx0XHQvLyBTYXZlIHNlbGVjdG9yIGFuZCB0b2tlbml6YXRpb25cblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3Rvcjtcblx0fVxuXHRyZXR1cm4gY2FjaGVkO1xufTtcblxuLyoqXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb25zXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc2VsZWN0b3IgQSBzZWxlY3RvciBvciBhIHByZS1jb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcbiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGV4dFxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHNdXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxuICovXG5zZWxlY3QgPSBTaXp6bGUuc2VsZWN0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcblx0XHRjb21waWxlZCA9IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHNlbGVjdG9yLFxuXHRcdG1hdGNoID0gIXNlZWQgJiYgdG9rZW5pemUoIChzZWxlY3RvciA9IGNvbXBpbGVkLnNlbGVjdG9yIHx8IHNlbGVjdG9yKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG5vIHNlZWQgYW5kIG9ubHkgb25lIGdyb3VwXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xuXG5cdFx0Ly8gVGFrZSBhIHNob3J0Y3V0IGFuZCBzZXQgdGhlIGNvbnRleHQgaWYgdGhlIHJvb3Qgc2VsZWN0b3IgaXMgYW4gSURcblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAodG9rZW4gPSB0b2tlbnNbMF0pLnR5cGUgPT09IFwiSURcIiAmJlxuXHRcdFx0XHRzdXBwb3J0LmdldEJ5SWQgJiYgY29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbXCJJRFwiXSggdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKHJ1bmVzY2FwZSwgZnVuZXNjYXBlKSwgY29udGV4dCApIHx8IFtdIClbMF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRva2VuID0gdG9rZW5zW2ldO1xuXG5cdFx0XHQvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yXG5cdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbICh0eXBlID0gdG9rZW4udHlwZSkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIChmaW5kID0gRXhwci5maW5kWyB0eXBlIF0pICkge1xuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcblx0XHRcdFx0aWYgKCAoc2VlZCA9IGZpbmQoXG5cdFx0XHRcdFx0dG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLFxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0XHRcdFx0KSkgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcblx0XHRcdFx0XHR0b2tlbnMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHRcdFx0c2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTtcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNlZWQgKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ29tcGlsZSBhbmQgZXhlY3V0ZSBhIGZpbHRlcmluZyBmdW5jdGlvbiBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcblx0KCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKFxuXHRcdHNlZWQsXG5cdFx0Y29udGV4dCxcblx0XHQhZG9jdW1lbnRJc0hUTUwsXG5cdFx0cmVzdWx0cyxcblx0XHRyc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdCk7XG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gT25lLXRpbWUgYXNzaWdubWVudHNcblxuLy8gU29ydCBzdGFiaWxpdHlcbnN1cHBvcnQuc29ydFN0YWJsZSA9IGV4cGFuZG8uc3BsaXQoXCJcIikuc29ydCggc29ydE9yZGVyICkuam9pbihcIlwiKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lIDE0LTM1K1xuLy8gQWx3YXlzIGFzc3VtZSBkdXBsaWNhdGVzIGlmIHRoZXkgYXJlbid0IHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvblxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XG5cbi8vIEluaXRpYWxpemUgYWdhaW5zdCB0aGUgZGVmYXVsdCBkb2N1bWVudFxuc2V0RG9jdW1lbnQoKTtcblxuLy8gU3VwcG9ydDogV2Via2l0PDUzNy4zMiAtIFNhZmFyaSA2LjAuMy9DaHJvbWUgMjUgKGZpeGVkIGluIENocm9tZSAyNylcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdjEgKSB7XG5cdC8vIFNob3VsZCByZXR1cm4gMSwgYnV0IHJldHVybnMgNCAoZm9sbG93aW5nKVxuXHRyZXR1cm4gZGl2MS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSApICYgMTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBJRTw4XG4vLyBQcmV2ZW50IGF0dHJpYnV0ZS9wcm9wZXJ0eSBcImludGVycG9sYXRpb25cIlxuLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM2NDI5JTI4VlMuODUlMjkuYXNweFxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdGRpdi5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JyMnPjwvYT5cIjtcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZShcImhyZWZcIikgPT09IFwiI1wiIDtcbn0pICkge1xuXHRhZGRIYW5kbGUoIFwidHlwZXxocmVmfGhlaWdodHx3aWR0aFwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0eXBlXCIgPyAxIDogMiApO1xuXHRcdH1cblx0fSk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcbmlmICggIXN1cHBvcnQuYXR0cmlidXRlcyB8fCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdGRpdi5pbm5lckhUTUwgPSBcIjxpbnB1dC8+XCI7XG5cdGRpdi5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiApID09PSBcIlwiO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggXCJ2YWx1ZVwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kZWZhdWx0VmFsdWU7XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGdldEF0dHJpYnV0ZU5vZGUgdG8gZmV0Y2ggYm9vbGVhbnMgd2hlbiBnZXRBdHRyaWJ1dGUgbGllc1xuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdHJldHVybiBkaXYuZ2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIikgPT0gbnVsbDtcbn0pICkge1xuXHRhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHZhbDtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtWyBuYW1lIF0gPT09IHRydWUgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHRcdCh2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcblx0XHR9XG5cdH0pO1xufVxuXG5yZXR1cm4gU2l6emxlO1xuXG59KSggd2luZG93ICk7XG5cblxuXG5qUXVlcnkuZmluZCA9IFNpenpsZTtcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcbmpRdWVyeS5leHByW1wiOlwiXSA9IGpRdWVyeS5leHByLnBzZXVkb3M7XG5qUXVlcnkudW5pcXVlID0gU2l6emxlLnVuaXF1ZVNvcnQ7XG5qUXVlcnkudGV4dCA9IFNpenpsZS5nZXRUZXh0O1xualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xualF1ZXJ5LmNvbnRhaW5zID0gU2l6emxlLmNvbnRhaW5zO1xuXG5cblxudmFyIHJuZWVkc0NvbnRleHQgPSBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQ7XG5cbnZhciByc2luZ2xlVGFnID0gKC9ePChcXHcrKVxccypcXC8/Pig/OjxcXC9cXDE+fCkkLyk7XG5cblxuXG52YXIgcmlzU2ltcGxlID0gL14uW146I1xcW1xcLixdKiQvO1xuXG4vLyBJbXBsZW1lbnQgdGhlIGlkZW50aWNhbCBmdW5jdGlvbmFsaXR5IGZvciBmaWx0ZXIgYW5kIG5vdFxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHF1YWxpZmllciApICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0LyoganNoaW50IC1XMDE4ICovXG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSk7XG5cblx0fVxuXG5cdGlmICggcXVhbGlmaWVyLm5vZGVUeXBlICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICggZWxlbSA9PT0gcXVhbGlmaWVyICkgIT09IG5vdDtcblx0XHR9KTtcblxuXHR9XG5cblx0aWYgKCB0eXBlb2YgcXVhbGlmaWVyID09PSBcInN0cmluZ1wiICkge1xuXHRcdGlmICggcmlzU2ltcGxlLnRlc3QoIHF1YWxpZmllciApICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApO1xuXHRcdH1cblxuXHRcdHF1YWxpZmllciA9IGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMgKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiAoIGluZGV4T2YuY2FsbCggcXVhbGlmaWVyLCBlbGVtICkgPj0gMCApICE9PSBub3Q7XG5cdH0pO1xufVxuXG5qUXVlcnkuZmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7XG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcblxuXHRpZiAoIG5vdCApIHtcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xuXHR9XG5cblx0cmV0dXJuIGVsZW1zLmxlbmd0aCA9PT0gMSAmJiBlbGVtLm5vZGVUeXBlID09PSAxID9cblx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGVsZW0sIGV4cHIgKSA/IFsgZWxlbSBdIDogW10gOlxuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXMoIGV4cHIsIGpRdWVyeS5ncmVwKCBlbGVtcywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTtcblx0XHR9KSk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0ZmluZDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBpLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdHNlbGYgPSB0aGlzO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHNlbGZbIGkgXSwgdGhpcyApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KSApO1xuXHRcdH1cblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRqUXVlcnkuZmluZCggc2VsZWN0b3IsIHNlbGZbIGkgXSwgcmV0ICk7XG5cdFx0fVxuXG5cdFx0Ly8gTmVlZGVkIGJlY2F1c2UgJCggc2VsZWN0b3IsIGNvbnRleHQgKSBiZWNvbWVzICQoIGNvbnRleHQgKS5maW5kKCBzZWxlY3RvciApXG5cdFx0cmV0ID0gdGhpcy5wdXNoU3RhY2soIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlKCByZXQgKSA6IHJldCApO1xuXHRcdHJldC5zZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IgPyB0aGlzLnNlbGVjdG9yICsgXCIgXCIgKyBzZWxlY3RvciA6IHNlbGVjdG9yO1xuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cdGZpbHRlcjogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KHRoaXMsIHNlbGVjdG9yIHx8IFtdLCBmYWxzZSkgKTtcblx0fSxcblx0bm90OiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3codGhpcywgc2VsZWN0b3IgfHwgW10sIHRydWUpICk7XG5cdH0sXG5cdGlzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuICEhd2lubm93KFxuXHRcdFx0dGhpcyxcblxuXHRcdFx0Ly8gSWYgdGhpcyBpcyBhIHBvc2l0aW9uYWwvcmVsYXRpdmUgc2VsZWN0b3IsIGNoZWNrIG1lbWJlcnNoaXAgaW4gdGhlIHJldHVybmVkIHNldFxuXHRcdFx0Ly8gc28gJChcInA6Zmlyc3RcIikuaXMoXCJwOmxhc3RcIikgd29uJ3QgcmV0dXJuIHRydWUgZm9yIGEgZG9jIHdpdGggdHdvIFwicFwiLlxuXHRcdFx0dHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICYmIHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/XG5cdFx0XHRcdGpRdWVyeSggc2VsZWN0b3IgKSA6XG5cdFx0XHRcdHNlbGVjdG9yIHx8IFtdLFxuXHRcdFx0ZmFsc2Vcblx0XHQpLmxlbmd0aDtcblx0fVxufSk7XG5cblxuLy8gSW5pdGlhbGl6ZSBhIGpRdWVyeSBvYmplY3RcblxuXG4vLyBBIGNlbnRyYWwgcmVmZXJlbmNlIHRvIHRoZSByb290IGpRdWVyeShkb2N1bWVudClcbnZhciByb290alF1ZXJ5LFxuXG5cdC8vIEEgc2ltcGxlIHdheSB0byBjaGVjayBmb3IgSFRNTCBzdHJpbmdzXG5cdC8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoICgjOTUyMSlcblx0Ly8gU3RyaWN0IEhUTUwgcmVjb2duaXRpb24gKCMxMTI5MDogbXVzdCBzdGFydCB3aXRoIDwpXG5cdHJxdWlja0V4cHIgPSAvXig/OlxccyooPFtcXHdcXFddKz4pW14+XSp8IyhbXFx3LV0qKSkkLyxcblxuXHRpbml0ID0galF1ZXJ5LmZuLmluaXQgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0dmFyIG1hdGNoLCBlbGVtO1xuXG5cdFx0Ly8gSEFORExFOiAkKFwiXCIpLCAkKG51bGwpLCAkKHVuZGVmaW5lZCksICQoZmFsc2UpXG5cdFx0aWYgKCAhc2VsZWN0b3IgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgSFRNTCBzdHJpbmdzXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRpZiAoIHNlbGVjdG9yWzBdID09PSBcIjxcIiAmJiBzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJiBzZWxlY3Rvci5sZW5ndGggPj0gMyApIHtcblx0XHRcdFx0Ly8gQXNzdW1lIHRoYXQgc3RyaW5ncyB0aGF0IHN0YXJ0IGFuZCBlbmQgd2l0aCA8PiBhcmUgSFRNTCBhbmQgc2tpcCB0aGUgcmVnZXggY2hlY2tcblx0XHRcdFx0bWF0Y2ggPSBbIG51bGwsIHNlbGVjdG9yLCBudWxsIF07XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1hdGNoID0gcnF1aWNrRXhwci5leGVjKCBzZWxlY3RvciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYXRjaCBodG1sIG9yIG1ha2Ugc3VyZSBubyBjb250ZXh0IGlzIHNwZWNpZmllZCBmb3IgI2lkXG5cdFx0XHRpZiAoIG1hdGNoICYmIChtYXRjaFsxXSB8fCAhY29udGV4dCkgKSB7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwpIC0+ICQoYXJyYXkpXG5cdFx0XHRcdGlmICggbWF0Y2hbMV0gKSB7XG5cdFx0XHRcdFx0Y29udGV4dCA9IGNvbnRleHQgaW5zdGFuY2VvZiBqUXVlcnkgPyBjb250ZXh0WzBdIDogY29udGV4dDtcblxuXHRcdFx0XHRcdC8vIE9wdGlvbiB0byBydW4gc2NyaXB0cyBpcyB0cnVlIGZvciBiYWNrLWNvbXBhdFxuXHRcdFx0XHRcdC8vIEludGVudGlvbmFsbHkgbGV0IHRoZSBlcnJvciBiZSB0aHJvd24gaWYgcGFyc2VIVE1MIGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxuXHRcdFx0XHRcdFx0bWF0Y2hbMV0sXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxuXHRcdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHRcdCkgKTtcblxuXHRcdFx0XHRcdC8vIEhBTkRMRTogJChodG1sLCBwcm9wcylcblx0XHRcdFx0XHRpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbMV0gKSAmJiBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29udGV4dCApICkge1xuXHRcdFx0XHRcdFx0Zm9yICggbWF0Y2ggaW4gY29udGV4dCApIHtcblx0XHRcdFx0XHRcdFx0Ly8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB0aGlzWyBtYXRjaCBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBvdGhlcndpc2Ugc2V0IGFzIGF0dHJpYnV0ZXNcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmF0dHIoIG1hdGNoLCBjb250ZXh0WyBtYXRjaCBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoI2lkKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbWF0Y2hbMl0gKTtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEJsYWNrYmVycnkgNC42XG5cdFx0XHRcdFx0Ly8gZ0VCSUQgcmV0dXJucyBub2RlcyBubyBsb25nZXIgaW4gdGhlIGRvY3VtZW50ICgjNjk2Mylcblx0XHRcdFx0XHRpZiAoIGVsZW0gJiYgZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0Ly8gSW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3Rcblx0XHRcdFx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdFx0XHRcdHRoaXNbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHRoaXMuY29udGV4dCA9IGRvY3VtZW50O1xuXHRcdFx0XHRcdHRoaXMuc2VsZWN0b3IgPSBzZWxlY3Rvcjtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgJCguLi4pKVxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGNvbnRleHQgfHwgcm9vdGpRdWVyeSApLmZpbmQoIHNlbGVjdG9yICk7XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxuXHRcdFx0Ly8gKHdoaWNoIGlzIGp1c3QgZXF1aXZhbGVudCB0bzogJChjb250ZXh0KS5maW5kKGV4cHIpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcblx0XHR9IGVsc2UgaWYgKCBzZWxlY3Rvci5ub2RlVHlwZSApIHtcblx0XHRcdHRoaXMuY29udGV4dCA9IHRoaXNbMF0gPSBzZWxlY3Rvcjtcblx0XHRcdHRoaXMubGVuZ3RoID0gMTtcblx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0Ly8gSEFORExFOiAkKGZ1bmN0aW9uKVxuXHRcdC8vIFNob3J0Y3V0IGZvciBkb2N1bWVudCByZWFkeVxuXHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBzZWxlY3RvciApICkge1xuXHRcdFx0cmV0dXJuIHR5cGVvZiByb290alF1ZXJ5LnJlYWR5ICE9PSBcInVuZGVmaW5lZFwiID9cblx0XHRcdFx0cm9vdGpRdWVyeS5yZWFkeSggc2VsZWN0b3IgKSA6XG5cdFx0XHRcdC8vIEV4ZWN1dGUgaW1tZWRpYXRlbHkgaWYgcmVhZHkgaXMgbm90IHByZXNlbnRcblx0XHRcdFx0c2VsZWN0b3IoIGpRdWVyeSApO1xuXHRcdH1cblxuXHRcdGlmICggc2VsZWN0b3Iuc2VsZWN0b3IgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHRoaXMuc2VsZWN0b3IgPSBzZWxlY3Rvci5zZWxlY3Rvcjtcblx0XHRcdHRoaXMuY29udGV4dCA9IHNlbGVjdG9yLmNvbnRleHQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpRdWVyeS5tYWtlQXJyYXkoIHNlbGVjdG9yLCB0aGlzICk7XG5cdH07XG5cbi8vIEdpdmUgdGhlIGluaXQgZnVuY3Rpb24gdGhlIGpRdWVyeSBwcm90b3R5cGUgZm9yIGxhdGVyIGluc3RhbnRpYXRpb25cbmluaXQucHJvdG90eXBlID0galF1ZXJ5LmZuO1xuXG4vLyBJbml0aWFsaXplIGNlbnRyYWwgcmVmZXJlbmNlXG5yb290alF1ZXJ5ID0galF1ZXJ5KCBkb2N1bWVudCApO1xuXG5cbnZhciBycGFyZW50c3ByZXYgPSAvXig/OnBhcmVudHN8cHJldig/OlVudGlsfEFsbCkpLyxcblx0Ly8gTWV0aG9kcyBndWFyYW50ZWVkIHRvIHByb2R1Y2UgYSB1bmlxdWUgc2V0IHdoZW4gc3RhcnRpbmcgZnJvbSBhIHVuaXF1ZSBzZXRcblx0Z3VhcmFudGVlZFVuaXF1ZSA9IHtcblx0XHRjaGlsZHJlbjogdHJ1ZSxcblx0XHRjb250ZW50czogdHJ1ZSxcblx0XHRuZXh0OiB0cnVlLFxuXHRcdHByZXY6IHRydWVcblx0fTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdGRpcjogZnVuY3Rpb24oIGVsZW0sIGRpciwgdW50aWwgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBbXSxcblx0XHRcdHRydW5jYXRlID0gdW50aWwgIT09IHVuZGVmaW5lZDtcblxuXHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgJiYgZWxlbS5ub2RlVHlwZSAhPT0gOSApIHtcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0aWYgKCB0cnVuY2F0ZSAmJiBqUXVlcnkoIGVsZW0gKS5pcyggdW50aWwgKSApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0XHRtYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG1hdGNoZWQ7XG5cdH0sXG5cblx0c2libGluZzogZnVuY3Rpb24oIG4sIGVsZW0gKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBbXTtcblxuXHRcdGZvciAoIDsgbjsgbiA9IG4ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRpZiAoIG4ubm9kZVR5cGUgPT09IDEgJiYgbiAhPT0gZWxlbSApIHtcblx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBuICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZWQ7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xuXHRcdHZhciB0YXJnZXRzID0galF1ZXJ5KCB0YXJnZXQsIHRoaXMgKSxcblx0XHRcdGwgPSB0YXJnZXRzLmxlbmd0aDtcblxuXHRcdHJldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHRoaXMsIHRhcmdldHNbaV0gKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGNsb3Nlc3Q6IGZ1bmN0aW9uKCBzZWxlY3RvcnMsIGNvbnRleHQgKSB7XG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0bCA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0bWF0Y2hlZCA9IFtdLFxuXHRcdFx0cG9zID0gcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSB8fCB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvcnMsIGNvbnRleHQgfHwgdGhpcy5jb250ZXh0ICkgOlxuXHRcdFx0XHQwO1xuXG5cdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0Zm9yICggY3VyID0gdGhpc1tpXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xuXHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA8IDExICYmIChwb3MgP1xuXHRcdFx0XHRcdHBvcy5pbmRleChjdXIpID4gLTEgOlxuXG5cdFx0XHRcdFx0Ly8gRG9uJ3QgcGFzcyBub24tZWxlbWVudHMgdG8gU2l6emxlXG5cdFx0XHRcdFx0Y3VyLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoY3VyLCBzZWxlY3RvcnMpKSApIHtcblxuXHRcdFx0XHRcdG1hdGNoZWQucHVzaCggY3VyICk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQubGVuZ3RoID4gMSA/IGpRdWVyeS51bmlxdWUoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZShcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLmdldCgpLCBqUXVlcnkoIHNlbGVjdG9yLCBjb250ZXh0ICkgKVxuXHRcdFx0KVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkQmFjazogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLmFkZCggc2VsZWN0b3IgPT0gbnVsbCA/XG5cdFx0XHR0aGlzLnByZXZPYmplY3QgOiB0aGlzLnByZXZPYmplY3QuZmlsdGVyKHNlbGVjdG9yKVxuXHRcdCk7XG5cdH1cbn0pO1xuXG5mdW5jdGlvbiBzaWJsaW5nKCBjdXIsIGRpciApIHtcblx0d2hpbGUgKCAoY3VyID0gY3VyW2Rpcl0pICYmIGN1ci5ub2RlVHlwZSAhPT0gMSApIHt9XG5cdHJldHVybiBjdXI7XG59XG5cbmpRdWVyeS5lYWNoKHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiApO1xuXHR9LFxuXHRwYXJlbnRzVW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwYXJlbnROb2RlXCIsIHVudGlsICk7XG5cdH0sXG5cdG5leHQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dEFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuc2libGluZyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnNpYmxpbmcoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0uY29udGVudERvY3VtZW50IHx8IGpRdWVyeS5tZXJnZSggW10sIGVsZW0uY2hpbGROb2RlcyApO1xuXHR9XG59LCBmdW5jdGlvbiggbmFtZSwgZm4gKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHVudGlsLCBzZWxlY3RvciApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IGpRdWVyeS5tYXAoIHRoaXMsIGZuLCB1bnRpbCApO1xuXG5cdFx0aWYgKCBuYW1lLnNsaWNlKCAtNSApICE9PSBcIlVudGlsXCIgKSB7XG5cdFx0XHRzZWxlY3RvciA9IHVudGlsO1xuXHRcdH1cblxuXHRcdGlmICggc2VsZWN0b3IgJiYgdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0bWF0Y2hlZCA9IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBtYXRjaGVkICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlKCBtYXRjaGVkICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldmVyc2Ugb3JkZXIgZm9yIHBhcmVudHMqIGFuZCBwcmV2LWRlcml2YXRpdmVzXG5cdFx0XHRpZiAoIHJwYXJlbnRzcHJldi50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHRcdG1hdGNoZWQucmV2ZXJzZSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZCApO1xuXHR9O1xufSk7XG52YXIgcm5vdHdoaXRlID0gKC9cXFMrL2cpO1xuXG5cblxuLy8gU3RyaW5nIHRvIE9iamVjdCBvcHRpb25zIGZvcm1hdCBjYWNoZVxudmFyIG9wdGlvbnNDYWNoZSA9IHt9O1xuXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lcyBhbmQgc3RvcmUgaW4gY2FjaGVcbmZ1bmN0aW9uIGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSB7XG5cdHZhciBvYmplY3QgPSBvcHRpb25zQ2FjaGVbIG9wdGlvbnMgXSA9IHt9O1xuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSk7XG5cdHJldHVybiBvYmplY3Q7XG59XG5cbi8qXG4gKiBDcmVhdGUgYSBjYWxsYmFjayBsaXN0IHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcbiAqXG4gKlx0b3B0aW9uczogYW4gb3B0aW9uYWwgbGlzdCBvZiBzcGFjZS1zZXBhcmF0ZWQgb3B0aW9ucyB0aGF0IHdpbGwgY2hhbmdlIGhvd1xuICpcdFx0XHR0aGUgY2FsbGJhY2sgbGlzdCBiZWhhdmVzIG9yIGEgbW9yZSB0cmFkaXRpb25hbCBvcHRpb24gb2JqZWN0XG4gKlxuICogQnkgZGVmYXVsdCBhIGNhbGxiYWNrIGxpc3Qgd2lsbCBhY3QgbGlrZSBhbiBldmVudCBjYWxsYmFjayBsaXN0IGFuZCBjYW4gYmVcbiAqIFwiZmlyZWRcIiBtdWx0aXBsZSB0aW1lcy5cbiAqXG4gKiBQb3NzaWJsZSBvcHRpb25zOlxuICpcbiAqXHRvbmNlOlx0XHRcdHdpbGwgZW5zdXJlIHRoZSBjYWxsYmFjayBsaXN0IGNhbiBvbmx5IGJlIGZpcmVkIG9uY2UgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0bWVtb3J5Olx0XHRcdHdpbGwga2VlcCB0cmFjayBvZiBwcmV2aW91cyB2YWx1ZXMgYW5kIHdpbGwgY2FsbCBhbnkgY2FsbGJhY2sgYWRkZWRcbiAqXHRcdFx0XHRcdGFmdGVyIHRoZSBsaXN0IGhhcyBiZWVuIGZpcmVkIHJpZ2h0IGF3YXkgd2l0aCB0aGUgbGF0ZXN0IFwibWVtb3JpemVkXCJcbiAqXHRcdFx0XHRcdHZhbHVlcyAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHR1bmlxdWU6XHRcdFx0d2lsbCBlbnN1cmUgYSBjYWxsYmFjayBjYW4gb25seSBiZSBhZGRlZCBvbmNlIChubyBkdXBsaWNhdGUgaW4gdGhlIGxpc3QpXG4gKlxuICpcdHN0b3BPbkZhbHNlOlx0aW50ZXJydXB0IGNhbGxpbmdzIHdoZW4gYSBjYWxsYmFjayByZXR1cm5zIGZhbHNlXG4gKlxuICovXG5qUXVlcnkuQ2FsbGJhY2tzID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cblx0Ly8gQ29udmVydCBvcHRpb25zIGZyb20gU3RyaW5nLWZvcm1hdHRlZCB0byBPYmplY3QtZm9ybWF0dGVkIGlmIG5lZWRlZFxuXHQvLyAod2UgY2hlY2sgaW4gY2FjaGUgZmlyc3QpXG5cdG9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0KCBvcHRpb25zQ2FjaGVbIG9wdGlvbnMgXSB8fCBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gTGFzdCBmaXJlIHZhbHVlIChmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzKVxuXHRcdG1lbW9yeSxcblx0XHQvLyBGbGFnIHRvIGtub3cgaWYgbGlzdCB3YXMgYWxyZWFkeSBmaXJlZFxuXHRcdGZpcmVkLFxuXHRcdC8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IGlzIGN1cnJlbnRseSBmaXJpbmdcblx0XHRmaXJpbmcsXG5cdFx0Ly8gRmlyc3QgY2FsbGJhY2sgdG8gZmlyZSAodXNlZCBpbnRlcm5hbGx5IGJ5IGFkZCBhbmQgZmlyZVdpdGgpXG5cdFx0ZmlyaW5nU3RhcnQsXG5cdFx0Ly8gRW5kIG9mIHRoZSBsb29wIHdoZW4gZmlyaW5nXG5cdFx0ZmlyaW5nTGVuZ3RoLFxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IHJlbW92ZSBpZiBuZWVkZWQpXG5cdFx0ZmlyaW5nSW5kZXgsXG5cdFx0Ly8gQWN0dWFsIGNhbGxiYWNrIGxpc3Rcblx0XHRsaXN0ID0gW10sXG5cdFx0Ly8gU3RhY2sgb2YgZmlyZSBjYWxscyBmb3IgcmVwZWF0YWJsZSBsaXN0c1xuXHRcdHN0YWNrID0gIW9wdGlvbnMub25jZSAmJiBbXSxcblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0XHRcdG1lbW9yeSA9IG9wdGlvbnMubWVtb3J5ICYmIGRhdGE7XG5cdFx0XHRmaXJlZCA9IHRydWU7XG5cdFx0XHRmaXJpbmdJbmRleCA9IGZpcmluZ1N0YXJ0IHx8IDA7XG5cdFx0XHRmaXJpbmdTdGFydCA9IDA7XG5cdFx0XHRmaXJpbmdMZW5ndGggPSBsaXN0Lmxlbmd0aDtcblx0XHRcdGZpcmluZyA9IHRydWU7XG5cdFx0XHRmb3IgKCA7IGxpc3QgJiYgZmlyaW5nSW5kZXggPCBmaXJpbmdMZW5ndGg7IGZpcmluZ0luZGV4KysgKSB7XG5cdFx0XHRcdGlmICggbGlzdFsgZmlyaW5nSW5kZXggXS5hcHBseSggZGF0YVsgMCBdLCBkYXRhWyAxIF0gKSA9PT0gZmFsc2UgJiYgb3B0aW9ucy5zdG9wT25GYWxzZSApIHtcblx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTsgLy8gVG8gcHJldmVudCBmdXJ0aGVyIGNhbGxzIHVzaW5nIGFkZFxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0aWYgKCBzdGFjayApIHtcblx0XHRcdFx0XHRpZiAoIHN0YWNrLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGZpcmUoIHN0YWNrLnNoaWZ0KCkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1lbW9yeSApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2VsZi5kaXNhYmxlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXHRcdC8vIEFjdHVhbCBDYWxsYmFja3Mgb2JqZWN0XG5cdFx0c2VsZiA9IHtcblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHQvLyBGaXJzdCwgd2Ugc2F2ZSB0aGUgY3VycmVudCBsZW5ndGhcblx0XHRcdFx0XHR2YXIgc3RhcnQgPSBsaXN0Lmxlbmd0aDtcblx0XHRcdFx0XHQoZnVuY3Rpb24gYWRkKCBhcmdzICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3MsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciB0eXBlID0galF1ZXJ5LnR5cGUoIGFyZyApO1xuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gSW5zcGVjdCByZWN1cnNpdmVseVxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdH0pKCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHQvLyBEbyB3ZSBuZWVkIHRvIGFkZCB0aGUgY2FsbGJhY2tzIHRvIHRoZVxuXHRcdFx0XHRcdC8vIGN1cnJlbnQgZmlyaW5nIGJhdGNoP1xuXHRcdFx0XHRcdGlmICggZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyaW5nTGVuZ3RoID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0Ly8gV2l0aCBtZW1vcnksIGlmIHdlJ3JlIG5vdCBmaXJpbmcgdGhlblxuXHRcdFx0XHRcdC8vIHdlIHNob3VsZCBjYWxsIHJpZ2h0IGF3YXlcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdTdGFydCA9IHN0YXJ0O1xuXHRcdFx0XHRcdFx0ZmlyZSggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJndW1lbnRzLCBmdW5jdGlvbiggXywgYXJnICkge1xuXHRcdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdFx0d2hpbGUgKCAoIGluZGV4ID0galF1ZXJ5LmluQXJyYXkoIGFyZywgbGlzdCwgaW5kZXggKSApID4gLTEgKSB7XG5cdFx0XHRcdFx0XHRcdGxpc3Quc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgZmlyaW5nIGluZGV4ZXNcblx0XHRcdFx0XHRcdFx0aWYgKCBmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdMZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmaXJpbmdMZW5ndGgtLTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ2hlY2sgaWYgYSBnaXZlbiBjYWxsYmFjayBpcyBpbiB0aGUgbGlzdC5cblx0XHRcdC8vIElmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCByZXR1cm4gd2hldGhlciBvciBub3QgbGlzdCBoYXMgY2FsbGJhY2tzIGF0dGFjaGVkLlxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XG5cdFx0XHRcdHJldHVybiBmbiA/IGpRdWVyeS5pbkFycmF5KCBmbiwgbGlzdCApID4gLTEgOiAhISggbGlzdCAmJiBsaXN0Lmxlbmd0aCApO1xuXHRcdFx0fSxcblx0XHRcdC8vIFJlbW92ZSBhbGwgY2FsbGJhY2tzIGZyb20gdGhlIGxpc3Rcblx0XHRcdGVtcHR5OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bGlzdCA9IFtdO1xuXHRcdFx0XHRmaXJpbmdMZW5ndGggPSAwO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBIYXZlIHRoZSBsaXN0IGRvIG5vdGhpbmcgYW55bW9yZVxuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxpc3QgPSBzdGFjayA9IG1lbW9yeSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gSXMgaXQgZGlzYWJsZWQ/XG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cdFx0XHQvLyBMb2NrIHRoZSBsaXN0IGluIGl0cyBjdXJyZW50IHN0YXRlXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c3RhY2sgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdGlmICggIW1lbW9yeSApIHtcblx0XHRcdFx0XHRzZWxmLmRpc2FibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBJcyBpdCBsb2NrZWQ/XG5cdFx0XHRsb2NrZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gIXN0YWNrO1xuXHRcdFx0fSxcblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcblx0XHRcdGZpcmVXaXRoOiBmdW5jdGlvbiggY29udGV4dCwgYXJncyApIHtcblx0XHRcdFx0aWYgKCBsaXN0ICYmICggIWZpcmVkIHx8IHN0YWNrICkgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRpZiAoIGZpcmluZyApIHtcblx0XHRcdFx0XHRcdHN0YWNrLnB1c2goIGFyZ3MgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZmlyZSggYXJncyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBDYWxsIGFsbCB0aGUgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBUbyBrbm93IGlmIHRoZSBjYWxsYmFja3MgaGF2ZSBhbHJlYWR5IGJlZW4gY2FsbGVkIGF0IGxlYXN0IG9uY2Vcblx0XHRcdGZpcmVkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhZmlyZWQ7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRyZXR1cm4gc2VsZjtcbn07XG5cblxualF1ZXJ5LmV4dGVuZCh7XG5cblx0RGVmZXJyZWQ6IGZ1bmN0aW9uKCBmdW5jICkge1xuXHRcdHZhciB0dXBsZXMgPSBbXG5cdFx0XHRcdC8vIGFjdGlvbiwgYWRkIGxpc3RlbmVyLCBsaXN0ZW5lciBsaXN0LCBmaW5hbCBzdGF0ZVxuXHRcdFx0XHRbIFwicmVzb2x2ZVwiLCBcImRvbmVcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLCBcInJlc29sdmVkXCIgXSxcblx0XHRcdFx0WyBcInJlamVjdFwiLCBcImZhaWxcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLCBcInJlamVjdGVkXCIgXSxcblx0XHRcdFx0WyBcIm5vdGlmeVwiLCBcInByb2dyZXNzXCIsIGpRdWVyeS5DYWxsYmFja3MoXCJtZW1vcnlcIikgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0aGVuOiBmdW5jdGlvbiggLyogZm5Eb25lLCBmbkZhaWwsIGZuUHJvZ3Jlc3MgKi8gKSB7XG5cdFx0XHRcdFx0dmFyIGZucyA9IGFyZ3VtZW50cztcblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKGZ1bmN0aW9uKCBuZXdEZWZlciApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdFx0XHRcdFx0dmFyIGZuID0galF1ZXJ5LmlzRnVuY3Rpb24oIGZuc1sgaSBdICkgJiYgZm5zWyBpIF07XG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkWyBkb25lIHwgZmFpbCB8IHByb2dyZXNzIF0gZm9yIGZvcndhcmRpbmcgYWN0aW9ucyB0byBuZXdEZWZlclxuXHRcdFx0XHRcdFx0XHRkZWZlcnJlZFsgdHVwbGVbMV0gXShmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHR2YXIgcmV0dXJuZWQgPSBmbiAmJiBmbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCAmJiBqUXVlcnkuaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5kb25lKCBuZXdEZWZlci5yZXNvbHZlIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gcHJvbWlzZSA/IG5ld0RlZmVyLnByb21pc2UoKSA6IHRoaXMsIGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0Zm5zID0gbnVsbDtcblx0XHRcdFx0XHR9KS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdC8vIEdldCBhIHByb21pc2UgZm9yIHRoaXMgZGVmZXJyZWRcblx0XHRcdFx0Ly8gSWYgb2JqIGlzIHByb3ZpZGVkLCB0aGUgcHJvbWlzZSBhc3BlY3QgaXMgYWRkZWQgdG8gdGhlIG9iamVjdFxuXHRcdFx0XHRwcm9taXNlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdFx0XHRcdHJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlZmVycmVkID0ge307XG5cblx0XHQvLyBLZWVwIHBpcGUgZm9yIGJhY2stY29tcGF0XG5cdFx0cHJvbWlzZS5waXBlID0gcHJvbWlzZS50aGVuO1xuXG5cdFx0Ly8gQWRkIGxpc3Qtc3BlY2lmaWMgbWV0aG9kc1xuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcblx0XHRcdHZhciBsaXN0ID0gdHVwbGVbIDIgXSxcblx0XHRcdFx0c3RhdGVTdHJpbmcgPSB0dXBsZVsgMyBdO1xuXG5cdFx0XHQvLyBwcm9taXNlWyBkb25lIHwgZmFpbCB8IHByb2dyZXNzIF0gPSBsaXN0LmFkZFxuXHRcdFx0cHJvbWlzZVsgdHVwbGVbMV0gXSA9IGxpc3QuYWRkO1xuXG5cdFx0XHQvLyBIYW5kbGUgc3RhdGVcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XG5cdFx0XHRcdGxpc3QuYWRkKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdC8vIHN0YXRlID0gWyByZXNvbHZlZCB8IHJlamVjdGVkIF1cblx0XHRcdFx0XHRzdGF0ZSA9IHN0YXRlU3RyaW5nO1xuXG5cdFx0XHRcdC8vIFsgcmVqZWN0X2xpc3QgfCByZXNvbHZlX2xpc3QgXS5kaXNhYmxlOyBwcm9ncmVzc19saXN0LmxvY2tcblx0XHRcdFx0fSwgdHVwbGVzWyBpIF4gMSBdWyAyIF0uZGlzYWJsZSwgdHVwbGVzWyAyIF1bIDIgXS5sb2NrICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGRlZmVycmVkWyByZXNvbHZlIHwgcmVqZWN0IHwgbm90aWZ5IF1cblx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSArIFwiV2l0aFwiIF0oIHRoaXMgPT09IGRlZmVycmVkID8gcHJvbWlzZSA6IHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH07XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbMF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9KTtcblxuXHRcdC8vIE1ha2UgdGhlIGRlZmVycmVkIGEgcHJvbWlzZVxuXHRcdHByb21pc2UucHJvbWlzZSggZGVmZXJyZWQgKTtcblxuXHRcdC8vIENhbGwgZ2l2ZW4gZnVuYyBpZiBhbnlcblx0XHRpZiAoIGZ1bmMgKSB7XG5cdFx0XHRmdW5jLmNhbGwoIGRlZmVycmVkLCBkZWZlcnJlZCApO1xuXHRcdH1cblxuXHRcdC8vIEFsbCBkb25lIVxuXHRcdHJldHVybiBkZWZlcnJlZDtcblx0fSxcblxuXHQvLyBEZWZlcnJlZCBoZWxwZXJcblx0d2hlbjogZnVuY3Rpb24oIHN1Ym9yZGluYXRlIC8qICwgLi4uLCBzdWJvcmRpbmF0ZU4gKi8gKSB7XG5cdFx0dmFyIGkgPSAwLFxuXHRcdFx0cmVzb2x2ZVZhbHVlcyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLFxuXHRcdFx0bGVuZ3RoID0gcmVzb2x2ZVZhbHVlcy5sZW5ndGgsXG5cblx0XHRcdC8vIHRoZSBjb3VudCBvZiB1bmNvbXBsZXRlZCBzdWJvcmRpbmF0ZXNcblx0XHRcdHJlbWFpbmluZyA9IGxlbmd0aCAhPT0gMSB8fCAoIHN1Ym9yZGluYXRlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBzdWJvcmRpbmF0ZS5wcm9taXNlICkgKSA/IGxlbmd0aCA6IDAsXG5cblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWQuIElmIHJlc29sdmVWYWx1ZXMgY29uc2lzdCBvZiBvbmx5IGEgc2luZ2xlIERlZmVycmVkLCBqdXN0IHVzZSB0aGF0LlxuXHRcdFx0ZGVmZXJyZWQgPSByZW1haW5pbmcgPT09IDEgPyBzdWJvcmRpbmF0ZSA6IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBVcGRhdGUgZnVuY3Rpb24gZm9yIGJvdGggcmVzb2x2ZSBhbmQgcHJvZ3Jlc3MgdmFsdWVzXG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGksIGNvbnRleHRzLCB2YWx1ZXMgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0Y29udGV4dHNbIGkgXSA9IHRoaXM7XG5cdFx0XHRcdFx0dmFsdWVzWyBpIF0gPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApIDogdmFsdWU7XG5cdFx0XHRcdFx0aWYgKCB2YWx1ZXMgPT09IHByb2dyZXNzVmFsdWVzICkge1xuXHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH0sXG5cblx0XHRcdHByb2dyZXNzVmFsdWVzLCBwcm9ncmVzc0NvbnRleHRzLCByZXNvbHZlQ29udGV4dHM7XG5cblx0XHQvLyBBZGQgbGlzdGVuZXJzIHRvIERlZmVycmVkIHN1Ym9yZGluYXRlczsgdHJlYXQgb3RoZXJzIGFzIHJlc29sdmVkXG5cdFx0aWYgKCBsZW5ndGggPiAxICkge1xuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMgPSBuZXcgQXJyYXkoIGxlbmd0aCApO1xuXHRcdFx0cHJvZ3Jlc3NDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRyZXNvbHZlQ29udGV4dHMgPSBuZXcgQXJyYXkoIGxlbmd0aCApO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0ucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXS5wcm9taXNlKClcblx0XHRcdFx0XHRcdC5kb25lKCB1cGRhdGVGdW5jKCBpLCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKSApXG5cdFx0XHRcdFx0XHQuZmFpbCggZGVmZXJyZWQucmVqZWN0IClcblx0XHRcdFx0XHRcdC5wcm9ncmVzcyggdXBkYXRlRnVuYyggaSwgcHJvZ3Jlc3NDb250ZXh0cywgcHJvZ3Jlc3NWYWx1ZXMgKSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC0tcmVtYWluaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSWYgd2UncmUgbm90IHdhaXRpbmcgb24gYW55dGhpbmcsIHJlc29sdmUgdGhlIG1hc3RlclxuXHRcdGlmICggIXJlbWFpbmluZyApIHtcblx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuXHR9XG59KTtcblxuXG4vLyBUaGUgZGVmZXJyZWQgdXNlZCBvbiBET00gcmVhZHlcbnZhciByZWFkeUxpc3Q7XG5cbmpRdWVyeS5mbi5yZWFkeSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0Ly8gQWRkIHRoZSBjYWxsYmFja1xuXHRqUXVlcnkucmVhZHkucHJvbWlzZSgpLmRvbmUoIGZuICk7XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Ly8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy5cblx0aXNSZWFkeTogZmFsc2UsXG5cblx0Ly8gQSBjb3VudGVyIHRvIHRyYWNrIGhvdyBtYW55IGl0ZW1zIHRvIHdhaXQgZm9yIGJlZm9yZVxuXHQvLyB0aGUgcmVhZHkgZXZlbnQgZmlyZXMuIFNlZSAjNjc4MVxuXHRyZWFkeVdhaXQ6IDEsXG5cblx0Ly8gSG9sZCAob3IgcmVsZWFzZSkgdGhlIHJlYWR5IGV2ZW50XG5cdGhvbGRSZWFkeTogZnVuY3Rpb24oIGhvbGQgKSB7XG5cdFx0aWYgKCBob2xkICkge1xuXHRcdFx0alF1ZXJ5LnJlYWR5V2FpdCsrO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqUXVlcnkucmVhZHkoIHRydWUgKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gSGFuZGxlIHdoZW4gdGhlIERPTSBpcyByZWFkeVxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XG5cblx0XHQvLyBBYm9ydCBpZiB0aGVyZSBhcmUgcGVuZGluZyBob2xkcyBvciB3ZSdyZSBhbHJlYWR5IHJlYWR5XG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gUmVtZW1iZXIgdGhhdCB0aGUgRE9NIGlzIHJlYWR5XG5cdFx0alF1ZXJ5LmlzUmVhZHkgPSB0cnVlO1xuXG5cdFx0Ly8gSWYgYSBub3JtYWwgRE9NIFJlYWR5IGV2ZW50IGZpcmVkLCBkZWNyZW1lbnQsIGFuZCB3YWl0IGlmIG5lZWQgYmVcblx0XHRpZiAoIHdhaXQgIT09IHRydWUgJiYgLS1qUXVlcnkucmVhZHlXYWl0ID4gMCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXG5cdFx0cmVhZHlMaXN0LnJlc29sdmVXaXRoKCBkb2N1bWVudCwgWyBqUXVlcnkgXSApO1xuXG5cdFx0Ly8gVHJpZ2dlciBhbnkgYm91bmQgcmVhZHkgZXZlbnRzXG5cdFx0aWYgKCBqUXVlcnkuZm4udHJpZ2dlckhhbmRsZXIgKSB7XG5cdFx0XHRqUXVlcnkoIGRvY3VtZW50ICkudHJpZ2dlckhhbmRsZXIoIFwicmVhZHlcIiApO1xuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLm9mZiggXCJyZWFkeVwiICk7XG5cdFx0fVxuXHR9XG59KTtcblxuLyoqXG4gKiBUaGUgcmVhZHkgZXZlbnQgaGFuZGxlciBhbmQgc2VsZiBjbGVhbnVwIG1ldGhvZFxuICovXG5mdW5jdGlvbiBjb21wbGV0ZWQoKSB7XG5cdGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXHRqUXVlcnkucmVhZHkoKTtcbn1cblxualF1ZXJ5LnJlYWR5LnByb21pc2UgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoICFyZWFkeUxpc3QgKSB7XG5cblx0XHRyZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxuXHRcdC8vIENhdGNoIGNhc2VzIHdoZXJlICQoZG9jdW1lbnQpLnJlYWR5KCkgaXMgY2FsbGVkIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuXHRcdC8vIFdlIG9uY2UgdHJpZWQgdG8gdXNlIHJlYWR5U3RhdGUgXCJpbnRlcmFjdGl2ZVwiIGhlcmUsIGJ1dCBpdCBjYXVzZWQgaXNzdWVzIGxpa2UgdGhlIG9uZVxuXHRcdC8vIGRpc2NvdmVyZWQgYnkgQ2hyaXNTIGhlcmU6IGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMjgyI2NvbW1lbnQ6MTVcblx0XHRpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiApIHtcblx0XHRcdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxuXHRcdFx0c2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBVc2UgdGhlIGhhbmR5IGV2ZW50IGNhbGxiYWNrXG5cdFx0XHRkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXG5cdFx0XHQvLyBBIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQsIHRoYXQgd2lsbCBhbHdheXMgd29ya1xuXHRcdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZWFkeUxpc3QucHJvbWlzZSggb2JqICk7XG59O1xuXG4vLyBLaWNrIG9mZiB0aGUgRE9NIHJlYWR5IGNoZWNrIGV2ZW4gaWYgdGhlIHVzZXIgZG9lcyBub3RcbmpRdWVyeS5yZWFkeS5wcm9taXNlKCk7XG5cblxuXG5cbi8vIE11bHRpZnVuY3Rpb25hbCBtZXRob2QgdG8gZ2V0IGFuZCBzZXQgdmFsdWVzIG9mIGEgY29sbGVjdGlvblxuLy8gVGhlIHZhbHVlL3MgY2FuIG9wdGlvbmFsbHkgYmUgZXhlY3V0ZWQgaWYgaXQncyBhIGZ1bmN0aW9uXG52YXIgYWNjZXNzID0galF1ZXJ5LmFjY2VzcyA9IGZ1bmN0aW9uKCBlbGVtcywgZm4sIGtleSwgdmFsdWUsIGNoYWluYWJsZSwgZW1wdHlHZXQsIHJhdyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcblx0XHRidWxrID0ga2V5ID09IG51bGw7XG5cblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xuXHRpZiAoIGpRdWVyeS50eXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0alF1ZXJ5LmFjY2VzcyggZWxlbXMsIGZuLCBpLCBrZXlbaV0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTtcblx0XHR9XG5cblx0Ly8gU2V0cyBvbmUgdmFsdWVcblx0fSBlbHNlIGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXG5cdFx0aWYgKCAhalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyYXcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICggYnVsayApIHtcblx0XHRcdC8vIEJ1bGsgb3BlcmF0aW9ucyBydW4gYWdhaW5zdCB0aGUgZW50aXJlIHNldFxuXHRcdFx0aWYgKCByYXcgKSB7XG5cdFx0XHRcdGZuLmNhbGwoIGVsZW1zLCB2YWx1ZSApO1xuXHRcdFx0XHRmbiA9IG51bGw7XG5cblx0XHRcdC8vIC4uLmV4Y2VwdCB3aGVuIGV4ZWN1dGluZyBmdW5jdGlvbiB2YWx1ZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGJ1bGsgPSBmbjtcblx0XHRcdFx0Zm4gPSBmdW5jdGlvbiggZWxlbSwga2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKCBlbGVtc1tpXSwga2V5LCByYXcgPyB2YWx1ZSA6IHZhbHVlLmNhbGwoIGVsZW1zW2ldLCBpLCBmbiggZWxlbXNbaV0sIGtleSApICkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gY2hhaW5hYmxlID9cblx0XHRlbGVtcyA6XG5cblx0XHQvLyBHZXRzXG5cdFx0YnVsayA/XG5cdFx0XHRmbi5jYWxsKCBlbGVtcyApIDpcblx0XHRcdGxlbiA/IGZuKCBlbGVtc1swXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG5cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IGNhbiBoYXZlIGRhdGFcbiAqL1xualF1ZXJ5LmFjY2VwdERhdGEgPSBmdW5jdGlvbiggb3duZXIgKSB7XG5cdC8vIEFjY2VwdHMgb25seTpcblx0Ly8gIC0gTm9kZVxuXHQvLyAgICAtIE5vZGUuRUxFTUVOVF9OT0RFXG5cdC8vICAgIC0gTm9kZS5ET0NVTUVOVF9OT0RFXG5cdC8vICAtIE9iamVjdFxuXHQvLyAgICAtIEFueVxuXHQvKiBqc2hpbnQgLVcwMTggKi9cblx0cmV0dXJuIG93bmVyLm5vZGVUeXBlID09PSAxIHx8IG93bmVyLm5vZGVUeXBlID09PSA5IHx8ICEoICtvd25lci5ub2RlVHlwZSApO1xufTtcblxuXG5mdW5jdGlvbiBEYXRhKCkge1xuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQsXG5cdC8vIE9sZCBXZWJLaXQgZG9lcyBub3QgaGF2ZSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMvZnJlZXplIG1ldGhvZCxcblx0Ly8gcmV0dXJuIG5ldyBlbXB0eSBvYmplY3QgaW5zdGVhZCB3aXRoIG5vIFtbc2V0XV0gYWNjZXNzb3Jcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLmNhY2hlID0ge30sIDAsIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHt9O1xuXHRcdH1cblx0fSk7XG5cblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xufVxuXG5EYXRhLnVpZCA9IDE7XG5EYXRhLmFjY2VwdHMgPSBqUXVlcnkuYWNjZXB0RGF0YTtcblxuRGF0YS5wcm90b3R5cGUgPSB7XG5cdGtleTogZnVuY3Rpb24oIG93bmVyICkge1xuXHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxuXHRcdC8vIGJ1dCB3ZSBzaG91bGQgbm90LCBzZWUgIzgzMzUuXG5cdFx0Ly8gQWx3YXlzIHJldHVybiB0aGUga2V5IGZvciBhIGZyb3plbiBvYmplY3QuXG5cdFx0aWYgKCAhRGF0YS5hY2NlcHRzKCBvd25lciApICkge1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSB7fSxcblx0XHRcdC8vIENoZWNrIGlmIHRoZSBvd25lciBvYmplY3QgYWxyZWFkeSBoYXMgYSBjYWNoZSBrZXlcblx0XHRcdHVubG9jayA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblxuXHRcdC8vIElmIG5vdCwgY3JlYXRlIG9uZVxuXHRcdGlmICggIXVubG9jayApIHtcblx0XHRcdHVubG9jayA9IERhdGEudWlkKys7XG5cblx0XHRcdC8vIFNlY3VyZSBpdCBpbiBhIG5vbi1lbnVtZXJhYmxlLCBub24td3JpdGFibGUgcHJvcGVydHlcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRlc2NyaXB0b3JbIHRoaXMuZXhwYW5kbyBdID0geyB2YWx1ZTogdW5sb2NrIH07XG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBvd25lciwgZGVzY3JpcHRvciApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDRcblx0XHRcdC8vIEZhbGxiYWNrIHRvIGEgbGVzcyBzZWN1cmUgZGVmaW5pdGlvblxuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdGRlc2NyaXB0b3JbIHRoaXMuZXhwYW5kbyBdID0gdW5sb2NrO1xuXHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCBvd25lciwgZGVzY3JpcHRvciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSB0aGUgY2FjaGUgb2JqZWN0XG5cdFx0aWYgKCAhdGhpcy5jYWNoZVsgdW5sb2NrIF0gKSB7XG5cdFx0XHR0aGlzLmNhY2hlWyB1bmxvY2sgXSA9IHt9O1xuXHRcdH1cblxuXHRcdHJldHVybiB1bmxvY2s7XG5cdH0sXG5cdHNldDogZnVuY3Rpb24oIG93bmVyLCBkYXRhLCB2YWx1ZSApIHtcblx0XHR2YXIgcHJvcCxcblx0XHRcdC8vIFRoZXJlIG1heSBiZSBhbiB1bmxvY2sgYXNzaWduZWQgdG8gdGhpcyBub2RlLFxuXHRcdFx0Ly8gaWYgdGhlcmUgaXMgbm8gZW50cnkgZm9yIHRoaXMgXCJvd25lclwiLCBjcmVhdGUgb25lIGlubGluZVxuXHRcdFx0Ly8gYW5kIHNldCB0aGUgdW5sb2NrIGFzIHRob3VnaCBhbiBvd25lciBlbnRyeSBoYWQgYWx3YXlzIGV4aXN0ZWRcblx0XHRcdHVubG9jayA9IHRoaXMua2V5KCBvd25lciApLFxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlWyB1bmxvY2sgXTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwga2V5LCB2YWx1ZSBdIGFyZ3Ncblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0Y2FjaGVbIGRhdGEgXSA9IHZhbHVlO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCB7IHByb3BlcnRpZXMgfSBdIGFyZ3Ncblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gRnJlc2ggYXNzaWdubWVudHMgYnkgb2JqZWN0IGFyZSBzaGFsbG93IGNvcGllZFxuXHRcdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKSApIHtcblx0XHRcdFx0alF1ZXJ5LmV4dGVuZCggdGhpcy5jYWNoZVsgdW5sb2NrIF0sIGRhdGEgKTtcblx0XHRcdC8vIE90aGVyd2lzZSwgY29weSB0aGUgcHJvcGVydGllcyBvbmUtYnktb25lIHRvIHRoZSBjYWNoZSBvYmplY3Rcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIHByb3AgaW4gZGF0YSApIHtcblx0XHRcdFx0XHRjYWNoZVsgcHJvcCBdID0gZGF0YVsgcHJvcCBdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBjYWNoZTtcblx0fSxcblx0Z2V0OiBmdW5jdGlvbiggb3duZXIsIGtleSApIHtcblx0XHQvLyBFaXRoZXIgYSB2YWxpZCBjYWNoZSBpcyBmb3VuZCwgb3Igd2lsbCBiZSBjcmVhdGVkLlxuXHRcdC8vIE5ldyBjYWNoZXMgd2lsbCBiZSBjcmVhdGVkIGFuZCB0aGUgdW5sb2NrIHJldHVybmVkLFxuXHRcdC8vIGFsbG93aW5nIGRpcmVjdCBhY2Nlc3MgdG8gdGhlIG5ld2x5IGNyZWF0ZWRcblx0XHQvLyBlbXB0eSBkYXRhIG9iamVjdC4gQSB2YWxpZCBvd25lciBvYmplY3QgbXVzdCBiZSBwcm92aWRlZC5cblx0XHR2YXIgY2FjaGUgPSB0aGlzLmNhY2hlWyB0aGlzLmtleSggb3duZXIgKSBdO1xuXG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdGNhY2hlIDogY2FjaGVbIGtleSBdO1xuXHR9LFxuXHRhY2Nlc3M6IGZ1bmN0aW9uKCBvd25lciwga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgc3RvcmVkO1xuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gTm8ga2V5IHdhcyBzcGVjaWZpZWRcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcblx0XHQvL1xuXHRcdC8vIFRha2UgdGhlIFwicmVhZFwiIHBhdGggYW5kIGFsbG93IHRoZSBnZXQgbWV0aG9kIHRvIGRldGVybWluZVxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gVGhlIGVudGlyZSBjYWNoZSBvYmplY3Rcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XG5cdFx0Ly9cblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdCgoa2V5ICYmIHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIpICYmIHZhbHVlID09PSB1bmRlZmluZWQpICkge1xuXG5cdFx0XHRzdG9yZWQgPSB0aGlzLmdldCggb3duZXIsIGtleSApO1xuXG5cdFx0XHRyZXR1cm4gc3RvcmVkICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRzdG9yZWQgOiB0aGlzLmdldCggb3duZXIsIGpRdWVyeS5jYW1lbENhc2Uoa2V5KSApO1xuXHRcdH1cblxuXHRcdC8vIFsqXVdoZW4gdGhlIGtleSBpcyBub3QgYSBzdHJpbmcsIG9yIGJvdGggYSBrZXkgYW5kIHZhbHVlXG5cdFx0Ly8gYXJlIHNwZWNpZmllZCwgc2V0IG9yIGV4dGVuZCAoZXhpc3Rpbmcgb2JqZWN0cykgd2l0aCBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIEFuIG9iamVjdCBvZiBwcm9wZXJ0aWVzXG5cdFx0Ly8gICAyLiBBIGtleSBhbmQgdmFsdWVcblx0XHQvL1xuXHRcdHRoaXMuc2V0KCBvd25lciwga2V5LCB2YWx1ZSApO1xuXG5cdFx0Ly8gU2luY2UgdGhlIFwic2V0XCIgcGF0aCBjYW4gaGF2ZSB0d28gcG9zc2libGUgZW50cnkgcG9pbnRzXG5cdFx0Ly8gcmV0dXJuIHRoZSBleHBlY3RlZCBkYXRhIGJhc2VkIG9uIHdoaWNoIHBhdGggd2FzIHRha2VuWypdXG5cdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IGtleTtcblx0fSxcblx0cmVtb3ZlOiBmdW5jdGlvbiggb3duZXIsIGtleSApIHtcblx0XHR2YXIgaSwgbmFtZSwgY2FtZWwsXG5cdFx0XHR1bmxvY2sgPSB0aGlzLmtleSggb3duZXIgKSxcblx0XHRcdGNhY2hlID0gdGhpcy5jYWNoZVsgdW5sb2NrIF07XG5cblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dGhpcy5jYWNoZVsgdW5sb2NrIF0gPSB7fTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBTdXBwb3J0IGFycmF5IG9yIHNwYWNlIHNlcGFyYXRlZCBzdHJpbmcgb2Yga2V5c1xuXHRcdFx0aWYgKCBqUXVlcnkuaXNBcnJheSgga2V5ICkgKSB7XG5cdFx0XHRcdC8vIElmIFwibmFtZVwiIGlzIGFuIGFycmF5IG9mIGtleXMuLi5cblx0XHRcdFx0Ly8gV2hlbiBkYXRhIGlzIGluaXRpYWxseSBjcmVhdGVkLCB2aWEgKFwia2V5XCIsIFwidmFsXCIpIHNpZ25hdHVyZSxcblx0XHRcdFx0Ly8ga2V5cyB3aWxsIGJlIGNvbnZlcnRlZCB0byBjYW1lbENhc2UuXG5cdFx0XHRcdC8vIFNpbmNlIHRoZXJlIGlzIG5vIHdheSB0byB0ZWxsIF9ob3dfIGEga2V5IHdhcyBhZGRlZCwgcmVtb3ZlXG5cdFx0XHRcdC8vIGJvdGggcGxhaW4ga2V5IGFuZCBjYW1lbENhc2Uga2V5LiAjMTI3ODZcblx0XHRcdFx0Ly8gVGhpcyB3aWxsIG9ubHkgcGVuYWxpemUgdGhlIGFycmF5IGFyZ3VtZW50IHBhdGguXG5cdFx0XHRcdG5hbWUgPSBrZXkuY29uY2F0KCBrZXkubWFwKCBqUXVlcnkuY2FtZWxDYXNlICkgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNhbWVsID0galF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICk7XG5cdFx0XHRcdC8vIFRyeSB0aGUgc3RyaW5nIGFzIGEga2V5IGJlZm9yZSBhbnkgbWFuaXB1bGF0aW9uXG5cdFx0XHRcdGlmICgga2V5IGluIGNhY2hlICkge1xuXHRcdFx0XHRcdG5hbWUgPSBbIGtleSwgY2FtZWwgXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBJZiBhIGtleSB3aXRoIHRoZSBzcGFjZXMgZXhpc3RzLCB1c2UgaXQuXG5cdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBjcmVhdGUgYW4gYXJyYXkgYnkgbWF0Y2hpbmcgbm9uLXdoaXRlc3BhY2Vcblx0XHRcdFx0XHRuYW1lID0gY2FtZWw7XG5cdFx0XHRcdFx0bmFtZSA9IG5hbWUgaW4gY2FjaGUgP1xuXHRcdFx0XHRcdFx0WyBuYW1lIF0gOiAoIG5hbWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aSA9IG5hbWUubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGRlbGV0ZSBjYWNoZVsgbmFtZVsgaSBdIF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRoYXNEYXRhOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0cmV0dXJuICFqUXVlcnkuaXNFbXB0eU9iamVjdChcblx0XHRcdHRoaXMuY2FjaGVbIG93bmVyWyB0aGlzLmV4cGFuZG8gXSBdIHx8IHt9XG5cdFx0KTtcblx0fSxcblx0ZGlzY2FyZDogZnVuY3Rpb24oIG93bmVyICkge1xuXHRcdGlmICggb3duZXJbIHRoaXMuZXhwYW5kbyBdICkge1xuXHRcdFx0ZGVsZXRlIHRoaXMuY2FjaGVbIG93bmVyWyB0aGlzLmV4cGFuZG8gXSBdO1xuXHRcdH1cblx0fVxufTtcbnZhciBkYXRhX3ByaXYgPSBuZXcgRGF0YSgpO1xuXG52YXIgZGF0YV91c2VyID0gbmV3IERhdGEoKTtcblxuXG5cbi8vXHRJbXBsZW1lbnRhdGlvbiBTdW1tYXJ5XG4vL1xuLy9cdDEuIEVuZm9yY2UgQVBJIHN1cmZhY2UgYW5kIHNlbWFudGljIGNvbXBhdGliaWxpdHkgd2l0aCAxLjkueCBicmFuY2hcbi8vXHQyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2Vcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cbi8vXHQzLiBVc2UgdGhlIHNhbWUgc2luZ2xlIG1lY2hhbmlzbSB0byBzdXBwb3J0IFwicHJpdmF0ZVwiIGFuZCBcInVzZXJcIiBkYXRhLlxuLy9cdDQuIF9OZXZlcl8gZXhwb3NlIFwicHJpdmF0ZVwiIGRhdGEgdG8gdXNlciBjb2RlIChUT0RPOiBEcm9wIF9kYXRhLCBfcmVtb3ZlRGF0YSlcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcbi8vXHQ2LiBQcm92aWRlIGEgY2xlYXIgcGF0aCBmb3IgaW1wbGVtZW50YXRpb24gdXBncmFkZSB0byBXZWFrTWFwIGluIDIwMTRcblxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcblx0cm11bHRpRGFzaCA9IC8oW0EtWl0pL2c7XG5cbmZ1bmN0aW9uIGRhdGFBdHRyKCBlbGVtLCBrZXksIGRhdGEgKSB7XG5cdHZhciBuYW1lO1xuXG5cdC8vIElmIG5vdGhpbmcgd2FzIGZvdW5kIGludGVybmFsbHksIHRyeSB0byBmZXRjaCBhbnlcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXG5cdGlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0bmFtZSA9IFwiZGF0YS1cIiArIGtleS5yZXBsYWNlKCBybXVsdGlEYXNoLCBcIi0kMVwiICkudG9Mb3dlckNhc2UoKTtcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcblxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRkYXRhID0gZGF0YSA9PT0gXCJ0cnVlXCIgPyB0cnVlIDpcblx0XHRcdFx0XHRkYXRhID09PSBcImZhbHNlXCIgPyBmYWxzZSA6XG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJudWxsXCIgPyBudWxsIDpcblx0XHRcdFx0XHQvLyBPbmx5IGNvbnZlcnQgdG8gYSBudW1iZXIgaWYgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIHN0cmluZ1xuXHRcdFx0XHRcdCtkYXRhICsgXCJcIiA9PT0gZGF0YSA/ICtkYXRhIDpcblx0XHRcdFx0XHRyYnJhY2UudGVzdCggZGF0YSApID8galF1ZXJ5LnBhcnNlSlNPTiggZGF0YSApIDpcblx0XHRcdFx0XHRkYXRhO1xuXHRcdFx0fSBjYXRjaCggZSApIHt9XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB3ZSBzZXQgdGhlIGRhdGEgc28gaXQgaXNuJ3QgY2hhbmdlZCBsYXRlclxuXHRcdFx0ZGF0YV91c2VyLnNldCggZWxlbSwga2V5LCBkYXRhICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBkYXRhO1xufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblx0aGFzRGF0YTogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRhdGFfdXNlci5oYXNEYXRhKCBlbGVtICkgfHwgZGF0YV9wcml2Lmhhc0RhdGEoIGVsZW0gKTtcblx0fSxcblxuXHRkYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YV91c2VyLmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFfdXNlci5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fSxcblxuXHQvLyBUT0RPOiBOb3cgdGhhdCBhbGwgY2FsbHMgdG8gX2RhdGEgYW5kIF9yZW1vdmVEYXRhIGhhdmUgYmVlbiByZXBsYWNlZFxuXHQvLyB3aXRoIGRpcmVjdCBjYWxscyB0byBkYXRhX3ByaXYgbWV0aG9kcywgdGhlc2UgY2FuIGJlIGRlcHJlY2F0ZWQuXG5cdF9kYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YV9wcml2LmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xuXHR9LFxuXG5cdF9yZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhX3ByaXYucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0ZGF0YTogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7XG5cdFx0dmFyIGksIG5hbWUsIGRhdGEsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0YXR0cnMgPSBlbGVtICYmIGVsZW0uYXR0cmlidXRlcztcblxuXHRcdC8vIEdldHMgYWxsIHZhbHVlc1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xuXHRcdFx0XHRkYXRhID0gZGF0YV91c2VyLmdldCggZWxlbSApO1xuXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAhZGF0YV9wcml2LmdldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiApICkge1xuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTErXG5cdFx0XHRcdFx0XHQvLyBUaGUgYXR0cnMgZWxlbWVudHMgY2FuIGJlIG51bGwgKCMxNDg5NClcblx0XHRcdFx0XHRcdGlmICggYXR0cnNbIGkgXSApIHtcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcblx0XHRcdFx0XHRcdFx0aWYgKCBuYW1lLmluZGV4T2YoIFwiZGF0YS1cIiApID09PSAwICkge1xuXHRcdFx0XHRcdFx0XHRcdG5hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lLnNsaWNlKDUpICk7XG5cdFx0XHRcdFx0XHRcdFx0ZGF0YUF0dHIoIGVsZW0sIG5hbWUsIGRhdGFbIG5hbWUgXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRhdGFfcHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRhdGFfdXNlci5zZXQoIHRoaXMsIGtleSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGRhdGEsXG5cdFx0XHRcdGNhbWVsS2V5ID0galF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICk7XG5cblx0XHRcdC8vIFRoZSBjYWxsaW5nIGpRdWVyeSBvYmplY3QgKGVsZW1lbnQgbWF0Y2hlcykgaXMgbm90IGVtcHR5XG5cdFx0XHQvLyAoYW5kIHRoZXJlZm9yZSBoYXMgYW4gZWxlbWVudCBhcHBlYXJzIGF0IHRoaXNbIDAgXSkgYW5kIHRoZVxuXHRcdFx0Ly8gYHZhbHVlYCBwYXJhbWV0ZXIgd2FzIG5vdCB1bmRlZmluZWQuIEFuIGVtcHR5IGpRdWVyeSBvYmplY3Rcblx0XHRcdC8vIHdpbGwgcmVzdWx0IGluIGB1bmRlZmluZWRgIGZvciBlbGVtID0gdGhpc1sgMCBdIHdoaWNoIHdpbGxcblx0XHRcdC8vIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhbiBhdHRlbXB0IHRvIHJlYWQgYSBkYXRhIGNhY2hlIGlzIG1hZGUuXG5cdFx0XHRpZiAoIGVsZW0gJiYgdmFsdWUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgYXMtaXNcblx0XHRcdFx0ZGF0YSA9IGRhdGFfdXNlci5nZXQoIGVsZW0sIGtleSApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcblx0XHRcdFx0Ly8gd2l0aCB0aGUga2V5IGNhbWVsaXplZFxuXHRcdFx0XHRkYXRhID0gZGF0YV91c2VyLmdldCggZWxlbSwgY2FtZWxLZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIFwiZGlzY292ZXJcIiB0aGUgZGF0YSBpblxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXG5cdFx0XHRcdGRhdGEgPSBkYXRhQXR0ciggZWxlbSwgY2FtZWxLZXksIHVuZGVmaW5lZCApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFdlIHRyaWVkIHJlYWxseSBoYXJkLCBidXQgdGhlIGRhdGEgZG9lc24ndCBleGlzdC5cblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIGRhdGEuLi5cblx0XHRcdHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gRmlyc3QsIGF0dGVtcHQgdG8gc3RvcmUgYSBjb3B5IG9yIHJlZmVyZW5jZSBvZiBhbnlcblx0XHRcdFx0Ly8gZGF0YSB0aGF0IG1pZ2h0J3ZlIGJlZW4gc3RvcmUgd2l0aCBhIGNhbWVsQ2FzZWQga2V5LlxuXHRcdFx0XHR2YXIgZGF0YSA9IGRhdGFfdXNlci5nZXQoIHRoaXMsIGNhbWVsS2V5ICk7XG5cblx0XHRcdFx0Ly8gRm9yIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGUgaW50ZXJvcCwgd2UgaGF2ZSB0b1xuXHRcdFx0XHQvLyBzdG9yZSBwcm9wZXJ0eSBuYW1lcyB3aXRoIGRhc2hlcyBpbiBhIGNhbWVsQ2FzZSBmb3JtLlxuXHRcdFx0XHQvLyBUaGlzIG1pZ2h0IG5vdCBhcHBseSB0byBhbGwgcHJvcGVydGllcy4uLipcblx0XHRcdFx0ZGF0YV91c2VyLnNldCggdGhpcywgY2FtZWxLZXksIHZhbHVlICk7XG5cblx0XHRcdFx0Ly8gKi4uLiBJbiB0aGUgY2FzZSBvZiBwcm9wZXJ0aWVzIHRoYXQgbWlnaHQgX2FjdHVhbGx5X1xuXHRcdFx0XHQvLyBoYXZlIGRhc2hlcywgd2UgbmVlZCB0byBhbHNvIHN0b3JlIGEgY29weSBvZiB0aGF0XG5cdFx0XHRcdC8vIHVuY2hhbmdlZCBwcm9wZXJ0eS5cblx0XHRcdFx0aWYgKCBrZXkuaW5kZXhPZihcIi1cIikgIT09IC0xICYmIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRkYXRhX3VzZXIuc2V0KCB0aGlzLCBrZXksIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGRhdGFfdXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xuXHRcdH0pO1xuXHR9XG59KTtcblxuXG5qUXVlcnkuZXh0ZW5kKHtcblx0cXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBxdWV1ZTtcblxuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHR5cGUgPSAoIHR5cGUgfHwgXCJmeFwiICkgKyBcInF1ZXVlXCI7XG5cdFx0XHRxdWV1ZSA9IGRhdGFfcHJpdi5nZXQoIGVsZW0sIHR5cGUgKTtcblxuXHRcdFx0Ly8gU3BlZWQgdXAgZGVxdWV1ZSBieSBnZXR0aW5nIG91dCBxdWlja2x5IGlmIHRoaXMgaXMganVzdCBhIGxvb2t1cFxuXHRcdFx0aWYgKCBkYXRhICkge1xuXHRcdFx0XHRpZiAoICFxdWV1ZSB8fCBqUXVlcnkuaXNBcnJheSggZGF0YSApICkge1xuXHRcdFx0XHRcdHF1ZXVlID0gZGF0YV9wcml2LmFjY2VzcyggZWxlbSwgdHlwZSwgalF1ZXJ5Lm1ha2VBcnJheShkYXRhKSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHF1ZXVlLnB1c2goIGRhdGEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHF1ZXVlIHx8IFtdO1xuXHRcdH1cblx0fSxcblxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggZWxlbSwgdHlwZSApIHtcblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIGVsZW0sIHR5cGUgKSxcblx0XHRcdHN0YXJ0TGVuZ3RoID0gcXVldWUubGVuZ3RoLFxuXHRcdFx0Zm4gPSBxdWV1ZS5zaGlmdCgpLFxuXHRcdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIHR5cGUgKSxcblx0XHRcdG5leHQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIGVsZW0sIHR5cGUgKTtcblx0XHRcdH07XG5cblx0XHQvLyBJZiB0aGUgZnggcXVldWUgaXMgZGVxdWV1ZWQsIGFsd2F5cyByZW1vdmUgdGhlIHByb2dyZXNzIHNlbnRpbmVsXG5cdFx0aWYgKCBmbiA9PT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCk7XG5cdFx0XHRzdGFydExlbmd0aC0tO1xuXHRcdH1cblxuXHRcdGlmICggZm4gKSB7XG5cblx0XHRcdC8vIEFkZCBhIHByb2dyZXNzIHNlbnRpbmVsIHRvIHByZXZlbnQgdGhlIGZ4IHF1ZXVlIGZyb20gYmVpbmdcblx0XHRcdC8vIGF1dG9tYXRpY2FsbHkgZGVxdWV1ZWRcblx0XHRcdGlmICggdHlwZSA9PT0gXCJmeFwiICkge1xuXHRcdFx0XHRxdWV1ZS51bnNoaWZ0KCBcImlucHJvZ3Jlc3NcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDbGVhciB1cCB0aGUgbGFzdCBxdWV1ZSBzdG9wIGZ1bmN0aW9uXG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdGZuLmNhbGwoIGVsZW0sIG5leHQsIGhvb2tzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAhc3RhcnRMZW5ndGggJiYgaG9va3MgKSB7XG5cdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIE5vdCBwdWJsaWMgLSBnZW5lcmF0ZSBhIHF1ZXVlSG9va3Mgb2JqZWN0LCBvciByZXR1cm4gdGhlIGN1cnJlbnQgb25lXG5cdF9xdWV1ZUhvb2tzOiBmdW5jdGlvbiggZWxlbSwgdHlwZSApIHtcblx0XHR2YXIga2V5ID0gdHlwZSArIFwicXVldWVIb29rc1wiO1xuXHRcdHJldHVybiBkYXRhX3ByaXYuZ2V0KCBlbGVtLCBrZXkgKSB8fCBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcblx0XHRcdGVtcHR5OiBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIikuYWRkKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhX3ByaXYucmVtb3ZlKCBlbGVtLCBbIHR5cGUgKyBcInF1ZXVlXCIsIGtleSBdICk7XG5cdFx0XHR9KVxuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgc2V0dGVyID0gMjtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRkYXRhID0gdHlwZTtcblx0XHRcdHR5cGUgPSBcImZ4XCI7XG5cdFx0XHRzZXR0ZXItLTtcblx0XHR9XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnF1ZXVlKCB0aGlzWzBdLCB0eXBlICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRhdGEgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHR0aGlzIDpcblx0XHRcdHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBkYXRhICk7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7XG5cblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbMF0gIT09IFwiaW5wcm9ncmVzc1wiICkge1xuXHRcdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHR9LFxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHR9KTtcblx0fSxcblx0Y2xlYXJRdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xuXHR9LFxuXHQvLyBHZXQgYSBwcm9taXNlIHJlc29sdmVkIHdoZW4gcXVldWVzIG9mIGEgY2VydGFpbiB0eXBlXG5cdC8vIGFyZSBlbXB0aWVkIChmeCBpcyB0aGUgdHlwZSBieSBkZWZhdWx0KVxuXHRwcm9taXNlOiBmdW5jdGlvbiggdHlwZSwgb2JqICkge1xuXHRcdHZhciB0bXAsXG5cdFx0XHRjb3VudCA9IDEsXG5cdFx0XHRkZWZlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXHRcdFx0ZWxlbWVudHMgPSB0aGlzLFxuXHRcdFx0aSA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0cmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICEoIC0tY291bnQgKSApIHtcblx0XHRcdFx0XHRkZWZlci5yZXNvbHZlV2l0aCggZWxlbWVudHMsIFsgZWxlbWVudHMgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG9iaiA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRtcCA9IGRhdGFfcHJpdi5nZXQoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0pO1xudmFyIHBudW0gPSAoL1srLV0/KD86XFxkKlxcLnwpXFxkKyg/OltlRV1bKy1dP1xcZCt8KS8pLnNvdXJjZTtcblxudmFyIGNzc0V4cGFuZCA9IFsgXCJUb3BcIiwgXCJSaWdodFwiLCBcIkJvdHRvbVwiLCBcIkxlZnRcIiBdO1xuXG52YXIgaXNIaWRkZW4gPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7XG5cdFx0Ly8gaXNIaWRkZW4gbWlnaHQgYmUgY2FsbGVkIGZyb20galF1ZXJ5I2ZpbHRlciBmdW5jdGlvbjtcblx0XHQvLyBpbiB0aGF0IGNhc2UsIGVsZW1lbnQgd2lsbCBiZSBzZWNvbmQgYXJndW1lbnRcblx0XHRlbGVtID0gZWwgfHwgZWxlbTtcblx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCIgfHwgIWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cdH07XG5cbnZhciByY2hlY2thYmxlVHlwZSA9ICgvXig/OmNoZWNrYm94fHJhZGlvKSQvaSk7XG5cblxuXG4oZnVuY3Rpb24oKSB7XG5cdHZhciBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxcblx0XHRkaXYgPSBmcmFnbWVudC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICksXG5cdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblxuXHQvLyBTdXBwb3J0OiBTYWZhcmk8PTUuMVxuXHQvLyBDaGVjayBzdGF0ZSBsb3N0IGlmIHRoZSBuYW1lIGlzIHNldCAoIzExMjE3KVxuXHQvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcInJhZGlvXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcImNoZWNrZWRcIiwgXCJjaGVja2VkXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcblxuXHRkaXYuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cblx0Ly8gU3VwcG9ydDogU2FmYXJpPD01LjEsIEFuZHJvaWQ8NC4yXG5cdC8vIE9sZGVyIFdlYktpdCBkb2Vzbid0IGNsb25lIGNoZWNrZWQgc3RhdGUgY29ycmVjdGx5IGluIGZyYWdtZW50c1xuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUU8PTExK1xuXHQvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZFxuXHRkaXYuaW5uZXJIVE1MID0gXCI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+XCI7XG5cdHN1cHBvcnQubm9DbG9uZUNoZWNrZWQgPSAhIWRpdi5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlO1xufSkoKTtcbnZhciBzdHJ1bmRlZmluZWQgPSB0eXBlb2YgdW5kZWZpbmVkO1xuXG5cblxuc3VwcG9ydC5mb2N1c2luQnViYmxlcyA9IFwib25mb2N1c2luXCIgaW4gd2luZG93O1xuXG5cbnZhclxuXHRya2V5RXZlbnQgPSAvXmtleS8sXG5cdHJtb3VzZUV2ZW50ID0gL14oPzptb3VzZXxwb2ludGVyfGNvbnRleHRtZW51KXxjbGljay8sXG5cdHJmb2N1c01vcnBoID0gL14oPzpmb2N1c2luZm9jdXN8Zm9jdXNvdXRibHVyKSQvLFxuXHRydHlwZW5hbWVzcGFjZSA9IC9eKFteLl0qKSg/OlxcLiguKyl8KSQvO1xuXG5mdW5jdGlvbiByZXR1cm5UcnVlKCkge1xuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gcmV0dXJuRmFsc2UoKSB7XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gc2FmZUFjdGl2ZUVsZW1lbnQoKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cdH0gY2F0Y2ggKCBlcnIgKSB7IH1cbn1cblxuLypcbiAqIEhlbHBlciBmdW5jdGlvbnMgZm9yIG1hbmFnaW5nIGV2ZW50cyAtLSBub3QgcGFydCBvZiB0aGUgcHVibGljIGludGVyZmFjZS5cbiAqIFByb3BzIHRvIERlYW4gRWR3YXJkcycgYWRkRXZlbnQgbGlicmFyeSBmb3IgbWFueSBvZiB0aGUgaWRlYXMuXG4gKi9cbmpRdWVyeS5ldmVudCA9IHtcblxuXHRnbG9iYWw6IHt9LFxuXG5cdGFkZDogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBkYXRhLCBzZWxlY3RvciApIHtcblxuXHRcdHZhciBoYW5kbGVPYmpJbiwgZXZlbnRIYW5kbGUsIHRtcCxcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBkYXRhX3ByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHQvLyBEb24ndCBhdHRhY2ggZXZlbnRzIHRvIG5vRGF0YSBvciB0ZXh0L2NvbW1lbnQgbm9kZXMgKGJ1dCBhbGxvdyBwbGFpbiBvYmplY3RzKVxuXHRcdGlmICggIWVsZW1EYXRhICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlclxuXHRcdGlmICggaGFuZGxlci5oYW5kbGVyICkge1xuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xuXHRcdFx0aGFuZGxlciA9IGhhbmRsZU9iakluLmhhbmRsZXI7XG5cdFx0XHRzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBoYW5kbGVyIGhhcyBhIHVuaXF1ZSBJRCwgdXNlZCB0byBmaW5kL3JlbW92ZSBpdCBsYXRlclxuXHRcdGlmICggIWhhbmRsZXIuZ3VpZCApIHtcblx0XHRcdGhhbmRsZXIuZ3VpZCA9IGpRdWVyeS5ndWlkKys7XG5cdFx0fVxuXG5cdFx0Ly8gSW5pdCB0aGUgZWxlbWVudCdzIGV2ZW50IHN0cnVjdHVyZSBhbmQgbWFpbiBoYW5kbGVyLCBpZiB0aGlzIGlzIHRoZSBmaXJzdFxuXHRcdGlmICggIShldmVudHMgPSBlbGVtRGF0YS5ldmVudHMpICkge1xuXHRcdFx0ZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzID0ge307XG5cdFx0fVxuXHRcdGlmICggIShldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSkgKSB7XG5cdFx0XHRldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSA9IGZ1bmN0aW9uKCBlICkge1xuXHRcdFx0XHQvLyBEaXNjYXJkIHRoZSBzZWNvbmQgZXZlbnQgb2YgYSBqUXVlcnkuZXZlbnQudHJpZ2dlcigpIGFuZFxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgalF1ZXJ5ICE9PSBzdHJ1bmRlZmluZWQgJiYgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCAhPT0gZS50eXBlID9cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuZGlzcGF0Y2guYXBwbHkoIGVsZW0sIGFyZ3VtZW50cyApIDogdW5kZWZpbmVkO1xuXHRcdFx0fTtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGFyYXRlZCBieSBhIHNwYWNlXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoIHQtLSApIHtcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzW3RdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbMV07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbMl0gfHwgXCJcIiApLnNwbGl0KCBcIi5cIiApLnNvcnQoKTtcblxuXHRcdFx0Ly8gVGhlcmUgKm11c3QqIGJlIGEgdHlwZSwgbm8gYXR0YWNoaW5nIG5hbWVzcGFjZS1vbmx5IGhhbmRsZXJzXG5cdFx0XHRpZiAoICF0eXBlICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlXG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XG5cblx0XHRcdC8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVyc1xuXHRcdFx0aGFuZGxlT2JqID0galF1ZXJ5LmV4dGVuZCh7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdG9yaWdUeXBlOiBvcmlnVHlwZSxcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0aGFuZGxlcjogaGFuZGxlcixcblx0XHRcdFx0Z3VpZDogaGFuZGxlci5ndWlkLFxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXG5cdFx0XHRcdG5lZWRzQ29udGV4dDogc2VsZWN0b3IgJiYgalF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICksXG5cdFx0XHRcdG5hbWVzcGFjZTogbmFtZXNwYWNlcy5qb2luKFwiLlwiKVxuXHRcdFx0fSwgaGFuZGxlT2JqSW4gKTtcblxuXHRcdFx0Ly8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZSBpZiB3ZSdyZSB0aGUgZmlyc3Rcblx0XHRcdGlmICggIShoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdKSApIHtcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xuXHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50ID0gMDtcblxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2Vcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC5zZXR1cCB8fCBzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBldmVudEhhbmRsZSwgZmFsc2UgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBzcGVjaWFsLmFkZCApIHtcblx0XHRcdFx0c3BlY2lhbC5hZGQuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cblx0XHRcdFx0aWYgKCAhaGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCApIHtcblx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlci5ndWlkID0gaGFuZGxlci5ndWlkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdCwgZGVsZWdhdGVzIGluIGZyb250XG5cdFx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGhhbmRsZXJzLmRlbGVnYXRlQ291bnQrKywgMCwgaGFuZGxlT2JqICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRoYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gS2VlcCB0cmFjayBvZiB3aGljaCBldmVudHMgaGF2ZSBldmVyIGJlZW4gdXNlZCwgZm9yIGV2ZW50IG9wdGltaXphdGlvblxuXHRcdFx0alF1ZXJ5LmV2ZW50Lmdsb2JhbFsgdHlwZSBdID0gdHJ1ZTtcblx0XHR9XG5cblx0fSxcblxuXHQvLyBEZXRhY2ggYW4gZXZlbnQgb3Igc2V0IG9mIGV2ZW50cyBmcm9tIGFuIGVsZW1lbnRcblx0cmVtb3ZlOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIHNlbGVjdG9yLCBtYXBwZWRUeXBlcyApIHtcblxuXHRcdHZhciBqLCBvcmlnQ291bnQsIHRtcCxcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBkYXRhX3ByaXYuaGFzRGF0YSggZWxlbSApICYmIGRhdGFfcHJpdi5nZXQoIGVsZW0gKTtcblxuXHRcdGlmICggIWVsZW1EYXRhIHx8ICEoZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBPbmNlIGZvciBlYWNoIHR5cGUubmFtZXNwYWNlIGluIHR5cGVzOyB0eXBlIG1heSBiZSBvbWl0dGVkXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoIHQtLSApIHtcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzW3RdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbMV07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbMl0gfHwgXCJcIiApLnNwbGl0KCBcIi5cIiApLnNvcnQoKTtcblxuXHRcdFx0Ly8gVW5iaW5kIGFsbCBldmVudHMgKG9uIHRoaXMgbmFtZXNwYWNlLCBpZiBwcm92aWRlZCkgZm9yIHRoZSBlbGVtZW50XG5cdFx0XHRpZiAoICF0eXBlICkge1xuXHRcdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICsgdHlwZXNbIHQgXSwgaGFuZGxlciwgc2VsZWN0b3IsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XG5cdFx0XHRoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdIHx8IFtdO1xuXHRcdFx0dG1wID0gdG1wWzJdICYmIG5ldyBSZWdFeHAoIFwiKF58XFxcXC4pXCIgKyBuYW1lc3BhY2VzLmpvaW4oXCJcXFxcLig/Oi4qXFxcXC58KVwiKSArIFwiKFxcXFwufCQpXCIgKTtcblxuXHRcdFx0Ly8gUmVtb3ZlIG1hdGNoaW5nIGV2ZW50c1xuXHRcdFx0b3JpZ0NvdW50ID0gaiA9IGhhbmRsZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaiBdO1xuXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcblx0XHRcdFx0XHQoICFoYW5kbGVyIHx8IGhhbmRsZXIuZ3VpZCA9PT0gaGFuZGxlT2JqLmd1aWQgKSAmJlxuXHRcdFx0XHRcdCggIXRtcCB8fCB0bXAudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkgJiZcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBcIioqXCIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7XG5cdFx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBqLCAxICk7XG5cblx0XHRcdFx0XHRpZiAoIGhhbmRsZU9iai5zZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQtLTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBzcGVjaWFsLnJlbW92ZSApIHtcblx0XHRcdFx0XHRcdHNwZWNpYWwucmVtb3ZlLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZW1vdmUgZ2VuZXJpYyBldmVudCBoYW5kbGVyIGlmIHdlIHJlbW92ZWQgc29tZXRoaW5nIGFuZCBubyBtb3JlIGhhbmRsZXJzIGV4aXN0XG5cdFx0XHQvLyAoYXZvaWRzIHBvdGVudGlhbCBmb3IgZW5kbGVzcyByZWN1cnNpb24gZHVyaW5nIHJlbW92YWwgb2Ygc3BlY2lhbCBldmVudCBoYW5kbGVycylcblx0XHRcdGlmICggb3JpZ0NvdW50ICYmICFoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRcdGlmICggIXNwZWNpYWwudGVhcmRvd24gfHwgc3BlY2lhbC50ZWFyZG93bi5jYWxsKCBlbGVtLCBuYW1lc3BhY2VzLCBlbGVtRGF0YS5oYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBlbGVtRGF0YS5oYW5kbGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGRlbGV0ZSBldmVudHNbIHR5cGUgXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZW1vdmUgdGhlIGV4cGFuZG8gaWYgaXQncyBubyBsb25nZXIgdXNlZFxuXHRcdGlmICggalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGV2ZW50cyApICkge1xuXHRcdFx0ZGVsZXRlIGVsZW1EYXRhLmhhbmRsZTtcblx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIFwiZXZlbnRzXCIgKTtcblx0XHR9XG5cdH0sXG5cblx0dHJpZ2dlcjogZnVuY3Rpb24oIGV2ZW50LCBkYXRhLCBlbGVtLCBvbmx5SGFuZGxlcnMgKSB7XG5cblx0XHR2YXIgaSwgY3VyLCB0bXAsIGJ1YmJsZVR5cGUsIG9udHlwZSwgaGFuZGxlLCBzcGVjaWFsLFxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXG5cdFx0XHR0eXBlID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcInR5cGVcIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LFxuXHRcdFx0bmFtZXNwYWNlcyA9IGhhc093bi5jYWxsKCBldmVudCwgXCJuYW1lc3BhY2VcIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KFwiLlwiKSA6IFtdO1xuXG5cdFx0Y3VyID0gdG1wID0gZWxlbSA9IGVsZW0gfHwgZG9jdW1lbnQ7XG5cblx0XHQvLyBEb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGZvY3VzL2JsdXIgbW9ycGhzIHRvIGZvY3VzaW4vb3V0OyBlbnN1cmUgd2UncmUgbm90IGZpcmluZyB0aGVtIHJpZ2h0IG5vd1xuXHRcdGlmICggcmZvY3VzTW9ycGgudGVzdCggdHlwZSArIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGUuaW5kZXhPZihcIi5cIikgPj0gMCApIHtcblx0XHRcdC8vIE5hbWVzcGFjZWQgdHJpZ2dlcjsgY3JlYXRlIGEgcmVnZXhwIHRvIG1hdGNoIGV2ZW50IHR5cGUgaW4gaGFuZGxlKClcblx0XHRcdG5hbWVzcGFjZXMgPSB0eXBlLnNwbGl0KFwiLlwiKTtcblx0XHRcdHR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7XG5cdFx0XHRuYW1lc3BhY2VzLnNvcnQoKTtcblx0XHR9XG5cdFx0b250eXBlID0gdHlwZS5pbmRleE9mKFwiOlwiKSA8IDAgJiYgXCJvblwiICsgdHlwZTtcblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xuXHRcdGV2ZW50ID0gZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gP1xuXHRcdFx0ZXZlbnQgOlxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XG5cblx0XHQvLyBUcmlnZ2VyIGJpdG1hc2s6ICYgMSBmb3IgbmF0aXZlIGhhbmRsZXJzOyAmIDIgZm9yIGpRdWVyeSAoYWx3YXlzIHRydWUpXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XG5cdFx0ZXZlbnQubmFtZXNwYWNlID0gbmFtZXNwYWNlcy5qb2luKFwiLlwiKTtcblx0XHRldmVudC5uYW1lc3BhY2VfcmUgPSBldmVudC5uYW1lc3BhY2UgP1xuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbihcIlxcXFwuKD86LipcXFxcLnwpXCIpICsgXCIoXFxcXC58JClcIiApIDpcblx0XHRcdG51bGw7XG5cblx0XHQvLyBDbGVhbiB1cCB0aGUgZXZlbnQgaW4gY2FzZSBpdCBpcyBiZWluZyByZXVzZWRcblx0XHRldmVudC5yZXN1bHQgPSB1bmRlZmluZWQ7XG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZWxlbTtcblx0XHR9XG5cblx0XHQvLyBDbG9uZSBhbnkgaW5jb21pbmcgZGF0YSBhbmQgcHJlcGVuZCB0aGUgZXZlbnQsIGNyZWF0aW5nIHRoZSBoYW5kbGVyIGFyZyBsaXN0XG5cdFx0ZGF0YSA9IGRhdGEgPT0gbnVsbCA/XG5cdFx0XHRbIGV2ZW50IF0gOlxuXHRcdFx0alF1ZXJ5Lm1ha2VBcnJheSggZGF0YSwgWyBldmVudCBdICk7XG5cblx0XHQvLyBBbGxvdyBzcGVjaWFsIGV2ZW50cyB0byBkcmF3IG91dHNpZGUgdGhlIGxpbmVzXG5cdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmIHNwZWNpYWwudHJpZ2dlciAmJiBzcGVjaWFsLnRyaWdnZXIuYXBwbHkoIGVsZW0sIGRhdGEgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZXJtaW5lIGV2ZW50IHByb3BhZ2F0aW9uIHBhdGggaW4gYWR2YW5jZSwgcGVyIFczQyBldmVudHMgc3BlYyAoIzk5NTEpXG5cdFx0Ly8gQnViYmxlIHVwIHRvIGRvY3VtZW50LCB0aGVuIHRvIHdpbmRvdzsgd2F0Y2ggZm9yIGEgZ2xvYmFsIG93bmVyRG9jdW1lbnQgdmFyICgjOTcyNClcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIXNwZWNpYWwubm9CdWJibGUgJiYgIWpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXG5cdFx0XHRidWJibGVUeXBlID0gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgfHwgdHlwZTtcblx0XHRcdGlmICggIXJmb2N1c01vcnBoLnRlc3QoIGJ1YmJsZVR5cGUgKyB0eXBlICkgKSB7XG5cdFx0XHRcdGN1ciA9IGN1ci5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXHRcdFx0Zm9yICggOyBjdXI7IGN1ciA9IGN1ci5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRldmVudFBhdGgucHVzaCggY3VyICk7XG5cdFx0XHRcdHRtcCA9IGN1cjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT25seSBhZGQgd2luZG93IGlmIHdlIGdvdCB0byBkb2N1bWVudCAoZS5nLiwgbm90IHBsYWluIG9iaiBvciBkZXRhY2hlZCBET00pXG5cdFx0XHRpZiAoIHRtcCA9PT0gKGVsZW0ub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudCkgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCB0bXAuZGVmYXVsdFZpZXcgfHwgdG1wLnBhcmVudFdpbmRvdyB8fCB3aW5kb3cgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXJlIGhhbmRsZXJzIG9uIHRoZSBldmVudCBwYXRoXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoY3VyID0gZXZlbnRQYXRoW2krK10pICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRldmVudC50eXBlID0gaSA+IDEgP1xuXHRcdFx0XHRidWJibGVUeXBlIDpcblx0XHRcdFx0c3BlY2lhbC5iaW5kVHlwZSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBqUXVlcnkgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gKCBkYXRhX3ByaXYuZ2V0KCBjdXIsIFwiZXZlbnRzXCIgKSB8fCB7fSApWyBldmVudC50eXBlIF0gJiYgZGF0YV9wcml2LmdldCggY3VyLCBcImhhbmRsZVwiICk7XG5cdFx0XHRpZiAoIGhhbmRsZSApIHtcblx0XHRcdFx0aGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTmF0aXZlIGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9IG9udHlwZSAmJiBjdXJbIG9udHlwZSBdO1xuXHRcdFx0aWYgKCBoYW5kbGUgJiYgaGFuZGxlLmFwcGx5ICYmIGpRdWVyeS5hY2NlcHREYXRhKCBjdXIgKSApIHtcblx0XHRcdFx0ZXZlbnQucmVzdWx0ID0gaGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZXZlbnQudHlwZSA9IHR5cGU7XG5cblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblxuXHRcdFx0aWYgKCAoIXNwZWNpYWwuX2RlZmF1bHQgfHwgc3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlKSAmJlxuXHRcdFx0XHRqUXVlcnkuYWNjZXB0RGF0YSggZWxlbSApICkge1xuXG5cdFx0XHRcdC8vIENhbGwgYSBuYXRpdmUgRE9NIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHdpdGggdGhlIHNhbWUgbmFtZSBuYW1lIGFzIHRoZSBldmVudC5cblx0XHRcdFx0Ly8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBqUXVlcnkuaXNGdW5jdGlvbiggZWxlbVsgdHlwZSBdICkgJiYgIWpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXG5cdFx0XHRcdFx0Ly8gRG9uJ3QgcmUtdHJpZ2dlciBhbiBvbkZPTyBldmVudCB3aGVuIHdlIGNhbGwgaXRzIEZPTygpIG1ldGhvZFxuXHRcdFx0XHRcdHRtcCA9IGVsZW1bIG9udHlwZSBdO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gUHJldmVudCByZS10cmlnZ2VyaW5nIG9mIHRoZSBzYW1lIGV2ZW50LCBzaW5jZSB3ZSBhbHJlYWR5IGJ1YmJsZWQgaXQgYWJvdmVcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdHlwZTtcblx0XHRcdFx0XHRlbGVtWyB0eXBlIF0oKTtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdGRpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHQvLyBNYWtlIGEgd3JpdGFibGUgalF1ZXJ5LkV2ZW50IGZyb20gdGhlIG5hdGl2ZSBldmVudCBvYmplY3Rcblx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICk7XG5cblx0XHR2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcblx0XHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcblx0XHRcdGhhbmRsZXJzID0gKCBkYXRhX3ByaXYuZ2V0KCB0aGlzLCBcImV2ZW50c1wiICkgfHwge30gKVsgZXZlbnQudHlwZSBdIHx8IFtdLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyBldmVudC50eXBlIF0gfHwge307XG5cblx0XHQvLyBVc2UgdGhlIGZpeC1lZCBqUXVlcnkuRXZlbnQgcmF0aGVyIHRoYW4gdGhlIChyZWFkLW9ubHkpIG5hdGl2ZSBldmVudFxuXHRcdGFyZ3NbMF0gPSBldmVudDtcblx0XHRldmVudC5kZWxlZ2F0ZVRhcmdldCA9IHRoaXM7XG5cblx0XHQvLyBDYWxsIHRoZSBwcmVEaXNwYXRjaCBob29rIGZvciB0aGUgbWFwcGVkIHR5cGUsIGFuZCBsZXQgaXQgYmFpbCBpZiBkZXNpcmVkXG5cdFx0aWYgKCBzcGVjaWFsLnByZURpc3BhdGNoICYmIHNwZWNpYWwucHJlRGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZXJtaW5lIGhhbmRsZXJzXG5cdFx0aGFuZGxlclF1ZXVlID0galF1ZXJ5LmV2ZW50LmhhbmRsZXJzLmNhbGwoIHRoaXMsIGV2ZW50LCBoYW5kbGVycyApO1xuXG5cdFx0Ly8gUnVuIGRlbGVnYXRlcyBmaXJzdDsgdGhleSBtYXkgd2FudCB0byBzdG9wIHByb3BhZ2F0aW9uIGJlbmVhdGggdXNcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChtYXRjaGVkID0gaGFuZGxlclF1ZXVlWyBpKysgXSkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRldmVudC5jdXJyZW50VGFyZ2V0ID0gbWF0Y2hlZC5lbGVtO1xuXG5cdFx0XHRqID0gMDtcblx0XHRcdHdoaWxlICggKGhhbmRsZU9iaiA9IG1hdGNoZWQuaGFuZGxlcnNbIGorKyBdKSAmJiAhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0XHQvLyBUcmlnZ2VyZWQgZXZlbnQgbXVzdCBlaXRoZXIgMSkgaGF2ZSBubyBuYW1lc3BhY2UsIG9yIDIpIGhhdmUgbmFtZXNwYWNlKHMpXG5cdFx0XHRcdC8vIGEgc3Vic2V0IG9yIGVxdWFsIHRvIHRob3NlIGluIHRoZSBib3VuZCBldmVudCAoYm90aCBjYW4gaGF2ZSBubyBuYW1lc3BhY2UpLlxuXHRcdFx0XHRpZiAoICFldmVudC5uYW1lc3BhY2VfcmUgfHwgZXZlbnQubmFtZXNwYWNlX3JlLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApIHtcblxuXHRcdFx0XHRcdGV2ZW50LmhhbmRsZU9iaiA9IGhhbmRsZU9iajtcblx0XHRcdFx0XHRldmVudC5kYXRhID0gaGFuZGxlT2JqLmRhdGE7XG5cblx0XHRcdFx0XHRyZXQgPSAoIChqUXVlcnkuZXZlbnQuc3BlY2lhbFsgaGFuZGxlT2JqLm9yaWdUeXBlIF0gfHwge30pLmhhbmRsZSB8fCBoYW5kbGVPYmouaGFuZGxlciApXG5cdFx0XHRcdFx0XHRcdC5hcHBseSggbWF0Y2hlZC5lbGVtLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHJldCAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZXZlbnQucmVzdWx0ID0gcmV0KSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGwgdGhlIHBvc3REaXNwYXRjaCBob29rIGZvciB0aGUgbWFwcGVkIHR5cGVcblx0XHRpZiAoIHNwZWNpYWwucG9zdERpc3BhdGNoICkge1xuXHRcdFx0c3BlY2lhbC5wb3N0RGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdGhhbmRsZXJzOiBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXJzICkge1xuXHRcdHZhciBpLCBtYXRjaGVzLCBzZWwsIGhhbmRsZU9iaixcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXG5cdFx0XHRjdXIgPSBldmVudC50YXJnZXQ7XG5cblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXG5cdFx0Ly8gQmxhY2staG9sZSBTVkcgPHVzZT4gaW5zdGFuY2UgdHJlZXMgKCMxMzE4MClcblx0XHQvLyBBdm9pZCBub24tbGVmdC1jbGljayBidWJibGluZyBpbiBGaXJlZm94ICgjMzg2MSlcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgJiYgY3VyLm5vZGVUeXBlICYmICghZXZlbnQuYnV0dG9uIHx8IGV2ZW50LnR5cGUgIT09IFwiY2xpY2tcIikgKSB7XG5cblx0XHRcdGZvciAoIDsgY3VyICE9PSB0aGlzOyBjdXIgPSBjdXIucGFyZW50Tm9kZSB8fCB0aGlzICkge1xuXG5cdFx0XHRcdC8vIERvbid0IHByb2Nlc3MgY2xpY2tzIG9uIGRpc2FibGVkIGVsZW1lbnRzICgjNjkxMSwgIzgxNjUsICMxMTM4MiwgIzExNzY0KVxuXHRcdFx0XHRpZiAoIGN1ci5kaXNhYmxlZCAhPT0gdHJ1ZSB8fCBldmVudC50eXBlICE9PSBcImNsaWNrXCIgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlcyA9IFtdO1xuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZGVsZWdhdGVDb3VudDsgaSsrICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKCMxMzIwMylcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xuXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXNbIHNlbCBdID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZXNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5KCBzZWwsIHRoaXMgKS5pbmRleCggY3VyICkgPj0gMCA6XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQoIHNlbCwgdGhpcywgbnVsbCwgWyBjdXIgXSApLmxlbmd0aDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlc1sgc2VsIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZXMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggbWF0Y2hlcy5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVyUXVldWUucHVzaCh7IGVsZW06IGN1ciwgaGFuZGxlcnM6IG1hdGNoZXMgfSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQWRkIHRoZSByZW1haW5pbmcgKGRpcmVjdGx5LWJvdW5kKSBoYW5kbGVyc1xuXHRcdGlmICggZGVsZWdhdGVDb3VudCA8IGhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKHsgZWxlbTogdGhpcywgaGFuZGxlcnM6IGhhbmRsZXJzLnNsaWNlKCBkZWxlZ2F0ZUNvdW50ICkgfSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGhhbmRsZXJRdWV1ZTtcblx0fSxcblxuXHQvLyBJbmNsdWRlcyBzb21lIGV2ZW50IHByb3BzIHNoYXJlZCBieSBLZXlFdmVudCBhbmQgTW91c2VFdmVudFxuXHRwcm9wczogXCJhbHRLZXkgYnViYmxlcyBjYW5jZWxhYmxlIGN0cmxLZXkgY3VycmVudFRhcmdldCBldmVudFBoYXNlIG1ldGFLZXkgcmVsYXRlZFRhcmdldCBzaGlmdEtleSB0YXJnZXQgdGltZVN0YW1wIHZpZXcgd2hpY2hcIi5zcGxpdChcIiBcIiksXG5cblx0Zml4SG9va3M6IHt9LFxuXG5cdGtleUhvb2tzOiB7XG5cdFx0cHJvcHM6IFwiY2hhciBjaGFyQ29kZSBrZXkga2V5Q29kZVwiLnNwbGl0KFwiIFwiKSxcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XG5cblx0XHRcdC8vIEFkZCB3aGljaCBmb3Iga2V5IGV2ZW50c1xuXHRcdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICkge1xuXHRcdFx0XHRldmVudC53aGljaCA9IG9yaWdpbmFsLmNoYXJDb2RlICE9IG51bGwgPyBvcmlnaW5hbC5jaGFyQ29kZSA6IG9yaWdpbmFsLmtleUNvZGU7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBldmVudDtcblx0XHR9XG5cdH0sXG5cblx0bW91c2VIb29rczoge1xuXHRcdHByb3BzOiBcImJ1dHRvbiBidXR0b25zIGNsaWVudFggY2xpZW50WSBvZmZzZXRYIG9mZnNldFkgcGFnZVggcGFnZVkgc2NyZWVuWCBzY3JlZW5ZIHRvRWxlbWVudFwiLnNwbGl0KFwiIFwiKSxcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XG5cdFx0XHR2YXIgZXZlbnREb2MsIGRvYywgYm9keSxcblx0XHRcdFx0YnV0dG9uID0gb3JpZ2luYWwuYnV0dG9uO1xuXG5cdFx0XHQvLyBDYWxjdWxhdGUgcGFnZVgvWSBpZiBtaXNzaW5nIGFuZCBjbGllbnRYL1kgYXZhaWxhYmxlXG5cdFx0XHRpZiAoIGV2ZW50LnBhZ2VYID09IG51bGwgJiYgb3JpZ2luYWwuY2xpZW50WCAhPSBudWxsICkge1xuXHRcdFx0XHRldmVudERvYyA9IGV2ZW50LnRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xuXHRcdFx0XHRkb2MgPSBldmVudERvYy5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0XHRcdGJvZHkgPSBldmVudERvYy5ib2R5O1xuXG5cdFx0XHRcdGV2ZW50LnBhZ2VYID0gb3JpZ2luYWwuY2xpZW50WCArICggZG9jICYmIGRvYy5zY3JvbGxMZWZ0IHx8IGJvZHkgJiYgYm9keS5zY3JvbGxMZWZ0IHx8IDAgKSAtICggZG9jICYmIGRvYy5jbGllbnRMZWZ0IHx8IGJvZHkgJiYgYm9keS5jbGllbnRMZWZ0IHx8IDAgKTtcblx0XHRcdFx0ZXZlbnQucGFnZVkgPSBvcmlnaW5hbC5jbGllbnRZICsgKCBkb2MgJiYgZG9jLnNjcm9sbFRvcCAgfHwgYm9keSAmJiBib2R5LnNjcm9sbFRvcCAgfHwgMCApIC0gKCBkb2MgJiYgZG9jLmNsaWVudFRvcCAgfHwgYm9keSAmJiBib2R5LmNsaWVudFRvcCAgfHwgMCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgd2hpY2ggZm9yIGNsaWNrOiAxID09PSBsZWZ0OyAyID09PSBtaWRkbGU7IDMgPT09IHJpZ2h0XG5cdFx0XHQvLyBOb3RlOiBidXR0b24gaXMgbm90IG5vcm1hbGl6ZWQsIHNvIGRvbid0IHVzZSBpdFxuXHRcdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdGV2ZW50LndoaWNoID0gKCBidXR0b24gJiAxID8gMSA6ICggYnV0dG9uICYgMiA/IDMgOiAoIGJ1dHRvbiAmIDQgPyAyIDogMCApICkgKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV2ZW50O1xuXHRcdH1cblx0fSxcblxuXHRmaXg6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRpZiAoIGV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdICkge1xuXHRcdFx0cmV0dXJuIGV2ZW50O1xuXHRcdH1cblxuXHRcdC8vIENyZWF0ZSBhIHdyaXRhYmxlIGNvcHkgb2YgdGhlIGV2ZW50IG9iamVjdCBhbmQgbm9ybWFsaXplIHNvbWUgcHJvcGVydGllc1xuXHRcdHZhciBpLCBwcm9wLCBjb3B5LFxuXHRcdFx0dHlwZSA9IGV2ZW50LnR5cGUsXG5cdFx0XHRvcmlnaW5hbEV2ZW50ID0gZXZlbnQsXG5cdFx0XHRmaXhIb29rID0gdGhpcy5maXhIb29rc1sgdHlwZSBdO1xuXG5cdFx0aWYgKCAhZml4SG9vayApIHtcblx0XHRcdHRoaXMuZml4SG9va3NbIHR5cGUgXSA9IGZpeEhvb2sgPVxuXHRcdFx0XHRybW91c2VFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLm1vdXNlSG9va3MgOlxuXHRcdFx0XHRya2V5RXZlbnQudGVzdCggdHlwZSApID8gdGhpcy5rZXlIb29rcyA6XG5cdFx0XHRcdHt9O1xuXHRcdH1cblx0XHRjb3B5ID0gZml4SG9vay5wcm9wcyA/IHRoaXMucHJvcHMuY29uY2F0KCBmaXhIb29rLnByb3BzICkgOiB0aGlzLnByb3BzO1xuXG5cdFx0ZXZlbnQgPSBuZXcgalF1ZXJ5LkV2ZW50KCBvcmlnaW5hbEV2ZW50ICk7XG5cblx0XHRpID0gY29weS5sZW5ndGg7XG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRwcm9wID0gY29weVsgaSBdO1xuXHRcdFx0ZXZlbnRbIHByb3AgXSA9IG9yaWdpbmFsRXZlbnRbIHByb3AgXTtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBDb3Jkb3ZhIDIuNSAoV2ViS2l0KSAoIzEzMjU1KVxuXHRcdC8vIEFsbCBldmVudHMgc2hvdWxkIGhhdmUgYSB0YXJnZXQ7IENvcmRvdmEgZGV2aWNlcmVhZHkgZG9lc24ndFxuXHRcdGlmICggIWV2ZW50LnRhcmdldCApIHtcblx0XHRcdGV2ZW50LnRhcmdldCA9IGRvY3VtZW50O1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA2LjArLCBDaHJvbWU8Mjhcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxuXHRcdGlmICggZXZlbnQudGFyZ2V0Lm5vZGVUeXBlID09PSAzICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZXZlbnQudGFyZ2V0LnBhcmVudE5vZGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZpeEhvb2suZmlsdGVyID8gZml4SG9vay5maWx0ZXIoIGV2ZW50LCBvcmlnaW5hbEV2ZW50ICkgOiBldmVudDtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXHRcdFx0Ly8gUHJldmVudCB0cmlnZ2VyZWQgaW1hZ2UubG9hZCBldmVudHMgZnJvbSBidWJibGluZyB0byB3aW5kb3cubG9hZFxuXHRcdFx0bm9CdWJibGU6IHRydWVcblx0XHR9LFxuXHRcdGZvY3VzOiB7XG5cdFx0XHQvLyBGaXJlIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3Rcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHRoaXMgIT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5mb2N1cyApIHtcblx0XHRcdFx0XHR0aGlzLmZvY3VzKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3VzaW5cIlxuXHRcdH0sXG5cdFx0Ymx1cjoge1xuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcyA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmJsdXIgKSB7XG5cdFx0XHRcdFx0dGhpcy5ibHVyKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3Vzb3V0XCJcblx0XHR9LFxuXHRcdGNsaWNrOiB7XG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcy50eXBlID09PSBcImNoZWNrYm94XCIgJiYgdGhpcy5jbGljayAmJiBqUXVlcnkubm9kZU5hbWUoIHRoaXMsIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHRcdHRoaXMuY2xpY2soKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBkb24ndCBmaXJlIG5hdGl2ZSAuY2xpY2soKSBvbiBsaW5rc1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5ub2RlTmFtZSggZXZlbnQudGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0c2ltdWxhdGU6IGZ1bmN0aW9uKCB0eXBlLCBlbGVtLCBldmVudCwgYnViYmxlICkge1xuXHRcdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZS5cblx0XHQvLyBGYWtlIG9yaWdpbmFsRXZlbnQgdG8gYXZvaWQgZG9ub3IncyBzdG9wUHJvcGFnYXRpb24sIGJ1dCBpZiB0aGVcblx0XHQvLyBzaW11bGF0ZWQgZXZlbnQgcHJldmVudHMgZGVmYXVsdCB0aGVuIHdlIGRvIHRoZSBzYW1lIG9uIHRoZSBkb25vci5cblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCksXG5cdFx0XHRldmVudCxcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0aXNTaW11bGF0ZWQ6IHRydWUsXG5cdFx0XHRcdG9yaWdpbmFsRXZlbnQ6IHt9XG5cdFx0XHR9XG5cdFx0KTtcblx0XHRpZiAoIGJ1YmJsZSApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBlLCBudWxsLCBlbGVtICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5jYWxsKCBlbGVtLCBlICk7XG5cdFx0fVxuXHRcdGlmICggZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkucmVtb3ZlRXZlbnQgPSBmdW5jdGlvbiggZWxlbSwgdHlwZSwgaGFuZGxlICkge1xuXHRpZiAoIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHtcblx0XHRlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGhhbmRsZSwgZmFsc2UgKTtcblx0fVxufTtcblxualF1ZXJ5LkV2ZW50ID0gZnVuY3Rpb24oIHNyYywgcHJvcHMgKSB7XG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEodGhpcyBpbnN0YW5jZW9mIGpRdWVyeS5FdmVudCkgKSB7XG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuRXZlbnQoIHNyYywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIEV2ZW50IG9iamVjdFxuXHRpZiAoIHNyYyAmJiBzcmMudHlwZSApIHtcblx0XHR0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7XG5cdFx0dGhpcy50eXBlID0gc3JjLnR5cGU7XG5cblx0XHQvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZFxuXHRcdC8vIGJ5IGEgaGFuZGxlciBsb3dlciBkb3duIHRoZSB0cmVlOyByZWZsZWN0IHRoZSBjb3JyZWN0IHZhbHVlLlxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gc3JjLmRlZmF1bHRQcmV2ZW50ZWQgfHxcblx0XHRcdFx0c3JjLmRlZmF1bHRQcmV2ZW50ZWQgPT09IHVuZGVmaW5lZCAmJlxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMFxuXHRcdFx0XHRzcmMucmV0dXJuVmFsdWUgPT09IGZhbHNlID9cblx0XHRcdHJldHVyblRydWUgOlxuXHRcdFx0cmV0dXJuRmFsc2U7XG5cblx0Ly8gRXZlbnQgdHlwZVxuXHR9IGVsc2Uge1xuXHRcdHRoaXMudHlwZSA9IHNyYztcblx0fVxuXG5cdC8vIFB1dCBleHBsaWNpdGx5IHByb3ZpZGVkIHByb3BlcnRpZXMgb250byB0aGUgZXZlbnQgb2JqZWN0XG5cdGlmICggcHJvcHMgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXG5cdHRoaXMudGltZVN0YW1wID0gc3JjICYmIHNyYy50aW1lU3RhbXAgfHwgalF1ZXJ5Lm5vdygpO1xuXG5cdC8vIE1hcmsgaXQgYXMgZml4ZWRcblx0dGhpc1sgalF1ZXJ5LmV4cGFuZG8gXSA9IHRydWU7XG59O1xuXG4vLyBqUXVlcnkuRXZlbnQgaXMgYmFzZWQgb24gRE9NMyBFdmVudHMgYXMgc3BlY2lmaWVkIGJ5IHRoZSBFQ01BU2NyaXB0IExhbmd1YWdlIEJpbmRpbmdcbi8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cblx0cHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmIGUucHJldmVudERlZmF1bHQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5zdG9wUHJvcGFnYXRpb24gKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBDcmVhdGUgbW91c2VlbnRlci9sZWF2ZSBldmVudHMgdXNpbmcgbW91c2VvdmVyL291dCBhbmQgZXZlbnQtdGltZSBjaGVja3Ncbi8vIFN1cHBvcnQ6IENocm9tZSAxNStcbmpRdWVyeS5lYWNoKHtcblx0bW91c2VlbnRlcjogXCJtb3VzZW92ZXJcIixcblx0bW91c2VsZWF2ZTogXCJtb3VzZW91dFwiLFxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcblx0cG9pbnRlcmxlYXZlOiBcInBvaW50ZXJvdXRcIlxufSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcblx0XHRkZWxlZ2F0ZVR5cGU6IGZpeCxcblx0XHRiaW5kVHlwZTogZml4LFxuXG5cdFx0aGFuZGxlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxuXHRcdFx0XHRyZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldCxcblx0XHRcdFx0aGFuZGxlT2JqID0gZXZlbnQuaGFuZGxlT2JqO1xuXG5cdFx0XHQvLyBGb3IgbW91c2VudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZFRhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAocmVsYXRlZCAhPT0gdGFyZ2V0ICYmICFqUXVlcnkuY29udGFpbnMoIHRhcmdldCwgcmVsYXRlZCApKSApIHtcblx0XHRcdFx0ZXZlbnQudHlwZSA9IGhhbmRsZU9iai5vcmlnVHlwZTtcblx0XHRcdFx0cmV0ID0gaGFuZGxlT2JqLmhhbmRsZXIuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cdH07XG59KTtcblxuLy8gU3VwcG9ydDogRmlyZWZveCwgQ2hyb21lLCBTYWZhcmlcbi8vIENyZWF0ZSBcImJ1YmJsaW5nXCIgZm9jdXMgYW5kIGJsdXIgZXZlbnRzXG5pZiAoICFzdXBwb3J0LmZvY3VzaW5CdWJibGVzICkge1xuXHRqUXVlcnkuZWFjaCh7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XG5cblx0XHQvLyBBdHRhY2ggYSBzaW5nbGUgY2FwdHVyaW5nIGhhbmRsZXIgb24gdGhlIGRvY3VtZW50IHdoaWxlIHNvbWVvbmUgd2FudHMgZm9jdXNpbi9mb2N1c291dFxuXHRcdHZhciBoYW5kbGVyID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApLCB0cnVlICk7XG5cdFx0XHR9O1xuXG5cdFx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGZpeCBdID0ge1xuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xuXHRcdFx0fSxcblx0XHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhX3ByaXYucmVtb3ZlKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXgsIGF0dGFjaGVzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9KTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cblx0b246IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAvKklOVEVSTkFMKi8gb25lICkge1xuXHRcdHZhciBvcmlnRm4sIHR5cGU7XG5cblx0XHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApXG5cdFx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gKCB0eXBlcy1PYmplY3QsIGRhdGEgKVxuXHRcdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9uKCB0eXBlLCBzZWxlY3RvciwgZGF0YSwgdHlwZXNbIHR5cGUgXSwgb25lICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXHRcdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRcdGRhdGEgPSBzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdC8vICggdHlwZXMsIHNlbGVjdG9yLCBmbiApXG5cdFx0XHRcdGZuID0gZGF0YTtcblx0XHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vICggdHlwZXMsIGRhdGEsIGZuIClcblx0XHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdFx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0XHRvcmlnRm4gPSBmbjtcblx0XHRcdGZuID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHQvLyBDYW4gdXNlIGFuIGVtcHR5IHNldCwgc2luY2UgZXZlbnQgY29udGFpbnMgdGhlIGluZm9cblx0XHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0XHRyZXR1cm4gb3JpZ0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdH07XG5cdFx0XHQvLyBVc2Ugc2FtZSBndWlkIHNvIGNhbGxlciBjYW4gcmVtb3ZlIHVzaW5nIG9yaWdGblxuXHRcdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHRcdH0pO1xuXHR9LFxuXHRvbmU6IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAxICk7XG5cdH0sXG5cdG9mZjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZm4gKSB7XG5cdFx0dmFyIGhhbmRsZU9iaiwgdHlwZTtcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcblx0XHRcdC8vICggZXZlbnQgKSAgZGlzcGF0Y2hlZCBqUXVlcnkuRXZlbnRcblx0XHRcdGhhbmRsZU9iaiA9IHR5cGVzLmhhbmRsZU9iajtcblx0XHRcdGpRdWVyeSggdHlwZXMuZGVsZWdhdGVUYXJnZXQgKS5vZmYoXG5cdFx0XHRcdGhhbmRsZU9iai5uYW1lc3BhY2UgPyBoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOiBoYW5kbGVPYmoub3JpZ1R5cGUsXG5cdFx0XHRcdGhhbmRsZU9iai5zZWxlY3Rvcixcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHQvLyAoIHR5cGVzLW9iamVjdCBbLCBzZWxlY3Rvcl0gKVxuXHRcdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcblx0XHRcdFx0dGhpcy5vZmYoIHR5cGUsIHNlbGVjdG9yLCB0eXBlc1sgdHlwZSBdICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCBzZWxlY3RvciA9PT0gZmFsc2UgfHwgdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgKSB7XG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIHRoaXMsIHR5cGVzLCBmbiwgc2VsZWN0b3IgKTtcblx0XHR9KTtcblx0fSxcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9KTtcblx0fSxcblx0dHJpZ2dlckhhbmRsZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBlbGVtID0gdGhpc1swXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0pO1xuXG5cbnZhclxuXHRyeGh0bWxUYWcgPSAvPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbXFx3Ol0rKVtePl0qKVxcLz4vZ2ksXG5cdHJ0YWdOYW1lID0gLzwoW1xcdzpdKykvLFxuXHRyaHRtbCA9IC88fCYjP1xcdys7Lyxcblx0cm5vSW5uZXJodG1sID0gLzwoPzpzY3JpcHR8c3R5bGV8bGluaykvaSxcblx0Ly8gY2hlY2tlZD1cImNoZWNrZWRcIiBvciBjaGVja2VkXG5cdHJjaGVja2VkID0gL2NoZWNrZWRcXHMqKD86W149XXw9XFxzKi5jaGVja2VkLikvaSxcblx0cnNjcmlwdFR5cGUgPSAvXiR8XFwvKD86amF2YXxlY21hKXNjcmlwdC9pLFxuXHRyc2NyaXB0VHlwZU1hc2tlZCA9IC9edHJ1ZVxcLyguKikvLFxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2csXG5cblx0Ly8gV2UgaGF2ZSB0byBjbG9zZSB0aGVzZSB0YWdzIHRvIHN1cHBvcnQgWEhUTUwgKCMxMzIwMClcblx0d3JhcE1hcCA9IHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFOVxuXHRcdG9wdGlvbjogWyAxLCBcIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz5cIiwgXCI8L3NlbGVjdD5cIiBdLFxuXG5cdFx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRcdGNvbDogWyAyLCBcIjx0YWJsZT48Y29sZ3JvdXA+XCIsIFwiPC9jb2xncm91cD48L3RhYmxlPlwiIF0sXG5cdFx0dHI6IFsgMiwgXCI8dGFibGU+PHRib2R5PlwiLCBcIjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXHRcdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRcdF9kZWZhdWx0OiBbIDAsIFwiXCIsIFwiXCIgXVxuXHR9O1xuXG4vLyBTdXBwb3J0OiBJRTlcbndyYXBNYXAub3B0Z3JvdXAgPSB3cmFwTWFwLm9wdGlvbjtcblxud3JhcE1hcC50Ym9keSA9IHdyYXBNYXAudGZvb3QgPSB3cmFwTWFwLmNvbGdyb3VwID0gd3JhcE1hcC5jYXB0aW9uID0gd3JhcE1hcC50aGVhZDtcbndyYXBNYXAudGggPSB3cmFwTWFwLnRkO1xuXG4vLyBTdXBwb3J0OiAxLnggY29tcGF0aWJpbGl0eVxuLy8gTWFuaXB1bGF0aW5nIHRhYmxlcyByZXF1aXJlcyBhIHRib2R5XG5mdW5jdGlvbiBtYW5pcHVsYXRpb25UYXJnZXQoIGVsZW0sIGNvbnRlbnQgKSB7XG5cdHJldHVybiBqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwidGFibGVcIiApICYmXG5cdFx0alF1ZXJ5Lm5vZGVOYW1lKCBjb250ZW50Lm5vZGVUeXBlICE9PSAxMSA/IGNvbnRlbnQgOiBjb250ZW50LmZpcnN0Q2hpbGQsIFwidHJcIiApID9cblxuXHRcdGVsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJ0Ym9keVwiKVswXSB8fFxuXHRcdFx0ZWxlbS5hcHBlbmRDaGlsZCggZWxlbS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiKSApIDpcblx0XHRlbGVtO1xufVxuXG4vLyBSZXBsYWNlL3Jlc3RvcmUgdGhlIHR5cGUgYXR0cmlidXRlIG9mIHNjcmlwdCBlbGVtZW50cyBmb3Igc2FmZSBET00gbWFuaXB1bGF0aW9uXG5mdW5jdGlvbiBkaXNhYmxlU2NyaXB0KCBlbGVtICkge1xuXHRlbGVtLnR5cGUgPSAoZWxlbS5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpICE9PSBudWxsKSArIFwiL1wiICsgZWxlbS50eXBlO1xuXHRyZXR1cm4gZWxlbTtcbn1cbmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7XG5cdHZhciBtYXRjaCA9IHJzY3JpcHRUeXBlTWFza2VkLmV4ZWMoIGVsZW0udHlwZSApO1xuXG5cdGlmICggbWF0Y2ggKSB7XG5cdFx0ZWxlbS50eXBlID0gbWF0Y2hbIDEgXTtcblx0fSBlbHNlIHtcblx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZShcInR5cGVcIik7XG5cdH1cblxuXHRyZXR1cm4gZWxlbTtcbn1cblxuLy8gTWFyayBzY3JpcHRzIGFzIGhhdmluZyBhbHJlYWR5IGJlZW4gZXZhbHVhdGVkXG5mdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRkYXRhX3ByaXYuc2V0KFxuXHRcdFx0ZWxlbXNbIGkgXSwgXCJnbG9iYWxFdmFsXCIsICFyZWZFbGVtZW50cyB8fCBkYXRhX3ByaXYuZ2V0KCByZWZFbGVtZW50c1sgaSBdLCBcImdsb2JhbEV2YWxcIiApXG5cdFx0KTtcblx0fVxufVxuXG5mdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkge1xuXHR2YXIgaSwgbCwgdHlwZSwgcGRhdGFPbGQsIHBkYXRhQ3VyLCB1ZGF0YU9sZCwgdWRhdGFDdXIsIGV2ZW50cztcblxuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gMS4gQ29weSBwcml2YXRlIGRhdGE6IGV2ZW50cywgaGFuZGxlcnMsIGV0Yy5cblx0aWYgKCBkYXRhX3ByaXYuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0cGRhdGFPbGQgPSBkYXRhX3ByaXYuYWNjZXNzKCBzcmMgKTtcblx0XHRwZGF0YUN1ciA9IGRhdGFfcHJpdi5zZXQoIGRlc3QsIHBkYXRhT2xkICk7XG5cdFx0ZXZlbnRzID0gcGRhdGFPbGQuZXZlbnRzO1xuXG5cdFx0aWYgKCBldmVudHMgKSB7XG5cdFx0XHRkZWxldGUgcGRhdGFDdXIuaGFuZGxlO1xuXHRcdFx0cGRhdGFDdXIuZXZlbnRzID0ge307XG5cblx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IGV2ZW50c1sgdHlwZSBdLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBkZXN0LCB0eXBlLCBldmVudHNbIHR5cGUgXVsgaSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyAyLiBDb3B5IHVzZXIgZGF0YVxuXHRpZiAoIGRhdGFfdXNlci5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHR1ZGF0YU9sZCA9IGRhdGFfdXNlci5hY2Nlc3MoIHNyYyApO1xuXHRcdHVkYXRhQ3VyID0galF1ZXJ5LmV4dGVuZCgge30sIHVkYXRhT2xkICk7XG5cblx0XHRkYXRhX3VzZXIuc2V0KCBkZXN0LCB1ZGF0YUN1ciApO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGdldEFsbCggY29udGV4dCwgdGFnICkge1xuXHR2YXIgcmV0ID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSA/IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyB8fCBcIipcIiApIDpcblx0XHRcdGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCA/IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnIHx8IFwiKlwiICkgOlxuXHRcdFx0W107XG5cblx0cmV0dXJuIHRhZyA9PT0gdW5kZWZpbmVkIHx8IHRhZyAmJiBqUXVlcnkubm9kZU5hbWUoIGNvbnRleHQsIHRhZyApID9cblx0XHRqUXVlcnkubWVyZ2UoIFsgY29udGV4dCBdLCByZXQgKSA6XG5cdFx0cmV0O1xufVxuXG4vLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHNcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cblx0XHQvLyBGaXggSUUgY2xvbmluZyBpc3N1ZXNcblx0XHRpZiAoICFzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkICYmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBlbGVtLm5vZGVUeXBlID09PSAxMSApICYmXG5cdFx0XHRcdCFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gV2UgZXNjaGV3IFNpenpsZSBoZXJlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zOiBodHRwOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGJ1aWxkRnJhZ21lbnQ6IGZ1bmN0aW9uKCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uICkge1xuXHRcdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgY29udGFpbnMsIGosXG5cdFx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdFx0bm9kZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdGVsZW0gPSBlbGVtc1sgaSBdO1xuXG5cdFx0XHRpZiAoIGVsZW0gfHwgZWxlbSA9PT0gMCApIHtcblxuXHRcdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcblx0XHRcdFx0aWYgKCBqUXVlcnkudHlwZSggZWxlbSApID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0LCBQaGFudG9tSlNcblx0XHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xuXG5cdFx0XHRcdC8vIENvbnZlcnQgbm9uLWh0bWwgaW50byBhIHRleHQgbm9kZVxuXHRcdFx0XHR9IGVsc2UgaWYgKCAhcmh0bWwudGVzdCggZWxlbSApICkge1xuXHRcdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0gKSApO1xuXG5cdFx0XHRcdC8vIENvbnZlcnQgaHRtbCBpbnRvIERPTSBub2Rlc1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRtcCA9IHRtcCB8fCBmcmFnbWVudC5hcHBlbmRDaGlsZCggY29udGV4dC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpICk7XG5cblx0XHRcdFx0XHQvLyBEZXNlcmlhbGl6ZSBhIHN0YW5kYXJkIHJlcHJlc2VudGF0aW9uXG5cdFx0XHRcdFx0dGFnID0gKCBydGFnTmFtZS5leGVjKCBlbGVtICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0d3JhcCA9IHdyYXBNYXBbIHRhZyBdIHx8IHdyYXBNYXAuX2RlZmF1bHQ7XG5cdFx0XHRcdFx0dG1wLmlubmVySFRNTCA9IHdyYXBbIDEgXSArIGVsZW0ucmVwbGFjZSggcnhodG1sVGFnLCBcIjwkMT48LyQyPlwiICkgKyB3cmFwWyAyIF07XG5cblx0XHRcdFx0XHQvLyBEZXNjZW5kIHRocm91Z2ggd3JhcHBlcnMgdG8gdGhlIHJpZ2h0IGNvbnRlbnRcblx0XHRcdFx0XHRqID0gd3JhcFsgMCBdO1xuXHRcdFx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRcdFx0dG1wID0gdG1wLmxhc3RDaGlsZDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBRdFdlYktpdCwgUGhhbnRvbUpTXG5cdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7XG5cblx0XHRcdFx0XHQvLyBSZW1lbWJlciB0aGUgdG9wLWxldmVsIGNvbnRhaW5lclxuXHRcdFx0XHRcdHRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdFx0XHQvLyBFbnN1cmUgdGhlIGNyZWF0ZWQgbm9kZXMgYXJlIG9ycGhhbmVkICgjMTIzOTIpXG5cdFx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB3cmFwcGVyIGZyb20gZnJhZ21lbnRcblx0XHRmcmFnbWVudC50ZXh0Q29udGVudCA9IFwiXCI7XG5cblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChlbGVtID0gbm9kZXNbIGkrKyBdKSApIHtcblxuXHRcdFx0Ly8gIzQwODcgLSBJZiBvcmlnaW4gYW5kIGRlc3RpbmF0aW9uIGVsZW1lbnRzIGFyZSB0aGUgc2FtZSwgYW5kIHRoaXMgaXNcblx0XHRcdC8vIHRoYXQgZWxlbWVudCwgZG8gbm90IGRvIGFueXRoaW5nXG5cdFx0XHRpZiAoIHNlbGVjdGlvbiAmJiBqUXVlcnkuaW5BcnJheSggZWxlbSwgc2VsZWN0aW9uICkgIT09IC0xICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Y29udGFpbnMgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXG5cdFx0XHQvLyBBcHBlbmQgdG8gZnJhZ21lbnRcblx0XHRcdHRtcCA9IGdldEFsbCggZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGVsZW0gKSwgXCJzY3JpcHRcIiApO1xuXG5cdFx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0XHRpZiAoIGNvbnRhaW5zICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdFx0aWYgKCBzY3JpcHRzICkge1xuXHRcdFx0XHRqID0gMDtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHRtcFsgaisrIF0pICkge1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRcdHNjcmlwdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmcmFnbWVudDtcblx0fSxcblxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblx0XHR2YXIgZGF0YSwgZWxlbSwgdHlwZSwga2V5LFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gZWxlbXNbIGkgXSkgIT09IHVuZGVmaW5lZDsgaSsrICkge1xuXHRcdFx0aWYgKCBqUXVlcnkuYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0XHRrZXkgPSBlbGVtWyBkYXRhX3ByaXYuZXhwYW5kbyBdO1xuXG5cdFx0XHRcdGlmICgga2V5ICYmIChkYXRhID0gZGF0YV9wcml2LmNhY2hlWyBrZXkgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdGZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggc3BlY2lhbFsgdHlwZSBdICkge1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBUaGlzIGlzIGEgc2hvcnRjdXQgdG8gYXZvaWQgalF1ZXJ5LmV2ZW50LnJlbW92ZSdzIG92ZXJoZWFkXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBkYXRhLmhhbmRsZSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggZGF0YV9wcml2LmNhY2hlWyBrZXkgXSApIHtcblx0XHRcdFx0XHRcdC8vIERpc2NhcmQgYW55IHJlbWFpbmluZyBgcHJpdmF0ZWAgZGF0YVxuXHRcdFx0XHRcdFx0ZGVsZXRlIGRhdGFfcHJpdi5jYWNoZVsga2V5IF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBEaXNjYXJkIGFueSByZW1haW5pbmcgYHVzZXJgIGRhdGFcblx0XHRcdGRlbGV0ZSBkYXRhX3VzZXIuY2FjaGVbIGVsZW1bIGRhdGFfdXNlci5leHBhbmRvIF0gXTtcblx0XHR9XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0dGV4dDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnRleHQoIHRoaXMgKSA6XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdFx0dGhpcy50ZXh0Q29udGVudCA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcblx0XHRcdFx0dGFyZ2V0LmFwcGVuZENoaWxkKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0cHJlcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGJlZm9yZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcyApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzLm5leHRTaWJsaW5nICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0cmVtb3ZlOiBmdW5jdGlvbiggc2VsZWN0b3IsIGtlZXBEYXRhIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHRcdHZhciBlbGVtLFxuXHRcdFx0ZWxlbXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCB0aGlzICkgOiB0aGlzLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggIWtlZXBEYXRhICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSApICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRpZiAoIGtlZXBEYXRhICYmIGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0c2V0R2xvYmFsRXZhbCggZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSB0aGlzW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gUHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cblx0XHRcdFx0Ly8gUmVtb3ZlIGFueSByZW1haW5pbmcgbm9kZXNcblx0XHRcdFx0ZWxlbS50ZXh0Q29udGVudCA9IFwiXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRkYXRhQW5kRXZlbnRzID0gZGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZmFsc2UgOiBkYXRhQW5kRXZlbnRzO1xuXHRcdGRlZXBEYXRhQW5kRXZlbnRzID0gZGVlcERhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGRhdGFBbmRFdmVudHMgOiBkZWVwRGF0YUFuZEV2ZW50cztcblxuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY2xvbmUoIHRoaXMsIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICk7XG5cdFx0fSk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0gdmFsdWUucmVwbGFjZSggcnhodG1sVGFnLCBcIjwkMT48LyQyPlwiICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2goIGUgKSB7fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5hcHBlbmQoIHZhbHVlICk7XG5cdFx0XHR9XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRyZXBsYWNlV2l0aDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGFyZyA9IGFyZ3VtZW50c1sgMCBdO1xuXG5cdFx0Ly8gTWFrZSB0aGUgY2hhbmdlcywgcmVwbGFjaW5nIGVhY2ggY29udGV4dCBlbGVtZW50IHdpdGggdGhlIG5ldyBjb250ZW50XG5cdFx0dGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGFyZyA9IHRoaXMucGFyZW50Tm9kZTtcblxuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCB0aGlzICkgKTtcblxuXHRcdFx0aWYgKCBhcmcgKSB7XG5cdFx0XHRcdGFyZy5yZXBsYWNlQ2hpbGQoIGVsZW0sIHRoaXMgKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEZvcmNlIHJlbW92YWwgaWYgdGhlcmUgd2FzIG5vIG5ldyBjb250ZW50IChlLmcuLCBmcm9tIGVtcHR5IGFyZ3VtZW50cylcblx0XHRyZXR1cm4gYXJnICYmIChhcmcubGVuZ3RoIHx8IGFyZy5ub2RlVHlwZSkgPyB0aGlzIDogdGhpcy5yZW1vdmUoKTtcblx0fSxcblxuXHRkZXRhY2g6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5yZW1vdmUoIHNlbGVjdG9yLCB0cnVlICk7XG5cdH0sXG5cblx0ZG9tTWFuaXA6IGZ1bmN0aW9uKCBhcmdzLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRhcmdzID0gY29uY2F0LmFwcGx5KCBbXSwgYXJncyApO1xuXG5cdFx0dmFyIGZyYWdtZW50LCBmaXJzdCwgc2NyaXB0cywgaGFzU2NyaXB0cywgbm9kZSwgZG9jLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRzZXQgPSB0aGlzLFxuXHRcdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHRcdHZhbHVlID0gYXJnc1sgMCBdLFxuXHRcdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0Ly8gV2UgY2FuJ3QgY2xvbmVOb2RlIGZyYWdtZW50cyB0aGF0IGNvbnRhaW4gY2hlY2tlZCwgaW4gV2ViS2l0XG5cdFx0aWYgKCBpc0Z1bmN0aW9uIHx8XG5cdFx0XHRcdCggbCA+IDEgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcblx0XHRcdFx0dmFyIHNlbGYgPSBzZXQuZXEoIGluZGV4ICk7XG5cdFx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcblx0XHRcdFx0XHRhcmdzWyAwIF0gPSB2YWx1ZS5jYWxsKCB0aGlzLCBpbmRleCwgc2VsZi5odG1sKCkgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzZWxmLmRvbU1hbmlwKCBhcmdzLCBjYWxsYmFjayApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCBsICkge1xuXHRcdFx0ZnJhZ21lbnQgPSBqUXVlcnkuYnVpbGRGcmFnbWVudCggYXJncywgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCB0aGlzICk7XG5cdFx0XHRmaXJzdCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdGlmICggZnJhZ21lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDEgKSB7XG5cdFx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZmlyc3QgKSB7XG5cdFx0XHRcdHNjcmlwdHMgPSBqUXVlcnkubWFwKCBnZXRBbGwoIGZyYWdtZW50LCBcInNjcmlwdFwiICksIGRpc2FibGVTY3JpcHQgKTtcblx0XHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHRcdC8vIFVzZSB0aGUgb3JpZ2luYWwgZnJhZ21lbnQgZm9yIHRoZSBsYXN0IGl0ZW0gaW5zdGVhZCBvZiB0aGUgZmlyc3QgYmVjYXVzZSBpdCBjYW4gZW5kIHVwXG5cdFx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gZnJhZ21lbnQ7XG5cblx0XHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IGpRdWVyeS5jbG9uZSggbm9kZSwgdHJ1ZSwgdHJ1ZSApO1xuXG5cdFx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXG5cdFx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHRcdFx0XHRcdC8vIGpRdWVyeS5tZXJnZSBiZWNhdXNlIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Ncblx0XHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwoIHRoaXNbIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0XHQvLyBSZWVuYWJsZSBzY3JpcHRzXG5cdFx0XHRcdFx0alF1ZXJ5Lm1hcCggc2NyaXB0cywgcmVzdG9yZVNjcmlwdCApO1xuXG5cdFx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgaGFzU2NyaXB0czsgaSsrICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IHNjcmlwdHNbIGkgXTtcblx0XHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0XHQhZGF0YV9wcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJiBqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkge1xuXG5cdFx0XHRcdFx0XHRcdGlmICggbm9kZS5zcmMgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5fZXZhbFVybCggbm9kZS5zcmMgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICkgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goe1xuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcblx0cHJlcGVuZFRvOiBcInByZXBlbmRcIixcblx0aW5zZXJ0QmVmb3JlOiBcImJlZm9yZVwiLFxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxuXHRyZXBsYWNlQWxsOiBcInJlcGxhY2VXaXRoXCJcbn0sIGZ1bmN0aW9uKCBuYW1lLCBvcmlnaW5hbCApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGVsZW1zLFxuXHRcdFx0cmV0ID0gW10sXG5cdFx0XHRpbnNlcnQgPSBqUXVlcnkoIHNlbGVjdG9yICksXG5cdFx0XHRsYXN0ID0gaW5zZXJ0Lmxlbmd0aCAtIDEsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgaSA8PSBsYXN0OyBpKysgKSB7XG5cdFx0XHRlbGVtcyA9IGkgPT09IGxhc3QgPyB0aGlzIDogdGhpcy5jbG9uZSggdHJ1ZSApO1xuXHRcdFx0alF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBRdFdlYktpdFxuXHRcdFx0Ly8gLmdldCgpIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0cHVzaC5hcHBseSggcmV0LCBlbGVtcy5nZXQoKSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggcmV0ICk7XG5cdH07XG59KTtcblxuXG52YXIgaWZyYW1lLFxuXHRlbGVtZGlzcGxheSA9IHt9O1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBhY3R1YWwgZGlzcGxheSBvZiBhIGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5vZGVOYW1lIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gZG9jIERvY3VtZW50IG9iamVjdFxuICovXG4vLyBDYWxsZWQgb25seSBmcm9tIHdpdGhpbiBkZWZhdWx0RGlzcGxheVxuZnVuY3Rpb24gYWN0dWFsRGlzcGxheSggbmFtZSwgZG9jICkge1xuXHR2YXIgc3R5bGUsXG5cdFx0ZWxlbSA9IGpRdWVyeSggZG9jLmNyZWF0ZUVsZW1lbnQoIG5hbWUgKSApLmFwcGVuZFRvKCBkb2MuYm9keSApLFxuXG5cdFx0Ly8gZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUgbWlnaHQgYmUgcmVsaWFibHkgdXNlZCBvbmx5IG9uIGF0dGFjaGVkIGVsZW1lbnRcblx0XHRkaXNwbGF5ID0gd2luZG93LmdldERlZmF1bHRDb21wdXRlZFN0eWxlICYmICggc3R5bGUgPSB3aW5kb3cuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUoIGVsZW1bIDAgXSApICkgP1xuXG5cdFx0XHQvLyBVc2Ugb2YgdGhpcyBtZXRob2QgaXMgYSB0ZW1wb3JhcnkgZml4IChtb3JlIGxpa2Ugb3B0aW1pemF0aW9uKSB1bnRpbCBzb21ldGhpbmcgYmV0dGVyIGNvbWVzIGFsb25nLFxuXHRcdFx0Ly8gc2luY2UgaXQgd2FzIHJlbW92ZWQgZnJvbSBzcGVjaWZpY2F0aW9uIGFuZCBzdXBwb3J0ZWQgb25seSBpbiBGRlxuXHRcdFx0c3R5bGUuZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW1bIDAgXSwgXCJkaXNwbGF5XCIgKTtcblxuXHQvLyBXZSBkb24ndCBoYXZlIGFueSBkYXRhIHN0b3JlZCBvbiB0aGUgZWxlbWVudCxcblx0Ly8gc28gdXNlIFwiZGV0YWNoXCIgbWV0aG9kIGFzIGZhc3Qgd2F5IHRvIGdldCByaWQgb2YgdGhlIGVsZW1lbnRcblx0ZWxlbS5kZXRhY2goKTtcblxuXHRyZXR1cm4gZGlzcGxheTtcbn1cblxuLyoqXG4gKiBUcnkgdG8gZGV0ZXJtaW5lIHRoZSBkZWZhdWx0IGRpc3BsYXkgdmFsdWUgb2YgYW4gZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IG5vZGVOYW1lXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHREaXNwbGF5KCBub2RlTmFtZSApIHtcblx0dmFyIGRvYyA9IGRvY3VtZW50LFxuXHRcdGRpc3BsYXkgPSBlbGVtZGlzcGxheVsgbm9kZU5hbWUgXTtcblxuXHRpZiAoICFkaXNwbGF5ICkge1xuXHRcdGRpc3BsYXkgPSBhY3R1YWxEaXNwbGF5KCBub2RlTmFtZSwgZG9jICk7XG5cblx0XHQvLyBJZiB0aGUgc2ltcGxlIHdheSBmYWlscywgcmVhZCBmcm9tIGluc2lkZSBhbiBpZnJhbWVcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiIHx8ICFkaXNwbGF5ICkge1xuXG5cdFx0XHQvLyBVc2UgdGhlIGFscmVhZHktY3JlYXRlZCBpZnJhbWUgaWYgcG9zc2libGVcblx0XHRcdGlmcmFtZSA9IChpZnJhbWUgfHwgalF1ZXJ5KCBcIjxpZnJhbWUgZnJhbWVib3JkZXI9JzAnIHdpZHRoPScwJyBoZWlnaHQ9JzAnLz5cIiApKS5hcHBlbmRUbyggZG9jLmRvY3VtZW50RWxlbWVudCApO1xuXG5cdFx0XHQvLyBBbHdheXMgd3JpdGUgYSBuZXcgSFRNTCBza2VsZXRvbiBzbyBXZWJraXQgYW5kIEZpcmVmb3ggZG9uJ3QgY2hva2Ugb24gcmV1c2Vcblx0XHRcdGRvYyA9IGlmcmFtZVsgMCBdLmNvbnRlbnREb2N1bWVudDtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUVcblx0XHRcdGRvYy53cml0ZSgpO1xuXHRcdFx0ZG9jLmNsb3NlKCk7XG5cblx0XHRcdGRpc3BsYXkgPSBhY3R1YWxEaXNwbGF5KCBub2RlTmFtZSwgZG9jICk7XG5cdFx0XHRpZnJhbWUuZGV0YWNoKCk7XG5cdFx0fVxuXG5cdFx0Ly8gU3RvcmUgdGhlIGNvcnJlY3QgZGVmYXVsdCBkaXNwbGF5XG5cdFx0ZWxlbWRpc3BsYXlbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xuXHR9XG5cblx0cmV0dXJuIGRpc3BsYXk7XG59XG52YXIgcm1hcmdpbiA9ICgvXm1hcmdpbi8pO1xuXG52YXIgcm51bW5vbnB4ID0gbmV3IFJlZ0V4cCggXCJeKFwiICsgcG51bSArIFwiKSg/IXB4KVthLXolXSskXCIsIFwiaVwiICk7XG5cbnZhciBnZXRTdHlsZXMgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHQvLyBTdXBwb3J0OiBJRTw9MTErLCBGaXJlZm94PD0zMCsgKCMxNTA5OCwgIzE0MTUwKVxuXHRcdC8vIElFIHRocm93cyBvbiBlbGVtZW50cyBjcmVhdGVkIGluIHBvcHVwc1xuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxuXHRcdGlmICggZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3Lm9wZW5lciApIHtcblx0XHRcdHJldHVybiBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSwgbnVsbCApO1xuXHRcdH1cblxuXHRcdHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSwgbnVsbCApO1xuXHR9O1xuXG5cblxuZnVuY3Rpb24gY3VyQ1NTKCBlbGVtLCBuYW1lLCBjb21wdXRlZCApIHtcblx0dmFyIHdpZHRoLCBtaW5XaWR0aCwgbWF4V2lkdGgsIHJldCxcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHQvLyBTdXBwb3J0OiBJRTlcblx0Ly8gZ2V0UHJvcGVydHlWYWx1ZSBpcyBvbmx5IG5lZWRlZCBmb3IgLmNzcygnZmlsdGVyJykgKCMxMjUzNylcblx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblx0fVxuXG5cdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRpZiAoIHJldCA9PT0gXCJcIiAmJiAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdHJldCA9IGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IGlPUyA8IDZcblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gaU9TIDwgNiAoYXQgbGVhc3QpIHJldHVybnMgcGVyY2VudGFnZSBmb3IgYSBsYXJnZXIgc2V0IG9mIHZhbHVlcywgYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVsc1xuXHRcdC8vIHRoaXMgaXMgYWdhaW5zdCB0aGUgQ1NTT00gZHJhZnQgc3BlYzogaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3Nzb20vI3Jlc29sdmVkLXZhbHVlc1xuXHRcdGlmICggcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJtYXJnaW4udGVzdCggbmFtZSApICkge1xuXG5cdFx0XHQvLyBSZW1lbWJlciB0aGUgb3JpZ2luYWwgdmFsdWVzXG5cdFx0XHR3aWR0aCA9IHN0eWxlLndpZHRoO1xuXHRcdFx0bWluV2lkdGggPSBzdHlsZS5taW5XaWR0aDtcblx0XHRcdG1heFdpZHRoID0gc3R5bGUubWF4V2lkdGg7XG5cblx0XHRcdC8vIFB1dCBpbiB0aGUgbmV3IHZhbHVlcyB0byBnZXQgYSBjb21wdXRlZCB2YWx1ZSBvdXRcblx0XHRcdHN0eWxlLm1pbldpZHRoID0gc3R5bGUubWF4V2lkdGggPSBzdHlsZS53aWR0aCA9IHJldDtcblx0XHRcdHJldCA9IGNvbXB1dGVkLndpZHRoO1xuXG5cdFx0XHQvLyBSZXZlcnQgdGhlIGNoYW5nZWQgdmFsdWVzXG5cdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xuXHRcdFx0c3R5bGUubWluV2lkdGggPSBtaW5XaWR0aDtcblx0XHRcdHN0eWxlLm1heFdpZHRoID0gbWF4V2lkdGg7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHJldCAhPT0gdW5kZWZpbmVkID9cblx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblx0Ly8gRGVmaW5lIHRoZSBob29rLCB3ZSdsbCBjaGVjayBvbiB0aGUgZmlyc3QgcnVuIGlmIGl0J3MgcmVhbGx5IG5lZWRlZC5cblx0cmV0dXJuIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBjb25kaXRpb25GbigpICkge1xuXHRcdFx0XHQvLyBIb29rIG5vdCBuZWVkZWQgKG9yIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBpdCBkdWVcblx0XHRcdFx0Ly8gdG8gbWlzc2luZyBkZXBlbmRlbmN5KSwgcmVtb3ZlIGl0LlxuXHRcdFx0XHRkZWxldGUgdGhpcy5nZXQ7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSG9vayBuZWVkZWQ7IHJlZGVmaW5lIGl0IHNvIHRoYXQgdGhlIHN1cHBvcnQgdGVzdCBpcyBub3QgZXhlY3V0ZWQgYWdhaW4uXG5cdFx0XHRyZXR1cm4gKHRoaXMuZ2V0ID0gaG9va0ZuKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLFxuXHRcdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUU5LTExK1xuXHQvLyBTdHlsZSBvZiBjbG9uZWQgZWxlbWVudCBhZmZlY3RzIHNvdXJjZSBlbGVtZW50IGNsb25lZCAoIzg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjA7d2lkdGg6MDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHg7bWFyZ2luLXRvcDoxcHg7XCIgK1xuXHRcdFwicG9zaXRpb246YWJzb2x1dGVcIjtcblx0Y29udGFpbmVyLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHQvLyBFeGVjdXRpbmcgYm90aCBwaXhlbFBvc2l0aW9uICYgYm94U2l6aW5nUmVsaWFibGUgdGVzdHMgcmVxdWlyZSBvbmx5IG9uZSBsYXlvdXRcblx0Ly8gc28gdGhleSdyZSBleGVjdXRlZCBhdCB0aGUgc2FtZSB0aW1lIHRvIHNhdmUgdGhlIHNlY29uZCBjb21wdXRhdGlvbi5cblx0ZnVuY3Rpb24gY29tcHV0ZVBpeGVsUG9zaXRpb25BbmRCb3hTaXppbmdSZWxpYWJsZSgpIHtcblx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9XG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xuXHRcdFx0Ly8gVmVuZG9yLXByZWZpeCBib3gtc2l6aW5nXG5cdFx0XHRcIi13ZWJraXQtYm94LXNpemluZzpib3JkZXItYm94Oy1tb3otYm94LXNpemluZzpib3JkZXItYm94O1wiICtcblx0XHRcdFwiYm94LXNpemluZzpib3JkZXItYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luLXRvcDoxJTt0b3A6MSU7XCIgK1xuXHRcdFx0XCJib3JkZXI6MXB4O3BhZGRpbmc6MXB4O3dpZHRoOjRweDtwb3NpdGlvbjphYnNvbHV0ZVwiO1xuXHRcdGRpdi5pbm5lckhUTUwgPSBcIlwiO1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiwgbnVsbCApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblx0XHRib3hTaXppbmdSZWxpYWJsZVZhbCA9IGRpdlN0eWxlLndpZHRoID09PSBcIjRweFwiO1xuXG5cdFx0ZG9jRWxlbS5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBub2RlLmpzIGpzZG9tXG5cdC8vIERvbid0IGFzc3VtZSB0aGF0IGdldENvbXB1dGVkU3R5bGUgaXMgYSBwcm9wZXJ0eSBvZiB0aGUgZ2xvYmFsIG9iamVjdFxuXHRpZiAoIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHN1cHBvcnQsIHtcblx0XHRcdHBpeGVsUG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdC8vIFRoaXMgdGVzdCBpcyBleGVjdXRlZCBvbmx5IG9uY2UgYnV0IHdlIHN0aWxsIGRvIG1lbW9pemluZ1xuXHRcdFx0XHQvLyBzaW5jZSB3ZSBjYW4gdXNlIHRoZSBib3hTaXppbmdSZWxpYWJsZSBwcmUtY29tcHV0aW5nLlxuXHRcdFx0XHQvLyBObyBuZWVkIHRvIGNoZWNrIGlmIHRoZSB0ZXN0IHdhcyBhbHJlYWR5IHBlcmZvcm1lZCwgdGhvdWdoLlxuXHRcdFx0XHRjb21wdXRlUGl4ZWxQb3NpdGlvbkFuZEJveFNpemluZ1JlbGlhYmxlKCk7XG5cdFx0XHRcdHJldHVybiBwaXhlbFBvc2l0aW9uVmFsO1xuXHRcdFx0fSxcblx0XHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xuXHRcdFx0XHRcdGNvbXB1dGVQaXhlbFBvc2l0aW9uQW5kQm94U2l6aW5nUmVsaWFibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gYm94U2l6aW5nUmVsaWFibGVWYWw7XG5cdFx0XHR9LFxuXHRcdFx0cmVsaWFibGVNYXJnaW5SaWdodDogZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCAyLjNcblx0XHRcdFx0Ly8gQ2hlY2sgaWYgZGl2IHdpdGggZXhwbGljaXQgd2lkdGggYW5kIG5vIG1hcmdpbi1yaWdodCBpbmNvcnJlY3RseVxuXHRcdFx0XHQvLyBnZXRzIGNvbXB1dGVkIG1hcmdpbi1yaWdodCBiYXNlZCBvbiB3aWR0aCBvZiBjb250YWluZXIuICgjMzMzMylcblx0XHRcdFx0Ly8gV2ViS2l0IEJ1ZyAxMzM0MyAtIGdldENvbXB1dGVkU3R5bGUgcmV0dXJucyB3cm9uZyB2YWx1ZSBmb3IgbWFyZ2luLXJpZ2h0XG5cdFx0XHRcdC8vIFRoaXMgc3VwcG9ydCBmdW5jdGlvbiBpcyBvbmx5IGV4ZWN1dGVkIG9uY2Ugc28gbm8gbWVtb2l6aW5nIGlzIG5lZWRlZC5cblx0XHRcdFx0dmFyIHJldCxcblx0XHRcdFx0XHRtYXJnaW5EaXYgPSBkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApO1xuXG5cdFx0XHRcdC8vIFJlc2V0IENTUzogYm94LXNpemluZzsgZGlzcGxheTsgbWFyZ2luOyBib3JkZXI7IHBhZGRpbmdcblx0XHRcdFx0bWFyZ2luRGl2LnN0eWxlLmNzc1RleHQgPSBkaXYuc3R5bGUuY3NzVGV4dCA9XG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveDwyOSwgQW5kcm9pZCAyLjNcblx0XHRcdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcblx0XHRcdFx0XHRcIi13ZWJraXQtYm94LXNpemluZzpjb250ZW50LWJveDstbW96LWJveC1zaXppbmc6Y29udGVudC1ib3g7XCIgK1xuXHRcdFx0XHRcdFwiYm94LXNpemluZzpjb250ZW50LWJveDtkaXNwbGF5OmJsb2NrO21hcmdpbjowO2JvcmRlcjowO3BhZGRpbmc6MFwiO1xuXHRcdFx0XHRtYXJnaW5EaXYuc3R5bGUubWFyZ2luUmlnaHQgPSBtYXJnaW5EaXYuc3R5bGUud2lkdGggPSBcIjBcIjtcblx0XHRcdFx0ZGl2LnN0eWxlLndpZHRoID0gXCIxcHhcIjtcblx0XHRcdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHRcdFx0cmV0ID0gIXBhcnNlRmxvYXQoIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKCBtYXJnaW5EaXYsIG51bGwgKS5tYXJnaW5SaWdodCApO1xuXG5cdFx0XHRcdGRvY0VsZW0ucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xuXHRcdFx0XHRkaXYucmVtb3ZlQ2hpbGQoIG1hcmdpbkRpdiApO1xuXG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pKCk7XG5cblxuLy8gQSBtZXRob2QgZm9yIHF1aWNrbHkgc3dhcHBpbmcgaW4vb3V0IENTUyBwcm9wZXJ0aWVzIHRvIGdldCBjb3JyZWN0IGNhbGN1bGF0aW9ucy5cbmpRdWVyeS5zd2FwID0gZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGNhbGxiYWNrLCBhcmdzICkge1xuXHR2YXIgcmV0LCBuYW1lLFxuXHRcdG9sZCA9IHt9O1xuXG5cdC8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0b2xkWyBuYW1lIF0gPSBlbGVtLnN0eWxlWyBuYW1lIF07XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdO1xuXHR9XG5cblx0cmV0ID0gY2FsbGJhY2suYXBwbHkoIGVsZW0sIGFyZ3MgfHwgW10gKTtcblxuXHQvLyBSZXZlcnQgdGhlIG9sZCB2YWx1ZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9sZFsgbmFtZSBdO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn07XG5cblxudmFyXG5cdC8vIFN3YXBwYWJsZSBpZiBkaXNwbGF5IGlzIG5vbmUgb3Igc3RhcnRzIHdpdGggdGFibGUgZXhjZXB0IFwidGFibGVcIiwgXCJ0YWJsZS1jZWxsXCIsIG9yIFwidGFibGUtY2FwdGlvblwiXG5cdC8vIFNlZSBoZXJlIGZvciBkaXNwbGF5IHZhbHVlczogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9DU1MvZGlzcGxheVxuXHRyZGlzcGxheXN3YXAgPSAvXihub25lfHRhYmxlKD8hLWNbZWFdKS4rKS8sXG5cdHJudW1zcGxpdCA9IG5ldyBSZWdFeHAoIFwiXihcIiArIHBudW0gKyBcIikoLiopJFwiLCBcImlcIiApLFxuXHRycmVsTnVtID0gbmV3IFJlZ0V4cCggXCJeKFsrLV0pPShcIiArIHBudW0gKyBcIilcIiwgXCJpXCIgKSxcblxuXHRjc3NTaG93ID0geyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCBkaXNwbGF5OiBcImJsb2NrXCIgfSxcblx0Y3NzTm9ybWFsVHJhbnNmb3JtID0ge1xuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxuXHRcdGZvbnRXZWlnaHQ6IFwiNDAwXCJcblx0fSxcblxuXHRjc3NQcmVmaXhlcyA9IFsgXCJXZWJraXRcIiwgXCJPXCIsIFwiTW96XCIsIFwibXNcIiBdO1xuXG4vLyBSZXR1cm4gYSBjc3MgcHJvcGVydHkgbWFwcGVkIHRvIGEgcG90ZW50aWFsbHkgdmVuZG9yIHByZWZpeGVkIHByb3BlcnR5XG5mdW5jdGlvbiB2ZW5kb3JQcm9wTmFtZSggc3R5bGUsIG5hbWUgKSB7XG5cblx0Ly8gU2hvcnRjdXQgZm9yIG5hbWVzIHRoYXQgYXJlIG5vdCB2ZW5kb3IgcHJlZml4ZWRcblx0aWYgKCBuYW1lIGluIHN0eWxlICkge1xuXHRcdHJldHVybiBuYW1lO1xuXHR9XG5cblx0Ly8gQ2hlY2sgZm9yIHZlbmRvciBwcmVmaXhlZCBuYW1lc1xuXHR2YXIgY2FwTmFtZSA9IG5hbWVbMF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoMSksXG5cdFx0b3JpZ05hbWUgPSBuYW1lLFxuXHRcdGkgPSBjc3NQcmVmaXhlcy5sZW5ndGg7XG5cblx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0bmFtZSA9IGNzc1ByZWZpeGVzWyBpIF0gKyBjYXBOYW1lO1xuXHRcdGlmICggbmFtZSBpbiBzdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBvcmlnTmFtZTtcbn1cblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApIHtcblx0dmFyIG1hdGNoZXMgPSBybnVtc3BsaXQuZXhlYyggdmFsdWUgKTtcblx0cmV0dXJuIG1hdGNoZXMgP1xuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDEgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDIgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGF1Z21lbnRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSwgaXNCb3JkZXJCb3gsIHN0eWxlcyApIHtcblx0dmFyIGkgPSBleHRyYSA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApID9cblx0XHQvLyBJZiB3ZSBhbHJlYWR5IGhhdmUgdGhlIHJpZ2h0IG1lYXN1cmVtZW50LCBhdm9pZCBhdWdtZW50YXRpb25cblx0XHQ0IDpcblx0XHQvLyBPdGhlcndpc2UgaW5pdGlhbGl6ZSBmb3IgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBwcm9wZXJ0aWVzXG5cdFx0bmFtZSA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cblx0XHR2YWwgPSAwO1xuXG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHtcblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW4sIHNvIGFkZCBpdCBpZiB3ZSB3YW50IGl0XG5cdFx0aWYgKCBleHRyYSA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBleHRyYSArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIGlzQm9yZGVyQm94ICkge1xuXHRcdFx0Ly8gYm9yZGVyLWJveCBpbmNsdWRlcyBwYWRkaW5nLCBzbyByZW1vdmUgaXQgaWYgd2Ugd2FudCBjb250ZW50XG5cdFx0XHRpZiAoIGV4dHJhID09PSBcImNvbnRlbnRcIiApIHtcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwicGFkZGluZ1wiICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBib3JkZXIgbm9yIG1hcmdpbiwgc28gcmVtb3ZlIGJvcmRlclxuXHRcdFx0aWYgKCBleHRyYSAhPT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQsIHNvIGFkZCBwYWRkaW5nXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQgbm9yIHBhZGRpbmcsIHNvIGFkZCBib3JkZXJcblx0XHRcdGlmICggZXh0cmEgIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdmFsO1xufVxuXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIG9mZnNldCBwcm9wZXJ0eSwgd2hpY2ggaXMgZXF1aXZhbGVudCB0byB0aGUgYm9yZGVyLWJveCB2YWx1ZVxuXHR2YXIgdmFsdWVJc0JvcmRlckJveCA9IHRydWUsXG5cdFx0dmFsID0gbmFtZSA9PT0gXCJ3aWR0aFwiID8gZWxlbS5vZmZzZXRXaWR0aCA6IGVsZW0ub2Zmc2V0SGVpZ2h0LFxuXHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLFxuXHRcdGlzQm9yZGVyQm94ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIjtcblxuXHQvLyBTb21lIG5vbi1odG1sIGVsZW1lbnRzIHJldHVybiB1bmRlZmluZWQgZm9yIG9mZnNldFdpZHRoLCBzbyBjaGVjayBmb3IgbnVsbC91bmRlZmluZWRcblx0Ly8gc3ZnIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjQ5Mjg1XG5cdC8vIE1hdGhNTCAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTQ5MTY2OFxuXHRpZiAoIHZhbCA8PSAwIHx8IHZhbCA9PSBudWxsICkge1xuXHRcdC8vIEZhbGwgYmFjayB0byBjb21wdXRlZCB0aGVuIHVuY29tcHV0ZWQgY3NzIGlmIG5lY2Vzc2FyeVxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XG5cdFx0aWYgKCB2YWwgPCAwIHx8IHZhbCA9PSBudWxsICkge1xuXHRcdFx0dmFsID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xuXHRcdH1cblxuXHRcdC8vIENvbXB1dGVkIHVuaXQgaXMgbm90IHBpeGVscy4gU3RvcCBoZXJlIGFuZCByZXR1cm4uXG5cdFx0aWYgKCBybnVtbm9ucHgudGVzdCh2YWwpICkge1xuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9XG5cblx0XHQvLyBDaGVjayBmb3Igc3R5bGUgaW4gY2FzZSBhIGJyb3dzZXIgd2hpY2ggcmV0dXJucyB1bnJlbGlhYmxlIHZhbHVlc1xuXHRcdC8vIGZvciBnZXRDb21wdXRlZFN0eWxlIHNpbGVudGx5IGZhbGxzIGJhY2sgdG8gdGhlIHJlbGlhYmxlIGVsZW0uc3R5bGVcblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gaXNCb3JkZXJCb3ggJiZcblx0XHRcdCggc3VwcG9ydC5ib3hTaXppbmdSZWxpYWJsZSgpIHx8IHZhbCA9PT0gZWxlbS5zdHlsZVsgbmFtZSBdICk7XG5cblx0XHQvLyBOb3JtYWxpemUgXCJcIiwgYXV0bywgYW5kIHByZXBhcmUgZm9yIGV4dHJhXG5cdFx0dmFsID0gcGFyc2VGbG9hdCggdmFsICkgfHwgMDtcblx0fVxuXG5cdC8vIFVzZSB0aGUgYWN0aXZlIGJveC1zaXppbmcgbW9kZWwgdG8gYWRkL3N1YnRyYWN0IGlycmVsZXZhbnQgc3R5bGVzXG5cdHJldHVybiAoIHZhbCArXG5cdFx0YXVnbWVudFdpZHRoT3JIZWlnaHQoXG5cdFx0XHRlbGVtLFxuXHRcdFx0bmFtZSxcblx0XHRcdGV4dHJhIHx8ICggaXNCb3JkZXJCb3ggPyBcImJvcmRlclwiIDogXCJjb250ZW50XCIgKSxcblx0XHRcdHZhbHVlSXNCb3JkZXJCb3gsXG5cdFx0XHRzdHlsZXNcblx0XHQpXG5cdCkgKyBcInB4XCI7XG59XG5cbmZ1bmN0aW9uIHNob3dIaWRlKCBlbGVtZW50cywgc2hvdyApIHtcblx0dmFyIGRpc3BsYXksIGVsZW0sIGhpZGRlbixcblx0XHR2YWx1ZXMgPSBbXSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhX3ByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApO1xuXHRcdGRpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXk7XG5cdFx0aWYgKCBzaG93ICkge1xuXHRcdFx0Ly8gUmVzZXQgdGhlIGlubGluZSBkaXNwbGF5IG9mIHRoaXMgZWxlbWVudCB0byBsZWFybiBpZiBpdCBpc1xuXHRcdFx0Ly8gYmVpbmcgaGlkZGVuIGJ5IGNhc2NhZGVkIHJ1bGVzIG9yIG5vdFxuXHRcdFx0aWYgKCAhdmFsdWVzWyBpbmRleCBdICYmIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgZWxlbWVudHMgd2hpY2ggaGF2ZSBiZWVuIG92ZXJyaWRkZW4gd2l0aCBkaXNwbGF5OiBub25lXG5cdFx0XHQvLyBpbiBhIHN0eWxlc2hlZXQgdG8gd2hhdGV2ZXIgdGhlIGRlZmF1bHQgYnJvd3NlciBzdHlsZSBpc1xuXHRcdFx0Ly8gZm9yIHN1Y2ggYW4gZWxlbWVudFxuXHRcdFx0aWYgKCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwiXCIgJiYgaXNIaWRkZW4oIGVsZW0gKSApIHtcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YV9wcml2LmFjY2VzcyggZWxlbSwgXCJvbGRkaXNwbGF5XCIsIGRlZmF1bHREaXNwbGF5KGVsZW0ubm9kZU5hbWUpICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhpZGRlbiA9IGlzSGlkZGVuKCBlbGVtICk7XG5cblx0XHRcdGlmICggZGlzcGxheSAhPT0gXCJub25lXCIgfHwgIWhpZGRlbiApIHtcblx0XHRcdFx0ZGF0YV9wcml2LnNldCggZWxlbSwgXCJvbGRkaXNwbGF5XCIsIGhpZGRlbiA/IGRpc3BsYXkgOiBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gU2V0IHRoZSBkaXNwbGF5IG9mIG1vc3Qgb2YgdGhlIGVsZW1lbnRzIGluIGEgc2Vjb25kIGxvb3Bcblx0Ly8gdG8gYXZvaWQgdGhlIGNvbnN0YW50IHJlZmxvd1xuXHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGVsZW0gPSBlbGVtZW50c1sgaW5kZXggXTtcblx0XHRpZiAoICFlbGVtLnN0eWxlICkge1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXHRcdGlmICggIXNob3cgfHwgZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIm5vbmVcIiB8fCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwiXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPSBzaG93ID8gdmFsdWVzWyBpbmRleCBdIHx8IFwiXCIgOiBcIm5vbmVcIjtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudHM7XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XG5cdFx0XHRcdFx0dmFyIHJldCA9IGN1ckNTUyggZWxlbSwgXCJvcGFjaXR5XCIgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmV0ID09PSBcIlwiID8gXCIxXCIgOiByZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgXCJweFwiIHRvIHRoZXNlIHBvc3NpYmx5LXVuaXRsZXNzIHByb3BlcnRpZXNcblx0Y3NzTnVtYmVyOiB7XG5cdFx0XCJjb2x1bW5Db3VudFwiOiB0cnVlLFxuXHRcdFwiZmlsbE9wYWNpdHlcIjogdHJ1ZSxcblx0XHRcImZsZXhHcm93XCI6IHRydWUsXG5cdFx0XCJmbGV4U2hyaW5rXCI6IHRydWUsXG5cdFx0XCJmb250V2VpZ2h0XCI6IHRydWUsXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXG5cdFx0XCJvcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJvcmRlclwiOiB0cnVlLFxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxuXHRcdFwid2lkb3dzXCI6IHRydWUsXG5cdFx0XCJ6SW5kZXhcIjogdHJ1ZSxcblx0XHRcInpvb21cIjogdHJ1ZVxuXHR9LFxuXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcblx0Ly8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZVxuXHRjc3NQcm9wczoge1xuXHRcdFwiZmxvYXRcIjogXCJjc3NGbG9hdFwiXG5cdH0sXG5cblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcblx0c3R5bGU6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSwgZXh0cmEgKSB7XG5cblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApLFxuXHRcdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdFx0bmFtZSA9IGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSB8fCAoIGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBzdHlsZSwgb3JpZ05hbWUgKSApO1xuXG5cdFx0Ly8gR2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvbiwgdGhlbiB1bnByZWZpeGVkIHZlcnNpb25cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIENoZWNrIGlmIHdlJ3JlIHNldHRpbmcgYSB2YWx1ZVxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRcdC8vIENvbnZlcnQgXCIrPVwiIG9yIFwiLT1cIiB0byByZWxhdGl2ZSBudW1iZXJzICgjNzM0NSlcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiAmJiAocmV0ID0gcnJlbE51bS5leGVjKCB2YWx1ZSApKSApIHtcblx0XHRcdFx0dmFsdWUgPSAoIHJldFsxXSArIDEgKSAqIHJldFsyXSArIHBhcnNlRmxvYXQoIGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKSApO1xuXHRcdFx0XHQvLyBGaXhlcyBidWcgIzkyMzdcblx0XHRcdFx0dHlwZSA9IFwibnVtYmVyXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG51bGwgYW5kIE5hTiB2YWx1ZXMgYXJlbid0IHNldCAoIzcxMTYpXG5cdFx0XHRpZiAoIHZhbHVlID09IG51bGwgfHwgdmFsdWUgIT09IHZhbHVlICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgbnVtYmVyLCBhZGQgJ3B4JyB0byB0aGUgKGV4Y2VwdCBmb3IgY2VydGFpbiBDU1MgcHJvcGVydGllcylcblx0XHRcdGlmICggdHlwZSA9PT0gXCJudW1iZXJcIiAmJiAhalF1ZXJ5LmNzc051bWJlclsgb3JpZ05hbWUgXSApIHtcblx0XHRcdFx0dmFsdWUgKz0gXCJweFwiO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTktMTErXG5cdFx0XHQvLyBiYWNrZ3JvdW5kLSogcHJvcHMgYWZmZWN0IG9yaWdpbmFsIGNsb25lJ3MgdmFsdWVzXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSBcImluaGVyaXRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCwgdXNlIHRoYXQgdmFsdWUsIG90aGVyd2lzZSBqdXN0IHNldCB0aGUgc3BlY2lmaWVkIHZhbHVlXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKFwic2V0XCIgaW4gaG9va3MpIHx8ICh2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgbm9uLWNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBmYWxzZSwgZXh0cmEgKSkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIGp1c3QgZ2V0IHRoZSB2YWx1ZSBmcm9tIHRoZSBzdHlsZSBvYmplY3Rcblx0XHRcdHJldHVybiBzdHlsZVsgbmFtZSBdO1xuXHRcdH1cblx0fSxcblxuXHRjc3M6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBleHRyYSwgc3R5bGVzICkge1xuXHRcdHZhciB2YWwsIG51bSwgaG9va3MsXG5cdFx0XHRvcmlnTmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUgKTtcblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZVxuXHRcdG5hbWUgPSBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gfHwgKCBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggZWxlbS5zdHlsZSwgb3JpZ05hbWUgKSApO1xuXG5cdFx0Ly8gVHJ5IHByZWZpeGVkIG5hbWUgZm9sbG93ZWQgYnkgdGhlIHVucHJlZml4ZWQgbmFtZVxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWwgPSBob29rcy5nZXQoIGVsZW0sIHRydWUsIGV4dHJhICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiBhIHdheSB0byBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGV4aXN0cywgdXNlIHRoYXRcblx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBDb252ZXJ0IFwibm9ybWFsXCIgdG8gY29tcHV0ZWQgdmFsdWVcblx0XHRpZiAoIHZhbCA9PT0gXCJub3JtYWxcIiAmJiBuYW1lIGluIGNzc05vcm1hbFRyYW5zZm9ybSApIHtcblx0XHRcdHZhbCA9IGNzc05vcm1hbFRyYW5zZm9ybVsgbmFtZSBdO1xuXHRcdH1cblxuXHRcdC8vIE1ha2UgbnVtZXJpYyBpZiBmb3JjZWQgb3IgYSBxdWFsaWZpZXIgd2FzIHByb3ZpZGVkIGFuZCB2YWwgbG9va3MgbnVtZXJpY1xuXHRcdGlmICggZXh0cmEgPT09IFwiXCIgfHwgZXh0cmEgKSB7XG5cdFx0XHRudW0gPSBwYXJzZUZsb2F0KCB2YWwgKTtcblx0XHRcdHJldHVybiBleHRyYSA9PT0gdHJ1ZSB8fCBqUXVlcnkuaXNOdW1lcmljKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblx0XHRyZXR1cm4gdmFsO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goWyBcImhlaWdodFwiLCBcIndpZHRoXCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0Ly8gQ2VydGFpbiBlbGVtZW50cyBjYW4gaGF2ZSBkaW1lbnNpb24gaW5mbyBpZiB3ZSBpbnZpc2libHkgc2hvdyB0aGVtXG5cdFx0XHRcdC8vIGJ1dCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0XG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmIGVsZW0ub2Zmc2V0V2lkdGggPT09IDAgP1xuXHRcdFx0XHRcdGpRdWVyeS5zd2FwKCBlbGVtLCBjc3NTaG93LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHJldHVybiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApO1xuXHRcdFx0XHRcdH0pIDpcblx0XHRcdFx0XHRnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgc3R5bGVzID0gZXh0cmEgJiYgZ2V0U3R5bGVzKCBlbGVtICk7XG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBleHRyYSA/XG5cdFx0XHRcdGF1Z21lbnRXaWR0aE9ySGVpZ2h0KFxuXHRcdFx0XHRcdGVsZW0sXG5cdFx0XHRcdFx0bmFtZSxcblx0XHRcdFx0XHRleHRyYSxcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiLFxuXHRcdFx0XHRcdHN0eWxlc1xuXHRcdFx0XHQpIDogMFxuXHRcdFx0KTtcblx0XHR9XG5cdH07XG59KTtcblxuLy8gU3VwcG9ydDogQW5kcm9pZCAyLjNcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5SaWdodCA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5yZWxpYWJsZU1hcmdpblJpZ2h0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuc3dhcCggZWxlbSwgeyBcImRpc3BsYXlcIjogXCJpbmxpbmUtYmxvY2tcIiB9LFxuXHRcdFx0XHRjdXJDU1MsIFsgZWxlbSwgXCJtYXJnaW5SaWdodFwiIF0gKTtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKHtcblx0bWFyZ2luOiBcIlwiLFxuXHRwYWRkaW5nOiBcIlwiLFxuXHRib3JkZXI6IFwiV2lkdGhcIlxufSwgZnVuY3Rpb24oIHByZWZpeCwgc3VmZml4ICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdID0ge1xuXHRcdGV4cGFuZDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGkgPSAwLFxuXHRcdFx0XHRleHBhbmRlZCA9IHt9LFxuXG5cdFx0XHRcdC8vIEFzc3VtZXMgYSBzaW5nbGUgbnVtYmVyIGlmIG5vdCBhIHN0cmluZ1xuXHRcdFx0XHRwYXJ0cyA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnNwbGl0KFwiIFwiKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggIXJtYXJnaW4udGVzdCggcHJlZml4ICkgKSB7XG5cdFx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXS5zZXQgPSBzZXRQb3NpdGl2ZU51bWJlcjtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRjc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXG5cdFx0XHRcdG1hcCA9IHt9LFxuXHRcdFx0XHRpID0gMDtcblxuXHRcdFx0aWYgKCBqUXVlcnkuaXNBcnJheSggbmFtZSApICkge1xuXHRcdFx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKTtcblx0XHRcdFx0bGVuID0gbmFtZS5sZW5ndGg7XG5cblx0XHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0bWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIG1hcDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUsIHZhbHVlICkgOlxuXHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBuYW1lICk7XG5cdFx0fSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cdHNob3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xuXHR9LFxuXHRoaWRlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcblx0fSxcblx0dG9nZ2xlOiBmdW5jdGlvbiggc3RhdGUgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlID8gdGhpcy5zaG93KCkgOiB0aGlzLmhpZGUoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBpc0hpZGRlbiggdGhpcyApICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5zaG93KCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5oaWRlKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5cbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcblx0cmV0dXJuIG5ldyBUd2Vlbi5wcm90b3R5cGUuaW5pdCggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKTtcbn1cbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xuXG5Ud2Vlbi5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBUd2Vlbixcblx0aW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkge1xuXHRcdHRoaXMuZWxlbSA9IGVsZW07XG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcblx0XHR0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBcInN3aW5nXCI7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblx0XHR0aGlzLnN0YXJ0ID0gdGhpcy5ub3cgPSB0aGlzLmN1cigpO1xuXHRcdHRoaXMuZW5kID0gZW5kO1xuXHRcdHRoaXMudW5pdCA9IHVuaXQgfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdH0sXG5cdGN1cjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xuXHRcdFx0aG9va3MuZ2V0KCB0aGlzICkgOlxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LmdldCggdGhpcyApO1xuXHR9LFxuXHRydW46IGZ1bmN0aW9uKCBwZXJjZW50ICkge1xuXHRcdHZhciBlYXNlZCxcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLmR1cmF0aW9uICkge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXG5cdFx0XHRcdHBlcmNlbnQsIHRoaXMub3B0aW9ucy5kdXJhdGlvbiAqIHBlcmNlbnQsIDAsIDEsIHRoaXMub3B0aW9ucy5kdXJhdGlvblxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IHBlcmNlbnQ7XG5cdFx0fVxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLnN0ZXAgKSB7XG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XG5cdFx0XHRob29rcy5zZXQoIHRoaXMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxufTtcblxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xuXG5Ud2Vlbi5wcm9wSG9va3MgPSB7XG5cdF9kZWZhdWx0OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0XHR2YXIgcmVzdWx0O1xuXG5cdFx0XHRpZiAoIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSAhPSBudWxsICYmXG5cdFx0XHRcdCghdHdlZW4uZWxlbS5zdHlsZSB8fCB0d2Vlbi5lbGVtLnN0eWxlWyB0d2Vlbi5wcm9wIF0gPT0gbnVsbCkgKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxuXHRcdFx0Ly8gYXR0ZW1wdCBhIHBhcnNlRmxvYXQgYW5kIGZhbGxiYWNrIHRvIGEgc3RyaW5nIGlmIHRoZSBwYXJzZSBmYWlscy5cblx0XHRcdC8vIFNpbXBsZSB2YWx1ZXMgc3VjaCBhcyBcIjEwcHhcIiBhcmUgcGFyc2VkIHRvIEZsb2F0O1xuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cblx0XHRcdHJlc3VsdCA9IGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIFwiXCIgKTtcblx0XHRcdC8vIEVtcHR5IHN0cmluZ3MsIG51bGwsIHVuZGVmaW5lZCBhbmQgXCJhdXRvXCIgYXJlIGNvbnZlcnRlZCB0byAwLlxuXHRcdFx0cmV0dXJuICFyZXN1bHQgfHwgcmVzdWx0ID09PSBcImF1dG9cIiA/IDAgOiByZXN1bHQ7XG5cdFx0fSxcblx0XHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRcdC8vIFVzZSBzdGVwIGhvb2sgZm9yIGJhY2sgY29tcGF0LlxuXHRcdFx0Ly8gVXNlIGNzc0hvb2sgaWYgaXRzIHRoZXJlLlxuXHRcdFx0Ly8gVXNlIC5zdHlsZSBpZiBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZS5cblx0XHRcdGlmICggalF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSApIHtcblx0XHRcdFx0alF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSggdHdlZW4gKTtcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0uc3R5bGUgJiYgKCB0d2Vlbi5lbGVtLnN0eWxlWyBqUXVlcnkuY3NzUHJvcHNbIHR3ZWVuLnByb3AgXSBdICE9IG51bGwgfHwgalF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gKSApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCB0d2Vlbi5ub3cgKyB0d2Vlbi51bml0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBTdXBwb3J0OiBJRTlcbi8vIFBhbmljIGJhc2VkIGFwcHJvYWNoIHRvIHNldHRpbmcgdGhpbmdzIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuVHdlZW4ucHJvcEhvb2tzLnNjcm9sbFRvcCA9IFR3ZWVuLnByb3BIb29rcy5zY3JvbGxMZWZ0ID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgJiYgdHdlZW4uZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93O1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmVhc2luZyA9IHtcblx0bGluZWFyOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gcDtcblx0fSxcblx0c3dpbmc6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiAwLjUgLSBNYXRoLmNvcyggcCAqIE1hdGguUEkgKSAvIDI7XG5cdH1cbn07XG5cbmpRdWVyeS5meCA9IFR3ZWVuLnByb3RvdHlwZS5pbml0O1xuXG4vLyBCYWNrIENvbXBhdCA8MS44IGV4dGVuc2lvbiBwb2ludFxualF1ZXJ5LmZ4LnN0ZXAgPSB7fTtcblxuXG5cblxudmFyXG5cdGZ4Tm93LCB0aW1lcklkLFxuXHRyZnh0eXBlcyA9IC9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxcblx0cmZ4bnVtID0gbmV3IFJlZ0V4cCggXCJeKD86KFsrLV0pPXwpKFwiICsgcG51bSArIFwiKShbYS16JV0qKSRcIiwgXCJpXCIgKSxcblx0cnJ1biA9IC9xdWV1ZUhvb2tzJC8sXG5cdGFuaW1hdGlvblByZWZpbHRlcnMgPSBbIGRlZmF1bHRQcmVmaWx0ZXIgXSxcblx0dHdlZW5lcnMgPSB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKSxcblx0XHRcdFx0dGFyZ2V0ID0gdHdlZW4uY3VyKCksXG5cdFx0XHRcdHBhcnRzID0gcmZ4bnVtLmV4ZWMoIHZhbHVlICksXG5cdFx0XHRcdHVuaXQgPSBwYXJ0cyAmJiBwYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0XHRcdC8vIFN0YXJ0aW5nIHZhbHVlIGNvbXB1dGF0aW9uIGlzIHJlcXVpcmVkIGZvciBwb3RlbnRpYWwgdW5pdCBtaXNtYXRjaGVzXG5cdFx0XHRcdHN0YXJ0ID0gKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICt0YXJnZXQgKSAmJlxuXHRcdFx0XHRcdHJmeG51bS5leGVjKCBqUXVlcnkuY3NzKCB0d2Vlbi5lbGVtLCBwcm9wICkgKSxcblx0XHRcdFx0c2NhbGUgPSAxLFxuXHRcdFx0XHRtYXhJdGVyYXRpb25zID0gMjA7XG5cblx0XHRcdGlmICggc3RhcnQgJiYgc3RhcnRbIDMgXSAhPT0gdW5pdCApIHtcblx0XHRcdFx0Ly8gVHJ1c3QgdW5pdHMgcmVwb3J0ZWQgYnkgalF1ZXJ5LmNzc1xuXHRcdFx0XHR1bml0ID0gdW5pdCB8fCBzdGFydFsgMyBdO1xuXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB3ZSB1cGRhdGUgdGhlIHR3ZWVuIHByb3BlcnRpZXMgbGF0ZXIgb25cblx0XHRcdFx0cGFydHMgPSBwYXJ0cyB8fCBbXTtcblxuXHRcdFx0XHQvLyBJdGVyYXRpdmVseSBhcHByb3hpbWF0ZSBmcm9tIGEgbm9uemVybyBzdGFydGluZyBwb2ludFxuXHRcdFx0XHRzdGFydCA9ICt0YXJnZXQgfHwgMTtcblxuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0Ly8gSWYgcHJldmlvdXMgaXRlcmF0aW9uIHplcm9lZCBvdXQsIGRvdWJsZSB1bnRpbCB3ZSBnZXQgKnNvbWV0aGluZyouXG5cdFx0XHRcdFx0Ly8gVXNlIHN0cmluZyBmb3IgZG91Ymxpbmcgc28gd2UgZG9uJ3QgYWNjaWRlbnRhbGx5IHNlZSBzY2FsZSBhcyB1bmNoYW5nZWQgYmVsb3dcblx0XHRcdFx0XHRzY2FsZSA9IHNjYWxlIHx8IFwiLjVcIjtcblxuXHRcdFx0XHRcdC8vIEFkanVzdCBhbmQgYXBwbHlcblx0XHRcdFx0XHRzdGFydCA9IHN0YXJ0IC8gc2NhbGU7XG5cdFx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCBwcm9wLCBzdGFydCArIHVuaXQgKTtcblxuXHRcdFx0XHQvLyBVcGRhdGUgc2NhbGUsIHRvbGVyYXRpbmcgemVybyBvciBOYU4gZnJvbSB0d2Vlbi5jdXIoKSxcblx0XHRcdFx0Ly8gYnJlYWsgdGhlIGxvb3AgaWYgc2NhbGUgaXMgdW5jaGFuZ2VkIG9yIHBlcmZlY3QsIG9yIGlmIHdlJ3ZlIGp1c3QgaGFkIGVub3VnaFxuXHRcdFx0XHR9IHdoaWxlICggc2NhbGUgIT09IChzY2FsZSA9IHR3ZWVuLmN1cigpIC8gdGFyZ2V0KSAmJiBzY2FsZSAhPT0gMSAmJiAtLW1heEl0ZXJhdGlvbnMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVXBkYXRlIHR3ZWVuIHByb3BlcnRpZXNcblx0XHRcdGlmICggcGFydHMgKSB7XG5cdFx0XHRcdHN0YXJ0ID0gdHdlZW4uc3RhcnQgPSArc3RhcnQgfHwgK3RhcmdldCB8fCAwO1xuXHRcdFx0XHR0d2Vlbi51bml0ID0gdW5pdDtcblx0XHRcdFx0Ly8gSWYgYSArPS8tPSB0b2tlbiB3YXMgcHJvdmlkZWQsIHdlJ3JlIGRvaW5nIGEgcmVsYXRpdmUgYW5pbWF0aW9uXG5cdFx0XHRcdHR3ZWVuLmVuZCA9IHBhcnRzWyAxIF0gP1xuXHRcdFx0XHRcdHN0YXJ0ICsgKCBwYXJ0c1sgMSBdICsgMSApICogcGFydHNbIDIgXSA6XG5cdFx0XHRcdFx0K3BhcnRzWyAyIF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9IF1cblx0fTtcblxuLy8gQW5pbWF0aW9ucyBjcmVhdGVkIHN5bmNocm9ub3VzbHkgd2lsbCBydW4gc3luY2hyb25vdXNseVxuZnVuY3Rpb24gY3JlYXRlRnhOb3coKSB7XG5cdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XG5cdH0pO1xuXHRyZXR1cm4gKCBmeE5vdyA9IGpRdWVyeS5ub3coKSApO1xufVxuXG4vLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvblxuZnVuY3Rpb24gZ2VuRngoIHR5cGUsIGluY2x1ZGVXaWR0aCApIHtcblx0dmFyIHdoaWNoLFxuXHRcdGkgPSAwLFxuXHRcdGF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTtcblxuXHQvLyBJZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsXG5cdC8vIG90aGVyd2lzZSBzdGVwIHZhbHVlIGlzIDIgdG8gc2tpcCBvdmVyIExlZnQgYW5kIFJpZ2h0XG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xuXHRmb3IgKCA7IGkgPCA0IDsgaSArPSAyIC0gaW5jbHVkZVdpZHRoICkge1xuXHRcdHdoaWNoID0gY3NzRXhwYW5kWyBpIF07XG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XG5cdH1cblxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcblx0XHRhdHRycy5vcGFjaXR5ID0gYXR0cnMud2lkdGggPSB0eXBlO1xuXHR9XG5cblx0cmV0dXJuIGF0dHJzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUd2VlbiggdmFsdWUsIHByb3AsIGFuaW1hdGlvbiApIHtcblx0dmFyIHR3ZWVuLFxuXHRcdGNvbGxlY3Rpb24gPSAoIHR3ZWVuZXJzWyBwcm9wIF0gfHwgW10gKS5jb25jYXQoIHR3ZWVuZXJzWyBcIipcIiBdICksXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGlmICggKHR3ZWVuID0gY29sbGVjdGlvblsgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIHByb3AsIHZhbHVlICkpICkge1xuXG5cdFx0XHQvLyBXZSdyZSBkb25lIHdpdGggdGhpcyBwcm9wZXJ0eVxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0UHJlZmlsdGVyKCBlbGVtLCBwcm9wcywgb3B0cyApIHtcblx0LyoganNoaW50IHZhbGlkdGhpczogdHJ1ZSAqL1xuXHR2YXIgcHJvcCwgdmFsdWUsIHRvZ2dsZSwgdHdlZW4sIGhvb2tzLCBvbGRmaXJlLCBkaXNwbGF5LCBjaGVja0Rpc3BsYXksXG5cdFx0YW5pbSA9IHRoaXMsXG5cdFx0b3JpZyA9IHt9LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZSxcblx0XHRoaWRkZW4gPSBlbGVtLm5vZGVUeXBlICYmIGlzSGlkZGVuKCBlbGVtICksXG5cdFx0ZGF0YVNob3cgPSBkYXRhX3ByaXYuZ2V0KCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cblx0Ly8gSGFuZGxlIHF1ZXVlOiBmYWxzZSBwcm9taXNlc1xuXHRpZiAoICFvcHRzLnF1ZXVlICkge1xuXHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCBcImZ4XCIgKTtcblx0XHRpZiAoIGhvb2tzLnVucXVldWVkID09IG51bGwgKSB7XG5cdFx0XHRob29rcy51bnF1ZXVlZCA9IDA7XG5cdFx0XHRvbGRmaXJlID0gaG9va3MuZW1wdHkuZmlyZTtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhaG9va3MudW5xdWV1ZWQgKSB7XG5cdFx0XHRcdFx0b2xkZmlyZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0XHRob29rcy51bnF1ZXVlZCsrO1xuXG5cdFx0YW5pbS5hbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBFbnN1cmUgdGhlIGNvbXBsZXRlIGhhbmRsZXIgaXMgY2FsbGVkIGJlZm9yZSB0aGlzIGNvbXBsZXRlc1xuXHRcdFx0YW5pbS5hbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGhvb2tzLnVucXVldWVkLS07XG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHQvLyBIZWlnaHQvd2lkdGggb3ZlcmZsb3cgcGFzc1xuXHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcImhlaWdodFwiIGluIHByb3BzIHx8IFwid2lkdGhcIiBpbiBwcm9wcyApICkge1xuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG5vdGhpbmcgc25lYWtzIG91dFxuXHRcdC8vIFJlY29yZCBhbGwgMyBvdmVyZmxvdyBhdHRyaWJ1dGVzIGJlY2F1c2UgSUU5LTEwIGRvIG5vdFxuXHRcdC8vIGNoYW5nZSB0aGUgb3ZlcmZsb3cgYXR0cmlidXRlIHdoZW4gb3ZlcmZsb3dYIGFuZFxuXHRcdC8vIG92ZXJmbG93WSBhcmUgc2V0IHRvIHRoZSBzYW1lIHZhbHVlXG5cdFx0b3B0cy5vdmVyZmxvdyA9IFsgc3R5bGUub3ZlcmZsb3csIHN0eWxlLm92ZXJmbG93WCwgc3R5bGUub3ZlcmZsb3dZIF07XG5cblx0XHQvLyBTZXQgZGlzcGxheSBwcm9wZXJ0eSB0byBpbmxpbmUtYmxvY2sgZm9yIGhlaWdodC93aWR0aFxuXHRcdC8vIGFuaW1hdGlvbnMgb24gaW5saW5lIGVsZW1lbnRzIHRoYXQgYXJlIGhhdmluZyB3aWR0aC9oZWlnaHQgYW5pbWF0ZWRcblx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblxuXHRcdC8vIFRlc3QgZGVmYXVsdCBkaXNwbGF5IGlmIGRpc3BsYXkgaXMgY3VycmVudGx5IFwibm9uZVwiXG5cdFx0Y2hlY2tEaXNwbGF5ID0gZGlzcGxheSA9PT0gXCJub25lXCIgP1xuXHRcdFx0ZGF0YV9wcml2LmdldCggZWxlbSwgXCJvbGRkaXNwbGF5XCIgKSB8fCBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheTtcblxuXHRcdGlmICggY2hlY2tEaXNwbGF5ID09PSBcImlubGluZVwiICYmIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcblx0XHRcdHN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0YW5pbS5hbHdheXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRzdHlsZS5vdmVyZmxvdyA9IG9wdHMub3ZlcmZsb3dbIDAgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WCA9IG9wdHMub3ZlcmZsb3dbIDEgXTtcblx0XHRcdHN0eWxlLm92ZXJmbG93WSA9IG9wdHMub3ZlcmZsb3dbIDIgXTtcblx0XHR9KTtcblx0fVxuXG5cdC8vIHNob3cvaGlkZSBwYXNzXG5cdGZvciAoIHByb3AgaW4gcHJvcHMgKSB7XG5cdFx0dmFsdWUgPSBwcm9wc1sgcHJvcCBdO1xuXHRcdGlmICggcmZ4dHlwZXMuZXhlYyggdmFsdWUgKSApIHtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgcHJvcCBdO1xuXHRcdFx0dG9nZ2xlID0gdG9nZ2xlIHx8IHZhbHVlID09PSBcInRvZ2dsZVwiO1xuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyBcImhpZGVcIiA6IFwic2hvd1wiICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgZGF0YVNob3cgbGVmdCBvdmVyIGZyb20gYSBzdG9wcGVkIGhpZGUgb3Igc2hvdyBhbmQgd2UgYXJlIGdvaW5nIHRvIHByb2NlZWQgd2l0aCBzaG93LCB3ZSBzaG91bGQgcHJldGVuZCB0byBiZSBoaWRkZW5cblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJzaG93XCIgJiYgZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IHRydWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdG9yaWdbIHByb3AgXSA9IGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gfHwgalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wICk7XG5cblx0XHQvLyBBbnkgbm9uLWZ4IHZhbHVlIHN0b3BzIHVzIGZyb20gcmVzdG9yaW5nIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlXG5cdFx0fSBlbHNlIHtcblx0XHRcdGRpc3BsYXkgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHtcblx0XHRpZiAoIGRhdGFTaG93ICkge1xuXHRcdFx0aWYgKCBcImhpZGRlblwiIGluIGRhdGFTaG93ICkge1xuXHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGRhdGFTaG93ID0gZGF0YV9wcml2LmFjY2VzcyggZWxlbSwgXCJmeHNob3dcIiwge30gKTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSBzdGF0ZSBpZiBpdHMgdG9nZ2xlIC0gZW5hYmxlcyAuc3RvcCgpLnRvZ2dsZSgpIHRvIFwicmV2ZXJzZVwiXG5cdFx0aWYgKCB0b2dnbGUgKSB7XG5cdFx0XHRkYXRhU2hvdy5oaWRkZW4gPSAhaGlkZGVuO1xuXHRcdH1cblx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdGpRdWVyeSggZWxlbSApLnNob3coKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YW5pbS5kb25lKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkoIGVsZW0gKS5oaWRlKCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0YW5pbS5kb25lKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHByb3A7XG5cblx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIFwiZnhzaG93XCIgKTtcblx0XHRcdGZvciAoIHByb3AgaW4gb3JpZyApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHR0d2VlbiA9IGNyZWF0ZVR3ZWVuKCBoaWRkZW4gPyBkYXRhU2hvd1sgcHJvcCBdIDogMCwgcHJvcCwgYW5pbSApO1xuXG5cdFx0XHRpZiAoICEoIHByb3AgaW4gZGF0YVNob3cgKSApIHtcblx0XHRcdFx0ZGF0YVNob3dbIHByb3AgXSA9IHR3ZWVuLnN0YXJ0O1xuXHRcdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0XHR0d2Vlbi5lbmQgPSB0d2Vlbi5zdGFydDtcblx0XHRcdFx0XHR0d2Vlbi5zdGFydCA9IHByb3AgPT09IFwid2lkdGhcIiB8fCBwcm9wID09PSBcImhlaWdodFwiID8gMSA6IDA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0Ly8gSWYgdGhpcyBpcyBhIG5vb3AgbGlrZSAuaGlkZSgpLmhpZGUoKSwgcmVzdG9yZSBhbiBvdmVyd3JpdHRlbiBkaXNwbGF5IHZhbHVlXG5cdH0gZWxzZSBpZiAoIChkaXNwbGF5ID09PSBcIm5vbmVcIiA/IGRlZmF1bHREaXNwbGF5KCBlbGVtLm5vZGVOYW1lICkgOiBkaXNwbGF5KSA9PT0gXCJpbmxpbmVcIiApIHtcblx0XHRzdHlsZS5kaXNwbGF5ID0gZGlzcGxheTtcblx0fVxufVxuXG5mdW5jdGlvbiBwcm9wRmlsdGVyKCBwcm9wcywgc3BlY2lhbEVhc2luZyApIHtcblx0dmFyIGluZGV4LCBuYW1lLCBlYXNpbmcsIHZhbHVlLCBob29rcztcblxuXHQvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3Ncblx0Zm9yICggaW5kZXggaW4gcHJvcHMgKSB7XG5cdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIGluZGV4ICk7XG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xuXHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF07XG5cdFx0aWYgKCBqUXVlcnkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdGVhc2luZyA9IHZhbHVlWyAxIF07XG5cdFx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdID0gdmFsdWVbIDAgXTtcblx0XHR9XG5cblx0XHRpZiAoIGluZGV4ICE9PSBuYW1lICkge1xuXHRcdFx0cHJvcHNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBpbmRleCBdO1xuXHRcdH1cblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF07XG5cdFx0aWYgKCBob29rcyAmJiBcImV4cGFuZFwiIGluIGhvb2tzICkge1xuXHRcdFx0dmFsdWUgPSBob29rcy5leHBhbmQoIHZhbHVlICk7XG5cdFx0XHRkZWxldGUgcHJvcHNbIG5hbWUgXTtcblxuXHRcdFx0Ly8gTm90IHF1aXRlICQuZXh0ZW5kLCB0aGlzIHdvbid0IG92ZXJ3cml0ZSBleGlzdGluZyBrZXlzLlxuXHRcdFx0Ly8gUmV1c2luZyAnaW5kZXgnIGJlY2F1c2Ugd2UgaGF2ZSB0aGUgY29ycmVjdCBcIm5hbWVcIlxuXHRcdFx0Zm9yICggaW5kZXggaW4gdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggISggaW5kZXggaW4gcHJvcHMgKSApIHtcblx0XHRcdFx0XHRwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyBpbmRleCBdO1xuXHRcdFx0XHRcdHNwZWNpYWxFYXNpbmdbIGluZGV4IF0gPSBlYXNpbmc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0c3BlY2lhbEVhc2luZ1sgbmFtZSBdID0gZWFzaW5nO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBBbmltYXRpb24oIGVsZW0sIHByb3BlcnRpZXMsIG9wdGlvbnMgKSB7XG5cdHZhciByZXN1bHQsXG5cdFx0c3RvcHBlZCxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gYW5pbWF0aW9uUHJlZmlsdGVycy5sZW5ndGgsXG5cdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gRG9uJ3QgbWF0Y2ggZWxlbSBpbiB0aGUgOmFuaW1hdGVkIHNlbGVjdG9yXG5cdFx0XHRkZWxldGUgdGljay5lbGVtO1xuXHRcdH0pLFxuXHRcdHRpY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGN1cnJlbnRUaW1lID0gZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuXHRcdFx0XHQvLyBBcmNoYWljIGNyYXNoIGJ1ZyB3b24ndCBhbGxvdyB1cyB0byB1c2UgYDEgLSAoIDAuNSB8fCAwIClgICgjMTI0OTcpXG5cdFx0XHRcdHRlbXAgPSByZW1haW5pbmcgLyBhbmltYXRpb24uZHVyYXRpb24gfHwgMCxcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxuXHRcdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRcdGxlbmd0aCA9IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoIDsgaW5kZXgrKyApIHtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIHBlcmNlbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIHBlcmNlbnQsIHJlbWFpbmluZyBdKTtcblxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XG5cdFx0XHRcdHJldHVybiByZW1haW5pbmc7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRhbmltYXRpb24gPSBkZWZlcnJlZC5wcm9taXNlKHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRwcm9wczogalF1ZXJ5LmV4dGVuZCgge30sIHByb3BlcnRpZXMgKSxcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHsgc3BlY2lhbEVhc2luZzoge30gfSwgb3B0aW9ucyApLFxuXHRcdFx0b3JpZ2luYWxQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuXHRcdFx0b3JpZ2luYWxPcHRpb25zOiBvcHRpb25zLFxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0ZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sXG5cdFx0XHR0d2VlbnM6IFtdLFxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XG5cdFx0XHRcdHZhciB0d2VlbiA9IGpRdWVyeS5Ud2VlbiggZWxlbSwgYW5pbWF0aW9uLm9wdHMsIHByb3AsIGVuZCxcblx0XHRcdFx0XHRcdGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmdbIHByb3AgXSB8fCBhbmltYXRpb24ub3B0cy5lYXNpbmcgKTtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xuXHRcdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0XHR9LFxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IDAsXG5cdFx0XHRcdFx0Ly8gSWYgd2UgYXJlIGdvaW5nIHRvIHRoZSBlbmQsIHdlIHdhbnQgdG8gcnVuIGFsbCB0aGUgdHdlZW5zXG5cdFx0XHRcdFx0Ly8gb3RoZXJ3aXNlIHdlIHNraXAgdGhpcyBwYXJ0XG5cdFx0XHRcdFx0bGVuZ3RoID0gZ290b0VuZCA/IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoIDogMDtcblx0XHRcdFx0aWYgKCBzdG9wcGVkICkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHN0b3BwZWQgPSB0cnVlO1xuXHRcdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoIDsgaW5kZXgrKyApIHtcblx0XHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggMSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVzb2x2ZSB3aGVuIHdlIHBsYXllZCB0aGUgbGFzdCBmcmFtZTsgb3RoZXJ3aXNlLCByZWplY3Rcblx0XHRcdFx0aWYgKCBnb3RvRW5kICkge1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fVxuXHRcdH0pLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0cmVzdWx0ID0gYW5pbWF0aW9uUHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGFuaW1hdGlvbi5vcHRzLnN0YXJ0ICkgKSB7XG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XG5cdH1cblxuXHRqUXVlcnkuZngudGltZXIoXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGljaywge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcblx0XHRcdHF1ZXVlOiBhbmltYXRpb24ub3B0cy5xdWV1ZVxuXHRcdH0pXG5cdCk7XG5cblx0Ly8gYXR0YWNoIGNhbGxiYWNrcyBmcm9tIG9wdGlvbnNcblx0cmV0dXJuIGFuaW1hdGlvbi5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xufVxuXG5qUXVlcnkuQW5pbWF0aW9uID0galF1ZXJ5LmV4dGVuZCggQW5pbWF0aW9uLCB7XG5cblx0dHdlZW5lcjogZnVuY3Rpb24oIHByb3BzLCBjYWxsYmFjayApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLnNwbGl0KFwiIFwiKTtcblx0XHR9XG5cblx0XHR2YXIgcHJvcCxcblx0XHRcdGluZGV4ID0gMCxcblx0XHRcdGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0dHdlZW5lcnNbIHByb3AgXSA9IHR3ZWVuZXJzWyBwcm9wIF0gfHwgW107XG5cdFx0XHR0d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdGFuaW1hdGlvblByZWZpbHRlcnMudW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YW5pbWF0aW9uUHJlZmlsdGVycy5wdXNoKCBjYWxsYmFjayApO1xuXHRcdH1cblx0fVxufSk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRqUXVlcnkuaXNGdW5jdGlvbiggc3BlZWQgKSAmJiBzcGVlZCxcblx0XHRkdXJhdGlvbjogc3BlZWQsXG5cdFx0ZWFzaW5nOiBmbiAmJiBlYXNpbmcgfHwgZWFzaW5nICYmICFqUXVlcnkuaXNGdW5jdGlvbiggZWFzaW5nICkgJiYgZWFzaW5nXG5cdH07XG5cblx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4Lm9mZiA/IDAgOiB0eXBlb2Ygb3B0LmR1cmF0aW9uID09PSBcIm51bWJlclwiID8gb3B0LmR1cmF0aW9uIDpcblx0XHRvcHQuZHVyYXRpb24gaW4galF1ZXJ5LmZ4LnNwZWVkcyA/IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdIDogalF1ZXJ5LmZ4LnNwZWVkcy5fZGVmYXVsdDtcblxuXHQvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcblx0aWYgKCBvcHQucXVldWUgPT0gbnVsbCB8fCBvcHQucXVldWUgPT09IHRydWUgKSB7XG5cdFx0b3B0LnF1ZXVlID0gXCJmeFwiO1xuXHR9XG5cblx0Ly8gUXVldWVpbmdcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcblxuXHRvcHQuY29tcGxldGUgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHQub2xkICkgKSB7XG5cdFx0XHRvcHQub2xkLmNhbGwoIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdC5xdWV1ZSApIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCBvcHQucXVldWUgKTtcblx0XHR9XG5cdH07XG5cblx0cmV0dXJuIG9wdDtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRmYWRlVG86IGZ1bmN0aW9uKCBzcGVlZCwgdG8sIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cblx0XHQvLyBTaG93IGFueSBoaWRkZW4gZWxlbWVudHMgYWZ0ZXIgc2V0dGluZyBvcGFjaXR5IHRvIDBcblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKHsgb3BhY2l0eTogdG8gfSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fSxcblx0YW5pbWF0ZTogZnVuY3Rpb24oIHByb3AsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHZhciBlbXB0eSA9IGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBwcm9wICksXG5cdFx0XHRvcHRhbGwgPSBqUXVlcnkuc3BlZWQoIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICksXG5cdFx0XHRkb0FuaW1hdGlvbiA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YV9wcml2LmdldCggdGhpcywgXCJmaW5pc2hcIiApICkge1xuXHRcdFx0XHRcdGFuaW0uc3RvcCggdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdFx0ZG9BbmltYXRpb24uZmluaXNoID0gZG9BbmltYXRpb247XG5cblx0XHRyZXR1cm4gZW1wdHkgfHwgb3B0YWxsLnF1ZXVlID09PSBmYWxzZSA/XG5cdFx0XHR0aGlzLmVhY2goIGRvQW5pbWF0aW9uICkgOlxuXHRcdFx0dGhpcy5xdWV1ZSggb3B0YWxsLnF1ZXVlLCBkb0FuaW1hdGlvbiApO1xuXHR9LFxuXHRzdG9wOiBmdW5jdGlvbiggdHlwZSwgY2xlYXJRdWV1ZSwgZ290b0VuZCApIHtcblx0XHR2YXIgc3RvcFF1ZXVlID0gZnVuY3Rpb24oIGhvb2tzICkge1xuXHRcdFx0dmFyIHN0b3AgPSBob29rcy5zdG9wO1xuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRzdG9wKCBnb3RvRW5kICk7XG5cdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRnb3RvRW5kID0gY2xlYXJRdWV1ZTtcblx0XHRcdGNsZWFyUXVldWUgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0aWYgKCBjbGVhclF1ZXVlICYmIHR5cGUgIT09IGZhbHNlICkge1xuXHRcdFx0dGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YV9wcml2LmdldCggdGhpcyApO1xuXG5cdFx0XHRpZiAoIGluZGV4ICkge1xuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xuXHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpbmRleCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgJiYgcnJ1bi50ZXN0KCBpbmRleCApICkge1xuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgKHR5cGUgPT0gbnVsbCB8fCB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUpICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcblx0XHRcdFx0XHRkZXF1ZXVlID0gZmFsc2U7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkLlxuXHRcdFx0Ly8gVGltZXJzIGN1cnJlbnRseSB3aWxsIGNhbGwgdGhlaXIgY29tcGxldGUgY2FsbGJhY2tzLCB3aGljaFxuXHRcdFx0Ly8gd2lsbCBkZXF1ZXVlIGJ1dCBvbmx5IGlmIHRoZXkgd2VyZSBnb3RvRW5kLlxuXHRcdFx0aWYgKCBkZXF1ZXVlIHx8ICFnb3RvRW5kICkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXHRmaW5pc2g6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdGlmICggdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaW5kZXgsXG5cdFx0XHRcdGRhdGEgPSBkYXRhX3ByaXYuZ2V0KCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRW1wdHkgdGhlIHF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdHZhciBjc3NGbiA9IGpRdWVyeS5mblsgbmFtZSBdO1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gc3BlZWQgPT0gbnVsbCB8fCB0eXBlb2Ygc3BlZWQgPT09IFwiYm9vbGVhblwiID9cblx0XHRcdGNzc0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSA6XG5cdFx0XHR0aGlzLmFuaW1hdGUoIGdlbkZ4KCBuYW1lLCB0cnVlICksIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH07XG59KTtcblxuLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9uc1xualF1ZXJ5LmVhY2goe1xuXHRzbGlkZURvd246IGdlbkZ4KFwic2hvd1wiKSxcblx0c2xpZGVVcDogZ2VuRngoXCJoaWRlXCIpLFxuXHRzbGlkZVRvZ2dsZTogZ2VuRngoXCJ0b2dnbGVcIiksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSk7XG5cbmpRdWVyeS50aW1lcnMgPSBbXTtcbmpRdWVyeS5meC50aWNrID0gZnVuY3Rpb24oKSB7XG5cdHZhciB0aW1lcixcblx0XHRpID0gMCxcblx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzO1xuXG5cdGZ4Tm93ID0galF1ZXJ5Lm5vdygpO1xuXG5cdGZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHtcblx0XHR0aW1lciA9IHRpbWVyc1sgaSBdO1xuXHRcdC8vIENoZWNrcyB0aGUgdGltZXIgaGFzIG5vdCBhbHJlYWR5IGJlZW4gcmVtb3ZlZFxuXHRcdGlmICggIXRpbWVyKCkgJiYgdGltZXJzWyBpIF0gPT09IHRpbWVyICkge1xuXHRcdFx0dGltZXJzLnNwbGljZSggaS0tLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhdGltZXJzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZnguc3RvcCgpO1xuXHR9XG5cdGZ4Tm93ID0gdW5kZWZpbmVkO1xufTtcblxualF1ZXJ5LmZ4LnRpbWVyID0gZnVuY3Rpb24oIHRpbWVyICkge1xuXHRqUXVlcnkudGltZXJzLnB1c2goIHRpbWVyICk7XG5cdGlmICggdGltZXIoKSApIHtcblx0XHRqUXVlcnkuZnguc3RhcnQoKTtcblx0fSBlbHNlIHtcblx0XHRqUXVlcnkudGltZXJzLnBvcCgpO1xuXHR9XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcblxualF1ZXJ5LmZ4LnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggIXRpbWVySWQgKSB7XG5cdFx0dGltZXJJZCA9IHNldEludGVydmFsKCBqUXVlcnkuZngudGljaywgalF1ZXJ5LmZ4LmludGVydmFsICk7XG5cdH1cbn07XG5cbmpRdWVyeS5meC5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdGNsZWFySW50ZXJ2YWwoIHRpbWVySWQgKTtcblx0dGltZXJJZCA9IG51bGw7XG59O1xuXG5qUXVlcnkuZnguc3BlZWRzID0ge1xuXHRzbG93OiA2MDAsXG5cdGZhc3Q6IDIwMCxcblx0Ly8gRGVmYXVsdCBzcGVlZFxuXHRfZGVmYXVsdDogNDAwXG59O1xuXG5cbi8vIEJhc2VkIG9mZiBvZiB0aGUgcGx1Z2luIGJ5IENsaW50IEhlbGZlcnMsIHdpdGggcGVybWlzc2lvbi5cbi8vIGh0dHA6Ly9ibGluZHNpZ25hbHMuY29tL2luZGV4LnBocC8yMDA5LzA3L2pxdWVyeS1kZWxheS9cbmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkge1xuXHR0aW1lID0galF1ZXJ5LmZ4ID8galF1ZXJ5LmZ4LnNwZWVkc1sgdGltZSBdIHx8IHRpbWUgOiB0aW1lO1xuXHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUsIGZ1bmN0aW9uKCBuZXh0LCBob29rcyApIHtcblx0XHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVvdXQgKTtcblx0XHR9O1xuXHR9KTtcbn07XG5cblxuKGZ1bmN0aW9uKCkge1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNlbGVjdFwiICksXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcblxuXHRpbnB1dC50eXBlID0gXCJjaGVja2JveFwiO1xuXG5cdC8vIFN1cHBvcnQ6IGlPUzw9NS4xLCBBbmRyb2lkPD00LjIrXG5cdC8vIERlZmF1bHQgdmFsdWUgZm9yIGEgY2hlY2tib3ggc2hvdWxkIGJlIFwib25cIlxuXHRzdXBwb3J0LmNoZWNrT24gPSBpbnB1dC52YWx1ZSAhPT0gXCJcIjtcblxuXHQvLyBTdXBwb3J0OiBJRTw9MTErXG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw9Mi4zXG5cdC8vIE9wdGlvbnMgaW5zaWRlIGRpc2FibGVkIHNlbGVjdHMgYXJlIGluY29ycmVjdGx5IG1hcmtlZCBhcyBkaXNhYmxlZFxuXHRzZWxlY3QuZGlzYWJsZWQgPSB0cnVlO1xuXHRzdXBwb3J0Lm9wdERpc2FibGVkID0gIW9wdC5kaXNhYmxlZDtcblxuXHQvLyBTdXBwb3J0OiBJRTw9MTErXG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0pKCk7XG5cblxudmFyIG5vZGVIb29rLCBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRhdHRyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggdGhpcywgbmFtZSApO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdGF0dHI6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIGRvbid0IGdldC9zZXQgYXR0cmlidXRlcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIHRvIHByb3Agd2hlbiBhdHRyaWJ1dGVzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgPT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgYXR0cmlidXRlcyBhcmUgbG93ZXJjYXNlXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdIHx8XG5cdFx0XHRcdCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgPyBib29sSG9vayA6IG5vZGVIb29rICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkpICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdC8vIE5vbi1leGlzdGVudCBhdHRyaWJ1dGVzIHJldHVybiBudWxsLCB3ZSBub3JtYWxpemUgdG8gdW5kZWZpbmVkXG5cdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgP1xuXHRcdFx0XHR1bmRlZmluZWQgOlxuXHRcdFx0XHRyZXQ7XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSwgcHJvcE5hbWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKTtcblxuXHRcdGlmICggYXR0ck5hbWVzICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHR3aGlsZSAoIChuYW1lID0gYXR0ck5hbWVzW2krK10pICkge1xuXHRcdFx0XHRwcm9wTmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblxuXHRcdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgZ2V0IHNwZWNpYWwgdHJlYXRtZW50ICgjMTA4NzApXG5cdFx0XHRcdGlmICggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHRcdFx0Ly8gU2V0IGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdG8gZmFsc2Vcblx0XHRcdFx0XHRlbGVtWyBwcm9wTmFtZSBdID0gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggbmFtZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHRcdHZhciB2YWwgPSBlbGVtLnZhbHVlO1xuXHRcdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgdmFsdWUgKTtcblx0XHRcdFx0XHRpZiAoIHZhbCApIHtcblx0XHRcdFx0XHRcdGVsZW0udmFsdWUgPSB2YWw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufSk7XG5cbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdC8vIFJlbW92ZSBib29sZWFuIGF0dHJpYnV0ZXMgd2hlbiBzZXQgdG8gZmFsc2Vcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lICk7XG5cdFx0fVxuXHRcdHJldHVybiBuYW1lO1xuXHR9XG59O1xualF1ZXJ5LmVhY2goIGpRdWVyeS5leHByLm1hdGNoLmJvb2wuc291cmNlLm1hdGNoKCAvXFx3Ky9nICksIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXHR2YXIgZ2V0dGVyID0gYXR0ckhhbmRsZVsgbmFtZSBdIHx8IGpRdWVyeS5maW5kLmF0dHI7XG5cblx0YXR0ckhhbmRsZVsgbmFtZSBdID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdHZhciByZXQsIGhhbmRsZTtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdC8vIEF2b2lkIGFuIGluZmluaXRlIGxvb3AgYnkgdGVtcG9yYXJpbHkgcmVtb3ZpbmcgdGhpcyBmdW5jdGlvbiBmcm9tIHRoZSBnZXR0ZXJcblx0XHRcdGhhbmRsZSA9IGF0dHJIYW5kbGVbIG5hbWUgXTtcblx0XHRcdGF0dHJIYW5kbGVbIG5hbWUgXSA9IHJldDtcblx0XHRcdHJldCA9IGdldHRlciggZWxlbSwgbmFtZSwgaXNYTUwgKSAhPSBudWxsID9cblx0XHRcdFx0bmFtZS50b0xvd2VyQ2FzZSgpIDpcblx0XHRcdFx0bnVsbDtcblx0XHRcdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGhhbmRsZTtcblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fTtcbn0pO1xuXG5cblxuXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2k7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LnByb3AsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZVByb3A6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRkZWxldGUgdGhpc1sgalF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lIF07XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0cHJvcEZpeDoge1xuXHRcdFwiZm9yXCI6IFwiaHRtbEZvclwiLFxuXHRcdFwiY2xhc3NcIjogXCJjbGFzc05hbWVcIlxuXHR9LFxuXG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgcmV0LCBob29rcywgbm90eG1sLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBwcm9wZXJ0aWVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bm90eG1sID0gblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApO1xuXG5cdFx0aWYgKCBub3R4bWwgKSB7XG5cdFx0XHQvLyBGaXggbmFtZSBhbmQgYXR0YWNoIGhvb2tzXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkucHJvcEhvb2tzWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSkgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHJldCA6XG5cdFx0XHRcdCggZWxlbVsgbmFtZSBdID0gdmFsdWUgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkpICE9PSBudWxsID9cblx0XHRcdFx0cmV0IDpcblx0XHRcdFx0ZWxlbVsgbmFtZSBdO1xuXHRcdH1cblx0fSxcblxuXHRwcm9wSG9va3M6IHtcblx0XHR0YWJJbmRleDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaGFzQXR0cmlidXRlKCBcInRhYmluZGV4XCIgKSB8fCByZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fCBlbGVtLmhyZWYgP1xuXHRcdFx0XHRcdGVsZW0udGFiSW5kZXggOlxuXHRcdFx0XHRcdC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSk7XG5cbmlmICggIXN1cHBvcnQub3B0U2VsZWN0ZWQgKSB7XG5cdGpRdWVyeS5wcm9wSG9va3Muc2VsZWN0ZWQgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goW1xuXHRcInRhYkluZGV4XCIsXG5cdFwicmVhZE9ubHlcIixcblx0XCJtYXhMZW5ndGhcIixcblx0XCJjZWxsU3BhY2luZ1wiLFxuXHRcImNlbGxQYWRkaW5nXCIsXG5cdFwicm93U3BhblwiLFxuXHRcImNvbFNwYW5cIixcblx0XCJ1c2VNYXBcIixcblx0XCJmcmFtZUJvcmRlclwiLFxuXHRcImNvbnRlbnRFZGl0YWJsZVwiXG5dLCBmdW5jdGlvbigpIHtcblx0alF1ZXJ5LnByb3BGaXhbIHRoaXMudG9Mb3dlckNhc2UoKSBdID0gdGhpcztcbn0pO1xuXG5cblxuXG52YXIgcmNsYXNzID0gL1tcXHRcXHJcXG5cXGZdL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGNsYXp6LCBqLCBmaW5hbFZhbHVlLFxuXHRcdFx0cHJvY2VlZCA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGg7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuYWRkQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIHRoaXMuY2xhc3NOYW1lICkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICggcHJvY2VlZCApIHtcblx0XHRcdC8vIFRoZSBkaXNqdW5jdGlvbiBoZXJlIGlzIGZvciBiZXR0ZXIgY29tcHJlc3NpYmlsaXR5IChzZWUgcmVtb3ZlQ2xhc3MpXG5cdFx0XHRjbGFzc2VzID0gKCB2YWx1ZSB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXTtcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIGVsZW0uY2xhc3NOYW1lID9cblx0XHRcdFx0XHQoIFwiIFwiICsgZWxlbS5jbGFzc05hbWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKSA6XG5cdFx0XHRcdFx0XCIgXCJcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChjbGF6eiA9IGNsYXNzZXNbaisrXSkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIG9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IGpRdWVyeS50cmltKCBjdXIgKTtcblx0XHRcdFx0XHRpZiAoIGVsZW0uY2xhc3NOYW1lICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5jbGFzc05hbWUgPSBmaW5hbFZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRwcm9jZWVkID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGogKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlbW92ZUNsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCB0aGlzLmNsYXNzTmFtZSApICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKCBwcm9jZWVkICkge1xuXHRcdFx0Y2xhc3NlcyA9ICggdmFsdWUgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGVsZW0gPSB0aGlzWyBpIF07XG5cdFx0XHRcdC8vIFRoaXMgZXhwcmVzc2lvbiBpcyBoZXJlIGZvciBiZXR0ZXIgY29tcHJlc3NpYmlsaXR5IChzZWUgYWRkQ2xhc3MpXG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBlbGVtLmNsYXNzTmFtZSA/XG5cdFx0XHRcdFx0KCBcIiBcIiArIGVsZW0uY2xhc3NOYW1lICsgXCIgXCIgKS5yZXBsYWNlKCByY2xhc3MsIFwiIFwiICkgOlxuXHRcdFx0XHRcdFwiXCJcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChjbGF6eiA9IGNsYXNzZXNbaisrXSkgKSB7XG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+PSAwICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHZhbHVlID8galF1ZXJ5LnRyaW0oIGN1ciApIDogXCJcIjtcblx0XHRcdFx0XHRpZiAoIGVsZW0uY2xhc3NOYW1lICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5jbGFzc05hbWUgPSBmaW5hbFZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xuXHRcdHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGVWYWwgPT09IFwiYm9vbGVhblwiICYmIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGVWYWwgPyB0aGlzLmFkZENsYXNzKCB2YWx1ZSApIDogdGhpcy5yZW1vdmVDbGFzcyggdmFsdWUgKTtcblx0XHR9XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkudG9nZ2xlQ2xhc3MoIHZhbHVlLmNhbGwodGhpcywgaSwgdGhpcy5jbGFzc05hbWUsIHN0YXRlVmFsKSwgc3RhdGVWYWwgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdC8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdHZhciBjbGFzc05hbWUsXG5cdFx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdFx0c2VsZiA9IGpRdWVyeSggdGhpcyApLFxuXHRcdFx0XHRcdGNsYXNzTmFtZXMgPSB2YWx1ZS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRcdFx0d2hpbGUgKCAoY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0pICkge1xuXHRcdFx0XHRcdC8vIENoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB0eXBlID09PSBzdHJ1bmRlZmluZWQgfHwgdHlwZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRcdGlmICggdGhpcy5jbGFzc05hbWUgKSB7XG5cdFx0XHRcdFx0Ly8gc3RvcmUgY2xhc3NOYW1lIGlmIHNldFxuXHRcdFx0XHRcdGRhdGFfcHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCB0aGlzLmNsYXNzTmFtZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgYGZhbHNlYCxcblx0XHRcdFx0Ly8gdGhlbiByZW1vdmUgdGhlIHdob2xlIGNsYXNzbmFtZSAoaWYgdGhlcmUgd2FzIG9uZSwgdGhlIGFib3ZlIHNhdmVkIGl0KS5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGJyaW5nIGJhY2sgd2hhdGV2ZXIgd2FzIHByZXZpb3VzbHkgc2F2ZWQgKGlmIGFueXRoaW5nKSxcblx0XHRcdFx0Ly8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLlxuXHRcdFx0XHR0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/IFwiXCIgOiBkYXRhX3ByaXYuZ2V0KCB0aGlzLCBcIl9fY2xhc3NOYW1lX19cIiApIHx8IFwiXCI7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0aGFzQ2xhc3M6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgY2xhc3NOYW1lID0gXCIgXCIgKyBzZWxlY3RvciArIFwiIFwiLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGg7XG5cdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0aWYgKCB0aGlzW2ldLm5vZGVUeXBlID09PSAxICYmIChcIiBcIiArIHRoaXNbaV0uY2xhc3NOYW1lICsgXCIgXCIpLnJlcGxhY2UocmNsYXNzLCBcIiBcIikuaW5kZXhPZiggY2xhc3NOYW1lICkgPj0gMCApIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59KTtcblxuXG5cblxudmFyIHJyZXR1cm4gPSAvXFxyL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR2YWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCwgaXNGdW5jdGlvbixcblx0XHRcdGVsZW0gPSB0aGlzWzBdO1xuXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdGlmICggZWxlbSApIHtcblx0XHRcdFx0aG9va3MgPSBqUXVlcnkudmFsSG9va3NbIGVsZW0udHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXQgPSBlbGVtLnZhbHVlO1xuXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgcmV0ID09PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXG5cdFx0XHRcdFx0cmV0LnJlcGxhY2UocnJldHVybiwgXCJcIikgOlxuXHRcdFx0XHRcdC8vIEhhbmRsZSBjYXNlcyB3aGVyZSB2YWx1ZSBpcyBudWxsL3VuZGVmIG9yIG51bWJlclxuXHRcdFx0XHRcdHJldCA9PSBudWxsID8gXCJcIiA6IHJldDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlzRnVuY3Rpb24gPSBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHR2YXIgdmFsO1xuXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uICkge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzIFwiXCI7IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBqUXVlcnkuaXNBcnJheSggdmFsICkgKSB7XG5cdFx0XHRcdHZhbCA9IGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0XHRcdHJldHVybiB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICsgXCJcIjtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyB0aGlzLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIHRoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHQvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZ1xuXHRcdFx0aWYgKCAhaG9va3MgfHwgIShcInNldFwiIGluIGhvb2tzKSB8fCBob29rcy5zZXQoIHRoaXMsIHZhbCwgXCJ2YWx1ZVwiICkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0dGhpcy52YWx1ZSA9IHZhbDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5leHRlbmQoe1xuXHR2YWxIb29rczoge1xuXHRcdG9wdGlvbjoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidmFsdWVcIiApO1xuXHRcdFx0XHRyZXR1cm4gdmFsICE9IG51bGwgP1xuXHRcdFx0XHRcdHZhbCA6XG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMC0xMStcblx0XHRcdFx0XHQvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpXG5cdFx0XHRcdFx0alF1ZXJ5LnRyaW0oIGpRdWVyeS50ZXh0KCBlbGVtICkgKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHRpbmRleCA9IGVsZW0uc2VsZWN0ZWRJbmRleCxcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiIHx8IGluZGV4IDwgMCxcblx0XHRcdFx0XHR2YWx1ZXMgPSBvbmUgPyBudWxsIDogW10sXG5cdFx0XHRcdFx0bWF4ID0gb25lID8gaW5kZXggKyAxIDogb3B0aW9ucy5sZW5ndGgsXG5cdFx0XHRcdFx0aSA9IGluZGV4IDwgMCA/XG5cdFx0XHRcdFx0XHRtYXggOlxuXHRcdFx0XHRcdFx0b25lID8gaW5kZXggOiAwO1xuXG5cdFx0XHRcdC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnNcblx0XHRcdFx0Zm9yICggOyBpIDwgbWF4OyBpKysgKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0Ly8gSUU2LTkgZG9lc24ndCB1cGRhdGUgc2VsZWN0ZWQgYWZ0ZXIgZm9ybSByZXNldCAoIzI1NTEpXG5cdFx0XHRcdFx0aWYgKCAoIG9wdGlvbi5zZWxlY3RlZCB8fCBpID09PSBpbmRleCApICYmXG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHJldHVybiBvcHRpb25zIHRoYXQgYXJlIGRpc2FibGVkIG9yIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcblx0XHRcdFx0XHRcdFx0KCBzdXBwb3J0Lm9wdERpc2FibGVkID8gIW9wdGlvbi5kaXNhYmxlZCA6IG9wdGlvbi5nZXRBdHRyaWJ1dGUoIFwiZGlzYWJsZWRcIiApID09PSBudWxsICkgJiZcblx0XHRcdFx0XHRcdFx0KCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHwgIWpRdWVyeS5ub2RlTmFtZSggb3B0aW9uLnBhcmVudE5vZGUsIFwib3B0Z3JvdXBcIiApICkgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEdldCB0aGUgc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBvcHRpb25cblx0XHRcdFx0XHRcdHZhbHVlID0galF1ZXJ5KCBvcHRpb24gKS52YWwoKTtcblxuXHRcdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgbmVlZCBhbiBhcnJheSBmb3Igb25lIHNlbGVjdHNcblx0XHRcdFx0XHRcdGlmICggb25lICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIE11bHRpLVNlbGVjdHMgcmV0dXJuIGFuIGFycmF5XG5cdFx0XHRcdFx0XHR2YWx1ZXMucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fSxcblxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRcdHZhciBvcHRpb25TZXQsIG9wdGlvbixcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdHZhbHVlcyA9IGpRdWVyeS5tYWtlQXJyYXkoIHZhbHVlICksXG5cdFx0XHRcdFx0aSA9IG9wdGlvbnMubGVuZ3RoO1xuXG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblx0XHRcdFx0XHRpZiAoIChvcHRpb24uc2VsZWN0ZWQgPSBqUXVlcnkuaW5BcnJheSggb3B0aW9uLnZhbHVlLCB2YWx1ZXMgKSA+PSAwKSApIHtcblx0XHRcdFx0XHRcdG9wdGlvblNldCA9IHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gRm9yY2UgYnJvd3NlcnMgdG8gYmVoYXZlIGNvbnNpc3RlbnRseSB3aGVuIG5vbi1tYXRjaGluZyB2YWx1ZSBpcyBzZXRcblx0XHRcdFx0aWYgKCAhb3B0aW9uU2V0ICkge1xuXHRcdFx0XHRcdGVsZW0uc2VsZWN0ZWRJbmRleCA9IC0xO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gUmFkaW9zIGFuZCBjaGVja2JveGVzIGdldHRlci9zZXR0ZXJcbmpRdWVyeS5lYWNoKFsgXCJyYWRpb1wiLCBcImNoZWNrYm94XCIgXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdID0ge1xuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0aWYgKCBqUXVlcnkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeShlbGVtKS52YWwoKSwgdmFsdWUgKSA+PSAwICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXHRpZiAoICFzdXBwb3J0LmNoZWNrT24gKSB7XG5cdFx0alF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0uZ2V0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSA9PT0gbnVsbCA/IFwib25cIiA6IGVsZW0udmFsdWU7XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbi8vIFJldHVybiBqUXVlcnkgZm9yIGF0dHJpYnV0ZXMtb25seSBpbmNsdXNpb25cblxuXG5qUXVlcnkuZWFjaCggKFwiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IGxvYWQgcmVzaXplIHNjcm9sbCB1bmxvYWQgY2xpY2sgZGJsY2xpY2sgXCIgK1xuXHRcIm1vdXNlZG93biBtb3VzZXVwIG1vdXNlbW92ZSBtb3VzZW92ZXIgbW91c2VvdXQgbW91c2VlbnRlciBtb3VzZWxlYXZlIFwiICtcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGVycm9yIGNvbnRleHRtZW51XCIpLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cblx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID9cblx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxuXHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdH07XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpcy5tb3VzZWVudGVyKCBmbk92ZXIgKS5tb3VzZWxlYXZlKCBmbk91dCB8fCBmbk92ZXIgKTtcblx0fSxcblxuXHRiaW5kOiBmdW5jdGlvbiggdHlwZXMsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgbnVsbCwgZGF0YSwgZm4gKTtcblx0fSxcblx0dW5iaW5kOiBmdW5jdGlvbiggdHlwZXMsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9mZiggdHlwZXMsIG51bGwsIGZuICk7XG5cdH0sXG5cblx0ZGVsZWdhdGU6IGZ1bmN0aW9uKCBzZWxlY3RvciwgdHlwZXMsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuZGVsZWdhdGU6IGZ1bmN0aW9uKCBzZWxlY3RvciwgdHlwZXMsIGZuICkge1xuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IHRoaXMub2ZmKCBzZWxlY3RvciwgXCIqKlwiICkgOiB0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcblx0fVxufSk7XG5cblxudmFyIG5vbmNlID0galF1ZXJ5Lm5vdygpO1xuXG52YXIgcnF1ZXJ5ID0gKC9cXD8vKTtcblxuXG5cbi8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXG4vLyBXb3JrYXJvdW5kIGZhaWx1cmUgdG8gc3RyaW5nLWNhc3QgbnVsbCBpbnB1dFxualF1ZXJ5LnBhcnNlSlNPTiA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHRyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSArIFwiXCIgKTtcbn07XG5cblxuLy8gQ3Jvc3MtYnJvd3NlciB4bWwgcGFyc2luZ1xualF1ZXJ5LnBhcnNlWE1MID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdHZhciB4bWwsIHRtcDtcblx0aWYgKCAhZGF0YSB8fCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gbnVsbDtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IElFOVxuXHR0cnkge1xuXHRcdHRtcCA9IG5ldyBET01QYXJzZXIoKTtcblx0XHR4bWwgPSB0bXAucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcblx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0eG1sID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0aWYgKCAheG1sIHx8IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJwYXJzZXJlcnJvclwiICkubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XG5cdH1cblx0cmV0dXJuIHhtbDtcbn07XG5cblxudmFyXG5cdHJoYXNoID0gLyMuKiQvLFxuXHRydHMgPSAvKFs/Jl0pXz1bXiZdKi8sXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXG5cdHJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sXG5cdHJub0NvbnRlbnQgPSAvXig/OkdFVHxIRUFEKSQvLFxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXG5cdHJ1cmwgPSAvXihbXFx3ListXSs6KSg/OlxcL1xcLyg/OlteXFwvPyNdKkB8KShbXlxcLz8jOl0qKSg/OjooXFxkKyl8KXwpLyxcblxuXHQvKiBQcmVmaWx0ZXJzXG5cdCAqIDEpIFRoZXkgYXJlIHVzZWZ1bCB0byBpbnRyb2R1Y2UgY3VzdG9tIGRhdGFUeXBlcyAoc2VlIGFqYXgvanNvbnAuanMgZm9yIGFuIGV4YW1wbGUpXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XG5cdCAqICAgIC0gQkVGT1JFIGFza2luZyBmb3IgYSB0cmFuc3BvcnRcblx0ICogICAgLSBBRlRFUiBwYXJhbSBzZXJpYWxpemF0aW9uIChzLmRhdGEgaXMgYSBzdHJpbmcgaWYgcy5wcm9jZXNzRGF0YSBpcyB0cnVlKVxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDQpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHByZWZpbHRlcnMgPSB7fSxcblxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXG5cdCAqIDEpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogMikgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHRyYW5zcG9ydHMgPSB7fSxcblxuXHQvLyBBdm9pZCBjb21tZW50LXByb2xvZyBjaGFyIHNlcXVlbmNlICgjMTAwOTgpOyBtdXN0IGFwcGVhc2UgbGludCBhbmQgZXZhZGUgY29tcHJlc3Npb25cblx0YWxsVHlwZXMgPSBcIiovXCIuY29uY2F0KCBcIipcIiApLFxuXG5cdC8vIERvY3VtZW50IGxvY2F0aW9uXG5cdGFqYXhMb2NhdGlvbiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxuXG5cdC8vIFNlZ21lbnQgbG9jYXRpb24gaW50byBwYXJ0c1xuXHRhamF4TG9jUGFydHMgPSBydXJsLmV4ZWMoIGFqYXhMb2NhdGlvbi50b0xvd2VyQ2FzZSgpICkgfHwgW107XG5cbi8vIEJhc2UgXCJjb25zdHJ1Y3RvclwiIGZvciBqUXVlcnkuYWpheFByZWZpbHRlciBhbmQgalF1ZXJ5LmFqYXhUcmFuc3BvcnRcbmZ1bmN0aW9uIGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlICkge1xuXG5cdC8vIGRhdGFUeXBlRXhwcmVzc2lvbiBpcyBvcHRpb25hbCBhbmQgZGVmYXVsdHMgdG8gXCIqXCJcblx0cmV0dXJuIGZ1bmN0aW9uKCBkYXRhVHlwZUV4cHJlc3Npb24sIGZ1bmMgKSB7XG5cblx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZUV4cHJlc3Npb24gIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRmdW5jID0gZGF0YVR5cGVFeHByZXNzaW9uO1xuXHRcdFx0ZGF0YVR5cGVFeHByZXNzaW9uID0gXCIqXCI7XG5cdFx0fVxuXG5cdFx0dmFyIGRhdGFUeXBlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRkYXRhVHlwZXMgPSBkYXRhVHlwZUV4cHJlc3Npb24udG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBmdW5jICkgKSB7XG5cdFx0XHQvLyBGb3IgZWFjaCBkYXRhVHlwZSBpbiB0aGUgZGF0YVR5cGVFeHByZXNzaW9uXG5cdFx0XHR3aGlsZSAoIChkYXRhVHlwZSA9IGRhdGFUeXBlc1tpKytdKSApIHtcblx0XHRcdFx0Ly8gUHJlcGVuZCBpZiByZXF1ZXN0ZWRcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVswXSA9PT0gXCIrXCIgKSB7XG5cdFx0XHRcdFx0ZGF0YVR5cGUgPSBkYXRhVHlwZS5zbGljZSggMSApIHx8IFwiKlwiO1xuXHRcdFx0XHRcdChzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10pLnVuc2hpZnQoIGZ1bmMgKTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYXBwZW5kXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0KHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSkucHVzaCggZnVuYyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG4vLyBCYXNlIGluc3BlY3Rpb24gZnVuY3Rpb24gZm9yIHByZWZpbHRlcnMgYW5kIHRyYW5zcG9ydHNcbmZ1bmN0aW9uIGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUsIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKSB7XG5cblx0dmFyIGluc3BlY3RlZCA9IHt9LFxuXHRcdHNlZWtpbmdUcmFuc3BvcnQgPSAoIHN0cnVjdHVyZSA9PT0gdHJhbnNwb3J0cyApO1xuXG5cdGZ1bmN0aW9uIGluc3BlY3QoIGRhdGFUeXBlICkge1xuXHRcdHZhciBzZWxlY3RlZDtcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xuXHRcdGpRdWVyeS5lYWNoKCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10sIGZ1bmN0aW9uKCBfLCBwcmVmaWx0ZXJPckZhY3RvcnkgKSB7XG5cdFx0XHR2YXIgZGF0YVR5cGVPclRyYW5zcG9ydCA9IHByZWZpbHRlck9yRmFjdG9yeSggb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApO1xuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJiAhc2Vla2luZ1RyYW5zcG9ydCAmJiAhaW5zcGVjdGVkWyBkYXRhVHlwZU9yVHJhbnNwb3J0IF0gKSB7XG5cdFx0XHRcdG9wdGlvbnMuZGF0YVR5cGVzLnVuc2hpZnQoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0aW5zcGVjdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9IGVsc2UgaWYgKCBzZWVraW5nVHJhbnNwb3J0ICkge1xuXHRcdFx0XHRyZXR1cm4gISggc2VsZWN0ZWQgPSBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHR9XG5cblx0cmV0dXJuIGluc3BlY3QoIG9wdGlvbnMuZGF0YVR5cGVzWyAwIF0gKSB8fCAhaW5zcGVjdGVkWyBcIipcIiBdICYmIGluc3BlY3QoIFwiKlwiICk7XG59XG5cbi8vIEEgc3BlY2lhbCBleHRlbmQgZm9yIGFqYXggb3B0aW9uc1xuLy8gdGhhdCB0YWtlcyBcImZsYXRcIiBvcHRpb25zIChub3QgdG8gYmUgZGVlcCBleHRlbmRlZClcbi8vIEZpeGVzICM5ODg3XG5mdW5jdGlvbiBhamF4RXh0ZW5kKCB0YXJnZXQsIHNyYyApIHtcblx0dmFyIGtleSwgZGVlcCxcblx0XHRmbGF0T3B0aW9ucyA9IGpRdWVyeS5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnMgfHwge307XG5cblx0Zm9yICgga2V5IGluIHNyYyApIHtcblx0XHRpZiAoIHNyY1sga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdCggZmxhdE9wdGlvbnNbIGtleSBdID8gdGFyZ2V0IDogKCBkZWVwIHx8IChkZWVwID0ge30pICkgKVsga2V5IF0gPSBzcmNbIGtleSBdO1xuXHRcdH1cblx0fVxuXHRpZiAoIGRlZXAgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdHJ1ZSwgdGFyZ2V0LCBkZWVwICk7XG5cdH1cblxuXHRyZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6XG4gKiAtIGZpbmRzIHRoZSByaWdodCBkYXRhVHlwZSAobWVkaWF0ZXMgYmV0d2VlbiBjb250ZW50LXR5cGUgYW5kIGV4cGVjdGVkIGRhdGFUeXBlKVxuICogLSByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKSB7XG5cblx0dmFyIGN0LCB0eXBlLCBmaW5hbERhdGFUeXBlLCBmaXJzdERhdGFUeXBlLFxuXHRcdGNvbnRlbnRzID0gcy5jb250ZW50cyxcblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcztcblxuXHQvLyBSZW1vdmUgYXV0byBkYXRhVHlwZSBhbmQgZ2V0IGNvbnRlbnQtdHlwZSBpbiB0aGUgcHJvY2Vzc1xuXHR3aGlsZSAoIGRhdGFUeXBlc1sgMCBdID09PSBcIipcIiApIHtcblx0XHRkYXRhVHlwZXMuc2hpZnQoKTtcblx0XHRpZiAoIGN0ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRjdCA9IHMubWltZVR5cGUgfHwganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoXCJDb250ZW50LVR5cGVcIik7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgaWYgd2UncmUgZGVhbGluZyB3aXRoIGEga25vd24gY29udGVudC10eXBlXG5cdGlmICggY3QgKSB7XG5cdFx0Zm9yICggdHlwZSBpbiBjb250ZW50cyApIHtcblx0XHRcdGlmICggY29udGVudHNbIHR5cGUgXSAmJiBjb250ZW50c1sgdHlwZSBdLnRlc3QoIGN0ICkgKSB7XG5cdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0eXBlICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgcmVzcG9uc2UgZm9yIHRoZSBleHBlY3RlZCBkYXRhVHlwZVxuXHRpZiAoIGRhdGFUeXBlc1sgMCBdIGluIHJlc3BvbnNlcyApIHtcblx0XHRmaW5hbERhdGFUeXBlID0gZGF0YVR5cGVzWyAwIF07XG5cdH0gZWxzZSB7XG5cdFx0Ly8gVHJ5IGNvbnZlcnRpYmxlIGRhdGFUeXBlc1xuXHRcdGZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkge1xuXHRcdFx0aWYgKCAhZGF0YVR5cGVzWyAwIF0gfHwgcy5jb252ZXJ0ZXJzWyB0eXBlICsgXCIgXCIgKyBkYXRhVHlwZXNbMF0gXSApIHtcblx0XHRcdFx0ZmluYWxEYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCAhZmlyc3REYXRhVHlwZSApIHtcblx0XHRcdFx0Zmlyc3REYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZVxuXHRcdGZpbmFsRGF0YVR5cGUgPSBmaW5hbERhdGFUeXBlIHx8IGZpcnN0RGF0YVR5cGU7XG5cdH1cblxuXHQvLyBJZiB3ZSBmb3VuZCBhIGRhdGFUeXBlXG5cdC8vIFdlIGFkZCB0aGUgZGF0YVR5cGUgdG8gdGhlIGxpc3QgaWYgbmVlZGVkXG5cdC8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2Vcblx0aWYgKCBmaW5hbERhdGFUeXBlICkge1xuXHRcdGlmICggZmluYWxEYXRhVHlwZSAhPT0gZGF0YVR5cGVzWyAwIF0gKSB7XG5cdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApO1xuXHRcdH1cblx0XHRyZXR1cm4gcmVzcG9uc2VzWyBmaW5hbERhdGFUeXBlIF07XG5cdH1cbn1cblxuLyogQ2hhaW4gY29udmVyc2lvbnMgZ2l2ZW4gdGhlIHJlcXVlc3QgYW5kIHRoZSBvcmlnaW5hbCByZXNwb25zZVxuICogQWxzbyBzZXRzIHRoZSByZXNwb25zZVhYWCBmaWVsZHMgb24gdGhlIGpxWEhSIGluc3RhbmNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApIHtcblx0dmFyIGNvbnYyLCBjdXJyZW50LCBjb252LCB0bXAsIHByZXYsXG5cdFx0Y29udmVydGVycyA9IHt9LFxuXHRcdC8vIFdvcmsgd2l0aCBhIGNvcHkgb2YgZGF0YVR5cGVzIGluIGNhc2Ugd2UgbmVlZCB0byBtb2RpZnkgaXQgZm9yIGNvbnZlcnNpb25cblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpO1xuXG5cdC8vIENyZWF0ZSBjb252ZXJ0ZXJzIG1hcCB3aXRoIGxvd2VyY2FzZWQga2V5c1xuXHRpZiAoIGRhdGFUeXBlc1sgMSBdICkge1xuXHRcdGZvciAoIGNvbnYgaW4gcy5jb252ZXJ0ZXJzICkge1xuXHRcdFx0Y29udmVydGVyc1sgY29udi50b0xvd2VyQ2FzZSgpIF0gPSBzLmNvbnZlcnRlcnNbIGNvbnYgXTtcblx0XHR9XG5cdH1cblxuXHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0Ly8gQ29udmVydCB0byBlYWNoIHNlcXVlbnRpYWwgZGF0YVR5cGVcblx0d2hpbGUgKCBjdXJyZW50ICkge1xuXG5cdFx0aWYgKCBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gKSB7XG5cdFx0XHRqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSB0aGUgZGF0YUZpbHRlciBpZiBwcm92aWRlZFxuXHRcdGlmICggIXByZXYgJiYgaXNTdWNjZXNzICYmIHMuZGF0YUZpbHRlciApIHtcblx0XHRcdHJlc3BvbnNlID0gcy5kYXRhRmlsdGVyKCByZXNwb25zZSwgcy5kYXRhVHlwZSApO1xuXHRcdH1cblxuXHRcdHByZXYgPSBjdXJyZW50O1xuXHRcdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHRcdGlmICggY3VycmVudCApIHtcblxuXHRcdC8vIFRoZXJlJ3Mgb25seSB3b3JrIHRvIGRvIGlmIGN1cnJlbnQgZGF0YVR5cGUgaXMgbm9uLWF1dG9cblx0XHRcdGlmICggY3VycmVudCA9PT0gXCIqXCIgKSB7XG5cblx0XHRcdFx0Y3VycmVudCA9IHByZXY7XG5cblx0XHRcdC8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnRcblx0XHRcdH0gZWxzZSBpZiAoIHByZXYgIT09IFwiKlwiICYmIHByZXYgIT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0Ly8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXJcblx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIGN1cnJlbnQgXSB8fCBjb252ZXJ0ZXJzWyBcIiogXCIgKyBjdXJyZW50IF07XG5cblx0XHRcdFx0Ly8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXJcblx0XHRcdFx0aWYgKCAhY29udiApIHtcblx0XHRcdFx0XHRmb3IgKCBjb252MiBpbiBjb252ZXJ0ZXJzICkge1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBjb252MiBvdXRwdXRzIGN1cnJlbnRcblx0XHRcdFx0XHRcdHRtcCA9IGNvbnYyLnNwbGl0KCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0aWYgKCB0bXBbIDEgXSA9PT0gY3VycmVudCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBJZiBwcmV2IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYWNjZXB0ZWQgaW5wdXRcblx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIHRtcFsgMCBdIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRjb252ZXJ0ZXJzWyBcIiogXCIgKyB0bXBbIDAgXSBdO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gQ29uZGVuc2UgZXF1aXZhbGVuY2UgY29udmVydGVyc1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY29udiA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBjb252MiBdO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBpbnNlcnQgdGhlIGludGVybWVkaWF0ZSBkYXRhVHlwZVxuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGNvbnZlcnRlcnNbIGNvbnYyIF0gIT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50ID0gdG1wWyAwIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdG1wWyAxIF0gKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBcHBseSBjb252ZXJ0ZXIgKGlmIG5vdCBhbiBlcXVpdmFsZW5jZSlcblx0XHRcdFx0aWYgKCBjb252ICE9PSB0cnVlICkge1xuXG5cdFx0XHRcdFx0Ly8gVW5sZXNzIGVycm9ycyBhcmUgYWxsb3dlZCB0byBidWJibGUsIGNhdGNoIGFuZCByZXR1cm4gdGhlbVxuXHRcdFx0XHRcdGlmICggY29udiAmJiBzWyBcInRocm93c1wiIF0gKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4geyBzdGF0ZTogXCJwYXJzZXJlcnJvclwiLCBlcnJvcjogY29udiA/IGUgOiBcIk5vIGNvbnZlcnNpb24gZnJvbSBcIiArIHByZXYgKyBcIiB0byBcIiArIGN1cnJlbnQgfTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4geyBzdGF0ZTogXCJzdWNjZXNzXCIsIGRhdGE6IHJlc3BvbnNlIH07XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXG5cdC8vIENvdW50ZXIgZm9yIGhvbGRpbmcgdGhlIG51bWJlciBvZiBhY3RpdmUgcXVlcmllc1xuXHRhY3RpdmU6IDAsXG5cblx0Ly8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdFxuXHRsYXN0TW9kaWZpZWQ6IHt9LFxuXHRldGFnOiB7fSxcblxuXHRhamF4U2V0dGluZ3M6IHtcblx0XHR1cmw6IGFqYXhMb2NhdGlvbixcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGlzTG9jYWw6IHJsb2NhbFByb3RvY29sLnRlc3QoIGFqYXhMb2NQYXJ0c1sgMSBdICksXG5cdFx0Z2xvYmFsOiB0cnVlLFxuXHRcdHByb2Nlc3NEYXRhOiB0cnVlLFxuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOFwiLFxuXHRcdC8qXG5cdFx0dGltZW91dDogMCxcblx0XHRkYXRhOiBudWxsLFxuXHRcdGRhdGFUeXBlOiBudWxsLFxuXHRcdHVzZXJuYW1lOiBudWxsLFxuXHRcdHBhc3N3b3JkOiBudWxsLFxuXHRcdGNhY2hlOiBudWxsLFxuXHRcdHRocm93czogZmFsc2UsXG5cdFx0dHJhZGl0aW9uYWw6IGZhbHNlLFxuXHRcdGhlYWRlcnM6IHt9LFxuXHRcdCovXG5cblx0XHRhY2NlcHRzOiB7XG5cdFx0XHRcIipcIjogYWxsVHlwZXMsXG5cdFx0XHR0ZXh0OiBcInRleHQvcGxhaW5cIixcblx0XHRcdGh0bWw6IFwidGV4dC9odG1sXCIsXG5cdFx0XHR4bWw6IFwiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbFwiLFxuXHRcdFx0anNvbjogXCJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHRcIlxuXHRcdH0sXG5cblx0XHRjb250ZW50czoge1xuXHRcdFx0eG1sOiAveG1sLyxcblx0XHRcdGh0bWw6IC9odG1sLyxcblx0XHRcdGpzb246IC9qc29uL1xuXHRcdH0sXG5cblx0XHRyZXNwb25zZUZpZWxkczoge1xuXHRcdFx0eG1sOiBcInJlc3BvbnNlWE1MXCIsXG5cdFx0XHR0ZXh0OiBcInJlc3BvbnNlVGV4dFwiLFxuXHRcdFx0anNvbjogXCJyZXNwb25zZUpTT05cIlxuXHRcdH0sXG5cblx0XHQvLyBEYXRhIGNvbnZlcnRlcnNcblx0XHQvLyBLZXlzIHNlcGFyYXRlIHNvdXJjZSAob3IgY2F0Y2hhbGwgXCIqXCIpIGFuZCBkZXN0aW5hdGlvbiB0eXBlcyB3aXRoIGEgc2luZ2xlIHNwYWNlXG5cdFx0Y29udmVydGVyczoge1xuXG5cdFx0XHQvLyBDb252ZXJ0IGFueXRoaW5nIHRvIHRleHRcblx0XHRcdFwiKiB0ZXh0XCI6IFN0cmluZyxcblxuXHRcdFx0Ly8gVGV4dCB0byBodG1sICh0cnVlID0gbm8gdHJhbnNmb3JtYXRpb24pXG5cdFx0XHRcInRleHQgaHRtbFwiOiB0cnVlLFxuXG5cdFx0XHQvLyBFdmFsdWF0ZSB0ZXh0IGFzIGEganNvbiBleHByZXNzaW9uXG5cdFx0XHRcInRleHQganNvblwiOiBqUXVlcnkucGFyc2VKU09OLFxuXG5cdFx0XHQvLyBQYXJzZSB0ZXh0IGFzIHhtbFxuXHRcdFx0XCJ0ZXh0IHhtbFwiOiBqUXVlcnkucGFyc2VYTUxcblx0XHR9LFxuXG5cdFx0Ly8gRm9yIG9wdGlvbnMgdGhhdCBzaG91bGRuJ3QgYmUgZGVlcCBleHRlbmRlZDpcblx0XHQvLyB5b3UgY2FuIGFkZCB5b3VyIG93biBjdXN0b20gb3B0aW9ucyBoZXJlIGlmXG5cdFx0Ly8gYW5kIHdoZW4geW91IGNyZWF0ZSBvbmUgdGhhdCBzaG91bGRuJ3QgYmVcblx0XHQvLyBkZWVwIGV4dGVuZGVkIChzZWUgYWpheEV4dGVuZClcblx0XHRmbGF0T3B0aW9uczoge1xuXHRcdFx0dXJsOiB0cnVlLFxuXHRcdFx0Y29udGV4dDogdHJ1ZVxuXHRcdH1cblx0fSxcblxuXHQvLyBDcmVhdGVzIGEgZnVsbCBmbGVkZ2VkIHNldHRpbmdzIG9iamVjdCBpbnRvIHRhcmdldFxuXHQvLyB3aXRoIGJvdGggYWpheFNldHRpbmdzIGFuZCBzZXR0aW5ncyBmaWVsZHMuXG5cdC8vIElmIHRhcmdldCBpcyBvbWl0dGVkLCB3cml0ZXMgaW50byBhamF4U2V0dGluZ3MuXG5cdGFqYXhTZXR1cDogZnVuY3Rpb24oIHRhcmdldCwgc2V0dGluZ3MgKSB7XG5cdFx0cmV0dXJuIHNldHRpbmdzID9cblxuXHRcdFx0Ly8gQnVpbGRpbmcgYSBzZXR0aW5ncyBvYmplY3Rcblx0XHRcdGFqYXhFeHRlbmQoIGFqYXhFeHRlbmQoIHRhcmdldCwgalF1ZXJ5LmFqYXhTZXR0aW5ncyApLCBzZXR0aW5ncyApIDpcblxuXHRcdFx0Ly8gRXh0ZW5kaW5nIGFqYXhTZXR0aW5nc1xuXHRcdFx0YWpheEV4dGVuZCggalF1ZXJ5LmFqYXhTZXR0aW5ncywgdGFyZ2V0ICk7XG5cdH0sXG5cblx0YWpheFByZWZpbHRlcjogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzICksXG5cdGFqYXhUcmFuc3BvcnQ6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cyApLFxuXG5cdC8vIE1haW4gbWV0aG9kXG5cdGFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7XG5cblx0XHQvLyBJZiB1cmwgaXMgYW4gb2JqZWN0LCBzaW11bGF0ZSBwcmUtMS41IHNpZ25hdHVyZVxuXHRcdGlmICggdHlwZW9mIHVybCA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdG9wdGlvbnMgPSB1cmw7XG5cdFx0XHR1cmwgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gRm9yY2Ugb3B0aW9ucyB0byBiZSBhbiBvYmplY3Rcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXHRcdHZhciB0cmFuc3BvcnQsXG5cdFx0XHQvLyBVUkwgd2l0aG91dCBhbnRpLWNhY2hlIHBhcmFtXG5cdFx0XHRjYWNoZVVSTCxcblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyxcblx0XHRcdHJlc3BvbnNlSGVhZGVycyxcblx0XHRcdC8vIHRpbWVvdXQgaGFuZGxlXG5cdFx0XHR0aW1lb3V0VGltZXIsXG5cdFx0XHQvLyBDcm9zcy1kb21haW4gZGV0ZWN0aW9uIHZhcnNcblx0XHRcdHBhcnRzLFxuXHRcdFx0Ly8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkXG5cdFx0XHRmaXJlR2xvYmFscyxcblx0XHRcdC8vIExvb3AgdmFyaWFibGVcblx0XHRcdGksXG5cdFx0XHQvLyBDcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XG5cdFx0XHRjYWxsYmFja0NvbnRleHQgPSBzLmNvbnRleHQgfHwgcyxcblx0XHRcdC8vIENvbnRleHQgZm9yIGdsb2JhbCBldmVudHMgaXMgY2FsbGJhY2tDb250ZXh0IGlmIGl0IGlzIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IGNvbGxlY3Rpb25cblx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dCA9IHMuY29udGV4dCAmJiAoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xuXHRcdFx0XHRqUXVlcnkoIGNhbGxiYWNrQ29udGV4dCApIDpcblx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXHRcdFx0Ly8gRGVmZXJyZWRzXG5cdFx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZCA9IGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKSxcblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXHRcdFx0Ly8gSGVhZGVycyAodGhleSBhcmUgc2VudCBhbGwgYXQgb25jZSlcblx0XHRcdHJlcXVlc3RIZWFkZXJzID0ge30sXG5cdFx0XHRyZXF1ZXN0SGVhZGVyc05hbWVzID0ge30sXG5cdFx0XHQvLyBUaGUganFYSFIgc3RhdGVcblx0XHRcdHN0YXRlID0gMCxcblx0XHRcdC8vIERlZmF1bHQgYWJvcnQgbWVzc2FnZVxuXHRcdFx0c3RyQWJvcnQgPSBcImNhbmNlbGVkXCIsXG5cdFx0XHQvLyBGYWtlIHhoclxuXHRcdFx0anFYSFIgPSB7XG5cdFx0XHRcdHJlYWR5U3RhdGU6IDAsXG5cblx0XHRcdFx0Ly8gQnVpbGRzIGhlYWRlcnMgaGFzaHRhYmxlIGlmIG5lZWRlZFxuXHRcdFx0XHRnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24oIGtleSApIHtcblx0XHRcdFx0XHR2YXIgbWF0Y2g7XG5cdFx0XHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcblx0XHRcdFx0XHRcdGlmICggIXJlc3BvbnNlSGVhZGVycyApIHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzID0ge307XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVyc1sgbWF0Y2hbMV0udG9Mb3dlckNhc2UoKSBdID0gbWF0Y2hbIDIgXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0bWF0Y2ggPSByZXNwb25zZUhlYWRlcnNbIGtleS50b0xvd2VyQ2FzZSgpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGUgPT09IDIgPyByZXNwb25zZUhlYWRlcnNTdHJpbmcgOiBudWxsO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIENhY2hlcyB0aGUgaGVhZGVyXG5cdFx0XHRcdHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdFx0XHR2YXIgbG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0aWYgKCAhc3RhdGUgKSB7XG5cdFx0XHRcdFx0XHRuYW1lID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIGxuYW1lIF0gfHwgbmFtZTtcblx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGVzIHJlc3BvbnNlIGNvbnRlbnQtdHlwZSBoZWFkZXJcblx0XHRcdFx0b3ZlcnJpZGVNaW1lVHlwZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0XHRcdFx0aWYgKCAhc3RhdGUgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKCBjb2RlIGluIG1hcCApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBMYXp5LWFkZCB0aGUgbmV3IGNhbGxiYWNrIGluIGEgd2F5IHRoYXQgcHJlc2VydmVzIG9sZCBvbmVzXG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICkuY29tcGxldGUgPSBjb21wbGV0ZURlZmVycmVkLmFkZDtcblx0XHRqcVhIUi5zdWNjZXNzID0ganFYSFIuZG9uZTtcblx0XHRqcVhIUi5lcnJvciA9IGpxWEhSLmZhaWw7XG5cblx0XHQvLyBSZW1vdmUgaGFzaCBjaGFyYWN0ZXIgKCM3NTMxOiBhbmQgc3RyaW5nIHByb21vdGlvbilcblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkIChwcmVmaWx0ZXJzIG1pZ2h0IGV4cGVjdCBpdClcblx0XHQvLyBIYW5kbGUgZmFsc3kgdXJsIGluIHRoZSBzZXR0aW5ncyBvYmplY3QgKCMxMDA5MzogY29uc2lzdGVuY3kgd2l0aCBvbGQgc2lnbmF0dXJlKVxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxuXHRcdHMudXJsID0gKCAoIHVybCB8fCBzLnVybCB8fCBhamF4TG9jYXRpb24gKSArIFwiXCIgKS5yZXBsYWNlKCByaGFzaCwgXCJcIiApXG5cdFx0XHQucmVwbGFjZSggcnByb3RvY29sLCBhamF4TG9jUGFydHNbIDEgXSArIFwiLy9cIiApO1xuXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0XG5cdFx0cy50eXBlID0gb3B0aW9ucy5tZXRob2QgfHwgb3B0aW9ucy50eXBlIHx8IHMubWV0aG9kIHx8IHMudHlwZTtcblxuXHRcdC8vIEV4dHJhY3QgZGF0YVR5cGVzIGxpc3Rcblx0XHRzLmRhdGFUeXBlcyA9IGpRdWVyeS50cmltKCBzLmRhdGFUeXBlIHx8IFwiKlwiICkudG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XG5cblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gd2UgaGF2ZSBhIHByb3RvY29sOmhvc3Q6cG9ydCBtaXNtYXRjaFxuXHRcdGlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkge1xuXHRcdFx0cGFydHMgPSBydXJsLmV4ZWMoIHMudXJsLnRvTG93ZXJDYXNlKCkgKTtcblx0XHRcdHMuY3Jvc3NEb21haW4gPSAhISggcGFydHMgJiZcblx0XHRcdFx0KCBwYXJ0c1sgMSBdICE9PSBhamF4TG9jUGFydHNbIDEgXSB8fCBwYXJ0c1sgMiBdICE9PSBhamF4TG9jUGFydHNbIDIgXSB8fFxuXHRcdFx0XHRcdCggcGFydHNbIDMgXSB8fCAoIHBhcnRzWyAxIF0gPT09IFwiaHR0cDpcIiA/IFwiODBcIiA6IFwiNDQzXCIgKSApICE9PVxuXHRcdFx0XHRcdFx0KCBhamF4TG9jUGFydHNbIDMgXSB8fCAoIGFqYXhMb2NQYXJ0c1sgMSBdID09PSBcImh0dHA6XCIgPyBcIjgwXCIgOiBcIjQ0M1wiICkgKSApXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgZGF0YSBpZiBub3QgYWxyZWFkeSBhIHN0cmluZ1xuXHRcdGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiYgdHlwZW9mIHMuZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xuXHRcdGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcblx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0cmV0dXJuIGpxWEhSO1xuXHRcdH1cblxuXHRcdC8vIFdlIGNhbiBmaXJlIGdsb2JhbCBldmVudHMgYXMgb2Ygbm93IGlmIGFza2VkIHRvXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKCMxNTExOClcblx0XHRmaXJlR2xvYmFscyA9IGpRdWVyeS5ldmVudCAmJiBzLmdsb2JhbDtcblxuXHRcdC8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHNcblx0XHRpZiAoIGZpcmVHbG9iYWxzICYmIGpRdWVyeS5hY3RpdmUrKyA9PT0gMCApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKFwiYWpheFN0YXJ0XCIpO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdGNhY2hlVVJMID0gcy51cmw7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gKCBzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgcy5kYXRhICk7XG5cdFx0XHRcdC8vICM5NjgyOiByZW1vdmUgZGF0YSBzbyB0aGF0IGl0J3Mgbm90IHVzZWQgaW4gYW4gZXZlbnR1YWwgcmV0cnlcblx0XHRcdFx0ZGVsZXRlIHMuZGF0YTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGFudGktY2FjaGUgaW4gdXJsIGlmIG5lZWRlZFxuXHRcdFx0aWYgKCBzLmNhY2hlID09PSBmYWxzZSApIHtcblx0XHRcdFx0cy51cmwgPSBydHMudGVzdCggY2FjaGVVUkwgKSA/XG5cblx0XHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBhbHJlYWR5IGEgJ18nIHBhcmFtZXRlciwgc2V0IGl0cyB2YWx1ZVxuXHRcdFx0XHRcdGNhY2hlVVJMLnJlcGxhY2UoIHJ0cywgXCIkMV89XCIgKyBub25jZSsrICkgOlxuXG5cdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFkZCBvbmUgdG8gdGhlIGVuZFxuXHRcdFx0XHRcdGNhY2hlVVJMICsgKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArIG5vbmNlKys7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdGlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Nb2RpZmllZC1TaW5jZVwiLCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU5vbmUtTWF0Y2hcIiwgalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIGNvcnJlY3QgaGVhZGVyLCBpZiBkYXRhIGlzIGJlaW5nIHNlbnRcblx0XHRpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiQ29udGVudC1UeXBlXCIsIHMuY29udGVudFR5cGUgKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIEFjY2VwdHMgaGVhZGVyIGZvciB0aGUgc2VydmVyLCBkZXBlbmRpbmcgb24gdGhlIGRhdGFUeXBlXG5cdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlcihcblx0XHRcdFwiQWNjZXB0XCIsXG5cdFx0XHRzLmRhdGFUeXBlc1sgMCBdICYmIHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbMF0gXSA/XG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbMF0gXSArICggcy5kYXRhVHlwZXNbIDAgXSAhPT0gXCIqXCIgPyBcIiwgXCIgKyBhbGxUeXBlcyArIFwiOyBxPTAuMDFcIiA6IFwiXCIgKSA6XG5cdFx0XHRcdHMuYWNjZXB0c1sgXCIqXCIgXVxuXHRcdCk7XG5cblx0XHQvLyBDaGVjayBmb3IgaGVhZGVycyBvcHRpb25cblx0XHRmb3IgKCBpIGluIHMuaGVhZGVycyApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsb3cgY3VzdG9tIGhlYWRlcnMvbWltZXR5cGVzIGFuZCBlYXJseSBhYm9ydFxuXHRcdGlmICggcy5iZWZvcmVTZW5kICYmICggcy5iZWZvcmVTZW5kLmNhbGwoIGNhbGxiYWNrQ29udGV4dCwganFYSFIsIHMgKSA9PT0gZmFsc2UgfHwgc3RhdGUgPT09IDIgKSApIHtcblx0XHRcdC8vIEFib3J0IGlmIG5vdCBkb25lIGFscmVhZHkgYW5kIHJldHVyblxuXHRcdFx0cmV0dXJuIGpxWEhSLmFib3J0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gQWJvcnRpbmcgaXMgbm8gbG9uZ2VyIGEgY2FuY2VsbGF0aW9uXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrcyBvbiBkZWZlcnJlZHNcblx0XHRmb3IgKCBpIGluIHsgc3VjY2VzczogMSwgZXJyb3I6IDEsIGNvbXBsZXRlOiAxIH0gKSB7XG5cdFx0XHRqcVhIUlsgaSBdKCBzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBHZXQgdHJhbnNwb3J0XG5cdFx0dHJhbnNwb3J0ID0gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiBubyB0cmFuc3BvcnQsIHdlIGF1dG8tYWJvcnRcblx0XHRpZiAoICF0cmFuc3BvcnQgKSB7XG5cdFx0XHRkb25lKCAtMSwgXCJObyBUcmFuc3BvcnRcIiApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gMTtcblxuXHRcdFx0Ly8gU2VuZCBnbG9iYWwgZXZlbnRcblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhTZW5kXCIsIFsganFYSFIsIHMgXSApO1xuXHRcdFx0fVxuXHRcdFx0Ly8gVGltZW91dFxuXHRcdFx0aWYgKCBzLmFzeW5jICYmIHMudGltZW91dCA+IDAgKSB7XG5cdFx0XHRcdHRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0anFYSFIuYWJvcnQoXCJ0aW1lb3V0XCIpO1xuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcblx0XHRcdH1cblxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0c3RhdGUgPSAxO1xuXHRcdFx0XHR0cmFuc3BvcnQuc2VuZCggcmVxdWVzdEhlYWRlcnMsIGRvbmUgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHQvLyBQcm9wYWdhdGUgZXhjZXB0aW9uIGFzIGVycm9yIGlmIG5vdCBkb25lXG5cdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xuXHRcdFx0XHRcdGRvbmUoIC0xLCBlICk7XG5cdFx0XHRcdC8vIFNpbXBseSByZXRocm93IG90aGVyd2lzZVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcblx0XHRmdW5jdGlvbiBkb25lKCBzdGF0dXMsIG5hdGl2ZVN0YXR1c1RleHQsIHJlc3BvbnNlcywgaGVhZGVycyApIHtcblx0XHRcdHZhciBpc1N1Y2Nlc3MsIHN1Y2Nlc3MsIGVycm9yLCByZXNwb25zZSwgbW9kaWZpZWQsXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xuXG5cdFx0XHQvLyBDYWxsZWQgb25jZVxuXHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0ZSBpcyBcImRvbmVcIiBub3dcblx0XHRcdHN0YXRlID0gMjtcblxuXHRcdFx0Ly8gQ2xlYXIgdGltZW91dCBpZiBpdCBleGlzdHNcblx0XHRcdGlmICggdGltZW91dFRpbWVyICkge1xuXHRcdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVvdXRUaW1lciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXJlZmVyZW5jZSB0cmFuc3BvcnQgZm9yIGVhcmx5IGdhcmJhZ2UgY29sbGVjdGlvblxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcblx0XHRcdHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nID0gaGVhZGVycyB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDtcblxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcblx0XHRcdGlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0O1xuXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxuXHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb252ZXJ0IG5vIG1hdHRlciB3aGF0ICh0aGF0IHdheSByZXNwb25zZVhYWCBmaWVsZHMgYXJlIGFsd2F5cyBzZXQpXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xuXG5cdFx0XHQvLyBJZiBzdWNjZXNzZnVsLCBoYW5kbGUgdHlwZSBjaGFpbmluZ1xuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcIkxhc3QtTW9kaWZpZWRcIik7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcImV0YWdcIik7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gaWYgbm8gY29udGVudFxuXHRcdFx0XHRpZiAoIHN0YXR1cyA9PT0gMjA0IHx8IHMudHlwZSA9PT0gXCJIRUFEXCIgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XG5cblx0XHRcdFx0Ly8gaWYgbm90IG1vZGlmaWVkXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vdG1vZGlmaWVkXCI7XG5cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXRlO1xuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xuXHRcdFx0XHRcdGVycm9yID0gcmVzcG9uc2UuZXJyb3I7XG5cdFx0XHRcdFx0aXNTdWNjZXNzID0gIWVycm9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBFeHRyYWN0IGVycm9yIGZyb20gc3RhdHVzVGV4dCBhbmQgbm9ybWFsaXplIGZvciBub24tYWJvcnRzXG5cdFx0XHRcdGVycm9yID0gc3RhdHVzVGV4dDtcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwiZXJyb3JcIjtcblx0XHRcdFx0XHRpZiAoIHN0YXR1cyA8IDAgKSB7XG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgZGF0YSBmb3IgdGhlIGZha2UgeGhyIG9iamVjdFxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xuXHRcdFx0anFYSFIuc3RhdHVzVGV4dCA9ICggbmF0aXZlU3RhdHVzVGV4dCB8fCBzdGF0dXNUZXh0ICkgKyBcIlwiO1xuXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBzdWNjZXNzLCBzdGF0dXNUZXh0LCBqcVhIUiBdICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQsIGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdGpxWEhSLnN0YXR1c0NvZGUoIHN0YXR1c0NvZGUgKTtcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxuXHRcdFx0XHRcdFsganFYSFIsIHMsIGlzU3VjY2VzcyA/IHN1Y2Nlc3MgOiBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXBsZXRlXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkLmZpcmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQgXSApO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4Q29tcGxldGVcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHRcdC8vIEhhbmRsZSB0aGUgZ2xvYmFsIEFKQVggY291bnRlclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKFwiYWpheFN0b3BcIik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4ganFYSFI7XG5cdH0sXG5cblx0Z2V0SlNPTjogZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgZGF0YSwgY2FsbGJhY2ssIFwianNvblwiICk7XG5cdH0sXG5cblx0Z2V0U2NyaXB0OiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggaSwgbWV0aG9kICkge1xuXHRqUXVlcnlbIG1ldGhvZCBdID0gZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2ssIHR5cGUgKSB7XG5cdFx0Ly8gU2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWRcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBkYXRhICkgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcblx0XHRcdGNhbGxiYWNrID0gZGF0YTtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KHtcblx0XHRcdHVybDogdXJsLFxuXHRcdFx0dHlwZTogbWV0aG9kLFxuXHRcdFx0ZGF0YVR5cGU6IHR5cGUsXG5cdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0c3VjY2VzczogY2FsbGJhY2tcblx0XHR9KTtcblx0fTtcbn0pO1xuXG5cbmpRdWVyeS5fZXZhbFVybCA9IGZ1bmN0aW9uKCB1cmwgKSB7XG5cdHJldHVybiBqUXVlcnkuYWpheCh7XG5cdFx0dXJsOiB1cmwsXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0Z2xvYmFsOiBmYWxzZSxcblx0XHRcInRocm93c1wiOiB0cnVlXG5cdH0pO1xufTtcblxuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0d3JhcEFsbDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIHdyYXA7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwQWxsKCBodG1sLmNhbGwodGhpcywgaSkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICggdGhpc1sgMCBdICkge1xuXG5cdFx0XHQvLyBUaGUgZWxlbWVudHMgdG8gd3JhcCB0aGUgdGFyZ2V0IGFyb3VuZFxuXHRcdFx0d3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7XG5cblx0XHRcdGlmICggdGhpc1sgMCBdLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0d3JhcC5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBlbGVtID0gdGhpcztcblxuXHRcdFx0XHR3aGlsZSAoIGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQgKSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZWxlbTtcblx0XHRcdH0pLmFwcGVuZCggdGhpcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcElubmVyKCBodG1sLmNhbGwodGhpcywgaSkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgc2VsZiA9IGpRdWVyeSggdGhpcyApLFxuXHRcdFx0XHRjb250ZW50cyA9IHNlbGYuY29udGVudHMoKTtcblxuXHRcdFx0aWYgKCBjb250ZW50cy5sZW5ndGggKSB7XG5cdFx0XHRcdGNvbnRlbnRzLndyYXBBbGwoIGh0bWwgKTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c2VsZi5hcHBlbmQoIGh0bWwgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHR3cmFwOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHR2YXIgaXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICk7XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaXNGdW5jdGlvbiA/IGh0bWwuY2FsbCh0aGlzLCBpKSA6IGh0bWwgKTtcblx0XHR9KTtcblx0fSxcblxuXHR1bndyYXA6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnBhcmVudCgpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFqUXVlcnkubm9kZU5hbWUoIHRoaXMsIFwiYm9keVwiICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlcGxhY2VXaXRoKCB0aGlzLmNoaWxkTm9kZXMgKTtcblx0XHRcdH1cblx0XHR9KS5lbmQoKTtcblx0fVxufSk7XG5cblxualF1ZXJ5LmV4cHIuZmlsdGVycy5oaWRkZW4gPSBmdW5jdGlvbiggZWxlbSApIHtcblx0Ly8gU3VwcG9ydDogT3BlcmEgPD0gMTIuMTJcblx0Ly8gT3BlcmEgcmVwb3J0cyBvZmZzZXRXaWR0aHMgYW5kIG9mZnNldEhlaWdodHMgbGVzcyB0aGFuIHplcm8gb24gc29tZSBlbGVtZW50c1xuXHRyZXR1cm4gZWxlbS5vZmZzZXRXaWR0aCA8PSAwICYmIGVsZW0ub2Zmc2V0SGVpZ2h0IDw9IDA7XG59O1xualF1ZXJ5LmV4cHIuZmlsdGVycy52aXNpYmxlID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhalF1ZXJ5LmV4cHIuZmlsdGVycy5oaWRkZW4oIGVsZW0gKTtcbn07XG5cblxuXG5cbnZhciByMjAgPSAvJTIwL2csXG5cdHJicmFja2V0ID0gL1xcW1xcXSQvLFxuXHRyQ1JMRiA9IC9cXHI/XFxuL2csXG5cdHJzdWJtaXR0ZXJUeXBlcyA9IC9eKD86c3VibWl0fGJ1dHRvbnxpbWFnZXxyZXNldHxmaWxlKSQvaSxcblx0cnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO1xuXG5mdW5jdGlvbiBidWlsZFBhcmFtcyggcHJlZml4LCBvYmosIHRyYWRpdGlvbmFsLCBhZGQgKSB7XG5cdHZhciBuYW1lO1xuXG5cdGlmICggalF1ZXJ5LmlzQXJyYXkoIG9iaiApICkge1xuXHRcdC8vIFNlcmlhbGl6ZSBhcnJheSBpdGVtLlxuXHRcdGpRdWVyeS5lYWNoKCBvYmosIGZ1bmN0aW9uKCBpLCB2ICkge1xuXHRcdFx0aWYgKCB0cmFkaXRpb25hbCB8fCByYnJhY2tldC50ZXN0KCBwcmVmaXggKSApIHtcblx0XHRcdFx0Ly8gVHJlYXQgZWFjaCBhcnJheSBpdGVtIGFzIGEgc2NhbGFyLlxuXHRcdFx0XHRhZGQoIHByZWZpeCwgdiApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBJdGVtIGlzIG5vbi1zY2FsYXIgKGFycmF5IG9yIG9iamVjdCksIGVuY29kZSBpdHMgbnVtZXJpYyBpbmRleC5cblx0XHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgKCB0eXBlb2YgdiA9PT0gXCJvYmplY3RcIiA/IGkgOiBcIlwiICkgKyBcIl1cIiwgdiwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdH0gZWxzZSBpZiAoICF0cmFkaXRpb25hbCAmJiBqUXVlcnkudHlwZSggb2JqICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIG9iamVjdCBpdGVtLlxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXHRcdC8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS5cblx0XHRhZGQoIHByZWZpeCwgb2JqICk7XG5cdH1cbn1cblxuLy8gU2VyaWFsaXplIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMgb3IgYSBzZXQgb2Zcbi8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZ1xualF1ZXJ5LnBhcmFtID0gZnVuY3Rpb24oIGEsIHRyYWRpdGlvbmFsICkge1xuXHR2YXIgcHJlZml4LFxuXHRcdHMgPSBbXSxcblx0XHRhZGQgPSBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHRcdC8vIElmIHZhbHVlIGlzIGEgZnVuY3Rpb24sIGludm9rZSBpdCBhbmQgcmV0dXJuIGl0cyB2YWx1ZVxuXHRcdFx0dmFsdWUgPSBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSA/IHZhbHVlKCkgOiAoIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKTtcblx0XHRcdHNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoIHZhbHVlICk7XG5cdFx0fTtcblxuXHQvLyBTZXQgdHJhZGl0aW9uYWwgdG8gdHJ1ZSBmb3IgalF1ZXJ5IDw9IDEuMy4yIGJlaGF2aW9yLlxuXHRpZiAoIHRyYWRpdGlvbmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0dHJhZGl0aW9uYWwgPSBqUXVlcnkuYWpheFNldHRpbmdzICYmIGpRdWVyeS5hamF4U2V0dGluZ3MudHJhZGl0aW9uYWw7XG5cdH1cblxuXHQvLyBJZiBhbiBhcnJheSB3YXMgcGFzc2VkIGluLCBhc3N1bWUgdGhhdCBpdCBpcyBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzLlxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBhICkgfHwgKCBhLmpxdWVyeSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGEgKSApICkge1xuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xuXHRcdGpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpIHtcblx0XHRcdGFkZCggdGhpcy5uYW1lLCB0aGlzLnZhbHVlICk7XG5cdFx0fSk7XG5cblx0fSBlbHNlIHtcblx0XHQvLyBJZiB0cmFkaXRpb25hbCwgZW5jb2RlIHRoZSBcIm9sZFwiIHdheSAodGhlIHdheSAxLjMuMiBvciBvbGRlclxuXHRcdC8vIGRpZCBpdCksIG90aGVyd2lzZSBlbmNvZGUgcGFyYW1zIHJlY3Vyc2l2ZWx5LlxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCwgYVsgcHJlZml4IF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICkucmVwbGFjZSggcjIwLCBcIitcIiApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5wYXJhbSggdGhpcy5zZXJpYWxpemVBcnJheSgpICk7XG5cdH0sXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXG5cdFx0XHR2YXIgZWxlbWVudHMgPSBqUXVlcnkucHJvcCggdGhpcywgXCJlbGVtZW50c1wiICk7XG5cdFx0XHRyZXR1cm4gZWxlbWVudHMgPyBqUXVlcnkubWFrZUFycmF5KCBlbGVtZW50cyApIDogdGhpcztcblx0XHR9KVxuXHRcdC5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdHlwZSA9IHRoaXMudHlwZTtcblxuXHRcdFx0Ly8gVXNlIC5pcyggXCI6ZGlzYWJsZWRcIiApIHNvIHRoYXQgZmllbGRzZXRbZGlzYWJsZWRdIHdvcmtzXG5cdFx0XHRyZXR1cm4gdGhpcy5uYW1lICYmICFqUXVlcnkoIHRoaXMgKS5pcyggXCI6ZGlzYWJsZWRcIiApICYmXG5cdFx0XHRcdHJzdWJtaXR0YWJsZS50ZXN0KCB0aGlzLm5vZGVOYW1lICkgJiYgIXJzdWJtaXR0ZXJUeXBlcy50ZXN0KCB0eXBlICkgJiZcblx0XHRcdFx0KCB0aGlzLmNoZWNrZWQgfHwgIXJjaGVja2FibGVUeXBlLnRlc3QoIHR5cGUgKSApO1xuXHRcdH0pXG5cdFx0Lm1hcChmdW5jdGlvbiggaSwgZWxlbSApIHtcblx0XHRcdHZhciB2YWwgPSBqUXVlcnkoIHRoaXMgKS52YWwoKTtcblxuXHRcdFx0cmV0dXJuIHZhbCA9PSBudWxsID9cblx0XHRcdFx0bnVsbCA6XG5cdFx0XHRcdGpRdWVyeS5pc0FycmF5KCB2YWwgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHRcdFx0XHR9KSA6XG5cdFx0XHRcdFx0eyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdH0pLmdldCgpO1xuXHR9XG59KTtcblxuXG5qUXVlcnkuYWpheFNldHRpbmdzLnhociA9IGZ1bmN0aW9uKCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcblx0fSBjYXRjaCggZSApIHt9XG59O1xuXG52YXIgeGhySWQgPSAwLFxuXHR4aHJDYWxsYmFja3MgPSB7fSxcblx0eGhyU3VjY2Vzc1N0YXR1cyA9IHtcblx0XHQvLyBmaWxlIHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIGNvZGUgMCwgYXNzdW1lIDIwMFxuXHRcdDA6IDIwMCxcblx0XHQvLyBTdXBwb3J0OiBJRTlcblx0XHQvLyAjMTQ1MDogc29tZXRpbWVzIElFIHJldHVybnMgMTIyMyB3aGVuIGl0IHNob3VsZCBiZSAyMDRcblx0XHQxMjIzOiAyMDRcblx0fSxcblx0eGhyU3VwcG9ydGVkID0galF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIoKTtcblxuLy8gU3VwcG9ydDogSUU5XG4vLyBPcGVuIHJlcXVlc3RzIG11c3QgYmUgbWFudWFsbHkgYWJvcnRlZCBvbiB1bmxvYWQgKCM1MjgwKVxuLy8gU2VlIGh0dHBzOi8vc3VwcG9ydC5taWNyb3NvZnQuY29tL2tiLzI4NTY3NDYgZm9yIG1vcmUgaW5mb1xuaWYgKCB3aW5kb3cuYXR0YWNoRXZlbnQgKSB7XG5cdHdpbmRvdy5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCBmdW5jdGlvbigpIHtcblx0XHRmb3IgKCB2YXIga2V5IGluIHhockNhbGxiYWNrcyApIHtcblx0XHRcdHhockNhbGxiYWNrc1sga2V5IF0oKTtcblx0XHR9XG5cdH0pO1xufVxuXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XG5zdXBwb3J0LmFqYXggPSB4aHJTdXBwb3J0ZWQgPSAhIXhoclN1cHBvcnRlZDtcblxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdHZhciBjYWxsYmFjaztcblxuXHQvLyBDcm9zcyBkb21haW4gb25seSBhbGxvd2VkIGlmIHN1cHBvcnRlZCB0aHJvdWdoIFhNTEh0dHBSZXF1ZXN0XG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIGhlYWRlcnMsIGNvbXBsZXRlICkge1xuXHRcdFx0XHR2YXIgaSxcblx0XHRcdFx0XHR4aHIgPSBvcHRpb25zLnhocigpLFxuXHRcdFx0XHRcdGlkID0gKyt4aHJJZDtcblxuXHRcdFx0XHR4aHIub3Blbiggb3B0aW9ucy50eXBlLCBvcHRpb25zLnVybCwgb3B0aW9ucy5hc3luYywgb3B0aW9ucy51c2VybmFtZSwgb3B0aW9ucy5wYXNzd29yZCApO1xuXG5cdFx0XHRcdC8vIEFwcGx5IGN1c3RvbSBmaWVsZHMgaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdFx0eGhyWyBpIF0gPSBvcHRpb25zLnhockZpZWxkc1sgaSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLm1pbWVUeXBlICYmIHhoci5vdmVycmlkZU1pbWVUeXBlICkge1xuXHRcdFx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCBvcHRpb25zLm1pbWVUeXBlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBYLVJlcXVlc3RlZC1XaXRoIGhlYWRlclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXG5cdFx0XHRcdC8vIGFraW4gdG8gYSBqaWdzYXcgcHV6emxlLCB3ZSBzaW1wbHkgbmV2ZXIgc2V0IGl0IHRvIGJlIHN1cmUuXG5cdFx0XHRcdC8vIChpdCBjYW4gYWx3YXlzIGJlIHNldCBvbiBhIHBlci1yZXF1ZXN0IGJhc2lzIG9yIGV2ZW4gdXNpbmcgYWpheFNldHVwKVxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cblx0XHRcdFx0aWYgKCAhb3B0aW9ucy5jcm9zc0RvbWFpbiAmJiAhaGVhZGVyc1tcIlgtUmVxdWVzdGVkLVdpdGhcIl0gKSB7XG5cdFx0XHRcdFx0aGVhZGVyc1tcIlgtUmVxdWVzdGVkLVdpdGhcIl0gPSBcIlhNTEh0dHBSZXF1ZXN0XCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZXQgaGVhZGVyc1xuXHRcdFx0XHRmb3IgKCBpIGluIGhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgeGhyQ2FsbGJhY2tzWyBpZCBdO1xuXHRcdFx0XHRcdFx0XHRjYWxsYmFjayA9IHhoci5vbmxvYWQgPSB4aHIub25lcnJvciA9IG51bGw7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlID09PSBcImFib3J0XCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0eGhyLmFib3J0KCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IFwiZXJyb3JcIiApIHtcblx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3XG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1c1RleHRcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyU3VjY2Vzc1N0YXR1c1sgeGhyLnN0YXR1cyBdIHx8IHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dCxcblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFOVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gQWNjZXNzaW5nIGJpbmFyeS1kYXRhIHJlc3BvbnNlVGV4dCB0aHJvd3MgYW4gZXhjZXB0aW9uXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyAoIzExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0dHlwZW9mIHhoci5yZXNwb25zZVRleHQgPT09IFwic3RyaW5nXCIgPyB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRleHQ6IHhoci5yZXNwb25zZVRleHRcblx0XHRcdFx0XHRcdFx0XHRcdH0gOiB1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHR4aHIub25lcnJvciA9IGNhbGxiYWNrKFwiZXJyb3JcIik7XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIHRoZSBhYm9ydCBjYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IHhockNhbGxiYWNrc1sgaWQgXSA9IGNhbGxiYWNrKFwiYWJvcnRcIik7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pXG5cdFx0XHRcdFx0eGhyLnNlbmQoIG9wdGlvbnMuaGFzQ29udGVudCAmJiBvcHRpb25zLmRhdGEgfHwgbnVsbCApO1xuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHQvLyAjMTQ2ODM6IE9ubHkgcmV0aHJvdyBpZiB0aGlzIGhhc24ndCBiZWVuIG5vdGlmaWVkIGFzIGFuIGVycm9yIHlldFxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59KTtcblxuXG5cblxuLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGVcbmpRdWVyeS5hamF4U2V0dXAoe1xuXHRhY2NlcHRzOiB7XG5cdFx0c2NyaXB0OiBcInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcblx0fSxcblx0Y29udGVudHM6IHtcblx0XHRzY3JpcHQ6IC8oPzpqYXZhfGVjbWEpc2NyaXB0L1xuXHR9LFxuXHRjb252ZXJ0ZXJzOiB7XG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7XG5cdFx0XHRyZXR1cm4gdGV4dDtcblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jYWNoZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdHMuY2FjaGUgPSBmYWxzZTtcblx0fVxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy50eXBlID0gXCJHRVRcIjtcblx0fVxufSk7XG5cbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXHQvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIHJlcXVlc3RzXG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIF8sIGNvbXBsZXRlICkge1xuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoXCI8c2NyaXB0PlwiKS5wcm9wKHtcblx0XHRcdFx0XHRhc3luYzogdHJ1ZSxcblx0XHRcdFx0XHRjaGFyc2V0OiBzLnNjcmlwdENoYXJzZXQsXG5cdFx0XHRcdFx0c3JjOiBzLnVybFxuXHRcdFx0XHR9KS5vbihcblx0XHRcdFx0XHRcImxvYWQgZXJyb3JcIixcblx0XHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRzY3JpcHQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XG5cdFx0XHRcdFx0XHRpZiAoIGV2dCApIHtcblx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIGV2dC50eXBlID09PSBcImVycm9yXCIgPyA0MDQgOiAyMDAsIGV2dC50eXBlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHRbIDAgXSApO1xuXHRcdFx0fSxcblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcblx0cmpzb25wID0gLyg9KVxcPyg/PSZ8JCl8XFw/XFw/LztcblxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xualF1ZXJ5LmFqYXhTZXR1cCh7XG5cdGpzb25wOiBcImNhbGxiYWNrXCIsXG5cdGpzb25wQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlKysgKSApO1xuXHRcdHRoaXNbIGNhbGxiYWNrIF0gPSB0cnVlO1xuXHRcdHJldHVybiBjYWxsYmFjaztcblx0fVxufSk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiYgISggcy5jb250ZW50VHlwZSB8fCBcIlwiICkuaW5kZXhPZihcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKSAmJiByanNvbnAudGVzdCggcy5kYXRhICkgJiYgXCJkYXRhXCJcblx0XHQpO1xuXG5cdC8vIEhhbmRsZSBpZmYgdGhlIGV4cGVjdGVkIGRhdGEgdHlwZSBpcyBcImpzb25wXCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXRcblx0aWYgKCBqc29uUHJvcCB8fCBzLmRhdGFUeXBlc1sgMCBdID09PSBcImpzb25wXCIgKSB7XG5cblx0XHQvLyBHZXQgY2FsbGJhY2sgbmFtZSwgcmVtZW1iZXJpbmcgcHJlZXhpc3RpbmcgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0XG5cdFx0Y2FsbGJhY2tOYW1lID0gcy5qc29ucENhbGxiYWNrID0galF1ZXJ5LmlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID9cblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcblx0XHRcdHMuanNvbnBDYWxsYmFjaztcblxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcblx0XHRpZiAoIGpzb25Qcm9wICkge1xuXHRcdFx0c1sganNvblByb3AgXSA9IHNbIGpzb25Qcm9wIF0ucmVwbGFjZSggcmpzb25wLCBcIiQxXCIgKyBjYWxsYmFja05hbWUgKTtcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcblx0XHRcdHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIHMudXJsICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmpzb25wICsgXCI9XCIgKyBjYWxsYmFja05hbWU7XG5cdFx0fVxuXG5cdFx0Ly8gVXNlIGRhdGEgY29udmVydGVyIHRvIHJldHJpZXZlIGpzb24gYWZ0ZXIgc2NyaXB0IGV4ZWN1dGlvblxuXHRcdHMuY29udmVydGVyc1tcInNjcmlwdCBqc29uXCJdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHtcblx0XHRcdFx0alF1ZXJ5LmVycm9yKCBjYWxsYmFja05hbWUgKyBcIiB3YXMgbm90IGNhbGxlZFwiICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTtcblx0XHR9O1xuXG5cdFx0Ly8gZm9yY2UganNvbiBkYXRhVHlwZVxuXHRcdHMuZGF0YVR5cGVzWyAwIF0gPSBcImpzb25cIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tcblx0XHRvdmVyd3JpdHRlbiA9IHdpbmRvd1sgY2FsbGJhY2tOYW1lIF07XG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBhcmd1bWVudHM7XG5cdFx0fTtcblxuXHRcdC8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKVxuXHRcdGpxWEhSLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIFJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcblx0XHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBvdmVyd3JpdHRlbjtcblxuXHRcdFx0Ly8gU2F2ZSBiYWNrIGFzIGZyZWVcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XG5cdFx0XHRcdC8vIG1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxuXHRcdFx0XHRzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHRcdFx0Ly8gc2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxuXHRcdFx0XHRvbGRDYWxsYmFja3MucHVzaCggY2FsbGJhY2tOYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbGwgaWYgaXQgd2FzIGEgZnVuY3Rpb24gYW5kIHdlIGhhdmUgYSByZXNwb25zZVxuXHRcdFx0aWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBqUXVlcnkuaXNGdW5jdGlvbiggb3ZlcndyaXR0ZW4gKSApIHtcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcblx0XHR9KTtcblxuXHRcdC8vIERlbGVnYXRlIHRvIHNjcmlwdFxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xuXHR9XG59KTtcblxuXG5cblxuLy8gZGF0YTogc3RyaW5nIG9mIGh0bWxcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCwgZGVmYXVsdHMgdG8gZG9jdW1lbnRcbi8vIGtlZXBTY3JpcHRzIChvcHRpb25hbCk6IElmIHRydWUsIHdpbGwgaW5jbHVkZSBzY3JpcHRzIHBhc3NlZCBpbiB0aGUgaHRtbCBzdHJpbmdcbmpRdWVyeS5wYXJzZUhUTUwgPSBmdW5jdGlvbiggZGF0YSwgY29udGV4dCwga2VlcFNjcmlwdHMgKSB7XG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblxuXHR2YXIgcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICksXG5cdFx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWzFdICkgXTtcblx0fVxuXG5cdHBhcnNlZCA9IGpRdWVyeS5idWlsZEZyYWdtZW50KCBbIGRhdGEgXSwgY29udGV4dCwgc2NyaXB0cyApO1xuXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkoIHNjcmlwdHMgKS5yZW1vdmUoKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBwYXJzZWQuY2hpbGROb2RlcyApO1xufTtcblxuXG4vLyBLZWVwIGEgY29weSBvZiB0aGUgb2xkIGxvYWQgbWV0aG9kXG52YXIgX2xvYWQgPSBqUXVlcnkuZm4ubG9hZDtcblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0aWYgKCB0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiICYmIF9sb2FkICkge1xuXHRcdHJldHVybiBfbG9hZC5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdH1cblxuXHR2YXIgc2VsZWN0b3IsIHR5cGUsIHJlc3BvbnNlLFxuXHRcdHNlbGYgPSB0aGlzLFxuXHRcdG9mZiA9IHVybC5pbmRleE9mKFwiIFwiKTtcblxuXHRpZiAoIG9mZiA+PSAwICkge1xuXHRcdHNlbGVjdG9yID0galF1ZXJ5LnRyaW0oIHVybC5zbGljZSggb2ZmICkgKTtcblx0XHR1cmwgPSB1cmwuc2xpY2UoIDAsIG9mZiApO1xuXHR9XG5cblx0Ly8gSWYgaXQncyBhIGZ1bmN0aW9uXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xuXG5cdFx0Ly8gV2UgYXNzdW1lIHRoYXQgaXQncyB0aGUgY2FsbGJhY2tcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcblx0XHRwYXJhbXMgPSB1bmRlZmluZWQ7XG5cblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xuXHR9IGVsc2UgaWYgKCBwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHR0eXBlID0gXCJQT1NUXCI7XG5cdH1cblxuXHQvLyBJZiB3ZSBoYXZlIGVsZW1lbnRzIHRvIG1vZGlmeSwgbWFrZSB0aGUgcmVxdWVzdFxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcblx0XHRqUXVlcnkuYWpheCh7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gaWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcblx0XHRcdGRhdGE6IHBhcmFtc1xuXHRcdH0pLmRvbmUoZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoXCI8ZGl2PlwiKS5hcHBlbmQoIGpRdWVyeS5wYXJzZUhUTUwoIHJlc3BvbnNlVGV4dCApICkuZmluZCggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcblx0XHRcdFx0cmVzcG9uc2VUZXh0ICk7XG5cblx0XHR9KS5jb21wbGV0ZSggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGNhbGxiYWNrLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gdGhpcztcbn07XG5cblxuXG5cbi8vIEF0dGFjaCBhIGJ1bmNoIG9mIGZ1bmN0aW9ucyBmb3IgaGFuZGxpbmcgY29tbW9uIEFKQVggZXZlbnRzXG5qUXVlcnkuZWFjaCggWyBcImFqYXhTdGFydFwiLCBcImFqYXhTdG9wXCIsIFwiYWpheENvbXBsZXRlXCIsIFwiYWpheEVycm9yXCIsIFwiYWpheFN1Y2Nlc3NcIiwgXCJhamF4U2VuZFwiIF0sIGZ1bmN0aW9uKCBpLCB0eXBlICkge1xuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZSwgZm4gKTtcblx0fTtcbn0pO1xuXG5cblxuXG5qUXVlcnkuZXhwci5maWx0ZXJzLmFuaW1hdGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiBqUXVlcnkuZ3JlcChqUXVlcnkudGltZXJzLCBmdW5jdGlvbiggZm4gKSB7XG5cdFx0cmV0dXJuIGVsZW0gPT09IGZuLmVsZW07XG5cdH0pLmxlbmd0aDtcbn07XG5cblxuXG5cbnZhciBkb2NFbGVtID0gd2luZG93LmRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuLyoqXG4gKiBHZXRzIGEgd2luZG93IGZyb20gYW4gZWxlbWVudFxuICovXG5mdW5jdGlvbiBnZXRXaW5kb3coIGVsZW0gKSB7XG5cdHJldHVybiBqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSA/IGVsZW0gOiBlbGVtLm5vZGVUeXBlID09PSA5ICYmIGVsZW0uZGVmYXVsdFZpZXc7XG59XG5cbmpRdWVyeS5vZmZzZXQgPSB7XG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XG5cdFx0dmFyIGN1clBvc2l0aW9uLCBjdXJMZWZ0LCBjdXJDU1NUb3AsIGN1clRvcCwgY3VyT2Zmc2V0LCBjdXJDU1NMZWZ0LCBjYWxjdWxhdGVQb3NpdGlvbixcblx0XHRcdHBvc2l0aW9uID0galF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICksXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXG5cdFx0XHRwcm9wcyA9IHt9O1xuXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxuXHRcdGlmICggcG9zaXRpb24gPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHRcdH1cblxuXHRcdGN1ck9mZnNldCA9IGN1ckVsZW0ub2Zmc2V0KCk7XG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xuXHRcdGN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImxlZnRcIiApO1xuXHRcdGNhbGN1bGF0ZVBvc2l0aW9uID0gKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSAmJlxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZihcImF1dG9cIikgPiAtMTtcblxuXHRcdC8vIE5lZWQgdG8gYmUgYWJsZSB0byBjYWxjdWxhdGUgcG9zaXRpb24gaWYgZWl0aGVyXG5cdFx0Ly8gdG9wIG9yIGxlZnQgaXMgYXV0byBhbmQgcG9zaXRpb24gaXMgZWl0aGVyIGFic29sdXRlIG9yIGZpeGVkXG5cdFx0aWYgKCBjYWxjdWxhdGVQb3NpdGlvbiApIHtcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xuXHRcdFx0Y3VyVG9wID0gY3VyUG9zaXRpb24udG9wO1xuXHRcdFx0Y3VyTGVmdCA9IGN1clBvc2l0aW9uLmxlZnQ7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3VyVG9wID0gcGFyc2VGbG9hdCggY3VyQ1NTVG9wICkgfHwgMDtcblx0XHRcdGN1ckxlZnQgPSBwYXJzZUZsb2F0KCBjdXJDU1NMZWZ0ICkgfHwgMDtcblx0XHR9XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XG5cdFx0XHRvcHRpb25zID0gb3B0aW9ucy5jYWxsKCBlbGVtLCBpLCBjdXJPZmZzZXQgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdGlvbnMudG9wICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xuXHRcdH1cblx0XHRpZiAoIG9wdGlvbnMubGVmdCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XG5cdFx0fVxuXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcblx0XHRcdG9wdGlvbnMudXNpbmcuY2FsbCggZWxlbSwgcHJvcHMgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiBvcHRpb25zID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHR0aGlzIDpcblx0XHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRcdGpRdWVyeS5vZmZzZXQuc2V0T2Zmc2V0KCB0aGlzLCBvcHRpb25zLCBpICk7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHZhciBkb2NFbGVtLCB3aW4sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0Ym94ID0geyB0b3A6IDAsIGxlZnQ6IDAgfSxcblx0XHRcdGRvYyA9IGVsZW0gJiYgZWxlbS5vd25lckRvY3VtZW50O1xuXG5cdFx0aWYgKCAhZG9jICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0Ly8gTWFrZSBzdXJlIGl0J3Mgbm90IGEgZGlzY29ubmVjdGVkIERPTSBub2RlXG5cdFx0aWYgKCAhalF1ZXJ5LmNvbnRhaW5zKCBkb2NFbGVtLCBlbGVtICkgKSB7XG5cdFx0XHRyZXR1cm4gYm94O1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IEJsYWNrQmVycnkgNSwgaU9TIDMgKG9yaWdpbmFsIGlQaG9uZSlcblx0XHQvLyBJZiB3ZSBkb24ndCBoYXZlIGdCQ1IsIGp1c3QgdXNlIDAsMCByYXRoZXIgdGhhbiBlcnJvclxuXHRcdGlmICggdHlwZW9mIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0ICE9PSBzdHJ1bmRlZmluZWQgKSB7XG5cdFx0XHRib3ggPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdH1cblx0XHR3aW4gPSBnZXRXaW5kb3coIGRvYyApO1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IGJveC50b3AgKyB3aW4ucGFnZVlPZmZzZXQgLSBkb2NFbGVtLmNsaWVudFRvcCxcblx0XHRcdGxlZnQ6IGJveC5sZWZ0ICsgd2luLnBhZ2VYT2Zmc2V0IC0gZG9jRWxlbS5jbGllbnRMZWZ0XG5cdFx0fTtcblx0fSxcblxuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpc1sgMCBdICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBvZmZzZXRQYXJlbnQsIG9mZnNldCxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRwYXJlbnRPZmZzZXQgPSB7IHRvcDogMCwgbGVmdDogMCB9O1xuXG5cdFx0Ly8gRml4ZWQgZWxlbWVudHMgYXJlIG9mZnNldCBmcm9tIHdpbmRvdyAocGFyZW50T2Zmc2V0ID0ge3RvcDowLCBsZWZ0OiAwfSwgYmVjYXVzZSBpdCBpcyBpdHMgb25seSBvZmZzZXQgcGFyZW50XG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xuXHRcdFx0Ly8gQXNzdW1lIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBpcyB0aGVyZSB3aGVuIGNvbXB1dGVkIHBvc2l0aW9uIGlzIGZpeGVkXG5cdFx0XHRvZmZzZXQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50XG5cdFx0XHRvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCgpO1xuXG5cdFx0XHQvLyBHZXQgY29ycmVjdCBvZmZzZXRzXG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXHRcdFx0aWYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJodG1sXCIgKSApIHtcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcblx0XHRcdHBhcmVudE9mZnNldC50b3AgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50WyAwIF0sIFwiYm9yZGVyVG9wV2lkdGhcIiwgdHJ1ZSApO1xuXHRcdFx0cGFyZW50T2Zmc2V0LmxlZnQgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50WyAwIF0sIFwiYm9yZGVyTGVmdFdpZHRoXCIsIHRydWUgKTtcblx0XHR9XG5cblx0XHQvLyBTdWJ0cmFjdCBwYXJlbnQgb2Zmc2V0cyBhbmQgZWxlbWVudCBtYXJnaW5zXG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogb2Zmc2V0LnRvcCAtIHBhcmVudE9mZnNldC50b3AgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpblRvcFwiLCB0cnVlICksXG5cdFx0XHRsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0IC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIsIHRydWUgKVxuXHRcdH07XG5cdH0sXG5cblx0b2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQgfHwgZG9jRWxlbTtcblxuXHRcdFx0d2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnQsIFwiaHRtbFwiICkgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApICkge1xuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0UGFyZW50O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gb2Zmc2V0UGFyZW50IHx8IGRvY0VsZW07XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cdFx0XHR2YXIgd2luID0gZ2V0V2luZG93KCBlbGVtICk7XG5cblx0XHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiB3aW5kb3cucGFnZVhPZmZzZXQsXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luZG93LnBhZ2VZT2Zmc2V0XG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoLCBudWxsICk7XG5cdH07XG59KTtcblxuLy8gU3VwcG9ydDogU2FmYXJpPDcrLCBDaHJvbWU8MzcrXG4vLyBBZGQgdGhlIHRvcC9sZWZ0IGNzc0hvb2tzIHVzaW5nIGpRdWVyeS5mbi5wb3NpdGlvblxuLy8gV2Via2l0IGJ1ZzogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTI5MDg0XG4vLyBCbGluayBidWc6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0yMjkyODBcbi8vIGdldENvbXB1dGVkU3R5bGUgcmV0dXJucyBwZXJjZW50IHdoZW4gc3BlY2lmaWVkIGZvciB0b3AvbGVmdC9ib3R0b20vcmlnaHQ7XG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwganVzdCBjaGVjayBmb3IgaXQgaGVyZVxualF1ZXJ5LmVhY2goIFsgXCJ0b3BcIiwgXCJsZWZ0XCIgXSwgZnVuY3Rpb24oIGksIHByb3AgKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgcHJvcCBdID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnBpeGVsUG9zaXRpb24sXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdFx0Y29tcHV0ZWQgPSBjdXJDU1MoIGVsZW0sIHByb3AgKTtcblx0XHRcdFx0Ly8gSWYgY3VyQ1NTIHJldHVybnMgcGVyY2VudGFnZSwgZmFsbGJhY2sgdG8gb2Zmc2V0XG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBlbGVtICkucG9zaXRpb24oKVsgcHJvcCBdICsgXCJweFwiIDpcblx0XHRcdFx0XHRjb21wdXRlZDtcblx0XHRcdH1cblx0XHR9XG5cdCk7XG59KTtcblxuXG4vLyBDcmVhdGUgaW5uZXJIZWlnaHQsIGlubmVyV2lkdGgsIGhlaWdodCwgd2lkdGgsIG91dGVySGVpZ2h0IGFuZCBvdXRlcldpZHRoIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IEhlaWdodDogXCJoZWlnaHRcIiwgV2lkdGg6IFwid2lkdGhcIiB9LCBmdW5jdGlvbiggbmFtZSwgdHlwZSApIHtcblx0alF1ZXJ5LmVhY2goIHsgcGFkZGluZzogXCJpbm5lclwiICsgbmFtZSwgY29udGVudDogdHlwZSwgXCJcIjogXCJvdXRlclwiICsgbmFtZSB9LCBmdW5jdGlvbiggZGVmYXVsdEV4dHJhLCBmdW5jTmFtZSApIHtcblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0Ly8gQXMgb2YgNS84LzIwMTIgdGhpcyB3aWxsIHlpZWxkIGluY29ycmVjdCByZXN1bHRzIGZvciBNb2JpbGUgU2FmYXJpLCBidXQgdGhlcmVcblx0XHRcdFx0XHQvLyBpc24ndCBhIHdob2xlIGxvdCB3ZSBjYW4gZG8uIFNlZSBwdWxsIHJlcXVlc3QgYXQgdGhpcyBVUkwgZm9yIGRpc2N1c3Npb246XG5cdFx0XHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvcHVsbC83NjRcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbIFwiY2xpZW50XCIgKyBuYW1lIF07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBHZXQgZG9jdW1lbnQgd2lkdGggb3IgaGVpZ2h0XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRkb2MgPSBlbGVtLmRvY3VtZW50RWxlbWVudDtcblxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcblx0XHRcdFx0XHQvLyB3aGljaGV2ZXIgaXMgZ3JlYXRlc3Rcblx0XHRcdFx0XHRyZXR1cm4gTWF0aC5tYXgoXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJvZmZzZXRcIiArIG5hbWUgXSwgZG9jWyBcIm9mZnNldFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZG9jWyBcImNsaWVudFwiICsgbmFtZSBdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0XHQvLyBHZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50LCByZXF1ZXN0aW5nIGJ1dCBub3QgZm9yY2luZyBwYXJzZUZsb2F0XG5cdFx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgdHlwZSwgZXh0cmEgKSA6XG5cblx0XHRcdFx0XHQvLyBTZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50XG5cdFx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCB0eXBlLCB2YWx1ZSwgZXh0cmEgKTtcblx0XHRcdH0sIHR5cGUsIGNoYWluYWJsZSA/IG1hcmdpbiA6IHVuZGVmaW5lZCwgY2hhaW5hYmxlLCBudWxsICk7XG5cdFx0fTtcblx0fSk7XG59KTtcblxuXG4vLyBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIGNvbnRhaW5lZCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldFxualF1ZXJ5LmZuLnNpemUgPSBmdW5jdGlvbigpIHtcblx0cmV0dXJuIHRoaXMubGVuZ3RoO1xufTtcblxualF1ZXJ5LmZuLmFuZFNlbGYgPSBqUXVlcnkuZm4uYWRkQmFjaztcblxuXG5cblxuLy8gUmVnaXN0ZXIgYXMgYSBuYW1lZCBBTUQgbW9kdWxlLCBzaW5jZSBqUXVlcnkgY2FuIGJlIGNvbmNhdGVuYXRlZCB3aXRoIG90aGVyXG4vLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0XG4vLyB1bmRlcnN0YW5kcyBhbm9ueW1vdXMgQU1EIG1vZHVsZXMuIEEgbmFtZWQgQU1EIGlzIHNhZmVzdCBhbmQgbW9zdCByb2J1c3Rcbi8vIHdheSB0byByZWdpc3Rlci4gTG93ZXJjYXNlIGpxdWVyeSBpcyB1c2VkIGJlY2F1c2UgQU1EIG1vZHVsZSBuYW1lcyBhcmVcbi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZVxuLy8gZmlsZSBuYW1lLiBEbyB0aGlzIGFmdGVyIGNyZWF0aW5nIHRoZSBnbG9iYWwgc28gdGhhdCBpZiBhbiBBTUQgbW9kdWxlIHdhbnRzXG4vLyB0byBjYWxsIG5vQ29uZmxpY3QgdG8gaGlkZSB0aGlzIHZlcnNpb24gb2YgalF1ZXJ5LCBpdCB3aWxsIHdvcmsuXG5cbi8vIE5vdGUgdGhhdCBmb3IgbWF4aW11bSBwb3J0YWJpbGl0eSwgbGlicmFyaWVzIHRoYXQgYXJlIG5vdCBqUXVlcnkgc2hvdWxkXG4vLyBkZWNsYXJlIHRoZW1zZWx2ZXMgYXMgYW5vbnltb3VzIG1vZHVsZXMsIGFuZCBhdm9pZCBzZXR0aW5nIGEgZ2xvYmFsIGlmIGFuXG4vLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2pyYnVya2UvcmVxdWlyZWpzL3dpa2kvVXBkYXRpbmctZXhpc3RpbmctbGlicmFyaWVzI3dpa2ktYW5vblxuXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xuXHRkZWZpbmUoIFwianF1ZXJ5XCIsIFtdLCBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5O1xuXHR9KTtcbn1cblxuXG5cblxudmFyXG5cdC8vIE1hcCBvdmVyIGpRdWVyeSBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfalF1ZXJ5ID0gd2luZG93LmpRdWVyeSxcblxuXHQvLyBNYXAgb3ZlciB0aGUgJCBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfJCA9IHdpbmRvdy4kO1xuXG5qUXVlcnkubm9Db25mbGljdCA9IGZ1bmN0aW9uKCBkZWVwICkge1xuXHRpZiAoIHdpbmRvdy4kID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LiQgPSBfJDtcblx0fVxuXG5cdGlmICggZGVlcCAmJiB3aW5kb3cualF1ZXJ5ID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LmpRdWVyeSA9IF9qUXVlcnk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5O1xufTtcblxuLy8gRXhwb3NlIGpRdWVyeSBhbmQgJCBpZGVudGlmaWVycywgZXZlbiBpbiBBTURcbi8vICgjNzEwMiNjb21tZW50OjEwLCBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzU1Nylcbi8vIGFuZCBDb21tb25KUyBmb3IgYnJvd3NlciBlbXVsYXRvcnMgKCMxMzU2NilcbmlmICggdHlwZW9mIG5vR2xvYmFsID09PSBzdHJ1bmRlZmluZWQgKSB7XG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcbn1cblxuXG5cblxucmV0dXJuIGpRdWVyeTtcblxufSkpO1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307Ly8hIG1vbWVudC5qc1xuLy8hIHZlcnNpb24gOiAyLjguNFxuLy8hIGF1dGhvcnMgOiBUaW0gV29vZCwgSXNrcmVuIENoZXJuZXYsIE1vbWVudC5qcyBjb250cmlidXRvcnNcbi8vISBsaWNlbnNlIDogTUlUXG4vLyEgbW9tZW50anMuY29tXG5cbihmdW5jdGlvbiAodW5kZWZpbmVkKSB7XG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBDb25zdGFudHNcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbiAgICB2YXIgbW9tZW50LFxuICAgICAgICBWRVJTSU9OID0gJzIuOC40JyxcbiAgICAgICAgLy8gdGhlIGdsb2JhbC1zY29wZSB0aGlzIGlzIE5PVCB0aGUgZ2xvYmFsIG9iamVjdCBpbiBOb2RlLmpzXG4gICAgICAgIGdsb2JhbFNjb3BlID0gdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0aGlzLFxuICAgICAgICBvbGRHbG9iYWxNb21lbnQsXG4gICAgICAgIHJvdW5kID0gTWF0aC5yb3VuZCxcbiAgICAgICAgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LFxuICAgICAgICBpLFxuXG4gICAgICAgIFlFQVIgPSAwLFxuICAgICAgICBNT05USCA9IDEsXG4gICAgICAgIERBVEUgPSAyLFxuICAgICAgICBIT1VSID0gMyxcbiAgICAgICAgTUlOVVRFID0gNCxcbiAgICAgICAgU0VDT05EID0gNSxcbiAgICAgICAgTUlMTElTRUNPTkQgPSA2LFxuXG4gICAgICAgIC8vIGludGVybmFsIHN0b3JhZ2UgZm9yIGxvY2FsZSBjb25maWcgZmlsZXNcbiAgICAgICAgbG9jYWxlcyA9IHt9LFxuXG4gICAgICAgIC8vIGV4dHJhIG1vbWVudCBpbnRlcm5hbCBwcm9wZXJ0aWVzIChwbHVnaW5zIHJlZ2lzdGVyIHByb3BzIGhlcmUpXG4gICAgICAgIG1vbWVudFByb3BlcnRpZXMgPSBbXSxcblxuICAgICAgICAvLyBjaGVjayBmb3Igbm9kZUpTXG4gICAgICAgIGhhc01vZHVsZSA9ICh0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyAmJiBtb2R1bGUgJiYgbW9kdWxlLmV4cG9ydHMpLFxuXG4gICAgICAgIC8vIEFTUC5ORVQganNvbiBkYXRlIGZvcm1hdCByZWdleFxuICAgICAgICBhc3BOZXRKc29uUmVnZXggPSAvXlxcLz9EYXRlXFwoKFxcLT9cXGQrKS9pLFxuICAgICAgICBhc3BOZXRUaW1lU3Bhbkpzb25SZWdleCA9IC8oXFwtKT8oPzooXFxkKilcXC4pPyhcXGQrKVxcOihcXGQrKSg/OlxcOihcXGQrKVxcLj8oXFxkezN9KT8pPy8sXG5cbiAgICAgICAgLy8gZnJvbSBodHRwOi8vZG9jcy5jbG9zdXJlLWxpYnJhcnkuZ29vZ2xlY29kZS5jb20vZ2l0L2Nsb3N1cmVfZ29vZ19kYXRlX2RhdGUuanMuc291cmNlLmh0bWxcbiAgICAgICAgLy8gc29tZXdoYXQgbW9yZSBpbiBsaW5lIHdpdGggNC40LjMuMiAyMDA0IHNwZWMsIGJ1dCBhbGxvd3MgZGVjaW1hbCBhbnl3aGVyZVxuICAgICAgICBpc29EdXJhdGlvblJlZ2V4ID0gL14oLSk/UCg/Oig/OihbMC05LC5dKilZKT8oPzooWzAtOSwuXSopTSk/KD86KFswLTksLl0qKUQpPyg/OlQoPzooWzAtOSwuXSopSCk/KD86KFswLTksLl0qKU0pPyg/OihbMC05LC5dKilTKT8pP3woWzAtOSwuXSopVykkLyxcblxuICAgICAgICAvLyBmb3JtYXQgdG9rZW5zXG4gICAgICAgIGZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTW98TU0/TT9NP3xEb3xERERvfEREP0Q/RD98ZGRkP2Q/fGRvP3x3W298d10/fFdbb3xXXT98UXxZWVlZWVl8WVlZWVl8WVlZWXxZWXxnZyhnZ2c/KT98R0coR0dHPyk/fGV8RXxhfEF8aGg/fEhIP3xtbT98c3M/fFN7MSw0fXx4fFh8eno/fFpaP3wuKS9nLFxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMgPSAvKFxcW1teXFxbXSpcXF0pfChcXFxcKT8oTFRTfExUfExMP0w/TD98bHsxLDR9KS9nLFxuXG4gICAgICAgIC8vIHBhcnNpbmcgdG9rZW4gcmVnZXhlc1xuICAgICAgICBwYXJzZVRva2VuT25lT3JUd29EaWdpdHMgPSAvXFxkXFxkPy8sIC8vIDAgLSA5OVxuICAgICAgICBwYXJzZVRva2VuT25lVG9UaHJlZURpZ2l0cyA9IC9cXGR7MSwzfS8sIC8vIDAgLSA5OTlcbiAgICAgICAgcGFyc2VUb2tlbk9uZVRvRm91ckRpZ2l0cyA9IC9cXGR7MSw0fS8sIC8vIDAgLSA5OTk5XG4gICAgICAgIHBhcnNlVG9rZW5PbmVUb1NpeERpZ2l0cyA9IC9bK1xcLV0/XFxkezEsNn0vLCAvLyAtOTk5LDk5OSAtIDk5OSw5OTlcbiAgICAgICAgcGFyc2VUb2tlbkRpZ2l0cyA9IC9cXGQrLywgLy8gbm9uemVybyBudW1iZXIgb2YgZGlnaXRzXG4gICAgICAgIHBhcnNlVG9rZW5Xb3JkID0gL1swLTldKlsnYS16XFx1MDBBMC1cXHUwNUZGXFx1MDcwMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSt8W1xcdTA2MDAtXFx1MDZGRlxcL10rKFxccyo/W1xcdTA2MDAtXFx1MDZGRl0rKXsxLDJ9L2ksIC8vIGFueSB3b3JkIChvciB0d28pIGNoYXJhY3RlcnMgb3IgbnVtYmVycyBpbmNsdWRpbmcgdHdvL3RocmVlIHdvcmQgbW9udGggaW4gYXJhYmljLlxuICAgICAgICBwYXJzZVRva2VuVGltZXpvbmUgPSAvWnxbXFwrXFwtXVxcZFxcZDo/XFxkXFxkL2dpLCAvLyArMDA6MDAgLTAwOjAwICswMDAwIC0wMDAwIG9yIFpcbiAgICAgICAgcGFyc2VUb2tlblQgPSAvVC9pLCAvLyBUIChJU08gc2VwYXJhdG9yKVxuICAgICAgICBwYXJzZVRva2VuT2Zmc2V0TXMgPSAvW1xcK1xcLV0/XFxkKy8sIC8vIDEyMzQ1Njc4OTAxMjNcbiAgICAgICAgcGFyc2VUb2tlblRpbWVzdGFtcE1zID0gL1tcXCtcXC1dP1xcZCsoXFwuXFxkezEsM30pPy8sIC8vIDEyMzQ1Njc4OSAxMjM0NTY3ODkuMTIzXG5cbiAgICAgICAgLy9zdHJpY3QgcGFyc2luZyByZWdleGVzXG4gICAgICAgIHBhcnNlVG9rZW5PbmVEaWdpdCA9IC9cXGQvLCAvLyAwIC0gOVxuICAgICAgICBwYXJzZVRva2VuVHdvRGlnaXRzID0gL1xcZFxcZC8sIC8vIDAwIC0gOTlcbiAgICAgICAgcGFyc2VUb2tlblRocmVlRGlnaXRzID0gL1xcZHszfS8sIC8vIDAwMCAtIDk5OVxuICAgICAgICBwYXJzZVRva2VuRm91ckRpZ2l0cyA9IC9cXGR7NH0vLCAvLyAwMDAwIC0gOTk5OVxuICAgICAgICBwYXJzZVRva2VuU2l4RGlnaXRzID0gL1srLV0/XFxkezZ9LywgLy8gLTk5OSw5OTkgLSA5OTksOTk5XG4gICAgICAgIHBhcnNlVG9rZW5TaWduZWROdW1iZXIgPSAvWystXT9cXGQrLywgLy8gLWluZiAtIGluZlxuXG4gICAgICAgIC8vIGlzbyA4NjAxIHJlZ2V4XG4gICAgICAgIC8vIDAwMDAtMDAtMDAgMDAwMC1XMDAgb3IgMDAwMC1XMDAtMCArIFQgKyAwMCBvciAwMDowMCBvciAwMDowMDowMCBvciAwMDowMDowMC4wMDAgKyArMDA6MDAgb3IgKzAwMDAgb3IgKzAwKVxuICAgICAgICBpc29SZWdleCA9IC9eXFxzKig/OlsrLV1cXGR7Nn18XFxkezR9KS0oPzooXFxkXFxkLVxcZFxcZCl8KFdcXGRcXGQkKXwoV1xcZFxcZC1cXGQpfChcXGRcXGRcXGQpKSgoVHwgKShcXGRcXGQoOlxcZFxcZCg6XFxkXFxkKFxcLlxcZCspPyk/KT8pPyhbXFwrXFwtXVxcZFxcZCg/Ojo/XFxkXFxkKT98XFxzKlopPyk/JC8sXG5cbiAgICAgICAgaXNvRm9ybWF0ID0gJ1lZWVktTU0tRERUSEg6bW06c3NaJyxcblxuICAgICAgICBpc29EYXRlcyA9IFtcbiAgICAgICAgICAgIFsnWVlZWVlZLU1NLUREJywgL1srLV1cXGR7Nn0tXFxkezJ9LVxcZHsyfS9dLFxuICAgICAgICAgICAgWydZWVlZLU1NLUREJywgL1xcZHs0fS1cXGR7Mn0tXFxkezJ9L10sXG4gICAgICAgICAgICBbJ0dHR0ctW1ddV1ctRScsIC9cXGR7NH0tV1xcZHsyfS1cXGQvXSxcbiAgICAgICAgICAgIFsnR0dHRy1bV11XVycsIC9cXGR7NH0tV1xcZHsyfS9dLFxuICAgICAgICAgICAgWydZWVlZLURERCcsIC9cXGR7NH0tXFxkezN9L11cbiAgICAgICAgXSxcblxuICAgICAgICAvLyBpc28gdGltZSBmb3JtYXRzIGFuZCByZWdleGVzXG4gICAgICAgIGlzb1RpbWVzID0gW1xuICAgICAgICAgICAgWydISDptbTpzcy5TU1NTJywgLyhUfCApXFxkXFxkOlxcZFxcZDpcXGRcXGRcXC5cXGQrL10sXG4gICAgICAgICAgICBbJ0hIOm1tOnNzJywgLyhUfCApXFxkXFxkOlxcZFxcZDpcXGRcXGQvXSxcbiAgICAgICAgICAgIFsnSEg6bW0nLCAvKFR8IClcXGRcXGQ6XFxkXFxkL10sXG4gICAgICAgICAgICBbJ0hIJywgLyhUfCApXFxkXFxkL11cbiAgICAgICAgXSxcblxuICAgICAgICAvLyB0aW1lem9uZSBjaHVua2VyICcrMTA6MDAnID4gWycxMCcsICcwMCddIG9yICctMTUzMCcgPiBbJy0xNScsICczMCddXG4gICAgICAgIHBhcnNlVGltZXpvbmVDaHVua2VyID0gLyhbXFwrXFwtXXxcXGRcXGQpL2dpLFxuXG4gICAgICAgIC8vIGdldHRlciBhbmQgc2V0dGVyIG5hbWVzXG4gICAgICAgIHByb3h5R2V0dGVyc0FuZFNldHRlcnMgPSAnRGF0ZXxIb3Vyc3xNaW51dGVzfFNlY29uZHN8TWlsbGlzZWNvbmRzJy5zcGxpdCgnfCcpLFxuICAgICAgICB1bml0TWlsbGlzZWNvbmRGYWN0b3JzID0ge1xuICAgICAgICAgICAgJ01pbGxpc2Vjb25kcycgOiAxLFxuICAgICAgICAgICAgJ1NlY29uZHMnIDogMWUzLFxuICAgICAgICAgICAgJ01pbnV0ZXMnIDogNmU0LFxuICAgICAgICAgICAgJ0hvdXJzJyA6IDM2ZTUsXG4gICAgICAgICAgICAnRGF5cycgOiA4NjRlNSxcbiAgICAgICAgICAgICdNb250aHMnIDogMjU5MmU2LFxuICAgICAgICAgICAgJ1llYXJzJyA6IDMxNTM2ZTZcbiAgICAgICAgfSxcblxuICAgICAgICB1bml0QWxpYXNlcyA9IHtcbiAgICAgICAgICAgIG1zIDogJ21pbGxpc2Vjb25kJyxcbiAgICAgICAgICAgIHMgOiAnc2Vjb25kJyxcbiAgICAgICAgICAgIG0gOiAnbWludXRlJyxcbiAgICAgICAgICAgIGggOiAnaG91cicsXG4gICAgICAgICAgICBkIDogJ2RheScsXG4gICAgICAgICAgICBEIDogJ2RhdGUnLFxuICAgICAgICAgICAgdyA6ICd3ZWVrJyxcbiAgICAgICAgICAgIFcgOiAnaXNvV2VlaycsXG4gICAgICAgICAgICBNIDogJ21vbnRoJyxcbiAgICAgICAgICAgIFEgOiAncXVhcnRlcicsXG4gICAgICAgICAgICB5IDogJ3llYXInLFxuICAgICAgICAgICAgREREIDogJ2RheU9mWWVhcicsXG4gICAgICAgICAgICBlIDogJ3dlZWtkYXknLFxuICAgICAgICAgICAgRSA6ICdpc29XZWVrZGF5JyxcbiAgICAgICAgICAgIGdnOiAnd2Vla1llYXInLFxuICAgICAgICAgICAgR0c6ICdpc29XZWVrWWVhcidcbiAgICAgICAgfSxcblxuICAgICAgICBjYW1lbEZ1bmN0aW9ucyA9IHtcbiAgICAgICAgICAgIGRheW9meWVhciA6ICdkYXlPZlllYXInLFxuICAgICAgICAgICAgaXNvd2Vla2RheSA6ICdpc29XZWVrZGF5JyxcbiAgICAgICAgICAgIGlzb3dlZWsgOiAnaXNvV2VlaycsXG4gICAgICAgICAgICB3ZWVreWVhciA6ICd3ZWVrWWVhcicsXG4gICAgICAgICAgICBpc293ZWVreWVhciA6ICdpc29XZWVrWWVhcidcbiAgICAgICAgfSxcblxuICAgICAgICAvLyBmb3JtYXQgZnVuY3Rpb24gc3RyaW5nc1xuICAgICAgICBmb3JtYXRGdW5jdGlvbnMgPSB7fSxcblxuICAgICAgICAvLyBkZWZhdWx0IHJlbGF0aXZlIHRpbWUgdGhyZXNob2xkc1xuICAgICAgICByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzID0ge1xuICAgICAgICAgICAgczogNDUsICAvLyBzZWNvbmRzIHRvIG1pbnV0ZVxuICAgICAgICAgICAgbTogNDUsICAvLyBtaW51dGVzIHRvIGhvdXJcbiAgICAgICAgICAgIGg6IDIyLCAgLy8gaG91cnMgdG8gZGF5XG4gICAgICAgICAgICBkOiAyNiwgIC8vIGRheXMgdG8gbW9udGhcbiAgICAgICAgICAgIE06IDExICAgLy8gbW9udGhzIHRvIHllYXJcbiAgICAgICAgfSxcblxuICAgICAgICAvLyB0b2tlbnMgdG8gb3JkaW5hbGl6ZSBhbmQgcGFkXG4gICAgICAgIG9yZGluYWxpemVUb2tlbnMgPSAnREREIHcgVyBNIEQgZCcuc3BsaXQoJyAnKSxcbiAgICAgICAgcGFkZGVkVG9rZW5zID0gJ00gRCBIIGggbSBzIHcgVycuc3BsaXQoJyAnKSxcblxuICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9ucyA9IHtcbiAgICAgICAgICAgIE0gICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubW9udGgoKSArIDE7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgTU1NICA6IGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzU2hvcnQodGhpcywgZm9ybWF0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBNTU1NIDogZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5tb250aHModGhpcywgZm9ybWF0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBEICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBEREQgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRheU9mWWVhcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGQgICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF5KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGQgICA6IGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNNaW4odGhpcywgZm9ybWF0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZGQgIDogZnVuY3Rpb24gKGZvcm1hdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS53ZWVrZGF5c1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGRkZCA6IGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXModGhpcywgZm9ybWF0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB3ICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndlZWsoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBXICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzb1dlZWsoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBZWSAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy55ZWFyKCkgJSAxMDAsIDIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFlZWVkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLnllYXIoKSwgNCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgWVlZWVkgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLnllYXIoKSwgNSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgWVlZWVlZIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciB5ID0gdGhpcy55ZWFyKCksIHNpZ24gPSB5ID49IDAgPyAnKycgOiAnLSc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNpZ24gKyBsZWZ0WmVyb0ZpbGwoTWF0aC5hYnMoeSksIDYpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdnICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLndlZWtZZWFyKCkgJSAxMDAsIDIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdnZ2cgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLndlZWtZZWFyKCksIDQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdnZ2dnIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy53ZWVrWWVhcigpLCA1KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBHRyAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy5pc29XZWVrWWVhcigpICUgMTAwLCAyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBHR0dHIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy5pc29XZWVrWWVhcigpLCA0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBHR0dHRyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMuaXNvV2Vla1llYXIoKSwgNSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53ZWVrZGF5KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgRSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrZGF5KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYSAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubWVyaWRpZW0odGhpcy5ob3VycygpLCB0aGlzLm1pbnV0ZXMoKSwgdHJ1ZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgQSAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubWVyaWRpZW0odGhpcy5ob3VycygpLCB0aGlzLm1pbnV0ZXMoKSwgZmFsc2UpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIEggICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaG91cnMoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhvdXJzKCkgJSAxMiB8fCAxMjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1pbnV0ZXMoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnNlY29uZHMoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBTICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0b0ludCh0aGlzLm1pbGxpc2Vjb25kcygpIC8gMTAwKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBTUyAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodG9JbnQodGhpcy5taWxsaXNlY29uZHMoKSAvIDEwKSwgMik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgU1NTICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMubWlsbGlzZWNvbmRzKCksIDMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFNTU1MgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLm1pbGxpc2Vjb25kcygpLCAzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBaICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhID0gLXRoaXMuem9uZSgpLFxuICAgICAgICAgICAgICAgICAgICBiID0gJysnO1xuICAgICAgICAgICAgICAgIGlmIChhIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBhID0gLWE7XG4gICAgICAgICAgICAgICAgICAgIGIgPSAnLSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBiICsgbGVmdFplcm9GaWxsKHRvSW50KGEgLyA2MCksIDIpICsgJzonICsgbGVmdFplcm9GaWxsKHRvSW50KGEpICUgNjAsIDIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFpaICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGEgPSAtdGhpcy56b25lKCksXG4gICAgICAgICAgICAgICAgICAgIGIgPSAnKyc7XG4gICAgICAgICAgICAgICAgaWYgKGEgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGEgPSAtYTtcbiAgICAgICAgICAgICAgICAgICAgYiA9ICctJztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGIgKyBsZWZ0WmVyb0ZpbGwodG9JbnQoYSAvIDYwKSwgMikgKyBsZWZ0WmVyb0ZpbGwodG9JbnQoYSkgJSA2MCwgMik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeiA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy56b25lQWJicigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHp6IDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnpvbmVOYW1lKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeCAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgWCAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy51bml4KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5xdWFydGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGVwcmVjYXRpb25zID0ge30sXG5cbiAgICAgICAgbGlzdHMgPSBbJ21vbnRocycsICdtb250aHNTaG9ydCcsICd3ZWVrZGF5cycsICd3ZWVrZGF5c1Nob3J0JywgJ3dlZWtkYXlzTWluJ107XG5cbiAgICAvLyBQaWNrIHRoZSBmaXJzdCBkZWZpbmVkIG9mIHR3byBvciB0aHJlZSBhcmd1bWVudHMuIGRmbCBjb21lcyBmcm9tXG4gICAgLy8gZGVmYXVsdC5cbiAgICBmdW5jdGlvbiBkZmwoYSwgYiwgYykge1xuICAgICAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMjogcmV0dXJuIGEgIT0gbnVsbCA/IGEgOiBiO1xuICAgICAgICAgICAgY2FzZSAzOiByZXR1cm4gYSAhPSBudWxsID8gYSA6IGIgIT0gbnVsbCA/IGIgOiBjO1xuICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdJbXBsZW1lbnQgbWUnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhc093blByb3AoYSwgYikge1xuICAgICAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChhLCBiKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZWZhdWx0UGFyc2luZ0ZsYWdzKCkge1xuICAgICAgICAvLyBXZSBuZWVkIHRvIGRlZXAgY2xvbmUgdGhpcyBvYmplY3QsIGFuZCBlczUgc3RhbmRhcmQgaXMgbm90IHZlcnlcbiAgICAgICAgLy8gaGVscGZ1bC5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVtcHR5IDogZmFsc2UsXG4gICAgICAgICAgICB1bnVzZWRUb2tlbnMgOiBbXSxcbiAgICAgICAgICAgIHVudXNlZElucHV0IDogW10sXG4gICAgICAgICAgICBvdmVyZmxvdyA6IC0yLFxuICAgICAgICAgICAgY2hhcnNMZWZ0T3ZlciA6IDAsXG4gICAgICAgICAgICBudWxsSW5wdXQgOiBmYWxzZSxcbiAgICAgICAgICAgIGludmFsaWRNb250aCA6IG51bGwsXG4gICAgICAgICAgICBpbnZhbGlkRm9ybWF0IDogZmFsc2UsXG4gICAgICAgICAgICB1c2VySW52YWxpZGF0ZWQgOiBmYWxzZSxcbiAgICAgICAgICAgIGlzbzogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwcmludE1zZyhtc2cpIHtcbiAgICAgICAgaWYgKG1vbWVudC5zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZ3MgPT09IGZhbHNlICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdEZXByZWNhdGlvbiB3YXJuaW5nOiAnICsgbXNnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRlcHJlY2F0ZShtc2csIGZuKSB7XG4gICAgICAgIHZhciBmaXJzdFRpbWUgPSB0cnVlO1xuICAgICAgICByZXR1cm4gZXh0ZW5kKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChmaXJzdFRpbWUpIHtcbiAgICAgICAgICAgICAgICBwcmludE1zZyhtc2cpO1xuICAgICAgICAgICAgICAgIGZpcnN0VGltZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH0sIGZuKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGVTaW1wbGUobmFtZSwgbXNnKSB7XG4gICAgICAgIGlmICghZGVwcmVjYXRpb25zW25hbWVdKSB7XG4gICAgICAgICAgICBwcmludE1zZyhtc2cpO1xuICAgICAgICAgICAgZGVwcmVjYXRpb25zW25hbWVdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBhZFRva2VuKGZ1bmMsIGNvdW50KSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoYSkge1xuICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbChmdW5jLmNhbGwodGhpcywgYSksIGNvdW50KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgZnVuY3Rpb24gb3JkaW5hbGl6ZVRva2VuKGZ1bmMsIHBlcmlvZCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5vcmRpbmFsKGZ1bmMuY2FsbCh0aGlzLCBhKSwgcGVyaW9kKTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICB3aGlsZSAob3JkaW5hbGl6ZVRva2Vucy5sZW5ndGgpIHtcbiAgICAgICAgaSA9IG9yZGluYWxpemVUb2tlbnMucG9wKCk7XG4gICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW2kgKyAnbyddID0gb3JkaW5hbGl6ZVRva2VuKGZvcm1hdFRva2VuRnVuY3Rpb25zW2ldLCBpKTtcbiAgICB9XG4gICAgd2hpbGUgKHBhZGRlZFRva2Vucy5sZW5ndGgpIHtcbiAgICAgICAgaSA9IHBhZGRlZFRva2Vucy5wb3AoKTtcbiAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnNbaSArIGldID0gcGFkVG9rZW4oZm9ybWF0VG9rZW5GdW5jdGlvbnNbaV0sIDIpO1xuICAgIH1cbiAgICBmb3JtYXRUb2tlbkZ1bmN0aW9ucy5EREREID0gcGFkVG9rZW4oZm9ybWF0VG9rZW5GdW5jdGlvbnMuRERELCAzKTtcblxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBDb25zdHJ1Y3RvcnNcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbiAgICBmdW5jdGlvbiBMb2NhbGUoKSB7XG4gICAgfVxuXG4gICAgLy8gTW9tZW50IHByb3RvdHlwZSBvYmplY3RcbiAgICBmdW5jdGlvbiBNb21lbnQoY29uZmlnLCBza2lwT3ZlcmZsb3cpIHtcbiAgICAgICAgaWYgKHNraXBPdmVyZmxvdyAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGNoZWNrT3ZlcmZsb3coY29uZmlnKTtcbiAgICAgICAgfVxuICAgICAgICBjb3B5Q29uZmlnKHRoaXMsIGNvbmZpZyk7XG4gICAgICAgIHRoaXMuX2QgPSBuZXcgRGF0ZSgrY29uZmlnLl9kKTtcbiAgICB9XG5cbiAgICAvLyBEdXJhdGlvbiBDb25zdHJ1Y3RvclxuICAgIGZ1bmN0aW9uIER1cmF0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQgPSBub3JtYWxpemVPYmplY3RVbml0cyhkdXJhdGlvbiksXG4gICAgICAgICAgICB5ZWFycyA9IG5vcm1hbGl6ZWRJbnB1dC55ZWFyIHx8IDAsXG4gICAgICAgICAgICBxdWFydGVycyA9IG5vcm1hbGl6ZWRJbnB1dC5xdWFydGVyIHx8IDAsXG4gICAgICAgICAgICBtb250aHMgPSBub3JtYWxpemVkSW5wdXQubW9udGggfHwgMCxcbiAgICAgICAgICAgIHdlZWtzID0gbm9ybWFsaXplZElucHV0LndlZWsgfHwgMCxcbiAgICAgICAgICAgIGRheXMgPSBub3JtYWxpemVkSW5wdXQuZGF5IHx8IDAsXG4gICAgICAgICAgICBob3VycyA9IG5vcm1hbGl6ZWRJbnB1dC5ob3VyIHx8IDAsXG4gICAgICAgICAgICBtaW51dGVzID0gbm9ybWFsaXplZElucHV0Lm1pbnV0ZSB8fCAwLFxuICAgICAgICAgICAgc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQgfHwgMCxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZCB8fCAwO1xuXG4gICAgICAgIC8vIHJlcHJlc2VudGF0aW9uIGZvciBkYXRlQWRkUmVtb3ZlXG4gICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyA9ICttaWxsaXNlY29uZHMgK1xuICAgICAgICAgICAgc2Vjb25kcyAqIDFlMyArIC8vIDEwMDBcbiAgICAgICAgICAgIG1pbnV0ZXMgKiA2ZTQgKyAvLyAxMDAwICogNjBcbiAgICAgICAgICAgIGhvdXJzICogMzZlNTsgLy8gMTAwMCAqIDYwICogNjBcbiAgICAgICAgLy8gQmVjYXVzZSBvZiBkYXRlQWRkUmVtb3ZlIHRyZWF0cyAyNCBob3VycyBhcyBkaWZmZXJlbnQgZnJvbSBhXG4gICAgICAgIC8vIGRheSB3aGVuIHdvcmtpbmcgYXJvdW5kIERTVCwgd2UgbmVlZCB0byBzdG9yZSB0aGVtIHNlcGFyYXRlbHlcbiAgICAgICAgdGhpcy5fZGF5cyA9ICtkYXlzICtcbiAgICAgICAgICAgIHdlZWtzICogNztcbiAgICAgICAgLy8gSXQgaXMgaW1wb3NzaWJsZSB0cmFuc2xhdGUgbW9udGhzIGludG8gZGF5cyB3aXRob3V0IGtub3dpbmdcbiAgICAgICAgLy8gd2hpY2ggbW9udGhzIHlvdSBhcmUgYXJlIHRhbGtpbmcgYWJvdXQsIHNvIHdlIGhhdmUgdG8gc3RvcmVcbiAgICAgICAgLy8gaXQgc2VwYXJhdGVseS5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gK21vbnRocyArXG4gICAgICAgICAgICBxdWFydGVycyAqIDMgK1xuICAgICAgICAgICAgeWVhcnMgKiAxMjtcblxuICAgICAgICB0aGlzLl9kYXRhID0ge307XG5cbiAgICAgICAgdGhpcy5fbG9jYWxlID0gbW9tZW50LmxvY2FsZURhdGEoKTtcblxuICAgICAgICB0aGlzLl9idWJibGUoKTtcbiAgICB9XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICAgIEhlbHBlcnNcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIGZ1bmN0aW9uIGV4dGVuZChhLCBiKSB7XG4gICAgICAgIGZvciAodmFyIGkgaW4gYikge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3AoYiwgaSkpIHtcbiAgICAgICAgICAgICAgICBhW2ldID0gYltpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYXNPd25Qcm9wKGIsICd0b1N0cmluZycpKSB7XG4gICAgICAgICAgICBhLnRvU3RyaW5nID0gYi50b1N0cmluZztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChoYXNPd25Qcm9wKGIsICd2YWx1ZU9mJykpIHtcbiAgICAgICAgICAgIGEudmFsdWVPZiA9IGIudmFsdWVPZjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvcHlDb25maWcodG8sIGZyb20pIHtcbiAgICAgICAgdmFyIGksIHByb3AsIHZhbDtcblxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX2lzQU1vbWVudE9iamVjdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl9pc0FNb21lbnRPYmplY3QgPSBmcm9tLl9pc0FNb21lbnRPYmplY3Q7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9pICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX2kgPSBmcm9tLl9pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5fZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl9mID0gZnJvbS5fZjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX2wgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fbCA9IGZyb20uX2w7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9zdHJpY3QgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fc3RyaWN0ID0gZnJvbS5fc3RyaWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5fdHptICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX3R6bSA9IGZyb20uX3R6bTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX2lzVVRDICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX2lzVVRDID0gZnJvbS5faXNVVEM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9vZmZzZXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fb2Zmc2V0ID0gZnJvbS5fb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5fcGYgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fcGYgPSBmcm9tLl9wZjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX2xvY2FsZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl9sb2NhbGUgPSBmcm9tLl9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobW9tZW50UHJvcGVydGllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmb3IgKGkgaW4gbW9tZW50UHJvcGVydGllcykge1xuICAgICAgICAgICAgICAgIHByb3AgPSBtb21lbnRQcm9wZXJ0aWVzW2ldO1xuICAgICAgICAgICAgICAgIHZhbCA9IGZyb21bcHJvcF07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvW3Byb3BdID0gdmFsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0bztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhYnNSb3VuZChudW1iZXIpIHtcbiAgICAgICAgaWYgKG51bWJlciA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwobnVtYmVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKG51bWJlcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBsZWZ0IHplcm8gZmlsbCBhIG51bWJlclxuICAgIC8vIHNlZSBodHRwOi8vanNwZXJmLmNvbS9sZWZ0LXplcm8tZmlsbGluZyBmb3IgcGVyZm9ybWFuY2UgY29tcGFyaXNvblxuICAgIGZ1bmN0aW9uIGxlZnRaZXJvRmlsbChudW1iZXIsIHRhcmdldExlbmd0aCwgZm9yY2VTaWduKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSAnJyArIE1hdGguYWJzKG51bWJlciksXG4gICAgICAgICAgICBzaWduID0gbnVtYmVyID49IDA7XG5cbiAgICAgICAgd2hpbGUgKG91dHB1dC5sZW5ndGggPCB0YXJnZXRMZW5ndGgpIHtcbiAgICAgICAgICAgIG91dHB1dCA9ICcwJyArIG91dHB1dDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHNpZ24gPyAoZm9yY2VTaWduID8gJysnIDogJycpIDogJy0nKSArIG91dHB1dDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXMgPSB7bWlsbGlzZWNvbmRzOiAwLCBtb250aHM6IDB9O1xuXG4gICAgICAgIHJlcy5tb250aHMgPSBvdGhlci5tb250aCgpIC0gYmFzZS5tb250aCgpICtcbiAgICAgICAgICAgIChvdGhlci55ZWFyKCkgLSBiYXNlLnllYXIoKSkgKiAxMjtcbiAgICAgICAgaWYgKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKS5pc0FmdGVyKG90aGVyKSkge1xuICAgICAgICAgICAgLS1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9ICtvdGhlciAtICsoYmFzZS5jbG9uZSgpLmFkZChyZXMubW9udGhzLCAnTScpKTtcblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKSB7XG4gICAgICAgIHZhciByZXM7XG4gICAgICAgIG90aGVyID0gbWFrZUFzKG90aGVyLCBiYXNlKTtcbiAgICAgICAgaWYgKGJhc2UuaXNCZWZvcmUob3RoZXIpKSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKGJhc2UsIG90aGVyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlcyA9IHBvc2l0aXZlTW9tZW50c0RpZmZlcmVuY2Uob3RoZXIsIGJhc2UpO1xuICAgICAgICAgICAgcmVzLm1pbGxpc2Vjb25kcyA9IC1yZXMubWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgcmVzLm1vbnRocyA9IC1yZXMubW9udGhzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICAvLyBUT0RPOiByZW1vdmUgJ25hbWUnIGFyZyBhZnRlciBkZXByZWNhdGlvbiBpcyByZW1vdmVkXG4gICAgZnVuY3Rpb24gY3JlYXRlQWRkZXIoZGlyZWN0aW9uLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsLCBwZXJpb2QpIHtcbiAgICAgICAgICAgIHZhciBkdXIsIHRtcDtcbiAgICAgICAgICAgIC8vaW52ZXJ0IHRoZSBhcmd1bWVudHMsIGJ1dCBjb21wbGFpbiBhYm91dCBpdFxuICAgICAgICAgICAgaWYgKHBlcmlvZCAhPT0gbnVsbCAmJiAhaXNOYU4oK3BlcmlvZCkpIHtcbiAgICAgICAgICAgICAgICBkZXByZWNhdGVTaW1wbGUobmFtZSwgJ21vbWVudCgpLicgKyBuYW1lICArICcocGVyaW9kLCBudW1iZXIpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgbW9tZW50KCkuJyArIG5hbWUgKyAnKG51bWJlciwgcGVyaW9kKS4nKTtcbiAgICAgICAgICAgICAgICB0bXAgPSB2YWw7IHZhbCA9IHBlcmlvZDsgcGVyaW9kID0gdG1wO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YWwgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/ICt2YWwgOiB2YWw7XG4gICAgICAgICAgICBkdXIgPSBtb21lbnQuZHVyYXRpb24odmFsLCBwZXJpb2QpO1xuICAgICAgICAgICAgYWRkT3JTdWJ0cmFjdER1cmF0aW9uRnJvbU1vbWVudCh0aGlzLCBkdXIsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhZGRPclN1YnRyYWN0RHVyYXRpb25Gcm9tTW9tZW50KG1vbSwgZHVyYXRpb24sIGlzQWRkaW5nLCB1cGRhdGVPZmZzZXQpIHtcbiAgICAgICAgdmFyIG1pbGxpc2Vjb25kcyA9IGR1cmF0aW9uLl9taWxsaXNlY29uZHMsXG4gICAgICAgICAgICBkYXlzID0gZHVyYXRpb24uX2RheXMsXG4gICAgICAgICAgICBtb250aHMgPSBkdXJhdGlvbi5fbW9udGhzO1xuICAgICAgICB1cGRhdGVPZmZzZXQgPSB1cGRhdGVPZmZzZXQgPT0gbnVsbCA/IHRydWUgOiB1cGRhdGVPZmZzZXQ7XG5cbiAgICAgICAgaWYgKG1pbGxpc2Vjb25kcykge1xuICAgICAgICAgICAgbW9tLl9kLnNldFRpbWUoK21vbS5fZCArIG1pbGxpc2Vjb25kcyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGF5cykge1xuICAgICAgICAgICAgcmF3U2V0dGVyKG1vbSwgJ0RhdGUnLCByYXdHZXR0ZXIobW9tLCAnRGF0ZScpICsgZGF5cyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobW9udGhzKSB7XG4gICAgICAgICAgICByYXdNb250aFNldHRlcihtb20sIHJhd0dldHRlcihtb20sICdNb250aCcpICsgbW9udGhzICogaXNBZGRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1cGRhdGVPZmZzZXQpIHtcbiAgICAgICAgICAgIG1vbWVudC51cGRhdGVPZmZzZXQobW9tLCBkYXlzIHx8IG1vbnRocyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiBpcyBhbiBhcnJheVxuICAgIGZ1bmN0aW9uIGlzQXJyYXkoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpbnB1dCkgPT09ICdbb2JqZWN0IEFycmF5XSc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNEYXRlKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBEYXRlXScgfHxcbiAgICAgICAgICAgIGlucHV0IGluc3RhbmNlb2YgRGF0ZTtcbiAgICB9XG5cbiAgICAvLyBjb21wYXJlIHR3byBhcnJheXMsIHJldHVybiB0aGUgbnVtYmVyIG9mIGRpZmZlcmVuY2VzXG4gICAgZnVuY3Rpb24gY29tcGFyZUFycmF5cyhhcnJheTEsIGFycmF5MiwgZG9udENvbnZlcnQpIHtcbiAgICAgICAgdmFyIGxlbiA9IE1hdGgubWluKGFycmF5MS5sZW5ndGgsIGFycmF5Mi5sZW5ndGgpLFxuICAgICAgICAgICAgbGVuZ3RoRGlmZiA9IE1hdGguYWJzKGFycmF5MS5sZW5ndGggLSBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGRpZmZzID0gMCxcbiAgICAgICAgICAgIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgaWYgKChkb250Q29udmVydCAmJiBhcnJheTFbaV0gIT09IGFycmF5MltpXSkgfHxcbiAgICAgICAgICAgICAgICAoIWRvbnRDb252ZXJ0ICYmIHRvSW50KGFycmF5MVtpXSkgIT09IHRvSW50KGFycmF5MltpXSkpKSB7XG4gICAgICAgICAgICAgICAgZGlmZnMrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGlmZnMgKyBsZW5ndGhEaWZmO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKSB7XG4gICAgICAgIGlmICh1bml0cykge1xuICAgICAgICAgICAgdmFyIGxvd2VyZWQgPSB1bml0cy50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoLyguKXMkLywgJyQxJyk7XG4gICAgICAgICAgICB1bml0cyA9IHVuaXRBbGlhc2VzW3VuaXRzXSB8fCBjYW1lbEZ1bmN0aW9uc1tsb3dlcmVkXSB8fCBsb3dlcmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bml0cztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVPYmplY3RVbml0cyhpbnB1dE9iamVjdCkge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0ge30sXG4gICAgICAgICAgICBub3JtYWxpemVkUHJvcCxcbiAgICAgICAgICAgIHByb3A7XG5cbiAgICAgICAgZm9yIChwcm9wIGluIGlucHV0T2JqZWN0KSB7XG4gICAgICAgICAgICBpZiAoaGFzT3duUHJvcChpbnB1dE9iamVjdCwgcHJvcCkpIHtcbiAgICAgICAgICAgICAgICBub3JtYWxpemVkUHJvcCA9IG5vcm1hbGl6ZVVuaXRzKHByb3ApO1xuICAgICAgICAgICAgICAgIGlmIChub3JtYWxpemVkUHJvcCkge1xuICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkSW5wdXRbbm9ybWFsaXplZFByb3BdID0gaW5wdXRPYmplY3RbcHJvcF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZWRJbnB1dDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlTGlzdChmaWVsZCkge1xuICAgICAgICB2YXIgY291bnQsIHNldHRlcjtcblxuICAgICAgICBpZiAoZmllbGQuaW5kZXhPZignd2VlaycpID09PSAwKSB7XG4gICAgICAgICAgICBjb3VudCA9IDc7XG4gICAgICAgICAgICBzZXR0ZXIgPSAnZGF5JztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChmaWVsZC5pbmRleE9mKCdtb250aCcpID09PSAwKSB7XG4gICAgICAgICAgICBjb3VudCA9IDEyO1xuICAgICAgICAgICAgc2V0dGVyID0gJ21vbnRoJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG1vbWVudFtmaWVsZF0gPSBmdW5jdGlvbiAoZm9ybWF0LCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIGksIGdldHRlcixcbiAgICAgICAgICAgICAgICBtZXRob2QgPSBtb21lbnQuX2xvY2FsZVtmaWVsZF0sXG4gICAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGZvcm1hdCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGZvcm1hdDtcbiAgICAgICAgICAgICAgICBmb3JtYXQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGdldHRlciA9IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgICAgICAgICAgdmFyIG0gPSBtb21lbnQoKS51dGMoKS5zZXQoc2V0dGVyLCBpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWV0aG9kLmNhbGwobW9tZW50Ll9sb2NhbGUsIG0sIGZvcm1hdCB8fCAnJyk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXR0ZXIoaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGdldHRlcihpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRvSW50KGFyZ3VtZW50Rm9yQ29lcmNpb24pIHtcbiAgICAgICAgdmFyIGNvZXJjZWROdW1iZXIgPSArYXJndW1lbnRGb3JDb2VyY2lvbixcbiAgICAgICAgICAgIHZhbHVlID0gMDtcblxuICAgICAgICBpZiAoY29lcmNlZE51bWJlciAhPT0gMCAmJiBpc0Zpbml0ZShjb2VyY2VkTnVtYmVyKSkge1xuICAgICAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgPj0gMCkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gTWF0aC5mbG9vcihjb2VyY2VkTnVtYmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBNYXRoLmNlaWwoY29lcmNlZE51bWJlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGF5c0luTW9udGgoeWVhciwgbW9udGgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKHllYXIsIG1vbnRoICsgMSwgMCkpLmdldFVUQ0RhdGUoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3ZWVrc0luWWVhcih5ZWFyLCBkb3csIGRveSkge1xuICAgICAgICByZXR1cm4gd2Vla09mWWVhcihtb21lbnQoW3llYXIsIDExLCAzMSArIGRvdyAtIGRveV0pLCBkb3csIGRveSkud2VlaztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlzSW5ZZWFyKHllYXIpIHtcbiAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIoeWVhcikgPyAzNjYgOiAzNjU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgeWVhciAlIDEwMCAhPT0gMCkgfHwgeWVhciAlIDQwMCA9PT0gMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja092ZXJmbG93KG0pIHtcbiAgICAgICAgdmFyIG92ZXJmbG93O1xuICAgICAgICBpZiAobS5fYSAmJiBtLl9wZi5vdmVyZmxvdyA9PT0gLTIpIHtcbiAgICAgICAgICAgIG92ZXJmbG93ID1cbiAgICAgICAgICAgICAgICBtLl9hW01PTlRIXSA8IDAgfHwgbS5fYVtNT05USF0gPiAxMSA/IE1PTlRIIDpcbiAgICAgICAgICAgICAgICBtLl9hW0RBVEVdIDwgMSB8fCBtLl9hW0RBVEVdID4gZGF5c0luTW9udGgobS5fYVtZRUFSXSwgbS5fYVtNT05USF0pID8gREFURSA6XG4gICAgICAgICAgICAgICAgbS5fYVtIT1VSXSA8IDAgfHwgbS5fYVtIT1VSXSA+IDI0IHx8XG4gICAgICAgICAgICAgICAgICAgIChtLl9hW0hPVVJdID09PSAyNCAmJiAobS5fYVtNSU5VVEVdICE9PSAwIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5fYVtTRUNPTkRdICE9PSAwIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS5fYVtNSUxMSVNFQ09ORF0gIT09IDApKSA/IEhPVVIgOlxuICAgICAgICAgICAgICAgIG0uX2FbTUlOVVRFXSA8IDAgfHwgbS5fYVtNSU5VVEVdID4gNTkgPyBNSU5VVEUgOlxuICAgICAgICAgICAgICAgIG0uX2FbU0VDT05EXSA8IDAgfHwgbS5fYVtTRUNPTkRdID4gNTkgPyBTRUNPTkQgOlxuICAgICAgICAgICAgICAgIG0uX2FbTUlMTElTRUNPTkRdIDwgMCB8fCBtLl9hW01JTExJU0VDT05EXSA+IDk5OSA/IE1JTExJU0VDT05EIDpcbiAgICAgICAgICAgICAgICAtMTtcblxuICAgICAgICAgICAgaWYgKG0uX3BmLl9vdmVyZmxvd0RheU9mWWVhciAmJiAob3ZlcmZsb3cgPCBZRUFSIHx8IG92ZXJmbG93ID4gREFURSkpIHtcbiAgICAgICAgICAgICAgICBvdmVyZmxvdyA9IERBVEU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG0uX3BmLm92ZXJmbG93ID0gb3ZlcmZsb3c7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkKG0pIHtcbiAgICAgICAgaWYgKG0uX2lzVmFsaWQgPT0gbnVsbCkge1xuICAgICAgICAgICAgbS5faXNWYWxpZCA9ICFpc05hTihtLl9kLmdldFRpbWUoKSkgJiZcbiAgICAgICAgICAgICAgICBtLl9wZi5vdmVyZmxvdyA8IDAgJiZcbiAgICAgICAgICAgICAgICAhbS5fcGYuZW1wdHkgJiZcbiAgICAgICAgICAgICAgICAhbS5fcGYuaW52YWxpZE1vbnRoICYmXG4gICAgICAgICAgICAgICAgIW0uX3BmLm51bGxJbnB1dCAmJlxuICAgICAgICAgICAgICAgICFtLl9wZi5pbnZhbGlkRm9ybWF0ICYmXG4gICAgICAgICAgICAgICAgIW0uX3BmLnVzZXJJbnZhbGlkYXRlZDtcblxuICAgICAgICAgICAgaWYgKG0uX3N0cmljdCkge1xuICAgICAgICAgICAgICAgIG0uX2lzVmFsaWQgPSBtLl9pc1ZhbGlkICYmXG4gICAgICAgICAgICAgICAgICAgIG0uX3BmLmNoYXJzTGVmdE92ZXIgPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgbS5fcGYudW51c2VkVG9rZW5zLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgICAgICAgICAgICAgICBtLl9wZi5iaWdIb3VyID09PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG0uX2lzVmFsaWQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbm9ybWFsaXplTG9jYWxlKGtleSkge1xuICAgICAgICByZXR1cm4ga2V5ID8ga2V5LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgnXycsICctJykgOiBrZXk7XG4gICAgfVxuXG4gICAgLy8gcGljayB0aGUgbG9jYWxlIGZyb20gdGhlIGFycmF5XG4gICAgLy8gdHJ5IFsnZW4tYXUnLCAnZW4tZ2InXSBhcyAnZW4tYXUnLCAnZW4tZ2InLCAnZW4nLCBhcyBpbiBtb3ZlIHRocm91Z2ggdGhlIGxpc3QgdHJ5aW5nIGVhY2hcbiAgICAvLyBzdWJzdHJpbmcgZnJvbSBtb3N0IHNwZWNpZmljIHRvIGxlYXN0LCBidXQgbW92ZSB0byB0aGUgbmV4dCBhcnJheSBpdGVtIGlmIGl0J3MgYSBtb3JlIHNwZWNpZmljIHZhcmlhbnQgdGhhbiB0aGUgY3VycmVudCByb290XG4gICAgZnVuY3Rpb24gY2hvb3NlTG9jYWxlKG5hbWVzKSB7XG4gICAgICAgIHZhciBpID0gMCwgaiwgbmV4dCwgbG9jYWxlLCBzcGxpdDtcblxuICAgICAgICB3aGlsZSAoaSA8IG5hbWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgc3BsaXQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaV0pLnNwbGl0KCctJyk7XG4gICAgICAgICAgICBqID0gc3BsaXQubGVuZ3RoO1xuICAgICAgICAgICAgbmV4dCA9IG5vcm1hbGl6ZUxvY2FsZShuYW1lc1tpICsgMV0pO1xuICAgICAgICAgICAgbmV4dCA9IG5leHQgPyBuZXh0LnNwbGl0KCctJykgOiBudWxsO1xuICAgICAgICAgICAgd2hpbGUgKGogPiAwKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShzcGxpdC5zbGljZSgwLCBqKS5qb2luKCctJykpO1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG5leHQgJiYgbmV4dC5sZW5ndGggPj0gaiAmJiBjb21wYXJlQXJyYXlzKHNwbGl0LCBuZXh0LCB0cnVlKSA+PSBqIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICAvL3RoZSBuZXh0IGFycmF5IGl0ZW0gaXMgYmV0dGVyIHRoYW4gYSBzaGFsbG93ZXIgc3Vic3RyaW5nIG9mIHRoaXMgb25lXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBqLS07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbG9hZExvY2FsZShuYW1lKSB7XG4gICAgICAgIHZhciBvbGRMb2NhbGUgPSBudWxsO1xuICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0gJiYgaGFzTW9kdWxlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG9sZExvY2FsZSA9IG1vbWVudC5sb2NhbGUoKTtcbiAgICAgICAgICAgICAgICByZXF1aXJlKCcuL2xvY2FsZS8nICsgbmFtZSk7XG4gICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBkZWZpbmVMb2NhbGUgY3VycmVudGx5IGFsc28gc2V0cyB0aGUgZ2xvYmFsIGxvY2FsZSwgd2Ugd2FudCB0byB1bmRvIHRoYXQgZm9yIGxhenkgbG9hZGVkIGxvY2FsZXNcbiAgICAgICAgICAgICAgICBtb21lbnQubG9jYWxlKG9sZExvY2FsZSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gYSBtb21lbnQgZnJvbSBpbnB1dCwgdGhhdCBpcyBsb2NhbC91dGMvem9uZSBlcXVpdmFsZW50IHRvIG1vZGVsLlxuICAgIGZ1bmN0aW9uIG1ha2VBcyhpbnB1dCwgbW9kZWwpIHtcbiAgICAgICAgdmFyIHJlcywgZGlmZjtcbiAgICAgICAgaWYgKG1vZGVsLl9pc1VUQykge1xuICAgICAgICAgICAgcmVzID0gbW9kZWwuY2xvbmUoKTtcbiAgICAgICAgICAgIGRpZmYgPSAobW9tZW50LmlzTW9tZW50KGlucHV0KSB8fCBpc0RhdGUoaW5wdXQpID9cbiAgICAgICAgICAgICAgICAgICAgK2lucHV0IDogK21vbWVudChpbnB1dCkpIC0gKCtyZXMpO1xuICAgICAgICAgICAgLy8gVXNlIGxvdy1sZXZlbCBhcGksIGJlY2F1c2UgdGhpcyBmbiBpcyBsb3ctbGV2ZWwgYXBpLlxuICAgICAgICAgICAgcmVzLl9kLnNldFRpbWUoK3Jlcy5fZCArIGRpZmYpO1xuICAgICAgICAgICAgbW9tZW50LnVwZGF0ZU9mZnNldChyZXMsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiByZXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbW9tZW50KGlucHV0KS5sb2NhbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBMb2NhbGVcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIGV4dGVuZChMb2NhbGUucHJvdG90eXBlLCB7XG5cbiAgICAgICAgc2V0IDogZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgdmFyIHByb3AsIGk7XG4gICAgICAgICAgICBmb3IgKGkgaW4gY29uZmlnKSB7XG4gICAgICAgICAgICAgICAgcHJvcCA9IGNvbmZpZ1tpXTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tpXSA9IHByb3A7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1snXycgKyBpXSA9IHByb3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTGVuaWVudCBvcmRpbmFsIHBhcnNpbmcgYWNjZXB0cyBqdXN0IGEgbnVtYmVyIGluIGFkZGl0aW9uIHRvXG4gICAgICAgICAgICAvLyBudW1iZXIgKyAocG9zc2libHkpIHN0dWZmIGNvbWluZyBmcm9tIF9vcmRpbmFsUGFyc2VMZW5pZW50LlxuICAgICAgICAgICAgdGhpcy5fb3JkaW5hbFBhcnNlTGVuaWVudCA9IG5ldyBSZWdFeHAodGhpcy5fb3JkaW5hbFBhcnNlLnNvdXJjZSArICd8JyArIC9cXGR7MSwyfS8uc291cmNlKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfbW9udGhzIDogJ0phbnVhcnlfRmVicnVhcnlfTWFyY2hfQXByaWxfTWF5X0p1bmVfSnVseV9BdWd1c3RfU2VwdGVtYmVyX09jdG9iZXJfTm92ZW1iZXJfRGVjZW1iZXInLnNwbGl0KCdfJyksXG4gICAgICAgIG1vbnRocyA6IGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzW20ubW9udGgoKV07XG4gICAgICAgIH0sXG5cbiAgICAgICAgX21vbnRoc1Nob3J0IDogJ0phbl9GZWJfTWFyX0Fwcl9NYXlfSnVuX0p1bF9BdWdfU2VwX09jdF9Ob3ZfRGVjJy5zcGxpdCgnXycpLFxuICAgICAgICBtb250aHNTaG9ydCA6IGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbW9udGhzU2hvcnRbbS5tb250aCgpXTtcbiAgICAgICAgfSxcblxuICAgICAgICBtb250aHNQYXJzZSA6IGZ1bmN0aW9uIChtb250aE5hbWUsIGZvcm1hdCwgc3RyaWN0KSB7XG4gICAgICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLl9tb250aHNQYXJzZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlID0gW107XG4gICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTI7IGkrKykge1xuICAgICAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgICAgIG1vbSA9IG1vbWVudC51dGMoWzIwMDAsIGldKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RyaWN0ICYmICF0aGlzLl9sb25nTW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cCgnXicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpLnJlcGxhY2UoJy4nLCAnJykgKyAnJCcsICdpJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghc3RyaWN0ICYmICF0aGlzLl9tb250aHNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgICAgICByZWdleCA9ICdeJyArIHRoaXMubW9udGhzKG1vbSwgJycpICsgJ3xeJyArIHRoaXMubW9udGhzU2hvcnQobW9tLCAnJyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX21vbnRoc1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB0ZXN0IHRoZSByZWdleFxuICAgICAgICAgICAgICAgIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NTScgJiYgdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmljdCAmJiBmb3JtYXQgPT09ICdNTU0nICYmIHRoaXMuX3Nob3J0TW9udGhzUGFyc2VbaV0udGVzdChtb250aE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIXN0cmljdCAmJiB0aGlzLl9tb250aHNQYXJzZVtpXS50ZXN0KG1vbnRoTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF93ZWVrZGF5cyA6ICdTdW5kYXlfTW9uZGF5X1R1ZXNkYXlfV2VkbmVzZGF5X1RodXJzZGF5X0ZyaWRheV9TYXR1cmRheScuc3BsaXQoJ18nKSxcbiAgICAgICAgd2Vla2RheXMgOiBmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzW20uZGF5KCldO1xuICAgICAgICB9LFxuXG4gICAgICAgIF93ZWVrZGF5c1Nob3J0IDogJ1N1bl9Nb25fVHVlX1dlZF9UaHVfRnJpX1NhdCcuc3BsaXQoJ18nKSxcbiAgICAgICAgd2Vla2RheXNTaG9ydCA6IGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fd2Vla2RheXNTaG9ydFttLmRheSgpXTtcbiAgICAgICAgfSxcblxuICAgICAgICBfd2Vla2RheXNNaW4gOiAnU3VfTW9fVHVfV2VfVGhfRnJfU2EnLnNwbGl0KCdfJyksXG4gICAgICAgIHdlZWtkYXlzTWluIDogZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c01pblttLmRheSgpXTtcbiAgICAgICAgfSxcblxuICAgICAgICB3ZWVrZGF5c1BhcnNlIDogZnVuY3Rpb24gKHdlZWtkYXlOYW1lKSB7XG4gICAgICAgICAgICB2YXIgaSwgbW9tLCByZWdleDtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLl93ZWVrZGF5c1BhcnNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gbWFrZSB0aGUgcmVnZXggaWYgd2UgZG9uJ3QgaGF2ZSBpdCBhbHJlYWR5XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl93ZWVrZGF5c1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIG1vbSA9IG1vbWVudChbMjAwMCwgMV0pLmRheShpKTtcbiAgICAgICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLndlZWtkYXlzKG1vbSwgJycpICsgJ3xeJyArIHRoaXMud2Vla2RheXNTaG9ydChtb20sICcnKSArICd8XicgKyB0aGlzLndlZWtkYXlzTWluKG1vbSwgJycpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl93ZWVrZGF5c1BhcnNlW2ldID0gbmV3IFJlZ0V4cChyZWdleC5yZXBsYWNlKCcuJywgJycpLCAnaScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyB0ZXN0IHRoZSByZWdleFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLl93ZWVrZGF5c1BhcnNlW2ldLnRlc3Qod2Vla2RheU5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfbG9uZ0RhdGVGb3JtYXQgOiB7XG4gICAgICAgICAgICBMVFMgOiAnaDptbTpzcyBBJyxcbiAgICAgICAgICAgIExUIDogJ2g6bW0gQScsXG4gICAgICAgICAgICBMIDogJ01NL0REL1lZWVknLFxuICAgICAgICAgICAgTEwgOiAnTU1NTSBELCBZWVlZJyxcbiAgICAgICAgICAgIExMTCA6ICdNTU1NIEQsIFlZWVkgTFQnLFxuICAgICAgICAgICAgTExMTCA6ICdkZGRkLCBNTU1NIEQsIFlZWVkgTFQnXG4gICAgICAgIH0sXG4gICAgICAgIGxvbmdEYXRlRm9ybWF0IDogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX2xvbmdEYXRlRm9ybWF0W2tleV07XG4gICAgICAgICAgICBpZiAoIW91dHB1dCAmJiB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV0pIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXkudG9VcHBlckNhc2UoKV0ucmVwbGFjZSgvTU1NTXxNTXxERHxkZGRkL2csIGZ1bmN0aW9uICh2YWwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbC5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldID0gb3V0cHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfSxcblxuICAgICAgICBpc1BNIDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICAvLyBJRTggUXVpcmtzIE1vZGUgJiBJRTcgU3RhbmRhcmRzIE1vZGUgZG8gbm90IGFsbG93IGFjY2Vzc2luZyBzdHJpbmdzIGxpa2UgYXJyYXlzXG4gICAgICAgICAgICAvLyBVc2luZyBjaGFyQXQgc2hvdWxkIGJlIG1vcmUgY29tcGF0aWJsZS5cbiAgICAgICAgICAgIHJldHVybiAoKGlucHV0ICsgJycpLnRvTG93ZXJDYXNlKCkuY2hhckF0KDApID09PSAncCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9tZXJpZGllbVBhcnNlIDogL1thcF1cXC4/bT9cXC4/L2ksXG4gICAgICAgIG1lcmlkaWVtIDogZnVuY3Rpb24gKGhvdXJzLCBtaW51dGVzLCBpc0xvd2VyKSB7XG4gICAgICAgICAgICBpZiAoaG91cnMgPiAxMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ3BtJyA6ICdQTSc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBpc0xvd2VyID8gJ2FtJyA6ICdBTSc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2NhbGVuZGFyIDoge1xuICAgICAgICAgICAgc2FtZURheSA6ICdbVG9kYXkgYXRdIExUJyxcbiAgICAgICAgICAgIG5leHREYXkgOiAnW1RvbW9ycm93IGF0XSBMVCcsXG4gICAgICAgICAgICBuZXh0V2VlayA6ICdkZGRkIFthdF0gTFQnLFxuICAgICAgICAgICAgbGFzdERheSA6ICdbWWVzdGVyZGF5IGF0XSBMVCcsXG4gICAgICAgICAgICBsYXN0V2VlayA6ICdbTGFzdF0gZGRkZCBbYXRdIExUJyxcbiAgICAgICAgICAgIHNhbWVFbHNlIDogJ0wnXG4gICAgICAgIH0sXG4gICAgICAgIGNhbGVuZGFyIDogZnVuY3Rpb24gKGtleSwgbW9tLCBub3cpIHtcbiAgICAgICAgICAgIHZhciBvdXRwdXQgPSB0aGlzLl9jYWxlbmRhcltrZXldO1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBvdXRwdXQgPT09ICdmdW5jdGlvbicgPyBvdXRwdXQuYXBwbHkobW9tLCBbbm93XSkgOiBvdXRwdXQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3JlbGF0aXZlVGltZSA6IHtcbiAgICAgICAgICAgIGZ1dHVyZSA6ICdpbiAlcycsXG4gICAgICAgICAgICBwYXN0IDogJyVzIGFnbycsXG4gICAgICAgICAgICBzIDogJ2EgZmV3IHNlY29uZHMnLFxuICAgICAgICAgICAgbSA6ICdhIG1pbnV0ZScsXG4gICAgICAgICAgICBtbSA6ICclZCBtaW51dGVzJyxcbiAgICAgICAgICAgIGggOiAnYW4gaG91cicsXG4gICAgICAgICAgICBoaCA6ICclZCBob3VycycsXG4gICAgICAgICAgICBkIDogJ2EgZGF5JyxcbiAgICAgICAgICAgIGRkIDogJyVkIGRheXMnLFxuICAgICAgICAgICAgTSA6ICdhIG1vbnRoJyxcbiAgICAgICAgICAgIE1NIDogJyVkIG1vbnRocycsXG4gICAgICAgICAgICB5IDogJ2EgeWVhcicsXG4gICAgICAgICAgICB5eSA6ICclZCB5ZWFycydcbiAgICAgICAgfSxcblxuICAgICAgICByZWxhdGl2ZVRpbWUgOiBmdW5jdGlvbiAobnVtYmVyLCB3aXRob3V0U3VmZml4LCBzdHJpbmcsIGlzRnV0dXJlKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gdGhpcy5fcmVsYXRpdmVUaW1lW3N0cmluZ107XG4gICAgICAgICAgICByZXR1cm4gKHR5cGVvZiBvdXRwdXQgPT09ICdmdW5jdGlvbicpID9cbiAgICAgICAgICAgICAgICBvdXRwdXQobnVtYmVyLCB3aXRob3V0U3VmZml4LCBzdHJpbmcsIGlzRnV0dXJlKSA6XG4gICAgICAgICAgICAgICAgb3V0cHV0LnJlcGxhY2UoLyVkL2ksIG51bWJlcik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcGFzdEZ1dHVyZSA6IGZ1bmN0aW9uIChkaWZmLCBvdXRwdXQpIHtcbiAgICAgICAgICAgIHZhciBmb3JtYXQgPSB0aGlzLl9yZWxhdGl2ZVRpbWVbZGlmZiA+IDAgPyAnZnV0dXJlJyA6ICdwYXN0J107XG4gICAgICAgICAgICByZXR1cm4gdHlwZW9mIGZvcm1hdCA9PT0gJ2Z1bmN0aW9uJyA/IGZvcm1hdChvdXRwdXQpIDogZm9ybWF0LnJlcGxhY2UoLyVzL2ksIG91dHB1dCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgb3JkaW5hbCA6IGZ1bmN0aW9uIChudW1iZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmRpbmFsLnJlcGxhY2UoJyVkJywgbnVtYmVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgX29yZGluYWwgOiAnJWQnLFxuICAgICAgICBfb3JkaW5hbFBhcnNlIDogL1xcZHsxLDJ9LyxcblxuICAgICAgICBwcmVwYXJzZSA6IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcG9zdGZvcm1hdCA6IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHJpbmc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgd2VlayA6IGZ1bmN0aW9uIChtb20pIHtcbiAgICAgICAgICAgIHJldHVybiB3ZWVrT2ZZZWFyKG1vbSwgdGhpcy5fd2Vlay5kb3csIHRoaXMuX3dlZWsuZG95KS53ZWVrO1xuICAgICAgICB9LFxuXG4gICAgICAgIF93ZWVrIDoge1xuICAgICAgICAgICAgZG93IDogMCwgLy8gU3VuZGF5IGlzIHRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWsuXG4gICAgICAgICAgICBkb3kgOiA2ICAvLyBUaGUgd2VlayB0aGF0IGNvbnRhaW5zIEphbiAxc3QgaXMgdGhlIGZpcnN0IHdlZWsgb2YgdGhlIHllYXIuXG4gICAgICAgIH0sXG5cbiAgICAgICAgX2ludmFsaWREYXRlOiAnSW52YWxpZCBkYXRlJyxcbiAgICAgICAgaW52YWxpZERhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbnZhbGlkRGF0ZTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBGb3JtYXR0aW5nXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICBmdW5jdGlvbiByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGlucHV0KSB7XG4gICAgICAgIGlmIChpbnB1dC5tYXRjaCgvXFxbW1xcc1xcU10vKSkge1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL15cXFt8XFxdJC9nLCAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xcXFwvZywgJycpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VGb3JtYXRGdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgICAgdmFyIGFycmF5ID0gZm9ybWF0Lm1hdGNoKGZvcm1hdHRpbmdUb2tlbnMpLCBpLCBsZW5ndGg7XG5cbiAgICAgICAgZm9yIChpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV0pIHtcbiAgICAgICAgICAgICAgICBhcnJheVtpXSA9IGZvcm1hdFRva2VuRnVuY3Rpb25zW2FycmF5W2ldXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSByZW1vdmVGb3JtYXR0aW5nVG9rZW5zKGFycmF5W2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gJyc7XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgKz0gYXJyYXlbaV0gaW5zdGFuY2VvZiBGdW5jdGlvbiA/IGFycmF5W2ldLmNhbGwobW9tLCBmb3JtYXQpIDogYXJyYXlbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vIGZvcm1hdCBkYXRlIHVzaW5nIG5hdGl2ZSBkYXRlIG9iamVjdFxuICAgIGZ1bmN0aW9uIGZvcm1hdE1vbWVudChtLCBmb3JtYXQpIHtcbiAgICAgICAgaWYgKCFtLmlzVmFsaWQoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG0ubG9jYWxlRGF0YSgpLmludmFsaWREYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3JtYXQgPSBleHBhbmRGb3JtYXQoZm9ybWF0LCBtLmxvY2FsZURhdGEoKSk7XG5cbiAgICAgICAgaWYgKCFmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XSkge1xuICAgICAgICAgICAgZm9ybWF0RnVuY3Rpb25zW2Zvcm1hdF0gPSBtYWtlRm9ybWF0RnVuY3Rpb24oZm9ybWF0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXRGdW5jdGlvbnNbZm9ybWF0XShtKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBleHBhbmRGb3JtYXQoZm9ybWF0LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGkgPSA1O1xuXG4gICAgICAgIGZ1bmN0aW9uIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2VucyhpbnB1dCkge1xuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5sb25nRGF0ZUZvcm1hdChpbnB1dCkgfHwgaW5wdXQ7XG4gICAgICAgIH1cblxuICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPj0gMCAmJiBsb2NhbEZvcm1hdHRpbmdUb2tlbnMudGVzdChmb3JtYXQpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSBmb3JtYXQucmVwbGFjZShsb2NhbEZvcm1hdHRpbmdUb2tlbnMsIHJlcGxhY2VMb25nRGF0ZUZvcm1hdFRva2Vucyk7XG4gICAgICAgICAgICBsb2NhbEZvcm1hdHRpbmdUb2tlbnMubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICAgIGkgLT0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmb3JtYXQ7XG4gICAgfVxuXG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICAgIFBhcnNpbmdcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIC8vIGdldCB0aGUgcmVnZXggdG8gZmluZCB0aGUgbmV4dCB0b2tlblxuICAgIGZ1bmN0aW9uIGdldFBhcnNlUmVnZXhGb3JUb2tlbih0b2tlbiwgY29uZmlnKSB7XG4gICAgICAgIHZhciBhLCBzdHJpY3QgPSBjb25maWcuX3N0cmljdDtcbiAgICAgICAgc3dpdGNoICh0b2tlbikge1xuICAgICAgICBjYXNlICdRJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuT25lRGlnaXQ7XG4gICAgICAgIGNhc2UgJ0REREQnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5UaHJlZURpZ2l0cztcbiAgICAgICAgY2FzZSAnWVlZWSc6XG4gICAgICAgIGNhc2UgJ0dHR0cnOlxuICAgICAgICBjYXNlICdnZ2dnJzpcbiAgICAgICAgICAgIHJldHVybiBzdHJpY3QgPyBwYXJzZVRva2VuRm91ckRpZ2l0cyA6IHBhcnNlVG9rZW5PbmVUb0ZvdXJEaWdpdHM7XG4gICAgICAgIGNhc2UgJ1knOlxuICAgICAgICBjYXNlICdHJzpcbiAgICAgICAgY2FzZSAnZyc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlblNpZ25lZE51bWJlcjtcbiAgICAgICAgY2FzZSAnWVlZWVlZJzpcbiAgICAgICAgY2FzZSAnWVlZWVknOlxuICAgICAgICBjYXNlICdHR0dHRyc6XG4gICAgICAgIGNhc2UgJ2dnZ2dnJzpcbiAgICAgICAgICAgIHJldHVybiBzdHJpY3QgPyBwYXJzZVRva2VuU2l4RGlnaXRzIDogcGFyc2VUb2tlbk9uZVRvU2l4RGlnaXRzO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICAgIGlmIChzdHJpY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbk9uZURpZ2l0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICBjYXNlICdTUyc6XG4gICAgICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5Ud29EaWdpdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgIGNhc2UgJ1NTUyc6XG4gICAgICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5UaHJlZURpZ2l0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgY2FzZSAnREREJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuT25lVG9UaHJlZURpZ2l0cztcbiAgICAgICAgY2FzZSAnTU1NJzpcbiAgICAgICAgY2FzZSAnTU1NTSc6XG4gICAgICAgIGNhc2UgJ2RkJzpcbiAgICAgICAgY2FzZSAnZGRkJzpcbiAgICAgICAgY2FzZSAnZGRkZCc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbldvcmQ7XG4gICAgICAgIGNhc2UgJ2EnOlxuICAgICAgICBjYXNlICdBJzpcbiAgICAgICAgICAgIHJldHVybiBjb25maWcuX2xvY2FsZS5fbWVyaWRpZW1QYXJzZTtcbiAgICAgICAgY2FzZSAneCc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbk9mZnNldE1zO1xuICAgICAgICBjYXNlICdYJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuVGltZXN0YW1wTXM7XG4gICAgICAgIGNhc2UgJ1onOlxuICAgICAgICBjYXNlICdaWic6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlblRpbWV6b25lO1xuICAgICAgICBjYXNlICdUJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuVDtcbiAgICAgICAgY2FzZSAnU1NTUyc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbkRpZ2l0cztcbiAgICAgICAgY2FzZSAnTU0nOlxuICAgICAgICBjYXNlICdERCc6XG4gICAgICAgIGNhc2UgJ1lZJzpcbiAgICAgICAgY2FzZSAnR0cnOlxuICAgICAgICBjYXNlICdnZyc6XG4gICAgICAgIGNhc2UgJ0hIJzpcbiAgICAgICAgY2FzZSAnaGgnOlxuICAgICAgICBjYXNlICdtbSc6XG4gICAgICAgIGNhc2UgJ3NzJzpcbiAgICAgICAgY2FzZSAnd3cnOlxuICAgICAgICBjYXNlICdXVyc6XG4gICAgICAgICAgICByZXR1cm4gc3RyaWN0ID8gcGFyc2VUb2tlblR3b0RpZ2l0cyA6IHBhcnNlVG9rZW5PbmVPclR3b0RpZ2l0cztcbiAgICAgICAgY2FzZSAnTSc6XG4gICAgICAgIGNhc2UgJ0QnOlxuICAgICAgICBjYXNlICdkJzpcbiAgICAgICAgY2FzZSAnSCc6XG4gICAgICAgIGNhc2UgJ2gnOlxuICAgICAgICBjYXNlICdtJzpcbiAgICAgICAgY2FzZSAncyc6XG4gICAgICAgIGNhc2UgJ3cnOlxuICAgICAgICBjYXNlICdXJzpcbiAgICAgICAgY2FzZSAnZSc6XG4gICAgICAgIGNhc2UgJ0UnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5PbmVPclR3b0RpZ2l0cztcbiAgICAgICAgY2FzZSAnRG8nOlxuICAgICAgICAgICAgcmV0dXJuIHN0cmljdCA/IGNvbmZpZy5fbG9jYWxlLl9vcmRpbmFsUGFyc2UgOiBjb25maWcuX2xvY2FsZS5fb3JkaW5hbFBhcnNlTGVuaWVudDtcbiAgICAgICAgZGVmYXVsdCA6XG4gICAgICAgICAgICBhID0gbmV3IFJlZ0V4cChyZWdleHBFc2NhcGUodW5lc2NhcGVGb3JtYXQodG9rZW4ucmVwbGFjZSgnXFxcXCcsICcnKSksICdpJykpO1xuICAgICAgICAgICAgcmV0dXJuIGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0aW1lem9uZU1pbnV0ZXNGcm9tU3RyaW5nKHN0cmluZykge1xuICAgICAgICBzdHJpbmcgPSBzdHJpbmcgfHwgJyc7XG4gICAgICAgIHZhciBwb3NzaWJsZVR6TWF0Y2hlcyA9IChzdHJpbmcubWF0Y2gocGFyc2VUb2tlblRpbWV6b25lKSB8fCBbXSksXG4gICAgICAgICAgICB0ekNodW5rID0gcG9zc2libGVUek1hdGNoZXNbcG9zc2libGVUek1hdGNoZXMubGVuZ3RoIC0gMV0gfHwgW10sXG4gICAgICAgICAgICBwYXJ0cyA9ICh0ekNodW5rICsgJycpLm1hdGNoKHBhcnNlVGltZXpvbmVDaHVua2VyKSB8fCBbJy0nLCAwLCAwXSxcbiAgICAgICAgICAgIG1pbnV0ZXMgPSArKHBhcnRzWzFdICogNjApICsgdG9JbnQocGFydHNbMl0pO1xuXG4gICAgICAgIHJldHVybiBwYXJ0c1swXSA9PT0gJysnID8gLW1pbnV0ZXMgOiBtaW51dGVzO1xuICAgIH1cblxuICAgIC8vIGZ1bmN0aW9uIHRvIGNvbnZlcnQgc3RyaW5nIGlucHV0IHRvIGRhdGVcbiAgICBmdW5jdGlvbiBhZGRUaW1lVG9BcnJheUZyb21Ub2tlbih0b2tlbiwgaW5wdXQsIGNvbmZpZykge1xuICAgICAgICB2YXIgYSwgZGF0ZVBhcnRBcnJheSA9IGNvbmZpZy5fYTtcblxuICAgICAgICBzd2l0Y2ggKHRva2VuKSB7XG4gICAgICAgIC8vIFFVQVJURVJcbiAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbTU9OVEhdID0gKHRvSW50KGlucHV0KSAtIDEpICogMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBNT05USFxuICAgICAgICBjYXNlICdNJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBNTVxuICAgICAgICBjYXNlICdNTScgOlxuICAgICAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkYXRlUGFydEFycmF5W01PTlRIXSA9IHRvSW50KGlucHV0KSAtIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnTU1NJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBNTU1NXG4gICAgICAgIGNhc2UgJ01NTU0nIDpcbiAgICAgICAgICAgIGEgPSBjb25maWcuX2xvY2FsZS5tb250aHNQYXJzZShpbnB1dCwgdG9rZW4sIGNvbmZpZy5fc3RyaWN0KTtcbiAgICAgICAgICAgIC8vIGlmIHdlIGRpZG4ndCBmaW5kIGEgbW9udGggbmFtZSwgbWFyayB0aGUgZGF0ZSBhcyBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbTU9OVEhdID0gYTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9wZi5pbnZhbGlkTW9udGggPSBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBEQVkgT0YgTU9OVEhcbiAgICAgICAgY2FzZSAnRCcgOiAvLyBmYWxsIHRocm91Z2ggdG8gRERcbiAgICAgICAgY2FzZSAnREQnIDpcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtEQVRFXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdEbycgOlxuICAgICAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkYXRlUGFydEFycmF5W0RBVEVdID0gdG9JbnQocGFyc2VJbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXQubWF0Y2goL1xcZHsxLDJ9LylbMF0sIDEwKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gREFZIE9GIFlFQVJcbiAgICAgICAgY2FzZSAnREREJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBEREREXG4gICAgICAgIGNhc2UgJ0REREQnIDpcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9kYXlPZlllYXIgPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBZRUFSXG4gICAgICAgIGNhc2UgJ1lZJyA6XG4gICAgICAgICAgICBkYXRlUGFydEFycmF5W1lFQVJdID0gbW9tZW50LnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdZWVlZJyA6XG4gICAgICAgIGNhc2UgJ1lZWVlZJyA6XG4gICAgICAgIGNhc2UgJ1lZWVlZWScgOlxuICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtZRUFSXSA9IHRvSW50KGlucHV0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBBTSAvIFBNXG4gICAgICAgIGNhc2UgJ2EnIDogLy8gZmFsbCB0aHJvdWdoIHRvIEFcbiAgICAgICAgY2FzZSAnQScgOlxuICAgICAgICAgICAgY29uZmlnLl9pc1BtID0gY29uZmlnLl9sb2NhbGUuaXNQTShpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gSE9VUlxuICAgICAgICBjYXNlICdoJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBoaFxuICAgICAgICBjYXNlICdoaCcgOlxuICAgICAgICAgICAgY29uZmlnLl9wZi5iaWdIb3VyID0gdHJ1ZTtcbiAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgY2FzZSAnSCcgOiAvLyBmYWxsIHRocm91Z2ggdG8gSEhcbiAgICAgICAgY2FzZSAnSEgnIDpcbiAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbSE9VUl0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gTUlOVVRFXG4gICAgICAgIGNhc2UgJ20nIDogLy8gZmFsbCB0aHJvdWdoIHRvIG1tXG4gICAgICAgIGNhc2UgJ21tJyA6XG4gICAgICAgICAgICBkYXRlUGFydEFycmF5W01JTlVURV0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gU0VDT05EXG4gICAgICAgIGNhc2UgJ3MnIDogLy8gZmFsbCB0aHJvdWdoIHRvIHNzXG4gICAgICAgIGNhc2UgJ3NzJyA6XG4gICAgICAgICAgICBkYXRlUGFydEFycmF5W1NFQ09ORF0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gTUlMTElTRUNPTkRcbiAgICAgICAgY2FzZSAnUycgOlxuICAgICAgICBjYXNlICdTUycgOlxuICAgICAgICBjYXNlICdTU1MnIDpcbiAgICAgICAgY2FzZSAnU1NTUycgOlxuICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtNSUxMSVNFQ09ORF0gPSB0b0ludCgoJzAuJyArIGlucHV0KSAqIDEwMDApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIFVOSVggT0ZGU0VUIChNSUxMSVNFQ09ORFMpXG4gICAgICAgIGNhc2UgJ3gnOlxuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUodG9JbnQoaW5wdXQpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBVTklYIFRJTUVTVEFNUCBXSVRIIE1TXG4gICAgICAgIGNhc2UgJ1gnOlxuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUocGFyc2VGbG9hdChpbnB1dCkgKiAxMDAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBUSU1FWk9ORVxuICAgICAgICBjYXNlICdaJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBaWlxuICAgICAgICBjYXNlICdaWicgOlxuICAgICAgICAgICAgY29uZmlnLl91c2VVVEMgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl90em0gPSB0aW1lem9uZU1pbnV0ZXNGcm9tU3RyaW5nKGlucHV0KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBXRUVLREFZIC0gaHVtYW5cbiAgICAgICAgY2FzZSAnZGQnOlxuICAgICAgICBjYXNlICdkZGQnOlxuICAgICAgICBjYXNlICdkZGRkJzpcbiAgICAgICAgICAgIGEgPSBjb25maWcuX2xvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KTtcbiAgICAgICAgICAgIC8vIGlmIHdlIGRpZG4ndCBnZXQgYSB3ZWVrZGF5IG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZFxuICAgICAgICAgICAgaWYgKGEgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fdyA9IGNvbmZpZy5fdyB8fCB7fTtcbiAgICAgICAgICAgICAgICBjb25maWcuX3dbJ2QnXSA9IGE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fcGYuaW52YWxpZFdlZWtkYXkgPSBpbnB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBXRUVLLCBXRUVLIERBWSAtIG51bWVyaWNcbiAgICAgICAgY2FzZSAndyc6XG4gICAgICAgIGNhc2UgJ3d3JzpcbiAgICAgICAgY2FzZSAnVyc6XG4gICAgICAgIGNhc2UgJ1dXJzpcbiAgICAgICAgY2FzZSAnZCc6XG4gICAgICAgIGNhc2UgJ2UnOlxuICAgICAgICBjYXNlICdFJzpcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW4uc3Vic3RyKDAsIDEpO1xuICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICBjYXNlICdnZ2dnJzpcbiAgICAgICAgY2FzZSAnR0dHRyc6XG4gICAgICAgIGNhc2UgJ0dHR0dHJzpcbiAgICAgICAgICAgIHRva2VuID0gdG9rZW4uc3Vic3RyKDAsIDIpO1xuICAgICAgICAgICAgaWYgKGlucHV0KSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fd1t0b2tlbl0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZ2cnOlxuICAgICAgICBjYXNlICdHRyc6XG4gICAgICAgICAgICBjb25maWcuX3cgPSBjb25maWcuX3cgfHwge307XG4gICAgICAgICAgICBjb25maWcuX3dbdG9rZW5dID0gbW9tZW50LnBhcnNlVHdvRGlnaXRZZWFyKGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrSW5mbyhjb25maWcpIHtcbiAgICAgICAgdmFyIHcsIHdlZWtZZWFyLCB3ZWVrLCB3ZWVrZGF5LCBkb3csIGRveSwgdGVtcDtcblxuICAgICAgICB3ID0gY29uZmlnLl93O1xuICAgICAgICBpZiAody5HRyAhPSBudWxsIHx8IHcuVyAhPSBudWxsIHx8IHcuRSAhPSBudWxsKSB7XG4gICAgICAgICAgICBkb3cgPSAxO1xuICAgICAgICAgICAgZG95ID0gNDtcblxuICAgICAgICAgICAgLy8gVE9ETzogV2UgbmVlZCB0byB0YWtlIHRoZSBjdXJyZW50IGlzb1dlZWtZZWFyLCBidXQgdGhhdCBkZXBlbmRzIG9uXG4gICAgICAgICAgICAvLyBob3cgd2UgaW50ZXJwcmV0IG5vdyAobG9jYWwsIHV0YywgZml4ZWQgb2Zmc2V0KS4gU28gY3JlYXRlXG4gICAgICAgICAgICAvLyBhIG5vdyB2ZXJzaW9uIG9mIGN1cnJlbnQgY29uZmlnICh0YWtlIGxvY2FsL3V0Yy9vZmZzZXQgZmxhZ3MsIGFuZFxuICAgICAgICAgICAgLy8gY3JlYXRlIG5vdykuXG4gICAgICAgICAgICB3ZWVrWWVhciA9IGRmbCh3LkdHLCBjb25maWcuX2FbWUVBUl0sIHdlZWtPZlllYXIobW9tZW50KCksIDEsIDQpLnllYXIpO1xuICAgICAgICAgICAgd2VlayA9IGRmbCh3LlcsIDEpO1xuICAgICAgICAgICAgd2Vla2RheSA9IGRmbCh3LkUsIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZG93ID0gY29uZmlnLl9sb2NhbGUuX3dlZWsuZG93O1xuICAgICAgICAgICAgZG95ID0gY29uZmlnLl9sb2NhbGUuX3dlZWsuZG95O1xuXG4gICAgICAgICAgICB3ZWVrWWVhciA9IGRmbCh3LmdnLCBjb25maWcuX2FbWUVBUl0sIHdlZWtPZlllYXIobW9tZW50KCksIGRvdywgZG95KS55ZWFyKTtcbiAgICAgICAgICAgIHdlZWsgPSBkZmwody53LCAxKTtcblxuICAgICAgICAgICAgaWYgKHcuZCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gd2Vla2RheSAtLSBsb3cgZGF5IG51bWJlcnMgYXJlIGNvbnNpZGVyZWQgbmV4dCB3ZWVrXG4gICAgICAgICAgICAgICAgd2Vla2RheSA9IHcuZDtcbiAgICAgICAgICAgICAgICBpZiAod2Vla2RheSA8IGRvdykge1xuICAgICAgICAgICAgICAgICAgICArK3dlZWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmICh3LmUgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGxvY2FsIHdlZWtkYXkgLS0gY291bnRpbmcgc3RhcnRzIGZyb20gYmVnaW5pbmcgb2Ygd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmUgKyBkb3c7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gYmVnaW5pbmcgb2Ygd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSBkb3c7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGVtcCA9IGRheU9mWWVhckZyb21XZWVrcyh3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG95LCBkb3cpO1xuXG4gICAgICAgIGNvbmZpZy5fYVtZRUFSXSA9IHRlbXAueWVhcjtcbiAgICAgICAgY29uZmlnLl9kYXlPZlllYXIgPSB0ZW1wLmRheU9mWWVhcjtcbiAgICB9XG5cbiAgICAvLyBjb252ZXJ0IGFuIGFycmF5IHRvIGEgZGF0ZS5cbiAgICAvLyB0aGUgYXJyYXkgc2hvdWxkIG1pcnJvciB0aGUgcGFyYW1ldGVycyBiZWxvd1xuICAgIC8vIG5vdGU6IGFsbCB2YWx1ZXMgcGFzdCB0aGUgeWVhciBhcmUgb3B0aW9uYWwgYW5kIHdpbGwgZGVmYXVsdCB0byB0aGUgbG93ZXN0IHBvc3NpYmxlIHZhbHVlLlxuICAgIC8vIFt5ZWFyLCBtb250aCwgZGF5ICwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1pbGxpc2Vjb25kXVxuICAgIGZ1bmN0aW9uIGRhdGVGcm9tQ29uZmlnKGNvbmZpZykge1xuICAgICAgICB2YXIgaSwgZGF0ZSwgaW5wdXQgPSBbXSwgY3VycmVudERhdGUsIHllYXJUb1VzZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9kKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50RGF0ZSA9IGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKTtcblxuICAgICAgICAvL2NvbXB1dGUgZGF5IG9mIHRoZSB5ZWFyIGZyb20gd2Vla3MgYW5kIHdlZWtkYXlzXG4gICAgICAgIGlmIChjb25maWcuX3cgJiYgY29uZmlnLl9hW0RBVEVdID09IG51bGwgJiYgY29uZmlnLl9hW01PTlRIXSA9PSBudWxsKSB7XG4gICAgICAgICAgICBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vaWYgdGhlIGRheSBvZiB0aGUgeWVhciBpcyBzZXQsIGZpZ3VyZSBvdXQgd2hhdCBpdCBpc1xuICAgICAgICBpZiAoY29uZmlnLl9kYXlPZlllYXIpIHtcbiAgICAgICAgICAgIHllYXJUb1VzZSA9IGRmbChjb25maWcuX2FbWUVBUl0sIGN1cnJlbnREYXRlW1lFQVJdKTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5fZGF5T2ZZZWFyID4gZGF5c0luWWVhcih5ZWFyVG9Vc2UpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9wZi5fb3ZlcmZsb3dEYXlPZlllYXIgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkYXRlID0gbWFrZVVUQ0RhdGUoeWVhclRvVXNlLCAwLCBjb25maWcuX2RheU9mWWVhcik7XG4gICAgICAgICAgICBjb25maWcuX2FbTU9OVEhdID0gZGF0ZS5nZXRVVENNb250aCgpO1xuICAgICAgICAgICAgY29uZmlnLl9hW0RBVEVdID0gZGF0ZS5nZXRVVENEYXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEZWZhdWx0IHRvIGN1cnJlbnQgZGF0ZS5cbiAgICAgICAgLy8gKiBpZiBubyB5ZWFyLCBtb250aCwgZGF5IG9mIG1vbnRoIGFyZSBnaXZlbiwgZGVmYXVsdCB0byB0b2RheVxuICAgICAgICAvLyAqIGlmIGRheSBvZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBtb250aCBhbmQgeWVhclxuICAgICAgICAvLyAqIGlmIG1vbnRoIGlzIGdpdmVuLCBkZWZhdWx0IG9ubHkgeWVhclxuICAgICAgICAvLyAqIGlmIHllYXIgaXMgZ2l2ZW4sIGRvbid0IGRlZmF1bHQgYW55dGhpbmdcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDMgJiYgY29uZmlnLl9hW2ldID09IG51bGw7ICsraSkge1xuICAgICAgICAgICAgY29uZmlnLl9hW2ldID0gaW5wdXRbaV0gPSBjdXJyZW50RGF0ZVtpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFplcm8gb3V0IHdoYXRldmVyIHdhcyBub3QgZGVmYXVsdGVkLCBpbmNsdWRpbmcgdGltZVxuICAgICAgICBmb3IgKDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgY29uZmlnLl9hW2ldID0gaW5wdXRbaV0gPSAoY29uZmlnLl9hW2ldID09IG51bGwpID8gKGkgPT09IDIgPyAxIDogMCkgOiBjb25maWcuX2FbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBmb3IgMjQ6MDA6MDAuMDAwXG4gICAgICAgIGlmIChjb25maWcuX2FbSE9VUl0gPT09IDI0ICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW01JTlVURV0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbU0VDT05EXSA9PT0gMCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSUxMSVNFQ09ORF0gPT09IDApIHtcbiAgICAgICAgICAgIGNvbmZpZy5fbmV4dERheSA9IHRydWU7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAwO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnLl9kID0gKGNvbmZpZy5fdXNlVVRDID8gbWFrZVVUQ0RhdGUgOiBtYWtlRGF0ZSkuYXBwbHkobnVsbCwgaW5wdXQpO1xuICAgICAgICAvLyBBcHBseSB0aW1lem9uZSBvZmZzZXQgZnJvbSBpbnB1dC4gVGhlIGFjdHVhbCB6b25lIGNhbiBiZSBjaGFuZ2VkXG4gICAgICAgIC8vIHdpdGggcGFyc2Vab25lLlxuICAgICAgICBpZiAoY29uZmlnLl90em0gIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kLnNldFVUQ01pbnV0ZXMoY29uZmlnLl9kLmdldFVUQ01pbnV0ZXMoKSArIGNvbmZpZy5fdHptKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb25maWcuX25leHREYXkpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IDI0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGF0ZUZyb21PYmplY3QoY29uZmlnKSB7XG4gICAgICAgIHZhciBub3JtYWxpemVkSW5wdXQ7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbm9ybWFsaXplZElucHV0ID0gbm9ybWFsaXplT2JqZWN0VW5pdHMoY29uZmlnLl9pKTtcbiAgICAgICAgY29uZmlnLl9hID0gW1xuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0LnllYXIsXG4gICAgICAgICAgICBub3JtYWxpemVkSW5wdXQubW9udGgsXG4gICAgICAgICAgICBub3JtYWxpemVkSW5wdXQuZGF5IHx8IG5vcm1hbGl6ZWRJbnB1dC5kYXRlLFxuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0LmhvdXIsXG4gICAgICAgICAgICBub3JtYWxpemVkSW5wdXQubWludXRlLFxuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0LnNlY29uZCxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJbnB1dC5taWxsaXNlY29uZFxuICAgICAgICBdO1xuXG4gICAgICAgIGRhdGVGcm9tQ29uZmlnKGNvbmZpZyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY3VycmVudERhdGVBcnJheShjb25maWcpIHtcbiAgICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGlmIChjb25maWcuX3VzZVVUQykge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICBub3cuZ2V0VVRDRnVsbFllYXIoKSxcbiAgICAgICAgICAgICAgICBub3cuZ2V0VVRDTW9udGgoKSxcbiAgICAgICAgICAgICAgICBub3cuZ2V0VVRDRGF0ZSgpXG4gICAgICAgICAgICBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFtub3cuZ2V0RnVsbFllYXIoKSwgbm93LmdldE1vbnRoKCksIG5vdy5nZXREYXRlKCldO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBmcm9tIHN0cmluZyBhbmQgZm9ybWF0IHN0cmluZ1xuICAgIGZ1bmN0aW9uIG1ha2VEYXRlRnJvbVN0cmluZ0FuZEZvcm1hdChjb25maWcpIHtcbiAgICAgICAgaWYgKGNvbmZpZy5fZiA9PT0gbW9tZW50LklTT184NjAxKSB7XG4gICAgICAgICAgICBwYXJzZUlTTyhjb25maWcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uZmlnLl9hID0gW107XG4gICAgICAgIGNvbmZpZy5fcGYuZW1wdHkgPSB0cnVlO1xuXG4gICAgICAgIC8vIFRoaXMgYXJyYXkgaXMgdXNlZCB0byBtYWtlIGEgRGF0ZSwgZWl0aGVyIHdpdGggYG5ldyBEYXRlYCBvciBgRGF0ZS5VVENgXG4gICAgICAgIHZhciBzdHJpbmcgPSAnJyArIGNvbmZpZy5faSxcbiAgICAgICAgICAgIGksIHBhcnNlZElucHV0LCB0b2tlbnMsIHRva2VuLCBza2lwcGVkLFxuICAgICAgICAgICAgc3RyaW5nTGVuZ3RoID0gc3RyaW5nLmxlbmd0aCxcbiAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggPSAwO1xuXG4gICAgICAgIHRva2VucyA9IGV4cGFuZEZvcm1hdChjb25maWcuX2YsIGNvbmZpZy5fbG9jYWxlKS5tYXRjaChmb3JtYXR0aW5nVG9rZW5zKSB8fCBbXTtcblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0b2tlbiA9IHRva2Vuc1tpXTtcbiAgICAgICAgICAgIHBhcnNlZElucHV0ID0gKHN0cmluZy5tYXRjaChnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykpIHx8IFtdKVswXTtcbiAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgIHNraXBwZWQgPSBzdHJpbmcuc3Vic3RyKDAsIHN0cmluZy5pbmRleE9mKHBhcnNlZElucHV0KSk7XG4gICAgICAgICAgICAgICAgaWYgKHNraXBwZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcuX3BmLnVudXNlZElucHV0LnB1c2goc2tpcHBlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0cmluZyA9IHN0cmluZy5zbGljZShzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkgKyBwYXJzZWRJbnB1dC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGggKz0gcGFyc2VkSW5wdXQubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG9uJ3QgcGFyc2UgaWYgaXQncyBub3QgYSBrbm93biB0b2tlblxuICAgICAgICAgICAgaWYgKGZvcm1hdFRva2VuRnVuY3Rpb25zW3Rva2VuXSkge1xuICAgICAgICAgICAgICAgIGlmIChwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcuX3BmLmVtcHR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcuX3BmLnVudXNlZFRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYWRkVGltZVRvQXJyYXlGcm9tVG9rZW4odG9rZW4sIHBhcnNlZElucHV0LCBjb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29uZmlnLl9zdHJpY3QgJiYgIXBhcnNlZElucHV0KSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9wZi51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgcmVtYWluaW5nIHVucGFyc2VkIGlucHV0IGxlbmd0aCB0byB0aGUgc3RyaW5nXG4gICAgICAgIGNvbmZpZy5fcGYuY2hhcnNMZWZ0T3ZlciA9IHN0cmluZ0xlbmd0aCAtIHRvdGFsUGFyc2VkSW5wdXRMZW5ndGg7XG4gICAgICAgIGlmIChzdHJpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uZmlnLl9wZi51bnVzZWRJbnB1dC5wdXNoKHN0cmluZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjbGVhciBfMTJoIGZsYWcgaWYgaG91ciBpcyA8PSAxMlxuICAgICAgICBpZiAoY29uZmlnLl9wZi5iaWdIb3VyID09PSB0cnVlICYmIGNvbmZpZy5fYVtIT1VSXSA8PSAxMikge1xuICAgICAgICAgICAgY29uZmlnLl9wZi5iaWdIb3VyID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhhbmRsZSBhbSBwbVxuICAgICAgICBpZiAoY29uZmlnLl9pc1BtICYmIGNvbmZpZy5fYVtIT1VSXSA8IDEyKSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gKz0gMTI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgaXMgMTIgYW0sIGNoYW5nZSBob3VycyB0byAwXG4gICAgICAgIGlmIChjb25maWcuX2lzUG0gPT09IGZhbHNlICYmIGNvbmZpZy5fYVtIT1VSXSA9PT0gMTIpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtIT1VSXSA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgZGF0ZUZyb21Db25maWcoY29uZmlnKTtcbiAgICAgICAgY2hlY2tPdmVyZmxvdyhjb25maWcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVuZXNjYXBlRm9ybWF0KHMpIHtcbiAgICAgICAgcmV0dXJuIHMucmVwbGFjZSgvXFxcXChcXFspfFxcXFwoXFxdKXxcXFsoW15cXF1cXFtdKilcXF18XFxcXCguKS9nLCBmdW5jdGlvbiAobWF0Y2hlZCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgICAgICAgICAgIHJldHVybiBwMSB8fCBwMiB8fCBwMyB8fCBwNDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29kZSBmcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzU2MTQ5My9pcy10aGVyZS1hLXJlZ2V4cC1lc2NhcGUtZnVuY3Rpb24taW4tamF2YXNjcmlwdFxuICAgIGZ1bmN0aW9uIHJlZ2V4cEVzY2FwZShzKSB7XG4gICAgICAgIHJldHVybiBzLnJlcGxhY2UoL1stXFwvXFxcXF4kKis/LigpfFtcXF17fV0vZywgJ1xcXFwkJicpO1xuICAgIH1cblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGFycmF5IG9mIGZvcm1hdCBzdHJpbmdzXG4gICAgZnVuY3Rpb24gbWFrZURhdGVGcm9tU3RyaW5nQW5kQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIHZhciB0ZW1wQ29uZmlnLFxuICAgICAgICAgICAgYmVzdE1vbWVudCxcblxuICAgICAgICAgICAgc2NvcmVUb0JlYXQsXG4gICAgICAgICAgICBpLFxuICAgICAgICAgICAgY3VycmVudFNjb3JlO1xuXG4gICAgICAgIGlmIChjb25maWcuX2YubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX3BmLmludmFsaWRGb3JtYXQgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoTmFOKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb25maWcuX2YubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSA9IDA7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnID0gY29weUNvbmZpZyh7fSwgY29uZmlnKTtcbiAgICAgICAgICAgIGlmIChjb25maWcuX3VzZVVUQyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGVtcENvbmZpZy5fdXNlVVRDID0gY29uZmlnLl91c2VVVEM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcbiAgICAgICAgICAgIHRlbXBDb25maWcuX2YgPSBjb25maWcuX2ZbaV07XG4gICAgICAgICAgICBtYWtlRGF0ZUZyb21TdHJpbmdBbmRGb3JtYXQodGVtcENvbmZpZyk7XG5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZCh0ZW1wQ29uZmlnKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbnkgaW5wdXQgdGhhdCB3YXMgbm90IHBhcnNlZCBhZGQgYSBwZW5hbHR5IGZvciB0aGF0IGZvcm1hdFxuICAgICAgICAgICAgY3VycmVudFNjb3JlICs9IHRlbXBDb25maWcuX3BmLmNoYXJzTGVmdE92ZXI7XG5cbiAgICAgICAgICAgIC8vb3IgdG9rZW5zXG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgKz0gdGVtcENvbmZpZy5fcGYudW51c2VkVG9rZW5zLmxlbmd0aCAqIDEwO1xuXG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9wZi5zY29yZSA9IGN1cnJlbnRTY29yZTtcblxuICAgICAgICAgICAgaWYgKHNjb3JlVG9CZWF0ID09IG51bGwgfHwgY3VycmVudFNjb3JlIDwgc2NvcmVUb0JlYXQpIHtcbiAgICAgICAgICAgICAgICBzY29yZVRvQmVhdCA9IGN1cnJlbnRTY29yZTtcbiAgICAgICAgICAgICAgICBiZXN0TW9tZW50ID0gdGVtcENvbmZpZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGV4dGVuZChjb25maWcsIGJlc3RNb21lbnQgfHwgdGVtcENvbmZpZyk7XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBmcm9tIGlzbyBmb3JtYXRcbiAgICBmdW5jdGlvbiBwYXJzZUlTTyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGwsXG4gICAgICAgICAgICBzdHJpbmcgPSBjb25maWcuX2ksXG4gICAgICAgICAgICBtYXRjaCA9IGlzb1JlZ2V4LmV4ZWMoc3RyaW5nKTtcblxuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fcGYuaXNvID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29EYXRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvRGF0ZXNbaV1bMV0uZXhlYyhzdHJpbmcpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG1hdGNoWzVdIHNob3VsZCBiZSAnVCcgb3IgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5fZiA9IGlzb0RhdGVzW2ldWzBdICsgKG1hdGNoWzZdIHx8ICcgJyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoaSA9IDAsIGwgPSBpc29UaW1lcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNvVGltZXNbaV1bMV0uZXhlYyhzdHJpbmcpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZy5fZiArPSBpc29UaW1lc1tpXVswXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN0cmluZy5tYXRjaChwYXJzZVRva2VuVGltZXpvbmUpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnLl9mICs9ICdaJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1ha2VEYXRlRnJvbVN0cmluZ0FuZEZvcm1hdChjb25maWcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uZmlnLl9pc1ZhbGlkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gaXNvIGZvcm1hdCBvciBmYWxsYmFja1xuICAgIGZ1bmN0aW9uIG1ha2VEYXRlRnJvbVN0cmluZyhjb25maWcpIHtcbiAgICAgICAgcGFyc2VJU08oY29uZmlnKTtcbiAgICAgICAgaWYgKGNvbmZpZy5faXNWYWxpZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBjb25maWcuX2lzVmFsaWQ7XG4gICAgICAgICAgICBtb21lbnQuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2soY29uZmlnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1hcChhcnIsIGZuKSB7XG4gICAgICAgIHZhciByZXMgPSBbXSwgaTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgcmVzLnB1c2goZm4oYXJyW2ldLCBpKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlRGF0ZUZyb21JbnB1dChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLCBtYXRjaGVkO1xuICAgICAgICBpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0RhdGUoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZSgraW5wdXQpO1xuICAgICAgICB9IGVsc2UgaWYgKChtYXRjaGVkID0gYXNwTmV0SnNvblJlZ2V4LmV4ZWMoaW5wdXQpKSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK21hdGNoZWRbMV0pO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG1ha2VEYXRlRnJvbVN0cmluZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgICAgICBjb25maWcuX2EgPSBtYXAoaW5wdXQuc2xpY2UoMCksIGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQob2JqLCAxMCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGRhdGVGcm9tQ29uZmlnKGNvbmZpZyk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mKGlucHV0KSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIGRhdGVGcm9tT2JqZWN0KGNvbmZpZyk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mKGlucHV0KSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIC8vIGZyb20gbWlsbGlzZWNvbmRzXG4gICAgICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShpbnB1dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtb21lbnQuY3JlYXRlRnJvbUlucHV0RmFsbGJhY2soY29uZmlnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIG1ha2VEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKSB7XG4gICAgICAgIC8vY2FuJ3QganVzdCBhcHBseSgpIHRvIGNyZWF0ZSBhIGRhdGU6XG4gICAgICAgIC8vaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xODEzNDgvaW5zdGFudGlhdGluZy1hLWphdmFzY3JpcHQtb2JqZWN0LWJ5LWNhbGxpbmctcHJvdG90eXBlLWNvbnN0cnVjdG9yLWFwcGx5XG4gICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoeSwgbSwgZCwgaCwgTSwgcywgbXMpO1xuXG4gICAgICAgIC8vdGhlIGRhdGUgY29uc3RydWN0b3IgZG9lc24ndCBhY2NlcHQgeWVhcnMgPCAxOTcwXG4gICAgICAgIGlmICh5IDwgMTk3MCkge1xuICAgICAgICAgICAgZGF0ZS5zZXRGdWxsWWVhcih5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlVVRDRGF0ZSh5KSB7XG4gICAgICAgIHZhciBkYXRlID0gbmV3IERhdGUoRGF0ZS5VVEMuYXBwbHkobnVsbCwgYXJndW1lbnRzKSk7XG4gICAgICAgIGlmICh5IDwgMTk3MCkge1xuICAgICAgICAgICAgZGF0ZS5zZXRVVENGdWxsWWVhcih5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoaW5wdXQsIGxvY2FsZSkge1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IHBhcnNlSW50KGlucHV0LCAxMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IGxvY2FsZS53ZWVrZGF5c1BhcnNlKGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGlucHV0ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgIH1cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgUmVsYXRpdmUgVGltZVxuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG4gICAgLy8gaGVscGVyIGZ1bmN0aW9uIGZvciBtb21lbnQuZm4uZnJvbSwgbW9tZW50LmZuLmZyb21Ob3csIGFuZCBtb21lbnQuZHVyYXRpb24uZm4uaHVtYW5pemVcbiAgICBmdW5jdGlvbiBzdWJzdGl0dXRlVGltZUFnbyhzdHJpbmcsIG51bWJlciwgd2l0aG91dFN1ZmZpeCwgaXNGdXR1cmUsIGxvY2FsZSkge1xuICAgICAgICByZXR1cm4gbG9jYWxlLnJlbGF0aXZlVGltZShudW1iZXIgfHwgMSwgISF3aXRob3V0U3VmZml4LCBzdHJpbmcsIGlzRnV0dXJlKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZWxhdGl2ZVRpbWUocG9zTmVnRHVyYXRpb24sIHdpdGhvdXRTdWZmaXgsIGxvY2FsZSkge1xuICAgICAgICB2YXIgZHVyYXRpb24gPSBtb21lbnQuZHVyYXRpb24ocG9zTmVnRHVyYXRpb24pLmFicygpLFxuICAgICAgICAgICAgc2Vjb25kcyA9IHJvdW5kKGR1cmF0aW9uLmFzKCdzJykpLFxuICAgICAgICAgICAgbWludXRlcyA9IHJvdW5kKGR1cmF0aW9uLmFzKCdtJykpLFxuICAgICAgICAgICAgaG91cnMgPSByb3VuZChkdXJhdGlvbi5hcygnaCcpKSxcbiAgICAgICAgICAgIGRheXMgPSByb3VuZChkdXJhdGlvbi5hcygnZCcpKSxcbiAgICAgICAgICAgIG1vbnRocyA9IHJvdW5kKGR1cmF0aW9uLmFzKCdNJykpLFxuICAgICAgICAgICAgeWVhcnMgPSByb3VuZChkdXJhdGlvbi5hcygneScpKSxcblxuICAgICAgICAgICAgYXJncyA9IHNlY29uZHMgPCByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzLnMgJiYgWydzJywgc2Vjb25kc10gfHxcbiAgICAgICAgICAgICAgICBtaW51dGVzID09PSAxICYmIFsnbSddIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA8IHJlbGF0aXZlVGltZVRocmVzaG9sZHMubSAmJiBbJ21tJywgbWludXRlc10gfHxcbiAgICAgICAgICAgICAgICBob3VycyA9PT0gMSAmJiBbJ2gnXSB8fFxuICAgICAgICAgICAgICAgIGhvdXJzIDwgcmVsYXRpdmVUaW1lVGhyZXNob2xkcy5oICYmIFsnaGgnLCBob3Vyc10gfHxcbiAgICAgICAgICAgICAgICBkYXlzID09PSAxICYmIFsnZCddIHx8XG4gICAgICAgICAgICAgICAgZGF5cyA8IHJlbGF0aXZlVGltZVRocmVzaG9sZHMuZCAmJiBbJ2RkJywgZGF5c10gfHxcbiAgICAgICAgICAgICAgICBtb250aHMgPT09IDEgJiYgWydNJ10gfHxcbiAgICAgICAgICAgICAgICBtb250aHMgPCByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzLk0gJiYgWydNTScsIG1vbnRoc10gfHxcbiAgICAgICAgICAgICAgICB5ZWFycyA9PT0gMSAmJiBbJ3knXSB8fCBbJ3l5JywgeWVhcnNdO1xuXG4gICAgICAgIGFyZ3NbMl0gPSB3aXRob3V0U3VmZml4O1xuICAgICAgICBhcmdzWzNdID0gK3Bvc05lZ0R1cmF0aW9uID4gMDtcbiAgICAgICAgYXJnc1s0XSA9IGxvY2FsZTtcbiAgICAgICAgcmV0dXJuIHN1YnN0aXR1dGVUaW1lQWdvLmFwcGx5KHt9LCBhcmdzKTtcbiAgICB9XG5cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgV2VlayBvZiBZZWFyXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICAvLyBmaXJzdERheU9mV2VlayAgICAgICAwID0gc3VuLCA2ID0gc2F0XG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgdGhlIGRheSBvZiB0aGUgd2VlayB0aGF0IHN0YXJ0cyB0aGUgd2Vla1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICh1c3VhbGx5IHN1bmRheSBvciBtb25kYXkpXG4gICAgLy8gZmlyc3REYXlPZldlZWtPZlllYXIgMCA9IHN1biwgNiA9IHNhdFxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgIHRoZSBmaXJzdCB3ZWVrIGlzIHRoZSB3ZWVrIHRoYXQgY29udGFpbnMgdGhlIGZpcnN0XG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgb2YgdGhpcyBkYXkgb2YgdGhlIHdlZWtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAoZWcuIElTTyB3ZWVrcyB1c2UgdGh1cnNkYXkgKDQpKVxuICAgIGZ1bmN0aW9uIHdlZWtPZlllYXIobW9tLCBmaXJzdERheU9mV2VlaywgZmlyc3REYXlPZldlZWtPZlllYXIpIHtcbiAgICAgICAgdmFyIGVuZCA9IGZpcnN0RGF5T2ZXZWVrT2ZZZWFyIC0gZmlyc3REYXlPZldlZWssXG4gICAgICAgICAgICBkYXlzVG9EYXlPZldlZWsgPSBmaXJzdERheU9mV2Vla09mWWVhciAtIG1vbS5kYXkoKSxcbiAgICAgICAgICAgIGFkanVzdGVkTW9tZW50O1xuXG5cbiAgICAgICAgaWYgKGRheXNUb0RheU9mV2VlayA+IGVuZCkge1xuICAgICAgICAgICAgZGF5c1RvRGF5T2ZXZWVrIC09IDc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGF5c1RvRGF5T2ZXZWVrIDwgZW5kIC0gNykge1xuICAgICAgICAgICAgZGF5c1RvRGF5T2ZXZWVrICs9IDc7XG4gICAgICAgIH1cblxuICAgICAgICBhZGp1c3RlZE1vbWVudCA9IG1vbWVudChtb20pLmFkZChkYXlzVG9EYXlPZldlZWssICdkJyk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB3ZWVrOiBNYXRoLmNlaWwoYWRqdXN0ZWRNb21lbnQuZGF5T2ZZZWFyKCkgLyA3KSxcbiAgICAgICAgICAgIHllYXI6IGFkanVzdGVkTW9tZW50LnllYXIoKVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8vaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fd2Vla19kYXRlI0NhbGN1bGF0aW5nX2FfZGF0ZV9naXZlbl90aGVfeWVhci4yQ193ZWVrX251bWJlcl9hbmRfd2Vla2RheVxuICAgIGZ1bmN0aW9uIGRheU9mWWVhckZyb21XZWVrcyh5ZWFyLCB3ZWVrLCB3ZWVrZGF5LCBmaXJzdERheU9mV2Vla09mWWVhciwgZmlyc3REYXlPZldlZWspIHtcbiAgICAgICAgdmFyIGQgPSBtYWtlVVRDRGF0ZSh5ZWFyLCAwLCAxKS5nZXRVVENEYXkoKSwgZGF5c1RvQWRkLCBkYXlPZlllYXI7XG5cbiAgICAgICAgZCA9IGQgPT09IDAgPyA3IDogZDtcbiAgICAgICAgd2Vla2RheSA9IHdlZWtkYXkgIT0gbnVsbCA/IHdlZWtkYXkgOiBmaXJzdERheU9mV2VlaztcbiAgICAgICAgZGF5c1RvQWRkID0gZmlyc3REYXlPZldlZWsgLSBkICsgKGQgPiBmaXJzdERheU9mV2Vla09mWWVhciA/IDcgOiAwKSAtIChkIDwgZmlyc3REYXlPZldlZWsgPyA3IDogMCk7XG4gICAgICAgIGRheU9mWWVhciA9IDcgKiAod2VlayAtIDEpICsgKHdlZWtkYXkgLSBmaXJzdERheU9mV2VlaykgKyBkYXlzVG9BZGQgKyAxO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB5ZWFyOiBkYXlPZlllYXIgPiAwID8geWVhciA6IHllYXIgLSAxLFxuICAgICAgICAgICAgZGF5T2ZZZWFyOiBkYXlPZlllYXIgPiAwID8gIGRheU9mWWVhciA6IGRheXNJblllYXIoeWVhciAtIDEpICsgZGF5T2ZZZWFyXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBUb3AgTGV2ZWwgRnVuY3Rpb25zXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZnVuY3Rpb24gbWFrZU1vbWVudChjb25maWcpIHtcbiAgICAgICAgdmFyIGlucHV0ID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgZm9ybWF0ID0gY29uZmlnLl9mLFxuICAgICAgICAgICAgcmVzO1xuXG4gICAgICAgIGNvbmZpZy5fbG9jYWxlID0gY29uZmlnLl9sb2NhbGUgfHwgbW9tZW50LmxvY2FsZURhdGEoY29uZmlnLl9sKTtcblxuICAgICAgICBpZiAoaW5wdXQgPT09IG51bGwgfHwgKGZvcm1hdCA9PT0gdW5kZWZpbmVkICYmIGlucHV0ID09PSAnJykpIHtcbiAgICAgICAgICAgIHJldHVybiBtb21lbnQuaW52YWxpZCh7bnVsbElucHV0OiB0cnVlfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY29uZmlnLl9pID0gaW5wdXQgPSBjb25maWcuX2xvY2FsZS5wcmVwYXJzZShpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobW9tZW50LmlzTW9tZW50KGlucHV0KSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBNb21lbnQoaW5wdXQsIHRydWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdCkge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkoZm9ybWF0KSkge1xuICAgICAgICAgICAgICAgIG1ha2VEYXRlRnJvbVN0cmluZ0FuZEFycmF5KGNvbmZpZyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1ha2VEYXRlRnJvbVN0cmluZ0FuZEZvcm1hdChjb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWFrZURhdGVGcm9tSW5wdXQoY29uZmlnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcyA9IG5ldyBNb21lbnQoY29uZmlnKTtcbiAgICAgICAgaWYgKHJlcy5fbmV4dERheSkge1xuICAgICAgICAgICAgLy8gQWRkaW5nIGlzIHNtYXJ0IGVub3VnaCBhcm91bmQgRFNUXG4gICAgICAgICAgICByZXMuYWRkKDEsICdkJyk7XG4gICAgICAgICAgICByZXMuX25leHREYXkgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIG1vbWVudCA9IGZ1bmN0aW9uIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgYztcblxuICAgICAgICBpZiAodHlwZW9mKGxvY2FsZSkgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgc3RyaWN0ID0gbG9jYWxlO1xuICAgICAgICAgICAgbG9jYWxlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIG9iamVjdCBjb25zdHJ1Y3Rpb24gbXVzdCBiZSBkb25lIHRoaXMgd2F5LlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50L21vbWVudC9pc3N1ZXMvMTQyM1xuICAgICAgICBjID0ge307XG4gICAgICAgIGMuX2lzQU1vbWVudE9iamVjdCA9IHRydWU7XG4gICAgICAgIGMuX2kgPSBpbnB1dDtcbiAgICAgICAgYy5fZiA9IGZvcm1hdDtcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5fc3RyaWN0ID0gc3RyaWN0O1xuICAgICAgICBjLl9pc1VUQyA9IGZhbHNlO1xuICAgICAgICBjLl9wZiA9IGRlZmF1bHRQYXJzaW5nRmxhZ3MoKTtcblxuICAgICAgICByZXR1cm4gbWFrZU1vbWVudChjKTtcbiAgICB9O1xuXG4gICAgbW9tZW50LnN1cHByZXNzRGVwcmVjYXRpb25XYXJuaW5ncyA9IGZhbHNlO1xuXG4gICAgbW9tZW50LmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50IGNvbnN0cnVjdGlvbiBmYWxscyBiYWNrIHRvIGpzIERhdGUuIFRoaXMgaXMgJyArXG4gICAgICAgICdkaXNjb3VyYWdlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIHVwY29taW5nIG1ham9yICcgK1xuICAgICAgICAncmVsZWFzZS4gUGxlYXNlIHJlZmVyIHRvICcgK1xuICAgICAgICAnaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MDcgZm9yIG1vcmUgaW5mby4nLFxuICAgICAgICBmdW5jdGlvbiAoY29uZmlnKSB7XG4gICAgICAgICAgICBjb25maWcuX2QgPSBuZXcgRGF0ZShjb25maWcuX2kgKyAoY29uZmlnLl91c2VVVEMgPyAnIFVUQycgOiAnJykpO1xuICAgICAgICB9XG4gICAgKTtcblxuICAgIC8vIFBpY2sgYSBtb21lbnQgbSBmcm9tIG1vbWVudHMgc28gdGhhdCBtW2ZuXShvdGhlcikgaXMgdHJ1ZSBmb3IgYWxsXG4gICAgLy8gb3RoZXIuIFRoaXMgcmVsaWVzIG9uIHRoZSBmdW5jdGlvbiBmbiB0byBiZSB0cmFuc2l0aXZlLlxuICAgIC8vXG4gICAgLy8gbW9tZW50cyBzaG91bGQgZWl0aGVyIGJlIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzIG9yIGFuIGFycmF5LCB3aG9zZVxuICAgIC8vIGZpcnN0IGVsZW1lbnQgaXMgYW4gYXJyYXkgb2YgbW9tZW50IG9iamVjdHMuXG4gICAgZnVuY3Rpb24gcGlja0J5KGZuLCBtb21lbnRzKSB7XG4gICAgICAgIHZhciByZXMsIGk7XG4gICAgICAgIGlmIChtb21lbnRzLmxlbmd0aCA9PT0gMSAmJiBpc0FycmF5KG1vbWVudHNbMF0pKSB7XG4gICAgICAgICAgICBtb21lbnRzID0gbW9tZW50c1swXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW1vbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gbW9tZW50KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzID0gbW9tZW50c1swXTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IG1vbWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChtb21lbnRzW2ldW2ZuXShyZXMpKSB7XG4gICAgICAgICAgICAgICAgcmVzID0gbW9tZW50c1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIG1vbWVudC5taW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQmVmb3JlJywgYXJncyk7XG4gICAgfTtcblxuICAgIG1vbWVudC5tYXggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xuXG4gICAgICAgIHJldHVybiBwaWNrQnkoJ2lzQWZ0ZXInLCBhcmdzKTtcbiAgICB9O1xuXG4gICAgLy8gY3JlYXRpbmcgd2l0aCB1dGNcbiAgICBtb21lbnQudXRjID0gZnVuY3Rpb24gKGlucHV0LCBmb3JtYXQsIGxvY2FsZSwgc3RyaWN0KSB7XG4gICAgICAgIHZhciBjO1xuXG4gICAgICAgIGlmICh0eXBlb2YobG9jYWxlKSA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICBzdHJpY3QgPSBsb2NhbGU7XG4gICAgICAgICAgICBsb2NhbGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gb2JqZWN0IGNvbnN0cnVjdGlvbiBtdXN0IGJlIGRvbmUgdGhpcyB3YXkuXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L2lzc3Vlcy8xNDIzXG4gICAgICAgIGMgPSB7fTtcbiAgICAgICAgYy5faXNBTW9tZW50T2JqZWN0ID0gdHJ1ZTtcbiAgICAgICAgYy5fdXNlVVRDID0gdHJ1ZTtcbiAgICAgICAgYy5faXNVVEMgPSB0cnVlO1xuICAgICAgICBjLl9sID0gbG9jYWxlO1xuICAgICAgICBjLl9pID0gaW5wdXQ7XG4gICAgICAgIGMuX2YgPSBmb3JtYXQ7XG4gICAgICAgIGMuX3N0cmljdCA9IHN0cmljdDtcbiAgICAgICAgYy5fcGYgPSBkZWZhdWx0UGFyc2luZ0ZsYWdzKCk7XG5cbiAgICAgICAgcmV0dXJuIG1ha2VNb21lbnQoYykudXRjKCk7XG4gICAgfTtcblxuICAgIC8vIGNyZWF0aW5nIHdpdGggdW5peCB0aW1lc3RhbXAgKGluIHNlY29uZHMpXG4gICAgbW9tZW50LnVuaXggPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIG1vbWVudChpbnB1dCAqIDEwMDApO1xuICAgIH07XG5cbiAgICAvLyBkdXJhdGlvblxuICAgIG1vbWVudC5kdXJhdGlvbiA9IGZ1bmN0aW9uIChpbnB1dCwga2V5KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbiA9IGlucHV0LFxuICAgICAgICAgICAgLy8gbWF0Y2hpbmcgYWdhaW5zdCByZWdleHAgaXMgZXhwZW5zaXZlLCBkbyBpdCBvbiBkZW1hbmRcbiAgICAgICAgICAgIG1hdGNoID0gbnVsbCxcbiAgICAgICAgICAgIHNpZ24sXG4gICAgICAgICAgICByZXQsXG4gICAgICAgICAgICBwYXJzZUlzbyxcbiAgICAgICAgICAgIGRpZmZSZXM7XG5cbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKGlucHV0KSkge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgbXM6IGlucHV0Ll9taWxsaXNlY29uZHMsXG4gICAgICAgICAgICAgICAgZDogaW5wdXQuX2RheXMsXG4gICAgICAgICAgICAgICAgTTogaW5wdXQuX21vbnRoc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBkdXJhdGlvbiA9IHt9O1xuICAgICAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uW2tleV0gPSBpbnB1dDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb24ubWlsbGlzZWNvbmRzID0gaW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoISEobWF0Y2ggPSBhc3BOZXRUaW1lU3Bhbkpzb25SZWdleC5leGVjKGlucHV0KSkpIHtcbiAgICAgICAgICAgIHNpZ24gPSAobWF0Y2hbMV0gPT09ICctJykgPyAtMSA6IDE7XG4gICAgICAgICAgICBkdXJhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICB5OiAwLFxuICAgICAgICAgICAgICAgIGQ6IHRvSW50KG1hdGNoW0RBVEVdKSAqIHNpZ24sXG4gICAgICAgICAgICAgICAgaDogdG9JbnQobWF0Y2hbSE9VUl0pICogc2lnbixcbiAgICAgICAgICAgICAgICBtOiB0b0ludChtYXRjaFtNSU5VVEVdKSAqIHNpZ24sXG4gICAgICAgICAgICAgICAgczogdG9JbnQobWF0Y2hbU0VDT05EXSkgKiBzaWduLFxuICAgICAgICAgICAgICAgIG1zOiB0b0ludChtYXRjaFtNSUxMSVNFQ09ORF0pICogc2lnblxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICghIShtYXRjaCA9IGlzb0R1cmF0aW9uUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgcGFyc2VJc28gPSBmdW5jdGlvbiAoaW5wKSB7XG4gICAgICAgICAgICAgICAgLy8gV2UnZCBub3JtYWxseSB1c2Ugfn5pbnAgZm9yIHRoaXMsIGJ1dCB1bmZvcnR1bmF0ZWx5IGl0IGFsc29cbiAgICAgICAgICAgICAgICAvLyBjb252ZXJ0cyBmbG9hdHMgdG8gaW50cy5cbiAgICAgICAgICAgICAgICAvLyBpbnAgbWF5IGJlIHVuZGVmaW5lZCwgc28gY2FyZWZ1bCBjYWxsaW5nIHJlcGxhY2Ugb24gaXQuXG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IGlucCAmJiBwYXJzZUZsb2F0KGlucC5yZXBsYWNlKCcsJywgJy4nKSk7XG4gICAgICAgICAgICAgICAgLy8gYXBwbHkgc2lnbiB3aGlsZSB3ZSdyZSBhdCBpdFxuICAgICAgICAgICAgICAgIHJldHVybiAoaXNOYU4ocmVzKSA/IDAgOiByZXMpICogc2lnbjtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBkdXJhdGlvbiA9IHtcbiAgICAgICAgICAgICAgICB5OiBwYXJzZUlzbyhtYXRjaFsyXSksXG4gICAgICAgICAgICAgICAgTTogcGFyc2VJc28obWF0Y2hbM10pLFxuICAgICAgICAgICAgICAgIGQ6IHBhcnNlSXNvKG1hdGNoWzRdKSxcbiAgICAgICAgICAgICAgICBoOiBwYXJzZUlzbyhtYXRjaFs1XSksXG4gICAgICAgICAgICAgICAgbTogcGFyc2VJc28obWF0Y2hbNl0pLFxuICAgICAgICAgICAgICAgIHM6IHBhcnNlSXNvKG1hdGNoWzddKSxcbiAgICAgICAgICAgICAgICB3OiBwYXJzZUlzbyhtYXRjaFs4XSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGR1cmF0aW9uID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgICAgICAgICgnZnJvbScgaW4gZHVyYXRpb24gfHwgJ3RvJyBpbiBkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGRpZmZSZXMgPSBtb21lbnRzRGlmZmVyZW5jZShtb21lbnQoZHVyYXRpb24uZnJvbSksIG1vbWVudChkdXJhdGlvbi50bykpO1xuXG4gICAgICAgICAgICBkdXJhdGlvbiA9IHt9O1xuICAgICAgICAgICAgZHVyYXRpb24ubXMgPSBkaWZmUmVzLm1pbGxpc2Vjb25kcztcbiAgICAgICAgICAgIGR1cmF0aW9uLk0gPSBkaWZmUmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldCA9IG5ldyBEdXJhdGlvbihkdXJhdGlvbik7XG5cbiAgICAgICAgaWYgKG1vbWVudC5pc0R1cmF0aW9uKGlucHV0KSAmJiBoYXNPd25Qcm9wKGlucHV0LCAnX2xvY2FsZScpKSB7XG4gICAgICAgICAgICByZXQuX2xvY2FsZSA9IGlucHV0Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH07XG5cbiAgICAvLyB2ZXJzaW9uIG51bWJlclxuICAgIG1vbWVudC52ZXJzaW9uID0gVkVSU0lPTjtcblxuICAgIC8vIGRlZmF1bHQgZm9ybWF0XG4gICAgbW9tZW50LmRlZmF1bHRGb3JtYXQgPSBpc29Gb3JtYXQ7XG5cbiAgICAvLyBjb25zdGFudCB0aGF0IHJlZmVycyB0byB0aGUgSVNPIHN0YW5kYXJkXG4gICAgbW9tZW50LklTT184NjAxID0gZnVuY3Rpb24gKCkge307XG5cbiAgICAvLyBQbHVnaW5zIHRoYXQgYWRkIHByb3BlcnRpZXMgc2hvdWxkIGFsc28gYWRkIHRoZSBrZXkgaGVyZSAobnVsbCB2YWx1ZSksXG4gICAgLy8gc28gd2UgY2FuIHByb3Blcmx5IGNsb25lIG91cnNlbHZlcy5cbiAgICBtb21lbnQubW9tZW50UHJvcGVydGllcyA9IG1vbWVudFByb3BlcnRpZXM7XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkIHdoZW5ldmVyIGEgbW9tZW50IGlzIG11dGF0ZWQuXG4gICAgLy8gSXQgaXMgaW50ZW5kZWQgdG8ga2VlcCB0aGUgb2Zmc2V0IGluIHN5bmMgd2l0aCB0aGUgdGltZXpvbmUuXG4gICAgbW9tZW50LnVwZGF0ZU9mZnNldCA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiBhbGxvd3MgeW91IHRvIHNldCBhIHRocmVzaG9sZCBmb3IgcmVsYXRpdmUgdGltZSBzdHJpbmdzXG4gICAgbW9tZW50LnJlbGF0aXZlVGltZVRocmVzaG9sZCA9IGZ1bmN0aW9uICh0aHJlc2hvbGQsIGxpbWl0KSB7XG4gICAgICAgIGlmIChyZWxhdGl2ZVRpbWVUaHJlc2hvbGRzW3RocmVzaG9sZF0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVsYXRpdmVUaW1lVGhyZXNob2xkc1t0aHJlc2hvbGRdO1xuICAgICAgICB9XG4gICAgICAgIHJlbGF0aXZlVGltZVRocmVzaG9sZHNbdGhyZXNob2xkXSA9IGxpbWl0O1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xuXG4gICAgbW9tZW50LmxhbmcgPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQubGFuZyBpcyBkZXByZWNhdGVkLiBVc2UgbW9tZW50LmxvY2FsZSBpbnN0ZWFkLicsXG4gICAgICAgIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG4gICAgICAgICAgICByZXR1cm4gbW9tZW50LmxvY2FsZShrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgbG9hZCBsb2NhbGUgYW5kIHRoZW4gc2V0IHRoZSBnbG9iYWwgbG9jYWxlLiAgSWZcbiAgICAvLyBubyBhcmd1bWVudHMgYXJlIHBhc3NlZCBpbiwgaXQgd2lsbCBzaW1wbHkgcmV0dXJuIHRoZSBjdXJyZW50IGdsb2JhbFxuICAgIC8vIGxvY2FsZSBrZXkuXG4gICAgbW9tZW50LmxvY2FsZSA9IGZ1bmN0aW9uIChrZXksIHZhbHVlcykge1xuICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZih2YWx1ZXMpICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBtb21lbnQuZGVmaW5lTG9jYWxlKGtleSwgdmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBtb21lbnQubG9jYWxlRGF0YShrZXkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIG1vbWVudC5kdXJhdGlvbi5fbG9jYWxlID0gbW9tZW50Ll9sb2NhbGUgPSBkYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1vbWVudC5fbG9jYWxlLl9hYmJyO1xuICAgIH07XG5cbiAgICBtb21lbnQuZGVmaW5lTG9jYWxlID0gZnVuY3Rpb24gKG5hbWUsIHZhbHVlcykge1xuICAgICAgICBpZiAodmFsdWVzICE9PSBudWxsKSB7XG4gICAgICAgICAgICB2YWx1ZXMuYWJiciA9IG5hbWU7XG4gICAgICAgICAgICBpZiAoIWxvY2FsZXNbbmFtZV0pIHtcbiAgICAgICAgICAgICAgICBsb2NhbGVzW25hbWVdID0gbmV3IExvY2FsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9jYWxlc1tuYW1lXS5zZXQodmFsdWVzKTtcblxuICAgICAgICAgICAgLy8gYmFja3dhcmRzIGNvbXBhdCBmb3Igbm93OiBhbHNvIHNldCB0aGUgbG9jYWxlXG4gICAgICAgICAgICBtb21lbnQubG9jYWxlKG5hbWUpO1xuXG4gICAgICAgICAgICByZXR1cm4gbG9jYWxlc1tuYW1lXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHVzZWZ1bCBmb3IgdGVzdGluZ1xuICAgICAgICAgICAgZGVsZXRlIGxvY2FsZXNbbmFtZV07XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBtb21lbnQubGFuZ0RhdGEgPSBkZXByZWNhdGUoXG4gICAgICAgICdtb21lbnQubGFuZ0RhdGEgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGVEYXRhIGluc3RlYWQuJyxcbiAgICAgICAgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudC5sb2NhbGVEYXRhKGtleSk7XG4gICAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gcmV0dXJucyBsb2NhbGUgZGF0YVxuICAgIG1vbWVudC5sb2NhbGVEYXRhID0gZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgbG9jYWxlO1xuXG4gICAgICAgIGlmIChrZXkgJiYga2V5Ll9sb2NhbGUgJiYga2V5Ll9sb2NhbGUuX2FiYnIpIHtcbiAgICAgICAgICAgIGtleSA9IGtleS5fbG9jYWxlLl9hYmJyO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBtb21lbnQuX2xvY2FsZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaXNBcnJheShrZXkpKSB7XG4gICAgICAgICAgICAvL3Nob3J0LWNpcmN1aXQgZXZlcnl0aGluZyBlbHNlXG4gICAgICAgICAgICBsb2NhbGUgPSBsb2FkTG9jYWxlKGtleSk7XG4gICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGtleSA9IFtrZXldO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNob29zZUxvY2FsZShrZXkpO1xuICAgIH07XG5cbiAgICAvLyBjb21wYXJlIG1vbWVudCBvYmplY3RcbiAgICBtb21lbnQuaXNNb21lbnQgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIHJldHVybiBvYmogaW5zdGFuY2VvZiBNb21lbnQgfHxcbiAgICAgICAgICAgIChvYmogIT0gbnVsbCAmJiBoYXNPd25Qcm9wKG9iaiwgJ19pc0FNb21lbnRPYmplY3QnKSk7XG4gICAgfTtcblxuICAgIC8vIGZvciB0eXBlY2hlY2tpbmcgRHVyYXRpb24gb2JqZWN0c1xuICAgIG1vbWVudC5pc0R1cmF0aW9uID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgRHVyYXRpb247XG4gICAgfTtcblxuICAgIGZvciAoaSA9IGxpc3RzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIG1ha2VMaXN0KGxpc3RzW2ldKTtcbiAgICB9XG5cbiAgICBtb21lbnQubm9ybWFsaXplVW5pdHMgPSBmdW5jdGlvbiAodW5pdHMpIHtcbiAgICAgICAgcmV0dXJuIG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICB9O1xuXG4gICAgbW9tZW50LmludmFsaWQgPSBmdW5jdGlvbiAoZmxhZ3MpIHtcbiAgICAgICAgdmFyIG0gPSBtb21lbnQudXRjKE5hTik7XG4gICAgICAgIGlmIChmbGFncyAhPSBudWxsKSB7XG4gICAgICAgICAgICBleHRlbmQobS5fcGYsIGZsYWdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG0uX3BmLnVzZXJJbnZhbGlkYXRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbTtcbiAgICB9O1xuXG4gICAgbW9tZW50LnBhcnNlWm9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG1vbWVudC5hcHBseShudWxsLCBhcmd1bWVudHMpLnBhcnNlWm9uZSgpO1xuICAgIH07XG5cbiAgICBtb21lbnQucGFyc2VUd29EaWdpdFllYXIgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRvSW50KGlucHV0KSArICh0b0ludChpbnB1dCkgPiA2OCA/IDE5MDAgOiAyMDAwKTtcbiAgICB9O1xuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBNb21lbnQgUHJvdG90eXBlXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICBleHRlbmQobW9tZW50LmZuID0gTW9tZW50LnByb3RvdHlwZSwge1xuXG4gICAgICAgIGNsb25lIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudCh0aGlzKTtcbiAgICAgICAgfSxcblxuICAgICAgICB2YWx1ZU9mIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICt0aGlzLl9kICsgKCh0aGlzLl9vZmZzZXQgfHwgMCkgKiA2MDAwMCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdW5peCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKCt0aGlzIC8gMTAwMCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdG9TdHJpbmcgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLmxvY2FsZSgnZW4nKS5mb3JtYXQoJ2RkZCBNTU0gREQgWVlZWSBISDptbTpzcyBbR01UXVpaJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdG9EYXRlIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29mZnNldCA/IG5ldyBEYXRlKCt0aGlzKSA6IHRoaXMuX2Q7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdG9JU09TdHJpbmcgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgbSA9IG1vbWVudCh0aGlzKS51dGMoKTtcbiAgICAgICAgICAgIGlmICgwIDwgbS55ZWFyKCkgJiYgbS55ZWFyKCkgPD0gOTk5OSkge1xuICAgICAgICAgICAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbmF0aXZlIGltcGxlbWVudGF0aW9uIGlzIH41MHggZmFzdGVyLCB1c2UgaXQgd2hlbiB3ZSBjYW5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9EYXRlKCkudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0TW9tZW50KG0sICdZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTW1pdJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9ybWF0TW9tZW50KG0sICdZWVlZWVktTU0tRERbVF1ISDptbTpzcy5TU1NbWl0nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICB0b0FycmF5IDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG0gPSB0aGlzO1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICBtLnllYXIoKSxcbiAgICAgICAgICAgICAgICBtLm1vbnRoKCksXG4gICAgICAgICAgICAgICAgbS5kYXRlKCksXG4gICAgICAgICAgICAgICAgbS5ob3VycygpLFxuICAgICAgICAgICAgICAgIG0ubWludXRlcygpLFxuICAgICAgICAgICAgICAgIG0uc2Vjb25kcygpLFxuICAgICAgICAgICAgICAgIG0ubWlsbGlzZWNvbmRzKClcbiAgICAgICAgICAgIF07XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNWYWxpZCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBpc1ZhbGlkKHRoaXMpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzRFNUU2hpZnRlZCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpICYmIGNvbXBhcmVBcnJheXModGhpcy5fYSwgKHRoaXMuX2lzVVRDID8gbW9tZW50LnV0Yyh0aGlzLl9hKSA6IG1vbWVudCh0aGlzLl9hKSkudG9BcnJheSgpKSA+IDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcblxuICAgICAgICBwYXJzaW5nRmxhZ3MgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZXh0ZW5kKHt9LCB0aGlzLl9wZik7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaW52YWxpZEF0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGYub3ZlcmZsb3c7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdXRjIDogZnVuY3Rpb24gKGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnpvbmUoMCwga2VlcExvY2FsVGltZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgbG9jYWwgOiBmdW5jdGlvbiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzVVRDKSB7XG4gICAgICAgICAgICAgICAgdGhpcy56b25lKDAsIGtlZXBMb2NhbFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBpZiAoa2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZCh0aGlzLl9kYXRlVHpPZmZzZXQoKSwgJ20nKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBmb3JtYXQgOiBmdW5jdGlvbiAoaW5wdXRTdHJpbmcpIHtcbiAgICAgICAgICAgIHZhciBvdXRwdXQgPSBmb3JtYXRNb21lbnQodGhpcywgaW5wdXRTdHJpbmcgfHwgbW9tZW50LmRlZmF1bHRGb3JtYXQpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLnBvc3Rmb3JtYXQob3V0cHV0KTtcbiAgICAgICAgfSxcblxuICAgICAgICBhZGQgOiBjcmVhdGVBZGRlcigxLCAnYWRkJyksXG5cbiAgICAgICAgc3VidHJhY3QgOiBjcmVhdGVBZGRlcigtMSwgJ3N1YnRyYWN0JyksXG5cbiAgICAgICAgZGlmZiA6IGZ1bmN0aW9uIChpbnB1dCwgdW5pdHMsIGFzRmxvYXQpIHtcbiAgICAgICAgICAgIHZhciB0aGF0ID0gbWFrZUFzKGlucHV0LCB0aGlzKSxcbiAgICAgICAgICAgICAgICB6b25lRGlmZiA9ICh0aGlzLnpvbmUoKSAtIHRoYXQuem9uZSgpKSAqIDZlNCxcbiAgICAgICAgICAgICAgICBkaWZmLCBvdXRwdXQsIGRheXNBZGp1c3Q7XG5cbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuXG4gICAgICAgICAgICBpZiAodW5pdHMgPT09ICd5ZWFyJyB8fCB1bml0cyA9PT0gJ21vbnRoJykge1xuICAgICAgICAgICAgICAgIC8vIGF2ZXJhZ2UgbnVtYmVyIG9mIGRheXMgaW4gdGhlIG1vbnRocyBpbiB0aGUgZ2l2ZW4gZGF0ZXNcbiAgICAgICAgICAgICAgICBkaWZmID0gKHRoaXMuZGF5c0luTW9udGgoKSArIHRoYXQuZGF5c0luTW9udGgoKSkgKiA0MzJlNTsgLy8gMjQgKiA2MCAqIDYwICogMTAwMCAvIDJcbiAgICAgICAgICAgICAgICAvLyBkaWZmZXJlbmNlIGluIG1vbnRoc1xuICAgICAgICAgICAgICAgIG91dHB1dCA9ICgodGhpcy55ZWFyKCkgLSB0aGF0LnllYXIoKSkgKiAxMikgKyAodGhpcy5tb250aCgpIC0gdGhhdC5tb250aCgpKTtcbiAgICAgICAgICAgICAgICAvLyBhZGp1c3QgYnkgdGFraW5nIGRpZmZlcmVuY2UgaW4gZGF5cywgYXZlcmFnZSBudW1iZXIgb2YgZGF5c1xuICAgICAgICAgICAgICAgIC8vIGFuZCBkc3QgaW4gdGhlIGdpdmVuIG1vbnRocy5cbiAgICAgICAgICAgICAgICBkYXlzQWRqdXN0ID0gKHRoaXMgLSBtb21lbnQodGhpcykuc3RhcnRPZignbW9udGgnKSkgLVxuICAgICAgICAgICAgICAgICAgICAodGhhdCAtIG1vbWVudCh0aGF0KS5zdGFydE9mKCdtb250aCcpKTtcbiAgICAgICAgICAgICAgICAvLyBzYW1lIGFzIGFib3ZlIGJ1dCB3aXRoIHpvbmVzLCB0byBuZWdhdGUgYWxsIGRzdFxuICAgICAgICAgICAgICAgIGRheXNBZGp1c3QgLT0gKCh0aGlzLnpvbmUoKSAtIG1vbWVudCh0aGlzKS5zdGFydE9mKCdtb250aCcpLnpvbmUoKSkgLVxuICAgICAgICAgICAgICAgICAgICAgICAgKHRoYXQuem9uZSgpIC0gbW9tZW50KHRoYXQpLnN0YXJ0T2YoJ21vbnRoJykuem9uZSgpKSkgKiA2ZTQ7XG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGRheXNBZGp1c3QgLyBkaWZmO1xuICAgICAgICAgICAgICAgIGlmICh1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dCA9IG91dHB1dCAvIDEyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZGlmZiA9ICh0aGlzIC0gdGhhdCk7XG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gdW5pdHMgPT09ICdzZWNvbmQnID8gZGlmZiAvIDFlMyA6IC8vIDEwMDBcbiAgICAgICAgICAgICAgICAgICAgdW5pdHMgPT09ICdtaW51dGUnID8gZGlmZiAvIDZlNCA6IC8vIDEwMDAgKiA2MFxuICAgICAgICAgICAgICAgICAgICB1bml0cyA9PT0gJ2hvdXInID8gZGlmZiAvIDM2ZTUgOiAvLyAxMDAwICogNjAgKiA2MFxuICAgICAgICAgICAgICAgICAgICB1bml0cyA9PT0gJ2RheScgPyAoZGlmZiAtIHpvbmVEaWZmKSAvIDg2NGU1IDogLy8gMTAwMCAqIDYwICogNjAgKiAyNCwgbmVnYXRlIGRzdFxuICAgICAgICAgICAgICAgICAgICB1bml0cyA9PT0gJ3dlZWsnID8gKGRpZmYgLSB6b25lRGlmZikgLyA2MDQ4ZTUgOiAvLyAxMDAwICogNjAgKiA2MCAqIDI0ICogNywgbmVnYXRlIGRzdFxuICAgICAgICAgICAgICAgICAgICBkaWZmO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFzRmxvYXQgPyBvdXRwdXQgOiBhYnNSb3VuZChvdXRwdXQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZyb20gOiBmdW5jdGlvbiAodGltZSwgd2l0aG91dFN1ZmZpeCkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudC5kdXJhdGlvbih7dG86IHRoaXMsIGZyb206IHRpbWV9KS5sb2NhbGUodGhpcy5sb2NhbGUoKSkuaHVtYW5pemUoIXdpdGhvdXRTdWZmaXgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGZyb21Ob3cgOiBmdW5jdGlvbiAod2l0aG91dFN1ZmZpeCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZnJvbShtb21lbnQoKSwgd2l0aG91dFN1ZmZpeCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FsZW5kYXIgOiBmdW5jdGlvbiAodGltZSkge1xuICAgICAgICAgICAgLy8gV2Ugd2FudCB0byBjb21wYXJlIHRoZSBzdGFydCBvZiB0b2RheSwgdnMgdGhpcy5cbiAgICAgICAgICAgIC8vIEdldHRpbmcgc3RhcnQtb2YtdG9kYXkgZGVwZW5kcyBvbiB3aGV0aGVyIHdlJ3JlIHpvbmUnZCBvciBub3QuXG4gICAgICAgICAgICB2YXIgbm93ID0gdGltZSB8fCBtb21lbnQoKSxcbiAgICAgICAgICAgICAgICBzb2QgPSBtYWtlQXMobm93LCB0aGlzKS5zdGFydE9mKCdkYXknKSxcbiAgICAgICAgICAgICAgICBkaWZmID0gdGhpcy5kaWZmKHNvZCwgJ2RheXMnLCB0cnVlKSxcbiAgICAgICAgICAgICAgICBmb3JtYXQgPSBkaWZmIDwgLTYgPyAnc2FtZUVsc2UnIDpcbiAgICAgICAgICAgICAgICAgICAgZGlmZiA8IC0xID8gJ2xhc3RXZWVrJyA6XG4gICAgICAgICAgICAgICAgICAgIGRpZmYgPCAwID8gJ2xhc3REYXknIDpcbiAgICAgICAgICAgICAgICAgICAgZGlmZiA8IDEgPyAnc2FtZURheScgOlxuICAgICAgICAgICAgICAgICAgICBkaWZmIDwgMiA/ICduZXh0RGF5JyA6XG4gICAgICAgICAgICAgICAgICAgIGRpZmYgPCA3ID8gJ25leHRXZWVrJyA6ICdzYW1lRWxzZSc7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXQodGhpcy5sb2NhbGVEYXRhKCkuY2FsZW5kYXIoZm9ybWF0LCB0aGlzLCBtb21lbnQobm93KSkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzTGVhcFllYXIgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNMZWFwWWVhcih0aGlzLnllYXIoKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNEU1QgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gKHRoaXMuem9uZSgpIDwgdGhpcy5jbG9uZSgpLm1vbnRoKDApLnpvbmUoKSB8fFxuICAgICAgICAgICAgICAgIHRoaXMuem9uZSgpIDwgdGhpcy5jbG9uZSgpLm1vbnRoKDUpLnpvbmUoKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGF5IDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgZGF5ID0gdGhpcy5faXNVVEMgPyB0aGlzLl9kLmdldFVUQ0RheSgpIDogdGhpcy5fZC5nZXREYXkoKTtcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBwYXJzZVdlZWtkYXkoaW5wdXQsIHRoaXMubG9jYWxlRGF0YSgpKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGQoaW5wdXQgLSBkYXksICdkJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYXk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgbW9udGggOiBtYWtlQWNjZXNzb3IoJ01vbnRoJywgdHJ1ZSksXG5cbiAgICAgICAgc3RhcnRPZiA6IGZ1bmN0aW9uICh1bml0cykge1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgICAgICAvLyB0aGUgZm9sbG93aW5nIHN3aXRjaCBpbnRlbnRpb25hbGx5IG9taXRzIGJyZWFrIGtleXdvcmRzXG4gICAgICAgICAgICAvLyB0byB1dGlsaXplIGZhbGxpbmcgdGhyb3VnaCB0aGUgY2FzZXMuXG4gICAgICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlICd5ZWFyJzpcbiAgICAgICAgICAgICAgICB0aGlzLm1vbnRoKDApO1xuICAgICAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgICAgIGNhc2UgJ3F1YXJ0ZXInOlxuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRoaXMuZGF0ZSgxKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgICAgIGNhc2UgJ2lzb1dlZWsnOlxuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgICB0aGlzLmhvdXJzKDApO1xuICAgICAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICAgICAgICAgIHRoaXMubWludXRlcygwKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICAgIHRoaXMuc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICAgICAgICAgIHRoaXMubWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gd2Vla3MgYXJlIGEgc3BlY2lhbCBjYXNlXG4gICAgICAgICAgICBpZiAodW5pdHMgPT09ICd3ZWVrJykge1xuICAgICAgICAgICAgICAgIHRoaXMud2Vla2RheSgwKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodW5pdHMgPT09ICdpc29XZWVrJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaXNvV2Vla2RheSgxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcXVhcnRlcnMgYXJlIGFsc28gc3BlY2lhbFxuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAncXVhcnRlcicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1vbnRoKE1hdGguZmxvb3IodGhpcy5tb250aCgpIC8gMykgKiAzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZW5kT2Y6IGZ1bmN0aW9uICh1bml0cykge1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBpZiAodW5pdHMgPT09IHVuZGVmaW5lZCB8fCB1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRPZih1bml0cykuYWRkKDEsICh1bml0cyA9PT0gJ2lzb1dlZWsnID8gJ3dlZWsnIDogdW5pdHMpKS5zdWJ0cmFjdCgxLCAnbXMnKTtcbiAgICAgICAgfSxcblxuICAgICAgICBpc0FmdGVyOiBmdW5jdGlvbiAoaW5wdXQsIHVuaXRzKSB7XG4gICAgICAgICAgICB2YXIgaW5wdXRNcztcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModHlwZW9mIHVuaXRzICE9PSAndW5kZWZpbmVkJyA/IHVuaXRzIDogJ21pbGxpc2Vjb25kJyk7XG4gICAgICAgICAgICBpZiAodW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IG1vbWVudC5pc01vbWVudChpbnB1dCkgPyBpbnB1dCA6IG1vbWVudChpbnB1dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICt0aGlzID4gK2lucHV0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dE1zID0gbW9tZW50LmlzTW9tZW50KGlucHV0KSA/ICtpbnB1dCA6ICttb21lbnQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dE1zIDwgK3RoaXMuY2xvbmUoKS5zdGFydE9mKHVuaXRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBpc0JlZm9yZTogZnVuY3Rpb24gKGlucHV0LCB1bml0cykge1xuICAgICAgICAgICAgdmFyIGlucHV0TXM7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHR5cGVvZiB1bml0cyAhPT0gJ3VuZGVmaW5lZCcgPyB1bml0cyA6ICdtaWxsaXNlY29uZCcpO1xuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAnbWlsbGlzZWNvbmQnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBtb21lbnQuaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBtb21lbnQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiArdGhpcyA8ICtpbnB1dDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5wdXRNcyA9IG1vbWVudC5pc01vbWVudChpbnB1dCkgPyAraW5wdXQgOiArbW9tZW50KGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gK3RoaXMuY2xvbmUoKS5lbmRPZih1bml0cykgPCBpbnB1dE1zO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGlzU2FtZTogZnVuY3Rpb24gKGlucHV0LCB1bml0cykge1xuICAgICAgICAgICAgdmFyIGlucHV0TXM7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzIHx8ICdtaWxsaXNlY29uZCcpO1xuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAnbWlsbGlzZWNvbmQnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBtb21lbnQuaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBtb21lbnQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiArdGhpcyA9PT0gK2lucHV0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dE1zID0gK21vbWVudChpbnB1dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICsodGhpcy5jbG9uZSgpLnN0YXJ0T2YodW5pdHMpKSA8PSBpbnB1dE1zICYmIGlucHV0TXMgPD0gKyh0aGlzLmNsb25lKCkuZW5kT2YodW5pdHMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBtaW46IGRlcHJlY2F0ZShcbiAgICAgICAgICAgICAgICAgJ21vbWVudCgpLm1pbiBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1pbiBpbnN0ZWFkLiBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50L21vbWVudC9pc3N1ZXMvMTU0OCcsXG4gICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICAgICAgICAgICAgICAgb3RoZXIgPSBtb21lbnQuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgIHJldHVybiBvdGhlciA8IHRoaXMgPyB0aGlzIDogb3RoZXI7XG4gICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICksXG5cbiAgICAgICAgbWF4OiBkZXByZWNhdGUoXG4gICAgICAgICAgICAgICAgJ21vbWVudCgpLm1heCBpcyBkZXByZWNhdGVkLCB1c2UgbW9tZW50Lm1heCBpbnN0ZWFkLiBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50L21vbWVudC9pc3N1ZXMvMTU0OCcsXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKG90aGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIG90aGVyID0gbW9tZW50LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvdGhlciA+IHRoaXMgPyB0aGlzIDogb3RoZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICApLFxuXG4gICAgICAgIC8vIGtlZXBMb2NhbFRpbWUgPSB0cnVlIG1lYW5zIG9ubHkgY2hhbmdlIHRoZSB0aW1lem9uZSwgd2l0aG91dFxuICAgICAgICAvLyBhZmZlY3RpbmcgdGhlIGxvY2FsIGhvdXIuIFNvIDU6MzE6MjYgKzAzMDAgLS1bem9uZSgyLCB0cnVlKV0tLT5cbiAgICAgICAgLy8gNTozMToyNiArMDIwMCBJdCBpcyBwb3NzaWJsZSB0aGF0IDU6MzE6MjYgZG9lc24ndCBleGlzdCBpbnQgem9uZVxuICAgICAgICAvLyArMDIwMCwgc28gd2UgYWRqdXN0IHRoZSB0aW1lIGFzIG5lZWRlZCwgdG8gYmUgdmFsaWQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEtlZXBpbmcgdGhlIHRpbWUgYWN0dWFsbHkgYWRkcy9zdWJ0cmFjdHMgKG9uZSBob3VyKVxuICAgICAgICAvLyBmcm9tIHRoZSBhY3R1YWwgcmVwcmVzZW50ZWQgdGltZS4gVGhhdCBpcyB3aHkgd2UgY2FsbCB1cGRhdGVPZmZzZXRcbiAgICAgICAgLy8gYSBzZWNvbmQgdGltZS4gSW4gY2FzZSBpdCB3YW50cyB1cyB0byBjaGFuZ2UgdGhlIG9mZnNldCBhZ2FpblxuICAgICAgICAvLyBfY2hhbmdlSW5Qcm9ncmVzcyA9PSB0cnVlIGNhc2UsIHRoZW4gd2UgaGF2ZSB0byBhZGp1c3QsIGJlY2F1c2VcbiAgICAgICAgLy8gdGhlcmUgaXMgbm8gc3VjaCB0aW1lIGluIHRoZSBnaXZlbiB0aW1lem9uZS5cbiAgICAgICAgem9uZSA6IGZ1bmN0aW9uIChpbnB1dCwga2VlcExvY2FsVGltZSkge1xuICAgICAgICAgICAgdmFyIG9mZnNldCA9IHRoaXMuX29mZnNldCB8fCAwLFxuICAgICAgICAgICAgICAgIGxvY2FsQWRqdXN0O1xuICAgICAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBpbnB1dCA9IHRpbWV6b25lTWludXRlc0Zyb21TdHJpbmcoaW5wdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnMoaW5wdXQpIDwgMTYpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQgPSBpbnB1dCAqIDYwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2lzVVRDICYmIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxBZGp1c3QgPSB0aGlzLl9kYXRlVHpPZmZzZXQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fb2Zmc2V0ID0gaW5wdXQ7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNVVEMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChsb2NhbEFkanVzdCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3VidHJhY3QobG9jYWxBZGp1c3QsICdtJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgIT09IGlucHV0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICgha2VlcExvY2FsVGltZSB8fCB0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRPclN1YnRyYWN0RHVyYXRpb25Gcm9tTW9tZW50KHRoaXMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vbWVudC5kdXJhdGlvbihvZmZzZXQgLSBpbnB1dCwgJ20nKSwgMSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLl9jaGFuZ2VJblByb2dyZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vbWVudC51cGRhdGVPZmZzZXQodGhpcywgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jaGFuZ2VJblByb2dyZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gb2Zmc2V0IDogdGhpcy5fZGF0ZVR6T2Zmc2V0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICB6b25lQWJiciA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/ICdVVEMnIDogJyc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgem9uZU5hbWUgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNVVEMgPyAnQ29vcmRpbmF0ZWQgVW5pdmVyc2FsIFRpbWUnIDogJyc7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcGFyc2Vab25lIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3R6bSkge1xuICAgICAgICAgICAgICAgIHRoaXMuem9uZSh0aGlzLl90em0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5faSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnpvbmUodGhpcy5faSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBoYXNBbGlnbmVkSG91ck9mZnNldCA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgaWYgKCFpbnB1dCkge1xuICAgICAgICAgICAgICAgIGlucHV0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0ID0gbW9tZW50KGlucHV0KS56b25lKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAodGhpcy56b25lKCkgLSBpbnB1dCkgJSA2MCA9PT0gMDtcbiAgICAgICAgfSxcblxuICAgICAgICBkYXlzSW5Nb250aCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXlzSW5Nb250aCh0aGlzLnllYXIoKSwgdGhpcy5tb250aCgpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBkYXlPZlllYXIgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciBkYXlPZlllYXIgPSByb3VuZCgobW9tZW50KHRoaXMpLnN0YXJ0T2YoJ2RheScpIC0gbW9tZW50KHRoaXMpLnN0YXJ0T2YoJ3llYXInKSkgLyA4NjRlNSkgKyAxO1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyBkYXlPZlllYXIgOiB0aGlzLmFkZCgoaW5wdXQgLSBkYXlPZlllYXIpLCAnZCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHF1YXJ0ZXIgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gTWF0aC5jZWlsKCh0aGlzLm1vbnRoKCkgKyAxKSAvIDMpIDogdGhpcy5tb250aCgoaW5wdXQgLSAxKSAqIDMgKyB0aGlzLm1vbnRoKCkgJSAzKTtcbiAgICAgICAgfSxcblxuICAgICAgICB3ZWVrWWVhciA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgdmFyIHllYXIgPSB3ZWVrT2ZZZWFyKHRoaXMsIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdywgdGhpcy5sb2NhbGVEYXRhKCkuX3dlZWsuZG95KS55ZWFyO1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB5ZWFyIDogdGhpcy5hZGQoKGlucHV0IC0geWVhciksICd5Jyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNvV2Vla1llYXIgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gd2Vla09mWWVhcih0aGlzLCAxLCA0KS55ZWFyO1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB5ZWFyIDogdGhpcy5hZGQoKGlucHV0IC0geWVhciksICd5Jyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgd2VlayA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgdmFyIHdlZWsgPSB0aGlzLmxvY2FsZURhdGEoKS53ZWVrKHRoaXMpO1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzb1dlZWsgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrID0gd2Vla09mWWVhcih0aGlzLCAxLCA0KS53ZWVrO1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrIDogdGhpcy5hZGQoKGlucHV0IC0gd2VlaykgKiA3LCAnZCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdlZWtkYXkgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrZGF5ID0gKHRoaXMuZGF5KCkgKyA3IC0gdGhpcy5sb2NhbGVEYXRhKCkuX3dlZWsuZG93KSAlIDc7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgPT0gbnVsbCA/IHdlZWtkYXkgOiB0aGlzLmFkZChpbnB1dCAtIHdlZWtkYXksICdkJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNvV2Vla2RheSA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgLy8gYmVoYXZlcyB0aGUgc2FtZSBhcyBtb21lbnQjZGF5IGV4Y2VwdFxuICAgICAgICAgICAgLy8gYXMgYSBnZXR0ZXIsIHJldHVybnMgNyBpbnN0ZWFkIG9mIDAgKDEtNyByYW5nZSBpbnN0ZWFkIG9mIDAtNilcbiAgICAgICAgICAgIC8vIGFzIGEgc2V0dGVyLCBzdW5kYXkgc2hvdWxkIGJlbG9uZyB0byB0aGUgcHJldmlvdXMgd2Vlay5cbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gdGhpcy5kYXkoKSB8fCA3IDogdGhpcy5kYXkodGhpcy5kYXkoKSAlIDcgPyBpbnB1dCA6IGlucHV0IC0gNyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNvV2Vla3NJblllYXIgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIDEsIDQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdlZWtzSW5ZZWFyIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHdlZWtJbmZvID0gdGhpcy5sb2NhbGVEYXRhKCkuX3dlZWs7XG4gICAgICAgICAgICByZXR1cm4gd2Vla3NJblllYXIodGhpcy55ZWFyKCksIHdlZWtJbmZvLmRvdywgd2Vla0luZm8uZG95KTtcbiAgICAgICAgfSxcblxuICAgICAgICBnZXQgOiBmdW5jdGlvbiAodW5pdHMpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbdW5pdHNdKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgc2V0IDogZnVuY3Rpb24gKHVuaXRzLCB2YWx1ZSkge1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXNbdW5pdHNdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpc1t1bml0c10odmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gSWYgcGFzc2VkIGEgbG9jYWxlIGtleSwgaXQgd2lsbCBzZXQgdGhlIGxvY2FsZSBmb3IgdGhpc1xuICAgICAgICAvLyBpbnN0YW5jZS4gIE90aGVyd2lzZSwgaXQgd2lsbCByZXR1cm4gdGhlIGxvY2FsZSBjb25maWd1cmF0aW9uXG4gICAgICAgIC8vIHZhcmlhYmxlcyBmb3IgdGhpcyBpbnN0YW5jZS5cbiAgICAgICAgbG9jYWxlIDogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgdmFyIG5ld0xvY2FsZURhdGE7XG5cbiAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2NhbGUuX2FiYnI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5ld0xvY2FsZURhdGEgPSBtb21lbnQubG9jYWxlRGF0YShrZXkpO1xuICAgICAgICAgICAgICAgIGlmIChuZXdMb2NhbGVEYXRhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbG9jYWxlID0gbmV3TG9jYWxlRGF0YTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgbGFuZyA6IGRlcHJlY2F0ZShcbiAgICAgICAgICAgICdtb21lbnQoKS5sYW5nKCkgaXMgZGVwcmVjYXRlZC4gSW5zdGVhZCwgdXNlIG1vbWVudCgpLmxvY2FsZURhdGEoKSB0byBnZXQgdGhlIGxhbmd1YWdlIGNvbmZpZ3VyYXRpb24uIFVzZSBtb21lbnQoKS5sb2NhbGUoKSB0byBjaGFuZ2UgbGFuZ3VhZ2VzLicsXG4gICAgICAgICAgICBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGUoa2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICksXG5cbiAgICAgICAgbG9jYWxlRGF0YSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2NhbGU7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2RhdGVUek9mZnNldCA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIE9uIEZpcmVmb3guMjQgRGF0ZSNnZXRUaW1lem9uZU9mZnNldCByZXR1cm5zIGEgZmxvYXRpbmcgcG9pbnQuXG4gICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50L21vbWVudC9wdWxsLzE4NzFcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuX2QuZ2V0VGltZXpvbmVPZmZzZXQoKSAvIDE1KSAqIDE1O1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiByYXdNb250aFNldHRlcihtb20sIHZhbHVlKSB7XG4gICAgICAgIHZhciBkYXlPZk1vbnRoO1xuXG4gICAgICAgIC8vIFRPRE86IE1vdmUgdGhpcyBvdXQgb2YgaGVyZSFcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHZhbHVlID0gbW9tLmxvY2FsZURhdGEoKS5tb250aHNQYXJzZSh2YWx1ZSk7XG4gICAgICAgICAgICAvLyBUT0RPOiBBbm90aGVyIHNpbGVudCBmYWlsdXJlP1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbW9tO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGF5T2ZNb250aCA9IE1hdGgubWluKG1vbS5kYXRlKCksXG4gICAgICAgICAgICAgICAgZGF5c0luTW9udGgobW9tLnllYXIoKSwgdmFsdWUpKTtcbiAgICAgICAgbW9tLl9kWydzZXQnICsgKG1vbS5faXNVVEMgPyAnVVRDJyA6ICcnKSArICdNb250aCddKHZhbHVlLCBkYXlPZk1vbnRoKTtcbiAgICAgICAgcmV0dXJuIG1vbTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByYXdHZXR0ZXIobW9tLCB1bml0KSB7XG4gICAgICAgIHJldHVybiBtb20uX2RbJ2dldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0oKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByYXdTZXR0ZXIobW9tLCB1bml0LCB2YWx1ZSkge1xuICAgICAgICBpZiAodW5pdCA9PT0gJ01vbnRoJykge1xuICAgICAgICAgICAgcmV0dXJuIHJhd01vbnRoU2V0dGVyKG1vbSwgdmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyB1bml0XSh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlQWNjZXNzb3IodW5pdCwga2VlcFRpbWUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICByYXdTZXR0ZXIodGhpcywgdW5pdCwgdmFsdWUpO1xuICAgICAgICAgICAgICAgIG1vbWVudC51cGRhdGVPZmZzZXQodGhpcywga2VlcFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmF3R2V0dGVyKHRoaXMsIHVuaXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cblxuICAgIG1vbWVudC5mbi5taWxsaXNlY29uZCA9IG1vbWVudC5mbi5taWxsaXNlY29uZHMgPSBtYWtlQWNjZXNzb3IoJ01pbGxpc2Vjb25kcycsIGZhbHNlKTtcbiAgICBtb21lbnQuZm4uc2Vjb25kID0gbW9tZW50LmZuLnNlY29uZHMgPSBtYWtlQWNjZXNzb3IoJ1NlY29uZHMnLCBmYWxzZSk7XG4gICAgbW9tZW50LmZuLm1pbnV0ZSA9IG1vbWVudC5mbi5taW51dGVzID0gbWFrZUFjY2Vzc29yKCdNaW51dGVzJywgZmFsc2UpO1xuICAgIC8vIFNldHRpbmcgdGhlIGhvdXIgc2hvdWxkIGtlZXAgdGhlIHRpbWUsIGJlY2F1c2UgdGhlIHVzZXIgZXhwbGljaXRseVxuICAgIC8vIHNwZWNpZmllZCB3aGljaCBob3VyIGhlIHdhbnRzLiBTbyB0cnlpbmcgdG8gbWFpbnRhaW4gdGhlIHNhbWUgaG91ciAoaW5cbiAgICAvLyBhIG5ldyB0aW1lem9uZSkgbWFrZXMgc2Vuc2UuIEFkZGluZy9zdWJ0cmFjdGluZyBob3VycyBkb2VzIG5vdCBmb2xsb3dcbiAgICAvLyB0aGlzIHJ1bGUuXG4gICAgbW9tZW50LmZuLmhvdXIgPSBtb21lbnQuZm4uaG91cnMgPSBtYWtlQWNjZXNzb3IoJ0hvdXJzJywgdHJ1ZSk7XG4gICAgLy8gbW9tZW50LmZuLm1vbnRoIGlzIGRlZmluZWQgc2VwYXJhdGVseVxuICAgIG1vbWVudC5mbi5kYXRlID0gbWFrZUFjY2Vzc29yKCdEYXRlJywgdHJ1ZSk7XG4gICAgbW9tZW50LmZuLmRhdGVzID0gZGVwcmVjYXRlKCdkYXRlcyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgZGF0ZSBpbnN0ZWFkLicsIG1ha2VBY2Nlc3NvcignRGF0ZScsIHRydWUpKTtcbiAgICBtb21lbnQuZm4ueWVhciA9IG1ha2VBY2Nlc3NvcignRnVsbFllYXInLCB0cnVlKTtcbiAgICBtb21lbnQuZm4ueWVhcnMgPSBkZXByZWNhdGUoJ3llYXJzIGFjY2Vzc29yIGlzIGRlcHJlY2F0ZWQuIFVzZSB5ZWFyIGluc3RlYWQuJywgbWFrZUFjY2Vzc29yKCdGdWxsWWVhcicsIHRydWUpKTtcblxuICAgIC8vIGFkZCBwbHVyYWwgbWV0aG9kc1xuICAgIG1vbWVudC5mbi5kYXlzID0gbW9tZW50LmZuLmRheTtcbiAgICBtb21lbnQuZm4ubW9udGhzID0gbW9tZW50LmZuLm1vbnRoO1xuICAgIG1vbWVudC5mbi53ZWVrcyA9IG1vbWVudC5mbi53ZWVrO1xuICAgIG1vbWVudC5mbi5pc29XZWVrcyA9IG1vbWVudC5mbi5pc29XZWVrO1xuICAgIG1vbWVudC5mbi5xdWFydGVycyA9IG1vbWVudC5mbi5xdWFydGVyO1xuXG4gICAgLy8gYWRkIGFsaWFzZWQgZm9ybWF0IG1ldGhvZHNcbiAgICBtb21lbnQuZm4udG9KU09OID0gbW9tZW50LmZuLnRvSVNPU3RyaW5nO1xuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBEdXJhdGlvbiBQcm90b3R5cGVcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIGZ1bmN0aW9uIGRheXNUb1llYXJzIChkYXlzKSB7XG4gICAgICAgIC8vIDQwMCB5ZWFycyBoYXZlIDE0NjA5NyBkYXlzICh0YWtpbmcgaW50byBhY2NvdW50IGxlYXAgeWVhciBydWxlcylcbiAgICAgICAgcmV0dXJuIGRheXMgKiA0MDAgLyAxNDYwOTc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24geWVhcnNUb0RheXMgKHllYXJzKSB7XG4gICAgICAgIC8vIHllYXJzICogMzY1ICsgYWJzUm91bmQoeWVhcnMgLyA0KSAtXG4gICAgICAgIC8vICAgICBhYnNSb3VuZCh5ZWFycyAvIDEwMCkgKyBhYnNSb3VuZCh5ZWFycyAvIDQwMCk7XG4gICAgICAgIHJldHVybiB5ZWFycyAqIDE0NjA5NyAvIDQwMDtcbiAgICB9XG5cbiAgICBleHRlbmQobW9tZW50LmR1cmF0aW9uLmZuID0gRHVyYXRpb24ucHJvdG90eXBlLCB7XG5cbiAgICAgICAgX2J1YmJsZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSB0aGlzLl9taWxsaXNlY29uZHMsXG4gICAgICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMsXG4gICAgICAgICAgICAgICAgbW9udGhzID0gdGhpcy5fbW9udGhzLFxuICAgICAgICAgICAgICAgIGRhdGEgPSB0aGlzLl9kYXRhLFxuICAgICAgICAgICAgICAgIHNlY29uZHMsIG1pbnV0ZXMsIGhvdXJzLCB5ZWFycyA9IDA7XG5cbiAgICAgICAgICAgIC8vIFRoZSBmb2xsb3dpbmcgY29kZSBidWJibGVzIHVwIHZhbHVlcywgc2VlIHRoZSB0ZXN0cyBmb3JcbiAgICAgICAgICAgIC8vIGV4YW1wbGVzIG9mIHdoYXQgdGhhdCBtZWFucy5cbiAgICAgICAgICAgIGRhdGEubWlsbGlzZWNvbmRzID0gbWlsbGlzZWNvbmRzICUgMTAwMDtcblxuICAgICAgICAgICAgc2Vjb25kcyA9IGFic1JvdW5kKG1pbGxpc2Vjb25kcyAvIDEwMDApO1xuICAgICAgICAgICAgZGF0YS5zZWNvbmRzID0gc2Vjb25kcyAlIDYwO1xuXG4gICAgICAgICAgICBtaW51dGVzID0gYWJzUm91bmQoc2Vjb25kcyAvIDYwKTtcbiAgICAgICAgICAgIGRhdGEubWludXRlcyA9IG1pbnV0ZXMgJSA2MDtcblxuICAgICAgICAgICAgaG91cnMgPSBhYnNSb3VuZChtaW51dGVzIC8gNjApO1xuICAgICAgICAgICAgZGF0YS5ob3VycyA9IGhvdXJzICUgMjQ7XG5cbiAgICAgICAgICAgIGRheXMgKz0gYWJzUm91bmQoaG91cnMgLyAyNCk7XG5cbiAgICAgICAgICAgIC8vIEFjY3VyYXRlbHkgY29udmVydCBkYXlzIHRvIHllYXJzLCBhc3N1bWUgc3RhcnQgZnJvbSB5ZWFyIDAuXG4gICAgICAgICAgICB5ZWFycyA9IGFic1JvdW5kKGRheXNUb1llYXJzKGRheXMpKTtcbiAgICAgICAgICAgIGRheXMgLT0gYWJzUm91bmQoeWVhcnNUb0RheXMoeWVhcnMpKTtcblxuICAgICAgICAgICAgLy8gMzAgZGF5cyB0byBhIG1vbnRoXG4gICAgICAgICAgICAvLyBUT0RPIChpc2tyZW4pOiBVc2UgYW5jaG9yIGRhdGUgKGxpa2UgMXN0IEphbikgdG8gY29tcHV0ZSB0aGlzLlxuICAgICAgICAgICAgbW9udGhzICs9IGFic1JvdW5kKGRheXMgLyAzMCk7XG4gICAgICAgICAgICBkYXlzICU9IDMwO1xuXG4gICAgICAgICAgICAvLyAxMiBtb250aHMgLT4gMSB5ZWFyXG4gICAgICAgICAgICB5ZWFycyArPSBhYnNSb3VuZChtb250aHMgLyAxMik7XG4gICAgICAgICAgICBtb250aHMgJT0gMTI7XG5cbiAgICAgICAgICAgIGRhdGEuZGF5cyA9IGRheXM7XG4gICAgICAgICAgICBkYXRhLm1vbnRocyA9IG1vbnRocztcbiAgICAgICAgICAgIGRhdGEueWVhcnMgPSB5ZWFycztcbiAgICAgICAgfSxcblxuICAgICAgICBhYnMgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSBNYXRoLmFicyh0aGlzLl9taWxsaXNlY29uZHMpO1xuICAgICAgICAgICAgdGhpcy5fZGF5cyA9IE1hdGguYWJzKHRoaXMuX2RheXMpO1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzID0gTWF0aC5hYnModGhpcy5fbW9udGhzKTtcblxuICAgICAgICAgICAgdGhpcy5fZGF0YS5taWxsaXNlY29uZHMgPSBNYXRoLmFicyh0aGlzLl9kYXRhLm1pbGxpc2Vjb25kcyk7XG4gICAgICAgICAgICB0aGlzLl9kYXRhLnNlY29uZHMgPSBNYXRoLmFicyh0aGlzLl9kYXRhLnNlY29uZHMpO1xuICAgICAgICAgICAgdGhpcy5fZGF0YS5taW51dGVzID0gTWF0aC5hYnModGhpcy5fZGF0YS5taW51dGVzKTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEuaG91cnMgPSBNYXRoLmFicyh0aGlzLl9kYXRhLmhvdXJzKTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEubW9udGhzID0gTWF0aC5hYnModGhpcy5fZGF0YS5tb250aHMpO1xuICAgICAgICAgICAgdGhpcy5fZGF0YS55ZWFycyA9IE1hdGguYWJzKHRoaXMuX2RhdGEueWVhcnMpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICB3ZWVrcyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBhYnNSb3VuZCh0aGlzLmRheXMoKSAvIDcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHZhbHVlT2YgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgICAgdGhpcy5fZGF5cyAqIDg2NGU1ICtcbiAgICAgICAgICAgICAgKHRoaXMuX21vbnRocyAlIDEyKSAqIDI1OTJlNiArXG4gICAgICAgICAgICAgIHRvSW50KHRoaXMuX21vbnRocyAvIDEyKSAqIDMxNTM2ZTY7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaHVtYW5pemUgOiBmdW5jdGlvbiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgdmFyIG91dHB1dCA9IHJlbGF0aXZlVGltZSh0aGlzLCAhd2l0aFN1ZmZpeCwgdGhpcy5sb2NhbGVEYXRhKCkpO1xuXG4gICAgICAgICAgICBpZiAod2l0aFN1ZmZpeCkge1xuICAgICAgICAgICAgICAgIG91dHB1dCA9IHRoaXMubG9jYWxlRGF0YSgpLnBhc3RGdXR1cmUoK3RoaXMsIG91dHB1dCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5wb3N0Zm9ybWF0KG91dHB1dCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYWRkIDogZnVuY3Rpb24gKGlucHV0LCB2YWwpIHtcbiAgICAgICAgICAgIC8vIHN1cHBvcnRzIG9ubHkgMi4wLXN0eWxlIGFkZCgxLCAncycpIG9yIGFkZChtb21lbnQpXG4gICAgICAgICAgICB2YXIgZHVyID0gbW9tZW50LmR1cmF0aW9uKGlucHV0LCB2YWwpO1xuXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgKz0gZHVyLl9taWxsaXNlY29uZHM7XG4gICAgICAgICAgICB0aGlzLl9kYXlzICs9IGR1ci5fZGF5cztcbiAgICAgICAgICAgIHRoaXMuX21vbnRocyArPSBkdXIuX21vbnRocztcblxuICAgICAgICAgICAgdGhpcy5fYnViYmxlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIHN1YnRyYWN0IDogZnVuY3Rpb24gKGlucHV0LCB2YWwpIHtcbiAgICAgICAgICAgIHZhciBkdXIgPSBtb21lbnQuZHVyYXRpb24oaW5wdXQsIHZhbCk7XG5cbiAgICAgICAgICAgIHRoaXMuX21pbGxpc2Vjb25kcyAtPSBkdXIuX21pbGxpc2Vjb25kcztcbiAgICAgICAgICAgIHRoaXMuX2RheXMgLT0gZHVyLl9kYXlzO1xuICAgICAgICAgICAgdGhpcy5fbW9udGhzIC09IGR1ci5fbW9udGhzO1xuXG4gICAgICAgICAgICB0aGlzLl9idWJibGUoKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKHVuaXRzKSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzLnRvTG93ZXJDYXNlKCkgKyAncyddKCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYXMgOiBmdW5jdGlvbiAodW5pdHMpIHtcbiAgICAgICAgICAgIHZhciBkYXlzLCBtb250aHM7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAnbW9udGgnIHx8IHVuaXRzID09PSAneWVhcicpIHtcbiAgICAgICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIHRoaXMuX21pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgIG1vbnRocyA9IHRoaXMuX21vbnRocyArIGRheXNUb1llYXJzKGRheXMpICogMTI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuaXRzID09PSAnbW9udGgnID8gbW9udGhzIDogbW9udGhzIC8gMTI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBtaWxsaXNlY29uZHMgc2VwYXJhdGVseSBiZWNhdXNlIG9mIGZsb2F0aW5nIHBvaW50IG1hdGggZXJyb3JzIChpc3N1ZSAjMTg2NylcbiAgICAgICAgICAgICAgICBkYXlzID0gdGhpcy5fZGF5cyArIE1hdGgucm91bmQoeWVhcnNUb0RheXModGhpcy5fbW9udGhzIC8gMTIpKTtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKHVuaXRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ3dlZWsnOiByZXR1cm4gZGF5cyAvIDcgKyB0aGlzLl9taWxsaXNlY29uZHMgLyA2MDQ4ZTU7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2RheSc6IHJldHVybiBkYXlzICsgdGhpcy5fbWlsbGlzZWNvbmRzIC8gODY0ZTU7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ2hvdXInOiByZXR1cm4gZGF5cyAqIDI0ICsgdGhpcy5fbWlsbGlzZWNvbmRzIC8gMzZlNTtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbWludXRlJzogcmV0dXJuIGRheXMgKiAyNCAqIDYwICsgdGhpcy5fbWlsbGlzZWNvbmRzIC8gNmU0O1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdzZWNvbmQnOiByZXR1cm4gZGF5cyAqIDI0ICogNjAgKiA2MCArIHRoaXMuX21pbGxpc2Vjb25kcyAvIDEwMDA7XG4gICAgICAgICAgICAgICAgICAgIC8vIE1hdGguZmxvb3IgcHJldmVudHMgZmxvYXRpbmcgcG9pbnQgbWF0aCBlcnJvcnMgaGVyZVxuICAgICAgICAgICAgICAgICAgICBjYXNlICdtaWxsaXNlY29uZCc6IHJldHVybiBNYXRoLmZsb29yKGRheXMgKiAyNCAqIDYwICogNjAgKiAxMDAwKSArIHRoaXMuX21pbGxpc2Vjb25kcztcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIHVuaXQgJyArIHVuaXRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgbGFuZyA6IG1vbWVudC5mbi5sYW5nLFxuICAgICAgICBsb2NhbGUgOiBtb21lbnQuZm4ubG9jYWxlLFxuXG4gICAgICAgIHRvSXNvU3RyaW5nIDogZGVwcmVjYXRlKFxuICAgICAgICAgICAgJ3RvSXNvU3RyaW5nKCkgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSB0b0lTT1N0cmluZygpIGluc3RlYWQgJyArXG4gICAgICAgICAgICAnKG5vdGljZSB0aGUgY2FwaXRhbHMpJyxcbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICApLFxuXG4gICAgICAgIHRvSVNPU3RyaW5nIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gaW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL2RvcmRpbGxlL21vbWVudC1pc29kdXJhdGlvbi9ibG9iL21hc3Rlci9tb21lbnQuaXNvZHVyYXRpb24uanNcbiAgICAgICAgICAgIHZhciB5ZWFycyA9IE1hdGguYWJzKHRoaXMueWVhcnMoKSksXG4gICAgICAgICAgICAgICAgbW9udGhzID0gTWF0aC5hYnModGhpcy5tb250aHMoKSksXG4gICAgICAgICAgICAgICAgZGF5cyA9IE1hdGguYWJzKHRoaXMuZGF5cygpKSxcbiAgICAgICAgICAgICAgICBob3VycyA9IE1hdGguYWJzKHRoaXMuaG91cnMoKSksXG4gICAgICAgICAgICAgICAgbWludXRlcyA9IE1hdGguYWJzKHRoaXMubWludXRlcygpKSxcbiAgICAgICAgICAgICAgICBzZWNvbmRzID0gTWF0aC5hYnModGhpcy5zZWNvbmRzKCkgKyB0aGlzLm1pbGxpc2Vjb25kcygpIC8gMTAwMCk7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5hc1NlY29uZHMoKSkge1xuICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgdGhlIHNhbWUgYXMgQyMncyAoTm9kYSkgYW5kIHB5dGhvbiAoaXNvZGF0ZSkuLi5cbiAgICAgICAgICAgICAgICAvLyBidXQgbm90IG90aGVyIEpTIChnb29nLmRhdGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuICdQMEQnO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKHRoaXMuYXNTZWNvbmRzKCkgPCAwID8gJy0nIDogJycpICtcbiAgICAgICAgICAgICAgICAnUCcgK1xuICAgICAgICAgICAgICAgICh5ZWFycyA/IHllYXJzICsgJ1knIDogJycpICtcbiAgICAgICAgICAgICAgICAobW9udGhzID8gbW9udGhzICsgJ00nIDogJycpICtcbiAgICAgICAgICAgICAgICAoZGF5cyA/IGRheXMgKyAnRCcgOiAnJykgK1xuICAgICAgICAgICAgICAgICgoaG91cnMgfHwgbWludXRlcyB8fCBzZWNvbmRzKSA/ICdUJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgKGhvdXJzID8gaG91cnMgKyAnSCcgOiAnJykgK1xuICAgICAgICAgICAgICAgIChtaW51dGVzID8gbWludXRlcyArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgKHNlY29uZHMgPyBzZWNvbmRzICsgJ1MnIDogJycpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGxvY2FsZURhdGEgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBtb21lbnQuZHVyYXRpb24uZm4udG9TdHJpbmcgPSBtb21lbnQuZHVyYXRpb24uZm4udG9JU09TdHJpbmc7XG5cbiAgICBmdW5jdGlvbiBtYWtlRHVyYXRpb25HZXR0ZXIobmFtZSkge1xuICAgICAgICBtb21lbnQuZHVyYXRpb24uZm5bbmFtZV0gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGF0YVtuYW1lXTtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3IgKGkgaW4gdW5pdE1pbGxpc2Vjb25kRmFjdG9ycykge1xuICAgICAgICBpZiAoaGFzT3duUHJvcCh1bml0TWlsbGlzZWNvbmRGYWN0b3JzLCBpKSkge1xuICAgICAgICAgICAgbWFrZUR1cmF0aW9uR2V0dGVyKGkudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNNaWxsaXNlY29uZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdtcycpO1xuICAgIH07XG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzU2Vjb25kcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXMoJ3MnKTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5hc01pbnV0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdtJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNIb3VycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXMoJ2gnKTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5hc0RheXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdkJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNXZWVrcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXMoJ3dlZWtzJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNNb250aHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdNJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNZZWFycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXMoJ3knKTtcbiAgICB9O1xuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBEZWZhdWx0IExvY2FsZVxuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG4gICAgLy8gU2V0IGRlZmF1bHQgbG9jYWxlLCBvdGhlciBsb2NhbGUgd2lsbCBpbmhlcml0IGZyb20gRW5nbGlzaC5cbiAgICBtb21lbnQubG9jYWxlKCdlbicsIHtcbiAgICAgICAgb3JkaW5hbFBhcnNlOiAvXFxkezEsMn0odGh8c3R8bmR8cmQpLyxcbiAgICAgICAgb3JkaW5hbCA6IGZ1bmN0aW9uIChudW1iZXIpIHtcbiAgICAgICAgICAgIHZhciBiID0gbnVtYmVyICUgMTAsXG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gKHRvSW50KG51bWJlciAlIDEwMCAvIDEwKSA9PT0gMSkgPyAndGgnIDpcbiAgICAgICAgICAgICAgICAoYiA9PT0gMSkgPyAnc3QnIDpcbiAgICAgICAgICAgICAgICAoYiA9PT0gMikgPyAnbmQnIDpcbiAgICAgICAgICAgICAgICAoYiA9PT0gMykgPyAncmQnIDogJ3RoJztcbiAgICAgICAgICAgIHJldHVybiBudW1iZXIgKyBvdXRwdXQ7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qIEVNQkVEX0xPQ0FMRVMgKi9cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgRXhwb3NpbmcgTW9tZW50XG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZnVuY3Rpb24gbWFrZUdsb2JhbChzaG91bGREZXByZWNhdGUpIHtcbiAgICAgICAgLypnbG9iYWwgZW5kZXI6ZmFsc2UgKi9cbiAgICAgICAgaWYgKHR5cGVvZiBlbmRlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBvbGRHbG9iYWxNb21lbnQgPSBnbG9iYWxTY29wZS5tb21lbnQ7XG4gICAgICAgIGlmIChzaG91bGREZXByZWNhdGUpIHtcbiAgICAgICAgICAgIGdsb2JhbFNjb3BlLm1vbWVudCA9IGRlcHJlY2F0ZShcbiAgICAgICAgICAgICAgICAgICAgJ0FjY2Vzc2luZyBNb21lbnQgdGhyb3VnaCB0aGUgZ2xvYmFsIHNjb3BlIGlzICcgK1xuICAgICAgICAgICAgICAgICAgICAnZGVwcmVjYXRlZCwgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhbiB1cGNvbWluZyAnICtcbiAgICAgICAgICAgICAgICAgICAgJ3JlbGVhc2UuJyxcbiAgICAgICAgICAgICAgICAgICAgbW9tZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGdsb2JhbFNjb3BlLm1vbWVudCA9IG1vbWVudDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIENvbW1vbkpTIG1vZHVsZSBpcyBkZWZpbmVkXG4gICAgaWYgKGhhc01vZHVsZSkge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IG1vbWVudDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICBkZWZpbmUoJ21vbWVudCcsIGZ1bmN0aW9uIChyZXF1aXJlLCBleHBvcnRzLCBtb2R1bGUpIHtcbiAgICAgICAgICAgIGlmIChtb2R1bGUuY29uZmlnICYmIG1vZHVsZS5jb25maWcoKSAmJiBtb2R1bGUuY29uZmlnKCkubm9HbG9iYWwgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICAvLyByZWxlYXNlIHRoZSBnbG9iYWwgdmFyaWFibGVcbiAgICAgICAgICAgICAgICBnbG9iYWxTY29wZS5tb21lbnQgPSBvbGRHbG9iYWxNb21lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBtb21lbnQ7XG4gICAgICAgIH0pO1xuICAgICAgICBtYWtlR2xvYmFsKHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIG1ha2VHbG9iYWwoKTtcbiAgICB9XG59KS5jYWxsKHRoaXMpO1xuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vbGliLycpO1xuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHVybCA9IHJlcXVpcmUoJy4vdXJsJyk7XG52YXIgcGFyc2VyID0gcmVxdWlyZSgnc29ja2V0LmlvLXBhcnNlcicpO1xudmFyIE1hbmFnZXIgPSByZXF1aXJlKCcuL21hbmFnZXInKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBsb29rdXA7XG5cbi8qKlxuICogTWFuYWdlcnMgY2FjaGUuXG4gKi9cblxudmFyIGNhY2hlID0gZXhwb3J0cy5tYW5hZ2VycyA9IHt9O1xuXG4vKipcbiAqIExvb2tzIHVwIGFuIGV4aXN0aW5nIGBNYW5hZ2VyYCBmb3IgbXVsdGlwbGV4aW5nLlxuICogSWYgdGhlIHVzZXIgc3VtbW9uczpcbiAqXG4gKiAgIGBpbygnaHR0cDovL2xvY2FsaG9zdC9hJyk7YFxuICogICBgaW8oJ2h0dHA6Ly9sb2NhbGhvc3QvYicpO2BcbiAqXG4gKiBXZSByZXVzZSB0aGUgZXhpc3RpbmcgaW5zdGFuY2UgYmFzZWQgb24gc2FtZSBzY2hlbWUvcG9ydC9ob3N0LFxuICogYW5kIHdlIGluaXRpYWxpemUgc29ja2V0cyBmb3IgZWFjaCBuYW1lc3BhY2UuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb29rdXAodXJpLCBvcHRzKSB7XG4gIGlmICh0eXBlb2YgdXJpID09ICdvYmplY3QnKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICB2YXIgcGFyc2VkID0gdXJsKHVyaSk7XG4gIHZhciBzb3VyY2UgPSBwYXJzZWQuc291cmNlO1xuICB2YXIgaWQgPSBwYXJzZWQuaWQ7XG4gIHZhciBpbztcblxuICBpZiAob3B0cy5mb3JjZU5ldyB8fCBvcHRzWydmb3JjZSBuZXcgY29ubmVjdGlvbiddIHx8IGZhbHNlID09PSBvcHRzLm11bHRpcGxleCkge1xuICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICBpbyA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgZGVidWcoJ25ldyBpbyBpbnN0YW5jZSBmb3IgJXMnLCBzb3VyY2UpO1xuICAgICAgY2FjaGVbaWRdID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgIH1cbiAgICBpbyA9IGNhY2hlW2lkXTtcbiAgfVxuXG4gIHJldHVybiBpby5zb2NrZXQocGFyc2VkLnBhdGgpO1xufVxuXG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sO1xuXG4vKipcbiAqIGBjb25uZWN0YC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuY29ubmVjdCA9IGxvb2t1cDtcblxuLyoqXG4gKiBFeHBvc2UgY29uc3RydWN0b3JzIGZvciBzdGFuZGFsb25lIGJ1aWxkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5NYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG5leHBvcnRzLlNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG4iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdXJsID0gcmVxdWlyZSgnLi91cmwnKTtcbnZhciBlaW8gPSByZXF1aXJlKCdlbmdpbmUuaW8tY2xpZW50Jyk7XG52YXIgU29ja2V0ID0gcmVxdWlyZSgnLi9zb2NrZXQnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgb2JqZWN0ID0gcmVxdWlyZSgnb2JqZWN0LWNvbXBvbmVudCcpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudDptYW5hZ2VyJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyKHVyaSwgb3B0cyl7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBNYW5hZ2VyKSkgcmV0dXJuIG5ldyBNYW5hZ2VyKHVyaSwgb3B0cyk7XG4gIGlmICh1cmkgJiYgKCdvYmplY3QnID09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGVkID0gMDtcbiAgdGhpcy5hdHRlbXB0cyA9IDA7XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgdGhpcy5wYWNrZXRCdWZmZXIgPSBbXTtcbiAgdGhpcy5lbmNvZGVyID0gbmV3IHBhcnNlci5FbmNvZGVyKCk7XG4gIHRoaXMuZGVjb2RlciA9IG5ldyBwYXJzZXIuRGVjb2RlcigpO1xuICB0aGlzLmF1dG9Db25uZWN0ID0gb3B0cy5hdXRvQ29ubmVjdCAhPT0gZmFsc2U7XG4gIGlmICh0aGlzLmF1dG9Db25uZWN0KSB0aGlzLm9wZW4oKTtcbn1cblxuLyoqXG4gKiBQcm9wYWdhdGUgZ2l2ZW4gZXZlbnQgdG8gc29ja2V0cyBhbmQgZW1pdCBvbiBgdGhpc2BcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5lbWl0QWxsID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICBmb3IgKHZhciBuc3AgaW4gdGhpcy5uc3BzKSB7XG4gICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoTWFuYWdlci5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFNldHMgdGhlIGByZWNvbm5lY3Rpb25gIGNvbmZpZy5cbiAqXG4gKiBAcGFyYW0ge0Jvb2xlYW59IHRydWUvZmFsc2UgaWYgaXQgc2hvdWxkIGF1dG9tYXRpY2FsbHkgcmVjb25uZWN0XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbiA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb247XG4gIHRoaXMuX3JlY29ubmVjdGlvbiA9ICEhdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgYmVmb3JlIGdpdmluZyB1cFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cztcbiAgdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHMgPSB2O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheSA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheTtcbiAgdGhpcy5fcmVjb25uZWN0aW9uRGVsYXkgPSB2O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgbWF4aW11bSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGRlbGF5XG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5TWF4ID0gZnVuY3Rpb24odil7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5TWF4O1xuICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBjb25uZWN0aW9uIHRpbWVvdXQuIGBmYWxzZWAgdG8gZGlzYWJsZVxuICpcbiAqIEByZXR1cm4ge01hbmFnZXJ9IHNlbGYgb3IgdmFsdWVcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl90aW1lb3V0O1xuICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyB0cnlpbmcgdG8gcmVjb25uZWN0IGlmIHJlY29ubmVjdGlvbiBpcyBlbmFibGVkIGFuZCB3ZSBoYXZlIG5vdFxuICogc3RhcnRlZCByZWNvbm5lY3RpbmcgeWV0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbigpIHtcbiAgLy8gT25seSB0cnkgdG8gcmVjb25uZWN0IGlmIGl0J3MgdGhlIGZpcnN0IHRpbWUgd2UncmUgY29ubmVjdGluZ1xuICBpZiAoIXRoaXMub3BlblJlY29ubmVjdCAmJiAhdGhpcy5yZWNvbm5lY3RpbmcgJiYgdGhpcy5fcmVjb25uZWN0aW9uICYmIHRoaXMuYXR0ZW1wdHMgPT09IDApIHtcbiAgICAvLyBrZWVwcyByZWNvbm5lY3Rpb24gZnJvbSBmaXJpbmcgdHdpY2UgZm9yIHRoZSBzYW1lIHJlY29ubmVjdGlvbiBsb29wXG4gICAgdGhpcy5vcGVuUmVjb25uZWN0ID0gdHJ1ZTtcbiAgICB0aGlzLnJlY29ubmVjdCgpO1xuICB9XG59O1xuXG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB0cmFuc3BvcnQgYHNvY2tldGAuXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9uYWwsIGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9wZW4gPVxuTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKGZuKXtcbiAgZGVidWcoJ3JlYWR5U3RhdGUgJXMnLCB0aGlzLnJlYWR5U3RhdGUpO1xuICBpZiAofnRoaXMucmVhZHlTdGF0ZS5pbmRleE9mKCdvcGVuJykpIHJldHVybiB0aGlzO1xuXG4gIGRlYnVnKCdvcGVuaW5nICVzJywgdGhpcy51cmkpO1xuICB0aGlzLmVuZ2luZSA9IGVpbyh0aGlzLnVyaSwgdGhpcy5vcHRzKTtcbiAgdmFyIHNvY2tldCA9IHRoaXMuZW5naW5lO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBlbWl0IGBvcGVuYFxuICB2YXIgb3BlblN1YiA9IG9uKHNvY2tldCwgJ29wZW4nLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLm9ub3BlbigpO1xuICAgIGZuICYmIGZuKCk7XG4gIH0pO1xuXG4gIC8vIGVtaXQgYGNvbm5lY3RfZXJyb3JgXG4gIHZhciBlcnJvclN1YiA9IG9uKHNvY2tldCwgJ2Vycm9yJywgZnVuY3Rpb24oZGF0YSl7XG4gICAgZGVidWcoJ2Nvbm5lY3RfZXJyb3InKTtcbiAgICBzZWxmLmNsZWFudXAoKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfZXJyb3InLCBkYXRhKTtcbiAgICBpZiAoZm4pIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgIGVyci5kYXRhID0gZGF0YTtcbiAgICAgIGZuKGVycik7XG4gICAgfVxuXG4gICAgc2VsZi5tYXliZVJlY29ubmVjdE9uT3BlbigpO1xuICB9KTtcblxuICAvLyBlbWl0IGBjb25uZWN0X3RpbWVvdXRgXG4gIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgIHZhciB0aW1lb3V0ID0gdGhpcy5fdGltZW91dDtcbiAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHdpbGwgdGltZW91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuXG4gICAgLy8gc2V0IHRpbWVyXG4gICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgZGVidWcoJ2Nvbm5lY3QgYXR0ZW1wdCB0aW1lZCBvdXQgYWZ0ZXIgJWQnLCB0aW1lb3V0KTtcbiAgICAgIG9wZW5TdWIuZGVzdHJveSgpO1xuICAgICAgc29ja2V0LmNsb3NlKCk7XG4gICAgICBzb2NrZXQuZW1pdCgnZXJyb3InLCAndGltZW91dCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdjb25uZWN0X3RpbWVvdXQnLCB0aW1lb3V0KTtcbiAgICB9LCB0aW1lb3V0KTtcblxuICAgIHRoaXMuc3Vicy5wdXNoKHtcbiAgICAgIGRlc3Ryb3k6IGZ1bmN0aW9uKCl7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICB0aGlzLnN1YnMucHVzaChvcGVuU3ViKTtcbiAgdGhpcy5zdWJzLnB1c2goZXJyb3JTdWIpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgb3Blbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbigpe1xuICBkZWJ1Zygnb3BlbicpO1xuXG4gIC8vIGNsZWFyIG9sZCBzdWJzXG4gIHRoaXMuY2xlYW51cCgpO1xuXG4gIC8vIG1hcmsgYXMgb3BlblxuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuXG4gIC8vIGFkZCBuZXcgc3Vic1xuICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHNvY2tldCwgJ2RhdGEnLCBiaW5kKHRoaXMsICdvbmRhdGEnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbih0aGlzLmRlY29kZXIsICdkZWNvZGVkJywgYmluZCh0aGlzLCAnb25kZWNvZGVkJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAnZXJyb3InLCBiaW5kKHRoaXMsICdvbmVycm9yJykpKTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggZGF0YS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmRhdGEgPSBmdW5jdGlvbihkYXRhKXtcbiAgdGhpcy5kZWNvZGVyLmFkZChkYXRhKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdoZW4gcGFyc2VyIGZ1bGx5IGRlY29kZXMgYSBwYWNrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25kZWNvZGVkID0gZnVuY3Rpb24ocGFja2V0KSB7XG4gIHRoaXMuZW1pdCgncGFja2V0JywgcGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gc29ja2V0IGVycm9yLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZXJyb3IgPSBmdW5jdGlvbihlcnIpe1xuICBkZWJ1ZygnZXJyb3InLCBlcnIpO1xuICB0aGlzLmVtaXRBbGwoJ2Vycm9yJywgZXJyKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBzb2NrZXQgZm9yIHRoZSBnaXZlbiBgbnNwYC5cbiAqXG4gKiBAcmV0dXJuIHtTb2NrZXR9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnNvY2tldCA9IGZ1bmN0aW9uKG5zcCl7XG4gIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgaWYgKCFzb2NrZXQpIHtcbiAgICBzb2NrZXQgPSBuZXcgU29ja2V0KHRoaXMsIG5zcCk7XG4gICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNvY2tldC5vbignY29ubmVjdCcsIGZ1bmN0aW9uKCl7XG4gICAgICBzZWxmLmNvbm5lY3RlZCsrO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBzb2NrZXQ7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc29ja2V0IGNsb3NlLlxuICpcbiAqIEBwYXJhbSB7U29ja2V0fSBzb2NrZXRcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oc29ja2V0KXtcbiAgLS10aGlzLmNvbm5lY3RlZCB8fCB0aGlzLmNsb3NlKCk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5wYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICBkZWJ1Zygnd3JpdGluZyBwYWNrZXQgJWonLCBwYWNrZXQpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCFzZWxmLmVuY29kaW5nKSB7XG4gICAgLy8gZW5jb2RlLCB0aGVuIHdyaXRlIHRvIGVuZ2luZSB3aXRoIHJlc3VsdFxuICAgIHNlbGYuZW5jb2RpbmcgPSB0cnVlO1xuICAgIHRoaXMuZW5jb2Rlci5lbmNvZGUocGFja2V0LCBmdW5jdGlvbihlbmNvZGVkUGFja2V0cykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkUGFja2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSk7XG4gICAgICB9XG4gICAgICBzZWxmLmVuY29kaW5nID0gZmFsc2U7XG4gICAgICBzZWxmLnByb2Nlc3NQYWNrZXRRdWV1ZSgpO1xuICAgIH0pO1xuICB9IGVsc2UgeyAvLyBhZGQgcGFja2V0IHRvIHRoZSBxdWV1ZVxuICAgIHNlbGYucGFja2V0QnVmZmVyLnB1c2gocGFja2V0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBJZiBwYWNrZXQgYnVmZmVyIGlzIG5vbi1lbXB0eSwgYmVnaW5zIGVuY29kaW5nIHRoZVxuICogbmV4dCBwYWNrZXQgaW4gbGluZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5wcm9jZXNzUGFja2V0UXVldWUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMucGFja2V0QnVmZmVyLmxlbmd0aCA+IDAgJiYgIXRoaXMuZW5jb2RpbmcpIHtcbiAgICB2YXIgcGFjayA9IHRoaXMucGFja2V0QnVmZmVyLnNoaWZ0KCk7XG4gICAgdGhpcy5wYWNrZXQocGFjayk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2xlYW4gdXAgdHJhbnNwb3J0IHN1YnNjcmlwdGlvbnMgYW5kIHBhY2tldCBidWZmZXIuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzdWI7XG4gIHdoaWxlIChzdWIgPSB0aGlzLnN1YnMuc2hpZnQoKSkgc3ViLmRlc3Ryb3koKTtcblxuICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICB0aGlzLmVuY29kaW5nID0gZmFsc2U7XG5cbiAgdGhpcy5kZWNvZGVyLmRlc3Ryb3koKTtcbn07XG5cbi8qKlxuICogQ2xvc2UgdGhlIGN1cnJlbnQgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLmNsb3NlID1cbk1hbmFnZXIucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbigpe1xuICB0aGlzLnNraXBSZWNvbm5lY3QgPSB0cnVlO1xuICB0aGlzLmVuZ2luZS5jbG9zZSgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25jbG9zZSA9IGZ1bmN0aW9uKHJlYXNvbil7XG4gIGRlYnVnKCdjbG9zZScpO1xuICB0aGlzLmNsZWFudXAoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuICBpZiAodGhpcy5fcmVjb25uZWN0aW9uICYmICF0aGlzLnNraXBSZWNvbm5lY3QpIHtcbiAgICB0aGlzLnJlY29ubmVjdCgpO1xuICB9XG59O1xuXG4vKipcbiAqIEF0dGVtcHQgYSByZWNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMucmVjb25uZWN0aW5nKSByZXR1cm4gdGhpcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuYXR0ZW1wdHMrKztcblxuICBpZiAodGhpcy5hdHRlbXB0cyA+IHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzKSB7XG4gICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICB0aGlzLmVtaXRBbGwoJ3JlY29ubmVjdF9mYWlsZWQnKTtcbiAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIHZhciBkZWxheSA9IHRoaXMuYXR0ZW1wdHMgKiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KCk7XG4gICAgZGVsYXkgPSBNYXRoLm1pbihkZWxheSwgdGhpcy5yZWNvbm5lY3Rpb25EZWxheU1heCgpKTtcbiAgICBkZWJ1Zygnd2lsbCB3YWl0ICVkbXMgYmVmb3JlIHJlY29ubmVjdCBhdHRlbXB0JywgZGVsYXkpO1xuXG4gICAgdGhpcy5yZWNvbm5lY3RpbmcgPSB0cnVlO1xuICAgIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYXR0ZW1wdHMpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RpbmcnLCBzZWxmLmF0dGVtcHRzKTtcbiAgICAgIHNlbGYub3BlbihmdW5jdGlvbihlcnIpe1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbnJlY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBhdHRlbXB0ID0gdGhpcy5hdHRlbXB0cztcbiAgdGhpcy5hdHRlbXB0cyA9IDA7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gb247XG5cbi8qKlxuICogSGVscGVyIGZvciBzdWJzY3JpcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEV2ZW50RW1pdHRlcn0gb2JqIHdpdGggYEVtaXR0ZXJgIG1peGluIG9yIGBFdmVudEVtaXR0ZXJgXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgbmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gb24ob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgIG9iai5yZW1vdmVMaXN0ZW5lcihldiwgZm4pO1xuICAgIH1cbiAgfTtcbn1cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgdG9BcnJheSA9IHJlcXVpcmUoJ3RvLWFycmF5Jyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGhhc0JpbiA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcbnZhciBpbmRleE9mID0gcmVxdWlyZSgnaW5kZXhvZicpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IFNvY2tldDtcblxuLyoqXG4gKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAqIFRoZXNlIGV2ZW50cyBjYW4ndCBiZSBlbWl0dGVkIGJ5IHRoZSB1c2VyLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbnZhciBldmVudHMgPSB7XG4gIGNvbm5lY3Q6IDEsXG4gIGNvbm5lY3RfZXJyb3I6IDEsXG4gIGNvbm5lY3RfdGltZW91dDogMSxcbiAgZGlzY29ubmVjdDogMSxcbiAgZXJyb3I6IDEsXG4gIHJlY29ubmVjdDogMSxcbiAgcmVjb25uZWN0X2F0dGVtcHQ6IDEsXG4gIHJlY29ubmVjdF9mYWlsZWQ6IDEsXG4gIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgcmVjb25uZWN0aW5nOiAxXG59O1xuXG4vKipcbiAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICovXG5cbnZhciBlbWl0ID0gRW1pdHRlci5wcm90b3R5cGUuZW1pdDtcblxuLyoqXG4gKiBgU29ja2V0YCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFNvY2tldChpbywgbnNwKXtcbiAgdGhpcy5pbyA9IGlvO1xuICB0aGlzLm5zcCA9IG5zcDtcbiAgdGhpcy5qc29uID0gdGhpczsgLy8gY29tcGF0XG4gIHRoaXMuaWRzID0gMDtcbiAgdGhpcy5hY2tzID0ge307XG4gIGlmICh0aGlzLmlvLmF1dG9Db25uZWN0KSB0aGlzLm9wZW4oKTtcbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIHRoaXMuc3ViRXZlbnRzKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFNvY2tldC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc3ViRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpbyA9IHRoaXMuaW87XG4gIHRoaXMuc3VicyA9IFtcbiAgICBvbihpbywgJ29wZW4nLCBiaW5kKHRoaXMsICdvbm9wZW4nKSksXG4gICAgb24oaW8sICdwYWNrZXQnLCBiaW5kKHRoaXMsICdvbnBhY2tldCcpKSxcbiAgICBvbihpbywgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKVxuICBdO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgYG9wZW5gLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub3BlbiA9XG5Tb2NrZXQucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5jb25uZWN0ZWQpIHJldHVybiB0aGlzO1xuXG4gIHRoaXMuaW8ub3BlbigpOyAvLyBlbnN1cmUgb3BlblxuICBpZiAoJ29wZW4nID09IHRoaXMuaW8ucmVhZHlTdGF0ZSkgdGhpcy5vbm9wZW4oKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbigpe1xuICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgYXJncy51bnNoaWZ0KCdtZXNzYWdlJyk7XG4gIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlIGBlbWl0YC5cbiAqIElmIHRoZSBldmVudCBpcyBpbiBgZXZlbnRzYCwgaXQncyBlbWl0dGVkIG5vcm1hbGx5LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBuYW1lXG4gKiBAcmV0dXJuIHtTb2NrZXR9IHNlbGZcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXYpe1xuICBpZiAoZXZlbnRzLmhhc093blByb3BlcnR5KGV2KSkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICB2YXIgcGFyc2VyVHlwZSA9IHBhcnNlci5FVkVOVDsgLy8gZGVmYXVsdFxuICBpZiAoaGFzQmluKGFyZ3MpKSB7IHBhcnNlclR5cGUgPSBwYXJzZXIuQklOQVJZX0VWRU5UOyB9IC8vIGJpbmFyeVxuICB2YXIgcGFja2V0ID0geyB0eXBlOiBwYXJzZXJUeXBlLCBkYXRhOiBhcmdzIH07XG5cbiAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBhcmdzW2FyZ3MubGVuZ3RoIC0gMV0pIHtcbiAgICBkZWJ1ZygnZW1pdHRpbmcgcGFja2V0IHdpdGggYWNrIGlkICVkJywgdGhpcy5pZHMpO1xuICAgIHRoaXMuYWNrc1t0aGlzLmlkc10gPSBhcmdzLnBvcCgpO1xuICAgIHBhY2tldC5pZCA9IHRoaXMuaWRzKys7XG4gIH1cblxuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICB0aGlzLnBhY2tldChwYWNrZXQpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuc2VuZEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgYSBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5wYWNrZXQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICBwYWNrZXQubnNwID0gdGhpcy5uc3A7XG4gIHRoaXMuaW8ucGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25vcGVuID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ3RyYW5zcG9ydCBpcyBvcGVuIC0gY29ubmVjdGluZycpO1xuXG4gIC8vIHdyaXRlIGNvbm5lY3QgcGFja2V0IGlmIG5lY2Vzc2FyeVxuICBpZiAoJy8nICE9IHRoaXMubnNwKSB7XG4gICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuQ09OTkVDVCB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgYGNsb3NlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbihyZWFzb24pe1xuICBkZWJ1ZygnY2xvc2UgKCVzKScsIHJlYXNvbik7XG4gIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdkaXNjb25uZWN0JywgcmVhc29uKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHdpdGggc29ja2V0IHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9ucGFja2V0ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgaWYgKHBhY2tldC5uc3AgIT0gdGhpcy5uc3ApIHJldHVybjtcblxuICBzd2l0Y2ggKHBhY2tldC50eXBlKSB7XG4gICAgY2FzZSBwYXJzZXIuQ09OTkVDVDpcbiAgICAgIHRoaXMub25jb25uZWN0KCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcGFyc2VyLkVWRU5UOlxuICAgICAgdGhpcy5vbmV2ZW50KHBhY2tldCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcGFyc2VyLkJJTkFSWV9FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5BQ0s6XG4gICAgICB0aGlzLm9uYWNrKHBhY2tldCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcGFyc2VyLkJJTkFSWV9BQ0s6XG4gICAgICB0aGlzLm9uYWNrKHBhY2tldCk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcGFyc2VyLkRJU0NPTk5FQ1Q6XG4gICAgICB0aGlzLm9uZGlzY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FUlJPUjpcbiAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBwYWNrZXQuZGF0YSk7XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBhIHNlcnZlciBldmVudC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uZXZlbnQgPSBmdW5jdGlvbihwYWNrZXQpe1xuICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICBkZWJ1ZygnZW1pdHRpbmcgZXZlbnQgJWonLCBhcmdzKTtcblxuICBpZiAobnVsbCAhPSBwYWNrZXQuaWQpIHtcbiAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgIGFyZ3MucHVzaCh0aGlzLmFjayhwYWNrZXQuaWQpKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIGVtaXQuYXBwbHkodGhpcywgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gIH1cbn07XG5cbi8qKlxuICogUHJvZHVjZXMgYW4gYWNrIGNhbGxiYWNrIHRvIGVtaXQgd2l0aCBhbiBldmVudC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmFjayA9IGZ1bmN0aW9uKGlkKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgc2VudCA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24oKXtcbiAgICAvLyBwcmV2ZW50IGRvdWJsZSBjYWxsYmFja3NcbiAgICBpZiAoc2VudCkgcmV0dXJuO1xuICAgIHNlbnQgPSB0cnVlO1xuICAgIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICAgIGRlYnVnKCdzZW5kaW5nIGFjayAlaicsIGFyZ3MpO1xuXG4gICAgdmFyIHR5cGUgPSBoYXNCaW4oYXJncykgPyBwYXJzZXIuQklOQVJZX0FDSyA6IHBhcnNlci5BQ0s7XG4gICAgc2VsZi5wYWNrZXQoe1xuICAgICAgdHlwZTogdHlwZSxcbiAgICAgIGlkOiBpZCxcbiAgICAgIGRhdGE6IGFyZ3NcbiAgICB9KTtcbiAgfTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgYWNrbm93bGVnZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmFjayA9IGZ1bmN0aW9uKHBhY2tldCl7XG4gIGRlYnVnKCdjYWxsaW5nIGFjayAlcyB3aXRoICVqJywgcGFja2V0LmlkLCBwYWNrZXQuZGF0YSk7XG4gIHZhciBmbiA9IHRoaXMuYWNrc1twYWNrZXQuaWRdO1xuICBmbi5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gIGRlbGV0ZSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gc2VydmVyIGNvbm5lY3QuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNvbm5lY3QgPSBmdW5jdGlvbigpe1xuICB0aGlzLmNvbm5lY3RlZCA9IHRydWU7XG4gIHRoaXMuZGlzY29ubmVjdGVkID0gZmFsc2U7XG4gIHRoaXMuZW1pdCgnY29ubmVjdCcpO1xuICB0aGlzLmVtaXRCdWZmZXJlZCgpO1xufTtcblxuLyoqXG4gKiBFbWl0IGJ1ZmZlcmVkIGV2ZW50cyAocmVjZWl2ZWQgYW5kIGVtaXR0ZWQpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZW1pdEJ1ZmZlcmVkID0gZnVuY3Rpb24oKXtcbiAgdmFyIGk7XG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIHRoaXMucmVjZWl2ZUJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgZm9yIChpID0gMDsgaSA8IHRoaXMuc2VuZEJ1ZmZlci5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMucGFja2V0KHRoaXMuc2VuZEJ1ZmZlcltpXSk7XG4gIH1cbiAgdGhpcy5zZW5kQnVmZmVyID0gW107XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBkaXNjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25kaXNjb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ3NlcnZlciBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gIHRoaXMuZGVzdHJveSgpO1xuICB0aGlzLm9uY2xvc2UoJ2lvIHNlcnZlciBkaXNjb25uZWN0Jyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGZvcmNlZCBjbGllbnQvc2VydmVyIHNpZGUgZGlzY29ubmVjdGlvbnMsXG4gKiB0aGlzIG1ldGhvZCBlbnN1cmVzIHRoZSBtYW5hZ2VyIHN0b3BzIHRyYWNraW5nIHVzIGFuZFxuICogdGhhdCByZWNvbm5lY3Rpb25zIGRvbid0IGdldCB0cmlnZ2VyZWQgZm9yIHRoaXMuXG4gKlxuICogQGFwaSBwcml2YXRlLlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCl7XG4gIC8vIGNsZWFuIHN1YnNjcmlwdGlvbnMgdG8gYXZvaWQgcmVjb25uZWN0aW9uc1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc3Vicy5sZW5ndGg7IGkrKykge1xuICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKCF0aGlzLmNvbm5lY3RlZCkgcmV0dXJuIHRoaXM7XG5cbiAgZGVidWcoJ3BlcmZvcm1pbmcgZGlzY29ubmVjdCAoJXMpJywgdGhpcy5uc3ApO1xuICB0aGlzLnBhY2tldCh7IHR5cGU6IHBhcnNlci5ESVNDT05ORUNUIH0pO1xuXG4gIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gIHRoaXMuZGVzdHJveSgpO1xuXG4gIC8vIGZpcmUgZXZlbnRzXG4gIHRoaXMub25jbG9zZSgnaW8gY2xpZW50IGRpc2Nvbm5lY3QnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307XG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNldXJpID0gcmVxdWlyZSgncGFyc2V1cmknKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSB1cmw7XG5cbi8qKlxuICogVVJMIHBhcnNlci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gdXJsXG4gKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAqICAgICAgICAgICAgICAgICBEZWZhdWx0cyB0byB3aW5kb3cubG9jYXRpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHVybCh1cmksIGxvYyl7XG4gIHZhciBvYmogPSB1cmk7XG5cbiAgLy8gZGVmYXVsdCB0byB3aW5kb3cubG9jYXRpb25cbiAgdmFyIGxvYyA9IGxvYyB8fCBnbG9iYWwubG9jYXRpb247XG4gIGlmIChudWxsID09IHVyaSkgdXJpID0gbG9jLnByb3RvY29sICsgJy8vJyArIGxvYy5ob3N0bmFtZTtcblxuICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB1cmkpIHtcbiAgICBpZiAoJy8nID09IHVyaS5jaGFyQXQoMCkpIHtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgbG9jKSB7XG4gICAgICAgIHVyaSA9IGxvYy5ob3N0bmFtZSArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgbG9jKSB7XG4gICAgICAgIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSAnaHR0cHM6Ly8nICsgdXJpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHBhcnNlXG4gICAgZGVidWcoJ3BhcnNlICVzJywgdXJpKTtcbiAgICBvYmogPSBwYXJzZXVyaSh1cmkpO1xuICB9XG5cbiAgLy8gbWFrZSBzdXJlIHdlIHRyZWF0IGBsb2NhbGhvc3Q6ODBgIGFuZCBgbG9jYWxob3N0YCBlcXVhbGx5XG4gIGlmICghb2JqLnBvcnQpIHtcbiAgICBpZiAoL14oaHR0cHx3cykkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzgwJztcbiAgICB9XG4gICAgZWxzZSBpZiAoL14oaHR0cHx3cylzJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc0NDMnO1xuICAgIH1cbiAgfVxuXG4gIG9iai5wYXRoID0gb2JqLnBhdGggfHwgJy8nO1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBvYmouaG9zdCArICc6JyArIG9iai5wb3J0O1xuICAvLyBkZWZpbmUgaHJlZlxuICBvYmouaHJlZiA9IG9iai5wcm90b2NvbCArICc6Ly8nICsgb2JqLmhvc3QgKyAobG9jICYmIGxvYy5wb3J0ID09IG9iai5wb3J0ID8gJycgOiAoJzonICsgb2JqLnBvcnQpKTtcblxuICByZXR1cm4gb2JqO1xufVxuIiwiLyoqXG4gKiBTbGljZSByZWZlcmVuY2UuXG4gKi9cblxudmFyIHNsaWNlID0gW10uc2xpY2U7XG5cbi8qKlxuICogQmluZCBgb2JqYCB0byBgZm5gLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBmbiBvciBzdHJpbmdcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iaiwgZm4pe1xuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIGZuKSBmbiA9IG9ialtmbl07XG4gIGlmICgnZnVuY3Rpb24nICE9IHR5cGVvZiBmbikgdGhyb3cgbmV3IEVycm9yKCdiaW5kKCkgcmVxdWlyZXMgYSBmdW5jdGlvbicpO1xuICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG9iaiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gIH1cbn07XG4iLCJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iLCJcbi8qKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtUeXBlfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZWJ1ZyhuYW1lKSB7XG4gIGlmICghZGVidWcuZW5hYmxlZChuYW1lKSkgcmV0dXJuIGZ1bmN0aW9uKCl7fTtcblxuICByZXR1cm4gZnVuY3Rpb24oZm10KXtcbiAgICBmbXQgPSBjb2VyY2UoZm10KTtcblxuICAgIHZhciBjdXJyID0gbmV3IERhdGU7XG4gICAgdmFyIG1zID0gY3VyciAtIChkZWJ1Z1tuYW1lXSB8fCBjdXJyKTtcbiAgICBkZWJ1Z1tuYW1lXSA9IGN1cnI7XG5cbiAgICBmbXQgPSBuYW1lXG4gICAgICArICcgJ1xuICAgICAgKyBmbXRcbiAgICAgICsgJyArJyArIGRlYnVnLmh1bWFuaXplKG1zKTtcblxuICAgIC8vIFRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4XG4gICAgLy8gd2hlcmUgYGNvbnNvbGUubG9nYCBkb2Vzbid0IGhhdmUgJ2FwcGx5J1xuICAgIHdpbmRvdy5jb25zb2xlXG4gICAgICAmJiBjb25zb2xlLmxvZ1xuICAgICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLlxuICovXG5cbmRlYnVnLm5hbWVzID0gW107XG5kZWJ1Zy5za2lwcyA9IFtdO1xuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWUuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZGVidWcuZW5hYmxlID0gZnVuY3Rpb24obmFtZSkge1xuICB0cnkge1xuICAgIGxvY2FsU3RvcmFnZS5kZWJ1ZyA9IG5hbWU7XG4gIH0gY2F0Y2goZSl7fVxuXG4gIHZhciBzcGxpdCA9IChuYW1lIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pXG4gICAgLCBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG5hbWUgPSBzcGxpdFtpXS5yZXBsYWNlKCcqJywgJy4qPycpO1xuICAgIGlmIChuYW1lWzBdID09PSAnLScpIHtcbiAgICAgIGRlYnVnLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lLnN1YnN0cigxKSArICckJykpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGRlYnVnLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lICsgJyQnKSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIERpc2FibGUgZGVidWcgb3V0cHV0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZGVidWcuZGlzYWJsZSA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnLmVuYWJsZSgnJyk7XG59O1xuXG4vKipcbiAqIEh1bWFuaXplIHRoZSBnaXZlbiBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5kZWJ1Zy5odW1hbml6ZSA9IGZ1bmN0aW9uKG1zKSB7XG4gIHZhciBzZWMgPSAxMDAwXG4gICAgLCBtaW4gPSA2MCAqIDEwMDBcbiAgICAsIGhvdXIgPSA2MCAqIG1pbjtcblxuICBpZiAobXMgPj0gaG91cikgcmV0dXJuIChtcyAvIGhvdXIpLnRvRml4ZWQoMSkgKyAnaCc7XG4gIGlmIChtcyA+PSBtaW4pIHJldHVybiAobXMgLyBtaW4pLnRvRml4ZWQoMSkgKyAnbSc7XG4gIGlmIChtcyA+PSBzZWMpIHJldHVybiAobXMgLyBzZWMgfCAwKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5kZWJ1Zy5lbmFibGVkID0gZnVuY3Rpb24obmFtZSkge1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gZGVidWcuc2tpcHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoZGVidWcuc2tpcHNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gZGVidWcubmFtZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoZGVidWcubmFtZXNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICovXG5cbmZ1bmN0aW9uIGNvZXJjZSh2YWwpIHtcbiAgaWYgKHZhbCBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gdmFsLnN0YWNrIHx8IHZhbC5tZXNzYWdlO1xuICByZXR1cm4gdmFsO1xufVxuXG4vLyBwZXJzaXN0XG5cbnRyeSB7XG4gIGlmICh3aW5kb3cubG9jYWxTdG9yYWdlKSBkZWJ1Zy5lbmFibGUobG9jYWxTdG9yYWdlLmRlYnVnKTtcbn0gY2F0Y2goZSl7fVxuIiwiXG5tb2R1bGUuZXhwb3J0cyA9ICByZXF1aXJlKCcuL2xpYi8nKTtcbiIsIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3NvY2tldCcpO1xuXG4vKipcbiAqIEV4cG9ydHMgcGFyc2VyXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqXG4gKi9cbm1vZHVsZS5leHBvcnRzLnBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0cycpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpzb2NrZXQnKTtcbnZhciBpbmRleCA9IHJlcXVpcmUoJ2luZGV4b2YnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgcGFyc2V1cmkgPSByZXF1aXJlKCdwYXJzZXVyaScpO1xudmFyIHBhcnNlanNvbiA9IHJlcXVpcmUoJ3BhcnNlanNvbicpO1xudmFyIHBhcnNlcXMgPSByZXF1aXJlKCdwYXJzZXFzJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBTb2NrZXQ7XG5cbi8qKlxuICogTm9vcCBmdW5jdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fVxuXG4vKipcbiAqIFNvY2tldCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IHVyaSBvciBvcHRpb25zXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBTb2NrZXQodXJpLCBvcHRzKXtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PSB0eXBlb2YgdXJpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSBudWxsO1xuICB9XG5cbiAgaWYgKHVyaSkge1xuICAgIHVyaSA9IHBhcnNldXJpKHVyaSk7XG4gICAgb3B0cy5ob3N0ID0gdXJpLmhvc3Q7XG4gICAgb3B0cy5zZWN1cmUgPSB1cmkucHJvdG9jb2wgPT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT0gJ3dzcyc7XG4gICAgb3B0cy5wb3J0ID0gdXJpLnBvcnQ7XG4gICAgaWYgKHVyaS5xdWVyeSkgb3B0cy5xdWVyeSA9IHVyaS5xdWVyeTtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlIDpcbiAgICAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sKTtcblxuICBpZiAob3B0cy5ob3N0KSB7XG4gICAgdmFyIHBpZWNlcyA9IG9wdHMuaG9zdC5zcGxpdCgnOicpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSBwaWVjZXMuc2hpZnQoKTtcbiAgICBpZiAocGllY2VzLmxlbmd0aCkgb3B0cy5wb3J0ID0gcGllY2VzLnBvcCgpO1xuICB9XG5cbiAgdGhpcy5hZ2VudCA9IG9wdHMuYWdlbnQgfHwgZmFsc2U7XG4gIHRoaXMuaG9zdG5hbWUgPSBvcHRzLmhvc3RuYW1lIHx8XG4gICAgKGdsb2JhbC5sb2NhdGlvbiA/IGxvY2F0aW9uLmhvc3RuYW1lIDogJ2xvY2FsaG9zdCcpO1xuICB0aGlzLnBvcnQgPSBvcHRzLnBvcnQgfHwgKGdsb2JhbC5sb2NhdGlvbiAmJiBsb2NhdGlvbi5wb3J0ID9cbiAgICAgICBsb2NhdGlvbi5wb3J0IDpcbiAgICAgICAodGhpcy5zZWN1cmUgPyA0NDMgOiA4MCkpO1xuICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeSB8fCB7fTtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5jYWxsYmFja0J1ZmZlciA9IFtdO1xuICB0aGlzLnBvbGljeVBvcnQgPSBvcHRzLnBvbGljeVBvcnQgfHwgODQzO1xuICB0aGlzLnJlbWVtYmVyVXBncmFkZSA9IG9wdHMucmVtZW1iZXJVcGdyYWRlIHx8IGZhbHNlO1xuICB0aGlzLm9wZW4oKTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT0gLTEpIHtcbiAgICB0cmFuc3BvcnQgPSAnd2Vic29ja2V0JztcbiAgfSBlbHNlIGlmICgwID09IHRoaXMudHJhbnNwb3J0cy5sZW5ndGgpIHtcbiAgICAvLyBFbWl0IGVycm9yIG9uIG5leHQgdGljayBzbyBpdCBjYW4gYmUgbGlzdGVuZWQgdG9cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHZhciB0cmFuc3BvcnQ7XG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odHJhbnNwb3J0KXtcbiAgZGVidWcoJ3NldHRpbmcgdHJhbnNwb3J0ICVzJywgdHJhbnNwb3J0Lm5hbWUpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMudHJhbnNwb3J0KSB7XG4gICAgZGVidWcoJ2NsZWFyaW5nIGV4aXN0aW5nIHRyYW5zcG9ydCAlcycsIHRoaXMudHJhbnNwb3J0Lm5hbWUpO1xuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygpO1xuICB9XG5cbiAgLy8gc2V0IHVwIHRyYW5zcG9ydFxuICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0IGxpc3RlbmVyc1xuICB0cmFuc3BvcnRcbiAgLm9uKCdkcmFpbicsIGZ1bmN0aW9uKCl7XG4gICAgc2VsZi5vbkRyYWluKCk7XG4gIH0pXG4gIC5vbigncGFja2V0JywgZnVuY3Rpb24ocGFja2V0KXtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbihlKXtcbiAgICBzZWxmLm9uRXJyb3IoZSk7XG4gIH0pXG4gIC5vbignY2xvc2UnLCBmdW5jdGlvbigpe1xuICAgIHNlbGYub25DbG9zZSgndHJhbnNwb3J0IGNsb3NlJyk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBQcm9iZXMgYSB0cmFuc3BvcnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgZGVidWcoJ3Byb2JpbmcgdHJhbnNwb3J0IFwiJXNcIicsIG5hbWUpO1xuICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQobmFtZSwgeyBwcm9iZTogMSB9KVxuICAgICwgZmFpbGVkID0gZmFsc2VcbiAgICAsIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4oKXtcbiAgICBpZiAoc2VsZi5vbmx5QmluYXJ5VXBncmFkZXMpIHtcbiAgICAgIHZhciB1cGdyYWRlTG9zZXNCaW5hcnkgPSAhdGhpcy5zdXBwb3J0c0JpbmFyeSAmJiBzZWxmLnRyYW5zcG9ydC5zdXBwb3J0c0JpbmFyeTtcbiAgICAgIGZhaWxlZCA9IGZhaWxlZCB8fCB1cGdyYWRlTG9zZXNCaW5hcnk7XG4gICAgfVxuICAgIGlmIChmYWlsZWQpIHJldHVybjtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIG9wZW5lZCcsIG5hbWUpO1xuICAgIHRyYW5zcG9ydC5zZW5kKFt7IHR5cGU6ICdwaW5nJywgZGF0YTogJ3Byb2JlJyB9XSk7XG4gICAgdHJhbnNwb3J0Lm9uY2UoJ3BhY2tldCcsIGZ1bmN0aW9uIChtc2cpIHtcbiAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgIGlmICgncG9uZycgPT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PSBtc2cuZGF0YSkge1xuICAgICAgICBkZWJ1ZygncHJvYmUgdHJhbnNwb3J0IFwiJXNcIiBwb25nJywgbmFtZSk7XG4gICAgICAgIHNlbGYudXBncmFkaW5nID0gdHJ1ZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRpbmcnLCB0cmFuc3BvcnQpO1xuICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gJ3dlYnNvY2tldCcgPT0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICAgICAgZGVidWcoJ3BhdXNpbmcgY3VycmVudCB0cmFuc3BvcnQgXCIlc1wiJywgc2VsZi50cmFuc3BvcnQubmFtZSk7XG4gICAgICAgIHNlbGYudHJhbnNwb3J0LnBhdXNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAoZmFpbGVkKSByZXR1cm47XG4gICAgICAgICAgaWYgKCdjbG9zZWQnID09IHNlbGYucmVhZHlTdGF0ZSB8fCAnY2xvc2luZycgPT0gc2VsZi5yZWFkeVN0YXRlKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0KCkge1xuICAgIGlmIChmYWlsZWQpIHJldHVybjtcblxuICAgIC8vIEFueSBjYWxsYmFjayBjYWxsZWQgYnkgdHJhbnNwb3J0IHNob3VsZCBiZSBpZ25vcmVkIHNpbmNlIG5vd1xuICAgIGZhaWxlZCA9IHRydWU7XG5cbiAgICBjbGVhbnVwKCk7XG5cbiAgICB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICB0cmFuc3BvcnQgPSBudWxsO1xuICB9XG5cbiAgLy9IYW5kbGUgYW55IGVycm9yIHRoYXQgaGFwcGVucyB3aGlsZSBwcm9iaW5nXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UoKXtcbiAgICBvbmVycm9yKFwidHJhbnNwb3J0IGNsb3NlZFwiKTtcbiAgfVxuXG4gIC8vV2hlbiB0aGUgc29ja2V0IGlzIGNsb3NlZCB3aGlsZSB3ZSdyZSBwcm9iaW5nXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKXtcbiAgICBvbmVycm9yKFwic29ja2V0IGNsb3NlZFwiKTtcbiAgfVxuXG4gIC8vV2hlbiB0aGUgc29ja2V0IGlzIHVwZ3JhZGVkIHdoaWxlIHdlJ3JlIHByb2JpbmdcbiAgZnVuY3Rpb24gb251cGdyYWRlKHRvKXtcbiAgICBpZiAodHJhbnNwb3J0ICYmIHRvLm5hbWUgIT0gdHJhbnNwb3J0Lm5hbWUpIHtcbiAgICAgIGRlYnVnKCdcIiVzXCIgd29ya3MgLSBhYm9ydGluZyBcIiVzXCInLCB0by5uYW1lLCB0cmFuc3BvcnQubmFtZSk7XG4gICAgICBmcmVlemVUcmFuc3BvcnQoKTtcbiAgICB9XG4gIH1cblxuICAvL1JlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCgpe1xuICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignb3BlbicsIG9uVHJhbnNwb3J0T3Blbik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ3VwZ3JhZGluZycsIG9udXBncmFkZSk7XG4gIH1cblxuICB0cmFuc3BvcnQub25jZSgnb3BlbicsIG9uVHJhbnNwb3J0T3Blbik7XG4gIHRyYW5zcG9ydC5vbmNlKCdlcnJvcicsIG9uZXJyb3IpO1xuICB0cmFuc3BvcnQub25jZSgnY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcblxuICB0aGlzLm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIHRoaXMub25jZSgndXBncmFkaW5nJywgb251cGdyYWRlKTtcblxuICB0cmFuc3BvcnQub3BlbigpO1xuXG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09IHRoaXMudHJhbnNwb3J0Lm5hbWU7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuICB0aGlzLmZsdXNoKCk7XG5cbiAgLy8gd2UgY2hlY2sgZm9yIGByZWFkeVN0YXRlYCBpbiBjYXNlIGFuIGBvcGVuYFxuICAvLyBsaXN0ZW5lciBhbHJlYWR5IGNsb3NlZCB0aGUgc29ja2V0XG4gIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudXBncmFkZSAmJiB0aGlzLnRyYW5zcG9ydC5wYXVzZSkge1xuICAgIGRlYnVnKCdzdGFydGluZyB1cGdyYWRlIHByb2JlcycpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy51cGdyYWRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMucHJvYmUodGhpcy51cGdyYWRlc1tpXSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEhhbmRsZXMgYSBwYWNrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vblBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIGRlYnVnKCdzb2NrZXQgcmVjZWl2ZTogdHlwZSBcIiVzXCIsIGRhdGEgXCIlc1wiJywgcGFja2V0LnR5cGUsIHBhY2tldC5kYXRhKTtcblxuICAgIHRoaXMuZW1pdCgncGFja2V0JywgcGFja2V0KTtcblxuICAgIC8vIFNvY2tldCBpcyBsaXZlIC0gYW55IHBhY2tldCBjb3VudHNcbiAgICB0aGlzLmVtaXQoJ2hlYXJ0YmVhdCcpO1xuXG4gICAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgICAgY2FzZSAnb3Blbic6XG4gICAgICAgIHRoaXMub25IYW5kc2hha2UocGFyc2Vqc29uKHBhY2tldC5kYXRhKSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdwb25nJzpcbiAgICAgICAgdGhpcy5zZXRQaW5nKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICAoJ2Nsb3NlZCcgPT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PSBzZWxmLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICBzZWxmLm9uQ2xvc2UoJ3BpbmcgdGltZW91dCcpO1xuICB9LCB0aW1lb3V0IHx8IChzZWxmLnBpbmdJbnRlcnZhbCArIHNlbGYucGluZ1RpbWVvdXQpKTtcbn07XG5cbi8qKlxuICogUGluZ3Mgc2VydmVyIGV2ZXJ5IGB0aGlzLnBpbmdJbnRlcnZhbGAgYW5kIGV4cGVjdHMgcmVzcG9uc2VcbiAqIHdpdGhpbiBgdGhpcy5waW5nVGltZW91dGAgb3IgY2xvc2VzIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5zZXRQaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNsZWFyVGltZW91dChzZWxmLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgc2VsZi5waW5nSW50ZXJ2YWxUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIHBpbmcgcGFja2V0IC0gZXhwZWN0aW5nIHBvbmcgd2l0aGluICVzbXMnLCBzZWxmLnBpbmdUaW1lb3V0KTtcbiAgICBzZWxmLnBpbmcoKTtcbiAgICBzZWxmLm9uSGVhcnRiZWF0KHNlbGYucGluZ1RpbWVvdXQpO1xuICB9LCBzZWxmLnBpbmdJbnRlcnZhbCk7XG59O1xuXG4vKipcbiogU2VuZHMgYSBwaW5nIHBhY2tldC5cbipcbiogQGFwaSBwdWJsaWNcbiovXG5cblNvY2tldC5wcm90b3R5cGUucGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24oKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wcmV2QnVmZmVyTGVuOyBpKyspIHtcbiAgICBpZiAodGhpcy5jYWxsYmFja0J1ZmZlcltpXSkge1xuICAgICAgdGhpcy5jYWxsYmFja0J1ZmZlcltpXSgpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMud3JpdGVCdWZmZXIuc3BsaWNlKDAsIHRoaXMucHJldkJ1ZmZlckxlbik7XG4gIHRoaXMuY2FsbGJhY2tCdWZmZXIuc3BsaWNlKDAsIHRoaXMucHJldkJ1ZmZlckxlbik7XG5cbiAgLy8gc2V0dGluZyBwcmV2QnVmZmVyTGVuID0gMCBpcyB2ZXJ5IGltcG9ydGFudFxuICAvLyBmb3IgZXhhbXBsZSwgd2hlbiB1cGdyYWRpbmcsIHVwZ3JhZGUgcGFja2V0IGlzIHNlbnQgb3ZlcixcbiAgLy8gYW5kIGEgbm9uemVybyBwcmV2QnVmZmVyTGVuIGNvdWxkIGNhdXNlIHByb2JsZW1zIG9uIGBkcmFpbmBcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcblxuICBpZiAodGhpcy53cml0ZUJ1ZmZlci5sZW5ndGggPT0gMCkge1xuICAgIHRoaXMuZW1pdCgnZHJhaW4nKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZsdXNoKCk7XG4gIH1cbn07XG5cbi8qKlxuICogRmx1c2ggd3JpdGUgYnVmZmVycy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAoJ2Nsb3NlZCcgIT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge1NvY2tldH0gZm9yIGNoYWluaW5nLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLndyaXRlID1cblNvY2tldC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChtc2csIGZuKSB7XG4gIHRoaXMuc2VuZFBhY2tldCgnbWVzc2FnZScsIG1zZywgZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgYSBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhY2tldCB0eXBlLlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2VuZFBhY2tldCA9IGZ1bmN0aW9uICh0eXBlLCBkYXRhLCBmbikge1xuICB2YXIgcGFja2V0ID0geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG4gIHRoaXMuZW1pdCgncGFja2V0Q3JlYXRlJywgcGFja2V0KTtcbiAgdGhpcy53cml0ZUJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIHRoaXMuY2FsbGJhY2tCdWZmZXIucHVzaChmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICB0aGlzLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgIGRlYnVnKCdzb2NrZXQgY2xvc2luZyAtIHRlbGxpbmcgdHJhbnNwb3J0IHRvIGNsb3NlJyk7XG4gICAgdGhpcy50cmFuc3BvcnQuY2xvc2UoKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgZXJyb3JcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbiAoZXJyKSB7XG4gIGRlYnVnKCdzb2NrZXQgZXJyb3IgJWonLCBlcnIpO1xuICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gZmFsc2U7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICB0aGlzLm9uQ2xvc2UoJ3RyYW5zcG9ydCBlcnJvcicsIGVycik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHRyYW5zcG9ydCBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAocmVhc29uLCBkZXNjKSB7XG4gIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgaW4gbmV4dCB0aWNrLCBzbyBkZXZlbG9wZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLndyaXRlQnVmZmVyID0gW107XG4gICAgICBzZWxmLmNhbGxiYWNrQnVmZmVyID0gW107XG4gICAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICAgIH0sIDApO1xuXG4gICAgLy8gc3RvcCBldmVudCBmcm9tIGZpcmluZyBhZ2FpbiBmb3IgdHJhbnNwb3J0XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCdjbG9zZScpO1xuXG4gICAgLy8gZW5zdXJlIHRyYW5zcG9ydCB3b24ndCBzdGF5IG9wZW5cbiAgICB0aGlzLnRyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgLy8gaWdub3JlIGZ1cnRoZXIgdHJhbnNwb3J0IGNvbW11bmljYXRpb25cbiAgICB0aGlzLnRyYW5zcG9ydC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIC8vIHNldCByZWFkeSBzdGF0ZVxuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuXG4gICAgLy8gY2xlYXIgc2Vzc2lvbiBpZFxuICAgIHRoaXMuaWQgPSBudWxsO1xuXG4gICAgLy8gZW1pdCBjbG9zZSBldmVudFxuICAgIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24sIGRlc2MpO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGk8ajsgaSsrKSB7XG4gICAgaWYgKH5pbmRleCh0aGlzLnRyYW5zcG9ydHMsIHVwZ3JhZGVzW2ldKSkgZmlsdGVyZWRVcGdyYWRlcy5wdXNoKHVwZ3JhZGVzW2ldKTtcbiAgfVxuICByZXR1cm4gZmlsdGVyZWRVcGdyYWRlcztcbn07XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zcG9ydDtcblxuLyoqXG4gKiBUcmFuc3BvcnQgYWJzdHJhY3QgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBUcmFuc3BvcnQgKG9wdHMpIHtcbiAgdGhpcy5wYXRoID0gb3B0cy5wYXRoO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0O1xuICB0aGlzLnNlY3VyZSA9IG9wdHMuc2VjdXJlO1xuICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW07XG4gIHRoaXMudGltZXN0YW1wUmVxdWVzdHMgPSBvcHRzLnRpbWVzdGFtcFJlcXVlc3RzO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnJztcbiAgdGhpcy5hZ2VudCA9IG9wdHMuYWdlbnQgfHwgZmFsc2U7XG4gIHRoaXMuc29ja2V0ID0gb3B0cy5zb2NrZXQ7XG4gIHRoaXMuZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoVHJhbnNwb3J0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogQSBjb3VudGVyIHVzZWQgdG8gcHJldmVudCBjb2xsaXNpb25zIGluIHRoZSB0aW1lc3RhbXBzIHVzZWRcbiAqIGZvciBjYWNoZSBidXN0aW5nLlxuICovXG5cblRyYW5zcG9ydC50aW1lc3RhbXBzID0gMDtcblxuLyoqXG4gKiBFbWl0cyBhbiBlcnJvci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbiAobXNnLCBkZXNjKSB7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnR5cGUgPSAnVHJhbnNwb3J0RXJyb3InO1xuICBlcnIuZGVzY3JpcHRpb24gPSBkZXNjO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE9wZW5zIHRoZSB0cmFuc3BvcnQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICAgIHRoaXMuZG9PcGVuKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSB0cmFuc3BvcnQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24ocGFja2V0cyl7XG4gIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBwYWNrZXQgPSBwYXJzZXIuZGVjb2RlUGFja2V0KGRhdGEsIHRoaXMuc29ja2V0LmJpbmFyeVR5cGUpO1xuICB0aGlzLm9uUGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGEgZGVjb2RlZCBwYWNrZXQuXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5vblBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneG1saHR0cHJlcXVlc3QnKTtcbnZhciBYSFIgPSByZXF1aXJlKCcuL3BvbGxpbmcteGhyJyk7XG52YXIgSlNPTlAgPSByZXF1aXJlKCcuL3BvbGxpbmctanNvbnAnKTtcbnZhciB3ZWJzb2NrZXQgPSByZXF1aXJlKCcuL3dlYnNvY2tldCcpO1xuXG4vKipcbiAqIEV4cG9ydCB0cmFuc3BvcnRzLlxuICovXG5cbmV4cG9ydHMucG9sbGluZyA9IHBvbGxpbmc7XG5leHBvcnRzLndlYnNvY2tldCA9IHdlYnNvY2tldDtcblxuLyoqXG4gKiBQb2xsaW5nIHRyYW5zcG9ydCBwb2x5bW9ycGhpYyBjb25zdHJ1Y3Rvci5cbiAqIERlY2lkZXMgb24geGhyIHZzIGpzb25wIGJhc2VkIG9uIGZlYXR1cmUgZGV0ZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBvbGxpbmcob3B0cyl7XG4gIHZhciB4aHI7XG4gIHZhciB4ZCA9IGZhbHNlO1xuICB2YXIgeHMgPSBmYWxzZTtcbiAgdmFyIGpzb25wID0gZmFsc2UgIT09IG9wdHMuanNvbnA7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sO1xuICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgIC8vIHNvbWUgdXNlciBhZ2VudHMgaGF2ZSBlbXB0eSBgbG9jYXRpb24ucG9ydGBcbiAgICBpZiAoIXBvcnQpIHtcbiAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgIH1cblxuICAgIHhkID0gb3B0cy5ob3N0bmFtZSAhPSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9IG9wdHMucG9ydDtcbiAgICB4cyA9IG9wdHMuc2VjdXJlICE9IGlzU1NMO1xuICB9XG5cbiAgb3B0cy54ZG9tYWluID0geGQ7XG4gIG9wdHMueHNjaGVtZSA9IHhzO1xuICB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3Qob3B0cyk7XG5cbiAgaWYgKCdvcGVuJyBpbiB4aHIgJiYgIW9wdHMuZm9yY2VKU09OUCkge1xuICAgIHJldHVybiBuZXcgWEhSKG9wdHMpO1xuICB9IGVsc2Uge1xuICAgIGlmICghanNvbnApIHRocm93IG5ldyBFcnJvcignSlNPTlAgZGlzYWJsZWQnKTtcbiAgICByZXR1cm4gbmV3IEpTT05QKG9wdHMpO1xuICB9XG59XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTtcbi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgUG9sbGluZyA9IHJlcXVpcmUoJy4vcG9sbGluZycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gSlNPTlBQb2xsaW5nO1xuXG4vKipcbiAqIENhY2hlZCByZWd1bGFyIGV4cHJlc3Npb25zLlxuICovXG5cbnZhciByTmV3bGluZSA9IC9cXG4vZztcbnZhciByRXNjYXBlZE5ld2xpbmUgPSAvXFxcXG4vZztcblxuLyoqXG4gKiBHbG9iYWwgSlNPTlAgY2FsbGJhY2tzLlxuICovXG5cbnZhciBjYWxsYmFja3M7XG5cbi8qKlxuICogQ2FsbGJhY2tzIGNvdW50LlxuICovXG5cbnZhciBpbmRleCA9IDA7XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBlbXB0eSAoKSB7IH1cblxuLyoqXG4gKiBKU09OUCBQb2xsaW5nIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBKU09OUFBvbGxpbmcgKG9wdHMpIHtcbiAgUG9sbGluZy5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIHRoaXMucXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuXG4gIC8vIGRlZmluZSBnbG9iYWwgY2FsbGJhY2tzIGFycmF5IGlmIG5vdCBwcmVzZW50XG4gIC8vIHdlIGRvIHRoaXMgaGVyZSAobGF6aWx5KSB0byBhdm9pZCB1bm5lZWRlZCBnbG9iYWwgcG9sbHV0aW9uXG4gIGlmICghY2FsbGJhY2tzKSB7XG4gICAgLy8gd2UgbmVlZCB0byBjb25zaWRlciBtdWx0aXBsZSBlbmdpbmVzIGluIHRoZSBzYW1lIHBhZ2VcbiAgICBpZiAoIWdsb2JhbC5fX19laW8pIGdsb2JhbC5fX19laW8gPSBbXTtcbiAgICBjYWxsYmFja3MgPSBnbG9iYWwuX19fZWlvO1xuICB9XG5cbiAgLy8gY2FsbGJhY2sgaWRlbnRpZmllclxuICB0aGlzLmluZGV4ID0gY2FsbGJhY2tzLmxlbmd0aDtcblxuICAvLyBhZGQgY2FsbGJhY2sgdG8ganNvbnAgZ2xvYmFsXG4gIHZhciBzZWxmID0gdGhpcztcbiAgY2FsbGJhY2tzLnB1c2goZnVuY3Rpb24gKG1zZykge1xuICAgIHNlbGYub25EYXRhKG1zZyk7XG4gIH0pO1xuXG4gIC8vIGFwcGVuZCB0byBxdWVyeSBzdHJpbmdcbiAgdGhpcy5xdWVyeS5qID0gdGhpcy5pbmRleDtcblxuICAvLyBwcmV2ZW50IHNwdXJpb3VzIGVycm9ycyBmcm9tIGJlaW5nIGVtaXR0ZWQgd2hlbiB0aGUgd2luZG93IGlzIHVubG9hZGVkXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQgJiYgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuc2NyaXB0KSBzZWxmLnNjcmlwdC5vbmVycm9yID0gZW1wdHk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFBvbGxpbmcuXG4gKi9cblxuaW5oZXJpdChKU09OUFBvbGxpbmcsIFBvbGxpbmcpO1xuXG4vKlxuICogSlNPTlAgb25seSBzdXBwb3J0cyBiaW5hcnkgYXMgYmFzZTY0IGVuY29kZWQgc3RyaW5nc1xuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcblxuLyoqXG4gKiBDbG9zZXMgdGhlIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5KU09OUFBvbGxpbmcucHJvdG90eXBlLmRvQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIGlmICh0aGlzLmZvcm0pIHtcbiAgICB0aGlzLmZvcm0ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmZvcm0pO1xuICAgIHRoaXMuZm9ybSA9IG51bGw7XG4gIH1cblxuICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gIGlmICh0aGlzLnNjcmlwdCkge1xuICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgfVxuXG4gIHNjcmlwdC5hc3luYyA9IHRydWU7XG4gIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICBzY3JpcHQub25lcnJvciA9IGZ1bmN0aW9uKGUpe1xuICAgIHNlbGYub25FcnJvcignanNvbnAgcG9sbCBlcnJvcicsZSk7XG4gIH07XG5cbiAgdmFyIGluc2VydEF0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpWzBdO1xuICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgdGhpcy5zY3JpcHQgPSBzY3JpcHQ7XG5cbiAgdmFyIGlzVUFnZWNrbyA9ICd1bmRlZmluZWQnICE9IHR5cGVvZiBuYXZpZ2F0b3IgJiYgL2dlY2tvL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgXG4gIGlmIChpc1VBZ2Vja28pIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICB9LCAxMDApO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyB3aXRoIGEgaGlkZGVuIGlmcmFtZS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uIChkYXRhLCBmbikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCF0aGlzLmZvcm0pIHtcbiAgICB2YXIgZm9ybSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zvcm0nKTtcbiAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgdmFyIGlkID0gdGhpcy5pZnJhbWVJZCA9ICdlaW9faWZyYW1lXycgKyB0aGlzLmluZGV4O1xuICAgIHZhciBpZnJhbWU7XG5cbiAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgZm9ybS5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZm9ybS5zdHlsZS50b3AgPSAnLTEwMDBweCc7XG4gICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgIGZvcm0udGFyZ2V0ID0gaWQ7XG4gICAgZm9ybS5tZXRob2QgPSAnUE9TVCc7XG4gICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgYXJlYS5uYW1lID0gJ2QnO1xuICAgIGZvcm0uYXBwZW5kQ2hpbGQoYXJlYSk7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgIHRoaXMuZm9ybSA9IGZvcm07XG4gICAgdGhpcy5hcmVhID0gYXJlYTtcbiAgfVxuXG4gIHRoaXMuZm9ybS5hY3Rpb24gPSB0aGlzLnVyaSgpO1xuXG4gIGZ1bmN0aW9uIGNvbXBsZXRlICgpIHtcbiAgICBpbml0SWZyYW1lKCk7XG4gICAgZm4oKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRJZnJhbWUgKCkge1xuICAgIGlmIChzZWxmLmlmcmFtZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi5mb3JtLnJlbW92ZUNoaWxkKHNlbGYuaWZyYW1lKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIGllNiBkeW5hbWljIGlmcmFtZXMgd2l0aCB0YXJnZXQ9XCJcIiBzdXBwb3J0ICh0aGFua3MgQ2hyaXMgTGFtYmFjaGVyKVxuICAgICAgdmFyIGh0bWwgPSAnPGlmcmFtZSBzcmM9XCJqYXZhc2NyaXB0OjBcIiBuYW1lPVwiJysgc2VsZi5pZnJhbWVJZCArJ1wiPic7XG4gICAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGh0bWwpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgICAgaWZyYW1lLm5hbWUgPSBzZWxmLmlmcmFtZUlkO1xuICAgICAgaWZyYW1lLnNyYyA9ICdqYXZhc2NyaXB0OjAnO1xuICAgIH1cblxuICAgIGlmcmFtZS5pZCA9IHNlbGYuaWZyYW1lSWQ7XG5cbiAgICBzZWxmLmZvcm0uYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICBzZWxmLmlmcmFtZSA9IGlmcmFtZTtcbiAgfVxuXG4gIGluaXRJZnJhbWUoKTtcblxuICAvLyBlc2NhcGUgXFxuIHRvIHByZXZlbnQgaXQgZnJvbSBiZWluZyBjb252ZXJ0ZWQgaW50byBcXHJcXG4gYnkgc29tZSBVQXNcbiAgLy8gZG91YmxlIGVzY2FwaW5nIGlzIHJlcXVpcmVkIGZvciBlc2NhcGVkIG5ldyBsaW5lcyBiZWNhdXNlIHVuZXNjYXBpbmcgb2YgbmV3IGxpbmVzIGNhbiBiZSBkb25lIHNhZmVseSBvbiBzZXJ2ZXItc2lkZVxuICBkYXRhID0gZGF0YS5yZXBsYWNlKHJFc2NhcGVkTmV3bGluZSwgJ1xcXFxcXG4nKTtcbiAgdGhpcy5hcmVhLnZhbHVlID0gZGF0YS5yZXBsYWNlKHJOZXdsaW5lLCAnXFxcXG4nKTtcblxuICB0cnkge1xuICAgIHRoaXMuZm9ybS5zdWJtaXQoKTtcbiAgfSBjYXRjaChlKSB7fVxuXG4gIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgIHRoaXMuaWZyYW1lLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCl7XG4gICAgICBpZiAoc2VsZi5pZnJhbWUucmVhZHlTdGF0ZSA9PSAnY29tcGxldGUnKSB7XG4gICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgfVxufTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdCcpO1xudmFyIFBvbGxpbmcgPSByZXF1aXJlKCcuL3BvbGxpbmcnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6cG9sbGluZy14aHInKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFhIUjtcbm1vZHVsZS5leHBvcnRzLlJlcXVlc3QgPSBSZXF1ZXN0O1xuXG4vKipcbiAqIEVtcHR5IGZ1bmN0aW9uXG4gKi9cblxuZnVuY3Rpb24gZW1wdHkoKXt9XG5cbi8qKlxuICogWEhSIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gWEhSKG9wdHMpe1xuICBQb2xsaW5nLmNhbGwodGhpcywgb3B0cyk7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sO1xuICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgIC8vIHNvbWUgdXNlciBhZ2VudHMgaGF2ZSBlbXB0eSBgbG9jYXRpb24ucG9ydGBcbiAgICBpZiAoIXBvcnQpIHtcbiAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgIH1cblxuICAgIHRoaXMueGQgPSBvcHRzLmhvc3RuYW1lICE9IGdsb2JhbC5sb2NhdGlvbi5ob3N0bmFtZSB8fFxuICAgICAgcG9ydCAhPSBvcHRzLnBvcnQ7XG4gICAgdGhpcy54cyA9IG9wdHMuc2VjdXJlICE9IGlzU1NMO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuLyoqXG4gKiBYSFIgc3VwcG9ydHMgYmluYXJ5XG4gKi9cblxuWEhSLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1ldGhvZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24ob3B0cyl7XG4gIG9wdHMgPSBvcHRzIHx8IHt9O1xuICBvcHRzLnVyaSA9IHRoaXMudXJpKCk7XG4gIG9wdHMueGQgPSB0aGlzLnhkO1xuICBvcHRzLnhzID0gdGhpcy54cztcbiAgb3B0cy5hZ2VudCA9IHRoaXMuYWdlbnQgfHwgZmFsc2U7XG4gIG9wdHMuc3VwcG9ydHNCaW5hcnkgPSB0aGlzLnN1cHBvcnRzQmluYXJ5O1xuICBvcHRzLmVuYWJsZXNYRFIgPSB0aGlzLmVuYWJsZXNYRFI7XG4gIHJldHVybiBuZXcgUmVxdWVzdChvcHRzKTtcbn07XG5cbi8qKlxuICogU2VuZHMgZGF0YS5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSB0byBzZW5kLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGVkIHVwb24gZmx1c2guXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5YSFIucHJvdG90eXBlLmRvV3JpdGUgPSBmdW5jdGlvbihkYXRhLCBmbil7XG4gIHZhciBpc0JpbmFyeSA9IHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJyAmJiBkYXRhICE9PSB1bmRlZmluZWQ7XG4gIHZhciByZXEgPSB0aGlzLnJlcXVlc3QoeyBtZXRob2Q6ICdQT1NUJywgZGF0YTogZGF0YSwgaXNCaW5hcnk6IGlzQmluYXJ5IH0pO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJlcS5vbignc3VjY2VzcycsIGZuKTtcbiAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uKGVycil7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9zdCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnNlbmRYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuWEhSLnByb3RvdHlwZS5kb1BvbGwgPSBmdW5jdGlvbigpe1xuICBkZWJ1ZygneGhyIHBvbGwnKTtcbiAgdmFyIHJlcSA9IHRoaXMucmVxdWVzdCgpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJlcS5vbignZGF0YScsIGZ1bmN0aW9uKGRhdGEpe1xuICAgIHNlbGYub25EYXRhKGRhdGEpO1xuICB9KTtcbiAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uKGVycil7XG4gICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gIH0pO1xuICB0aGlzLnBvbGxYaHIgPSByZXE7XG59O1xuXG4vKipcbiAqIFJlcXVlc3QgY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBSZXF1ZXN0KG9wdHMpe1xuICB0aGlzLm1ldGhvZCA9IG9wdHMubWV0aG9kIHx8ICdHRVQnO1xuICB0aGlzLnVyaSA9IG9wdHMudXJpO1xuICB0aGlzLnhkID0gISFvcHRzLnhkO1xuICB0aGlzLnhzID0gISFvcHRzLnhzO1xuICB0aGlzLmFzeW5jID0gZmFsc2UgIT09IG9wdHMuYXN5bmM7XG4gIHRoaXMuZGF0YSA9IHVuZGVmaW5lZCAhPSBvcHRzLmRhdGEgPyBvcHRzLmRhdGEgOiBudWxsO1xuICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgdGhpcy5pc0JpbmFyeSA9IG9wdHMuaXNCaW5hcnk7XG4gIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBvcHRzLnN1cHBvcnRzQmluYXJ5O1xuICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG4gIHRoaXMuY3JlYXRlKCk7XG59XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBYSFIgb2JqZWN0IGFuZCBzZW5kcyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbigpe1xuICB2YXIgeGhyID0gdGhpcy54aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoeyBhZ2VudDogdGhpcy5hZ2VudCwgeGRvbWFpbjogdGhpcy54ZCwgeHNjaGVtZTogdGhpcy54cywgZW5hYmxlc1hEUjogdGhpcy5lbmFibGVzWERSIH0pO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdHJ5IHtcbiAgICBkZWJ1ZygneGhyIG9wZW4gJXM6ICVzJywgdGhpcy5tZXRob2QsIHRoaXMudXJpKTtcbiAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmksIHRoaXMuYXN5bmMpO1xuICAgIGlmICh0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAvLyBUaGlzIGhhcyB0byBiZSBkb25lIGFmdGVyIG9wZW4gYmVjYXVzZSBGaXJlZm94IGlzIHN0dXBpZFxuICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICB9XG5cbiAgICBpZiAoJ1BPU1QnID09IHRoaXMubWV0aG9kKSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAodGhpcy5pc0JpbmFyeSkge1xuICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICd0ZXh0L3BsYWluO2NoYXJzZXQ9VVRGLTgnKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge31cbiAgICB9XG5cbiAgICAvLyBpZTYgY2hlY2tcbiAgICBpZiAoJ3dpdGhDcmVkZW50aWFscycgaW4geGhyKSB7XG4gICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNYRFIoKSkge1xuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICB9O1xuICAgICAgeGhyLm9uZXJyb3IgPSBmdW5jdGlvbigpe1xuICAgICAgICBzZWxmLm9uRXJyb3IoeGhyLnJlc3BvbnNlVGV4dCk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKXtcbiAgICAgICAgaWYgKDQgIT0geGhyLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICAgICAgaWYgKDIwMCA9PSB4aHIuc3RhdHVzIHx8IDEyMjMgPT0geGhyLnN0YXR1cykge1xuICAgICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBgZXJyb3JgIGV2ZW50IGhhbmRsZXIgdGhhdCdzIHVzZXItc2V0XG4gICAgICAgICAgLy8gZG9lcyBub3QgdGhyb3cgaW4gdGhlIHNhbWUgdGljayBhbmQgZ2V0cyBjYXVnaHQgaGVyZVxuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHNlbGYub25FcnJvcih4aHIuc3RhdHVzKTtcbiAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9XG5cbiAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgIHhoci5zZW5kKHRoaXMuZGF0YSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gYW5kIHRodXMgdGhlICdlcnJvcicgZXZlbnQgY2FuIG9ubHkgYmUgb25seSBib3VuZCAqYWZ0ZXIqIHRoaXMgZXhjZXB0aW9uXG4gICAgLy8gb2NjdXJzLiAgVGhlcmVmb3JlLCBhbHNvLCB3ZSBjYW5ub3QgdGhyb3cgaGVyZSBhdCBhbGwuXG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYub25FcnJvcihlKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gICAgdGhpcy5pbmRleCA9IFJlcXVlc3QucmVxdWVzdHNDb3VudCsrO1xuICAgIFJlcXVlc3QucmVxdWVzdHNbdGhpcy5pbmRleF0gPSB0aGlzO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVzcG9uc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUub25TdWNjZXNzID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5lbWl0KCdzdWNjZXNzJyk7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgaWYgd2UgaGF2ZSBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uKGRhdGEpe1xuICB0aGlzLmVtaXQoJ2RhdGEnLCBkYXRhKTtcbiAgdGhpcy5vblN1Y2Nlc3MoKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uKGVycil7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQ2xlYW5zIHVwIGhvdXNlLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNsZWFudXAgPSBmdW5jdGlvbigpe1xuICBpZiAoJ3VuZGVmaW5lZCcgPT0gdHlwZW9mIHRoaXMueGhyIHx8IG51bGwgPT09IHRoaXMueGhyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIHhtbGh0dHByZXF1ZXN0XG4gIGlmICh0aGlzLmhhc1hEUigpKSB7XG4gICAgdGhpcy54aHIub25sb2FkID0gdGhpcy54aHIub25lcnJvciA9IGVtcHR5O1xuICB9IGVsc2Uge1xuICAgIHRoaXMueGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGVtcHR5O1xuICB9XG5cbiAgdHJ5IHtcbiAgICB0aGlzLnhoci5hYm9ydCgpO1xuICB9IGNhdGNoKGUpIHt9XG5cbiAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgIGRlbGV0ZSBSZXF1ZXN0LnJlcXVlc3RzW3RoaXMuaW5kZXhdO1xuICB9XG5cbiAgdGhpcy54aHIgPSBudWxsO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBsb2FkLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLm9uTG9hZCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBkYXRhO1xuICB0cnkge1xuICAgIHZhciBjb250ZW50VHlwZTtcbiAgICB0cnkge1xuICAgICAgY29udGVudFR5cGUgPSB0aGlzLnhoci5nZXRSZXNwb25zZUhlYWRlcignQ29udGVudC1UeXBlJyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgICBpZiAoY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nKSB7XG4gICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICBkYXRhID0gdGhpcy54aHIucmVzcG9uc2VUZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGF0YSA9ICdvayc7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgdGhpcy5vbkVycm9yKGUpO1xuICB9XG4gIGlmIChudWxsICE9IGRhdGEpIHtcbiAgICB0aGlzLm9uRGF0YShkYXRhKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDaGVjayBpZiBpdCBoYXMgWERvbWFpblJlcXVlc3QuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuaGFzWERSID0gZnVuY3Rpb24oKXtcbiAgcmV0dXJuICd1bmRlZmluZWQnICE9PSB0eXBlb2YgZ2xvYmFsLlhEb21haW5SZXF1ZXN0ICYmICF0aGlzLnhzICYmIHRoaXMuZW5hYmxlc1hEUjtcbn07XG5cbi8qKlxuICogQWJvcnRzIHRoZSByZXF1ZXN0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbigpe1xuICB0aGlzLmNsZWFudXAoKTtcbn07XG5cbi8qKlxuICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICogbWVtb3J5IGxlYWtzIChlLmcuIHdoZW4gdXNpbmcgSUUpIGFuZCB0byBlbnN1cmUgdGhhdCBubyBzcHVyaW91cyBlcnJvciBpc1xuICogZW1pdHRlZC5cbiAqL1xuXG5pZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gIFJlcXVlc3QucmVxdWVzdHNDb3VudCA9IDA7XG4gIFJlcXVlc3QucmVxdWVzdHMgPSB7fTtcbiAgaWYgKGdsb2JhbC5hdHRhY2hFdmVudCkge1xuICAgIGdsb2JhbC5hdHRhY2hFdmVudCgnb251bmxvYWQnLCB1bmxvYWRIYW5kbGVyKTtcbiAgfSBlbHNlIGlmIChnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCB1bmxvYWRIYW5kbGVyKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bmxvYWRIYW5kbGVyKCkge1xuICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICBpZiAoUmVxdWVzdC5yZXF1ZXN0cy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgUmVxdWVzdC5yZXF1ZXN0c1tpXS5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXFzID0gcmVxdWlyZSgncGFyc2VxcycpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6cG9sbGluZycpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gUG9sbGluZztcblxuLyoqXG4gKiBJcyBYSFIyIHN1cHBvcnRlZD9cbiAqL1xuXG52YXIgaGFzWEhSMiA9IChmdW5jdGlvbigpIHtcbiAgdmFyIFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneG1saHR0cHJlcXVlc3QnKTtcbiAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IGFnZW50OiB0aGlzLmFnZW50LCB4ZG9tYWluOiBmYWxzZSB9KTtcbiAgcmV0dXJuIG51bGwgIT0geGhyLnJlc3BvbnNlVHlwZTtcbn0pKCk7XG5cbi8qKlxuICogUG9sbGluZyBpbnRlcmZhY2UuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIFBvbGxpbmcob3B0cyl7XG4gIHZhciBmb3JjZUJhc2U2NCA9IChvcHRzICYmIG9wdHMuZm9yY2VCYXNlNjQpO1xuICBpZiAoIWhhc1hIUjIgfHwgZm9yY2VCYXNlNjQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cbiAgVHJhbnNwb3J0LmNhbGwodGhpcywgb3B0cyk7XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBUcmFuc3BvcnQuXG4gKi9cblxuaW5oZXJpdChQb2xsaW5nLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLm5hbWUgPSAncG9sbGluZyc7XG5cbi8qKlxuICogT3BlbnMgdGhlIHNvY2tldCAodHJpZ2dlcnMgcG9sbGluZykuIFdlIHdyaXRlIGEgUElORyBtZXNzYWdlIHRvIGRldGVybWluZVxuICogd2hlbiB0aGUgdHJhbnNwb3J0IGlzIG9wZW4uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5wb2xsKCk7XG59O1xuXG4vKipcbiAqIFBhdXNlcyBwb2xsaW5nLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbihvblBhdXNlKXtcbiAgdmFyIHBlbmRpbmcgPSAwO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5yZWFkeVN0YXRlID0gJ3BhdXNpbmcnO1xuXG4gIGZ1bmN0aW9uIHBhdXNlKCl7XG4gICAgZGVidWcoJ3BhdXNlZCcpO1xuICAgIHNlbGYucmVhZHlTdGF0ZSA9ICdwYXVzZWQnO1xuICAgIG9uUGF1c2UoKTtcbiAgfVxuXG4gIGlmICh0aGlzLnBvbGxpbmcgfHwgIXRoaXMud3JpdGFibGUpIHtcbiAgICB2YXIgdG90YWwgPSAwO1xuXG4gICAgaWYgKHRoaXMucG9sbGluZykge1xuICAgICAgZGVidWcoJ3dlIGFyZSBjdXJyZW50bHkgcG9sbGluZyAtIHdhaXRpbmcgdG8gcGF1c2UnKTtcbiAgICAgIHRvdGFsKys7XG4gICAgICB0aGlzLm9uY2UoJ3BvbGxDb21wbGV0ZScsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2UgcG9sbGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMud3JpdGFibGUpIHtcbiAgICAgIGRlYnVnKCd3ZSBhcmUgY3VycmVudGx5IHdyaXRpbmcgLSB3YWl0aW5nIHRvIHBhdXNlJyk7XG4gICAgICB0b3RhbCsrO1xuICAgICAgdGhpcy5vbmNlKCdkcmFpbicsIGZ1bmN0aW9uKCl7XG4gICAgICAgIGRlYnVnKCdwcmUtcGF1c2Ugd3JpdGluZyBjb21wbGV0ZScpO1xuICAgICAgICAtLXRvdGFsIHx8IHBhdXNlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcGF1c2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTdGFydHMgcG9sbGluZyBjeWNsZS5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBvbGwgPSBmdW5jdGlvbigpe1xuICBkZWJ1ZygncG9sbGluZycpO1xuICB0aGlzLnBvbGxpbmcgPSB0cnVlO1xuICB0aGlzLmRvUG9sbCgpO1xuICB0aGlzLmVtaXQoJ3BvbGwnKTtcbn07XG5cbi8qKlxuICogT3ZlcmxvYWRzIG9uRGF0YSB0byBkZXRlY3QgcGF5bG9hZHMuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgZGVidWcoJ3BvbGxpbmcgZ290IGRhdGEgJXMnLCBkYXRhKTtcbiAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24ocGFja2V0LCBpbmRleCwgdG90YWwpIHtcbiAgICAvLyBpZiBpdHMgdGhlIGZpcnN0IG1lc3NhZ2Ugd2UgY29uc2lkZXIgdGhlIHRyYW5zcG9ydCBvcGVuXG4gICAgaWYgKCdvcGVuaW5nJyA9PSBzZWxmLnJlYWR5U3RhdGUpIHtcbiAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgfVxuXG4gICAgLy8gaWYgaXRzIGEgY2xvc2UgcGFja2V0LCB3ZSBjbG9zZSB0aGUgb25nb2luZyByZXF1ZXN0c1xuICAgIGlmICgnY2xvc2UnID09IHBhY2tldC50eXBlKSB7XG4gICAgICBzZWxmLm9uQ2xvc2UoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBvdGhlcndpc2UgYnlwYXNzIG9uRGF0YSBhbmQgaGFuZGxlIHRoZSBtZXNzYWdlXG4gICAgc2VsZi5vblBhY2tldChwYWNrZXQpO1xuICB9O1xuXG4gIC8vIGRlY29kZSBwYXlsb2FkXG4gIHBhcnNlci5kZWNvZGVQYXlsb2FkKGRhdGEsIHRoaXMuc29ja2V0LmJpbmFyeVR5cGUsIGNhbGxiYWNrKTtcblxuICAvLyBpZiBhbiBldmVudCBkaWQgbm90IHRyaWdnZXIgY2xvc2luZ1xuICBpZiAoJ2Nsb3NlZCcgIT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgLy8gaWYgd2UgZ290IGRhdGEgd2UncmUgbm90IHBvbGxpbmdcbiAgICB0aGlzLnBvbGxpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmVtaXQoJ3BvbGxDb21wbGV0ZScpO1xuXG4gICAgaWYgKCdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgIHRoaXMucG9sbCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWJ1ZygnaWdub3JpbmcgcG9sbCAtIHRyYW5zcG9ydCBzdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBGb3IgcG9sbGluZywgc2VuZCBhIGNsb3NlIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24oKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZ1bmN0aW9uIGNsb3NlKCl7XG4gICAgZGVidWcoJ3dyaXRpbmcgY2xvc2UgcGFja2V0Jyk7XG4gICAgc2VsZi53cml0ZShbeyB0eXBlOiAnY2xvc2UnIH1dKTtcbiAgfVxuXG4gIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgZGVidWcoJ3RyYW5zcG9ydCBvcGVuIC0gY2xvc2luZycpO1xuICAgIGNsb3NlKCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gaW4gY2FzZSB3ZSdyZSB0cnlpbmcgdG8gY2xvc2Ugd2hpbGVcbiAgICAvLyBoYW5kc2hha2luZyBpcyBpbiBwcm9ncmVzcyAoR0gtMTY0KVxuICAgIGRlYnVnKCd0cmFuc3BvcnQgbm90IG9wZW4gLSBkZWZlcnJpbmcgY2xvc2UnKTtcbiAgICB0aGlzLm9uY2UoJ29wZW4nLCBjbG9zZSk7XG4gIH1cbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0cyBwYXlsb2FkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgcGFja2V0c1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZHJhaW4gY2FsbGJhY2tcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ocGFja2V0cyl7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdGhpcy53cml0YWJsZSA9IGZhbHNlO1xuICB2YXIgY2FsbGJhY2tmbiA9IGZ1bmN0aW9uKCkge1xuICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgIHNlbGYuZW1pdCgnZHJhaW4nKTtcbiAgfTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHBhcnNlci5lbmNvZGVQYXlsb2FkKHBhY2tldHMsIHRoaXMuc3VwcG9ydHNCaW5hcnksIGZ1bmN0aW9uKGRhdGEpIHtcbiAgICBzZWxmLmRvV3JpdGUoZGF0YSwgY2FsbGJhY2tmbik7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgdXJpIGZvciBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICdodHRwcycgOiAnaHR0cCc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgaWYgKGZhbHNlICE9PSB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSArbmV3IERhdGUgKyAnLScgKyBUcmFuc3BvcnQudGltZXN0YW1wcysrO1xuICB9XG5cbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmICFxdWVyeS5zaWQpIHtcbiAgICBxdWVyeS5iNjQgPSAxO1xuICB9XG5cbiAgcXVlcnkgPSBwYXJzZXFzLmVuY29kZShxdWVyeSk7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCdodHRwcycgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA0NDMpIHx8XG4gICAgICgnaHR0cCcgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA4MCkpKSB7XG4gICAgcG9ydCA9ICc6JyArIHRoaXMucG9ydDtcbiAgfVxuXG4gIC8vIHByZXBlbmQgPyB0byBxdWVyeVxuICBpZiAocXVlcnkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSAnPycgKyBxdWVyeTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIHRoaXMuaG9zdG5hbWUgKyBwb3J0ICsgdGhpcy5wYXRoICsgcXVlcnk7XG59O1xuIiwiLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBUcmFuc3BvcnQgPSByZXF1aXJlKCcuLi90cmFuc3BvcnQnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgcGFyc2VxcyA9IHJlcXVpcmUoJ3BhcnNlcXMnKTtcbnZhciBpbmhlcml0ID0gcmVxdWlyZSgnY29tcG9uZW50LWluaGVyaXQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ2VuZ2luZS5pby1jbGllbnQ6d2Vic29ja2V0Jyk7XG5cbi8qKlxuICogYHdzYCBleHBvc2VzIGEgV2ViU29ja2V0LWNvbXBhdGlibGUgaW50ZXJmYWNlIGluXG4gKiBOb2RlLCBvciB0aGUgYFdlYlNvY2tldGAgb3IgYE1veldlYlNvY2tldGAgZ2xvYmFsc1xuICogaW4gdGhlIGJyb3dzZXIuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IHJlcXVpcmUoJ3dzJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBXUztcblxuLyoqXG4gKiBXZWJTb2NrZXQgdHJhbnNwb3J0IGNvbnN0cnVjdG9yLlxuICpcbiAqIEBhcGkge09iamVjdH0gY29ubmVjdGlvbiBvcHRpb25zXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFdTKG9wdHMpe1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoV1MsIFRyYW5zcG9ydCk7XG5cbi8qKlxuICogVHJhbnNwb3J0IG5hbWUuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUubmFtZSA9ICd3ZWJzb2NrZXQnO1xuXG4vKlxuICogV2ViU29ja2V0cyBzdXBwb3J0IGJpbmFyeVxuICovXG5cbldTLnByb3RvdHlwZS5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG5cbi8qKlxuICogT3BlbnMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb09wZW4gPSBmdW5jdGlvbigpe1xuICBpZiAoIXRoaXMuY2hlY2soKSkge1xuICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgdXJpID0gdGhpcy51cmkoKTtcbiAgdmFyIHByb3RvY29scyA9IHZvaWQoMCk7XG4gIHZhciBvcHRzID0geyBhZ2VudDogdGhpcy5hZ2VudCB9O1xuXG4gIHRoaXMud3MgPSBuZXcgV2ViU29ja2V0KHVyaSwgcHJvdG9jb2xzLCBvcHRzKTtcblxuICBpZiAodGhpcy53cy5iaW5hcnlUeXBlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gIH1cblxuICB0aGlzLndzLmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICB0aGlzLmFkZEV2ZW50TGlzdGVuZXJzKCk7XG59O1xuXG4vKipcbiAqIEFkZHMgZXZlbnQgbGlzdGVuZXJzIHRvIHRoZSBzb2NrZXRcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lcnMgPSBmdW5jdGlvbigpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbigpe1xuICAgIHNlbGYub25PcGVuKCk7XG4gIH07XG4gIHRoaXMud3Mub25jbG9zZSA9IGZ1bmN0aW9uKCl7XG4gICAgc2VsZi5vbkNsb3NlKCk7XG4gIH07XG4gIHRoaXMud3Mub25tZXNzYWdlID0gZnVuY3Rpb24oZXYpe1xuICAgIHNlbGYub25EYXRhKGV2LmRhdGEpO1xuICB9O1xuICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbihlKXtcbiAgICBzZWxmLm9uRXJyb3IoJ3dlYnNvY2tldCBlcnJvcicsIGUpO1xuICB9O1xufTtcblxuLyoqXG4gKiBPdmVycmlkZSBgb25EYXRhYCB0byB1c2UgYSB0aW1lciBvbiBpT1MuXG4gKiBTZWU6IGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL21sb3VnaHJhbi8yMDUyMDA2XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuaWYgKCd1bmRlZmluZWQnICE9IHR5cGVvZiBuYXZpZ2F0b3JcbiAgJiYgL2lQYWR8aVBob25lfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gIFdTLnByb3RvdHlwZS5vbkRhdGEgPSBmdW5jdGlvbihkYXRhKXtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgVHJhbnNwb3J0LnByb3RvdHlwZS5vbkRhdGEuY2FsbChzZWxmLCBkYXRhKTtcbiAgICB9LCAwKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBXcml0ZXMgZGF0YSB0byBzb2NrZXQuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgb2YgcGFja2V0cy5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHBhY2tldHMpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgLy8gZW5jb2RlUGFja2V0IGVmZmljaWVudCBhcyBpdCB1c2VzIFdTIGZyYW1pbmdcbiAgLy8gbm8gbmVlZCBmb3IgZW5jb2RlUGF5bG9hZFxuICBmb3IgKHZhciBpID0gMCwgbCA9IHBhY2tldHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgcGFyc2VyLmVuY29kZVBhY2tldChwYWNrZXRzW2ldLCB0aGlzLnN1cHBvcnRzQmluYXJ5LCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICAvL1NvbWV0aW1lcyB0aGUgd2Vic29ja2V0IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIGJ1dCB0aGUgYnJvd3NlciBkaWRuJ3RcbiAgICAgIC8vaGF2ZSBhIGNoYW5jZSBvZiBpbmZvcm1pbmcgdXMgYWJvdXQgaXQgeWV0LCBpbiB0aGF0IGNhc2Ugc2VuZCB3aWxsXG4gICAgICAvL3Rocm93IGFuIGVycm9yXG4gICAgICB0cnkge1xuICAgICAgICBzZWxmLndzLnNlbmQoZGF0YSk7XG4gICAgICB9IGNhdGNoIChlKXtcbiAgICAgICAgZGVidWcoJ3dlYnNvY2tldCBjbG9zZWQgYmVmb3JlIG9uY2xvc2UgZXZlbnQnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uZHJhaW4oKSB7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICB9XG4gIC8vIGZha2UgZHJhaW5cbiAgLy8gZGVmZXIgdG8gbmV4dCB0aWNrIHRvIGFsbG93IFNvY2tldCB0byBjbGVhciB3cml0ZUJ1ZmZlclxuICBzZXRUaW1lb3V0KG9uZHJhaW4sIDApO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBjbG9zZVxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24oKXtcbiAgVHJhbnNwb3J0LnByb3RvdHlwZS5vbkNsb3NlLmNhbGwodGhpcyk7XG59O1xuXG4vKipcbiAqIENsb3NlcyBzb2NrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmRvQ2xvc2UgPSBmdW5jdGlvbigpe1xuICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgdGhpcy53cy5jbG9zZSgpO1xuICB9XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyB1cmkgZm9yIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gIHZhciBzY2hlbWEgPSB0aGlzLnNlY3VyZSA/ICd3c3MnIDogJ3dzJztcbiAgdmFyIHBvcnQgPSAnJztcblxuICAvLyBhdm9pZCBwb3J0IGlmIGRlZmF1bHQgZm9yIHNjaGVtYVxuICBpZiAodGhpcy5wb3J0ICYmICgoJ3dzcycgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA0NDMpXG4gICAgfHwgKCd3cycgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA4MCkpKSB7XG4gICAgcG9ydCA9ICc6JyArIHRoaXMucG9ydDtcbiAgfVxuXG4gIC8vIGFwcGVuZCB0aW1lc3RhbXAgdG8gVVJJXG4gIGlmICh0aGlzLnRpbWVzdGFtcFJlcXVlc3RzKSB7XG4gICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSArbmV3IERhdGU7XG4gIH1cblxuICAvLyBjb21tdW5pY2F0ZSBiaW5hcnkgc3VwcG9ydCBjYXBhYmlsaXRpZXNcbiAgaWYgKCF0aGlzLnN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcXVlcnkuYjY0ID0gMTtcbiAgfVxuXG4gIHF1ZXJ5ID0gcGFyc2Vxcy5lbmNvZGUocXVlcnkpO1xuXG4gIC8vIHByZXBlbmQgPyB0byBxdWVyeVxuICBpZiAocXVlcnkubGVuZ3RoKSB7XG4gICAgcXVlcnkgPSAnPycgKyBxdWVyeTtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWEgKyAnOi8vJyArIHRoaXMuaG9zdG5hbWUgKyBwb3J0ICsgdGhpcy5wYXRoICsgcXVlcnk7XG59O1xuXG4vKipcbiAqIEZlYXR1cmUgZGV0ZWN0aW9uIGZvciBXZWJTb2NrZXQuXG4gKlxuICogQHJldHVybiB7Qm9vbGVhbn0gd2hldGhlciB0aGlzIHRyYW5zcG9ydCBpcyBhdmFpbGFibGUuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbldTLnByb3RvdHlwZS5jaGVjayA9IGZ1bmN0aW9uKCl7XG4gIHJldHVybiAhIVdlYlNvY2tldCAmJiAhKCdfX2luaXRpYWxpemUnIGluIFdlYlNvY2tldCAmJiB0aGlzLm5hbWUgPT09IFdTLnByb3RvdHlwZS5uYW1lKTtcbn07XG4iLCIvLyBicm93c2VyIHNoaW0gZm9yIHhtbGh0dHByZXF1ZXN0IG1vZHVsZVxudmFyIGhhc0NPUlMgPSByZXF1aXJlKCdoYXMtY29ycycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdHMpIHtcbiAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgLy8gc2NoZW1lIG11c3QgYmUgc2FtZSB3aGVuIHVzaWduIFhEb21haW5SZXF1ZXN0XG4gIC8vIGh0dHA6Ly9ibG9ncy5tc2RuLmNvbS9iL2llaW50ZXJuYWxzL2FyY2hpdmUvMjAxMC8wNS8xMy94ZG9tYWlucmVxdWVzdC1yZXN0cmljdGlvbnMtbGltaXRhdGlvbnMtYW5kLXdvcmthcm91bmRzLmFzcHhcbiAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgLy8gWERvbWFpblJlcXVlc3QgaGFzIGEgZmxvdyBvZiBub3Qgc2VuZGluZyBjb29raWUsIHRoZXJlZm9yZSBpdCBzaG91bGQgYmUgZGlzYWJsZWQgYXMgYSBkZWZhdWx0LlxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vQXV0b21hdHRpYy9lbmdpbmUuaW8tY2xpZW50L3B1bGwvMjE3XG4gIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gIC8vIFVzZSBYRG9tYWluUmVxdWVzdCBmb3IgSUU4IGlmIGVuYWJsZXNYRFIgaXMgdHJ1ZVxuICAvLyBiZWNhdXNlIGxvYWRpbmcgYmFyIGtlZXBzIGZsYXNoaW5nIHdoZW4gdXNpbmcganNvbnAtcG9sbGluZ1xuICAvLyBodHRwczovL2dpdGh1Yi5jb20veXVqaW9zYWthL3NvY2tlLmlvLWllOC1sb2FkaW5nLWV4YW1wbGVcbiAgdHJ5IHtcbiAgICBpZiAoJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIFhEb21haW5SZXF1ZXN0ICYmICF4c2NoZW1lICYmIGVuYWJsZXNYRFIpIHtcbiAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHsgfVxuXG4gIC8vIFhNTEh0dHBSZXF1ZXN0IGNhbiBiZSBkaXNhYmxlZCBvbiBJRVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgWE1MSHR0cFJlcXVlc3QgJiYgKCF4ZG9tYWluIHx8IGhhc0NPUlMpKSB7XG4gICAgICByZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7IH1cblxuICBpZiAoIXhkb21haW4pIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpO1xuICAgIH0gY2F0Y2goZSkgeyB9XG4gIH1cbn1cbiIsIlxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhLCBiKXtcbiAgdmFyIGZuID0gZnVuY3Rpb24oKXt9O1xuICBmbi5wcm90b3R5cGUgPSBiLnByb3RvdHlwZTtcbiAgYS5wcm90b3R5cGUgPSBuZXcgZm47XG4gIGEucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gYTtcbn07IiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG52YXIgc2xpY2VCdWZmZXIgPSByZXF1aXJlKCdhcnJheWJ1ZmZlci5zbGljZScpO1xudmFyIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbnZhciBhZnRlciA9IHJlcXVpcmUoJ2FmdGVyJyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJ3V0ZjgnKTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSk7XG5cbi8qKlxuICogQ3VycmVudCBwcm90b2NvbCB2ZXJzaW9uLlxuICovXG5cbmV4cG9ydHMucHJvdG9jb2wgPSAzO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlcy5cbiAqL1xuXG52YXIgcGFja2V0cyA9IGV4cG9ydHMucGFja2V0cyA9IHtcbiAgICBvcGVuOiAgICAgMCAgICAvLyBub24td3NcbiAgLCBjbG9zZTogICAgMSAgICAvLyBub24td3NcbiAgLCBwaW5nOiAgICAgMlxuICAsIHBvbmc6ICAgICAzXG4gICwgbWVzc2FnZTogIDRcbiAgLCB1cGdyYWRlOiAgNVxuICAsIG5vb3A6ICAgICA2XG59O1xuXG52YXIgcGFja2V0c2xpc3QgPSBrZXlzKHBhY2tldHMpO1xuXG4vKipcbiAqIFByZW1hZGUgZXJyb3IgcGFja2V0LlxuICovXG5cbnZhciBlcnIgPSB7IHR5cGU6ICdlcnJvcicsIGRhdGE6ICdwYXJzZXIgZXJyb3InIH07XG5cbi8qKlxuICogQ3JlYXRlIGEgYmxvYiBhcGkgZXZlbiBmb3IgYmxvYiBidWlsZGVyIHdoZW4gdmVuZG9yIHByZWZpeGVzIGV4aXN0XG4gKi9cblxudmFyIEJsb2IgPSByZXF1aXJlKCdibG9iJyk7XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldC5cbiAqXG4gKiAgICAgPHBhY2tldCB0eXBlIGlkPiBbIDxkYXRhPiBdXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgNWhlbGxvIHdvcmxkXG4gKiAgICAgM1xuICogICAgIDRcbiAqXG4gKiBCaW5hcnkgaXMgZW5jb2RlZCBpbiBhbiBpZGVudGljYWwgcHJpbmNpcGxlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdXRmOGVuY29kZSwgY2FsbGJhY2spIHtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHN1cHBvcnRzQmluYXJ5KSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHV0ZjhlbmNvZGUpIHtcbiAgICBjYWxsYmFjayA9IHV0ZjhlbmNvZGU7XG4gICAgdXRmOGVuY29kZSA9IG51bGw7XG4gIH1cblxuICB2YXIgZGF0YSA9IChwYWNrZXQuZGF0YSA9PT0gdW5kZWZpbmVkKVxuICAgID8gdW5kZWZpbmVkXG4gICAgOiBwYWNrZXQuZGF0YS5idWZmZXIgfHwgcGFja2V0LmRhdGE7XG5cbiAgaWYgKGdsb2JhbC5BcnJheUJ1ZmZlciAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZW5jb2RlQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKEJsb2IgJiYgZGF0YSBpbnN0YW5jZW9mIGdsb2JhbC5CbG9iKSB7XG4gICAgcmV0dXJuIGVuY29kZUJsb2IocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgaGVscGVycyBmb3IgYmluYXJ5IHR5cGVzXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcGFja2V0LmRhdGE7XG4gIHZhciBjb250ZW50QXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgdmFyIHJlc3VsdEJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDEgKyBkYXRhLmJ5dGVMZW5ndGgpO1xuXG4gIHJlc3VsdEJ1ZmZlclswXSA9IHBhY2tldHNbcGFja2V0LnR5cGVdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRlbnRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdEJ1ZmZlcltpKzFdID0gY29udGVudEFycmF5W2ldO1xuICB9XG5cbiAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEJ1ZmZlci5idWZmZXIpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iQXNBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgcGFja2V0LmRhdGEgPSBmci5yZXN1bHQ7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdHJ1ZSwgY2FsbGJhY2spO1xuICB9O1xuICByZXR1cm4gZnIucmVhZEFzQXJyYXlCdWZmZXIocGFja2V0LmRhdGEpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAoaXNBbmRyb2lkKSB7XG4gICAgcmV0dXJuIGVuY29kZUJsb2JBc0FycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBuZXcgVWludDhBcnJheSgxKTtcbiAgbGVuZ3RoWzBdID0gcGFja2V0c1twYWNrZXQudHlwZV07XG4gIHZhciBibG9iID0gbmV3IEJsb2IoW2xlbmd0aC5idWZmZXIsIHBhY2tldC5kYXRhXSk7XG5cbiAgcmV0dXJuIGNhbGxiYWNrKGJsb2IpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgYSBwYWNrZXQgd2l0aCBiaW5hcnkgZGF0YSBpbiBhIGJhc2U2NCBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0LCBoYXMgYHR5cGVgIGFuZCBgZGF0YWBcbiAqIEByZXR1cm4ge1N0cmluZ30gYmFzZTY0IGVuY29kZWQgbWVzc2FnZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0LCBjYWxsYmFjaykge1xuICB2YXIgbWVzc2FnZSA9ICdiJyArIGV4cG9ydHMucGFja2V0c1twYWNrZXQudHlwZV07XG4gIGlmIChCbG9iICYmIHBhY2tldC5kYXRhIGluc3RhbmNlb2YgQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnIHx8IGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkYXRhLmNoYXJBdCgwKSA9PSAnYicpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlY29kZUJhc2U2NFBhY2tldChkYXRhLnN1YnN0cigxKSwgYmluYXJ5VHlwZSk7XG4gICAgfVxuXG4gICAgaWYgKHV0ZjhkZWNvZGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGVycjtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHR5cGUgPSBkYXRhLmNoYXJBdCgwKTtcblxuICAgIGlmIChOdW1iZXIodHlwZSkgIT0gdHlwZSB8fCAhcGFja2V0c2xpc3RbdHlwZV0pIHtcbiAgICAgIHJldHVybiBlcnI7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0sIGRhdGE6IGRhdGEuc3Vic3RyaW5nKDEpIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIGFzQXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgdmFyIHR5cGUgPSBhc0FycmF5WzBdO1xuICB2YXIgcmVzdCA9IHNsaWNlQnVmZmVyKGRhdGEsIDEpO1xuICBpZiAoQmxvYiAmJiBiaW5hcnlUeXBlID09PSAnYmxvYicpIHtcbiAgICByZXN0ID0gbmV3IEJsb2IoW3Jlc3RdKTtcbiAgfVxuICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogcmVzdCB9O1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogdHlwZSwgZGF0YTogeyBiYXNlNjQ6IHRydWUsIGRhdGE6IG1zZy5zdWJzdHIoMSkgfSB9O1xuICB9XG5cbiAgdmFyIGRhdGEgPSBiYXNlNjRlbmNvZGVyLmRlY29kZShtc2cuc3Vic3RyKDEpKTtcblxuICBpZiAoYmluYXJ5VHlwZSA9PT0gJ2Jsb2InICYmIEJsb2IpIHtcbiAgICBkYXRhID0gbmV3IEJsb2IoW2RhdGFdKTtcbiAgfVxuXG4gIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IGRhdGEgfTtcbn07XG5cbi8qKlxuICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkuXG4gKlxuICogICAgIDxsZW5ndGg+OmRhdGFcbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAxMTpoZWxsbyB3b3JsZDI6aGlcbiAqXG4gKiBJZiBhbnkgY29udGVudHMgYXJlIGJpbmFyeSwgdGhleSB3aWxsIGJlIGVuY29kZWQgYXMgYmFzZTY0IHN0cmluZ3MuIEJhc2U2NFxuICogZW5jb2RlZCBzdHJpbmdzIGFyZSBtYXJrZWQgd2l0aCBhIGIgYmVmb3JlIHRoZSBsZW5ndGggc3BlY2lmaWVyXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKHBhY2tldHMsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIHN1cHBvcnRzQmluYXJ5ID09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gbnVsbDtcbiAgfVxuXG4gIGlmIChzdXBwb3J0c0JpbmFyeSkge1xuICAgIGlmIChCbG9iICYmICFpc0FuZHJvaWQpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB0cnVlLCBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICBkb25lQ2FsbGJhY2sobnVsbCwgc2V0TGVuZ3RoSGVhZGVyKG1lc3NhZ2UpKTtcbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhyZXN1bHRzLmpvaW4oJycpKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEFzeW5jIGFycmF5IG1hcCB1c2luZyBhZnRlclxuICovXG5cbmZ1bmN0aW9uIG1hcChhcnksIGVhY2gsIGRvbmUpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShhcnkubGVuZ3RoKTtcbiAgdmFyIG5leHQgPSBhZnRlcihhcnkubGVuZ3RoLCBkb25lKTtcblxuICB2YXIgZWFjaFdpdGhJbmRleCA9IGZ1bmN0aW9uKGksIGVsLCBjYikge1xuICAgIGVhY2goZWwsIGZ1bmN0aW9uKGVycm9yLCBtc2cpIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1zZztcbiAgICAgIGNiKGVycm9yLCByZXN1bHQpO1xuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgZWFjaFdpdGhJbmRleChpLCBhcnlbaV0sIG5leHQpO1xuICB9XG59XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFBvc3NpYmxlIGJpbmFyeSBjb250ZW50cyBhcmVcbiAqIGRlY29kZWQgZnJvbSB0aGVpciBiYXNlNjQgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRhdGEgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5kZWNvZGVQYXlsb2FkQXNCaW5hcnkoZGF0YSwgYmluYXJ5VHlwZSwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBiaW5hcnlUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBiaW5hcnlUeXBlO1xuICAgIGJpbmFyeVR5cGUgPSBudWxsO1xuICB9XG5cbiAgdmFyIHBhY2tldDtcbiAgaWYgKGRhdGEgPT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gJydcbiAgICAsIG4sIG1zZztcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IGRhdGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGNociA9IGRhdGEuY2hhckF0KGkpO1xuXG4gICAgaWYgKCc6JyAhPSBjaHIpIHtcbiAgICAgIGxlbmd0aCArPSBjaHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgnJyA9PSBsZW5ndGggfHwgKGxlbmd0aCAhPSAobiA9IE51bWJlcihsZW5ndGgpKSkpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgbXNnID0gZGF0YS5zdWJzdHIoaSArIDEsIG4pO1xuXG4gICAgICBpZiAobGVuZ3RoICE9IG1zZy5sZW5ndGgpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1zZy5sZW5ndGgpIHtcbiAgICAgICAgcGFja2V0ID0gZXhwb3J0cy5kZWNvZGVQYWNrZXQobXNnLCBiaW5hcnlUeXBlLCB0cnVlKTtcblxuICAgICAgICBpZiAoZXJyLnR5cGUgPT0gcGFja2V0LnR5cGUgJiYgZXJyLmRhdGEgPT0gcGFja2V0LmRhdGEpIHtcbiAgICAgICAgICAvLyBwYXJzZXIgZXJyb3IgaW4gaW5kaXZpZHVhbCBwYWNrZXQgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmV0ID0gY2FsbGJhY2socGFja2V0LCBpICsgbiwgbCk7XG4gICAgICAgIGlmIChmYWxzZSA9PT0gcmV0KSByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGFkdmFuY2UgY3Vyc29yXG4gICAgICBpICs9IG47XG4gICAgICBsZW5ndGggPSAnJztcbiAgICB9XG4gIH1cblxuICBpZiAobGVuZ3RoICE9ICcnKSB7XG4gICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICB9XG5cbn07XG5cbi8qKlxuICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkgYXMgYmluYXJ5LlxuICpcbiAqIDwxID0gYmluYXJ5LCAwID0gc3RyaW5nPjxudW1iZXIgZnJvbSAwLTk+PG51bWJlciBmcm9tIDAtOT5bLi4uXTxudW1iZXJcbiAqIDI1NT48ZGF0YT5cbiAqXG4gKiBFeGFtcGxlOlxuICogMSAzIDI1NSAxIDIgMywgaWYgdGhlIGJpbmFyeSBjb250ZW50cyBhcmUgaW50ZXJwcmV0ZWQgYXMgOCBiaXQgaW50ZWdlcnNcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWNrZXRzXG4gKiBAcmV0dXJuIHtBcnJheUJ1ZmZlcn0gZW5jb2RlZCBwYXlsb2FkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgaWYgKCFwYWNrZXRzLmxlbmd0aCkge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQXJyYXlCdWZmZXIoMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gZG9uZUNhbGxiYWNrKG51bGwsIGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCBlbmNvZGVkUGFja2V0cykge1xuICAgIHZhciB0b3RhbExlbmd0aCA9IGVuY29kZWRQYWNrZXRzLnJlZHVjZShmdW5jdGlvbihhY2MsIHApIHtcbiAgICAgIHZhciBsZW47XG4gICAgICBpZiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgbGVuID0gcC5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZW4gPSBwLmJ5dGVMZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjICsgbGVuLnRvU3RyaW5nKCkubGVuZ3RoICsgbGVuICsgMjsgLy8gc3RyaW5nL2JpbmFyeSBpZGVudGlmaWVyICsgc2VwYXJhdG9yID0gMlxuICAgIH0sIDApO1xuXG4gICAgdmFyIHJlc3VsdEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuXG4gICAgdmFyIGJ1ZmZlckluZGV4ID0gMDtcbiAgICBlbmNvZGVkUGFja2V0cy5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgIHZhciBpc1N0cmluZyA9IHR5cGVvZiBwID09PSAnc3RyaW5nJztcbiAgICAgIHZhciBhYiA9IHA7XG4gICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShwLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZpZXdbaV0gPSBwLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgYWIgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU3RyaW5nKSB7IC8vIG5vdCB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDA7XG4gICAgICB9IGVsc2UgeyAvLyB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDE7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW5TdHIgPSBhYi5ieXRlTGVuZ3RoLnRvU3RyaW5nKCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDI1NTtcblxuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShhYik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0QXJyYXlbYnVmZmVySW5kZXgrK10gPSB2aWV3W2ldO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEFycmF5LmJ1ZmZlcik7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBFbmNvZGUgYXMgQmxvYlxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQmxvYiA9IGZ1bmN0aW9uKHBhY2tldHMsIGNhbGxiYWNrKSB7XG4gIGZ1bmN0aW9uIGVuY29kZU9uZShwYWNrZXQsIGRvbmVDYWxsYmFjaykge1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgdHJ1ZSwgdHJ1ZSwgZnVuY3Rpb24oZW5jb2RlZCkge1xuICAgICAgdmFyIGJpbmFyeUlkZW50aWZpZXIgPSBuZXcgVWludDhBcnJheSgxKTtcbiAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAxO1xuICAgICAgaWYgKHR5cGVvZiBlbmNvZGVkID09PSAnc3RyaW5nJykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWQubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IGVuY29kZWQuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGVkID0gdmlldy5idWZmZXI7XG4gICAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAwO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGVuID0gKGVuY29kZWQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilcbiAgICAgICAgPyBlbmNvZGVkLmJ5dGVMZW5ndGhcbiAgICAgICAgOiBlbmNvZGVkLnNpemU7XG5cbiAgICAgIHZhciBsZW5TdHIgPSBsZW4udG9TdHJpbmcoKTtcbiAgICAgIHZhciBsZW5ndGhBcnkgPSBuZXcgVWludDhBcnJheShsZW5TdHIubGVuZ3RoICsgMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZW5ndGhBcnlbaV0gPSBwYXJzZUludChsZW5TdHJbaV0pO1xuICAgICAgfVxuICAgICAgbGVuZ3RoQXJ5W2xlblN0ci5sZW5ndGhdID0gMjU1O1xuXG4gICAgICBpZiAoQmxvYikge1xuICAgICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtiaW5hcnlJZGVudGlmaWVyLmJ1ZmZlciwgbGVuZ3RoQXJ5LmJ1ZmZlciwgZW5jb2RlZF0pO1xuICAgICAgICBkb25lQ2FsbGJhY2sobnVsbCwgYmxvYik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IEJsb2IocmVzdWx0cykpO1xuICB9KTtcbn07XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFN0cmluZ3MgYXJlIGRlY29kZWQgYnlcbiAqIGludGVycHJldGluZyBlYWNoIGJ5dGUgYXMgYSBrZXkgY29kZSBmb3IgZW50cmllcyBtYXJrZWQgdG8gc3RhcnQgd2l0aCAwLiBTZWVcbiAqIGRlc2NyaXB0aW9uIG9mIGVuY29kZVBheWxvYWRBc0JpbmFyeVxuICpcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGEsIGNhbGxiYWNrIG1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeSA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgYnVmZmVyVGFpbCA9IGRhdGE7XG4gIHZhciBidWZmZXJzID0gW107XG5cbiAgdmFyIG51bWJlclRvb0xvbmcgPSBmYWxzZTtcbiAgd2hpbGUgKGJ1ZmZlclRhaWwuYnl0ZUxlbmd0aCA+IDApIHtcbiAgICB2YXIgdGFpbEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyVGFpbCk7XG4gICAgdmFyIGlzU3RyaW5nID0gdGFpbEFycmF5WzBdID09PSAwO1xuICAgIHZhciBtc2dMZW5ndGggPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAxOyA7IGkrKykge1xuICAgICAgaWYgKHRhaWxBcnJheVtpXSA9PSAyNTUpIGJyZWFrO1xuXG4gICAgICBpZiAobXNnTGVuZ3RoLmxlbmd0aCA+IDMxMCkge1xuICAgICAgICBudW1iZXJUb29Mb25nID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIG1zZ0xlbmd0aCArPSB0YWlsQXJyYXlbaV07XG4gICAgfVxuXG4gICAgaWYobnVtYmVyVG9vTG9uZykgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG5cbiAgICBidWZmZXJUYWlsID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMiArIG1zZ0xlbmd0aC5sZW5ndGgpO1xuICAgIG1zZ0xlbmd0aCA9IHBhcnNlSW50KG1zZ0xlbmd0aCk7XG5cbiAgICB2YXIgbXNnID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMCwgbXNnTGVuZ3RoKTtcbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1zZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkobXNnKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlQaG9uZSBTYWZhcmkgZG9lc24ndCBsZXQgeW91IGFwcGx5IHRvIHR5cGVkIGFycmF5c1xuICAgICAgICB2YXIgdHlwZWQgPSBuZXcgVWludDhBcnJheShtc2cpO1xuICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG1zZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHR5cGVkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGJ1ZmZlcnMucHVzaChtc2cpO1xuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCBtc2dMZW5ndGgpO1xuICB9XG5cbiAgdmFyIHRvdGFsID0gYnVmZmVycy5sZW5ndGg7XG4gIGJ1ZmZlcnMuZm9yRWFjaChmdW5jdGlvbihidWZmZXIsIGkpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLmRlY29kZVBhY2tldChidWZmZXIsIGJpbmFyeVR5cGUsIHRydWUpLCBpLCB0b3RhbCk7XG4gIH0pO1xufTtcbiIsIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFmdGVyXG5cbmZ1bmN0aW9uIGFmdGVyKGNvdW50LCBjYWxsYmFjaywgZXJyX2NiKSB7XG4gICAgdmFyIGJhaWwgPSBmYWxzZVxuICAgIGVycl9jYiA9IGVycl9jYiB8fCBub29wXG4gICAgcHJveHkuY291bnQgPSBjb3VudFxuXG4gICAgcmV0dXJuIChjb3VudCA9PT0gMCkgPyBjYWxsYmFjaygpIDogcHJveHlcblxuICAgIGZ1bmN0aW9uIHByb3h5KGVyciwgcmVzdWx0KSB7XG4gICAgICAgIGlmIChwcm94eS5jb3VudCA8PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FmdGVyIGNhbGxlZCB0b28gbWFueSB0aW1lcycpXG4gICAgICAgIH1cbiAgICAgICAgLS1wcm94eS5jb3VudFxuXG4gICAgICAgIC8vIGFmdGVyIGZpcnN0IGVycm9yLCByZXN0IGFyZSBwYXNzZWQgdG8gZXJyX2NiXG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGJhaWwgPSB0cnVlXG4gICAgICAgICAgICBjYWxsYmFjayhlcnIpXG4gICAgICAgICAgICAvLyBmdXR1cmUgZXJyb3IgY2FsbGJhY2tzIHdpbGwgZ28gdG8gZXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgY2FsbGJhY2sgPSBlcnJfY2JcbiAgICAgICAgfSBlbHNlIGlmIChwcm94eS5jb3VudCA9PT0gMCAmJiAhYmFpbCkge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBub29wKCkge31cbiIsIi8qKlxuICogQW4gYWJzdHJhY3Rpb24gZm9yIHNsaWNpbmcgYW4gYXJyYXlidWZmZXIgZXZlbiB3aGVuXG4gKiBBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgaXMgbm90IHN1cHBvcnRlZFxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnJheWJ1ZmZlciwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBhcnJheWJ1ZmZlci5ieXRlTGVuZ3RoO1xuICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gIGVuZCA9IGVuZCB8fCBieXRlcztcblxuICBpZiAoYXJyYXlidWZmZXIuc2xpY2UpIHsgcmV0dXJuIGFycmF5YnVmZmVyLnNsaWNlKHN0YXJ0LCBlbmQpOyB9XG5cbiAgaWYgKHN0YXJ0IDwgMCkgeyBzdGFydCArPSBieXRlczsgfVxuICBpZiAoZW5kIDwgMCkgeyBlbmQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA+IGJ5dGVzKSB7IGVuZCA9IGJ5dGVzOyB9XG5cbiAgaWYgKHN0YXJ0ID49IGJ5dGVzIHx8IHN0YXJ0ID49IGVuZCB8fCBieXRlcyA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gIH1cblxuICB2YXIgYWJ2ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpO1xuICB2YXIgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoZW5kIC0gc3RhcnQpO1xuICBmb3IgKHZhciBpID0gc3RhcnQsIGlpID0gMDsgaSA8IGVuZDsgaSsrLCBpaSsrKSB7XG4gICAgcmVzdWx0W2lpXSA9IGFidltpXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0LmJ1ZmZlcjtcbn07XG4iLCIvKlxuICogYmFzZTY0LWFycmF5YnVmZmVyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbmlrbGFzdmgvYmFzZTY0LWFycmF5YnVmZmVyXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIE5pa2xhcyB2b24gSGVydHplblxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG4oZnVuY3Rpb24oY2hhcnMpe1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBleHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uKGFycmF5YnVmZmVyKSB7XG4gICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpLFxuICAgIGksIGxlbiA9IGJ5dGVzLmxlbmd0aCwgYmFzZTY0ID0gXCJcIjtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrPTMpIHtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1tieXRlc1tpXSA+PiAyXTtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2ldICYgMykgPDwgNCkgfCAoYnl0ZXNbaSArIDFdID4+IDQpXTtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2kgKyAxXSAmIDE1KSA8PCAyKSB8IChieXRlc1tpICsgMl0gPj4gNildO1xuICAgICAgYmFzZTY0ICs9IGNoYXJzW2J5dGVzW2kgKyAyXSAmIDYzXTtcbiAgICB9XG5cbiAgICBpZiAoKGxlbiAlIDMpID09PSAyKSB7XG4gICAgICBiYXNlNjQgPSBiYXNlNjQuc3Vic3RyaW5nKDAsIGJhc2U2NC5sZW5ndGggLSAxKSArIFwiPVwiO1xuICAgIH0gZWxzZSBpZiAobGVuICUgMyA9PT0gMSkge1xuICAgICAgYmFzZTY0ID0gYmFzZTY0LnN1YnN0cmluZygwLCBiYXNlNjQubGVuZ3RoIC0gMikgKyBcIj09XCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJhc2U2NDtcbiAgfTtcblxuICBleHBvcnRzLmRlY29kZSA9ICBmdW5jdGlvbihiYXNlNjQpIHtcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYmFzZTY0Lmxlbmd0aCAqIDAuNzUsXG4gICAgbGVuID0gYmFzZTY0Lmxlbmd0aCwgaSwgcCA9IDAsXG4gICAgZW5jb2RlZDEsIGVuY29kZWQyLCBlbmNvZGVkMywgZW5jb2RlZDQ7XG5cbiAgICBpZiAoYmFzZTY0W2Jhc2U2NC5sZW5ndGggLSAxXSA9PT0gXCI9XCIpIHtcbiAgICAgIGJ1ZmZlckxlbmd0aC0tO1xuICAgICAgaWYgKGJhc2U2NFtiYXNlNjQubGVuZ3RoIC0gMl0gPT09IFwiPVwiKSB7XG4gICAgICAgIGJ1ZmZlckxlbmd0aC0tO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBhcnJheWJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXJMZW5ndGgpLFxuICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSs9NCkge1xuICAgICAgZW5jb2RlZDEgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpXSk7XG4gICAgICBlbmNvZGVkMiA9IGNoYXJzLmluZGV4T2YoYmFzZTY0W2krMV0pO1xuICAgICAgZW5jb2RlZDMgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpKzJdKTtcbiAgICAgIGVuY29kZWQ0ID0gY2hhcnMuaW5kZXhPZihiYXNlNjRbaSszXSk7XG5cbiAgICAgIGJ5dGVzW3ArK10gPSAoZW5jb2RlZDEgPDwgMikgfCAoZW5jb2RlZDIgPj4gNCk7XG4gICAgICBieXRlc1twKytdID0gKChlbmNvZGVkMiAmIDE1KSA8PCA0KSB8IChlbmNvZGVkMyA+PiAyKTtcbiAgICAgIGJ5dGVzW3ArK10gPSAoKGVuY29kZWQzICYgMykgPDwgNikgfCAoZW5jb2RlZDQgJiA2Myk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5YnVmZmVyO1xuICB9O1xufSkoXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIpO1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBDcmVhdGUgYSBibG9iIGJ1aWxkZXIgZXZlbiB3aGVuIHZlbmRvciBwcmVmaXhlcyBleGlzdFxuICovXG5cbnZhciBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlclxuICB8fCBnbG9iYWwuV2ViS2l0QmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLk1TQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLk1vekJsb2JCdWlsZGVyO1xuXG4vKipcbiAqIENoZWNrIGlmIEJsb2IgY29uc3RydWN0b3IgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JTdXBwb3J0ZWQgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgdmFyIGIgPSBuZXcgQmxvYihbJ2hpJ10pO1xuICAgIHJldHVybiBiLnNpemUgPT0gMjtcbiAgfSBjYXRjaChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59KSgpO1xuXG4vKipcbiAqIENoZWNrIGlmIEJsb2JCdWlsZGVyIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iQnVpbGRlclN1cHBvcnRlZCA9IEJsb2JCdWlsZGVyXG4gICYmIEJsb2JCdWlsZGVyLnByb3RvdHlwZS5hcHBlbmRcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmdldEJsb2I7XG5cbmZ1bmN0aW9uIEJsb2JCdWlsZGVyQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBiYiA9IG5ldyBCbG9iQnVpbGRlcigpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyeS5sZW5ndGg7IGkrKykge1xuICAgIGJiLmFwcGVuZChhcnlbaV0pO1xuICB9XG4gIHJldHVybiAob3B0aW9ucy50eXBlKSA/IGJiLmdldEJsb2Iob3B0aW9ucy50eXBlKSA6IGJiLmdldEJsb2IoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gKGZ1bmN0aW9uKCkge1xuICBpZiAoYmxvYlN1cHBvcnRlZCkge1xuICAgIHJldHVybiBnbG9iYWwuQmxvYjtcbiAgfSBlbHNlIGlmIChibG9iQnVpbGRlclN1cHBvcnRlZCkge1xuICAgIHJldHVybiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn0pKCk7XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTsvKiEgaHR0cDovL210aHMuYmUvdXRmOGpzIHYyLjAuMCBieSBAbWF0aGlhcyAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGVzIGBleHBvcnRzYFxuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgXG5cdHZhciBmcmVlTW9kdWxlID0gdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiZcblx0XHRtb2R1bGUuZXhwb3J0cyA9PSBmcmVlRXhwb3J0cyAmJiBtb2R1bGU7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAsIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSxcblx0Ly8gYW5kIHVzZSBpdCBhcyBgcm9vdGBcblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHR2YXIgc3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuXHQvLyBUYWtlbiBmcm9tIGh0dHA6Ly9tdGhzLmJlL3B1bnljb2RlXG5cdGZ1bmN0aW9uIHVjczJkZWNvZGUoc3RyaW5nKSB7XG5cdFx0dmFyIG91dHB1dCA9IFtdO1xuXHRcdHZhciBjb3VudGVyID0gMDtcblx0XHR2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblx0XHR2YXIgdmFsdWU7XG5cdFx0dmFyIGV4dHJhO1xuXHRcdHdoaWxlIChjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHR2YWx1ZSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRpZiAodmFsdWUgPj0gMHhEODAwICYmIHZhbHVlIDw9IDB4REJGRiAmJiBjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHRcdC8vIGhpZ2ggc3Vycm9nYXRlLCBhbmQgdGhlcmUgaXMgYSBuZXh0IGNoYXJhY3RlclxuXHRcdFx0XHRleHRyYSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRcdGlmICgoZXh0cmEgJiAweEZDMDApID09IDB4REMwMCkgeyAvLyBsb3cgc3Vycm9nYXRlXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2goKCh2YWx1ZSAmIDB4M0ZGKSA8PCAxMCkgKyAoZXh0cmEgJiAweDNGRikgKyAweDEwMDAwKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyB1bm1hdGNoZWQgc3Vycm9nYXRlOyBvbmx5IGFwcGVuZCB0aGlzIGNvZGUgdW5pdCwgaW4gY2FzZSB0aGUgbmV4dFxuXHRcdFx0XHRcdC8vIGNvZGUgdW5pdCBpcyB0aGUgaGlnaCBzdXJyb2dhdGUgb2YgYSBzdXJyb2dhdGUgcGFpclxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdFx0XHRjb3VudGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8vIFRha2VuIGZyb20gaHR0cDovL210aHMuYmUvcHVueWNvZGVcblx0ZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuXHRcdHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cdFx0dmFyIGluZGV4ID0gLTE7XG5cdFx0dmFyIHZhbHVlO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBhcnJheVtpbmRleF07XG5cdFx0XHRpZiAodmFsdWUgPiAweEZGRkYpIHtcblx0XHRcdFx0dmFsdWUgLT0gMHgxMDAwMDtcblx0XHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG5cdFx0XHRcdHZhbHVlID0gMHhEQzAwIHwgdmFsdWUgJiAweDNGRjtcblx0XHRcdH1cblx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0ZnVuY3Rpb24gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIHNoaWZ0KSB7XG5cdFx0cmV0dXJuIHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiBzaGlmdCkgJiAweDNGKSB8IDB4ODApO1xuXHR9XG5cblx0ZnVuY3Rpb24gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCkge1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRkY4MCkgPT0gMCkgeyAvLyAxLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHJldHVybiBzdHJpbmdGcm9tQ2hhckNvZGUoY29kZVBvaW50KTtcblx0XHR9XG5cdFx0dmFyIHN5bWJvbCA9ICcnO1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRjgwMCkgPT0gMCkgeyAvLyAyLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiA2KSAmIDB4MUYpIHwgMHhDMCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKChjb2RlUG9pbnQgJiAweEZGRkYwMDAwKSA9PSAwKSB7IC8vIDMtYnl0ZSBzZXF1ZW5jZVxuXHRcdFx0c3ltYm9sID0gc3RyaW5nRnJvbUNoYXJDb2RlKCgoY29kZVBvaW50ID4+IDEyKSAmIDB4MEYpIHwgMHhFMCk7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRlbHNlIGlmICgoY29kZVBvaW50ICYgMHhGRkUwMDAwMCkgPT0gMCkgeyAvLyA0LWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiAxOCkgJiAweDA3KSB8IDB4RjApO1xuXHRcdFx0c3ltYm9sICs9IGNyZWF0ZUJ5dGUoY29kZVBvaW50LCAxMik7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRzeW1ib2wgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKChjb2RlUG9pbnQgJiAweDNGKSB8IDB4ODApO1xuXHRcdHJldHVybiBzeW1ib2w7XG5cdH1cblxuXHRmdW5jdGlvbiB1dGY4ZW5jb2RlKHN0cmluZykge1xuXHRcdHZhciBjb2RlUG9pbnRzID0gdWNzMmRlY29kZShzdHJpbmcpO1xuXG5cdFx0Ly8gY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoY29kZVBvaW50cy5tYXAoZnVuY3Rpb24oeCkge1xuXHRcdC8vIFx0cmV0dXJuICdVKycgKyB4LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuXHRcdC8vIH0pKSk7XG5cblx0XHR2YXIgbGVuZ3RoID0gY29kZVBvaW50cy5sZW5ndGg7XG5cdFx0dmFyIGluZGV4ID0gLTE7XG5cdFx0dmFyIGNvZGVQb2ludDtcblx0XHR2YXIgYnl0ZVN0cmluZyA9ICcnO1xuXHRcdHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG5cdFx0XHRjb2RlUG9pbnQgPSBjb2RlUG9pbnRzW2luZGV4XTtcblx0XHRcdGJ5dGVTdHJpbmcgKz0gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCk7XG5cdFx0fVxuXHRcdHJldHVybiBieXRlU3RyaW5nO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0ZnVuY3Rpb24gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKSB7XG5cdFx0aWYgKGJ5dGVJbmRleCA+PSBieXRlQ291bnQpIHtcblx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGJ5dGUgaW5kZXgnKTtcblx0XHR9XG5cblx0XHR2YXIgY29udGludWF0aW9uQnl0ZSA9IGJ5dGVBcnJheVtieXRlSW5kZXhdICYgMHhGRjtcblx0XHRieXRlSW5kZXgrKztcblxuXHRcdGlmICgoY29udGludWF0aW9uQnl0ZSAmIDB4QzApID09IDB4ODApIHtcblx0XHRcdHJldHVybiBjb250aW51YXRpb25CeXRlICYgMHgzRjtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBlbmQgdXAgaGVyZSwgaXTigJlzIG5vdCBhIGNvbnRpbnVhdGlvbiBieXRlXG5cdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgY29udGludWF0aW9uIGJ5dGUnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGRlY29kZVN5bWJvbCgpIHtcblx0XHR2YXIgYnl0ZTE7XG5cdFx0dmFyIGJ5dGUyO1xuXHRcdHZhciBieXRlMztcblx0XHR2YXIgYnl0ZTQ7XG5cdFx0dmFyIGNvZGVQb2ludDtcblxuXHRcdGlmIChieXRlSW5kZXggPiBieXRlQ291bnQpIHtcblx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGJ5dGUgaW5kZXgnKTtcblx0XHR9XG5cblx0XHRpZiAoYnl0ZUluZGV4ID09IGJ5dGVDb3VudCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIFJlYWQgZmlyc3QgYnl0ZVxuXHRcdGJ5dGUxID0gYnl0ZUFycmF5W2J5dGVJbmRleF0gJiAweEZGO1xuXHRcdGJ5dGVJbmRleCsrO1xuXG5cdFx0Ly8gMS1ieXRlIHNlcXVlbmNlIChubyBjb250aW51YXRpb24gYnl0ZXMpXG5cdFx0aWYgKChieXRlMSAmIDB4ODApID09IDApIHtcblx0XHRcdHJldHVybiBieXRlMTtcblx0XHR9XG5cblx0XHQvLyAyLWJ5dGUgc2VxdWVuY2Vcblx0XHRpZiAoKGJ5dGUxICYgMHhFMCkgPT0gMHhDMCkge1xuXHRcdFx0dmFyIGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGNvZGVQb2ludCA9ICgoYnl0ZTEgJiAweDFGKSA8PCA2KSB8IGJ5dGUyO1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDgwKSB7XG5cdFx0XHRcdHJldHVybiBjb2RlUG9pbnQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIDMtYnl0ZSBzZXF1ZW5jZSAobWF5IGluY2x1ZGUgdW5wYWlyZWQgc3Vycm9nYXRlcylcblx0XHRpZiAoKGJ5dGUxICYgMHhGMCkgPT0gMHhFMCkge1xuXHRcdFx0Ynl0ZTIgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuXHRcdFx0Ynl0ZTMgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuXHRcdFx0Y29kZVBvaW50ID0gKChieXRlMSAmIDB4MEYpIDw8IDEyKSB8IChieXRlMiA8PCA2KSB8IGJ5dGUzO1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDA4MDApIHtcblx0XHRcdFx0cmV0dXJuIGNvZGVQb2ludDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGNvbnRpbnVhdGlvbiBieXRlJyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gNC1ieXRlIHNlcXVlbmNlXG5cdFx0aWYgKChieXRlMSAmIDB4RjgpID09IDB4RjApIHtcblx0XHRcdGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGJ5dGUzID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGJ5dGU0ID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGNvZGVQb2ludCA9ICgoYnl0ZTEgJiAweDBGKSA8PCAweDEyKSB8IChieXRlMiA8PCAweDBDKSB8XG5cdFx0XHRcdChieXRlMyA8PCAweDA2KSB8IGJ5dGU0O1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDAxMDAwMCAmJiBjb2RlUG9pbnQgPD0gMHgxMEZGRkYpIHtcblx0XHRcdFx0cmV0dXJuIGNvZGVQb2ludDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBVVEYtOCBkZXRlY3RlZCcpO1xuXHR9XG5cblx0dmFyIGJ5dGVBcnJheTtcblx0dmFyIGJ5dGVDb3VudDtcblx0dmFyIGJ5dGVJbmRleDtcblx0ZnVuY3Rpb24gdXRmOGRlY29kZShieXRlU3RyaW5nKSB7XG5cdFx0Ynl0ZUFycmF5ID0gdWNzMmRlY29kZShieXRlU3RyaW5nKTtcblx0XHRieXRlQ291bnQgPSBieXRlQXJyYXkubGVuZ3RoO1xuXHRcdGJ5dGVJbmRleCA9IDA7XG5cdFx0dmFyIGNvZGVQb2ludHMgPSBbXTtcblx0XHR2YXIgdG1wO1xuXHRcdHdoaWxlICgodG1wID0gZGVjb2RlU3ltYm9sKCkpICE9PSBmYWxzZSkge1xuXHRcdFx0Y29kZVBvaW50cy5wdXNoKHRtcCk7XG5cdFx0fVxuXHRcdHJldHVybiB1Y3MyZW5jb2RlKGNvZGVQb2ludHMpO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0dmFyIHV0ZjggPSB7XG5cdFx0J3ZlcnNpb24nOiAnMi4wLjAnLFxuXHRcdCdlbmNvZGUnOiB1dGY4ZW5jb2RlLFxuXHRcdCdkZWNvZGUnOiB1dGY4ZGVjb2RlXG5cdH07XG5cblx0Ly8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3Igc3BlY2lmaWMgY29uZGl0aW9uIHBhdHRlcm5zXG5cdC8vIGxpa2UgdGhlIGZvbGxvd2luZzpcblx0aWYgKFxuXHRcdHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBkZWZpbmUuYW1kID09ICdvYmplY3QnICYmXG5cdFx0ZGVmaW5lLmFtZFxuXHQpIHtcblx0XHRkZWZpbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdXRmODtcblx0XHR9KTtcblx0fVx0ZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG5cdFx0aWYgKGZyZWVNb2R1bGUpIHsgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IHV0Zjg7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdHZhciBvYmplY3QgPSB7fTtcblx0XHRcdHZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdC5oYXNPd25Qcm9wZXJ0eTtcblx0XHRcdGZvciAodmFyIGtleSBpbiB1dGY4KSB7XG5cdFx0XHRcdGhhc093blByb3BlcnR5LmNhbGwodXRmOCwga2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IHV0Zjhba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC51dGY4ID0gdXRmODtcblx0fVxuXG59KHRoaXMpKTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBnbG9iYWwgPSByZXF1aXJlKCdnbG9iYWwnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqXG4gKiBMb2dpYyBib3Jyb3dlZCBmcm9tIE1vZGVybml6cjpcbiAqXG4gKiAgIC0gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2NvcnMuanNcbiAqL1xuXG50cnkge1xuICBtb2R1bGUuZXhwb3J0cyA9ICdYTUxIdHRwUmVxdWVzdCcgaW4gZ2xvYmFsICYmXG4gICAgJ3dpdGhDcmVkZW50aWFscycgaW4gbmV3IGdsb2JhbC5YTUxIdHRwUmVxdWVzdCgpO1xufSBjYXRjaCAoZXJyKSB7XG4gIC8vIGlmIFhNTEh0dHAgc3VwcG9ydCBpcyBkaXNhYmxlZCBpbiBJRSB0aGVuIGl0IHdpbGwgdGhyb3dcbiAgLy8gd2hlbiB0cnlpbmcgdG8gY3JlYXRlXG4gIG1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG59XG4iLCJcbi8qKlxuICogUmV0dXJucyBgdGhpc2AuIEV4ZWN1dGUgdGhpcyB3aXRob3V0IGEgXCJjb250ZXh0XCIgKGkuZS4gd2l0aG91dCBpdCBiZWluZ1xuICogYXR0YWNoZWQgdG8gYW4gb2JqZWN0IG9mIHRoZSBsZWZ0LWhhbmQgc2lkZSksIGFuZCBgdGhpc2AgcG9pbnRzIHRvIHRoZVxuICogXCJnbG9iYWxcIiBzY29wZSBvZiB0aGUgY3VycmVudCBKUyBleGVjdXRpb24uXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSAoZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSkoKTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogSlNPTiBwYXJzZS5cbiAqXG4gKiBAc2VlIEJhc2VkIG9uIGpRdWVyeSNwYXJzZUpTT04gKE1JVCkgYW5kIEpTT04yXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcnZhbGlkY2hhcnMgPSAvXltcXF0sOnt9XFxzXSokLztcbnZhciBydmFsaWRlc2NhcGUgPSAvXFxcXCg/OltcIlxcXFxcXC9iZm5ydF18dVswLTlhLWZBLUZdezR9KS9nO1xudmFyIHJ2YWxpZHRva2VucyA9IC9cIlteXCJcXFxcXFxuXFxyXSpcInx0cnVlfGZhbHNlfG51bGx8LT9cXGQrKD86XFwuXFxkKik/KD86W2VFXVsrXFwtXT9cXGQrKT8vZztcbnZhciBydmFsaWRicmFjZXMgPSAvKD86Xnw6fCwpKD86XFxzKlxcWykrL2c7XG52YXIgcnRyaW1MZWZ0ID0gL15cXHMrLztcbnZhciBydHJpbVJpZ2h0ID0gL1xccyskLztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZWpzb24oZGF0YSkge1xuICBpZiAoJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgfHwgIWRhdGEpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UocnRyaW1MZWZ0LCAnJykucmVwbGFjZShydHJpbVJpZ2h0LCAnJyk7XG5cbiAgLy8gQXR0ZW1wdCB0byBwYXJzZSB1c2luZyB0aGUgbmF0aXZlIEpTT04gcGFyc2VyIGZpcnN0XG4gIGlmIChnbG9iYWwuSlNPTiAmJiBKU09OLnBhcnNlKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH1cblxuICBpZiAocnZhbGlkY2hhcnMudGVzdChkYXRhLnJlcGxhY2UocnZhbGlkZXNjYXBlLCAnQCcpXG4gICAgICAucmVwbGFjZShydmFsaWR0b2tlbnMsICddJylcbiAgICAgIC5yZXBsYWNlKHJ2YWxpZGJyYWNlcywgJycpKSkge1xuICAgIHJldHVybiAobmV3IEZ1bmN0aW9uKCdyZXR1cm4gJyArIGRhdGEpKSgpO1xuICB9XG59OyIsIi8qKlxuICogQ29tcGlsZXMgYSBxdWVyeXN0cmluZ1xuICogUmV0dXJucyBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIGlmIChzdHIubGVuZ3RoKSBzdHIgKz0gJyYnO1xuICAgICAgc3RyICs9IGVuY29kZVVSSUNvbXBvbmVudChpKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG4vKipcbiAqIFBhcnNlcyBhIHNpbXBsZSBxdWVyeXN0cmluZyBpbnRvIGFuIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBxc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbihxcyl7XG4gIHZhciBxcnkgPSB7fTtcbiAgdmFyIHBhaXJzID0gcXMuc3BsaXQoJyYnKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYWlycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgcGFpciA9IHBhaXJzW2ldLnNwbGl0KCc9Jyk7XG4gICAgcXJ5W2RlY29kZVVSSUNvbXBvbmVudChwYWlyWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFpclsxXSk7XG4gIH1cbiAgcmV0dXJuIHFyeTtcbn07XG4iLCIvKipcbiAqIFBhcnNlcyBhbiBVUklcbiAqXG4gKiBAYXV0aG9yIFN0ZXZlbiBMZXZpdGhhbiA8c3RldmVubGV2aXRoYW4uY29tPiAoTUlUIGxpY2Vuc2UpXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcmUgPSAvXig/Oig/IVteOkBdKzpbXjpAXFwvXSpAKShodHRwfGh0dHBzfHdzfHdzcyk6XFwvXFwvKT8oKD86KChbXjpAXSopKD86OihbXjpAXSopKT8pP0ApPygoPzpbYS1mMC05XXswLDR9Oil7Miw3fVthLWYwLTldezAsNH18W146XFwvPyNdKikoPzo6KFxcZCopKT8pKCgoXFwvKD86W14/I10oPyFbXj8jXFwvXSpcXC5bXj8jXFwvLl0rKD86Wz8jXXwkKSkpKlxcLz8pPyhbXj8jXFwvXSopKSg/OlxcPyhbXiNdKikpPyg/OiMoLiopKT8pLztcblxudmFyIHBhcnRzID0gW1xuICAgICdzb3VyY2UnLCAncHJvdG9jb2wnLCAnYXV0aG9yaXR5JywgJ3VzZXJJbmZvJywgJ3VzZXInLCAncGFzc3dvcmQnLCAnaG9zdCcsICdwb3J0JywgJ3JlbGF0aXZlJywgJ3BhdGgnLCAnZGlyZWN0b3J5JywgJ2ZpbGUnLCAncXVlcnknLCAnYW5jaG9yJ1xuXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZXVyaShzdHIpIHtcbiAgICB2YXIgc3JjID0gc3RyLFxuICAgICAgICBiID0gc3RyLmluZGV4T2YoJ1snKSxcbiAgICAgICAgZSA9IHN0ci5pbmRleE9mKCddJyk7XG5cbiAgICBpZiAoYiAhPSAtMSAmJiBlICE9IC0xKSB7XG4gICAgICAgIHN0ciA9IHN0ci5zdWJzdHJpbmcoMCwgYikgKyBzdHIuc3Vic3RyaW5nKGIsIGUpLnJlcGxhY2UoLzovZywgJzsnKSArIHN0ci5zdWJzdHJpbmcoZSwgc3RyLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgdmFyIG0gPSByZS5leGVjKHN0ciB8fCAnJyksXG4gICAgICAgIHVyaSA9IHt9LFxuICAgICAgICBpID0gMTQ7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIHVyaVtwYXJ0c1tpXV0gPSBtW2ldIHx8ICcnO1xuICAgIH1cblxuICAgIGlmIChiICE9IC0xICYmIGUgIT0gLTEpIHtcbiAgICAgICAgdXJpLnNvdXJjZSA9IHNyYztcbiAgICAgICAgdXJpLmhvc3QgPSB1cmkuaG9zdC5zdWJzdHJpbmcoMSwgdXJpLmhvc3QubGVuZ3RoIC0gMSkucmVwbGFjZSgvOy9nLCAnOicpO1xuICAgICAgICB1cmkuYXV0aG9yaXR5ID0gdXJpLmF1dGhvcml0eS5yZXBsYWNlKCdbJywgJycpLnJlcGxhY2UoJ10nLCAnJykucmVwbGFjZSgvOy9nLCAnOicpO1xuICAgICAgICB1cmkuaXB2NnVyaSA9IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVyaTtcbn07XG4iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgZ2xvYmFsID0gKGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSkoKTtcblxuLyoqXG4gKiBXZWJTb2NrZXQgY29uc3RydWN0b3IuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldCA/IHdzIDogbnVsbDtcblxuLyoqXG4gKiBXZWJTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogVGhlIHRoaXJkIGBvcHRzYCBvcHRpb25zIG9iamVjdCBnZXRzIGlnbm9yZWQgaW4gd2ViIGJyb3dzZXJzLCBzaW5jZSBpdCdzXG4gKiBub24tc3RhbmRhcmQsIGFuZCB0aHJvd3MgYSBUeXBlRXJyb3IgaWYgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAqIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2VpbmFyb3Mvd3MvaXNzdWVzLzIyN1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmlcbiAqIEBwYXJhbSB7QXJyYXl9IHByb3RvY29scyAob3B0aW9uYWwpXG4gKiBAcGFyYW0ge09iamVjdCkgb3B0cyAob3B0aW9uYWwpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHdzKHVyaSwgcHJvdG9jb2xzLCBvcHRzKSB7XG4gIHZhciBpbnN0YW5jZTtcbiAgaWYgKHByb3RvY29scykge1xuICAgIGluc3RhbmNlID0gbmV3IFdlYlNvY2tldCh1cmksIHByb3RvY29scyk7XG4gIH0gZWxzZSB7XG4gICAgaW5zdGFuY2UgPSBuZXcgV2ViU29ja2V0KHVyaSk7XG4gIH1cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuXG5pZiAoV2ViU29ja2V0KSB3cy5wcm90b3R5cGUgPSBXZWJTb2NrZXQucHJvdG90eXBlO1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307XG4vKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc0JpbmFyeTtcblxuLyoqXG4gKiBDaGVja3MgZm9yIGJpbmFyeSBkYXRhLlxuICpcbiAqIFJpZ2h0IG5vdyBvbmx5IEJ1ZmZlciBhbmQgQXJyYXlCdWZmZXIgYXJlIHN1cHBvcnRlZC4uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFueXRoaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGhhc0JpbmFyeShkYXRhKSB7XG5cbiAgZnVuY3Rpb24gX2hhc0JpbmFyeShvYmopIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCAoZ2xvYmFsLkJ1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fFxuICAgICAgICAgKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgICAoZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSlcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChfaGFzQmluYXJ5KG9ialtpXSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2JqICYmICdvYmplY3QnID09IHR5cGVvZiBvYmopIHtcbiAgICAgIGlmIChvYmoudG9KU09OKSB7XG4gICAgICAgIG9iaiA9IG9iai50b0pTT04oKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkgJiYgX2hhc0JpbmFyeShvYmpba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBfaGFzQmluYXJ5KGRhdGEpO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIlxuLyoqXG4gKiBIT1AgcmVmLlxuICovXG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFJldHVybiBvd24ga2V5cyBpbiBgb2JqYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ob2JqKXtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ga2V5cztcbn07XG5cbi8qKlxuICogUmV0dXJuIG93biB2YWx1ZXMgaW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudmFsdWVzID0gZnVuY3Rpb24ob2JqKXtcbiAgdmFyIHZhbHMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIHZhbHMucHVzaChvYmpba2V5XSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWxzO1xufTtcblxuLyoqXG4gKiBNZXJnZSBgYmAgaW50byBgYWAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBiXG4gKiBAcmV0dXJuIHtPYmplY3R9IGFcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5tZXJnZSA9IGZ1bmN0aW9uKGEsIGIpe1xuICBmb3IgKHZhciBrZXkgaW4gYikge1xuICAgIGlmIChoYXMuY2FsbChiLCBrZXkpKSB7XG4gICAgICBhW2tleV0gPSBiW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBhO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gbGVuZ3RoIG9mIGBvYmpgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5sZW5ndGggPSBmdW5jdGlvbihvYmope1xuICByZXR1cm4gZXhwb3J0cy5rZXlzKG9iaikubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBlbXB0eS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmlzRW1wdHkgPSBmdW5jdGlvbihvYmope1xuICByZXR1cm4gMCA9PSBleHBvcnRzLmxlbmd0aChvYmopO1xufTsiLCIvKipcbiAqIFBhcnNlcyBhbiBVUklcbiAqXG4gKiBAYXV0aG9yIFN0ZXZlbiBMZXZpdGhhbiA8c3RldmVubGV2aXRoYW4uY29tPiAoTUlUIGxpY2Vuc2UpXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcmUgPSAvXig/Oig/IVteOkBdKzpbXjpAXFwvXSpAKShodHRwfGh0dHBzfHdzfHdzcyk6XFwvXFwvKT8oKD86KChbXjpAXSopKD86OihbXjpAXSopKT8pP0ApPygoPzpbYS1mMC05XXswLDR9Oil7Miw3fVthLWYwLTldezAsNH18W146XFwvPyNdKikoPzo6KFxcZCopKT8pKCgoXFwvKD86W14/I10oPyFbXj8jXFwvXSpcXC5bXj8jXFwvLl0rKD86Wz8jXXwkKSkpKlxcLz8pPyhbXj8jXFwvXSopKSg/OlxcPyhbXiNdKikpPyg/OiMoLiopKT8pLztcblxudmFyIHBhcnRzID0gW1xuICAgICdzb3VyY2UnLCAncHJvdG9jb2wnLCAnYXV0aG9yaXR5JywgJ3VzZXJJbmZvJywgJ3VzZXInLCAncGFzc3dvcmQnLCAnaG9zdCdcbiAgLCAncG9ydCcsICdyZWxhdGl2ZScsICdwYXRoJywgJ2RpcmVjdG9yeScsICdmaWxlJywgJ3F1ZXJ5JywgJ2FuY2hvcidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2V1cmkoc3RyKSB7XG4gIHZhciBtID0gcmUuZXhlYyhzdHIgfHwgJycpXG4gICAgLCB1cmkgPSB7fVxuICAgICwgaSA9IDE0O1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICB1cmlbcGFydHNbaV1dID0gbVtpXSB8fCAnJztcbiAgfVxuXG4gIHJldHVybiB1cmk7XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LypnbG9iYWwgQmxvYixGaWxlKi9cblxuLyoqXG4gKiBNb2R1bGUgcmVxdWlyZW1lbnRzXG4gKi9cblxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG52YXIgaXNCdWYgPSByZXF1aXJlKCcuL2lzLWJ1ZmZlcicpO1xuXG4vKipcbiAqIFJlcGxhY2VzIGV2ZXJ5IEJ1ZmZlciB8IEFycmF5QnVmZmVyIGluIHBhY2tldCB3aXRoIGEgbnVtYmVyZWQgcGxhY2Vob2xkZXIuXG4gKiBBbnl0aGluZyB3aXRoIGJsb2JzIG9yIGZpbGVzIHNob3VsZCBiZSBmZWQgdGhyb3VnaCByZW1vdmVCbG9icyBiZWZvcmUgY29taW5nXG4gKiBoZXJlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBzb2NrZXQuaW8gZXZlbnQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggZGVjb25zdHJ1Y3RlZCBwYWNrZXQgYW5kIGxpc3Qgb2YgYnVmZmVyc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmRlY29uc3RydWN0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgdmFyIHBhY2tldERhdGEgPSBwYWNrZXQuZGF0YTtcblxuICBmdW5jdGlvbiBfZGVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmICghZGF0YSkgcmV0dXJuIGRhdGE7XG5cbiAgICBpZiAoaXNCdWYoZGF0YSkpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHsgX3BsYWNlaG9sZGVyOiB0cnVlLCBudW06IGJ1ZmZlcnMubGVuZ3RoIH07XG4gICAgICBidWZmZXJzLnB1c2goZGF0YSk7XG4gICAgICByZXR1cm4gcGxhY2Vob2xkZXI7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICB2YXIgbmV3RGF0YSA9IG5ldyBBcnJheShkYXRhLmxlbmd0aCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbmV3RGF0YVtpXSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXdEYXRhO1xuICAgIH0gZWxzZSBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIGRhdGEgJiYgIShkYXRhIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0ge307XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBuZXdEYXRhW2tleV0gPSBfZGVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXdEYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHZhciBwYWNrID0gcGFja2V0O1xuICBwYWNrLmRhdGEgPSBfZGVjb25zdHJ1Y3RQYWNrZXQocGFja2V0RGF0YSk7XG4gIHBhY2suYXR0YWNobWVudHMgPSBidWZmZXJzLmxlbmd0aDsgLy8gbnVtYmVyIG9mIGJpbmFyeSAnYXR0YWNobWVudHMnXG4gIHJldHVybiB7cGFja2V0OiBwYWNrLCBidWZmZXJzOiBidWZmZXJzfTtcbn07XG5cbi8qKlxuICogUmVjb25zdHJ1Y3RzIGEgYmluYXJ5IHBhY2tldCBmcm9tIGl0cyBwbGFjZWhvbGRlciBwYWNrZXQgYW5kIGJ1ZmZlcnNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0IC0gZXZlbnQgcGFja2V0IHdpdGggcGxhY2Vob2xkZXJzXG4gKiBAcGFyYW0ge0FycmF5fSBidWZmZXJzIC0gYmluYXJ5IGJ1ZmZlcnMgdG8gcHV0IGluIHBsYWNlaG9sZGVyIHBvc2l0aW9uc1xuICogQHJldHVybiB7T2JqZWN0fSByZWNvbnN0cnVjdGVkIHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnJlY29uc3RydWN0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0LCBidWZmZXJzKSB7XG4gIHZhciBjdXJQbGFjZUhvbGRlciA9IDA7XG5cbiAgZnVuY3Rpb24gX3JlY29uc3RydWN0UGFja2V0KGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLl9wbGFjZWhvbGRlcikge1xuICAgICAgdmFyIGJ1ZiA9IGJ1ZmZlcnNbZGF0YS5udW1dOyAvLyBhcHByb3ByaWF0ZSBidWZmZXIgKHNob3VsZCBiZSBuYXR1cmFsIG9yZGVyIGFueXdheSlcbiAgICAgIHJldHVybiBidWY7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZGF0YVtpXSA9IF9yZWNvbnN0cnVjdFBhY2tldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0gZWxzZSBpZiAoZGF0YSAmJiAnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSkge1xuICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgICAgZGF0YVtrZXldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFba2V5XSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwYWNrZXQuZGF0YSA9IF9yZWNvbnN0cnVjdFBhY2tldChwYWNrZXQuZGF0YSk7XG4gIHBhY2tldC5hdHRhY2htZW50cyA9IHVuZGVmaW5lZDsgLy8gbm8gbG9uZ2VyIHVzZWZ1bFxuICByZXR1cm4gcGFja2V0O1xufTtcblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSByZW1vdmVzIEJsb2JzIG9yIEZpbGVzIGZyb20gZGF0YSB2aWFcbiAqIEZpbGVSZWFkZXIncyByZWFkQXNBcnJheUJ1ZmZlciBtZXRob2QuIFVzZWQgYmVmb3JlIGVuY29kaW5nXG4gKiBkYXRhIGFzIG1zZ3BhY2suIENhbGxzIGNhbGxiYWNrIHdpdGggdGhlIGJsb2JsZXNzIGRhdGEuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLnJlbW92ZUJsb2JzID0gZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gX3JlbW92ZUJsb2JzKG9iaiwgY3VyS2V5LCBjb250YWluaW5nT2JqZWN0KSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBvYmo7XG5cbiAgICAvLyBjb252ZXJ0IGFueSBibG9iXG4gICAgaWYgKChnbG9iYWwuQmxvYiAmJiBvYmogaW5zdGFuY2VvZiBCbG9iKSB8fFxuICAgICAgICAoZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSkpIHtcbiAgICAgIHBlbmRpbmdCbG9icysrO1xuXG4gICAgICAvLyBhc3luYyBmaWxlcmVhZGVyXG4gICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkgeyAvLyB0aGlzLnJlc3VsdCA9PSBhcnJheWJ1ZmZlclxuICAgICAgICBpZiAoY29udGFpbmluZ09iamVjdCkge1xuICAgICAgICAgIGNvbnRhaW5pbmdPYmplY3RbY3VyS2V5XSA9IHRoaXMucmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGJsb2JsZXNzRGF0YSA9IHRoaXMucmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm90aGluZyBwZW5kaW5nIGl0cyBjYWxsYmFjayB0aW1lXG4gICAgICAgIGlmKCEgLS1wZW5kaW5nQmxvYnMpIHtcbiAgICAgICAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKG9iaik7IC8vIGJsb2IgLT4gYXJyYXlidWZmZXJcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqKSkgeyAvLyBoYW5kbGUgYXJyYXlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIF9yZW1vdmVCbG9icyhvYmpbaV0sIGksIG9iaik7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvYmogJiYgJ29iamVjdCcgPT0gdHlwZW9mIG9iaiAmJiAhaXNCdWYob2JqKSkgeyAvLyBhbmQgb2JqZWN0XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIF9yZW1vdmVCbG9icyhvYmpba2V5XSwga2V5LCBvYmopO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBwZW5kaW5nQmxvYnMgPSAwO1xuICB2YXIgYmxvYmxlc3NEYXRhID0gZGF0YTtcbiAgX3JlbW92ZUJsb2JzKGJsb2JsZXNzRGF0YSk7XG4gIGlmICghcGVuZGluZ0Jsb2JzKSB7XG4gICAgY2FsbGJhY2soYmxvYmxlc3NEYXRhKTtcbiAgfVxufTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIGJpbmFyeSA9IHJlcXVpcmUoJy4vYmluYXJ5Jyk7XG52YXIgaXNCdWYgPSByZXF1aXJlKCcuL2lzLWJ1ZmZlcicpO1xuXG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gNDtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZXMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnR5cGVzID0gW1xuICAnQ09OTkVDVCcsXG4gICdESVNDT05ORUNUJyxcbiAgJ0VWRU5UJyxcbiAgJ0JJTkFSWV9FVkVOVCcsXG4gICdBQ0snLFxuICAnQklOQVJZX0FDSycsXG4gICdFUlJPUidcbl07XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGNvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5DT05ORUNUID0gMDtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZGlzY29ubmVjdGAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRJU0NPTk5FQ1QgPSAxO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBldmVudGAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVWRU5UID0gMjtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgYWNrYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQUNLID0gMztcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXJyb3JgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FUlJPUiA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgJ2JpbmFyeSBldmVudCdcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQklOQVJZX0VWRU5UID0gNTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgYmluYXJ5IGFja2AuIEZvciBhY2tzIHdpdGggYmluYXJ5IGFyZ3VtZW50cy5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQklOQVJZX0FDSyA9IDY7XG5cbi8qKlxuICogRW5jb2RlciBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRW5jb2RlciA9IEVuY29kZXI7XG5cbi8qKlxuICogRGVjb2RlciBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRGVjb2RlciA9IERlY29kZXI7XG5cbi8qKlxuICogQSBzb2NrZXQuaW8gRW5jb2RlciBpbnN0YW5jZVxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW5jb2RlcigpIHt9XG5cbi8qKlxuICogRW5jb2RlIGEgcGFja2V0IGFzIGEgc2luZ2xlIHN0cmluZyBpZiBub24tYmluYXJ5LCBvciBhcyBhXG4gKiBidWZmZXIgc2VxdWVuY2UsIGRlcGVuZGluZyBvbiBwYWNrZXQgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIC0gcGFja2V0IG9iamVjdFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBmdW5jdGlvbiB0byBoYW5kbGUgZW5jb2RpbmdzIChsaWtlbHkgZW5naW5lLndyaXRlKVxuICogQHJldHVybiBDYWxscyBjYWxsYmFjayB3aXRoIEFycmF5IG9mIGVuY29kaW5nc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbihvYmosIGNhbGxiYWNrKXtcbiAgZGVidWcoJ2VuY29kaW5nIHBhY2tldCAlaicsIG9iaik7XG5cbiAgaWYgKGV4cG9ydHMuQklOQVJZX0VWRU5UID09IG9iai50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBvYmoudHlwZSkge1xuICAgIGVuY29kZUFzQmluYXJ5KG9iaiwgY2FsbGJhY2spO1xuICB9XG4gIGVsc2Uge1xuICAgIHZhciBlbmNvZGluZyA9IGVuY29kZUFzU3RyaW5nKG9iaik7XG4gICAgY2FsbGJhY2soW2VuY29kaW5nXSk7XG4gIH1cbn07XG5cbi8qKlxuICogRW5jb2RlIHBhY2tldCBhcyBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7U3RyaW5nfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc1N0cmluZyhvYmopIHtcbiAgdmFyIHN0ciA9ICcnO1xuICB2YXIgbnNwID0gZmFsc2U7XG5cbiAgLy8gZmlyc3QgaXMgdHlwZVxuICBzdHIgKz0gb2JqLnR5cGU7XG5cbiAgLy8gYXR0YWNobWVudHMgaWYgd2UgaGF2ZSB0aGVtXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBzdHIgKz0gb2JqLmF0dGFjaG1lbnRzO1xuICAgIHN0ciArPSAnLSc7XG4gIH1cblxuICAvLyBpZiB3ZSBoYXZlIGEgbmFtZXNwYWNlIG90aGVyIHRoYW4gYC9gXG4gIC8vIHdlIGFwcGVuZCBpdCBmb2xsb3dlZCBieSBhIGNvbW1hIGAsYFxuICBpZiAob2JqLm5zcCAmJiAnLycgIT0gb2JqLm5zcCkge1xuICAgIG5zcCA9IHRydWU7XG4gICAgc3RyICs9IG9iai5uc3A7XG4gIH1cblxuICAvLyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSB0aGUgaWRcbiAgaWYgKG51bGwgIT0gb2JqLmlkKSB7XG4gICAgaWYgKG5zcCkge1xuICAgICAgc3RyICs9ICcsJztcbiAgICAgIG5zcCA9IGZhbHNlO1xuICAgIH1cbiAgICBzdHIgKz0gb2JqLmlkO1xuICB9XG5cbiAgLy8ganNvbiBkYXRhXG4gIGlmIChudWxsICE9IG9iai5kYXRhKSB7XG4gICAgaWYgKG5zcCkgc3RyICs9ICcsJztcbiAgICBzdHIgKz0ganNvbi5zdHJpbmdpZnkob2JqLmRhdGEpO1xuICB9XG5cbiAgZGVidWcoJ2VuY29kZWQgJWogYXMgJXMnLCBvYmosIHN0cik7XG4gIHJldHVybiBzdHI7XG59XG5cbi8qKlxuICogRW5jb2RlIHBhY2tldCBhcyAnYnVmZmVyIHNlcXVlbmNlJyBieSByZW1vdmluZyBibG9icywgYW5kXG4gKiBkZWNvbnN0cnVjdGluZyBwYWNrZXQgaW50byBvYmplY3Qgd2l0aCBwbGFjZWhvbGRlcnMgYW5kXG4gKiBhIGxpc3Qgb2YgYnVmZmVycy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAcmV0dXJuIHtCdWZmZXJ9IGVuY29kZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFzQmluYXJ5KG9iaiwgY2FsbGJhY2spIHtcblxuICBmdW5jdGlvbiB3cml0ZUVuY29kaW5nKGJsb2JsZXNzRGF0YSkge1xuICAgIHZhciBkZWNvbnN0cnVjdGlvbiA9IGJpbmFyeS5kZWNvbnN0cnVjdFBhY2tldChibG9ibGVzc0RhdGEpO1xuICAgIHZhciBwYWNrID0gZW5jb2RlQXNTdHJpbmcoZGVjb25zdHJ1Y3Rpb24ucGFja2V0KTtcbiAgICB2YXIgYnVmZmVycyA9IGRlY29uc3RydWN0aW9uLmJ1ZmZlcnM7XG5cbiAgICBidWZmZXJzLnVuc2hpZnQocGFjayk7IC8vIGFkZCBwYWNrZXQgaW5mbyB0byBiZWdpbm5pbmcgb2YgZGF0YSBsaXN0XG4gICAgY2FsbGJhY2soYnVmZmVycyk7IC8vIHdyaXRlIGFsbCB0aGUgYnVmZmVyc1xuICB9XG5cbiAgYmluYXJ5LnJlbW92ZUJsb2JzKG9iaiwgd3JpdGVFbmNvZGluZyk7XG59XG5cbi8qKlxuICogQSBzb2NrZXQuaW8gRGVjb2RlciBpbnN0YW5jZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZGVjb2RlclxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBEZWNvZGVyKCkge1xuICB0aGlzLnJlY29uc3RydWN0b3IgPSBudWxsO1xufVxuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAgd2l0aCBEZWNvZGVyLlxuICovXG5cbkVtaXR0ZXIoRGVjb2Rlci5wcm90b3R5cGUpO1xuXG4vKipcbiAqIERlY29kZXMgYW4gZWNvZGVkIHBhY2tldCBzdHJpbmcgaW50byBwYWNrZXQgSlNPTi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gb2JqIC0gZW5jb2RlZCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKG9iaikge1xuICB2YXIgcGFja2V0O1xuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIG9iaikge1xuICAgIHBhY2tldCA9IGRlY29kZVN0cmluZyhvYmopO1xuICAgIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwYWNrZXQudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gcGFja2V0LnR5cGUpIHsgLy8gYmluYXJ5IHBhY2tldCdzIGpzb25cbiAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG5ldyBCaW5hcnlSZWNvbnN0cnVjdG9yKHBhY2tldCk7XG5cbiAgICAgIC8vIG5vIGF0dGFjaG1lbnRzLCBsYWJlbGVkIGJpbmFyeSBidXQgbm8gYmluYXJ5IGRhdGEgdG8gZm9sbG93XG4gICAgICBpZiAodGhpcy5yZWNvbnN0cnVjdG9yLnJlY29uUGFjay5hdHRhY2htZW50cyA9PSAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHsgLy8gbm9uLWJpbmFyeSBmdWxsIHBhY2tldFxuICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoaXNCdWYob2JqKSB8fCBvYmouYmFzZTY0KSB7IC8vIHJhdyBiaW5hcnkgZGF0YVxuICAgIGlmICghdGhpcy5yZWNvbnN0cnVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dvdCBiaW5hcnkgZGF0YSB3aGVuIG5vdCByZWNvbnN0cnVjdGluZyBhIHBhY2tldCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWNrZXQgPSB0aGlzLnJlY29uc3RydWN0b3IudGFrZUJpbmFyeURhdGEob2JqKTtcbiAgICAgIGlmIChwYWNrZXQpIHsgLy8gcmVjZWl2ZWQgZmluYWwgYnVmZmVyXG4gICAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biB0eXBlOiAnICsgb2JqKTtcbiAgfVxufTtcblxuLyoqXG4gKiBEZWNvZGUgYSBwYWNrZXQgU3RyaW5nIChKU09OIGRhdGEpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGRlY29kZVN0cmluZyhzdHIpIHtcbiAgdmFyIHAgPSB7fTtcbiAgdmFyIGkgPSAwO1xuXG4gIC8vIGxvb2sgdXAgdHlwZVxuICBwLnR5cGUgPSBOdW1iZXIoc3RyLmNoYXJBdCgwKSk7XG4gIGlmIChudWxsID09IGV4cG9ydHMudHlwZXNbcC50eXBlXSkgcmV0dXJuIGVycm9yKCk7XG5cbiAgLy8gbG9vayB1cCBhdHRhY2htZW50cyBpZiB0eXBlIGJpbmFyeVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcC50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBwLnR5cGUpIHtcbiAgICBwLmF0dGFjaG1lbnRzID0gJyc7XG4gICAgd2hpbGUgKHN0ci5jaGFyQXQoKytpKSAhPSAnLScpIHtcbiAgICAgIHAuYXR0YWNobWVudHMgKz0gc3RyLmNoYXJBdChpKTtcbiAgICB9XG4gICAgcC5hdHRhY2htZW50cyA9IE51bWJlcihwLmF0dGFjaG1lbnRzKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgKyAxID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBwLm5zcCA9ICcvJztcbiAgfVxuXG4gIC8vIGxvb2sgdXAgaWRcbiAgdmFyIG5leHQgPSBzdHIuY2hhckF0KGkgKyAxKTtcbiAgaWYgKCcnICE9IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgKyAxID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgICBwLmlkID0gTnVtYmVyKHAuaWQpO1xuICB9XG5cbiAgLy8gbG9vayB1cCBqc29uIGRhdGFcbiAgaWYgKHN0ci5jaGFyQXQoKytpKSkge1xuICAgIHRyeSB7XG4gICAgICBwLmRhdGEgPSBqc29uLnBhcnNlKHN0ci5zdWJzdHIoaSkpO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICByZXR1cm4gZXJyb3IoKTtcbiAgICB9XG4gIH1cblxuICBkZWJ1ZygnZGVjb2RlZCAlcyBhcyAlaicsIHN0ciwgcCk7XG4gIHJldHVybiBwO1xufVxuXG4vKipcbiAqIERlYWxsb2NhdGVzIGEgcGFyc2VyJ3MgcmVzb3VyY2VzXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICB0aGlzLnJlY29uc3RydWN0b3IuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICB9XG59O1xuXG4vKipcbiAqIEEgbWFuYWdlciBvZiBhIGJpbmFyeSBldmVudCdzICdidWZmZXIgc2VxdWVuY2UnLiBTaG91bGRcbiAqIGJlIGNvbnN0cnVjdGVkIHdoZW5ldmVyIGEgcGFja2V0IG9mIHR5cGUgQklOQVJZX0VWRU5UIGlzXG4gKiBkZWNvZGVkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge0JpbmFyeVJlY29uc3RydWN0b3J9IGluaXRpYWxpemVkIHJlY29uc3RydWN0b3JcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIEJpbmFyeVJlY29uc3RydWN0b3IocGFja2V0KSB7XG4gIHRoaXMucmVjb25QYWNrID0gcGFja2V0O1xuICB0aGlzLmJ1ZmZlcnMgPSBbXTtcbn1cblxuLyoqXG4gKiBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYmluYXJ5IGRhdGEgcmVjZWl2ZWQgZnJvbSBjb25uZWN0aW9uXG4gKiBhZnRlciBhIEJJTkFSWV9FVkVOVCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtCdWZmZXIgfCBBcnJheUJ1ZmZlcn0gYmluRGF0YSAtIHRoZSByYXcgYmluYXJ5IGRhdGEgcmVjZWl2ZWRcbiAqIEByZXR1cm4ge251bGwgfCBPYmplY3R9IHJldHVybnMgbnVsbCBpZiBtb3JlIGJpbmFyeSBkYXRhIGlzIGV4cGVjdGVkIG9yXG4gKiAgIGEgcmVjb25zdHJ1Y3RlZCBwYWNrZXQgb2JqZWN0IGlmIGFsbCBidWZmZXJzIGhhdmUgYmVlbiByZWNlaXZlZC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkJpbmFyeVJlY29uc3RydWN0b3IucHJvdG90eXBlLnRha2VCaW5hcnlEYXRhID0gZnVuY3Rpb24oYmluRGF0YSkge1xuICB0aGlzLmJ1ZmZlcnMucHVzaChiaW5EYXRhKTtcbiAgaWYgKHRoaXMuYnVmZmVycy5sZW5ndGggPT0gdGhpcy5yZWNvblBhY2suYXR0YWNobWVudHMpIHsgLy8gZG9uZSB3aXRoIGJ1ZmZlciBsaXN0XG4gICAgdmFyIHBhY2tldCA9IGJpbmFyeS5yZWNvbnN0cnVjdFBhY2tldCh0aGlzLnJlY29uUGFjaywgdGhpcy5idWZmZXJzKTtcbiAgICB0aGlzLmZpbmlzaGVkUmVjb25zdHJ1Y3Rpb24oKTtcbiAgICByZXR1cm4gcGFja2V0O1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgYmluYXJ5IHBhY2tldCByZWNvbnN0cnVjdGlvbiB2YXJpYWJsZXMuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUuZmluaXNoZWRSZWNvbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnJlY29uUGFjayA9IG51bGw7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufTtcblxuZnVuY3Rpb24gZXJyb3IoZGF0YSl7XG4gIHJldHVybiB7XG4gICAgdHlwZTogZXhwb3J0cy5FUlJPUixcbiAgICBkYXRhOiAncGFyc2VyIGVycm9yJ1xuICB9O1xufVxuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307XG5tb2R1bGUuZXhwb3J0cyA9IGlzQnVmO1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBvYmogaXMgYSBidWZmZXIgb3IgYW4gYXJyYXlidWZmZXIuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNCdWYob2JqKSB7XG4gIHJldHVybiAoZ2xvYmFsLkJ1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcbn1cbiIsIi8qISBKU09OIHYzLjIuNiB8IGh0dHA6Ly9iZXN0aWVqcy5naXRodWIuaW8vanNvbjMgfCBDb3B5cmlnaHQgMjAxMi0yMDEzLCBLaXQgQ2FtYnJpZGdlIHwgaHR0cDovL2tpdC5taXQtbGljZW5zZS5vcmcgKi9cbjsoZnVuY3Rpb24gKHdpbmRvdykge1xuICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLlxuICB2YXIgZ2V0Q2xhc3MgPSB7fS50b1N0cmluZywgaXNQcm9wZXJ0eSwgZm9yRWFjaCwgdW5kZWY7XG5cbiAgLy8gRGV0ZWN0IHRoZSBgZGVmaW5lYCBmdW5jdGlvbiBleHBvc2VkIGJ5IGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy4gVGhlXG4gIC8vIHN0cmljdCBgZGVmaW5lYCBjaGVjayBpcyBuZWNlc3NhcnkgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBgci5qc2AuXG4gIHZhciBpc0xvYWRlciA9IHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kO1xuXG4gIC8vIERldGVjdCBuYXRpdmUgaW1wbGVtZW50YXRpb25zLlxuICB2YXIgbmF0aXZlSlNPTiA9IHR5cGVvZiBKU09OID09IFwib2JqZWN0XCIgJiYgSlNPTjtcblxuICAvLyBTZXQgdXAgdGhlIEpTT04gMyBuYW1lc3BhY2UsIHByZWZlcnJpbmcgdGhlIENvbW1vbkpTIGBleHBvcnRzYCBvYmplY3QgaWZcbiAgLy8gYXZhaWxhYmxlLlxuICB2YXIgSlNPTjMgPSB0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuICBpZiAoSlNPTjMgJiYgbmF0aXZlSlNPTikge1xuICAgIC8vIEV4cGxpY2l0bHkgZGVsZWdhdGUgdG8gdGhlIG5hdGl2ZSBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAgIC8vIGltcGxlbWVudGF0aW9ucyBpbiBDb21tb25KUyBlbnZpcm9ubWVudHMuXG4gICAgSlNPTjMuc3RyaW5naWZ5ID0gbmF0aXZlSlNPTi5zdHJpbmdpZnk7XG4gICAgSlNPTjMucGFyc2UgPSBuYXRpdmVKU09OLnBhcnNlO1xuICB9IGVsc2Uge1xuICAgIC8vIEV4cG9ydCBmb3Igd2ViIGJyb3dzZXJzLCBKYXZhU2NyaXB0IGVuZ2luZXMsIGFuZCBhc3luY2hyb25vdXMgbW9kdWxlXG4gICAgLy8gbG9hZGVycywgdXNpbmcgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGlmIGF2YWlsYWJsZS5cbiAgICBKU09OMyA9IHdpbmRvdy5KU09OID0gbmF0aXZlSlNPTiB8fCB7fTtcbiAgfVxuXG4gIC8vIFRlc3QgdGhlIGBEYXRlI2dldFVUQypgIG1ldGhvZHMuIEJhc2VkIG9uIHdvcmsgYnkgQFlhZmZsZS5cbiAgdmFyIGlzRXh0ZW5kZWQgPSBuZXcgRGF0ZSgtMzUwOTgyNzMzNDU3MzI5Mik7XG4gIHRyeSB7XG4gICAgLy8gVGhlIGBnZXRVVENGdWxsWWVhcmAsIGBNb250aGAsIGFuZCBgRGF0ZWAgbWV0aG9kcyByZXR1cm4gbm9uc2Vuc2ljYWxcbiAgICAvLyByZXN1bHRzIGZvciBjZXJ0YWluIGRhdGVzIGluIE9wZXJhID49IDEwLjUzLlxuICAgIGlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkLmdldFVUQ0Z1bGxZZWFyKCkgPT0gLTEwOTI1MiAmJiBpc0V4dGVuZGVkLmdldFVUQ01vbnRoKCkgPT09IDAgJiYgaXNFeHRlbmRlZC5nZXRVVENEYXRlKCkgPT09IDEgJiZcbiAgICAgIC8vIFNhZmFyaSA8IDIuMC4yIHN0b3JlcyB0aGUgaW50ZXJuYWwgbWlsbGlzZWNvbmQgdGltZSB2YWx1ZSBjb3JyZWN0bHksXG4gICAgICAvLyBidXQgY2xpcHMgdGhlIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgZGF0ZSBtZXRob2RzIHRvIHRoZSByYW5nZSBvZlxuICAgICAgLy8gc2lnbmVkIDMyLWJpdCBpbnRlZ2VycyAoWy0yICoqIDMxLCAyICoqIDMxIC0gMV0pLlxuICAgICAgaXNFeHRlbmRlZC5nZXRVVENIb3VycygpID09IDEwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWludXRlcygpID09IDM3ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDU2Vjb25kcygpID09IDYgJiYgaXNFeHRlbmRlZC5nZXRVVENNaWxsaXNlY29uZHMoKSA9PSA3MDg7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cblxuICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBuYXRpdmUgYEpTT04uc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAvLyBpbXBsZW1lbnRhdGlvbnMgYXJlIHNwZWMtY29tcGxpYW50LiBCYXNlZCBvbiB3b3JrIGJ5IEtlbiBTbnlkZXIuXG4gIGZ1bmN0aW9uIGhhcyhuYW1lKSB7XG4gICAgaWYgKGhhc1tuYW1lXSAhPT0gdW5kZWYpIHtcbiAgICAgIC8vIFJldHVybiBjYWNoZWQgZmVhdHVyZSB0ZXN0IHJlc3VsdC5cbiAgICAgIHJldHVybiBoYXNbbmFtZV07XG4gICAgfVxuXG4gICAgdmFyIGlzU3VwcG9ydGVkO1xuICAgIGlmIChuYW1lID09IFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpIHtcbiAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmVcbiAgICAgIC8vIGJyYWNrZXQgbm90YXRpb24uIElFIDggb25seSBzdXBwb3J0cyB0aGlzIGZvciBwcmltaXRpdmVzLlxuICAgICAgaXNTdXBwb3J0ZWQgPSBcImFcIlswXSAhPSBcImFcIjtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT0gXCJqc29uXCIpIHtcbiAgICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGJvdGggYEpTT04uc3RyaW5naWZ5YCBhbmQgYEpTT04ucGFyc2VgIGFyZVxuICAgICAgLy8gc3VwcG9ydGVkLlxuICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSAmJiBoYXMoXCJqc29uLXBhcnNlXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdmFsdWUsIHNlcmlhbGl6ZWQgPSAne1wiYVwiOlsxLHRydWUsZmFsc2UsbnVsbCxcIlxcXFx1MDAwMFxcXFxiXFxcXG5cXFxcZlxcXFxyXFxcXHRcIl19JztcbiAgICAgIC8vIFRlc3QgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgIGlmIChuYW1lID09IFwianNvbi1zdHJpbmdpZnlcIikge1xuICAgICAgICB2YXIgc3RyaW5naWZ5ID0gSlNPTjMuc3RyaW5naWZ5LCBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09IFwiZnVuY3Rpb25cIiAmJiBpc0V4dGVuZGVkO1xuICAgICAgICBpZiAoc3RyaW5naWZ5U3VwcG9ydGVkKSB7XG4gICAgICAgICAgLy8gQSB0ZXN0IGZ1bmN0aW9uIG9iamVjdCB3aXRoIGEgY3VzdG9tIGB0b0pTT05gIG1ldGhvZC5cbiAgICAgICAgICAodmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KS50b0pTT04gPSB2YWx1ZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID1cbiAgICAgICAgICAgICAgLy8gRmlyZWZveCAzLjFiMSBhbmQgYjIgc2VyaWFsaXplIHN0cmluZywgbnVtYmVyLCBhbmQgYm9vbGVhblxuICAgICAgICAgICAgICAvLyBwcmltaXRpdmVzIGFzIG9iamVjdCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KDApID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIsIGFuZCBKU09OIDIgc2VyaWFsaXplIHdyYXBwZWQgcHJpbWl0aXZlcyBhcyBvYmplY3RcbiAgICAgICAgICAgICAgLy8gbGl0ZXJhbHMuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgTnVtYmVyKCkpID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IFN0cmluZygpKSA9PSAnXCJcIicgJiZcbiAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHZhbHVlIGlzIGBudWxsYCwgYHVuZGVmaW5lZGAsIG9yXG4gICAgICAgICAgICAgIC8vIGRvZXMgbm90IGRlZmluZSBhIGNhbm9uaWNhbCBKU09OIHJlcHJlc2VudGF0aW9uICh0aGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGB0b0pTT05gIHByb3BlcnRpZXMgYXMgd2VsbCwgKnVubGVzcyogdGhleSBhcmUgbmVzdGVkXG4gICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvYmplY3Qgb3IgYXJyYXkpLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkoZ2V0Q2xhc3MpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBJRSA4IHNlcmlhbGl6ZXMgYHVuZGVmaW5lZGAgYXMgYFwidW5kZWZpbmVkXCJgLiBTYWZhcmkgPD0gNS4xLjcgYW5kXG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIzIHBhc3MgdGhpcyB0ZXN0LlxuICAgICAgICAgICAgICBzdHJpbmdpZnkodW5kZWYpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjcgYW5kIEZGIDMuMWIzIHRocm93IGBFcnJvcmBzIGFuZCBgVHlwZUVycm9yYHMsXG4gICAgICAgICAgICAgIC8vIHJlc3BlY3RpdmVseSwgaWYgdGhlIHZhbHVlIGlzIG9taXR0ZWQgZW50aXJlbHkuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeSgpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgbm90IGEgbnVtYmVyLFxuICAgICAgICAgICAgICAvLyBzdHJpbmcsIGFycmF5LCBvYmplY3QsIEJvb2xlYW4sIG9yIGBudWxsYCBsaXRlcmFsLiBUaGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzIGFzIHdlbGwsIHVubGVzcyB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgLy8gaW5zaWRlIG9iamVjdCBvciBhcnJheSBsaXRlcmFscy4gWVVJIDMuMC4wYjEgaWdub3JlcyBjdXN0b20gYHRvSlNPTmBcbiAgICAgICAgICAgICAgLy8gbWV0aG9kcyBlbnRpcmVseS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt2YWx1ZV0pID09IFwiWzFdXCIgJiZcbiAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIHNlcmlhbGl6ZXMgYFt1bmRlZmluZWRdYCBhcyBgXCJbXVwiYCBpbnN0ZWFkIG9mXG4gICAgICAgICAgICAgIC8vIGBcIltudWxsXVwiYC5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZl0pID09IFwiW251bGxdXCIgJiZcbiAgICAgICAgICAgICAgLy8gWVVJIDMuMC4wYjEgZmFpbHMgdG8gc2VyaWFsaXplIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwpID09IFwibnVsbFwiICYmXG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIGhhbHRzIHNlcmlhbGl6YXRpb24gaWYgYW4gYXJyYXkgY29udGFpbnMgYSBmdW5jdGlvbjpcbiAgICAgICAgICAgICAgLy8gYFsxLCB0cnVlLCBnZXRDbGFzcywgMV1gIHNlcmlhbGl6ZXMgYXMgXCJbMSx0cnVlLF0sXCIuIEZGIDMuMWIzXG4gICAgICAgICAgICAgIC8vIGVsaWRlcyBub24tSlNPTiB2YWx1ZXMgZnJvbSBvYmplY3RzIGFuZCBhcnJheXMsIHVubGVzcyB0aGV5XG4gICAgICAgICAgICAgIC8vIGRlZmluZSBjdXN0b20gYHRvSlNPTmAgbWV0aG9kcy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZiwgZ2V0Q2xhc3MsIG51bGxdKSA9PSBcIltudWxsLG51bGwsbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAvLyBTaW1wbGUgc2VyaWFsaXphdGlvbiB0ZXN0LiBGRiAzLjFiMSB1c2VzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlc1xuICAgICAgICAgICAgICAvLyB3aGVyZSBjaGFyYWN0ZXIgZXNjYXBlIGNvZGVzIGFyZSBleHBlY3RlZCAoZS5nLiwgYFxcYmAgPT4gYFxcdTAwMDhgKS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KHsgXCJhXCI6IFt2YWx1ZSwgdHJ1ZSwgZmFsc2UsIG51bGwsIFwiXFx4MDBcXGJcXG5cXGZcXHJcXHRcIl0gfSkgPT0gc2VyaWFsaXplZCAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSBhbmQgYjIgaWdub3JlIHRoZSBgZmlsdGVyYCBhbmQgYHdpZHRoYCBhcmd1bWVudHMuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShudWxsLCB2YWx1ZSkgPT09IFwiMVwiICYmXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShbMSwgMl0sIG51bGwsIDEpID09IFwiW1xcbiAxLFxcbiAyXFxuXVwiICYmXG4gICAgICAgICAgICAgIC8vIEpTT04gMiwgUHJvdG90eXBlIDw9IDEuNywgYW5kIG9sZGVyIFdlYktpdCBidWlsZHMgaW5jb3JyZWN0bHlcbiAgICAgICAgICAgICAgLy8gc2VyaWFsaXplIGV4dGVuZGVkIHllYXJzLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTguNjRlMTUpKSA9PSAnXCItMjcxODIxLTA0LTIwVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgLy8gVGhlIG1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNSwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKDguNjRlMTUpKSA9PSAnXCIrMjc1NzYwLTA5LTEzVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgLy8gRmlyZWZveCA8PSAxMS4wIGluY29ycmVjdGx5IHNlcmlhbGl6ZXMgeWVhcnMgcHJpb3IgdG8gMCBhcyBuZWdhdGl2ZVxuICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IHllYXJzIGluc3RlYWQgb2Ygc2l4LWRpZ2l0IHllYXJzLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTYyMTk4NzU1MmU1KSkgPT0gJ1wiLTAwMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNSBhbmQgT3BlcmEgPj0gMTAuNTMgaW5jb3JyZWN0bHkgc2VyaWFsaXplIG1pbGxpc2Vjb25kXG4gICAgICAgICAgICAgIC8vIHZhbHVlcyBsZXNzIHRoYW4gMTAwMC4gQ3JlZGl0czogQFlhZmZsZS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC0xKSkgPT0gJ1wiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaXCInO1xuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlzU3VwcG9ydGVkID0gc3RyaW5naWZ5U3VwcG9ydGVkO1xuICAgICAgfVxuICAgICAgLy8gVGVzdCBgSlNPTi5wYXJzZWAuXG4gICAgICBpZiAobmFtZSA9PSBcImpzb24tcGFyc2VcIikge1xuICAgICAgICB2YXIgcGFyc2UgPSBKU09OMy5wYXJzZTtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJzZSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGEgYmFyZSBsaXRlcmFsIGlzIHByb3ZpZGVkLlxuICAgICAgICAgICAgLy8gQ29uZm9ybWluZyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGFsc28gY29lcmNlIHRoZSBpbml0aWFsIGFyZ3VtZW50IHRvXG4gICAgICAgICAgICAvLyBhIHN0cmluZyBwcmlvciB0byBwYXJzaW5nLlxuICAgICAgICAgICAgaWYgKHBhcnNlKFwiMFwiKSA9PT0gMCAmJiAhcGFyc2UoZmFsc2UpKSB7XG4gICAgICAgICAgICAgIC8vIFNpbXBsZSBwYXJzaW5nIHRlc3QuXG4gICAgICAgICAgICAgIHZhbHVlID0gcGFyc2Uoc2VyaWFsaXplZCk7XG4gICAgICAgICAgICAgIHZhciBwYXJzZVN1cHBvcnRlZCA9IHZhbHVlW1wiYVwiXS5sZW5ndGggPT0gNSAmJiB2YWx1ZVtcImFcIl1bMF0gPT09IDE7XG4gICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjIgYW5kIEZGIDMuMWIxIGFsbG93IHVuZXNjYXBlZCB0YWJzIGluIHN0cmluZ3MuXG4gICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9ICFwYXJzZSgnXCJcXHRcIicpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCBhbmQgNC4wLjEgYWxsb3cgbGVhZGluZyBgK2Agc2lnbnMgYW5kIGxlYWRpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gZGVjaW1hbCBwb2ludHMuIEZGIDQuMCwgNC4wLjEsIGFuZCBJRSA5LTEwIGFsc28gYWxsb3dcbiAgICAgICAgICAgICAgICAgICAgLy8gY2VydGFpbiBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjAxXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCwgNC4wLjEsIGFuZCBSaGlubyAxLjdSMy1SNCBhbGxvdyB0cmFpbGluZyBkZWNpbWFsXG4gICAgICAgICAgICAgICAgICAgIC8vIHBvaW50cy4gVGhlc2UgZW52aXJvbm1lbnRzLCBhbG9uZyB3aXRoIEZGIDMuMWIxIGFuZCAyLFxuICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGFsbG93IHRyYWlsaW5nIGNvbW1hcyBpbiBKU09OIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjEuXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaXNTdXBwb3J0ZWQgPSBwYXJzZVN1cHBvcnRlZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhhc1tuYW1lXSA9ICEhaXNTdXBwb3J0ZWQ7XG4gIH1cblxuICBpZiAoIWhhcyhcImpzb25cIikpIHtcbiAgICAvLyBDb21tb24gYFtbQ2xhc3NdXWAgbmFtZSBhbGlhc2VzLlxuICAgIHZhciBmdW5jdGlvbkNsYXNzID0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiO1xuICAgIHZhciBkYXRlQ2xhc3MgPSBcIltvYmplY3QgRGF0ZV1cIjtcbiAgICB2YXIgbnVtYmVyQ2xhc3MgPSBcIltvYmplY3QgTnVtYmVyXVwiO1xuICAgIHZhciBzdHJpbmdDbGFzcyA9IFwiW29iamVjdCBTdHJpbmddXCI7XG4gICAgdmFyIGFycmF5Q2xhc3MgPSBcIltvYmplY3QgQXJyYXldXCI7XG4gICAgdmFyIGJvb2xlYW5DbGFzcyA9IFwiW29iamVjdCBCb29sZWFuXVwiO1xuXG4gICAgLy8gRGV0ZWN0IGluY29tcGxldGUgc3VwcG9ydCBmb3IgYWNjZXNzaW5nIHN0cmluZyBjaGFyYWN0ZXJzIGJ5IGluZGV4LlxuICAgIHZhciBjaGFySW5kZXhCdWdneSA9IGhhcyhcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKTtcblxuICAgIC8vIERlZmluZSBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kcyBpZiB0aGUgYERhdGVgIG1ldGhvZHMgYXJlIGJ1Z2d5LlxuICAgIGlmICghaXNFeHRlbmRlZCkge1xuICAgICAgdmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbiAgICAgIC8vIEEgbWFwcGluZyBiZXR3ZWVuIHRoZSBtb250aHMgb2YgdGhlIHllYXIgYW5kIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuXG4gICAgICAvLyBKYW51YXJ5IDFzdCBhbmQgdGhlIGZpcnN0IG9mIHRoZSByZXNwZWN0aXZlIG1vbnRoLlxuICAgICAgdmFyIE1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNF07XG4gICAgICAvLyBJbnRlcm5hbDogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgVW5peCBlcG9jaCBhbmQgdGhlXG4gICAgICAvLyBmaXJzdCBkYXkgb2YgdGhlIGdpdmVuIG1vbnRoLlxuICAgICAgdmFyIGdldERheSA9IGZ1bmN0aW9uICh5ZWFyLCBtb250aCkge1xuICAgICAgICByZXR1cm4gTW9udGhzW21vbnRoXSArIDM2NSAqICh5ZWFyIC0gMTk3MCkgKyBmbG9vcigoeWVhciAtIDE5NjkgKyAobW9udGggPSArKG1vbnRoID4gMSkpKSAvIDQpIC0gZmxvb3IoKHllYXIgLSAxOTAxICsgbW9udGgpIC8gMTAwKSArIGZsb29yKCh5ZWFyIC0gMTYwMSArIG1vbnRoKSAvIDQwMCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIGlmIGEgcHJvcGVydHkgaXMgYSBkaXJlY3QgcHJvcGVydHkgb2YgdGhlIGdpdmVuXG4gICAgLy8gb2JqZWN0LiBEZWxlZ2F0ZXMgdG8gdGhlIG5hdGl2ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBtZXRob2QuXG4gICAgaWYgKCEoaXNQcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5KSkge1xuICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBjb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKChtZW1iZXJzLl9fcHJvdG9fXyA9IG51bGwsIG1lbWJlcnMuX19wcm90b19fID0ge1xuICAgICAgICAgIC8vIFRoZSAqcHJvdG8qIHByb3BlcnR5IGNhbm5vdCBiZSBzZXQgbXVsdGlwbGUgdGltZXMgaW4gcmVjZW50XG4gICAgICAgICAgLy8gdmVyc2lvbnMgb2YgRmlyZWZveCBhbmQgU2VhTW9ua2V5LlxuICAgICAgICAgIFwidG9TdHJpbmdcIjogMVxuICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykge1xuICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuMyBkb2Vzbid0IGltcGxlbWVudCBgT2JqZWN0I2hhc093blByb3BlcnR5YCwgYnV0XG4gICAgICAgICAgLy8gc3VwcG9ydHMgdGhlIG11dGFibGUgKnByb3RvKiBwcm9wZXJ0eS5cbiAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAvLyBDYXB0dXJlIGFuZCBicmVhayB0aGUgb2JqZWN0J3MgcHJvdG90eXBlIGNoYWluIChzZWUgc2VjdGlvbiA4LjYuMlxuICAgICAgICAgICAgLy8gb2YgdGhlIEVTIDUuMSBzcGVjKS4gVGhlIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBwcmV2ZW50cyBhblxuICAgICAgICAgICAgLy8gdW5zYWZlIHRyYW5zZm9ybWF0aW9uIGJ5IHRoZSBDbG9zdXJlIENvbXBpbGVyLlxuICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpcy5fX3Byb3RvX18sIHJlc3VsdCA9IHByb3BlcnR5IGluICh0aGlzLl9fcHJvdG9fXyA9IG51bGwsIHRoaXMpO1xuICAgICAgICAgICAgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBvcmlnaW5hbDtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBDYXB0dXJlIGEgcmVmZXJlbmNlIHRvIHRoZSB0b3AtbGV2ZWwgYE9iamVjdGAgY29uc3RydWN0b3IuXG4gICAgICAgICAgY29uc3RydWN0b3IgPSBtZW1iZXJzLmNvbnN0cnVjdG9yO1xuICAgICAgICAgIC8vIFVzZSB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSB0byBzaW11bGF0ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpblxuICAgICAgICAgIC8vIG90aGVyIGVudmlyb25tZW50cy5cbiAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTtcbiAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eSBpbiB0aGlzICYmICEocHJvcGVydHkgaW4gcGFyZW50ICYmIHRoaXNbcHJvcGVydHldID09PSBwYXJlbnRbcHJvcGVydHldKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIG1lbWJlcnMgPSBudWxsO1xuICAgICAgICByZXR1cm4gaXNQcm9wZXJ0eS5jYWxsKHRoaXMsIHByb3BlcnR5KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSW50ZXJuYWw6IEEgc2V0IG9mIHByaW1pdGl2ZSB0eXBlcyB1c2VkIGJ5IGBpc0hvc3RUeXBlYC5cbiAgICB2YXIgUHJpbWl0aXZlVHlwZXMgPSB7XG4gICAgICAnYm9vbGVhbic6IDEsXG4gICAgICAnbnVtYmVyJzogMSxcbiAgICAgICdzdHJpbmcnOiAxLFxuICAgICAgJ3VuZGVmaW5lZCc6IDFcbiAgICB9O1xuXG4gICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgdGhlIGdpdmVuIG9iamVjdCBgcHJvcGVydHlgIHZhbHVlIGlzIGFcbiAgICAvLyBub24tcHJpbWl0aXZlLlxuICAgIHZhciBpc0hvc3RUeXBlID0gZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV07XG4gICAgICByZXR1cm4gdHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6ICFQcmltaXRpdmVUeXBlc1t0eXBlXTtcbiAgICB9O1xuXG4gICAgLy8gSW50ZXJuYWw6IE5vcm1hbGl6ZXMgdGhlIGBmb3IuLi5pbmAgaXRlcmF0aW9uIGFsZ29yaXRobSBhY3Jvc3NcbiAgICAvLyBlbnZpcm9ubWVudHMuIEVhY2ggZW51bWVyYXRlZCBrZXkgaXMgeWllbGRlZCB0byBhIGBjYWxsYmFja2AgZnVuY3Rpb24uXG4gICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgc2l6ZSA9IDAsIFByb3BlcnRpZXMsIG1lbWJlcnMsIHByb3BlcnR5O1xuXG4gICAgICAvLyBUZXN0cyBmb3IgYnVncyBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCdzIGBmb3IuLi5pbmAgYWxnb3JpdGhtLiBUaGVcbiAgICAgIC8vIGB2YWx1ZU9mYCBwcm9wZXJ0eSBpbmhlcml0cyB0aGUgbm9uLWVudW1lcmFibGUgZmxhZyBmcm9tXG4gICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS5cbiAgICAgIChQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnZhbHVlT2YgPSAwO1xuICAgICAgfSkucHJvdG90eXBlLnZhbHVlT2YgPSAwO1xuXG4gICAgICAvLyBJdGVyYXRlIG92ZXIgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGBQcm9wZXJ0aWVzYCBjbGFzcy5cbiAgICAgIG1lbWJlcnMgPSBuZXcgUHJvcGVydGllcygpO1xuICAgICAgZm9yIChwcm9wZXJ0eSBpbiBtZW1iZXJzKSB7XG4gICAgICAgIC8vIElnbm9yZSBhbGwgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgIGlmIChpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpKSB7XG4gICAgICAgICAgc2l6ZSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBQcm9wZXJ0aWVzID0gbWVtYmVycyA9IG51bGw7XG5cbiAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgaXRlcmF0aW9uIGFsZ29yaXRobS5cbiAgICAgIGlmICghc2l6ZSkge1xuICAgICAgICAvLyBBIGxpc3Qgb2Ygbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgIG1lbWJlcnMgPSBbXCJ2YWx1ZU9mXCIsIFwidG9TdHJpbmdcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInByb3BlcnR5SXNFbnVtZXJhYmxlXCIsIFwiaXNQcm90b3R5cGVPZlwiLCBcImhhc093blByb3BlcnR5XCIsIFwiY29uc3RydWN0b3JcIl07XG4gICAgICAgIC8vIElFIDw9IDgsIE1vemlsbGEgMS4wLCBhbmQgTmV0c2NhcGUgNi4yIGlnbm9yZSBzaGFkb3dlZCBub24tZW51bWVyYWJsZVxuICAgICAgICAvLyBwcm9wZXJ0aWVzLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgbGVuZ3RoO1xuICAgICAgICAgIHZhciBoYXNQcm9wZXJ0eSA9ICFpc0Z1bmN0aW9uICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgIT0gJ2Z1bmN0aW9uJyAmJiBpc0hvc3RUeXBlKG9iamVjdCwgJ2hhc093blByb3BlcnR5JykgPyBvYmplY3QuaGFzT3duUHJvcGVydHkgOiBpc1Byb3BlcnR5O1xuICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAvLyBHZWNrbyA8PSAxLjAgZW51bWVyYXRlcyB0aGUgYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIHVuZGVyXG4gICAgICAgICAgICAvLyBjZXJ0YWluIGNvbmRpdGlvbnM7IElFIGRvZXMgbm90LlxuICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eS5cbiAgICAgICAgICBmb3IgKGxlbmd0aCA9IG1lbWJlcnMubGVuZ3RoOyBwcm9wZXJ0eSA9IG1lbWJlcnNbLS1sZW5ndGhdOyBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmIGNhbGxiYWNrKHByb3BlcnR5KSk7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikge1xuICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjQgZW51bWVyYXRlcyBzaGFkb3dlZCBwcm9wZXJ0aWVzIHR3aWNlLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAvLyBDcmVhdGUgYSBzZXQgb2YgaXRlcmF0ZWQgcHJvcGVydGllcy5cbiAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5O1xuICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAvLyBTdG9yZSBlYWNoIHByb3BlcnR5IG5hbWUgdG8gcHJldmVudCBkb3VibGUgZW51bWVyYXRpb24uIFRoZVxuICAgICAgICAgICAgLy8gYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIGlzIG5vdCBlbnVtZXJhdGVkIGR1ZSB0byBjcm9zcy1cbiAgICAgICAgICAgIC8vIGVudmlyb25tZW50IGluY29uc2lzdGVuY2llcy5cbiAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgIWlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkgJiYgKG1lbWJlcnNbcHJvcGVydHldID0gMSkgJiYgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBObyBidWdzIGRldGVjdGVkOyB1c2UgdGhlIHN0YW5kYXJkIGBmb3IuLi5pbmAgYWxnb3JpdGhtLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgaXNDb25zdHJ1Y3RvcjtcbiAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgIShpc0NvbnN0cnVjdG9yID0gcHJvcGVydHkgPT09IFwiY29uc3RydWN0b3JcIikpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBNYW51YWxseSBpbnZva2UgdGhlIGNhbGxiYWNrIGZvciB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBkdWUgdG9cbiAgICAgICAgICAvLyBjcm9zcy1lbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IgfHwgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgKHByb3BlcnR5ID0gXCJjb25zdHJ1Y3RvclwiKSkpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgLy8gUHVibGljOiBTZXJpYWxpemVzIGEgSmF2YVNjcmlwdCBgdmFsdWVgIGFzIGEgSlNPTiBzdHJpbmcuIFRoZSBvcHRpb25hbFxuICAgIC8vIGBmaWx0ZXJgIGFyZ3VtZW50IG1heSBzcGVjaWZ5IGVpdGhlciBhIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIGhvdyBvYmplY3QgYW5kXG4gICAgLy8gYXJyYXkgbWVtYmVycyBhcmUgc2VyaWFsaXplZCwgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhbmQgbnVtYmVycyB0aGF0XG4gICAgLy8gaW5kaWNhdGVzIHdoaWNoIHByb3BlcnRpZXMgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuIFRoZSBvcHRpb25hbCBgd2lkdGhgXG4gICAgLy8gYXJndW1lbnQgbWF5IGJlIGVpdGhlciBhIHN0cmluZyBvciBudW1iZXIgdGhhdCBzcGVjaWZpZXMgdGhlIGluZGVudGF0aW9uXG4gICAgLy8gbGV2ZWwgb2YgdGhlIG91dHB1dC5cbiAgICBpZiAoIWhhcyhcImpzb24tc3RyaW5naWZ5XCIpKSB7XG4gICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgY29udHJvbCBjaGFyYWN0ZXJzIGFuZCB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLlxuICAgICAgdmFyIEVzY2FwZXMgPSB7XG4gICAgICAgIDkyOiBcIlxcXFxcXFxcXCIsXG4gICAgICAgIDM0OiAnXFxcXFwiJyxcbiAgICAgICAgODogXCJcXFxcYlwiLFxuICAgICAgICAxMjogXCJcXFxcZlwiLFxuICAgICAgICAxMDogXCJcXFxcblwiLFxuICAgICAgICAxMzogXCJcXFxcclwiLFxuICAgICAgICA5OiBcIlxcXFx0XCJcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBDb252ZXJ0cyBgdmFsdWVgIGludG8gYSB6ZXJvLXBhZGRlZCBzdHJpbmcgc3VjaCB0aGF0IGl0c1xuICAgICAgLy8gbGVuZ3RoIGlzIGF0IGxlYXN0IGVxdWFsIHRvIGB3aWR0aGAuIFRoZSBgd2lkdGhgIG11c3QgYmUgPD0gNi5cbiAgICAgIHZhciBsZWFkaW5nWmVyb2VzID0gXCIwMDAwMDBcIjtcbiAgICAgIHZhciB0b1BhZGRlZFN0cmluZyA9IGZ1bmN0aW9uICh3aWR0aCwgdmFsdWUpIHtcbiAgICAgICAgLy8gVGhlIGB8fCAwYCBleHByZXNzaW9uIGlzIG5lY2Vzc2FyeSB0byB3b3JrIGFyb3VuZCBhIGJ1ZyBpblxuICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgd2hlcmUgYDAgPT0gLTBgLCBidXQgYFN0cmluZygtMCkgIT09IFwiMFwiYC5cbiAgICAgICAgcmV0dXJuIChsZWFkaW5nWmVyb2VzICsgKHZhbHVlIHx8IDApKS5zbGljZSgtd2lkdGgpO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IERvdWJsZS1xdW90ZXMgYSBzdHJpbmcgYHZhbHVlYCwgcmVwbGFjaW5nIGFsbCBBU0NJSSBjb250cm9sXG4gICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoXG4gICAgICAvLyB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgLy8gYFF1b3RlKHZhbHVlKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gXCJcXFxcdTAwXCI7XG4gICAgICB2YXIgcXVvdGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9ICdcIicsIGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoLCBpc0xhcmdlID0gbGVuZ3RoID4gMTAgJiYgY2hhckluZGV4QnVnZ3ksIHN5bWJvbHM7XG4gICAgICAgIGlmIChpc0xhcmdlKSB7XG4gICAgICAgICAgc3ltYm9scyA9IHZhbHVlLnNwbGl0KFwiXCIpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgIHZhciBjaGFyQ29kZSA9IHZhbHVlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yXG4gICAgICAgICAgLy8gc2hvcnRoYW5kIGVzY2FwZSBzZXF1ZW5jZTsgb3RoZXJ3aXNlLCBhcHBlbmQgdGhlIGNoYXJhY3RlciBhcy1pcy5cbiAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICBjYXNlIDg6IGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMjogY2FzZSAxMzogY2FzZSAzNDogY2FzZSA5MjpcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IEVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVuaWNvZGVQcmVmaXggKyB0b1BhZGRlZFN0cmluZygyLCBjaGFyQ29kZS50b1N0cmluZygxNikpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBpc0xhcmdlID8gc3ltYm9sc1tpbmRleF0gOiBjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdChpbmRleCkgOiB2YWx1ZVtpbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgKyAnXCInO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZXMgYW4gb2JqZWN0LiBJbXBsZW1lbnRzIHRoZVxuICAgICAgLy8gYFN0cihrZXksIGhvbGRlcilgLCBgSk8odmFsdWUpYCwgYW5kIGBKQSh2YWx1ZSlgIG9wZXJhdGlvbnMuXG4gICAgICB2YXIgc2VyaWFsaXplID0gZnVuY3Rpb24gKHByb3BlcnR5LCBvYmplY3QsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spIHtcbiAgICAgICAgdmFyIHZhbHVlLCBjbGFzc05hbWUsIHllYXIsIG1vbnRoLCBkYXRlLCB0aW1lLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzLCByZXN1bHRzLCBlbGVtZW50LCBpbmRleCwgbGVuZ3RoLCBwcmVmaXgsIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIGhvc3Qgb2JqZWN0IHN1cHBvcnQuXG4gICAgICAgICAgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gZGF0ZUNsYXNzICYmICFpc1Byb3BlcnR5LmNhbGwodmFsdWUsIFwidG9KU09OXCIpKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkge1xuICAgICAgICAgICAgICAvLyBEYXRlcyBhcmUgc2VyaWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGBEYXRlI3RvSlNPTmAgbWV0aG9kXG4gICAgICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS45LjUuNDQuIFNlZSBzZWN0aW9uIDE1LjkuMS4xNVxuICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LlxuICAgICAgICAgICAgICBpZiAoZ2V0RGF5KSB7XG4gICAgICAgICAgICAgICAgLy8gTWFudWFsbHkgY29tcHV0ZSB0aGUgeWVhciwgbW9udGgsIGRhdGUsIGhvdXJzLCBtaW51dGVzLFxuICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZVxuICAgICAgICAgICAgICAgIC8vIGJ1Z2d5LiBBZGFwdGVkIGZyb20gQFlhZmZsZSdzIGBkYXRlLXNoaW1gIHByb2plY3QuXG4gICAgICAgICAgICAgICAgZGF0ZSA9IGZsb29yKHZhbHVlIC8gODY0ZTUpO1xuICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspO1xuICAgICAgICAgICAgICAgIGZvciAobW9udGggPSBmbG9vcigoZGF0ZSAtIGdldERheSh5ZWFyLCAwKSkgLyAzMC40Mik7IGdldERheSh5ZWFyLCBtb250aCArIDEpIDw9IGRhdGU7IG1vbnRoKyspO1xuICAgICAgICAgICAgICAgIGRhdGUgPSAxICsgZGF0ZSAtIGdldERheSh5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGB0aW1lYCB2YWx1ZSBzcGVjaWZpZXMgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkgKHNlZSBFU1xuICAgICAgICAgICAgICAgIC8vIDUuMSBzZWN0aW9uIDE1LjkuMS4yKS4gVGhlIGZvcm11bGEgYChBICUgQiArIEIpICUgQmAgaXMgdXNlZFxuICAgICAgICAgICAgICAgIC8vIHRvIGNvbXB1dGUgYEEgbW9kdWxvIEJgLCBhcyB0aGUgYCVgIG9wZXJhdG9yIGRvZXMgbm90XG4gICAgICAgICAgICAgICAgLy8gY29ycmVzcG9uZCB0byB0aGUgYG1vZHVsb2Agb3BlcmF0aW9uIGZvciBuZWdhdGl2ZSBudW1iZXJzLlxuICAgICAgICAgICAgICAgIHRpbWUgPSAodmFsdWUgJSA4NjRlNSArIDg2NGU1KSAlIDg2NGU1O1xuICAgICAgICAgICAgICAgIC8vIFRoZSBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kcyBhcmUgb2J0YWluZWQgYnlcbiAgICAgICAgICAgICAgICAvLyBkZWNvbXBvc2luZyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheS4gU2VlIHNlY3Rpb24gMTUuOS4xLjEwLlxuICAgICAgICAgICAgICAgIGhvdXJzID0gZmxvb3IodGltZSAvIDM2ZTUpICUgMjQ7XG4gICAgICAgICAgICAgICAgbWludXRlcyA9IGZsb29yKHRpbWUgLyA2ZTQpICUgNjA7XG4gICAgICAgICAgICAgICAgc2Vjb25kcyA9IGZsb29yKHRpbWUgLyAxZTMpICUgNjA7XG4gICAgICAgICAgICAgICAgbWlsbGlzZWNvbmRzID0gdGltZSAlIDFlMztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB5ZWFyID0gdmFsdWUuZ2V0VVRDRnVsbFllYXIoKTtcbiAgICAgICAgICAgICAgICBtb250aCA9IHZhbHVlLmdldFVUQ01vbnRoKCk7XG4gICAgICAgICAgICAgICAgZGF0ZSA9IHZhbHVlLmdldFVUQ0RhdGUoKTtcbiAgICAgICAgICAgICAgICBob3VycyA9IHZhbHVlLmdldFVUQ0hvdXJzKCk7XG4gICAgICAgICAgICAgICAgbWludXRlcyA9IHZhbHVlLmdldFVUQ01pbnV0ZXMoKTtcbiAgICAgICAgICAgICAgICBzZWNvbmRzID0gdmFsdWUuZ2V0VVRDU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHZhbHVlLmdldFVUQ01pbGxpc2Vjb25kcygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFNlcmlhbGl6ZSBleHRlbmRlZCB5ZWFycyBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgIHZhbHVlID0gKHllYXIgPD0gMCB8fCB5ZWFyID49IDFlNCA/ICh5ZWFyIDwgMCA/IFwiLVwiIDogXCIrXCIpICsgdG9QYWRkZWRTdHJpbmcoNiwgeWVhciA8IDAgPyAteWVhciA6IHllYXIpIDogdG9QYWRkZWRTdHJpbmcoNCwgeWVhcikpICtcbiAgICAgICAgICAgICAgICBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1vbnRoICsgMSkgKyBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIGRhdGUpICtcbiAgICAgICAgICAgICAgICAvLyBNb250aHMsIGRhdGVzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgc2hvdWxkIGhhdmUgdHdvXG4gICAgICAgICAgICAgICAgLy8gZGlnaXRzOyBtaWxsaXNlY29uZHMgc2hvdWxkIGhhdmUgdGhyZWUuXG4gICAgICAgICAgICAgICAgXCJUXCIgKyB0b1BhZGRlZFN0cmluZygyLCBob3VycykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1pbnV0ZXMpICsgXCI6XCIgKyB0b1BhZGRlZFN0cmluZygyLCBzZWNvbmRzKSArXG4gICAgICAgICAgICAgICAgLy8gTWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LjAsIGJ1dCByZXF1aXJlZCBpbiA1LjEuXG4gICAgICAgICAgICAgICAgXCIuXCIgKyB0b1BhZGRlZFN0cmluZygzLCBtaWxsaXNlY29uZHMpICsgXCJaXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUudG9KU09OID09IFwiZnVuY3Rpb25cIiAmJiAoKGNsYXNzTmFtZSAhPSBudW1iZXJDbGFzcyAmJiBjbGFzc05hbWUgIT0gc3RyaW5nQ2xhc3MgJiYgY2xhc3NOYW1lICE9IGFycmF5Q2xhc3MpIHx8IGlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpKSB7XG4gICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgYWRkcyBub24tc3RhbmRhcmQgYHRvSlNPTmAgbWV0aG9kcyB0byB0aGVcbiAgICAgICAgICAgIC8vIGBOdW1iZXJgLCBgU3RyaW5nYCwgYERhdGVgLCBhbmQgYEFycmF5YCBwcm90b3R5cGVzLiBKU09OIDNcbiAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmVcbiAgICAgICAgICAgIC8vIGRlZmluZWQgZGlyZWN0bHkgb24gYW4gaW5zdGFuY2UuXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvSlNPTihwcm9wZXJ0eSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWVcbiAgICAgICAgICAvLyBmb3Igc2VyaWFsaXphdGlvbi5cbiAgICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgfVxuICAgICAgICBjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKTtcbiAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHtcbiAgICAgICAgICAvLyBCb29sZWFucyBhcmUgcmVwcmVzZW50ZWQgbGl0ZXJhbGx5LlxuICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgLy8gSlNPTiBudW1iZXJzIG11c3QgYmUgZmluaXRlLiBgSW5maW5pdHlgIGFuZCBgTmFOYCBhcmUgc2VyaWFsaXplZCBhc1xuICAgICAgICAgIC8vIGBcIm51bGxcImAuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDAgPyBcIlwiICsgdmFsdWUgOiBcIm51bGxcIjtcbiAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAvLyBTdHJpbmdzIGFyZSBkb3VibGUtcXVvdGVkIGFuZCBlc2NhcGVkLlxuICAgICAgICAgIHJldHVybiBxdW90ZShcIlwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIC8vIENoZWNrIGZvciBjeWNsaWMgc3RydWN0dXJlcy4gVGhpcyBpcyBhIGxpbmVhciBzZWFyY2g7IHBlcmZvcm1hbmNlXG4gICAgICAgICAgLy8gaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mIHVuaXF1ZSBuZXN0ZWQgb2JqZWN0cy5cbiAgICAgICAgICBmb3IgKGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICBpZiAoc3RhY2tbbGVuZ3RoXSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgLy8gQ3ljbGljIHN0cnVjdHVyZXMgY2Fubm90IGJlIHNlcmlhbGl6ZWQgYnkgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEFkZCB0aGUgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgaW5kZW50IG9uZSBhZGRpdGlvbmFsIGxldmVsLlxuICAgICAgICAgIHByZWZpeCA9IGluZGVudGF0aW9uO1xuICAgICAgICAgIGluZGVudGF0aW9uICs9IHdoaXRlc3BhY2U7XG4gICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgYXJyYXkgZWxlbWVudHMuXG4gICAgICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICBlbGVtZW50ID0gc2VyaWFsaXplKGluZGV4LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaChlbGVtZW50ID09PSB1bmRlZiA/IFwibnVsbFwiIDogZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJbXFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIl1cIiA6IChcIltcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIl1cIikpIDogXCJbXVwiO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0IG1lbWJlcnMuIE1lbWJlcnMgYXJlIHNlbGVjdGVkIGZyb21cbiAgICAgICAgICAgIC8vIGVpdGhlciBhIHVzZXItc3BlY2lmaWVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMsIG9yIHRoZSBvYmplY3RcbiAgICAgICAgICAgIC8vIGl0c2VsZi5cbiAgICAgICAgICAgIGZvckVhY2gocHJvcGVydGllcyB8fCB2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gc2VyaWFsaXplKHByb3BlcnR5LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB1bmRlZikge1xuICAgICAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zOiBcIklmIGBnYXBgIHt3aGl0ZXNwYWNlfVxuICAgICAgICAgICAgICAgIC8vIGlzIG5vdCB0aGUgZW1wdHkgc3RyaW5nLCBsZXQgYG1lbWJlcmAge3F1b3RlKHByb3BlcnR5KSArIFwiOlwifVxuICAgICAgICAgICAgICAgIC8vIGJlIHRoZSBjb25jYXRlbmF0aW9uIG9mIGBtZW1iZXJgIGFuZCB0aGUgYHNwYWNlYCBjaGFyYWN0ZXIuXCJcbiAgICAgICAgICAgICAgICAvLyBUaGUgXCJgc3BhY2VgIGNoYXJhY3RlclwiIHJlZmVycyB0byB0aGUgbGl0ZXJhbCBzcGFjZVxuICAgICAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgbm90IHRoZSBgc3BhY2VgIHt3aWR0aH0gYXJndW1lbnQgcHJvdmlkZWQgdG9cbiAgICAgICAgICAgICAgICAvLyBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChxdW90ZShwcm9wZXJ0eSkgKyBcIjpcIiArICh3aGl0ZXNwYWNlID8gXCIgXCIgOiBcIlwiKSArIGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID8gKHdoaXRlc3BhY2UgPyBcIntcXG5cIiArIGluZGVudGF0aW9uICsgcmVzdWx0cy5qb2luKFwiLFxcblwiICsgaW5kZW50YXRpb24pICsgXCJcXG5cIiArIHByZWZpeCArIFwifVwiIDogKFwie1wiICsgcmVzdWx0cy5qb2luKFwiLFwiKSArIFwifVwiKSkgOiBcInt9XCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb2JqZWN0IGZyb20gdGhlIHRyYXZlcnNlZCBvYmplY3Qgc3RhY2suXG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gUHVibGljOiBgSlNPTi5zdHJpbmdpZnlgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgIEpTT04zLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChzb3VyY2UsIGZpbHRlciwgd2lkdGgpIHtcbiAgICAgICAgdmFyIHdoaXRlc3BhY2UsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCBjbGFzc05hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgZmlsdGVyID09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgZmlsdGVyID09IFwib2JqZWN0XCIgJiYgZmlsdGVyKSB7XG4gICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKGZpbHRlcikpID09IGZ1bmN0aW9uQ2xhc3MpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHByb3BlcnR5IG5hbWVzIGFycmF5IGludG8gYSBtYWtlc2hpZnQgc2V0LlxuICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGggPSBmaWx0ZXIubGVuZ3RoLCB2YWx1ZTsgaW5kZXggPCBsZW5ndGg7IHZhbHVlID0gZmlsdGVyW2luZGV4KytdLCAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpKSwgY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzIHx8IGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykgJiYgKHByb3BlcnRpZXNbdmFsdWVdID0gMSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod2lkdGgpIHtcbiAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwod2lkdGgpKSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgLy8gYHdpZHRoYCBudW1iZXIgb2Ygc3BhY2UgY2hhcmFjdGVycy5cbiAgICAgICAgICAgIGlmICgod2lkdGggLT0gd2lkdGggJSAxKSA+IDApIHtcbiAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzKSB7XG4gICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5c1xuICAgICAgICAvLyAoYFwiXCJgKSBvbmx5IGlmIHRoZXkgYXJlIHVzZWQgZGlyZWN0bHkgd2l0aGluIGFuIG9iamVjdCBtZW1iZXIgbGlzdFxuICAgICAgICAvLyAoZS5nLiwgYCEoXCJcIiBpbiB7IFwiXCI6IDF9KWApLlxuICAgICAgICByZXR1cm4gc2VyaWFsaXplKFwiXCIsICh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHNvdXJjZSwgdmFsdWUpLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgXCJcIiwgW10pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IFBhcnNlcyBhIEpTT04gc291cmNlIHN0cmluZy5cbiAgICBpZiAoIWhhcyhcImpzb24tcGFyc2VcIikpIHtcbiAgICAgIHZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xuXG4gICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIHVuZXNjYXBlZFxuICAgICAgLy8gZXF1aXZhbGVudHMuXG4gICAgICB2YXIgVW5lc2NhcGVzID0ge1xuICAgICAgICA5MjogXCJcXFxcXCIsXG4gICAgICAgIDM0OiAnXCInLFxuICAgICAgICA0NzogXCIvXCIsXG4gICAgICAgIDk4OiBcIlxcYlwiLFxuICAgICAgICAxMTY6IFwiXFx0XCIsXG4gICAgICAgIDExMDogXCJcXG5cIixcbiAgICAgICAgMTAyOiBcIlxcZlwiLFxuICAgICAgICAxMTQ6IFwiXFxyXCJcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgIHZhciBJbmRleCwgU291cmNlO1xuXG4gICAgICAvLyBJbnRlcm5hbDogUmVzZXRzIHRoZSBwYXJzZXIgc3RhdGUgYW5kIHRocm93cyBhIGBTeW50YXhFcnJvcmAuXG4gICAgICB2YXIgYWJvcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICB0aHJvdyBTeW50YXhFcnJvcigpO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGBcIiRcImAgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZFxuICAgICAgLy8gdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmluZy4gQSB0b2tlbiBtYXkgYmUgYSBzdHJpbmcsIG51bWJlciwgYG51bGxgXG4gICAgICAvLyBsaXRlcmFsLCBvciBCb29sZWFuIGxpdGVyYWwuXG4gICAgICB2YXIgbGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc291cmNlID0gU291cmNlLCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoLCB2YWx1ZSwgYmVnaW4sIHBvc2l0aW9uLCBpc1NpZ25lZCwgY2hhckNvZGU7XG4gICAgICAgIHdoaWxlIChJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgIGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMzogY2FzZSAzMjpcbiAgICAgICAgICAgICAgLy8gU2tpcCB3aGl0ZXNwYWNlIHRva2VucywgaW5jbHVkaW5nIHRhYnMsIGNhcnJpYWdlIHJldHVybnMsIGxpbmVcbiAgICAgICAgICAgICAgLy8gZmVlZHMsIGFuZCBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMTIzOiBjYXNlIDEyNTogY2FzZSA5MTogY2FzZSA5MzogY2FzZSA1ODogY2FzZSA0NDpcbiAgICAgICAgICAgICAgLy8gUGFyc2UgYSBwdW5jdHVhdG9yIHRva2VuIChge2AsIGB9YCwgYFtgLCBgXWAsIGA6YCwgb3IgYCxgKSBhdFxuICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgdmFsdWUgPSBjaGFySW5kZXhCdWdneSA/IHNvdXJjZS5jaGFyQXQoSW5kZXgpIDogc291cmNlW0luZGV4XTtcbiAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgICAgLy8gYFwiYCBkZWxpbWl0cyBhIEpTT04gc3RyaW5nOyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmRcbiAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAvLyBzZW50aW5lbCBgQGAgY2hhcmFjdGVyIHRvIGRpc3Rpbmd1aXNoIHRoZW0gZnJvbSBwdW5jdHVhdG9ycyBhbmRcbiAgICAgICAgICAgICAgLy8gZW5kLW9mLXN0cmluZyB0b2tlbnMuXG4gICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhhbiB0aGUgc3BhY2UgY2hhcmFjdGVyKSBhcmUgbm90IHBlcm1pdHRlZC5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgLy8gQSByZXZlcnNlIHNvbGlkdXMgKGBcXGApIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYW4gZXNjYXBlZFxuICAgICAgICAgICAgICAgICAgLy8gY29udHJvbCBjaGFyYWN0ZXIgKGluY2x1ZGluZyBgXCJgLCBgXFxgLCBhbmQgYC9gKSBvciBVbmljb2RlXG4gICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOiBjYXNlIDM0OiBjYXNlIDQ3OiBjYXNlIDk4OiBjYXNlIDExNjogY2FzZSAxMTA6IGNhc2UgMTAyOiBjYXNlIDExNDpcbiAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gVW5lc2NhcGVzW2NoYXJDb2RlXTtcbiAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDExNzpcbiAgICAgICAgICAgICAgICAgICAgICAvLyBgXFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCB2YWxpZGF0ZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IGNvZGUgcG9pbnQuXG4gICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24gPSBJbmRleCArIDQ7IEluZGV4IDwgcG9zaXRpb247IEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnNlbnNpdGl2ZSkgdGhhdCBmb3JtIGEgc2luZ2xlIGhleGFkZWNpbWFsIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcgfHwgY2hhckNvZGUgPj0gOTcgJiYgY2hhckNvZGUgPD0gMTAyIHx8IGNoYXJDb2RlID49IDY1ICYmIGNoYXJDb2RlIDw9IDcwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IGZyb21DaGFyQ29kZShcIjB4XCIgKyBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEFuIHVuZXNjYXBlZCBkb3VibGUtcXVvdGUgY2hhcmFjdGVyIG1hcmtzIHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZSBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGEgc3RyaW5nIGlzIHZhbGlkLlxuICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoYXJDb2RlID49IDMyICYmIGNoYXJDb2RlICE9IDkyICYmIGNoYXJDb2RlICE9IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgdGhlIHN0cmluZyBhcy1pcy5cbiAgICAgICAgICAgICAgICAgIHZhbHVlICs9IHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDM0KSB7XG4gICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kIHJldHVybiB0aGUgcmV2aXZlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIHN0cmluZy5cbiAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIC8vIFBhcnNlIG51bWJlcnMgYW5kIGxpdGVyYWxzLlxuICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAvLyBBZHZhbmNlIHBhc3QgdGhlIG5lZ2F0aXZlIHNpZ24sIGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFBhcnNlIGFuIGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQgdmFsdWUuXG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nykge1xuICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgemVyb2VzIGFyZSBpbnRlcnByZXRlZCBhcyBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4ICsgMSkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgb2N0YWwgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBJbmRleCsrKTtcbiAgICAgICAgICAgICAgICAvLyBGbG9hdHMgY2Fubm90IGNvbnRhaW4gYSBsZWFkaW5nIGRlY2ltYWwgcG9pbnQ7IGhvd2V2ZXIsIHRoaXNcbiAgICAgICAgICAgICAgICAvLyBjYXNlIGlzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSB0aGUgcGFyc2VyLlxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gKytJbmRleDtcbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkZWNpbWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIHRyYWlsaW5nIGRlY2ltYWwuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBleHBvbmVudHMuIFRoZSBgZWAgZGVub3RpbmcgdGhlIGV4cG9uZW50IGlzXG4gICAgICAgICAgICAgICAgLy8gY2FzZS1pbnNlbnNpdGl2ZS5cbiAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMTAxIHx8IGNoYXJDb2RlID09IDY5KSB7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkLlxuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQzIHx8IGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZXhwb25lbnRpYWwgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIGVtcHR5IGV4cG9uZW50LlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQ29lcmNlIHRoZSBwYXJzZWQgdmFsdWUgdG8gYSBKYXZhU2NyaXB0IG51bWJlci5cbiAgICAgICAgICAgICAgICByZXR1cm4gK3NvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIEEgbmVnYXRpdmUgc2lnbiBtYXkgb25seSBwcmVjZWRlIG51bWJlcnMuXG4gICAgICAgICAgICAgIGlmIChpc1NpZ25lZCkge1xuICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gYHRydWVgLCBgZmFsc2VgLCBhbmQgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyBVbnJlY29nbml6ZWQgdG9rZW4uXG4gICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiB0aGUgc2VudGluZWwgYCRgIGNoYXJhY3RlciBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgIHJldHVybiBcIiRcIjtcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICB2YXIgZ2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByZXN1bHRzLCBoYXNNZW1iZXJzO1xuICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAvLyBVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dC5cbiAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIGlmICgoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgPT0gXCJAXCIpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICBpZiAodmFsdWUgPT0gXCJbXCIpIHtcbiAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gYXJyYXksIHJldHVybmluZyBhIG5ldyBKYXZhU2NyaXB0IGFycmF5LlxuICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIl1cIikge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIElmIHRoZSBhcnJheSBsaXRlcmFsIGNvbnRhaW5zIGVsZW1lbnRzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0aW5nIHRoZSBwcmV2aW91cyBlbGVtZW50IGZyb20gdGhlXG4gICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gRWxpc2lvbnMgYW5kIGxlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaChnZXQodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gXCJ7XCIpIHtcbiAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICByZXN1bHRzID0ge307XG4gICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAvLyBBIGNsb3NpbmcgY3VybHkgYnJhY2UgbWFya3MgdGhlIGVuZCBvZiB0aGUgb2JqZWN0IGxpdGVyYWwuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIElmIHRoZSBvYmplY3QgbGl0ZXJhbCBjb250YWlucyBtZW1iZXJzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIG9iamVjdCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIExlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLCBvYmplY3QgcHJvcGVydHkgbmFtZXMgbXVzdCBiZVxuICAgICAgICAgICAgICAvLyBkb3VibGUtcXVvdGVkIHN0cmluZ3MsIGFuZCBhIGA6YCBtdXN0IHNlcGFyYXRlIGVhY2ggcHJvcGVydHlcbiAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIiB8fCB0eXBlb2YgdmFsdWUgIT0gXCJzdHJpbmdcIiB8fCAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgIT0gXCJAXCIgfHwgbGV4KCkgIT0gXCI6XCIpIHtcbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdHNbdmFsdWUuc2xpY2UoMSldID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRva2VuIGVuY291bnRlcmVkLlxuICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFVwZGF0ZXMgYSB0cmF2ZXJzZWQgb2JqZWN0IG1lbWJlci5cbiAgICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbihzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHdhbGsoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHtcbiAgICAgICAgICBkZWxldGUgc291cmNlW3Byb3BlcnR5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBhIHBhcnNlZCBKU09OIG9iamVjdCwgaW52b2tpbmcgdGhlXG4gICAgICAvLyBgY2FsbGJhY2tgIGZ1bmN0aW9uIGZvciBlYWNoIHZhbHVlLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgLy8gYFdhbGsoaG9sZGVyLCBuYW1lKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgIHZhciB3YWxrID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtwcm9wZXJ0eV0sIGxlbmd0aDtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlKSB7XG4gICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NFxuICAgICAgICAgIC8vIGJlY2F1c2UgaXRzIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIGltcGxlbWVudGF0aW9uIHJldHVybnMgYGZhbHNlYFxuICAgICAgICAgIC8vIGZvciBhcnJheSBpbmRpY2VzIChlLmcuLCBgIVsxLCAyLCAzXS5oYXNPd25Qcm9wZXJ0eShcIjBcIilgKS5cbiAgICAgICAgICBpZiAoZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgZm9yIChsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGxlbmd0aC0tOykge1xuICAgICAgICAgICAgICB1cGRhdGUodmFsdWUsIGxlbmd0aCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHNvdXJjZSwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgIH07XG5cbiAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgIEpTT04zLnBhcnNlID0gZnVuY3Rpb24gKHNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJlc3VsdCwgdmFsdWU7XG4gICAgICAgIEluZGV4ID0gMDtcbiAgICAgICAgU291cmNlID0gXCJcIiArIHNvdXJjZTtcbiAgICAgICAgcmVzdWx0ID0gZ2V0KGxleCgpKTtcbiAgICAgICAgLy8gSWYgYSBKU09OIHN0cmluZyBjb250YWlucyBtdWx0aXBsZSB0b2tlbnMsIGl0IGlzIGludmFsaWQuXG4gICAgICAgIGlmIChsZXgoKSAhPSBcIiRcIikge1xuICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzZXQgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sgJiYgZ2V0Q2xhc3MuY2FsbChjYWxsYmFjaykgPT0gZnVuY3Rpb25DbGFzcyA/IHdhbGsoKHZhbHVlID0ge30sIHZhbHVlW1wiXCJdID0gcmVzdWx0LCB2YWx1ZSksIFwiXCIsIGNhbGxiYWNrKSA6IHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gRXhwb3J0IGZvciBhc3luY2hyb25vdXMgbW9kdWxlIGxvYWRlcnMuXG4gIGlmIChpc0xvYWRlcikge1xuICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gSlNPTjM7XG4gICAgfSk7XG4gIH1cbn0odGhpcykpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB0b0FycmF5XG5cbmZ1bmN0aW9uIHRvQXJyYXkobGlzdCwgaW5kZXgpIHtcbiAgICB2YXIgYXJyYXkgPSBbXVxuXG4gICAgaW5kZXggPSBpbmRleCB8fCAwXG5cbiAgICBmb3IgKHZhciBpID0gaW5kZXggfHwgMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJyYXlbaSAtIGluZGV4XSA9IGxpc3RbaV1cbiAgICB9XG5cbiAgICByZXR1cm4gYXJyYXlcbn1cbiIsInZhciB0cmF2ZXJzZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBuZXcgVHJhdmVyc2Uob2JqKTtcbn07XG5cbmZ1bmN0aW9uIFRyYXZlcnNlIChvYmopIHtcbiAgICB0aGlzLnZhbHVlID0gb2JqO1xufVxuXG5UcmF2ZXJzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBzKSB7XG4gICAgdmFyIG5vZGUgPSB0aGlzLnZhbHVlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHMubGVuZ3RoOyBpICsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBwc1tpXTtcbiAgICAgICAgaWYgKCFub2RlIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUsIGtleSkpIHtcbiAgICAgICAgICAgIG5vZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZVtrZXldO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbn07XG5cblRyYXZlcnNlLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAocHMpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMudmFsdWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcy5sZW5ndGg7IGkgKyspIHtcbiAgICAgICAgdmFyIGtleSA9IHBzW2ldO1xuICAgICAgICBpZiAoIW5vZGUgfHwgIWhhc093blByb3BlcnR5LmNhbGwobm9kZSwga2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBub2RlW2tleV07XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChwcywgdmFsdWUpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMudmFsdWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcy5sZW5ndGggLSAxOyBpICsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBwc1tpXTtcbiAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUsIGtleSkpIG5vZGVba2V5XSA9IHt9O1xuICAgICAgICBub2RlID0gbm9kZVtrZXldO1xuICAgIH1cbiAgICBub2RlW3BzW2ldXSA9IHZhbHVlO1xuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cblRyYXZlcnNlLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICByZXR1cm4gd2Fsayh0aGlzLnZhbHVlLCBjYiwgdHJ1ZSk7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYikge1xuICAgIHRoaXMudmFsdWUgPSB3YWxrKHRoaXMudmFsdWUsIGNiLCBmYWxzZSk7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUucmVkdWNlID0gZnVuY3Rpb24gKGNiLCBpbml0KSB7XG4gICAgdmFyIHNraXAgPSBhcmd1bWVudHMubGVuZ3RoID09PSAxO1xuICAgIHZhciBhY2MgPSBza2lwID8gdGhpcy52YWx1ZSA6IGluaXQ7XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1Jvb3QgfHwgIXNraXApIHtcbiAgICAgICAgICAgIGFjYyA9IGNiLmNhbGwodGhpcywgYWNjLCB4KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhY2M7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUucGF0aHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICBhY2MucHVzaCh0aGlzLnBhdGgpOyBcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLm5vZGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgYWNjLnB1c2godGhpcy5ub2RlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwYXJlbnRzID0gW10sIG5vZGVzID0gW107XG4gICAgXG4gICAgcmV0dXJuIChmdW5jdGlvbiBjbG9uZSAoc3JjKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFyZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHBhcmVudHNbaV0gPT09IHNyYykge1xuICAgICAgICAgICAgICAgIHJldHVybiBub2Rlc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdvYmplY3QnICYmIHNyYyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGRzdCA9IGNvcHkoc3JjKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50cy5wdXNoKHNyYyk7XG4gICAgICAgICAgICBub2Rlcy5wdXNoKGRzdCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvckVhY2gob2JqZWN0S2V5cyhzcmMpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgZHN0W2tleV0gPSBjbG9uZShzcmNba2V5XSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50cy5wb3AoKTtcbiAgICAgICAgICAgIG5vZGVzLnBvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIGRzdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzcmM7XG4gICAgICAgIH1cbiAgICB9KSh0aGlzLnZhbHVlKTtcbn07XG5cbmZ1bmN0aW9uIHdhbGsgKHJvb3QsIGNiLCBpbW11dGFibGUpIHtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIHZhciBwYXJlbnRzID0gW107XG4gICAgdmFyIGFsaXZlID0gdHJ1ZTtcbiAgICBcbiAgICByZXR1cm4gKGZ1bmN0aW9uIHdhbGtlciAobm9kZV8pIHtcbiAgICAgICAgdmFyIG5vZGUgPSBpbW11dGFibGUgPyBjb3B5KG5vZGVfKSA6IG5vZGVfO1xuICAgICAgICB2YXIgbW9kaWZpZXJzID0ge307XG4gICAgICAgIFxuICAgICAgICB2YXIga2VlcEdvaW5nID0gdHJ1ZTtcbiAgICAgICAgXG4gICAgICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgICAgIG5vZGUgOiBub2RlLFxuICAgICAgICAgICAgbm9kZV8gOiBub2RlXyxcbiAgICAgICAgICAgIHBhdGggOiBbXS5jb25jYXQocGF0aCksXG4gICAgICAgICAgICBwYXJlbnQgOiBwYXJlbnRzW3BhcmVudHMubGVuZ3RoIC0gMV0sXG4gICAgICAgICAgICBwYXJlbnRzIDogcGFyZW50cyxcbiAgICAgICAgICAgIGtleSA6IHBhdGguc2xpY2UoLTEpWzBdLFxuICAgICAgICAgICAgaXNSb290IDogcGF0aC5sZW5ndGggPT09IDAsXG4gICAgICAgICAgICBsZXZlbCA6IHBhdGgubGVuZ3RoLFxuICAgICAgICAgICAgY2lyY3VsYXIgOiBudWxsLFxuICAgICAgICAgICAgdXBkYXRlIDogZnVuY3Rpb24gKHgsIHN0b3BIZXJlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5pc1Jvb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUucGFyZW50Lm5vZGVbc3RhdGUua2V5XSA9IHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0YXRlLm5vZGUgPSB4O1xuICAgICAgICAgICAgICAgIGlmIChzdG9wSGVyZSkga2VlcEdvaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2RlbGV0ZScgOiBmdW5jdGlvbiAoc3RvcEhlcmUpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc3RhdGUucGFyZW50Lm5vZGVbc3RhdGUua2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoc3RvcEhlcmUpIGtlZXBHb2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZSA6IGZ1bmN0aW9uIChzdG9wSGVyZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHN0YXRlLnBhcmVudC5ub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wYXJlbnQubm9kZS5zcGxpY2Uoc3RhdGUua2V5LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZS5wYXJlbnQubm9kZVtzdGF0ZS5rZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcEhlcmUpIGtlZXBHb2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleXMgOiBudWxsLFxuICAgICAgICAgICAgYmVmb3JlIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLmJlZm9yZSA9IGYgfSxcbiAgICAgICAgICAgIGFmdGVyIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLmFmdGVyID0gZiB9LFxuICAgICAgICAgICAgcHJlIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLnByZSA9IGYgfSxcbiAgICAgICAgICAgIHBvc3QgOiBmdW5jdGlvbiAoZikgeyBtb2RpZmllcnMucG9zdCA9IGYgfSxcbiAgICAgICAgICAgIHN0b3AgOiBmdW5jdGlvbiAoKSB7IGFsaXZlID0gZmFsc2UgfSxcbiAgICAgICAgICAgIGJsb2NrIDogZnVuY3Rpb24gKCkgeyBrZWVwR29pbmcgPSBmYWxzZSB9XG4gICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm4gc3RhdGU7XG4gICAgICAgIFxuICAgICAgICBmdW5jdGlvbiB1cGRhdGVTdGF0ZSgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RhdGUubm9kZSA9PT0gJ29iamVjdCcgJiYgc3RhdGUubm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICghc3RhdGUua2V5cyB8fCBzdGF0ZS5ub2RlXyAhPT0gc3RhdGUubm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5rZXlzID0gb2JqZWN0S2V5cyhzdGF0ZS5ub2RlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBzdGF0ZS5pc0xlYWYgPSBzdGF0ZS5rZXlzLmxlbmd0aCA9PSAwO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFyZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50c1tpXS5ub2RlXyA9PT0gbm9kZV8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmNpcmN1bGFyID0gcGFyZW50c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhdGUuaXNMZWFmID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5rZXlzID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgc3RhdGUubm90TGVhZiA9ICFzdGF0ZS5pc0xlYWY7XG4gICAgICAgICAgICBzdGF0ZS5ub3RSb290ID0gIXN0YXRlLmlzUm9vdDtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgdXBkYXRlU3RhdGUoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIHVzZSByZXR1cm4gdmFsdWVzIHRvIHVwZGF0ZSBpZiBkZWZpbmVkXG4gICAgICAgIHZhciByZXQgPSBjYi5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkICYmIHN0YXRlLnVwZGF0ZSkgc3RhdGUudXBkYXRlKHJldCk7XG4gICAgICAgIFxuICAgICAgICBpZiAobW9kaWZpZXJzLmJlZm9yZSkgbW9kaWZpZXJzLmJlZm9yZS5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgXG4gICAgICAgIGlmICgha2VlcEdvaW5nKSByZXR1cm4gc3RhdGU7XG4gICAgICAgIFxuICAgICAgICBpZiAodHlwZW9mIHN0YXRlLm5vZGUgPT0gJ29iamVjdCdcbiAgICAgICAgJiYgc3RhdGUubm9kZSAhPT0gbnVsbCAmJiAhc3RhdGUuY2lyY3VsYXIpIHtcbiAgICAgICAgICAgIHBhcmVudHMucHVzaChzdGF0ZSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHVwZGF0ZVN0YXRlKCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvckVhY2goc3RhdGUua2V5cywgZnVuY3Rpb24gKGtleSwgaSkge1xuICAgICAgICAgICAgICAgIHBhdGgucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChtb2RpZmllcnMucHJlKSBtb2RpZmllcnMucHJlLmNhbGwoc3RhdGUsIHN0YXRlLm5vZGVba2V5XSwga2V5KTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSB3YWxrZXIoc3RhdGUubm9kZVtrZXldKTtcbiAgICAgICAgICAgICAgICBpZiAoaW1tdXRhYmxlICYmIGhhc093blByb3BlcnR5LmNhbGwoc3RhdGUubm9kZSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5ub2RlW2tleV0gPSBjaGlsZC5ub2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBjaGlsZC5pc0xhc3QgPSBpID09IHN0YXRlLmtleXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICBjaGlsZC5pc0ZpcnN0ID0gaSA9PSAwO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChtb2RpZmllcnMucG9zdCkgbW9kaWZpZXJzLnBvc3QuY2FsbChzdGF0ZSwgY2hpbGQpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHBhdGgucG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhcmVudHMucG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmIChtb2RpZmllcnMuYWZ0ZXIpIG1vZGlmaWVycy5hZnRlci5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9KShyb290KS5ub2RlO1xufVxuXG5mdW5jdGlvbiBjb3B5IChzcmMpIHtcbiAgICBpZiAodHlwZW9mIHNyYyA9PT0gJ29iamVjdCcgJiYgc3JjICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBkc3Q7XG4gICAgICAgIFxuICAgICAgICBpZiAoaXNBcnJheShzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0RhdGUoc3JjKSkge1xuICAgICAgICAgICAgZHN0ID0gbmV3IERhdGUoc3JjLmdldFRpbWUgPyBzcmMuZ2V0VGltZSgpIDogc3JjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1JlZ0V4cChzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSBuZXcgUmVnRXhwKHNyYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNFcnJvcihzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSB7IG1lc3NhZ2U6IHNyYy5tZXNzYWdlIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNCb29sZWFuKHNyYykpIHtcbiAgICAgICAgICAgIGRzdCA9IG5ldyBCb29sZWFuKHNyYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNOdW1iZXIoc3JjKSkge1xuICAgICAgICAgICAgZHN0ID0gbmV3IE51bWJlcihzcmMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHNyYykpIHtcbiAgICAgICAgICAgIGRzdCA9IG5ldyBTdHJpbmcoc3JjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChPYmplY3QuY3JlYXRlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZikge1xuICAgICAgICAgICAgZHN0ID0gT2JqZWN0LmNyZWF0ZShPYmplY3QuZ2V0UHJvdG90eXBlT2Yoc3JjKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3JjLmNvbnN0cnVjdG9yID09PSBPYmplY3QpIHtcbiAgICAgICAgICAgIGRzdCA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHByb3RvID1cbiAgICAgICAgICAgICAgICAoc3JjLmNvbnN0cnVjdG9yICYmIHNyYy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgfHwgc3JjLl9fcHJvdG9fX1xuICAgICAgICAgICAgICAgIHx8IHt9XG4gICAgICAgICAgICA7XG4gICAgICAgICAgICB2YXIgVCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgVC5wcm90b3R5cGUgPSBwcm90bztcbiAgICAgICAgICAgIGRzdCA9IG5ldyBUO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBmb3JFYWNoKG9iamVjdEtleXMoc3JjKSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgZHN0W2tleV0gPSBzcmNba2V5XTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkc3Q7XG4gICAgfVxuICAgIGVsc2UgcmV0dXJuIHNyYztcbn1cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzIChvYmopIHtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgcmVzLnB1c2goa2V5KVxuICAgIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiB0b1MgKG9iaikgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgfVxuZnVuY3Rpb24gaXNEYXRlIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBEYXRlXScgfVxuZnVuY3Rpb24gaXNSZWdFeHAgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nIH1cbmZ1bmN0aW9uIGlzRXJyb3IgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IEVycm9yXScgfVxuZnVuY3Rpb24gaXNCb29sZWFuIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgfVxuZnVuY3Rpb24gaXNOdW1iZXIgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IE51bWJlcl0nIH1cbmZ1bmN0aW9uIGlzU3RyaW5nIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBTdHJpbmddJyB9XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5ICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuKVxuICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBmbih4c1tpXSwgaSwgeHMpO1xuICAgIH1cbn07XG5cbmZvckVhY2gob2JqZWN0S2V5cyhUcmF2ZXJzZS5wcm90b3R5cGUpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdHJhdmVyc2Vba2V5XSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIHZhciB0ID0gbmV3IFRyYXZlcnNlKG9iaik7XG4gICAgICAgIHJldHVybiB0W2tleV0uYXBwbHkodCwgYXJncyk7XG4gICAgfTtcbn0pO1xuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QuaGFzT3duUHJvcGVydHkgfHwgZnVuY3Rpb24gKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGtleSBpbiBvYmo7XG59O1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgbGFuZztcblxuICBsYW5nID0gZnVuY3Rpb24obW9tZW50LCBUd2l4KSB7XG4gICAgdmFyIGJlZm9yZTtcbiAgICBiZWZvcmUgPSBtb21lbnQubGFuZygpO1xuICAgIFR3aXgucmVnaXN0ZXJMYW5nKFwiZnJcIiwge1xuICAgICAgdHdlbnR5Rm91ckhvdXI6IHRydWUsXG4gICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMuZGF5Rm9ybWF0ICsgXCIgXCIgKyBvcHRpb25zLm1vbnRoRm9ybWF0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBzbG90OiAzXG4gICAgICB9LFxuICAgICAgbW9udGg6IHtcbiAgICAgICAgc2xvdDogM1xuICAgICAgfSxcbiAgICAgIGRhdGU6IHtcbiAgICAgICAgc2xvdDogMlxuICAgICAgfVxuICAgIH0pO1xuICAgIFR3aXgucmVnaXN0ZXJMYW5nKFwiZnItY2FcIiwge1xuICAgICAgdHdlbnR5Rm91ckhvdXI6IHRydWUsXG4gICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMuZGF5Rm9ybWF0ICsgXCIgXCIgKyBvcHRpb25zLm1vbnRoRm9ybWF0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBzbG90OiAzXG4gICAgICB9LFxuICAgICAgbW9udGg6IHtcbiAgICAgICAgc2xvdDogM1xuICAgICAgfSxcbiAgICAgIGRhdGU6IHtcbiAgICAgICAgc2xvdDogMlxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtb21lbnQubGFuZyhiZWZvcmUpO1xuICB9O1xuXG4gIGlmICgodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUgIT09IG51bGwpICYmIChtb2R1bGUuZXhwb3J0cyAhPSBudWxsKSkge1xuICAgIG1vZHVsZS5leHBvcnRzID0gbGFuZztcbiAgfVxuXG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXCJtb21lbnRcIiwgXCJ0d2l4XCJdLCBmdW5jdGlvbihtb21lbnQsIFR3aXgpIHtcbiAgICAgIHJldHVybiBsYW5nKG1vbWVudCwgVHdpeCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAodGhpcy5Ud2l4ICYmIHRoaXMubW9tZW50KSB7XG4gICAgbGFuZyh0aGlzLm1vbWVudCwgdGhpcy5Ud2l4KTtcbiAgfVxuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgZGVwcmVjYXRlLCBoYXNNb2R1bGUsIG1ha2VUd2l4LFxuICAgIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuICBoYXNNb2R1bGUgPSAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUgIT09IG51bGwpICYmIChtb2R1bGUuZXhwb3J0cyAhPSBudWxsKTtcblxuICBkZXByZWNhdGUgPSBmdW5jdGlvbihuYW1lLCBpbnN0ZWFkLCBmbikge1xuICAgIHZhciBhbHJlYWR5RG9uZTtcbiAgICBhbHJlYWR5RG9uZSA9IGZhbHNlO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzO1xuICAgICAgYXJncyA9IDEgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDApIDogW107XG4gICAgICBpZiAoIWFscmVhZHlEb25lKSB7XG4gICAgICAgIGlmICgodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29uc29sZSAhPT0gbnVsbCkgJiYgKGNvbnNvbGUud2FybiAhPSBudWxsKSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcIiNcIiArIG5hbWUgKyBcIiBpcyBkZXByZWNhdGVkLiBVc2UgI1wiICsgaW5zdGVhZCArIFwiIGluc3RlYWQuXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhbHJlYWR5RG9uZSA9IHRydWU7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfTtcbiAgfTtcblxuICBtYWtlVHdpeCA9IGZ1bmN0aW9uKG1vbWVudCkge1xuICAgIHZhciBUd2l4LCBnZXRQcm90b3R5cGVPZiwgbGFuZ3VhZ2VzTG9hZGVkO1xuICAgIGlmIChtb21lbnQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgXCJDYW4ndCBmaW5kIG1vbWVudFwiO1xuICAgIH1cbiAgICBsYW5ndWFnZXNMb2FkZWQgPSBmYWxzZTtcbiAgICBUd2l4ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gVHdpeChzdGFydCwgZW5kLCBwYXJzZUZvcm1hdCwgb3B0aW9ucykge1xuICAgICAgICB2YXIgX3JlZjtcbiAgICAgICAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhcnNlRm9ybWF0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IHBhcnNlRm9ybWF0ICE9IG51bGwgPyBwYXJzZUZvcm1hdCA6IHt9O1xuICAgICAgICAgIHBhcnNlRm9ybWF0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGFsbERheTogb3B0aW9uc1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGFydCA9IG1vbWVudChzdGFydCwgcGFyc2VGb3JtYXQsIG9wdGlvbnMucGFyc2VTdHJpY3QpO1xuICAgICAgICB0aGlzLmVuZCA9IG1vbWVudChlbmQsIHBhcnNlRm9ybWF0LCBvcHRpb25zLnBhcnNlU3RyaWN0KTtcbiAgICAgICAgdGhpcy5hbGxEYXkgPSAoX3JlZiA9IG9wdGlvbnMuYWxsRGF5KSAhPSBudWxsID8gX3JlZiA6IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBUd2l4Ll9leHRlbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGF0dHIsIGZpcnN0LCBvdGhlciwgb3RoZXJzLCBfaSwgX2xlbjtcbiAgICAgICAgZmlyc3QgPSBhcmd1bWVudHNbMF0sIG90aGVycyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpIDogW107XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gb3RoZXJzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgb3RoZXIgPSBvdGhlcnNbX2ldO1xuICAgICAgICAgIGZvciAoYXR0ciBpbiBvdGhlcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvdGhlclthdHRyXSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICBmaXJzdFthdHRyXSA9IG90aGVyW2F0dHJdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlyc3Q7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LmRlZmF1bHRzID0ge1xuICAgICAgICB0d2VudHlGb3VySG91cjogZmFsc2UsXG4gICAgICAgIGFsbERheVNpbXBsZToge1xuICAgICAgICAgIGZuOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmFsbERheTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiAwLFxuICAgICAgICAgIHByZTogXCIgXCJcbiAgICAgICAgfSxcbiAgICAgICAgZGF5T2ZXZWVrOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChvcHRpb25zLndlZWtkYXlGb3JtYXQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDEsXG4gICAgICAgICAgcHJlOiBcIiBcIlxuICAgICAgICB9LFxuICAgICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICAgIGZuOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZGF0ZSkge1xuICAgICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMubW9udGhGb3JtYXQgKyBcIiBcIiArIG9wdGlvbnMuZGF5Rm9ybWF0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiAyLFxuICAgICAgICAgIHByZTogXCIgXCJcbiAgICAgICAgfSxcbiAgICAgICAgbW9udGg6IHtcbiAgICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRhdGUuZm9ybWF0KG9wdGlvbnMubW9udGhGb3JtYXQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDIsXG4gICAgICAgICAgcHJlOiBcIiBcIlxuICAgICAgICB9LFxuICAgICAgICBkYXRlOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChvcHRpb25zLmRheUZvcm1hdCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2xvdDogMyxcbiAgICAgICAgICBwcmU6IFwiIFwiXG4gICAgICAgIH0sXG4gICAgICAgIHllYXI6IHtcbiAgICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRhdGUuZm9ybWF0KG9wdGlvbnMueWVhckZvcm1hdCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2xvdDogNCxcbiAgICAgICAgICBwcmU6IFwiLCBcIlxuICAgICAgICB9LFxuICAgICAgICB0aW1lOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHZhciBzdHI7XG4gICAgICAgICAgICAgIHN0ciA9IGRhdGUubWludXRlcygpID09PSAwICYmIG9wdGlvbnMuaW1wbGljaXRNaW51dGVzICYmICFvcHRpb25zLnR3ZW50eUZvdXJIb3VyID8gZGF0ZS5mb3JtYXQob3B0aW9ucy5ob3VyRm9ybWF0KSA6IGRhdGUuZm9ybWF0KFwiXCIgKyBvcHRpb25zLmhvdXJGb3JtYXQgKyBcIjpcIiArIG9wdGlvbnMubWludXRlRm9ybWF0KTtcbiAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmdyb3VwTWVyaWRpZW1zICYmICFvcHRpb25zLnR3ZW50eUZvdXJIb3VyKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3BhY2VCZWZvcmVNZXJpZGllbSkge1xuICAgICAgICAgICAgICAgICAgc3RyICs9IFwiIFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzdHIgKz0gZGF0ZS5mb3JtYXQob3B0aW9ucy5tZXJpZGllbUZvcm1hdCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiA1LFxuICAgICAgICAgIHByZTogXCIsIFwiXG4gICAgICAgIH0sXG4gICAgICAgIG1lcmlkaWVtOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdC5mb3JtYXQob3B0aW9ucy5tZXJpZGllbUZvcm1hdCk7XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDYsXG4gICAgICAgICAgcHJlOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zcGFjZUJlZm9yZU1lcmlkaWVtKSB7XG4gICAgICAgICAgICAgIHJldHVybiBcIiBcIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgVHdpeC5yZWdpc3RlckxhbmcgPSBmdW5jdGlvbihuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQubGFuZyhuYW1lLCB7XG4gICAgICAgICAgdHdpeDogVHdpeC5fZXh0ZW5kKHt9LCBUd2l4LmRlZmF1bHRzLCBvcHRpb25zKVxuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmlzU2FtZSA9IGZ1bmN0aW9uKHBlcmlvZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5pc1NhbWUodGhpcy5lbmQsIHBlcmlvZCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbihwZXJpb2QpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RydWVFbmQodHJ1ZSkuZGlmZih0aGlzLl90cnVlU3RhcnQoKSwgcGVyaW9kKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmNvdW50ID0gZnVuY3Rpb24ocGVyaW9kKSB7XG4gICAgICAgIHZhciBlbmQsIHN0YXJ0O1xuICAgICAgICBzdGFydCA9IHRoaXMuc3RhcnQuY2xvbmUoKS5zdGFydE9mKHBlcmlvZCk7XG4gICAgICAgIGVuZCA9IHRoaXMuZW5kLmNsb25lKCkuc3RhcnRPZihwZXJpb2QpO1xuICAgICAgICByZXR1cm4gZW5kLmRpZmYoc3RhcnQsIHBlcmlvZCkgKyAxO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuY291bnRJbm5lciA9IGZ1bmN0aW9uKHBlcmlvZCkge1xuICAgICAgICB2YXIgZW5kLCBzdGFydCwgX3JlZjtcbiAgICAgICAgX3JlZiA9IHRoaXMuX2lubmVyKHBlcmlvZCksIHN0YXJ0ID0gX3JlZlswXSwgZW5kID0gX3JlZlsxXTtcbiAgICAgICAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbmQuZGlmZihzdGFydCwgcGVyaW9kKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbihpbnRlcnZhbEFtb3VudCwgcGVyaW9kLCBtaW5Ib3Vycykge1xuICAgICAgICB2YXIgZW5kLCBoYXNOZXh0LCBzdGFydCwgX3JlZjtcbiAgICAgICAgaWYgKGludGVydmFsQW1vdW50ID09IG51bGwpIHtcbiAgICAgICAgICBpbnRlcnZhbEFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgX3JlZiA9IHRoaXMuX3ByZXBJdGVyYXRlSW5wdXRzKGludGVydmFsQW1vdW50LCBwZXJpb2QsIG1pbkhvdXJzKSwgaW50ZXJ2YWxBbW91bnQgPSBfcmVmWzBdLCBwZXJpb2QgPSBfcmVmWzFdLCBtaW5Ib3VycyA9IF9yZWZbMl07XG4gICAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5jbG9uZSgpLnN0YXJ0T2YocGVyaW9kKTtcbiAgICAgICAgZW5kID0gdGhpcy5lbmQuY2xvbmUoKS5zdGFydE9mKHBlcmlvZCk7XG4gICAgICAgIGhhc05leHQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnQgPD0gZW5kICYmICghbWluSG91cnMgfHwgc3RhcnQudmFsdWVPZigpICE9PSBlbmQudmFsdWVPZigpIHx8IF90aGlzLmVuZC5ob3VycygpID4gbWluSG91cnMgfHwgX3RoaXMuYWxsRGF5KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXJhdGVIZWxwZXIocGVyaW9kLCBzdGFydCwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaXRlcmF0ZUlubmVyID0gZnVuY3Rpb24oaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCkge1xuICAgICAgICB2YXIgZW5kLCBoYXNOZXh0LCBzdGFydCwgX3JlZiwgX3JlZjE7XG4gICAgICAgIGlmIChpbnRlcnZhbEFtb3VudCA9PSBudWxsKSB7XG4gICAgICAgICAgaW50ZXJ2YWxBbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIF9yZWYgPSB0aGlzLl9wcmVwSXRlcmF0ZUlucHV0cyhpbnRlcnZhbEFtb3VudCwgcGVyaW9kKSwgaW50ZXJ2YWxBbW91bnQgPSBfcmVmWzBdLCBwZXJpb2QgPSBfcmVmWzFdO1xuICAgICAgICBfcmVmMSA9IHRoaXMuX2lubmVyKHBlcmlvZCwgaW50ZXJ2YWxBbW91bnQpLCBzdGFydCA9IF9yZWYxWzBdLCBlbmQgPSBfcmVmMVsxXTtcbiAgICAgICAgaGFzTmV4dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBzdGFydCA8IGVuZDtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXJhdGVIZWxwZXIocGVyaW9kLCBzdGFydCwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaHVtYW5pemVMZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgaWYgKHRoaXMuaXNTYW1lKFwiZGF5XCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJhbGwgZGF5XCI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0LmZyb20odGhpcy5lbmQuY2xvbmUoKS5hZGQoMSwgXCJkYXlcIiksIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5mcm9tKHRoaXMuZW5kLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuYXNEdXJhdGlvbiA9IGZ1bmN0aW9uKHVuaXRzKSB7XG4gICAgICAgIHZhciBkaWZmO1xuICAgICAgICBkaWZmID0gdGhpcy5lbmQuZGlmZih0aGlzLnN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIG1vbWVudC5kdXJhdGlvbihkaWZmKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmlzUGFzdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbmQuY2xvbmUoKS5lbmRPZihcImRheVwiKSA8IG1vbWVudCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVuZCA8IG1vbWVudCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc0Z1dHVyZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5jbG9uZSgpLnN0YXJ0T2YoXCJkYXlcIikgPiBtb21lbnQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydCA+IG1vbWVudCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc0N1cnJlbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzUGFzdCgpICYmICF0aGlzLmlzRnV0dXJlKCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKG1vbSkge1xuICAgICAgICBtb20gPSBtb21lbnQobW9tKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RydWVTdGFydCgpIDw9IG1vbSAmJiB0aGlzLl90cnVlRW5kKCkgPj0gbW9tO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZVN0YXJ0KCkudmFsdWVPZigpID09PSB0aGlzLl90cnVlRW5kKCkudmFsdWVPZigpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUub3ZlcmxhcHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZUVuZCgpLmlzQWZ0ZXIob3RoZXIuX3RydWVTdGFydCgpKSAmJiB0aGlzLl90cnVlU3RhcnQoKS5pc0JlZm9yZShvdGhlci5fdHJ1ZUVuZCgpKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmVuZ3VsZnMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZVN0YXJ0KCkgPD0gb3RoZXIuX3RydWVTdGFydCgpICYmIHRoaXMuX3RydWVFbmQoKSA+PSBvdGhlci5fdHJ1ZUVuZCgpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUudW5pb24gPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICB2YXIgYWxsRGF5LCBuZXdFbmQsIG5ld1N0YXJ0O1xuICAgICAgICBhbGxEYXkgPSB0aGlzLmFsbERheSAmJiBvdGhlci5hbGxEYXk7XG4gICAgICAgIGlmIChhbGxEYXkpIHtcbiAgICAgICAgICBuZXdTdGFydCA9IHRoaXMuc3RhcnQgPCBvdGhlci5zdGFydCA/IHRoaXMuc3RhcnQgOiBvdGhlci5zdGFydDtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLmVuZCA+IG90aGVyLmVuZCA/IHRoaXMuZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1N0YXJ0ID0gdGhpcy5fdHJ1ZVN0YXJ0KCkgPCBvdGhlci5fdHJ1ZVN0YXJ0KCkgPyB0aGlzLl90cnVlU3RhcnQoKSA6IG90aGVyLl90cnVlU3RhcnQoKTtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLl90cnVlRW5kKCkgPiBvdGhlci5fdHJ1ZUVuZCgpID8gdGhpcy5fdHJ1ZUVuZCgpIDogb3RoZXIuX3RydWVFbmQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFR3aXgobmV3U3RhcnQsIG5ld0VuZCwgYWxsRGF5KTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICAgIHZhciBhbGxEYXksIGVuZCwgbmV3RW5kLCBuZXdTdGFydDtcbiAgICAgICAgbmV3U3RhcnQgPSB0aGlzLnN0YXJ0ID4gb3RoZXIuc3RhcnQgPyB0aGlzLnN0YXJ0IDogb3RoZXIuc3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSkge1xuICAgICAgICAgIGVuZCA9IG1vbWVudCh0aGlzLmVuZCk7XG4gICAgICAgICAgZW5kLmFkZCgxLCBcImRheVwiKTtcbiAgICAgICAgICBlbmQuc3VidHJhY3QoMSwgXCJtaWxsaXNlY29uZFwiKTtcbiAgICAgICAgICBpZiAob3RoZXIuYWxsRGF5KSB7XG4gICAgICAgICAgICBuZXdFbmQgPSBlbmQgPCBvdGhlci5lbmQgPyB0aGlzLmVuZCA6IG90aGVyLmVuZDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3RW5kID0gZW5kIDwgb3RoZXIuZW5kID8gZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLmVuZCA8IG90aGVyLmVuZCA/IHRoaXMuZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICB9XG4gICAgICAgIGFsbERheSA9IHRoaXMuYWxsRGF5ICYmIG90aGVyLmFsbERheTtcbiAgICAgICAgcmV0dXJuIG5ldyBUd2l4KG5ld1N0YXJ0LCBuZXdFbmQsIGFsbERheSk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc1ZhbGlkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cnVlU3RhcnQoKSA8PSB0aGlzLl90cnVlRW5kKCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gKG90aGVyIGluc3RhbmNlb2YgVHdpeCkgJiYgdGhpcy5hbGxEYXkgPT09IG90aGVyLmFsbERheSAmJiB0aGlzLnN0YXJ0LnZhbHVlT2YoKSA9PT0gb3RoZXIuc3RhcnQudmFsdWVPZigpICYmIHRoaXMuZW5kLnZhbHVlT2YoKSA9PT0gb3RoZXIuZW5kLnZhbHVlT2YoKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfcmVmO1xuICAgICAgICByZXR1cm4gXCJ7c3RhcnQ6IFwiICsgKHRoaXMuc3RhcnQuZm9ybWF0KCkpICsgXCIsIGVuZDogXCIgKyAodGhpcy5lbmQuZm9ybWF0KCkpICsgXCIsIGFsbERheTogXCIgKyAoKF9yZWYgPSB0aGlzLmFsbERheSkgIT0gbnVsbCA/IF9yZWYgOiB7XG4gICAgICAgICAgXCJ0cnVlXCI6IFwiZmFsc2VcIlxuICAgICAgICB9KSArIFwifVwiO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuc2ltcGxlRm9ybWF0ID0gZnVuY3Rpb24obW9tZW50T3B0cywgaW5vcHRzKSB7XG4gICAgICAgIHZhciBvcHRpb25zLCBzO1xuICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgIGFsbERheTogXCIoYWxsIGRheSlcIixcbiAgICAgICAgICB0ZW1wbGF0ZTogVHdpeC5mb3JtYXRUZW1wbGF0ZVxuICAgICAgICB9O1xuICAgICAgICBUd2l4Ll9leHRlbmQob3B0aW9ucywgaW5vcHRzIHx8IHt9KTtcbiAgICAgICAgcyA9IG9wdGlvbnMudGVtcGxhdGUodGhpcy5zdGFydC5mb3JtYXQobW9tZW50T3B0cyksIHRoaXMuZW5kLmZvcm1hdChtb21lbnRPcHRzKSk7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSAmJiBvcHRpb25zLmFsbERheSkge1xuICAgICAgICAgIHMgKz0gXCIgXCIgKyBvcHRpb25zLmFsbERheTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcztcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uKGlub3B0cykge1xuICAgICAgICB2YXIgY29tbW9uX2J1Y2tldCwgZW5kX2J1Y2tldCwgZm9sZCwgZm9ybWF0LCBmcywgZ2xvYmFsX2ZpcnN0LCBnb2VzSW50b1RoZU1vcm5pbmcsIG5lZWREYXRlLCBvcHRpb25zLCBwcm9jZXNzLCBzdGFydF9idWNrZXQsIHRvZ2V0aGVyLCBfaSwgX2xlbjtcbiAgICAgICAgdGhpcy5fbGF6eUxhbmcoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICBncm91cE1lcmlkaWVtczogdHJ1ZSxcbiAgICAgICAgICBzcGFjZUJlZm9yZU1lcmlkaWVtOiB0cnVlLFxuICAgICAgICAgIHNob3dEYXRlOiB0cnVlLFxuICAgICAgICAgIHNob3dEYXlPZldlZWs6IGZhbHNlLFxuICAgICAgICAgIHR3ZW50eUZvdXJIb3VyOiB0aGlzLmxhbmdEYXRhLnR3ZW50eUZvdXJIb3VyLFxuICAgICAgICAgIGltcGxpY2l0TWludXRlczogdHJ1ZSxcbiAgICAgICAgICBpbXBsaWNpdFllYXI6IHRydWUsXG4gICAgICAgICAgeWVhckZvcm1hdDogXCJZWVlZXCIsXG4gICAgICAgICAgbW9udGhGb3JtYXQ6IFwiTU1NXCIsXG4gICAgICAgICAgd2Vla2RheUZvcm1hdDogXCJkZGRcIixcbiAgICAgICAgICBkYXlGb3JtYXQ6IFwiRFwiLFxuICAgICAgICAgIG1lcmlkaWVtRm9ybWF0OiBcIkFcIixcbiAgICAgICAgICBob3VyRm9ybWF0OiBcImhcIixcbiAgICAgICAgICBtaW51dGVGb3JtYXQ6IFwibW1cIixcbiAgICAgICAgICBhbGxEYXk6IFwiYWxsIGRheVwiLFxuICAgICAgICAgIGV4cGxpY2l0QWxsRGF5OiBmYWxzZSxcbiAgICAgICAgICBsYXN0TmlnaHRFbmRzQXQ6IDAsXG4gICAgICAgICAgdGVtcGxhdGU6IFR3aXguZm9ybWF0VGVtcGxhdGVcbiAgICAgICAgfTtcbiAgICAgICAgVHdpeC5fZXh0ZW5kKG9wdGlvbnMsIGlub3B0cyB8fCB7fSk7XG4gICAgICAgIGZzID0gW107XG4gICAgICAgIGlmIChvcHRpb25zLnR3ZW50eUZvdXJIb3VyKSB7XG4gICAgICAgICAgb3B0aW9ucy5ob3VyRm9ybWF0ID0gb3B0aW9ucy5ob3VyRm9ybWF0LnJlcGxhY2UoXCJoXCIsIFwiSFwiKTtcbiAgICAgICAgfVxuICAgICAgICBnb2VzSW50b1RoZU1vcm5pbmcgPSBvcHRpb25zLmxhc3ROaWdodEVuZHNBdCA+IDAgJiYgIXRoaXMuYWxsRGF5ICYmIHRoaXMuZW5kLmNsb25lKCkuc3RhcnRPZihcImRheVwiKS52YWx1ZU9mKCkgPT09IHRoaXMuc3RhcnQuY2xvbmUoKS5hZGQoMSwgXCJkYXlcIikuc3RhcnRPZihcImRheVwiKS52YWx1ZU9mKCkgJiYgdGhpcy5zdGFydC5ob3VycygpID4gMTIgJiYgdGhpcy5lbmQuaG91cnMoKSA8IG9wdGlvbnMubGFzdE5pZ2h0RW5kc0F0O1xuICAgICAgICBuZWVkRGF0ZSA9IG9wdGlvbnMuc2hvd0RhdGUgfHwgKCF0aGlzLmlzU2FtZShcImRheVwiKSAmJiAhZ29lc0ludG9UaGVNb3JuaW5nKTtcbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5ICYmIHRoaXMuaXNTYW1lKFwiZGF5XCIpICYmICghb3B0aW9ucy5zaG93RGF0ZSB8fCBvcHRpb25zLmV4cGxpY2l0QWxsRGF5KSkge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJhbGwgZGF5IHNpbXBsZVwiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdhbGxEYXlTaW1wbGUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCdhbGxEYXlTaW1wbGUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ2FsbERheVNpbXBsZScpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lZWREYXRlICYmICghb3B0aW9ucy5pbXBsaWNpdFllYXIgfHwgdGhpcy5zdGFydC55ZWFyKCkgIT09IG1vbWVudCgpLnllYXIoKSB8fCAhdGhpcy5pc1NhbWUoXCJ5ZWFyXCIpKSkge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJ5ZWFyXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ3llYXInLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCd5ZWFyJywgb3B0aW9ucyksXG4gICAgICAgICAgICBzbG90OiB0aGlzLl9mb3JtYXRTbG90KCd5ZWFyJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuYWxsRGF5ICYmIG5lZWREYXRlKSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcImFsbCBkYXkgbW9udGhcIixcbiAgICAgICAgICAgIGZuOiB0aGlzLl9mb3JtYXRGbignYWxsRGF5TW9udGgnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIGlnbm9yZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiBnb2VzSW50b1RoZU1vcm5pbmc7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJlOiB0aGlzLl9mb3JtYXRQcmUoJ2FsbERheU1vbnRoJywgb3B0aW9ucyksXG4gICAgICAgICAgICBzbG90OiB0aGlzLl9mb3JtYXRTbG90KCdhbGxEYXlNb250aCcpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5ICYmIG5lZWREYXRlKSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcIm1vbnRoXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ21vbnRoJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnbW9udGgnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ21vbnRoJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbGxEYXkgJiYgbmVlZERhdGUpIHtcbiAgICAgICAgICBmcy5wdXNoKHtcbiAgICAgICAgICAgIG5hbWU6IFwiZGF0ZVwiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdkYXRlJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnZGF0ZScsIG9wdGlvbnMpLFxuICAgICAgICAgICAgc2xvdDogdGhpcy5fZm9ybWF0U2xvdCgnZGF0ZScpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lZWREYXRlICYmIG9wdGlvbnMuc2hvd0RheU9mV2Vlaykge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJkYXkgb2Ygd2Vla1wiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdkYXlPZldlZWsnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCdkYXlPZldlZWsnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ2RheU9mV2VlaycpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZ3JvdXBNZXJpZGllbXMgJiYgIW9wdGlvbnMudHdlbnR5Rm91ckhvdXIgJiYgIXRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcIm1lcmlkaWVtXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ21lcmlkaWVtJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnbWVyaWRpZW0nLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ21lcmlkaWVtJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcInRpbWVcIixcbiAgICAgICAgICAgIGZuOiB0aGlzLl9mb3JtYXRGbigndGltZScsIG9wdGlvbnMpLFxuICAgICAgICAgICAgcHJlOiB0aGlzLl9mb3JtYXRQcmUoJ3RpbWUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ3RpbWUnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0X2J1Y2tldCA9IFtdO1xuICAgICAgICBlbmRfYnVja2V0ID0gW107XG4gICAgICAgIGNvbW1vbl9idWNrZXQgPSBbXTtcbiAgICAgICAgdG9nZXRoZXIgPSB0cnVlO1xuICAgICAgICBwcm9jZXNzID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGZvcm1hdCkge1xuICAgICAgICAgICAgdmFyIGVuZF9zdHIsIHN0YXJ0X2dyb3VwLCBzdGFydF9zdHI7XG4gICAgICAgICAgICBzdGFydF9zdHIgPSBmb3JtYXQuZm4oX3RoaXMuc3RhcnQpO1xuICAgICAgICAgICAgZW5kX3N0ciA9IGZvcm1hdC5pZ25vcmVFbmQgJiYgZm9ybWF0Lmlnbm9yZUVuZCgpID8gc3RhcnRfc3RyIDogZm9ybWF0LmZuKF90aGlzLmVuZCk7XG4gICAgICAgICAgICBzdGFydF9ncm91cCA9IHtcbiAgICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRfc3RyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGVuZF9zdHIgPT09IHN0YXJ0X3N0ciAmJiB0b2dldGhlcikge1xuICAgICAgICAgICAgICByZXR1cm4gY29tbW9uX2J1Y2tldC5wdXNoKHN0YXJ0X2dyb3VwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh0b2dldGhlcikge1xuICAgICAgICAgICAgICAgIHRvZ2V0aGVyID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY29tbW9uX2J1Y2tldC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgICAgICAgICAgICBzbG90OiBmb3JtYXQuc2xvdCxcbiAgICAgICAgICAgICAgICAgICAgcHJlOiBcIlwiXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy50ZW1wbGF0ZShmb2xkKHN0YXJ0X2J1Y2tldCksIGZvbGQoZW5kX2J1Y2tldCwgdHJ1ZSkudHJpbSgpKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzdGFydF9idWNrZXQucHVzaChzdGFydF9ncm91cCk7XG4gICAgICAgICAgICAgIHJldHVybiBlbmRfYnVja2V0LnB1c2goe1xuICAgICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlbmRfc3RyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcyk7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZnMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgICBmb3JtYXQgPSBmc1tfaV07XG4gICAgICAgICAgcHJvY2Vzcyhmb3JtYXQpO1xuICAgICAgICB9XG4gICAgICAgIGdsb2JhbF9maXJzdCA9IHRydWU7XG4gICAgICAgIGZvbGQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIHNraXBfcHJlKSB7XG4gICAgICAgICAgICB2YXIgbG9jYWxfZmlyc3QsIHNlY3Rpb24sIHN0ciwgX2osIF9sZW4xLCBfcmVmO1xuICAgICAgICAgICAgbG9jYWxfZmlyc3QgPSB0cnVlO1xuICAgICAgICAgICAgc3RyID0gXCJcIjtcbiAgICAgICAgICAgIF9yZWYgPSBhcnJheS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGEuZm9ybWF0LnNsb3QgLSBiLmZvcm1hdC5zbG90O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmb3IgKF9qID0gMCwgX2xlbjEgPSBfcmVmLmxlbmd0aDsgX2ogPCBfbGVuMTsgX2orKykge1xuICAgICAgICAgICAgICBzZWN0aW9uID0gX3JlZltfal07XG4gICAgICAgICAgICAgIGlmICghZ2xvYmFsX2ZpcnN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGxvY2FsX2ZpcnN0ICYmIHNraXBfcHJlKSB7XG4gICAgICAgICAgICAgICAgICBzdHIgKz0gXCIgXCI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHN0ciArPSBzZWN0aW9uLmZvcm1hdC5wcmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0ciArPSBzZWN0aW9uLnZhbHVlKCk7XG4gICAgICAgICAgICAgIGdsb2JhbF9maXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgICBsb2NhbF9maXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIGZvbGQoY29tbW9uX2J1Y2tldCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fdHJ1ZVN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0LmNsb25lKCkuc3RhcnRPZihcImRheVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5jbG9uZSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fdHJ1ZUVuZCA9IGZ1bmN0aW9uKGRpZmZhYmxlRW5kKSB7XG4gICAgICAgIGlmIChkaWZmYWJsZUVuZCA9PSBudWxsKSB7XG4gICAgICAgICAgZGlmZmFibGVFbmQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICBpZiAoZGlmZmFibGVFbmQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuZC5jbG9uZSgpLmFkZCgxLCBcImRheVwiKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5kLmNsb25lKCkuZW5kT2YoXCJkYXlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVuZC5jbG9uZSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5faXRlcmF0ZUhlbHBlciA9IGZ1bmN0aW9uKHBlcmlvZCwgaXRlciwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpIHtcbiAgICAgICAgaWYgKGludGVydmFsQW1vdW50ID09IG51bGwpIHtcbiAgICAgICAgICBpbnRlcnZhbEFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuZXh0OiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHZhbDtcbiAgICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWwgPSBpdGVyLmNsb25lKCk7XG4gICAgICAgICAgICAgICAgaXRlci5hZGQoaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKSxcbiAgICAgICAgICBoYXNOZXh0OiBoYXNOZXh0XG4gICAgICAgIH07XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fcHJlcEl0ZXJhdGVJbnB1dHMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGlucHV0cywgaW50ZXJ2YWxBbW91bnQsIG1pbkhvdXJzLCBwZXJpb2QsIF9yZWYsIF9yZWYxO1xuICAgICAgICBpbnB1dHMgPSAxIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSA6IFtdO1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0c1swXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXR1cm4gaW5wdXRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXRzWzBdID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHBlcmlvZCA9IGlucHV0cy5zaGlmdCgpO1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gKF9yZWYgPSBpbnB1dHMucG9wKCkpICE9IG51bGwgPyBfcmVmIDogMTtcbiAgICAgICAgICBpZiAoaW5wdXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgbWluSG91cnMgPSAoX3JlZjEgPSBpbnB1dHNbMF0pICE9IG51bGwgPyBfcmVmMSA6IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24oaW5wdXRzWzBdKSkge1xuICAgICAgICAgIHBlcmlvZCA9ICdtaWxsaXNlY29uZHMnO1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gaW5wdXRzWzBdLmFzKHBlcmlvZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtpbnRlcnZhbEFtb3VudCwgcGVyaW9kLCBtaW5Ib3Vyc107XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5faW5uZXIgPSBmdW5jdGlvbihwZXJpb2QsIGludGVydmFsQW1vdW50KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbkNvdW50LCBkdXJhdGlvblBlcmlvZCwgZW5kLCBtb2R1bHVzLCBzdGFydDtcbiAgICAgICAgaWYgKHBlcmlvZCA9PSBudWxsKSB7XG4gICAgICAgICAgcGVyaW9kID0gXCJtaWxsaXNlY29uZHNcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW50ZXJ2YWxBbW91bnQgPT0gbnVsbCkge1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCA9IHRoaXMuX3RydWVTdGFydCgpO1xuICAgICAgICBlbmQgPSB0aGlzLl90cnVlRW5kKHRydWUpO1xuICAgICAgICBpZiAoc3RhcnQgPiBzdGFydC5jbG9uZSgpLnN0YXJ0T2YocGVyaW9kKSkge1xuICAgICAgICAgIHN0YXJ0LnN0YXJ0T2YocGVyaW9kKS5hZGQoaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZCA8IGVuZC5jbG9uZSgpLmVuZE9mKHBlcmlvZCkpIHtcbiAgICAgICAgICBlbmQuc3RhcnRPZihwZXJpb2QpO1xuICAgICAgICB9XG4gICAgICAgIGR1cmF0aW9uUGVyaW9kID0gc3RhcnQudHdpeChlbmQpLmFzRHVyYXRpb24ocGVyaW9kKTtcbiAgICAgICAgZHVyYXRpb25Db3VudCA9IGR1cmF0aW9uUGVyaW9kLmdldChwZXJpb2QpO1xuICAgICAgICBtb2R1bHVzID0gZHVyYXRpb25Db3VudCAlIGludGVydmFsQW1vdW50O1xuICAgICAgICBlbmQuc3VidHJhY3QobW9kdWx1cywgcGVyaW9kKTtcbiAgICAgICAgcmV0dXJuIFtzdGFydCwgZW5kXTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLl9sYXp5TGFuZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZSwgbGFuZ0RhdGEsIGxhbmd1YWdlcywgX3JlZjtcbiAgICAgICAgbGFuZ0RhdGEgPSB0aGlzLnN0YXJ0LmxhbmcoKTtcbiAgICAgICAgaWYgKChsYW5nRGF0YSAhPSBudWxsKSAmJiB0aGlzLmVuZC5sYW5nKCkuX2FiYnIgIT09IGxhbmdEYXRhLl9hYmJyKSB7XG4gICAgICAgICAgdGhpcy5lbmQubGFuZyhsYW5nRGF0YS5fYWJicik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCh0aGlzLmxhbmdEYXRhICE9IG51bGwpICYmIHRoaXMubGFuZ0RhdGEuX2FiYnIgPT09IGxhbmdEYXRhLl9hYmJyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNNb2R1bGUgJiYgIShsYW5ndWFnZXNMb2FkZWQgfHwgbGFuZ0RhdGEuX2FiYnIgPT09IFwiZW5cIikpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGFuZ3VhZ2VzID0gcmVxdWlyZShcIi4vbGFuZ1wiKTtcbiAgICAgICAgICAgIGxhbmd1YWdlcyhtb21lbnQsIFR3aXgpO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZSA9IF9lcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGFuZ3VhZ2VzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5sYW5nRGF0YSA9IChfcmVmID0gbGFuZ0RhdGEgIT0gbnVsbCA/IGxhbmdEYXRhLl90d2l4IDogdm9pZCAwKSAhPSBudWxsID8gX3JlZiA6IFR3aXguZGVmYXVsdHM7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fZm9ybWF0Rm4gPSBmdW5jdGlvbihuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhbmdEYXRhW25hbWVdLmZuKG9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuX2Zvcm1hdFNsb3QgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhbmdEYXRhW25hbWVdLnNsb3Q7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fZm9ybWF0UHJlID0gZnVuY3Rpb24obmFtZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMubGFuZ0RhdGFbbmFtZV0ucHJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5sYW5nRGF0YVtuYW1lXS5wcmUob3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubGFuZ0RhdGFbbmFtZV0ucHJlO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5zYW1lRGF5ID0gZGVwcmVjYXRlKFwic2FtZURheVwiLCBcImlzU2FtZSgnZGF5JylcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU2FtZShcImRheVwiKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5zYW1lWWVhciA9IGRlcHJlY2F0ZShcInNhbWVZZWFyXCIsIFwiaXNTYW1lKCd5ZWFyJylcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU2FtZShcInllYXJcIik7XG4gICAgICB9KTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuY291bnREYXlzID0gZGVwcmVjYXRlKFwiY291bnREYXlzXCIsIFwiY291bnRPdXRlcignZGF5cycpXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb3VudE91dGVyKFwiZGF5c1wiKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5kYXlzSW4gPSBkZXByZWNhdGUoXCJkYXlzSW5cIiwgXCJpdGVyYXRlKCdkYXlzJyBbLG1pbkhvdXJzXSlcIiwgZnVuY3Rpb24obWluSG91cnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlcmF0ZSgnZGF5cycsIG1pbkhvdXJzKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5wYXN0ID0gZGVwcmVjYXRlKFwicGFzdFwiLCBcImlzUGFzdCgpXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1Bhc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5kdXJhdGlvbiA9IGRlcHJlY2F0ZShcImR1cmF0aW9uXCIsIFwiaHVtYW5pemVMZW5ndGgoKVwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHVtYW5pemVMZW5ndGgoKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5tZXJnZSA9IGRlcHJlY2F0ZShcIm1lcmdlXCIsIFwidW5pb24ob3RoZXIpXCIsIGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuaW9uKG90aGVyKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gVHdpeDtcblxuICAgIH0pKCk7XG4gICAgZ2V0UHJvdG90eXBlT2YgPSBmdW5jdGlvbihvKSB7XG4gICAgICBpZiAodHlwZW9mIE9iamVjdC5nZXRQcm90b3R5cGVPZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gICAgICB9IGVsc2UgaWYgKFwiXCIuX19wcm90b19fID09PSBTdHJpbmcucHJvdG90eXBlKSB7XG4gICAgICAgIHJldHVybiBvLl9fcHJvdG9fXztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIFR3aXguX2V4dGVuZChtb21lbnQuX2xvY2FsZSB8fCBnZXRQcm90b3R5cGVPZihtb21lbnQuZm4uX2xhbmcpLCB7XG4gICAgICBfdHdpeDogVHdpeC5kZWZhdWx0c1xuICAgIH0pO1xuICAgIFR3aXguZm9ybWF0VGVtcGxhdGUgPSBmdW5jdGlvbihsZWZ0U2lkZSwgcmlnaHRTaWRlKSB7XG4gICAgICByZXR1cm4gXCJcIiArIGxlZnRTaWRlICsgXCIgLSBcIiArIHJpZ2h0U2lkZTtcbiAgICB9O1xuICAgIG1vbWVudC50d2l4ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gKGZ1bmN0aW9uKGZ1bmMsIGFyZ3MsIGN0b3IpIHtcbiAgICAgICAgY3Rvci5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcbiAgICAgICAgdmFyIGNoaWxkID0gbmV3IGN0b3IsIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY2hpbGQsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCA/IHJlc3VsdCA6IGNoaWxkO1xuICAgICAgfSkoVHdpeCwgYXJndW1lbnRzLCBmdW5jdGlvbigpe30pO1xuICAgIH07XG4gICAgbW9tZW50LmZuLnR3aXggPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAoZnVuY3Rpb24oZnVuYywgYXJncywgY3Rvcikge1xuICAgICAgICBjdG9yLnByb3RvdHlwZSA9IGZ1bmMucHJvdG90eXBlO1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgY3RvciwgcmVzdWx0ID0gZnVuYy5hcHBseShjaGlsZCwgYXJncyk7XG4gICAgICAgIHJldHVybiBPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0ID8gcmVzdWx0IDogY2hpbGQ7XG4gICAgICB9KShUd2l4LCBbdGhpc10uY29uY2F0KF9fc2xpY2UuY2FsbChhcmd1bWVudHMpKSwgZnVuY3Rpb24oKXt9KTtcbiAgICB9O1xuICAgIG1vbWVudC5mbi5mb3JEdXJhdGlvbiA9IGZ1bmN0aW9uKGR1cmF0aW9uLCBhbGxEYXkpIHtcbiAgICAgIHJldHVybiBuZXcgVHdpeCh0aGlzLCB0aGlzLmNsb25lKCkuYWRkKGR1cmF0aW9uKSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5hZnRlck1vbWVudCA9IGZ1bmN0aW9uKHN0YXJ0aW5nVGltZSwgYWxsRGF5KSB7XG4gICAgICByZXR1cm4gbmV3IFR3aXgoc3RhcnRpbmdUaW1lLCBtb21lbnQoc3RhcnRpbmdUaW1lKS5jbG9uZSgpLmFkZCh0aGlzKSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5iZWZvcmVNb21lbnQgPSBmdW5jdGlvbihzdGFydGluZ1RpbWUsIGFsbERheSkge1xuICAgICAgcmV0dXJuIG5ldyBUd2l4KG1vbWVudChzdGFydGluZ1RpbWUpLmNsb25lKCkuc3VidHJhY3QodGhpcyksIHN0YXJ0aW5nVGltZSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC50d2l4Q2xhc3MgPSBUd2l4O1xuICAgIHJldHVybiBUd2l4O1xuICB9O1xuXG4gIGlmIChoYXNNb2R1bGUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IG1ha2VUd2l4KHJlcXVpcmUoXCJtb21lbnRcIikpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGRlZmluZShcInR3aXhcIiwgW1wibW9tZW50XCJdLCBmdW5jdGlvbihtb21lbnQpIHtcbiAgICAgIHJldHVybiBtYWtlVHdpeChtb21lbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHRoaXMubW9tZW50ICE9IG51bGwpIHtcbiAgICB0aGlzLlR3aXggPSBtYWtlVHdpeCh0aGlzLm1vbWVudCk7XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vICAgICBVbmRlcnNjb3JlLmpzIDEuNS4yXG4vLyAgICAgaHR0cDovL3VuZGVyc2NvcmVqcy5vcmdcbi8vICAgICAoYykgMjAwOS0yMDEzIEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4vLyAgICAgVW5kZXJzY29yZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cblxuKGZ1bmN0aW9uKCkge1xuXG4gIC8vIEJhc2VsaW5lIHNldHVwXG4gIC8vIC0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gRXN0YWJsaXNoIHRoZSByb290IG9iamVjdCwgYHdpbmRvd2AgaW4gdGhlIGJyb3dzZXIsIG9yIGBleHBvcnRzYCBvbiB0aGUgc2VydmVyLlxuICB2YXIgcm9vdCA9IHRoaXM7XG5cbiAgLy8gU2F2ZSB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIGBfYCB2YXJpYWJsZS5cbiAgdmFyIHByZXZpb3VzVW5kZXJzY29yZSA9IHJvb3QuXztcblxuICAvLyBFc3RhYmxpc2ggdGhlIG9iamVjdCB0aGF0IGdldHMgcmV0dXJuZWQgdG8gYnJlYWsgb3V0IG9mIGEgbG9vcCBpdGVyYXRpb24uXG4gIHZhciBicmVha2VyID0ge307XG5cbiAgLy8gU2F2ZSBieXRlcyBpbiB0aGUgbWluaWZpZWQgKGJ1dCBub3QgZ3ppcHBlZCkgdmVyc2lvbjpcbiAgdmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGUsIE9ialByb3RvID0gT2JqZWN0LnByb3RvdHlwZSwgRnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIC8vIENyZWF0ZSBxdWljayByZWZlcmVuY2UgdmFyaWFibGVzIGZvciBzcGVlZCBhY2Nlc3MgdG8gY29yZSBwcm90b3R5cGVzLlxuICB2YXJcbiAgICBwdXNoICAgICAgICAgICAgID0gQXJyYXlQcm90by5wdXNoLFxuICAgIHNsaWNlICAgICAgICAgICAgPSBBcnJheVByb3RvLnNsaWNlLFxuICAgIGNvbmNhdCAgICAgICAgICAgPSBBcnJheVByb3RvLmNvbmNhdCxcbiAgICB0b1N0cmluZyAgICAgICAgID0gT2JqUHJvdG8udG9TdHJpbmcsXG4gICAgaGFzT3duUHJvcGVydHkgICA9IE9ialByb3RvLmhhc093blByb3BlcnR5O1xuXG4gIC8vIEFsbCAqKkVDTUFTY3JpcHQgNSoqIG5hdGl2ZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB3ZSBob3BlIHRvIHVzZVxuICAvLyBhcmUgZGVjbGFyZWQgaGVyZS5cbiAgdmFyXG4gICAgbmF0aXZlRm9yRWFjaCAgICAgID0gQXJyYXlQcm90by5mb3JFYWNoLFxuICAgIG5hdGl2ZU1hcCAgICAgICAgICA9IEFycmF5UHJvdG8ubWFwLFxuICAgIG5hdGl2ZVJlZHVjZSAgICAgICA9IEFycmF5UHJvdG8ucmVkdWNlLFxuICAgIG5hdGl2ZVJlZHVjZVJpZ2h0ICA9IEFycmF5UHJvdG8ucmVkdWNlUmlnaHQsXG4gICAgbmF0aXZlRmlsdGVyICAgICAgID0gQXJyYXlQcm90by5maWx0ZXIsXG4gICAgbmF0aXZlRXZlcnkgICAgICAgID0gQXJyYXlQcm90by5ldmVyeSxcbiAgICBuYXRpdmVTb21lICAgICAgICAgPSBBcnJheVByb3RvLnNvbWUsXG4gICAgbmF0aXZlSW5kZXhPZiAgICAgID0gQXJyYXlQcm90by5pbmRleE9mLFxuICAgIG5hdGl2ZUxhc3RJbmRleE9mICA9IEFycmF5UHJvdG8ubGFzdEluZGV4T2YsXG4gICAgbmF0aXZlSXNBcnJheSAgICAgID0gQXJyYXkuaXNBcnJheSxcbiAgICBuYXRpdmVLZXlzICAgICAgICAgPSBPYmplY3Qua2V5cyxcbiAgICBuYXRpdmVCaW5kICAgICAgICAgPSBGdW5jUHJvdG8uYmluZDtcblxuICAvLyBDcmVhdGUgYSBzYWZlIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QgZm9yIHVzZSBiZWxvdy5cbiAgdmFyIF8gPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgXykgcmV0dXJuIG9iajtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgXykpIHJldHVybiBuZXcgXyhvYmopO1xuICAgIHRoaXMuX3dyYXBwZWQgPSBvYmo7XG4gIH07XG5cbiAgLy8gRXhwb3J0IHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgKipOb2RlLmpzKiosIHdpdGhcbiAgLy8gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgZm9yIHRoZSBvbGQgYHJlcXVpcmUoKWAgQVBJLiBJZiB3ZSdyZSBpblxuICAvLyB0aGUgYnJvd3NlciwgYWRkIGBfYCBhcyBhIGdsb2JhbCBvYmplY3QgdmlhIGEgc3RyaW5nIGlkZW50aWZpZXIsXG4gIC8vIGZvciBDbG9zdXJlIENvbXBpbGVyIFwiYWR2YW5jZWRcIiBtb2RlLlxuICBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfO1xuICAgIH1cbiAgICBleHBvcnRzLl8gPSBfO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuXyA9IF87XG4gIH1cblxuICAvLyBDdXJyZW50IHZlcnNpb24uXG4gIF8uVkVSU0lPTiA9ICcxLjUuMic7XG5cbiAgLy8gQ29sbGVjdGlvbiBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBUaGUgY29ybmVyc3RvbmUsIGFuIGBlYWNoYCBpbXBsZW1lbnRhdGlvbiwgYWthIGBmb3JFYWNoYC5cbiAgLy8gSGFuZGxlcyBvYmplY3RzIHdpdGggdGhlIGJ1aWx0LWluIGBmb3JFYWNoYCwgYXJyYXlzLCBhbmQgcmF3IG9iamVjdHMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBmb3JFYWNoYCBpZiBhdmFpbGFibGUuXG4gIHZhciBlYWNoID0gXy5lYWNoID0gXy5mb3JFYWNoID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuO1xuICAgIGlmIChuYXRpdmVGb3JFYWNoICYmIG9iai5mb3JFYWNoID09PSBuYXRpdmVGb3JFYWNoKSB7XG4gICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXlzW2ldXSwga2V5c1tpXSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIHJlc3VsdHMgb2YgYXBwbHlpbmcgdGhlIGl0ZXJhdG9yIHRvIGVhY2ggZWxlbWVudC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYG1hcGAgaWYgYXZhaWxhYmxlLlxuICBfLm1hcCA9IF8uY29sbGVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdHM7XG4gICAgaWYgKG5hdGl2ZU1hcCAmJiBvYmoubWFwID09PSBuYXRpdmVNYXApIHJldHVybiBvYmoubWFwKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICB2YXIgcmVkdWNlRXJyb3IgPSAnUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZSc7XG5cbiAgLy8gKipSZWR1Y2UqKiBidWlsZHMgdXAgYSBzaW5nbGUgcmVzdWx0IGZyb20gYSBsaXN0IG9mIHZhbHVlcywgYWthIGBpbmplY3RgLFxuICAvLyBvciBgZm9sZGxgLiBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgcmVkdWNlYCBpZiBhdmFpbGFibGUuXG4gIF8ucmVkdWNlID0gXy5mb2xkbCA9IF8uaW5qZWN0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgbWVtbywgY29udGV4dCkge1xuICAgIHZhciBpbml0aWFsID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpZiAobmF0aXZlUmVkdWNlICYmIG9iai5yZWR1Y2UgPT09IG5hdGl2ZVJlZHVjZSkge1xuICAgICAgaWYgKGNvbnRleHQpIGl0ZXJhdG9yID0gXy5iaW5kKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBpbml0aWFsID8gb2JqLnJlZHVjZShpdGVyYXRvciwgbWVtbykgOiBvYmoucmVkdWNlKGl0ZXJhdG9yKTtcbiAgICB9XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKCFpbml0aWFsKSB7XG4gICAgICAgIG1lbW8gPSB2YWx1ZTtcbiAgICAgICAgaW5pdGlhbCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZW1vID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBtZW1vLCB2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghaW5pdGlhbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihyZWR1Y2VFcnJvcik7XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gVGhlIHJpZ2h0LWFzc29jaWF0aXZlIHZlcnNpb24gb2YgcmVkdWNlLCBhbHNvIGtub3duIGFzIGBmb2xkcmAuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGByZWR1Y2VSaWdodGAgaWYgYXZhaWxhYmxlLlxuICBfLnJlZHVjZVJpZ2h0ID0gXy5mb2xkciA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIG1lbW8sIGNvbnRleHQpIHtcbiAgICB2YXIgaW5pdGlhbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xuICAgIGlmIChvYmogPT0gbnVsbCkgb2JqID0gW107XG4gICAgaWYgKG5hdGl2ZVJlZHVjZVJpZ2h0ICYmIG9iai5yZWR1Y2VSaWdodCA9PT0gbmF0aXZlUmVkdWNlUmlnaHQpIHtcbiAgICAgIGlmIChjb250ZXh0KSBpdGVyYXRvciA9IF8uYmluZChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgICByZXR1cm4gaW5pdGlhbCA/IG9iai5yZWR1Y2VSaWdodChpdGVyYXRvciwgbWVtbykgOiBvYmoucmVkdWNlUmlnaHQoaXRlcmF0b3IpO1xuICAgIH1cbiAgICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoICE9PSArbGVuZ3RoKSB7XG4gICAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgICAgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgfVxuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGluZGV4ID0ga2V5cyA/IGtleXNbLS1sZW5ndGhdIDogLS1sZW5ndGg7XG4gICAgICBpZiAoIWluaXRpYWwpIHtcbiAgICAgICAgbWVtbyA9IG9ialtpbmRleF07XG4gICAgICAgIGluaXRpYWwgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWVtbyA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgbWVtbywgb2JqW2luZGV4XSwgaW5kZXgsIGxpc3QpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghaW5pdGlhbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihyZWR1Y2VFcnJvcik7XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB3aGljaCBwYXNzZXMgYSB0cnV0aCB0ZXN0LiBBbGlhc2VkIGFzIGBkZXRlY3RgLlxuICBfLmZpbmQgPSBfLmRldGVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIGFueShvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkge1xuICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyB0aGF0IHBhc3MgYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgZmlsdGVyYCBpZiBhdmFpbGFibGUuXG4gIC8vIEFsaWFzZWQgYXMgYHNlbGVjdGAuXG4gIF8uZmlsdGVyID0gXy5zZWxlY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHRzO1xuICAgIGlmIChuYXRpdmVGaWx0ZXIgJiYgb2JqLmZpbHRlciA9PT0gbmF0aXZlRmlsdGVyKSByZXR1cm4gb2JqLmZpbHRlcihpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBmb3Igd2hpY2ggYSB0cnV0aCB0ZXN0IGZhaWxzLlxuICBfLnJlamVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiAhaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgIH0sIGNvbnRleHQpO1xuICB9O1xuXG4gIC8vIERldGVybWluZSB3aGV0aGVyIGFsbCBvZiB0aGUgZWxlbWVudHMgbWF0Y2ggYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgZXZlcnlgIGlmIGF2YWlsYWJsZS5cbiAgLy8gQWxpYXNlZCBhcyBgYWxsYC5cbiAgXy5ldmVyeSA9IF8uYWxsID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yIHx8IChpdGVyYXRvciA9IF8uaWRlbnRpdHkpO1xuICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAobmF0aXZlRXZlcnkgJiYgb2JqLmV2ZXJ5ID09PSBuYXRpdmVFdmVyeSkgcmV0dXJuIG9iai5ldmVyeShpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKCEocmVzdWx0ID0gcmVzdWx0ICYmIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkpIHJldHVybiBicmVha2VyO1xuICAgIH0pO1xuICAgIHJldHVybiAhIXJlc3VsdDtcbiAgfTtcblxuICAvLyBEZXRlcm1pbmUgaWYgYXQgbGVhc3Qgb25lIGVsZW1lbnQgaW4gdGhlIG9iamVjdCBtYXRjaGVzIGEgdHJ1dGggdGVzdC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYHNvbWVgIGlmIGF2YWlsYWJsZS5cbiAgLy8gQWxpYXNlZCBhcyBgYW55YC5cbiAgdmFyIGFueSA9IF8uc29tZSA9IF8uYW55ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yIHx8IChpdGVyYXRvciA9IF8uaWRlbnRpdHkpO1xuICAgIHZhciByZXN1bHQgPSBmYWxzZTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHQ7XG4gICAgaWYgKG5hdGl2ZVNvbWUgJiYgb2JqLnNvbWUgPT09IG5hdGl2ZVNvbWUpIHJldHVybiBvYmouc29tZShpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHJlc3VsdCB8fCAocmVzdWx0ID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpKSkgcmV0dXJuIGJyZWFrZXI7XG4gICAgfSk7XG4gICAgcmV0dXJuICEhcmVzdWx0O1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiB0aGUgYXJyYXkgb3Igb2JqZWN0IGNvbnRhaW5zIGEgZ2l2ZW4gdmFsdWUgKHVzaW5nIGA9PT1gKS5cbiAgLy8gQWxpYXNlZCBhcyBgaW5jbHVkZWAuXG4gIF8uY29udGFpbnMgPSBfLmluY2x1ZGUgPSBmdW5jdGlvbihvYmosIHRhcmdldCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChuYXRpdmVJbmRleE9mICYmIG9iai5pbmRleE9mID09PSBuYXRpdmVJbmRleE9mKSByZXR1cm4gb2JqLmluZGV4T2YodGFyZ2V0KSAhPSAtMTtcbiAgICByZXR1cm4gYW55KG9iaiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdGFyZ2V0O1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEludm9rZSBhIG1ldGhvZCAod2l0aCBhcmd1bWVudHMpIG9uIGV2ZXJ5IGl0ZW0gaW4gYSBjb2xsZWN0aW9uLlxuICBfLmludm9rZSA9IGZ1bmN0aW9uKG9iaiwgbWV0aG9kKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGlzRnVuYyA9IF8uaXNGdW5jdGlvbihtZXRob2QpO1xuICAgIHJldHVybiBfLm1hcChvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKGlzRnVuYyA/IG1ldGhvZCA6IHZhbHVlW21ldGhvZF0pLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBtYXBgOiBmZXRjaGluZyBhIHByb3BlcnR5LlxuICBfLnBsdWNrID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSl7IHJldHVybiB2YWx1ZVtrZXldOyB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBmaWx0ZXJgOiBzZWxlY3Rpbmcgb25seSBvYmplY3RzXG4gIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8ud2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzLCBmaXJzdCkge1xuICAgIGlmIChfLmlzRW1wdHkoYXR0cnMpKSByZXR1cm4gZmlyc3QgPyB2b2lkIDAgOiBbXTtcbiAgICByZXR1cm4gX1tmaXJzdCA/ICdmaW5kJyA6ICdmaWx0ZXInXShvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gYXR0cnMpIHtcbiAgICAgICAgaWYgKGF0dHJzW2tleV0gIT09IHZhbHVlW2tleV0pIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbmRgOiBnZXR0aW5nIHRoZSBmaXJzdCBvYmplY3RcbiAgLy8gY29udGFpbmluZyBzcGVjaWZpYyBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy5maW5kV2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzKSB7XG4gICAgcmV0dXJuIF8ud2hlcmUob2JqLCBhdHRycywgdHJ1ZSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtYXhpbXVtIGVsZW1lbnQgb3IgKGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICAvLyBDYW4ndCBvcHRpbWl6ZSBhcnJheXMgb2YgaW50ZWdlcnMgbG9uZ2VyIHRoYW4gNjUsNTM1IGVsZW1lbnRzLlxuICAvLyBTZWUgW1dlYktpdCBCdWcgODA3OTddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD04MDc5NylcbiAgXy5tYXggPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKCFpdGVyYXRvciAmJiBfLmlzQXJyYXkob2JqKSAmJiBvYmpbMF0gPT09ICtvYmpbMF0gJiYgb2JqLmxlbmd0aCA8IDY1NTM1KSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkoTWF0aCwgb2JqKTtcbiAgICB9XG4gICAgaWYgKCFpdGVyYXRvciAmJiBfLmlzRW1wdHkob2JqKSkgcmV0dXJuIC1JbmZpbml0eTtcbiAgICB2YXIgcmVzdWx0ID0ge2NvbXB1dGVkIDogLUluZmluaXR5LCB2YWx1ZTogLUluZmluaXR5fTtcbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICB2YXIgY29tcHV0ZWQgPSBpdGVyYXRvciA/IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSA6IHZhbHVlO1xuICAgICAgY29tcHV0ZWQgPiByZXN1bHQuY29tcHV0ZWQgJiYgKHJlc3VsdCA9IHt2YWx1ZSA6IHZhbHVlLCBjb21wdXRlZCA6IGNvbXB1dGVkfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG1pbmltdW0gZWxlbWVudCAob3IgZWxlbWVudC1iYXNlZCBjb21wdXRhdGlvbikuXG4gIF8ubWluID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGlmICghaXRlcmF0b3IgJiYgXy5pc0FycmF5KG9iaikgJiYgb2JqWzBdID09PSArb2JqWzBdICYmIG9iai5sZW5ndGggPCA2NTUzNSkge1xuICAgICAgcmV0dXJuIE1hdGgubWluLmFwcGx5KE1hdGgsIG9iaik7XG4gICAgfVxuICAgIGlmICghaXRlcmF0b3IgJiYgXy5pc0VtcHR5KG9iaikpIHJldHVybiBJbmZpbml0eTtcbiAgICB2YXIgcmVzdWx0ID0ge2NvbXB1dGVkIDogSW5maW5pdHksIHZhbHVlOiBJbmZpbml0eX07XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgdmFyIGNvbXB1dGVkID0gaXRlcmF0b3IgPyBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgbGlzdCkgOiB2YWx1ZTtcbiAgICAgIGNvbXB1dGVkIDwgcmVzdWx0LmNvbXB1dGVkICYmIChyZXN1bHQgPSB7dmFsdWUgOiB2YWx1ZSwgY29tcHV0ZWQgOiBjb21wdXRlZH0pO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQudmFsdWU7XG4gIH07XG5cbiAgLy8gU2h1ZmZsZSBhbiBhcnJheSwgdXNpbmcgdGhlIG1vZGVybiB2ZXJzaW9uIG9mIHRoZSBcbiAgLy8gW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlcuKAk1lhdGVzX3NodWZmbGUpLlxuICBfLnNodWZmbGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmFuZDtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBzaHVmZmxlZCA9IFtdO1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmFuZCA9IF8ucmFuZG9tKGluZGV4KyspO1xuICAgICAgc2h1ZmZsZWRbaW5kZXggLSAxXSA9IHNodWZmbGVkW3JhbmRdO1xuICAgICAgc2h1ZmZsZWRbcmFuZF0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gc2h1ZmZsZWQ7XG4gIH07XG5cbiAgLy8gU2FtcGxlICoqbioqIHJhbmRvbSB2YWx1ZXMgZnJvbSBhbiBhcnJheS5cbiAgLy8gSWYgKipuKiogaXMgbm90IHNwZWNpZmllZCwgcmV0dXJucyBhIHNpbmdsZSByYW5kb20gZWxlbWVudCBmcm9tIHRoZSBhcnJheS5cbiAgLy8gVGhlIGludGVybmFsIGBndWFyZGAgYXJndW1lbnQgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgbWFwYC5cbiAgXy5zYW1wbGUgPSBmdW5jdGlvbihvYmosIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyIHx8IGd1YXJkKSB7XG4gICAgICByZXR1cm4gb2JqW18ucmFuZG9tKG9iai5sZW5ndGggLSAxKV07XG4gICAgfVxuICAgIHJldHVybiBfLnNodWZmbGUob2JqKS5zbGljZSgwLCBNYXRoLm1heCgwLCBuKSk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgbG9va3VwIGl0ZXJhdG9ycy5cbiAgdmFyIGxvb2t1cEl0ZXJhdG9yID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlIDogZnVuY3Rpb24ob2JqKXsgcmV0dXJuIG9ialt2YWx1ZV07IH07XG4gIH07XG5cbiAgLy8gU29ydCB0aGUgb2JqZWN0J3MgdmFsdWVzIGJ5IGEgY3JpdGVyaW9uIHByb2R1Y2VkIGJ5IGFuIGl0ZXJhdG9yLlxuICBfLnNvcnRCeSA9IGZ1bmN0aW9uKG9iaiwgdmFsdWUsIGNvbnRleHQpIHtcbiAgICB2YXIgaXRlcmF0b3IgPSBsb29rdXBJdGVyYXRvcih2YWx1ZSk7XG4gICAgcmV0dXJuIF8ucGx1Y2soXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICBjcml0ZXJpYTogaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpXG4gICAgICB9O1xuICAgIH0pLnNvcnQoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgIHZhciBhID0gbGVmdC5jcml0ZXJpYTtcbiAgICAgIHZhciBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICBpZiAoYSAhPT0gYikge1xuICAgICAgICBpZiAoYSA+IGIgfHwgYSA9PT0gdm9pZCAwKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKGEgPCBiIHx8IGIgPT09IHZvaWQgMCkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxlZnQuaW5kZXggLSByaWdodC5pbmRleDtcbiAgICB9KSwgJ3ZhbHVlJyk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBmb3IgYWdncmVnYXRlIFwiZ3JvdXAgYnlcIiBvcGVyYXRpb25zLlxuICB2YXIgZ3JvdXAgPSBmdW5jdGlvbihiZWhhdmlvcikge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmosIHZhbHVlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICB2YXIgaXRlcmF0b3IgPSB2YWx1ZSA9PSBudWxsID8gXy5pZGVudGl0eSA6IGxvb2t1cEl0ZXJhdG9yKHZhbHVlKTtcbiAgICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGtleSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBvYmopO1xuICAgICAgICBiZWhhdmlvcihyZXN1bHQsIGtleSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gR3JvdXBzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24uIFBhc3MgZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZVxuICAvLyB0byBncm91cCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGNyaXRlcmlvbi5cbiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCBrZXksIHZhbHVlKSB7XG4gICAgKF8uaGFzKHJlc3VsdCwga2V5KSA/IHJlc3VsdFtrZXldIDogKHJlc3VsdFtrZXldID0gW10pKS5wdXNoKHZhbHVlKTtcbiAgfSk7XG5cbiAgLy8gSW5kZXhlcyB0aGUgb2JqZWN0J3MgdmFsdWVzIGJ5IGEgY3JpdGVyaW9uLCBzaW1pbGFyIHRvIGBncm91cEJ5YCwgYnV0IGZvclxuICAvLyB3aGVuIHlvdSBrbm93IHRoYXQgeW91ciBpbmRleCB2YWx1ZXMgd2lsbCBiZSB1bmlxdWUuXG4gIF8uaW5kZXhCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwga2V5LCB2YWx1ZSkge1xuICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gIH0pO1xuXG4gIC8vIENvdW50cyBpbnN0YW5jZXMgb2YgYW4gb2JqZWN0IHRoYXQgZ3JvdXAgYnkgYSBjZXJ0YWluIGNyaXRlcmlvbi4gUGFzc1xuICAvLyBlaXRoZXIgYSBzdHJpbmcgYXR0cmlidXRlIHRvIGNvdW50IGJ5LCBvciBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGVcbiAgLy8gY3JpdGVyaW9uLlxuICBfLmNvdW50QnkgPSBncm91cChmdW5jdGlvbihyZXN1bHQsIGtleSkge1xuICAgIF8uaGFzKHJlc3VsdCwga2V5KSA/IHJlc3VsdFtrZXldKysgOiByZXN1bHRba2V5XSA9IDE7XG4gIH0pO1xuXG4gIC8vIFVzZSBhIGNvbXBhcmF0b3IgZnVuY3Rpb24gdG8gZmlndXJlIG91dCB0aGUgc21hbGxlc3QgaW5kZXggYXQgd2hpY2hcbiAgLy8gYW4gb2JqZWN0IHNob3VsZCBiZSBpbnNlcnRlZCBzbyBhcyB0byBtYWludGFpbiBvcmRlci4gVXNlcyBiaW5hcnkgc2VhcmNoLlxuICBfLnNvcnRlZEluZGV4ID0gZnVuY3Rpb24oYXJyYXksIG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yID09IG51bGwgPyBfLmlkZW50aXR5IDogbG9va3VwSXRlcmF0b3IoaXRlcmF0b3IpO1xuICAgIHZhciB2YWx1ZSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqKTtcbiAgICB2YXIgbG93ID0gMCwgaGlnaCA9IGFycmF5Lmxlbmd0aDtcbiAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgdmFyIG1pZCA9IChsb3cgKyBoaWdoKSA+Pj4gMTtcbiAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgYXJyYXlbbWlkXSkgPCB2YWx1ZSA/IGxvdyA9IG1pZCArIDEgOiBoaWdoID0gbWlkO1xuICAgIH1cbiAgICByZXR1cm4gbG93O1xuICB9O1xuXG4gIC8vIFNhZmVseSBjcmVhdGUgYSByZWFsLCBsaXZlIGFycmF5IGZyb20gYW55dGhpbmcgaXRlcmFibGUuXG4gIF8udG9BcnJheSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmICghb2JqKSByZXR1cm4gW107XG4gICAgaWYgKF8uaXNBcnJheShvYmopKSByZXR1cm4gc2xpY2UuY2FsbChvYmopO1xuICAgIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkgcmV0dXJuIF8ubWFwKG9iaiwgXy5pZGVudGl0eSk7XG4gICAgcmV0dXJuIF8udmFsdWVzKG9iaik7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gYW4gb2JqZWN0LlxuICBfLnNpemUgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiAwO1xuICAgIHJldHVybiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpID8gb2JqLmxlbmd0aCA6IF8ua2V5cyhvYmopLmxlbmd0aDtcbiAgfTtcblxuICAvLyBBcnJheSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYGhlYWRgIGFuZCBgdGFrZWAuIFRoZSAqKmd1YXJkKiogY2hlY2tcbiAgLy8gYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmZpcnN0ID0gXy5oZWFkID0gXy50YWtlID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgcmV0dXJuIChuID09IG51bGwpIHx8IGd1YXJkID8gYXJyYXlbMF0gOiBzbGljZS5jYWxsKGFycmF5LCAwLCBuKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsYXN0IGVudHJ5IG9mIHRoZSBhcnJheS4gRXNwZWNpYWxseSB1c2VmdWwgb25cbiAgLy8gdGhlIGFyZ3VtZW50cyBvYmplY3QuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gYWxsIHRoZSB2YWx1ZXMgaW5cbiAgLy8gdGhlIGFycmF5LCBleGNsdWRpbmcgdGhlIGxhc3QgTi4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoXG4gIC8vIGBfLm1hcGAuXG4gIF8uaW5pdGlhbCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBhcnJheS5sZW5ndGggLSAoKG4gPT0gbnVsbCkgfHwgZ3VhcmQgPyAxIDogbikpO1xuICB9O1xuXG4gIC8vIEdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBsYXN0IE5cbiAgLy8gdmFsdWVzIGluIHRoZSBhcnJheS4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8ubGFzdCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gdm9pZCAwO1xuICAgIGlmICgobiA9PSBudWxsKSB8fCBndWFyZCkge1xuICAgICAgcmV0dXJuIGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgTWF0aC5tYXgoYXJyYXkubGVuZ3RoIC0gbiwgMCkpO1xuICAgIH1cbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYHRhaWxgIGFuZCBgZHJvcGAuXG4gIC8vIEVzcGVjaWFsbHkgdXNlZnVsIG9uIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBQYXNzaW5nIGFuICoqbioqIHdpbGwgcmV0dXJuXG4gIC8vIHRoZSByZXN0IE4gdmFsdWVzIGluIHRoZSBhcnJheS4gVGhlICoqZ3VhcmQqKlxuICAvLyBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8ucmVzdCA9IF8udGFpbCA9IF8uZHJvcCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAobiA9PSBudWxsKSB8fCBndWFyZCA/IDEgOiBuKTtcbiAgfTtcblxuICAvLyBUcmltIG91dCBhbGwgZmFsc3kgdmFsdWVzIGZyb20gYW4gYXJyYXkuXG4gIF8uY29tcGFjdCA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKGFycmF5LCBfLmlkZW50aXR5KTtcbiAgfTtcblxuICAvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiBhIHJlY3Vyc2l2ZSBgZmxhdHRlbmAgZnVuY3Rpb24uXG4gIHZhciBmbGF0dGVuID0gZnVuY3Rpb24oaW5wdXQsIHNoYWxsb3csIG91dHB1dCkge1xuICAgIGlmIChzaGFsbG93ICYmIF8uZXZlcnkoaW5wdXQsIF8uaXNBcnJheSkpIHtcbiAgICAgIHJldHVybiBjb25jYXQuYXBwbHkob3V0cHV0LCBpbnB1dCk7XG4gICAgfVxuICAgIGVhY2goaW5wdXQsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHZhbHVlKSB8fCBfLmlzQXJndW1lbnRzKHZhbHVlKSkge1xuICAgICAgICBzaGFsbG93ID8gcHVzaC5hcHBseShvdXRwdXQsIHZhbHVlKSA6IGZsYXR0ZW4odmFsdWUsIHNoYWxsb3csIG91dHB1dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQucHVzaCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICAvLyBGbGF0dGVuIG91dCBhbiBhcnJheSwgZWl0aGVyIHJlY3Vyc2l2ZWx5IChieSBkZWZhdWx0KSwgb3IganVzdCBvbmUgbGV2ZWwuXG4gIF8uZmxhdHRlbiA9IGZ1bmN0aW9uKGFycmF5LCBzaGFsbG93KSB7XG4gICAgcmV0dXJuIGZsYXR0ZW4oYXJyYXksIHNoYWxsb3csIFtdKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSB2ZXJzaW9uIG9mIHRoZSBhcnJheSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gdGhlIHNwZWNpZmllZCB2YWx1ZShzKS5cbiAgXy53aXRob3V0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICByZXR1cm4gXy5kaWZmZXJlbmNlKGFycmF5LCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIHRoZSBhcnJheS4gSWYgdGhlIGFycmF5IGhhcyBhbHJlYWR5XG4gIC8vIGJlZW4gc29ydGVkLCB5b3UgaGF2ZSB0aGUgb3B0aW9uIG9mIHVzaW5nIGEgZmFzdGVyIGFsZ29yaXRobS5cbiAgLy8gQWxpYXNlZCBhcyBgdW5pcXVlYC5cbiAgXy51bmlxID0gXy51bmlxdWUgPSBmdW5jdGlvbihhcnJheSwgaXNTb3J0ZWQsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbihpc1NvcnRlZCkpIHtcbiAgICAgIGNvbnRleHQgPSBpdGVyYXRvcjtcbiAgICAgIGl0ZXJhdG9yID0gaXNTb3J0ZWQ7XG4gICAgICBpc1NvcnRlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaW5pdGlhbCA9IGl0ZXJhdG9yID8gXy5tYXAoYXJyYXksIGl0ZXJhdG9yLCBjb250ZXh0KSA6IGFycmF5O1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdmFyIHNlZW4gPSBbXTtcbiAgICBlYWNoKGluaXRpYWwsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKGlzU29ydGVkID8gKCFpbmRleCB8fCBzZWVuW3NlZW4ubGVuZ3RoIC0gMV0gIT09IHZhbHVlKSA6ICFfLmNvbnRhaW5zKHNlZW4sIHZhbHVlKSkge1xuICAgICAgICBzZWVuLnB1c2godmFsdWUpO1xuICAgICAgICByZXN1bHRzLnB1c2goYXJyYXlbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHVuaW9uOiBlYWNoIGRpc3RpbmN0IGVsZW1lbnQgZnJvbSBhbGwgb2ZcbiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8udW5pb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXy51bmlxKF8uZmxhdHRlbihhcmd1bWVudHMsIHRydWUpKTtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgZXZlcnkgaXRlbSBzaGFyZWQgYmV0d2VlbiBhbGwgdGhlXG4gIC8vIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8uaW50ZXJzZWN0aW9uID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gXy5maWx0ZXIoXy51bmlxKGFycmF5KSwgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgcmV0dXJuIF8uZXZlcnkocmVzdCwgZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIF8uaW5kZXhPZihvdGhlciwgaXRlbSkgPj0gMDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIFRha2UgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBvbmUgYXJyYXkgYW5kIGEgbnVtYmVyIG9mIG90aGVyIGFycmF5cy5cbiAgLy8gT25seSB0aGUgZWxlbWVudHMgcHJlc2VudCBpbiBqdXN0IHRoZSBmaXJzdCBhcnJheSB3aWxsIHJlbWFpbi5cbiAgXy5kaWZmZXJlbmNlID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIHJldHVybiBfLmZpbHRlcihhcnJheSwgZnVuY3Rpb24odmFsdWUpeyByZXR1cm4gIV8uY29udGFpbnMocmVzdCwgdmFsdWUpOyB9KTtcbiAgfTtcblxuICAvLyBaaXAgdG9nZXRoZXIgbXVsdGlwbGUgbGlzdHMgaW50byBhIHNpbmdsZSBhcnJheSAtLSBlbGVtZW50cyB0aGF0IHNoYXJlXG4gIC8vIGFuIGluZGV4IGdvIHRvZ2V0aGVyLlxuICBfLnppcCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBsZW5ndGggPSBfLm1heChfLnBsdWNrKGFyZ3VtZW50cywgXCJsZW5ndGhcIikuY29uY2F0KDApKTtcbiAgICB2YXIgcmVzdWx0cyA9IG5ldyBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdHNbaV0gPSBfLnBsdWNrKGFyZ3VtZW50cywgJycgKyBpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH07XG5cbiAgLy8gQ29udmVydHMgbGlzdHMgaW50byBvYmplY3RzLiBQYXNzIGVpdGhlciBhIHNpbmdsZSBhcnJheSBvZiBgW2tleSwgdmFsdWVdYFxuICAvLyBwYWlycywgb3IgdHdvIHBhcmFsbGVsIGFycmF5cyBvZiB0aGUgc2FtZSBsZW5ndGggLS0gb25lIG9mIGtleXMsIGFuZCBvbmUgb2ZcbiAgLy8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICBfLm9iamVjdCA9IGZ1bmN0aW9uKGxpc3QsIHZhbHVlcykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiB7fTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGxpc3QubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh2YWx1ZXMpIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1dID0gdmFsdWVzW2ldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1bMF1dID0gbGlzdFtpXVsxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBJZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBseSB1cyB3aXRoIGluZGV4T2YgKEknbSBsb29raW5nIGF0IHlvdSwgKipNU0lFKiopLFxuICAvLyB3ZSBuZWVkIHRoaXMgZnVuY3Rpb24uIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW5cbiAgLy8gaXRlbSBpbiBhbiBhcnJheSwgb3IgLTEgaWYgdGhlIGl0ZW0gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBhcnJheS5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYGluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgLy8gSWYgdGhlIGFycmF5IGlzIGxhcmdlIGFuZCBhbHJlYWR5IGluIHNvcnQgb3JkZXIsIHBhc3MgYHRydWVgXG4gIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guXG4gIF8uaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBpc1NvcnRlZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICBpZiAodHlwZW9mIGlzU29ydGVkID09ICdudW1iZXInKSB7XG4gICAgICAgIGkgPSAoaXNTb3J0ZWQgPCAwID8gTWF0aC5tYXgoMCwgbGVuZ3RoICsgaXNTb3J0ZWQpIDogaXNTb3J0ZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IF8uc29ydGVkSW5kZXgoYXJyYXksIGl0ZW0pO1xuICAgICAgICByZXR1cm4gYXJyYXlbaV0gPT09IGl0ZW0gPyBpIDogLTE7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChuYXRpdmVJbmRleE9mICYmIGFycmF5LmluZGV4T2YgPT09IG5hdGl2ZUluZGV4T2YpIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0sIGlzU29ydGVkKTtcbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgbGFzdEluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgXy5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBmcm9tKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiAtMTtcbiAgICB2YXIgaGFzSW5kZXggPSBmcm9tICE9IG51bGw7XG4gICAgaWYgKG5hdGl2ZUxhc3RJbmRleE9mICYmIGFycmF5Lmxhc3RJbmRleE9mID09PSBuYXRpdmVMYXN0SW5kZXhPZikge1xuICAgICAgcmV0dXJuIGhhc0luZGV4ID8gYXJyYXkubGFzdEluZGV4T2YoaXRlbSwgZnJvbSkgOiBhcnJheS5sYXN0SW5kZXhPZihpdGVtKTtcbiAgICB9XG4gICAgdmFyIGkgPSAoaGFzSW5kZXggPyBmcm9tIDogYXJyYXkubGVuZ3RoKTtcbiAgICB3aGlsZSAoaS0tKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhbiBpbnRlZ2VyIEFycmF5IGNvbnRhaW5pbmcgYW4gYXJpdGhtZXRpYyBwcm9ncmVzc2lvbi4gQSBwb3J0IG9mXG4gIC8vIHRoZSBuYXRpdmUgUHl0aG9uIGByYW5nZSgpYCBmdW5jdGlvbi4gU2VlXG4gIC8vIFt0aGUgUHl0aG9uIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS9mdW5jdGlvbnMuaHRtbCNyYW5nZSkuXG4gIF8ucmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDEpIHtcbiAgICAgIHN0b3AgPSBzdGFydCB8fCAwO1xuICAgICAgc3RhcnQgPSAwO1xuICAgIH1cbiAgICBzdGVwID0gYXJndW1lbnRzWzJdIHx8IDE7XG5cbiAgICB2YXIgbGVuZ3RoID0gTWF0aC5tYXgoTWF0aC5jZWlsKChzdG9wIC0gc3RhcnQpIC8gc3RlcCksIDApO1xuICAgIHZhciBpZHggPSAwO1xuICAgIHZhciByYW5nZSA9IG5ldyBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUoaWR4IDwgbGVuZ3RoKSB7XG4gICAgICByYW5nZVtpZHgrK10gPSBzdGFydDtcbiAgICAgIHN0YXJ0ICs9IHN0ZXA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhbmdlO1xuICB9O1xuXG4gIC8vIEZ1bmN0aW9uIChhaGVtKSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV1c2FibGUgY29uc3RydWN0b3IgZnVuY3Rpb24gZm9yIHByb3RvdHlwZSBzZXR0aW5nLlxuICB2YXIgY3RvciA9IGZ1bmN0aW9uKCl7fTtcblxuICAvLyBDcmVhdGUgYSBmdW5jdGlvbiBib3VuZCB0byBhIGdpdmVuIG9iamVjdCAoYXNzaWduaW5nIGB0aGlzYCwgYW5kIGFyZ3VtZW50cyxcbiAgLy8gb3B0aW9uYWxseSkuIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBGdW5jdGlvbi5iaW5kYCBpZlxuICAvLyBhdmFpbGFibGUuXG4gIF8uYmluZCA9IGZ1bmN0aW9uKGZ1bmMsIGNvbnRleHQpIHtcbiAgICB2YXIgYXJncywgYm91bmQ7XG4gICAgaWYgKG5hdGl2ZUJpbmQgJiYgZnVuYy5iaW5kID09PSBuYXRpdmVCaW5kKSByZXR1cm4gbmF0aXZlQmluZC5hcHBseShmdW5jLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGlmICghXy5pc0Z1bmN0aW9uKGZ1bmMpKSB0aHJvdyBuZXcgVHlwZUVycm9yO1xuICAgIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGJvdW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgYm91bmQpKSByZXR1cm4gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgIGN0b3IucHJvdG90eXBlID0gZnVuYy5wcm90b3R5cGU7XG4gICAgICB2YXIgc2VsZiA9IG5ldyBjdG9yO1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBudWxsO1xuICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkoc2VsZiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICBpZiAoT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUGFydGlhbGx5IGFwcGx5IGEgZnVuY3Rpb24gYnkgY3JlYXRpbmcgYSB2ZXJzaW9uIHRoYXQgaGFzIGhhZCBzb21lIG9mIGl0c1xuICAvLyBhcmd1bWVudHMgcHJlLWZpbGxlZCwgd2l0aG91dCBjaGFuZ2luZyBpdHMgZHluYW1pYyBgdGhpc2AgY29udGV4dC5cbiAgXy5wYXJ0aWFsID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gQmluZCBhbGwgb2YgYW4gb2JqZWN0J3MgbWV0aG9kcyB0byB0aGF0IG9iamVjdC4gVXNlZnVsIGZvciBlbnN1cmluZyB0aGF0XG4gIC8vIGFsbCBjYWxsYmFja3MgZGVmaW5lZCBvbiBhbiBvYmplY3QgYmVsb25nIHRvIGl0LlxuICBfLmJpbmRBbGwgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgZnVuY3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgaWYgKGZ1bmNzLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKFwiYmluZEFsbCBtdXN0IGJlIHBhc3NlZCBmdW5jdGlvbiBuYW1lc1wiKTtcbiAgICBlYWNoKGZ1bmNzLCBmdW5jdGlvbihmKSB7IG9ialtmXSA9IF8uYmluZChvYmpbZl0sIG9iaik7IH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gTWVtb2l6ZSBhbiBleHBlbnNpdmUgZnVuY3Rpb24gYnkgc3RvcmluZyBpdHMgcmVzdWx0cy5cbiAgXy5tZW1vaXplID0gZnVuY3Rpb24oZnVuYywgaGFzaGVyKSB7XG4gICAgdmFyIG1lbW8gPSB7fTtcbiAgICBoYXNoZXIgfHwgKGhhc2hlciA9IF8uaWRlbnRpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrZXkgPSBoYXNoZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiBfLmhhcyhtZW1vLCBrZXkpID8gbWVtb1trZXldIDogKG1lbW9ba2V5XSA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgfTtcbiAgfTtcblxuICAvLyBEZWxheXMgYSBmdW5jdGlvbiBmb3IgdGhlIGdpdmVuIG51bWJlciBvZiBtaWxsaXNlY29uZHMsIGFuZCB0aGVuIGNhbGxzXG4gIC8vIGl0IHdpdGggdGhlIGFyZ3VtZW50cyBzdXBwbGllZC5cbiAgXy5kZWxheSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpeyByZXR1cm4gZnVuYy5hcHBseShudWxsLCBhcmdzKTsgfSwgd2FpdCk7XG4gIH07XG5cbiAgLy8gRGVmZXJzIGEgZnVuY3Rpb24sIHNjaGVkdWxpbmcgaXQgdG8gcnVuIGFmdGVyIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzXG4gIC8vIGNsZWFyZWQuXG4gIF8uZGVmZXIgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgcmV0dXJuIF8uZGVsYXkuYXBwbHkoXywgW2Z1bmMsIDFdLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIHdoZW4gaW52b2tlZCwgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBhdCBtb3N0IG9uY2VcbiAgLy8gZHVyaW5nIGEgZ2l2ZW4gd2luZG93IG9mIHRpbWUuIE5vcm1hbGx5LCB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHdpbGwgcnVuXG4gIC8vIGFzIG11Y2ggYXMgaXQgY2FuLCB3aXRob3V0IGV2ZXIgZ29pbmcgbW9yZSB0aGFuIG9uY2UgcGVyIGB3YWl0YCBkdXJhdGlvbjtcbiAgLy8gYnV0IGlmIHlvdSdkIGxpa2UgdG8gZGlzYWJsZSB0aGUgZXhlY3V0aW9uIG9uIHRoZSBsZWFkaW5nIGVkZ2UsIHBhc3NcbiAgLy8gYHtsZWFkaW5nOiBmYWxzZX1gLiBUbyBkaXNhYmxlIGV4ZWN1dGlvbiBvbiB0aGUgdHJhaWxpbmcgZWRnZSwgZGl0dG8uXG4gIF8udGhyb3R0bGUgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdDtcbiAgICB2YXIgdGltZW91dCA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuICAgIHZhciBsYXRlciA9IGZ1bmN0aW9uKCkge1xuICAgICAgcHJldmlvdXMgPSBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlID8gMCA6IG5ldyBEYXRlO1xuICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlO1xuICAgICAgaWYgKCFwcmV2aW91cyAmJiBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlKSBwcmV2aW91cyA9IG5vdztcbiAgICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKTtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRpbWVvdXQgJiYgb3B0aW9ucy50cmFpbGluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHJlbWFpbmluZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uLCB0aGF0LCBhcyBsb25nIGFzIGl0IGNvbnRpbnVlcyB0byBiZSBpbnZva2VkLCB3aWxsIG5vdFxuICAvLyBiZSB0cmlnZ2VyZWQuIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciBpdCBzdG9wcyBiZWluZyBjYWxsZWQgZm9yXG4gIC8vIE4gbWlsbGlzZWNvbmRzLiBJZiBgaW1tZWRpYXRlYCBpcyBwYXNzZWQsIHRyaWdnZXIgdGhlIGZ1bmN0aW9uIG9uIHRoZVxuICAvLyBsZWFkaW5nIGVkZ2UsIGluc3RlYWQgb2YgdGhlIHRyYWlsaW5nLlxuICBfLmRlYm91bmNlID0gZnVuY3Rpb24oZnVuYywgd2FpdCwgaW1tZWRpYXRlKSB7XG4gICAgdmFyIHRpbWVvdXQsIGFyZ3MsIGNvbnRleHQsIHRpbWVzdGFtcCwgcmVzdWx0O1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIHRpbWVzdGFtcCA9IG5ldyBEYXRlKCk7XG4gICAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxhc3QgPSAobmV3IERhdGUoKSkgLSB0aW1lc3RhbXA7XG4gICAgICAgIGlmIChsYXN0IDwgd2FpdCkge1xuICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0IC0gbGFzdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dDtcbiAgICAgIGlmICghdGltZW91dCkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7XG4gICAgICB9XG4gICAgICBpZiAoY2FsbE5vdykgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGF0IG1vc3Qgb25lIHRpbWUsIG5vIG1hdHRlciBob3dcbiAgLy8gb2Z0ZW4geW91IGNhbGwgaXQuIFVzZWZ1bCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbi5cbiAgXy5vbmNlID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHZhciByYW4gPSBmYWxzZSwgbWVtbztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAocmFuKSByZXR1cm4gbWVtbztcbiAgICAgIHJhbiA9IHRydWU7XG4gICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgZnVuYyA9IG51bGw7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgdGhlIGZpcnN0IGZ1bmN0aW9uIHBhc3NlZCBhcyBhbiBhcmd1bWVudCB0byB0aGUgc2Vjb25kLFxuICAvLyBhbGxvd2luZyB5b3UgdG8gYWRqdXN0IGFyZ3VtZW50cywgcnVuIGNvZGUgYmVmb3JlIGFuZCBhZnRlciwgYW5kXG4gIC8vIGNvbmRpdGlvbmFsbHkgZXhlY3V0ZSB0aGUgb3JpZ2luYWwgZnVuY3Rpb24uXG4gIF8ud3JhcCA9IGZ1bmN0aW9uKGZ1bmMsIHdyYXBwZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJncyA9IFtmdW5jXTtcbiAgICAgIHB1c2guYXBwbHkoYXJncywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB3cmFwcGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2hcbiAgLy8gY29uc3VtaW5nIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXQgZm9sbG93cy5cbiAgXy5jb21wb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZ1bmNzID0gYXJndW1lbnRzO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgZm9yICh2YXIgaSA9IGZ1bmNzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGFyZ3MgPSBbZnVuY3NbaV0uYXBwbHkodGhpcywgYXJncyldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFyZ3NbMF07XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYmVpbmcgY2FsbGVkIE4gdGltZXMuXG4gIF8uYWZ0ZXIgPSBmdW5jdGlvbih0aW1lcywgZnVuYykge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgtLXRpbWVzIDwgMSkge1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gT2JqZWN0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV0cmlldmUgdGhlIG5hbWVzIG9mIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBPYmplY3Qua2V5c2BcbiAgXy5rZXlzID0gbmF0aXZlS2V5cyB8fCBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqICE9PSBPYmplY3Qob2JqKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBvYmplY3QnKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChfLmhhcyhvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgXy52YWx1ZXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdmFsdWVzW2ldID0gb2JqW2tleXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9O1xuXG4gIC8vIENvbnZlcnQgYW4gb2JqZWN0IGludG8gYSBsaXN0IG9mIGBba2V5LCB2YWx1ZV1gIHBhaXJzLlxuICBfLnBhaXJzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIHBhaXJzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcGFpcnNbaV0gPSBba2V5c1tpXSwgb2JqW2tleXNbaV1dXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXJzO1xuICB9O1xuXG4gIC8vIEludmVydCB0aGUga2V5cyBhbmQgdmFsdWVzIG9mIGFuIG9iamVjdC4gVGhlIHZhbHVlcyBtdXN0IGJlIHNlcmlhbGl6YWJsZS5cbiAgXy5pbnZlcnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W29ialtrZXlzW2ldXV0gPSBrZXlzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHNvcnRlZCBsaXN0IG9mIHRoZSBmdW5jdGlvbiBuYW1lcyBhdmFpbGFibGUgb24gdGhlIG9iamVjdC5cbiAgLy8gQWxpYXNlZCBhcyBgbWV0aG9kc2BcbiAgXy5mdW5jdGlvbnMgPSBfLm1ldGhvZHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgbmFtZXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKG9ialtrZXldKSkgbmFtZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZXMuc29ydCgpO1xuICB9O1xuXG4gIC8vIEV4dGVuZCBhIGdpdmVuIG9iamVjdCB3aXRoIGFsbCB0aGUgcHJvcGVydGllcyBpbiBwYXNzZWQtaW4gb2JqZWN0KHMpLlxuICBfLmV4dGVuZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIGNvcHkgb2YgdGhlIG9iamVjdCBvbmx5IGNvbnRhaW5pbmcgdGhlIHdoaXRlbGlzdGVkIHByb3BlcnRpZXMuXG4gIF8ucGljayA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBjb3B5ID0ge307XG4gICAgdmFyIGtleXMgPSBjb25jYXQuYXBwbHkoQXJyYXlQcm90bywgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICBlYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgaWYgKGtleSBpbiBvYmopIGNvcHlba2V5XSA9IG9ialtrZXldO1xuICAgIH0pO1xuICAgIHJldHVybiBjb3B5O1xuICB9O1xuXG4gICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgd2l0aG91dCB0aGUgYmxhY2tsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5vbWl0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGNvcHkgPSB7fTtcbiAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmICghXy5jb250YWlucyhrZXlzLCBrZXkpKSBjb3B5W2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG4gIH07XG5cbiAgLy8gRmlsbCBpbiBhIGdpdmVuIG9iamVjdCB3aXRoIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgXy5kZWZhdWx0cyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBpZiAob2JqW3Byb3BdID09PSB2b2lkIDApIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gQ3JlYXRlIGEgKHNoYWxsb3ctY2xvbmVkKSBkdXBsaWNhdGUgb2YgYW4gb2JqZWN0LlxuICBfLmNsb25lID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIF8uaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBfLmV4dGVuZCh7fSwgb2JqKTtcbiAgfTtcblxuICAvLyBJbnZva2VzIGludGVyY2VwdG9yIHdpdGggdGhlIG9iaiwgYW5kIHRoZW4gcmV0dXJucyBvYmouXG4gIC8vIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluLCBpblxuICAvLyBvcmRlciB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaW50ZXJtZWRpYXRlIHJlc3VsdHMgd2l0aGluIHRoZSBjaGFpbi5cbiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7XG4gICAgaW50ZXJjZXB0b3Iob2JqKTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuXG4gIHZhciBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7XG4gICAgLy8gSWRlbnRpY2FsIG9iamVjdHMgYXJlIGVxdWFsLiBgMCA9PT0gLTBgLCBidXQgdGhleSBhcmVuJ3QgaWRlbnRpY2FsLlxuICAgIC8vIFNlZSB0aGUgW0hhcm1vbnkgYGVnYWxgIHByb3Bvc2FsXShodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmVnYWwpLlxuICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PSAxIC8gYjtcbiAgICAvLyBBIHN0cmljdCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGBudWxsID09IHVuZGVmaW5lZGAuXG4gICAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHJldHVybiBhID09PSBiO1xuICAgIC8vIFVud3JhcCBhbnkgd3JhcHBlZCBvYmplY3RzLlxuICAgIGlmIChhIGluc3RhbmNlb2YgXykgYSA9IGEuX3dyYXBwZWQ7XG4gICAgaWYgKGIgaW5zdGFuY2VvZiBfKSBiID0gYi5fd3JhcHBlZDtcbiAgICAvLyBDb21wYXJlIGBbW0NsYXNzXV1gIG5hbWVzLlxuICAgIHZhciBjbGFzc05hbWUgPSB0b1N0cmluZy5jYWxsKGEpO1xuICAgIGlmIChjbGFzc05hbWUgIT0gdG9TdHJpbmcuY2FsbChiKSkgcmV0dXJuIGZhbHNlO1xuICAgIHN3aXRjaCAoY2xhc3NOYW1lKSB7XG4gICAgICAvLyBTdHJpbmdzLCBudW1iZXJzLCBkYXRlcywgYW5kIGJvb2xlYW5zIGFyZSBjb21wYXJlZCBieSB2YWx1ZS5cbiAgICAgIGNhc2UgJ1tvYmplY3QgU3RyaW5nXSc6XG4gICAgICAgIC8vIFByaW1pdGl2ZXMgYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgb2JqZWN0IHdyYXBwZXJzIGFyZSBlcXVpdmFsZW50OyB0aHVzLCBgXCI1XCJgIGlzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gYG5ldyBTdHJpbmcoXCI1XCIpYC5cbiAgICAgICAgcmV0dXJuIGEgPT0gU3RyaW5nKGIpO1xuICAgICAgY2FzZSAnW29iamVjdCBOdW1iZXJdJzpcbiAgICAgICAgLy8gYE5hTmBzIGFyZSBlcXVpdmFsZW50LCBidXQgbm9uLXJlZmxleGl2ZS4gQW4gYGVnYWxgIGNvbXBhcmlzb24gaXMgcGVyZm9ybWVkIGZvclxuICAgICAgICAvLyBvdGhlciBudW1lcmljIHZhbHVlcy5cbiAgICAgICAgcmV0dXJuIGEgIT0gK2EgPyBiICE9ICtiIDogKGEgPT0gMCA/IDEgLyBhID09IDEgLyBiIDogYSA9PSArYik7XG4gICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzpcbiAgICAgIGNhc2UgJ1tvYmplY3QgQm9vbGVhbl0nOlxuICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWVyaWMgcHJpbWl0aXZlIHZhbHVlcy4gRGF0ZXMgYXJlIGNvbXBhcmVkIGJ5IHRoZWlyXG4gICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcbiAgICAgICAgLy8gb2YgYE5hTmAgYXJlIG5vdCBlcXVpdmFsZW50LlxuICAgICAgICByZXR1cm4gK2EgPT0gK2I7XG4gICAgICAvLyBSZWdFeHBzIGFyZSBjb21wYXJlZCBieSB0aGVpciBzb3VyY2UgcGF0dGVybnMgYW5kIGZsYWdzLlxuICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzpcbiAgICAgICAgcmV0dXJuIGEuc291cmNlID09IGIuc291cmNlICYmXG4gICAgICAgICAgICAgICBhLmdsb2JhbCA9PSBiLmdsb2JhbCAmJlxuICAgICAgICAgICAgICAgYS5tdWx0aWxpbmUgPT0gYi5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgICAgIGEuaWdub3JlQ2FzZSA9PSBiLmlnbm9yZUNhc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIEFzc3VtZSBlcXVhbGl0eSBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoZSBhbGdvcml0aG0gZm9yIGRldGVjdGluZyBjeWNsaWNcbiAgICAvLyBzdHJ1Y3R1cmVzIGlzIGFkYXB0ZWQgZnJvbSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLCBhYnN0cmFjdCBvcGVyYXRpb24gYEpPYC5cbiAgICB2YXIgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIC8vIExpbmVhciBzZWFyY2guIFBlcmZvcm1hbmNlIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZlxuICAgICAgLy8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuICAgICAgaWYgKGFTdGFja1tsZW5ndGhdID09IGEpIHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PSBiO1xuICAgIH1cbiAgICAvLyBPYmplY3RzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWl2YWxlbnQsIGJ1dCBgT2JqZWN0YHNcbiAgICAvLyBmcm9tIGRpZmZlcmVudCBmcmFtZXMgYXJlLlxuICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoYUN0b3IgIT09IGJDdG9yICYmICEoXy5pc0Z1bmN0aW9uKGFDdG9yKSAmJiAoYUN0b3IgaW5zdGFuY2VvZiBhQ3RvcikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5pc0Z1bmN0aW9uKGJDdG9yKSAmJiAoYkN0b3IgaW5zdGFuY2VvZiBiQ3RvcikpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucHVzaChhKTtcbiAgICBiU3RhY2sucHVzaChiKTtcbiAgICB2YXIgc2l6ZSA9IDAsIHJlc3VsdCA9IHRydWU7XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgaWYgKGNsYXNzTmFtZSA9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICAvLyBDb21wYXJlIGFycmF5IGxlbmd0aHMgdG8gZGV0ZXJtaW5lIGlmIGEgZGVlcCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeS5cbiAgICAgIHNpemUgPSBhLmxlbmd0aDtcbiAgICAgIHJlc3VsdCA9IHNpemUgPT0gYi5sZW5ndGg7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIERlZXAgY29tcGFyZSB0aGUgY29udGVudHMsIGlnbm9yaW5nIG5vbi1udW1lcmljIHByb3BlcnRpZXMuXG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBlcShhW3NpemVdLCBiW3NpemVdLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWVwIGNvbXBhcmUgb2JqZWN0cy5cbiAgICAgIGZvciAodmFyIGtleSBpbiBhKSB7XG4gICAgICAgIGlmIChfLmhhcyhhLCBrZXkpKSB7XG4gICAgICAgICAgLy8gQ291bnQgdGhlIGV4cGVjdGVkIG51bWJlciBvZiBwcm9wZXJ0aWVzLlxuICAgICAgICAgIHNpemUrKztcbiAgICAgICAgICAvLyBEZWVwIGNvbXBhcmUgZWFjaCBtZW1iZXIuXG4gICAgICAgICAgaWYgKCEocmVzdWx0ID0gXy5oYXMoYiwga2V5KSAmJiBlcShhW2tleV0sIGJba2V5XSwgYVN0YWNrLCBiU3RhY2spKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEVuc3VyZSB0aGF0IGJvdGggb2JqZWN0cyBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzLlxuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBmb3IgKGtleSBpbiBiKSB7XG4gICAgICAgICAgaWYgKF8uaGFzKGIsIGtleSkgJiYgIShzaXplLS0pKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSAhc2l6ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIHRoZSBmaXJzdCBvYmplY3QgZnJvbSB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgYVN0YWNrLnBvcCgpO1xuICAgIGJTdGFjay5wb3AoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFBlcmZvcm0gYSBkZWVwIGNvbXBhcmlzb24gdG8gY2hlY2sgaWYgdHdvIG9iamVjdHMgYXJlIGVxdWFsLlxuICBfLmlzRXF1YWwgPSBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGVxKGEsIGIsIFtdLCBbXSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiBhcnJheSwgc3RyaW5nLCBvciBvYmplY3QgZW1wdHk/XG4gIC8vIEFuIFwiZW1wdHlcIiBvYmplY3QgaGFzIG5vIGVudW1lcmFibGUgb3duLXByb3BlcnRpZXMuXG4gIF8uaXNFbXB0eSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gICAgaWYgKF8uaXNBcnJheShvYmopIHx8IF8uaXNTdHJpbmcob2JqKSkgcmV0dXJuIG9iai5sZW5ndGggPT09IDA7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgaWYgKF8uaGFzKG9iaiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBET00gZWxlbWVudD9cbiAgXy5pc0VsZW1lbnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gISEob2JqICYmIG9iai5ub2RlVHlwZSA9PT0gMSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhbiBhcnJheT9cbiAgLy8gRGVsZWdhdGVzIHRvIEVDTUE1J3MgbmF0aXZlIEFycmF5LmlzQXJyYXlcbiAgXy5pc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09ICdbb2JqZWN0IEFycmF5XSc7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSBhbiBvYmplY3Q/XG4gIF8uaXNPYmplY3QgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSBPYmplY3Qob2JqKTtcbiAgfTtcblxuICAvLyBBZGQgc29tZSBpc1R5cGUgbWV0aG9kczogaXNBcmd1bWVudHMsIGlzRnVuY3Rpb24sIGlzU3RyaW5nLCBpc051bWJlciwgaXNEYXRlLCBpc1JlZ0V4cC5cbiAgZWFjaChbJ0FyZ3VtZW50cycsICdGdW5jdGlvbicsICdTdHJpbmcnLCAnTnVtYmVyJywgJ0RhdGUnLCAnUmVnRXhwJ10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBfWydpcycgKyBuYW1lXSA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PSAnW29iamVjdCAnICsgbmFtZSArICddJztcbiAgICB9O1xuICB9KTtcblxuICAvLyBEZWZpbmUgYSBmYWxsYmFjayB2ZXJzaW9uIG9mIHRoZSBtZXRob2QgaW4gYnJvd3NlcnMgKGFoZW0sIElFKSwgd2hlcmVcbiAgLy8gdGhlcmUgaXNuJ3QgYW55IGluc3BlY3RhYmxlIFwiQXJndW1lbnRzXCIgdHlwZS5cbiAgaWYgKCFfLmlzQXJndW1lbnRzKGFyZ3VtZW50cykpIHtcbiAgICBfLmlzQXJndW1lbnRzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gISEob2JqICYmIF8uaGFzKG9iaiwgJ2NhbGxlZScpKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gT3B0aW1pemUgYGlzRnVuY3Rpb25gIGlmIGFwcHJvcHJpYXRlLlxuICBpZiAodHlwZW9mICgvLi8pICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgXy5pc0Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9O1xuICB9XG5cbiAgLy8gSXMgYSBnaXZlbiBvYmplY3QgYSBmaW5pdGUgbnVtYmVyP1xuICBfLmlzRmluaXRlID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIGlzRmluaXRlKG9iaikgJiYgIWlzTmFOKHBhcnNlRmxvYXQob2JqKSk7XG4gIH07XG5cbiAgLy8gSXMgdGhlIGdpdmVuIHZhbHVlIGBOYU5gPyAoTmFOIGlzIHRoZSBvbmx5IG51bWJlciB3aGljaCBkb2VzIG5vdCBlcXVhbCBpdHNlbGYpLlxuICBfLmlzTmFOID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIF8uaXNOdW1iZXIob2JqKSAmJiBvYmogIT0gK29iajtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGEgYm9vbGVhbj9cbiAgXy5pc0Jvb2xlYW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB0cnVlIHx8IG9iaiA9PT0gZmFsc2UgfHwgdG9TdHJpbmcuY2FsbChvYmopID09ICdbb2JqZWN0IEJvb2xlYW5dJztcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGVxdWFsIHRvIG51bGw/XG4gIF8uaXNOdWxsID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIG9iaiA9PT0gbnVsbDtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhcmlhYmxlIHVuZGVmaW5lZD9cbiAgXy5pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IHZvaWQgMDtcbiAgfTtcblxuICAvLyBTaG9ydGN1dCBmdW5jdGlvbiBmb3IgY2hlY2tpbmcgaWYgYW4gb2JqZWN0IGhhcyBhIGdpdmVuIHByb3BlcnR5IGRpcmVjdGx5XG4gIC8vIG9uIGl0c2VsZiAoaW4gb3RoZXIgd29yZHMsIG5vdCBvbiBhIHByb3RvdHlwZSkuXG4gIF8uaGFzID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XG4gIH07XG5cbiAgLy8gVXRpbGl0eSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSdW4gVW5kZXJzY29yZS5qcyBpbiAqbm9Db25mbGljdCogbW9kZSwgcmV0dXJuaW5nIHRoZSBgX2AgdmFyaWFibGUgdG8gaXRzXG4gIC8vIHByZXZpb3VzIG93bmVyLiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgcm9vdC5fID0gcHJldmlvdXNVbmRlcnNjb3JlO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIEtlZXAgdGhlIGlkZW50aXR5IGZ1bmN0aW9uIGFyb3VuZCBmb3IgZGVmYXVsdCBpdGVyYXRvcnMuXG4gIF8uaWRlbnRpdHkgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfTtcblxuICAvLyBSdW4gYSBmdW5jdGlvbiAqKm4qKiB0aW1lcy5cbiAgXy50aW1lcyA9IGZ1bmN0aW9uKG4sIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIGFjY3VtID0gQXJyYXkoTWF0aC5tYXgoMCwgbikpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSBhY2N1bVtpXSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgaSk7XG4gICAgcmV0dXJuIGFjY3VtO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gbWluIGFuZCBtYXggKGluY2x1c2l2ZSkuXG4gIF8ucmFuZG9tID0gZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgICBpZiAobWF4ID09IG51bGwpIHtcbiAgICAgIG1heCA9IG1pbjtcbiAgICAgIG1pbiA9IDA7XG4gICAgfVxuICAgIHJldHVybiBtaW4gKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkpO1xuICB9O1xuXG4gIC8vIExpc3Qgb2YgSFRNTCBlbnRpdGllcyBmb3IgZXNjYXBpbmcuXG4gIHZhciBlbnRpdHlNYXAgPSB7XG4gICAgZXNjYXBlOiB7XG4gICAgICAnJic6ICcmYW1wOycsXG4gICAgICAnPCc6ICcmbHQ7JyxcbiAgICAgICc+JzogJyZndDsnLFxuICAgICAgJ1wiJzogJyZxdW90OycsXG4gICAgICBcIidcIjogJyYjeDI3OydcbiAgICB9XG4gIH07XG4gIGVudGl0eU1hcC51bmVzY2FwZSA9IF8uaW52ZXJ0KGVudGl0eU1hcC5lc2NhcGUpO1xuXG4gIC8vIFJlZ2V4ZXMgY29udGFpbmluZyB0aGUga2V5cyBhbmQgdmFsdWVzIGxpc3RlZCBpbW1lZGlhdGVseSBhYm92ZS5cbiAgdmFyIGVudGl0eVJlZ2V4ZXMgPSB7XG4gICAgZXNjYXBlOiAgIG5ldyBSZWdFeHAoJ1snICsgXy5rZXlzKGVudGl0eU1hcC5lc2NhcGUpLmpvaW4oJycpICsgJ10nLCAnZycpLFxuICAgIHVuZXNjYXBlOiBuZXcgUmVnRXhwKCcoJyArIF8ua2V5cyhlbnRpdHlNYXAudW5lc2NhcGUpLmpvaW4oJ3wnKSArICcpJywgJ2cnKVxuICB9O1xuXG4gIC8vIEZ1bmN0aW9ucyBmb3IgZXNjYXBpbmcgYW5kIHVuZXNjYXBpbmcgc3RyaW5ncyB0by9mcm9tIEhUTUwgaW50ZXJwb2xhdGlvbi5cbiAgXy5lYWNoKFsnZXNjYXBlJywgJ3VuZXNjYXBlJ10sIGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIF9bbWV0aG9kXSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgICByZXR1cm4gKCcnICsgc3RyaW5nKS5yZXBsYWNlKGVudGl0eVJlZ2V4ZXNbbWV0aG9kXSwgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eU1hcFttZXRob2RdW21hdGNoXTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZWQgYHByb3BlcnR5YCBpcyBhIGZ1bmN0aW9uIHRoZW4gaW52b2tlIGl0IHdpdGggdGhlXG4gIC8vIGBvYmplY3RgIGFzIGNvbnRleHQ7IG90aGVyd2lzZSwgcmV0dXJuIGl0LlxuICBfLnJlc3VsdCA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgdmFyIHZhbHVlID0gb2JqZWN0W3Byb3BlcnR5XTtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlLmNhbGwob2JqZWN0KSA6IHZhbHVlO1xuICB9O1xuXG4gIC8vIEFkZCB5b3VyIG93biBjdXN0b20gZnVuY3Rpb25zIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5taXhpbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goXy5mdW5jdGlvbnMob2JqKSwgZnVuY3Rpb24obmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBfW25hbWVdID0gb2JqW25hbWVdO1xuICAgICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbdGhpcy5fd3JhcHBlZF07XG4gICAgICAgIHB1c2guYXBwbHkoYXJncywgYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5jYWxsKHRoaXMsIGZ1bmMuYXBwbHkoXywgYXJncykpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhIHVuaXF1ZSBpbnRlZ2VyIGlkICh1bmlxdWUgd2l0aGluIHRoZSBlbnRpcmUgY2xpZW50IHNlc3Npb24pLlxuICAvLyBVc2VmdWwgZm9yIHRlbXBvcmFyeSBET00gaWRzLlxuICB2YXIgaWRDb3VudGVyID0gMDtcbiAgXy51bmlxdWVJZCA9IGZ1bmN0aW9uKHByZWZpeCkge1xuICAgIHZhciBpZCA9ICsraWRDb3VudGVyICsgJyc7XG4gICAgcmV0dXJuIHByZWZpeCA/IHByZWZpeCArIGlkIDogaWQ7XG4gIH07XG5cbiAgLy8gQnkgZGVmYXVsdCwgVW5kZXJzY29yZSB1c2VzIEVSQi1zdHlsZSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLCBjaGFuZ2UgdGhlXG4gIC8vIGZvbGxvd2luZyB0ZW1wbGF0ZSBzZXR0aW5ncyB0byB1c2UgYWx0ZXJuYXRpdmUgZGVsaW1pdGVycy5cbiAgXy50ZW1wbGF0ZVNldHRpbmdzID0ge1xuICAgIGV2YWx1YXRlICAgIDogLzwlKFtcXHNcXFNdKz8pJT4vZyxcbiAgICBpbnRlcnBvbGF0ZSA6IC88JT0oW1xcc1xcU10rPyklPi9nLFxuICAgIGVzY2FwZSAgICAgIDogLzwlLShbXFxzXFxTXSs/KSU+L2dcbiAgfTtcblxuICAvLyBXaGVuIGN1c3RvbWl6aW5nIGB0ZW1wbGF0ZVNldHRpbmdzYCwgaWYgeW91IGRvbid0IHdhbnQgdG8gZGVmaW5lIGFuXG4gIC8vIGludGVycG9sYXRpb24sIGV2YWx1YXRpb24gb3IgZXNjYXBpbmcgcmVnZXgsIHdlIG5lZWQgb25lIHRoYXQgaXNcbiAgLy8gZ3VhcmFudGVlZCBub3QgdG8gbWF0Y2guXG4gIHZhciBub01hdGNoID0gLyguKV4vO1xuXG4gIC8vIENlcnRhaW4gY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQgc28gdGhhdCB0aGV5IGNhbiBiZSBwdXQgaW50byBhXG4gIC8vIHN0cmluZyBsaXRlcmFsLlxuICB2YXIgZXNjYXBlcyA9IHtcbiAgICBcIidcIjogICAgICBcIidcIixcbiAgICAnXFxcXCc6ICAgICAnXFxcXCcsXG4gICAgJ1xccic6ICAgICAncicsXG4gICAgJ1xcbic6ICAgICAnbicsXG4gICAgJ1xcdCc6ICAgICAndCcsXG4gICAgJ1xcdTIwMjgnOiAndTIwMjgnLFxuICAgICdcXHUyMDI5JzogJ3UyMDI5J1xuICB9O1xuXG4gIHZhciBlc2NhcGVyID0gL1xcXFx8J3xcXHJ8XFxufFxcdHxcXHUyMDI4fFxcdTIwMjkvZztcblxuICAvLyBKYXZhU2NyaXB0IG1pY3JvLXRlbXBsYXRpbmcsIHNpbWlsYXIgdG8gSm9obiBSZXNpZydzIGltcGxlbWVudGF0aW9uLlxuICAvLyBVbmRlcnNjb3JlIHRlbXBsYXRpbmcgaGFuZGxlcyBhcmJpdHJhcnkgZGVsaW1pdGVycywgcHJlc2VydmVzIHdoaXRlc3BhY2UsXG4gIC8vIGFuZCBjb3JyZWN0bHkgZXNjYXBlcyBxdW90ZXMgd2l0aGluIGludGVycG9sYXRlZCBjb2RlLlxuICBfLnRlbXBsYXRlID0gZnVuY3Rpb24odGV4dCwgZGF0YSwgc2V0dGluZ3MpIHtcbiAgICB2YXIgcmVuZGVyO1xuICAgIHNldHRpbmdzID0gXy5kZWZhdWx0cyh7fSwgc2V0dGluZ3MsIF8udGVtcGxhdGVTZXR0aW5ncyk7XG5cbiAgICAvLyBDb21iaW5lIGRlbGltaXRlcnMgaW50byBvbmUgcmVndWxhciBleHByZXNzaW9uIHZpYSBhbHRlcm5hdGlvbi5cbiAgICB2YXIgbWF0Y2hlciA9IG5ldyBSZWdFeHAoW1xuICAgICAgKHNldHRpbmdzLmVzY2FwZSB8fCBub01hdGNoKS5zb3VyY2UsXG4gICAgICAoc2V0dGluZ3MuaW50ZXJwb2xhdGUgfHwgbm9NYXRjaCkuc291cmNlLFxuICAgICAgKHNldHRpbmdzLmV2YWx1YXRlIHx8IG5vTWF0Y2gpLnNvdXJjZVxuICAgIF0uam9pbignfCcpICsgJ3wkJywgJ2cnKTtcblxuICAgIC8vIENvbXBpbGUgdGhlIHRlbXBsYXRlIHNvdXJjZSwgZXNjYXBpbmcgc3RyaW5nIGxpdGVyYWxzIGFwcHJvcHJpYXRlbHkuXG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgc291cmNlID0gXCJfX3ArPSdcIjtcbiAgICB0ZXh0LnJlcGxhY2UobWF0Y2hlciwgZnVuY3Rpb24obWF0Y2gsIGVzY2FwZSwgaW50ZXJwb2xhdGUsIGV2YWx1YXRlLCBvZmZzZXQpIHtcbiAgICAgIHNvdXJjZSArPSB0ZXh0LnNsaWNlKGluZGV4LCBvZmZzZXQpXG4gICAgICAgIC5yZXBsYWNlKGVzY2FwZXIsIGZ1bmN0aW9uKG1hdGNoKSB7IHJldHVybiAnXFxcXCcgKyBlc2NhcGVzW21hdGNoXTsgfSk7XG5cbiAgICAgIGlmIChlc2NhcGUpIHtcbiAgICAgICAgc291cmNlICs9IFwiJytcXG4oKF9fdD0oXCIgKyBlc2NhcGUgKyBcIikpPT1udWxsPycnOl8uZXNjYXBlKF9fdCkpK1xcbidcIjtcbiAgICAgIH1cbiAgICAgIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInK1xcbigoX190PShcIiArIGludGVycG9sYXRlICsgXCIpKT09bnVsbD8nJzpfX3QpK1xcbidcIjtcbiAgICAgIH1cbiAgICAgIGlmIChldmFsdWF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInO1xcblwiICsgZXZhbHVhdGUgKyBcIlxcbl9fcCs9J1wiO1xuICAgICAgfVxuICAgICAgaW5kZXggPSBvZmZzZXQgKyBtYXRjaC5sZW5ndGg7XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfSk7XG4gICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgIC8vIElmIGEgdmFyaWFibGUgaXMgbm90IHNwZWNpZmllZCwgcGxhY2UgZGF0YSB2YWx1ZXMgaW4gbG9jYWwgc2NvcGUuXG4gICAgaWYgKCFzZXR0aW5ncy52YXJpYWJsZSkgc291cmNlID0gJ3dpdGgob2JqfHx7fSl7XFxuJyArIHNvdXJjZSArICd9XFxuJztcblxuICAgIHNvdXJjZSA9IFwidmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLFwiICtcbiAgICAgIFwicHJpbnQ9ZnVuY3Rpb24oKXtfX3ArPV9fai5jYWxsKGFyZ3VtZW50cywnJyk7fTtcXG5cIiArXG4gICAgICBzb3VyY2UgKyBcInJldHVybiBfX3A7XFxuXCI7XG5cbiAgICB0cnkge1xuICAgICAgcmVuZGVyID0gbmV3IEZ1bmN0aW9uKHNldHRpbmdzLnZhcmlhYmxlIHx8ICdvYmonLCAnXycsIHNvdXJjZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZS5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIGlmIChkYXRhKSByZXR1cm4gcmVuZGVyKGRhdGEsIF8pO1xuICAgIHZhciB0ZW1wbGF0ZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiByZW5kZXIuY2FsbCh0aGlzLCBkYXRhLCBfKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24gc291cmNlIGFzIGEgY29udmVuaWVuY2UgZm9yIHByZWNvbXBpbGF0aW9uLlxuICAgIHRlbXBsYXRlLnNvdXJjZSA9ICdmdW5jdGlvbignICsgKHNldHRpbmdzLnZhcmlhYmxlIHx8ICdvYmonKSArICcpe1xcbicgKyBzb3VyY2UgKyAnfSc7XG5cbiAgICByZXR1cm4gdGVtcGxhdGU7XG4gIH07XG5cbiAgLy8gQWRkIGEgXCJjaGFpblwiIGZ1bmN0aW9uLCB3aGljaCB3aWxsIGRlbGVnYXRlIHRvIHRoZSB3cmFwcGVyLlxuICBfLmNoYWluID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIF8ob2JqKS5jaGFpbigpO1xuICB9O1xuXG4gIC8vIE9PUFxuICAvLyAtLS0tLS0tLS0tLS0tLS1cbiAgLy8gSWYgVW5kZXJzY29yZSBpcyBjYWxsZWQgYXMgYSBmdW5jdGlvbiwgaXQgcmV0dXJucyBhIHdyYXBwZWQgb2JqZWN0IHRoYXRcbiAgLy8gY2FuIGJlIHVzZWQgT08tc3R5bGUuIFRoaXMgd3JhcHBlciBob2xkcyBhbHRlcmVkIHZlcnNpb25zIG9mIGFsbCB0aGVcbiAgLy8gdW5kZXJzY29yZSBmdW5jdGlvbnMuIFdyYXBwZWQgb2JqZWN0cyBtYXkgYmUgY2hhaW5lZC5cblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gY29udGludWUgY2hhaW5pbmcgaW50ZXJtZWRpYXRlIHJlc3VsdHMuXG4gIHZhciByZXN1bHQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdGhpcy5fY2hhaW4gPyBfKG9iaikuY2hhaW4oKSA6IG9iajtcbiAgfTtcblxuICAvLyBBZGQgYWxsIG9mIHRoZSBVbmRlcnNjb3JlIGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlciBvYmplY3QuXG4gIF8ubWl4aW4oXyk7XG5cbiAgLy8gQWRkIGFsbCBtdXRhdG9yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgZWFjaChbJ3BvcCcsICdwdXNoJywgJ3JldmVyc2UnLCAnc2hpZnQnLCAnc29ydCcsICdzcGxpY2UnLCAndW5zaGlmdCddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIG1ldGhvZCA9IEFycmF5UHJvdG9bbmFtZV07XG4gICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvYmogPSB0aGlzLl93cmFwcGVkO1xuICAgICAgbWV0aG9kLmFwcGx5KG9iaiwgYXJndW1lbnRzKTtcbiAgICAgIGlmICgobmFtZSA9PSAnc2hpZnQnIHx8IG5hbWUgPT0gJ3NwbGljZScpICYmIG9iai5sZW5ndGggPT09IDApIGRlbGV0ZSBvYmpbMF07XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgb2JqKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBBZGQgYWxsIGFjY2Vzc29yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgZWFjaChbJ2NvbmNhdCcsICdqb2luJywgJ3NsaWNlJ10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgbWV0aG9kID0gQXJyYXlQcm90b1tuYW1lXTtcbiAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlc3VsdC5jYWxsKHRoaXMsIG1ldGhvZC5hcHBseSh0aGlzLl93cmFwcGVkLCBhcmd1bWVudHMpKTtcbiAgICB9O1xuICB9KTtcblxuICBfLmV4dGVuZChfLnByb3RvdHlwZSwge1xuXG4gICAgLy8gU3RhcnQgY2hhaW5pbmcgYSB3cmFwcGVkIFVuZGVyc2NvcmUgb2JqZWN0LlxuICAgIGNoYWluOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX2NoYWluID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBFeHRyYWN0cyB0aGUgcmVzdWx0IGZyb20gYSB3cmFwcGVkIGFuZCBjaGFpbmVkIG9iamVjdC5cbiAgICB2YWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fd3JhcHBlZDtcbiAgICB9XG5cbiAgfSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCJtb2R1bGUuZXhwb3J0cz1tb2R1bGUuZXhwb3J0cz17XG4gIFwibmFtZVwiOiBcImpvb2xhLnNka1wiLFxuICBcInByZWZlckdsb2JhbFwiOiBmYWxzZSxcbiAgXCJ2ZXJzaW9uXCI6IFwiMC44LjFcIixcbiAgXCJhdXRob3JcIjogXCJKb29sYSA8aW5mb0Bqb28ubGE+XCIsXG4gIFwiZGVzY3JpcHRpb25cIjogXCJqb29sYSdzIHNvZnR3YXJlIGRldmVsb3BtZW50IGtpdCAoU0RLKVwiLFxuICBcImVuZ2luZVwiOiBcIm5vZGUgPj0gMC4xMC54XCIsXG4gIFwicHJpdmF0ZVwiOiBmYWxzZSxcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImh0dHBzOi8vZ2l0aHViLmNvbS9qb29sYS9qb29sYS5zZGsuZ2l0XCJcbiAgfSxcbiAgXCJidWdzXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2pvb2xhL2pvb2xhLnNkay9pc3N1ZXNcIixcbiAgXCJjb250cmlidXRvcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIkl0YXkgV2VpbmJlcmdlclwiLFxuICAgICAgXCJlbWFpbFwiOiBcIml0YXlAam9vLmxhXCIsXG4gICAgICBcInVybFwiOiBcImh0dHA6Ly9qb28ubGFcIlxuICAgIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiT3IgV2VpbmJlcmdlclwiLFxuICAgICAgXCJlbWFpbFwiOiBcIm9yQGpvby5sYVwiLFxuICAgICAgXCJ1cmxcIjogXCJodHRwOi8vam9vLmxhXCJcbiAgICB9XG4gIF0sXG4gIFwibWFpblwiOiBcIi4vc3JjL2xpYi9pbmRleC5qc1wiLFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwidGVzdFwiOiBcIm1ha2UgdGVzdFwiLFxuICAgIFwiY292ZXJhbGxzXCI6IFwibW9jaGEgLS1yZXF1aXJlIGJsYW5rZXQgLS1yZXBvcnRlciBtb2NoYS1sY292LXJlcG9ydGVyIHwgbm9kZSAuL25vZGVfbW9kdWxlcy9jb3ZlcmFsbHMvYmluL2NvdmVyYWxscy5qc1wiXG4gIH0sXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImFzeW5jXCI6IFwifjAuMi4xMFwiLFxuICAgIFwiY2xvbmVleHRlbmRcIjogXCJeMC4wLjNcIixcbiAgICBcImRlZXAtZXh0ZW5kXCI6IFwiXjAuMi4xMFwiLFxuICAgIFwiZXZlbnRlbWl0dGVyMlwiOiBcIn4wLjQuMTNcIixcbiAgICBcImpxdWVyeVwiOiBcIl4yLjEuMVwiLFxuICAgIFwianF1ZXJ5LXVpXCI6IFwiXjEuMTAuNVwiLFxuICAgIFwibW9tZW50XCI6IFwiXjIuOC40XCIsXG4gICAgXCJzb2NrZXQuaW8tY2xpZW50XCI6IFwiXjEuMC4yXCIsXG4gICAgXCJ0cmF2ZXJzZVwiOiBcIl4wLjYuNlwiLFxuICAgIFwidHdpeFwiOiBcIl4wLjUuMVwiLFxuICAgIFwidW5kZXJzY29yZVwiOiBcIn4xLjUuMlwiXG4gIH0sXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImNoYWlcIjogXCJ+MS45LjFcIixcbiAgICBcImdydW50LWJyb3dzZXJpZnlcIjogXCJ+Mi4wLjhcIixcbiAgICBcImdydW50LWNvbnRyaWItY2xlYW5cIjogXCJ+MC41LjBcIixcbiAgICBcImdydW50LWNvbnRyaWItY29uY2F0XCI6IFwifjAuNC4wXCIsXG4gICAgXCJncnVudC1jb250cmliLWNvbm5lY3RcIjogXCJ+MC43LjFcIixcbiAgICBcImdydW50LWNvbnRyaWItY29weVwiOiBcIn4wLjUuMFwiLFxuICAgIFwiZ3J1bnQtY29udHJpYi1qc2hpbnRcIjogXCJ+MC4xMC4wXCIsXG4gICAgXCJncnVudC1jb250cmliLXVnbGlmeVwiOiBcIn4wLjQuMFwiLFxuICAgIFwiZ3J1bnQtY3NzXCI6IFwifjAuNS40XCIsXG4gICAgXCJncnVudC1odHRwXCI6IFwiXjEuNC4yXCIsXG4gICAgXCJncnVudC1tb2NoYVwiOiBcIn4wLjQuMTBcIixcbiAgICBcImdydW50LXNhdWNlbGFic1wiOiBcIn41LjEuM1wiLFxuICAgIFwiZ3J1bnQtd2F0Y2hpZnlcIjogXCJ+MC4xLjBcIixcbiAgICBcIm1vY2hhXCI6IFwifjEuMTkuMFwiLFxuICAgIFwibW9jaGEtcGhhbnRvbS1jb3ZlcmFnZS1yZXBvcnRlclwiOiBcIn4wLjEuMFwiLFxuICAgIFwic2lub25cIjogXCJ+MS4xMC4wXCJcbiAgfSxcbiAgXCJsaWNlbnNlXCI6IFwiR1BMLTMuMFwiXG59XG4iLCIvKipcbiAqICBAdGl0bGUgam9vbGEvbGliL3Nkay9jb21tb24vYXBpXG4gKiAgQGNvcHlyaWdodCAoYykgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPi4gU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTXG4gKlxuICogIFByb3ZpZGVzIHRoZSBTREsgd2l0aCBhIGNlbnRyYWxpemVkIG1hbmFnZW1lbnQgZm9yIGNvbnN1bWluZyBkYXRhIGZyb20gYSBqb29sYVxuICogIG5vZGUuIEFsbCBBUEkgY2FsbHMgYXJlIHJvdXRlZCB0aHJvdWdoIHRoaXMgaW50ZXJmYWNlLlxuICoqL1xuXG52YXJcbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuXG5cbiAgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKSxcbiAgaHR0cHMgPSByZXF1aXJlKCdodHRwcycpLFxuICBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5cbnZhciBhcGkgPSBleHBvcnRzO1xuYXBpLl9pZCA9ICdhcGknO1xuXG4vKiBBZGQgc3VwcG9ydCBmb3IgSlNPTiBwYXJzaW5nIG9mIHF1ZXJ5IHN0cmluZyAqL1xucXVlcnlzdHJpbmcuZXNjYXBlID0gZnVuY3Rpb24gKHN0cikge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cik7XG59O1xuXG52YXIgc3RyaW5naWZ5UHJpbWl0aXZlID0gZnVuY3Rpb24gKHYpIHtcbiAgc3dpdGNoICh0eXBlb2Ygdikge1xuICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICByZXR1cm4gdjtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB2ID8gJ3RydWUnIDogJ2ZhbHNlJztcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIGlzRmluaXRlKHYpID8gdiA6ICcnO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICcnO1xuICB9XG59O1xuXG5xdWVyeXN0cmluZy5zdHJpbmdpZnkgPSBxdWVyeXN0cmluZy5lbmNvZGUgPSBmdW5jdGlvbiAob2JqLCBzZXAsIGVxLCBuYW1lKSB7XG4gIHNlcCA9IHNlcCB8fCAnJic7XG4gIGVxID0gZXEgfHwgJz0nO1xuICBvYmogPSAob2JqID09PSBudWxsKSA/IHVuZGVmaW5lZCA6IG9iajtcblxuICB0cnkge1xuICAgIHN3aXRjaCAodHlwZW9mIG9iaikge1xuICAgICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikubWFwKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgICAgICAgcmV0dXJuIG9ialtrXS5tYXAoZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHF1ZXJ5c3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUoaykpICtcbiAgICAgICAgICAgICAgICBlcSArXG4gICAgICAgICAgICAgICAgcXVlcnlzdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZSh2KSk7XG4gICAgICAgICAgICB9KS5qb2luKHNlcCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSBxdWVyeXN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKGspKSArXG4gICAgICAgICAgICAgIGVxICtcbiAgICAgICAgICAgICAgcXVlcnlzdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShvYmpba10pKTtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5qb2luKHNlcCk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICghbmFtZSkgcmV0dXJuICcnO1xuICAgICAgICByZXR1cm4gcXVlcnlzdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShuYW1lKSkgKyBlcSArXG4gICAgICAgICAgcXVlcnlzdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShvYmopKTtcbiAgICB9XG4gIH1cbiAgY2F0Y2ggKGV4KSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBjb25zb2xlLmxvZyhleCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGxlbmd0aEluVXRmOEJ5dGVzKHN0cikge1xuICAvLyBNYXRjaGVzIG9ubHkgdGhlIDEwLi4gYnl0ZXMgdGhhdCBhcmUgbm9uLWluaXRpYWwgY2hhcmFjdGVycyBpbiBhIG11bHRpLWJ5dGUgc2VxdWVuY2UuXG4gIHZhciBtID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0cikubWF0Y2goLyVbODlBQmFiXS9nKTtcbiAgcmV0dXJuIHN0ci5sZW5ndGggKyAobSA/IG0ubGVuZ3RoIDogMCk7XG59XG4vKiBFTkQgT0YgQWRkIHN1cHBvcnQgZm9yIEpTT04gcGFyc2luZyBvZiBxdWVyeSBzdHJpbmcgKi9cblxuXG5hcGkucmVxdWVzdENvdW50ID0gMDtcbmFwaS53YWl0aW5nUmVxdWVzdHMgPSBbXTtcblxuLyoqXG4gKiBDb25zdW1lcyBhbiBBUEkgZW5kcG9pbnQgYmFzZWQgb24gb3B0aW9ucyBwYXNzZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5kcG9pbnQgdGhlIGVuZHBvaW50IHRvIGNvbnN1bWVcbiAqIEBwYXJhbSB7b2JqZWN0fSBvYmpPcHRpb25zIG9wdGlvbnMgZm9yIHRoZSBhY3R1YWwgZW5kcG9pbnQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHJlc3VsdCBhcnJpdmVzL2Vycm9yXG4gKi9cbmFwaS5mZXRjaCA9IGZ1bmN0aW9uICh0b2tlbnMsIGVuZHBvaW50LCBvYmpPcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IGFwaTtcbiAgaWYgKCFjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb2JqT3B0aW9ucztcbiAgICBvYmpPcHRpb25zID0gZW5kcG9pbnQ7XG4gICAgZW5kcG9pbnQgPSB0b2tlbnM7XG4gICAgdG9rZW5zID0ge186IG51bGwsIF9fOiBudWxsfTtcbiAgfVxuXG4gIGlmIChhcGkucmVxdWVzdENvdW50IDwgKGpvb2xhLm9wdGlvbnMubWF4UmVxdWVzdHMgfHwgMTAwKSkge1xuICAgIGFwaS5yZXF1ZXN0Q291bnQrKztcbiAgICB0cnkge1xuICAgICAgdmFyIHBhcnRzID0gcmVxdWlyZSgndXJsJykucGFyc2Uoam9vbGEub3B0aW9ucy5ob3N0KTtcbiAgICAgIHZhciBvcHRpb25zID0ge1xuICAgICAgICB0b2tlbnM6IHRva2VucyxcbiAgICAgICAgaG9zdDogcGFydHMuaG9zdG5hbWUsXG4gICAgICAgIHBvcnQ6IHBhcnRzLnBvcnQsXG4gICAgICAgIHNlY3VyZTogcGFydHMucHJvdG9jb2wgIT09ICdodHRwOicsXG4gICAgICAgIHBhdGg6IGVuZHBvaW50LFxuICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBzZWxmLmdldEpTT04ob3B0aW9ucywgb2JqT3B0aW9ucywgZnVuY3Rpb24gKGVyciwgcmVzdWx0LCBoZWFkZXJzKSB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICBpZiAoIXJlc3VsdC5yZWFsdGltZSlcbiAgICAgICAgICAgIGFwaS5yZXF1ZXN0Q291bnQtLTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgYXBpLnJlcXVlc3RDb3VudC0tO1xuXG4gICAgICAgIGlmIChzZWxmLnJlcXVlc3RDb3VudCA8IDApXG4gICAgICAgICAgc2VsZi5yZXF1ZXN0Q291bnQgPSAwO1xuXG4gICAgICAgIGlmIChhcGkud2FpdGluZ1JlcXVlc3RzLmxlbmd0aClcbiAgICAgICAgICBhcGkuZmV0Y2guYXBwbHkobnVsbCwgYXBpLndhaXRpbmdSZXF1ZXN0cy5zaGlmdCgpKTtcblxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCByZXN1bHQsIGhlYWRlcnMpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGNhdGNoIChleCkge1xuICAgICAgY29uc29sZS5sb2coZXgpO1xuICAgICAgY29uc29sZS5sb2coZXguc3RhY2spO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKGV4KTtcbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICBhcGkud2FpdGluZ1JlcXVlc3RzLnB1c2goYXJndW1lbnRzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBUaGUgYWN0dWFsIHdvcmtlciBmb3IgZ2V0dGluZyBhIGpzb24gb2JqZWN0IGZyb20gdGhlIEFQSSBzZXJ2aWNlIGJhc2VkIG9uIHRoZSBvcHRpb25zIHBhc3NlZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIG9wdGlvbnMgcmVsYXRpbmcgdG8gdGhlIGNvbm5lY3Rpb24gYW5kIGVuZHBvaW50XG4gKiBAcGFyYW0ge29iamVjdH0gb2JqT3B0aW9ucyBvcHRpb25zIGZvciB0aGUgYWN0dWFsIGVuZHBvaW50IHBhcmFtZXRlcnNcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrIGNhbGxlZCB3aGVuIHRoZSByZXN1bHQgYXJyaXZlcy9lcnJvclxuICovXG5hcGkuZ2V0SlNPTiA9IGZ1bmN0aW9uIChvcHRpb25zLCBvYmpPcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgcHJvdCA9IG9wdGlvbnMuc2VjdXJlID8gaHR0cHMgOiBodHRwO1xuICBqb29sYS5sb2dnZXIuc2lsbHkoJ1thcGldIEZldGNoaW5nIEpTT04gZnJvbSAnICsgb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0ICsgb3B0aW9ucy5wYXRoICsgJ0AnICsgKGpvb2xhLkFQSVRPS0VOIHx8IGpvb2xhLlRPS0VOICkpO1xuXG4gIGlmICgham9vbGEuaW8gfHwgam9vbGEub3B0aW9ucy5hamF4IHx8IG9wdGlvbnMuYWpheCkge1xuICAgIHZhciBxcyA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvYmpPcHRpb25zKTtcbiAgICBvcHRpb25zLnBhdGggKz0gJz8nICsgcXM7XG4gICAgdmFyIHRpbWVySUQsIGFib3J0ZWQ7XG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXEgPSBwcm90LnJlcXVlc3Qob3B0aW9ucywgZnVuY3Rpb24gKHJlcykge1xuICAgICAgICB2YXIgb3V0cHV0ID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGZ1bmN0aW9uIChjaHVuaykge1xuICAgICAgICAgIG91dHB1dCArPSBjaHVuaztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmVzLm9uKCdlbmQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySUQpO1xuICAgICAgICAgIGlmIChhYm9ydGVkKVxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignW2FwaV0gVGltZW91dCB3aGlsZSBmZXRjaGluZzogJyArIG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydCArIG9wdGlvbnMucGF0aCkpO1xuXG4gICAgICAgICAgdmFyIG9iajtcblxuICAgICAgICAgIGlmICh0eXBlb2Ygb3V0cHV0ID09PSAnb2JqZWN0Jykge1xuXG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHJlcy5zdGF0dXNDb2RlID09IDIwMCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgb2JqID0gSlNPTi5wYXJzZShvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgICAgIGpvb2xhLmxvZ2dlci5lcnJvcignW2FwaV0gRXJyb3I6ICcgKyBvcHRpb25zLmhvc3QgKyAnOicgKyBvcHRpb25zLnBvcnQgKyBvcHRpb25zLnBhdGggKyAnLiBFcnJvcjogJyArIGV4Lm1lc3NhZ2UpO1xuICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdbYXBpXSBFcnJvcjogJyArIG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydCArIG9wdGlvbnMucGF0aCArICcuIEVycm9yOiAnICsgZXgubWVzc2FnZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzLnN0YXR1c0NvZGUgPT0gMjAwKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgb2JqKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAocmVzLnN0YXR1c0NvZGUgPT0gMzAyKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSByZXF1ZXN0IFsnICsgcmVzLnN0YXR1c0NvZGUgKyAnXTogQXV0aGVudGljYXRpb24gRmFpbGVkJykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChyZXMuc3RhdHVzQ29kZSA9PSA0MDEpIHtcbiAgICAgICAgICAgIC8vbGV0J3MgcmVkaXJlY3QgdG8gbG9naW5cbiAgICAgICAgICAgIGlmIChqb29sYS5vcHRpb25zLmxvZ291dHVybClcbiAgICAgICAgICAgICAgbG9jYXRpb24uaHJlZiA9IGpvb2xhLm9wdGlvbnMubG9nb3V0dXJsO1xuXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSByZXF1ZXN0IFsnICsgcmVzLnN0YXR1c0NvZGUgKyAnXTogJyArIChvYmogJiYgb2JqLm1lc3NhZ2UgIT09ICd1bmRlZmluZWQnID8gb2JqLm1lc3NhZ2UgOiAnVW5hdXRob3JpemVkJykpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSByZXF1ZXN0IFsnICsgcmVzLnN0YXR1c0NvZGUgKyAnXTogJyArIChvYmogJiYgb2JqLm1lc3NhZ2UgPyBvYmoubWVzc2FnZSA6IG9iaiB8fCAnbi9hJykpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHRpbWVySUQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYWJvcnRlZCA9IHRydWU7XG4gICAgICAgIC8vQWJvcnRpbmcgdGhlIHhociBvZiBodHRwKHMpLWJyb3dzZXJpZnlcbiAgICAgICAgaWYgKHJlcS54aHIpXG4gICAgICAgICAgcmVxLnhoci5hYm9ydCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgcmVxLmFib3J0KCk7XG4gICAgICB9LCBvcHRpb25zLnRpbWVvdXQgfHwgam9vbGEub3B0aW9ucy50aW1lb3V0IHx8IDE1MDAwKTtcblxuICAgICAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICB9KTtcblxuICAgICAgLy9yZXEud3JpdGUocXMpO1xuICAgICAgcmVxLmVuZCgpO1xuICAgIH1cbiAgICBjYXRjaCAoZXgpIHtcbiAgICAgIGNvbnNvbGUubG9nKGV4KTtcbiAgICB9XG4gIH1cbiAgZWxzZSB7XG4gICAgb3B0aW9ucy5wYXRoID0gb3B0aW9ucy5wYXRoLnN1YnN0cmluZygxKTtcblxuICAgIHZhciBwcm9jZXNzUmVzcG9uc2UgPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgdmFyIGhlYWRlcnMgPSBkYXRhLmhlYWRlcnM7XG4gICAgICB2YXIgbWVzc2FnZSA9IGRhdGEubWVzc2FnZTtcblxuICAgICAgaWYgKG1lc3NhZ2UgJiYgIW1lc3NhZ2UuaGFzT3duUHJvcGVydHkoJ3JlYWx0aW1lJykpIHtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JwYzpkb25lJywgMSk7XG4gICAgICAgIC8vam9vbGEuZXZlbnRzLmVtaXQoJ2JhbmR3aWR0aCcsIGxlbmd0aEluVXRmOEJ5dGVzKEpTT04uc3RyaW5naWZ5KG9iak9wdGlvbnMpKSk7XG4gICAgICAgIGlmIChoZWFkZXJzICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSlcbiAgICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnd2FpdHRpbWUnLCBoZWFkZXJzWydYLWpvb2xhLUR1cmF0aW9uJ10pO1xuICAgICAgICBpZiAoaGVhZGVycyAmJiBoZWFkZXJzWydYLWpvb2xhLUR1cmF0aW9uLUZ1bGZpbGxlZCddICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSlcbiAgICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnbGF0ZW5jeScsIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSAtIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24tRnVsZmlsbGVkJ10pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JwYzpkb25lJywgMSk7XG4gICAgICAgIC8vam9vbGEuZXZlbnRzLmVtaXQoJ2JhbmR3aWR0aCcsIGxlbmd0aEluVXRmOEJ5dGVzKEpTT04uc3RyaW5naWZ5KG9iak9wdGlvbnMpKSk7XG4gICAgICAgIGlmIChoZWFkZXJzICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSlcbiAgICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnd2FpdHRpbWUnLCBoZWFkZXJzWydYLWpvb2xhLUR1cmF0aW9uJ10pO1xuICAgICAgICBpZiAoaGVhZGVycyAmJiBoZWFkZXJzWydYLWpvb2xhLUR1cmF0aW9uLUZ1bGZpbGxlZCddICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSlcbiAgICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnbGF0ZW5jeScsIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSAtIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24tRnVsZmlsbGVkJ10pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGVhZGVycyAmJiBoZWFkZXJzLlN0YXR1c0NvZGUgJiYgaGVhZGVycy5TdGF0dXNDb2RlID09IDQwMSkge1xuICAgICAgICAvL2xldCdzIHJlZGlyZWN0IHRvIGxvZ2luXG4gICAgICAgIGlmIChqb29sYS5vcHRpb25zLmxvZ291dHVybClcbiAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gam9vbGEub3B0aW9ucy5sb2dvdXR1cmw7XG5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignRmFpbGVkIHRvIGV4ZWN1dGUgcmVxdWVzdDogJyArIGRhdGEubWVzc2FnZS5tZXNzYWdlKSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChoZWFkZXJzICYmIGhlYWRlcnMuU3RhdHVzQ29kZSAmJiBoZWFkZXJzLlN0YXR1c0NvZGUgPT0gNTAwKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobWVzc2FnZS5tZXNzYWdlID8gbWVzc2FnZS5tZXNzYWdlIDogJ3Vua25vd24gZXJyb3InKTtcblxuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG1lc3NhZ2UsIGhlYWRlcnMpO1xuICAgIH07XG5cblxuICAgIHZhciByb3V0ZUlEID0gb3B0aW9ucy5wYXRoICsgJy0nICsgam9vbGEuY29tbW9uLnV1aWQoKTtcblxuICAgIGlmIChqb29sYS5UT0tFTilcbiAgICAgIG9iak9wdGlvbnMuX3Rva2VuID0gam9vbGEuVE9LRU47XG4gICAgaWYgKCFvYmpPcHRpb25zLl90b2tlbilcbiAgICAgIG9iak9wdGlvbnMuQVBJVG9rZW4gPSBqb29sYS5BUElUT0tFTjtcblxuICAgIGlmIChvcHRpb25zLnRva2VucyAmJiAob3B0aW9ucy50b2tlbnMuXyB8fCBvcHRpb25zLnRva2Vucy5fXykpIHtcbiAgICAgIG9iak9wdGlvbnMuX3Rva2VuID0gbnVsbDtcbiAgICAgIG9iak9wdGlvbnMuQVBJVG9rZW4gPSBudWxsO1xuICAgICAgaWYgKG9wdGlvbnMudG9rZW5zLl8pXG4gICAgICAgIG9iak9wdGlvbnMuX3Rva2VuID0gb3B0aW9ucy50b2tlbnMuXztcbiAgICAgIGlmIChvcHRpb25zLnRva2Vucy5fXylcbiAgICAgICAgb2JqT3B0aW9ucy5BUElUb2tlbiA9IG9wdGlvbnMudG9rZW5zLl9fO1xuICAgIH1cblxuICAgIG9iak9wdGlvbnMuX3BhdGggPSBvcHRpb25zLnBhdGg7XG5cbiAgICBqb29sYS5pby5zb2NrZXQuZW1pdChyb3V0ZUlELCBvYmpPcHRpb25zKTtcbiAgICBqb29sYS5ldmVudHMuZW1pdCgncnBjOnN0YXJ0JywgMSk7XG4gICAgam9vbGEuZXZlbnRzLmVtaXQoJ2JhbmR3aWR0aCcsIGxlbmd0aEluVXRmOEJ5dGVzKEpTT04uc3RyaW5naWZ5KG9iak9wdGlvbnMpKSk7XG4gICAgdmFyIHNob3VsZE9uID0gb2JqT3B0aW9ucyAmJiAob2JqT3B0aW9ucy5yZWFsdGltZSB8fCAob2JqT3B0aW9ucy5vcHRpb25zICYmIEFycmF5LmlzQXJyYXkob2JqT3B0aW9ucy5vcHRpb25zKSAmJiBvYmpPcHRpb25zLm9wdGlvbnMubGVuZ3RoID4gMCAmJiBvYmpPcHRpb25zLm9wdGlvbnNbMF0ucmVhbHRpbWUpKTtcbiAgICBpZiAob2JqT3B0aW9ucyAmJiBvYmpPcHRpb25zLm9wdGlvbnMgJiYgb2JqT3B0aW9ucy5vcHRpb25zLnJlYWx0aW1lKVxuICAgICAgc2hvdWxkT24gPSB0cnVlO1xuICAgIGlmIChzaG91bGRPbikge1xuICAgICAgam9vbGEuaW8uc29ja2V0Lm9uKHJvdXRlSUQgKyAnOmRvbmUnLCBwcm9jZXNzUmVzcG9uc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGpvb2xhLmlvLnNvY2tldC5vbmNlKHJvdXRlSUQgKyAnOmRvbmUnLCBwcm9jZXNzUmVzcG9uc2UpO1xuICAgIH1cbiAgfVxufTtcblxuam9vbGEuZXZlbnRzLm9uKCdycGM6c3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gIGlmICgham9vbGEudXNhZ2UpXG4gICAgam9vbGEudXNhZ2UgPSB7Y3VycmVudENhbGxzOiAwfTtcbiAgam9vbGEudXNhZ2UuY3VycmVudENhbGxzKys7XG59KTtcblxuam9vbGEuZXZlbnRzLm9uKCdycGM6ZG9uZScsIGZ1bmN0aW9uICgpIHtcbiAgaWYgKCFqb29sYS51c2FnZSlcbiAgICBqb29sYS51c2FnZSA9IHtjdXJyZW50Q2FsbHM6IDB9O1xuICBqb29sYS51c2FnZS5jdXJyZW50Q2FsbHMtLTtcbn0pOyIsIi8qKlxuICogIGpvb2xhXG4gKlxuICogIENvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICpcbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKTtcblxudmFyIGRpc3BhdGNoID0gZXhwb3J0cztcbmRpc3BhdGNoLl9pZCA9ICdkaXNwYXRjaCc7XG5cbmRpc3BhdGNoLmZldGNoTWV0YSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB2YXIgbWV0YSA9IHJlcXVpcmUoJy4uLy4uLy4uL2J1aWxkL3RlbXAvbWV0YS5qc29uJyk7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBtZXRhKTtcbn07XG5cbmRpc3BhdGNoLmJ1aWxkc3R1YiA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGVtcHR5ZnVuYztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZGlzcGF0Y2guZmV0Y2hNZXRhKGZ1bmN0aW9uIChlcnIsIHJlc3VsdCkge1xuICAgIGpvb2xhLmFwaS5kZXNjcmliZSA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHJlc3VsdCkuZm9yRWFjaChmdW5jdGlvbiAoZW5kcG9pbnRzKSB7XG4gICAgICBkaXNwYXRjaFtlbmRwb2ludHNdID0ge307XG4gICAgICBPYmplY3Qua2V5cyhyZXN1bHRbZW5kcG9pbnRzXSkuZm9yRWFjaChmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgaWYgKCFqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXSlcbiAgICAgICAgICBqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXSA9IHt9O1xuICAgICAgICBqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXVtmbl0gPSBjZS5jbG9uZWV4dGVuZChyZXN1bHRbZW5kcG9pbnRzXVtmbl0pO1xuXG4gICAgICAgIHZhciBfZm4gPSByZXN1bHRbZW5kcG9pbnRzXVtmbl07XG4gICAgICAgIGRpc3BhdGNoW2VuZHBvaW50c11bZm5dID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciB0b2tlbnMgPSB7XG4gICAgICAgICAgICBfOiBudWxsLFxuICAgICAgICAgICAgX186IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICBpZiAoYXJncyAmJiBhcmdzLmxlbmd0aCA+IDAgJiYgYXJnc1swXSAmJiAoYXJnc1swXS5fIHx8IGFyZ3NbMF0uX18pKSB7XG4gICAgICAgICAgICB0b2tlbnMuXyA9IGFyZ3NbMF0uXztcbiAgICAgICAgICAgIHRva2Vucy5fXyA9IGFyZ3NbMF0uX187XG4gICAgICAgICAgICBhcmdzLnNwbGljZSgwLCAxKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYWxsYmFjayA9IGVtcHR5ZnVuYztcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZ3NbT2JqZWN0LmtleXMoYXJncykubGVuZ3RoIC0gMV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gYXJnc1tPYmplY3Qua2V5cyhhcmdzKS5sZW5ndGggLSAxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFsndmVyaWZ5QVBJVG9rZW4nLCAnZ2V0QnlUb2tlbiddLmluZGV4T2YoZm4pID09PSAtMSkge1xuICAgICAgICAgICAgaWYgKCFqb29sYS5jb25uZWN0ZWQpXG4gICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ0pvb2xhIG5vdCBjb25uZWN0ZWQuJykpO1xuICAgICAgICAgICAgaWYgKCFqb29sYS5VU0VSKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZuKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignSm9vbGEgbm90IGNvbm5lY3RlZCwgaW52YWxpZCB1c2VyLicpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGFyZ0NvdW50ZXIgPSAwO1xuICAgICAgICAgIHZhciBfYXJncyA9IHt9O1xuICAgICAgICAgIGlmIChfZm4uaW5wdXRzLnJlcXVpcmVkKVxuICAgICAgICAgICAgX2ZuLmlucHV0cyA9IF9mbi5pbnB1dHMucmVxdWlyZWQuY29uY2F0KF9mbi5pbnB1dHMub3B0aW9uYWwpO1xuXG4gICAgICAgICAgdmFyIHNob3VsZEFwcGVuZFdvcmtzcGFjZSA9IDA7XG5cbiAgICAgICAgICAvL2lmICgoYXJncy5sZW5ndGggLSAxID09IF9mbi5pbnB1dHMubGVuZ3RoIC0gMSB8fCAoYXJncy5sZW5ndGggLSAxID09IF9mbi5pbnB1dHMubGVuZ3RoIC0gMiAmJiBfZm4uaW5wdXRzW19mbi5pbnB1dHMubGVuZ3RoIC0gMV0gPT0gJ29wdGlvbnMnKSkgJiYgX2ZuLmlucHV0c1swXSAmJiAoX2ZuLmlucHV0c1swXSA9PT0gJ3dvcmtzcGFjZScpKSB7XG4gICAgICAgICAgaWYgKF9mbi5pbnB1dHNbMF0gPT09ICd3b3Jrc3BhY2UnICYmIGFyZ3MubGVuZ3RoIC0gMSA8IF9mbi5pbnB1dHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBzaG91bGRBcHBlbmRXb3Jrc3BhY2UgPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2hvdWxkQXBwZW5kV29ya3NwYWNlID4gMClcbiAgICAgICAgICAgIF9hcmdzW19mbi5pbnB1dHNbMF1dID0gam9vbGEuVVNFUi53b3Jrc3BhY2U7XG4gICAgICAgICAgT2JqZWN0LmtleXMoYXJncykuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICBpZiAoYXJnQ291bnRlciA8IF9mbi5pbnB1dHMubGVuZ3RoIC0gc2hvdWxkQXBwZW5kV29ya3NwYWNlKSB7XG4gICAgICAgICAgICAgIGFyZ3NbX2ZuLmlucHV0c1thcmdDb3VudGVyICsgc2hvdWxkQXBwZW5kV29ya3NwYWNlXV0gPSBhcmdzW2FyZ107XG4gICAgICAgICAgICAgIF9hcmdzW19mbi5pbnB1dHNbYXJnQ291bnRlciArIHNob3VsZEFwcGVuZFdvcmtzcGFjZV1dID0gYXJnc1thcmddO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWxldGUgYXJnc1thcmddO1xuICAgICAgICAgICAgYXJnQ291bnRlcisrO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXJncyA9IF9hcmdzO1xuICAgICAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnWycgKyBlbmRwb2ludHMgKyAnOicgKyBmbiArICddIGNhbGxlZCB3aXRoOiAnICsgSlNPTi5zdHJpbmdpZnkoYXJncykpO1xuXG4gICAgICAgICAgdmFyIF9jYWxsYmFjayA9IGNlLmNsb25lKGNhbGxiYWNrKTsvLy5jbG9uZSgpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBqb29sYS5hcGkuZmV0Y2godG9rZW5zLCBfZm4ubmFtZSwgYXJncywgZnVuY3Rpb24gKGVyciwgcmVzdWx0LCBoZWFkZXJzKSB7XG4gICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NhbGxiYWNrKGVyciwgcmVzdWx0LCBoZWFkZXJzKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgIHJldHVybiBfY2FsbGJhY2soZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCFqb29sYVtlbmRwb2ludHNdKVxuICAgICAgICAgIGpvb2xhW2VuZHBvaW50c10gPSB7fTtcbiAgICAgICAgaWYgKCFqb29sYVtlbmRwb2ludHNdW2ZuXSlcbiAgICAgICAgICBqb29sYVtlbmRwb2ludHNdW2ZuXSA9IGRpc3BhdGNoW2VuZHBvaW50c11bZm5dO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvL21hcCBhbGlhc2VzXG4gICAgam9vbGEuaW5zZXJ0ID0gam9vbGEuYmVhY29uLmluc2VydDtcbiAgICBqb29sYS5mZXRjaCA9IGpvb2xhLnF1ZXJ5LmZldGNoO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICB9KTtcbn07XG5cbiIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgRXZlbnRFbWl0dGVyMiA9IHJlcXVpcmUoJ2V2ZW50ZW1pdHRlcjInKS5FdmVudEVtaXR0ZXIyO1xuXG52YXIgX2V2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXIyKHt3aWxkY2FyZDogdHJ1ZSwgbmV3TGlzdGVuZXI6IHRydWV9KTtcbl9ldmVudHMuX2lkID0gJ2V2ZW50cyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IF9ldmVudHM7XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTsvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXIgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpO1xuXG5nbG9iYWwuZW1wdHlmdW5jID0gZnVuY3Rpb24gKCkge1xuXG59O1xuXG5qb29sYS50aW1lem9uZSA9IGZ1bmN0aW9uICh0eikge1xuICBpZiAodHopXG4gICAgam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCA9IHR6O1xuXG4gIHZhciBvZmZzZXQgPSAwO1xuICBpZiAoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldClcbiAgICBvZmZzZXQgPSBqb29sYS5vcHRpb25zLnRpbWV6b25lT2Zmc2V0IHx8IChuZXcgRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MCAqIC0xKTtcblxuICByZXR1cm4gb2Zmc2V0O1xufTsiLCJ2YXIgQnVmZmVyPXJlcXVpcmUoXCJfX2Jyb3dzZXJpZnlfQnVmZmVyXCIpLkJ1ZmZlcjsvKmpzaGludCAtVzA4MyAqL1xuXG4vKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyksXG4gIGRlID0gcmVxdWlyZSgnZGVlcC1leHRlbmQnKSxcbiAgdHJhdmVyc2UgPSByZXF1aXJlKCd0cmF2ZXJzZScpLFxuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpOy8vLFxuLy9KU09OU3RyZWFtID0gcmVxdWlyZSgnSlNPTlN0cmVhbScpO1xuXG52YXIgY29tbW9uID0gY2UuY2xvbmUodXRpbCk7XG5jb21tb24uX2lkID0gJ2NvbW1vbic7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBjb21tb247XG5jb21tb24uZXh0ZW5kID0gY29tbW9uLl9leHRlbmQ7XG5jb21tb24uXyA9IF87XG5cbnJlcXVpcmUoJy4vbW9kaWZpZXJzJyk7XG5cbmNvbW1vbi5taXhpbiA9IGZ1bmN0aW9uIChvcmlnaW4sIGFkZCwgb3ZlcndyaXRlKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgdHlwZW9mIGFkZCAhPT0gJ29iamVjdCcpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IDA7Ly9rZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGkgPCBrZXlzLmxlbmd0aCkge1xuICAgIGlmIChvcmlnaW4uaGFzT3duUHJvcGVydHkoa2V5c1tpXSkpIHtcbiAgICAgIGlmIChvdmVyd3JpdGUpXG4gICAgICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgICAgIC8vZWxzZVxuICAgICAgLy9jb21tb24uZXh0ZW5kKG9yaWdpbltrZXlzW2ldXSwgYWRkW2tleXNbaV1dKTtcblxuICAgIH1cbiAgICBlbHNlXG4gICAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gICAgaSsrO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5jb21tb24uX21peGluID0gZnVuY3Rpb24gKGRlc3RpbmF0aW9uLCBzb3VyY2UpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAxIHx8IHR5cGVvZiBhcmd1bWVudHNbMF0gIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gYXJndW1lbnRzWzBdO1xuXG4gIHZhciB0YXJnZXQgPSBhcmd1bWVudHNbMF07XG5cbiAgLy8gY29udmVydCBhcmd1bWVudHMgdG8gYXJyYXkgYW5kIGN1dCBvZmYgdGFyZ2V0IG9iamVjdFxuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgdmFyIGtleSwgdmFsLCBzcmMsIGNsb25lLCB0bXBCdWY7XG5cbiAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHJldHVybjtcblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmICghKGtleSBpbiBvYmopKSBjb250aW51ZTtcblxuICAgICAgc3JjID0gdGFyZ2V0W2tleV07XG4gICAgICB2YWwgPSBvYmpba2V5XTtcblxuICAgICAgaWYgKHZhbCA9PT0gdGFyZ2V0KSBjb250aW51ZTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIGtleSA9PT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSB2YWw7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHZhbCAhPT0gJ29iamVjdCcgfHwgdmFsID09PSBudWxsKSB7XG4gICAgICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgIHRtcEJ1ZiA9IG5ldyBCdWZmZXIodmFsLmxlbmd0aCk7XG4gICAgICAgIHZhbC5jb3B5KHRtcEJ1Zik7XG4gICAgICAgIHRhcmdldFtrZXldID0gdG1wQnVmO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBzcmMgIT09ICdvYmplY3QnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgICAgICBjbG9uZSA9IChBcnJheS5pc0FycmF5KHZhbCkpID8gW10gOiB7fTtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBjb21tb24uX21peGluKGNsb25lLCB2YWwpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICBjbG9uZSA9IChBcnJheS5pc0FycmF5KHNyYykpID8gc3JjIDogW107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9uZSA9ICghQXJyYXkuaXNBcnJheShzcmMpKSA/IHNyYyA6IHt9O1xuICAgICAgfVxuXG4gICAgICB0YXJnZXRba2V5XSA9IGNvbW1vbi5fbWl4aW4oY2xvbmUsIHZhbCk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG5cbi8vaG9vayBmdW5jdGlvbnMgZm9yIHRpbWluZ3Ncbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5jb21tb24uaG9va0V2ZW50cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYgKCFvYmopXG4gICAgcmV0dXJuO1xuICB2YXIgbmFtZSwgZm4sIG9ial9pZDtcblxuICBpZiAob2JqLl9pZClcbiAgICBvYmpfaWQgPSBvYmouX2lkO1xuXG4gIGZvciAobmFtZSBpbiBvYmopIHtcbiAgICBmbiA9IG9ialtuYW1lXTtcbiAgICBpZiAobmFtZS5zdWJzdHJpbmcoMCwgMSkgPT0gJ18nKVxuICAgICAgY29udGludWU7XG5cbiAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIG5hbWUgIT09ICdob29rRXZlbnRzJykge1xuICAgICAgb2JqW25hbWVdID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICB2YXIgdGltZUlEID0gJ0Z1bmN0aW9uICcgKyAob2JqX2lkID8gb2JqX2lkICsgJy4nIDogJycpICsgbmFtZTtcblxuICAgICAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkICYmIGNvbnNvbGUudGltZSlcbiAgICAgICAgICAgIGNvbnNvbGUudGltZSh0aW1lSUQpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBmbi5hcHBseShzZWxmLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkICYmIGNvbnNvbGUudGltZSkge1xuICAgICAgICAgICAgY29uc29sZS50aW1lRW5kKHRpbWVJRCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9KG5hbWUsIGZuKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGZuID09PSAnb2JqZWN0JylcbiAgICAgIHRoaXMuaG9va0V2ZW50cyhmbik7XG4gIH1cbn07XG5cbmNvbW1vbi51dWlkID0gZnVuY3Rpb24gKGxlbmd0aCkge1xuICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg4NTU2ODcvc2VjdXJlLXJhbmRvbS10b2tlbi1pbi1ub2RlLWpzXG4gIGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhsZW5ndGgsIGNoYXJzKSB7XG4gICAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICAgIHZhciByYW5kb21CeXRlcyA9IGNyeXB0by5yYW5kb21CeXRlcyhsZW5ndGgpO1xuICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB2YXIgY3Vyc29yID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjdXJzb3IgKz0gcmFuZG9tQnl0ZXNbaV07XG4gICAgICByZXN1bHRbaV0gPSBjaGFyc1tjdXJzb3IgJSBjaGFyc0xlbmd0aF07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gIH1cblxuICByZXR1cm4gcmFuZG9tU3RyaW5nKGxlbmd0aCB8fCAzMiwgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVXWFlaMDEyMzQ1Njc4OScpO1xufTtcblxuY29tbW9uLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBKU09OLnN0cmluZ2lmeShvYmopKTtcbn07XG5cbmNvbW1vbi5wYXJzZSA9IGZ1bmN0aW9uIChzdHJpbmcsIGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBKU09OLnBhcnNlKHN0cmluZykpO1xufTtcblxuY29tbW9uLmhhc2ggPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gIHJldHVybiByZXF1aXJlKCdjcnlwdG8nKS5jcmVhdGVIYXNoKCdtZDUnKS51cGRhdGUoc3RyaW5nKS5kaWdlc3QoXCJoZXhcIik7XG59O1xuXG5jb21tb24uZW5zdXJlTGVuZ3RoID0gZnVuY3Rpb24gKHN0cmluZywgbGVuZ3RoKSB7XG4gIGlmICghc3RyaW5nKVxuICAgIHJldHVybiBzdHJpbmc7XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJylcbiAgICByZXR1cm4gc3RyaW5nO1xuICBpZiAoc3RyaW5nID09PSAnJylcbiAgICByZXR1cm47XG4gIHZhciBjb3VudGVyID0gMDtcbiAgd2hpbGUgKHN0cmluZy5sZW5ndGggPiBsZW5ndGggJiYgY291bnRlciA8IDEwMCkge1xuICAgIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKCcuLi4nLCAnJyk7XG4gICAgc3RyaW5nID0gc3RyaW5nLnN1YnN0cmluZygwLCBzdHJpbmcubGVuZ3RoIC0gMSkgKyAnLi4uJztcbiAgICBjb3VudGVyKys7XG4gIH1cbiAgcmV0dXJuIHN0cmluZztcbn07XG5cbmNvbW1vbi5mbGF0R2V0U2V0ID0gZnVuY3Rpb24gKG9iaiwgaXMsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgaXMgPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gY29tbW9uLmZsYXRHZXRTZXQob2JqLCBpcy5zcGxpdCgnLicpLCB2YWx1ZSk7XG4gIH1cbiAgZWxzZSBpZiAoaXMubGVuZ3RoID09IDEgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGRlbGV0ZSBvYmpbaXNbMF1dO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9ialtpc1swXV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgZWxzZSB7XG4gICAgICAvL2NoZWNrIGlmIGNvbnZlcnRlZCBhcnJheVxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIE9iamVjdC5rZXlzKG9iailbMF0gPT09ICcwJylcbiAgICAgICAgcmV0dXJuIGNvbW1vbi5vYmpUb0FycmF5KG9iaik7XG5cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJyB8fCBvYmogPT09IG51bGwpXG4gICAgICBvYmogPSB7fTtcbiAgICBpZiAodHlwZW9mIG9ialtpc1swXV0gPT09ICd1bmRlZmluZWQnIHx8IG9ialtpc1swXV0gPT09IG51bGwpXG4gICAgICBvYmpbaXNbMF1dID0ge307XG4gICAgcmV0dXJuIGNvbW1vbi5mbGF0R2V0U2V0KG9ialtpc1swXV0sIGlzLnNsaWNlKDEpLCB2YWx1ZSk7XG4gIH1cbn07XG5cbmNvbW1vbi5pc051bWVyaWMgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShvYmopICYmIChvYmogLSBwYXJzZUZsb2F0KG9iaikgKyAxKSA+PSAwO1xufTtcblxuY29tbW9uLmZvcm1hdERpbWVuc2lvbiA9IGZ1bmN0aW9uICh2YWx1ZSwgZGltZW5zaW9uKSB7XG4gIHZhciByZXN1bHQgPSB2YWx1ZTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbW1vbi5mb3JtYXRNZXRyaWMgPSBmdW5jdGlvbiAodmFsdWUsIG1ldHJpYykge1xuICBpZiAoIW1ldHJpYylcbiAgICBtZXRyaWMgPSB7fTtcbiAgdmFyIHJlc3VsdCA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICBpZiAobWV0cmljLmRlY2ltYWxzKVxuICAgIHJlc3VsdCA9IHJlc3VsdC50b0ZpeGVkKG1ldHJpYy5kZWNpbWFscyk7XG4gIGlmICgobWV0cmljLmhhc093blByb3BlcnR5KCdjb21tYXMnKSAmJiBtZXRyaWMuY29tbWFzICkgfHwgdHJ1ZSkge1xuICAgIHJlc3VsdCA9IHJlc3VsdC5jb21tYXMoKTtcbiAgfVxuICBpZiAobWV0cmljLnByZWZpeClcbiAgICByZXN1bHQgPSBtZXRyaWMucHJlZml4ICsgcmVzdWx0O1xuICBpZiAobWV0cmljLnN1ZmZpeClcbiAgICByZXN1bHQgKz0gbWV0cmljLnN1ZmZpeDtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbW1vbi5wZXJjZW50YWdlQ2hhbmdlID0gZnVuY3Rpb24gKG51bTEsIG51bTIpIHtcbiAgdmFyIHJlc3VsdCA9ICgobnVtMiAtIG51bTEpIC8gbnVtMSAqIDEwMCkudG9GaXhlZCgyKTtcbiAgXG4gIGlmIChudW0xID09PSAwKVxuICAgIHJlc3VsdCA9ICfiiJ4nO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuY29tbW9uLmZvcm1hdERhdGUgPSBmdW5jdGlvbiAoZGF0ZSkge1xuICB2YXIgZm9ybWF0ID0gZnVuY3Rpb24gKGRhdGUsIGZvcm1hdFN0cmluZykge1xuICAgIHZhciBmb3JtYXREYXRlID0gZGF0ZTtcbiAgICB2YXIgbW9udGhzID0gW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdO1xuICAgIHZhciB5eXl5ID0gZm9ybWF0RGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIHZhciB5eSA9IHl5eXkudG9TdHJpbmcoKS5zdWJzdHJpbmcoMik7XG4gICAgdmFyIG0gPSBmb3JtYXREYXRlLmdldE1vbnRoKCkgKyAxO1xuICAgIHZhciBtbSA9IG0gPCAxMCA/IFwiMFwiICsgbSA6IG07XG4gICAgdmFyIG1tbSA9IG1vbnRoc1ttIC0gMV07XG4gICAgdmFyIGQgPSBmb3JtYXREYXRlLmdldERhdGUoKTtcbiAgICB2YXIgZGQgPSBkIDwgMTAgPyBcIjBcIiArIGQgOiBkO1xuICAgIHZhciBmZmYgPSBmb3JtYXREYXRlLmdldE1pbGxpc2Vjb25kcygpLnRvU3RyaW5nKCk7XG4gICAgZmZmID0gKGZmZiA8IDEwMCA/IGZmZiA8IDEwID8gJzAwJyArIGZmZiA6ICsnMCcgKyBmZmYgOiBmZmYpO1xuICAgIHZhciBoID0gZm9ybWF0RGF0ZS5nZXRIb3VycygpO1xuICAgIHZhciBoaCA9IGggPCAxMCA/IFwiMFwiICsgaCA6IGg7XG4gICAgdmFyIG4gPSBmb3JtYXREYXRlLmdldE1pbnV0ZXMoKTtcbiAgICB2YXIgbm4gPSBuIDwgMTAgPyBcIjBcIiArIG4gOiBuO1xuICAgIHZhciBzID0gZm9ybWF0RGF0ZS5nZXRTZWNvbmRzKCk7XG4gICAgdmFyIHNzID0gcyA8IDEwID8gXCIwXCIgKyBzIDogcztcblxuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC95eXl5L2ksIHl5eXkpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC95eS9pLCB5eSk7XG4gICAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL21tbS9pLCBtbW0pO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9tbS9pLCBtbSk7XG4gICAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbS9pLCBtKTtcbiAgICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvZGQvaSwgZGQpO1xuICAgIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2QvaSwgZCk7XG4gICAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2hoL2ksIGhoKTtcbiAgICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9oL2ksIGgpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9ubi9pLCBubik7XG4gICAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbi9pLCBuKTtcbiAgICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvc3MvaSwgc3MpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9mZmYvaSwgZmZmKTtcbiAgICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9zL2ksIHMpO1xuXG4gICAgcmV0dXJuIGZvcm1hdFN0cmluZztcbiAgfTtcblxuICByZXR1cm4gZm9ybWF0KGRhdGUsICdtbW0gZGQsIHl5eXknKTtcbn07IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKTtcbiAgXG52YXIgbG9nZ2VyID0gZXhwb3J0cztcbmxvZ2dlci5faWQgPSAnbG9nZ2VyJztcblxubG9nZ2VyLl9sb2cgPSBmdW5jdGlvbiAobGV2ZWwsIG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdkZWJ1Zyc6XG4gICAgY2FzZSAnaW5mbyc6XG4gICAgY2FzZSAnd2Fybic6XG4gICAgY2FzZSAnZXJyb3InOlxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2lsbHknOlxuICAgICAgbGV2ZWwgPSAnZGVidWcnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndHJhY2UnOlxuICAgICAgbGV2ZWwgPSAnZGVidWcnO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKCFqb29sYS5vcHRpb25zLmRlYnVnLmVuYWJsZWQpXG4gICAgcmV0dXJuO1xuXG4gIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ29iamVjdCcpXG4gICAgbWVzc2FnZSA9ICdbJyArIG5ldyBEYXRlKCkuZm9ybWF0KCdoaDpubjpzcy5mZmYnKSArICddICcgKyBKU09OLnN0cmluZ2lmeShtZXNzYWdlKTtcbiAgZWxzZVxuICAgIG1lc3NhZ2UgPSAnWycgKyBuZXcgRGF0ZSgpLmZvcm1hdCgnaGg6bm46c3MuZmZmJykgKyAnXSAnICsgbWVzc2FnZTtcblxuICBpZiAoam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIgJiYgY29uc29sZS5kZWJ1Zykge1xuICAgIGlmIChbJ3NpbGx5JywgJ2RlYnVnJ10uaW5kZXhPZihsZXZlbCkgPT0gLTEpXG4gICAgICBjb25zb2xlW2xldmVsXShtZXNzYWdlKTtcbiAgICBlbHNlIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmVuYWJsZWQgJiYgWydzaWxseScsICdkZWJ1ZyddLmluZGV4T2YobGV2ZWwpID4gLTEpXG4gICAgICBjb25zb2xlW2xldmVsXShtZXNzYWdlKTtcbiAgfVxuICBlbHNlXG4gICAgY29uc29sZS5sb2cobWVzc2FnZSk7XG5cbiAgaWYgKGNhbGxiYWNrKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbn07XG5cbmxvZ2dlci50cmFjZSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCd0cmFjZScsIG1lc3NhZ2UsIGNhbGxiYWNrKTtcbn07XG5cbmxvZ2dlci5zaWxseSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCdzaWxseScsIG1lc3NhZ2UsIGNhbGxiYWNrKTtcbn07XG5cbmxvZ2dlci5pbmZvID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9sb2coJ2luZm8nLCBtZXNzYWdlLCBjYWxsYmFjayk7XG59O1xuXG5sb2dnZXIuZGVidWcgPSBmdW5jdGlvbiAobWVzc2FnZSwgY2FsbGJhY2spIHtcbiAgcmV0dXJuIHRoaXMuX2xvZygnZGVidWcnLCBtZXNzYWdlLCBjYWxsYmFjayk7XG59O1xuXG5sb2dnZXIud2FybiA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCd3YXJuJywgbWVzc2FnZSwgY2FsbGJhY2spO1xufTtcblxubG9nZ2VyLmVycm9yID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9sb2coJ2Vycm9yJywgbWVzc2FnZSwgY2FsbGJhY2spO1xufTtcblxuIiwidmFyIG1lbW9yeSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb250ZW50ID0ge307XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbiAoa2V5LCBkYXRhLCBleHBpcmUpIHtcbiAgICBleHBpcmUgPSBleHBpcmUgfHwgMTAwMDtcbiAgICB0aGlzLnJlbW92ZShrZXkpO1xuICAgIHRoaXMuY29udGVudFtrZXldID0ge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIHRpbWVyOiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoa2V5KTtcbiAgICAgIH0uYmluZCh0aGlzKSwgZXhwaXJlKVxuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKHR5cGVvZih0aGlzLmNvbnRlbnRba2V5XSkgIT09IFwidW5kZWZpbmVkXCIgJiYgdGhpcy5jb250ZW50W2tleV0gIT09IG51bGwgJiYgdHlwZW9mKHRoaXMuY29udGVudFtrZXldLmRhdGEpICE9PSBcInVuZGVmaW5lZFwiICYmIHRoaXMuY29udGVudFtrZXldLmRhdGEgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRba2V5XS5kYXRhO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAodHlwZW9mKHRoaXMuY29udGVudFtrZXldKSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0aGlzLmNvbnRlbnRba2V5XSAhPT0gbnVsbCAmJiB0eXBlb2YodGhpcy5jb250ZW50W2tleV0udGltZXIpICE9PSBcInVuZGVmaW5lZFwiICYmIHRoaXMuY29udGVudFtrZXldLnRpbWVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jb250ZW50W2tleV0udGltZXIpO1xuICAgICAgZGVsZXRlIHRoaXMuY29udGVudFtrZXldO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldFN0b3JlQ29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50O1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgbWVtb3J5KCk7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhL2xpYi9jb21tb24vbW9kaWZpZXJzXG4gKiAgQG92ZXJ2aWV3IEluY2x1ZGVzIGRpZmZlcmVudCBwcm90b3R5cGUgbW9kaWZpZXJzIHVzZWQgYnkgam9vbGFcbiAqICBAZGVzY3JpcHRpb25cbiAqICBqb29sYSByZXF1aXJlcyBzb21lIGFkZGl0aW9uYWwgc3VwcG9ydCBmb3IgcHJvdG90eXBlIG1vZGlmaWNhdGlvbiwgZm9yIGV4YW1wbGUsIGV4dGVuZGluZyBEYXRlIHRvIHN1cHBvcnQgZm9ybWF0LlxuICpcbiAqICBAY29weXJpZ2h0IChjKSBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+LiBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlNcbiAqKi9cblxuLyoqXG4gKiBAZnVuY3Rpb24gRGF0ZS5wcm90b3R5cGUuZm9ybWF0XG4gKiBNb2RpZmllcyBEYXRlIHRvIHN1cHBvcnQgZm9ybWF0dGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdFN0cmluZyBob2xkcyB0aGUgZm9ybWF0dGluZyBzdHJpbmcgdG8gYXBwbHkgb24gdGhlIGRhdGVcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGZvcm1hdHRlZCBzdHJpbmcgZnJvbSB0aGUgZGF0ZS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBvbiBjb21wbGV0aW9uIGEgZm9ybWF0dGVkIHN0cmluZyBiYXNlZCBvbiBgZm9ybWF0U3RyaW5nYCBmcm9tIHRoZSBEYXRlIG9iamVjdDpcbiAqXG4gKiBgYGBqc1xuICogdmFyIGZvcm1hdHRlZCA9IG5ldyBEYXRlKCkuZm9ybWF0KCd5eXl5LW1tLWRkIGhoOm1tOnNzLmZmZicpO1xuICogYGBgXG4gKi9cbkRhdGUucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uIChmb3JtYXRTdHJpbmcpIHtcbiAgdmFyIGZvcm1hdERhdGUgPSB0aGlzO1xuICB2YXIgbW9udGhzID0gW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdO1xuICB2YXIgeXl5eSA9IGZvcm1hdERhdGUuZ2V0RnVsbFllYXIoKTtcbiAgdmFyIHl5ID0geXl5eS50b1N0cmluZygpLnN1YnN0cmluZygyKTtcbiAgdmFyIG0gPSBmb3JtYXREYXRlLmdldE1vbnRoKCkgKyAxO1xuICB2YXIgbW0gPSBtIDwgMTAgPyBcIjBcIiArIG0gOiBtO1xuICB2YXIgbW1tID0gbW9udGhzW20gLSAxXTtcbiAgdmFyIGQgPSBmb3JtYXREYXRlLmdldERhdGUoKTtcbiAgdmFyIGRkID0gZCA8IDEwID8gXCIwXCIgKyBkIDogZDtcbiAgdmFyIGZmZiA9IGZvcm1hdERhdGUuZ2V0TWlsbGlzZWNvbmRzKCkudG9TdHJpbmcoKTtcbiAgZmZmID0gKGZmZiA8IDEwMCA/IGZmZiA8IDEwID8gJzAwJyArIGZmZiA6ICsnMCcgKyBmZmYgOiBmZmYpO1xuICB2YXIgaCA9IGZvcm1hdERhdGUuZ2V0SG91cnMoKTtcbiAgdmFyIGhoID0gaCA8IDEwID8gXCIwXCIgKyBoIDogaDtcbiAgdmFyIG4gPSBmb3JtYXREYXRlLmdldE1pbnV0ZXMoKTtcbiAgdmFyIG5uID0gbiA8IDEwID8gXCIwXCIgKyBuIDogbjtcbiAgdmFyIHMgPSBmb3JtYXREYXRlLmdldFNlY29uZHMoKTtcbiAgdmFyIHNzID0gcyA8IDEwID8gXCIwXCIgKyBzIDogcztcblxuICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgveXl5eS9pLCB5eXl5KTtcbiAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL3l5L2ksIHl5KTtcbiAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL21tbS9pLCBtbW0pO1xuICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbW0vaSwgbW0pO1xuICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9tLywgbSk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9kZC9pLCBkZCk7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2QvaSwgZCk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9oaC9pLCBoaCk7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2gvaSwgaCk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9ubi9pLCBubik7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL24vaSwgbik7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9zcy9pLCBzcyk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9mZmYvaSwgZmZmKTtcbiAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvcy9pLCBzKTtcblxuICByZXR1cm4gZm9ybWF0U3RyaW5nO1xufTtcblxuRGF0ZS5kYXRlRGlmZiA9IGZ1bmN0aW9uIChkYXRlcGFydCwgZnJvbWRhdGUsIHRvZGF0ZSkge1xuICBkYXRlcGFydCA9IGRhdGVwYXJ0LnRvTG93ZXJDYXNlKCk7XG4gIHZhciBkaWZmID0gdG9kYXRlIC0gZnJvbWRhdGU7XG4gIHZhciBkaXZpZGVCeSA9IHsgdzogNjA0ODAwMDAwLFxuICAgIGQ6IDg2NDAwMDAwLFxuICAgIGg6IDM2MDAwMDAsXG4gICAgbjogNjAwMDAsXG4gICAgczogMTAwMCB9O1xuXG4gIHJldHVybiBNYXRoLmZsb29yKGRpZmYgLyBkaXZpZGVCeVtkYXRlcGFydF0pO1xufTtcblxuLyoqXG4gKiBAZnVuY3Rpb24gT2JqZWN0LmRlZmluZVByb3BlcnR5LnRvSlNPTlxuICogTW9kaWZpZXMgdGhlIGJ1aWx0LWluIGB0b0pTT05gIHByb3BlcnR5IG9mIHRoZSBgRXJyb3JgIG9iamVjdC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gZXh0ZW5kcyB0aGUgYEVycm9yYCBwcm90b3R5cGUgYW5kIGNoYW5nZXMgdGhlIGB0b0pTT05gIGZ1bmN0aW9uXG4gKiB0byBzdXBwb3J0IEpTT04uc3RyaW5naWZ5IG9mIEVycm9yIG9iamVjdC5cbiAqXG4gKiBgYGBqc1xuICogbmV3IEVycm9yKCdUZXN0IGVycm9yJykudG9KU09OKCk7XG4gKiBgYGBcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEVycm9yLnByb3RvdHlwZSwgJ3RvSlNPTicsIHtcbiAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYWx0ID0ge307XG5cbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGFsdFtrZXldID0gdGhpc1trZXldO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIGFsdDtcbiAgfSxcbiAgY29uZmlndXJhYmxlOiB0cnVlXG59KTtcbi8qXG4gQXJyYXkucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuIHJldHVybiB0aGlzLnNsaWNlKDApO1xuIH07XG5cblxuIHZhciBzdHJpbmdpZnkgPSByZXF1aXJlKCdqc29uLXN0cmluZ2lmeS1zYWZlJyk7XG5cblxuIEpTT04uX3BhcnNlID0gSlNPTi5wYXJzZS5jbG9uZSgpO1xuIEpTT04ucGFyc2UgPSBmdW5jdGlvbiAob2JqKSB7XG4gdmFyIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gdmFyIHJlc3VsdCA9IEpTT04uX3BhcnNlKG9iaik7XG4gdmFyIGVuZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuIGlmIChlbmQgLSBzdGFydCA+IDUwKSB7XG4gY29uc29sZS5sb2coJ0JMT0NLSU5HIFBBUlNFOiAnICsgKGVuZCAtIHN0YXJ0KS50b1N0cmluZygpICsgJ21zJyk7XG4gY29uc29sZS50cmFjZSgpO1xuIH1cbiByZXR1cm4gcmVzdWx0O1xuIH07XG5cblxuIEpTT04uX3N0cmluZ2lmeSA9IHN0cmluZ2lmeS5jbG9uZSgpO1xuIEpTT04uc3RyaW5naWZ5ID0gZnVuY3Rpb24gKG9iaikge1xuIHZhciBzdGFydCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuIHZhciByZXN1bHQgPSBKU09OLl9zdHJpbmdpZnkob2JqKTtcbiB2YXIgZW5kID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gaWYgKGVuZCAtIHN0YXJ0ID4gNTApIHtcbiBjb25zb2xlLmxvZygnQkxPQ0tJTkcgU1RSSU5HSUZZOiAnICsgKGVuZCAtIHN0YXJ0KS50b1N0cmluZygpICsgJ21zJyk7XG4gY29uc29sZS50cmFjZSgpO1xuIH1cbiByZXR1cm4gcmVzdWx0O1xuIH07XG4gKi9cblxuLy8gYXR0YWNoIHRoZSAuZXF1YWxzIG1ldGhvZCB0byBBcnJheSdzIHByb3RvdHlwZSB0byBjYWxsIGl0IG9uIGFueSBhcnJheVxuQXJyYXkucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChhcnJheSkge1xuICAvLyBpZiB0aGUgb3RoZXIgYXJyYXkgaXMgYSBmYWxzeSB2YWx1ZSwgcmV0dXJuXG4gIGlmICghYXJyYXkpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGNvbXBhcmUgbGVuZ3RocyAtIGNhbiBzYXZlIGEgbG90IG9mIHRpbWUgXG4gIGlmICh0aGlzLmxlbmd0aCAhPSBhcnJheS5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIG5lc3RlZCBhcnJheXNcbiAgICBpZiAodGhpc1tpXSBpbnN0YW5jZW9mIEFycmF5ICYmIGFycmF5W2ldIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIC8vIHJlY3Vyc2UgaW50byB0aGUgbmVzdGVkIGFycmF5c1xuICAgICAgaWYgKCF0aGlzW2ldLmVxdWFscyhhcnJheVtpXSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpc1tpXSAhPSBhcnJheVtpXSkge1xuICAgICAgLy8gV2FybmluZyAtIHR3byBkaWZmZXJlbnQgb2JqZWN0IGluc3RhbmNlcyB3aWxsIG5ldmVyIGJlIGVxdWFsOiB7eDoyMH0gIT0ge3g6MjB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuTnVtYmVyLnByb3RvdHlwZS5jb21tYXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB4ID0gdGhpcztcbiAgdmFyIHBhcnRzID0geC50b1N0cmluZygpLnNwbGl0KFwiLlwiKTtcbiAgcGFydHNbMF0gPSBwYXJ0c1swXS5yZXBsYWNlKC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLCBcIixcIik7XG4gIHJldHVybiBwYXJ0cy5qb2luKFwiLlwiKTtcbn07XG5cblN0cmluZy5wcm90b3R5cGUuY29tbWFzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeCA9IHRoaXM7XG4gIHZhciBwYXJ0cyA9IHgudG9TdHJpbmcoKS5zcGxpdChcIi5cIik7XG4gIHBhcnRzWzBdID0gcGFydHNbMF0ucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgXCIsXCIpO1xuICByZXR1cm4gcGFydHMuam9pbihcIi5cIik7XG59OyIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbi8vVEhFIE9CSkVDVFxudmFyIGpvb2xhID0gZXhwb3J0cztcblxuLy90cnkgaW5qZWN0aW5nIGdsb2JhbFxuaWYgKCFnbG9iYWwuam9vbGEpIHtcbiAgZ2xvYmFsLmpvb2xhID0gam9vbGE7XG59XG5cbi8vYmFzZSBvcHRpb25zXG5qb29sYS5vcHRpb25zID0ge1xuICB0b2tlbjogbnVsbCxcbiAgaG9zdDogbnVsbCxcbiAgaW5jbHVkZWNzczogdHJ1ZSxcbiAgdGhlbWU6ICdkZWZhdWx0JyxcbiAgY3NzSG9zdDogJycsXG4gIEFQSVRva2VuOiBudWxsLFxuICBsb2dvdXR1cmw6IG51bGwsXG4gIGlzQnJvd3NlcjogZnVuY3Rpb24gaXNCcm93c2VyKCkge1xuICAgIHJldHVybiB0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCc7XG4gIH0oKSxcbiAgbWF4UmVxdWVzdHM6IDEwMDAsXG4gIGRlYnVnOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgZXZlbnRzOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIHRyYWNlOiBmYWxzZVxuICAgIH0sXG4gICAgZnVuY3Rpb25zOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgdGltZXpvbmVPZmZzZXQ6IG51bGxcblxufTtcbmpvb2xhLmNvbm5lY3RlZCA9IGZhbHNlO1xuLy9saWJyYXJpZXNcbmpvb2xhLmdsb2JhbHMgPSByZXF1aXJlKCcuL2NvbW1vbi9nbG9iYWxzJyk7XG5qb29sYS5sb2dnZXIgPSByZXF1aXJlKCcuL2NvbW1vbi9sb2dnZXInKTtcbmpvb2xhLmRpc3BhdGNoID0gcmVxdWlyZSgnLi9jb21tb24vZGlzcGF0Y2gnKTtcbmpvb2xhLmNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uL2luZGV4Jyk7XG5qb29sYS5tZW1vcnkgPSByZXF1aXJlKCcuL2NvbW1vbi9tZW1vcnknKTtcbmpvb2xhLmV2ZW50cyA9IHJlcXVpcmUoJy4vY29tbW9uL2V2ZW50cycpO1xuam9vbGEuZXZlbnRzLnNldE1heExpc3RlbmVycygxMDApO1xuam9vbGEub24gPSBmdW5jdGlvbiAoZXZlbnQsIGNiKSB7XG4gIGpvb2xhLmV2ZW50cy5vbihldmVudCwgY2IpO1xufTtcbmpvb2xhLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQsIG1lc3NhZ2UpIHtcbiAgam9vbGEuZXZlbnRzLmVtaXQoZXZlbnQsIG1lc3NhZ2UpO1xufTtcbmpvb2xhLmFwaSA9IHJlcXVpcmUoJy4vY29tbW9uL2FwaScpO1xuam9vbGEuc3RhdGUgPSB7fTtcbmpvb2xhLnZpeiA9IHJlcXVpcmUoJy4vdml6L2luZGV4Jyk7XG5cbmpvb2xhLlZFUlNJT04gPSByZXF1aXJlKCcuLy4uLy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG5qb29sYS5fdG9rZW4gPSBudWxsO1xuam9vbGEuX2FwaXRva2VuID0gbnVsbDtcblxucmVxdWlyZSgnLi9jb21tb24vbW9kaWZpZXJzJyk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShqb29sYSwgJ1RPS0VOJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gam9vbGEuX3Rva2VuO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGpvb2xhLl90b2tlbiA9IHZhbHVlO1xuICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdjb3JlLmluaXQuZmluaXNoJyk7XG4gICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JlYWR5Jyk7XG4gIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoam9vbGEsICdBUElUT0tFTicsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGpvb2xhLl9hcGl0b2tlbjtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBqb29sYS5fYXBpdG9rZW4gPSB2YWx1ZTtcbiAgICBqb29sYS5VU0VSID0gbnVsbDtcbiAgICBqb29sYS5fdG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuQVBJVE9LRU4sIGZ1bmN0aW9uIChlcnIsIHVzZXIpIHtcbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgLy9qb29sYS5UT0tFTiA9IHVzZXIudG9rZW4uXztcbiAgICB9KTtcbiAgfVxufSk7XG5cbnJlcXVpcmUoJy4vY29tbW9uL2dsb2JhbHMnKTtcblxuLy9wYXJzZSB0aGUgcXVlcnlzdHJpbmcgaWYgYnJvd3NlciBmb3IgZGVmYXVsdCBvcHRpb25zXG5mdW5jdGlvbiBpc0Jyb3dzZXIoKSB7XG4gIHJldHVybiB0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCc7XG59XG5cbmlmIChpc0Jyb3dzZXIoKSkge1xuICB2YXIgZWxlbXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG5cbiAgT2JqZWN0LmtleXMoZWxlbXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBzY3IgPSBlbGVtc1trZXldO1xuICAgIGlmIChzY3Iuc3JjKSB7XG4gICAgICBpZiAoc2NyLnNyYy5pbmRleE9mKCdqb29sYS5qcycpID4gLTEgfHwgc2NyLnNyYy5pbmRleE9mKCdqb29sYS5taW4uanMnKSA+IC0xKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlKHNjci5zcmMpO1xuICAgICAgICB2YXIgcHJvdG9jb2wgPSBwYXJ0cy5wcm90b2NvbDtcbiAgICAgICAgdmFyIGhvc3QgPSBwYXJ0cy5ob3N0O1xuICAgICAgICB2YXIgcG9ydCA9IHBhcnRzLnBvcnQ7XG4gICAgICAgIGlmICghcG9ydCkge1xuICAgICAgICAgIHBvcnQgPSA0NDM7XG4gICAgICAgICAgaWYgKHByb3RvY29sICE9PSAnaHR0cHM6JylcbiAgICAgICAgICAgIHBvcnQgPSA4MDtcbiAgICAgICAgfVxuICAgICAgICBqb29sYS5vcHRpb25zLmhvc3QgPSBwYXJ0cy5wcm90b2NvbCArICcvLycgKyBwYXJ0cy5ob3N0bmFtZSArICc6JyArIHBvcnQ7XG4gICAgICAgIGlmIChwYXJ0cy5xdWVyeSkge1xuICAgICAgICAgIHZhciBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJykucGFyc2UocGFydHMucXVlcnkpO1xuICAgICAgICAgIGlmIChxcyAmJiBxcy5BUElUb2tlbikge1xuICAgICAgICAgICAgam9vbGEub3B0aW9ucy5BUElUb2tlbiA9IHFzLkFQSVRva2VuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocXMgJiYgcXMudG9rZW4pIHtcbiAgICAgICAgICAgIGpvb2xhLm9wdGlvbnMudG9rZW4gPSBxcy50b2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHFzICYmIHFzLmhvc3QpIHtcbiAgICAgICAgICAgIHBhcnRzID0gcmVxdWlyZSgndXJsJykucGFyc2UocXMuaG9zdCk7XG4gICAgICAgICAgICBwcm90b2NvbCA9IHBhcnRzLnByb3RvY29sO1xuICAgICAgICAgICAgaG9zdCA9IHBhcnRzLmhvc3Q7XG4gICAgICAgICAgICBwb3J0ID0gNDQzO1xuICAgICAgICAgICAgaWYgKHByb3RvY29sICE9PSAnaHR0cHM6JylcbiAgICAgICAgICAgICAgcG9ydCA9IDgwO1xuICAgICAgICAgICAgam9vbGEub3B0aW9ucy5ob3N0ID0gcGFydHMucHJvdG9jb2wgKyAnLy8nICsgcGFydHMuaG9zdG5hbWUgKyAnOicgKyBwb3J0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmpvb2xhLmRpc3BhdGNoLmJ1aWxkc3R1YigpO1xuXG4vL2luaXQgcHJvY2VkdXJlXG5qb29sYS5pbml0ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZW1wdHlmdW5jO1xuICBqb29sYS5vcHRpb25zID0gam9vbGEuY29tbW9uLl9taXhpbihqb29sYS5vcHRpb25zLCBvcHRpb25zKTtcbiAgam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIgPSBpc0Jyb3dzZXIoKTtcblxuICBpZiAob3B0aW9ucy50b2tlbikge1xuICAgIGpvb2xhLl90b2tlbiA9IG9wdGlvbnMudG9rZW47XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG4gICAgICB2YXIgcGFydHMgPSBxcy5wYXJzZShsb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEsIGxvY2F0aW9uLnNlYXJjaC5sZW5ndGgpKTtcbiAgICAgIGlmIChwYXJ0cy50b2tlbilcbiAgICAgICAgam9vbGEuX3Rva2VuID0gcGFydHMudG9rZW47XG4gICAgfVxuICB9XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdjb3JlLmluaXQuc3RhcnQnKTtcbiAgam9vbGEubG9nZ2VyLmluZm8oJ1N0YXJ0aW5nIGpvb2xhIGNsaWVudCBTREssIHZlcnNpb24gJyArIGpvb2xhLlZFUlNJT04pO1xuXG4gIGlmICgham9vbGEub3B0aW9ucy5ob3N0ICYmIGpvb2xhLm9wdGlvbnMuaXNCcm93c2VyKSB7XG4gICAgam9vbGEub3B0aW9ucy5ob3N0ID0gbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgbG9jYXRpb24uaG9zdDtcbiAgfVxuICBpZiAoIWpvb2xhLm9wdGlvbnMuaG9zdClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2pvb2xhIGhvc3Qgbm90IHNwZWNpZmllZCcpO1xuXG4gIHZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcbiAgam9vbGEuaW8gPSBpbztcbiAgam9vbGEuaW8uc29ja2V0ID0gam9vbGEuaW8uY29ubmVjdChqb29sYS5vcHRpb25zLmhvc3QpO1xuICBqb29sYS5pby5zb2NrZXQub24oJ2V2ZW50JywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgfSk7XG4gIGpvb2xhLmlvLnNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBqb29sYS5lbWl0KCdkaXNjb25uZWN0ZWQnLCByZWFzb24pO1xuICB9KTtcbiAgam9vbGEuaW8uc29ja2V0Lm9uKCdjb25uZWN0X2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xuICAgIGpvb2xhLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIGlmICgham9vbGEub25saW5lKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY29ubmVjdCB0byBKb29sYSBlbmdpbmU6ICcgKyBlcnIpO1xuICAgIGpvb2xhLmVtaXQoJ2Rpc2Nvbm5lY3RlZCcsIGVycik7XG4gIH0pO1xuICBqb29sYS5pby5zb2NrZXQub24oJ2Nvbm5lY3RfdGltZW91dCcsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBpZiAoIWpvb2xhLm9ubGluZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGNvbm5lY3QgdG8gSm9vbGEgZW5naW5lOiBUaW1lb3V0Jyk7XG4gICAgam9vbGEuZW1pdCgnZGlzY29ubmVjdGVkJywgJ3RpbWVvdXQnKTtcbiAgfSk7XG4gIGpvb2xhLmlvLnNvY2tldC5vbignY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSB0cnVlO1xuICAgIGlmICgham9vbGEub25saW5lKSB7XG4gICAgICBqb29sYS5vbmxpbmUgPSB0cnVlO1xuICAgICAgam9vbGEuYnJpbmdPbmxpbmUoY2FsbGJhY2spO1xuICAgIH1cbiAgICBqb29sYS5lbWl0KCdjb25uZWN0ZWQnKTtcbiAgfSk7XG5cbiAgLy9nbG9iYWwgZnVuY3Rpb24gaG9vayAoZm9yIGRlYnVnKVxuICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1ZyAmJiBqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucyAmJiBqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkKVxuICAgIFtqb29sYV0uZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG4gICAgICBqb29sYS5jb21tb24uaG9va0V2ZW50cyhvYmosIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgLy9nbG9iYWwgZXZlbnQgY2F0Y2hlciAoZm9yIGRlYnVnKVxuICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1Zy5lbmFibGVkICYmIGpvb2xhLm9wdGlvbnMuZGVidWcuZXZlbnRzKVxuICAgIGpvb2xhLmV2ZW50cy5vbkFueShmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1Zy5ldmVudHMuZW5hYmxlZClcbiAgICAgICAgam9vbGEubG9nZ2VyLmRlYnVnKCdFdmVudCByYWlzZWQ6ICcgKyB0aGlzLmV2ZW50KTtcbiAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmV2ZW50cy5lbmFibGVkICYmIGpvb2xhLm9wdGlvbnMuZGVidWcuZXZlbnRzLnRyYWNlKVxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgfSk7XG59O1xuXG5pZiAoam9vbGEub3B0aW9ucy5BUElUb2tlbiB8fCBqb29sYS5vcHRpb25zLnRva2VuKSB7XG4gIGpvb2xhLmluaXQoe30pO1xufVxuXG5qb29sYS5icm93c2VyM3JkID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIHZhciBleHBlY3RlZCA9IDA7XG5cbiAgZnVuY3Rpb24gZG9uZSh3aGljaCkge1xuICAgIGV4cGVjdGVkLS07XG4gICAgaWYgKGV4cGVjdGVkIDw9IDApIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc2NyaXB0O1xuICBpZiAoam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIpIHtcblxuICAgIC8vY3NzXG4gICAgaWYgKGpvb2xhLm9wdGlvbnMuaW5jbHVkZWNzcykge1xuICAgICAgdmFyIGNzcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcbiAgICAgIC8vZXhwZWN0ZWQrKztcbiAgICAgIGNzcy5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8valF1ZXJ5Lm5vQ29uZmxpY3QodHJ1ZSk7XG4gICAgICAgIC8vZG9uZSgnY3NzJyk7XG4gICAgICB9O1xuICAgICAgY3NzLnJlbCA9ICdzdHlsZXNoZWV0JztcbiAgICAgIGNzcy5ocmVmID0gam9vbGEub3B0aW9ucy5ob3N0ICsgJy9qb29sYS5taW4uY3NzJztcbiAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoY3NzKTtcbiAgICAgIC8vZG9uZSgnY3NzJyk7XG4gICAgfVxuICAgIC8vaWYgKGV4cGVjdGVkID09PSAwKVxuICAgIHJldHVybiBkb25lKCdub25lJyk7XG4gIH1cbiAgZWxzZSB7XG4gICAgcmV0dXJuIGRvbmUoJ25vdCBicm93c2VyJyk7XG4gIH1cbn07XG5cbmpvb2xhLmJyaW5nT25saW5lID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGpvb2xhLmJyb3dzZXIzcmQoZnVuY3Rpb24gKCkge1xuICAgIGlmIChqb29sYS5vcHRpb25zLnRva2VuKSB7XG4gICAgICBqb29sYS5kaXNwYXRjaC51c2Vycy5nZXRCeVRva2VuKGpvb2xhLl90b2tlbiwgZnVuY3Rpb24gKGVyciwgdXNlcikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgICBqb29sYS5UT0tFTiA9IGpvb2xhLl90b2tlbjtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2NvcmUuaW5pdC5maW5pc2gnKTtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIGlmIChjYWxsYmFjaylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgam9vbGEpO1xuXG4gICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoam9vbGEub3B0aW9ucy5BUElUb2tlbikge1xuICAgICAgam9vbGEuX2FwaXRva2VuID0gam9vbGEub3B0aW9ucy5BUElUb2tlbjtcbiAgICAgIGpvb2xhLlVTRVIgPSBudWxsO1xuICAgICAgam9vbGEuX3Rva2VuID0gbnVsbDtcblxuICAgICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuX2FwaXRva2VuLCBmdW5jdGlvbiAoZXJyLCB1c2VyKSB7XG4gICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnY29yZS5pbml0LmZpbmlzaCcpO1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncmVhZHknKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgam9vbGEpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2NvcmUuaW5pdC5maW5pc2gnKTtcbiAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdyZWFkeScpO1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGpvb2xhKTtcbiAgICB9XG4gIH0pO1xufTtcblxuam9vbGEuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUsIGNhbGxiYWNrKSB7XG4gIGpvb2xhLm9wdGlvbnNba2V5XSA9IHZhbHVlO1xuICBpZiAoa2V5ID09PSAnQVBJVG9rZW4nKSB7XG4gICAgam9vbGEuX2FwaXRva2VuID0gam9vbGEub3B0aW9ucy5BUElUb2tlbjtcbiAgICBqb29sYS5VU0VSID0gbnVsbDtcbiAgICBqb29sYS5fdG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuX2FwaXRva2VuLCBmdW5jdGlvbiAoZXJyLCB1c2VyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIGlmICghdXNlcilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignRmFpbGVkIHRvIHZlcmlmeSBBUEkgVG9rZW4nKSk7XG5cbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgZWxzZSBpZiAoa2V5ID09PSAndG9rZW4nKSB7XG4gICAgam9vbGEuX3Rva2VuID0gam9vbGEub3B0aW9ucy5fdG9rZW47XG4gICAgam9vbGEuVVNFUiA9IG51bGw7XG4gICAgam9vbGEuQVBJVG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMuZ2V0QnlUb2tlbihqb29sYS5fdG9rZW4sIGZ1bmN0aW9uIChlcnIsIHVzZXIpIHtcbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgam9vbGEuVE9LRU4gPSB1c2VyLnRva2VuLl87XG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgfSk7XG4gIH1cbn07XG5cbmpvb2xhLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIGpvb2xhLm9wdGlvbnNba2V5XTtcbn07XG5cbmpvb2xhLmNvbG9ycyA9IFsnIzA1OERDNycsICcjNTBCNDMyJywgJyNFRDdFMTcnLCAnI0FGNDlDNScsICcjRURFRjAwJywgJyM4MDgwRkYnLCAnI0EwQTQyNCcsICcjRTMwNzFDJywgJyM2QUY5QzQnLCAnI0IyREVGRicsICcjNjRFNTcyJywgJyNDQ0NDQ0MnXTtcbmpvb2xhLm9mZmNvbG9ycyA9IFsnI0FBREZGMycsICcjQzlFN0JFJywgJyNGMkQ1QkQnLCAnI0UxQzlFOCcsICcjRjZGM0IxJywgJyNEQURCRkInLCAnI0U3RTZCNCcsICcjRjRCM0JDJywgJyNBQURGRjMnLCAnI0YyRDVCRCcsICcjQzlFN0JFJywgJyNFRUVFRUUnXTtcblxudmFyIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5qb29sYS5vbigncmVhZHknLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBlbmQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbn0pO1xuIiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIEJhclRhYmxlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vbWl4aW5cbiAgdGhpcy50eXBlID0gJ2JhcnRhYmxlJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICB0aGlzLmRhdGEgPSBbXTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICBjb2xvcnM6IFtdLFxuICAgIG9mZmNvbG9yczogW10sXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwiYmFydGFibGUtY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgJzx0YWJsZSBjbGFzcz1cImppbyBiYXJ0YWJsZSB0YWJsZVwiPicgK1xuICAgICAgJzx0aGVhZD4nICtcbiAgICAgICc8L3RoZWFkPicgK1xuICAgICAgJzx0Ym9keT4nICtcbiAgICAgICc8L3Rib2R5PicgK1xuICAgICAgJzwvdGFibGU+JyxcbiAgICBxdWVyeTogbnVsbCxcbiAgICBzdHJpbmdzOiB7XG4gICAgICBsb2FkaW5nOiAnTm8gZGF0YSBhdmFpbGFibGUuJyxcbiAgICAgIG5vZGF0YTogJ05vIGRhdGEgYXZhaWxhYmxlLicsXG4gICAgICBub3Rfc2hvd246ICdOb3Qgc2hvd24nXG4gICAgfSxcbiAgICBsaW1pdDogMTAsXG4gICAgaGVhZGVyczogZmFsc2UsXG4gICAgaW5jbHVkZV9ub3Rfc2hvd246IHRydWUsXG4gICAgYWxsb3dTZWxlY3Q6IHRydWVcbiAgfTtcbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IFtvcHRpb25zXS4nO1xuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkgPSBbc2VsZi5vcHRpb25zLnF1ZXJ5XTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5sZW5ndGggPT09IDAgfHwgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMubGVuZ3RoID4gMSlcbiAgICAgICAgcmV0dXJuICdQbGVhc2Ugc3BlY2lmeSBhIHNpbmdsZSBkaW1lbnNpb24uJztcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5sZW5ndGggPT09IDAgfHwgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MubGVuZ3RoID4gMSlcbiAgICAgICAgcmV0dXJuICdQbGVhc2Ugc3BlY2lmeSBhIHNpbmdsZSBtZXRyaWMuJztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgdGhpcy5lbnRlciA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgX3F1ZXJ5ID0gX3F1ZXJ5WzBdO1xuICAgIHZhciBkaW1lbnNpb25rZXkgPSBfcXVlcnkuZGltZW5zaW9uc1swXS5rZXkgfHwgX3F1ZXJ5LmRpbWVuc2lvbnNbMF07XG4gICAgdmFyIG1ldHJpY2tleSA9IF9xdWVyeS5tZXRyaWNzWzBdLmtleSB8fCBfcXVlcnkubWV0cmljc1swXTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcblxuICAgIGZ1bmN0aW9uIGFkZFJvdyhwb2ludCwgdG90YWwsIHNob3duLCBub3RzaG93bikge1xuICAgICAgdmFyICR0YWJsZSA9ICQkKCQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3RhYmxlJylbMF0pO1xuICAgICAgdmFyICR0Ym9keSA9ICQkKCR0YWJsZS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICAgIHZhciBwZXJjZW50YWdlLCAkdHI7XG4gICAgICBpZiAoJHRib2R5LmZpbmQoJ3RyLm5vZGF0YScpLmxlbmd0aCA+IDApXG4gICAgICAgICR0Ym9keS5maW5kKCd0ci5ub2RhdGEnKS5yZW1vdmUoKTtcbiAgICAgIGlmICgkdGJvZHkuZmluZCgndHIubG9hZGluZycpLmxlbmd0aCA+IDApXG4gICAgICAgICR0Ym9keS5maW5kKCd0ci5sb2FkaW5nJykucmVtb3ZlKCk7XG4gICAgICBpZiAocG9pbnQubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHBvaW50ID0gcG9pbnRbMF07XG4gICAgICAgIGlmICgkdGJvZHkuZmluZCgndHInKS5sZW5ndGggPj0gc2VsZi5vcHRpb25zLmxpbWl0KSB7XG4gICAgICAgICAgaWYgKCR0Ym9keS5maW5kKCd0ZC5ub3RzaG93bicpLmxlbmd0aCA+IDAgfHwgIXNlbGYub3B0aW9ucy5pbmNsdWRlX25vdF9zaG93bilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgIHBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KG5vdHNob3duWzBdKSAvIHRvdGFsWzBdICogMTAwO1xuICAgICAgICAgIGlmIChwZXJjZW50YWdlID4gMTAwKVxuICAgICAgICAgICAgcGVyY2VudGFnZSA9IDEwMDtcbiAgICAgICAgICAkdHIgPSAkJCgnPHRyIGRhdGEtaWQ9XCJvdGhlclwiIGRhdGEtdmFsdWU9XCInICsgbm90c2hvd25bMF0gKyAnXCIgZGF0YS1uYW1lPVwiJyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biArICdcIiBkYXRhLXZhbHVlLXNvcnQ9XCInICsgcGVyY2VudGFnZSArICdcIj48L3RyPicpO1xuICAgICAgICAgIE9iamVjdC5rZXlzKHBvaW50Lm1ldHJpY3MpLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiamlvIGJhcnRhYmxlIHZhbHVlIG1ldHJpY1wiPicgK1xuICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cImJhcndyYXBwZXJcIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJ0YWJsZWJhclwiIHN0eWxlPVwid2lkdGg6JyArIHBlcmNlbnRhZ2UgKyAnJVwiIHRpdGxlPVwiJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMobm90c2hvd25bMF0sIGRhdGFbMF0ubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUpXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgJzwvdGQ+Jyk7XG4gICAgICAgICAgICAkdGQuZmluZCgnLnRhYmxlYmFyJykuY3NzKHsnYmFja2dyb3VuZC1jb2xvcic6IHNlbGYub3B0aW9ucy5jb2xvcnNbMTFdfSk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBPYmplY3Qua2V5cyhwb2ludC5kaW1lbnNpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICB2YXIgZGltZW5zaW9ua2V5ID0gZC5rZXkgfHwgZDtcbiAgICAgICAgICAgIHZhciB0aXRsZSA9IHBvaW50Lm1ldGFbZGltZW5zaW9ua2V5XTtcbiAgICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb24gbm90c2hvd25cIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJjYXB0aW9uXCIgdGl0bGU9XCInICsgdGl0bGUgKyAnXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgICAgJHRkLmZpbmQoJy5jYXB0aW9uJykudGV4dChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biB8fCAnTm90IHNob3duJykpO1xuICAgICAgICAgICAgJHRkLmZpbmQoJy5zdWJjYXB0aW9uJykudGV4dChqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKG5vdHNob3duWzBdLCBwb2ludC5tZXRhW21ldHJpY2tleV0pICsgJyAnICsgbWV0cmljbmFtZSk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy93ZSBoYXZlIGEgc2ltcGxlIHJvd1xuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICBwZXJjZW50YWdlID0gcGFyc2VGbG9hdChwb2ludC5tZXRyaWNzW21ldHJpY2tleV0pIC8gdG90YWxbaW5kZXhdICogMTAwO1xuICAgICAgICAkdHIgPSAkJCgnPHRyIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcG9pbnQubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiIGRhdGEtbmFtZT1cIicgKyBwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gKyAnXCIgZGF0YS12YWx1ZS1zb3J0PVwiJyArIHBlcmNlbnRhZ2UgKyAnXCIgZGF0YS1zZWxlY3RhYmxlPVwiJyArIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QgIT09IGZhbHNlICkgKyAnXCI+PC90cj4nKTtcblxuICAgICAgICAvL3Nob3VsZCB3ZSBtYXJrIHRoaXMgcm93IGFzIGFjdGl2ZT9cbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMgJiYgc2VsZi5vcHRpb25zLmNhbnZhcy5vcHRpb25zLmZpbHRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMub3B0aW9ucy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgICAgICAgaWYgKGZpbHRlci5rZXkgPT09IHBvaW50LmtleSlcbiAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZVwiPicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyXCI+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyXCIgc3R5bGU9XCJ3aWR0aDonICsgcGVyY2VudGFnZSArICclO2JhY2tncm91bmQtY29sb3I6JyArIHNlbGYub3B0aW9ucy5jb2xvcnNbMF0gKyAnXCIgdGl0bGU9XCInICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhwb2ludC5tZXRyaWNzW21ldHJpY2tleV0sIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lICsgJyAoJyArIHBlcmNlbnRhZ2UudG9GaXhlZCgyKSArICclKVwiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QpIHtcbiAgICAgICAgICAgICR0ZC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGlmICgkdHIuaGFzQ2xhc3MoJ2FjdGl2ZScpKVxuICAgICAgICAgICAgICAgICR0ci5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAkdHIuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3NlbGVjdCcsIFtwb2ludF0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtwb2ludF0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBfcXVlcnkuZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgdmFyIHRpdGxlID0gcG9pbnQubWV0YVtkaW1lbnNpb25rZXldO1xuICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUudGl0bGUgfHwgdGl0bGUubmFtZSB8fCB0aXRsZS5rZXk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJqaW8gYmFydGFibGUgdmFsdWUgZGltZW5zaW9uXCI+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cImNhcHRpb25cIiB0aXRsZT1cIicgKyB0aXRsZSArICdcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzwvdGQ+Jyk7XG5cbiAgICAgICAgICAkdGQuZmluZCgnLmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5lbnN1cmVMZW5ndGgocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArIChwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpLCAyMykpO1xuICAgICAgICAgICR0ZC5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhwb2ludC5tZXRyaWNzW21ldHJpY2tleV0sIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lKTtcbiAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5hbGxvd1NlbGVjdCkge1xuICAgICAgICAgICAgJHRkLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaWYgKCR0ci5oYXNDbGFzcygnYWN0aXZlJykpXG4gICAgICAgICAgICAgICAgJHRyLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICR0ci5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdlbWl0Jyk7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnc2VsZWN0JywgW3BvaW50XSk7XG4gICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2VsZWN0KVxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5zZWxlY3QuYXBwbHkodGhpcywgW3BvaW50XSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy93ZSBoYXZlIGEgY29tcGFyaXNvblxuICAgICAgICB2YXIgYmFzZSA9IHBvaW50WzBdO1xuICAgICAgICB2YXIgY29tcGFyZSA9IHBvaW50WzFdO1xuXG4gICAgICAgIHZhciBiYXNlX3BlcmNlbnRhZ2UsIGNvbXBhcmVfcGVyY2VudGFnZTtcblxuICAgICAgICBpZiAoJHRib2R5LmZpbmQoJ3RyJykubGVuZ3RoID49IHNlbGYub3B0aW9ucy5saW1pdCkge1xuICAgICAgICAgIGlmICgkdGJvZHkuZmluZCgndGQubm90c2hvd24nKS5sZW5ndGggPiAwIHx8ICFzZWxmLm9wdGlvbnMuaW5jbHVkZV9ub3Rfc2hvd24pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgJHRyID0gJCQoJzx0cj48L3RyPicpO1xuICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQobm90c2hvd25bMF0pIC8gdG90YWxbMF0gKiAxMDA7XG4gICAgICAgICAgaWYgKGJhc2VfcGVyY2VudGFnZSA+IDEwMClcbiAgICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IDEwMDtcbiAgICAgICAgICBjb21wYXJlX3BlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KG5vdHNob3duWzFdKSAvIHRvdGFsWzFdICogMTAwO1xuICAgICAgICAgIGlmIChjb21wYXJlX3BlcmNlbnRhZ2UgPiAxMDApXG4gICAgICAgICAgICBjb21wYXJlX3BlcmNlbnRhZ2UgPSAxMDA7XG4gICAgICAgICAgT2JqZWN0LmtleXMoYmFzZS5tZXRyaWNzKS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZVwiPicgK1xuICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyIGNvbXBhcmVcIj4nICtcbiAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwidGFibGViYXJcIiBzdHlsZT1cIndpZHRoOicgKyAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhiYXNlX3BlcmNlbnRhZ2UpID8gKGJhc2VfcGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IGJhc2VfcGVyY2VudGFnZSArICclJykgOiAwKSArICc7YmFja2dyb3VuZC1jb2xvcjogJyArIHNlbGYub3B0aW9ucy5jb2xvcnNbMF0gKyAnO1wiIHRpdGxlPVwiJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgYmFzZV9wZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSlcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwiY2xlYXI6Ym90aFwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJ0YWJsZWJhciBjb21wYXJlX3JhdGlvXCIgc3R5bGU9XCJ3aWR0aDonICsgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMoY29tcGFyZV9wZXJjZW50YWdlKSA/IChjb21wYXJlX3BlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBjb21wYXJlX3BlcmNlbnRhZ2UgKyAnJScpIDogMCkgKyAnO2JhY2tncm91bmQtY29sb3I6ICcgKyBzZWxmLm9wdGlvbnMub2ZmY29sb3JzWzBdICsgJ1wiICB0aXRsZT1cIicgKyAoY29tcGFyZS5tZXRyaWNzICYmIGNvbXBhcmUubWV0cmljc1ttZXRyaWNrZXldID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSwgY29tcGFyZS5tZXRhW21ldHJpY2tleV0pIDogJ04vQScpICsgJyAnICsgbWV0cmljbmFtZSArICcgKCcgKyAoY29tcGFyZV9wZXJjZW50YWdlID8gY29tcGFyZV9wZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJScgOiAnTi9BJykgKyAnKVwiPiZuYnNwOzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzwvdGQ+J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGJhc2UuZGltZW5zaW9ucykuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgICB2YXIgdGl0bGUgPSBiYXNlLm1ldGFbZGltZW5zaW9ua2V5XTtcbiAgICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb24gbm90c2hvd25cIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJjYXB0aW9uXCIgdGl0bGU9XCInICsgdGl0bGUgKyAnXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgICAgJHRkLmZpbmQoJy5jYXB0aW9uJykudGV4dCgnTi9BICcgKyAoc2VsZi5vcHRpb25zLnN0cmluZ3Mubm90X3Nob3duIHx8ICdOb3Qgc2hvd24nKSk7XG4gICAgICAgICAgICAkdGQuZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMobm90c2hvd25bMF0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgdnMuICcgKyAoY29tcGFyZS5taXNzaW5nID8gJ04vQScgOiBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKG5vdHNob3duWzFdLCBiZXRhLm1ldGFbbWV0cmlja2V5XSkpKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmFzZS5taXNzaW5nIHx8IGNvbXBhcmUubWlzc2luZylcbiAgICAgICAgICBwZXJjZW50YWdlID0gbnVsbDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHBlcmNlbnRhZ2UgPSAoKGJhc2UubWV0cmljc1ttZXRyaWNrZXldIC0gY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0pIC8gY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0gKiAxMDApO1xuXG4gICAgICAgIGlmICghYmFzZS5taXNzaW5nKVxuICAgICAgICAgICR0ciA9ICQkKCc8dHIgZGF0YS1pZD1cIicgKyBiYXNlLmtleSArICdcIiBkYXRhLXZhbHVlPVwiJyArIGJhc2UubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiIGRhdGEtbmFtZT1cIicgKyBiYXNlLmRpbWVuc2lvbnNbZGltZW5zaW9ua2V5XSArICdcIiBkYXRhLXZhbHVlLXNvcnQ9XCInICsgcGVyY2VudGFnZSArICdcIiBkYXRhLXNlbGVjdGFibGU9XCInICsgKHNlbGYub3B0aW9ucy5hbGxvd1NlbGVjdCAhPT0gZmFsc2UgKSArICdcIj48L3RyPicpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgJHRyID0gJCQoJzx0ciBkYXRhLWlkPVwiJyArIGNvbXBhcmUua2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0gKyAnXCIgZGF0YS1uYW1lPVwiJyArIGNvbXBhcmUuZGltZW5zaW9uc1tkaW1lbnNpb25rZXldICsgJ1wiIGRhdGEtdmFsdWUtc29ydD1cIicgKyBwZXJjZW50YWdlICsgJ1wiIGRhdGEtc2VsZWN0YWJsZT1cIicgKyAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0ICE9PSBmYWxzZSApICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgIC8vc2hvdWxkIHdlIG1hcmsgdGhpcyByb3cgYXMgYWN0aXZlP1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcyAmJiBzZWxmLm9wdGlvbnMuY2FudmFzLm9wdGlvbnMuZmlsdGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5vcHRpb25zLmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVyLmtleSA9PT0gYmFzZS5rZXkpXG4gICAgICAgICAgICAgICR0ci5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFiYXNlLm1pc3NpbmcpXG4gICAgICAgICAgYmFzZV9wZXJjZW50YWdlID0gcGFyc2VGbG9hdChiYXNlLm1ldHJpY3NbbWV0cmlja2V5XSkgLyB0b3RhbFswXSAqIDEwMDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IG51bGw7XG4gICAgICAgIGlmIChiYXNlX3BlcmNlbnRhZ2UgPiAxMDApXG4gICAgICAgICAgYmFzZV9wZXJjZW50YWdlID0gMTAwO1xuICAgICAgICBpZiAoIWNvbXBhcmUubWlzc2luZykge1xuICAgICAgICAgIGNvbXBhcmVfcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0pIC8gdG90YWxbMV0gKiAxMDA7XG4gICAgICAgICAgaWYgKGNvbXBhcmVfcGVyY2VudGFnZSA+IDEwMCkge1xuICAgICAgICAgICAgY29tcGFyZV9wZXJjZW50YWdlID0gMTAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgY29tcGFyZV9wZXJjZW50YWdlID0gbnVsbDtcbiAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiamlvIGJhcnRhYmxlIHZhbHVlXCI+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyIGNvbXBhcmVcIj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyXCIgc3R5bGU9XCJ3aWR0aDonICsgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMoYmFzZV9wZXJjZW50YWdlKSA/IChiYXNlX3BlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBiYXNlX3BlcmNlbnRhZ2UgKyAnJScpIDogMCkgKyAnO2JhY2tncm91bmQtY29sb3I6ICcgKyBzZWxmLm9wdGlvbnMuY29sb3JzWzBdICsgJztcIiB0aXRsZT1cIicgKyAoIWJhc2UubWlzc2luZyA/IGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgKGJhc2VfcGVyY2VudGFnZSA/IGJhc2VfcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUnIDogJ04vQScpICsgJylcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBzdHlsZT1cImNsZWFyOmJvdGhcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyIGNvbXBhcmVfcmF0aW9cIiBzdHlsZT1cIndpZHRoOicgKyAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhjb21wYXJlX3BlcmNlbnRhZ2UpID8gKGNvbXBhcmVfcGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IGNvbXBhcmVfcGVyY2VudGFnZSArICclJykgOiAwKSArICc7YmFja2dyb3VuZC1jb2xvcjogJyArIHNlbGYub3B0aW9ucy5vZmZjb2xvcnNbMF0gKyAnXCIgdGl0bGU9XCInICsgKGNvbXBhcmUubWV0cmljcyAmJiBjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSA/IGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0sIGNvbXBhcmUubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgKGNvbXBhcmVfcGVyY2VudGFnZSA/IGNvbXBhcmVfcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUnIDogJ04vQScpICsgJylcIj4mbmJzcDs8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzwvdGQ+J1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0KSB7XG4gICAgICAgICAgICAkdGQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoJHRyLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICAkdHIucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdzZWxlY3QnLCBbYmFzZSwgY29tcGFyZV0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtiYXNlLCBjb21wYXJlXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfcXVlcnkuZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgdmFyIHRpdGxlID0gYmFzZS5tZXRhW2RpbWVuc2lvbmtleV07XG4gICAgICAgICAgaWYgKHRpdGxlKVxuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aXRsZSA9IGQubmFtZSB8fCBkLmtleTtcbiAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb25cIj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiY2FwdGlvblwiIHRpdGxlPVwiJyArIHRpdGxlICsgJ1wiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzdWJjYXB0aW9uXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgIHZhciB0ZXh0O1xuICAgICAgICAgIGlmIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpKVxuICAgICAgICAgICAgdGV4dCA9IGpvb2xhLmNvbW1vbi5lbnN1cmVMZW5ndGgocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArICghYmFzZS5taXNzaW5nID8gYmFzZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gOiAoY29tcGFyZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpKSwgMjMpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKCdOL0EgJyArICghYmFzZS5taXNzaW5nID8gYmFzZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gOiAoY29tcGFyZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpKSwgMjMpO1xuICAgICAgICAgICR0ZC5maW5kKCcuY2FwdGlvbicpLnRleHQodGV4dCk7XG4gICAgICAgICAgaWYgKCFiYXNlLm1pc3NpbmcgJiYgIWNvbXBhcmUubWlzc2luZylcbiAgICAgICAgICAgICR0ZC5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhiYXNlLm1ldHJpY3NbbWV0cmlja2V5XSwgYmFzZS5tZXRhW21ldHJpY2tleV0pICsgJyB2cy4gJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0sIGNvbXBhcmUubWV0YVttZXRyaWNrZXldKSk7XG4gICAgICAgICAgZWxzZSBpZiAoYmFzZS5taXNzaW5nKVxuICAgICAgICAgICAgJHRkLmZpbmQoJy5zdWJjYXB0aW9uJykudGV4dCgnTi9BIHZzLiAnICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSwgY29tcGFyZS5tZXRhW21ldHJpY2tleV0pKTtcbiAgICAgICAgICBlbHNlIGlmIChjb21wYXJlLm1pc3NpbmcpXG4gICAgICAgICAgICAkdGQuZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgdnMuIE4vQScpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0KSB7XG4gICAgICAgICAgICAkdGQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoJHRyLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICAkdHIucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdzZWxlY3QnLCBbYmFzZSwgY29tcGFyZV0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtiYXNlLCBjb21wYXJlXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRvdGFsID0gWzAsIDBdO1xuICAgIHZhciBzaG93biA9IFswLCAwXTtcbiAgICB2YXIgbm90c2hvd24gPSBbMCwgMF07XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgYWxsZGF0YVtpbmRleF0uZm9yRWFjaChmdW5jdGlvbiAocG9pbnQsIGkpIHtcbiAgICAgICAgdG90YWxbaW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICAgaWYgKGkgPCAoc2VsZi5vcHRpb25zLmxpbWl0ICYmIHNlbGYub3B0aW9ucy5saW1pdCA8IGRhdGEubGVuZ3RoID8gc2VsZi5vcHRpb25zLmxpbWl0IC0gMSA6IHNlbGYub3B0aW9ucy5saW1pdCApKVxuICAgICAgICAgIHNob3duW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBub3RzaG93bltpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKCFzZWxmLm9wdGlvbnMuaW5jbHVkZV9ub3Rfc2hvd24pIHtcbiAgICAgIHRvdGFsID0gc2hvd247XG4gICAgICBub3RzaG93biA9IFswLCAwXTtcbiAgICB9XG4gICAgYWRkUm93KGRhdGEsIHRvdGFsLCBzaG93biwgbm90c2hvd24pO1xuICAgIC8vc2VsZi5zb3J0KCk7XG4gIH07XG4gIHRoaXMuZXhpdCA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgX3F1ZXJ5ID0gX3F1ZXJ5WzBdO1xuICAgIHZhciBkaW1lbnNpb25rZXkgPSBfcXVlcnkuZGltZW5zaW9uc1swXS5rZXkgfHwgX3F1ZXJ5LmRpbWVuc2lvbnNbMF07XG4gICAgdmFyIG1ldHJpY2tleSA9IF9xdWVyeS5tZXRyaWNzWzBdLmtleSB8fCBfcXVlcnkubWV0cmljc1swXTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcblxuICAgIHZhciB0b3RhbCA9IFswLCAwXTtcbiAgICB2YXIgc2hvd24gPSBbMCwgMF07XG4gICAgdmFyIG5vdHNob3duID0gWzAsIDBdO1xuXG4gICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgaW5kZXgpIHtcbiAgICAgIGFsbGRhdGFbaW5kZXhdLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpKSB7XG4gICAgICAgIHRvdGFsW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICAgIGlmIChpIDwgKHNlbGYub3B0aW9ucy5saW1pdCAmJiBzZWxmLm9wdGlvbnMubGltaXQgPCBkYXRhLmxlbmd0aCA/IHNlbGYub3B0aW9ucy5saW1pdCAtIDEgOiBzZWxmLm9wdGlvbnMubGltaXQgKSlcbiAgICAgICAgICBzaG93bltpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgbm90c2hvd25baW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGlmICghc2VsZi5vcHRpb25zLmluY2x1ZGVfbm90X3Nob3duKSB7XG4gICAgICB0b3RhbCA9IHNob3duO1xuICAgICAgbm90c2hvd24gPSBbMCwgMF07XG4gICAgfVxuXG4gICAgaWYgKGRhdGEubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgcG9pbnQgPSBkYXRhWzBdO1xuICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0cicpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBlbGVtKSB7XG4gICAgICAgIC8vdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCdbZGF0YS1pZD1cIicgKyBwb2ludC5rZXkgKyAnXCJdJylbMF07XG4gICAgICAgIHZhciAkZWxlbSA9ICQkKGVsZW0pO1xuICAgICAgICB2YXIgcGVyY2VudGFnZSwgdGV4dDtcbiAgICAgICAgdmFyIG5hbWUgPSAkZWxlbS5hdHRyKCdkYXRhLW5hbWUnKTtcbiAgICAgICAgdmFyIHZhbHVlID0gcGFyc2VGbG9hdCgkZWxlbS5hdHRyKCdkYXRhLXZhbHVlJykpO1xuICAgICAgICBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSBwb2ludC5rZXkpIHtcbiAgICAgICAgICAkZWxlbS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgkZWxlbS5hdHRyKCdkYXRhLWlkJykgPT09ICdvdGhlcicpIHtcbiAgICAgICAgICB2YWx1ZSA9IG5vdHNob3duWzBdO1xuICAgICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQodmFsdWUgLyB0b3RhbFswXSAqIDEwMCk7XG4gICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUtc29ydCcsIHBlcmNlbnRhZ2UpO1xuXG4gICAgICAgIGlmIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpKVxuICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKHBlcmNlbnRhZ2UudG9GaXhlZCgyKSArICclICcgKyAobmFtZSB8fCAnKG5vdCBzZXQpJyksIDIzKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKCdOL0EgJyArIChuYW1lIHx8ICcobm90IHNldCknKSwgMjMpO1xuICAgICAgICAkZWxlbS5maW5kKCcudGFibGViYXInKS5jc3MoJ3dpZHRoJywgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMocGVyY2VudGFnZSkgPyAocGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IHBlcmNlbnRhZ2UgKyAnJScpIDogMCkpO1xuICAgICAgICBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSAnb3RoZXInKVxuICAgICAgICAgICRlbGVtLmZpbmQoJy5jYXB0aW9uJykudGV4dChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biB8fCAnTm90IHNob3duJykpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgJGVsZW0uZmluZCgnLmNhcHRpb24nKS50ZXh0KHRleHQpO1xuICAgICAgICAkZWxlbS5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh2YWx1ZSwgcG9pbnQubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHNlbGYuc29ydCgpO1xuICAgIGlmIChzZWxmLmRhdGFbMF0ubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgJHRib2R5ID0gJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgndGJvZHknKTtcbiAgICAgICR0Ym9keSA9ICQkKCR0Ym9keSk7XG4gICAgICAkdGJvZHkuZW1wdHkoKTtcbiAgICAgIHZhciAkdHIgPSAkJCgnPHRyIGNsYXNzPVwibm9kYXRhXCI+PC90cj4nKTtcbiAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNvbHNwYW49XCIyXCI+JyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vZGF0YSArICc8L3RkPicpO1xuICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgIH1cbiAgfTtcbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIHZhciBfcXVlcnkgPSBzZWxmLm9wdGlvbnMucXVlcnk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgIF9xdWVyeSA9IF9xdWVyeVswXTtcbiAgICB2YXIgZGltZW5zaW9ua2V5ID0gX3F1ZXJ5LmRpbWVuc2lvbnNbMF0ua2V5IHx8IF9xdWVyeS5kaW1lbnNpb25zWzBdO1xuICAgIHZhciBtZXRyaWNrZXkgPSBfcXVlcnkubWV0cmljc1swXS5rZXkgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG4gICAgdmFyIG1ldHJpY25hbWUgPSBkYXRhWzBdLm1ldGFbbWV0cmlja2V5XS5uYW1lIHx8IF9xdWVyeS5tZXRyaWNzWzBdLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG5cbiAgICB2YXIgdG90YWwgPSBbMCwgMF07XG4gICAgdmFyIHNob3duID0gWzAsIDBdO1xuICAgIHZhciBub3RzaG93biA9IFswLCAwXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQsIGluZGV4KSB7XG4gICAgICBhbGxkYXRhW2luZGV4XS5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgaSkge1xuICAgICAgICB0b3RhbFtpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICBpZiAoaSA8IChzZWxmLm9wdGlvbnMubGltaXQgJiYgc2VsZi5vcHRpb25zLmxpbWl0IDwgZGF0YS5sZW5ndGggPyBzZWxmLm9wdGlvbnMubGltaXQgLSAxIDogc2VsZi5vcHRpb25zLmxpbWl0ICkpXG4gICAgICAgICAgc2hvd25baW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG5vdHNob3duW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAoIXNlbGYub3B0aW9ucy5pbmNsdWRlX25vdF9zaG93bikge1xuICAgICAgdG90YWwgPSBzaG93bjtcbiAgICAgIG5vdHNob3duID0gWzAsIDBdO1xuICAgIH1cblxuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIHBvaW50ID0gZGF0YVswXTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3RyJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGVsZW0pIHtcbiAgICAgICAgLy92YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ1tkYXRhLWlkPVwiJyArIHBvaW50LmtleSArICdcIl0nKVswXTtcbiAgICAgICAgdmFyICRlbGVtID0gJCQoZWxlbSk7XG4gICAgICAgIHZhciBwZXJjZW50YWdlLCB0ZXh0O1xuICAgICAgICB2YXIgbmFtZSA9ICRlbGVtLmF0dHIoJ2RhdGEtbmFtZScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZUZsb2F0KCRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnKSk7XG4gICAgICAgIGlmICgkZWxlbS5hdHRyKCdkYXRhLWlkJykgPT09IHBvaW50LmtleSkge1xuICAgICAgICAgIHZhbHVlID0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSAnb3RoZXInKSB7XG4gICAgICAgICAgdmFsdWUgPSBub3RzaG93blswXTtcbiAgICAgICAgICAkZWxlbS5hdHRyKCdkYXRhLXZhbHVlJywgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KHZhbHVlIC8gdG90YWxbMF0gKiAxMDApO1xuICAgICAgICAkZWxlbS5hdHRyKCdkYXRhLXZhbHVlLXNvcnQnLCBwZXJjZW50YWdlKTtcblxuICAgICAgICBpZiAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhwZXJjZW50YWdlKSlcbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmVuc3VyZUxlbmd0aChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKG5hbWUgfHwgJyhub3Qgc2V0KScpLCAyMyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmVuc3VyZUxlbmd0aCgnTi9BICcgKyAobmFtZSB8fCAnKG5vdCBzZXQpJyksIDIzKTtcbiAgICAgICAgJGVsZW0uZmluZCgnLnRhYmxlYmFyJykuY3NzKCd3aWR0aCcsIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpID8gKHBlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBwZXJjZW50YWdlICsgJyUnKSA6IDApKTtcbiAgICAgICAgaWYgKCRlbGVtLmF0dHIoJ2RhdGEtaWQnKSA9PT0gJ290aGVyJylcbiAgICAgICAgICAkZWxlbS5maW5kKCcuY2FwdGlvbicpLnRleHQocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArIChzZWxmLm9wdGlvbnMuc3RyaW5ncy5ub3Rfc2hvd24gfHwgJ05vdCBzaG93bicpKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICRlbGVtLmZpbmQoJy5jYXB0aW9uJykudGV4dCh0ZXh0KTtcbiAgICAgICAgJGVsZW0uZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModmFsdWUsIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBzZWxmLnNvcnQoKTtcbiAgICBpZiAoc2VsZi5kYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdmFyICR0Ym9keSA9ICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3Rib2R5Jyk7XG4gICAgICAkdGJvZHkgPSAkJCgkdGJvZHkpO1xuICAgICAgJHRib2R5LmVtcHR5KCk7XG4gICAgICB2YXIgJHRyID0gJCgnPHRyIGNsYXNzPVwibm9kYXRhXCI+PC90cj4nKTtcbiAgICAgIHZhciAkdGQgPSAkKCc8dGQgY29sc3Bhbj1cIjJcIj4nICsgc2VsZi5vcHRpb25zLnN0cmluZ3Mubm9kYXRhICsgJzwvdGQ+Jyk7XG4gICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS52aXouc3RvcChzZWxmKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0YWJsZScpLmVtcHR5KCk7XG4gIH07XG5cbiAgdGhpcy5zb3J0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGJvZHkgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICB2YXIgJHJvd3MgPSAkdGJvZHkuZmluZCgndHInKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8ICRyb3dzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCAkcm93cy5sZW5ndGggLSAoaSArIDEpOyBqKyspIHtcbiAgICAgICAgdmFyICRyb3cgPSAkJCgkcm93c1tqXSk7XG4gICAgICAgIHZhciB2YWx1ZSA9ICRyb3cuYXR0cignZGF0YS12YWx1ZS1zb3J0Jyk7XG4gICAgICAgIHZhciAkbmV4dHJvdyA9ICQkKCRyb3dzW2ogKyAxXSk7XG4gICAgICAgIHZhciBuZXh0dmFsdWUgPSAkbmV4dHJvdy5hdHRyKCdkYXRhLXZhbHVlLXNvcnQnKTtcblxuICAgICAgICBpZiAoJG5leHRyb3cuYXR0cignZGF0YS1uYW1lJykgIT09IHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93bikge1xuICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG5leHR2YWx1ZSkgPiBwYXJzZUZsb2F0KHZhbHVlKSlcbiAgICAgICAgICAgICRyb3cuYmVmb3JlKCRuZXh0cm93KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIC8vd2UgZHJhdyB0aGUgdGVtcGxhdGUgaW50byB0aGUgY29udGFpbmVyXG4gICAgdmFyICRodG1sID0gJCQoc2VsZi5vcHRpb25zLnRlbXBsYXRlKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5odG1sKCRodG1sKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhcHRpb24pXG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuYmFydGFibGUtY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24pO1xuICAgIC8vdmlzdWFsaXphdGlvbiBzcGVjaWZpYyBkcmF3aW5nXG4gICAgaWYgKHNlbGYub3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICB2YXIgJHRoZWFkID0gJCQoJGh0bWwuZmluZCgndGhlYWQnKSk7XG4gICAgICB2YXIgJGhlYWRfdHIgPSAkJCgnPHRyIGNsYXNzPVwiamlvIGJhcnRhYmxlIGNhcHRpb25zXCI+PC90cj4nKTtcbiAgICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJqaW8gYmFydGFibGUgY2FwdGlvbiBtZXRyaWNcIj48L3RoPicpO1xuICAgICAgICAvLyR0aC50ZXh0KG0ubmFtZSB8fCBtLmtleSB8fCBtKTtcbiAgICAgICAgJGhlYWRfdHIuYXBwZW5kKCR0aCk7XG4gICAgICB9KTtcbiAgICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJqaW8gYmFydGFibGUgY2FwdGlvbiBkaW1lbnNpb25cIj48L3RoPicpO1xuICAgICAgICAkdGgudGV4dChkLm5hbWUgfHwgZC5rZXkgfHwgZCk7XG4gICAgICAgICRoZWFkX3RyLmFwcGVuZCgkdGgpO1xuICAgICAgfSk7XG5cbiAgICAgICR0aGVhZC5hcHBlbmQoJGhlYWRfdHIpO1xuICAgICAgJGh0bWwuZmluZCgndGFibGUnKS5hcHBlbmQoJHRoZWFkKTtcbiAgICB9XG4gICAgdmFyICR0Ym9keSA9ICRodG1sLmZpbmQoJ3Rib2R5Jyk7XG4gICAgJHRib2R5ID0gJCQoJHRib2R5KTtcbiAgICAkdGJvZHkuZW1wdHkoKTtcbiAgICB2YXIgJHRyID0gJCQoJzx0ciBjbGFzcz1cImxvYWRpbmdcIj48L3RyPicpO1xuICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwibG9hZGluZ1wiIGNvbHNwYW49XCIyXCI+JyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLmxvYWRpbmcgKyAnPC90ZD4nKTtcbiAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICRodG1sLmZpbmQoJ3RhYmxlJykuYXBwZW5kKCR0Ym9keSk7XG4gIH07XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5xdWVyeSAmJiAhQXJyYXkuaXNBcnJheShvcHRpb25zLnF1ZXJ5KSlcbiAgICBvcHRpb25zLnF1ZXJ5ID0gW29wdGlvbnMucXVlcnldO1xuICAvL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG5cbiAgaWYgKHNlbGYub3B0aW9ucy5jb2xvcnMubGVuZ3RoID09PSAwKVxuICAgIHNlbGYub3B0aW9ucy5jb2xvcnMgPSBqb29sYS5jb2xvcnM7XG4gIGlmIChzZWxmLm9wdGlvbnMub2ZmY29sb3JzLmxlbmd0aCA9PT0gMClcbiAgICBzZWxmLm9wdGlvbnMub2ZmY29sb3JzID0gam9vbGEub2ZmY29sb3JzO1xuXG4gIHNlbGYuZHJhdygpO1xuXG4gIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICBpZiAoIXNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJCQoZWxlbSkuQ2FudmFzKCk7XG4gICAgfVxuICB9XG4gIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICB9XG5cbiAgLy93cmFwIHVwXG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZvdW5kO1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5CYXJUYWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5CYXJUYWJsZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBiYXJ0YWJsZSkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoQmFyVGFibGUsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpLFxuICBjZSA9IHJlcXVpcmUoJ2Nsb25lZXh0ZW5kJyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbnZhciBDYW52YXMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdjYW52YXMuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5faWQgPSAnX2NhbnZhcyc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICB2aXN1YWxpemF0aW9uczoge30sXG4gICAgbWV0cmljczogW10sXG4gICAgZGltZW5zaW9uczogW10sXG4gICAgZmlsdGVyczogW10sXG4gICAgc3RhdGU6IHt9XG4gIH07XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMucHJlcGFyZVF1ZXJ5ID0gZnVuY3Rpb24gKHF1ZXJ5LCBkYXRlcykge1xuICAgIGlmICghZGF0ZXMpXG4gICAgICBkYXRlcyA9IHt9O1xuICAgIHZhciBfcXVlcnkgPSBjZS5leHRlbmQoe30sIHF1ZXJ5KTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBfcXVlcnkgPSBqb29sYS5jb21tb24uX2V4dGVuZChjZS5jbG9uZShzZWxmLm9wdGlvbnMucXVlcnkpLCBfcXVlcnkpO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoX3F1ZXJ5KSlcbiAgICAgIF9xdWVyeSA9IFtfcXVlcnldO1xuICAgIGlmIChfcXVlcnlbMF0uZGltZW5zaW9ucyAmJiBfcXVlcnlbMF0uZGltZW5zaW9ucy5sZW5ndGggPiAwICYmIF9xdWVyeVswXS5kaW1lbnNpb25zICYmIF9xdWVyeVswXS5kaW1lbnNpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIF9xdWVyeVswXS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGRpbWVuc2lvbiwgaSkge1xuICAgICAgICB2YXIga2V5O1xuICAgICAgICBpZiAodHlwZW9mIGRpbWVuc2lvbiA9PT0gJ3N0cmluZycpXG4gICAgICAgICAga2V5ID0gZGltZW5zaW9uO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGltZW5zaW9uID09PSAnb2JqZWN0JylcbiAgICAgICAgICBrZXkgPSBkaW1lbnNpb24ua2V5O1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICB2YXIgZXhpc3QgPSBfLmZpbmQoX3F1ZXJ5WzBdLmRpbWVuc2lvbnMsIGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gKG0ua2V5IHx8IG0pID09PSBrZXk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGV4aXN0KVxuICAgICAgICAgICAgX3F1ZXJ5WzBdLmRpbWVuc2lvbnNbaV0gPSBleGlzdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKF9xdWVyeVswXS5tZXRyaWNzICYmIF9xdWVyeVswXS5tZXRyaWNzLmxlbmd0aCA+IDAgJiYgX3F1ZXJ5WzBdLm1ldHJpY3MgJiYgX3F1ZXJ5WzBdLm1ldHJpY3MubGVuZ3RoID4gMCkge1xuICAgICAgX3F1ZXJ5WzBdLm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobWV0cmljLCBpKSB7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGlmICh0eXBlb2YgbWV0cmljID09PSAnc3RyaW5nJylcbiAgICAgICAgICBrZXkgPSBtZXRyaWM7XG4gICAgICAgIC8vZWxzZSBpZiAodHlwZW9mIG1ldHJpYyA9PT0gJ29iamVjdCcpXG4gICAgICAgIC8vICBrZXkgPSBtZXRyaWMua2V5O1xuXG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICB2YXIgZXhpc3QgPSBfLmZpbmQoc2VsZi5vcHRpb25zLm1ldHJpY3MsIGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gKG0ua2V5IHx8IG0pID09PSBrZXk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGV4aXN0KVxuICAgICAgICAgICAgX3F1ZXJ5WzBdLm1ldHJpY3NbaV0gPSBleGlzdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIF9xdWVyeVswXS50eXBlID0gJ2Jhc2UnO1xuICAgIF9xdWVyeVswXS5oYXNoID0gJyc7XG4gICAgaWYgKF9xdWVyeVswXS5kaW1lbnNpb25zICYmIEFycmF5LmlzQXJyYXkoX3F1ZXJ5WzBdLmRpbWVuc2lvbnMpKSB7XG4gICAgICBfcXVlcnlbMF0uZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgIF9xdWVyeVswXS5oYXNoICs9IGQua2V5IHx8IGQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKF9xdWVyeVswXS5tZXRyaWNzICYmIEFycmF5LmlzQXJyYXkoX3F1ZXJ5WzBdLm1ldHJpY3MpKVxuICAgICAgX3F1ZXJ5WzBdLm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICBfcXVlcnlbMF0uaGFzaCArPSBtLmtleSB8fCBtO1xuICAgICAgfSk7XG4gICAgX3F1ZXJ5WzBdLmhhc2ggPSBqb29sYS5jb21tb24uaGFzaChfcXVlcnlbMF0uaGFzaCk7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5kYXRlcGlja2VyICYmIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLmNvbnRhaW5lcikge1xuICAgICAgZGF0ZXMgPSB7XG4gICAgICAgIGJhc2VfZnJvbWRhdGU6IHNlbGYub3B0aW9ucy4kZGF0ZXBpY2tlci5iYXNlX2Zyb21kYXRlLFxuICAgICAgICBiYXNlX3RvZGF0ZTogc2VsZi5vcHRpb25zLiRkYXRlcGlja2VyLmJhc2VfdG9kYXRlLFxuICAgICAgICBjb21wYXJlX2Zyb21kYXRlOiBzZWxmLm9wdGlvbnMuJGRhdGVwaWNrZXIuY29tcGFyZV9mcm9tZGF0ZSxcbiAgICAgICAgY29tcGFyZV90b2RhdGU6IHNlbGYub3B0aW9ucy4kZGF0ZXBpY2tlci5jb21wYXJlX3RvZGF0ZVxuICAgICAgfTtcbiAgICAgIF9xdWVyeVswXS50aW1lZnJhbWUgPSB7fTtcbiAgICAgIF9xdWVyeVswXS50aW1lZnJhbWUuc3RhcnQgPSBkYXRlcy5iYXNlX2Zyb21kYXRlIHx8IHNlbGYuX2RhdGVwaWNrZXIuYmFzZV9mcm9tZGF0ZTtcbiAgICAgIF9xdWVyeVswXS50aW1lZnJhbWUuZW5kID0gZGF0ZXMuYmFzZV90b2RhdGUgfHwgc2VsZi5fZGF0ZXBpY2tlci5iYXNlX3RvZGF0ZTtcbiAgICAgIF9xdWVyeVswXS5pbnRlcnZhbCA9ICdkYXknO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5kYXRlcGlja2VyICYmIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLl9pbnRlcnZhbClcbiAgICAgICAgX3F1ZXJ5WzBdLmludGVydmFsID0gc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsO1xuICAgIH1cbiAgICBfcXVlcnlbMF0ucmVhbHRpbWUgPSBfcXVlcnlbMF0ucmVhbHRpbWUgfHwgc2VsZi5vcHRpb25zLnJlYWx0aW1lIHx8IGZhbHNlO1xuICAgIGlmIChzZWxmLl9kYXRlcGlja2VyICYmIHNlbGYuX2RhdGVwaWNrZXIuY29tcGFyZVBlcmlvZCkge1xuICAgICAgX3F1ZXJ5WzBdLnJlYWx0aW1lID0gZmFsc2U7XG4gICAgICB2YXIgY3F1ZXJ5ID0gY2UuY2xvbmUoX3F1ZXJ5WzBdKTtcbiAgICAgIGNxdWVyeS50eXBlID0gJ2NvbXBhcmUnO1xuICAgICAgY3F1ZXJ5LnRpbWVmcmFtZSA9IHt9O1xuICAgICAgY3F1ZXJ5LnRpbWVmcmFtZS5zdGFydCA9IGRhdGVzLmNvbXBhcmVfZnJvbWRhdGUgfHwgc2VsZi5fZGF0ZXBpY2tlci5jb21wYXJlX2Zyb21kYXRlO1xuICAgICAgY3F1ZXJ5LnRpbWVmcmFtZS5lbmQgPSBkYXRlcy5jb21wYXJlX3RvZGF0ZSB8fCBzZWxmLl9kYXRlcGlja2VyLmNvbXBhcmVfdG9kYXRlO1xuICAgICAgY3F1ZXJ5LmludGVydmFsID0gJ2RheSc7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIgJiYgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsKVxuICAgICAgICBjcXVlcnkuaW50ZXJ2YWwgPSBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5faW50ZXJ2YWw7XG4gICAgICBfcXVlcnkgPSBbX3F1ZXJ5WzBdLCBjcXVlcnldO1xuICAgIH1cbiAgICByZXR1cm4gX3F1ZXJ5O1xuICB9O1xuXG4gIHRoaXMucGFyc2VJbnRlcnZhbCA9IGZ1bmN0aW9uICgkY29udGFpbmVyKSB7XG4gICAgcmV0dXJuICRjb250YWluZXIuZmluZCgnLmFjdGl2ZScpLmF0dHIoJ2RhdGEtaWQnKTtcbiAgfTtcblxuICB0aGlzLmJ1aWxkRmlsdGVyID0gZnVuY3Rpb24gKHBvaW50LCBkaW1lbnNpb25rZXkpIHtcbiAgICB2YXIgZmlsdGVycyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKHBvaW50LmRpbWVuc2lvbnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgaWYgKGRpbWVuc2lvbmtleSAmJiBkaW1lbnNpb25rZXkgPT09IGtleSB8fCAhZGltZW5zaW9ua2V5KSB7XG4gICAgICAgIHZhciBkaW1lbnNpb24gPSBwb2ludC5tZXRhW2tleV07XG4gICAgICAgIHZhciB2YWx1ZSA9IHBvaW50LmRpbWVuc2lvbnNba2V5XTtcbiAgICAgICAgdmFyIGZpbHRlciA9IFtkaW1lbnNpb24ua2V5LCAnZXEnLCBkaW1lbnNpb24uZGF0YXR5cGUgPT09ICdkYXRlJyA/IG5ldyBEYXRlKHZhbHVlKSA6IHZhbHVlXTtcbiAgICAgICAgZmlsdGVycy5wdXNoKGZpbHRlcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJ2J1aWxkIGZpbHRlcicsIGZpbHRlcnMpO1xuICAgIHJldHVybiBmaWx0ZXJzO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBpZiAoc2VsZi5vcHRpb25zLm9uRHJhdylcbiAgICAgIHdpbmRvd1tzZWxmLm9wdGlvbnMub25EcmF3XShzZWxmKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmZpbHRlcmJveCAmJiBzZWxmLm9wdGlvbnMuZmlsdGVyYm94LmNvbnRhaW5lcikge1xuICAgICAgc2VsZi5vcHRpb25zLmZpbHRlcmJveC5jYW52YXMgPSBzZWxmO1xuICAgICAgbmV3IGpvb2xhLnZpei5GaWx0ZXJCb3goc2VsZi5vcHRpb25zLmZpbHRlcmJveCwgZnVuY3Rpb24gKGVyciwgcmVmKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy5maWx0ZXJib3gucmVmID0gcmVmO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlciAmJiBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5jb250YWluZXIpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLmNhbnZhcyA9IHNlbGY7XG4gICAgICBuZXcgam9vbGEudml6LkRhdGVQaWNrZXIoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIsIGZ1bmN0aW9uIChlcnIsIHJlZikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgc2VsZi5fZGF0ZXBpY2tlciA9IHJlZjtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRkYXRlcGlja2VyID0gcmVmO1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuaW50ZXJ2YWwpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci4kaW50ZXJ2YWwgPSAkJChzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5pbnRlcnZhbCk7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsID0gc2VsZi5wYXJzZUludGVydmFsKHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLiRpbnRlcnZhbCk7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuJGludGVydmFsLmZpbmQoJy5idG4nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLiRpbnRlcnZhbC5maW5kKCcuYnRuJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgJHRoaXMuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5faW50ZXJ2YWwgPSAkdGhpcy5hdHRyKCdkYXRhLWlkJyk7XG4gICAgICAgICAgICBzZWxmLmVtaXQoJ2ludGVydmFsY2hhbmdlJywgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIE9iamVjdC5rZXlzKHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgdmFyIHZpeiA9IHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9uc1trZXldO1xuICAgICAgICAgIGlmICh2aXouY29udGFpbmVyKSB7XG4gICAgICAgICAgICB2aXoucXVlcnkgPSBzZWxmLnByZXBhcmVRdWVyeSh2aXoucXVlcnkpO1xuICAgICAgICAgICAgdml6LmZvcmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIHZpei5jYW52YXMgPSBzZWxmO1xuICAgICAgICAgICAgc3dpdGNoICh2aXoudHlwZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3RpbWVsaW5lJzpcbiAgICAgICAgICAgICAgICBuZXcgam9vbGEudml6LlRpbWVsaW5lKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ21ldHJpYyc6XG4gICAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5NZXRyaWModml6KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouVGFibGUodml6KS5vbignc2VsZWN0JywgZnVuY3Rpb24gKHBvaW50LCBkaW1lbnNpb25rZXkpIHtcbiAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBzZWxmLmJ1aWxkRmlsdGVyKHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgdmFyIGV4aXN0ID0gXy5maW5kKHNlbGYub3B0aW9ucy5maWx0ZXJzLCBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIua2V5ID09PSBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGlmIChleGlzdClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdyZW1vdmVmaWx0ZXInLCBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgnYWRkZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5LCBwb2ludC5tZXRhLCBmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdtaW5pdGFibGUnOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouTWluaVRhYmxlKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ2JhcnRhYmxlJzpcbiAgICAgICAgICAgICAgICBuZXcgam9vbGEudml6LkJhclRhYmxlKHZpeikub24oJ3NlbGVjdCcsIGZ1bmN0aW9uIChwb2ludCwgZGltZW5zaW9ua2V5KSB7XG4gICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBvaW50KSlcbiAgICAgICAgICAgICAgICAgICAgcG9pbnQgPSBwb2ludFswXTtcbiAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBzZWxmLmJ1aWxkRmlsdGVyKHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgdmFyIGV4aXN0ID0gXy5maW5kKHNlbGYub3B0aW9ucy5maWx0ZXJzLCBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIua2V5ID09PSBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGlmIChleGlzdClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdyZW1vdmVmaWx0ZXInLCBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgnYWRkZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5LCBwb2ludC5tZXRhLCBmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdwaWUnOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouUGllKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ2dlbyc6XG4gICAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5HZW8odml6KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgT2JqZWN0LmtleXMoc2VsZi5vcHRpb25zLnZpc3VhbGl6YXRpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgdmFyIHZpeiA9IHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9uc1trZXldO1xuICAgICAgICBpZiAodml6LmNvbnRhaW5lcikge1xuICAgICAgICAgIHZpei5xdWVyeSA9IHNlbGYucHJlcGFyZVF1ZXJ5KHZpei5xdWVyeSk7XG4gICAgICAgICAgdml6LmZvcmNlID0gdHJ1ZTtcbiAgICAgICAgICB2aXouY2FudmFzID0gc2VsZjtcbiAgICAgICAgICBzd2l0Y2ggKHZpei50eXBlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIGNhc2UgJ3RpbWVsaW5lJzpcbiAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5UaW1lbGluZSh2aXopO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21ldHJpYyc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouTWV0cmljKHZpeik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICAgICAgICBuZXcgam9vbGEudml6LlRhYmxlKHZpeikub24oJ3NlbGVjdCcsIGZ1bmN0aW9uIChwb2ludCwgZGltZW5zaW9ua2V5KSB7XG4gICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHNlbGYuYnVpbGRGaWx0ZXIocG9pbnQsIGRpbWVuc2lvbmtleSk7XG4gICAgICAgICAgICAgICAgdmFyIGV4aXN0ID0gXy5maW5kKHNlbGYub3B0aW9ucy5maWx0ZXJzLCBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyLmtleSA9PT0gcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChleGlzdClcbiAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgncmVtb3ZlZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgnYWRkZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5LCBwb2ludC5tZXRhLCBmaWx0ZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbWluaXRhYmxlJzpcbiAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5NaW5pVGFibGUodml6KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdiYXJ0YWJsZSc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouQmFyVGFibGUodml6KS5vbignc2VsZWN0JywgZnVuY3Rpb24gKHBvaW50LCBkaW1lbnNpb25rZXkpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwb2ludCkpXG4gICAgICAgICAgICAgICAgICBwb2ludCA9IHBvaW50WzBdO1xuICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBzZWxmLmJ1aWxkRmlsdGVyKHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChzZWxmLm9wdGlvbnMuZmlsdGVycywgZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlci5rZXkgPT09IHBvaW50LmtleSArIGRpbWVuc2lvbmtleTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3JlbW92ZWZpbHRlcicsIHBvaW50LmtleSArIGRpbWVuc2lvbmtleSk7XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ2FkZGZpbHRlcicsIHBvaW50LmtleSArIGRpbWVuc2lvbmtleSwgcG9pbnQubWV0YSwgZmlsdGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3BpZSc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouUGllKHZpeik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnZ2VvJzpcbiAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5HZW8odml6KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHNlbGYub24oJ2FkZGZpbHRlcicsIGZ1bmN0aW9uIChrZXksIG1ldGEsIGZpbHRlcikge1xuICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGYub3B0aW9ucy5maWx0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZmlsdGVyc1tpXS5rZXkgPT09IGtleSkge1xuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICBzZWxmLm9wdGlvbnMuZmlsdGVycy5wdXNoKHtrZXk6IGtleSwgZmlsdGVyczogZmlsdGVyfSk7XG4gICAgICAgIGZpbHRlci5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgdmFyICRmaWx0ZXIgPSAkJCgnPGRpdiBkYXRhLWlkPVwiJyArIGtleSArICdcIiBjbGFzcz1cImZpbHRlclwiPjwvZGl2PicpO1xuICAgICAgICAgIHZhciB0ZXh0ID0gbWV0YVtmWzBdXS5uYW1lICsgJzogPHN0cm9uZyBjbGFzcz1cInZhbHVlXCI+JyArIGZbMl0gKyAnPC9zdHJvbmc+JztcbiAgICAgICAgICB2YXIgJGlubmVyID0gJCQoJzxzcGFuIGNsYXNzPVwiY2FwdGlvblwiPicgKyB0ZXh0ICsgJzwvc3Bhbj4nKTtcbiAgICAgICAgICB2YXIgJGNsb3NlID0gJCQoJzxzcGFuIGNsYXNzPVwiY2xvc2UgaWNvbi1jbG9zZVwiPjwvc3Bhbj4nKTtcbiAgICAgICAgICAkY2xvc2Uub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgc2VsZi5lbWl0KCdyZW1vdmVmaWx0ZXInLCBrZXkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgICRmaWx0ZXIuYXBwZW5kKCRpbm5lcik7XG4gICAgICAgICAgJGZpbHRlci5hcHBlbmQoJGNsb3NlKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmZpbHRlcmJveCAmJiBzZWxmLm9wdGlvbnMuZmlsdGVyYm94LnJlZilcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5maWx0ZXJib3gucmVmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZmlsdGVyYm94JykuYXBwZW5kKCRmaWx0ZXIpO1xuICAgICAgICAgIHNlbGYuZW1pdCgnZmlsdGVyY2hhbmdlJyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHNlbGYub24oJ3JlbW92ZWZpbHRlcicsIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZi5vcHRpb25zLmZpbHRlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5maWx0ZXJzW2ldLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmZpbHRlcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZmlsdGVyYm94ICYmIHNlbGYub3B0aW9ucy5maWx0ZXJib3gucmVmKVxuICAgICAgICAgICAgc2VsZi5vcHRpb25zLmZpbHRlcmJveC5yZWYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJ1tkYXRhLWlkPVwiJyArIGtleSArICdcIl0nKS5yZW1vdmUoKTtcbiAgICAgICAgICBpID0gc2VsZi5vcHRpb25zLmZpbHRlcnMubGVuZ3RoO1xuICAgICAgICAgIHNlbGYuZW1pdCgnZmlsdGVyY2hhbmdlJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuYWRkVmlzdWFsaXphdGlvbiA9IGZ1bmN0aW9uICh2aXopIHtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy52aXN1YWxpemF0aW9ucylcbiAgICAgIHRoaXMub3B0aW9ucy52aXN1YWxpemF0aW9ucyA9IHt9O1xuICAgIHRoaXMub3B0aW9ucy52aXN1YWxpemF0aW9uc1t2aXoudXVpZF0gPSB2aXo7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIG9wdGlvbnMgfHwge30pO1xuXG4gIHNlbGYuZHJhdygpO1xuICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgfVxuXG4gIC8vd3JhcCB1cFxuICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLkNhbnZhcyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouQ2FudmFzKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIGNhbnZhcykge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIGNhbnZhcy4nLCBlcnIpO1xuICAgICAgICAgIGNhbnZhcy5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoQ2FudmFzLCBldmVudHMuRXZlbnRFbWl0dGVyKTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXJcbiAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG5cbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuICAkJCA9IHJlcXVpcmUoJ2pxdWVyeScpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpO1xuXG52YXIgRGF0ZVBpY2tlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcblxuICByZXF1aXJlKCdqcXVlcnktdWkvZGF0ZXBpY2tlcicpO1xuICBqb29sYS5ldmVudHMuZW1pdCgnZGF0ZXBpY2tlci5pbml0LnN0YXJ0Jyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuYWRkRGF5cyA9IGZ1bmN0aW9uIChvLCBkYXlzKSB7XG4vLyBrZWVwIGluIG1pbmQsIG1vbnRocyBpbiBqYXZhc2NyaXB0IGFyZSAwLTExXG4gICAgcmV0dXJuIG5ldyBEYXRlKG8uZ2V0RnVsbFllYXIoKSwgby5nZXRNb250aCgpLCBvLmdldERhdGUoKSArIGRheXMpO1xuICB9O1xuXG4gIHRoaXMuZml4RGF0ZSA9IGZ1bmN0aW9uICh0aW1lc3RhbXAsIHplcm8pIHtcbiAgICB2YXIgb2Zmc2V0ID0gLTEgKiAodGltZXN0YW1wLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MCk7XG5cbiAgICAvLyBNdWx0aXBseSBieSAxMDAwIGJlY2F1c2UgSlMgd29ya3MgaW4gbWlsbGlzZWNvbmRzIGluc3RlYWQgb2YgdGhlIFVOSVggc2Vjb25kc1xuICAgIHZhciBkYXRlID0gdGltZXN0YW1wOy8vIG5ldyBEYXRlKHRpbWVzdGFtcCAqIDEwMDApO1xuXG4gICAgdmFyIHllYXIgPSBkYXRlLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgdmFyIG1vbnRoID0gZGF0ZS5nZXRVVENNb250aCgpICsgMTsgLy8gZ2V0TW9udGgoKSBpcyB6ZXJvLWluZGV4ZWQsIHNvIHdlJ2xsIGluY3JlbWVudCB0byBnZXQgdGhlIGNvcnJlY3QgbW9udGggbnVtYmVyXG4gICAgdmFyIGRheSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgIHZhciBob3VycyA9IGRhdGUuZ2V0VVRDSG91cnMoKTtcbiAgICB2YXIgbWludXRlcyA9IGRhdGUuZ2V0VVRDTWludXRlcygpO1xuICAgIHZhciBzZWNvbmRzID0gZGF0ZS5nZXRVVENTZWNvbmRzKCk7XG5cbiAgICB2YXIgYkFkZERheSA9IGZhbHNlO1xuICAgIGhvdXJzID0gaG91cnMgKyBvZmZzZXQ7IC8vZ210XG5cbiAgICB2YXIgZml4ZWREYXRlID0gbnVsbDtcbiAgICBpZiAoIXplcm8pXG4gICAgICBmaXhlZERhdGUgPSBuZXcgRGF0ZSh5ZWFyICsgJy0nICsgbW9udGggKyAnLScgKyBkYXkgKyAnICcgKyBob3VycyArICc6JyArIG1pbnV0ZXMgKyAnIEdNVCcpO1xuICAgIGVsc2VcbiAgICAgIGZpeGVkRGF0ZSA9IG5ldyBEYXRlKHllYXIgKyAnLScgKyBtb250aCArICctJyArIGRheSArICcgJyArICcwMCcgKyAnOicgKyAnMDAnICsgJyBHTVQnKTtcbiAgICBpZiAoZml4ZWREYXRlID09ICdJbnZhbGlkIERhdGUnKSB7XG4gICAgICBpZiAoIXplcm8pIHtcbiAgICAgICAgZml4ZWREYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgZml4ZWREYXRlLnNldEZ1bGxZZWFyKHllYXIsIG1vbnRoIC0gMSwgZGF5KTtcbiAgICAgICAgZml4ZWREYXRlLnNldEhvdXJzKHBhcnNlSW50KGhvdXJzKSk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRNaW51dGVzKHBhcnNlSW50KG1pbnV0ZXMpKTtcbiAgICAgICAgZml4ZWREYXRlLnNldFNlY29uZHMocGFyc2VJbnQoc2Vjb25kcykpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIGZpeGVkRGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCAtIDEsIGRheSk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRIb3VycyhwYXJzZUludChob3VycykpO1xuICAgICAgICBmaXhlZERhdGUuc2V0TWludXRlcygwKTtcbiAgICAgICAgZml4ZWREYXRlLnNldFNlY29uZHMoMCk7XG4gICAgICB9XG4gICAgfVxuXG5cbiAgICBpZiAoYkFkZERheSlcbiAgICAgIGZpeGVkRGF0ZS5zZXREYXRlKGZpeGVkRGF0ZS5nZXREYXRlKCkgKyAxKTtcblxuICAgIHZhciBmaXhlZERhdGVfdXRjID0gbmV3IERhdGUoZml4ZWREYXRlLmdldFVUQ0Z1bGxZZWFyKCksIGZpeGVkRGF0ZS5nZXRVVENNb250aCgpLCBmaXhlZERhdGUuZ2V0VVRDRGF0ZSgpLCBmaXhlZERhdGUuZ2V0VVRDSG91cnMoKSwgZml4ZWREYXRlLmdldFVUQ01pbnV0ZXMoKSwgZml4ZWREYXRlLmdldFVUQ1NlY29uZHMoKSk7XG5cblxuICAgIHJldHVybiBmaXhlZERhdGU7XG4gIH07XG5cbiAgdGhpcy50eXBlID0gJ2RhdGVwaWNrZXInO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgY2FudmFzOiBudWxsLFxuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAkY29udGFpbmVyOiBudWxsLFxuICAgIGNvbXBhcmVQZXJpb2Q6IGZhbHNlLFxuICAgIGRpc2FibGVDb21wYXJlOiBmYWxzZVxuICB9O1xuXG4gIHRoaXMuY3VycmVudE1vZGUgPSAnYmFzZS1mcm9tJztcblxuICB0aGlzLm9yaWdpbmFsX2Jhc2VfZnJvbWRhdGUgPSBudWxsO1xuICB0aGlzLm9yaWdpbmFsX2Jhc2VfdG9kYXRlID0gbnVsbDtcbiAgdGhpcy5vcmlnaW5hbF9jb21wYXJlX2Zyb21kYXRlID0gbnVsbDtcbiAgdGhpcy5vcmlnaW5hbF9jb21wYXJlX3RvZGF0ZSA9IG51bGw7XG5cbiAgaWYgKG9wdGlvbnMubWluZGF0ZSlcbiAgICB0aGlzLm1pbl9kYXRlID0gb3B0aW9ucy5taW5fZGF0ZTtcbiAgLy90aGlzLm1pbl9kYXRlID0gbmV3IERhdGUoKTsvL25ldyBqb29sYS5vYmplY3RzLlF1ZXJ5KCkuU3lzdGVtU3RhcnREYXRlKCk7XG4gIC8vdGhpcy5taW5fZGF0ZS5zZXRNb250aCh0aGlzLm1pbl9kYXRlLmdldE1vbnRoKCkgLSA2KTtcbiAgaWYgKG9wdGlvbnMubWF4ZGF0ZSlcbiAgICB0aGlzLm1heF9kYXRlID0gb3B0aW9ucy5tYXhkYXRlO1xuICBlbHNlXG4gICAgdGhpcy5tYXhfZGF0ZSA9IG5ldyBEYXRlKCk7Ly9uZXcgam9vbGEub2JqZWN0cy5RdWVyeSgpLlN5c3RlbUVuZERhdGUoKTtcbiAgdGhpcy5tYXhfZGF0ZS5zZXRIb3VycygyMyk7XG4gIHRoaXMubWF4X2RhdGUuc2V0TWludXRlcyg1OSk7XG4gIHRoaXMubWF4X2RhdGUuc2V0U2Vjb25kcyg1OSk7XG4gIHRoaXMubWF4X2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG5cbiAgaWYgKG9wdGlvbnMudG9kYXRlKVxuICAgIHRoaXMuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZShvcHRpb25zLnRvZGF0ZSk7XG4gIGVsc2VcbiAgICB0aGlzLmJhc2VfdG9kYXRlID0gbmV3IERhdGUodGhpcy5tYXhfZGF0ZSk7XG4gIGlmIChvcHRpb25zLmZyb21kYXRlKVxuICAgIHRoaXMuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKG9wdGlvbnMuZnJvbWRhdGUpO1xuICBlbHNlXG4gICAgdGhpcy5iYXNlX2Zyb21kYXRlID0gc2VsZi5hZGREYXlzKHRoaXMuYmFzZV90b2RhdGUsIC0zMCk7XG5cbiAgaWYgKHRoaXMuYmFzZV9mcm9tZGF0ZSA8IHRoaXMubWluX2RhdGUpIHtcbiAgICB0aGlzLmJhc2VfZnJvbWRhdGUgPSBuZXcgRGF0ZSgpOy8vdGhpcy5taW5fZGF0ZS5maXhEYXRlKHRydWUsIGZhbHNlKTtcbiAgICB0aGlzLmJhc2VfZnJvbWRhdGUuc2V0RGF0ZSh0aGlzLmJhc2VfZnJvbWRhdGUuZ2V0RGF0ZSgpIC0gMSk7XG4gICAgdGhpcy5kaXNhYmxlQ29tcGFyZSA9IHRydWU7XG4gIH1cblxuICB2YXIgcmFuZ2VsZW5ndGggPSBEYXRlLmRhdGVEaWZmKCdkJywgdGhpcy5iYXNlX2Zyb21kYXRlLCB0aGlzLmJhc2VfdG9kYXRlKTtcbiAgaWYgKG9wdGlvbnMuY29tcGFyZV90b2RhdGUpXG4gICAgdGhpcy5jb21wYXJlX3RvZGF0ZSA9IG9wdGlvbnMuY29tcGFyZV90b2RhdGU7XG4gIGVsc2VcbiAgICB0aGlzLmNvbXBhcmVfdG9kYXRlID0gc2VsZi5hZGREYXlzKHRoaXMuYmFzZV9mcm9tZGF0ZSwgLTEpO1xuICB0aGlzLmNvbXBhcmVfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcbiAgaWYgKG9wdGlvbnMuY29tcGFyZV9mcm9tZGF0ZSlcbiAgICB0aGlzLmNvbXBhcmVfZnJvbWRhdGUgPSBvcHRpb25zLmNvbXBhcmVfZnJvbWRhdGU7XG4gIGVsc2VcbiAgICB0aGlzLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFkZERheXModGhpcy5jb21wYXJlX3RvZGF0ZSwgKC0xICogcmFuZ2VsZW5ndGgpKTtcblxuICB0aGlzLm9yaWdpbmFsX2Jhc2VfZnJvbWRhdGUgPSB0aGlzLmJhc2VfZnJvbWRhdGU7XG4gIHRoaXMub3JpZ2luYWxfYmFzZV90b2RhdGUgPSB0aGlzLmJhc2VfdG9kYXRlO1xuICB0aGlzLm9yaWdpbmFsX2NvbXBhcmVfZnJvbWRhdGUgPSB0aGlzLmNvbXBhcmVfZnJvbWRhdGU7XG4gIHRoaXMub3JpZ2luYWxfY29tcGFyZV90b2RhdGUgPSB0aGlzLmNvbXBhcmVfdG9kYXRlO1xuXG4gIHRoaXMuYXBwbGllZF9iYXNlX2Zyb21kYXRlID0gdGhpcy5iYXNlX2Zyb21kYXRlO1xuICB0aGlzLmFwcGxpZWRfYmFzZV90b2RhdGUgPSB0aGlzLmJhc2VfdG9kYXRlO1xuICB0aGlzLmFwcGxpZWRfY29tcGFyZV9mcm9tZGF0ZSA9IHRoaXMuY29tcGFyZV9mcm9tZGF0ZTtcbiAgdGhpcy5hcHBsaWVkX2NvbXBhcmVfdG9kYXRlID0gdGhpcy5jb21wYXJlX3RvZGF0ZTtcblxuICB0aGlzLmNvbXBhcmVQZXJpb2QgPSBvcHRpb25zLmNvbXBhcmUgfHwgZmFsc2U7XG4gIHRoaXMuaXNDb21wYXJlQ2hlY2tlZCA9IG9wdGlvbnMuY29tcGFyZSB8fCBmYWxzZTtcblxuICAvL3NlbGYuZ2V0U3RhdGUoc2VsZik7XG5cbiAgdGhpcy5vZmZzZXRYID0gMDtcbiAgdGhpcy5vZmZzZXRZID0gMDtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIGlmIChjYWxsYmFjaylcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuXG4gIHRoaXMudGVtcGxhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGJpbmRLZXkgPSBmdW5jdGlvbiAoYnRuKSB7XG4gICAgICB2YXIgJGJ0biA9ICQkKGJ0bik7XG4gICAgICAkYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmJ0bicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJGJ0bi5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAkYnRuO1xuICAgIH07XG5cbiAgICB2YXIgYmluZFBvcFVwID0gZnVuY3Rpb24gKGJ0bikge1xuICAgICAgdmFyICRidG4gPSAkJChidG4pO1xuICAgICAgJGJ0bi5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5idG4nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICRidG4uYWRkQ2xhc3MoJ2FjdGl2ZSBvcGVuJyk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiAkYnRuO1xuICAgIH07XG5cbiAgICB2YXIgJGdyb3VwID0gJCQoJzxkaXYgY2xhc3M9XCJqaW8gZGF0ZXBpY2tlciBidG4tZ3JvdXBcIj48L2Rpdj4nKTtcbiAgICB2YXIgJGxhc3RfZGF5ID0gJCQoJzxkaXYgY2xhc3M9XCJqaW8gZGF0ZXBpY2tlciBvcHRpb24gYnRuIGJ0bi1kZWZhdWx0IGxhc3RfZGF5XCI+UGFzdCBEYXk8L2Rpdj4nKTtcbiAgICB2YXIgJGxhc3Rfd2VlayA9ICQkKCc8ZGl2IGNsYXNzPVwiamlvIGRhdGVwaWNrZXIgb3B0aW9uIGJ0biBidG4tZGVmYXVsdCBsYXN0X3dlZWtcIj5QYXN0IFdlZWs8L2Rpdj4nKTtcbiAgICB2YXIgJGxhc3RfbW9udGggPSAkJCgnPGRpdiBjbGFzcz1cImppbyBkYXRlcGlja2VyIG9wdGlvbiBidG4gYnRuLWRlZmF1bHQgbGFzdF9tb250aFwiPlBhc3QgTW9udGg8L2Rpdj4nKTtcbiAgICB2YXIgJGN1c3RvbSA9ICQkKCc8ZGl2IGNsYXNzPVwiamlvIGRhdGVwaWNrZXIgb3B0aW9uIGJ0biBidG4tZGVmYXVsdCBjdXN0b21cIj5DdXN0b208L2Rpdj4nKTtcblxuICAgICRncm91cC5hcHBlbmQoYmluZEtleSgkbGFzdF9kYXkpKTtcbiAgICAkZ3JvdXAuYXBwZW5kKGJpbmRLZXkoJGxhc3Rfd2VlaykpO1xuICAgICRncm91cC5hcHBlbmQoYmluZEtleSgkbGFzdF9tb250aCkpO1xuICAgICRncm91cC5hcHBlbmQoYmluZFBvcFVwKCRjdXN0b20pKTtcblxuICAgIHJldHVybiAkZ3JvdXA7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5vbkRyYXcpXG4gICAgICB3aW5kb3dbc2VsZi5vcHRpb25zLm9uRHJhd10oc2VsZi5vcHRpb25zLmNvbnRhaW5lciwgc2VsZik7XG5cbiAgICB2YXIgJGNvbnRhaW5lciA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyO1xuICAgIC8vc2VsZi5vcHRpb25zLiRjb250YWluZXIuYXBwZW5kKHNlbGYudGVtcGxhdGUoKSk7XG4gICAgdmFyICR0YWJsZSA9ICQkKCc8ZGl2IGNsYXNzPVwiZGF0ZWJveCBqY29udGFpbmVyXCI+PHRhYmxlIGNsYXNzPVwiZGF0ZXRhYmxlIHVuc2VsZWN0YWJsZVwiPicgK1xuICAgICAgJzx0cj4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJkYXRlc1wiPjwvdGQ+JyArXG4gICAgICAnPHRkIGNsYXNzPVwiZHJvcGRvd25tYXJrZXItd3JhcHBlclwiPjxkaXYgY2xhc3M9XCJkcm9wZG93bm1hcmtlclwiPjwvZGl2PjwvdGQ+JyArXG4gICAgICAnPC90cj4nICtcbiAgICAgICc8L3RhYmxlPjwvZGl2PjwvZGl2PicpO1xuXG4gICAgJGNvbnRhaW5lci5hcHBlbmQoJHRhYmxlKTtcblxuICAgIHZhciAkZGF0ZXMgPSAkdGFibGUuZmluZCgnLmRhdGVzJyk7XG4gICAgJGRhdGVzLmFwcGVuZCgnPHNwYW4gY2xhc3M9XCJkYXRlbGFiZWwgZnJvbWRhdGVcIj4nICsgam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSArICc8L3NwYW4+Jyk7XG4gICAgJGRhdGVzLmFwcGVuZCgnIC0gJyk7XG4gICAgJGRhdGVzLmFwcGVuZCgnPHNwYW4gY2xhc3M9XCJkYXRlbGFiZWwgdG9kYXRlXCI+JyArIGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpICsgJzwvc3Bhbj4nKTtcbiAgICAkZGF0ZXMuYXBwZW5kKCc8ZGl2IGNsYXNzPVwiY29tcGFyZVwiIHN0eWxlPVwiZGlzcGxheTpub25lXCI+Q29tcGFyZSB0bzogPHNwYW4gY2xhc3M9XCJkYXRlbGFiZWwgY29tcGFyZSBmcm9tZGF0ZVwiPicgKyBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpICsgJzwvc3Bhbj4gLSA8c3BhbiBjbGFzcz1cImRhdGVsYWJlbCBjb21wYXJlIHRvZGF0ZVwiPicgKyBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSArICc8L3NwYW4+PC9kaXY+Jyk7XG5cbiAgICBpZiAoc2VsZi5jb21wYXJlUGVyaW9kKSB7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcyAuY29tcGFyZScpLnNob3coKTtcbiAgICAgICRjb250YWluZXIuYWRkQ2xhc3MoJ2NvbXBhcmUnKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAkY29udGFpbmVyLnJlbW92ZUNsYXNzKCdjb21wYXJlJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcyAuY29tcGFyZScpLmhpZGUoKTtcbiAgICB9XG4gICAgdmFyICRpdGVtID0gJCQoJzxkaXYgY2xhc3M9XCJwaWNrZXJcIiBzdHlsZT1cImRpc3BsYXk6bm9uZVwiPjwvZGl2PicpO1xuXG4gICAgJGl0ZW0uYXBwZW5kKCc8dGFibGUgY2xhc3M9XCJ3cmFwcGVyXCI+PHRyIHZhbGlnbj10b3A+JyArXG4gICAgICAnPHRkIGNsYXNzPVwiY2FsZW5kYXJzXCI+PC90ZD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJjb250cm9sXCI+PGRpdiBjbGFzcz1cIm9wdGlvbnNjb250YWluZXJcIj48L2Rpdj48L3RkPicgK1xuICAgICAgJzwvdHI+PC90YWJsZT4nKTtcblxuICAgICRjb250YWluZXIuYXBwZW5kKCRpdGVtKTtcbiAgICB2YXIgJG9wdGlvbnNjb250YWluZXIgPSAkY29udGFpbmVyLmZpbmQoJy5vcHRpb25zY29udGFpbmVyJyk7XG4gICAgJG9wdGlvbnNjb250YWluZXIuYXBwZW5kKCc8ZGl2IGNsYXNzPVwiY3VzdG9tZGF0ZVwiPkRhdGUgUmFuZ2U6JyArXG4gICAgICAnPHNlbGVjdCBjbGFzcz1cInNlbGVjdG9yXCI+PG9wdGlvbiB2YWx1ZT1cImN1c3RvbVwiPkN1c3RvbTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9XCJ0b2RheVwiPlRvZGF5PC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cInllc3RlcmRheVwiPlllc3RlcmRheTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9XCJsYXN0d2Vla1wiPkxhc3Qgd2Vlazwvb3B0aW9uPjxvcHRpb24gdmFsdWU9XCJsYXN0bW9udGhcIj5MYXN0IE1vbnRoPC9vcHRpb24+PC9zZWxlY3Q+JyArXG4gICAgICAnPC9kaXY+Jyk7XG4gICAgJG9wdGlvbnNjb250YWluZXIuYXBwZW5kKCc8aHIgY2xhc3M9XCJkaXZpZGVyXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiA1cHg7XCI+Jyk7XG5cbiAgICAkb3B0aW9uc2NvbnRhaW5lci5hcHBlbmQoJzxkaXYgY2xhc3M9XCJkYXRlcmFuZ2UgYmFzZXJhbmdlXCJcIj4nICtcbiAgICAgICc8aW5wdXQgY2xhc3M9XCJkYXRlb3B0aW9uIGFjdGl2ZVwiIHR5cGU9XCJ0ZXh0XCIgdmFsdWU9XCJKYW4gMSwgMjAxMlwiPicgK1xuICAgICAgJyAtICcgK1xuICAgICAgJzxpbnB1dCBjbGFzcz1cImRhdGVvcHRpb25cIiB0eXBlPVwidGV4dFwiIHZhbHVlPVwiSmFuIDEsIDIwMTJcIj4nICtcbiAgICAgICc8L2Rpdj4nKTtcblxuICAgICRvcHRpb25zY29udGFpbmVyLmFwcGVuZCgnPGRpdiBjbGFzcz1cImNvbXBhcmVvcHRpb24gdmlzaWJsZVwiXCI+JyArXG4gICAgICAnPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiY2hlY2tlclwiLz48c3BhbiBzdHlsZT1cInBhZGRpbmctbGVmdDo1cHg7XCI+Q29tcGFyZSB0byBwYXN0PC9zcGFuPicgK1xuICAgICAgJzwvZGl2PicpO1xuICAgIGlmIChzZWxmLm9wdGlvbnMuZGlzYWJsZUNvbXBhcmUpIHtcbiAgICAgICRvcHRpb25zY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uJykucmVtb3ZlQ2xhc3MoJ3Zpc2libGUnKTtcbiAgICB9XG4gICAgJG9wdGlvbnNjb250YWluZXIuYXBwZW5kKCc8ZGl2IGNsYXNzPVwiZGF0ZXJhbmdlIGNvbXBhcmVyYW5nZVwiXCI+JyArXG4gICAgICAnPGlucHV0IGNsYXNzPVwiZGF0ZW9wdGlvbiBhY3RpdmVcIiB0eXBlPVwidGV4dFwiIHZhbHVlPVwiSmFuIDEsIDIwMTJcIj4nICtcbiAgICAgICcgLSAnICtcbiAgICAgICc8aW5wdXQgY2xhc3M9XCJkYXRlb3B0aW9uXCIgdHlwZT1cInRleHRcIiB2YWx1ZT1cIkphbiAxLCAyMDEyXCI+JyArXG4gICAgICAnPC9kaXY+Jyk7XG5cbiAgICAkb3B0aW9uc2NvbnRhaW5lci5hcHBlbmQoJycgK1xuICAgICAgJzxociBjbGFzcz1cImRpdmlkZXJcIj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwiX2J1dHRvbnNcIj48YnV0dG9uIGNsYXNzPVwiYnRuIGFwcGx5XCIgdmFsdWU9XCJBcHBseVwiPkFwcGx5PC9idXR0b24+JyArXG4gICAgICAnPHNwYW4gY2xhc3M9XCJjYW5jZWxcIj5DYW5jZWw8L3NwYW4+PC9kaXY+Jyk7XG5cbiAgICB2YXIgJGNhbGVuZGFycyA9ICRjb250YWluZXIuZmluZCgnLmNhbGVuZGFycycpO1xuICAgIC8vJGl0ZW0gPSAkJCgnPGRpdiBjbGFzcz1cImRhdGVwaWNrZXJcIj48L2Rpdj4nKTtcblxuICAgICRpdGVtID0gJCQoJzx0YWJsZT48dHIgdmFsaWduPXRvcD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJkYXRldGFibGUtcHJldiB1bnNlbGVjdGFibGVcIj48L3RkPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImRhdGV0YWJsZVwiPjxkaXYgY2xhc3M9XCJkYXRlcGlja2VyIGRwMVwiPjwvZGl2PjwvdGQ+JyArXG4gICAgICAnPHRkIGNsYXNzPVwiZGF0ZXRhYmxlXCI+PGRpdiBjbGFzcz1cImRhdGVwaWNrZXIgZHAyXCI+PC9kaXY+PC90ZD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJkYXRldGFibGVcIj48ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlciBkcDNcIj48L2Rpdj48L3RkPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImRhdGV0YWJsZS1uZXh0IHVuc2VsZWN0YWJsZVwiPjwvdGQ+JyArXG4gICAgICAnPC90cj48L3RhYmxlPicpO1xuICAgICRjYWxlbmRhcnMuYXBwZW5kKCRpdGVtKTtcblxuICAgICRjb250YWluZXIuZmluZCgnLmRhdGV0YWJsZS1wcmV2JykuYXBwZW5kKCc8ZGl2IGNsYXNzPVwicHJldlwiPicgK1xuICAgICAgJzxkaXYgY2xhc3M9XCJpbmxpbmUtYmxvY2sgcHJldlwiPicgK1xuICAgICAgJzwvZGl2PicgK1xuICAgICAgJzwvZGl2PicpO1xuICAgICRjb250YWluZXIuZmluZCgnLmRhdGV0YWJsZS1wcmV2IC5wcmV2Jykub2ZmKCdjbGljaycpO1xuICAgICRjb250YWluZXIuZmluZCgnLmRhdGV0YWJsZS1wcmV2IC5wcmV2Jykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgIHZhciBjdXJyZW50TGVmdENlbGxEYXRlID0gJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpWzBdKS5kYXRlcGlja2VyKCdnZXREYXRlJyk7XG4gICAgICBpZiAoY3VycmVudExlZnRDZWxsRGF0ZS5zZXRNb250aChjdXJyZW50TGVmdENlbGxEYXRlLmdldE1vbnRoKCkpIDwgc2VsZi5taW5fZGF0ZSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICB2YXIgY3VycmVudFJpZ2h0Q2VsbERhdGUgPSAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJylbMl0pLmRhdGVwaWNrZXIoJ2dldERhdGUnKTtcbiAgICAgIGN1cnJlbnRSaWdodENlbGxEYXRlID0gbmV3IERhdGUoY3VycmVudFJpZ2h0Q2VsbERhdGUpO1xuICAgICAgY3VycmVudFJpZ2h0Q2VsbERhdGUuc2V0TW9udGgoY3VycmVudFJpZ2h0Q2VsbERhdGUuZ2V0TW9udGgoKSAtIDEpO1xuICAgICAgdmFyIHNlbGVjdGVkRGF0ZSA9IG5ldyBEYXRlKGN1cnJlbnRSaWdodENlbGxEYXRlKTtcblxuXG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcbiAgICAgICAgdmFyIGxvY2FsZGF0ZSA9IG5ldyBEYXRlKHNlbGVjdGVkRGF0ZSk7XG5cbiAgICAgICAgbG9jYWxkYXRlLnNldE1vbnRoKGxvY2FsZGF0ZS5nZXRNb250aCgpIC0gKDIgLSBpbmRleCkpO1xuICAgICAgICAkJChpdGVtKS5kYXRlcGlja2VyKCdzZXREYXRlJywgbG9jYWxkYXRlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLW5leHQnKS5hcHBlbmQoJzxkaXYgY2xhc3M9XCJuZXh0XCI+JyArXG4gICAgICAnPGRpdiBjbGFzcz1cImlubGluZS1ibG9jayBuZXh0XCI+JyArXG4gICAgICAnPC9kaXY+JyArXG4gICAgICAnPC9kaXY+Jyk7XG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLW5leHQgLm5leHQnKS5vZmYoJ2NsaWNrJyk7XG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLW5leHQgLm5leHQnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgdmFyIGN1cnJlbnRSaWdodENlbGxEYXRlID0gJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpWzJdKS5kYXRlcGlja2VyKCdnZXREYXRlJyk7XG4gICAgICBpZiAoY3VycmVudFJpZ2h0Q2VsbERhdGUuc2V0TW9udGgoY3VycmVudFJpZ2h0Q2VsbERhdGUuZ2V0TW9udGgoKSArIDEpID4gc2VsZi5tYXhfZGF0ZSlcbiAgICAgICAgcmV0dXJuO1xuXG4gICAgICBjdXJyZW50UmlnaHRDZWxsRGF0ZSA9IG5ldyBEYXRlKGN1cnJlbnRSaWdodENlbGxEYXRlKTtcblxuICAgICAgdmFyIHNlbGVjdGVkRGF0ZSA9IG5ldyBEYXRlKGN1cnJlbnRSaWdodENlbGxEYXRlKTtcblxuICAgICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG5cbiAgICAgICAgdmFyIGxvY2FsZGF0ZSA9IG5ldyBEYXRlKHNlbGVjdGVkRGF0ZSk7XG4gICAgICAgIGxvY2FsZGF0ZS5zZXRNb250aChsb2NhbGRhdGUuZ2V0TW9udGgoKSAtICgyIC0gaW5kZXgpKTtcbiAgICAgICAgJCQoaXRlbSkuZGF0ZXBpY2tlcignc2V0RGF0ZScsIGxvY2FsZGF0ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHZhciBjdXJyZW50Q2xpY2tJbmRleCA9IDA7XG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpLmRhdGVwaWNrZXIoe1xuICAgICAgZGF5TmFtZXNNaW46IFtcIlNcIiwgXCJNXCIsIFwiVFwiLCBcIldcIiwgXCJUXCIsIFwiRlwiLCBcIlNcIl0sXG4gICAgICBmaXJzdERheTogMCxcbiAgICAgIGJlZm9yZVNob3dEYXk6IGZ1bmN0aW9uIChkYXRlKSB7XG4gICAgICAgIHJldHVybiBzZWxmLmRyYXdDZWxsKGRhdGUpO1xuICAgICAgfSxcbiAgICAgIG9uU2VsZWN0OiBmdW5jdGlvbiAoZGF0ZVRleHQsIGluc3QpIHtcbiAgICAgICAgJG9wdGlvbnNjb250YWluZXIuZmluZCgnLnNlbGVjdG9yJykudmFsKCdjdXN0b20nKTtcbiAgICAgICAgc3dpdGNoIChzZWxmLmN1cnJlbnRNb2RlKSB7XG4gICAgICAgICAgY2FzZSAnYmFzZS1mcm9tJzpcblxuICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLXRvJztcbiAgICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKGRhdGVUZXh0KTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRIb3VycygwKTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuXG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG5cbiAgICAgICAgICAgIHZhciBfY2hlY2tMaW1pdCA9IG5ldyBEYXRlKHNlbGYubWluX2RhdGUpO1xuICAgICAgICAgICAgX2NoZWNrTGltaXQuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICAgICAgICBfY2hlY2tMaW1pdC5zZXREYXRlKF9jaGVja0xpbWl0LmdldERhdGUoKSArIDEpO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5iYXNlX2Zyb21kYXRlLmdldFRpbWUoKSA8PSBfY2hlY2tMaW1pdC5nZXRUaW1lKCkpIHtcbiAgICAgICAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5pcygnOmRpc2FibGVkJykpIHtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uIC5jaGVja2VyJykucmVtb3ZlQXR0cignZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcblxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYmFzZS10byc6XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICAgICBpZiAoc2VsZi5pc0NvbXBhcmVDaGVja2VkKSB7XG4gICAgICAgICAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS1mcm9tJztcblxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG5cbiAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLWZyb20nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnY29tcGFyZS1mcm9tJzpcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKGRhdGVUZXh0KTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZS5zZXRIb3VycygwKTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuXG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcblxuICAgICAgICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2NvbXBhcmUtdG8nO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnY29tcGFyZS10byc6XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2Jhc2UtZnJvbSc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5oYW5kbGVDaGFuZ2UoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuXG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpLmZpbmQoJ2FbaHJlZj1cIiNcIl0nKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xuICAgICAgJCQodGhpcykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcbiAgICAgIHZhciBzZWxlY3RlZERhdGUgPSBuZXcgRGF0ZShzZWxmLmJhc2VfdG9kYXRlLmdldEZ1bGxZZWFyKCksIHNlbGYuYmFzZV90b2RhdGUuZ2V0TW9udGgoKSwgMSk7XG4gICAgICBzZWxlY3RlZERhdGUuc2V0TW9udGgoc2VsZWN0ZWREYXRlLmdldE1vbnRoKCkgLSAoMiAtIGluZGV4KSk7XG4gICAgICAkJChpdGVtKS5kYXRlcGlja2VyKCdzZXREYXRlJywgc2VsZWN0ZWREYXRlKTtcbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkuZm9jdXMoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS1mcm9tJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmJsdXIoZnVuY3Rpb24gKGUpIHtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICAgJCQodGhpcykucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2Jhc2UtZnJvbSc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5rZXl1cChmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA9PSAnSW52YWxpZCBEYXRlJyB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPiBzZWxmLmJhc2VfdG9kYXRlIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYubWF4X2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICAkJCh0aGlzKS5hZGRDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkuZm9jdXMoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS10byc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5ibHVyKGZ1bmN0aW9uIChlKSB7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS10byc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkua2V5dXAoZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmIChuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPT0gJ0ludmFsaWQgRGF0ZScgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpIDwgc2VsZi5iYXNlX2Zyb21kYXRlIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYubWF4X2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICAkJCh0aGlzKS5hZGRDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSk7XG4gICAgICB9XG5cbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkuZm9jdXMoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS1mcm9tJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmJsdXIoZnVuY3Rpb24gKGUpIHtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAgJCQodGhpcykucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2NvbXBhcmUtZnJvbSc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5rZXl1cChmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA9PSAnSW52YWxpZCBEYXRlJyB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPiBzZWxmLmNvbXBhcmVfdG9kYXRlIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYubWF4X2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICAkJCh0aGlzKS5hZGRDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkuZm9jdXMoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS10byc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5ibHVyKGZ1bmN0aW9uIChlKSB7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG4gICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS10byc7XG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5rZXl1cChmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA9PSAnSW52YWxpZCBEYXRlJyB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPCBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpID4gc2VsZi5iYXNlX3RvZGF0ZSB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPiBzZWxmLm1heF9kYXRlIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgJCQodGhpcykuYWRkQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykuYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgJCQodGhpcykucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xuICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gbmV3IERhdGUoJCQodGhpcykudmFsKCkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgICRvcHRpb25zY29udGFpbmVyLmZpbmQoJy5jYW5jZWwnKS5jbGljayhmdW5jdGlvbiAoZSkge1xuXG4gICAgICBzZWxmLmJhc2VfZnJvbWRhdGUgPSBzZWxmLm9yaWdpbmFsX2Jhc2VfZnJvbWRhdGU7XG4gICAgICBzZWxmLmJhc2VfdG9kYXRlID0gc2VsZi5vcmlnaW5hbF9iYXNlX3RvZGF0ZTtcblxuICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5vcmlnaW5hbF9jb21wYXJlX2Zyb21kYXRlO1xuICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZSA9IHNlbGYub3JpZ2luYWxfY29tcGFyZV90b2RhdGU7XG5cbiAgICAgIGlmICghc2VsZi5jb21wYXJlUGVyaW9kKSB7XG4gICAgICAgIGlmICgkY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uIC5jaGVja2VyJykuaXMoXCI6Y2hlY2tlZFwiKSkge1xuICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5jbGljaygpO1xuICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5wcm9wKCdjaGVja2VkJywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKCEkY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uIC5jaGVja2VyJykuaXMoXCI6Y2hlY2tlZFwiKSkge1xuICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5jbGljaygpO1xuICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5wcm9wKCdjaGVja2VkJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX3RvZGF0ZSkpO1xuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG5cbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG5cbiAgICAgICRkYXRlYm94Y29udGFpbmVyLmNsaWNrKCk7XG4gICAgfSk7XG4gICAgJG9wdGlvbnNjb250YWluZXIuZmluZCgnLnNlbGVjdG9yJykuY2hhbmdlKGZ1bmN0aW9uIChlKSB7XG4gICAgICBzd2l0Y2ggKHRoaXMudmFsdWUpIHtcbiAgICAgICAgY2FzZSAndG9kYXknOlxuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0SG91cnMoMjMpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbGxpc2Vjb25kcyg5OTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKHNlbGYuYmFzZV90b2RhdGUpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRIb3VycygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWludXRlcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd5ZXN0ZXJkYXknOlxuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0RGF0ZShzZWxmLmJhc2VfdG9kYXRlLmdldERhdGUoKSAtIDEpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0SG91cnMoMjMpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbGxpc2Vjb25kcyg5OTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKHNlbGYuYmFzZV90b2RhdGUpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRIb3VycygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWludXRlcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsYXN0d2Vlayc6XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoc2VsZi5iYXNlX3RvZGF0ZSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlLmdldERhdGUoKSAtIDYpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRIb3VycygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWludXRlcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsYXN0bW9udGgnOlxuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0SG91cnMoMjMpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbGxpc2Vjb25kcyg5OTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IG5ldyBEYXRlKHNlbGYuYmFzZV90b2RhdGUpO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZS5nZXREYXRlKCkgLSAzMCk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB2YXIgcmFuZ2VsZW5ndGggPSBEYXRlLmRhdGVEaWZmKCdkJywgc2VsZi5iYXNlX2Zyb21kYXRlLCBzZWxmLmJhc2VfdG9kYXRlKTtcbiAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5iYXNlX2Zyb21kYXRlLCAtMSk7XG4gICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5jb21wYXJlX3RvZGF0ZSwgKC0xICogcmFuZ2VsZW5ndGgpKTtcblxuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSk7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcblxuICAgICAgc2VsZi5oYW5kbGVDaGFuZ2UoKTtcbiAgICB9KTtcbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuXG4gICAgdmFyICRkYXRlYm94Y29udGFpbmVyID0gJGNvbnRhaW5lci5maW5kKCcuamNvbnRhaW5lcicpO1xuICAgICRkYXRlYm94Y29udGFpbmVyLm9mZignY2xpY2snKTtcbiAgICB2YXIgJHBpY2tlciA9ICRjb250YWluZXIuZmluZCgnLnBpY2tlcicpO1xuICAgICRkYXRlYm94Y29udGFpbmVyLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAoJCQodGhpcykuaGFzQ2xhc3MoJ2V4cGFuZGVkJykpIHtcbiAgICAgICAgJCQodGhpcykucmVtb3ZlQ2xhc3MoJ2V4cGFuZGVkJyk7XG4gICAgICAgICRwaWNrZXIuaGlkZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICQkKHRoaXMpLmFkZENsYXNzKCdleHBhbmRlZCcpO1xuXG4gICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IHNlbGYuYXBwbGllZF9iYXNlX2Zyb21kYXRlO1xuICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gc2VsZi5hcHBsaWVkX2Jhc2VfdG9kYXRlO1xuICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFwcGxpZWRfY29tcGFyZV9mcm9tZGF0ZTtcbiAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZSA9IHNlbGYuYXBwbGllZF9jb21wYXJlX3RvZGF0ZTtcblxuICAgICAgICBzZWxmLm9yaWdpbmFsX2Jhc2VfZnJvbWRhdGUgPSBzZWxmLmFwcGxpZWRfYmFzZV9mcm9tZGF0ZTtcbiAgICAgICAgc2VsZi5vcmlnaW5hbF9iYXNlX3RvZGF0ZSA9IHNlbGYuYXBwbGllZF9iYXNlX3RvZGF0ZTtcbiAgICAgICAgc2VsZi5vcmlnaW5hbF9jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5hcHBsaWVkX2NvbXBhcmVfZnJvbWRhdGU7XG4gICAgICAgIHNlbGYub3JpZ2luYWxfY29tcGFyZV90b2RhdGUgPSBzZWxmLmFwcGxpZWRfY29tcGFyZV90b2RhdGU7XG5cbiAgICAgICAgJHBpY2tlci5zaG93KCk7XG4gICAgICAgICRwaWNrZXIub2Zmc2V0KHtcbiAgICAgICAgICB0b3A6ICRjb250YWluZXIub2Zmc2V0KCkudG9wICsgJGNvbnRhaW5lci5oZWlnaHQoKSAtIDEsXG4gICAgICAgICAgbGVmdDogJGRhdGVib3hjb250YWluZXIub2Zmc2V0KCkubGVmdCAtICRwaWNrZXIub3V0ZXJXaWR0aCgpICsgJGRhdGVib3hjb250YWluZXIub3V0ZXJXaWR0aCgpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgICR0YWJsZS5jbGljayhmdW5jdGlvbiAoZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgICRwaWNrZXIuY2xpY2soZnVuY3Rpb24gKGUpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG5cbiAgICAkJCgnYm9keScpLmNsaWNrKGZ1bmN0aW9uIChlKSB7XG4gICAgICAkZGF0ZWJveGNvbnRhaW5lci5yZW1vdmVDbGFzcygnZXhwYW5kZWQnKTtcbiAgICAgICRwaWNrZXIuaGlkZSgpO1xuICAgIH0pO1xuXG4gICAgJG9wdGlvbnNjb250YWluZXIuZmluZCgnLmFwcGx5JykuY2xpY2soZnVuY3Rpb24gKGUpIHtcbiAgICAgICRkYXRlYm94Y29udGFpbmVyLnJlbW92ZUNsYXNzKCdleHBhbmRlZCcpO1xuICAgICAgJHBpY2tlci5oaWRlKCk7XG4gICAgICBzZWxmLmNvbXBhcmVQZXJpb2QgPSBzZWxmLmlzQ29tcGFyZUNoZWNrZWQ7XG5cbiAgICAgIC8vaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpXG4gICAgICAvLyAgc2VsZi5vcHRpb25zLmNhbnZhcy5lbWl0KCdkYXRlY2hhbmdlJywgc2VsZik7XG5cblxuICAgICAgc2VsZi5EYXRlVXBkYXRlKCk7XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5jb21wYXJlUGVyaW9kKVxuICAgICAgdGhpcy5pc0NvbXBhcmVDaGVja2VkID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLmRpc2FibGVDb21wYXJlKVxuICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJyk7XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLm9uQWZ0ZXJEcmF3KVxuICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vbkFmdGVyRHJhd10oc2VsZi5vcHRpb25zLmNvbnRhaW5lciwgc2VsZik7XG5cbiAgICAvL3RoaXMucmVnaXN0ZXJEYXRlVXBkYXRlKHRoaXMudXBkYXRlTGFiZWxzKTtcbiAgICB0aGlzLmhhbmRsZUNoYW5nZSgpO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIH07XG5cbiAgdGhpcy5EYXRlVXBkYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgdmFyIG9wdGlvbnMgPSB7fTtcblxuICAgIHRoaXMuYmFzZV90b2RhdGUuc2V0SG91cnMoMjMpO1xuICAgIHRoaXMuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgdGhpcy5iYXNlX3RvZGF0ZS5zZXRTZWNvbmRzKDU5KTtcbiAgICB0aGlzLmJhc2VfdG9kYXRlLnNldE1pbGxpc2Vjb25kcyg5OTkpO1xuXG4gICAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICB0aGlzLmNvbXBhcmVfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgIHRoaXMuY29tcGFyZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG5cbiAgICBfdGhpcy5hcHBsaWVkX2Jhc2VfZnJvbWRhdGUgPSB0aGlzLmJhc2VfZnJvbWRhdGU7XG4gICAgX3RoaXMuYXBwbGllZF9iYXNlX3RvZGF0ZSA9IHRoaXMuYmFzZV90b2RhdGU7XG4gICAgX3RoaXMuYXBwbGllZF9jb21wYXJlX2Zyb21kYXRlID0gdGhpcy5jb21wYXJlX2Zyb21kYXRlO1xuICAgIF90aGlzLmFwcGxpZWRfY29tcGFyZV90b2RhdGUgPSB0aGlzLmNvbXBhcmVfdG9kYXRlO1xuICAgIG9wdGlvbnMgPSB7XG4gICAgICBiYXNlX2Zyb21kYXRlOiB0aGlzLmFwcGxpZWRfYmFzZV9mcm9tZGF0ZSxcbiAgICAgIGJhc2VfdG9kYXRlOiB0aGlzLmFwcGxpZWRfYmFzZV90b2RhdGUsXG4gICAgICBjb21wYXJlX2Zyb21kYXRlOiB0aGlzLmFwcGxpZWRfY29tcGFyZV9mcm9tZGF0ZSxcbiAgICAgIGNvbXBhcmVfdG9kYXRlOiB0aGlzLmFwcGxpZWRfY29tcGFyZV90b2RhdGUsXG4gICAgICBjb21wYXJlOiB0aGlzLmNvbXBhcmVQZXJpb2RcbiAgICB9O1xuXG4gICAgaWYgKHNlbGYuY29tcGFyZVBlcmlvZCkge1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVzIC5jb21wYXJlJykuc2hvdygpO1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuYWRkQ2xhc3MoJ2NvbXBhcmUnKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5yZW1vdmVDbGFzcygnY29tcGFyZScpO1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVzIC5jb21wYXJlJykuaGlkZSgpO1xuICAgIH1cblxuICAgIHZhciAkZnJvbWRhdGUgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXMgLmRhdGVsYWJlbC5mcm9tZGF0ZScpWzBdKTtcbiAgICB2YXIgdG9kYXRlID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVzIC5kYXRlbGFiZWwudG9kYXRlJylbMF0pO1xuXG4gICAgJGZyb21kYXRlLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3RoaXMuYXBwbGllZF9iYXNlX2Zyb21kYXRlKSk7XG4gICAgdG9kYXRlLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3RoaXMuYXBwbGllZF9iYXNlX3RvZGF0ZSkpO1xuXG4gICAgJCQodGhpcy5jYWxsYmFja3MpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICBfdGhpcy5jYWxsYmFja3NbaW5kZXhdLmNhbGxiYWNrKF90aGlzLCBvcHRpb25zKTtcbiAgICB9KTtcbiAgICAvL190aGlzLnNldFN0YXRlKF90aGlzKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5lbWl0KCdkYXRlY2hhbmdlJywgb3B0aW9ucyk7XG4gICAgfVxuICAgICQkKHNlbGYpLnRyaWdnZXIoXCJkYXRlY2hhbmdlXCIsIG9wdGlvbnMpO1xuICAgIC8vJCQoam9vbGEpLnRyaWdnZXIoXCJkYXRlY2hhbmdlXCIsIG9wdGlvbnMpO1xuXG4gICAgaWYgKHNlbGYub3B0aW9ucy5vblVwZGF0ZSlcbiAgICAgIHdpbmRvd1tzZWxmLm9wdGlvbnMub25VcGRhdGVdKHNlbGYuY29udGFpbmVyLCBzZWxmKTtcbiAgfTtcblxuICB0aGlzLmRyYXdDZWxsID0gZnVuY3Rpb24gKGRhdGUpIHtcbiAgICBpZiAoZGF0ZSA+PSB0aGlzLm1heF9kYXRlKVxuICAgICAgcmV0dXJuIFtmYWxzZSwgJ2RheWNlbGwgZGlzYWJsZWQnXTtcblxuICAgIGlmIChkYXRlIDw9IHRoaXMubWluX2RhdGUpXG4gICAgICByZXR1cm4gW2ZhbHNlLCAnZGF5Y2VsbCBkaXNhYmxlZCddO1xuXG4gICAgaWYgKHRoaXMuY3VycmVudE1vZGUgPT0gJ2Jhc2UtdG8nKSB7XG4gICAgICBpZiAoZGF0ZSA8IHRoaXMuYmFzZV9mcm9tZGF0ZSlcbiAgICAgICAgcmV0dXJuIFtmYWxzZSwgJ2RheWNlbGwgZGlzYWJsZWQnXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jdXJyZW50TW9kZSA9PSAnY29tcGFyZS10bycpIHtcbiAgICAgIGlmIChkYXRlIDwgdGhpcy5jb21wYXJlX2Zyb21kYXRlKVxuICAgICAgICByZXR1cm4gW2ZhbHNlLCAnZGF5Y2VsbCBjb21wYXJlIGRpc2FibGVkJ107XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNDb21wYXJlQ2hlY2tlZCkge1xuICAgICAgaWYgKGRhdGUgPT0gdGhpcy5jb21wYXJlX2Zyb21kYXRlKVxuICAgICAgICByZXR1cm4gW3RydWUsICdkYXljZWxsIGNvbXBhcmUgaW5yYW5nZSBzZWxlY3RlZCBmcm9tZGF0ZSddO1xuICAgICAgaWYgKGRhdGUgPT0gdGhpcy5jb21wYXJlX3RvZGF0ZSlcbiAgICAgICAgcmV0dXJuIFt0cnVlLCAnZGF5Y2VsbCBjb21wYXJlIGlucmFuZ2Ugc2VsZWN0ZWQgdG9kYXRlJ107XG4gICAgICBpZiAoKGRhdGUgPj0gdGhpcy5iYXNlX2Zyb21kYXRlICYmIGRhdGUgPD0gdGhpcy5iYXNlX3RvZGF0ZSkgJiYgKGRhdGUgPj0gdGhpcy5jb21wYXJlX2Zyb21kYXRlICYmIGRhdGUgPD0gdGhpcy5jb21wYXJlX3RvZGF0ZSkpXG4gICAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgYmFzZW5jb21wYXJlIGlucmFuZ2UnXTtcbiAgICAgIGlmIChkYXRlID49IHRoaXMuY29tcGFyZV9mcm9tZGF0ZSAmJiBkYXRlIDw9IHRoaXMuY29tcGFyZV90b2RhdGUpXG4gICAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgY29tcGFyZSBpbnJhbmdlJ107XG4gICAgICBpZiAoZGF0ZSA+IHRoaXMuYmFzZV90b2RhdGUgJiYgdGhpcy5jdXJyZW50TW9kZSAhPSAnYmFzZS10bycpIHtcbiAgICAgICAgcmV0dXJuIFtmYWxzZSwgJ2RheWNlbGwgY29tcGFyZSBkaXNhYmxlZCddO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChkYXRlID09IHRoaXMuYmFzZV9mcm9tZGF0ZSlcbiAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgaW5yYW5nZSBzZWxlY3RlZCBmcm9tZGF0ZSddO1xuICAgIGlmIChkYXRlID09IHRoaXMuYmFzZV90b2RhdGUpXG4gICAgICByZXR1cm4gW3RydWUsICdkYXljZWxsIGlucmFuZ2Ugc2VsZWN0ZWQgdG9kYXRlJ107XG4gICAgaWYgKGRhdGUgPj0gdGhpcy5iYXNlX2Zyb21kYXRlICYmIGRhdGUgPD0gdGhpcy5iYXNlX3RvZGF0ZSlcbiAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgaW5yYW5nZSddO1xuXG5cbiAgICBzd2l0Y2ggKHRoaXMuY3VycmVudE1vZGUpIHtcbiAgICAgIGNhc2UgJ2Jhc2UtZnJvbSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYmFzZS10byc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY29tcGFyZS1mcm9tJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjb21wYXJlLXRvJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gW3RydWUsICdkYXljZWxsJ107XG4gIH07XG5cbiAgdGhpcy5oYW5kbGVDaGFuZ2UgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciAkZGF0ZWJveCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyOy8vLmZpbmQoJ1tqaW8tdHlwZT1cImRhdGVwaWNrZXJcIl0nKTtcbiAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXBpY2tlcicpLm5vdCh0aGlzKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICQkKHRoaXMpLmRhdGVwaWNrZXIoJ3JlZnJlc2gnKTtcbiAgICB9KTtcblxuICAgIC8qXG4gICAgICQkKCQkKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgJCQoJCQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChmb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAgJCQoJCQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChmb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAkJCgkJCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuICAgICAqL1xuXG4gICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cbiAgICBzd2l0Y2ggKHRoaXMuY3VycmVudE1vZGUpIHtcbiAgICAgIGNhc2UgJ2Jhc2UtZnJvbSc6XG4gICAgICAgIGlmIChzZWxmLmJhc2VfZnJvbWRhdGUgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gc2VsZi5taW5fZGF0ZTtcbiAgICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGYuYmFzZV9mcm9tZGF0ZSA+IHNlbGYubWF4X2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUgPSBzZWxmLm1heF9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdiYXNlLXRvJzpcbiAgICAgICAgaWYgKHNlbGYuYmFzZV90b2RhdGUgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IHNlbGYubWluX2RhdGU7XG4gICAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZi5iYXNlX3RvZGF0ZSA+IHNlbGYubWF4X2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gc2VsZi5tYXhfZGF0ZTtcbiAgICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX3RvZGF0ZSkpO1xuICAgICAgICB9XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NvbXBhcmUtZnJvbSc6XG4gICAgICAgIGlmIChzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5taW5fZGF0ZTtcbiAgICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA+IHNlbGYubWF4X2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLm1heF9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NvbXBhcmUtdG8nOlxuICAgICAgICBpZiAoc2VsZi5jb21wYXJlX3RvZGF0ZSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gc2VsZi5taW5fZGF0ZTtcbiAgICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxmLmNvbXBhcmVfdG9kYXRlID4gc2VsZi5tYXhfZGF0ZSkge1xuICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBzZWxmLm1heF9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG4gICAgICAgIH1cblxuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA+IHNlbGYuYmFzZV90b2RhdGUgfHwgc2VsZi5jb21wYXJlX3RvZGF0ZSA+IHNlbGYuYmFzZV90b2RhdGUpICYmIHRoaXMuaXNDb21wYXJlQ2hlY2tlZCkge1xuICAgICAgdmFyIHJhbmdlbGVuZ3RoID0gRGF0ZS5kYXRlRGlmZignZCcsIHNlbGYuYmFzZV9mcm9tZGF0ZSwgc2VsZi5iYXNlX3RvZGF0ZSk7XG4gICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gc2VsZi5hZGREYXlzKHNlbGYuYmFzZV9mcm9tZGF0ZSwgLTEpO1xuICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5hZGREYXlzKHNlbGYuY29tcGFyZV90b2RhdGUsICgtMSAqIHJhbmdlbGVuZ3RoKSk7XG4gICAgICBpZiAoc2VsZi5jb21wYXJlX2Zyb21kYXRlIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLm1pbl9kYXRlO1xuICAgICAgfVxuICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcblxuXG4gICAgICBpZiAodGhpcy5jdXJyZW50TW9kZSA9PSAnY29tcGFyZS10bycpXG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLmZvY3VzKCk7XG4gICAgICBlbHNlIGlmICh0aGlzLmN1cnJlbnRNb2RlID09ICdjb21wYXJlLWZyb20nKVxuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5mb2N1cygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzQ29tcGFyZUNoZWNrZWQpIHtcbiAgICAgICRkYXRlYm94LmZpbmQoJy5vcHRpb25zY29udGFpbmVyIC5jaGVja2VyJykucHJvcChcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAkZGF0ZWJveC5maW5kKCcub3B0aW9uc2NvbnRhaW5lciAuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZScpLnNob3coKTtcblxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICRkYXRlYm94LmZpbmQoJy5vcHRpb25zY29udGFpbmVyIC5jaGVja2VyJykucHJvcChcImNoZWNrZWRcIiwgZmFsc2UpO1xuICAgICAgJGRhdGVib3guZmluZCgnLm9wdGlvbnNjb250YWluZXIgLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UnKS5oaWRlKCk7XG4gICAgfVxuXG4gICAgJGRhdGVib3guZmluZCgnLm9wdGlvbnNjb250YWluZXIgLmNoZWNrZXInKS5vZmYoJ2NsaWNrJyk7XG4gICAgJGRhdGVib3guZmluZCgnLm9wdGlvbnNjb250YWluZXIgLmNoZWNrZXInKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIHNlbGYuaXNDb21wYXJlQ2hlY2tlZCA9ICFzZWxmLmlzQ29tcGFyZUNoZWNrZWQ7XG4gICAgICBpZiAoc2VsZi5pc0NvbXBhcmVDaGVja2VkKVxuICAgICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2NvbXBhcmUtZnJvbSc7XG4gICAgICBlbHNlXG4gICAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS1mcm9tJztcblxuICAgICAgdmFyIHJhbmdlbGVuZ3RoID0gRGF0ZS5kYXRlRGlmZignZCcsIHNlbGYuYmFzZV9mcm9tZGF0ZSwgc2VsZi5iYXNlX3RvZGF0ZSk7XG5cbiAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5iYXNlX2Zyb21kYXRlLCAtMSk7XG4gICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5jb21wYXJlX3RvZGF0ZSwgKC0xICogcmFuZ2VsZW5ndGgpKTtcbiAgICAgIGlmIChzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYubWluX2RhdGU7XG4gICAgICB9XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuXG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuXG4gICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuZW1pdCgnZGF0ZWNoYW5naW5nJywgc2VsZik7XG4gICAgfVxuICAgICQkKHNlbGYpLnRyaWdnZXIoJ2RhdGVjaGFuZ2luZycsIHNlbGYpO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICAvKnRyeSB7XG4gICAgam9vbGEuY29tbW9uLl9leHRlbmQoc2VsZi5vcHRpb25zLCBvcHRpb25zLCB0cnVlKTtcbiAgICBjb25zb2xlLmxvZyhzZWxmLm9wdGlvbnMpO1xuICAgIHNlbGYudmVyaWZ5KHNlbGYub3B0aW9ucywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKGVycilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgICBzZWxmLm1hcmtDb250YWluZXIoc2VsZi5vcHRpb25zLiRjb250YWluZXIsIFtcbiAgICAgICAgeyd0eXBlJzogJ2RhdGVwaWNrZXInfSxcbiAgICAgICAgeyd1dWlkJzogc2VsZi51dWlkfSxcbiAgICAgICAge2Nzczogc2VsZi5vcHRpb25zLmNzc31cbiAgICAgIF0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgaWYgKGVycilcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICAgICAgdmFyIGVsZW0gPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5wYXJlbnQoKTtcbiAgICAgICAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJCQoZWxlbSkuQ2FudmFzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuZHJhdyhvcHRpb25zLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2RhdGVwaWNrZXIuaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGNhdGNoIChlcnIpIHtcbiAgICBjYWxsYmFjayhlcnIpO1xuICAgIHJldHVybiBzZWxmLm9uRXJyb3IoZXJyLCBjYWxsYmFjayk7XG4gIH1cblxuICAvL2NhbGxiYWNrKG51bGwsIHNlbGYpO1xuICByZXR1cm4gc2VsZjsqL1xuLy93ZSBjYWxsIHRoZSBjb3JlIGluaXRpYWxpemUgb3B0aW9uXG4gIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIG9wdGlvbnMgfHwge30pO1xuICBzZWxmLmRyYXcoc2VsZi5vcHRpb25zLGZ1bmN0aW9uKCl7fSk7XG5cbiAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHZhciBlbGVtID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIpLnBhcmVudCgpO1xuICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gIH1cblxuLy93cmFwIHVwXG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPT0gJ3VuZGVmaW5lZCcgfHwgdHlwZW9mICgkKSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLkRhdGVQaWNrZXIgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgb3B0aW9ucyA9IHtmb3JjZTogZmFsc2V9O1xuICAgICAgZWxzZSBpZiAoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2ZvcmNlJykpXG4gICAgICAgIG9wdGlvbnMuZm9yY2UgPSB0cnVlO1xuICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5EYXRlUGlja2VyKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIC8vYmFydGFibGUuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoRGF0ZVBpY2tlciwgZXZlbnRzLkV2ZW50RW1pdHRlcik7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxuXG52YXJcbiAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKSxcbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuICAkJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xuXG52YXIgRGltZW5zaW9uUGlja2VyID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCFjYWxsYmFjaylcbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB9O1xuICBqb29sYS5ldmVudHMuZW1pdCgnZGltZW5zaW9ucGlja2VyLmluaXQuc3RhcnQnKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMudHlwZSA9ICdkaW1lbnNpb25waWNrZXInO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgY2FudmFzOiBudWxsLFxuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAkY29udGFpbmVyOiBudWxsLFxuICAgIGRpbWVuc2lvbnM6IFtdLFxuICAgIGRpc2FibGVkOiBbXSxcbiAgICBzZWxlY3RlZDogbnVsbCxcbiAgICBhbGxvd1JlbW92ZTogdHJ1ZSxcbiAgICBhbGxvd1NlbGVjdDogdHJ1ZSxcbiAgICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJqaW8tZGltZW5zaW9ucGlja2VyLXdyYXBwZXJcIj5cXG4nICtcbiAgICAgICcgIDxidXR0b24gY2xhc3M9XCJidG4gamlvLWRpbWVuc2lvbnBpY2tlci1idXR0b25cIj4nICtcbiAgICAgICcgICA8c3BhbiBjbGFzcz1cImNhcHRpb25cIj48L3NwYW4+JyArXG4gICAgICAnICAgPHNwYW4gY2xhc3M9XCJjbG9zZVwiPsOXPC9zcGFuPicgK1xuICAgICAgJyAgPC9idXR0b24+JyArXG4gICAgICAnICA8ZGl2IGNsYXNzPVwicGlja2VyLWNvbnRhaW5lclwiPicgK1xuICAgICAgJyAgICA8ZGl2IGNsYXNzPVwic2VhcmNoIGlucHV0LXByZXBlbmRcIj48aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInF1aWNrc2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIj48c3BhbiBjbGFzcz1cImFkZC1vblwiPjxpIGNsYXNzPVwic2VhcmNoaWNvbiBpY29uLXNlYXJjaFwiPjwvaT48L3NwYW4+PC9kaXY+JyArXG4gICAgICAnICAgIDxkaXYgY2xhc3M9XCJjbGVhclwiPjwvZGl2PicgK1xuICAgICAgJyAgPC9kaXY+JyArXG4gICAgICAnICA8ZGl2IGNsYXNzPVwiY2xlYXJcIj48L2Rpdj4nICtcbiAgICAgICc8L2Rpdj4nXG4gIH07XG4gIHRoaXMuZHJhd24gPSBmYWxzZTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICBpZiAoIXNlbGYuZHJhd24pIHtcbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hcHBlbmQoc2VsZi5vcHRpb25zLnRlbXBsYXRlIHx8IHNlbGYudGVtcGxhdGUoKSk7XG4gICAgICB2YXIgJHVsID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnBpY2tlci1jb250YWluZXInKSk7XG4gICAgICB2YXIgJGJ0biA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5qaW8tZGltZW5zaW9ucGlja2VyLWJ1dHRvbicpKTtcbiAgICAgIHZhciAkY2xvc2UgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2xvc2UnKSk7XG4gICAgICBpZiAoIXNlbGYub3B0aW9ucy5hbGxvd1JlbW92ZSlcbiAgICAgICAgJGNsb3NlLnJlbW92ZSgpO1xuICAgICAgdmFyICRzZWFyY2ggPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcucXVpY2tzZWFyY2gnKSk7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmNhcHRpb24pXG4gICAgICAgICRidG4uZmluZCgnLmNhcHRpb24nKS50ZXh0KHNlbGYub3B0aW9ucy5jYXB0aW9uKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGltZW5zaW9ucy5sZW5ndGggPT09IDApXG4gICAgICAgIGpvb2xhLmRpbWVuc2lvbnMubGlzdChmdW5jdGlvbiAoZXJyLCBsaXN0KSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcblxuICAgICAgICAgIHZhciBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgIHZhciBtU2tpcE9uZSA9IGZhbHNlO1xuICAgICAgICAgIHZhciBtbGFzdHRhcmdldCA9IG51bGw7XG5cbiAgICAgICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgICAgIGxpc3QgPSBsaXN0LmZpbHRlcihmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgaWYgKGtleXMuaW5kZXhPZihpdGVtLmtleSkgPT09IC0xKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVtLmtleSAhPT0gJ3RpbWVzdGFtcCcpIHtcbiAgICAgICAgICAgICAgICBrZXlzLnB1c2goaXRlbS5rZXkpO1xuICAgICAgICAgICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBsaXN0LmZvckVhY2goZnVuY3Rpb24gKGRpbWVuc2lvbikge1xuICAgICAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSB7a2V5OiBkaW1lbnNpb24uY29sbGVjdGlvbn07XG4gICAgICAgICAgICB2YXIgJGxpID0gJCQoJzxkaXYgY2xhc3M9XCJkaW1lbnNpb25PcHRpb25cIiBkYXRhLW1lbWJlcj1cIicgKyBkaW1lbnNpb24ua2V5ICsgJ1wiPicgKyBkaW1lbnNpb24ubmFtZSArICc8L2Rpdj4nKTtcbiAgICAgICAgICAgICRsaS5vZmYoJ2NsaWNrJyk7XG4gICAgICAgICAgICAkbGkub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgICAgaWYgKCR0aGlzLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIGlmICgkdGhpcy5oYXNDbGFzcygnZGlzYWJsZWQnKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnNlbGVjdGVkID0gZGltZW5zaW9uO1xuICAgICAgICAgICAgICAvL3ZhciAkY29udGVudCA9ICc8c3BhbiBjbGFzcz1cIm5hbWVcIj4nICsgZGltZW5zaW9uLm5hbWUgKyAnPC9zcGFuPic7XG4gICAgICAgICAgICAgIC8vJGJ0bi5maW5kKCcuY2FwdGlvbicpLmh0bWwoKHNlbGYub3B0aW9ucy5wcmVmaXggfHwgJycgKSArICRjb250ZW50KTtcbiAgICAgICAgICAgICAgJGJ0bi5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICAgICAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuXG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnY2hhbmdlJywgZGltZW5zaW9uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJHVsLmFwcGVuZCgkbGkpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJGNsb3NlLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQgPSBudWxsO1xuICAgICAgICAgICAgc2VsZi5tYXJrU2VsZWN0ZWQoKTtcbiAgICAgICAgICAgIHNlbGYuZW1pdCgnY2hhbmdlJywgbnVsbCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkc2VhcmNoLmtleXVwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQkKHRoaXMpO1xuICAgICAgICAgICAgdmFyIHZhbCA9ICR0aGlzLnZhbCgpO1xuICAgICAgICAgICAgaWYgKHZhbC5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyXScpLmhpZGUoKTtcbiAgICAgICAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcio9XCInICsgdmFsICsgJ1wiXScpLnNob3coKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcl0nKS5zaG93KCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgIGlmIChtT3BlbiAmJiBtbGFzdHRhcmdldCA9PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgICAgICAgbU9wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG1Ta2lwT25lKSB7XG4gICAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgICAgICAgbU9wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgbVNraXBPbmUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAkdWwuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBtbGFzdHRhcmdldCA9IHRoaXMuaWQ7XG4gICAgICAgICAgICAgIG1PcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSAkYnRuLnBvc2l0aW9uKCk7XG4gICAgICAgICAgICAkdWwuY3NzKCd0b3AnLCBvZmZzZXQudG9wICsgJGJ0bi5vdXRlckhlaWdodCgpIC0gMSk7XG4gICAgICAgICAgICAkdWwuY3NzKCdsZWZ0Jywgb2Zmc2V0LmxlZnQpO1xuICAgICAgICAgICAgJHVsLmZpbmQoJ3VsLmFjdGl2ZScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICAgICAgJHVsLmF0dHIoJ2RhdGEtdGFyZ2V0JywgdGhpcy5pZCk7XG5cbiAgICAgICAgICAgIC8vc2V0IHNlbGVjdGVkXG4gICAgICAgICAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJHVsLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgICQkKCdib2R5Jykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJGJ0bi5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAkdWwucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgbU9wZW4gPSBmYWxzZTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRidG4ub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICAkdGhpcy50b2dnbGVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgICB9KTtcbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG5cbiAgICB9XG5cbiAgICBzZWxmLm1hcmtTZWxlY3RlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICR1bC5maW5kKCdkaXYnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0JiZzZWxmLm9wdGlvbnMuc2VsZWN0ZWQpIHtcbiAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcj1cIicgKyBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQua2V5ICsgJ1wiXScpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1kaW1lbnNpb25waWNrZXItYnV0dG9uJykuZmluZCgnLmNhcHRpb24nKS5odG1sKChzZWxmLm9wdGlvbnMucHJlZml4IHx8ICcnICkgKyAnPHNwYW4gY2xhc3M9XCJuYW1lXCI+JyArIChzZWxmLm9wdGlvbnMuc2VsZWN0ZWQubmFtZSB8fCBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQua2V5IHx8IHNlbGYub3B0aW9ucy5zZWxlY3RlZCkgKyAnPC9zcGFuPicpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2xvc2UnKS5zaG93KCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1kaW1lbnNpb25waWNrZXItYnV0dG9uJykuZmluZCgnLmNhcHRpb24nKS5odG1sKCdDaG9vc2UgYSBkaW1lbnNpb24uLi4nICsgJycpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2xvc2UnKS5oaWRlKCk7XG4gICAgICB9XG5cbiAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXJdJykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmRpc2FibGVkKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMuZGlzYWJsZWQpKVxuICAgICAgICAgIHNlbGYub3B0aW9ucy5kaXNhYmxlZCA9IFtzZWxmLm9wdGlvbnMuZGlzYWJsZWRdO1xuXG4gICAgICAgIHNlbGYub3B0aW9ucy5kaXNhYmxlZC5mb3JFYWNoKGZ1bmN0aW9uIChkaXNhYmxlKSB7XG4gICAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcj1cIicgKyBkaXNhYmxlLmtleSArICdcIl0nKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnF1ZXJ5ICYmICFBcnJheS5pc0FycmF5KG9wdGlvbnMucXVlcnkpKVxuICAgIG9wdGlvbnMucXVlcnkgPSBbb3B0aW9ucy5xdWVyeV07XG4gIC8vd2UgY2FsbCB0aGUgY29yZSBpbml0aWFsaXplIG9wdGlvblxuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcbiAgc2VsZi5kcmF3KCk7XG5cbiAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHZhciBlbGVtID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIpLnBhcmVudCgpO1xuICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gIH1cblxuICAvL3dyYXAgdXBcbiAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLkRpbWVuc2lvblBpY2tlciA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IChvcHRpb25zICYmIG9wdGlvbnMuZm9yY2UpKSB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LkRpbWVuc2lvblBpY2tlcihvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBkaW1lbnNpb25waWNrZXIpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIGRpbWVuc2lvbnBpY2tlci5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxudXRpbC5pbmhlcml0cyhEaW1lbnNpb25QaWNrZXIsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5JyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyk7XG5cbnZhciBGaWx0ZXJCb3ggPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLy9taXhpblxuICB0aGlzLnR5cGUgPSAnZmlsdGVyYm94JztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICB0aGlzLmRhdGEgPSBbXTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJmaWx0ZXJib3hcIj4nICtcbiAgICAnPC9kaXY+J1xuICB9O1xuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgdGhpcy5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmVtcHR5KCk7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAvL3dlIGRyYXcgdGhlIHRlbXBsYXRlIGludG8gdGhlIGNvbnRhaW5lclxuICAgIHZhciAkaHRtbCA9ICQkKHNlbGYub3B0aW9ucy50ZW1wbGF0ZSk7XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuaHRtbCgkaHRtbCk7XG4gICAgLy92aXN1YWxpemF0aW9uIHNwZWNpZmljIGRyYXdpbmdcbiAgfTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnF1ZXJ5ICYmICFBcnJheS5pc0FycmF5KG9wdGlvbnMucXVlcnkpKVxuICAgIG9wdGlvbnMucXVlcnkgPSBbb3B0aW9ucy5xdWVyeV07XG4gIC8vd2UgY2FsbCB0aGUgY29yZSBpbml0aWFsaXplIG9wdGlvblxuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcblxuICBzZWxmLmRyYXcoKTtcbiAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHZhciBlbGVtID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIpLnBhcmVudCgpO1xuICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gIH1cblxuICAvL3dyYXAgdXBcbiAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLkZpbHRlckJveCA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5GaWx0ZXJCb3gob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgZmlsdGVyYm94KSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXIgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpO1xuICBcbnZhciBHZW8gPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdnZW8uaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5faWQgPSAnX2dlbyc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBsZWdlbmQ6IHRydWUsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgcXVlcnk6IG51bGxcbiAgfTtcbiAgdGhpcy5jaGFydERyYXduID0gZmFsc2U7XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIudmVyaWZ5KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIuZmV0Y2godGhpcy5vcHRpb25zLnF1ZXJ5LCBmdW5jdGlvbiAoZXJyLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgICAvL2Vsc2VcbiAgICAgICAgLy8gIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIHZhciBvcHRpb25zID0ge1xuICAgICAgICBrZWVwQXNwZWN0UmF0aW86IHRydWUsXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjoge1xuICAgICAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCdcbiAgICAgICAgfSxcbiAgICAgICAgZGF0YWxlc3NSZWdpb25Db2xvcjogJ3doaXRlJ1xuXG4gICAgICB9O1xuXG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5fc3VwZXIubWFrZUdlb1NlcmllcyhtZXNzYWdlLmRpbWVuc2lvbnMsIG1lc3NhZ2UubWV0cmljcywgbWVzc2FnZS5kb2N1bWVudHMpO1xuICAgICAgaWYgKCFzZWxmLmRyYXduKSB7XG5cblxuICAgICAgICBzZWxmLmRyYXduID0gdHJ1ZTtcbiAgICAgICAgc2VsZi5jaGFydCA9IG5ldyBnb29nbGUudmlzdWFsaXphdGlvbi5HZW9DaGFydChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hdHRyKCdpZCcpKSk7XG4gICAgICAgIHNlbGYuY2hhcnQuZHJhdyhzZXJpZXMsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5LnJlYWx0aW1lKSB7XG4gICAgICAgIC8vd2UncmUgZGVhbGluZyB3aXRoIHJlYWx0aW1lXG5cbiAgICAgICAgc2VsZi5jaGFydC5kcmF3KHNlcmllcywgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIHRyeSB7XG4gICAgam9vbGEuY29tbW9uLm1peGluKHNlbGYub3B0aW9ucywgb3B0aW9ucywgdHJ1ZSk7XG4gICAgc2VsZi52ZXJpZnkoc2VsZi5vcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkKHNlbGYub3B0aW9ucy5jb250YWluZXIpO1xuICAgICAgc2VsZi5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLCBbXG4gICAgICAgIHsndHlwZSc6ICdnZW8nfSxcbiAgICAgICAgeyd1dWlkJzogc2VsZi51dWlkfVxuICAgICAgXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuXG4gICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdnZW8uaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjYXRjaCAoZXJyKSB7XG4gICAgY2FsbGJhY2soZXJyKTtcbiAgICByZXR1cm4gc2VsZi5vbkVycm9yKGVyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy9jYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLkdlbyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICB2YXIgdXVpZCA9IHRoaXMuYXR0cignamlvLXV1aWQnKTtcbiAgICAgIGlmICghdXVpZCkge1xuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5HZW8ob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgZ2VvKSB7XG4gICAgICAgICAgZ2VvLmRyYXcob3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXJcbiAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKSxcbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuICAkJCA9IHJlcXVpcmUoJ2pxdWVyeScpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpO1xuXG52YXIgTWV0cmljID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMudHlwZSA9ICdtZXRyaWMnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG4gIHRoaXMuZGF0YSA9IFtdO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgIGNhcHRpb246ICcnLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImppbyBtZXRyaWNib3hcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cInZhbHVlXCI+PC9kaXY+JyArXG4gICAgJzxkaXYgY2xhc3M9XCJzdW1tYXJ5XCIgc3R5bGU9XCJkaXNwbGF5Om5vbmU7XCI+JyArXG4gICAgJzxzcGFuIGNsYXNzPVwiYmFzZVwiPjwvc3Bhbj4nICtcbiAgICAnPHNwYW4gY2xhc3M9XCJzZXBcIj52cy48L3NwYW4+JyArXG4gICAgJzxzcGFuIGNsYXNzPVwiY29tcGFyZVwiPjwvc3Bhbj4nICtcbiAgICAnPC9kaXY+JyArXG4gICAgJzxkaXYgY2xhc3M9XCJjYXB0aW9uXCI+PC9kaXY+JyArXG4gICAgJzwvZGl2PicsXG4gICAgcXVlcnk6IG51bGwsXG4gICAgc3RyaW5nczoge1xuICAgICAgbG9hZGluZzogJy0tLScsXG4gICAgICBub2RhdGE6ICctLS0nXG4gICAgfVxuICB9O1xuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgaWYgKCFzZWxmLm9wdGlvbnMpXG4gICAgICByZXR1cm4gJ0ZhaWxlZCB0byB2ZXJpZnkgW29wdGlvbnNdLic7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5xdWVyeSkge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5xdWVyeSkpXG4gICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeSA9IFtzZWxmLm9wdGlvbnMucXVlcnldO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zICYmIHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmxlbmd0aCA+IDApXG4gICAgICAgIHJldHVybiAnUGxlYXNlIGRvblxcJ3Qgc3BlY2lmeSBhIGRpbWVuc2lvbi4nO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzICYmIChzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5sZW5ndGggPT09IDAgfHwgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MubGVuZ3RoID4gMSkgfHwgIXNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzKVxuICAgICAgICByZXR1cm4gJ1BsZWFzZSBzcGVjaWZ5IGEgc2luZ2xlIG1ldHJpYy4nO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLmVudGVyID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcbiAgICB2YXIgX3F1ZXJ5ID0gc2VsZi5vcHRpb25zLnF1ZXJ5O1xuICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5xdWVyeSkpXG4gICAgICBfcXVlcnkgPSBfcXVlcnlbMF07XG5cbiAgICB2YXIgbWV0cmlja2V5ID0gX3F1ZXJ5Lm1ldHJpY3NbMF0ua2V5IHx8IF9xdWVyeS5tZXRyaWNzWzBdO1xuICAgIHZhciBtZXRyaWMgPSBkYXRhWzBdLm1ldGFbbWV0cmlja2V5XTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IG1ldHJpYy5uYW1lIHx8IF9xdWVyeS5tZXRyaWNzWzBdLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG4gICAgaWYgKHNlbGYub3B0aW9ucy5lbnRlcilcbiAgICAgIHNlbGYub3B0aW9ucy5lbnRlci5hcHBseShzZWxmLCBbZGF0YSwgYWxsZGF0YV0pO1xuXG4gICAgdmFyIHZhbHVlLCAkJHN1bW1hcnksIHRvdGFsO1xuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5xdWVyeVswXS5maWx0ZXIgJiYgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmZpbHRlci5sZW5ndGggPiAwKVxuICAgICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuc3VtbWFyeScpLnNob3coKTtcbiAgICAgIHZhbHVlID0gZGF0YVswXS5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcudmFsdWUnKS5odG1sKGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModmFsdWUsIG1ldHJpYykpO1xuICAgICAgJCRzdW1tYXJ5ID0gJCQoJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnN1bW1hcnknKSk7XG4gICAgICB0b3RhbCA9IGRhdGFbMF0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgaWYgKG1ldHJpYy5hZ2dyZWdhdGlvbiA9PT0gJ3N1bScpXG4gICAgICAgICQkc3VtbWFyeS5odG1sKCclIG9mIHRvdGFsOiAxMDAlICgnICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh0b3RhbCwgbWV0cmljKSArICcpJyk7XG4gICAgICBlbHNlIGlmIChtZXRyaWMuYWdncmVnYXRpb24gPT09ICdhdmcnKVxuICAgICAgICAkJHN1bW1hcnkuaHRtbCgnT3ZlcmFsbCBhdmc6ICcgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHRvdGFsLCBtZXRyaWMpICsgJyAoMCUpJyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGRhdGEubGVuZ3RoID09PSAyICYmIGRhdGFbMV0udHlwZSA9PT0gJ292ZXJhbGwnKSB7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuc3VtbWFyeScpLnNob3coKTtcbiAgICAgIGlmICghZGF0YVswXS5taXNzaW5nKVxuICAgICAgICB2YWx1ZSA9IGRhdGFbMF0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgZWxzZVxuICAgICAgICB2YWx1ZSA9IDA7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcudmFsdWUnKS5odG1sKGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModmFsdWUsIG1ldHJpYykpO1xuICAgICAgJCRzdW1tYXJ5ID0gJCQoJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnN1bW1hcnknKSk7XG4gICAgICBpZiAoZGF0YVsxXS50eXBlID09PSAnb3ZlcmFsbCcpIHtcbiAgICAgICAgdG90YWwgPSBkYXRhWzFdLm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICAgdmFyIHBlcmNlbnRhZ2U7XG4gICAgICAgIGlmIChtZXRyaWMuYWdncmVnYXRpb24gPT09ICdzdW0nKSB7XG4gICAgICAgICAgcGVyY2VudGFnZSA9ICh2YWx1ZSAvIHRvdGFsICogMTAwKS50b0ZpeGVkKCkgKyAnJSc7XG4gICAgICAgICAgJCRzdW1tYXJ5Lmh0bWwoJyUgb2YgdG90YWw6ICcgKyBwZXJjZW50YWdlICsgJyAoJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModG90YWwsIG1ldHJpYykgKyAnKScpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1ldHJpYy5hZ2dyZWdhdGlvbiA9PT0gJ2F2ZycpIHtcbiAgICAgICAgICBwZXJjZW50YWdlID0gam9vbGEuY29tbW9uLnBlcmNlbnRhZ2VDaGFuZ2UodG90YWwsIHZhbHVlKTtcbiAgICAgICAgICAkJHN1bW1hcnkuaHRtbCgnT3ZlcmFsbCBhdmc6ICcgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHRvdGFsLCBtZXRyaWMpICsgJyAoJyArIHBlcmNlbnRhZ2UgKyAnJSknKTtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuc3BsaWNlKDEsIDEpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5zdW1tYXJ5Jykuc2hvdygpO1xuICAgICAgdmFyIGJhc2UsIGNvbXBhcmUsIGNoYW5nZSA9IDA7XG4gICAgICBpZiAoIWRhdGFbMF0ubWlzc2luZylcbiAgICAgICAgYmFzZSA9IGRhdGFbMF0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgaWYgKCFkYXRhWzFdLm1pc3NpbmcpXG4gICAgICAgIGNvbXBhcmUgPSBkYXRhWzFdLm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgIGlmIChiYXNlICYmIGNvbXBhcmUpXG4gICAgICAgIGNoYW5nZSA9IGpvb2xhLmNvbW1vbi5wZXJjZW50YWdlQ2hhbmdlKGNvbXBhcmUsIGJhc2UpICsgJyUnO1xuICAgICAgZWxzZVxuICAgICAgICBjaGFuZ2UgPSAnTi9BJztcblxuICAgICAgJCRzdW1tYXJ5ID0gJCQoJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnN1bW1hcnknKSk7XG4gICAgICAkJHN1bW1hcnkuaHRtbCgnPHNwYW4gY2xhc3M9XCJiYXNlXCI+PC9zcGFuPicgK1xuICAgICAgJzxzcGFuIGNsYXNzPVwic2VwXCI+dnMuPC9zcGFuPicgK1xuICAgICAgJzxzcGFuIGNsYXNzPVwiY29tcGFyZVwiPjwvc3Bhbj4nKTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy52YWx1ZScpLmh0bWwoY2hhbmdlKTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5iYXNlJykuaHRtbChiYXNlID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhiYXNlLCBtZXRyaWMpIDogJ04vQScpO1xuXG4gICAgICBpZiAoY29tcGFyZSkge1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuY29tcGFyZScpLmh0bWwoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlLCBtZXRyaWMpKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuY29tcGFyZScpLmh0bWwoJ04vQScpO1xuICAgICAgfVxuXG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZXhpdCA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnZhbHVlJykuaHRtbChzZWxmLm9wdGlvbnMuc3RyaW5ncy5ub2RhdGEpO1xuICB9O1xuXG4gIHRoaXMudXBkYXRlID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcbiAgICB2YXIgX3F1ZXJ5ID0gc2VsZi5vcHRpb25zLnF1ZXJ5O1xuICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5xdWVyeSkpXG4gICAgICBfcXVlcnkgPSBfcXVlcnlbMF07XG5cbiAgICB2YXIgbWV0cmlja2V5ID0gX3F1ZXJ5Lm1ldHJpY3NbMF0ua2V5IHx8IF9xdWVyeS5tZXRyaWNzWzBdO1xuICAgIHZhciBtZXRyaWMgPSBkYXRhWzBdLm1ldGFbbWV0cmlja2V5XTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IG1ldHJpYy5uYW1lIHx8IF9xdWVyeS5tZXRyaWNzWzBdLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLnVwZGF0ZSlcbiAgICAgIHNlbGYub3B0aW9ucy51cGRhdGUuYXBwbHkoc2VsZiwgW2RhdGEsIGFsbGRhdGFdKTtcblxuICAgIHZhciB2YWx1ZSA9IGRhdGFbMF0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy52YWx1ZScpLmh0bWwoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh2YWx1ZSwgbWV0cmljKSk7XG4gIH07XG5cbiAgdGhpcy5kb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHNlbGYuZW1pdCgnZG9uZScpO1xuICB9O1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS52aXouc3RvcChzZWxmKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5lbXB0eSgpO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgLy93ZSBkcmF3IHRoZSB0ZW1wbGF0ZSBpbnRvIHRoZSBjb250YWluZXJcbiAgICB2YXIgJGh0bWwgPSAkJChzZWxmLm9wdGlvbnMudGVtcGxhdGUpO1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmh0bWwoJGh0bWwpO1xuICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbikge1xuICAgICAgJGh0bWwuZmluZCgnLmNhcHRpb24nKS5odG1sKHNlbGYub3B0aW9ucy5jYXB0aW9uKTtcbiAgICB9XG4gICAgJGh0bWwuZmluZCgnLnZhbHVlJykuaHRtbChzZWxmLm9wdGlvbnMuc3RyaW5ncy5ub2RhdGEpO1xuICAgIC8vdmlzdWFsaXphdGlvbiBzcGVjaWZpYyBkcmF3aW5nXG4gICAgLy9pZiB3ZSBoYXZlIGEgZmlsdGVyLCBsZXQncyBhZGQgYSBxdWVyeSBmb3IgdGhlIG92ZXJhbGxcbiAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIHEgPSBzZWxmLm9wdGlvbnMucXVlcnlbMF07XG4gICAgICBpZiAoIXEuZmlsdGVyKVxuICAgICAgICBxLmZpbHRlciA9IFtdO1xuICAgICAgaWYgKHEuZmlsdGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmFyIF9xID0gY2UuY2xvbmUocSk7XG4gICAgICAgIF9xLmZpbHRlciA9IFtdO1xuICAgICAgICBfcS50eXBlID0gJ292ZXJhbGwnO1xuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkucHVzaChfcSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcblxuICAvL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG5cbiAgc2VsZi5kcmF3KCk7XG4gIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICBpZiAoIXNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJCQoZWxlbSkuQ2FudmFzKCk7XG4gICAgfVxuICB9XG4gIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICB9XG5cbiAgLy93cmFwIHVwXG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZvdW5kO1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5NZXRyaWMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgb3B0aW9ucyA9IHtmb3JjZTogZmFsc2V9O1xuICAgICAgZWxzZSBpZiAoIW9wdGlvbnMuaGFzT3duUHJvcGVydHkoJ2ZvcmNlJykpXG4gICAgICAgIG9wdGlvbnMuZm9yY2UgPSB0cnVlO1xuICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICB2YXIgdXVpZCA9IHRoaXMuYXR0cignamlvLXV1aWQnKTtcbiAgICAgIGlmICghdXVpZCB8fCBvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmZvcmNlICYmIHV1aWQpIHtcbiAgICAgICAgICB2YXIgZXhpc3RpbmcgPSBudWxsO1xuICAgICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgZXhpc3RpbmcgPSB2aXo7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoZm91bmQgJiYgZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIGV4aXN0aW5nLmRlc3Ryb3koKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouTWV0cmljKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIG1ldHJpYykge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoTWV0cmljLCBldmVudHMuRXZlbnRFbWl0dGVyKTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG5cbnZhclxuICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpLFxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbnZhciBNZXRyaWNQaWNrZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdtZXRyaWNwaWNrZXIuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy50eXBlID0gJ21ldHJpY3BpY2tlcic7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBjYW52YXM6IG51bGwsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgbWV0cmljczogW10sXG4gICAgZGlzYWJsZWQ6IFtdLFxuICAgIHNlbGVjdGVkOiBudWxsLFxuICAgIGFsbG93UmVtb3ZlOiB0cnVlLFxuICAgIGFsbG93U2VsZWN0OiB0cnVlLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImppby1tZXRyaWNwaWNrZXItd3JhcHBlclwiPlxcbicgK1xuICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cImJ0biBqaW8tbWV0cmljcGlja2VyLWJ1dHRvblwiPicgK1xuICAgICAgJyAgIDxzcGFuIGNsYXNzPVwiY2FwdGlvblwiPjwvc3Bhbj4nICtcbiAgICAgICcgICA8c3BhbiBjbGFzcz1cImNsb3NlXCI+w5c8L3NwYW4+JyArXG4gICAgICAnICA8L2J1dHRvbj4nICtcbiAgICAgICcgIDxkaXYgY2xhc3M9XCJwaWNrZXItY29udGFpbmVyXCI+JyArXG4gICAgICAnICAgIDxkaXYgY2xhc3M9XCJzZWFyY2ggaW5wdXQtcHJlcGVuZFwiPjxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwicXVpY2tzZWFyY2hcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiPjxzcGFuIGNsYXNzPVwiYWRkLW9uXCI+PGkgY2xhc3M9XCJzZWFyY2hpY29uIGljb24tc2VhcmNoXCI+PC9pPjwvc3Bhbj48L2Rpdj4nICtcbiAgICAgICcgICAgPGRpdiBjbGFzcz1cImNsZWFyXCI+PC9kaXY+JyArXG4gICAgICAnICA8L2Rpdj4nICtcbiAgICAgICcgIDxkaXYgY2xhc3M9XCJjbGVhclwiPjwvZGl2PicgK1xuICAgICAgJzwvZGl2PidcbiAgfTtcbiAgdGhpcy5kcmF3biA9IGZhbHNlO1xuXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblxuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIGlmICghc2VsZi5kcmF3bikge1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmFwcGVuZChzZWxmLm9wdGlvbnMudGVtcGxhdGUgfHwgc2VsZi50ZW1wbGF0ZSgpKTtcbiAgICAgIHZhciAkdWwgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcucGlja2VyLWNvbnRhaW5lcicpKTtcbiAgICAgIHZhciAkYnRuID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1tZXRyaWNwaWNrZXItYnV0dG9uJykpO1xuICAgICAgdmFyICRjbG9zZSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpKTtcbiAgICAgIGlmICghc2VsZi5vcHRpb25zLmFsbG93UmVtb3ZlKVxuICAgICAgICAkY2xvc2UucmVtb3ZlKCk7XG4gICAgICB2YXIgJHNlYXJjaCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5xdWlja3NlYXJjaCcpKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbilcbiAgICAgICAgJGJ0bi5maW5kKCcuY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24pO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5tZXRyaWNzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgam9vbGEubWV0cmljcy5saXN0KGZ1bmN0aW9uIChlcnIsIGxpc3QpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuXG4gICAgICAgICAgdmFyIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgdmFyIG1Ta2lwT25lID0gZmFsc2U7XG4gICAgICAgICAgdmFyIG1sYXN0dGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICAgIGxpc3QuZm9yRWFjaChmdW5jdGlvbiAobWV0cmljKSB7XG4gICAgICAgICAgICB2YXIgY29sbGVjdGlvbiA9IHtrZXk6IG1ldHJpYy5jb2xsZWN0aW9ufTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29sbGVjdGlvbiAhPT0gJ29iamVjdCcpXG4gICAgICAgICAgICAgIGNvbGxlY3Rpb24gPSB7a2V5OiBjb2xsZWN0aW9ufTtcblxuICAgICAgICAgICAgdmFyICRsaSA9ICQkKCc8ZGl2IGNsYXNzPVwibWV0cmljT3B0aW9uXCIgZGF0YS1tZW1iZXI9XCInICsgY29sbGVjdGlvbi5rZXkgKyAnLicgKyBtZXRyaWMua2V5ICsgJ1wiPicgKyAobWV0cmljLm5hbWUgfHwgbWV0cmljLmtleSkgKyAnPC9kaXY+Jyk7XG4gICAgICAgICAgICAkbGkub2ZmKCdjbGljaycpO1xuICAgICAgICAgICAgJGxpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgIHZhciAkdGhpcyA9ICQkKHRoaXMpO1xuICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgICAgICAgIGlmICgkdGhpcy5oYXNDbGFzcygnYWN0aXZlJykpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICBpZiAoJHRoaXMuaGFzQ2xhc3MoJ2Rpc2FibGVkJykpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5zZWxlY3RlZCA9IG1ldHJpYztcbiAgICAgICAgICAgICAgLy92YXIgJGNvbnRlbnQgPSAnPHNwYW4gY2xhc3M9XCJuYW1lXCI+JyArIG1ldHJpYy5uYW1lICsgJzwvc3Bhbj4nO1xuICAgICAgICAgICAgICAvLyRidG4uZmluZCgnLmNhcHRpb24nKS5odG1sKChzZWxmLm9wdGlvbnMucHJlZml4IHx8ICcnICkgKyAkY29udGVudCk7XG4gICAgICAgICAgICAgICRidG4ucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAkdWwucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICBtbGFzdHRhcmdldCA9IG51bGw7XG5cbiAgICAgICAgICAgICAgc2VsZi5tYXJrU2VsZWN0ZWQoKTtcblxuICAgICAgICAgICAgICBzZWxmLmVtaXQoJ2NoYW5nZScsIG1ldHJpYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICR1bC5hcHBlbmQoJGxpKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRjbG9zZS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5zZWxlY3RlZCA9IG51bGw7XG4gICAgICAgICAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuICAgICAgICAgICAgc2VsZi5lbWl0KCdjaGFuZ2UnLCBudWxsKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRzZWFyY2gua2V5dXAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICB2YXIgdmFsID0gJHRoaXMudmFsKCk7XG4gICAgICAgICAgICBpZiAodmFsLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXJdJykuaGlkZSgpO1xuICAgICAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyKj1cIicgKyB2YWwgKyAnXCJdJykuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyXScpLnNob3coKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRidG4ub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQkKHRoaXMpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgaWYgKG1PcGVuICYmIG1sYXN0dGFyZ2V0ID09IHRoaXMuaWQpIHtcbiAgICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAobVNraXBPbmUpIHtcbiAgICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICBtU2tpcE9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICR1bC5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gdGhpcy5pZDtcbiAgICAgICAgICAgICAgbU9wZW4gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG9mZnNldCA9ICRidG4ucG9zaXRpb24oKTtcbiAgICAgICAgICAgICR1bC5jc3MoJ3RvcCcsIG9mZnNldC50b3AgKyAkYnRuLm91dGVySGVpZ2h0KCkgLSAxKTtcbiAgICAgICAgICAgICR1bC5jc3MoJ2xlZnQnLCBvZmZzZXQubGVmdCk7XG4gICAgICAgICAgICAkdWwuZmluZCgndWwuYWN0aXZlJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgICAgICAkdWwuYXR0cignZGF0YS10YXJnZXQnLCB0aGlzLmlkKTtcblxuICAgICAgICAgICAgLy9zZXQgc2VsZWN0ZWRcbiAgICAgICAgICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkdWwub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgJCQoJ2JvZHknKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkYnRuLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICBtbGFzdHRhcmdldCA9IG51bGw7XG4gICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJGJ0bi5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgICR0aGlzLnRvZ2dsZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICAgIH0pO1xuICAgICAgZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcblxuICAgIH1cblxuICAgIHNlbGYubWFya1NlbGVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgJHVsLmZpbmQoJ2RpdicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QgJiYgc2VsZi5vcHRpb25zLnNlbGVjdGVkKSB7XG4gICAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXI9XCInICsgc2VsZi5vcHRpb25zLnNlbGVjdGVkLmNvbGxlY3Rpb24gKyAnLicgKyBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQua2V5ICsgJ1wiXScpLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1tZXRyaWNwaWNrZXItYnV0dG9uJykuZmluZCgnLmNhcHRpb24nKS5odG1sKChzZWxmLm9wdGlvbnMucHJlZml4IHx8ICcnICkgKyAnPHNwYW4gY2xhc3M9XCJuYW1lXCI+JyArIChzZWxmLm9wdGlvbnMuc2VsZWN0ZWQubmFtZSB8fCBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQua2V5IHx8IHNlbGYub3B0aW9ucy5zZWxlY3RlZCkgKyAnPC9zcGFuPicpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2xvc2UnKS5zaG93KCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1tZXRyaWNwaWNrZXItYnV0dG9uJykuZmluZCgnLmNhcHRpb24nKS5odG1sKCdDaG9vc2UgYSBtZXRyaWMuLi4nICsgJycpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2xvc2UnKS5oaWRlKCk7XG4gICAgICB9XG5cbiAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXJdJykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmRpc2FibGVkKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMuZGlzYWJsZWQpKVxuICAgICAgICAgIHNlbGYub3B0aW9ucy5kaXNhYmxlZCA9IFtzZWxmLm9wdGlvbnMuZGlzYWJsZWRdO1xuXG4gICAgICAgIHNlbGYub3B0aW9ucy5kaXNhYmxlZC5mb3JFYWNoKGZ1bmN0aW9uIChkaXNhYmxlKSB7XG4gICAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcj1cIicgKyBkaXNhYmxlLmNvbGxlY3Rpb24gKyAnLicgKyBkaXNhYmxlLmtleSArICdcIl0nKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnF1ZXJ5ICYmICFBcnJheS5pc0FycmF5KG9wdGlvbnMucXVlcnkpKVxuICAgIG9wdGlvbnMucXVlcnkgPSBbb3B0aW9ucy5xdWVyeV07XG4gIC8vd2UgY2FsbCB0aGUgY29yZSBpbml0aWFsaXplIG9wdGlvblxuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcbiAgc2VsZi5kcmF3KCk7XG5cbiAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHZhciBlbGVtID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIpLnBhcmVudCgpO1xuICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gIH1cblxuICAvL3dyYXAgdXBcbiAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLk1ldHJpY1BpY2tlciA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IChvcHRpb25zICYmIG9wdGlvbnMuZm9yY2UpKSB7XG4gICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6Lk1ldHJpY1BpY2tlcihvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBtZXRyaWNwaWNrZXIpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIG1ldHJpY3BpY2tlci5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxudXRpbC5pbmhlcml0cyhNZXRyaWNQaWNrZXIsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyk7XG5cbnZhciBNaW5pVGFibGUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdtaW5pdGFibGUuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5faWQgPSAnX21pbml0YWJsZSc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBsZWdlbmQ6IHRydWUsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgcXVlcnk6IG51bGxcbiAgfTtcbiAgdGhpcy5jaGFydERyYXduID0gZmFsc2U7XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIudmVyaWZ5KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfTtcblxuICB0aGlzLnRlbXBsYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkaHRtbCA9ICQoJzx0YWJsZSBjbGFzcz1cImppbyBtaW5pdGFibGUgdGFibGVcIj4nICtcbiAgICAgICc8dGhlYWQ+JyArXG4gICAgICAnPC90aGVhZD4nICtcbiAgICAgICc8dGJvZHk+JyArXG4gICAgICAnPC90Ym9keT4nICtcbiAgICAgICc8L3RhYmxlPicpO1xuICAgIHJldHVybiAkaHRtbDtcbiAgfTtcblxuICB0aGlzLnNvcnQgPSBmdW5jdGlvbiAoa2V5LCBjYWxsYmFjaykge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gIH07XG5cbiAgdGhpcy5fZHJhdyA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgc2VsZi5zdG9wKCk7XG4gICAgcmV0dXJuIHRoaXMuX3N1cGVyLmZldGNoKHRoaXMub3B0aW9ucy5xdWVyeSwgZnVuY3Rpb24gKGVyciwgbWVzc2FnZSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobWVzc2FnZSkpXG4gICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlWzBdO1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyICRjb2wsICR0ciwgdHJzO1xuICAgICAgdmFyIHNlcmllcyA9IHNlbGYuX3N1cGVyLm1ha2VUYWJsZUNoYXJ0U2VyaWVzKG1lc3NhZ2UuZGltZW5zaW9ucywgbWVzc2FnZS5tZXRyaWNzLCBtZXNzYWdlLmRvY3VtZW50cyk7XG4gICAgICBpZiAoIXNlbGYuY2hhcnREcmF3bikge1xuICAgICAgICBzZWxmLmNoYXJ0RHJhd24gPSB0cnVlO1xuXG4gICAgICAgIHZhciAkaHRtbCA9IHNlbGYudGVtcGxhdGUoKTtcblxuICAgICAgICB2YXIgJHRoZWFkID0gJCgkaHRtbC5maW5kKCd0aGVhZCcpKTtcbiAgICAgICAgdmFyICRoZWFkX3RyID0gJCgnPHRyIGNsYXNzPVwiamlvIG1pbml0YWJsZSBjYXB0aW9uc1wiPjwvdHI+Jyk7XG5cbiAgICAgICAgbWVzc2FnZS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICB2YXIgJHRoID0gJCgnPHRoIGNsYXNzPVwiamlvIG1pbml0YWJsZSBjYXB0aW9uIGRpbWVuc2lvblwiPjwvdGg+Jyk7XG4gICAgICAgICAgJHRoLnRleHQoZC5uYW1lKTtcbiAgICAgICAgICAkaGVhZF90ci5hcHBlbmQoJHRoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1lc3NhZ2UubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgdmFyICR0aCA9ICQoJzx0aCBjbGFzcz1cImppbyBtaW5pdGFibGUgY2FwdGlvbiBtZXRyaWNcIj48L3RoPicpO1xuICAgICAgICAgICR0aC50ZXh0KG0ubmFtZSk7XG4gICAgICAgICAgJGhlYWRfdHIuYXBwZW5kKCR0aCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICR0aGVhZC5hcHBlbmQoJGhlYWRfdHIpO1xuICAgICAgICAkaHRtbC5hcHBlbmQoJHRoZWFkKTtcblxuICAgICAgICB2YXIgJHRib2R5ID0gJCgkaHRtbC5maW5kKCd0Ym9keScpKTtcbiAgICAgICAgc2VyaWVzLmZvckVhY2goZnVuY3Rpb24gKHNlciwgc2VySW5kZXgpIHtcbiAgICAgICAgICBzZXIuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICAgICAgdmFyICR0ciA9ICQoJzx0cj48L3RyPicpO1xuXG4gICAgICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICAgICAgbWVzc2FnZS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgdmFyICR0ZCA9ICQoJzx0ZCBjbGFzcz1cImppbyBtaW5pdGFibGUgdmFsdWUgZGltZW5zaW9uXCI+PC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRkLnRleHQocG9pbnRbaW5kZXgrK10pO1xuICAgICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1lc3NhZ2UubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgIHZhciAkdGQgPSAkKCc8dGQgY2xhc3M9XCJqaW8gbWluaXRhYmxlIHZhbHVlIG1ldHJpY1wiPjwvdGQ+Jyk7XG4gICAgICAgICAgICAgICR0ZC50ZXh0KHBvaW50W2luZGV4KytdKTtcbiAgICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgICRodG1sLmFwcGVuZCgkdGJvZHkpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hcHBlbmQoJGh0bWwpO1xuXG4gICAgICAgIHNlbGYudGFibGVzb3J0ID0gbmV3IFRhYmxlc29ydCgkaHRtbC5nZXQoMCksIHtcbiAgICAgICAgICBkZXNjZW5kaW5nOiB0cnVlLFxuICAgICAgICAgIGN1cnJlbnQ6ICRodG1sLmZpbmQoJ3RoJylbMV1cbiAgICAgICAgfSk7XG5cblxuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLm9uRHJhdylcbiAgICAgICAgICB3aW5kb3dbc2VsZi5vcHRpb25zLm9uRHJhd10oc2VsZik7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChzZWxmLm9wdGlvbnMucXVlcnkucmVhbHRpbWUpIHtcbiAgICAgICAgLy93ZSdyZSBkZWFsaW5nIHdpdGggcmVhbHRpbWVcbiAgICAgICAgdHJzID0gc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgndGJvZHknKS5maW5kKCd0cicpO1xuICAgICAgICB2YXIgZXhpc3RpbmdrZXlzID0gW107XG4gICAgICAgIHNlcmllc1swXS5kYXRhLmZvckVhY2goZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgICAgICB2YXIga2V5ID0gJyc7XG4gICAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgbWVzc2FnZS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIGtleSArPSBwb2ludFtpbmRleCsrXTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGV4aXN0aW5na2V5cy5wdXNoKGtleSk7XG5cbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgJHRyID0gJCh0cnNbaV0pO1xuICAgICAgICAgICAgdmFyIGNvbHMgPSAkdHIuZmluZCgndGQnKTtcblxuICAgICAgICAgICAgdmFyIF9rZXkgPSAnJztcbiAgICAgICAgICAgIHZhciBqO1xuICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG1lc3NhZ2UuZGltZW5zaW9ucy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAkY29sID0gJChjb2xzW2pdKTtcbiAgICAgICAgICAgICAgX2tleSArPSAkY29sLnRleHQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKF9rZXkgPT0ga2V5KSB7XG4gICAgICAgICAgICAgIGZvciAoOyBqIDwgbWVzc2FnZS5kaW1lbnNpb25zLmxlbmd0aCArIG1lc3NhZ2UubWV0cmljcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICRjb2wgPSAkKGNvbHNbal0pO1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9ICRjb2wudGV4dCgpO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBwb2ludFtqXSlcbiAgICAgICAgICAgICAgICAgICRjb2wudGV4dChwb2ludFtqXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICAvL2FkZFxuICAgICAgICAgICAgdmFyICR0Ym9keSA9ICQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgndGJvZHknKVswXSk7XG4gICAgICAgICAgICAkdHIgPSAkKCc8dHI+PC90cj4nKTtcblxuICAgICAgICAgICAgaW5kZXggPSAwO1xuICAgICAgICAgICAgbWVzc2FnZS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgdmFyICR0ZCA9ICQoJzx0ZCBjbGFzcz1cImppbyBtaW5pdGFibGUgdmFsdWUgZGltZW5zaW9uXCI+PC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRkLnRleHQocG9pbnRbaW5kZXgrK10pO1xuICAgICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG1lc3NhZ2UubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICAgIHZhciAkdGQgPSAkKCc8dGQgY2xhc3M9XCJqaW8gbWluaXRhYmxlIHZhbHVlIG1ldHJpY1wiPjwvdGQ+Jyk7XG4gICAgICAgICAgICAgICR0ZC50ZXh0KHBvaW50W2luZGV4KytdKTtcbiAgICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICR0ciA9ICQodHJzW2ldKTtcbiAgICAgICAgICB2YXIgY29scyA9ICR0ci5maW5kKCd0ZCcpO1xuXG4gICAgICAgICAgdmFyIF9rZXkgPSAnJztcbiAgICAgICAgICB2YXIgajtcbiAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbWVzc2FnZS5kaW1lbnNpb25zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAkY29sID0gJChjb2xzW2pdKTtcbiAgICAgICAgICAgIF9rZXkgKz0gJGNvbC50ZXh0KCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGV4aXN0aW5na2V5cy5pbmRleE9mKF9rZXkpID09IC0xKVxuICAgICAgICAgICAgJHRyLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzZXJpZXNbMF0uZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHNlbGYudGFibGVzb3J0LnJlZnJlc2goKTtcblxuICAgICAgICB2YXIgbGltaXQgPSA1O1xuICAgICAgICB0cnMgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCd0Ym9keSB0cicpO1xuICAgICAgICBmb3IgKHZhciB6ID0gMDsgeiA8IHRycy5sZW5ndGg7IHorKykge1xuICAgICAgICAgIHZhciBlbGVtID0gdHJzW3pdO1xuICAgICAgICAgIHZhciAkZWxlbSA9ICQoZWxlbSk7XG4gICAgICAgICAgaWYgKHogKyAxID4gbGltaXQpXG4gICAgICAgICAgICAkZWxlbS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICB0cnkge1xuICAgIGpvb2xhLmNvbW1vbi5taXhpbihzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICAgIHNlbGYudmVyaWZ5KHNlbGYub3B0aW9ucywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKGVycilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYubWFya0NvbnRhaW5lcihzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciwgW1xuICAgICAgICB7J3R5cGUnOiAnbWluaXRhYmxlJ30sXG4gICAgICAgIHsndXVpZCc6IHNlbGYudXVpZH0sXG4gICAgICAgIHsnY3NzJzogc2VsZi5vcHRpb25zLmNzc31cbiAgICAgIF0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgaWYgKGVycilcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcblxuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnbWluaXRhYmxlLmluaXQuZmluaXNoJywgc2VsZik7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY2F0Y2ggKGVycikge1xuICAgIGNhbGxiYWNrKGVycik7XG4gICAgcmV0dXJuIHNlbGYub25FcnJvcihlcnIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLk1pbmlUYWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5NaW5pVGFibGUob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgbWluaXRhYmxlKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBtaW5pdGFibGUuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxuXG52YXIgUGllID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCFjYWxsYmFjaylcbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB9O1xuICBqb29sYS5ldmVudHMuZW1pdCgncGllLmluaXQuc3RhcnQnKTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuX2lkID0gJ19waWUnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgbGVnZW5kOiB0cnVlLFxuICAgIGxpbWl0OiA1LFxuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAkY29udGFpbmVyOiBudWxsLFxuICAgIHF1ZXJ5OiBudWxsXG4gIH07XG4gIHRoaXMuY2hhcnREcmF3biA9IGZhbHNlO1xuICB0aGlzLnJlYWx0aW1lUXVlcmllcyA9IFtdO1xuXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N1cGVyLnZlcmlmeShvcHRpb25zLCBjYWxsYmFjayk7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgc2VsZi5zdG9wKCk7XG4gICAgcmV0dXJuIHRoaXMuX3N1cGVyLmZldGNoKHRoaXMub3B0aW9ucy5xdWVyeSwgZnVuY3Rpb24gKGVyciwgbWVzc2FnZSkge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKG1lc3NhZ2UucmVhbHRpbWUgJiYgc2VsZi5yZWFsdGltZVF1ZXJpZXMuaW5kZXhPZihtZXNzYWdlLnJlYWx0aW1lKSA9PSAtMSlcbiAgICAgICAgc2VsZi5yZWFsdGltZVF1ZXJpZXMucHVzaChtZXNzYWdlLnJlYWx0aW1lKTtcblxuICAgICAgdmFyIHNlcmllcyA9IHNlbGYuX3N1cGVyLm1ha2VQaWVDaGFydFNlcmllcyhtZXNzYWdlLmRpbWVuc2lvbnMsIG1lc3NhZ2UubWV0cmljcywgbWVzc2FnZS5kb2N1bWVudHMpO1xuICAgICAgaWYgKCFzZWxmLmNoYXJ0RHJhd24pIHtcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5vbkRyYXcpXG4gICAgICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vbkRyYXddKHNlbGYpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hcHBlbmQoc2VsZi5vcHRpb25zLnRlbXBsYXRlIHx8IFBpZS50ZW1wbGF0ZSgpKTtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmNhcHRpb24nKS50ZXh0KHNlbGYub3B0aW9ucy5jYXB0aW9uIHx8ICcnKTtcbiAgICAgICAgdmFyIGNoYXJ0T3B0aW9ucyA9IGpvb2xhLmNvbW1vbi5fbWl4aW4oe1xuICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB0ZXh0OiBudWxsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjaGFydDoge1xuICAgICAgICAgICAgLyptYXJnaW5Ub3A6IDAsXG4gICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAwLFxuICAgICAgICAgICAgIG1hcmdpbkxlZnQ6IDAsXG4gICAgICAgICAgICAgbWFyZ2luUmlnaHQ6IDAsXG4gICAgICAgICAgICAgc3BhY2luZ1RvcDogMCxcbiAgICAgICAgICAgICBzcGFjaW5nQm90dG9tOiAwLFxuICAgICAgICAgICAgIHNwYWNpbmdMZWZ0OiAwLFxuICAgICAgICAgICAgIHNwYWNpbmdSaWdodDogMCwqL1xuICAgICAgICAgICAgYm9yZGVyV2lkdGg6IDAsXG4gICAgICAgICAgICBwbG90Qm9yZGVyV2lkdGg6IDAsXG4gICAgICAgICAgICB0eXBlOiAncGllJyxcbiAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3RyYW5zcGFyZW50J1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2VyaWVzOiBzZXJpZXMsXG5cbiAgICAgICAgICBsZWdlbmQ6IHtlbmFibGVkOiBzZWxmLm9wdGlvbnMubGVnZW5kfSxcbiAgICAgICAgICBjcmVkaXRzOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgICAgIGV4cG9ydGluZzoge2VuYWJsZWQ6IHRydWV9LFxuICAgICAgICAgIHBsb3RPcHRpb25zOiB7XG4gICAgICAgICAgICBwaWU6IHtcbiAgICAgICAgICAgICAgYWxsb3dQb2ludFNlbGVjdDogdHJ1ZSxcbiAgICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICAgIGRhdGFMYWJlbHM6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBjb2xvcjogJyMwMDAwMDAnLFxuICAgICAgICAgICAgICAgIGNvbm5lY3RvckNvbG9yOiAnIzAwMDAwMCcsXG4gICAgICAgICAgICAgICAgZm9ybWF0OiAnPGI+e3BvaW50Lm5hbWV9PC9iPjoge3BvaW50LnBlcmNlbnRhZ2U6LjFmfSAlJ1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBzaG93SW5MZWdlbmQ6IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIHNlbGYub3B0aW9ucy5jaGFydCk7XG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbilcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLXBpZS1jYXB0aW9uJykudGV4dChzZWxmLm9wdGlvbnMuY2FwdGlvbik7XG4gICAgICAgIHNlbGYuY2hhcnQgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLXBpZS1jaGFydCcpLmhpZ2hjaGFydHMoY2hhcnRPcHRpb25zKTtcblxuICAgICAgICBzZWxmLmNoYXJ0ID0gc2VsZi5jaGFydC5oaWdoY2hhcnRzKCk7XG4gICAgICAgIHNlbGYuY2hhcnREcmF3biA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5LnJlYWx0aW1lKSB7XG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMub25VcGRhdGUpXG4gICAgICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vblVwZGF0ZV0oc2VsZik7XG4gICAgICAgIC8vd2UncmUgZGVhbGluZyB3aXRoIHJlYWx0aW1lXG4gICAgICAgIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uIChzZXIsIHNlckluZGV4KSB7XG4gICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLnBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCkge1xuICAgICAgICAgICAgdmFyIGV4aXN0ID0gXy5maW5kKHNlci5kYXRhLCBmdW5jdGlvbiAocCkge1xuICAgICAgICAgICAgICByZXR1cm4gcFswXSA9PSBwb2ludC5uYW1lO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICAgIHBvaW50LnVwZGF0ZShleGlzdFsxXSwgZmFsc2UpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBwb2ludC5yZW1vdmUoZmFsc2UpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICB2YXIgZXhpc3QgPSBfLmZpbmQoc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLnBvaW50cywgZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHAubmFtZSA9PSBwb2ludFswXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCFleGlzdClcbiAgICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmFkZFBvaW50KFtwb2ludFswXSwgcG9pbnRbMV1dLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgc2VsZi5jaGFydC5yZWRyYXcoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvL2hlcmUgd2UgZ29cbiAgdHJ5IHtcbiAgICBqb29sYS5jb21tb24ubWl4aW4oc2VsZi5vcHRpb25zLCBvcHRpb25zLCB0cnVlKTtcbiAgICBzZWxmLnZlcmlmeShzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciA9ICQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgICBzZWxmLm1hcmtDb250YWluZXIoc2VsZi5vcHRpb25zLiRjb250YWluZXIsIHtcbiAgICAgICAgYXR0cjogW1xuICAgICAgICAgIHsndHlwZSc6ICdwaWUnfSxcbiAgICAgICAgICB7J3V1aWQnOiBzZWxmLnV1aWR9LFxuICAgICAgICAgIHtjc3M6IHNlbGYub3B0aW9ucy5jc3N9XG4gICAgICAgIF0sXG4gICAgICAgIGNzczogc2VsZi5vcHRpb25zLmNzc30sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgaWYgKGVycilcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcblxuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncGllLmluaXQuZmluaXNoJywgc2VsZik7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY2F0Y2ggKGVycikge1xuICAgIGNhbGxiYWNrKGVycik7XG4gICAgcmV0dXJuIHNlbGYub25FcnJvcihlcnIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLlBpZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5QaWUob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgcGllKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBwaWUuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cblBpZS50ZW1wbGF0ZSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIHZhciBodG1sID0gJzxkaXYgamlvLWRvbWFpbj1cImpvb2xhXCIgamlvLXR5cGU9XCJwaWVcIj5cXG4nICtcbiAgICAnICA8ZGl2IGNsYXNzPVwiamlvLXBpZS1jYXB0aW9uXCI+PC9kaXY+XFxuJyArXG4gICAgJyAgPGRpdiBjbGFzcz1cImppby1waWUtY2hhcnRcIj48L2Rpdj5cXG4nICtcbiAgICAnPC9kaXY+JztcbiAgcmV0dXJuIGh0bWw7XG59O1xuIiwiLypqc2hpbnQgLVcwODMgKi9cblxuLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyIFxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyk7XG5cbnZhciBQdW5jaENhcmQgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdwdW5jaGNhcmQuaW5pdC5zdGFydCcpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9pZCA9ICdfcHVuY2hjYXJkJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGxlZ2VuZDogdHJ1ZSxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBxdWVyeTogbnVsbFxuICB9O1xuICB0aGlzLmNoYXJ0RHJhd24gPSBmYWxzZTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci52ZXJpZnkob3B0aW9ucywgY2FsbGJhY2spO1xuICB9O1xuXG4gIHRoaXMubWFrZVNlcmllcyA9IGZ1bmN0aW9uIChkaW1lbnNpb25zLCBtZXRyaWNzLCBkb2N1bWVudHMpIHtcbiAgICB2YXIgbWF4VmFsdWU7XG4gICAgdmFyIG1pblZhbHVlO1xuXG4gICAgZG9jdW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGRvY3VtZW50KSB7XG4gICAgICB2YXIgdmFsdWUgPSBkb2N1bWVudC52YWx1ZXNbbWV0cmljc1swXS5rZXldO1xuICAgICAgaWYgKCFtYXhWYWx1ZSlcbiAgICAgICAgbWF4VmFsdWUgPSB2YWx1ZTtcbiAgICAgIGlmICghbWluVmFsdWUpXG4gICAgICAgIG1pblZhbHVlID0gdmFsdWU7XG4gICAgICBpZiAodmFsdWUgPiBtYXhWYWx1ZSlcbiAgICAgICAgbWF4VmFsdWUgPSB2YWx1ZTtcbiAgICAgIGlmICh2YWx1ZSA8IG1pblZhbHVlKVxuICAgICAgICBtaW5WYWx1ZSA9IHZhbHVlO1xuICAgIH0pO1xuXG4gICAgdmFyIHNjYWxlU2l6ZSA9IGZ1bmN0aW9uIChtaW4sIG1heCwgdGFyZ2V0bWluLCB0YXJnZXRtYXgsIHgpIHtcbiAgICAgIHZhciByZXN1bHQgPSAoKCh0YXJnZXRtYXggLSB0YXJnZXRtaW4pICogKHggLSBtaW4pKSAvIChtYXggLSBtaW4pKSArIHRhcmdldG1pbjtcbiAgICAgIGlmIChpc05hTihyZXN1bHQpKVxuICAgICAgICByZXN1bHQgPSB4O1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgdmFyIHNlcmllcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogbWV0cmljc1swXS5uYW1lLFxuICAgICAgICBkYXRhOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIF9kYXRhID0gW107XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgMjQ7IGorKykge1xuICAgICAgICAgICAgICB2YXIgcG9pbnQgPSB7XG4gICAgICAgICAgICAgICAgeTogaSxcbiAgICAgICAgICAgICAgICB4OiAzNjAwMDAwICogaixcblxuICAgICAgICAgICAgICAgIG1hcmtlcjoge3JhZGl1czogMCB9XG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgdmFyIGV4aXN0cyA9IF8uZmluZChkb2N1bWVudHMsIGZ1bmN0aW9uIChkb2N1bWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkb2N1bWVudC52YWx1ZXNbZGltZW5zaW9uc1swXS5rZXldID09PSBpICYmIGRvY3VtZW50LnZhbHVlc1tkaW1lbnNpb25zWzFdLmtleV0gPT09IGo7XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmIChleGlzdHMpXG4gICAgICAgICAgICAgICAgcG9pbnQubWFya2VyID0geyByYWRpdXM6IHNjYWxlU2l6ZShtaW5WYWx1ZSwgbWF4VmFsdWUsIDMsIDExLCBleGlzdHMudmFsdWVzW21ldHJpY3NbMF0ua2V5XSkgfTtcblxuICAgICAgICAgICAgICBfZGF0YS5wdXNoKHBvaW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIF9kYXRhO1xuXG4gICAgICAgIH0oKVxuICAgICAgfVxuICAgIF07XG5cbiAgICByZXR1cm4gc2VyaWVzO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci5mZXRjaCh0aGlzLm9wdGlvbnMucXVlcnksIGZ1bmN0aW9uIChlcnIsIG1lc3NhZ2UpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5tYWtlU2VyaWVzKG1lc3NhZ2UuZGltZW5zaW9ucywgbWVzc2FnZS5tZXRyaWNzLCBtZXNzYWdlLmRvY3VtZW50cyk7XG4gICAgICBpZiAoIXNlbGYuY2hhcnREcmF3bikge1xuICAgICAgICB2YXIgY2hhcnRPcHRpb25zID0gam9vbGEuY29tbW9uLm1peGluKHtcbiAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgdGV4dDogbnVsbFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2hhcnQ6IHtcblxuICAgICAgICAgICAgZGVmYXVsdFNlcmllc1R5cGU6ICdzY2F0dGVyJ1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2VyaWVzOiBzZXJpZXMsXG4gICAgICAgICAgeEF4aXM6IHtcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiBcImRhdGV0aW1lXCIsXG4gICAgICAgICAgICBkYXRlVGltZUxhYmVsRm9ybWF0czoge1xuICAgICAgICAgICAgICBob3VyOiAnJUkgJVAnXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGlja0ludGVydmFsOiAzNjAwMDAwICogMVxuICAgICAgICAgIH0sXG4gICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYXRlZ29yaWVzOiBbJ1N1bmRheScsICdNb25kYXknLCAnVHVlc2RheScsICdXZWRuZXNkYXknLCAnVGh1cnNkYXknLCAnRnJpZGF5JywgJ1NhdHVyZGF5J11cbiAgICAgICAgICB9LFxuICAgICAgICAgIGxlZ2VuZDoge2VuYWJsZWQ6IGZhbHNlfSxcbiAgICAgICAgICBjcmVkaXRzOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgICAgIGV4cG9ydGluZzoge2VuYWJsZWQ6IHRydWV9XG4gICAgICAgIH0sIHNlbGYub3B0aW9ucy5jaGFydCk7XG4gICAgICAgIHNlbGYuY2hhcnQgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5oaWdoY2hhcnRzKGNoYXJ0T3B0aW9ucyk7XG5cbiAgICAgICAgc2VsZi5jaGFydCA9IHNlbGYuY2hhcnQuaGlnaGNoYXJ0cygpO1xuICAgICAgICBzZWxmLmNoYXJ0RHJhd24gPSB0cnVlO1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHNlbGYub3B0aW9ucy5xdWVyeS5yZWFsdGltZSkge1xuICAgICAgICAvL3dlJ3JlIGRlYWxpbmcgd2l0aCByZWFsdGltZVxuICAgICAgICBzZXJpZXMuZm9yRWFjaChmdW5jdGlvbiAoc2VyLCBzZXJJbmRleCkge1xuICAgICAgICAgIHNlci5kYXRhLnNwbGljZSgwLCBzZXIuZGF0YS5sZW5ndGggLSAxKTtcblxuICAgICAgICAgIHZhciBwb2ludCA9IHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5wb2ludHNbc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLnBvaW50cy5sZW5ndGggLSAxXTtcbiAgICAgICAgICBpZiAocG9pbnQpIHtcbiAgICAgICAgICAgIGlmIChwb2ludC54LmdldFRpbWUoKSA9PSBzZXIuZGF0YVswXS54LmdldFRpbWUoKSlcbiAgICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmRhdGFbc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmRhdGEubGVuZ3RoIC0gMV0udXBkYXRlKHNlci5kYXRhWzBdLnkpO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uYWRkUG9pbnQoe3g6IHNlci5kYXRhWzBdLngsIHk6IHNlci5kYXRhWzBdLnl9LCB0cnVlLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICB0cnkge1xuICAgIGpvb2xhLmNvbW1vbi5taXhpbihzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICAgIHNlbGYudmVyaWZ5KHNlbGYub3B0aW9ucywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKGVycilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYubWFya0NvbnRhaW5lcihzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciwgW1xuICAgICAgICB7J3R5cGUnOiAncHVuY2hjYXJkJ30sXG4gICAgICAgIHsndXVpZCc6IHNlbGYudXVpZH1cbiAgICAgIF0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgaWYgKGVycilcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcblxuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncHVuY2hjYXJkLmluaXQuZmluaXNoJywgc2VsZik7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY2F0Y2ggKGVycikge1xuICAgIGNhbGxiYWNrKGVycik7XG4gICAgcmV0dXJuIHNlbGYub25FcnJvcihlcnIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5QdW5jaENhcmQgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQpIHtcbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouUHVuY2hDYXJkKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIHB1bmNoY2FyZCkge1xuICAgICAgICAgIHB1bmNoY2FyZC5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbiIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhciBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4Jyk7XG5cbnZhciBTcGFya2xpbmUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdzcGFya2xpbmUuaW5pdC5zdGFydCcpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9pZCA9ICdfc3BhcmtsaW5lJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGxlZ2VuZDogdHJ1ZSxcbiAgICBjYW52YXM6IG51bGwsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgcXVlcnk6IG51bGxcbiAgfTtcbiAgdGhpcy5jaGFydERyYXduID0gZmFsc2U7XG4gIHRoaXMucmVhbHRpbWVRdWVyaWVzID0gW107XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIudmVyaWZ5KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICBzZWxmLnN0b3AoKTtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIuZmV0Y2goc2VsZiwgdGhpcy5vcHRpb25zLnF1ZXJ5LCBmdW5jdGlvbiAoZXJyLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdlcnInLCBlcnIpO1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAvL2Vsc2VcbiAgICAgICAgLy90aHJvdyBlcnI7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZS5yZWFsdGltZSAmJiBzZWxmLnJlYWx0aW1lUXVlcmllcy5pbmRleE9mKG1lc3NhZ2UucmVhbHRpbWUpID09IC0xKVxuICAgICAgICBzZWxmLnJlYWx0aW1lUXVlcmllcy5wdXNoKG1lc3NhZ2UucmVhbHRpbWUpO1xuXG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5fc3VwZXIubWFrZUNoYXJ0VGltZWxpbmVTZXJpZXMobWVzc2FnZS5kaW1lbnNpb25zLCBtZXNzYWdlLm1ldHJpY3MsIG1lc3NhZ2UuZG9jdW1lbnRzKTtcbiAgICAgIGlmICghc2VsZi5jaGFydERyYXduKSB7XG4gICAgICAgIHZhciBjaGFydE9wdGlvbnMgPSBqb29sYS5jb21tb24ubWl4aW4oe1xuICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB0ZXh0OiBudWxsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjaGFydDoge1xuICAgICAgICAgICAgbWFyZ2luVG9wOiAwLFxuICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAobWVzc2FnZS5kaW1lbnNpb25zWzBdLmRhdGF0eXBlID09PSAnZGF0ZScgPyAwIDogMjApLFxuICAgICAgICAgICAgbWFyZ2luTGVmdDogMCxcbiAgICAgICAgICAgIG1hcmdpblJpZ2h0OiAwLFxuICAgICAgICAgICAgc3BhY2luZ1RvcDogMCxcbiAgICAgICAgICAgIHNwYWNpbmdCb3R0b206IDAsXG4gICAgICAgICAgICBzcGFjaW5nTGVmdDogMCxcbiAgICAgICAgICAgIHNwYWNpbmdSaWdodDogMCxcbiAgICAgICAgICAgIGJvcmRlcldpZHRoOiAwLFxuICAgICAgICAgICAgcGxvdEJvcmRlcldpZHRoOiAwLFxuICAgICAgICAgICAgdHlwZTogJ2FyZWEnXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXJpZXM6IHNlcmllcyxcbiAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgdHlwZTogKG1lc3NhZ2UuZGltZW5zaW9uc1swXS5kYXRhdHlwZSA9PT0gJ2RhdGUnID8gJ2RhdGV0aW1lJyA6ICdjYXRlZ29yeScpLFxuICAgICAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICAgIGVuYWJsZWQ6IChtZXNzYWdlLmRpbWVuc2lvbnNbMF0uZGF0YXR5cGUgIT09ICdkYXRlJylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHlBeGlzOiB7XG4gICAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgICB0ZXh0OiBudWxsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBsZWdlbmQ6IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICAgICAgY3JlZGl0czoge2VuYWJsZWQ6IGZhbHNlfSxcbiAgICAgICAgICBleHBvcnRpbmc6IHtlbmFibGVkOiB0cnVlfSxcbiAgICAgICAgICBwbG90T3B0aW9uczoge1xuICAgICAgICAgICAgY29sdW1uOiB7YWxsb3dQb2ludFNlbGVjdDogdHJ1ZX0sXG4gICAgICAgICAgICBzZXJpZXM6IHtcbiAgICAgICAgICAgICAgdHVyYm9UaHJlc2hvbGQ6IG1lc3NhZ2UuZG9jdW1lbnRzLmxlbmd0aCArIDEwMDAsXG4gICAgICAgICAgICAgIGNvbG9yOiAnIzMzMzMzMycsXG4gICAgICAgICAgICAgIGZpbGxPcGFjaXR5OiAwLjEsXG4gICAgICAgICAgICAgIGxpbmVXaWR0aDogMyxcbiAgICAgICAgICAgICAgY29ubmVjdE51bGxzOiB0cnVlLFxuICAgICAgICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzeW1ib2w6ICdjaXJjbGUnLFxuICAgICAgICAgICAgICAgIHN0YXRlczoge1xuICAgICAgICAgICAgICAgICAgaG92ZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgc2VsZi5vcHRpb25zLmNoYXJ0KTtcbiAgICAgICAgc2VsZi5jaGFydCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmhpZ2hjaGFydHMoY2hhcnRPcHRpb25zKTtcblxuICAgICAgICBzZWxmLmNoYXJ0ID0gc2VsZi5jaGFydC5oaWdoY2hhcnRzKCk7XG4gICAgICAgIHNlbGYuY2hhcnREcmF3biA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5LnJlYWx0aW1lKSB7XG4gICAgICAgIC8vd2UncmUgZGVhbGluZyB3aXRoIHJlYWx0aW1lXG4gICAgICAgIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uIChzZXIsIHNlckluZGV4KSB7XG4gICAgICAgICAgc2VyLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAoZGF0YXBvaW50KSB7XG4gICAgICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciBuYW1lQmFzZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciB5O1xuICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLnBvaW50cy5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgcEluZGV4KSB7XG4gICAgICAgICAgICAgIGlmIChwb2ludCkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRhcG9pbnQueCkge1xuICAgICAgICAgICAgICAgICAgaWYgKHBvaW50LnguZ2V0VGltZSgpID09IGRhdGFwb2ludC54LmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAgICAgICB5ID0gc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmRhdGFbcEluZGV4XS55O1xuICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh5ICE9IGRhdGFwb2ludC55KVxuICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5kYXRhW3BJbmRleF0udXBkYXRlKGRhdGFwb2ludC55KTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICBuYW1lQmFzZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgaWYgKHBvaW50Lm5hbWUgPT0gZGF0YXBvaW50Lm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgeSA9IHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5kYXRhW3BJbmRleF0ueTtcbiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAoeSAhPSBkYXRhcG9pbnQueSlcbiAgICAgICAgICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uZGF0YVtwSW5kZXhdLnVwZGF0ZShkYXRhcG9pbnQueSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAgICAgaWYgKG5hbWVCYXNlZClcbiAgICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uYWRkUG9pbnQoe25hbWU6IGRhdGFwb2ludC5uYW1lLCB5OiBkYXRhcG9pbnQueX0sIHRydWUpO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmFkZFBvaW50KHt4OiBkYXRhcG9pbnQueCwgeTogZGF0YXBvaW50Lnl9LCB0cnVlLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIHRyeSB7XG4gICAgam9vbGEuY29tbW9uLm1peGluKHNlbGYub3B0aW9ucywgb3B0aW9ucywgdHJ1ZSk7XG4gICAgc2VsZi52ZXJpZnkoc2VsZi5vcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkKHNlbGYub3B0aW9ucy5jb250YWluZXIpO1xuICAgICAgc2VsZi5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLCBbXG4gICAgICAgIHsndHlwZSc6ICdzcGFya2xpbmUnfSxcbiAgICAgICAgeyd1dWlkJzogc2VsZi51dWlkfVxuICAgICAgXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuXG4gICAgICAgIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgICAgIHZhciBlbGVtID0gc2VsZi5vcHRpb25zLiRjb250YWluZXIucGFyZW50KCk7XG4gICAgICAgICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQoZWxlbSkuQ2FudmFzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5vbignZGF0ZWNoYW5nZScsIGZ1bmN0aW9uIChkYXRlcykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ3NwYXJrbGluZScsICdkYXRlY2hhbmdlJywgZGF0ZXMpO1xuXG4gICAgICAgICAgICAvL2xldCdzIGNoYW5nZSBvdXIgcXVlcnkgYW5kIGZldGNoIGFnYWluXG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkudGltZWZyYW1lID0ge307XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkudGltZWZyYW1lLnN0YXJ0ID0gbmV3IERhdGUoZGF0ZXMuYmFzZV9mcm9tZGF0ZSk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkudGltZWZyYW1lLmVuZCA9IG5ldyBEYXRlKGRhdGVzLmJhc2VfdG9kYXRlKTtcblxuICAgICAgICAgICAgc2VsZi5kcmF3KHNlbGYub3B0aW9ucyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnc3BhcmtsaW5lLmluaXQuZmluaXNoJywgc2VsZik7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY2F0Y2ggKGVycikge1xuICAgIGNhbGxiYWNrKGVycik7XG4gICAgcmV0dXJuIHNlbGYub25FcnJvcihlcnIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLlNwYXJrbGluZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICB2YXIgdXVpZCA9IHRoaXMuYXR0cignamlvLXV1aWQnKTtcbiAgICAgIGlmICghdXVpZCB8fCBvcHRpb25zLmZvcmNlKSB7XG4gICAgICAgIGlmIChvcHRpb25zLmZvcmNlICYmIHV1aWQpIHtcbiAgICAgICAgICB2YXIgZXhpc3RpbmcgPSBudWxsO1xuICAgICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgZXhpc3RpbmcgPSB2aXo7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoZm91bmQgJiYgZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIGV4aXN0aW5nLmRlc3Ryb3koKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouU3BhcmtsaW5lKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIHNwYXJrbGluZSkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgc3BhcmtsaW5lLmRyYXcob3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5JyksXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICBjZSA9IHJlcXVpcmUoJ2Nsb25lZXh0ZW5kJyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIGFzeW5jID0gcmVxdWlyZSgnYXN5bmMnKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIFRhYmxlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICB0aGlzLnR5cGUgPSAndGFibGUnO1xuICAgIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gICAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgIHRoaXMuZGF0YSA9IFtdO1xuICAgIHRoaXMuc29ydEluZGV4ID0gLTE7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgY29udGFpbmVyOiBudWxsLFxuICAgICAgY29sb3JzOiBbXSxcbiAgICAgIG9mZmNvbG9yczogW10sXG4gICAgICBwYWdpbmc6IHtcbiAgICAgICAgY3VycmVudFBhZ2U6IDEsXG4gICAgICAgIHNpemVzOiBbMTAsIDI1LCA1MCwgMTAwLCAyNTAsIDUwMCwgMTAwMF0sXG4gICAgICAgIGN1cnJlbnRTaXplOiAxMFxuICAgICAgfSxcbiAgICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cInRhYmxlLWNhcHRpb25cIj48L2Rpdj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwiY29udHJvbHNcIj4nICtcbiAgICAgICcgPGRpdiBjbGFzcz1cInByaW1hcnktZGltZW5zaW9uLXBpY2tlclwiPjwvZGl2PicgK1xuICAgICAgJyA8ZGl2IGNsYXNzPVwiYWRkLWRpbWVuc2lvbi1waWNrZXJcIj48L2Rpdj4nICtcbiAgICAgICcgPGRpdiBjbGFzcz1cImFkZC1tZXRyaWMtcGlja2VyXCI+PC9kaXY+JyArXG4gICAgICAnIDxkaXYgY2xhc3M9XCJzZWFyY2gtd3JhcHBlclwiPicgK1xuICAgICAgJyAgIDxpbnB1dCBjbGFzcz1cInNlYXJjaFwiIHR5cGU9XCJ0ZXh0XCIgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIi8+JyArXG4gICAgICAnIDwvZGl2PicgK1xuICAgICAgJyA8ZGl2IGNsYXNzPVwiY2xlYXJmaXhcIj48L2Rpdj4nICtcbiAgICAgICc8L2Rpdj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwidGFibGUtd3JhcHBlclwiPicgK1xuICAgICAgJyA8dGFibGUgY2xhc3M9XCJqaW8gdGFibGVcIj4nICtcbiAgICAgICcgICA8dGhlYWQ+PC90aGVhZD4nICtcbiAgICAgICcgICA8dGJvZHk+PC90Ym9keT4nICtcbiAgICAgICcgPC90YWJsZT4nICtcbiAgICAgICc8L2Rpdj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwicGFnaW5nXCI+JyArXG4gICAgICAnIDxkaXYgY2xhc3M9XCJwYWdpbmctd3JhcHBlclwiPicgK1xuICAgICAgJyAgIDxkaXYgY2xhc3M9XCJwYWdlLXNpemVcIj4nICtcbiAgICAgICcgICAgIDxzcGFuIGNsYXNzPVwiY2FwdGlvblwiPlBhZ2Ugc2l6ZTogPC9zcGFuPicgK1xuICAgICAgJyAgICAgPHNlbGVjdD4nICtcbiAgICAgICcgICAgIDwvc2VsZWN0PicgK1xuICAgICAgJyAgIDwvZGl2PicgK1xuICAgICAgJyA8L2Rpdj4nICtcbiAgICAgICcgPGRpdiBjbGFzcz1cInNob3dpbmdcIj48L2Rpdj4nICtcbiAgICAgICcgPGRpdiBjbGFzcz1cIm5hdmlnYXRpb25cIj4nICtcbiAgICAgICcgICA8ZGl2IGNsYXNzPVwicHJldiBjaGV2cm9uIGxlZnRcIj48L2Rpdj4nICtcbiAgICAgICcgICA8ZGl2IGNsYXNzPVwibmV4dCBjaGV2cm9uIHJpZ2h0XCI+PC9kaXY+JyArXG4gICAgICAnIDwvZGl2PicgK1xuICAgICAgJzwvZGl2PicsXG4gICAgICBxdWVyeTogbnVsbCxcbiAgICAgIHN0cmluZ3M6IHtcbiAgICAgICAgbG9hZGluZzogJ05vIGRhdGEgYXZhaWxhYmxlLicsXG4gICAgICAgIG5vZGF0YTogJ05vIGRhdGEgYXZhaWxhYmxlLicsXG4gICAgICAgIG5vdF9zaG93bjogJ05vdCBzaG93bidcbiAgICAgIH0sXG4gICAgICBsaW1pdDogMTAsXG4gICAgICBoZWFkZXJzOiBmYWxzZSxcbiAgICAgIGluY2x1ZGVfbm90X3Nob3duOiB0cnVlLFxuICAgICAgc3VtbWFyeToge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICBwbGFjZW1lbnQ6ICd0b3AnXG4gICAgICB9XG4gICAgfTtcbiAgICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgICBpZiAoIXNlbGYub3B0aW9ucylcbiAgICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IFtvcHRpb25zXS4nO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5xdWVyeSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkgPSBbc2VsZi5vcHRpb25zLnF1ZXJ5XTtcblxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHRoaXMuZW50ZXIgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuXG4gICAgfVxuICAgIDtcbiAgICB0aGlzLmV4aXQgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuXG4gICAgfTtcbiAgICB0aGlzLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG5cbiAgICB9O1xuXG4gICAgdGhpcy5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgam9vbGEudml6LnN0b3Aoc2VsZik7XG4gICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBpbmRleCkge1xuICAgICAgICB2YXIgc3VtbWFyeSA9IHNlbGYuc3VtbWFyaWVzW2tleV07XG4gICAgICAgIHN1bW1hcnkuZGVzdHJveSgpO1xuICAgICAgfSk7XG5cbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3RhYmxlJykuZW1wdHkoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5maWx0ZXIgPSBmdW5jdGlvbiAoZGF0YSwgZmlsdGVyKSB7XG4gICAgICByZXR1cm4gXy5maWx0ZXIoZGF0YSwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIE9iamVjdC5rZXlzKGl0ZW0uZGltZW5zaW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgaWYgKGl0ZW0uZGltZW5zaW9uc1trZXldLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIudG9Mb3dlckNhc2UoKSkgPiAtMSlcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB0aGlzLnBhaW50ID0gZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeVswXTtcbiAgICAgIHZhciAkdGFibGUgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0YWJsZScpWzBdKTtcbiAgICAgIHZhciAkc2VhcmNoID0gJCQoJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnaW5wdXQuc2VhcmNoJylbMF0pO1xuICAgICAgdmFyICR0Ym9keSA9ICQkKCR0YWJsZS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICAgIGlmIChzZWxmLmRhdGFbMF0ubGVuZ3RoID4gMCB8fCAoc2VsZi5kYXRhLmxlbmd0aCA+IDEgJiYgc2VsZi5kYXRhWzFdLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICR0Ym9keS5maW5kKCd0ci5kYXRhLXJvdycpLnJlbW92ZSgpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG5cbiAgICAgIH1cblxuICAgICAgaWYgKHNlbGYuc29ydEluZGV4ID09PSAtMSkge1xuICAgICAgICBzZWxmLnNvcnRJbmRleCA9IHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmxlbmd0aCArIDE7XG4gICAgICAgIHNlbGYuc29ydERpciA9ICdkZXNjJztcbiAgICAgIH1cblxuICAgICAgdmFyIHN0YXJ0ID0gKChzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlIC0gMSkgKiBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplKSArIDE7XG4gICAgICB2YXIgbGVuZ3RoID0gc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50U2l6ZTtcbiAgICAgIHZhciBzZWFyY2gsIHRleHQ7XG4gICAgICBpZiAoc2VsZi5kYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICB2YXIgX2RhdGE7XG4gICAgICAgIHZhciBfdG90YWwgPSBbXTtcbiAgICAgICAgc2VhcmNoID0gJHNlYXJjaC52YWwoKTtcbiAgICAgICAgaWYgKHNlYXJjaCAmJiBzZWFyY2gubGVuZ3RoID4gMilcbiAgICAgICAgICBfZGF0YSA9IHNlbGYuZmlsdGVyKHNlbGYuZGF0YVswXSwgc2VhcmNoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIF9kYXRhID0gc2VsZi5kYXRhWzBdO1xuICAgICAgICBzZWxmLl9kYXRhID0gW107XG4gICAgICAgIHNlbGYuX2RhdGFbMF0gPSBfZGF0YS5zbGljZSgwKTtcbiAgICAgICAgX2RhdGEgPSBfZGF0YS5zbGljZShzdGFydCAtIDEsIChzdGFydCAtIDEpICsgbGVuZ3RoKTtcbiAgICAgICAgX2RhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgICAvL3dlIGhhdmUgYSBzaW1wbGUgcm93XG4gICAgICAgICAgdmFyICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgdmFyIGxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgX3F1ZXJ5LmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCwgZGkpIHtcbiAgICAgICAgICAgIGxhc3RJbmRleCsrO1xuICAgICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiPjxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgY2xhc3M9XCJmaWx0ZXJcIj4nICsgcG9pbnQuZGltZW5zaW9uc1tkaW1lbnNpb25rZXldICsgJzwvYT48L3RkPicpO1xuICAgICAgICAgICAgJHRkLmZpbmQoJy5maWx0ZXInKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnc2VsZWN0JywgcG9pbnQsIGRpbWVuc2lvbmtleSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChkaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICAgICAgICB2YXIgbWV0cmlja2V5ID0gbS5rZXkgfHwgbTtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljXCIgZGF0YS1rZXk9XCInICsgbWV0cmlja2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcG9pbnQubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiPicgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSwgcG9pbnQubWV0YVttZXRyaWNrZXldKSArICcnICtcbiAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInN1bW1hcnlcIj48L3NwYW4+JyArXG4gICAgICAgICAgICAnPC90ZD4nKTtcbiAgICAgICAgICAgIGlmIChsYXN0SW5kZXggKyBtaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc2VsZi5kYXRhLmxlbmd0aCA9PT0gMikge1xuICAgICAgICB2YXIgX2NvbXBhcmVxdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeVsxXTtcbiAgICAgICAgdmFyIGJhc2U7XG4gICAgICAgIHZhciBjb21wYXJlO1xuICAgICAgICBzZWFyY2ggPSAkc2VhcmNoLnZhbCgpO1xuICAgICAgICBpZiAoc2VhcmNoICYmIHNlYXJjaC5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgYmFzZSA9IHNlbGYuZmlsdGVyKHNlbGYuZGF0YVswXSwgc2VhcmNoKTtcbiAgICAgICAgICBjb21wYXJlID0gc2VsZi5maWx0ZXIoc2VsZi5kYXRhWzFdLCBzZWFyY2gpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGJhc2UgPSBzZWxmLmRhdGFbMF07XG4gICAgICAgICAgY29tcGFyZSA9IHNlbGYuZGF0YVsxXTtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLl9kYXRhID0gW107XG4gICAgICAgIHNlbGYuX2RhdGFbMF0gPSBzZWxmLmRhdGFbMF0uc2xpY2UoMCk7XG4gICAgICAgIHNlbGYuX2RhdGFbMV0gPSBzZWxmLmRhdGFbMV0uc2xpY2UoMCk7XG4gICAgICAgIGJhc2UgPSBiYXNlLnNsaWNlKHN0YXJ0IC0gMSwgKHN0YXJ0IC0gMSkgKyBsZW5ndGgpO1xuICAgICAgICB2YXIgaGFuZGxlZCA9IFtdO1xuICAgICAgICBiYXNlLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICAgIGhhbmRsZWQucHVzaChwb2ludC5rZXkpO1xuICAgICAgICAgIHZhciAkdHIgPSAkJCgnPHRyIGNsYXNzPVwiZGF0YS1yb3dcIiBkYXRhLWlkPVwiJyArIHBvaW50LmtleSArICdcIj48L3RyPicpO1xuICAgICAgICAgIHZhciBsYXN0SW5kZXggPSAwO1xuICAgICAgICAgIF9xdWVyeS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQsIGRpKSB7XG4gICAgICAgICAgICB2YXIgZGltZW5zaW9ua2V5ID0gZC5rZXkgfHwgZDtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgZGltZW5zaW9uXCI+PGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiBjbGFzcz1cImZpbHRlclwiPicgKyBwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gKyAnPC9hPjwvdGQ+Jyk7XG4gICAgICAgICAgICBsYXN0SW5kZXgrKztcbiAgICAgICAgICAgIGlmIChkaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgICAkdGQuZmluZCgnLmZpbHRlcicpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdzZWxlY3QnLCBwb2ludCwgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIG1ldHJpYyBlbXB0eVwiPjwvdGQ+Jyk7XG4gICAgICAgICAgICBpZiAobGFzdEluZGV4ICsgbWkgPT09IHNlbGYuc29ydEluZGV4KVxuICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcblxuICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfcXVlcnkudGltZWZyYW1lLnN0YXJ0KSArICcgLSAnO1xuICAgICAgICAgIHRleHQgKz0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3F1ZXJ5LnRpbWVmcmFtZS5lbmQpO1xuICAgICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBkaW1lbnNpb25cIiBjb2xzcGFuPVwiJyArIF9xdWVyeS5kaW1lbnNpb25zLmxlbmd0aCArICdcIj4nICsgdGV4dCArICc8L3RkPicpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcblxuICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICBsYXN0SW5kZXggPSBfcXVlcnkuZGltZW5zaW9ucy5sZW5ndGg7XG4gICAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSwgbWkpIHtcbiAgICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWNcIiBkYXRhLWtleT1cIicgKyBtZXRyaWNrZXkgKyAnXCIgZGF0YS12YWx1ZT1cIicgKyBwb2ludC5tZXRyaWNzW21ldHJpY2tleV0gKyAnXCI+JyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMocG9pbnQubWV0cmljc1ttZXRyaWNrZXldLCBwb2ludC5tZXRhW21ldHJpY2tleV0pICsgJycgK1xuICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic3VtbWFyeVwiPjwvc3Bhbj4nICtcbiAgICAgICAgICAgICc8L3RkPicpO1xuICAgICAgICAgICAgaWYgKGxhc3RJbmRleCArIG1pID09PSBzZWxmLnNvcnRJbmRleClcbiAgICAgICAgICAgICAgJHRkLmFkZENsYXNzKCdzb3J0ZWQnKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHZhciBjb21wYXJlUG9pbnQgPSBjb21wYXJlW2luZGV4XTtcbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX2NvbXBhcmVxdWVyeS50aW1lZnJhbWUuc3RhcnQpICsgJyAtICc7XG4gICAgICAgICAgdGV4dCArPSBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfY29tcGFyZXF1ZXJ5LnRpbWVmcmFtZS5lbmQpO1xuICAgICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgKGNvbXBhcmVQb2ludCA/IGNvbXBhcmVQb2ludC5rZXkgOiAnbWlzc2luZycpICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPicgKyB0ZXh0ICsgJzwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuXG4gICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICAgICAgICB2YXIgbWV0cmlja2V5ID0gbS5rZXkgfHwgbTtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljIGNvbXBhcmVcIiBkYXRhLWtleT1cIicgKyBtZXRyaWNrZXkgKyAnXCIgZGF0YS12YWx1ZT1cIicgKyAoY29tcGFyZVBvaW50ID8gY29tcGFyZVBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSA6ICdOL0EnKSArICdcIj4nICsgKGNvbXBhcmVQb2ludCA/IGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoY29tcGFyZVBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSwgY29tcGFyZVBvaW50Lm1ldGFbbWV0cmlja2V5XSkgOiAnTi9BJykgKyAnJyArXG4gICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPjwvdGQ+Jyk7XG4gICAgICAgICAgICBpZiAobGFzdEluZGV4ICsgbWkgPT09IHNlbGYuc29ydEluZGV4KVxuICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyBwb2ludC5rZXkgKyAnXCI+PC90cj4nKTtcbiAgICAgICAgICAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiY2FwdGlvbiBjaGFuZ2VcIiBjb2xzcGFuPVwiJyArIF9xdWVyeS5kaW1lbnNpb25zLmxlbmd0aCArICdcIj4lIENoYW5nZTwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuXG4gICAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSwgbWkpIHtcbiAgICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBjaGFuZ2VcIj4nICsgKHBvaW50ICYmIGNvbXBhcmVQb2ludCA/IGpvb2xhLmNvbW1vbi5wZXJjZW50YWdlQ2hhbmdlKGNvbXBhcmVQb2ludC5tZXRyaWNzW21ldHJpY2tleV0sIHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSkgOiAnTi9BJykgKyAnJTwvdGQ+Jyk7XG4gICAgICAgICAgICBpZiAobGFzdEluZGV4ICsgbWkgPT09IHNlbGYuc29ydEluZGV4KVxuICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29tcGFyZS5mb3JFYWNoKGZ1bmN0aW9uIChjb21wYXJlUG9pbnQsIGluZGV4KSB7XG4gICAgICAgICAgaWYgKGhhbmRsZWQuaW5kZXhPZihjb21wYXJlUG9pbnQua2V5KSA9PT0gLTEpIHtcbiAgICAgICAgICAgIHZhciAkdHIgPSAkJCgnPHRyIGNsYXNzPVwiZGF0YS1yb3dcIiBkYXRhLWlkPVwiJyArIGNvbXBhcmVQb2ludC5rZXkgKyAnXCI+PC90cj4nKTtcbiAgICAgICAgICAgIF9xdWVyeS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgZGltZW5zaW9uXCI+PGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiBjbGFzcz1cImZpbHRlclwiPicgKyBjb21wYXJlUG9pbnQuZGltZW5zaW9uc1tkaW1lbnNpb25rZXldICsgJzwvYT48L3RkPicpO1xuICAgICAgICAgICAgICAkdGQuZmluZCgnLmZpbHRlcicpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3NlbGVjdCcsIGNvbXBhcmVQb2ludCwgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIG1ldHJpYyBlbXB0eVwiPjwvdGQ+Jyk7XG4gICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuXG4gICAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3F1ZXJ5LnRpbWVmcmFtZS5zdGFydCkgKyAnIC0gJztcbiAgICAgICAgICAgIHRleHQgKz0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3F1ZXJ5LnRpbWVmcmFtZS5lbmQpO1xuICAgICAgICAgICAgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyBjb21wYXJlUG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPicgKyB0ZXh0ICsgJzwvdGQ+Jyk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG5cbiAgICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgdmFyIG1ldHJpY2tleSA9IG0ua2V5IHx8IG07XG4gICAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljXCIgZGF0YS1rZXk9XCInICsgbWV0cmlja2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgJ04vQScgKyAnXCI+JyArICdOL0EnICsgJycgK1xuICAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPicgK1xuICAgICAgICAgICAgICAnPC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfY29tcGFyZXF1ZXJ5LnRpbWVmcmFtZS5zdGFydCkgKyAnIC0gJztcbiAgICAgICAgICAgIHRleHQgKz0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX2NvbXBhcmVxdWVyeS50aW1lZnJhbWUuZW5kKTtcbiAgICAgICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgKGNvbXBhcmVQb2ludCA/IGNvbXBhcmVQb2ludC5rZXkgOiAnbWlzc2luZycpICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgICAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgZGltZW5zaW9uXCIgY29sc3Bhbj1cIicgKyBfcXVlcnkuZGltZW5zaW9ucy5sZW5ndGggKyAnXCI+JyArIHRleHQgKyAnPC90ZD4nKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcblxuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgICB2YXIgbWV0cmlja2V5ID0gbS5rZXkgfHwgbTtcbiAgICAgICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWMgY29tcGFyZVwiIGRhdGEta2V5PVwiJyArIG1ldHJpY2tleSArICdcIiBkYXRhLXZhbHVlPVwiJyArIChjb21wYXJlUG9pbnQgPyBjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldIDogJ04vQScpICsgJ1wiPicgKyAoY29tcGFyZVBvaW50ID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldLCBjb21wYXJlUG9pbnQubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcnICtcbiAgICAgICAgICAgICAgJzxzcGFuIGNsYXNzPVwic3VtbWFyeVwiPjwvc3Bhbj48L3RkPicpO1xuICAgICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyBjb21wYXJlUG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgICAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiY2FwdGlvbiBjaGFuZ2VcIiBjb2xzcGFuPVwiJyArIF9xdWVyeS5kaW1lbnNpb25zLmxlbmd0aCArICdcIj4lIENoYW5nZTwvdGQ+Jyk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG5cbiAgICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgdmFyIG1ldHJpY2tleSA9IG0ua2V5IHx8IG07XG4gICAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgY2hhbmdlXCI+Ti9BPC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc2VsZi5oYW5kbGVIZWFkZXJzKCk7XG4gICAgICBzZWxmLnN1bW1hcml6ZSgpO1xuICAgICAgc2VsZi5oYW5kbGVQYWdpbmcoKTtcbiAgICB9O1xuXG4gICAgdGhpcy5kb25lID0gZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5wYWludCgpO1xuICAgIH07XG5cbiAgICB0aGlzLmhhbmRsZUhlYWRlcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgbGFzdEluZGV4ID0gMDtcbiAgICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQsIGkpIHtcbiAgICAgICAgdmFyIG5hbWUgPSBkLm5hbWUgfHwgZC5rZXkgfHwgZDtcbiAgICAgICAgdmFyICR0aCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJ3RhYmxlIHRoJylbaV0pO1xuICAgICAgICBpZiAoISR0aC5oYXNDbGFzcygnZGltZW5zaW9uJykpIHtcbiAgICAgICAgICAkdGguYWZ0ZXIoJHRoLmNsb25lKHRydWUpKTtcbiAgICAgICAgfVxuICAgICAgICAkdGguZmluZCgnLm5hbWUnKS50ZXh0KG5hbWUpO1xuICAgICAgICBpZiAoIWQuZGVzY3JpcHRpb24pXG4gICAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5oaWRlKCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwJykuc2hvdygpO1xuICAgICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwIHNwYW4nKS50ZXh0KGQuZGVzY3JpcHRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RJbmRleCsrO1xuICAgICAgfSk7XG4gICAgICBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtLCBpKSB7XG4gICAgICAgIHZhciBuYW1lID0gbS5uYW1lIHx8IG0ua2V5IHx8IG07XG4gICAgICAgIHZhciAkdGggPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCd0YWJsZSB0aCcpW2kgKyBsYXN0SW5kZXhdKTtcbiAgICAgICAgaWYgKCFtLmRlc2NyaXB0aW9uKVxuICAgICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwJykuaGlkZSgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24taGVscCcpLnNob3coKTtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24taGVscCBzcGFuJykudGV4dChtLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAkdGguZmluZCgnLm5hbWUnKS50ZXh0KG5hbWUpO1xuICAgICAgfSk7XG5cbiAgICAgIHZhciAkaHRtbCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgdmFyICR0aGVhZCA9ICQkKCRodG1sLmZpbmQoJ3RoZWFkJykpO1xuICAgICAgdmFyICRoZWFkX3RyID0gJCQoJzx0ciBjbGFzcz1cImNhcHRpb25zXCI+PC90cj4nKTtcbiAgICAgIGxhc3RJbmRleCA9IDA7XG4gICAgICBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkLCBkaSkge1xuICAgICAgICBsYXN0SW5kZXgrKztcbiAgICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJjYXB0aW9uIGRpbWVuc2lvblwiPjxzcGFuIGNsYXNzPVwibmFtZVwiPjwvc3Bhbj48c3BhbiBjbGFzcz1cImljb24taGVscFwiPjxzcGFuPjwvc3Bhbj48L3NwYW4+PHNwYW4gY2xhc3M9XCJpY29uLWNsb3NlXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwiY2FyZXQtc29ydFwiPjwvc3Bhbj48L3RoPicpO1xuICAgICAgICAkdGguZmluZCgnLm5hbWUnKS50ZXh0KGQubmFtZSB8fCBkLmtleSB8fCBkKTtcbiAgICAgICAgaWYgKGQuYWxsb3dyZW1vdmUpIHtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24tY2xvc2UnKS5vZmYoJ2NsaWNrJyk7XG4gICAgICAgICAgJHRoLmZpbmQoJy5pY29uLWNsb3NlJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgcS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGl0ZW0sIGkpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5rZXkgPT09IGQua2V5KVxuICAgICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpXG4gICAgICAgICAgICAgICAgcS5kaW1lbnNpb25zLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICAgICAgICBzZWxmLnNvcnRJbmRleC0tO1xuICAgICAgICAgICAgc2VsZi5oYW5kbGVNZXRyaWNCb3hlcygpO1xuICAgICAgICAgICAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgJHRoLmZpbmQoJy5pY29uLWNsb3NlJykucmVtb3ZlKCk7XG4gICAgICAgIGlmICghZC5kZXNjcmlwdGlvbilcbiAgICAgICAgICAkdGguZmluZCgnLmljb24taGVscCcpLmhpZGUoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5zaG93KCk7XG4gICAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAgc3BhbicpLnRleHQoZC5kZXNjcmlwdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIH0pO1xuICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0LWRpcicsIG51bGwpO1xuICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0JywgbnVsbCk7XG4gICAgICAgICR0aC5maW5kKCcuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtZGVzYycpO1xuICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5yZW1vdmVDbGFzcygnaWNvbi1zb3J0LWFzYycpO1xuICAgICAgICBpZiAoZGkgPT09IHNlbGYuc29ydEluZGV4KSB7XG4gICAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydCcsIHRydWUpO1xuICAgICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJywgc2VsZi5zb3J0RGlyKTtcbiAgICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5hZGRDbGFzcygnaWNvbi1zb3J0LScgKyBzZWxmLnNvcnREaXIpO1xuICAgICAgICB9XG4gICAgICAgICR0aC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2VsZi5zb3J0SW5kZXggPSBkaTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBpbmRleCkge1xuICAgICAgICAgICAgdmFyIHN1bW1hcnkgPSBzZWxmLnN1bW1hcmllc1trZXldO1xuICAgICAgICAgICAgc3VtbWFyeS5vcHRpb25zLiRjb250YWluZXIucmVtb3ZlQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgc2VsZi5kYXRhWzBdID0gXy5zb3J0Qnkoc2VsZi5kYXRhWzBdLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW0uZGltZW5zaW9uc1tkLmtleSB8fCBkXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB2YXIgc29ydERpciA9ICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJykgfHwgJ2Rlc2MnO1xuICAgICAgICAgIGlmIChzb3J0RGlyID09PSAnZGVzYycpIHtcbiAgICAgICAgICAgIHNvcnREaXIgPSAnYXNjJztcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzZWxmLmRhdGFbMF0gPSBfLnNvcnRCeShzZWxmLmRhdGFbMF0sIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgIHJldHVybiBpdGVtLmRpbWVuc2lvbnNbZC5rZXkgfHwgZF07XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlbGYuZGF0YVswXS5yZXZlcnNlKCk7XG4gICAgICAgICAgICBzb3J0RGlyID0gJ2Rlc2MnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzZWxmLnNvcnREaXIgPSBzb3J0RGlyO1xuICAgICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoJykuYXR0cignZGF0YS1zb3J0LWRpcicsIG51bGwpO1xuICAgICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoJykuYXR0cignZGF0YS1zb3J0JywgbnVsbCk7XG4gICAgICAgICAgJGhlYWRfdHIuZmluZCgndGggLmNhcmV0LXNvcnQnKS5yZW1vdmVDbGFzcygnaWNvbi1zb3J0LWRlc2MnKTtcbiAgICAgICAgICAkaGVhZF90ci5maW5kKCd0aCAuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtYXNjJyk7XG4gICAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydCcsIHRydWUpO1xuICAgICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJywgc2VsZi5zb3J0RGlyKTtcbiAgICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5hZGRDbGFzcygnaWNvbi1zb3J0LScgKyBzZWxmLnNvcnREaXIpO1xuICAgICAgICAgIHNlbGYucGFpbnQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgICRoZWFkX3RyLmFwcGVuZCgkdGgpO1xuICAgICAgfSk7XG4gICAgICBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtLCBtaSkge1xuICAgICAgICB2YXIgJHRoID0gJCQoJzx0aCBjbGFzcz1cImNhcHRpb24gbWV0cmljXCI+PHNwYW4gY2xhc3M9XCJuYW1lXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwiaWNvbi1oZWxwXCI+PHNwYW4+PC9zcGFuPjwvc3Bhbj48c3BhbiBjbGFzcz1cImljb24tY2xvc2VcIj48L3NwYW4+PHNwYW4gY2xhc3M9XCJjYXJldC1zb3J0XCI+PC9zcGFuPjwvdGg+Jyk7XG4gICAgICAgICR0aC5maW5kKCcubmFtZScpLnRleHQobS5uYW1lIHx8IG0ua2V5IHx8IG0pO1xuICAgICAgICBpZiAobS5hbGxvd3JlbW92ZSkge1xuICAgICAgICAgICR0aC5maW5kKCcuaWNvbi1jbG9zZScpLm9mZignY2xpY2snKTtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24tY2xvc2UnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxKSB7XG4gICAgICAgICAgICAgIHZhciBpbmRleCA9IC0xO1xuICAgICAgICAgICAgICBxLm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICAgICAgICAgIGlmIChpdGVtLmtleSA9PT0gbS5rZXkpXG4gICAgICAgICAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBpZiAoaW5kZXggPiAtMSlcbiAgICAgICAgICAgICAgICBxLm1ldHJpY3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIF9zdW1tYXJpZXMgPSB7fTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHNlbGYuc3VtbWFyaWVzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgaXRlbSA9IHNlbGYuc3VtbWFyaWVzW2tleV07XG4gICAgICAgICAgICAgIGlmICgoaXRlbS5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbMF0ua2V5IHx8IGl0ZW0ub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzWzBdKSA9PT0gbS5rZXkpIHtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgX3N1bW1hcmllc1trZXldID0gc2VsZi5zdW1tYXJpZXNba2V5XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VsZi5zdW1tYXJpZXMgPSBfc3VtbWFyaWVzO1xuICAgICAgICAgICAgc2VsZi5kYXRhID0gW107XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlID0gMTtcbiAgICAgICAgICAgIHNlbGYuc29ydEluZGV4LS07XG4gICAgICAgICAgICBzZWxmLmhhbmRsZU1ldHJpY0JveGVzKCk7XG4gICAgICAgICAgICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBzZWxmLm9wdGlvbnMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAkdGguZmluZCgnLmljb24tY2xvc2UnKS5yZW1vdmUoKTtcbiAgICAgICAgaWYgKCFtLmRlc2NyaXB0aW9uKVxuICAgICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwJykuaGlkZSgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24taGVscCcpLnNob3coKTtcbiAgICAgICAgICAkdGguZmluZCgnLmljb24taGVscCBzcGFuJykudGV4dChtLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZi5zb3J0SW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgc2VsZi5zb3J0SW5kZXggPSBsYXN0SW5kZXg7XG4gICAgICAgICAgc2VsZi5zb3J0RGlyID0gJ2Rlc2MnO1xuICAgICAgICB9XG5cbiAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInLCBudWxsKTtcbiAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydCcsIG51bGwpO1xuICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5yZW1vdmVDbGFzcygnaWNvbi1zb3J0LWRlc2MnKTtcbiAgICAgICAgJHRoLmZpbmQoJy5jYXJldC1zb3J0JykucmVtb3ZlQ2xhc3MoJ2ljb24tc29ydC1hc2MnKTtcbiAgICAgICAgaWYgKGxhc3RJbmRleCArIG1pID09PSBzZWxmLnNvcnRJbmRleCkge1xuICAgICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQnLCB0cnVlKTtcbiAgICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0LWRpcicsIHNlbGYuc29ydERpcik7XG4gICAgICAgICAgJHRoLmZpbmQoJy5jYXJldC1zb3J0JykuYWRkQ2xhc3MoJ2ljb24tc29ydC0nICsgc2VsZi5zb3J0RGlyKTtcbiAgICAgICAgfVxuXG4gICAgICAgICR0aC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgc2VsZi5zb3J0SW5kZXggPSBsYXN0SW5kZXggKyBtaTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICB2YXIgc3VtbWFyeSA9IHNlbGYuc3VtbWFyaWVzW2tleV07XG4gICAgICAgICAgICBzdW1tYXJ5Lm9wdGlvbnMuJGNvbnRhaW5lci5yZW1vdmVDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgICBpZiAoa2V5ID09PSAobS5rZXkgfHwgbSkpXG4gICAgICAgICAgICAgIHN1bW1hcnkub3B0aW9ucy4kY29udGFpbmVyLmFkZENsYXNzKCdzb3J0ZWQnKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzZWxmLmRhdGFbMF0gPSBfLnNvcnRCeShzZWxmLmRhdGFbMF0sIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICByZXR1cm4gaXRlbS5tZXRyaWNzW20ua2V5IHx8IG1dO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHZhciBzb3J0RGlyID0gJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInKSB8fCAnZGVzYyc7XG4gICAgICAgICAgaWYgKHNvcnREaXIgPT09ICdkZXNjJykge1xuICAgICAgICAgICAgc29ydERpciA9ICdhc2MnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuZGF0YVswXSA9IF8uc29ydEJ5KHNlbGYuZGF0YVswXSwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0ubWV0cmljc1ttLmtleSB8fCBtXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VsZi5kYXRhWzBdLnJldmVyc2UoKTtcbiAgICAgICAgICAgIHNvcnREaXIgPSAnZGVzYyc7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlbGYuc29ydERpciA9IHNvcnREaXI7XG4gICAgICAgICAgJGhlYWRfdHIuZmluZCgndGgnKS5hdHRyKCdkYXRhLXNvcnQtZGlyJywgbnVsbCk7XG4gICAgICAgICAgJGhlYWRfdHIuZmluZCgndGgnKS5hdHRyKCdkYXRhLXNvcnQnLCBudWxsKTtcbiAgICAgICAgICAkaGVhZF90ci5maW5kKCd0aCAuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtZGVzYycpO1xuICAgICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoIC5jYXJldC1zb3J0JykucmVtb3ZlQ2xhc3MoJ2ljb24tc29ydC1hc2MnKTtcbiAgICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0JywgdHJ1ZSk7XG4gICAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInLCBzZWxmLnNvcnREaXIpO1xuICAgICAgICAgICR0aC5maW5kKCcuY2FyZXQtc29ydCcpLmFkZENsYXNzKCdpY29uLXNvcnQtJyArIHNlbGYuc29ydERpcik7XG4gICAgICAgICAgc2VsZi5wYWludCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgJGhlYWRfdHIuYXBwZW5kKCR0aCk7XG4gICAgICB9KTtcbiAgICAgICR0aGVhZC5odG1sKCRoZWFkX3RyKTtcbiAgICAgICRodG1sLmZpbmQoJ3RhYmxlIHRib2R5JykuYmVmb3JlKCR0aGVhZCk7XG4gICAgfTtcblxuICAgIHRoaXMuaGFuZGxlTWV0cmljQm94ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJGh0bWwgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIHZhciAkdGJvZHkgPSAkaHRtbC5maW5kKCd0Ym9keScpO1xuICAgICAgJHRib2R5ID0gJCQoJHRib2R5KTtcbiAgICAgIHZhciAkbWV0cmljX3RyID0gJCQoJzx0ciBjbGFzcz1cIm1ldHJpY2JveGVzXCI+PC90cj4nKTtcbiAgICAgIHZhciBsYXN0SW5kZXggPSAwO1xuICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cIm1ldHJpY2JveCBkaW1lbnNpb25cIj48L3RkPicpO1xuICAgICAgICAkbWV0cmljX3RyLmFwcGVuZCgkdGQpO1xuICAgICAgICBsYXN0SW5kZXgrKztcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgYXN5bmMubWFwU2VyaWVzKHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLCBmdW5jdGlvbiAobSwgY2IpIHtcbiAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJtZXRyaWNib3ggbWV0cmljXCI+PC90ZD4nKTtcbiAgICAgICAgJG1ldHJpY190ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgdmFyIF9xdWVyeSA9IGNlLmNsb25lKHNlbGYub3B0aW9ucy5xdWVyeSk7XG4gICAgICAgIF9xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxKSB7XG4gICAgICAgICAgcS5kaW1lbnNpb25zID0gW107XG4gICAgICAgICAgcS5tZXRyaWNzID0gW21dO1xuICAgICAgICAgIGlmICghcS5maWx0ZXIpXG4gICAgICAgICAgICBxLmZpbHRlciA9IFtdO1xuICAgICAgICAgIGlmIChxLmZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB2YXIgX3EgPSBjZS5jbG9uZShxKTtcbiAgICAgICAgICAgIF9xLmZpbHRlciA9IFtdO1xuICAgICAgICAgICAgX3EudHlwZSA9ICdvdmVyYWxsJztcbiAgICAgICAgICAgIF9xdWVyeS5wdXNoKF9xKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghc2VsZi5zdW1tYXJpZXMpXG4gICAgICAgICAgc2VsZi5zdW1tYXJpZXMgPSB7fTtcbiAgICAgICAgc2VsZi5zdW1tYXJpZXNbbS5rZXldID0gbmV3IGpvb2xhLnZpei5NZXRyaWMoe1xuICAgICAgICAgIGNvbnRhaW5lcjogJHRkLmdldCgwKSxcbiAgICAgICAgICBjc3M6IGxhc3RJbmRleCArIGluZGV4ID09PSBzZWxmLnNvcnRJbmRleCA/ICdzb3J0ZWQnIDogJycsXG4gICAgICAgICAgcXVlcnk6IF9xdWVyeVxuICAgICAgICB9KTtcbiAgICAgICAgc2VsZi5zdW1tYXJpZXNbbS5rZXldLm9uKCdkb25lJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHNlbGYuc3VtbWFyaWVzW20ua2V5XS5vcHRpb25zLiRjb250YWluZXIuYWRkQ2xhc3MobGFzdEluZGV4ICsgaW5kZXggPT09IHNlbGYuc29ydEluZGV4ID8gJ3NvcnRlZCcgOiAnJyk7XG4gICAgICAgICAgc2VsZi5zdW1tYXJpemUoKTtcbiAgICAgICAgICByZXR1cm4gY2IobnVsbCk7XG4gICAgICAgIH0pO1xuICAgICAgICBpbmRleCsrO1xuICAgICAgfSwgZnVuY3Rpb24gKGVyciwgcmVzdWx0cykge1xuICAgICAgfSk7XG4gICAgICBpZiAoJHRib2R5LmZpbmQoJy5tZXRyaWNib3hlcycpLmxlbmd0aCA+IDApXG4gICAgICAgICR0Ym9keS5maW5kKCcubWV0cmljYm94ZXMnKS5yZXBsYWNlV2l0aCgkbWV0cmljX3RyKTtcbiAgICAgIGVsc2VcbiAgICAgICAgJCQoJHRib2R5LmZpbmQoJ3RyLmRhdGEtcm93JylbMF0pLmJlZm9yZSgkbWV0cmljX3RyKTtcbiAgICB9O1xuXG4gICAgdGhpcy5oYW5kbGVQYWdpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgJHNob3dpbmcgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuc2hvd2luZycpKTtcblxuICAgICAgdmFyIHRvdGFsID0gc2VsZi5fZGF0YVswXS5sZW5ndGg7XG4gICAgICB2YXIgdG8gPSBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlICogc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50U2l6ZTtcbiAgICAgIGlmICh0byA+IHRvdGFsKVxuICAgICAgICB0byA9IHRvdGFsO1xuICAgICAgdmFyIHNob3dpbmdUZXh0ID0gKChzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlIC0gMSkgKiBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplICsgMSkgKyAnIC0gJyArIHRvICsgJyBvZiAnICsgdG90YWw7XG5cbiAgICAgICRzaG93aW5nLnRleHQoc2hvd2luZ1RleHQpO1xuXG4gICAgICB2YXIgJHByZXYgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcucHJldicpKTtcbiAgICAgIHZhciAkbmV4dCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5uZXh0JykpO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPiAxKSB7XG4gICAgICAgICRwcmV2LnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkcHJldi5vZmYoJ2NsaWNrJyk7XG4gICAgICAgICRwcmV2Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA+IDEpIHtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UtLTtcbiAgICAgICAgICAgIHNlbGYucGFpbnQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICRwcmV2LmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkcHJldi5vZmYoJ2NsaWNrJyk7XG4gICAgICB9XG4gICAgICB2YXIgbmV4dEluZGV4ID0gKChzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlICkgKiBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplKTtcbiAgICAgIGlmIChuZXh0SW5kZXggPCBzZWxmLl9kYXRhWzBdLmxlbmd0aCkge1xuICAgICAgICAkbmV4dC5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJG5leHQub2ZmKCdjbGljaycpO1xuICAgICAgICAkbmV4dC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdmFyIG5leHRJbmRleCA9ICgoc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSApICogc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50U2l6ZSk7XG4gICAgICAgICAgaWYgKG5leHRJbmRleCA8IHNlbGYuX2RhdGFbMF0ubGVuZ3RoKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlKys7XG4gICAgICAgICAgICBzZWxmLnBhaW50KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkbmV4dC5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJG5leHQub2ZmKCdjbGljaycpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLnNvcnQgPSBmdW5jdGlvbiAoKSB7XG5cbiAgICB9O1xuXG4gICAgdGhpcy5zdW1tYXJpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBtaW5kZXgpIHtcbiAgICAgICAgdmFyIHJlZiA9IHNlbGYuc3VtbWFyaWVzW2tleV07XG4gICAgICAgIHZhciBtID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbbWluZGV4XTtcblxuICAgICAgICBpZiAoKG0uYWdncmVnYXRpb24gfHwgJ3N1bScpID09PSAnc3VtJyAmJiByZWYuZGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFyIHRvdGFsLCBjb21wYXJldG90YWw7XG4gICAgICAgICAgaWYgKHJlZi5kYXRhWzBdLmxlbmd0aCA+IDApXG4gICAgICAgICAgICB0b3RhbCA9IHJlZi5kYXRhWzBdWzBdLm1ldHJpY3NbbS5rZXldO1xuICAgICAgICAgIGlmIChyZWYuZGF0YS5sZW5ndGggPiAxICYmIHJlZi5kYXRhWzFdLmxlbmd0aCA+IDAgJiYgcmVmLmRhdGFbMV0udHlwZSAhPT0gJ292ZXJhbGwnKSB7XG4gICAgICAgICAgICBjb21wYXJldG90YWwgPSByZWYuZGF0YVsxXVswXS5tZXRyaWNzW20ua2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyICRzdW1tYXJpZXMgPSAkJCgnLnZhbHVlLm1ldHJpY1tkYXRhLWtleT1cIicgKyBtLmtleSArICdcIl0nKTtcbiAgICAgICAgICAkc3VtbWFyaWVzLmVhY2goZnVuY3Rpb24gKGluZGV4LCBzdW1tYXJ5KSB7XG4gICAgICAgICAgICB2YXIgJHN1bW1hcnkgPSAkJChzdW1tYXJ5KTtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9ICRzdW1tYXJ5LmF0dHIoJ2RhdGEtdmFsdWUnKTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ04vQScpIHtcbiAgICAgICAgICAgICAgJHN1bW1hcnkuZmluZCgnc3Bhbi5zdW1tYXJ5JykudGV4dCgnIChOL0EpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCRzdW1tYXJ5Lmhhc0NsYXNzKCdjb21wYXJlJykpXG4gICAgICAgICAgICAgICAgdmFsdWUgPSAodmFsdWUgLyBjb21wYXJldG90YWwgKiAxMDApLnRvRml4ZWQoMikgKyAnJSc7XG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAvIHRvdGFsICogMTAwKS50b0ZpeGVkKDIpICsgJyUnO1xuICAgICAgICAgICAgICAkc3VtbWFyeS5maW5kKCdzcGFuLnN1bW1hcnknKS50ZXh0KCcgKCcgKyB2YWx1ZSArICcpJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgICAgLy93ZSBkcmF3IHRoZSB0ZW1wbGF0ZSBpbnRvIHRoZSBjb250YWluZXJcbiAgICAgIHZhciAkaHRtbCA9ICQkKHNlbGYub3B0aW9ucy50ZW1wbGF0ZSk7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5odG1sKCRodG1sKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbilcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnRhYmxlLWNhcHRpb24nKS50ZXh0KHNlbGYub3B0aW9ucy5jYXB0aW9uKTtcbiAgICAgIC8vdmlzdWFsaXphdGlvbiBzcGVjaWZpYyBkcmF3aW5nXG4gICAgICBpZiAoc2VsZi5vcHRpb25zLnBpY2tlcnMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMucHJpbWFyeSAmJiBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmVuYWJsZWQpIHtcbiAgICAgICAgdmFyICRwcmltYXJ5X2RpbWVuc2lvbl9waWNrZXIgPSAkJCgkaHRtbC5maW5kKCcucHJpbWFyeS1kaW1lbnNpb24tcGlja2VyJykpO1xuICAgICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmNzcyA9ICd0YWJsZS1waWNrZXInO1xuICAgICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmNvbnRhaW5lciA9ICRwcmltYXJ5X2RpbWVuc2lvbl9waWNrZXIuZ2V0KDApO1xuICAgICAgICB2YXIgZGltZW5zaW9uID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnNbMF07XG4gICAgICAgIGlmICghZGltZW5zaW9uLmtleSlcbiAgICAgICAgICBkaW1lbnNpb24gPSB7a2V5OiBkaW1lbnNpb259O1xuICAgICAgICBpZiAoIWRpbWVuc2lvbi5jb2xsZWN0aW9uKVxuICAgICAgICAgIGRpbWVuc2lvbi5jb2xsZWN0aW9uID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmNvbGxlY3Rpb247XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLnByaW1hcnkuc2VsZWN0ZWQgPSBkaW1lbnNpb247XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLnByaW1hcnkuZGlzYWJsZWQgPSBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucztcbiAgICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMucHJpbWFyeS5wcmVmaXggPSAnUHJpbWFyeSBkaW1lbnNpb246ICc7XG4gICAgICAgIHNlbGYucHJpbWFyeV9kaW1lbnNpb25fcGlja2VyID0gbmV3IGpvb2xhLnZpei5EaW1lbnNpb25QaWNrZXIoc2VsZi5vcHRpb25zLnBpY2tlcnMucHJpbWFyeSkub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChkaW1lbnNpb24pIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgICAgaWYgKGRpbWVuc2lvbilcbiAgICAgICAgICAgICAgcS5kaW1lbnNpb25zWzBdID0gZGltZW5zaW9uO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBxLmRpbWVuc2lvbnMuc3BsaWNlKDAsIDEpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24gJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5lbmFibGVkKSB7XG4gICAgICAgIHZhciAkYWRkX2RpbWVuc2lvbl9waWNrZXIgPSAkJCgkaHRtbC5maW5kKCcuYWRkLWRpbWVuc2lvbi1waWNrZXInKSk7XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24uY3NzID0gJ3RhYmxlLXBpY2tlcic7XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24uY29udGFpbmVyID0gJGFkZF9kaW1lbnNpb25fcGlja2VyLmdldCgwKTtcbiAgICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5jYXB0aW9uID0gc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5jYXB0aW9uIHx8ICdBZGQgZGltZW5zaW9uLi4uJztcbiAgICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5kaXNhYmxlZCA9IHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zO1xuICAgICAgICBzZWxmLmFkZF9kaW1lbnNpb25fcGlja2VyID0gbmV3IGpvb2xhLnZpei5EaW1lbnNpb25QaWNrZXIoc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbikub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChkaW1lbnNpb24pIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgICAgaWYgKGRpbWVuc2lvbikge1xuICAgICAgICAgICAgICBkaW1lbnNpb24uYWxsb3dyZW1vdmUgPSB0cnVlO1xuICAgICAgICAgICAgICBxLmRpbWVuc2lvbnMucHVzaChkaW1lbnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICAgIHNlbGYuc29ydEluZGV4Kys7XG4gICAgICAgICAgc2VsZi5oYW5kbGVNZXRyaWNCb3hlcygpO1xuICAgICAgICAgIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9tZXRyaWMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5lbmFibGVkKSB7XG4gICAgICAgIHZhciAkYWRkX21ldHJpY19waWNrZXIgPSAkJCgkaHRtbC5maW5kKCcuYWRkLW1ldHJpYy1waWNrZXInKSk7XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9tZXRyaWMuY3NzID0gJ3RhYmxlLXBpY2tlcic7XG4gICAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9tZXRyaWMuY29udGFpbmVyID0gJGFkZF9tZXRyaWNfcGlja2VyLmdldCgwKTtcbiAgICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5jYXB0aW9uID0gc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5jYXB0aW9uIHx8ICdBZGQgbWV0cmljLi4uJztcbiAgICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5kaXNhYmxlZCA9IHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzO1xuICAgICAgICBzZWxmLmFkZF9tZXRyaWNfcGlja2VyID0gbmV3IGpvb2xhLnZpei5NZXRyaWNQaWNrZXIoc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYykub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChtZXRyaWMpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgICAgaWYgKG1ldHJpYykge1xuICAgICAgICAgICAgICBtZXRyaWMuYWxsb3dyZW1vdmUgPSB0cnVlO1xuICAgICAgICAgICAgICBxLm1ldHJpY3MucHVzaChtZXRyaWMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICAgIHNlbGYuc29ydEluZGV4Kys7XG4gICAgICAgICAgc2VsZi5oYW5kbGVNZXRyaWNCb3hlcygpO1xuICAgICAgICAgIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdmFyICR0aGVhZCA9ICQkKCRodG1sLmZpbmQoJ3RoZWFkJykpO1xuICAgICAgJGh0bWwuZmluZCgndGFibGUnKS5hcHBlbmQoJHRoZWFkKTtcblxuICAgICAgdmFyICR0Ym9keSA9ICRodG1sLmZpbmQoJ3Rib2R5Jyk7XG4gICAgICAkdGJvZHkgPSAkJCgkdGJvZHkpO1xuICAgICAgJHRib2R5LmVtcHR5KCk7XG5cbiAgICAgIHZhciAkbWV0cmljX3RyID0gJCQoJzx0ciBjbGFzcz1cIm1ldHJpY2JveGVzXCI+PC90cj4nKTtcbiAgICAgICR0Ym9keS5hcHBlbmQoJG1ldHJpY190cik7XG4gICAgICBzZWxmLmhhbmRsZUhlYWRlcnMoKTtcbiAgICAgIHNlbGYuaGFuZGxlTWV0cmljQm94ZXMoKTtcbiAgICAgIHZhciAkdHIgPSAkJCgnPHRyIGNsYXNzPVwiZGF0YS1yb3cgbG9hZGluZ1wiPjwvdHI+Jyk7XG4gICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImxvYWRpbmdcIiBjb2xzcGFuPVwiJyArIChzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5sZW5ndGggKyBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5sZW5ndGgpICsgJ1wiPicgKyBzZWxmLm9wdGlvbnMuc3RyaW5ncy5sb2FkaW5nICsgJzwvdGQ+Jyk7XG4gICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAkaHRtbC5maW5kKCd0YWJsZScpLmFwcGVuZCgkdGJvZHkpO1xuXG4gICAgICB2YXIgJHBhZ2VTaXplID0gJCQoJGh0bWwuZmluZCgnLnBhZ2Utc2l6ZSBzZWxlY3QnKSk7XG4gICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLnNpemVzLmZvckVhY2goZnVuY3Rpb24gKHNpemUpIHtcbiAgICAgICAgdmFyICRvcHRpb24gPSAkJCgnPG9wdGlvbiB2YWx1ZT1cIicgKyBzaXplICsgJ1wiPicgKyBzaXplICsgJzwvb3B0aW9uPicpO1xuICAgICAgICAkcGFnZVNpemUuYXBwZW5kKCRvcHRpb24pO1xuICAgICAgfSk7XG4gICAgICAkcGFnZVNpemUub24oJ2NoYW5nZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFNpemUgPSBwYXJzZUludCgkcGFnZVNpemUudmFsKCksIDEwKTtcbiAgICAgICAgc2VsZi5wYWludCgpO1xuICAgICAgfSk7XG5cbiAgICAgIHZhciAkc2VhcmNoID0gJCQoJGh0bWwuZmluZCgnaW5wdXQuc2VhcmNoJykpO1xuICAgICAgJHNlYXJjaC5vbigna2V5dXAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICgkc2VhcmNoLnZhbCgpLmxlbmd0aCA+IDIpXG4gICAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICAgIHNlbGYucGFpbnQoKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLnF1ZXJ5ICYmICFBcnJheS5pc0FycmF5KG9wdGlvbnMucXVlcnkpKVxuICAgICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcblxuICAgIG9wdGlvbnMucXVlcnlbMF0uc29ydCA9IFtcbiAgICAgIFtvcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbMF0ua2V5IHx8IG9wdGlvbnMucXVlcnlbMF0ubWV0cmljc1swXSwgJ0RFU0MnXVxuICAgIF07XG4vL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcblxuICAgIGlmIChzZWxmLm9wdGlvbnMuY29sb3JzLmxlbmd0aCA9PT0gMClcbiAgICAgIHNlbGYub3B0aW9ucy5jb2xvcnMgPSBqb29sYS5jb2xvcnM7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5vZmZjb2xvcnMubGVuZ3RoID09PSAwKVxuICAgICAgc2VsZi5vcHRpb25zLm9mZmNvbG9ycyA9IGpvb2xhLm9mZmNvbG9ycztcblxuICAgIHNlbGYuZHJhdygpO1xuXG4gICAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gICAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICAgIH1cblxuLy93cmFwIHVwXG4gICAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICAgIHJldHVybiBzZWxmO1xuICB9XG4gIDtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLlRhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LlRhYmxlKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIHRhYmxlKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxudXRpbC5pbmhlcml0cyhUYWJsZSwgZXZlbnRzLkV2ZW50RW1pdHRlcik7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuICBjZSA9IHJlcXVpcmUoJ2Nsb25lZXh0ZW5kJyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5JyksXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgbW9tZW50ID0gcmVxdWlyZSgnbW9tZW50JyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyk7XG5cbnJlcXVpcmUoJ3R3aXgnKTtcblxudmFyIFRpbWVsaW5lID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgaWYgKCFjYWxsYmFjaylcbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB9O1xuICBqb29sYS5ldmVudHMuZW1pdCgndGltZWxpbmUuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy50eXBlID0gJ3RpbWVsaW5lJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5kYXRhID0gW107XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBsZWdlbmQ6IHRydWUsXG4gICAgY2FudmFzOiBudWxsLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImNhcHRpb25cIj48L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImNoYXJ0d3JhcHBlclwiPicgK1xuICAgICcgPGRpdiBjbGFzcz1cImNvbnRyb2xzXCI+JyArXG4gICAgJyAgIDxkaXYgY2xhc3M9XCJwcmltYXJ5LW1ldHJpYy1waWNrZXJcIj48L2Rpdj4nICtcbiAgICAnICAgPGRpdiBjbGFzcz1cInNlcFwiPnZzLjwvZGl2PicgK1xuICAgICcgICA8ZGl2IGNsYXNzPVwic2Vjb25kYXJ5LW1ldHJpYy1waWNrZXJcIj48L2Rpdj4nICtcbiAgICAnIDwvZGl2PicgK1xuICAgICcgJyArXG4gICAgJyA8ZGl2IGNsYXNzPVwidGhlY2hhcnRcIj48L2Rpdj4nICtcbiAgICAnPC9kaXY+JyxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBxdWVyeTogbnVsbCxcbiAgICBwaWNrZXJzOiB7XG4gICAgICBtYWluOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgc2Vjb25kYXJ5OiB7ZW5hYmxlZDogZmFsc2V9XG4gICAgfVxuICB9O1xuICB0aGlzLmNoYXJ0RHJhd24gPSBmYWxzZTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAoIXNlbGYub3B0aW9ucylcbiAgICAgIHJldHVybiAnRmFpbGVkIHRvIHZlcmlmeSBbb3B0aW9uc10uJztcbiAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5ID0gW3NlbGYub3B0aW9ucy5xdWVyeV07XG4gICAgfVxuICAgIGVsc2VcbiAgICAgIHJldHVybiAnRmFpbGVkIHRvIHZlcmlmeSBxdWVyeSBbb3B0aW9ucy5xdWVyeV0uJztcblxuICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zID0gWyd0aW1lc3RhbXAnXTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgam9vbGEudml6LnN0b3Aoc2VsZik7XG4gICAgc2VsZi5pbml0aWFsQ2hhcnREcmF3biA9IGZhbHNlO1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmVtcHR5KCk7XG4gIH07XG5cbiAgdGhpcy5yZXBseSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgaWYgKHNlbGYuaW5pdGlhbENoYXJ0RHJhd24gJiYgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLnJlYWx0aW1lID09PSB0cnVlICYmIHNlbGYub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbC5pbmRleE9mKCdzZWNvbmQnKSA+IC0xKSB7XG4gICAgICBzZWxmLmNoYXJ0LnNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uIChzZXJpZXMsIHNlckluZGV4KSB7XG4gICAgICAgIHNlcmllcy5hZGRQb2ludCh7eDogbmV3IERhdGUoKSwgeTogMH0sIGZhbHNlLCB0cnVlLCBmYWxzZSk7XG4gICAgICB9KTtcbiAgICAgIHNlbGYuY2hhcnQucmVkcmF3KHRydWUpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmVudGVyID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcbiAgICBpZiAoc2VsZi5jaGFydC5zZXJpZXMubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuO1xuICAgIGlmIChzZWxmLmRhdGEubGVuZ3RoID4gMSlcbiAgICAgIHJldHVybjtcbiAgICBPYmplY3Qua2V5cyhkYXRhWzBdLm1ldHJpY3MpLmZvckVhY2goZnVuY3Rpb24gKGtleSwgcG9pbnRJbmRleCkge1xuICAgICAgdmFyIHBvaW50ID0gZGF0YVswXTtcbiAgICAgIHZhciBzZXJpZXMgPSBzZWxmLmNoYXJ0LnNlcmllc1twb2ludEluZGV4XTtcbiAgICAgIHNlcmllcy5kYXRhW3Nlcmllcy5kYXRhLmxlbmd0aCAtIDFdLnVwZGF0ZShwb2ludC5tZXRyaWNzW2tleV0pO1xuICAgIH0pO1xuICAgIC8vc2VsZi5jaGFydC5yZWRyYXcoKTtcbiAgICAvKmV4dHJlbWVzXzAgPSBzZWxmLmNoYXJ0LnlBeGlzWzBdLmdldEV4dHJlbWVzKCk7XG4gICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICAgZXh0cmVtZXNfMC5tYXggPSBleHRyZW1lc18wLmRhdGFNYXggKiAxLjE7XG4gICAgIGlmIChleHRyZW1lc18wLmRhdGFNaW4gPT09IDAgJiYgZXh0cmVtZXNfMC5kYXRhTWF4ID09PSAwKSB7XG4gICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICAgZXh0cmVtZXNfMC5tYXggPSAxO1xuICAgICB9XG5cbiAgICAgc2VsZi5jaGFydC55QXhpc1swXS5zZXRFeHRyZW1lcyhleHRyZW1lc18wLm1pbiwgZXh0cmVtZXNfMC5tYXgpO1xuICAgICBpZiAoc2VsZi5jaGFydC55QXhpcy5sZW5ndGggPiAxKSB7XG4gICAgIGV4dHJlbWVzXzEgPSBzZWxmLmNoYXJ0LnlBeGlzWzFdLmdldEV4dHJlbWVzKCk7XG4gICAgIGV4dHJlbWVzXzEubWluID0gMDtcbiAgICAgZXh0cmVtZXNfMS5tYXggPSBleHRyZW1lc18xLmRhdGFNYXggKiAxLjE7XG4gICAgIGlmIChleHRyZW1lc18xLmRhdGFNaW4gPT09IDAgJiYgZXh0cmVtZXNfMS5kYXRhTWF4ID09PSAwKSB7XG4gICAgIGV4dHJlbWVzXzEubWluID0gMDtcbiAgICAgZXh0cmVtZXNfMS5tYXggPSAxO1xuICAgICB9XG4gICAgIHNlbGYuY2hhcnQueUF4aXNbMV0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMS5taW4sIGV4dHJlbWVzXzEubWF4KTtcbiAgICAgfSovXG4gIH07XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIGlmIChzZWxmLmNoYXJ0LnNlcmllcy5sZW5ndGggPT09IDApXG4gICAgICByZXR1cm47XG4gICAgaWYgKHNlbGYuZGF0YS5sZW5ndGggPiAxKVxuICAgICAgcmV0dXJuO1xuICAgIE9iamVjdC5rZXlzKGRhdGFbMF0ubWV0cmljcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBwb2ludEluZGV4KSB7XG4gICAgICB2YXIgcG9pbnQgPSBkYXRhWzBdO1xuICAgICAgdmFyIHNlcmllcyA9IHNlbGYuY2hhcnQuc2VyaWVzW3BvaW50SW5kZXhdO1xuICAgICAgc2VyaWVzLmRhdGFbc2VyaWVzLmRhdGEubGVuZ3RoIC0gMV0udXBkYXRlKHBvaW50Lm1ldHJpY3Nba2V5XSk7XG4gICAgfSk7XG4gICAgc2VsZi5jaGFydC5yZWRyYXcodHJ1ZSk7XG4gICAgZXh0cmVtZXNfMCA9IHNlbGYuY2hhcnQueUF4aXNbMF0uZ2V0RXh0cmVtZXMoKTtcbiAgICBleHRyZW1lc18wLm1pbiA9IDA7XG4gICAgZXh0cmVtZXNfMC5tYXggPSBleHRyZW1lc18wLmRhdGFNYXggKiAxLjE7XG4gICAgaWYgKGV4dHJlbWVzXzAuZGF0YU1pbiA9PT0gMCAmJiBleHRyZW1lc18wLmRhdGFNYXggPT09IDApIHtcbiAgICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICAgIGV4dHJlbWVzXzAubWF4ID0gMTtcbiAgICB9XG5cbiAgICBzZWxmLmNoYXJ0LnlBeGlzWzBdLnNldEV4dHJlbWVzKGV4dHJlbWVzXzAubWluLCBleHRyZW1lc18wLm1heCk7XG4gICAgaWYgKHNlbGYuY2hhcnQueUF4aXMubGVuZ3RoID4gMSkge1xuICAgICAgZXh0cmVtZXNfMSA9IHNlbGYuY2hhcnQueUF4aXNbMV0uZ2V0RXh0cmVtZXMoKTtcbiAgICAgIGV4dHJlbWVzXzEubWluID0gMDtcbiAgICAgIGV4dHJlbWVzXzEubWF4ID0gZXh0cmVtZXNfMS5kYXRhTWF4ICogMS4xO1xuICAgICAgaWYgKGV4dHJlbWVzXzEuZGF0YU1pbiA9PT0gMCAmJiBleHRyZW1lc18xLmRhdGFNYXggPT09IDApIHtcbiAgICAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICAgICBleHRyZW1lc18xLm1heCA9IDE7XG4gICAgICB9XG4gICAgICBzZWxmLmNoYXJ0LnlBeGlzWzFdLnNldEV4dHJlbWVzKGV4dHJlbWVzXzEubWluLCBleHRyZW1lc18xLm1heCk7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZXhpdCA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgLy9jb25zb2xlLmxvZygnZXhpdCcsIGRhdGEpO1xuICB9O1xuXG4gIHRoaXMuZG9uZSA9IGZ1bmN0aW9uIChkYXRhLCByYXcpIHtcbiAgICBpZiAoc2VsZi5pbml0aWFsQ2hhcnREcmF3bilcbiAgICAgIHJldHVybjtcbiAgICBzZWxmLmluaXRpYWxDaGFydERyYXduID0gdHJ1ZTtcbiAgICBzZWxmLmNoYXJ0RGF0YSA9IHNlbGYubWFrZUNoYXJ0VGltZWxpbmVTZXJpZXMocmF3KTtcbiAgICBzZWxmLnBhaW50KCk7XG4gIH07XG5cbiAgdGhpcy5tYWtlQ2hhcnRUaW1lbGluZVNlcmllcyA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKG1lc3NhZ2VbMF0ubWV0cmljcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgICAgbmFtZTogJ25vIGRhdGEnLFxuICAgICAgICAgIGRhdGE6IFtdXG4gICAgICAgIH1cbiAgICAgIF07XG4gICAgfVxuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgeUF4aXMgPSBbbnVsbCwgbnVsbF07XG4gICAgdmFyIHNlcmllcyA9IFtdO1xuICAgIHZhciBzZXJpZXNJbmRleCA9IC0xO1xuICAgIHZhciBpbnRlcnZhbCA9IEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSA/IHNlbGYub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbCA6IHNlbGYub3B0aW9ucy5xdWVyeS5pbnRlcnZhbDtcblxuICAgIHZhciBjaGVja0V4aXN0cyA9IGZ1bmN0aW9uICh0aW1lc3RhbXBEaW1lbnNpb24sIGRvY3VtZW50cywgZGF0ZSkge1xuICAgICAgcmV0dXJuIF8uZmluZChkb2N1bWVudHMsIGZ1bmN0aW9uIChkb2N1bWVudCkge1xuICAgICAgICBpZiAoIWRvY3VtZW50W3RpbWVzdGFtcERpbWVuc2lvbi5rZXldKVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHZhciBfZGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICAgIHZhciBfYmFzZWRhdGUgPSBuZXcgRGF0ZShkb2N1bWVudFt0aW1lc3RhbXBEaW1lbnNpb24ua2V5XSk7XG5cbiAgICAgICAgICBzd2l0Y2ggKGludGVydmFsKSB7XG4gICAgICAgICAgICBjYXNlICdtb250aCc6XG4gICAgICAgICAgICBjYXNlICdkYXknOlxuICAgICAgICAgICAgICBfZGF0ZS5zZXRIb3VycyhfZGF0ZS5nZXRIb3VycygpIC0gKF9kYXRlLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MCkpO1xuICAgICAgICAgICAgICByZXR1cm4gX2Jhc2VkYXRlLmdldFRpbWUoKSA9PT0gX2RhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgX2Jhc2VkYXRlLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIF9iYXNlZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIHJldHVybiBfYmFzZWRhdGUuZ2V0VGltZSgpID09PSBfZGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgICAgICAgICBfYmFzZWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgICAgICByZXR1cm4gX2Jhc2VkYXRlLmdldFRpbWUoKSA9PT0gX2RhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlZGF0ZS5nZXRUaW1lKCkgPT09IF9kYXRlLmdldFRpbWUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGV4KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ2V4Y2VwdGlvbiB3aGlsZSBjaGVja0V4aXN0cycsIGV4KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfTtcbiAgICB2YXIgZmlsbCA9IGZ1bmN0aW9uIChyZXN1bHRSb3csIHJvdywgdGltZXN0YW1wRGltZW5zaW9uKSB7XG4gICAgICBPYmplY3Qua2V5cyhyZXN1bHRSb3cpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoa2V5ICE9PSB0aW1lc3RhbXBEaW1lbnNpb24ua2V5KSB7XG4gICAgICAgICAgcm93W2tleV0gPSAwO1xuICAgICAgICAgIC8vcm93LmZ2YWx1ZXNba2V5XSA9IDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBtZXNzYWdlLmZvckVhY2goZnVuY3Rpb24gKHJlc3VsdCwgcmVzdWx0SW5kZXgpIHtcbiAgICAgIGlmIChyZXN1bHQuZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXN1bHQuZG9jdW1lbnRzLnB1c2goe3ZhbHVlczoge30sIGZ2YWx1ZXM6IHt9fSk7XG4gICAgICAgIHJlc3VsdC5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICByZXN1bHQuZG9jdW1lbnRzWzBdW2QubmFtZV0gPSBudWxsO1xuICAgICAgICAgIC8vcmVzdWx0LmRvY3VtZW50c1swXS5mdmFsdWVzW2QubmFtZV0gPSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgIHJlc3VsdC5kb2N1bWVudHNbMF1bbS5uYW1lXSA9IG51bGw7XG4gICAgICAgICAgLy9yZXN1bHQuZG9jdW1lbnRzWzBdLmZ2YWx1ZXNbbS5uYW1lXSA9IG51bGw7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgZGltZW5zaW9ucyA9IHJlc3VsdC5kaW1lbnNpb25zO1xuICAgICAgdmFyIG1ldHJpY3MgPSByZXN1bHQubWV0cmljcztcbiAgICAgIHZhciBkb2N1bWVudHMgPSBjZS5jbG9uZShyZXN1bHQuZG9jdW1lbnRzKTtcbiAgICAgIC8vc2hvdWxkIHdlIGZpbGwgdGhlIGRhdGUgcmFuZ2VcbiAgICAgIHZhciBxdWVyeSA9IGNlLmNsb25lKHJlc3VsdC5xdWVyeSk7XG5cbiAgICAgIHZhciB0aW1lc3RhbXBEaW1lbnNpb24gPSBfLmZpbmQocmVzdWx0LmRpbWVuc2lvbnMsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtLmRhdGF0eXBlID09PSAnZGF0ZSc7XG4gICAgICB9KTtcbiAgICAgIGlmICh0aW1lc3RhbXBEaW1lbnNpb24pIHtcbiAgICAgICAgLy92YWxpZGF0ZSBhbmQgZmlsbCB0aGUgZGF0ZSByYW5nZTtcbiAgICAgICAgaW50ZXJ2YWwgPSBpbnRlcnZhbCA9PT0gJ2RkYXRlJyA/ICdkYXknIDogKGludGVydmFsIHx8ICdkYXknKTtcbiAgICAgICAgaWYgKCFxdWVyeS50aW1lZnJhbWUpIHtcbiAgICAgICAgICBxdWVyeS50aW1lZnJhbWUgPSB7fTtcbiAgICAgICAgICBxdWVyeS50aW1lZnJhbWUuc3RhcnQgPSByZXN1bHQuZG9jdW1lbnRzW3Jlc3VsdC5kb2N1bWVudHMubGVuZ3RoIC0gMV0udGltZXN0YW1wO1xuICAgICAgICAgIHF1ZXJ5LnRpbWVmcmFtZS5lbmQgPSByZXN1bHQuZG9jdW1lbnRzWzBdLnRpbWVzdGFtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgdmFyIGZpeGVkID0gW107XG4gICAgICAgIHZhciBpdHIgPSBtb21lbnQudHdpeChxdWVyeS50aW1lZnJhbWUuc3RhcnQsIHF1ZXJ5LnRpbWVmcmFtZS5lbmQpLml0ZXJhdGUoaW50ZXJ2YWwpO1xuICAgICAgICB3aGlsZSAoaXRyLmhhc05leHQoKSAmJiBjb3VudGVyKysgPCAxMDAwKSB7XG4gICAgICAgICAgdmFyIF9kID0gbmV3IERhdGUoaXRyLm5leHQoKS5fZC5nZXRUaW1lKCkpO1xuICAgICAgICAgIHZhciBleGlzdHM7XG4gICAgICAgICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgX2Quc2V0SG91cnMoMCk7XG4gICAgICAgICAgICAgIF9kLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIF9kLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICBfZC5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgICAgICBfZC5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgX2Quc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgb2Zmc2V0ID0gbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjA7XG4gICAgICAgICAgZXhpc3RzID0gY2hlY2tFeGlzdHModGltZXN0YW1wRGltZW5zaW9uLCByZXN1bHQuZG9jdW1lbnRzLCBfZCk7XG4gICAgICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgICAgIC8vX2Quc2V0SG91cnMoX2QuZ2V0SG91cnMoKSArIChvZmZzZXQgKiAtMSkpO1xuICAgICAgICAgICAgZXhpc3RzID0ge3ZhbHVlczoge30sIGZ2YWx1ZXM6IHt9fTtcbiAgICAgICAgICAgIGV4aXN0c1t0aW1lc3RhbXBEaW1lbnNpb24ua2V5XSA9IF9kLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICAvL2V4aXN0cy5mdmFsdWVzW3RpbWVzdGFtcERpbWVuc2lvbi5rZXldID0gX2QudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICAgIGZpbGwocmVzdWx0LmRvY3VtZW50c1swXSwgZXhpc3RzLCB0aW1lc3RhbXBEaW1lbnNpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaXhlZC5wdXNoKGV4aXN0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZG9jdW1lbnRzID0gZml4ZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmICghbWV0cmljcylcbiAgICAgICAgcmV0dXJuIHNlcmllcztcbiAgICAgIG1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobWV0cmljLCBpbmRleCkge1xuICAgICAgICB2YXIgX3lheGlzID0gMDtcbiAgICAgICAgeUF4aXNbaW5kZXggJSAyXSA9IHlBeGlzIFtpbmRleCAlIDJdIHx8IG1ldHJpYy5kZXBlbmRzT24gfHwgbWV0cmljLmtleTtcbiAgICAgICAgaWYgKHlBeGlzWzBdID09PSAoeUF4aXMgW2luZGV4ICUgMl0gfHwgbWV0cmljLmRlcGVuZHNPbiB8fCBtZXRyaWMua2V5KSlcbiAgICAgICAgICBfeWF4aXMgPSAwO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgX3lheGlzID0gMTtcbiAgICAgICAgdmFyIG1ldHJpY19uYW1lID0gbWV0cmljLm5hbWU7XG4gICAgICAgIGlmIChyZXN1bHQucXVlcnkuZmlsdGVyKSB7XG4gICAgICAgICAgcmVzdWx0LnF1ZXJ5LmZpbHRlci5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICBtZXRyaWNfbmFtZSA9IGZbMl0gKyAnOiAnICsgbWV0cmljX25hbWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc2VyaWVzWysrc2VyaWVzSW5kZXhdID0ge1xuICAgICAgICAgIG5hbWU6IG1ldHJpY19uYW1lLFxuICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICAgIHlBeGlzOiBfeWF4aXMsXG4gICAgICAgICAgY29sb3I6IGpvb2xhLmNvbG9yc1tzZXJpZXNJbmRleF1cbiAgICAgICAgfTtcbiAgICAgICAgZG9jdW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGRvY3VtZW50LCBkb2NJbmRleCkge1xuICAgICAgICAgIHZhciB4ID0gZG9jdW1lbnQuZnZhbHVlc1tkaW1lbnNpb25zWzBdLmtleV07XG4gICAgICAgICAgdmFyIG5hbWVCYXNlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKGRpbWVuc2lvbnNbMF0uZGF0YXR5cGUgPT09ICdkYXRlJykge1xuICAgICAgICAgICAgeCA9IG5ldyBEYXRlKGRvY3VtZW50LmZ2YWx1ZXNbZGltZW5zaW9uc1swXS5rZXldKTtcbiAgICAgICAgICAgIG5hbWVCYXNlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuYW1lQmFzZWQpIHtcbiAgICAgICAgICAgIHNlcmllc1tzZXJpZXNJbmRleF0uZGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgbmFtZTogeCxcbiAgICAgICAgICAgICAgeTogZG9jdW1lbnRbbWV0cmljc1tpbmRleF0ua2V5XSA/IGRvY3VtZW50W21ldHJpY3NbaW5kZXhdLmtleV0gOiAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAoc2VyaWVzSW5kZXggPT09IDApIHtcbiAgICAgICAgICAgICAgc2VyaWVzW3Nlcmllc0luZGV4XS5kYXRhLnB1c2goe1xuICAgICAgICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgICAgICAgeTogZG9jdW1lbnRbbWV0cmljc1tpbmRleF0ua2V5XSA/IGRvY3VtZW50W21ldHJpY3NbaW5kZXhdLmtleV0gOiAwXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIHNlcmllc1tzZXJpZXNJbmRleF0uZGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgICB4OiBzZXJpZXNbMF0uZGF0YVtkb2NJbmRleF0ueCxcbiAgICAgICAgICAgICAgICB5OiBkb2N1bWVudFttZXRyaWNzW2luZGV4XS5rZXldID8gZG9jdW1lbnRbbWV0cmljc1tpbmRleF0ua2V5XSA6IDBcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBzZXJpZXM7XG5cbiAgfTtcblxuICB0aGlzLnBhaW50ID0gZnVuY3Rpb24gKHJlc2NhbGUpIHtcbiAgICBzZWxmLmNoYXJ0RGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxmLmNoYXJ0LmFkZFNlcmllcyhzKTtcbiAgICB9KTtcblxuICAgIC8vdmFyIGNvbFdpZHRoID0gKCQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLndpZHRoKCkgLyBzZWxmLmNoYXJ0RGF0YVswXS5kYXRhLmxlbmd0aCkgKyAxO1xuICAgIC8vY29uc29sZS5sb2coY29sV2lkdGgsIHNlbGYuY2hhcnQpO1xuICAgIC8vc2VsZi5jaGFydC5vcHRpb25zLnBsb3RPcHRpb25zLmNvbHVtbi5wb2ludFdpZHRoID0gY29sV2lkdGg7XG4gICAgc2VsZi5jaGFydC5yZWRyYXcoKTtcbiAgICAvL2lmICghc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLnJlYWx0aW1lIHx8IHJlc2NhbGUpIHtcbiAgICBleHRyZW1lc18wID0gc2VsZi5jaGFydC55QXhpc1swXS5nZXRFeHRyZW1lcygpO1xuICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICBleHRyZW1lc18wLm1heCA9IGV4dHJlbWVzXzAuZGF0YU1heCAqIDEuMTtcbiAgICBpZiAoZXh0cmVtZXNfMC5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzAuZGF0YU1heCA9PT0gMCkge1xuICAgICAgZXh0cmVtZXNfMC5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMC5tYXggPSAxO1xuICAgIH1cblxuICAgIGlmICghc2VsZi5sYXN0X2V4dHJlbWVzXzApXG4gICAgICBzZWxmLmxhc3RfZXh0cmVtZXNfMCA9IGV4dHJlbWVzXzA7XG4gICAgaWYgKHNlbGYubGFzdF9leHRyZW1lc18wLm1pbiAhPT0gZXh0cmVtZXNfMC5taW4gfHwgc2VsZi5sYXN0X2V4dHJlbWVzXzAubWF4ICE9PSBleHRyZW1lc18wLm1heClcbiAgICAgIHNlbGYuY2hhcnQueUF4aXNbMF0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMC5taW4sIGV4dHJlbWVzXzAubWF4KTtcbiAgICBpZiAoc2VsZi5jaGFydC55QXhpcy5sZW5ndGggPiAxKSB7XG4gICAgICBleHRyZW1lc18xID0gc2VsZi5jaGFydC55QXhpc1sxXS5nZXRFeHRyZW1lcygpO1xuICAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMS5tYXggPSBleHRyZW1lc18xLmRhdGFNYXggKiAxLjE7XG4gICAgICBpZiAoZXh0cmVtZXNfMS5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzEuZGF0YU1heCA9PT0gMCkge1xuICAgICAgICBleHRyZW1lc18xLm1pbiA9IDA7XG4gICAgICAgIGV4dHJlbWVzXzEubWF4ID0gMTtcbiAgICAgIH1cbiAgICAgIGlmICghc2VsZi5sYXN0X2V4dHJlbWVzXzEpXG4gICAgICAgIHNlbGYubGFzdF9leHRyZW1lc18xID0gZXh0cmVtZXNfMTtcbiAgICAgIGlmIChzZWxmLmxhc3RfZXh0cmVtZXNfMS5taW4gIT09IGV4dHJlbWVzXzEubWluIHx8IHNlbGYubGFzdF9leHRyZW1lc18xLm1heCAhPT0gZXh0cmVtZXNfMS5tYXgpXG4gICAgICAgIHNlbGYuY2hhcnQueUF4aXNbMV0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMS5taW4sIGV4dHJlbWVzXzEubWF4KTtcbiAgICB9XG4gICAgLy99XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgc2VsZi5jaGFydE9wdGlvbnMgPSBqb29sYS5jb21tb24uX21peGluKHt9LCBzZWxmLm9wdGlvbnMuY2hhcnQpO1xuICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmFwcGVuZChzZWxmLm9wdGlvbnMudGVtcGxhdGUgfHwgc2VsZi50ZW1wbGF0ZSgpKTtcbiAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24gfHwgJycpO1xuXG4gICAgLy9waWNrZXJzXG4gICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLm1haW4gJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMubWFpbi5lbmFibGVkKSB7XG4gICAgICB2YXIgJHByaW1hcnlfbWV0cmljX2NvbnRhaW5lcjtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucGlja2Vycy5tYWluLmNvbnRhaW5lcilcbiAgICAgICAgJHByaW1hcnlfbWV0cmljX2NvbnRhaW5lciA9ICQkKHNlbGYub3B0aW9ucy5waWNrZXJzLm1haW4uY29udGFpbmVyKTtcbiAgICAgIGVsc2VcbiAgICAgICAgJHByaW1hcnlfbWV0cmljX2NvbnRhaW5lciA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5wcmltYXJ5LW1ldHJpYy1waWNrZXInKVswXSk7XG5cbiAgICAgIGlmICgkcHJpbWFyeV9tZXRyaWNfY29udGFpbmVyKSB7XG4gICAgICAgIHNlbGYucHJpbWFyeV9tZXRyaWNfY29udGFpbmVyID0gbmV3IGpvb2xhLnZpei5NZXRyaWNQaWNrZXIoe1xuICAgICAgICAgIGNvbnRhaW5lcjogJHByaW1hcnlfbWV0cmljX2NvbnRhaW5lcixcbiAgICAgICAgICBjYW52YXM6IHNlbGYub3B0aW9ucy5jYW52YXMsXG4gICAgICAgICAgc2VsZWN0ZWQ6IHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzWzBdLFxuICAgICAgICAgIGFsbG93UmVtb3ZlOiBmYWxzZVxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyLCBfcGlja2VyKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBfcGlja2VyLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAobWV0cmljKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKSB7XG4gICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxdWVyeSkge1xuICAgICAgICAgICAgICAgIHF1ZXJ5Lm1ldHJpY3NbMF0gPSBtZXRyaWM7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkubWV0cmljc1swXSA9IG1ldHJpYztcblxuICAgICAgICAgICAgaWYgKHNlbGYuc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIpIHtcbiAgICAgICAgICAgICAgc2VsZi5zZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lci5vcHRpb25zLmRpc2FibGVkID0gW21ldHJpY107XG4gICAgICAgICAgICAgIHNlbGYuc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgICAgc2VsZi5jaGFydERhdGEgPSBbXTtcbiAgICAgICAgICAgIHNlbGYuaW5pdGlhbENoYXJ0RHJhd24gPSBmYWxzZTtcbiAgICAgICAgICAgIHdoaWxlIChzZWxmLmNoYXJ0LnNlcmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzWzBdLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLnNlY29uZGFyeSAmJiBzZWxmLm9wdGlvbnMucGlja2Vycy5zZWNvbmRhcnkuZW5hYmxlZCkge1xuICAgICAgdmFyICRzZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lcjtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucGlja2Vycy5zZWNvbmRhcnkuY29udGFpbmVyKVxuICAgICAgICAkc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMucGlja2Vycy5zZWNvbmRhcnkuY29udGFpbmVyKTtcbiAgICAgIGVsc2VcbiAgICAgICAgJHNlY29uZGFyeV9tZXRyaWNfY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnNlY29uZGFyeS1tZXRyaWMtcGlja2VyJylbMF0pO1xuXG4gICAgICBpZiAoJHNlY29uZGFyeV9tZXRyaWNfY29udGFpbmVyKSB7XG4gICAgICAgIHNlbGYuc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIgPSBuZXcgam9vbGEudml6Lk1ldHJpY1BpY2tlcih7XG4gICAgICAgICAgY29udGFpbmVyOiAkc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIsXG4gICAgICAgICAgY2FudmFzOiBzZWxmLm9wdGlvbnMuY2FudmFzLFxuICAgICAgICAgIHNlbGVjdGVkOiBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljc1sxXSxcbiAgICAgICAgICBkaXNhYmxlZDogc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbMF0sXG4gICAgICAgICAgYWxsb3dSZW1vdmU6IHRydWVcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVyciwgX3BpY2tlcikge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgX3BpY2tlci5vbignY2hhbmdlJywgZnVuY3Rpb24gKG1ldHJpYykge1xuICAgICAgICAgICAgaWYgKCFtZXRyaWMpIHtcbiAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxdWVyeSkge1xuICAgICAgICAgICAgICAgICAgcXVlcnkubWV0cmljcy5zcGxpY2UoMSwgMSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5tZXRyaWNzLnNwbGljZSgxLCAxKTtcblxuICAgICAgICAgICAgICBzZWxmLnByaW1hcnlfbWV0cmljX2NvbnRhaW5lci5vcHRpb25zLmRpc2FibGVkID0gW107XG4gICAgICAgICAgICAgIHNlbGYucHJpbWFyeV9tZXRyaWNfY29udGFpbmVyLm1hcmtTZWxlY3RlZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5xdWVyeSkpIHtcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5Lm1ldHJpY3NbMV0gPSBtZXRyaWM7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5tZXRyaWNzWzFdID0gbWV0cmljO1xuXG4gICAgICAgICAgICAgIHNlbGYucHJpbWFyeV9tZXRyaWNfY29udGFpbmVyLm9wdGlvbnMuZGlzYWJsZWQgPSBbbWV0cmljXTtcbiAgICAgICAgICAgICAgc2VsZi5wcmltYXJ5X21ldHJpY19jb250YWluZXIubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLmRhdGEgPSBbXTtcbiAgICAgICAgICAgIHNlbGYuY2hhcnREYXRhID0gW107XG4gICAgICAgICAgICBzZWxmLmluaXRpYWxDaGFydERyYXduID0gZmFsc2U7XG4gICAgICAgICAgICB3aGlsZSAoc2VsZi5jaGFydC5zZXJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1swXS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnNlcCcpKS5oaWRlKCk7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuc2Vjb25kYXJ5LW1ldHJpYy1waWNrZXInKSkuaGlkZSgpO1xuICAgIH1cblxuICAgIHNlbGYuY2hhcnRPcHRpb25zID0gam9vbGEuY29tbW9uLl9taXhpbih7XG4gICAgICB0aXRsZToge1xuICAgICAgICB0ZXh0OiBudWxsXG4gICAgICB9LFxuICAgICAgY2hhcnQ6IHtcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgICAgICAvKm1hcmdpblRvcDogMCxcbiAgICAgICAgIG1hcmdpbkJvdHRvbTogMCxcbiAgICAgICAgIG1hcmdpbkxlZnQ6IDAsXG4gICAgICAgICBtYXJnaW5SaWdodDogMCxcbiAgICAgICAgIHNwYWNpbmdUb3A6IDAsXG4gICAgICAgICBzcGFjaW5nQm90dG9tOiAwLFxuICAgICAgICAgc3BhY2luZ0xlZnQ6IDAsXG4gICAgICAgICBzcGFjaW5nUmlnaHQ6IDAsKi9cbiAgICAgICAgYm9yZGVyV2lkdGg6IDAsXG4gICAgICAgIHBsb3RCb3JkZXJXaWR0aDogMCxcbiAgICAgICAgdHlwZTogJ2xpbmUnLFxuICAgICAgICBoZWlnaHQ6IHNlbGYub3B0aW9ucy5oZWlnaHQgfHwgc2VsZi5vcHRpb25zLiRjb250YWluZXIuaGVpZ2h0KCkgfHwgMjUwLFxuICAgICAgICAvL3dpZHRoOiBzZWxmLm9wdGlvbnMud2lkdGggfHwgc2VsZi5vcHRpb25zLiRjb250YWluZXIud2lkdGgoKSB8fCBudWxsXG4gICAgICB9LFxuICAgICAgbGFuZzoge1xuICAgICAgICBub0RhdGE6ICdObyBkYXRhIHRvIGRpc3BsYXknXG4gICAgICB9LFxuICAgICAgbm9EYXRhOiB7XG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnLFxuICAgICAgICAgIGZvbnRTaXplOiAnMTVweCcsXG4gICAgICAgICAgY29sb3I6ICcjMzAzMDMwJ1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc2VyaWVzOiBbXSxcbiAgICAgIHhBeGlzOiB7XG4gICAgICAgIHR5cGU6ICdkYXRldGltZScsXG4gICAgICAgIGVuZE9uVGljazogZmFsc2UsXG5cbiAgICAgICAgdGlja1dpZHRoOiAwLFxuICAgICAgICBkYXRlVGltZUxhYmVsRm9ybWF0czoge1xuICAgICAgICAgIGRheTogJyVCICVlJ1xuICAgICAgICB9LFxuICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgIHN0YWdnZXJMaW5lczogMSxcbiAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgY29sb3I6ICcjYjNiM2IxJ1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHlBeGlzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBlbmRPblRpY2s6IGZhbHNlLFxuICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB0ZXh0OiBudWxsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgICBzdHlsZToge1xuICAgICAgICAgICAgICBjb2xvcjogJyNiM2IzYjEnXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBncmlkTGluZURhc2hTdHlsZTogJ0RvdCdcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGVuZE9uVGljazogZmFsc2UsXG4gICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsczoge1xuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiAnI2IzYjNiMSdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGdyaWRMaW5lRGFzaFN0eWxlOiAnRG90JyxcbiAgICAgICAgICBncmlkTGluZVdpZHRoOiAwLFxuICAgICAgICAgIG9wcG9zaXRlOiB0cnVlXG4gICAgICAgIH1cbiAgICAgIF0sXG4gICAgICBsZWdlbmQ6IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICBjcmVkaXRzOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgZXhwb3J0aW5nOiB7ZW5hYmxlZDogdHJ1ZX0sXG4gICAgICBwbG90T3B0aW9uczoge1xuICAgICAgICBjb2x1bW46IHtcbiAgICAgICAgICBhbGxvd1BvaW50U2VsZWN0OiB0cnVlLFxuICAgICAgICAgIGdyb3VwUGFkZGluZzogMC4wNSxcbiAgICAgICAgICBwb2ludFBhZGRpbmc6IDAsXG4gICAgICAgICAgYm9yZGVyV2lkdGg6IDBcbiAgICAgICAgfSxcbiAgICAgICAgbGluZToge1xuICAgICAgICAgIC8vdHVyYm9UaHJlc2hvbGQ6IG1lc3NhZ2UuZG9jdW1lbnRzID8gbWVzc2FnZS5kb2N1bWVudHMubGVuZ3RoICsgMTAwMCA6IDAsXG4gICAgICAgICAgY29sb3I6ICcjMzMzMzMzJyxcbiAgICAgICAgICBmaWxsT3BhY2l0eTogMC4xLFxuICAgICAgICAgIGxpbmVXaWR0aDogMyxcbiAgICAgICAgICBjb25uZWN0TnVsbHM6IHRydWUsXG4gICAgICAgICAgbWFya2VyOiB7XG4gICAgICAgICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICBzdGF0ZXM6IHtcbiAgICAgICAgICAgICAgaG92ZXI6IHtcbiAgICAgICAgICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LCBzZWxmLm9wdGlvbnMuY2hhcnQpO1xuXG4gICAgaWYgKCFzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcilcbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgc2VsZi5jaGFydE9wdGlvbnMuY2hhcnQucmVuZGVyVG8gPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcudGhlY2hhcnQnKS5nZXQoMCk7XG4gICAgc2VsZi5jaGFydCA9IG5ldyBIaWdoY2hhcnRzLkNoYXJ0KHNlbGYuY2hhcnRPcHRpb25zKTtcbiAgICAvL3NlbGYuY2hhcnQuc2V0U2l6ZSggJCQoc2VsZi5jaGFydC5jb250YWluZXIpLnBhcmVudCgpLndpZHRoKCksICQkKHNlbGYuY2hhcnQuY29udGFpbmVyKS5wYXJlbnQoKS5oZWlnaHQoKSApO1xuICAgIHNlbGYuY2hhcnREcmF3biA9IHRydWU7XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLm9uRHJhdylcbiAgICAgIHdpbmRvd1tzZWxmLm9wdGlvbnMub25EcmF3XShzZWxmLm9wdGlvbnMuY29udGFpbmVyLCBzZWxmKTtcblxuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcblxuICAvL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG5cbiAgc2VsZi5kcmF3KCk7XG4gIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICBpZiAoIXNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJCQoZWxlbSkuQ2FudmFzKCk7XG4gICAgfVxuICB9XG4gIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICB9XG5cbiAgLy93cmFwIHVwXG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZvdW5kO1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5UaW1lbGluZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5UaW1lbGluZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCB0aW1lbGluZSkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgdGltZWxpbmUuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoVGltZWxpbmUsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGFzeW5jID0gcmVxdWlyZSgnYXN5bmMnKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpLFxuICAkJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xuXG52YXIgdml6ID0gZXhwb3J0cztcbnZpei5faWQgPSAndml6JztcblxuLy9waWNrZXJzXG52aXouRGF0ZVBpY2tlciA9IHJlcXVpcmUoJy4vRGF0ZVBpY2tlcicpO1xudml6Lk1ldHJpY1BpY2tlciA9IHJlcXVpcmUoJy4vTWV0cmljUGlja2VyJyk7XG52aXouRGltZW5zaW9uUGlja2VyID0gcmVxdWlyZSgnLi9EaW1lbnNpb25QaWNrZXInKTtcbnZpei5GaWx0ZXJCb3ggPSByZXF1aXJlKCcuL0ZpbHRlckJveCcpO1xuLy9wYW5lbHNcbnZpei5DYW52YXMgPSByZXF1aXJlKCcuL0NhbnZhcycpO1xuXG4vL2NoYXJ0c1xudml6LlNwYXJrbGluZSA9IHJlcXVpcmUoJy4vU3BhcmtsaW5lJyk7XG52aXouTWV0cmljID0gcmVxdWlyZSgnLi9NZXRyaWMnKTtcbnZpei5HZW8gPSByZXF1aXJlKCcuL0dlbycpO1xudml6LlBpZSA9IHJlcXVpcmUoJy4vUGllJyk7XG52aXouTWluaVRhYmxlID0gcmVxdWlyZSgnLi9NaW5pVGFibGUnKTtcbnZpei5CYXJUYWJsZSA9IHJlcXVpcmUoJy4vQmFyVGFibGUnKTtcbnZpei5QdW5jaENhcmQgPSByZXF1aXJlKCcuL1B1bmNoQ2FyZCcpO1xudml6LlRhYmxlID0gcmVxdWlyZSgnLi9UYWJsZScpO1xudml6LlRpbWVsaW5lID0gcmVxdWlyZSgnLi9UaW1lbGluZScpO1xuXG4vL29uc2NyZWVuXG52aXoub25zY3JlZW4gPSBbXTtcblxudml6Lm1hcmtDb250YWluZXIgPSBmdW5jdGlvbiAoY29udGFpbmVyLCBhdHRyKSB7XG4gIGNvbnRhaW5lciA9ICQkKGNvbnRhaW5lcik7XG4gIGNvbnRhaW5lci5hdHRyKCdqaW8tZG9tYWluJywgJ2pvb2xhJyk7XG4gIGF0dHIgPSBhdHRyLmF0dHIgfHwgYXR0cjtcbiAgYXR0ci5mb3JFYWNoKGZ1bmN0aW9uIChhKSB7XG4gICAgT2JqZWN0LmtleXMoYSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnY3NzJyAmJiBhW2tleV0pIHtcbiAgICAgICAgdmFyIGN1cnJlbnRDbGFzc2VzID0gY29udGFpbmVyLmF0dHIoJ2NsYXNzJyk7XG4gICAgICAgIGNvbnRhaW5lci5hdHRyKCdjbGFzcycsIGN1cnJlbnRDbGFzc2VzICsgJyAnICsgYVtrZXldKTtcbiAgICAgIH1cbiAgICAgIGVsc2VcbiAgICAgICAgY29udGFpbmVyLmF0dHIoJ2ppby0nICsga2V5LCBhW2tleV0pO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbnZpei5pbml0aWFsaXplID0gZnVuY3Rpb24gKHNlbGYsIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGpvb2xhLmNvbW1vbi5taXhpbihzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICB2YXIgdmVyaWZpZWQgPSBzZWxmLnZlcmlmeS5hcHBseShzZWxmKTtcbiAgaWYgKHZlcmlmaWVkICE9PSBudWxsKVxuICAgIHRocm93IG5ldyBFcnJvcih2ZXJpZmllZCk7XG4gIGlmICghc2VsZi5pbml0aWFsaXplZCkge1xuICAgIHZpei5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy5jb250YWluZXIsIFtcbiAgICAgIHt0eXBlOiBzZWxmLnR5cGV9LFxuICAgICAge3V1aWQ6IHNlbGYudXVpZH0sXG4gICAgICB7Y3NzOiBzZWxmLm9wdGlvbnMuY3NzIHx8IG51bGx9XG4gICAgXSk7XG4gICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICAgICAgLy9zdWJzY3JpYmUgdG8gZGVmYXVsdCBldmVudHNcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuc2V0TWF4TGlzdGVuZXJzKDEwMCk7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLm9uKCdkYXRlY2hhbmdlJywgZnVuY3Rpb24gKGRhdGVzKSB7XG4gICAgICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMucXVlcnkpXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvL2xldCdzIGNoYW5nZSBvdXIgcXVlcnkgYW5kIGZldGNoIGFnYWluXG4gICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeSA9IGNlLmNsb25lKHNlbGYub3B0aW9ucy5jYW52YXMucHJlcGFyZVF1ZXJ5KHNlbGYub3B0aW9ucy5xdWVyeVswXSwgZGF0ZXMpKTtcbiAgICAgICAgdml6LmRlc3Ryb3koc2VsZiwge2xvYWRpbmc6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICB9KTtcblxuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5vbignZmlsdGVyY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXNlbGYub3B0aW9ucylcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICghc2VsZi5vcHRpb25zLnF1ZXJ5KVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocXVlcnkpIHtcbiAgICAgICAgICBpZiAoIXF1ZXJ5LmZpbHRlcnMpXG4gICAgICAgICAgICBxdWVyeS5maWx0ZXIgPSBbXTtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLm9wdGlvbnMuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICBmLmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZjIpIHtcbiAgICAgICAgICAgICAgcXVlcnkuZmlsdGVyLnB1c2goZjIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2aXouZGVzdHJveShzZWxmLCB7bG9hZGluZzogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5KSB7XG4gICAgdml6LmZldGNoKHNlbGYsIHNlbGYub3B0aW9ucy5xdWVyeSwgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGNhbGxiYWNrICYmIHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG52aXoubG9va3VwID0gZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICBpZiAoIWJhc2UpXG4gICAgcmV0dXJuIG51bGw7XG4gIHZhciByZXN1bHQgPSBfLmZpbHRlcihiYXNlLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgIHJldHVybiBpdGVtLmtleSA9PT0ga2V5O1xuICB9KTtcbiAgaWYgKHJlc3VsdC5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG51bGw7XG4gIHJldHVybiByZXN1bHRbMF07XG59O1xuXG52aXoubG9va3VwRGF0ZSA9IGZ1bmN0aW9uIChiYXNlLCBpbmRleCkge1xuICByZXR1cm4gYmFzZVtpbmRleF07XG59O1xuXG52aXouZmV0Y2ggPSBmdW5jdGlvbiAoY29udGV4dCwgcXVlcnksIGNhbGxiYWNrKSB7XG4gIGlmICghY29udGV4dC5yZWFsdGltZVF1ZXJpZXMpXG4gICAgY29udGV4dC5yZWFsdGltZVF1ZXJpZXMgPSBbXTtcbiAgaWYgKCFjYWxsYmFjayAmJiBjb250ZXh0ICYmIHF1ZXJ5KSB7XG4gICAgY2FsbGJhY2sgPSBxdWVyeTtcbiAgICBxdWVyeSA9IGNvbnRleHQ7XG4gIH1cbiAgdmFyIF9xdWVyeSA9IGNlLmNsb25lKHF1ZXJ5KTtcbiAgdml6LnN0b3AoY29udGV4dCwgZnVuY3Rpb24gKCkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShfcXVlcnkpKSB7XG4gICAgICBpZiAoY29udGV4dCAmJiBjb250ZXh0Lm9wdGlvbnMgJiYgY29udGV4dC5vcHRpb25zLmNhbnZhcykge1xuICAgICAgICBjb250ZXh0Lm9wdGlvbnMucXVlcnkuaW50ZXJ2YWwgPSBjb250ZXh0Lm9wdGlvbnMucXVlcnkuaW50ZXJ2YWwgfHwgY29udGV4dC5vcHRpb25zLmNhbnZhcy5vcHRpb25zLnF1ZXJ5LmludGVydmFsO1xuICAgICAgICBjb250ZXh0Lm9wdGlvbnMucXVlcnkudGltZWZyYW1lID0gY29udGV4dC5vcHRpb25zLnF1ZXJ5LnRpbWVmcmFtZSB8fCBjb250ZXh0Lm9wdGlvbnMuY2FudmFzLm9wdGlvbnMucXVlcnkudGltZWZyYW1lO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHQub3B0aW9ucyAmJiBjb250ZXh0Lm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICAgIGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbCA9IGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbCB8fCBjb250ZXh0Lm9wdGlvbnMuY2FudmFzLm9wdGlvbnMucXVlcnkuaW50ZXJ2YWw7XG4gICAgICAgIGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS50aW1lZnJhbWUgPSBjb250ZXh0Lm9wdGlvbnMucXVlcnlbMF0udGltZWZyYW1lIHx8IGNvbnRleHQub3B0aW9ucy5jYW52YXMub3B0aW9ucy5xdWVyeS50aW1lZnJhbWU7XG4gICAgICB9XG4gICAgfVxuICAgIC8vYWRqdXN0IG9mZnNldFxuICAgIGlmIChfcXVlcnkudGltZWZyYW1lICYmIHR5cGVvZiBfcXVlcnkudGltZWZyYW1lID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKF9xdWVyeS50aW1lZnJhbWUuc3RhcnQpXG4gICAgICAgIF9xdWVyeS50aW1lZnJhbWUuc3RhcnQuc2V0SG91cnMoX3F1ZXJ5LnRpbWVmcmFtZS5zdGFydC5nZXRIb3VycygpICsgam9vbGEudGltZXpvbmUoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCkpO1xuICAgICAgaWYgKF9xdWVyeS50aW1lZnJhbWUuZW5kKVxuICAgICAgICBfcXVlcnkudGltZWZyYW1lLmVuZC5zZXRIb3VycyhfcXVlcnkudGltZWZyYW1lLmVuZC5nZXRIb3VycygpICsgam9vbGEudGltZXpvbmUoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCkpO1xuICAgIH1cbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIGlmIChfcXVlcnkuYXV0aENvbnRleHQpXG4gICAgICBhcmdzLnB1c2goX3F1ZXJ5LmF1dGhDb250ZXh0KTtcbiAgICBhcmdzLnB1c2goX3F1ZXJ5KTtcbiAgICBhcmdzLnB1c2goZnVuY3Rpb24gKGVyciwgbWVzc2FnZXMpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSlcbiAgICAgICAgbWVzc2FnZXMgPSBbbWVzc2FnZXNdO1xuXG4gICAgICBpZiAoY29udGV4dC5yZXBseSlcbiAgICAgICAgY29udGV4dC5yZXBseShtZXNzYWdlcywgY29udGV4dC5kYXRhKTtcblxuICAgICAgbWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbiAobWVzc2FnZSwgbWluZGV4KSB7XG4gICAgICAgIGlmICghY29udGV4dC5kYXRhKVxuICAgICAgICAgIGNvbnRleHQuZGF0YSA9IFtdO1xuICAgICAgICB2YXIgX2RhdGEgPSBbXTtcbiAgICAgICAgaWYgKGNvbnRleHQuZGF0YVttaW5kZXhdKSB7XG4gICAgICAgICAgX2RhdGEgPSBjb250ZXh0LmRhdGFbbWluZGV4XTtcbiAgICAgICAgICBfZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpdGVtLnN0YXRlID0gJ2V4aXQnO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlICYmIG1lc3NhZ2UucXVlcnkgJiYgbWVzc2FnZS5xdWVyeS50cyAmJiBtZXNzYWdlLnF1ZXJ5LnRzLmR1cmF0aW9uKVxuICAgICAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnZmV0Y2ggdG9vazogJyArIG1lc3NhZ2UucXVlcnkudHMuZHVyYXRpb24udG9TdHJpbmcoKSArICdtcywgcmVzdWx0czogJyArIChtZXNzYWdlICYmIG1lc3NhZ2UuZG9jdW1lbnRzID8gbWVzc2FnZS5kb2N1bWVudHMubGVuZ3RoLnRvU3RyaW5nKCkgOiAnbi9hJykpO1xuICAgICAgICBpZiAobWVzc2FnZS5xdWVyeS5yZWFsdGltZVVJRCAmJiBjb250ZXh0LnJlYWx0aW1lUXVlcmllcy5pbmRleE9mKG1lc3NhZ2UucXVlcnkucmVhbHRpbWVVSUQpID09IC0xKVxuICAgICAgICAgIGNvbnRleHQucmVhbHRpbWVRdWVyaWVzLnB1c2gobWVzc2FnZS5xdWVyeS5yZWFsdGltZVVJRCk7XG4gICAgICAgIG1lc3NhZ2UuZG9jdW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGRvYywgZG9jaW5kZXgpIHtcbiAgICAgICAgICBkb2MgPSB7XG4gICAgICAgICAgICBkaW1lbnNpb25zOiB7fSxcbiAgICAgICAgICAgIG1ldHJpY3M6IHt9LFxuICAgICAgICAgICAgbWV0YToge30sXG4gICAgICAgICAgICByYXc6IGNlLmNsb25lKGRvYyksXG4gICAgICAgICAgICBzdGF0ZTogJ2VudGVyJyxcbiAgICAgICAgICAgIHR5cGU6IG1lc3NhZ2UucXVlcnkudHlwZSxcbiAgICAgICAgICAgIHJlYWx0aW1lOiBtZXNzYWdlLnF1ZXJ5LnJlYWx0aW1lXG4gICAgICAgICAgfTtcbiAgICAgICAgICB2YXIga2V5ID0gJyc7XG4gICAgICAgICAgY29uc29sZS5sb2coZG9jKTtcbiAgICAgICAgICBtZXNzYWdlLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAga2V5ICs9IGRvYy5yYXdbZC5rZXldO1xuICAgICAgICAgICAgZG9jLmRpbWVuc2lvbnNbZC5rZXldID0gZG9jLnJhd1tkLmtleV07XG4gICAgICAgICAgICBkb2MubWV0YVtkLmtleV0gPSBkO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIG1lc3NhZ2UubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICBkb2MubWV0cmljc1ttLmtleV0gPSBkb2MucmF3W20ua2V5XTtcbiAgICAgICAgICAgIGRvYy5tZXRhW20ua2V5XSA9IG07XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZG9jLmtleSA9IGpvb2xhLmNvbW1vbi5oYXNoKGtleSk7XG4gICAgICAgICAgLy9sb29rdXAga2V5XG4gICAgICAgICAgdmFyIGV4aXN0ID0gdml6Lmxvb2t1cChfZGF0YSwgZG9jLmtleSk7XG4gICAgICAgICAgaWYgKGV4aXN0KSB7XG4gICAgICAgICAgICB2YXIgZGlydHkgPSBmYWxzZTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGV4aXN0Lm1ldHJpY3MpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICBpZiAoZXhpc3QubWV0cmljc1trZXldICE9PSBkb2MubWV0cmljc1trZXldKSB7XG4gICAgICAgICAgICAgICAgZGlydHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGV4aXN0Lm1ldHJpY3Nba2V5XSA9IGRvYy5tZXRyaWNzW2tleV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGRpcnR5KVxuICAgICAgICAgICAgICBleGlzdC5zdGF0ZSA9ICd1cGRhdGUnO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICBleGlzdC5zdGF0ZSA9ICdzdGF0aWMnO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIF9kYXRhLnB1c2goZG9jKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBjb250ZXh0LmRhdGFbbWluZGV4XSA9IF9kYXRhO1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBoYW5kbGVkID0gW107XG4gICAgICBjb250ZXh0LmRhdGFbMF0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSwgcG9pbnRJbmRleCkge1xuICAgICAgICBoYW5kbGVkLnB1c2goZGF0YS5rZXkpO1xuICAgICAgICB2YXIgcG9pbnQgPSBbZGF0YV07XG4gICAgICAgIHZhciBwYWlyZWQgPSB7XG4gICAgICAgICAgbWlzc2luZzogdHJ1ZSxcbiAgICAgICAgICBtZXRhOiBwb2ludC5tZXRhXG4gICAgICAgIH07XG4gICAgICAgIGlmIChjb250ZXh0LmRhdGEubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgLy9maW5kIHRoZSBwYWlyXG4gICAgICAgICAgaWYgKE9iamVjdC5rZXlzKGRhdGEuZGltZW5zaW9ucykubGVuZ3RoID09PSAxICYmIGRhdGEuZGltZW5zaW9ucy50aW1lc3RhbXApIHtcbiAgICAgICAgICAgIHBhaXJlZCA9IGNvbnRleHQuZGF0YVsxXVtwb2ludEluZGV4XSB8fCBwYWlyZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcGFpcmVkID0gXy5maW5kKGNvbnRleHQuZGF0YVsxXSwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0ua2V5ID09PSBkYXRhLmtleTtcbiAgICAgICAgICAgIH0pIHx8IHBhaXJlZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHBhaXJlZCB8fCBjb250ZXh0LmRhdGEubGVuZ3RoID4gMSlcbiAgICAgICAgICAgIHBvaW50ID0gW2RhdGEsIHBhaXJlZF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEuc3RhdGUgPT09ICdlbnRlcicgfHwgcGFpcmVkLnN0YXRlID09PSAnZW50ZXInKSB7XG4gICAgICAgICAgaWYgKGNvbnRleHQub3B0aW9ucy5lbnRlcilcbiAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy5lbnRlci5hcHBseShjb250ZXh0LCBbcG9pbnQsIGNvbnRleHQuZGF0YV0pO1xuICAgICAgICAgIGNvbnRleHQuZW50ZXIocG9pbnQsIGNvbnRleHQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGF0YS5zdGF0ZSA9PT0gJ3VwZGF0ZScgfHwgcGFpcmVkLnN0YXRlID09PSAndXBkYXRlJykge1xuICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMudXBkYXRlKVxuICAgICAgICAgICAgY29udGV4dC5vcHRpb25zLnVwZGF0ZS5hcHBseShjb250ZXh0LCBbcG9pbnQsIGNvbnRleHQuZGF0YV0pO1xuICAgICAgICAgIGNvbnRleHQudXBkYXRlKHBvaW50LCBjb250ZXh0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRhdGEuc3RhdGUgPT09ICdleGl0JyB8fCBwYWlyZWQuc3RhdGUgPT09ICdleGl0Jykge1xuICAgICAgICAgIGNvbnRleHQuZGF0YVswXS5zcGxpY2UocG9pbnRJbmRleCwgMSk7XG4gICAgICAgICAgaWYgKGNvbnRleHQub3B0aW9ucy5leGl0KVxuICAgICAgICAgICAgY29udGV4dC5vcHRpb25zLmV4aXQuYXBwbHkoY29udGV4dCwgW3BvaW50LCBjb250ZXh0LmRhdGFdKTtcbiAgICAgICAgICBjb250ZXh0LmV4aXQocG9pbnQsIGNvbnRleHQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKGNvbnRleHQuZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICAgIGNvbnRleHQuZGF0YVsxXS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhLCBwb2ludEluZGV4KSB7XG4gICAgICAgICAgaWYgKGhhbmRsZWQuaW5kZXhPZihkYXRhLmtleSkgPT09IC0xKSB7XG4gICAgICAgICAgICB2YXIgcGFpcmVkID0gZGF0YTtcbiAgICAgICAgICAgIHZhciBwb2ludCA9IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1pc3Npbmc6IHRydWUsXG4gICAgICAgICAgICAgICAgbWV0YTogcGFpcmVkLm1ldGFcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZGF0YVxuICAgICAgICAgICAgXTtcblxuICAgICAgICAgICAgaWYgKGRhdGEuc3RhdGUgPT09ICdlbnRlcicgfHwgcGFpcmVkLnN0YXRlID09PSAnZW50ZXInKSB7XG4gICAgICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMuZW50ZXIpXG4gICAgICAgICAgICAgICAgY29udGV4dC5vcHRpb25zLmVudGVyLmFwcGx5KGNvbnRleHQsIFtwb2ludCwgY29udGV4dC5kYXRhXSk7XG4gICAgICAgICAgICAgIGNvbnRleHQuZW50ZXIocG9pbnQsIGNvbnRleHQuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkYXRhLnN0YXRlID09PSAndXBkYXRlJyB8fCBwYWlyZWQuc3RhdGUgPT09ICd1cGRhdGUnKSB7XG4gICAgICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMudXBkYXRlKVxuICAgICAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy51cGRhdGUuYXBwbHkoY29udGV4dCwgW3BvaW50LCBjb250ZXh0LmRhdGFdKTtcbiAgICAgICAgICAgICAgY29udGV4dC51cGRhdGUocG9pbnQsIGNvbnRleHQuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChkYXRhLnN0YXRlID09PSAnZXhpdCcgfHwgcGFpcmVkLnN0YXRlID09PSAnZXhpdCcpIHtcbiAgICAgICAgICAgICAgY29udGV4dC5kYXRhWzFdLnNwbGljZShwb2ludEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgaWYgKGNvbnRleHQub3B0aW9ucy5leGl0KVxuICAgICAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy5leGl0LmFwcGx5KGNvbnRleHQsIFtwb2ludCwgY29udGV4dC5kYXRhXSk7XG4gICAgICAgICAgICAgIGNvbnRleHQuZXhpdChwb2ludCwgY29udGV4dC5kYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRleHQub3B0aW9ucy5kb25lKVxuICAgICAgICBjb250ZXh0Lm9wdGlvbnMuZG9uZS5hcHBseShjb250ZXh0LCBjb250ZXh0LmRhdGEpO1xuICAgICAgaWYgKGNvbnRleHQuZG9uZSlcbiAgICAgICAgY29udGV4dC5kb25lKGNvbnRleHQuZGF0YSwgbWVzc2FnZXMpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGNvbnRleHQuZGF0YSk7XG4gICAgfSk7XG5cbiAgICAvL2NvbnNvbGUubG9nKCdxJywgYXJncyk7XG4gICAgam9vbGEucXVlcnkuZmV0Y2guYXBwbHkoY29udGV4dCwgYXJncyk7XG4gIH0pO1xufTtcblxudml6LnN0b3AgPSBmdW5jdGlvbiAoc2VsZiwgY2FsbGJhY2spIHtcbiAgaWYgKCFjYWxsYmFjaylcbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB9O1xuICBpZiAoc2VsZi5yZWFsdGltZVF1ZXJpZXMpIHtcbiAgICBhc3luYy5tYXAoc2VsZi5yZWFsdGltZVF1ZXJpZXMsIGZ1bmN0aW9uIChxLCBjYWxsYmFjaykge1xuICAgICAgam9vbGEubG9nZ2VyLmRlYnVnKCdTdG9wcGluZyByZWFsdGltZSBxdWVyeSBbJyArIHEgKyAnXS4nKTtcbiAgICAgIGpvb2xhLnF1ZXJ5LnN0b3AocSwgY2FsbGJhY2spO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgIH0pO1xuICB9XG4gIGVsc2VcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG59O1xuXG52aXouZGVzdHJveSA9IGZ1bmN0aW9uIChzZWxmLCB2aXpPcHRpb25zKSB7XG4gIGlmIChzZWxmLnJlYWx0aW1lUXVlcmllcykge1xuICAgIHNlbGYucmVhbHRpbWVRdWVyaWVzLmZvckVhY2goZnVuY3Rpb24gKHEpIHtcbiAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnU3RvcHBpbmcgcmVhbHRpbWUgcXVlcnkgWycgKyBxICsgJ10uJyk7XG4gICAgICBqb29sYS5xdWVyeS5zdG9wKHEpO1xuICAgIH0pO1xuICB9XG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgc2VsZi5kYXRhID0gW107XG4gIHNlbGYuZGVzdHJveSgpO1xuICBzZWxmLmRyYXcodml6T3B0aW9ucyk7XG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xufTtcblxuLy90aGlzIGlzIGEgbWFnaWMgZnVuY3Rpb24gZm9yIHBpY2tpbmcgdXAgbmFtZXNwYWNlJ2QgaXRlbXNcbi8qXG4gam9vbGEub24oJ3JlYWR5JywgZnVuY3Rpb24gKGVycikge1xuIGlmIChlcnIpXG4gcmV0dXJuO1xuXG4gT2JqZWN0LmtleXMoam9vbGEudml6KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiB2YXIgdmlzdWFsaXphdGlvbiA9IGpvb2xhLnZpeltrZXldO1xuIHZhciBqb29sYV9lbGVtZW50cyA9ICQkKCdqb29sYVxcXFw6JyArIGtleS50b0xvd2VyQ2FzZSgpKTtcbiBpZiAoam9vbGFfZWxlbWVudHMubGVuZ3RoID4gMCkge1xuICQuZWFjaChqb29sYV9lbGVtZW50cywgZnVuY3Rpb24gKGluZGV4LCBlbGVtZW50KSB7XG4gdmFyICRlbGVtZW50ID0gJCQoZWxlbWVudCk7XG4gLy9jaGVjayBub3QgbmVzdGVkIHVuZGVyIGEgY2FudmFzXG4gaWYgKCRlbGVtZW50LnBhcmVudHMoJ2pvb2xhXFxcXDpjYW52YXMnKS5sZW5ndGggPT09IDApIHtcbiB2YXIgYXR0cmlidXRlcyA9ICRlbGVtZW50LmdldCgwKS5hdHRyaWJ1dGVzO1xuIHZhciBvcHRpb25zID0ge1xuIGNvbnRhaW5lcjogJGVsZW1lbnRcbiB9O1xuIGZvciAodmFyIGkgPSAwOyBpIDwgYXR0cmlidXRlcy5sZW5ndGg7IGkrKykge1xuIHZhciBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGVzW2ldO1xuXG4gdmFyIHZhbHVlID0gbnVsbDtcbiB0cnkge1xuIHZhbHVlID0gSlNPTi5wYXJzZShhdHRyaWJ1dGUudmFsdWUpO1xuIH1cbiBjYXRjaCAoZXgpIHtcbiB0cnkge1xuIHZhbHVlID0gSlNPTi5wYXJzZShhdHRyaWJ1dGUudmFsdWUucmVwbGFjZSgvXFwnL2lnLCAnXCInKSk7XG4gfVxuIGNhdGNoIChleDIpIHtcbiB2YWx1ZSA9IGF0dHJpYnV0ZS52YWx1ZTtcbiB9XG4gfVxuIGpvb2xhLmNvbW1vbi5mbGF0R2V0U2V0KG9wdGlvbnMsIGF0dHJpYnV0ZS5uYW1lLCB2YWx1ZSk7XG4gfVxuIG5ldyB2aXN1YWxpemF0aW9uKG9wdGlvbnMpO1xuIH1cbiB9KTtcbiB9XG4gfSk7XG4gfSk7Ki8iXX0= +; \ No newline at end of file diff --git a/src/lib/common/api.js b/src/lib/common/api.js index 500dbf6..7ac9a6e 100644 --- a/src/lib/common/api.js +++ b/src/lib/common/api.js @@ -283,7 +283,10 @@ api.getJSON = function (options, objOptions, callback) { joola.io.socket.emit(routeID, objOptions); joola.events.emit('rpc:start', 1); joola.events.emit('bandwidth', lengthInUtf8Bytes(JSON.stringify(objOptions))); - if (objOptions && (objOptions.realtime || (objOptions.options && Array.isArray(objOptions.options) && objOptions.options.length > 0 && objOptions.options[0].realtime))) { + var shouldOn = objOptions && (objOptions.realtime || (objOptions.options && Array.isArray(objOptions.options) && objOptions.options.length > 0 && objOptions.options[0].realtime)); + if (objOptions && objOptions.options && objOptions.options.realtime) + shouldOn = true; + if (shouldOn) { joola.io.socket.on(routeID + ':done', processResponse); } else { diff --git a/src/lib/viz/Timeline.js b/src/lib/viz/Timeline.js index 7540b49..2213fdc 100644 --- a/src/lib/viz/Timeline.js +++ b/src/lib/viz/Timeline.js @@ -175,12 +175,12 @@ var Timeline = module.exports = function (options, callback) { var checkExists = function (timestampDimension, documents, date) { return _.find(documents, function (document) { - if (!document.values[timestampDimension.key]) + if (!document[timestampDimension.key]) return; try { var _date = new Date(date); - var _basedate = new Date(document.values[timestampDimension.key]); + var _basedate = new Date(document[timestampDimension.key]); switch (interval) { case 'month': @@ -206,8 +206,8 @@ var Timeline = module.exports = function (options, callback) { var fill = function (resultRow, row, timestampDimension) { Object.keys(resultRow).forEach(function (key) { if (key !== timestampDimension.key) { - row.values[key] = 0; - row.fvalues[key] = 0; + row[key] = 0; + //row.fvalues[key] = 0; } }); }; @@ -216,12 +216,12 @@ var Timeline = module.exports = function (options, callback) { if (result.documents.length === 0) { result.documents.push({values: {}, fvalues: {}}); result.dimensions.forEach(function (d) { - result.documents[0].values[d.name] = null; - result.documents[0].fvalues[d.name] = null; + result.documents[0][d.name] = null; + //result.documents[0].fvalues[d.name] = null; }); result.metrics.forEach(function (m) { - result.documents[0].values[m.name] = null; - result.documents[0].fvalues[m.name] = null; + result.documents[0][m.name] = null; + //result.documents[0].fvalues[m.name] = null; }); } @@ -239,8 +239,8 @@ var Timeline = module.exports = function (options, callback) { interval = interval === 'ddate' ? 'day' : (interval || 'day'); if (!query.timeframe) { query.timeframe = {}; - query.timeframe.start = result.documents[result.documents.length - 1].values.timestamp; - query.timeframe.end = result.documents[0].values.timestamp; + query.timeframe.start = result.documents[result.documents.length - 1].timestamp; + query.timeframe.end = result.documents[0].timestamp; } var counter = 0; @@ -270,9 +270,9 @@ var Timeline = module.exports = function (options, callback) { if (!exists) { //_d.setHours(_d.getHours() + (offset * -1)); exists = {values: {}, fvalues: {}}; - exists.values[timestampDimension.key] = _d.toISOString(); - exists.fvalues[timestampDimension.key] = _d.toISOString(); - fill(result.documents[0].values, exists, timestampDimension); + exists[timestampDimension.key] = _d.toISOString(); + //exists.fvalues[timestampDimension.key] = _d.toISOString(); + fill(result.documents[0], exists, timestampDimension); } fixed.push(exists); } @@ -311,20 +311,20 @@ var Timeline = module.exports = function (options, callback) { if (nameBased) { series[seriesIndex].data.push({ name: x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } else { if (seriesIndex === 0) { series[seriesIndex].data.push({ x: x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } else { series[seriesIndex].data.push({ x: series[0].data[docIndex].x, - y: document.values[metrics[index].key] ? document.values[metrics[index].key] : 0 + y: document[metrics[index].key] ? document[metrics[index].key] : 0 }); } } diff --git a/src/lib/viz/index.js b/src/lib/viz/index.js index ee84faa..18cf85c 100644 --- a/src/lib/viz/index.js +++ b/src/lib/viz/index.js @@ -194,13 +194,14 @@ viz.fetch = function (context, query, callback) { realtime: message.query.realtime }; var key = ''; + console.log(doc); message.dimensions.forEach(function (d) { - key += doc.raw.values[d.key]; - doc.dimensions[d.key] = doc.raw.values[d.key]; + key += doc.raw[d.key]; + doc.dimensions[d.key] = doc.raw[d.key]; doc.meta[d.key] = d; }); message.metrics.forEach(function (m) { - doc.metrics[m.key] = doc.raw.values[m.key]; + doc.metrics[m.key] = doc.raw[m.key]; doc.meta[m.key] = m; }); doc.key = joola.common.hash(key); From d07bf3e93b822e5d2e9236ddfd1d78df7feb0f8b Mon Sep 17 00:00:00 2001 From: Itay Weinberger Date: Mon, 19 Jan 2015 10:04:38 +0200 Subject: [PATCH 2/3] #152 cleanup of small bugs and defects. --- build/release/joola.js | 19398 ++++++++++++++++++------------- build/release/joola.min.css | 2 +- build/release/joola.min.js | 24 +- build/release/joola.min.js.map | 2 +- build/temp/joola.js | 2808 +++-- package.json | 2 +- src/lib/viz/Canvas.js | 53 +- src/lib/viz/Table.js | 1366 +-- src/lib/viz/Timeline.js | 38 +- src/lib/viz/index.js | 1 + 10 files changed, 14259 insertions(+), 9435 deletions(-) diff --git a/build/release/joola.js b/build/release/joola.js index dd1b09a..a2bafc2 100644 --- a/build/release/joola.js +++ b/build/release/joola.js @@ -1,3 +1,6 @@ +;(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0) + { + if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html + { a[key] = extenduptolevel([], b[key],levels-1,context,newobjs,a,key,true); } + else if(b[key]===null) + { a[key] = null; } + else if( b[key] instanceof Date ) + { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } + else + { a[key] = extenduptolevel({}, b[key],levels-1,context,newobjs,a,key,true); } + } + else + { a[key] = b[key]; } + } + else if(typeof a[key] === 'object' && a[key] !== null && levels>0) + { a[key] = extenduptolevel(a[key], b[key],levels-1,context,newobjs,a,key,true); } + else + { a[key] = b[key]; } + } + } + if(clean_context) {context=null;newobjs=null;} + + if(!haveaparent) + { + aparent=null; + return a; + } + if(typeof a === 'object' && !(a instanceof Array) ) + { + /*a.constructor = b.constructor; + a.prototype = b.prototype;*/ + } + return a; +} exports.extenduptolevel=extenduptolevel; + +function clone(obj) +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + if (obj instanceof Array ) + { return extend([], obj); } + else if( obj instanceof Date ) + { + var t= new obj.constructor(); + t.setTime(obj.getTime()); + return t; + } + else + { return extend({}, obj); } + } + return obj; +} exports.clone=clone; + +function cloneextend(obj,exteddata) +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + return extend(clone(obj),exteddata); + } + return obj; +} exports.cloneextend=cloneextend; + + +function cloneuptolevel(obj,level) // clone only numlevels levels other levels leave references +{ + if (typeof obj === 'object') + { + if (obj ===null ) { return null; } + if (obj instanceof Array ) { return extenduptolevel([], obj,level); } + return extenduptolevel({}, obj,level); + } + return obj; +} exports.cloneuptolevel=cloneuptolevel; + +function foreach(object, block, context) +{ + if (object) + { + if (typeof object === "object" && object instanceof Array) + return object.forEach(object, block, context) + else //if (typeof object === "object") // or (object instanceof Function)... + { + if(object) + for (var key in object) + { + if(object.hasOwnProperty(key)) + { + if(block.call(context, object[key], key, object)===false)break; + } + } + } + } +} exports.foreach=foreach; + +/* + hasbugs and useless, yet interesting maybe developed later for dot pathed object transformation: + + { + 'foo.bar':'bluebar', + 'foo.color':'blue' + } + + transforemed to + + { + foo: + { + bar:'bluebar', + color:'blue' + } + } + + like: + + var config={}; + cloneextend.dotpath(config,{ + 'foo.bar':'bluebar', + 'foo.color':'blue' + }) + + // + function dotpath(data,dotkeys,preserve) + { + if(!preserve)preserve=false; + var create=!preserve; + if(create) if(!data) data={}; + var keys= dotkeys.split("."),value=data; + for (var i=0;i + * @license MIT + * + * The MIT License (MIT) + * + * Copyright (c) 2013 Viacheslav Lotsmanov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. * - * @author Feross Aboukhadijeh - * @license MIT + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -var base64 = require('base64-js') -var ieee754 = require('ieee754') - -exports.Buffer = Buffer -exports.SlowBuffer = Buffer -exports.INSPECT_MAX_BYTES = 50 -Buffer.poolSize = 8192 - /** - * If `Buffer._useTypedArrays`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (compatible down to IE6) + * Extening object that entered in first argument. + * Returns extended object or false if have no target object or incorrect type. + * If you wish to clone object, simply use that: + * deepExtend({}, yourObj_1, [yourObj_N]) - first arg is new empty object */ -Buffer._useTypedArrays = (function () { - // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, - // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding - // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support - // because we need to be able to add all the node Buffer API methods. This is an issue - // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 - try { - var buf = new ArrayBuffer(0) - var arr = new Uint8Array(buf) - arr.foo = function () { return 42 } - return 42 === arr.foo() && - typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` - } catch (e) { - return false - } -})() +var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { + if (arguments.length < 1 || typeof arguments[0] !== 'object') { + return false; + } -/** - * Class: Buffer - * ============= - * - * The Buffer constructor returns instances of `Uint8Array` that are augmented - * with function properties for all the node `Buffer` API functions. We use - * `Uint8Array` so that square bracket notation works as expected -- it returns - * a single octet. - * - * By augmenting the instances, we can avoid modifying the `Uint8Array` - * prototype. - */ -function Buffer (subject, encoding, noZero) { - if (!(this instanceof Buffer)) - return new Buffer(subject, encoding, noZero) + if (arguments.length < 2) return arguments[0]; - var type = typeof subject + var target = arguments[0]; - // Workaround: node's base64 implementation allows for non-padded strings - // while base64-js does not. - if (encoding === 'base64' && type === 'string') { - subject = stringtrim(subject) - while (subject.length % 4 !== 0) { - subject = subject + '=' - } - } + // convert arguments to array and cut off target object + var args = Array.prototype.slice.call(arguments, 1); - // Find the length - var length - if (type === 'number') - length = coerce(subject) - else if (type === 'string') - length = Buffer.byteLength(subject, encoding) - else if (type === 'object') - length = coerce(subject.length) // assume that object is array-like - else - throw new Error('First argument needs to be a number, array or string.') + var key, val, src, clone, tmpBuf; - var buf - if (Buffer._useTypedArrays) { - // Preferred: Return an augmented `Uint8Array` instance for best performance - buf = Buffer._augment(new Uint8Array(length)) - } else { - // Fallback: Return THIS instance of Buffer (created by `new`) - buf = this - buf.length = length - buf._isBuffer = true - } - - var i - if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { - // Speed optimization -- use set if we're copying from a typed array - buf._set(subject) - } else if (isArrayish(subject)) { - // Treat array-ish objects as a byte array - for (i = 0; i < length; i++) { - if (Buffer.isBuffer(subject)) - buf[i] = subject.readUInt8(i) - else - buf[i] = subject[i] - } - } else if (type === 'string') { - buf.write(subject, 0, encoding) - } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { - for (i = 0; i < length; i++) { - buf[i] = 0 - } - } + args.forEach(function (obj) { + if (typeof obj !== 'object') return; - return buf -} + for (key in obj) { + if ( ! (key in obj)) continue; -// STATIC METHODS -// ============== + src = target[key]; + val = obj[key]; -Buffer.isEncoding = function (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'raw': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} + if (val === target) continue; -Buffer.isBuffer = function (b) { - return !!(b !== null && b !== undefined && b._isBuffer) -} + if (typeof val !== 'object' || val === null) { + target[key] = val; + continue; + } else if (val instanceof Buffer) { + tmpBuf = new Buffer(val.length); + val.copy(tmpBuf); + target[key] = tmpBuf; + continue; + } else if (val instanceof Date) { + target[key] = new Date(val.getTime()); + continue; + } -Buffer.byteLength = function (str, encoding) { - var ret - str = str + '' - switch (encoding || 'utf8') { - case 'hex': - ret = str.length / 2 - break - case 'utf8': - case 'utf-8': - ret = utf8ToBytes(str).length - break - case 'ascii': - case 'binary': - case 'raw': - ret = str.length - break - case 'base64': - ret = base64ToBytes(str).length - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = str.length * 2 - break - default: - throw new Error('Unknown encoding') - } - return ret + if (typeof src !== 'object' || src === null) { + clone = (Array.isArray(val)) ? [] : {}; + target[key] = deepExtend(clone, val); + continue; + } + + if (Array.isArray(val)) { + clone = (Array.isArray(src)) ? src : []; + } else { + clone = (!Array.isArray(src)) ? src : {}; + } + + target[key] = deepExtend(clone, val); + } + }); + + return target; } -Buffer.concat = function (list, totalLength) { - assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + - 'list should be an Array.') +},{"__browserify_Buffer":49}],6:[function(require,module,exports){ +/*! + * EventEmitter2 + * https://github.com/hij1nx/EventEmitter2 + * + * Copyright (c) 2013 hij1nx + * Licensed under the MIT license. + */ +;!function(undefined) { - if (list.length === 0) { - return new Buffer(0) - } else if (list.length === 1) { - return list[0] - } + var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }; + var defaultMaxListeners = 10; - var i - if (typeof totalLength !== 'number') { - totalLength = 0 - for (i = 0; i < list.length; i++) { - totalLength += list[i].length + function init() { + this._events = {}; + if (this._conf) { + configure.call(this, this._conf); } } - var buf = new Buffer(totalLength) - var pos = 0 - for (i = 0; i < list.length; i++) { - var item = list[i] - item.copy(buf, pos) - pos += item.length - } - return buf -} + function configure(conf) { + if (conf) { + + this._conf = conf; -// BUFFER INSTANCE METHODS -// ======================= + conf.delimiter && (this.delimiter = conf.delimiter); + conf.maxListeners && (this._events.maxListeners = conf.maxListeners); + conf.wildcard && (this.wildcard = conf.wildcard); + conf.newListener && (this.newListener = conf.newListener); -function _hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining + if (this.wildcard) { + this.listenerTree = {}; + } } } - // must be an even number of digits - var strLen = string.length - assert(strLen % 2 === 0, 'Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; i++) { - var byte = parseInt(string.substr(i * 2, 2), 16) - assert(!isNaN(byte), 'Invalid hex string') - buf[offset + i] = byte + function EventEmitter(conf) { + this._events = {}; + this.newListener = false; + configure.call(this, conf); } - Buffer._charsWritten = i * 2 - return i -} - -function _utf8Write (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(utf8ToBytes(string), buf, offset, length) - return charsWritten -} -function _asciiWrite (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(asciiToBytes(string), buf, offset, length) - return charsWritten -} + // + // Attention, function return type now is array, always ! + // It has zero elements if no any matches found and one or more + // elements (leafs) if there are matches + // + function searchListenerTree(handlers, type, tree, i) { + if (!tree) { + return []; + } + var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, + typeLength = type.length, currentType = type[i], nextType = type[i+1]; + if (i === typeLength && tree._listeners) { + // + // If at the end of the event(s) list and the tree has listeners + // invoke those listeners. + // + if (typeof tree._listeners === 'function') { + handlers && handlers.push(tree._listeners); + return [tree]; + } else { + for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { + handlers && handlers.push(tree._listeners[leaf]); + } + return [tree]; + } + } -function _binaryWrite (buf, string, offset, length) { - return _asciiWrite(buf, string, offset, length) -} + if ((currentType === '*' || currentType === '**') || tree[currentType]) { + // + // If the event emitted is '*' at this part + // or there is a concrete match at this patch + // + if (currentType === '*') { + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); + } + } + return listeners; + } else if(currentType === '**') { + endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); + if(endReached && tree._listeners) { + // The next element has a _listeners, add it to the handlers. + listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); + } -function _base64Write (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(base64ToBytes(string), buf, offset, length) - return charsWritten -} + for (branch in tree) { + if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { + if(branch === '*' || branch === '**') { + if(tree[branch]._listeners && !endReached) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); + } + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } else if(branch === nextType) { + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); + } else { + // No match on this one, shift into the tree but not in the type array. + listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); + } + } + } + return listeners; + } -function _utf16leWrite (buf, string, offset, length) { - var charsWritten = Buffer._charsWritten = - blitBuffer(utf16leToBytes(string), buf, offset, length) - return charsWritten -} + listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); + } -Buffer.prototype.write = function (string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length - length = undefined + xTree = tree['*']; + if (xTree) { + // + // If the listener tree will allow any match for this part, + // then recursively explore all branches of the tree + // + searchListenerTree(handlers, type, xTree, i+1); } - } else { // legacy - var swap = encoding - encoding = offset - offset = length - length = swap - } - offset = Number(offset) || 0 - var remaining = this.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining + xxTree = tree['**']; + if(xxTree) { + if(i < typeLength) { + if(xxTree._listeners) { + // If we have a listener on a '**', it will catch all, so add its handler. + searchListenerTree(handlers, type, xxTree, typeLength); + } + + // Build arrays of matching next branches and others. + for(branch in xxTree) { + if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { + if(branch === nextType) { + // We know the next element will match, so jump twice. + searchListenerTree(handlers, type, xxTree[branch], i+2); + } else if(branch === currentType) { + // Current node matches, move into the tree. + searchListenerTree(handlers, type, xxTree[branch], i+1); + } else { + isolatedBranch = {}; + isolatedBranch[branch] = xxTree[branch]; + searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); + } + } + } + } else if(xxTree._listeners) { + // We have reached the end and still on a '**' + searchListenerTree(handlers, type, xxTree, typeLength); + } else if(xxTree['*'] && xxTree['*']._listeners) { + searchListenerTree(handlers, type, xxTree['*'], typeLength); + } } - } - encoding = String(encoding || 'utf8').toLowerCase() - var ret - switch (encoding) { - case 'hex': - ret = _hexWrite(this, string, offset, length) - break - case 'utf8': - case 'utf-8': - ret = _utf8Write(this, string, offset, length) - break - case 'ascii': - ret = _asciiWrite(this, string, offset, length) - break - case 'binary': - ret = _binaryWrite(this, string, offset, length) - break - case 'base64': - ret = _base64Write(this, string, offset, length) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = _utf16leWrite(this, string, offset, length) - break - default: - throw new Error('Unknown encoding') + return listeners; } - return ret -} -Buffer.prototype.toString = function (encoding, start, end) { - var self = this + function growListenerTree(type, listener) { - encoding = String(encoding || 'utf8').toLowerCase() - start = Number(start) || 0 - end = (end !== undefined) - ? Number(end) - : end = self.length + type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - // Fastpath empty strings - if (end === start) - return '' + // + // Looks for two consecutive '**', if so, don't add the event at all. + // + for(var i = 0, len = type.length; i+1 < len; i++) { + if(type[i] === '**' && type[i+1] === '**') { + return; + } + } - var ret - switch (encoding) { - case 'hex': - ret = _hexSlice(self, start, end) - break - case 'utf8': - case 'utf-8': - ret = _utf8Slice(self, start, end) - break - case 'ascii': - ret = _asciiSlice(self, start, end) - break - case 'binary': - ret = _binarySlice(self, start, end) - break - case 'base64': - ret = _base64Slice(self, start, end) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = _utf16leSlice(self, start, end) - break - default: - throw new Error('Unknown encoding') - } - return ret -} + var tree = this.listenerTree; + var name = type.shift(); -Buffer.prototype.toJSON = function () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} + while (name) { -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function (target, target_start, start, end) { - var source = this + if (!tree[name]) { + tree[name] = {}; + } - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (!target_start) target_start = 0 + tree = tree[name]; - // Copy 0 bytes; we're done - if (end === start) return - if (target.length === 0 || source.length === 0) return + if (type.length === 0) { - // Fatal error conditions - assert(end >= start, 'sourceEnd < sourceStart') - assert(target_start >= 0 && target_start < target.length, - 'targetStart out of bounds') - assert(start >= 0 && start < source.length, 'sourceStart out of bounds') - assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + if (!tree._listeners) { + tree._listeners = listener; + } + else if(typeof tree._listeners === 'function') { + tree._listeners = [tree._listeners, listener]; + } + else if (isArray(tree._listeners)) { - // Are we oob? - if (end > this.length) - end = this.length - if (target.length - target_start < end - start) - end = target.length - target_start + start + tree._listeners.push(listener); - var len = end - start + if (!tree._listeners.warned) { - if (len < 100 || !Buffer._useTypedArrays) { - for (var i = 0; i < len; i++) - target[i + target_start] = this[i + start] - } else { - target._set(this.subarray(start, start + len), target_start) - } -} + var m = defaultMaxListeners; -function _base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } -function _utf8Slice (buf, start, end) { - var res = '' - var tmp = '' - end = Math.min(buf.length, end) + if (m > 0 && tree._listeners.length > m) { - for (var i = start; i < end; i++) { - if (buf[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) - tmp = '' - } else { - tmp += '%' + buf[i].toString(16) + tree._listeners.warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + tree._listeners.length); + console.trace(); + } + } + } + return true; + } + name = type.shift(); } + return true; } - return res + decodeUtf8Char(tmp) -} - -function _asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; i++) - ret += String.fromCharCode(buf[i]) - return ret -} - -function _binarySlice (buf, start, end) { - return _asciiSlice(buf, start, end) -} + // By default EventEmitters will print a warning if more than + // 10 listeners are added to it. This is a useful default which + // helps finding memory leaks. + // + // Obviously not all Emitters should be limited to 10. This function allows + // that to be increased. Set to zero for unlimited. -function _hexSlice (buf, start, end) { - var len = buf.length + EventEmitter.prototype.delimiter = '.'; - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len + EventEmitter.prototype.setMaxListeners = function(n) { + this._events || init.call(this); + this._events.maxListeners = n; + if (!this._conf) this._conf = {}; + this._conf.maxListeners = n; + }; - var out = '' - for (var i = start; i < end; i++) { - out += toHex(buf[i]) - } - return out -} + EventEmitter.prototype.event = ''; -function _utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i+1] * 256) - } - return res -} + EventEmitter.prototype.once = function(event, fn) { + this.many(event, 1, fn); + return this; + }; -Buffer.prototype.slice = function (start, end) { - var len = this.length - start = clamp(start, len, 0) - end = clamp(end, len, len) + EventEmitter.prototype.many = function(event, ttl, fn) { + var self = this; - if (Buffer._useTypedArrays) { - return Buffer._augment(this.subarray(start, end)) - } else { - var sliceLen = end - start - var newBuf = new Buffer(sliceLen, undefined, true) - for (var i = 0; i < sliceLen; i++) { - newBuf[i] = this[i + start] + if (typeof fn !== 'function') { + throw new Error('many only accepts instances of Function'); } - return newBuf - } -} - -// `get` will be removed in Node 0.13+ -Buffer.prototype.get = function (offset) { - console.log('.get() is deprecated. Access using array indexes instead.') - return this.readUInt8(offset) -} - -// `set` will be removed in Node 0.13+ -Buffer.prototype.set = function (v, offset) { - console.log('.set() is deprecated. Access using array indexes instead.') - return this.writeUInt8(v, offset) -} -Buffer.prototype.readUInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } + function listener() { + if (--ttl === 0) { + self.off(event, listener); + } + fn.apply(this, arguments); + } - if (offset >= this.length) - return + listener._origin = fn; - return this[offset] -} + this.on(event, listener); -function _readUInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } + return self; + }; - var len = buf.length - if (offset >= len) - return + EventEmitter.prototype.emit = function() { - var val - if (littleEndian) { - val = buf[offset] - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - } else { - val = buf[offset] << 8 - if (offset + 1 < len) - val |= buf[offset + 1] - } - return val -} + this._events || init.call(this); -Buffer.prototype.readUInt16LE = function (offset, noAssert) { - return _readUInt16(this, offset, true, noAssert) -} + var type = arguments[0]; -Buffer.prototype.readUInt16BE = function (offset, noAssert) { - return _readUInt16(this, offset, false, noAssert) -} + if (type === 'newListener' && !this.newListener) { + if (!this._events.newListener) { return false; } + } -function _readUInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + // Loop through the *_all* functions and invoke them. + if (this._all) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + for (i = 0, l = this._all.length; i < l; i++) { + this.event = type; + this._all[i].apply(this, args); + } + } - var len = buf.length - if (offset >= len) - return + // If there is no 'error' event listener then throw. + if (type === 'error') { - var val - if (littleEndian) { - if (offset + 2 < len) - val = buf[offset + 2] << 16 - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - val |= buf[offset] - if (offset + 3 < len) - val = val + (buf[offset + 3] << 24 >>> 0) - } else { - if (offset + 1 < len) - val = buf[offset + 1] << 16 - if (offset + 2 < len) - val |= buf[offset + 2] << 8 - if (offset + 3 < len) - val |= buf[offset + 3] - val = val + (buf[offset] << 24 >>> 0) - } - return val -} + if (!this._all && + !this._events.error && + !(this.wildcard && this.listenerTree.error)) { -Buffer.prototype.readUInt32LE = function (offset, noAssert) { - return _readUInt32(this, offset, true, noAssert) -} + if (arguments[1] instanceof Error) { + throw arguments[1]; // Unhandled 'error' event + } else { + throw new Error("Uncaught, unspecified 'error' event."); + } + return false; + } + } -Buffer.prototype.readUInt32BE = function (offset, noAssert) { - return _readUInt32(this, offset, false, noAssert) -} + var handler; -Buffer.prototype.readInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, - 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } + if(this.wildcard) { + handler = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handler, ns, this.listenerTree, 0); + } + else { + handler = this._events[type]; + } - if (offset >= this.length) - return + if (typeof handler === 'function') { + this.event = type; + if (arguments.length === 1) { + handler.call(this); + } + else if (arguments.length > 1) + switch (arguments.length) { + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; + handler.apply(this, args); + } + return true; + } + else if (handler) { + var l = arguments.length; + var args = new Array(l - 1); + for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - var neg = this[offset] & 0x80 - if (neg) - return (0xff - this[offset] + 1) * -1 - else - return this[offset] -} + var listeners = handler.slice(); + for (var i = 0, l = listeners.length; i < l; i++) { + this.event = type; + listeners[i].apply(this, args); + } + return (listeners.length > 0) || !!this._all; + } + else { + return !!this._all; + } -function _readInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } + }; - var len = buf.length - if (offset >= len) - return + EventEmitter.prototype.on = function(type, listener) { - var val = _readUInt16(buf, offset, littleEndian, true) - var neg = val & 0x8000 - if (neg) - return (0xffff - val + 1) * -1 - else - return val -} + if (typeof type === 'function') { + this.onAny(type); + return this; + } -Buffer.prototype.readInt16LE = function (offset, noAssert) { - return _readInt16(this, offset, true, noAssert) -} + if (typeof listener !== 'function') { + throw new Error('on only accepts instances of Function'); + } + this._events || init.call(this); -Buffer.prototype.readInt16BE = function (offset, noAssert) { - return _readInt16(this, offset, false, noAssert) -} + // To avoid recursion in the case that type == "newListeners"! Before + // adding it to the listeners, first emit "newListeners". + this.emit('newListener', type, listener); -function _readInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + if(this.wildcard) { + growListenerTree.call(this, type, listener); + return this; + } - var len = buf.length - if (offset >= len) - return + if (!this._events[type]) { + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + } + else if(typeof this._events[type] === 'function') { + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + } + else if (isArray(this._events[type])) { + // If we've already got an array, just append. + this._events[type].push(listener); - var val = _readUInt32(buf, offset, littleEndian, true) - var neg = val & 0x80000000 - if (neg) - return (0xffffffff - val + 1) * -1 - else - return val -} + // Check for listener leak + if (!this._events[type].warned) { -Buffer.prototype.readInt32LE = function (offset, noAssert) { - return _readInt32(this, offset, true, noAssert) -} + var m = defaultMaxListeners; -Buffer.prototype.readInt32BE = function (offset, noAssert) { - return _readInt32(this, offset, false, noAssert) -} + if (typeof this._events.maxListeners !== 'undefined') { + m = this._events.maxListeners; + } -function _readFloat (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } + if (m > 0 && this._events[type].length > m) { - return ieee754.read(buf, offset, littleEndian, 23, 4) -} + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } + } + } + return this; + }; -Buffer.prototype.readFloatLE = function (offset, noAssert) { - return _readFloat(this, offset, true, noAssert) -} + EventEmitter.prototype.onAny = function(fn) { -Buffer.prototype.readFloatBE = function (offset, noAssert) { - return _readFloat(this, offset, false, noAssert) -} + if (typeof fn !== 'function') { + throw new Error('onAny only accepts instances of Function'); + } -function _readDouble (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') - } + if(!this._all) { + this._all = []; + } - return ieee754.read(buf, offset, littleEndian, 52, 8) -} + // Add the function to the event listener collection. + this._all.push(fn); + return this; + }; -Buffer.prototype.readDoubleLE = function (offset, noAssert) { - return _readDouble(this, offset, true, noAssert) -} + EventEmitter.prototype.addListener = EventEmitter.prototype.on; -Buffer.prototype.readDoubleBE = function (offset, noAssert) { - return _readDouble(this, offset, false, noAssert) -} + EventEmitter.prototype.off = function(type, listener) { + if (typeof listener !== 'function') { + throw new Error('removeListener only takes instances of Function'); + } -Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'trying to write beyond buffer length') - verifuint(value, 0xff) - } + var handlers,leafs=[]; - if (offset >= this.length) return + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); + } + else { + // does not use listeners(), so no side effect of creating _events[type] + if (!this._events[type]) return this; + handlers = this._events[type]; + leafs.push({_listeners:handlers}); + } - this[offset] = value -} + for (var iLeaf=0; iLeaf= len) - return + for (var i = 0, length = handlers.length; i < length; i++) { + if (handlers[i] === listener || + (handlers[i].listener && handlers[i].listener === listener) || + (handlers[i]._origin && handlers[i]._origin === listener)) { + position = i; + break; + } + } - for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { - buf[offset + i] = - (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } -} + if (position < 0) { + continue; + } -Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { - _writeUInt16(this, value, offset, true, noAssert) -} + if(this.wildcard) { + leaf._listeners.splice(position, 1); + } + else { + this._events[type].splice(position, 1); + } -Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { - _writeUInt16(this, value, offset, false, noAssert) -} + if (handlers.length === 0) { + if(this.wildcard) { + delete leaf._listeners; + } + else { + delete this._events[type]; + } + } + return this; + } + else if (handlers === listener || + (handlers.listener && handlers.listener === listener) || + (handlers._origin && handlers._origin === listener)) { + if(this.wildcard) { + delete leaf._listeners; + } + else { + delete this._events[type]; + } + } + } -function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'trying to write beyond buffer length') - verifuint(value, 0xffffffff) - } + return this; + }; - var len = buf.length - if (offset >= len) - return + EventEmitter.prototype.offAny = function(fn) { + var i = 0, l = 0, fns; + if (fn && this._all && this._all.length > 0) { + fns = this._all; + for(i = 0, l = fns.length; i < l; i++) { + if(fn === fns[i]) { + fns.splice(i, 1); + return this; + } + } + } else { + this._all = []; + } + return this; + }; - for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { - buf[offset + i] = - (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } -} + EventEmitter.prototype.removeListener = EventEmitter.prototype.off; -Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { - _writeUInt32(this, value, offset, true, noAssert) -} + EventEmitter.prototype.removeAllListeners = function(type) { + if (arguments.length === 0) { + !this._events || init.call(this); + return this; + } -Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { - _writeUInt32(this, value, offset, false, noAssert) -} + if(this.wildcard) { + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); -Buffer.prototype.writeInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7f, -0x80) - } + for (var iLeaf=0; iLeaf= this.length) - return + EventEmitter.prototype.listeners = function(type) { + if(this.wildcard) { + var handlers = []; + var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); + searchListenerTree.call(this, handlers, ns, this.listenerTree, 0); + return handlers; + } - if (value >= 0) - this.writeUInt8(value, offset, noAssert) - else - this.writeUInt8(0xff + value + 1, offset, noAssert) -} + this._events || init.call(this); -function _writeInt16 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fff, -0x8000) - } + if (!this._events[type]) this._events[type] = []; + if (!isArray(this._events[type])) { + this._events[type] = [this._events[type]]; + } + return this._events[type]; + }; - var len = buf.length - if (offset >= len) - return + EventEmitter.prototype.listenersAny = function() { - if (value >= 0) - _writeUInt16(buf, value, offset, littleEndian, noAssert) - else - _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) -} + if(this._all) { + return this._all; + } + else { + return []; + } -Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { - _writeInt16(this, value, offset, true, noAssert) -} + }; -Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { - _writeInt16(this, value, offset, false, noAssert) -} - -function _writeInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fffffff, -0x80000000) + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(function() { + return EventEmitter; + }); + } else if (typeof exports === 'object') { + // CommonJS + exports.EventEmitter2 = EventEmitter; + } + else { + // Browser global. + window.EventEmitter2 = EventEmitter; } +}(); - var len = buf.length - if (offset >= len) - return +},{}],7:[function(require,module,exports){ - if (value >= 0) - _writeUInt32(buf, value, offset, littleEndian, noAssert) - else - _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) -} -Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { - _writeInt32(this, value, offset, true, noAssert) -} +// +// The shims in this file are not fully implemented shims for the ES5 +// features, but do work for the particular usecases there is in +// the other modules. +// -Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { - _writeInt32(this, value, offset, false, noAssert) +var toString = Object.prototype.toString; +var hasOwnProperty = Object.prototype.hasOwnProperty; + +// Array.isArray is supported in IE9 +function isArray(xs) { + return toString.call(xs) === '[object Array]'; } +exports.isArray = typeof Array.isArray === 'function' ? Array.isArray : isArray; -function _writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) +// Array.prototype.indexOf is supported in IE9 +exports.indexOf = function indexOf(xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; } + return -1; +}; - var len = buf.length - if (offset >= len) - return +// Array.prototype.filter is supported in IE9 +exports.filter = function filter(xs, fn) { + if (xs.filter) return xs.filter(fn); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (fn(xs[i], i, xs)) res.push(xs[i]); + } + return res; +}; - ieee754.write(buf, value, offset, littleEndian, 23, 4) -} +// Array.prototype.forEach is supported in IE9 +exports.forEach = function forEach(xs, fn, self) { + if (xs.forEach) return xs.forEach(fn, self); + for (var i = 0; i < xs.length; i++) { + fn.call(self, xs[i], i, xs); + } +}; -Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { - _writeFloat(this, value, offset, true, noAssert) -} +// Array.prototype.map is supported in IE9 +exports.map = function map(xs, fn) { + if (xs.map) return xs.map(fn); + var out = new Array(xs.length); + for (var i = 0; i < xs.length; i++) { + out[i] = fn(xs[i], i, xs); + } + return out; +}; -Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { - _writeFloat(this, value, offset, false, noAssert) -} +// Array.prototype.reduce is supported in IE9 +exports.reduce = function reduce(array, callback, opt_initialValue) { + if (array.reduce) return array.reduce(callback, opt_initialValue); + var value, isValueSet = false; -function _writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 7 < buf.length, - 'Trying to write beyond buffer length') - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + if (2 < arguments.length) { + value = opt_initialValue; + isValueSet = true; + } + for (var i = 0, l = array.length; l > i; ++i) { + if (array.hasOwnProperty(i)) { + if (isValueSet) { + value = callback(value, array[i], i, array); + } + else { + value = array[i]; + isValueSet = true; + } + } } - var len = buf.length - if (offset >= len) - return + return value; +}; - ieee754.write(buf, value, offset, littleEndian, 52, 8) -} +// String.prototype.substr - negative index don't work in IE8 +if ('ab'.substr(-1) !== 'b') { + exports.substr = function (str, start, length) { + // did we get a negative start, calculate how much it is from the beginning of the string + if (start < 0) start = str.length + start; -Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { - _writeDouble(this, value, offset, true, noAssert) + // call the original function + return str.substr(start, length); + }; +} else { + exports.substr = function (str, start, length) { + return str.substr(start, length); + }; } -Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { - _writeDouble(this, value, offset, false, noAssert) -} +// String.prototype.trim is supported in IE9 +exports.trim = function (str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +}; -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function (value, start, end) { - if (!value) value = 0 - if (!start) start = 0 - if (!end) end = this.length +// Function.prototype.bind is supported in IE9 +exports.bind = function () { + var args = Array.prototype.slice.call(arguments); + var fn = args.shift(); + if (fn.bind) return fn.bind.apply(fn, args); + var self = args.shift(); + return function () { + fn.apply(self, args.concat([Array.prototype.slice.call(arguments)])); + }; +}; - if (typeof value === 'string') { - value = value.charCodeAt(0) +// Object.create is supported in IE9 +function create(prototype, properties) { + var object; + if (prototype === null) { + object = { '__proto__' : null }; } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); + } + return object; +} +exports.create = typeof Object.create === 'function' ? Object.create : create; - assert(typeof value === 'number' && !isNaN(value), 'value is not a number') - assert(end >= start, 'end < start') - - // Fill 0 bytes; we're done - if (end === start) return - if (this.length === 0) return - - assert(start >= 0 && start < this.length, 'start out of bounds') - assert(end >= 0 && end <= this.length, 'end out of bounds') +// Object.keys and Object.getOwnPropertyNames is supported in IE9 however +// they do show a description and number property on Error objects +function notObject(object) { + return ((typeof object != "object" && typeof object != "function") || object === null); +} - for (var i = start; i < end; i++) { - this[i] = value +function keysShim(object) { + if (notObject(object)) { + throw new TypeError("Object.keys called on a non-object"); } -} -Buffer.prototype.inspect = function () { - var out = [] - var len = this.length - for (var i = 0; i < len; i++) { - out[i] = toHex(this[i]) - if (i === exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...' - break + var result = []; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result.push(name); } } - return '' + return result; } -/** - * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. - * Added in Node 0.12. Only available in browsers that support ArrayBuffer. - */ -Buffer.prototype.toArrayBuffer = function () { - if (typeof Uint8Array !== 'undefined') { - if (Buffer._useTypedArrays) { - return (new Buffer(this)).buffer - } else { - var buf = new Uint8Array(this.length) - for (var i = 0, len = buf.length; i < len; i += 1) - buf[i] = this[i] - return buf.buffer - } - } else { - throw new Error('Buffer.toArrayBuffer not supported in this browser') - } -} - -// HELPER FUNCTIONS -// ================ - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -var BP = Buffer.prototype - -/** - * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods - */ -Buffer._augment = function (arr) { - arr._isBuffer = true - - // save reference to original Uint8Array get/set methods before overwriting - arr._get = arr.get - arr._set = arr.set - - // deprecated, will be removed in node 0.13+ - arr.get = BP.get - arr.set = BP.set - - arr.write = BP.write - arr.toString = BP.toString - arr.toLocaleString = BP.toString - arr.toJSON = BP.toJSON - arr.copy = BP.copy - arr.slice = BP.slice - arr.readUInt8 = BP.readUInt8 - arr.readUInt16LE = BP.readUInt16LE - arr.readUInt16BE = BP.readUInt16BE - arr.readUInt32LE = BP.readUInt32LE - arr.readUInt32BE = BP.readUInt32BE - arr.readInt8 = BP.readInt8 - arr.readInt16LE = BP.readInt16LE - arr.readInt16BE = BP.readInt16BE - arr.readInt32LE = BP.readInt32LE - arr.readInt32BE = BP.readInt32BE - arr.readFloatLE = BP.readFloatLE - arr.readFloatBE = BP.readFloatBE - arr.readDoubleLE = BP.readDoubleLE - arr.readDoubleBE = BP.readDoubleBE - arr.writeUInt8 = BP.writeUInt8 - arr.writeUInt16LE = BP.writeUInt16LE - arr.writeUInt16BE = BP.writeUInt16BE - arr.writeUInt32LE = BP.writeUInt32LE - arr.writeUInt32BE = BP.writeUInt32BE - arr.writeInt8 = BP.writeInt8 - arr.writeInt16LE = BP.writeInt16LE - arr.writeInt16BE = BP.writeInt16BE - arr.writeInt32LE = BP.writeInt32LE - arr.writeInt32BE = BP.writeInt32BE - arr.writeFloatLE = BP.writeFloatLE - arr.writeFloatBE = BP.writeFloatBE - arr.writeDoubleLE = BP.writeDoubleLE - arr.writeDoubleBE = BP.writeDoubleBE - arr.fill = BP.fill - arr.inspect = BP.inspect - arr.toArrayBuffer = BP.toArrayBuffer - - return arr -} +// getOwnPropertyNames is almost the same as Object.keys one key feature +// is that it returns hidden properties, since that can't be implemented, +// this feature gets reduced so it just shows the length property on arrays +function propertyShim(object) { + if (notObject(object)) { + throw new TypeError("Object.getOwnPropertyNames called on a non-object"); + } -// slice(start, end) -function clamp (index, len, defaultValue) { - if (typeof index !== 'number') return defaultValue - index = ~~index; // Coerce to integer. - if (index >= len) return len - if (index >= 0) return index - index += len - if (index >= 0) return index - return 0 + var result = keysShim(object); + if (exports.isArray(object) && exports.indexOf(object, 'length') === -1) { + result.push('length'); + } + return result; } -function coerce (length) { - // Coerce length to a number (possibly NaN), round up - // in case it's fractional (e.g. 123.456) then do a - // double negate to coerce a NaN to 0. Easy, right? - length = ~~Math.ceil(+length) - return length < 0 ? 0 : length -} +var keys = typeof Object.keys === 'function' ? Object.keys : keysShim; +var getOwnPropertyNames = typeof Object.getOwnPropertyNames === 'function' ? + Object.getOwnPropertyNames : propertyShim; -function isArray (subject) { - return (Array.isArray || function (subject) { - return Object.prototype.toString.call(subject) === '[object Array]' - })(subject) -} +if (new Error().hasOwnProperty('description')) { + var ERROR_PROPERTY_FILTER = function (obj, array) { + if (toString.call(obj) === '[object Error]') { + array = exports.filter(array, function (name) { + return name !== 'description' && name !== 'number' && name !== 'message'; + }); + } + return array; + }; -function isArrayish (subject) { - return isArray(subject) || Buffer.isBuffer(subject) || - subject && typeof subject === 'object' && - typeof subject.length === 'number' + exports.keys = function (object) { + return ERROR_PROPERTY_FILTER(object, keys(object)); + }; + exports.getOwnPropertyNames = function (object) { + return ERROR_PROPERTY_FILTER(object, getOwnPropertyNames(object)); + }; +} else { + exports.keys = keys; + exports.getOwnPropertyNames = getOwnPropertyNames; } -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) +// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements +function valueObject(value, key) { + return { value: value[key] }; } -function utf8ToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - var b = str.charCodeAt(i) - if (b <= 0x7F) - byteArray.push(str.charCodeAt(i)) - else { - var start = i - if (b >= 0xD800 && b <= 0xDFFF) i++ - var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') - for (var j = 0; j < h.length; j++) - byteArray.push(parseInt(h[j], 16)) - } +if (typeof Object.getOwnPropertyDescriptor === 'function') { + try { + Object.getOwnPropertyDescriptor({'a': 1}, 'a'); + exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + } catch (e) { + // IE8 dom element issue - use a try catch and default to valueObject + exports.getOwnPropertyDescriptor = function (value, key) { + try { + return Object.getOwnPropertyDescriptor(value, key); + } catch (e) { + return valueObject(value, key); + } + }; } - return byteArray +} else { + exports.getOwnPropertyDescriptor = valueObject; } -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} +},{}],8:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -function utf16leToBytes (str) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; i++) { - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. - return byteArray -} +module.exports = Duplex; +var util = require('util'); +var shims = require('_shims'); +var timers = require('timers'); +var Readable = require('_stream_readable'); +var Writable = require('_stream_writable'); -function base64ToBytes (str) { - return base64.toByteArray(str) -} +util.inherits(Duplex, Readable); -function blitBuffer (src, dst, offset, length) { - var pos - for (var i = 0; i < length; i++) { - if ((i + offset >= dst.length) || (i >= src.length)) - break - dst[i + offset] = src[i] - } - return i -} +shims.forEach(shims.keys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); -function decodeUtf8Char (str) { - try { - return decodeURIComponent(str) - } catch (err) { - return String.fromCharCode(0xFFFD) // UTF 8 invalid char - } -} +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); -/* - * We have to make sure that the value is a valid integer. This means that it - * is non-negative. It has no fractional component and that it does not - * exceed the maximum allowed value. - */ -function verifuint (value, max) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value >= 0, 'specified a negative value for writing an unsigned value') - assert(value <= max, 'value is larger than maximum value for type') - assert(Math.floor(value) === value, 'value has a fractional component') -} + Readable.call(this, options); + Writable.call(this, options); -function verifsint (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') - assert(Math.floor(value) === value, 'value has a fractional component') -} + if (options && options.readable === false) + this.readable = false; + + if (options && options.writable === false) + this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; -function verifIEEE754 (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') + this.once('end', onend); } -function assert (test, message) { - if (!test) throw new Error(message || 'Failed assertion') +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; + + // no more data can be written. + // But allow more writes to happen in this tick. + timers.setImmediate(shims.bind(this.end, this)); } -},{"base64-js":4,"ieee754":5}],4:[function(require,module,exports){ -var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +},{"_shims":7,"_stream_readable":10,"_stream_writable":12,"timers":19,"util":21}],9:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -;(function (exports) { - 'use strict'; +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. - var Arr = (typeof Uint8Array !== 'undefined') - ? Uint8Array - : Array - - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS) - return 62 // '+' - if (code === SLASH) - return 63 // '/' - if (code < NUMBER) - return -1 //no match - if (code < NUMBER + 10) - return code - NUMBER + 26 + 26 - if (code < UPPER + 26) - return code - UPPER - if (code < LOWER + 26) - return code - LOWER + 26 - } - - function b64ToByteArray (b64) { - var i, j, l, tmp, placeHolders, arr +module.exports = PassThrough; - if (b64.length % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } +var Transform = require('_stream_transform'); +var util = require('util'); +util.inherits(PassThrough, Transform); - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - var len = b64.length - placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(b64.length * 3 / 4 - placeHolders) + Transform.call(this, options); +} - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); +}; - var L = 0 +},{"_stream_transform":11,"util":21}],10:[function(require,module,exports){ +var process=require("__browserify_process");// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - function push (v) { - arr[L++] = v - } +module.exports = Readable; +Readable.ReadableState = ReadableState; - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) - push((tmp & 0xFF0000) >> 16) - push((tmp & 0xFF00) >> 8) - push(tmp & 0xFF) - } +var EE = require('events').EventEmitter; +var Stream = require('stream'); +var shims = require('_shims'); +var Buffer = require('buffer').Buffer; +var timers = require('timers'); +var util = require('util'); +var StringDecoder; - if (placeHolders === 2) { - tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) - push(tmp & 0xFF) - } else if (placeHolders === 1) { - tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) - push((tmp >> 8) & 0xFF) - push(tmp & 0xFF) - } +util.inherits(Readable, Stream); - return arr - } +function ReadableState(options, stream) { + options = options || {}; - function uint8ToBase64 (uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length + // 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" + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; - function encode (num) { - return lookup.charAt(num) - } + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = false; + this.ended = false; + this.endEmitted = false; + this.reading = false; - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) - } + // In streams that never have any data, and do push(null) right away, + // the consumer can miss the 'end' event if they do some I/O before + // consuming the stream. So, we don't emit('end') until some reading + // happens. + this.calledRead = false; - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1] - output += encode(temp >> 2) - output += encode((temp << 4) & 0x3F) - output += '==' - break - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) - output += encode(temp >> 10) - output += encode((temp >> 4) & 0x3F) - output += encode((temp << 2) & 0x3F) - output += '=' - break - } + // 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, becuase any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; - return output - } + // 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; - exports.toByteArray = b64ToByteArray - exports.fromByteArray = uint8ToBase64 -}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) -},{}],5:[function(require,module,exports){ -exports.read = function(buffer, offset, isLE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isLE ? (nBytes - 1) : 0, - d = isLE ? -1 : 1, - s = buffer[offset + i]; + // 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; - i += d; + // 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'; - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; +} -exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isLE ? 0 : (nBytes - 1), - d = isLE ? 1 : -1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; +function Readable(options) { + if (!(this instanceof Readable)) + return new Readable(options); - value = Math.abs(value); + this._readableState = new ReadableState(options, this); - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } + // legacy + this.readable = true; - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; + Stream.call(this); +} + +// 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; + + if (typeof chunk === 'string' && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; } } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + return readableAddChunk(this, state, chunk, encoding, false); +}; - buffer[offset + i - d] |= s * 128; +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); }; -},{}],6:[function(require,module,exports){ -var Buffer = require('buffer').Buffer; -var intSize = 4; -var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); -var chrsz = 8; +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null || chunk === undefined) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); -function toArray(buf, bigEndian) { - if ((buf.length % intSize) !== 0) { - var len = buf.length + (intSize - (buf.length % intSize)); - buf = Buffer.concat([buf, zeroBuffer], len); - } + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) { + state.buffer.unshift(chunk); + } else { + state.reading = false; + state.buffer.push(chunk); + } - var arr = []; - var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; - for (var i = 0; i < buf.length; i += intSize) { - arr.push(fn.call(buf, i)); - } - return arr; -} + if (state.needReadable) + emitReadable(stream); -function toBuffer(arr, size, bigEndian) { - var buf = new Buffer(size); - var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; - for (var i = 0; i < arr.length; i++) { - fn.call(buf, arr[i], i * 4, true); + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; } - return buf; -} -function hash(buf, fn, hashSize, bigEndian) { - if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); - var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); - return toBuffer(arr, hashSize, bigEndian); + return needMoreData(state); } -module.exports = { hash: hash }; -},{"buffer":3}],7:[function(require,module,exports){ -var Buffer = require('buffer').Buffer -var sha = require('./sha') -var sha256 = require('./sha256') -var rng = require('./rng') -var md5 = require('./md5') -var algorithms = { - sha1: sha, - sha256: sha256, - md5: md5 +// if it's past the high water mark, we can push in some more. +// 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. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); } -var blocksize = 64 -var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0) -function hmac(fn, key, data) { - if(!Buffer.isBuffer(key)) key = new Buffer(key) - if(!Buffer.isBuffer(data)) data = new Buffer(data) +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; +}; - if(key.length > blocksize) { - key = fn(key) - } else if(key.length < blocksize) { - key = Buffer.concat([key, zeroBuffer], blocksize) +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || n === null) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + var state = this._readableState; + state.calledRead = true; + var nOrig = n; + + if (typeof n !== 'number' || 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.length >= state.highWaterMark || state.ended)) { + 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; + + // if we currently have less than the highWaterMark, then also read some + if (state.length - n <= state.highWaterMark) + doRead = true; + + // 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; + + if (doRead) { + 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 called its callback synchronously, then `reading` + // will be false, and we need to re-evaluate how much data we + // can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (ret === null) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we happened to read() exactly the remaining amount in the + // buffer, and the EOF has been seen at this point, then make sure + // that we emit 'end' on the very next tick. + if (state.ended && !state.endEmitted && state.length === 0) + endReadable(this); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode && + !er) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // if we've ended and we have some data left, then emit + // 'readable' now to make sure it gets picked up. + if (state.length > 0) + emitReadable(stream); + else + endReadable(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; + state.needReadable = false; + if (state.emittedReadable) + return; + + state.emittedReadable = true; + if (state.sync) + timers.setImmediate(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); +} + +function emitReadable_(stream) { + stream.emit('readable'); +} + + +// 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; + timers.setImmediate(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + 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) { + this.emit('error', new Error('not implemented')); +}; + +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; + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + timers.setImmediate(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + if (readable !== src) return; + cleanup(); + } + + function 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); + + function 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', cleanup); + + // 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 (!dest._writableState || dest._writableState.needDrain) + ondrain(); + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + // check for listeners before emit removes one-time listeners. + var errListeners = EE.listenerCount(dest, 'error'); + function onerror(er) { + unpipe(); + if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + dest.once('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() { + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function 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) { + // the handler that waits for readable events after all + // the data gets sucked out in flow. + // This would be easier to follow with a .once() handler + // in flow(), but that is too slow. + this.on('readable', pipeOnReadable); + + state.flowing = true; + timers.setImmediate(function() { + flow(src); + }); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var dest = this; + var state = src._readableState; + state.awaitDrain--; + if (state.awaitDrain === 0) + flow(src); + }; +} + +function flow(src) { + var state = src._readableState; + var chunk; + state.awaitDrain = 0; + + function write(dest, i, list) { + var written = dest.write(chunk); + if (false === written) { + state.awaitDrain++; + } + } + + while (state.pipesCount && null !== (chunk = src.read())) { + + if (state.pipesCount === 1) + write(state.pipes, 0, null); + else + shims.forEach(state.pipes, write); + + src.emit('data', chunk); + + // if anyone needs a drain, then we have to wait for that. + if (state.awaitDrain > 0) + return; + } + + // if every destination was unpiped, either before entering this + // function, or in the while loop, then stop flowing. + // + // NB: This is a pretty rare edge case. + if (state.pipesCount === 0) { + state.flowing = false; + + // if there were data event listeners added, then switch to old mode. + if (EE.listenerCount(src, 'data') > 0) + emitDataEvents(src); + return; + } + + // at this point, no one needed a drain, so we just ran out of data + // on the next readable event, start it over again. + state.ranOut = true; +} + +function pipeOnReadable() { + if (this._readableState.ranOut) { + this._readableState.ranOut = false; + flow(this); + } +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // 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; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + 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; + this.removeListener('readable', pipeOnReadable); + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = shims.indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + 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); + + if (ev === 'data' && !this._readableState.flowing) + emitDataEvents(this); + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + this.read(0); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// 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() { + emitDataEvents(this); + this.read(0); + this.emit('resume'); +}; + +Readable.prototype.pause = function() { + emitDataEvents(this, true); + this.emit('pause'); +}; + +function emitDataEvents(stream, startPaused) { + var state = stream._readableState; + + if (state.flowing) { + // https://github.com/isaacs/readable-stream/issues/16 + throw new Error('Cannot switch to old mode now.'); + } + + var paused = startPaused || false; + var readable = false; + + // convert to an old-style stream. + stream.readable = true; + stream.pipe = Stream.prototype.pipe; + stream.on = stream.addListener = Stream.prototype.on; + + stream.on('readable', function() { + readable = true; + + var c; + while (!paused && (null !== (c = stream.read()))) + stream.emit('data', c); + + if (c === null) { + readable = false; + stream._readableState.needReadable = true; + } + }); + + stream.pause = function() { + paused = true; + this.emit('pause'); + }; + + stream.resume = function() { + paused = false; + if (readable) + timers.setImmediate(function() { + stream.emit('readable'); + }); + else + this.read(0); + this.emit('resume'); + }; + + // now make it start, just in case it hadn't already. + stream.emit('readable'); +} + +// 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 state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.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 (typeof stream[i] === 'function' && + typeof this[i] === 'undefined') { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + shims.forEach(events, function(ev) { + stream.on(ev, shims.bind(self.emit, self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted && state.calledRead) { + state.ended = true; + timers.setImmediate(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +},{"__browserify_process":50,"_shims":7,"buffer":23,"events":14,"stream":17,"string_decoder":18,"timers":19,"util":21}],11:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('_stream_duplex'); +var util = require('util'); +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + var ts = this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // 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; + + this.once('finish', function() { + if ('function' === typeof this._flush) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +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) { + throw new Error('not implemented'); +}; + +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 && ts.writecb && !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; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var rs = stream._readableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} + +},{"_stream_duplex":8,"util":21}],12:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; +Writable.WritableState = WritableState; + +var util = require('util'); +var Stream = require('stream'); +var timers = require('timers'); +var Buffer = require('buffer').Buffer; + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + options = options || {}; + + // 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() + var hwm = options.highWaterMark; + this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + 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; + + // 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; + + // 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, becuase 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.buffer = []; +} + +function Writable(options) { + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + timers.setImmediate(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!Buffer.isBuffer(chunk) && + 'string' !== typeof chunk && + chunk !== null && + chunk !== undefined && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + timers.setImmediate(function() { + cb(er); + }); + valid = false; } + return valid; +} - var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) - for(var i = 0; i < blocksize; i++) { - ipad[i] = key[i] ^ 0x36 - opad[i] = key[i] ^ 0x5C +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; } - var hash = fn(Buffer.concat([ipad, data])) - return fn(Buffer.concat([opad, hash])) + if (Buffer.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (typeof cb !== 'function') + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) + ret = writeOrBuffer(this, state, chunk, encoding, cb); + + return ret; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + typeof chunk === 'string') { + chunk = new Buffer(chunk, encoding); + } + return chunk; } -function hash(alg, key) { - alg = alg || 'sha1' - var fn = algorithms[alg] - var bufs = [] - var length = 0 - if(!fn) error('algorithm:', alg, 'is not yet supported') - return { - update: function (data) { - if(!Buffer.isBuffer(data)) data = new Buffer(data) - - bufs.push(data) - length += data.length - return this - }, - digest: function (enc) { - var buf = Buffer.concat(bufs) - var r = key ? hmac(fn, key, buf) : fn(buf) - bufs = null - return enc ? r.toString(enc) : r +// 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, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + state.needDrain = !ret; + + if (state.writing) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + timers.setImmediate(function() { + cb(er); + }); + else + cb(er); + + stream.emit('error', er); +} + +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; + + 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(stream, state); + + if (!finished && !state.bufferProcessing && state.buffer.length) + clearBuffer(stream, state); + + if (sync) { + timers.setImmediate(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); } } } -function error () { - var m = [].slice.call(arguments).join(' ') - throw new Error([ - m, - 'we accept pull requests', - 'http://github.com/dominictarr/crypto-browserify' - ].join('\n')) +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + cb(); + if (finished) + finishMaybe(stream, state); } -exports.createHash = function (alg) { return hash(alg) } -exports.createHmac = function (alg, key) { return hash(alg, key) } -exports.randomBytes = function(size, callback) { - if (callback && callback.call) { - try { - callback.call(this, undefined, new Buffer(rng(size))) - } catch (err) { callback(err) } - } else { - return new Buffer(rng(size)) +// 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'); } } -function each(a, f) { - for(var i in a) - f(a[i], i) + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, len, chunk, encoding, cb); + + // 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) { + c++; + break; + } + } + + state.bufferProcessing = false; + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; } -// the least I can do is make error messages for the rest of the node.js/crypto api. -each(['createCredentials' -, 'createCipher' -, 'createCipheriv' -, 'createDecipher' -, 'createDecipheriv' -, 'createSign' -, 'createVerify' -, 'createDiffieHellman' -, 'pbkdf2'], function (name) { - exports[name] = function () { - error('sorry,', name, 'is not implemented yet') +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +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; } -}) -},{"./md5":8,"./rng":9,"./sha":10,"./sha256":11,"buffer":3}],8:[function(require,module,exports){ -/* - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ - -var helpers = require('./helpers'); - -/* - * Perform a simple self-test to see if the VM is working - */ -function md5_vm_test() -{ - return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; -} - -/* - * Calculate the MD5 of an array of little-endian words, and a bit length - */ -function core_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; - - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); - - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); - - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); - - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); - - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - } - return Array(a, b, c, d); - -} - -/* - * These functions implement the four basic operations the algorithm uses. - */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); -} -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); -} -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); -} -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} - -module.exports = function md5(buf) { - return helpers.hash(buf, core_md5, 16); -}; + if (typeof chunk !== 'undefined' && chunk !== null) + this.write(chunk, encoding); + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + state.finished = true; + stream.emit('finish'); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + timers.setImmediate(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +},{"buffer":23,"stream":17,"timers":19,"util":21}],13:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// UTILITY +var util = require('util'); +var shims = require('_shims'); +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + this.message = options.message || getMessage(this); +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. -},{"./helpers":6}],9:[function(require,module,exports){ -// Original code adapted from Robert Kieffer. -// details at https://github.com/broofa/node-uuid -(function() { - var _global = this; +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. - var mathRNG, whatwgRNG; +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} - // NOTE: Math.random() does not guarantee "cryptographic quality" - mathRNG = function(size) { - var bytes = new Array(size); - var r; +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; - for (var i = 0, r; i < size; i++) { - if ((i & 0x03) == 0) r = Math.random() * 0x100000000; - bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; - } +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. - return bytes; - } +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; - if (_global.crypto && crypto.getRandomValues) { - whatwgRNG = function(size) { - var bytes = new Uint8Array(size); - crypto.getRandomValues(bytes); - return bytes; - } - } +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); - module.exports = whatwgRNG || mathRNG; +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; -}()) +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); -},{}],10:[function(require,module,exports){ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS PUB 180-1 - * Version 2.1a Copyright Paul Johnston 2000 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; -var helpers = require('./helpers'); +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); -/* - * Calculate the SHA-1 of an array of big-endian words, and a bit length - */ -function core_sha1(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << (24 - len % 32); - x[((len + 64 >> 9) << 4) + 15] = len; +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; - var w = Array(80); - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - var e = -1009589776; +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - var olde = e; + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; - for(var j = 0; j < 80; j++) - { - if(j < 16) w[j] = x[i + j]; - else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); - var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), - safe_add(safe_add(e, w[j]), sha1_kt(j))); - e = d; - d = c; - c = rol(b, 30); - b = a; - a = t; + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; } - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); - e = safe_add(e, olde); - } - return Array(a, b, c, d, e); - -} + return true; -/* - * Perform the appropriate triplet combination function for the current - * iteration - */ -function sha1_ft(t, b, c, d) -{ - if(t < 20) return (b & c) | ((~b) & d); - if(t < 40) return b ^ c ^ d; - if(t < 60) return (b & c) | (b & d) | (c & d); - return b ^ c ^ d; + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } } -/* - * Determine the appropriate additive constant for the current iteration - */ -function sha1_kt(t) -{ - return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : - (t < 60) ? -1894007588 : -899497514; +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; } -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = shims.keys(a), + kb = shims.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; } -/* - * Bitwise rotate a 32-bit number to the left. - */ -function rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); -module.exports = function sha1(buf) { - return helpers.hash(buf, core_sha1, 20, true); +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } }; -},{"./helpers":6}],11:[function(require,module,exports){ +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; -var helpers = require('./helpers'); +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); -var safe_add = function(x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } }; -var S = function(X, n) { - return (X >>> n) | (X << (32 - n)); -}; +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } -var R = function(X, n) { - return (X >>> n); -}; + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } -var Ch = function(x, y, z) { - return ((x & y) ^ ((~x) & z)); -}; + return false; +} -var Maj = function(x, y, z) { - return ((x & y) ^ (x & z) ^ (y & z)); -}; +function _throws(shouldThrow, block, expected, message) { + var actual; -var Sigma0256 = function(x) { - return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); -}; + if (util.isString(expected)) { + message = expected; + expected = null; + } -var Sigma1256 = function(x) { - return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); -}; + try { + block(); + } catch (e) { + actual = e; + } -var Gamma0256 = function(x) { - return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); -}; + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); -var Gamma1256 = function(x) { - return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); -}; + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } -var core_sha256 = function(m, l) { - var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); - var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); - var W = new Array(64); - var a, b, c, d, e, f, g, h, i, j; - var T1, T2; - /* append padding */ - m[l >> 5] |= 0x80 << (24 - l % 32); - m[((l + 64 >> 9) << 4) + 15] = l; - for (var i = 0; i < m.length; i += 16) { - a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; - for (var j = 0; j < 64; j++) { - if (j < 16) { - W[j] = m[j + i]; - } else { - W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); - } - T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); - T2 = safe_add(Sigma0256(a), Maj(a, b, c)); - h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); - } - HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); - HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); } - return HASH; + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); }; -module.exports = function sha256(buf) { - return helpers.hash(buf, core_sha256, 32, true); +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); }; -},{"./helpers":6}],12:[function(require,module,exports){ +assert.ifError = function(err) { if (err) {throw err;}}; +},{"_shims":7,"util":21}],14:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -21162,6 +22390,8 @@ module.exports = function sha256(buf) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. +var util = require('util'); + function EventEmitter() { this._events = this._events || {}; this._maxListeners = this._maxListeners || undefined; @@ -21181,7 +22411,7 @@ EventEmitter.defaultMaxListeners = 10; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) + if (!util.isNumber(n) || n < 0) throw TypeError('n must be a positive number'); this._maxListeners = n; return this; @@ -21196,21 +22426,23 @@ EventEmitter.prototype.emit = function(type) { // If there is no 'error' event listener then throw. if (type === 'error') { if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { + (util.isObject(this._events.error) && !this._events.error.length)) { er = arguments[1]; if (er instanceof Error) { throw er; // Unhandled 'error' event + } else { + throw TypeError('Uncaught, unspecified "error" event.'); } - throw TypeError('Uncaught, unspecified "error" event.'); + return false; } } handler = this._events[type]; - if (isUndefined(handler)) + if (util.isUndefined(handler)) return false; - if (isFunction(handler)) { + if (util.isFunction(handler)) { switch (arguments.length) { // fast cases case 1: @@ -21230,7 +22462,7 @@ EventEmitter.prototype.emit = function(type) { args[i - 1] = arguments[i]; handler.apply(this, args); } - } else if (isObject(handler)) { + } else if (util.isObject(handler)) { len = arguments.length; args = new Array(len - 1); for (i = 1; i < len; i++) @@ -21248,7 +22480,7 @@ EventEmitter.prototype.emit = function(type) { EventEmitter.prototype.addListener = function(type, listener) { var m; - if (!isFunction(listener)) + if (!util.isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events) @@ -21258,13 +22490,13 @@ EventEmitter.prototype.addListener = function(type, listener) { // adding it to the listeners, first emit "newListener". if (this._events.newListener) this.emit('newListener', type, - isFunction(listener.listener) ? + util.isFunction(listener.listener) ? listener.listener : listener); if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; - else if (isObject(this._events[type])) + else if (util.isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); else @@ -21272,9 +22504,9 @@ EventEmitter.prototype.addListener = function(type, listener) { this._events[type] = [this._events[type], listener]; // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { + if (util.isObject(this._events[type]) && !this._events[type].warned) { var m; - if (!isUndefined(this._maxListeners)) { + if (!util.isUndefined(this._maxListeners)) { m = this._maxListeners; } else { m = EventEmitter.defaultMaxListeners; @@ -21286,10 +22518,7 @@ EventEmitter.prototype.addListener = function(type, listener) { 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } + console.trace(); } } @@ -21299,18 +22528,12 @@ EventEmitter.prototype.addListener = function(type, listener) { EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) + if (!util.isFunction(listener)) throw TypeError('listener must be a function'); - var fired = false; - function g() { this.removeListener(type, g); - - if (!fired) { - fired = true; - listener.apply(this, arguments); - } + listener.apply(this, arguments); } g.listener = listener; @@ -21323,7 +22546,7 @@ EventEmitter.prototype.once = function(type, listener) { EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; - if (!isFunction(listener)) + if (!util.isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) @@ -21334,12 +22557,12 @@ EventEmitter.prototype.removeListener = function(type, listener) { position = -1; if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { + (util.isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); - } else if (isObject(list)) { + } else if (util.isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { @@ -21393,7 +22616,7 @@ EventEmitter.prototype.removeAllListeners = function(type) { listeners = this._events[type]; - if (isFunction(listeners)) { + if (util.isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order @@ -21409,7 +22632,7 @@ EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; - else if (isFunction(this._events[type])) + else if (util.isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); @@ -21420,1160 +22643,1374 @@ EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; - else if (isFunction(emitter._events[type])) + else if (util.isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; +},{"util":21}],15:[function(require,module,exports){ +var http = require('http'); -function isFunction(arg) { - return typeof arg === 'function'; -} +var https = module.exports; -function isNumber(arg) { - return typeof arg === 'number'; +for (var key in http) { + if (http.hasOwnProperty(key)) https[key] = http[key]; +}; + +https.request = function (params, cb) { + if (!params) params = {}; + params.scheme = 'https'; + return http.request.call(this, params, cb); } +},{"http":31}],16:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +// Query String Utilities + +var QueryString = exports; +var util = require('util'); +var shims = require('_shims'); +var Buffer = require('buffer').Buffer; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); } -function isUndefined(arg) { - return arg === void 0; + +function charCode(c) { + return c.charCodeAt(0); } -},{}],13:[function(require,module,exports){ -var http = module.exports; -var EventEmitter = require('events').EventEmitter; -var Request = require('./lib/request'); -var url = require('url') -http.request = function (params, cb) { - if (typeof params === 'string') { - params = url.parse(params) - } - if (!params) params = {}; - if (!params.host && !params.port) { - params.port = parseInt(window.location.port, 10); - } - if (!params.host && params.hostname) { - params.host = params.hostname; - } - - if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; - if (!params.host) { - params.host = window.location.hostname || window.location.host; - } - if (/:/.test(params.host)) { - if (!params.port) { - params.port = params.host.split(':')[1]; +// a safe fast alternative to decodeURIComponent +QueryString.unescapeBuffer = function(s, decodeSpaces) { + var out = new Buffer(s.length); + var state = 'CHAR'; // states: CHAR, HEX0, HEX1 + var n, m, hexchar; + + for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) { + var c = s.charCodeAt(inIndex); + switch (state) { + case 'CHAR': + switch (c) { + case charCode('%'): + n = 0; + m = 0; + state = 'HEX0'; + break; + case charCode('+'): + if (decodeSpaces) c = charCode(' '); + // pass thru + default: + out[outIndex++] = c; + break; + } + break; + + case 'HEX0': + state = 'HEX1'; + hexchar = c; + if (charCode('0') <= c && c <= charCode('9')) { + n = c - charCode('0'); + } else if (charCode('a') <= c && c <= charCode('f')) { + n = c - charCode('a') + 10; + } else if (charCode('A') <= c && c <= charCode('F')) { + n = c - charCode('A') + 10; + } else { + out[outIndex++] = charCode('%'); + out[outIndex++] = c; + state = 'CHAR'; + break; + } + break; + + case 'HEX1': + state = 'CHAR'; + if (charCode('0') <= c && c <= charCode('9')) { + m = c - charCode('0'); + } else if (charCode('a') <= c && c <= charCode('f')) { + m = c - charCode('a') + 10; + } else if (charCode('A') <= c && c <= charCode('F')) { + m = c - charCode('A') + 10; + } else { + out[outIndex++] = charCode('%'); + out[outIndex++] = hexchar; + out[outIndex++] = c; + break; } - params.host = params.host.split(':')[0]; + out[outIndex++] = 16 * n + m; + break; } - if (!params.port) params.port = params.scheme == 'https' ? 443 : 80; - - var req = new Request(new xhrHttp, params); - if (cb) req.on('response', cb); - return req; + } + + // TODO support returning arbitrary buffers. + + return out.slice(0, outIndex - 1); }; -http.get = function (params, cb) { - params.method = 'GET'; - var req = http.request(params, cb); - req.end(); - return req; + +QueryString.unescape = function(s, decodeSpaces) { + return QueryString.unescapeBuffer(s, decodeSpaces).toString(); }; -http.Agent = function () {}; -http.Agent.defaultMaxSockets = 4; -var xhrHttp = (function () { - if (typeof window === 'undefined') { - throw new Error('no window object present'); +QueryString.escape = function(str) { + return encodeURIComponent(str); +}; + +var stringifyPrimitive = function(v) { + if (util.isString(v)) + return v; + if (util.isBoolean(v)) + return v ? 'true' : 'false'; + if (util.isNumber(v)) + return isFinite(v) ? v : ''; + return ''; +}; + + +QueryString.stringify = QueryString.encode = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (util.isNull(obj)) { + obj = undefined; + } + + if (util.isObject(obj)) { + return shims.map(shims.keys(obj), function(k) { + var ks = QueryString.escape(stringifyPrimitive(k)) + eq; + if (util.isArray(obj[k])) { + return shims.map(obj[k], function(v) { + return ks + QueryString.escape(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + QueryString.escape(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return QueryString.escape(stringifyPrimitive(name)) + eq + + QueryString.escape(stringifyPrimitive(obj)); +}; + +// Parse a key=val string. +QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (!util.isString(qs) || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && util.isNumber(options.maxKeys)) { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; } - else if (window.XMLHttpRequest) { - return window.XMLHttpRequest; + + try { + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + } catch (e) { + k = QueryString.unescape(kstr, true); + v = QueryString.unescape(vstr, true); } - else if (window.ActiveXObject) { - var axs = [ - 'Msxml2.XMLHTTP.6.0', - 'Msxml2.XMLHTTP.3.0', - 'Microsoft.XMLHTTP' - ]; - for (var i = 0; i < axs.length; i++) { - try { - var ax = new(window.ActiveXObject)(axs[i]); - return function () { - if (ax) { - var ax_ = ax; - ax = null; - return ax_; - } - else { - return new(window.ActiveXObject)(axs[i]); - } - }; - } - catch (e) {} - } - throw new Error('ajax not supported in this browser') + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (util.isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; } - else { - throw new Error('ajax not supported in this browser'); + } + + return obj; +}; +},{"_shims":7,"buffer":23,"util":21}],17:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Stream; + +var EE = require('events').EventEmitter; +var util = require('util'); + +util.inherits(Stream, EE); +Stream.Readable = require('_stream_readable'); +Stream.Writable = require('_stream_writable'); +Stream.Duplex = require('_stream_duplex'); +Stream.Transform = require('_stream_transform'); +Stream.PassThrough = require('_stream_passthrough'); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } } -})(); + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } + + source.on('error', onerror); + dest.on('error', onerror); + + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); + + source.removeListener('end', onend); + source.removeListener('close', onclose); -http.STATUS_CODES = { - 100 : 'Continue', - 101 : 'Switching Protocols', - 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 - 200 : 'OK', - 201 : 'Created', - 202 : 'Accepted', - 203 : 'Non-Authoritative Information', - 204 : 'No Content', - 205 : 'Reset Content', - 206 : 'Partial Content', - 207 : 'Multi-Status', // RFC 4918 - 300 : 'Multiple Choices', - 301 : 'Moved Permanently', - 302 : 'Moved Temporarily', - 303 : 'See Other', - 304 : 'Not Modified', - 305 : 'Use Proxy', - 307 : 'Temporary Redirect', - 400 : 'Bad Request', - 401 : 'Unauthorized', - 402 : 'Payment Required', - 403 : 'Forbidden', - 404 : 'Not Found', - 405 : 'Method Not Allowed', - 406 : 'Not Acceptable', - 407 : 'Proxy Authentication Required', - 408 : 'Request Time-out', - 409 : 'Conflict', - 410 : 'Gone', - 411 : 'Length Required', - 412 : 'Precondition Failed', - 413 : 'Request Entity Too Large', - 414 : 'Request-URI Too Large', - 415 : 'Unsupported Media Type', - 416 : 'Requested Range Not Satisfiable', - 417 : 'Expectation Failed', - 418 : 'I\'m a teapot', // RFC 2324 - 422 : 'Unprocessable Entity', // RFC 4918 - 423 : 'Locked', // RFC 4918 - 424 : 'Failed Dependency', // RFC 4918 - 425 : 'Unordered Collection', // RFC 4918 - 426 : 'Upgrade Required', // RFC 2817 - 428 : 'Precondition Required', // RFC 6585 - 429 : 'Too Many Requests', // RFC 6585 - 431 : 'Request Header Fields Too Large',// RFC 6585 - 500 : 'Internal Server Error', - 501 : 'Not Implemented', - 502 : 'Bad Gateway', - 503 : 'Service Unavailable', - 504 : 'Gateway Time-out', - 505 : 'HTTP Version Not Supported', - 506 : 'Variant Also Negotiates', // RFC 2295 - 507 : 'Insufficient Storage', // RFC 4918 - 509 : 'Bandwidth Limit Exceeded', - 510 : 'Not Extended', // RFC 2774 - 511 : 'Network Authentication Required' // RFC 6585 -}; -},{"./lib/request":14,"events":12,"url":32}],14:[function(require,module,exports){ -var Stream = require('stream'); -var Response = require('./response'); -var Base64 = require('Base64'); -var inherits = require('inherits'); + source.removeListener('error', onerror); + dest.removeListener('error', onerror); -var Request = module.exports = function (xhr, params) { - var self = this; - self.writable = true; - self.xhr = xhr; - self.body = []; - - self.uri = (params.scheme || 'http') + '://' - + params.host - + (params.port ? ':' + params.port : '') - + (params.path || '/') - ; - - if (typeof params.withCredentials === 'undefined') { - params.withCredentials = true; - } + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); - try { xhr.withCredentials = params.withCredentials } - catch (e) {} - - xhr.open( - params.method || 'GET', - self.uri, - true - ); + dest.removeListener('close', cleanup); + } - self._headers = {}; - - if (params.headers) { - var keys = objectKeys(params.headers); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - if (!self.isSafeRequestHeader(key)) continue; - var value = params.headers[key]; - self.setHeader(key, value); - } - } - - if (params.auth) { - //basic auth - this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); - } + source.on('end', cleanup); + source.on('close', cleanup); - var res = new Response; - res.on('close', function () { - self.emit('close'); - }); - - res.on('ready', function () { - self.emit('response', res); - }); - - xhr.onreadystatechange = function () { - // Fix for IE9 bug - // SCRIPT575: Could not complete the operation due to error c00c023f - // It happens when a request is aborted, calling the success callback anyway with readyState === 4 - if (xhr.__aborted) return; - res.handle(xhr); - }; -}; + dest.on('close', cleanup); -inherits(Request, Stream); + dest.emit('pipe', source); -Request.prototype.setHeader = function (key, value) { - this._headers[key.toLowerCase()] = value + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; }; -Request.prototype.getHeader = function (key) { - return this._headers[key.toLowerCase()] -}; +},{"_stream_duplex":8,"_stream_passthrough":9,"_stream_readable":10,"_stream_transform":11,"_stream_writable":12,"events":14,"util":21}],18:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -Request.prototype.removeHeader = function (key) { - delete this._headers[key.toLowerCase()] -}; +var Buffer = require('buffer').Buffer; -Request.prototype.write = function (s) { - this.body.push(s); -}; +function assertEncoding(encoding) { + if (encoding && !Buffer.isEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} -Request.prototype.destroy = function (s) { - this.xhr.__aborted = true; - this.xhr.abort(); - this.emit('close'); +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } + + this.charBuffer = new Buffer(6); + this.charReceived = 0; + this.charLength = 0; }; -Request.prototype.end = function (s) { - if (s !== undefined) this.body.push(s); - - var keys = objectKeys(this._headers); - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var value = this._headers[key]; - if (isArray(value)) { - for (var j = 0; j < value.length; j++) { - this.xhr.setRequestHeader(key, value[j]); - } - } - else this.xhr.setRequestHeader(key, value) - } - if (this.body.length === 0) { - this.xhr.send(''); - } - else if (typeof this.body[0] === 'string') { - this.xhr.send(this.body.join('')); - } - else if (isArray(this.body[0])) { - var body = []; - for (var i = 0; i < this.body.length; i++) { - body.push.apply(body, this.body[i]); - } - this.xhr.send(body); - } - else if (/Array/.test(Object.prototype.toString.call(this.body[0]))) { - var len = 0; - for (var i = 0; i < this.body.length; i++) { - len += this.body[i].length; - } - var body = new(this.body[0].constructor)(len); - var k = 0; - - for (var i = 0; i < this.body.length; i++) { - var b = this.body[i]; - for (var j = 0; j < b.length; j++) { - body[k++] = b[j]; - } - } - this.xhr.send(body); - } - else { - var body = ''; - for (var i = 0; i < this.body.length; i++) { - body += this.body[i].toString(); - } - this.xhr.send(body); - } -}; +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + var offset = 0; -// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html -Request.unsafeHeaders = [ - "accept-charset", - "accept-encoding", - "access-control-request-headers", - "access-control-request-method", - "connection", - "content-length", - "cookie", - "cookie2", - "content-transfer-encoding", - "date", - "expect", - "host", - "keep-alive", - "origin", - "referer", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "user-agent", - "via" -]; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var i = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; -Request.prototype.isSafeRequestHeader = function (headerName) { - if (!headerName) return false; - return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; -}; + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, offset, i); + this.charReceived += (i - offset); + offset = i; -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -}; + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); -var indexOf = function (xs, x) { - if (xs.indexOf) return xs.indexOf(x); - for (var i = 0; i < xs.length; i++) { - if (xs[i] === x) return i; + // lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; } - return -1; -}; + this.charReceived = this.charLength = 0; -},{"./response":15,"Base64":16,"inherits":18,"stream":25}],15:[function(require,module,exports){ -var Stream = require('stream'); -var util = require('util'); + // if there are no more bytes in this buffer, just emit our char + if (i == buffer.length) return charStr; -var Response = module.exports = function (res) { - this.offset = 0; - this.readable = true; -}; + // otherwise cut off the characters end from the beginning of this buffer + buffer = buffer.slice(i, buffer.length); + break; + } -util.inherits(Response, Stream); + var lenIncomplete = this.detectIncompleteChar(buffer); -var capable = { - streaming : true, - status2 : true -}; + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); + this.charReceived = lenIncomplete; + end -= lenIncomplete; + } -function parseHeaders (res) { - var lines = res.getAllResponseHeaders().split(/\r?\n/); - var headers = {}; - for (var i = 0; i < lines.length; i++) { - var line = lines[i]; - if (line === '') continue; - - var m = line.match(/^([^:]+):\s*(.*)/); - if (m) { - var key = m[1].toLowerCase(), value = m[2]; - - if (headers[key] !== undefined) { - - if (isArray(headers[key])) { - headers[key].push(value); - } - else { - headers[key] = [ headers[key], value ]; - } - } - else { - headers[key] = value; - } - } - else { - headers[line] = true; - } - } - return headers; -} + charStr += buffer.toString(this.encoding, 0, end); -Response.prototype.getResponse = function (xhr) { - var respType = String(xhr.responseType).toLowerCase(); - if (respType === 'blob') return xhr.responseBlob || xhr.response; - if (respType === 'arraybuffer') return xhr.response; - return xhr.responseText; -} + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); + return charStr.substring(0, end); + } -Response.prototype.getHeader = function (key) { - return this.headers[key.toLowerCase()]; + // or just emit the charStr + return charStr; }; -Response.prototype.handle = function (res) { - if (res.readyState === 2 && capable.status2) { - try { - this.statusCode = res.status; - this.headers = parseHeaders(res); - } - catch (err) { - capable.status2 = false; - } - - if (capable.status2) { - this.emit('ready'); - } - } - else if (capable.streaming && res.readyState === 3) { - try { - if (!this.statusCode) { - this.statusCode = res.status; - this.headers = parseHeaders(res); - this.emit('ready'); - } - } - catch (err) {} - - try { - this._emitData(res); - } - catch (err) { - capable.streaming = false; - } - } - else if (res.readyState === 4) { - if (!this.statusCode) { - this.statusCode = res.status; - this.emit('ready'); - } - this._emitData(res); - - if (res.error) { - this.emit('error', this.getResponse(res)); - } - else this.emit('end'); - - this.emit('close'); +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; + + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; } -}; -Response.prototype._emitData = function (res) { - var respBody = this.getResponse(res); - if (respBody.toString().match(/ArrayBuffer/)) { - this.emit('data', new Uint8Array(respBody, this.offset)); - this.offset = respBody.byteLength; - return; + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; } - if (respBody.length > this.offset) { - this.emit('data', respBody.slice(this.offset)); - this.offset = respBody.length; + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; } + } + + return i; }; -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; }; -},{"stream":25,"util":34}],16:[function(require,module,exports){ -;(function () { +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 2; + this.charLength = incomplete ? 2 : 0; + return incomplete; +} - var object = typeof exports != 'undefined' ? exports : this; // #8: web workers - var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; +function base64DetectIncompleteChar(buffer) { + var incomplete = this.charReceived = buffer.length % 3; + this.charLength = incomplete ? 3 : 0; + return incomplete; +} - function InvalidCharacterError(message) { - this.message = message; - } - InvalidCharacterError.prototype = new Error; - InvalidCharacterError.prototype.name = 'InvalidCharacterError'; +},{"buffer":23}],19:[function(require,module,exports){ +try { + // Old IE browsers that do not curry arguments + if (!setTimeout.call) { + var slicer = Array.prototype.slice; + exports.setTimeout = function(fn) { + var args = slicer.call(arguments, 1); + return setTimeout(function() { + return fn.apply(this, args); + }) + }; - // encoder - // [https://gist.github.com/999166] by [https://github.com/nignag] - object.btoa || ( - object.btoa = function (input) { - for ( - // initialize result and counter - var block, charCode, idx = 0, map = chars, output = ''; - // if the next input index does not exist: - // change the mapping table to "=" - // check if d has no fractional digits - input.charAt(idx | 0) || (map = '=', idx % 1); - // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 - output += map.charAt(63 & block >> 8 - idx % 1 * 8) - ) { - charCode = input.charCodeAt(idx += 3/4); - if (charCode > 0xFF) { - throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); + exports.setInterval = function(fn) { + var args = slicer.call(arguments, 1); + return setInterval(function() { + return fn.apply(this, args); + }); + }; + } else { + exports.setTimeout = setTimeout; + exports.setInterval = setInterval; + } + exports.clearTimeout = clearTimeout; + exports.clearInterval = clearInterval; + + if (window.setImmediate) { + exports.setImmediate = window.setImmediate; + exports.clearImmediate = window.clearImmediate; + } + + // Chrome and PhantomJS seems to depend on `this` pseudo variable being a + // `window` and throws invalid invocation exception otherwise. If this code + // runs in such JS runtime next line will throw and `catch` clause will + // exported timers functions bound to a window. + exports.setTimeout(function() {}); +} catch (_) { + function bind(f, context) { + return function () { return f.apply(context, arguments) }; + } + + if (typeof window !== 'undefined') { + exports.setTimeout = bind(setTimeout, window); + exports.setInterval = bind(setInterval, window); + exports.clearTimeout = bind(clearTimeout, window); + exports.clearInterval = bind(clearInterval, window); + if (window.setImmediate) { + exports.setImmediate = bind(window.setImmediate, window); + exports.clearImmediate = bind(window.clearImmediate, window); + } + } else { + if (typeof setTimeout !== 'undefined') { + exports.setTimeout = setTimeout; + } + if (typeof setInterval !== 'undefined') { + exports.setInterval = setInterval; + } + if (typeof clearTimeout !== 'undefined') { + exports.clearTimeout = clearTimeout; + } + if (typeof clearInterval === 'function') { + exports.clearInterval = clearInterval; } - block = block << 8 | charCode; - } - return output; - }); - - // decoder - // [https://gist.github.com/1020396] by [https://github.com/atk] - object.atob || ( - object.atob = function (input) { - input = input.replace(/=+$/, ''); - if (input.length % 4 == 1) { - throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); - } - for ( - // initialize result and counters - var bc = 0, bs, buffer, idx = 0, output = ''; - // get next character - buffer = input.charAt(idx++); - // character found in table? initialize bit storage and add its ascii value; - ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, - // and if not first of each 4 characters, - // convert the first 8 bits to one ascii character - bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 - ) { - // try to find character in table (0-63, not found => -1) - buffer = chars.indexOf(buffer); } - return output; - }); - -}()); +} -},{}],17:[function(require,module,exports){ -var http = require('http'); +exports.unref = function unref() {}; +exports.ref = function ref() {}; -var https = module.exports; +if (!exports.setImmediate) { + var currentKey = 0, queue = {}, active = false; -for (var key in http) { - if (http.hasOwnProperty(key)) https[key] = http[key]; -}; + exports.setImmediate = (function () { + function drain() { + active = false; + for (var key in queue) { + if (queue.hasOwnProperty(currentKey, key)) { + var fn = queue[key]; + delete queue[key]; + fn(); + } + } + } -https.request = function (params, cb) { - if (!params) params = {}; - params.scheme = 'https'; - return http.request.call(this, params, cb); -} + if (typeof window !== 'undefined' && + window.postMessage && window.addEventListener) { + window.addEventListener('message', function (ev) { + if (ev.source === window && ev.data === 'browserify-tick') { + ev.stopPropagation(); + drain(); + } + }, true); -},{"http":13}],18:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true + return function setImmediate(fn) { + var id = ++currentKey; + queue[id] = fn; + if (!active) { + active = true; + window.postMessage('browserify-tick', '*'); + } + return id; + }; + } else { + return function setImmediate(fn) { + var id = ++currentKey; + queue[id] = fn; + if (!active) { + active = true; + setTimeout(drain, 0); + } + return id; + }; } - }); + })(); + + exports.clearImmediate = function clearImmediate(id) { + delete queue[id]; }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } } -},{}],19:[function(require,module,exports){ -// shim for using process in browser +},{}],20:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -var process = module.exports = {}; +var punycode = { encode : function (s) { return s } }; +var util = require('util'); +var shims = require('_shims'); -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); +// Reference: RFC 3986, RFC 1808, RFC 2396 - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), -function noop() {} + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && util.isObject(url) && url instanceof Url) return url; -process.binding = function (name) { - throw new Error('process.binding is not supported'); + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; } -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!util.isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } -},{}],20:[function(require,module,exports){ -(function (global){ -/*! http://mths.be/punycode v1.2.4 by @mathias */ -;(function(root) { + var rest = url; - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports; - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = shims.trim(rest); - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } - /** Temporary variable */ - key; + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } - /*--------------------------------------------------------------------------*/ + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - while (length--) { - array[length] = fn(array[length]); - } - return array; - } + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); - /** - * A simple `Array#map`-like wrapper to work with domain name strings. - * @private - * @param {String} domain The domain name. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - return map(string.split(regexSeparators), fn).join('.'); - } + // pull out port. + this.parseHost(); - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; - if (index >= inputLength) { - error('invalid-input'); - } +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (util.isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} - digit = basicToDigit(input.charCodeAt(index++)); +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } - if (digit < t) { - break; - } + if (this.query && + util.isObject(this.query) && + shims.keys(this.query).length) { + query = querystring.stringify(this.query); + } - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } + var search = this.search || (query && ('?' + query)) || ''; - w *= baseMinusT; + if (protocol && shims.substr(protocol, -1) !== ':') protocol += ':'; - } + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); - n += floor(i / out); - i %= out; + return protocol + host + pathname + search + hash; +}; - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} - } +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; - return ucs2encode(output); - } +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} - /** - * Converts a string of Unicode symbols to a Punycode string of ASCII-only - * symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; +Url.prototype.resolveObject = function(relative) { + if (util.isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); + var result = new Url(); + shims.forEach(shims.keys(this), function(k) { + result[k] = this[k]; + }, this); - // Cache the length - inputLength = input.length; + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + shims.forEach(shims.keys(relative), function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); - handledCPCount = basicLength = output.length; + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. + result.href = result.format(); + return result; + } - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + shims.forEach(shims.keys(relative), function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } - // Main encoding loop: - while (handledCPCount < inputLength) { + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } - delta += (m - n) * handledCPCountPlusOne; - n = m; + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!util.isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } - ++delta; - ++n; + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } - } - return output.join(''); - } + if (hasTrailingSlash && (shims.substr(srcPath.join('/'), -1) !== '/')) { + srcPath.push(''); + } - /** - * Converts a Punycode string representing a domain name to Unicode. Only the - * Punycoded parts of the domain name will be converted, i.e. it doesn't - * matter if you call it on a string that has already been converted to - * Unicode. - * @memberOf punycode - * @param {String} domain The Punycode domain name to convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(domain) { - return mapDomain(domain, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); - /** - * Converts a Unicode string representing a domain name to Punycode. Only the - * non-ASCII parts of the domain name will be converted, i.e. it doesn't - * matter if you call it with a domain that's already in ASCII. - * @memberOf punycode - * @param {String} domain The domain name to convert, as a Unicode string. - * @returns {String} The Punycode representation of the given domain name. - */ - function toASCII(domain) { - return mapDomain(domain, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } - /*--------------------------------------------------------------------------*/ + mustEndAbs = mustEndAbs || (result.host && srcPath.length); - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.2.4', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { // in Rhino or a web browser - root.punycode = punycode; - } + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } -}(this)); + //to support request.http + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],21:[function(require,module,exports){ +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) this.hostname = host; +}; +},{"_shims":7,"querystring":16,"util":21}],21:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -22595,4415 +24032,5715 @@ process.chdir = function (dir) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -'use strict'; +var shims = require('_shims'); -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); } +exports.inspect = inspect; -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; - if (typeof qs !== 'string' || qs.length === 0) { - return obj; +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; } +} - var regexp = /\+/g; - qs = qs.split(sep); - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + shims.forEach(array, function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; } - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; } - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; + // Look up the keys of the object. + var keys = shims.keys(value); + var visibleKeys = arrayToHash(keys); - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; + if (ctx.showHidden) { + keys = shims.getOwnPropertyNames(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); } + if (isError(value)) { + return formatError(value); + } + } - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); + var base = '', array = false, braces = ['{', '}']; - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { - obj[k] = [obj[k], v]; + return ctx.stylize('[Object]', 'special'); } } - return obj; -}; + ctx.seen.push(value); -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} -},{}],22:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -'use strict'; +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; - case 'boolean': - return v ? 'true' : 'false'; +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} - case 'number': - return isFinite(v) ? v : ''; - default: - return ''; +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } } -}; -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; + shims.forEach(keys, function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = shims.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } } - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return obj[k].map(function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (shims.indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + str = formatValue(ctx, desc.value, recurseTimes - 1); } - }).join(sep); - + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } } - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; + return name + ': ' + str; +} -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = shims.reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; } - return res; -}; - -},{}],23:[function(require,module,exports){ -'use strict'; -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} -},{"./decode":21,"./encode":22}],24:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return shims.isArray(ar); +} +exports.isArray = isArray; -module.exports = Duplex; -var inherits = require('inherits'); -var setImmediate = require('process/browser.js').nextTick; -var Readable = require('./readable.js'); -var Writable = require('./writable.js'); +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; -inherits(Duplex, Readable); +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; -Duplex.prototype.write = Writable.prototype.write; -Duplex.prototype.end = Writable.prototype.end; -Duplex.prototype._write = Writable.prototype._write; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; -function Duplex(options) { - if (!(this instanceof Duplex)) - return new Duplex(options); +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - Readable.call(this, options); - Writable.call(this, options); +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - if (options && options.readable === false) - this.readable = false; +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - if (options && options.writable === false) - this.writable = false; +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) - this.allowHalfOpen = false; +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - this.once('end', onend); +function isObject(arg) { + return typeof arg === 'object' && arg; } +exports.isObject = isObject; -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) - return; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - // no more data can be written. - // But allow more writes to happen in this tick. - var self = this; - setImmediate(function () { - self.end(); - }); +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; } +exports.isError = isError; -},{"./readable.js":28,"./writable.js":30,"inherits":18,"process/browser.js":26}],25:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; -module.exports = Stream; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; -var EE = require('events').EventEmitter; -var inherits = require('inherits'); +function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.binarySlice === 'function' + ; +} +exports.isBuffer = isBuffer; -inherits(Stream, EE); -Stream.Readable = require('./readable.js'); -Stream.Writable = require('./writable.js'); -Stream.Duplex = require('./duplex.js'); -Stream.Transform = require('./transform.js'); -Stream.PassThrough = require('./passthrough.js'); +function objectToString(o) { + return Object.prototype.toString.call(o); +} -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; -function Stream() { - EE.call(this); +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); } -Stream.prototype.pipe = function(dest, options) { - var source = this; - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; - source.on('data', ondata); - function ondrain() { - if (source.readable && source.resume) { - source.resume(); +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = function(ctor, superCtor) { + ctor.super_ = superCtor; + ctor.prototype = shims.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true } - } + }); +}; - dest.on('drain', ondrain); +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); + var keys = shims.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; } + return origin; +}; - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} - dest.end(); - } +},{"_shims":7}],22:[function(require,module,exports){ +exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; + i += d; - function onclose() { - if (didOnEnd) return; - didOnEnd = true; + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - if (typeof dest.destroy === 'function') dest.destroy(); - } + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - source.removeListener('error', onerror); - dest.removeListener('error', onerror); + value = Math.abs(value); - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } - dest.removeListener('close', cleanup); + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } } - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - dest.emit('pipe', source); + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; + buffer[offset + i - d] |= s * 128; }; -},{"./duplex.js":24,"./passthrough.js":27,"./readable.js":28,"./transform.js":29,"./writable.js":30,"events":12,"inherits":18}],26:[function(require,module,exports){ -// shim for using process in browser +},{}],23:[function(require,module,exports){ +var assert; +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; -var process = module.exports = {}; +function stringtrim(str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +} -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; +function Buffer(subject, encoding, offset) { + if(!assert) assert= require('assert'); + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; + // Work-around: node's base64 implementation + // allows for non-padded strings while base64-js + // does not.. + if (encoding == "base64" && typeof subject == "string") { + subject = stringtrim(subject); + while (subject.length % 4 != 0) { + subject = subject + "="; } + } - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); + var type; - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + // slicing works, with limitations (no parent tracking/update) + // check https://github.com/toots/buffer-browserify/issues/19 + for (var i = 0; i < this.length; i++) { + this[i] = subject.get(i+offset); } + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; -process.binding = function (name) { - throw new Error('process.binding is not supported'); + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } + + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; + } + } + } } -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; }; -},{}],27:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. - -module.exports = PassThrough; +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; -var Transform = require('./transform.js'); -var inherits = require('inherits'); -inherits(PassThrough, Transform); +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; -function PassThrough(options) { - if (!(this instanceof PassThrough)) - return new PassThrough(options); + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; - Transform.call(this, options); -} + case 'ascii': + case 'binary': + return str.length; -PassThrough.prototype._transform = function(chunk, encoding, cb) { - cb(null, chunk); + case 'base64': + return base64ToBytes(str).length; + + default: + throw new Error('Unknown encoding'); + } }; -},{"./transform.js":29,"inherits":18}],28:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; -module.exports = Readable; -Readable.ReadableState = ReadableState; +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; -var EE = require('events').EventEmitter; -var Stream = require('./index.js'); -var Buffer = require('buffer').Buffer; -var setImmediate = require('process/browser.js').nextTick; -var StringDecoder; +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; -var inherits = require('inherits'); -inherits(Readable, Stream); +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; -function ReadableState(options, stream) { - options = options || {}; +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; - // 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" - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + i++; + } - this.buffer = []; - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = false; - this.ended = false; - this.endEmitted = false; - this.reading = false; + return res + decodeUtf8Char(tmp); +} - // In streams that never have any data, and do push(null) right away, - // the consumer can miss the 'end' event if they do some I/O before - // consuming the stream. So, we don't emit('end') until some reading - // happens. - this.calledRead = false; +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} - // 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, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; - // 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; +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; + } + } + return ''; +}; - // 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; +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; - // 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'; + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); + } + return out; +}; - // 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; +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) - StringDecoder = require('string_decoder').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; + // Fastpath empty strings + if (+end == start) { + return ''; } -} -function Readable(options) { - if (!(this instanceof Readable)) - return new Readable(options); + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); - this._readableState = new ReadableState(options, this); + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); - // legacy - this.readable = true; + case 'ascii': + return this.asciiSlice(start, end); - Stream.call(this); -} + case 'binary': + return this.binarySlice(start, end); -// 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; + case 'base64': + return this.base64Slice(start, end); - if (typeof chunk === 'string' && !state.objectMode) { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = new Buffer(chunk, encoding); - encoding = ''; - } - } + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); - return readableAddChunk(this, state, chunk, encoding, false); + default: + throw new Error('Unknown encoding'); + } }; -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function(chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); -}; -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null || chunk === undefined) { - state.reading = false; - if (!state.ended) - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var e = new Error('stream.unshift() after end event'); - stream.emit('error', e); - } else { - if (state.decoder && !addToFront && !encoding) - chunk = state.decoder.write(chunk); +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) { - state.buffer.unshift(chunk); - } else { - state.reading = false; - state.buffer.push(chunk); - } + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); + } + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; +}; - if (state.needReadable) - emitReadable(stream); - maybeReadMore(stream, state); +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; } - } else if (!addToFront) { - state.reading = false; + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; } - return needMoreData(state); -} - + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || 'utf8').toLowerCase(); + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); -// if it's past the high water mark, we can push in some more. -// 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. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && - (state.needReadable || - state.length < state.highWaterMark || - state.length === 0); -} + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); -// backwards compatibility. -Readable.prototype.setEncoding = function(enc) { - if (!StringDecoder) - StringDecoder = require('string_decoder').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; -}; + case 'ascii': + return this.asciiWrite(string, offset, length); -// Don't raise the hwm > 128MB -var MAX_HWM = 0x800000; -function roundUpToNextPowerOf2(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 - n--; - for (var p = 1; p < 32; p <<= 1) n |= n >> p; - n++; - } - return n; -} + case 'binary': + return this.binaryWrite(string, offset, length); -function howMuchToRead(n, state) { - if (state.length === 0 && state.ended) - return 0; + case 'base64': + return this.base64Write(string, offset, length); - if (state.objectMode) - return n === 0 ? 0 : 1; + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); - if (isNaN(n) || n === null) { - // only flow one buffer at a time - if (state.flowing && state.buffer.length) - return state.buffer[0].length; - else - return state.length; + default: + throw new Error('Unknown encoding'); } +}; - if (n <= 0) - return 0; +// slice(start, end) +function clamp(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; +} - // If we're asking for more than the target buffer level, - // then raise the water mark. Bump up to the next highest - // power of 2, to prevent increasing it excessively in tiny - // amounts. - if (n > state.highWaterMark) - state.highWaterMark = roundUpToNextPowerOf2(n); +Buffer.prototype.slice = function(start, end) { + var len = this.length; + start = clamp(start, len, 0); + end = clamp(end, len, len); + return new Buffer(this, end - start, +start); +}; - // don't have that much. return null, unless we've ended. - if (n > state.length) { - if (!state.ended) { - state.needReadable = true; - return 0; - } else - return state.length; +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; } + target_start || (target_start = 0); - return n; -} + if (end < start) throw new Error('sourceEnd < sourceStart'); -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function(n) { - var state = this._readableState; - state.calledRead = true; - var nOrig = n; + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; - if (typeof n !== 'number' || n > 0) - state.emittedReadable = false; + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); + } - // 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.length >= state.highWaterMark || state.ended)) { - emitReadable(this); - return null; + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); } - n = howMuchToRead(n, state); + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); + } - // 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; + // Are we oob? + if (end > this.length) { + end = this.length; } - // 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 (target.length - target_start < end - start) { + end = target.length - target_start + start; + } - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; + var temp = []; + for (var i=start; i 0) - ret = fromList(n, state); - else - ret = null; + // Fill 0 bytes; we're done + if (end === start) return 0; + if (this.length == 0) return 0; - if (ret === null) { - state.needReadable = true; - n = 0; + if (start < 0 || start >= this.length) { + throw new Error('start out of bounds'); } - state.length -= n; - - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (state.length === 0 && !state.ended) - state.needReadable = true; + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); + } - // If we happened to read() exactly the remaining amount in the - // buffer, and the EOF has been seen at this point, then make sure - // that we emit 'end' on the very next tick. - if (state.ended && !state.endEmitted && state.length === 0) - endReadable(this); + for (var i = start; i < end; i++) { + this[i] = value; + } +} - return ret; +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; }; -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode && - !er) { - er = new TypeError('Invalid non-string/buffer chunk'); +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); } - return er; -} + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; + } -function onEofChunk(stream, state) { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; } } - state.ended = true; - // if we've ended and we have some data left, then emit - // 'readable' now to make sure it gets picked up. - if (state.length > 0) - emitReadable(stream); - else - endReadable(stream); -} + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer; +}; -// 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; - state.needReadable = false; - if (state.emittedReadable) - return; +Buffer.isEncoding = function(encoding) { + switch ((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; - state.emittedReadable = true; - if (state.sync) - setImmediate(function() { - emitReadable_(stream); - }); - else - emitReadable_(stream); -} + default: + return false; + } +}; -function emitReadable_(stream) { - stream.emit('readable'); -} +// helpers +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; +} -// 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; - setImmediate(function() { - maybeReadMore_(stream, state); - }); - } +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) } -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && - state.length < state.highWaterMark) { - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break; - else - len = state.length; - } - state.readingMore = false; +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; } -// 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) { - this.emit('error', new Error('not implemented')); -}; +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); +} -Readable.prototype.pipe = function(dest, pipeOpts) { - var src = this; - var state = this._readableState; +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); + } - 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; + return byteArray; +} - var doEnd = (!pipeOpts || pipeOpts.end !== false) && - dest !== process.stdout && - dest !== process.stderr; +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) - setImmediate(endFn); - else - src.once('end', endFn); + return byteArray; +} - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - if (readable !== src) return; - cleanup(); +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} + +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; + + dst[i + offset] = src[i]; + i++; } + return i; +} - function onend() { - dest.end(); +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char } +} - // 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); +// read/write bit-twiddling - function 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', cleanup); +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; - // 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 (!dest._writableState || dest._writableState.needDrain) - ondrain(); - } + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - // check for listeners before emit removes one-time listeners. - var errListeners = EE.listenerCount(dest, 'error'); - function onerror(er) { - unpipe(); - if (errListeners === 0 && EE.listenerCount(dest, 'error') === 0) - dest.emit('error', er); + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); } - dest.once('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() { - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); + if (offset >= buffer.length) return; - function unpipe() { - src.unpipe(dest); - } + return buffer[offset]; +}; - // tell the dest that it's being piped to - dest.emit('pipe', src); +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; - // start the flow if it hasn't been started already. - if (!state.flowing) { - // the handler that waits for readable events after all - // the data gets sucked out in flow. - // This would be easier to follow with a .once() handler - // in flow(), but that is too slow. - this.on('readable', pipeOnReadable); - state.flowing = true; - setImmediate(function() { - flow(src); - }); - } + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - return dest; -}; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -function pipeOnDrain(src) { - return function() { - var dest = this; - var state = src._readableState; - state.awaitDrain--; - if (state.awaitDrain === 0) - flow(src); - }; -} + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); + } -function flow(src) { - var state = src._readableState; - var chunk; - state.awaitDrain = 0; + if (offset >= buffer.length) return 0; - function write(dest, i, list) { - var written = dest.write(chunk); - if (false === written) { - state.awaitDrain++; + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; + } + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; } } - while (state.pipesCount && null !== (chunk = src.read())) { + return val; +} - if (state.pipesCount === 1) - write(state.pipes, 0, null); - else - forEach(state.pipes, write); +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); +}; - src.emit('data', chunk); +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; - // if anyone needs a drain, then we have to wait for that. - if (state.awaitDrain > 0) - return; - } +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; - // if every destination was unpiped, either before entering this - // function, or in the while loop, then stop flowing. - // - // NB: This is a pretty rare edge case. - if (state.pipesCount === 0) { - state.flowing = false; + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - // if there were data event listeners added, then switch to old mode. - if (EE.listenerCount(src, 'data') > 0) - emitDataEvents(src); - return; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - // at this point, no one needed a drain, so we just ran out of data - // on the next readable event, start it over again. - state.ranOut = true; -} + if (offset >= buffer.length) return 0; -function pipeOnReadable() { - if (this._readableState.ranOut) { - this._readableState.ranOut = false; - flow(this); + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); } + + return val; } +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); +}; -Readable.prototype.unpipe = function(dest) { - var state = this._readableState; +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; - // 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; +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; - if (!dest) - dest = state.pipes; + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - // got a match. - state.pipes = null; - state.pipesCount = 0; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; - if (dest) - dest.emit('unpipe', this); - return this; + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); } - // slow case. multiple pipe destinations. + if (offset >= buffer.length) return; - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); + } - for (var i = 0; i < len; i++) - dests[i].emit('unpipe', this); - return this; + return ((0xff - buffer[offset] + 1) * -1); +}; + +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); } - // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) - return this; + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; + } - state.pipes.splice(i, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) - state.pipes = state.pipes[0]; + return (0xffff - val + 1) * -1; +} - dest.emit('unpipe', this); +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; - return this; +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); }; -// 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); +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; - if (ev === 'data' && !this._readableState.flowing) - emitDataEvents(this); + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (ev === 'readable' && this.readable) { - var state = this._readableState; - if (!state.readableListening) { - state.readableListening = true; - state.emittedReadable = false; - state.needReadable = true; - if (!state.reading) { - this.read(0); - } else if (state.length) { - emitReadable(this, state); - } - } + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - return res; + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); + } + + return (0xffffffff - val + 1) * -1; +} + +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); }; -Readable.prototype.addListener = Readable.prototype.on; -// 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() { - emitDataEvents(this); - this.read(0); - this.emit('resume'); +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); }; -Readable.prototype.pause = function() { - emitDataEvents(this, true); - this.emit('pause'); +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); + } + + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); }; -function emitDataEvents(stream, startPaused) { - var state = stream._readableState; +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; - if (state.flowing) { - // https://github.com/isaacs/readable-stream/issues/16 - throw new Error('Cannot switch to old mode now.'); +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); } - var paused = startPaused || false; - var readable = false; + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); +} - // convert to an old-style stream. - stream.readable = true; - stream.pipe = Stream.prototype.pipe; - stream.on = stream.addListener = Stream.prototype.on; +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); +}; - stream.on('readable', function() { - readable = true; +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); +}; - var c; - while (!paused && (null !== (c = stream.read()))) - stream.emit('data', c); - if (c === null) { - readable = false; - stream._readableState.needReadable = true; - } - }); +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - stream.pause = function() { - paused = true; - this.emit('pause'); - }; + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); - stream.resume = function() { - paused = false; - if (readable) - setImmediate(function() { - stream.emit('readable'); - }); - else - this.read(0); - this.emit('resume'); - }; + assert.ok(value <= max, 'value is larger than maximum value for type'); - // now make it start, just in case it hadn't already. - stream.emit('readable'); + assert.ok(Math.floor(value) === value, 'value has a fractional component'); } -// 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 state = this._readableState; - var paused = false; +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; - var self = this; - stream.on('end', function() { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) - self.push(chunk); - } + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - self.push(null); - }); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - stream.on('data', function(chunk) { - if (state.decoder) - chunk = state.decoder.write(chunk); - if (!chunk || !state.objectMode && !chunk.length) - return; + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); + verifuint(value, 0xff); + } - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (typeof stream[i] === 'function' && - typeof this[i] === 'undefined') { - this[i] = function(method) { return function() { - return stream[method].apply(stream, arguments); - }}(i); - } + if (offset < buffer.length) { + buffer[offset] = value; } +}; - // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function(ev) { - stream.on(ev, function (x) { - return self.emit.apply(self, ev, x); - }); - }); +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function(n) { - if (paused) { - paused = false; - stream.resume(); - } - }; + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - return self; -}; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); + verifuint(value, 0xffff); + } -// exposed for testing purposes only. -Readable._fromList = fromList; + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; + } -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -function fromList(n, state) { - var list = state.buffer; - var length = state.length; - var stringMode = !!state.decoder; - var objectMode = !!state.objectMode; - var ret; +} - // nothing in the list, definitely empty. - if (list.length === 0) - return null; +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; - if (length === 0) - ret = null; - else if (objectMode) - ret = list.shift(); - else if (!n || n >= length) { - // read it all, truncate the array. - if (stringMode) - ret = list.join(''); - else - ret = Buffer.concat(list, length); - list.length = 0; - } else { - // read just some of it. - if (n < list[0].length) { - // just take a part of the first list item. - // slice is the same for buffers and strings. - var buf = list[0]; - ret = buf.slice(0, n); - list[0] = buf.slice(n); - } else if (n === list[0].length) { - // first list is a perfect match - ret = list.shift(); - } else { - // complex case. - // we have enough to cover it, but it spans past the first buffer. - if (stringMode) - ret = ''; - else - ret = new Buffer(n); +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); +}; - var c = 0; - for (var i = 0, l = list.length; i < l && c < n; i++) { - var buf = list[0]; - var cpy = Math.min(n - c, buf.length); +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - if (stringMode) - ret += buf.slice(0, cpy); - else - buf.copy(ret, c, 0, cpy); + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (cpy < buf.length) - list[0] = buf.slice(cpy); - else - list.shift(); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - c += cpy; - } - } + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); } - return ret; + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; + } } -function endReadable(stream) { - var state = stream._readableState; +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) - throw new Error('endReadable called on non-empty stream'); +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; - if (!state.endEmitted && state.calledRead) { - state.ended = true; - setImmediate(function() { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } - }); - } -} -function forEach (xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: + * + * > -32 & 0xff + * 224 + * + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. + * + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: + * + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: + * + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. + */ + +/* + * A series of checks to make sure we actually have a signed 32-bit number + */ +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); + + assert.ok(Math.floor(value) === value, 'value has a fractional component'); } -function indexOf (xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); + + assert.ok(value <= max, 'value larger than maximum allowed value'); + + assert.ok(value >= min, 'value smaller than minimum allowed value'); } -}).call(this,require("FWaASH")) -},{"./index.js":25,"FWaASH":19,"buffer":3,"events":12,"inherits":18,"process/browser.js":26,"string_decoder":31}],29:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); -module.exports = Transform; + verifsint(value, 0x7f, -0x80); + } -var Duplex = require('./duplex.js'); -var inherits = require('inherits'); -inherits(Transform, Duplex); + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); + } +}; +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); -function TransformState(options, stream) { - this.afterTransform = function(er, data) { - return afterTransform(stream, er, data); - }; + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); + } + + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); + } } -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; - var cb = ts.writecb; +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; - if (!cb) - return stream.emit('error', new Error('no writecb in Transform class')); +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - ts.writechunk = null; - ts.writecb = null; + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (data !== null && data !== undefined) - stream.push(data); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - if (cb) - cb(er); + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); + verifsint(value, 0x7fffffff, -0x80000000); + } + + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); } } +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; -function Transform(options) { - if (!(this instanceof Transform)) - return new Transform(options); +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; - Duplex.call(this, options); +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - var ts = this._transformState = new TransformState(options, this); + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - // when the writable side finishes, then flush out anything remaining. - var stream = this; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); - // 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; + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + } - this.once('finish', function() { - if ('function' === typeof this._flush) - this._flush(function(er) { - done(stream, er); - }); - else - done(stream); - }); + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); } -Transform.prototype.push = function(chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); }; -// 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) { - throw new Error('not implemented'); +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); }; -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); - } -}; +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); -// 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; + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - if (ts.writechunk && ts.writecb && !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; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); }; +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; -function done(stream, er) { - if (er) - return stream.emit('error', er); +},{"./buffer_ieee754":22,"assert":13,"base64-js":24}],24:[function(require,module,exports){ +(function (exports) { + 'use strict'; - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var rs = stream._readableState; - var ts = stream._transformState; + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - if (ws.length) - throw new Error('calling transform done when ws.length != 0'); + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; + } - if (ts.transforming) - throw new Error('calling transform done when still transforming'); + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; - return stream.push(null); -} + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); -},{"./duplex.js":24,"inherits":18}],30:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; -// A bit simpler than readable streams. -// Implement an async ._write(chunk, cb), and it'll handle all -// the drain event emission and buffering. + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } -module.exports = Writable; -Writable.WritableState = WritableState; + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } -var isUint8Array = typeof Uint8Array !== 'undefined' - ? function (x) { return x instanceof Uint8Array } - : function (x) { - return x && x.constructor && x.constructor.name === 'Uint8Array' - } -; -var isArrayBuffer = typeof ArrayBuffer !== 'undefined' - ? function (x) { return x instanceof ArrayBuffer } - : function (x) { - return x && x.constructor && x.constructor.name === 'ArrayBuffer' - } -; + return arr; + } -var inherits = require('inherits'); -var Stream = require('./index.js'); -var setImmediate = require('process/browser.js').nextTick; -var Buffer = require('buffer').Buffer; + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; -inherits(Writable, Stream); + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; -} + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } -function WritableState(options, stream) { - options = options || {}; + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } - // 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() - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + return output; + } - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; +},{}],25:[function(require,module,exports){ +var Buffer = require('buffer').Buffer; +var intSize = 4; +var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); +var chrsz = 8; - 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; +function toArray(buf, bigEndian) { + if ((buf.length % intSize) !== 0) { + var len = buf.length + (intSize - (buf.length % intSize)); + buf = Buffer.concat([buf, zeroBuffer], len); + } - // 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; + var arr = []; + var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; + for (var i = 0; i < buf.length; i += intSize) { + arr.push(fn.call(buf, i)); + } + return arr; +} - // 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'; +function toBuffer(arr, size, bigEndian) { + var buf = new Buffer(size); + var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; + for (var i = 0; i < arr.length; i++) { + fn.call(buf, arr[i], i * 4, true); + } + return buf; +} - // 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; +function hash(buf, fn, hashSize, bigEndian) { + if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); + var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); + return toBuffer(arr, hashSize, bigEndian); +} - // a flag to see when we're in the middle of a write. - this.writing = false; +module.exports = { hash: hash }; - // 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, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; +},{"buffer":23}],26:[function(require,module,exports){ +var Buffer = require('buffer').Buffer +var sha = require('./sha') +var sha256 = require('./sha256') +var rng = require('./rng') +var md5 = require('./md5') - // 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; +var algorithms = { + sha1: sha, + sha256: sha256, + md5: md5 +} - // the callback that's passed to _write(chunk,cb) - this.onwrite = function(er) { - onwrite(stream, er); - }; +var blocksize = 64 +var zeroBuffer = new Buffer(blocksize); zeroBuffer.fill(0) +function hmac(fn, key, data) { + if(!Buffer.isBuffer(key)) key = new Buffer(key) + if(!Buffer.isBuffer(data)) data = new Buffer(data) - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; + if(key.length > blocksize) { + key = fn(key) + } else if(key.length < blocksize) { + key = Buffer.concat([key, zeroBuffer], blocksize) + } - // the amount that is being written when _write is called. - this.writelen = 0; + var ipad = new Buffer(blocksize), opad = new Buffer(blocksize) + for(var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } - this.buffer = []; + var hash = fn(Buffer.concat([ipad, data])) + return fn(Buffer.concat([opad, hash])) } -function Writable(options) { - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Stream.Duplex)) - return new Writable(options); +function hash(alg, key) { + alg = alg || 'sha1' + var fn = algorithms[alg] + var bufs = [] + var length = 0 + if(!fn) error('algorithm:', alg, 'is not yet supported') + return { + update: function (data) { + if(!Buffer.isBuffer(data)) data = new Buffer(data) + + bufs.push(data) + length += data.length + return this + }, + digest: function (enc) { + var buf = Buffer.concat(bufs) + var r = key ? hmac(fn, key, buf) : fn(buf) + bufs = null + return enc ? r.toString(enc) : r + } + } +} - this._writableState = new WritableState(options, this); +function error () { + var m = [].slice.call(arguments).join(' ') + throw new Error([ + m, + 'we accept pull requests', + 'http://github.com/dominictarr/crypto-browserify' + ].join('\n')) +} - // legacy. - this.writable = true; +exports.createHash = function (alg) { return hash(alg) } +exports.createHmac = function (alg, key) { return hash(alg, key) } +exports.randomBytes = function(size, callback) { + if (callback && callback.call) { + try { + callback.call(this, undefined, new Buffer(rng(size))) + } catch (err) { callback(err) } + } else { + return new Buffer(rng(size)) + } +} + +function each(a, f) { + for(var i in a) + f(a[i], i) +} + +// the least I can do is make error messages for the rest of the node.js/crypto api. +each(['createCredentials' +, 'createCipher' +, 'createCipheriv' +, 'createDecipher' +, 'createDecipheriv' +, 'createSign' +, 'createVerify' +, 'createDiffieHellman' +, 'pbkdf2'], function (name) { + exports[name] = function () { + error('sorry,', name, 'is not implemented yet') + } +}) + +},{"./md5":27,"./rng":28,"./sha":29,"./sha256":30,"buffer":23}],27:[function(require,module,exports){ +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +var helpers = require('./helpers'); + +/* + * Perform a simple self-test to see if the VM is working + */ +function md5_vm_test() +{ + return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); + + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); + + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + } + return Array(a, b, c, d); + +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} + +module.exports = function md5(buf) { + return helpers.hash(buf, core_md5, 16); +}; - Stream.call(this); -} +},{"./helpers":25}],28:[function(require,module,exports){ +// Original code adapted from Robert Kieffer. +// details at https://github.com/broofa/node-uuid +(function() { + var _global = this; -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function() { - this.emit('error', new Error('Cannot pipe. Not readable.')); -}; + var mathRNG, whatwgRNG; + // NOTE: Math.random() does not guarantee "cryptographic quality" + mathRNG = function(size) { + var bytes = new Array(size); + var r; -function writeAfterEnd(stream, state, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - setImmediate(function() { - cb(er); - }); -} + for (var i = 0, r; i < size; i++) { + if ((i & 0x03) == 0) r = Math.random() * 0x100000000; + bytes[i] = r >>> ((i & 0x03) << 3) & 0xff; + } -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. -function validChunk(stream, state, chunk, cb) { - var valid = true; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); - stream.emit('error', er); - setImmediate(function() { - cb(er); - }); - valid = false; + return bytes; } - return valid; -} -Writable.prototype.write = function(chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; + if (_global.crypto && crypto.getRandomValues) { + whatwgRNG = function(size) { + var bytes = new Uint8Array(size); + crypto.getRandomValues(bytes); + return bytes; + } } - if (!Buffer.isBuffer(chunk) && isUint8Array(chunk)) - chunk = new Buffer(chunk); - if (isArrayBuffer(chunk) && typeof Uint8Array !== 'undefined') - chunk = new Buffer(new Uint8Array(chunk)); - - if (Buffer.isBuffer(chunk)) - encoding = 'buffer'; - else if (!encoding) - encoding = state.defaultEncoding; + module.exports = whatwgRNG || mathRNG; - if (typeof cb !== 'function') - cb = function() {}; +}()) - if (state.ended) - writeAfterEnd(this, state, cb); - else if (validChunk(this, state, chunk, cb)) - ret = writeOrBuffer(this, state, chunk, encoding, cb); +},{}],29:[function(require,module,exports){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ - return ret; -}; +var helpers = require('./helpers'); -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && - state.decodeStrings !== false && - typeof chunk === 'string') { - chunk = new Buffer(chunk, encoding); - } - return chunk; -} +/* + * Calculate the SHA-1 of an array of big-endian words, and a bit length + */ +function core_sha1(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << (24 - len % 32); + x[((len + 64 >> 9) << 4) + 15] = len; -// 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, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - var len = state.objectMode ? 1 : chunk.length; + var w = Array(80); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; + var e = -1009589776; - state.length += len; + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; + var olde = e; - var ret = state.length < state.highWaterMark; - state.needDrain = !ret; + for(var j = 0; j < 80; j++) + { + if(j < 16) w[j] = x[i + j]; + else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); + var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), + safe_add(safe_add(e, w[j]), sha1_kt(j))); + e = d; + d = c; + c = rol(b, 30); + b = a; + a = t; + } - if (state.writing) - state.buffer.push(new WriteReq(chunk, encoding, cb)); - else - doWrite(stream, state, len, chunk, encoding, cb); + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); + e = safe_add(e, olde); + } + return Array(a, b, c, d, e); - return ret; } -function doWrite(stream, state, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - stream._write(chunk, encoding, state.onwrite); - state.sync = false; +/* + * Perform the appropriate triplet combination function for the current + * iteration + */ +function sha1_ft(t, b, c, d) +{ + if(t < 20) return (b & c) | ((~b) & d); + if(t < 40) return b ^ c ^ d; + if(t < 60) return (b & c) | (b & d) | (c & d); + return b ^ c ^ d; } -function onwriteError(stream, state, sync, er, cb) { - if (sync) - setImmediate(function() { - cb(er); - }); - else - cb(er); +/* + * Determine the appropriate additive constant for the current iteration + */ +function sha1_kt(t) +{ + return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : + (t < 60) ? -1894007588 : -899497514; +} - stream.emit('error', er); +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); } -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); } -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; +module.exports = function sha1(buf) { + return helpers.hash(buf, core_sha1, 20, true); +}; - onwriteStateUpdate(state); +},{"./helpers":25}],30:[function(require,module,exports){ - 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(stream, state); +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ - if (!finished && !state.bufferProcessing && state.buffer.length) - clearBuffer(stream, state); +var helpers = require('./helpers'); - if (sync) { - setImmediate(function() { - afterWrite(stream, state, finished, cb); - }); - } else { - afterWrite(stream, state, finished, cb); - } - } -} +var safe_add = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +}; -function afterWrite(stream, state, finished, cb) { - if (!finished) - onwriteDrain(stream, state); - cb(); - if (finished) - finishMaybe(stream, state); -} +var S = function(X, n) { + return (X >>> n) | (X << (32 - n)); +}; -// 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'); - } -} +var R = function(X, n) { + return (X >>> n); +}; +var Ch = function(x, y, z) { + return ((x & y) ^ ((~x) & z)); +}; -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; +var Maj = function(x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)); +}; - for (var c = 0; c < state.buffer.length; c++) { - var entry = state.buffer[c]; - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; +var Sigma0256 = function(x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); +}; - doWrite(stream, state, len, chunk, encoding, cb); +var Sigma1256 = function(x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); +}; - // 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) { - c++; - break; - } - } +var Gamma0256 = function(x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); +}; - state.bufferProcessing = false; - if (c < state.buffer.length) - state.buffer = state.buffer.slice(c); - else - state.buffer.length = 0; -} +var Gamma1256 = function(x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); +}; -Writable.prototype._write = function(chunk, encoding, cb) { - cb(new Error('not implemented')); +var core_sha256 = function(m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); + var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for (var i = 0; i < m.length; i += 16) { + a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7]; + for (var j = 0; j < 64; j++) { + if (j < 16) { + W[j] = m[j + i]; + } else { + W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]); + } + T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]); + T2 = safe_add(Sigma0256(a), Maj(a, b, c)); + h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2); + } + HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); + HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]); + } + return HASH; }; -Writable.prototype.end = function(chunk, encoding, cb) { - var state = this._writableState; +module.exports = function sha256(buf) { + return helpers.hash(buf, core_sha256, 32, true); +}; - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } +},{"./helpers":25}],31:[function(require,module,exports){ +var http = module.exports; +var EventEmitter = require('events').EventEmitter; +var Request = require('./lib/request'); - if (typeof chunk !== 'undefined' && chunk !== null) - this.write(chunk, encoding); +http.request = function (params, cb) { + if (!params) params = {}; + if (!params.host && !params.port) { + params.port = parseInt(window.location.port, 10); + } + if (!params.host) params.host = window.location.hostname; + if (!params.port) params.port = 80; + if (!params.scheme) params.scheme = window.location.protocol.split(':')[0]; + + var req = new Request(new xhrHttp, params); + if (cb) req.on('response', cb); + return req; +}; - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) - endWritable(this, state, cb); +http.get = function (params, cb) { + params.method = 'GET'; + var req = http.request(params, cb); + req.end(); + return req; }; +http.Agent = function () {}; +http.Agent.defaultMaxSockets = 4; -function needFinish(stream, state) { - return (state.ending && - state.length === 0 && - !state.finished && - !state.writing); -} +var xhrHttp = (function () { + if (typeof window === 'undefined') { + throw new Error('no window object present'); + } + else if (window.XMLHttpRequest) { + return window.XMLHttpRequest; + } + else if (window.ActiveXObject) { + var axs = [ + 'Msxml2.XMLHTTP.6.0', + 'Msxml2.XMLHTTP.3.0', + 'Microsoft.XMLHTTP' + ]; + for (var i = 0; i < axs.length; i++) { + try { + var ax = new(window.ActiveXObject)(axs[i]); + return function () { + if (ax) { + var ax_ = ax; + ax = null; + return ax_; + } + else { + return new(window.ActiveXObject)(axs[i]); + } + }; + } + catch (e) {} + } + throw new Error('ajax not supported in this browser') + } + else { + throw new Error('ajax not supported in this browser'); + } +})(); -function finishMaybe(stream, state) { - var need = needFinish(stream, state); - if (need) { - state.finished = true; - stream.emit('finish'); - } - return need; -} +},{"./lib/request":32,"events":14}],32:[function(require,module,exports){ +var Stream = require('stream'); +var Response = require('./response'); +var concatStream = require('concat-stream'); +var Base64 = require('Base64'); +var util = require('util'); -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) - setImmediate(cb); - else - stream.once('finish', cb); - } - state.ended = true; -} +var Request = module.exports = function (xhr, params) { + var self = this; + self.writable = true; + self.xhr = xhr; + self.body = concatStream() + + var uri = params.host + + (params.port ? ':' + params.port : '') + + (params.path || '/') + ; + + xhr.open( + params.method || 'GET', + (params.scheme || 'http') + '://' + uri, + true + ); + + if (params.headers) { + var keys = objectKeys(params.headers); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!self.isSafeRequestHeader(key)) continue; + var value = params.headers[key]; + if (isArray(value)) { + for (var j = 0; j < value.length; j++) { + xhr.setRequestHeader(key, value[j]); + } + } + else xhr.setRequestHeader(key, value) + } + } + + if (params.auth) { + //basic auth + this.setHeader('Authorization', 'Basic ' + Base64.btoa(params.auth)); + } -},{"./index.js":25,"buffer":3,"inherits":18,"process/browser.js":26}],31:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + var res = new Response; + res.on('close', function () { + self.emit('close'); + }); + + res.on('ready', function () { + self.emit('response', res); + }); + + xhr.onreadystatechange = function () { + res.handle(xhr); + }; +}; -var Buffer = require('buffer').Buffer; +util.inherits(Request, Stream); -function assertEncoding(encoding) { - if (encoding && !Buffer.isEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} +Request.prototype.setHeader = function (key, value) { + if (isArray(value)) { + for (var i = 0; i < value.length; i++) { + this.xhr.setRequestHeader(key, value[i]); + } + } + else { + this.xhr.setRequestHeader(key, value); + } +}; -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } +Request.prototype.write = function (s) { + this.body.write(s); +}; - this.charBuffer = new Buffer(6); - this.charReceived = 0; - this.charLength = 0; +Request.prototype.destroy = function (s) { + this.xhr.abort(); + this.emit('close'); }; +Request.prototype.end = function (s) { + if (s !== undefined) this.body.write(s); + this.body.end() + this.xhr.send(this.body.getBody()); +}; -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - var offset = 0; +// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html +Request.unsafeHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "cookie", + "cookie2", + "content-transfer-encoding", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "user-agent", + "via" +]; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var i = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; +Request.prototype.isSafeRequestHeader = function (headerName) { + if (!headerName) return false; + return indexOf(Request.unsafeHeaders, headerName.toLowerCase()) === -1; +}; - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, offset, i); - this.charReceived += (i - offset); - offset = i; +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +}; - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +var indexOf = function (xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (xs[i] === x) return i; } + return -1; +}; - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); +},{"./response":33,"Base64":34,"concat-stream":35,"stream":17,"util":21}],33:[function(require,module,exports){ +var Stream = require('stream'); +var util = require('util'); - // lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; +var Response = module.exports = function (res) { + this.offset = 0; + this.readable = true; +}; - // if there are no more bytes in this buffer, just emit our char - if (i == buffer.length) return charStr; +util.inherits(Response, Stream); - // otherwise cut off the characters end from the beginning of this buffer - buffer = buffer.slice(i, buffer.length); - break; - } +var capable = { + streaming : true, + status2 : true +}; - var lenIncomplete = this.detectIncompleteChar(buffer); +function parseHeaders (res) { + var lines = res.getAllResponseHeaders().split(/\r?\n/); + var headers = {}; + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + if (line === '') continue; + + var m = line.match(/^([^:]+):\s*(.*)/); + if (m) { + var key = m[1].toLowerCase(), value = m[2]; + + if (headers[key] !== undefined) { + + if (isArray(headers[key])) { + headers[key].push(value); + } + else { + headers[key] = [ headers[key], value ]; + } + } + else { + headers[key] = value; + } + } + else { + headers[line] = true; + } + } + return headers; +} - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - lenIncomplete, end); - this.charReceived = lenIncomplete; - end -= lenIncomplete; - } +Response.prototype.getResponse = function (xhr) { + var respType = String(xhr.responseType).toLowerCase(); + if (respType === 'blob') return xhr.responseBlob || xhr.response; + if (respType === 'arraybuffer') return xhr.response; + return xhr.responseText; +} - charStr += buffer.toString(this.encoding, 0, end); +Response.prototype.getHeader = function (key) { + return this.headers[key.toLowerCase()]; +}; - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - this.charBuffer.write(charStr.charAt(charStr.length - 1), this.encoding); - return charStr.substring(0, end); - } +Response.prototype.handle = function (res) { + if (res.readyState === 2 && capable.status2) { + try { + this.statusCode = res.status; + this.headers = parseHeaders(res); + } + catch (err) { + capable.status2 = false; + } + + if (capable.status2) { + this.emit('ready'); + } + } + else if (capable.streaming && res.readyState === 3) { + try { + if (!this.statusCode) { + this.statusCode = res.status; + this.headers = parseHeaders(res); + this.emit('ready'); + } + } + catch (err) {} + + try { + this._emitData(res); + } + catch (err) { + capable.streaming = false; + } + } + else if (res.readyState === 4) { + if (!this.statusCode) { + this.statusCode = res.status; + this.emit('ready'); + } + this._emitData(res); + + if (res.error) { + this.emit('error', this.getResponse(res)); + } + else this.emit('end'); + + this.emit('close'); + } +}; - // or just emit the charStr - return charStr; +Response.prototype._emitData = function (res) { + var respBody = this.getResponse(res); + if (respBody.toString().match(/ArrayBuffer/)) { + this.emit('data', new Uint8Array(respBody, this.offset)); + this.offset = respBody.byteLength; + return; + } + if (respBody.length > this.offset) { + this.emit('data', respBody.slice(this.offset)); + this.offset = respBody.length; + } }; -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; +},{"stream":17,"util":21}],34:[function(require,module,exports){ +;(function () { - // See http://en.wikipedia.org/wiki/UTF-8#Description + var + object = typeof exports != 'undefined' ? exports : this, // #8: web workers + chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', + INVALID_CHARACTER_ERR = (function () { + // fabricate a suitable error object + try { document.createElement('$'); } + catch (error) { return error; }}()); - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; + // encoder + // [https://gist.github.com/999166] by [https://github.com/nignag] + object.btoa || ( + object.btoa = function (input) { + for ( + // initialize result and counter + var block, charCode, idx = 0, map = chars, output = ''; + // if the next input index does not exist: + // change the mapping table to "=" + // check if d has no fractional digits + input.charAt(idx | 0) || (map = '=', idx % 1); + // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 + output += map.charAt(63 & block >> 8 - idx % 1 * 8) + ) { + charCode = input.charCodeAt(idx += 3/4); + if (charCode > 0xFF) throw INVALID_CHARACTER_ERR; + block = block << 8 | charCode; } + return output; + }); - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; + // decoder + // [https://gist.github.com/1020396] by [https://github.com/atk] + object.atob || ( + object.atob = function (input) { + input = input.replace(/=+$/, '') + if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR; + for ( + // initialize result and counters + var bc = 0, bs, buffer, idx = 0, output = ''; + // get next character + buffer = input.charAt(idx++); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); } + return output; + }); - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } +}()); - return i; -}; +},{}],35:[function(require,module,exports){ +var stream = require('stream') +var bops = require('bops') +var util = require('util') + +function ConcatStream(cb) { + stream.Stream.call(this) + this.writable = true + if (cb) this.cb = cb + this.body = [] + this.on('error', function(err) { + // no-op + }) +} -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); +util.inherits(ConcatStream, stream.Stream) - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } +ConcatStream.prototype.write = function(chunk) { + this.body.push(chunk) +} - return res; -}; +ConcatStream.prototype.destroy = function() {} -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); +ConcatStream.prototype.arrayConcat = function(arrs) { + if (arrs.length === 0) return [] + if (arrs.length === 1) return arrs[0] + return arrs.reduce(function (a, b) { return a.concat(b) }) } -function utf16DetectIncompleteChar(buffer) { - var incomplete = this.charReceived = buffer.length % 2; - this.charLength = incomplete ? 2 : 0; - return incomplete; +ConcatStream.prototype.isArray = function(arr) { + return Array.isArray(arr) } -function base64DetectIncompleteChar(buffer) { - var incomplete = this.charReceived = buffer.length % 3; - this.charLength = incomplete ? 3 : 0; - return incomplete; +ConcatStream.prototype.getBody = function () { + if (this.body.length === 0) return + if (typeof(this.body[0]) === "string") return this.body.join('') + if (this.isArray(this.body[0])) return this.arrayConcat(this.body) + if (bops.is(this.body[0])) return bops.join(this.body) + return this.body } -},{"buffer":3}],32:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var punycode = require('punycode'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; - -exports.Url = Url; +ConcatStream.prototype.end = function() { + if (this.cb) this.cb(this.getBody()) +} -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; +module.exports = function(cb) { + return new ConcatStream(cb) } -// Reference: RFC 3986, RFC 1808, RFC 2396 +module.exports.ConcatStream = ConcatStream -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, +},{"bops":36,"stream":17,"util":21}],36:[function(require,module,exports){ +var proto = {} +module.exports = proto - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], +proto.from = require('./from.js') +proto.to = require('./to.js') +proto.is = require('./is.js') +proto.subarray = require('./subarray.js') +proto.join = require('./join.js') +proto.copy = require('./copy.js') +proto.create = require('./create.js') - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), +mix(require('./read.js'), proto) +mix(require('./write.js'), proto) - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = require('querystring'); +function mix(from, into) { + for(var key in from) { + into[key] = from[key] + } +} -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && isObject(url) && url instanceof Url) return url; +},{"./copy.js":39,"./create.js":40,"./from.js":41,"./is.js":42,"./join.js":43,"./read.js":45,"./subarray.js":46,"./to.js":47,"./write.js":48}],37:[function(require,module,exports){ +module.exports=require(24) +},{}],38:[function(require,module,exports){ +module.exports = to_utf8 + +var out = [] + , col = [] + , fcc = String.fromCharCode + , mask = [0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01] + , unmask = [ + 0x00 + , 0x01 + , 0x02 | 0x01 + , 0x04 | 0x02 | 0x01 + , 0x08 | 0x04 | 0x02 | 0x01 + , 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + , 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + , 0x40 | 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01 + ] + +function to_utf8(bytes, start, end) { + start = start === undefined ? 0 : start + end = end === undefined ? bytes.length : end + + var idx = 0 + , hi = 0x80 + , collecting = 0 + , pos + , by + + col.length = + out.length = 0 + + while(idx < bytes.length) { + by = bytes[idx] + if(!collecting && by & hi) { + pos = find_pad_position(by) + collecting += pos + if(pos < 8) { + col[col.length] = by & unmask[6 - pos] + } + } else if(collecting) { + col[col.length] = by & unmask[6] + --collecting + if(!collecting && col.length) { + out[out.length] = fcc(reduced(col, pos)) + col.length = 0 + } + } else { + out[out.length] = fcc(by) + } + ++idx + } + if(col.length && !collecting) { + out[out.length] = fcc(reduced(col, pos)) + col.length = 0 + } + return out.join('') +} - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; +function find_pad_position(byt) { + for(var i = 0; i < 7; ++i) { + if(!(byt & mask[i])) { + break + } + } + return i } -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); +function reduced(list) { + var out = 0 + for(var i = 0, len = list.length; i < len; ++i) { + out |= list[i] << ((len - i - 1) * 6) } + return out +} - var rest = url; +},{}],39:[function(require,module,exports){ +module.exports = copy - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); +var slice = [].slice - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); +function copy(source, target, target_start, source_start, source_end) { + target_start = arguments.length < 3 ? 0 : target_start + source_start = arguments.length < 4 ? 0 : source_start + source_end = arguments.length < 5 ? source.length : source_end + + if(source_end === source_start) { + return } - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } + if(target.length === 0 || source.length === 0) { + return } - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { + if(source_end > source.length) { + source_end = source.length + } - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c + if(target.length - target_start < source_end - source_start) { + source_end = target.length - target_start + start + } - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. + if(source.buffer !== target.buffer) { + return fast_copy(source, target, target_start, source_start, source_end) + } + return slow_copy(source, target, target_start, source_start, source_end) +} - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } +function fast_copy(source, target, target_start, source_start, source_end) { + var len = (source_end - source_start) + target_start - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); - } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); - } + for(var i = target_start, j = source_start; + i < len; + ++i, + ++j) { + target[i] = source[j] + } +} - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); - } +function slow_copy(from, to, j, i, jend) { + // the buffers could overlap. + var iend = jend + i + , tmp = new Uint8Array(slice.call(from, i, iend)) + , x = 0 - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; + for(; i < iend; ++i, ++x) { + to[j++] = tmp[x] + } +} - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); +},{}],40:[function(require,module,exports){ +module.exports = function(size) { + return new Uint8Array(size) +} - // pull out port. - this.parseHost(); +},{}],41:[function(require,module,exports){ +module.exports = from - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; +var base64 = require('base64-js') - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; +var decoders = { + hex: from_hex + , utf8: from_utf + , base64: from_base64 +} - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } +function from(source, encoding) { + if(Array.isArray(source)) { + return new Uint8Array(source) + } - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); - } + return decoders[encoding || 'utf8'](source) +} - if (!ipv6Hostname) { - // IDNA Support: Returns a puny coded representation of "domain". - // It only converts the part of the domain name that - // has non ASCII characters. I.e. it dosent matter if - // you call it with a domain that already is in ASCII. - var domainArray = this.hostname.split('.'); - var newOut = []; - for (var i = 0; i < domainArray.length; ++i) { - var s = domainArray[i]; - newOut.push(s.match(/[^A-Za-z0-9_-]/) ? - 'xn--' + punycode.encode(s) : s); - } - this.hostname = newOut.join('.'); - } +function from_hex(str) { + var size = str.length / 2 + , buf = new Uint8Array(size) + , character = '' - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; + for(var i = 0, len = str.length; i < len; ++i) { + character += str.charAt(i) - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; - } + if(i > 0 && (i % 2) === 1) { + buf[i>>>1] = parseInt(character, 16) + character = '' } } - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { + return buf +} - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); +function from_utf(str) { + var bytes = [] + , tmp + , ch + + for(var i = 0, len = str.length; i < len; ++i) { + ch = str.charCodeAt(i) + if(ch & 0x80) { + tmp = encodeURIComponent(str.charAt(i)).substr(1).split('%') + for(var j = 0, jlen = tmp.length; j < jlen; ++j) { + bytes[bytes.length] = parseInt(tmp[j], 16) } - rest = rest.split(ae).join(esc); + } else { + bytes[bytes.length] = ch } } + return new Uint8Array(bytes) +} + +function from_base64(str) { + return new Uint8Array(base64.toByteArray(str)) +} - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); +},{"base64-js":37}],42:[function(require,module,exports){ + +module.exports = function(buffer) { + return buffer instanceof Uint8Array; +} + +},{}],43:[function(require,module,exports){ +module.exports = join + +function join(targets, hint) { + if(!targets.length) { + return new Uint8Array(0) } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); + + var len = hint !== undefined ? hint : get_length(targets) + , out = new Uint8Array(len) + , cur = targets[0] + , curlen = cur.length + , curidx = 0 + , curoff = 0 + , i = 0 + + while(i < len) { + if(curoff === curlen) { + curoff = 0 + ++curidx + cur = targets[curidx] + curlen = cur && cur.length + continue } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; + out[i++] = cur[curoff++] } - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; + return out +} + +function get_length(targets) { + var size = 0 + for(var i = 0, len = targets.length; i < len; ++i) { + size += targets[i].byteLength } + return size +} - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; +},{}],44:[function(require,module,exports){ +var proto + , map -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); +module.exports = proto = {} + +map = typeof WeakMap === 'undefined' ? null : new WeakMap + +proto.get = !map ? no_weakmap_get : get + +function no_weakmap_get(target) { + return new DataView(target.buffer, 0) } -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; +function get(target) { + var out = map.get(target.buffer) + if(!out) { + map.set(target.buffer, out = new DataView(target.buffer, 0)) } + return out +} - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; +},{}],45:[function(require,module,exports){ +module.exports = { + readUInt8: read_uint8 + , readInt8: read_int8 + , readUInt16LE: read_uint16_le + , readUInt32LE: read_uint32_le + , readInt16LE: read_int16_le + , readInt32LE: read_int32_le + , readFloatLE: read_float_le + , readDoubleLE: read_double_le + , readUInt16BE: read_uint16_be + , readUInt32BE: read_uint32_be + , readInt16BE: read_int16_be + , readInt32BE: read_int32_be + , readFloatBE: read_float_be + , readDoubleBE: read_double_be +} - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; - } - } +var map = require('./mapped.js') - if (this.query && - isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); - } +function read_uint8(target, at) { + return target[at] +} - var search = this.search || (query && ('?' + query)) || ''; +function read_int8(target, at) { + var v = target[at]; + return v < 0x80 ? v : v - 0x100 +} - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; +function read_uint16_le(target, at) { + var dv = map.get(target); + return dv.getUint16(at + target.byteOffset, true) +} - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; - } +function read_uint32_le(target, at) { + var dv = map.get(target); + return dv.getUint32(at + target.byteOffset, true) +} - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; +function read_int16_le(target, at) { + var dv = map.get(target); + return dv.getInt16(at + target.byteOffset, true) +} - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); +function read_int32_le(target, at) { + var dv = map.get(target); + return dv.getInt32(at + target.byteOffset, true) +} - return protocol + host + pathname + search + hash; -}; +function read_float_le(target, at) { + var dv = map.get(target); + return dv.getFloat32(at + target.byteOffset, true) +} -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); +function read_double_le(target, at) { + var dv = map.get(target); + return dv.getFloat64(at + target.byteOffset, true) } -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; +function read_uint16_be(target, at) { + var dv = map.get(target); + return dv.getUint16(at + target.byteOffset, false) +} -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); +function read_uint32_be(target, at) { + var dv = map.get(target); + return dv.getUint32(at + target.byteOffset, false) } -Url.prototype.resolveObject = function(relative) { - if (isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } +function read_int16_be(target, at) { + var dv = map.get(target); + return dv.getInt16(at + target.byteOffset, false) +} - var result = new Url(); - Object.keys(this).forEach(function(k) { - result[k] = this[k]; - }, this); +function read_int32_be(target, at) { + var dv = map.get(target); + return dv.getInt32(at + target.byteOffset, false) +} - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; +function read_float_be(target, at) { + var dv = map.get(target); + return dv.getFloat32(at + target.byteOffset, false) +} - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; +function read_double_be(target, at) { + var dv = map.get(target); + return dv.getFloat64(at + target.byteOffset, false) +} + +},{"./mapped.js":44}],46:[function(require,module,exports){ +module.exports = subarray + +function subarray(buf, from, to) { + return buf.subarray(from || 0, to || buf.length) +} + +},{}],47:[function(require,module,exports){ +module.exports = to + +var base64 = require('base64-js') + , toutf8 = require('to-utf8') + +var encoders = { + hex: to_hex + , utf8: to_utf + , base64: to_base64 +} + +function to(buf, encoding) { + return encoders[encoding || 'utf8'](buf) +} + +function to_hex(buf) { + var str = '' + , byt + + for(var i = 0, len = buf.length; i < len; ++i) { + byt = buf[i] + str += ((byt & 0xF0) >>> 4).toString(16) + str += (byt & 0x0F).toString(16) } - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - Object.keys(relative).forEach(function(k) { - if (k !== 'protocol') - result[k] = relative[k]; - }); + return str +} - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } +function to_utf(buf) { + return toutf8(buf) +} - result.href = result.format(); - return result; +function to_base64(buf) { + return base64.fromByteArray(buf) +} + + +},{"base64-js":37,"to-utf8":38}],48:[function(require,module,exports){ +module.exports = { + writeUInt8: write_uint8 + , writeInt8: write_int8 + , writeUInt16LE: write_uint16_le + , writeUInt32LE: write_uint32_le + , writeInt16LE: write_int16_le + , writeInt32LE: write_int32_le + , writeFloatLE: write_float_le + , writeDoubleLE: write_double_le + , writeUInt16BE: write_uint16_be + , writeUInt32BE: write_uint32_be + , writeInt16BE: write_int16_be + , writeInt32BE: write_int32_be + , writeFloatBE: write_float_be + , writeDoubleBE: write_double_be +} + +var map = require('./mapped.js') + +function write_uint8(target, value, at) { + return target[at] = value +} + +function write_int8(target, value, at) { + return target[at] = value < 0 ? value + 0x100 : value +} + +function write_uint16_le(target, value, at) { + var dv = map.get(target); + return dv.setUint16(at + target.byteOffset, value, true) +} + +function write_uint32_le(target, value, at) { + var dv = map.get(target); + return dv.setUint32(at + target.byteOffset, value, true) +} + +function write_int16_le(target, value, at) { + var dv = map.get(target); + return dv.setInt16(at + target.byteOffset, value, true) +} + +function write_int32_le(target, value, at) { + var dv = map.get(target); + return dv.setInt32(at + target.byteOffset, value, true) +} + +function write_float_le(target, value, at) { + var dv = map.get(target); + return dv.setFloat32(at + target.byteOffset, value, true) +} + +function write_double_le(target, value, at) { + var dv = map.get(target); + return dv.setFloat64(at + target.byteOffset, value, true) +} + +function write_uint16_be(target, value, at) { + var dv = map.get(target); + return dv.setUint16(at + target.byteOffset, value, false) +} + +function write_uint32_be(target, value, at) { + var dv = map.get(target); + return dv.setUint32(at + target.byteOffset, value, false) +} + +function write_int16_be(target, value, at) { + var dv = map.get(target); + return dv.setInt16(at + target.byteOffset, value, false) +} + +function write_int32_be(target, value, at) { + var dv = map.get(target); + return dv.setInt32(at + target.byteOffset, value, false) +} + +function write_float_be(target, value, at) { + var dv = map.get(target); + return dv.setFloat32(at + target.byteOffset, value, false) +} + +function write_double_be(target, value, at) { + var dv = map.get(target); + return dv.setFloat64(at + target.byteOffset, value, false) +} + +},{"./mapped.js":44}],49:[function(require,module,exports){ +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 1, + nBits = -7, + i = isBE ? 0 : (nBytes - 1), + d = isBE ? 1 : -1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - Object.keys(relative).forEach(function(k) { - result[k] = relative[k]; - }); - result.href = result.format(); - return result; - } +exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isBE ? (nBytes - 1) : 0, + d = isBE ? -1 : 1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; } else { - result.pathname = relative.pathname; + value += rt * Math.pow(2, 1 - eBias); } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; } - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; + +},{}],"q9TxCC":[function(require,module,exports){ +var assert; +exports.Buffer = Buffer; +exports.SlowBuffer = Buffer; +Buffer.poolSize = 8192; +exports.INSPECT_MAX_BYTES = 50; + +function stringtrim(str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +} + +function Buffer(subject, encoding, offset) { + if(!assert) assert= require('assert'); + if (!(this instanceof Buffer)) { + return new Buffer(subject, encoding, offset); + } + this.parent = this; + this.offset = 0; + + // Work-around: node's base64 implementation + // allows for non-padded strings while base64-js + // does not.. + if (encoding == "base64" && typeof subject == "string") { + subject = stringtrim(subject); + while (subject.length % 4 != 0) { + subject = subject + "="; } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } + var type; + + // Are we slicing? + if (typeof offset === 'number') { + this.length = coerce(encoding); + // slicing works, with limitations (no parent tracking/update) + // check https://github.com/toots/buffer-browserify/issues/19 + for (var i = 0; i < this.length; i++) { + this[i] = subject.get(i+offset); } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); + } else { + // Find the length + switch (type = typeof subject) { + case 'number': + this.length = coerce(subject); + break; + + case 'string': + this.length = Buffer.byteLength(subject, encoding); + break; + + case 'object': // Assume object is an array + this.length = coerce(subject.length); + break; + + default: + throw new Error('First argument needs to be a number, ' + + 'array or string.'); + } + + // Treat array-ish objects as a byte array. + if (isArrayIsh(subject)) { + for (var i = 0; i < this.length; i++) { + if (subject instanceof Buffer) { + this[i] = subject.readUInt8(i); + } + else { + this[i] = subject[i]; + } + } + } else if (type == 'string') { + // We are a string + this.length = this.write(subject, 0, encoding); + } else if (type === 'number') { + for (var i = 0; i < this.length; i++) { + this[i] = 0; + } } - result.href = result.format(); - return result; } +} - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; - //to support http.request - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - result.href = result.format(); - return result; +Buffer.prototype.get = function get(i) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i]; +}; + +Buffer.prototype.set = function set(i, v) { + if (i < 0 || i >= this.length) throw new Error('oob'); + return this[i] = v; +}; + +Buffer.byteLength = function (str, encoding) { + switch (encoding || "utf8") { + case 'hex': + return str.length / 2; + + case 'utf8': + case 'utf-8': + return utf8ToBytes(str).length; + + case 'ascii': + case 'binary': + return str.length; + + case 'base64': + return base64ToBytes(str).length; + + default: + throw new Error('Unknown encoding'); } +}; - // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = ( - (result.host || relative.host) && (last === '.' || last === '..') || - last === ''); +Buffer.prototype.utf8Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); +}; - // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last == '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } +Buffer.prototype.asciiWrite = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); +}; + +Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; + +Buffer.prototype.base64Write = function (string, offset, length) { + var bytes, pos; + return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); +}; + +Buffer.prototype.base64Slice = function (start, end) { + var bytes = Array.prototype.slice.apply(this, arguments) + return require("base64-js").fromByteArray(bytes); +}; + +Buffer.prototype.utf8Slice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var res = ""; + var tmp = ""; + var i = 0; + while (i < bytes.length) { + if (bytes[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); + tmp = ""; + } else + tmp += "%" + bytes[i].toString(16); + + i++; } - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); + return res + decodeUtf8Char(tmp); +} + +Buffer.prototype.asciiSlice = function () { + var bytes = Array.prototype.slice.apply(this, arguments); + var ret = ""; + for (var i = 0; i < bytes.length; i++) + ret += String.fromCharCode(bytes[i]); + return ret; +} + +Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; + +Buffer.prototype.inspect = function() { + var out = [], + len = this.length; + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]); + if (i == exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...'; + break; } } + return ''; +}; - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); +Buffer.prototype.hexSlice = function(start, end) { + var len = this.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; i++) { + out += toHex(this[i]); } + return out; +}; - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } +Buffer.prototype.toString = function(encoding, start, end) { + encoding = String(encoding || 'utf8').toLowerCase(); + start = +start || 0; + if (typeof end == 'undefined') end = this.length; + + // Fastpath empty strings + if (+end == start) { + return ''; } - mustEndAbs = mustEndAbs || (result.host && srcPath.length); + switch (encoding) { + case 'hex': + return this.hexSlice(start, end); - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); + case 'utf8': + case 'utf-8': + return this.utf8Slice(start, end); + + case 'ascii': + return this.asciiSlice(start, end); + + case 'binary': + return this.binarySlice(start, end); + + case 'base64': + return this.base64Slice(start, end); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Slice(start, end); + + default: + throw new Error('Unknown encoding'); } +}; - if (!srcPath.length) { - result.pathname = null; - result.path = null; + +Buffer.prototype.hexWrite = function(string, offset, length) { + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; } else { - result.pathname = srcPath.join('/'); + length = +length; + if (length > remaining) { + length = remaining; + } } - //to support request.http - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); + // must be an even number of digits + var strLen = string.length; + if (strLen % 2) { + throw new Error('Invalid hex string'); } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(byte)) throw new Error('Invalid hex string'); + this[offset + i] = byte; + } + Buffer._charsWritten = i * 2; + return i; }; -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); + +Buffer.prototype.write = function(string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length; + length = undefined; } - host = host.substr(0, host.length - port.length); + } else { // legacy + var swap = encoding; + encoding = offset; + offset = length; + length = swap; + } + + offset = +offset || 0; + var remaining = this.length - offset; + if (!length) { + length = remaining; + } else { + length = +length; + if (length > remaining) { + length = remaining; + } + } + encoding = String(encoding || 'utf8').toLowerCase(); + + switch (encoding) { + case 'hex': + return this.hexWrite(string, offset, length); + + case 'utf8': + case 'utf-8': + return this.utf8Write(string, offset, length); + + case 'ascii': + return this.asciiWrite(string, offset, length); + + case 'binary': + return this.binaryWrite(string, offset, length); + + case 'base64': + return this.base64Write(string, offset, length); + + case 'ucs2': + case 'ucs-2': + return this.ucs2Write(string, offset, length); + + default: + throw new Error('Unknown encoding'); } - if (host) this.hostname = host; }; -function isString(arg) { - return typeof arg === "string"; +// slice(start, end) +function clamp(index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue; + index = ~~index; // Coerce to integer. + if (index >= len) return len; + if (index >= 0) return index; + index += len; + if (index >= 0) return index; + return 0; } -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} +Buffer.prototype.slice = function(start, end) { + var len = this.length; + start = clamp(start, len, 0); + end = clamp(end, len, len); + return new Buffer(this, end - start, +start); +}; -function isNull(arg) { - return arg === null; -} -function isNullOrUndefined(arg) { - return arg == null; -} +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function(target, target_start, start, end) { + var source = this; + start || (start = 0); + if (end === undefined || isNaN(end)) { + end = this.length; + } + target_start || (target_start = 0); -},{"punycode":20,"querystring":23}],33:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],34:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + if (end < start) throw new Error('sourceEnd < sourceStart'); -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); + // Copy 0 bytes; we're done + if (end === start) return 0; + if (target.length == 0 || source.length == 0) return 0; + + if (target_start < 0 || target_start >= target.length) { + throw new Error('targetStart out of bounds'); } - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } + if (start < 0 || start >= source.length) { + throw new Error('sourceStart out of bounds'); } - return str; -}; + if (end < 0 || end > source.length) { + throw new Error('sourceEnd out of bounds'); + } -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; + // Are we oob? + if (end > this.length) { + end = this.length; } - if (process.noDeprecation === true) { - return fn; + if (target.length - target_start < end - start) { + end = target.length - target_start + start; } - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); + var temp = []; + for (var i=start; i= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); + // Fill 0 bytes; we're done + if (end === start) return 0; + if (this.length == 0) return 0; + + if (start < 0 || start >= this.length) { + throw new Error('start out of bounds'); + } + + if (end < 0 || end > this.length) { + throw new Error('end out of bounds'); + } + + for (var i = start; i < end; i++) { + this[i] = value; } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); } -exports.inspect = inspect; +// Static methods +Buffer.isBuffer = function isBuffer(b) { + return b instanceof Buffer || b instanceof Buffer; +}; -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) { + throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ + list should be an Array."); + } + + if (list.length === 0) { + return new Buffer(0); + } else if (list.length === 1) { + return list[0]; + } + + if (typeof totalLength !== 'number') { + totalLength = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + totalLength += buf.length; + } + } + + var buffer = new Buffer(totalLength); + var pos = 0; + for (var i = 0; i < list.length; i++) { + var buf = list[i]; + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer; }; -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' +Buffer.isEncoding = function(encoding) { + switch ((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; + } }; +// helpers -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; +function coerce(length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length); + return length < 0 ? 0 : length; +} - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } +function isArray(subject) { + return (Array.isArray || + function(subject){ + return {}.toString.apply(subject) == '[object Array]' + }) + (subject) } +function isArrayIsh(subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number'; +} -function stylizeNoColor(str, styleType) { - return str; +function toHex(n) { + if (n < 16) return '0' + n.toString(16); + return n.toString(16); } +function utf8ToBytes(str) { + var byteArray = []; + for (var i = 0; i < str.length; i++) + if (str.charCodeAt(i) <= 0x7F) + byteArray.push(str.charCodeAt(i)); + else { + var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)); + } -function arrayToHash(array) { - var hash = {}; + return byteArray; +} - array.forEach(function(val, idx) { - hash[val] = true; - }); +function asciiToBytes(str) { + var byteArray = [] + for (var i = 0; i < str.length; i++ ) + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push( str.charCodeAt(i) & 0xFF ); - return hash; + return byteArray; } +function base64ToBytes(str) { + return require("base64-js").toByteArray(str); +} -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; +function blitBuffer(src, dst, offset, length) { + var pos, i = 0; + while (i < length) { + if ((i+offset >= dst.length) || (i >= src.length)) + break; + + dst[i + offset] = src[i]; + i++; } + return i; +} - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; +function decodeUtf8Char(str) { + try { + return decodeURIComponent(str); + } catch (err) { + return String.fromCharCode(0xFFFD); // UTF 8 invalid char } +} - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); +// read/write bit-twiddling - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); +Buffer.prototype.readUInt8 = function(offset, noAssert) { + var buffer = this; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); } - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); + if (offset >= buffer.length) return; + + return buffer[offset]; +}; + +function readUInt16(buffer, offset, isBigEndian, noAssert) { + var val = 0; + + + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + val = buffer[offset] << 8; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1]; } - if (isError(value)) { - return formatError(value); + } else { + val = buffer[offset]; + if (offset + 1 < buffer.length) { + val |= buffer[offset + 1] << 8; } } - var base = '', array = false, braces = ['{', '}']; + return val; +} - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } +Buffer.prototype.readUInt16LE = function(offset, noAssert) { + return readUInt16(this, offset, false, noAssert); +}; - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } +Buffer.prototype.readUInt16BE = function(offset, noAssert) { + return readUInt16(this, offset, true, noAssert); +}; - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } +function readUInt32(buffer, offset, isBigEndian, noAssert) { + var val = 0; - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; + if (offset >= buffer.length) return 0; + + if (isBigEndian) { + if (offset + 1 < buffer.length) + val = buffer[offset + 1] << 16; + if (offset + 2 < buffer.length) + val |= buffer[offset + 2] << 8; + if (offset + 3 < buffer.length) + val |= buffer[offset + 3]; + val = val + (buffer[offset] << 24 >>> 0); + } else { + if (offset + 2 < buffer.length) + val = buffer[offset + 2] << 16; + if (offset + 1 < buffer.length) + val |= buffer[offset + 1] << 8; + val |= buffer[offset]; + if (offset + 3 < buffer.length) + val = val + (buffer[offset + 3] << 24 >>> 0); } - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } + return val; +} + +Buffer.prototype.readUInt32LE = function(offset, noAssert) { + return readUInt32(this, offset, false, noAssert); +}; + +Buffer.prototype.readUInt32BE = function(offset, noAssert) { + return readUInt32(this, offset, true, noAssert); +}; + + +/* + * Signed integer types, yay team! A reminder on how two's complement actually + * works. The first bit is the signed bit, i.e. tells us whether or not the + * number should be positive or negative. If the two's complement value is + * positive, then we're done, as it's equivalent to the unsigned representation. + * + * Now if the number is positive, you're pretty much done, you can just leverage + * the unsigned translations and return those. Unfortunately, negative numbers + * aren't quite that straightforward. + * + * At first glance, one might be inclined to use the traditional formula to + * translate binary numbers between the positive and negative values in two's + * complement. (Though it doesn't quite work for the most negative value) + * Mainly: + * - invert all the bits + * - add one to the result + * + * Of course, this doesn't quite work in Javascript. Take for example the value + * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of + * course, Javascript will do the following: + * + * > ~0xff80 + * -65409 + * + * Whoh there, Javascript, that's not quite right. But wait, according to + * Javascript that's perfectly correct. When Javascript ends up seeing the + * constant 0xff80, it has no notion that it is actually a signed number. It + * assumes that we've input the unsigned value 0xff80. Thus, when it does the + * binary negation, it casts it into a signed value, (positive 0xff80). Then + * when you perform binary negation on that, it turns it into a negative number. + * + * Instead, we're going to have to use the following general formula, that works + * in a rather Javascript friendly way. I'm glad we don't support this kind of + * weird numbering scheme in the kernel. + * + * (BIT-MAX - (unsigned)val + 1) * -1 + * + * The astute observer, may think that this doesn't make sense for 8-bit numbers + * (really it isn't necessary for them). However, when you get 16-bit numbers, + * you do. Let's go back to our prior example and see how this will look: + * + * (0xffff - 0xff80 + 1) * -1 + * (0x007f + 1) * -1 + * (0x0080) * -1 + */ +Buffer.prototype.readInt8 = function(offset, noAssert) { + var buffer = this; + var neg; + + if (!noAssert) { + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset < buffer.length, + 'Trying to read beyond buffer length'); } - ctx.seen.push(value); + if (offset >= buffer.length) return; - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); + neg = buffer[offset] & 0x80; + if (!neg) { + return (buffer[offset]); } - ctx.seen.pop(); + return ((0xff - buffer[offset] + 1) * -1); +}; + +function readInt16(buffer, offset, isBigEndian, noAssert) { + var neg, val; - return reduceToSingleString(output, base, braces); -} + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); + assert.ok(offset + 1 < buffer.length, + 'Trying to read beyond buffer length'); } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} + val = readUInt16(buffer, offset, isBigEndian, noAssert); + neg = val & 0x8000; + if (!neg) { + return val; + } -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; + return (0xffff - val + 1) * -1; } +Buffer.prototype.readInt16LE = function(offset, noAssert) { + return readInt16(this, offset, false, noAssert); +}; -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} +Buffer.prototype.readInt16BE = function(offset, noAssert) { + return readInt16(this, offset, true, noAssert); +}; +function readInt32(buffer, offset, isBigEndian, noAssert) { + var neg, val; -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } + + val = readUInt32(buffer, offset, isBigEndian, noAssert); + neg = val & 0x80000000; + if (!neg) { + return (val); } - return name + ': ' + str; + return (0xffffffff - val + 1) * -1; } +Buffer.prototype.readInt32LE = function(offset, noAssert) { + return readInt32(this, offset, false, noAssert); +}; -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); +Buffer.prototype.readInt32BE = function(offset, noAssert) { + return readInt32(this, offset, true, noAssert); +}; - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; +function readFloat(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to read beyond buffer length'); } - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 23, 4); } +Buffer.prototype.readFloatLE = function(offset, noAssert) { + return readFloat(this, offset, false, noAssert); +}; -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; +Buffer.prototype.readFloatBE = function(offset, noAssert) { + return readFloat(this, offset, true, noAssert); +}; -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; +function readDouble(buffer, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; + assert.ok(offset + 7 < buffer.length, + 'Trying to read beyond buffer length'); + } -function isNullOrUndefined(arg) { - return arg == null; + return require('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, + 52, 8); } -exports.isNullOrUndefined = isNullOrUndefined; -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; +Buffer.prototype.readDoubleLE = function(offset, noAssert) { + return readDouble(this, offset, false, noAssert); +}; -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; +Buffer.prototype.readDoubleBE = function(offset, noAssert) { + return readDouble(this, offset, true, noAssert); +}; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; +/* + * We have to make sure that the value is a valid integer. This means that it is + * non-negative. It has no fractional component and that it does not exceed the + * maximum allowed value. + * + * value The number to check for validity + * + * max The maximum value + */ +function verifuint(value, max) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + assert.ok(value >= 0, + 'specified a negative value for writing an unsigned value'); -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; + assert.ok(value <= max, 'value is larger than maximum value for type'); -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; + assert.ok(Math.floor(value) === value, 'value has a fractional component'); } -exports.isDate = isDate; -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; +Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { + var buffer = this; -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); -exports.isBuffer = require('./support/isBuffer'); + assert.ok(offset < buffer.length, + 'trying to write beyond buffer length'); -function objectToString(o) { - return Object.prototype.toString.call(o); -} + verifuint(value, 0xff); + } + if (offset < buffer.length) { + buffer[offset] = value; + } +}; -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} +function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffff); + } + + for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { + buffer[offset + i] = + (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> + (isBigEndian ? 1 - i : i) * 8; + } -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); } +Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, false, noAssert); +}; -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { + writeUInt16(this, value, offset, true, noAssert); }; +function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; + assert.ok(offset + 3 < buffer.length, + 'trying to write beyond buffer length'); + + verifuint(value, 0xffffffff); } - return origin; -}; -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); + for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { + buffer[offset + i] = + (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; + } } -}).call(this,require("FWaASH"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":33,"FWaASH":19,"inherits":18}],35:[function(require,module,exports){ -function replace(a, b) -{ - if (!b) - { - return a; - } - var key; - for (key in b) - { - if(b.hasOwnProperty(key)) - { - a[key] = b[key]; - } - } - - return a; -} exports.replace=replace; - -function add(a, b) -{ - if (!b) - { - return a; - } - var key; - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined' || a[key]===null) - { - a[key] = b[key]; - } - } - } - return a; -} exports.add=add; - - -function extend(a, b, context, newobjs, aparent, aname, haveaparent) // context is anti circular references mechanism -{ - if (a==b){ return a;} - if (!b) { return a;} - - var key, clean_context=false, return_sublevel=false,b_pos; - if(!haveaparent){ aparent={'a':a}; aname='a'; } - if(!context){clean_context=true;context=[];newobjs=[];} - b_pos=context.indexOf(b); - if( b_pos==-1 ) {context.push(b);newobjs.push([aparent, aname]);} else { return newobjs[b_pos][0][ newobjs[b_pos][1] ]; } - - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined') - { - if(typeof b[key] === 'object') - { - if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html - {a[key] = extend([], b[key],context,newobjs,a,key,true);} - else if(b[key]===null) - {a[key] = null;} - else if( b[key] instanceof Date ) - { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } - else - { a[key] = extend({}, b[key],context,newobjs,a,key,true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/ } - } - else - { a[key] = b[key]; } - } - else if(typeof a[key] === 'object' && a[key] !== null) - { a[key] = extend(a[key], b[key],context,newobjs,a,key,true); /*a[key].constructor = b[key].constructor; a[key].prototype = b[key].prototype;*/ } - else - { a[key] = b[key]; } - } - } - if(clean_context) {context=null;newobjs=null;} - if(!haveaparent) - { - aparent=null; - return a; - } - if(typeof a === 'object' && !(a instanceof Array) ) - { - /*a.constructor = b.constructor; - a.prototype = b.prototype*/; - } - return a; -} exports.extend=extend; - -function extenduptolevel(a, b, levels, context, newobjs, aparent, aname, haveaparent) -{ - if (a==b){ return a;} - if (!b){ return a;} - - var key, clean_context=false, return_sublevel=false; - if(!haveaparent){ aparent={'a':a}; aname='a'; } - if(!context){clean_context=true;context=[];newobjs=[];} - b_pos=context.indexOf(b); - if( b_pos==-1 ) {context.push(b);newobjs.push([aparent, aname]);} else { return newobjs[b_pos][0][ newobjs[b_pos][1] ]; } - - for (key in b) - { - if(b.hasOwnProperty(key)) - { - if(typeof a[key] === 'undefined') - { - if(typeof b[key] === 'object' && levels>0) - { - if( b[key] instanceof Array ) // http://javascript.crockford.com/remedial.html - { a[key] = extenduptolevel([], b[key],levels-1,context,newobjs,a,key,true); } - else if(b[key]===null) - { a[key] = null; } - else if( b[key] instanceof Date ) - { a[key]= new b[key].constructor();a[key].setTime(b[key].getTime()); } - else - { a[key] = extenduptolevel({}, b[key],levels-1,context,newobjs,a,key,true); } - } - else - { a[key] = b[key]; } - } - else if(typeof a[key] === 'object' && a[key] !== null && levels>0) - { a[key] = extenduptolevel(a[key], b[key],levels-1,context,newobjs,a,key,true); } - else - { a[key] = b[key]; } - } - } - if(clean_context) {context=null;newobjs=null;} - - if(!haveaparent) - { - aparent=null; - return a; - } - if(typeof a === 'object' && !(a instanceof Array) ) - { - /*a.constructor = b.constructor; - a.prototype = b.prototype;*/ - } - return a; -} exports.extenduptolevel=extenduptolevel; - -function clone(obj) -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - if (obj instanceof Array ) - { return extend([], obj); } - else if( obj instanceof Date ) - { - var t= new obj.constructor(); - t.setTime(obj.getTime()); - return t; - } - else - { return extend({}, obj); } - } - return obj; -} exports.clone=clone; - -function cloneextend(obj,exteddata) -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - return extend(clone(obj),exteddata); - } - return obj; -} exports.cloneextend=cloneextend; - - -function cloneuptolevel(obj,level) // clone only numlevels levels other levels leave references -{ - if (typeof obj === 'object') - { - if (obj ===null ) { return null; } - if (obj instanceof Array ) { return extenduptolevel([], obj,level); } - return extenduptolevel({}, obj,level); - } - return obj; -} exports.cloneuptolevel=cloneuptolevel; - -function foreach(object, block, context) -{ - if (object) - { - if (typeof object === "object" && object instanceof Array) - return object.forEach(object, block, context) - else //if (typeof object === "object") // or (object instanceof Function)... - { - if(object) - for (var key in object) - { - if(object.hasOwnProperty(key)) - { - if(block.call(context, object[key], key, object)===false)break; - } - } - } - } -} exports.foreach=foreach; - -/* - hasbugs and useless, yet interesting maybe developed later for dot pathed object transformation: - - { - 'foo.bar':'bluebar', - 'foo.color':'blue' - } - - transforemed to - - { - foo: - { - bar:'bluebar', - color:'blue' - } - } - - like: - - var config={}; - cloneextend.dotpath(config,{ - 'foo.bar':'bluebar', - 'foo.color':'blue' - }) - - // - function dotpath(data,dotkeys,preserve) - { - if(!preserve)preserve=false; - var create=!preserve; - if(create) if(!data) data={}; - var keys= dotkeys.split("."),value=data; - for (var i=0;i - * @license MIT +Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { + writeUInt32(this, value, offset, true, noAssert); +}; + + +/* + * We now move onto our friends in the signed number category. Unlike unsigned + * numbers, we're going to have to worry a bit more about how we put values into + * arrays. Since we are only worrying about signed 32-bit values, we're in + * slightly better shape. Unfortunately, we really can't do our favorite binary + * & in this system. It really seems to do the wrong thing. For example: * - * The MIT License (MIT) + * > -32 & 0xff + * 224 * - * Copyright (c) 2013 Viacheslav Lotsmanov + * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of + * this aren't treated as a signed number. Ultimately a bad thing. * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: + * What we're going to want to do is basically create the unsigned equivalent of + * our representation and pass that off to the wuint* functions. To do that + * we're going to do the following: * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * - if the value is positive + * we can pass it directly off to the equivalent wuint + * - if the value is negative + * we do the following computation: + * mb + val + 1, where + * mb is the maximum unsigned value in that byte size + * val is the Javascript negative integer + * + * + * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If + * you do out the computations: * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * 0xffff - 128 + 1 + * 0xffff - 127 + * 0xff80 + * + * You can then encode this value as the signed version. This is really rather + * hacky, but it should work and get the job done which is our goal here. */ -/** - * Extening object that entered in first argument. - * Returns extended object or false if have no target object or incorrect type. - * If you wish to clone object, simply use that: - * deepExtend({}, yourObj_1, [yourObj_N]) - first arg is new empty object +/* + * A series of checks to make sure we actually have a signed 32-bit number */ -var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { - if (arguments.length < 1 || typeof arguments[0] !== 'object') { - return false; - } +function verifsint(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - if (arguments.length < 2) return arguments[0]; + assert.ok(value <= max, 'value larger than maximum allowed value'); - var target = arguments[0]; + assert.ok(value >= min, 'value smaller than minimum allowed value'); - // convert arguments to array and cut off target object - var args = Array.prototype.slice.call(arguments, 1); + assert.ok(Math.floor(value) === value, 'value has a fractional component'); +} - var key, val, src, clone, tmpBuf; +function verifIEEE754(value, max, min) { + assert.ok(typeof (value) == 'number', + 'cannot write a non-number as a number'); - args.forEach(function (obj) { - if (typeof obj !== 'object') return; + assert.ok(value <= max, 'value larger than maximum allowed value'); - for (key in obj) { - if ( ! (key in obj)) continue; + assert.ok(value >= min, 'value smaller than minimum allowed value'); +} - src = target[key]; - val = obj[key]; +Buffer.prototype.writeInt8 = function(value, offset, noAssert) { + var buffer = this; - if (val === target) continue; + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); - if (typeof val !== 'object' || val === null) { - target[key] = val; - continue; - } else if (val instanceof Buffer) { - tmpBuf = new Buffer(val.length); - val.copy(tmpBuf); - target[key] = tmpBuf; - continue; - } else if (val instanceof Date) { - target[key] = new Date(val.getTime()); - continue; - } + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); - if (typeof src !== 'object' || src === null) { - clone = (Array.isArray(val)) ? [] : {}; - target[key] = deepExtend(clone, val); - continue; - } + assert.ok(offset < buffer.length, + 'Trying to write beyond buffer length'); - if (Array.isArray(val)) { - clone = (Array.isArray(src)) ? src : []; - } else { - clone = (!Array.isArray(src)) ? src : {}; - } + verifsint(value, 0x7f, -0x80); + } - target[key] = deepExtend(clone, val); + if (value >= 0) { + buffer.writeUInt8(value, offset, noAssert); + } else { + buffer.writeUInt8(0xff + value + 1, offset, noAssert); + } +}; + +function writeInt16(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 1 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fff, -0x8000); + } + + if (value >= 0) { + writeUInt16(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { + writeInt16(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { + writeInt16(this, value, offset, true, noAssert); +}; + +function writeInt32(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifsint(value, 0x7fffffff, -0x80000000); + } + + if (value >= 0) { + writeUInt32(buffer, value, offset, isBigEndian, noAssert); + } else { + writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); + } +} + +Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { + writeInt32(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { + writeInt32(this, value, offset, true, noAssert); +}; + +function writeFloat(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 3 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 23, 4); +} + +Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { + writeFloat(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { + writeFloat(this, value, offset, true, noAssert); +}; + +function writeDouble(buffer, value, offset, isBigEndian, noAssert) { + if (!noAssert) { + assert.ok(value !== undefined && value !== null, + 'missing value'); + + assert.ok(typeof (isBigEndian) === 'boolean', + 'missing or invalid endian'); + + assert.ok(offset !== undefined && offset !== null, + 'missing offset'); + + assert.ok(offset + 7 < buffer.length, + 'Trying to write beyond buffer length'); + + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); + } + + require('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, + 52, 8); +} + +Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { + writeDouble(this, value, offset, false, noAssert); +}; + +Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { + writeDouble(this, value, offset, true, noAssert); +}; + +},{"./buffer_ieee754":1,"assert":6,"base64-js":4}],"buffer-browserify":[function(require,module,exports){ +module.exports=require('q9TxCC'); +},{}],4:[function(require,module,exports){ +(function (exports) { + 'use strict'; + + var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + function b64ToByteArray(b64) { + var i, j, l, tmp, placeHolders, arr; + + if (b64.length % 4 > 0) { + throw 'Invalid string. Length must be a multiple of 4'; } - }); - return target; + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64.indexOf('='); + placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); + arr.push((tmp & 0xFF0000) >> 16); + arr.push((tmp & 0xFF00) >> 8); + arr.push(tmp & 0xFF); + } + + if (placeHolders === 2) { + tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); + arr.push(tmp & 0xFF); + } else if (placeHolders === 1) { + tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); + arr.push((tmp >> 8) & 0xFF); + arr.push(tmp & 0xFF); + } + + return arr; + } + + function uint8ToBase64(uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length; + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; + }; + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output += tripletToBase64(temp); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1]; + output += lookup[temp >> 2]; + output += lookup[(temp << 4) & 0x3F]; + output += '=='; + break; + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); + output += lookup[temp >> 10]; + output += lookup[(temp >> 4) & 0x3F]; + output += lookup[(temp << 2) & 0x3F]; + output += '='; + break; + } + + return output; + } + + module.exports.toByteArray = b64ToByteArray; + module.exports.fromByteArray = uint8ToBase64; +}()); + +},{}],5:[function(require,module,exports){ + + +// +// The shims in this file are not fully implemented shims for the ES5 +// features, but do work for the particular usecases there is in +// the other modules. +// + +var toString = Object.prototype.toString; +var hasOwnProperty = Object.prototype.hasOwnProperty; + +// Array.isArray is supported in IE9 +function isArray(xs) { + return toString.call(xs) === '[object Array]'; } +exports.isArray = typeof Array.isArray === 'function' ? Array.isArray : isArray; -}).call(this,require("buffer").Buffer) -},{"buffer":3}],37:[function(require,module,exports){ -/*! - * EventEmitter2 - * https://github.com/hij1nx/EventEmitter2 - * - * Copyright (c) 2013 hij1nx - * Licensed under the MIT license. - */ -;!function(undefined) { +// Array.prototype.indexOf is supported in IE9 +exports.indexOf = function indexOf(xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0; i < xs.length; i++) { + if (x === xs[i]) return i; + } + return -1; +}; - var isArray = Array.isArray ? Array.isArray : function _isArray(obj) { - return Object.prototype.toString.call(obj) === "[object Array]"; - }; - var defaultMaxListeners = 10; +// Array.prototype.filter is supported in IE9 +exports.filter = function filter(xs, fn) { + if (xs.filter) return xs.filter(fn); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (fn(xs[i], i, xs)) res.push(xs[i]); + } + return res; +}; - function init() { - this._events = {}; - if (this._conf) { - configure.call(this, this._conf); +// Array.prototype.forEach is supported in IE9 +exports.forEach = function forEach(xs, fn, self) { + if (xs.forEach) return xs.forEach(fn, self); + for (var i = 0; i < xs.length; i++) { + fn.call(self, xs[i], i, xs); + } +}; + +// Array.prototype.map is supported in IE9 +exports.map = function map(xs, fn) { + if (xs.map) return xs.map(fn); + var out = new Array(xs.length); + for (var i = 0; i < xs.length; i++) { + out[i] = fn(xs[i], i, xs); + } + return out; +}; + +// Array.prototype.reduce is supported in IE9 +exports.reduce = function reduce(array, callback, opt_initialValue) { + if (array.reduce) return array.reduce(callback, opt_initialValue); + var value, isValueSet = false; + + if (2 < arguments.length) { + value = opt_initialValue; + isValueSet = true; + } + for (var i = 0, l = array.length; l > i; ++i) { + if (array.hasOwnProperty(i)) { + if (isValueSet) { + value = callback(value, array[i], i, array); + } + else { + value = array[i]; + isValueSet = true; + } } } - function configure(conf) { - if (conf) { + return value; +}; - this._conf = conf; +// String.prototype.substr - negative index don't work in IE8 +if ('ab'.substr(-1) !== 'b') { + exports.substr = function (str, start, length) { + // did we get a negative start, calculate how much it is from the beginning of the string + if (start < 0) start = str.length + start; - conf.delimiter && (this.delimiter = conf.delimiter); - conf.maxListeners && (this._events.maxListeners = conf.maxListeners); - conf.wildcard && (this.wildcard = conf.wildcard); - conf.newListener && (this.newListener = conf.newListener); + // call the original function + return str.substr(start, length); + }; +} else { + exports.substr = function (str, start, length) { + return str.substr(start, length); + }; +} - if (this.wildcard) { - this.listenerTree = {}; - } +// String.prototype.trim is supported in IE9 +exports.trim = function (str) { + if (str.trim) return str.trim(); + return str.replace(/^\s+|\s+$/g, ''); +}; + +// Function.prototype.bind is supported in IE9 +exports.bind = function () { + var args = Array.prototype.slice.call(arguments); + var fn = args.shift(); + if (fn.bind) return fn.bind.apply(fn, args); + var self = args.shift(); + return function () { + fn.apply(self, args.concat([Array.prototype.slice.call(arguments)])); + }; +}; + +// Object.create is supported in IE9 +function create(prototype, properties) { + var object; + if (prototype === null) { + object = { '__proto__' : null }; + } + else { + if (typeof prototype !== 'object') { + throw new TypeError( + 'typeof prototype[' + (typeof prototype) + '] != \'object\'' + ); } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + object.__proto__ = prototype; + } + if (typeof properties !== 'undefined' && Object.defineProperties) { + Object.defineProperties(object, properties); } + return object; +} +exports.create = typeof Object.create === 'function' ? Object.create : create; - function EventEmitter(conf) { - this._events = {}; - this.newListener = false; - configure.call(this, conf); +// Object.keys and Object.getOwnPropertyNames is supported in IE9 however +// they do show a description and number property on Error objects +function notObject(object) { + return ((typeof object != "object" && typeof object != "function") || object === null); +} + +function keysShim(object) { + if (notObject(object)) { + throw new TypeError("Object.keys called on a non-object"); } - // - // Attention, function return type now is array, always ! - // It has zero elements if no any matches found and one or more - // elements (leafs) if there are matches - // - function searchListenerTree(handlers, type, tree, i) { - if (!tree) { - return []; + var result = []; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result.push(name); } - var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached, - typeLength = type.length, currentType = type[i], nextType = type[i+1]; - if (i === typeLength && tree._listeners) { - // - // If at the end of the event(s) list and the tree has listeners - // invoke those listeners. - // - if (typeof tree._listeners === 'function') { - handlers && handlers.push(tree._listeners); - return [tree]; - } else { - for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) { - handlers && handlers.push(tree._listeners[leaf]); - } - return [tree]; - } + } + return result; +} + +// getOwnPropertyNames is almost the same as Object.keys one key feature +// is that it returns hidden properties, since that can't be implemented, +// this feature gets reduced so it just shows the length property on arrays +function propertyShim(object) { + if (notObject(object)) { + throw new TypeError("Object.getOwnPropertyNames called on a non-object"); + } + + var result = keysShim(object); + if (exports.isArray(object) && exports.indexOf(object, 'length') === -1) { + result.push('length'); + } + return result; +} + +var keys = typeof Object.keys === 'function' ? Object.keys : keysShim; +var getOwnPropertyNames = typeof Object.getOwnPropertyNames === 'function' ? + Object.getOwnPropertyNames : propertyShim; + +if (new Error().hasOwnProperty('description')) { + var ERROR_PROPERTY_FILTER = function (obj, array) { + if (toString.call(obj) === '[object Error]') { + array = exports.filter(array, function (name) { + return name !== 'description' && name !== 'number' && name !== 'message'; + }); } + return array; + }; - if ((currentType === '*' || currentType === '**') || tree[currentType]) { - // - // If the event emitted is '*' at this part - // or there is a concrete match at this patch - // - if (currentType === '*') { - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1)); - } - } - return listeners; - } else if(currentType === '**') { - endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*')); - if(endReached && tree._listeners) { - // The next element has a _listeners, add it to the handlers. - listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength)); - } + exports.keys = function (object) { + return ERROR_PROPERTY_FILTER(object, keys(object)); + }; + exports.getOwnPropertyNames = function (object) { + return ERROR_PROPERTY_FILTER(object, getOwnPropertyNames(object)); + }; +} else { + exports.keys = keys; + exports.getOwnPropertyNames = getOwnPropertyNames; +} - for (branch in tree) { - if (branch !== '_listeners' && tree.hasOwnProperty(branch)) { - if(branch === '*' || branch === '**') { - if(tree[branch]._listeners && !endReached) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength)); - } - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } else if(branch === nextType) { - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2)); - } else { - // No match on this one, shift into the tree but not in the type array. - listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i)); - } - } - } - return listeners; +// Object.getOwnPropertyDescriptor - supported in IE8 but only on dom elements +function valueObject(value, key) { + return { value: value[key] }; +} + +if (typeof Object.getOwnPropertyDescriptor === 'function') { + try { + Object.getOwnPropertyDescriptor({'a': 1}, 'a'); + exports.getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + } catch (e) { + // IE8 dom element issue - use a try catch and default to valueObject + exports.getOwnPropertyDescriptor = function (value, key) { + try { + return Object.getOwnPropertyDescriptor(value, key); + } catch (e) { + return valueObject(value, key); } + }; + } +} else { + exports.getOwnPropertyDescriptor = valueObject; +} - listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1)); +},{}],6:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// UTILITY +var util = require('util'); +var shims = require('_shims'); +var pSlice = Array.prototype.slice; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + this.message = options.message || getMessage(this); +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; } - xTree = tree['*']; - if (xTree) { - // - // If the listener tree will allow any match for this part, - // then recursively explore all branches of the tree - // - searchListenerTree(handlers, type, xTree, i+1); + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = shims.keys(a), + kb = shims.keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} - xxTree = tree['**']; - if(xxTree) { - if(i < typeLength) { - if(xxTree._listeners) { - // If we have a listener on a '**', it will catch all, so add its handler. - searchListenerTree(handlers, type, xxTree, typeLength); - } +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); - // Build arrays of matching next branches and others. - for(branch in xxTree) { - if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) { - if(branch === nextType) { - // We know the next element will match, so jump twice. - searchListenerTree(handlers, type, xxTree[branch], i+2); - } else if(branch === currentType) { - // Current node matches, move into the tree. - searchListenerTree(handlers, type, xxTree[branch], i+1); - } else { - isolatedBranch = {}; - isolatedBranch[branch] = xxTree[branch]; - searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1); - } - } +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; +},{"_shims":5,"util":7}],7:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var shims = require('_shims'); + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; } - } else if(xxTree._listeners) { - // We have reached the end and still on a '**' - searchListenerTree(handlers, type, xxTree, typeLength); - } else if(xxTree['*'] && xxTree['*']._listeners) { - searchListenerTree(handlers, type, xxTree['*'], typeLength); - } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); } + } + return str; +}; - return listeners; +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; - function growListenerTree(type, listener) { - type = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; - // - // Looks for two consecutive '**', if so, don't add the event at all. - // - for(var i = 0, len = type.length; i+1 < len; i++) { - if(type[i] === '**' && type[i+1] === '**') { - return; - } - } +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - var tree = this.listenerTree; - var name = type.shift(); - while (name) { +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; - if (!tree[name]) { - tree[name] = {}; - } + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} - tree = tree[name]; - if (type.length === 0) { +function stylizeNoColor(str, styleType) { + return str; +} - if (!tree._listeners) { - tree._listeners = listener; - } - else if(typeof tree._listeners === 'function') { - tree._listeners = [tree._listeners, listener]; - } - else if (isArray(tree._listeners)) { - tree._listeners.push(listener); +function arrayToHash(array) { + var hash = {}; - if (!tree._listeners.warned) { + shims.forEach(array, function(val, idx) { + hash[val] = true; + }); - var m = defaultMaxListeners; + return hash; +} - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } - if (m > 0 && tree._listeners.length > m) { +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } - tree._listeners.warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - tree._listeners.length); - console.trace(); - } - } - } - return true; - } - name = type.shift(); + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = shims.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = shims.getOwnPropertyNames(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); } - return true; } - // By default EventEmitters will print a warning if more than - // 10 listeners are added to it. This is a useful default which - // helps finding memory leaks. - // - // Obviously not all Emitters should be limited to 10. This function allows - // that to be increased. Set to zero for unlimited. + var base = '', array = false, braces = ['{', '}']; - EventEmitter.prototype.delimiter = '.'; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - EventEmitter.prototype.setMaxListeners = function(n) { - this._events || init.call(this); - this._events.maxListeners = n; - if (!this._conf) this._conf = {}; - this._conf.maxListeners = n; - }; + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } - EventEmitter.prototype.event = ''; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } - EventEmitter.prototype.once = function(event, fn) { - this.many(event, 1, fn); - return this; - }; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } - EventEmitter.prototype.many = function(event, ttl, fn) { - var self = this; + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } - if (typeof fn !== 'function') { - throw new Error('many only accepts instances of Function'); - } + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } - function listener() { - if (--ttl === 0) { - self.off(event, listener); - } - fn.apply(this, arguments); + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); } + } - listener._origin = fn; + ctx.seen.push(value); - this.on(event, listener); + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } - return self; - }; + ctx.seen.pop(); - EventEmitter.prototype.emit = function() { + return reduceToSingleString(output, base, braces); +} - this._events || init.call(this); - var type = arguments[0]; +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} - if (type === 'newListener' && !this.newListener) { - if (!this._events.newListener) { return false; } - } - // Loop through the *_all* functions and invoke them. - if (this._all) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - for (i = 0, l = this._all.length; i < l; i++) { - this.event = type; - this._all[i].apply(this, args); - } - } +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._all && - !this._events.error && - !(this.wildcard && this.listenerTree.error)) { +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } + shims.forEach(keys, function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); } + }); + return output; +} - var handler; - if(this.wildcard) { - handler = []; - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - searchListenerTree.call(this, handler, ns, this.listenerTree, 0); +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = shims.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); } - else { - handler = this._events[type]; + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); } + } - if (typeof handler === 'function') { - this.event = type; - if (arguments.length === 1) { - handler.call(this); + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (shims.indexOf(ctx.seen, desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); } - else if (arguments.length > 1) - switch (arguments.length) { - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - handler.apply(this, args); + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); } - return true; - } - else if (handler) { - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - this.event = type; - listeners[i].apply(this, args); } - return (listeners.length > 0) || !!this._all; + } else { + str = ctx.stylize('[Circular]', 'special'); } - else { - return !!this._all; + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } + } - }; + return name + ': ' + str; +} - EventEmitter.prototype.on = function(type, listener) { - if (typeof type === 'function') { - this.onAny(type); - return this; - } +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = shims.reduce(output, function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); - if (typeof listener !== 'function') { - throw new Error('on only accepts instances of Function'); - } - this._events || init.call(this); + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} - if(this.wildcard) { - growListenerTree.call(this, type, listener); - return this; - } - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } - else if(typeof this._events[type] === 'function') { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - else if (isArray(this._events[type])) { - // If we've already got an array, just append. - this._events[type].push(listener); +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return shims.isArray(ar); +} +exports.isArray = isArray; - // Check for listener leak - if (!this._events[type].warned) { +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; - var m = defaultMaxListeners; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - if (typeof this._events.maxListeners !== 'undefined') { - m = this._events.maxListeners; - } +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - if (m > 0 && this._events[type].length > m) { +function isObject(arg) { + return typeof arg === 'object' && arg; +} +exports.isObject = isObject; - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - } - return this; - }; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - EventEmitter.prototype.onAny = function(fn) { +function isError(e) { + return isObject(e) && objectToString(e) === '[object Error]'; +} +exports.isError = isError; - if (typeof fn !== 'function') { - throw new Error('onAny only accepts instances of Function'); - } +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - if(!this._all) { - this._all = []; - } +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - // Add the function to the event listener collection. - this._all.push(fn); - return this; - }; +function isBuffer(arg) { + return arg instanceof Buffer; +} +exports.isBuffer = isBuffer; - EventEmitter.prototype.addListener = EventEmitter.prototype.on; +function objectToString(o) { + return Object.prototype.toString.call(o); +} - EventEmitter.prototype.off = function(type, listener) { - if (typeof listener !== 'function') { - throw new Error('removeListener only takes instances of Function'); - } - var handlers,leafs=[]; +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); - } - else { - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events[type]) return this; - handlers = this._events[type]; - leafs.push({_listeners:handlers}); - } - for (var iLeaf=0; iLeaf 0) { - fns = this._all; - for(i = 0, l = fns.length; i < l; i++) { - if(fn === fns[i]) { - fns.splice(i, 1); - return this; - } - } - } else { - this._all = []; - } - return this; - }; + var keys = shims.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; - EventEmitter.prototype.removeListener = EventEmitter.prototype.off; +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} - EventEmitter.prototype.removeAllListeners = function(type) { - if (arguments.length === 0) { - !this._events || init.call(this); - return this; - } +},{"_shims":5}]},{},[]) +;;module.exports=require("buffer-browserify") - if(this.wildcard) { - var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice(); - var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0); +},{}],50:[function(require,module,exports){ +// shim for using process in browser - for (var iLeaf=0; iLeaf 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); - if (!this._events[type]) this._events[type] = []; - if (!isArray(this._events[type])) { - this._events[type] = [this._events[type]]; + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; } - return this._events[type]; - }; - EventEmitter.prototype.listenersAny = function() { + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); - if(this._all) { - return this._all; - } - else { - return []; - } +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; - }; +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(function() { - return EventEmitter; - }); - } else if (typeof exports === 'object') { - // CommonJS - exports.EventEmitter2 = EventEmitter; - } - else { - // Browser global. - window.EventEmitter2 = EventEmitter; - } -}(); +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; -},{}],38:[function(require,module,exports){ +},{}],51:[function(require,module,exports){ var jQuery = require('jquery'); /*! @@ -27327,7 +30064,7 @@ $.extend( $.ui, { })( jQuery ); -},{"jquery":40}],39:[function(require,module,exports){ +},{"jquery":53}],52:[function(require,module,exports){ var jQuery = require('jquery'); require('./core'); @@ -29370,9 +32107,9 @@ $.datepicker.version = "1.10.4"; })(jQuery); -},{"./core":38,"jquery":40}],40:[function(require,module,exports){ +},{"./core":51,"jquery":53}],53:[function(require,module,exports){ /*! - * jQuery JavaScript Library v2.1.3 + * jQuery JavaScript Library v2.1.1 * http://jquery.com/ * * Includes Sizzle.js @@ -29382,19 +32119,19 @@ $.datepicker.version = "1.10.4"; * Released under the MIT license * http://jquery.org/license * - * Date: 2014-12-18T15:11Z + * Date: 2014-05-01T17:11Z */ (function( global, factory ) { if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper `window` - // is present, execute the factory and get jQuery. - // For environments that do not have a `window` with a `document` - // (such as Node.js), expose a factory as module.exports. - // This accentuates the need for the creation of a real `window`. + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info. + // See ticket #14549 for more info module.exports = global.document ? factory( global, true ) : function( w ) { @@ -29410,10 +32147,10 @@ $.datepicker.version = "1.10.4"; // Pass this if window is not defined yet }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { -// Support: Firefox 18+ -// Can't be in strict mode, several libs including ASP.NET trace +// Can't do this because several apps including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ // var arr = []; @@ -29440,7 +32177,7 @@ var // Use the correct document accordingly with window argument (sandbox) document = window.document, - version = "2.1.3", + version = "2.1.1", // Define a local copy of jQuery jQuery = function( selector, context ) { @@ -29558,7 +32295,7 @@ jQuery.extend = jQuery.fn.extend = function() { if ( typeof target === "boolean" ) { deep = target; - // Skip the boolean and the target + // skip the boolean and the target target = arguments[ i ] || {}; i++; } @@ -29568,7 +32305,7 @@ jQuery.extend = jQuery.fn.extend = function() { target = {}; } - // Extend jQuery itself if only one argument is passed + // extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; @@ -29625,6 +32362,9 @@ jQuery.extend({ noop: function() {}, + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). isFunction: function( obj ) { return jQuery.type(obj) === "function"; }, @@ -29639,8 +32379,7 @@ jQuery.extend({ // parseFloat NaNs numeric-cast false positives (null|true|false|"") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN - // adding 1 corrects loss of precision from parseFloat (#15100) - return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; }, isPlainObject: function( obj ) { @@ -29674,7 +32413,7 @@ jQuery.extend({ if ( obj == null ) { return obj + ""; } - // Support: Android<4.0, iOS<6 (functionish RegExp) + // Support: Android < 4.0, iOS < 6 (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ] || "object" : typeof obj; @@ -29704,7 +32443,6 @@ jQuery.extend({ }, // Convert dashed to camelCase; used by the css and data modules - // Support: IE9-11+ // Microsoft forgot to hump their vendor prefix (#9572) camelCase: function( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); @@ -29920,14 +32658,14 @@ function isArraylike( obj ) { } var Sizzle = /*! - * Sizzle CSS Selector Engine v2.2.0-pre + * Sizzle CSS Selector Engine v1.10.19 * http://sizzlejs.com/ * - * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Copyright 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2014-12-16 + * Date: 2014-04-18 */ (function( window ) { @@ -29954,7 +32692,7 @@ var i, contains, // Instance-specific data - expando = "sizzle" + 1 * new Date(), + expando = "sizzle" + -(new Date()), preferredDoc = window.document, dirruns = 0, done = 0, @@ -29969,6 +32707,7 @@ var i, }, // General-purpose constants + strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, // Instance methods @@ -29978,13 +32717,12 @@ var i, push_native = arr.push, push = arr.push, slice = arr.slice, - // Use a stripped-down indexOf as it's faster than native - // http://jsperf.com/thor-indexof-vs-for/5 - indexOf = function( list, elem ) { + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { var i = 0, - len = list.length; + len = this.length; for ( ; i < len; i++ ) { - if ( list[i] === elem ) { + if ( this[i] === elem ) { return i; } } @@ -30024,7 +32762,6 @@ var i, ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), @@ -30076,14 +32813,6 @@ var i, String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }, - - // Used for iframes - // See setDocument() - // Removing the function wrapper causes a "Permission Denied" - // error in IE - unloadHandler = function() { - setDocument(); }; // Optimize for push.apply( _, NodeList ) @@ -30126,18 +32855,19 @@ function Sizzle( selector, context, results, seed ) { context = context || document; results = results || []; - nodeType = context.nodeType; - - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + if ( !selector || typeof selector !== "string" ) { return results; } - if ( !seed && documentIsHTML ) { + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { - // Try to shortcut find operations when possible (e.g., not under DocumentFragment) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { @@ -30169,7 +32899,7 @@ function Sizzle( selector, context, results, seed ) { return results; // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName ) { + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } @@ -30179,7 +32909,7 @@ function Sizzle( selector, context, results, seed ) { if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { nid = old = expando; newContext = context; - newSelector = nodeType !== 1 && selector; + newSelector = nodeType === 9 && selector; // qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root @@ -30366,7 +33096,7 @@ function createPositionalPseudo( fn ) { * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { - return context && typeof context.getElementsByTagName !== "undefined" && context; + return context && typeof context.getElementsByTagName !== strundefined && context; } // Expose support vars for convenience @@ -30390,8 +33120,9 @@ isXML = Sizzle.isXML = function( elem ) { * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, parent, - doc = node ? node.ownerDocument || node : preferredDoc; + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; // If no document and documentElement is available, return if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { @@ -30401,7 +33132,9 @@ setDocument = Sizzle.setDocument = function( node ) { // Set our document document = doc; docElem = doc.documentElement; - parent = doc.defaultView; + + // Support tests + documentIsHTML = !isXML( doc ); // Support: IE>8 // If iframe document is assigned to "document" variable and if iframe has been reloaded, @@ -30410,22 +33143,21 @@ setDocument = Sizzle.setDocument = function( node ) { if ( parent && parent !== parent.top ) { // IE11 does not have attachEvent, so all must suffer if ( parent.addEventListener ) { - parent.addEventListener( "unload", unloadHandler, false ); + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", unloadHandler ); + parent.attachEvent( "onunload", function() { + setDocument(); + }); } } - /* Support tests - ---------------------------------------------------------------------- */ - documentIsHTML = !isXML( doc ); - /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties - // (excepting IE8 booleans) + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) support.attributes = assert(function( div ) { div.className = "i"; return !div.getAttribute("className"); @@ -30440,8 +33172,17 @@ setDocument = Sizzle.setDocument = function( node ) { return !div.getElementsByTagName("*").length; }); - // Support: IE<9 - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { + div.innerHTML = "
"; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); // Support: IE<10 // Check if getElementById returns elements by name @@ -30455,7 +33196,7 @@ setDocument = Sizzle.setDocument = function( node ) { // ID find and filter if ( support.getById ) { Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { var m = context.getElementById( id ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document #6963 @@ -30476,7 +33217,7 @@ setDocument = Sizzle.setDocument = function( node ) { Expr.filter["ID"] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); return node && node.value === attrId; }; }; @@ -30485,20 +33226,14 @@ setDocument = Sizzle.setDocument = function( node ) { // Tag Expr.find["TAG"] = support.getElementsByTagName ? function( tag, context ) { - if ( typeof context.getElementsByTagName !== "undefined" ) { + if ( typeof context.getElementsByTagName !== strundefined ) { return context.getElementsByTagName( tag ); - - // DocumentFragment nodes don't have gEBTN - } else if ( support.qsa ) { - return context.querySelectorAll( tag ); } } : - function( tag, context ) { var elem, tmp = [], i = 0, - // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments @@ -30516,7 +33251,7 @@ setDocument = Sizzle.setDocument = function( node ) { // Class Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( documentIsHTML ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { return context.getElementsByClassName( className ); } }; @@ -30545,15 +33280,13 @@ setDocument = Sizzle.setDocument = function( node ) { // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 - docElem.appendChild( div ).innerHTML = "" + - ""; + div.innerHTML = ""; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowcapture^='']").length ) { + if ( div.querySelectorAll("[msallowclip^='']").length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } @@ -30563,24 +33296,12 @@ setDocument = Sizzle.setDocument = function( node ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } - // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ - if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { - rbuggyQSA.push("~="); - } - // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !div.querySelectorAll(":checked").length ) { rbuggyQSA.push(":checked"); } - - // Support: Safari 8+, iOS 8+ - // https://bugs.webkit.org/show_bug.cgi?id=136851 - // In-page `selector#id sibing-combinator selector` fails - if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { - rbuggyQSA.push(".#.+[+~]"); - } }); assert(function( div ) { @@ -30697,7 +33418,7 @@ setDocument = Sizzle.setDocument = function( node ) { // Maintain original order return sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 0; } @@ -30724,7 +33445,7 @@ setDocument = Sizzle.setDocument = function( node ) { aup ? -1 : bup ? 1 : sortInput ? - ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check @@ -30787,7 +33508,7 @@ Sizzle.matchesSelector = function( elem, expr ) { elem.document && elem.document.nodeType !== 11 ) { return ret; } - } catch (e) {} + } catch(e) {} } return Sizzle( expr, document, null, [ elem ] ).length > 0; @@ -31006,7 +33727,7 @@ Expr = Sizzle.selectors = { return pattern || (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); }); }, @@ -31028,7 +33749,7 @@ Expr = Sizzle.selectors = { operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; }; @@ -31148,7 +33869,7 @@ Expr = Sizzle.selectors = { matched = fn( seed, argument ), i = matched.length; while ( i-- ) { - idx = indexOf( seed, matched[i] ); + idx = indexOf.call( seed, matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] ); } }) : @@ -31187,8 +33908,6 @@ Expr = Sizzle.selectors = { function( elem, context, xml ) { input[0] = elem; matcher( input, null, xml, results ); - // Don't keep the element (issue #299) - input[0] = null; return !results.pop(); }; }), @@ -31200,7 +33919,6 @@ Expr = Sizzle.selectors = { }), "contains": markFunction(function( text ) { - text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; }; @@ -31622,7 +34340,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS i = matcherOut.length; while ( i-- ) { if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { seed[temp] = !(results[temp] = elem); } @@ -31657,16 +34375,13 @@ function matcherFromTokens( tokens ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { - return indexOf( checkContext, elem ) > -1; + return indexOf.call( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { - var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( (checkContext = context).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); - // Avoid hanging onto element (issue #299) - checkContext = null; - return ret; } ]; for ( ; i < len; i++ ) { @@ -31916,7 +34631,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { // Sort stability support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; -// Support: Chrome 14-35+ +// Support: Chrome<14 // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; @@ -32125,7 +34840,7 @@ var rootjQuery, if ( match[1] ) { context = context instanceof jQuery ? context[0] : context; - // Option to run scripts is true for back-compat + // scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[1], @@ -32153,8 +34868,8 @@ var rootjQuery, } else { elem = document.getElementById( match[2] ); - // Support: Blackberry 4.6 - // gEBID returns nodes no longer in the document (#6963) + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 if ( elem && elem.parentNode ) { // Inject the element directly into the jQuery object this.length = 1; @@ -32207,7 +34922,7 @@ rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // Methods guaranteed to produce a unique set when starting from a unique set + // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, @@ -32287,7 +35002,8 @@ jQuery.fn.extend({ return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); }, - // Determine the position of an element within the set + // Determine the position of an element within + // the matched set of elements index: function( elem ) { // No argument, return index in parent @@ -32295,7 +35011,7 @@ jQuery.fn.extend({ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } - // Index in selector + // index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } @@ -32711,7 +35427,7 @@ jQuery.extend({ progressValues, progressContexts, resolveContexts; - // Add listeners to Deferred subordinates; treat others as resolved + // add listeners to Deferred subordinates; treat others as resolved if ( length > 1 ) { progressValues = new Array( length ); progressContexts = new Array( length ); @@ -32728,7 +35444,7 @@ jQuery.extend({ } } - // If we're not waiting on anything, resolve the master + // if we're not waiting on anything, resolve the master if ( !remaining ) { deferred.resolveWith( resolveContexts, resolveValues ); } @@ -32807,7 +35523,7 @@ jQuery.ready.promise = function( obj ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. - // We once tried to use readyState "interactive" here, but it caused issues like the one + // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready @@ -32901,7 +35617,7 @@ jQuery.acceptData = function( owner ) { function Data() { - // Support: Android<4, + // Support: Android < 4, // Old WebKit does not have Object.preventExtensions/freeze method, // return new empty object instead with no [[set]] accessor Object.defineProperty( this.cache = {}, 0, { @@ -32910,7 +35626,7 @@ function Data() { } }); - this.expando = jQuery.expando + Data.uid++; + this.expando = jQuery.expando + Math.random(); } Data.uid = 1; @@ -32938,7 +35654,7 @@ Data.prototype = { descriptor[ this.expando ] = { value: unlock }; Object.defineProperties( owner, descriptor ); - // Support: Android<4 + // Support: Android < 4 // Fallback to a less secure definition } catch ( e ) { descriptor[ this.expando ] = unlock; @@ -33078,16 +35794,17 @@ var data_user = new Data(); -// Implementation Summary -// -// 1. Enforce API surface and semantic compatibility with 1.9.x branch -// 2. Improve the module's maintainability by reducing the storage -// paths to a single mechanism. -// 3. Use the same single mechanism to support "private" and "user" data. -// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) -// 5. Avoid exposing implementation details on user objects (eg. expando properties) -// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 - +/* + Implementation Summary + + 1. Enforce API surface and semantic compatibility with 1.9.x branch + 2. Improve the module's maintainability by reducing the storage + paths to a single mechanism. + 3. Use the same single mechanism to support "private" and "user" data. + 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) + 5. Avoid exposing implementation details on user objects (eg. expando properties) + 6. Provide a clear path for implementation upgrade to WeakMap in 2014 +*/ var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /([A-Z])/g; @@ -33292,7 +36009,7 @@ jQuery.extend({ queue.unshift( "inprogress" ); } - // Clear up the last queue stop function + // clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } @@ -33302,7 +36019,7 @@ jQuery.extend({ } }, - // Not public - generate a queueHooks object, or return the current one + // not intended for public consumption - generates a queueHooks object, or returns the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return data_priv.get( elem, key ) || data_priv.access( elem, key, { @@ -33332,7 +36049,7 @@ jQuery.fn.extend({ this.each(function() { var queue = jQuery.queue( this, type, data ); - // Ensure a hooks for this queue + // ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[0] !== "inprogress" ) { @@ -33399,22 +36116,21 @@ var rcheckableType = (/^(?:checkbox|radio)$/i); div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); - // Support: Safari<=5.1 - // Check state lost if the name is set (#11217) + // #11217 - WebKit loses check when the name is after the checked attribute // Support: Windows Web Apps (WWA) - // `name` and `type` must use .setAttribute for WWA (#14901) + // `name` and `type` need .setAttribute for WWA input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); - // Support: Safari<=5.1, Android<4.2 - // Older WebKit doesn't clone checked state correctly in fragments + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - // Support: IE<=11+ // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE9-IE11+ div.innerHTML = ""; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; })(); @@ -33792,8 +36508,8 @@ jQuery.event = { j = 0; while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - // Triggered event must either 1) have no namespace, or 2) have namespace(s) - // a subset or equal to those in the bound event (both can have no namespace). + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { event.handleObj = handleObj; @@ -33943,7 +36659,7 @@ jQuery.event = { event.target = document; } - // Support: Safari 6.0+, Chrome<28 + // Support: Safari 6.0+, Chrome < 28 // Target should not be a text node (#504, #13143) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; @@ -34048,7 +36764,7 @@ jQuery.Event = function( src, props ) { // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && - // Support: Android<4.0 + // Support: Android < 4.0 src.returnValue === false ? returnTrue : returnFalse; @@ -34138,8 +36854,8 @@ jQuery.each({ }; }); -// Support: Firefox, Chrome, Safari // Create "bubbling" focus and blur events +// Support: Firefox, Chrome, Safari if ( !support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { @@ -34292,7 +37008,7 @@ var // We have to close these tags to support XHTML (#13200) wrapMap = { - // Support: IE9 + // Support: IE 9 option: [ 1, "" ], thead: [ 1, "", "
" ], @@ -34303,7 +37019,7 @@ var _default: [ 0, "", "" ] }; -// Support: IE9 +// Support: IE 9 wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; @@ -34393,7 +37109,7 @@ function getAll( context, tag ) { ret; } -// Fix IE bugs, see support tests +// Support: IE >= 9 function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); @@ -34413,7 +37129,8 @@ jQuery.extend({ clone = elem.cloneNode( true ), inPage = jQuery.contains( elem.ownerDocument, elem ); - // Fix IE cloning issues + // Support: IE >= 9 + // Fix Cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { @@ -34464,8 +37181,8 @@ jQuery.extend({ // Add nodes directly if ( jQuery.type( elem ) === "object" ) { - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node @@ -34487,14 +37204,15 @@ jQuery.extend({ tmp = tmp.lastChild; } - // Support: QtWebKit, PhantomJS - // push.apply(_, arraylike) throws on ancient WebKit + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; - // Ensure the created nodes are orphaned (#12392) + // Fixes #12346 + // Support: Webkit, IE tmp.textContent = ""; } } @@ -34856,7 +37574,7 @@ function actualDisplay( name, doc ) { // getDefaultComputedStyle might be reliably used only on attached element display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - // Use of this method is a temporary fix (more like optimization) until something better comes along, + // Use of this method is a temporary fix (more like optmization) until something better comes along, // since it was removed from specification and supported only in FF style.display : jQuery.css( elem[ 0 ], "display" ); @@ -34906,14 +37624,7 @@ var rmargin = (/^margin/); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { - // Support: IE<=11+, Firefox<=30+ (#15098, #14150) - // IE throws on elements created in popups - // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" - if ( elem.ownerDocument.defaultView.opener ) { - return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); - } - - return window.getComputedStyle( elem, null ); + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); }; @@ -34925,7 +37636,7 @@ function curCSS( elem, name, computed ) { computed = computed || getStyles( elem ); // Support: IE9 - // getPropertyValue is only needed for .css('filter') (#12537) + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; } @@ -34971,13 +37682,15 @@ function addGetHookIf( conditionFn, hookFn ) { return { get: function() { if ( conditionFn() ) { - // Hook not needed (or it's not possible to use it due - // to missing dependency), remove it. + // Hook not needed (or it's not possible to use it due to missing dependency), + // remove it. + // Since there are no other hooks for marginRight, remove the whole object. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. + return (this.get = hookFn).apply( this, arguments ); } }; @@ -34994,8 +37707,6 @@ function addGetHookIf( conditionFn, hookFn ) { return; } - // Support: IE9-11+ - // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; @@ -35028,7 +37739,6 @@ function addGetHookIf( conditionFn, hookFn ) { if ( window.getComputedStyle ) { jQuery.extend( support, { pixelPosition: function() { - // This test is executed only once but we still do memoizing // since we can use the boxSizingReliable pre-computing. // No need to check if the test was already performed, though. @@ -35042,7 +37752,6 @@ function addGetHookIf( conditionFn, hookFn ) { return boxSizingReliableVal; }, reliableMarginRight: function() { - // Support: Android 2.3 // Check if div with explicit width and no margin-right incorrectly // gets computed margin-right based on width of container. (#3333) @@ -35064,7 +37773,6 @@ function addGetHookIf( conditionFn, hookFn ) { ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); docElem.removeChild( container ); - div.removeChild( marginDiv ); return ret; } @@ -35096,8 +37804,8 @@ jQuery.swap = function( elem, options, callback, args ) { var - // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption" - // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), @@ -35110,15 +37818,15 @@ var cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; -// Return a css property mapped to a potentially vendor prefixed property +// return a css property mapped to a potentially vendor prefixed property function vendorPropName( style, name ) { - // Shortcut for names that are not vendor prefixed + // shortcut for names that are not vendor prefixed if ( name in style ) { return name; } - // Check for vendor prefixed names + // check for vendor prefixed names var capName = name[0].toUpperCase() + name.slice(1), origName = name, i = cssPrefixes.length; @@ -35151,7 +37859,7 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { val = 0; for ( ; i < 4; i += 2 ) { - // Both box models exclude margin, so add it if we want it + // both box models exclude margin, so add it if we want it if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } @@ -35162,15 +37870,15 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } - // At this point, extra isn't border nor margin, so remove border + // at this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { - // At this point, extra isn't content, so add padding + // at this point, extra isn't content, so add padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - // At this point, extra isn't content nor padding, so add border + // at this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } @@ -35188,7 +37896,7 @@ function getWidthOrHeight( elem, name, extra ) { styles = getStyles( elem ), isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - // Some non-html elements return undefined for offsetWidth, so check for null/undefined + // some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 if ( val <= 0 || val == null ) { @@ -35203,7 +37911,7 @@ function getWidthOrHeight( elem, name, extra ) { return val; } - // Check for style in case a browser which returns unreliable values + // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); @@ -35212,7 +37920,7 @@ function getWidthOrHeight( elem, name, extra ) { val = parseFloat( val ) || 0; } - // Use the active box-sizing model to add/subtract irrelevant styles + // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, @@ -35276,14 +37984,12 @@ function showHide( elements, show ) { } jQuery.extend({ - // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { - // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; @@ -35311,12 +38017,12 @@ jQuery.extend({ // Add in properties whose names you wish to fix before // setting or getting the value cssProps: { + // normalize float css property "float": "cssFloat" }, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { - // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; @@ -35329,32 +38035,33 @@ jQuery.extend({ name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); - // Gets hook for the prefixed version, then unprefixed version + // gets hook for the prefixed version + // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; - // Convert "+=" or "-=" to relative numbers (#7345) + // convert relative number strings (+= or -=) to relative numbers. #7345 if ( type === "string" && (ret = rrelNum.exec( value )) ) { value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); // Fixes bug #9237 type = "number"; } - // Make sure that null and NaN values aren't set (#7116) + // Make sure that null and NaN values aren't set. See: #7116 if ( value == null || value !== value ) { return; } - // If a number, add 'px' to the (except for certain CSS properties) + // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } - // Support: IE9-11+ - // background-* props affect original clone's values + // Fixes #8908, it can be done more correctly by specifying setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } @@ -35382,7 +38089,8 @@ jQuery.extend({ // Make sure that we're working with the right name name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); - // Try prefixed name followed by the unprefixed name + // gets hook for the prefixed version + // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there @@ -35395,12 +38103,12 @@ jQuery.extend({ val = curCSS( elem, name, styles ); } - // Convert "normal" to computed value + //convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } - // Make numeric if forced or a qualifier was provided and val looks numeric + // Return, converting to number if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; @@ -35413,9 +38121,8 @@ jQuery.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { - - // Certain elements can have dimension info if we invisibly show them - // but it must have a current display style that would benefit + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? jQuery.swap( elem, cssShow, function() { return getWidthOrHeight( elem, name, extra ); @@ -35443,6 +38150,8 @@ jQuery.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, function( elem, computed ) { if ( computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block return jQuery.swap( elem, { "display": "inline-block" }, curCSS, [ elem, "marginRight" ] ); } @@ -35460,7 +38169,7 @@ jQuery.each({ var i = 0, expanded = {}, - // Assumes a single number if not a string + // assumes a single number if not a string parts = typeof value === "string" ? value.split(" ") : [ value ]; for ( ; i < 4; i++ ) { @@ -35583,18 +38292,17 @@ Tween.propHooks = { return tween.elem[ tween.prop ]; } - // Passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails. - // Simple values such as "10px" are parsed to Float; - // complex values such as "rotate(1rad)" are returned as-is. + // passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { - // Use step hook for back compat. - // Use cssHook if its there. - // Use .style if available and use plain properties where available. + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { @@ -35608,6 +38316,7 @@ Tween.propHooks = { // Support: IE9 // Panic based approach to setting things on disconnected nodes + Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { @@ -35663,16 +38372,16 @@ var start = +target || 1; do { - // If previous iteration zeroed out, double until we get *something*. - // Use string for doubling so we don't accidentally see scale as unchanged below + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below scale = scale || ".5"; // Adjust and apply start = start / scale; jQuery.style( tween.elem, prop, start + unit ); - // Update scale, tolerating zero or NaN from tween.cur(), - // break the loop if scale is unchanged or perfect, or if we've just had enough + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); } @@ -35704,8 +38413,8 @@ function genFx( type, includeWidth ) { i = 0, attrs = { height: type }; - // If we include width, step value is 1 to do all cssExpand values, - // otherwise step value is 2 to skip over Left and Right + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4 ; i += 2 - includeWidth ) { which = cssExpand[ i ]; @@ -35727,7 +38436,7 @@ function createTween( value, prop, animation ) { for ( ; index < length; index++ ) { if ( (tween = collection[ index ].call( animation, prop, value )) ) { - // We're done with this property + // we're done with this property return tween; } } @@ -35742,7 +38451,7 @@ function defaultPrefilter( elem, props, opts ) { hidden = elem.nodeType && isHidden( elem ), dataShow = data_priv.get( elem, "fxshow" ); - // Handle queue: false promises + // handle queue: false promises if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { @@ -35757,7 +38466,8 @@ function defaultPrefilter( elem, props, opts ) { hooks.unqueued++; anim.always(function() { - // Ensure the complete handler is called before this completes + // doing this makes sure that the complete handler will be called + // before this completes anim.always(function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { @@ -35767,7 +38477,7 @@ function defaultPrefilter( elem, props, opts ) { }); } - // Height/width overflow pass + // height/width overflow pass if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE9-10 do not @@ -35829,7 +38539,7 @@ function defaultPrefilter( elem, props, opts ) { dataShow = data_priv.access( elem, "fxshow", {} ); } - // Store state if its toggle - enables .stop().toggle() to "reverse" + // store state if its toggle - enables .stop().toggle() to "reverse" if ( toggle ) { dataShow.hidden = !hidden; } @@ -35889,8 +38599,8 @@ function propFilter( props, specialEasing ) { value = hooks.expand( value ); delete props[ name ]; - // Not quite $.extend, this won't overwrite existing keys. - // Reusing 'index' because we have the correct "name" + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; @@ -35909,7 +38619,7 @@ function Animation( elem, properties, options ) { index = 0, length = animationPrefilters.length, deferred = jQuery.Deferred().always( function() { - // Don't match elem in the :animated selector + // don't match elem in the :animated selector delete tick.elem; }), tick = function() { @@ -35918,8 +38628,7 @@ function Animation( elem, properties, options ) { } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - // Support: Android 2.3 - // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, @@ -35955,7 +38664,7 @@ function Animation( elem, properties, options ) { }, stop: function( gotoEnd ) { var index = 0, - // If we are going to the end, we want to run all the tweens + // if we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { @@ -35966,7 +38675,8 @@ function Animation( elem, properties, options ) { animation.tweens[ index ].run( 1 ); } - // Resolve when we played the last frame; otherwise, reject + // resolve when we played the last frame + // otherwise, reject if ( gotoEnd ) { deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { @@ -36048,7 +38758,7 @@ jQuery.speed = function( speed, easing, fn ) { opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; - // Normalize opt.queue - true/undefined/null -> "fx" + // normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } @@ -36072,10 +38782,10 @@ jQuery.speed = function( speed, easing, fn ) { jQuery.fn.extend({ fadeTo: function( speed, to, easing, callback ) { - // Show any hidden elements after setting opacity to 0 + // show any hidden elements after setting opacity to 0 return this.filter( isHidden ).css( "opacity", 0 ).show() - // Animate to the value specified + // animate to the value specified .end().animate({ opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { @@ -36138,9 +38848,9 @@ jQuery.fn.extend({ } } - // Start the next in the queue if the last step wasn't forced. - // Timers currently will call their complete callbacks, which - // will dequeue but only if they were gotoEnd. + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } @@ -36158,17 +38868,17 @@ jQuery.fn.extend({ timers = jQuery.timers, length = queue ? queue.length : 0; - // Enable finishing flag on private data + // enable finishing flag on private data data.finish = true; - // Empty the queue first + // empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } - // Look for any active animations, and finish them + // look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); @@ -36176,14 +38886,14 @@ jQuery.fn.extend({ } } - // Look for any animations in the old queue and finish them + // look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } - // Turn off finishing flag + // turn off finishing flag delete data.finish; }); } @@ -36286,21 +38996,21 @@ jQuery.fn.delay = function( time, type ) { input.type = "checkbox"; - // Support: iOS<=5.1, Android<=4.2+ - // Default value for a checkbox should be "on" + // Support: iOS 5.1, Android 4.x, Android 2.3 + // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere) support.checkOn = input.value !== ""; - // Support: IE<=11+ - // Must access selectedIndex to make default options select + // Must access the parent to make an option select properly + // Support: IE9, IE10 support.optSelected = opt.selected; - // Support: Android<=2.3 - // Options inside disabled selects are incorrectly marked as disabled + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) select.disabled = true; support.optDisabled = !opt.disabled; - // Support: IE<=11+ - // An input loses its value after becoming a radio + // Check if an input maintains its value after becoming a radio + // Support: IE9, IE10 input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; @@ -36397,6 +39107,8 @@ jQuery.extend({ set: function( elem, value ) { if ( !support.radioValue && value === "radio" && jQuery.nodeName( elem, "input" ) ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { @@ -36466,7 +39178,7 @@ jQuery.extend({ var ret, hooks, notxml, nType = elem.nodeType; - // Don't get/set properties on text, comment and attribute nodes + // don't get/set properties on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return; } @@ -36502,6 +39214,8 @@ jQuery.extend({ } }); +// Support: IE9+ +// Selectedness for an option in an optgroup can be inaccurate if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { @@ -36609,7 +39323,7 @@ jQuery.fn.extend({ } } - // Only assign if different to avoid unneeded rendering. + // only assign if different to avoid unneeded rendering. finalValue = value ? jQuery.trim( cur ) : ""; if ( elem.className !== finalValue ) { elem.className = finalValue; @@ -36636,14 +39350,14 @@ jQuery.fn.extend({ return this.each(function() { if ( type === "string" ) { - // Toggle individual class names + // toggle individual class names var className, i = 0, self = jQuery( this ), classNames = value.match( rnotwhite ) || []; while ( (className = classNames[ i++ ]) ) { - // Check each className given, space separated list + // check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { @@ -36658,7 +39372,7 @@ jQuery.fn.extend({ data_priv.set( this, "__className__", this.className ); } - // If the element has a class name or if we're passed `false`, + // If the element has a class name or if we're passed "false", // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. @@ -36702,9 +39416,9 @@ jQuery.fn.extend({ ret = elem.value; return typeof ret === "string" ? - // Handle most common string cases + // handle most common string cases ret.replace(rreturn, "") : - // Handle cases where value is null/undef or number + // handle cases where value is null/undef or number ret == null ? "" : ret; } @@ -36812,7 +39526,7 @@ jQuery.extend({ } } - // Force browsers to behave consistently when non-matching value is set + // force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } @@ -36833,6 +39547,8 @@ jQuery.each([ "radio", "checkbox" ], function() { }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified return elem.getAttribute("value") === null ? "on" : elem.value; }; } @@ -36914,6 +39630,10 @@ jQuery.parseXML = function( data ) { var + // Document location + ajaxLocParts, + ajaxLocation, + rhash = /#.*$/, rts = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, @@ -36942,13 +39662,22 @@ var transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat( "*" ), + allTypes = "*/".concat("*"); - // Document location - ajaxLocation = window.location.href, +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} - // Segment location into parts - ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { @@ -37427,8 +40156,7 @@ jQuery.extend({ } // We can fire global events as of now if asked to - // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) - fireGlobals = jQuery.event && s.global; + fireGlobals = s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { @@ -37501,7 +40229,7 @@ jQuery.extend({ return jqXHR.abort(); } - // Aborting is no longer a cancellation + // aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds @@ -37613,7 +40341,8 @@ jQuery.extend({ isSuccess = !error; } } else { - // Extract error from statusText and normalize for non-aborts + // We extract error from statusText + // then normalize statusText and status for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; @@ -37669,7 +40398,7 @@ jQuery.extend({ jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { - // Shift arguments if data argument was omitted + // shift arguments if data argument was omitted if ( jQuery.isFunction( data ) ) { type = type || callback; callback = data; @@ -37686,6 +40415,13 @@ jQuery.each( [ "get", "post" ], function( i, method ) { }; }); +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +}); + jQuery._evalUrl = function( url ) { return jQuery.ajax({ @@ -37903,9 +40639,8 @@ var xhrId = 0, // Support: IE9 // Open requests must be manually aborted on unload (#5280) -// See https://support.microsoft.com/kb/2856746 for more info -if ( window.attachEvent ) { - window.attachEvent( "onunload", function() { +if ( window.ActiveXObject ) { + jQuery( window ).on( "unload", function() { for ( var key in xhrCallbacks ) { xhrCallbacks[ key ](); } @@ -38258,16 +40993,6 @@ jQuery.fn.load = function( url, params, callback ) { -// Attach a bunch of functions for handling common AJAX events -jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { - jQuery.fn[ type ] = function( fn ) { - return this.on( type, fn ); - }; -}); - - - - jQuery.expr.filters.animated = function( elem ) { return jQuery.grep(jQuery.timers, function( fn ) { return elem === fn.elem; @@ -38304,8 +41029,7 @@ jQuery.offset = { calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; - // Need to be able to calculate position if either - // top or left is auto and position is either absolute or fixed + // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); curTop = curPosition.top; @@ -38362,8 +41086,8 @@ jQuery.fn.extend({ return box; } - // Support: BlackBerry 5, iOS 3 (original iPhone) // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) if ( typeof elem.getBoundingClientRect !== strundefined ) { box = elem.getBoundingClientRect(); } @@ -38385,7 +41109,7 @@ jQuery.fn.extend({ // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent if ( jQuery.css( elem, "position" ) === "fixed" ) { - // Assume getBoundingClientRect is there when computed position is fixed + // We assume that getBoundingClientRect is available when computed position is fixed offset = elem.getBoundingClientRect(); } else { @@ -38448,18 +41172,16 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( }; }); -// Support: Safari<7+, Chrome<37+ // Add the top/left cssHooks using jQuery.fn.position // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 -// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280 -// getComputedStyle returns percent when specified for top/left/bottom/right; -// rather than make the css module depend on the offset module, just check for it here +// getComputedStyle returns percent when specified for top/left/bottom/right +// rather than make the css module depend on the offset module, we just check for it here jQuery.each( [ "top", "left" ], function( i, prop ) { jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, function( elem, computed ) { if ( computed ) { computed = curCSS( elem, prop ); - // If curCSS returns percentage, fallback to offset + // if curCSS returns percentage, fallback to offset return rnumnonpx.test( computed ) ? jQuery( elem ).position()[ prop ] + "px" : computed; @@ -38472,7 +41194,7 @@ jQuery.each( [ "top", "left" ], function( i, prop ) { // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { - // Margin is only for outerHeight, outerWidth + // margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); @@ -38563,8 +41285,8 @@ jQuery.noConflict = function( deep ) { return jQuery; }; -// Expose jQuery and $ identifiers, even in AMD -// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// Expose jQuery and $ identifiers, even in +// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) if ( typeof noGlobal === strundefined ) { window.jQuery = window.$ = jQuery; @@ -38577,23 +41299,25 @@ return jQuery; })); -},{}],41:[function(require,module,exports){ -//! moment.js -//! version : 2.5.1 +},{}],54:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};//! moment.js +//! version : 2.8.4 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com (function (undefined) { - /************************************ Constants ************************************/ var moment, - VERSION = "2.5.1", - global = this, + VERSION = '2.8.4', + // the global-scope this is NOT the global object in Node.js + globalScope = typeof global !== 'undefined' ? global : this, + oldGlobalMoment, round = Math.round, + hasOwnProperty = Object.prototype.hasOwnProperty, i, YEAR = 0, @@ -38604,24 +41328,14 @@ return jQuery; SECOND = 5, MILLISECOND = 6, - // internal storage for language config files - languages = {}, - - // moment internal properties - momentProperties = { - _isAMomentObject: null, - _i : null, - _f : null, - _l : null, - _strict : null, - _isUTC : null, - _offset : null, // optional. Combine with _isUTC - _pf : null, - _lang : null // optional - }, + // internal storage for locale config files + locales = {}, + + // extra moment internal properties (plugins register props here) + momentProperties = [], // check for nodeJS - hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'), + hasModule = (typeof module !== 'undefined' && module && module.exports), // ASP.NET json date format regex aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, @@ -38632,8 +41346,8 @@ return jQuery; isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, // format tokens - formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, - localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, + formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g, + localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, // parsing token regexes parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 @@ -38644,6 +41358,7 @@ return jQuery; parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z parseTokenT = /T/i, // T (ISO separator) + parseTokenOffsetMs = /[\+\-]?\d+/, // 1234567890123 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 //strict parsing regexes @@ -38670,13 +41385,13 @@ return jQuery; // iso time formats and regexes isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], + ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], ['HH:mm', /(T| )\d\d:\d\d/], ['HH', /(T| )\d\d/] ], - // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] + // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-15', '30'] parseTimezoneChunker = /([\+\-]|\d\d)/gi, // getter and setter names @@ -38701,6 +41416,7 @@ return jQuery; w : 'week', W : 'isoWeek', M : 'month', + Q : 'quarter', y : 'year', DDD : 'dayOfYear', e : 'weekday', @@ -38720,6 +41436,15 @@ return jQuery; // format function strings formatFunctions = {}, + // default relative time thresholds + relativeTimeThresholds = { + s: 45, // seconds to minute + m: 45, // minutes to hour + h: 22, // hours to day + d: 26, // days to month + M: 11 // months to year + }, + // tokens to ordinalize and pad ordinalizeTokens = 'DDD w W M D d'.split(' '), paddedTokens = 'M D H h m s w W'.split(' '), @@ -38729,10 +41454,10 @@ return jQuery; return this.month() + 1; }, MMM : function (format) { - return this.lang().monthsShort(this, format); + return this.localeData().monthsShort(this, format); }, MMMM : function (format) { - return this.lang().months(this, format); + return this.localeData().months(this, format); }, D : function () { return this.date(); @@ -38744,13 +41469,13 @@ return jQuery; return this.day(); }, dd : function (format) { - return this.lang().weekdaysMin(this, format); + return this.localeData().weekdaysMin(this, format); }, ddd : function (format) { - return this.lang().weekdaysShort(this, format); + return this.localeData().weekdaysShort(this, format); }, dddd : function (format) { - return this.lang().weekdays(this, format); + return this.localeData().weekdays(this, format); }, w : function () { return this.week(); @@ -38796,10 +41521,10 @@ return jQuery; return this.isoWeekday(); }, a : function () { - return this.lang().meridiem(this.hours(), this.minutes(), true); + return this.localeData().meridiem(this.hours(), this.minutes(), true); }, A : function () { - return this.lang().meridiem(this.hours(), this.minutes(), false); + return this.localeData().meridiem(this.hours(), this.minutes(), false); }, H : function () { return this.hours(); @@ -38827,19 +41552,19 @@ return jQuery; }, Z : function () { var a = -this.zone(), - b = "+"; + b = '+'; if (a < 0) { a = -a; - b = "-"; + b = '-'; } - return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); + return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2); }, ZZ : function () { var a = -this.zone(), - b = "+"; + b = '+'; if (a < 0) { a = -a; - b = "-"; + b = '-'; } return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); }, @@ -38849,6 +41574,9 @@ return jQuery; zz : function () { return this.zoneName(); }, + x : function () { + return this.valueOf(); + }, X : function () { return this.unix(); }, @@ -38857,8 +41585,24 @@ return jQuery; } }, + deprecations = {}, + lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; + // Pick the first defined of two or three arguments. dfl comes from + // default. + function dfl(a, b, c) { + switch (arguments.length) { + case 2: return a != null ? a : b; + case 3: return a != null ? a : b != null ? b : c; + default: throw new Error('Implement me'); + } + } + + function hasOwnProp(a, b) { + return hasOwnProperty.call(a, b); + } + function defaultParsingFlags() { // We need to deep clone this object, and es5 standard is not very // helpful. @@ -38876,6 +41620,31 @@ return jQuery; }; } + function printMsg(msg) { + if (moment.suppressDeprecationWarnings === false && + typeof console !== 'undefined' && console.warn) { + console.warn('Deprecation warning: ' + msg); + } + } + + function deprecate(msg, fn) { + var firstTime = true; + return extend(function () { + if (firstTime) { + printMsg(msg); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + function deprecateSimple(name, msg) { + if (!deprecations[name]) { + printMsg(msg); + deprecations[name] = true; + } + } + function padToken(func, count) { return function (a) { return leftZeroFill(func.call(this, a), count); @@ -38883,7 +41652,7 @@ return jQuery; } function ordinalizeToken(func, period) { return function (a) { - return this.lang().ordinal(func.call(this, a), period); + return this.localeData().ordinal(func.call(this, a), period); }; } @@ -38902,20 +41671,23 @@ return jQuery; Constructors ************************************/ - function Language() { - + function Locale() { } // Moment prototype object - function Moment(config) { - checkOverflow(config); - extend(this, config); + function Moment(config, skipOverflow) { + if (skipOverflow !== false) { + checkOverflow(config); + } + copyConfig(this, config); + this._d = new Date(+config._d); } // Duration Constructor function Duration(duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, months = normalizedInput.month || 0, weeks = normalizedInput.week || 0, days = normalizedInput.day || 0, @@ -38937,10 +41709,13 @@ return jQuery; // which months you are are talking about, so we have to store // it separately. this._months = +months + + quarters * 3 + years * 12; this._data = {}; + this._locale = moment.localeData(); + this._bubble(); } @@ -38951,31 +41726,67 @@ return jQuery; function extend(a, b) { for (var i in b) { - if (b.hasOwnProperty(i)) { + if (hasOwnProp(b, i)) { a[i] = b[i]; } } - if (b.hasOwnProperty("toString")) { + if (hasOwnProp(b, 'toString')) { a.toString = b.toString; } - if (b.hasOwnProperty("valueOf")) { + if (hasOwnProp(b, 'valueOf')) { a.valueOf = b.valueOf; } return a; } - function cloneMoment(m) { - var result = {}, i; - for (i in m) { - if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { - result[i] = m[i]; + function copyConfig(to, from) { + var i, prop, val; + + if (typeof from._isAMomentObject !== 'undefined') { + to._isAMomentObject = from._isAMomentObject; + } + if (typeof from._i !== 'undefined') { + to._i = from._i; + } + if (typeof from._f !== 'undefined') { + to._f = from._f; + } + if (typeof from._l !== 'undefined') { + to._l = from._l; + } + if (typeof from._strict !== 'undefined') { + to._strict = from._strict; + } + if (typeof from._tzm !== 'undefined') { + to._tzm = from._tzm; + } + if (typeof from._isUTC !== 'undefined') { + to._isUTC = from._isUTC; + } + if (typeof from._offset !== 'undefined') { + to._offset = from._offset; + } + if (typeof from._pf !== 'undefined') { + to._pf = from._pf; + } + if (typeof from._locale !== 'undefined') { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i in momentProperties) { + prop = momentProperties[i]; + val = from[prop]; + if (typeof val !== 'undefined') { + to[prop] = val; + } } } - return result; + return to; } function absRound(number) { @@ -38998,35 +41809,68 @@ return jQuery; return (sign ? (forceSign ? '+' : '') : '-') + output; } - // helper function for _.addTime and _.subtractTime - function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) { + function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; + } + + function momentsDifference(base, other) { + var res; + other = makeAs(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; + } + + // TODO: remove 'name' arg after deprecation is removed + function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = moment.duration(val, period); + addOrSubtractDurationFromMoment(this, dur, direction); + return this; + }; + } + + function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, days = duration._days, - months = duration._months, - minutes, - hours; + months = duration._months; + updateOffset = updateOffset == null ? true : updateOffset; if (milliseconds) { mom._d.setTime(+mom._d + milliseconds * isAdding); } - // store the minutes and hours so we can restore them - if (days || months) { - minutes = mom.minute(); - hours = mom.hour(); - } if (days) { - mom.date(mom.date() + days * isAdding); + rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding); } if (months) { - mom.month(mom.month() + months * isAdding); - } - if (milliseconds && !ignoreUpdateOffset) { - moment.updateOffset(mom); + rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding); } - // restore the minutes and hours after possibly changing dst - if (days || months) { - mom.minute(minutes); - mom.hour(hours); + if (updateOffset) { + moment.updateOffset(mom, days || months); } } @@ -39036,8 +41880,8 @@ return jQuery; } function isDate(input) { - return Object.prototype.toString.call(input) === '[object Date]' || - input instanceof Date; + return Object.prototype.toString.call(input) === '[object Date]' || + input instanceof Date; } // compare two arrays, return the number of differences @@ -39069,7 +41913,7 @@ return jQuery; prop; for (prop in inputObject) { - if (inputObject.hasOwnProperty(prop)) { + if (hasOwnProp(inputObject, prop)) { normalizedProp = normalizeUnits(prop); if (normalizedProp) { normalizedInput[normalizedProp] = inputObject[prop]; @@ -39097,7 +41941,7 @@ return jQuery; moment[field] = function (format, index) { var i, getter, - method = moment.fn._lang[field], + method = moment._locale[field], results = []; if (typeof format === 'number') { @@ -39107,7 +41951,7 @@ return jQuery; getter = function (i) { var m = moment().utc().set(setter, i); - return method.call(moment.fn._lang, m, format || ''); + return method.call(moment._locale, m, format || ''); }; if (index != null) { @@ -39141,6 +41985,10 @@ return jQuery; return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); } + function weeksInYear(year, dow, doy) { + return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week; + } + function daysInYear(year) { return isLeapYear(year) ? 366 : 365; } @@ -39155,7 +42003,10 @@ return jQuery; overflow = m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : - m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : + m._a[HOUR] < 0 || m._a[HOUR] > 24 || + (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 || + m._a[SECOND] !== 0 || + m._a[MILLISECOND] !== 0)) ? HOUR : m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : @@ -39182,28 +42033,79 @@ return jQuery; if (m._strict) { m._isValid = m._isValid && m._pf.charsLeftOver === 0 && - m._pf.unusedTokens.length === 0; + m._pf.unusedTokens.length === 0 && + m._pf.bigHour === undefined; } } return m._isValid; } - function normalizeLanguage(key) { + function normalizeLocale(key) { return key ? key.toLowerCase().replace('_', '-') : key; } + // pick the locale from the array + // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each + // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root + function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; + } + + function loadLocale(name) { + var oldLocale = null; + if (!locales[name] && hasModule) { + try { + oldLocale = moment.locale(); + require('./locale/' + name); + // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales + moment.locale(oldLocale); + } catch (e) { } + } + return locales[name]; + } + // Return a moment from input, that is local/utc/zone equivalent to model. function makeAs(input, model) { - return model._isUTC ? moment(input).zone(model._offset || 0) : - moment(input).local(); + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (moment.isMoment(input) || isDate(input) ? + +input : +moment(input)) - (+res); + // Use low-level api, because this fn is low-level api. + res._d.setTime(+res._d + diff); + moment.updateOffset(res, false); + return res; + } else { + return moment(input).local(); + } } /************************************ - Languages + Locale ************************************/ - extend(Language.prototype, { + extend(Locale.prototype, { set : function (config) { var prop, i; @@ -39215,50 +42117,63 @@ return jQuery; this['_' + i] = prop; } } + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _ordinalParseLenient. + this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\d{1,2}/.source); }, - _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), + _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'), months : function (m) { return this._months[m.month()]; }, - _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), + _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), monthsShort : function (m) { return this._monthsShort[m.month()]; }, - monthsParse : function (monthName) { + monthsParse : function (monthName, format, strict) { var i, mom, regex; if (!this._monthsParse) { this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; } for (i = 0; i < 12; i++) { // make the regex if we don't have it already - if (!this._monthsParse[i]) { - mom = moment.utc([2000, i]); + mom = moment.utc([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex - if (this._monthsParse[i].test(monthName)) { + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { return i; } } }, - _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), + _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), weekdays : function (m) { return this._weekdays[m.day()]; }, - _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), + _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), weekdaysShort : function (m) { return this._weekdaysShort[m.day()]; }, - _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), + _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), weekdaysMin : function (m) { return this._weekdaysMin[m.day()]; }, @@ -39285,11 +42200,12 @@ return jQuery; }, _longDateFormat : { - LT : "h:mm A", - L : "MM/DD/YYYY", - LL : "MMMM D YYYY", - LLL : "MMMM D YYYY LT", - LLLL : "dddd, MMMM D YYYY LT" + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY LT', + LLLL : 'dddd, MMMM D, YYYY LT' }, longDateFormat : function (key) { var output = this._longDateFormat[key]; @@ -39325,41 +42241,44 @@ return jQuery; lastWeek : '[Last] dddd [at] LT', sameElse : 'L' }, - calendar : function (key, mom) { + calendar : function (key, mom, now) { var output = this._calendar[key]; - return typeof output === 'function' ? output.apply(mom) : output; + return typeof output === 'function' ? output.apply(mom, [now]) : output; }, _relativeTime : { - future : "in %s", - past : "%s ago", - s : "a few seconds", - m : "a minute", - mm : "%d minutes", - h : "an hour", - hh : "%d hours", - d : "a day", - dd : "%d days", - M : "a month", - MM : "%d months", - y : "a year", - yy : "%d years" + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' }, + relativeTime : function (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; return (typeof output === 'function') ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); }, + pastFuture : function (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); }, ordinal : function (number) { - return this._ordinal.replace("%d", number); + return this._ordinal.replace('%d', number); }, - _ordinal : "%d", + _ordinal : '%d', + _ordinalParse : /\d{1,2}/, preparse : function (string) { return string; @@ -39384,78 +42303,6 @@ return jQuery; } }); - // Loads a language definition into the `languages` cache. The function - // takes a key and optionally values. If not in the browser and no values - // are provided, it will load the language file module. As a convenience, - // this function also returns the language values. - function loadLang(key, values) { - values.abbr = key; - if (!languages[key]) { - languages[key] = new Language(); - } - languages[key].set(values); - return languages[key]; - } - - // Remove a language from the `languages` cache. Mostly useful in tests. - function unloadLang(key) { - delete languages[key]; - } - - // Determines which language definition to use and returns it. - // - // With no parameters, it will return the global language. If you - // pass in a language key, such as 'en', it will return the - // definition for 'en', so long as 'en' has already been loaded using - // moment.lang. - function getLangDefinition(key) { - var i = 0, j, lang, next, split, - get = function (k) { - if (!languages[k] && hasModule) { - try { - require('./lang/' + k); - } catch (e) { } - } - return languages[k]; - }; - - if (!key) { - return moment.fn._lang; - } - - if (!isArray(key)) { - //short-circuit everything else - lang = get(key); - if (lang) { - return lang; - } - key = [key]; - } - - //pick the language from the array - //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each - //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root - while (i < key.length) { - split = normalizeLanguage(key[i]).split('-'); - j = split.length; - next = normalizeLanguage(key[i + 1]); - next = next ? next.split('-') : null; - while (j > 0) { - lang = get(split.slice(0, j).join('-')); - if (lang) { - return lang; - } - if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { - //the next array item is better than a shallower substring of this one - break; - } - j--; - } - i++; - } - return moment.fn._lang; - } - /************************************ Formatting ************************************/ @@ -39463,9 +42310,9 @@ return jQuery; function removeFormattingTokens(input) { if (input.match(/\[[\s\S]/)) { - return input.replace(/^\[|\]$/g, ""); + return input.replace(/^\[|\]$/g, ''); } - return input.replace(/\\/g, ""); + return input.replace(/\\/g, ''); } function makeFormatFunction(format) { @@ -39480,7 +42327,7 @@ return jQuery; } return function (mom) { - var output = ""; + var output = ''; for (i = 0; i < length; i++) { output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; } @@ -39490,12 +42337,11 @@ return jQuery; // format date using native date object function formatMoment(m, format) { - if (!m.isValid()) { - return m.lang().invalidDate(); + return m.localeData().invalidDate(); } - format = expandFormat(format, m.lang()); + format = expandFormat(format, m.localeData()); if (!formatFunctions[format]) { formatFunctions[format] = makeFormatFunction(format); @@ -39504,11 +42350,11 @@ return jQuery; return formatFunctions[format](m); } - function expandFormat(format, lang) { + function expandFormat(format, locale) { var i = 5; function replaceLongDateFormatTokens(input) { - return lang.longDateFormat(input) || input; + return locale.longDateFormat(input) || input; } localFormattingTokens.lastIndex = 0; @@ -39531,6 +42377,8 @@ return jQuery; function getParseRegexForToken(token, config) { var a, strict = config._strict; switch (token) { + case 'Q': + return parseTokenOneDigit; case 'DDDD': return parseTokenThreeDigits; case 'YYYY': @@ -39547,13 +42395,19 @@ return jQuery; case 'ggggg': return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; case 'S': - if (strict) { return parseTokenOneDigit; } + if (strict) { + return parseTokenOneDigit; + } /* falls through */ case 'SS': - if (strict) { return parseTokenTwoDigits; } + if (strict) { + return parseTokenTwoDigits; + } /* falls through */ case 'SSS': - if (strict) { return parseTokenThreeDigits; } + if (strict) { + return parseTokenThreeDigits; + } /* falls through */ case 'DDD': return parseTokenOneToThreeDigits; @@ -39565,7 +42419,9 @@ return jQuery; return parseTokenWord; case 'a': case 'A': - return getLangDefinition(config._l)._meridiemParse; + return config._locale._meridiemParse; + case 'x': + return parseTokenOffsetMs; case 'X': return parseTokenTimestampMs; case 'Z': @@ -39599,14 +42455,16 @@ return jQuery; case 'e': case 'E': return parseTokenOneOrTwoDigits; + case 'Do': + return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient; default : - a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); + a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i')); return a; } } function timezoneMinutesFromString(string) { - string = string || ""; + string = string || ''; var possibleTzMatches = (string.match(parseTokenTimezone) || []), tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], @@ -39620,6 +42478,12 @@ return jQuery; var a, datePartArray = config._a; switch (token) { + // QUARTER + case 'Q': + if (input != null) { + datePartArray[MONTH] = (toInt(input) - 1) * 3; + } + break; // MONTH case 'M' : // fall through to MM case 'MM' : @@ -39629,7 +42493,7 @@ return jQuery; break; case 'MMM' : // fall through to MMMM case 'MMMM' : - a = getLangDefinition(config._l).monthsParse(input); + a = config._locale.monthsParse(input, token, config._strict); // if we didn't find a month name, mark the date as invalid. if (a != null) { datePartArray[MONTH] = a; @@ -39644,6 +42508,12 @@ return jQuery; datePartArray[DATE] = toInt(input); } break; + case 'Do' : + if (input != null) { + datePartArray[DATE] = toInt(parseInt( + input.match(/\d{1,2}/)[0], 10)); + } + break; // DAY OF YEAR case 'DDD' : // fall through to DDDD case 'DDDD' : @@ -39654,7 +42524,7 @@ return jQuery; break; // YEAR case 'YY' : - datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); + datePartArray[YEAR] = moment.parseTwoDigitYear(input); break; case 'YYYY' : case 'YYYYY' : @@ -39664,13 +42534,15 @@ return jQuery; // AM / PM case 'a' : // fall through to A case 'A' : - config._isPm = getLangDefinition(config._l).isPM(input); + config._isPm = config._locale.isPM(input); break; - // 24 HOUR - case 'H' : // fall through to hh - case 'HH' : // fall through to hh + // HOUR case 'h' : // fall through to hh case 'hh' : + config._pf.bigHour = true; + /* falls through */ + case 'H' : // fall through to HH + case 'HH' : datePartArray[HOUR] = toInt(input); break; // MINUTE @@ -39690,6 +42562,10 @@ return jQuery; case 'SSSS' : datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); break; + // UNIX OFFSET (MILLISECONDS) + case 'x': + config._d = new Date(toInt(input)); + break; // UNIX TIMESTAMP WITH MS case 'X': config._d = new Date(parseFloat(input) * 1000); @@ -39700,30 +42576,85 @@ return jQuery; config._useUTC = true; config._tzm = timezoneMinutesFromString(input); break; + // WEEKDAY - human + case 'dd': + case 'ddd': + case 'dddd': + a = config._locale.weekdaysParse(input); + // if we didn't get a weekday name, mark the date as invalid + if (a != null) { + config._w = config._w || {}; + config._w['d'] = a; + } else { + config._pf.invalidWeekday = input; + } + break; + // WEEK, WEEK DAY - numeric case 'w': case 'ww': case 'W': case 'WW': case 'd': - case 'dd': - case 'ddd': - case 'dddd': case 'e': case 'E': token = token.substr(0, 1); /* falls through */ - case 'gg': case 'gggg': - case 'GG': case 'GGGG': case 'GGGGG': token = token.substr(0, 2); if (input) { config._w = config._w || {}; - config._w[token] = input; + config._w[token] = toInt(input); } break; + case 'gg': + case 'GG': + config._w = config._w || {}; + config._w[token] = moment.parseTwoDigitYear(input); + } + } + + function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year); + week = dfl(w.W, 1); + weekday = dfl(w.E, 1); + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year); + week = dfl(w.w, 1); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < dow) { + ++week; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + } else { + // default to begining of week + weekday = dow; + } } + temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); + + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; } // convert an array to a date. @@ -39731,8 +42662,7 @@ return jQuery; // note: all values past the year are optional and will default to the lowest possible value. // [year, month, day , hour, minute, second, millisecond] function dateFromConfig(config) { - var i, date, input = [], currentDate, - yearToUse, fixYear, w, temp, lang, weekday, week; + var i, date, input = [], currentDate, yearToUse; if (config._d) { return; @@ -39742,39 +42672,12 @@ return jQuery; //compute day of the year from weeks and weekdays if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { - fixYear = function (val) { - var int_val = parseInt(val, 10); - return val ? - (val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) : - (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); - }; - - w = config._w; - if (w.GG != null || w.W != null || w.E != null) { - temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); - } - else { - lang = getLangDefinition(config._l); - weekday = w.d != null ? parseWeekday(w.d, lang) : - (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); - - week = parseInt(w.w, 10) || 1; - - //if we're parsing 'd', then the low day numbers may be next week - if (w.d != null && weekday < lang._week.dow) { - week++; - } - - temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); - } - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; + dayOfYearFromWeekInfo(config); } //if the day of the year is set, figure out what it is if (config._dayOfYear) { - yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; + yearToUse = dfl(config._a[YEAR], currentDate[YEAR]); if (config._dayOfYear > daysInYear(yearToUse)) { config._pf._overflowDayOfYear = true; @@ -39799,11 +42702,25 @@ return jQuery; config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; } - // add the offsets to the time to be parsed so that we can have a clean array for checking isValid - input[HOUR] += toInt((config._tzm || 0) / 60); - input[MINUTE] += toInt((config._tzm || 0) % 60); + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); + // Apply timezone offset from input. The actual zone can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() + config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } } function dateFromObject(config) { @@ -39817,7 +42734,7 @@ return jQuery; config._a = [ normalizedInput.year, normalizedInput.month, - normalizedInput.day, + normalizedInput.day || normalizedInput.date, normalizedInput.hour, normalizedInput.minute, normalizedInput.second, @@ -39842,18 +42759,21 @@ return jQuery; // date from string and format string function makeDateFromStringAndFormat(config) { + if (config._f === moment.ISO_8601) { + parseISO(config); + return; + } config._a = []; config._pf.empty = true; // This array is used to make a Date, either with `new Date` or `Date.UTC` - var lang = getLangDefinition(config._l), - string = '' + config._i, + var string = '' + config._i, i, parsedInput, tokens, token, skipped, stringLength = string.length, totalParsedInputLength = 0; - tokens = expandFormat(config._f, lang).match(formattingTokens) || []; + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; for (i = 0; i < tokens.length; i++) { token = tokens[i]; @@ -39887,6 +42807,10 @@ return jQuery; config._pf.unusedInput.push(string); } + // clear _12h flag if hour is <= 12 + if (config._pf.bigHour === true && config._a[HOUR] <= 12) { + config._pf.bigHour = undefined; + } // handle am pm if (config._isPm && config._a[HOUR] < 12) { config._a[HOUR] += 12; @@ -39895,7 +42819,6 @@ return jQuery; if (config._isPm === false && config._a[HOUR] === 12) { config._a[HOUR] = 0; } - dateFromConfig(config); checkOverflow(config); } @@ -39928,7 +42851,10 @@ return jQuery; for (i = 0; i < config._f.length; i++) { currentScore = 0; - tempConfig = extend({}, config); + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } tempConfig._pf = defaultParsingFlags(); tempConfig._f = config._f[i]; makeDateFromStringAndFormat(tempConfig); @@ -39955,7 +42881,7 @@ return jQuery; } // date from iso format - function makeDateFromString(config) { + function parseISO(config) { var i, l, string = config._i, match = isoRegex.exec(string); @@ -39964,8 +42890,8 @@ return jQuery; config._pf.iso = true; for (i = 0, l = isoDates.length; i < l; i++) { if (isoDates[i][1].exec(string)) { - // match[5] should be "T" or undefined - config._f = isoDates[i][0] + (match[6] || " "); + // match[5] should be 'T' or undefined + config._f = isoDates[i][0] + (match[6] || ' '); break; } } @@ -39976,34 +42902,53 @@ return jQuery; } } if (string.match(parseTokenTimezone)) { - config._f += "Z"; + config._f += 'Z'; } makeDateFromStringAndFormat(config); + } else { + config._isValid = false; } - else { - config._d = new Date(string); + } + + // date from iso format or fallback + function makeDateFromString(config) { + parseISO(config); + if (config._isValid === false) { + delete config._isValid; + moment.createFromInputFallback(config); } } - function makeDateFromInput(config) { - var input = config._i, - matched = aspNetJsonRegex.exec(input); + function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; + } + function makeDateFromInput(config) { + var input = config._i, matched; if (input === undefined) { config._d = new Date(); - } else if (matched) { + } else if (isDate(input)) { + config._d = new Date(+input); + } else if ((matched = aspNetJsonRegex.exec(input)) !== null) { config._d = new Date(+matched[1]); } else if (typeof input === 'string') { makeDateFromString(config); } else if (isArray(input)) { - config._a = input.slice(0); + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); dateFromConfig(config); - } else if (isDate(input)) { - config._d = new Date(+input); } else if (typeof(input) === 'object') { dateFromObject(config); - } else { + } else if (typeof(input) === 'number') { + // from milliseconds config._d = new Date(input); + } else { + moment.createFromInputFallback(config); } } @@ -40027,13 +42972,13 @@ return jQuery; return date; } - function parseWeekday(input, language) { + function parseWeekday(input, locale) { if (typeof input === 'string') { if (!isNaN(input)) { input = parseInt(input, 10); } else { - input = language.weekdaysParse(input); + input = locale.weekdaysParse(input); if (typeof input !== 'number') { return null; } @@ -40048,29 +42993,33 @@ return jQuery; // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize - function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { - return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); + function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); } - function relativeTime(milliseconds, withoutSuffix, lang) { - var seconds = round(Math.abs(milliseconds) / 1000), - minutes = round(seconds / 60), - hours = round(minutes / 60), - days = round(hours / 24), - years = round(days / 365), - args = seconds < 45 && ['s', seconds] || + function relativeTime(posNegDuration, withoutSuffix, locale) { + var duration = moment.duration(posNegDuration).abs(), + seconds = round(duration.as('s')), + minutes = round(duration.as('m')), + hours = round(duration.as('h')), + days = round(duration.as('d')), + months = round(duration.as('M')), + years = round(duration.as('y')), + + args = seconds < relativeTimeThresholds.s && ['s', seconds] || minutes === 1 && ['m'] || - minutes < 45 && ['mm', minutes] || + minutes < relativeTimeThresholds.m && ['mm', minutes] || hours === 1 && ['h'] || - hours < 22 && ['hh', hours] || + hours < relativeTimeThresholds.h && ['hh', hours] || days === 1 && ['d'] || - days <= 25 && ['dd', days] || - days <= 45 && ['M'] || - days < 345 && ['MM', round(days / 30)] || + days < relativeTimeThresholds.d && ['dd', days] || + months === 1 && ['M'] || + months < relativeTimeThresholds.M && ['MM', months] || years === 1 && ['y'] || ['yy', years]; + args[2] = withoutSuffix; - args[3] = milliseconds > 0; - args[4] = lang; + args[3] = +posNegDuration > 0; + args[4] = locale; return substituteTimeAgo.apply({}, args); } @@ -40101,7 +43050,7 @@ return jQuery; daysToDayOfWeek += 7; } - adjustedMoment = moment(mom).add('d', daysToDayOfWeek); + adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd'); return { week: Math.ceil(adjustedMoment.dayOfYear() / 7), year: adjustedMoment.year() @@ -40112,6 +43061,7 @@ return jQuery; function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; + d = d === 0 ? 7 : d; weekday = weekday != null ? weekday : firstDayOfWeek; daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; @@ -40128,20 +43078,21 @@ return jQuery; function makeMoment(config) { var input = config._i, - format = config._f; + format = config._f, + res; - if (input === null) { + config._locale = config._locale || moment.localeData(config._l); + + if (input === null || (format === undefined && input === '')) { return moment.invalid({nullInput: true}); } if (typeof input === 'string') { - config._i = input = getLangDefinition().preparse(input); + config._i = input = config._locale.preparse(input); } if (moment.isMoment(input)) { - config = cloneMoment(input); - - config._d = new Date(+input._d); + return new Moment(input, true); } else if (format) { if (isArray(format)) { makeDateFromStringAndArray(config); @@ -40152,15 +43103,22 @@ return jQuery; makeDateFromInput(config); } - return new Moment(config); + res = new Moment(config); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; } - moment = function (input, format, lang, strict) { + moment = function (input, format, locale, strict) { var c; - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -40168,7 +43126,7 @@ return jQuery; c._isAMomentObject = true; c._i = input; c._f = format; - c._l = lang; + c._l = locale; c._strict = strict; c._isUTC = false; c._pf = defaultParsingFlags(); @@ -40176,13 +43134,59 @@ return jQuery; return makeMoment(c); }; + moment.suppressDeprecationWarnings = false; + + moment.createFromInputFallback = deprecate( + 'moment construction falls back to js Date. This is ' + + 'discouraged and will be removed in upcoming major ' + + 'release. Please refer to ' + + 'https://github.com/moment/moment/issues/1407 for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } + ); + + // Pick a moment m from moments so that m[fn](other) is true for all + // other. This relies on the function fn to be transitive. + // + // moments should either be an array of moment objects or an array, whose + // first element is an array of moment objects. + function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return moment(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (moments[i][fn](res)) { + res = moments[i]; + } + } + return res; + } + + moment.min = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); + }; + + moment.max = function () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); + }; + // creating with utc - moment.utc = function (input, format, lang, strict) { + moment.utc = function (input, format, locale, strict) { var c; - if (typeof(lang) === "boolean") { - strict = lang; - lang = undefined; + if (typeof(locale) === 'boolean') { + strict = locale; + locale = undefined; } // object construction must be done this way. // https://github.com/moment/moment/issues/1423 @@ -40190,7 +43194,7 @@ return jQuery; c._isAMomentObject = true; c._useUTC = true; c._isUTC = true; - c._l = lang; + c._l = locale; c._i = input; c._f = format; c._strict = strict; @@ -40211,7 +43215,8 @@ return jQuery; match = null, sign, ret, - parseIso; + parseIso, + diffRes; if (moment.isDuration(input)) { duration = { @@ -40227,7 +43232,7 @@ return jQuery; duration.milliseconds = input; } } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; + sign = (match[1] === '-') ? -1 : 1; duration = { y: 0, d: toInt(match[DATE]) * sign, @@ -40237,7 +43242,7 @@ return jQuery; ms: toInt(match[MILLISECOND]) * sign }; } else if (!!(match = isoDurationRegex.exec(input))) { - sign = (match[1] === "-") ? -1 : 1; + sign = (match[1] === '-') ? -1 : 1; parseIso = function (inp) { // We'd normally use ~~inp for this, but unfortunately it also // converts floats to ints. @@ -40255,12 +43260,19 @@ return jQuery; s: parseIso(match[7]), w: parseIso(match[8]) }; + } else if (typeof duration === 'object' && + ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(moment(duration.from), moment(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; } ret = new Duration(duration); - if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { - ret._lang = input._lang; + if (moment.isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; } return ret; @@ -40272,42 +43284,111 @@ return jQuery; // default format moment.defaultFormat = isoFormat; + // constant that refers to the ISO standard + moment.ISO_8601 = function () {}; + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. + moment.momentProperties = momentProperties; + // This function will be called whenever a moment is mutated. // It is intended to keep the offset in sync with the timezone. moment.updateOffset = function () {}; - // This function will load languages and then set the global language. If + // This function allows you to set a threshold for relative time strings + moment.relativeTimeThreshold = function (threshold, limit) { + if (relativeTimeThresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return relativeTimeThresholds[threshold]; + } + relativeTimeThresholds[threshold] = limit; + return true; + }; + + moment.lang = deprecate( + 'moment.lang is deprecated. Use moment.locale instead.', + function (key, value) { + return moment.locale(key, value); + } + ); + + // This function will load locale and then set the global locale. If // no arguments are passed in, it will simply return the current global - // language key. - moment.lang = function (key, values) { - var r; - if (!key) { - return moment.fn._lang._abbr; - } - if (values) { - loadLang(normalizeLanguage(key), values); - } else if (values === null) { - unloadLang(key); - key = 'en'; - } else if (!languages[key]) { - getLangDefinition(key); - } - r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); - return r._abbr; + // locale key. + moment.locale = function (key, values) { + var data; + if (key) { + if (typeof(values) !== 'undefined') { + data = moment.defineLocale(key, values); + } + else { + data = moment.localeData(key); + } + + if (data) { + moment.duration._locale = moment._locale = data; + } + } + + return moment._locale._abbr; + }; + + moment.defineLocale = function (name, values) { + if (values !== null) { + values.abbr = name; + if (!locales[name]) { + locales[name] = new Locale(); + } + locales[name].set(values); + + // backwards compat for now: also set the locale + moment.locale(name); + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } }; - // returns language data - moment.langData = function (key) { - if (key && key._lang && key._lang._abbr) { - key = key._lang._abbr; + moment.langData = deprecate( + 'moment.langData is deprecated. Use moment.localeData instead.', + function (key) { + return moment.localeData(key); + } + ); + + // returns locale data + moment.localeData = function (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return moment._locale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; } - return getLangDefinition(key); + + return chooseLocale(key); }; // compare moment object moment.isMoment = function (obj) { return obj instanceof Moment || - (obj != null && obj.hasOwnProperty('_isAMomentObject')); + (obj != null && hasOwnProp(obj, '_isAMomentObject')); }; // for typechecking Duration objects @@ -40335,8 +43416,12 @@ return jQuery; return m; }; - moment.parseZone = function (input) { - return moment(input).parseZone(); + moment.parseZone = function () { + return moment.apply(null, arguments).parseZone(); + }; + + moment.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); }; /************************************ @@ -40359,7 +43444,7 @@ return jQuery; }, toString : function () { - return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); }, toDate : function () { @@ -40369,7 +43454,12 @@ return jQuery; toISOString : function () { var m = moment(this).utc(); if (0 < m.year() && m.year() <= 9999) { - return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + if ('function' === typeof Date.prototype.toISOString) { + // native implementation is ~50x faster, use it when we can + return this.toDate().toISOString(); + } else { + return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); + } } else { return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); } @@ -40393,7 +43483,6 @@ return jQuery; }, isDSTShifted : function () { - if (this._a) { return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; } @@ -40409,49 +43498,35 @@ return jQuery; return this._pf.overflow; }, - utc : function () { - return this.zone(0); + utc : function (keepLocalTime) { + return this.zone(0, keepLocalTime); }, - local : function () { - this.zone(0); - this._isUTC = false; + local : function (keepLocalTime) { + if (this._isUTC) { + this.zone(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.add(this._dateTzOffset(), 'm'); + } + } return this; }, format : function (inputString) { var output = formatMoment(this, inputString || moment.defaultFormat); - return this.lang().postformat(output); + return this.localeData().postformat(output); }, - add : function (input, val) { - var dur; - // switch args to support add('s', 1) and add(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, 1); - return this; - }, + add : createAdder(1, 'add'), - subtract : function (input, val) { - var dur; - // switch args to support subtract('s', 1) and subtract(1, 's') - if (typeof input === 'string') { - dur = moment.duration(+val, input); - } else { - dur = moment.duration(input, val); - } - addOrSubtractDurationFromMoment(this, dur, -1); - return this; - }, + subtract : createAdder(-1, 'subtract'), diff : function (input, units, asFloat) { var that = makeAs(input, this), zoneDiff = (this.zone() - that.zone()) * 6e4, - diff, output; + diff, output, daysAdjust; units = normalizeUnits(units); @@ -40462,11 +43537,12 @@ return jQuery; output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); // adjust by taking difference in days, average number of days // and dst in the given months. - output += ((this - moment(this).startOf('month')) - - (that - moment(that).startOf('month'))) / diff; + daysAdjust = (this - moment(this).startOf('month')) - + (that - moment(that).startOf('month')); // same as above but with zones, to negate all dst - output -= ((this.zone() - moment(this).startOf('month').zone()) - - (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; + daysAdjust -= ((this.zone() - moment(this).startOf('month').zone()) - + (that.zone() - moment(that).startOf('month').zone())) * 6e4; + output += daysAdjust / diff; if (units === 'year') { output = output / 12; } @@ -40483,17 +43559,18 @@ return jQuery; }, from : function (time, withoutSuffix) { - return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); + return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); }, fromNow : function (withoutSuffix) { return this.from(moment(), withoutSuffix); }, - calendar : function () { + calendar : function (time) { // We want to compare the start of today, vs this. // Getting start-of-today depends on whether we're zone'd or not. - var sod = makeAs(moment(), this).startOf('day'), + var now = time || moment(), + sod = makeAs(now, this).startOf('day'), diff = this.diff(sod, 'days', true), format = diff < -6 ? 'sameElse' : diff < -1 ? 'lastWeek' : @@ -40501,7 +43578,7 @@ return jQuery; diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(this.lang().calendar(format, this)); + return this.format(this.localeData().calendar(format, this, moment(now))); }, isLeapYear : function () { @@ -40516,38 +43593,16 @@ return jQuery; day : function (input) { var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { - input = parseWeekday(input, this.lang()); - return this.add({ d : input - day }); + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); } else { return day; } }, - month : function (input) { - var utc = this._isUTC ? 'UTC' : '', - dayOfMonth; - - if (input != null) { - if (typeof input === 'string') { - input = this.lang().monthsParse(input); - if (typeof input !== 'number') { - return this; - } - } - - dayOfMonth = this.date(); - this.date(1); - this._d['set' + utc + 'Month'](input); - this.date(Math.min(dayOfMonth, this.daysInMonth())); - - moment.updateOffset(this); - return this; - } else { - return this._d['get' + utc + 'Month'](); - } - }, + month : makeAccessor('Month', true), - startOf: function (units) { + startOf : function (units) { units = normalizeUnits(units); // the following switch intentionally omits break keywords // to utilize falling through the cases. @@ -40555,6 +43610,7 @@ return jQuery; case 'year': this.month(0); /* falls through */ + case 'quarter': case 'month': this.date(1); /* falls through */ @@ -40581,65 +43637,124 @@ return jQuery; this.isoWeekday(1); } + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + return this; }, endOf: function (units) { units = normalizeUnits(units); - return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); + if (units === undefined || units === 'millisecond') { + return this; + } + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); }, isAfter: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) > +moment(input).startOf(units); + var inputMs; + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this > +input; + } else { + inputMs = moment.isMoment(input) ? +input : +moment(input); + return inputMs < +this.clone().startOf(units); + } }, isBefore: function (input, units) { - units = typeof units !== 'undefined' ? units : 'millisecond'; - return +this.clone().startOf(units) < +moment(input).startOf(units); + var inputMs; + units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this < +input; + } else { + inputMs = moment.isMoment(input) ? +input : +moment(input); + return +this.clone().endOf(units) < inputMs; + } }, isSame: function (input, units) { - units = units || 'ms'; - return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); - }, - - min: function (other) { - other = moment.apply(null, arguments); - return other < this ? this : other; - }, - - max: function (other) { - other = moment.apply(null, arguments); - return other > this ? this : other; + var inputMs; + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + input = moment.isMoment(input) ? input : moment(input); + return +this === +input; + } else { + inputMs = +moment(input); + return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + } }, - zone : function (input) { - var offset = this._offset || 0; + min: deprecate( + 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other < this ? this : other; + } + ), + + max: deprecate( + 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + function (other) { + other = moment.apply(null, arguments); + return other > this ? this : other; + } + ), + + // keepLocalTime = true means only change the timezone, without + // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]--> + // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone + // +0200, so we adjust the time as needed, to be valid. + // + // Keeping the time actually adds/subtracts (one hour) + // from the actual represented time. That is why we call updateOffset + // a second time. In case it wants us to change the offset again + // _changeInProgress == true case, then we have to adjust, because + // there is no such time in the given timezone. + zone : function (input, keepLocalTime) { + var offset = this._offset || 0, + localAdjust; if (input != null) { - if (typeof input === "string") { + if (typeof input === 'string') { input = timezoneMinutesFromString(input); } if (Math.abs(input) < 16) { input = input * 60; } + if (!this._isUTC && keepLocalTime) { + localAdjust = this._dateTzOffset(); + } this._offset = input; this._isUTC = true; + if (localAdjust != null) { + this.subtract(localAdjust, 'm'); + } if (offset !== input) { - addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true); + if (!keepLocalTime || this._changeInProgress) { + addOrSubtractDurationFromMoment(this, + moment.duration(offset - input, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + moment.updateOffset(this, true); + this._changeInProgress = null; + } } } else { - return this._isUTC ? offset : this._d.getTimezoneOffset(); + return this._isUTC ? offset : this._dateTzOffset(); } return this; }, zoneAbbr : function () { - return this._isUTC ? "UTC" : ""; + return this._isUTC ? 'UTC' : ''; }, zoneName : function () { - return this._isUTC ? "Coordinated Universal Time" : ""; + return this._isUTC ? 'Coordinated Universal Time' : ''; }, parseZone : function () { @@ -40668,36 +43783,36 @@ return jQuery; dayOfYear : function (input) { var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); }, - quarter : function () { - return Math.ceil((this.month() + 1.0) / 3.0); + quarter : function (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); }, weekYear : function (input) { - var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; - return input == null ? year : this.add("y", (input - year)); + var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; + return input == null ? year : this.add((input - year), 'y'); }, isoWeekYear : function (input) { var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add("y", (input - year)); + return input == null ? year : this.add((input - year), 'y'); }, week : function (input) { - var week = this.lang().week(this); - return input == null ? week : this.add("d", (input - week) * 7); + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); }, isoWeek : function (input) { var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add("d", (input - week) * 7); + return input == null ? week : this.add((input - week) * 7, 'd'); }, weekday : function (input) { - var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; - return input == null ? weekday : this.add("d", input - weekday); + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); }, isoWeekday : function (input) { @@ -40707,6 +43822,15 @@ return jQuery; return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); }, + isoWeeksInYear : function () { + return weeksInYear(this.year(), 1, 4); + }, + + weeksInYear : function () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); + }, + get : function (units) { units = normalizeUnits(units); return this[units](); @@ -40720,46 +43844,107 @@ return jQuery; return this; }, - // If passed a language key, it will set the language for this - // instance. Otherwise, it will return the language configuration + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration // variables for this instance. - lang : function (key) { + locale : function (key) { + var newLocaleData; + if (key === undefined) { - return this._lang; + return this._locale._abbr; } else { - this._lang = getLangDefinition(key); + newLocaleData = moment.localeData(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } return this; } + }, + + lang : deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } + ), + + localeData : function () { + return this._locale; + }, + + _dateTzOffset : function () { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return Math.round(this._d.getTimezoneOffset() / 15) * 15; } }); - // helper for adding shortcuts - function makeGetterAndSetter(name, key) { - moment.fn[name] = moment.fn[name + 's'] = function (input) { - var utc = this._isUTC ? 'UTC' : ''; - if (input != null) { - this._d['set' + utc + key](input); - moment.updateOffset(this); + function rawMonthSetter(mom, value) { + var dayOfMonth; + + // TODO: Move this out of here! + if (typeof value === 'string') { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } + } + + dayOfMonth = Math.min(mom.date(), + daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; + } + + function rawGetter(mom, unit) { + return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); + } + + function rawSetter(mom, unit, value) { + if (unit === 'Month') { + return rawMonthSetter(mom, value); + } else { + return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } + + function makeAccessor(unit, keepTime) { + return function (value) { + if (value != null) { + rawSetter(this, unit, value); + moment.updateOffset(this, keepTime); return this; } else { - return this._d['get' + utc + key](); + return rawGetter(this, unit); } }; } - // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) - for (i = 0; i < proxyGettersAndSetters.length; i ++) { - makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); - } - - // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') - makeGetterAndSetter('year', 'FullYear'); + moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false); + moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false); + moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false); + // Setting the hour should keep the time, because the user explicitly + // specified which hour he wants. So trying to maintain the same hour (in + // a new timezone) makes sense. Adding/subtracting hours does not follow + // this rule. + moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true); + // moment.fn.month is defined separately + moment.fn.date = makeAccessor('Date', true); + moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true)); + moment.fn.year = makeAccessor('FullYear', true); + moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true)); // add plural methods moment.fn.days = moment.fn.day; moment.fn.months = moment.fn.month; moment.fn.weeks = moment.fn.week; moment.fn.isoWeeks = moment.fn.isoWeek; + moment.fn.quarters = moment.fn.quarter; // add aliased format methods moment.fn.toJSON = moment.fn.toISOString; @@ -40769,6 +43954,17 @@ return jQuery; ************************************/ + function daysToYears (days) { + // 400 years have 146097 days (taking into account leap year rules) + return days * 400 / 146097; + } + + function yearsToDays (years) { + // years * 365 + absRound(years / 4) - + // absRound(years / 100) + absRound(years / 400); + return years * 146097 / 400; + } + extend(moment.duration.fn = Duration.prototype, { _bubble : function () { @@ -40776,7 +43972,7 @@ return jQuery; days = this._days, months = this._months, data = this._data, - seconds, minutes, hours, years; + seconds, minutes, hours, years = 0; // The following code bubbles up values, see the tests for // examples of what that means. @@ -40792,15 +43988,40 @@ return jQuery; data.hours = hours % 24; days += absRound(hours / 24); - data.days = days % 30; + // Accurately convert days to years, assume start from year 0. + years = absRound(daysToYears(days)); + days -= absRound(yearsToDays(years)); + + // 30 days to a month + // TODO (iskren): Use anchor date (like 1st Jan) to compute this. months += absRound(days / 30); - data.months = months % 12; + days %= 30; + + // 12 months -> 1 year + years += absRound(months / 12); + months %= 12; - years = absRound(months / 12); + data.days = days; + data.months = months; data.years = years; }, + abs : function () { + this._milliseconds = Math.abs(this._milliseconds); + this._days = Math.abs(this._days); + this._months = Math.abs(this._months); + + this._data.milliseconds = Math.abs(this._data.milliseconds); + this._data.seconds = Math.abs(this._data.seconds); + this._data.minutes = Math.abs(this._data.minutes); + this._data.hours = Math.abs(this._data.hours); + this._data.months = Math.abs(this._data.months); + this._data.years = Math.abs(this._data.years); + + return this; + }, + weeks : function () { return absRound(this.days() / 7); }, @@ -40813,14 +44034,13 @@ return jQuery; }, humanize : function (withSuffix) { - var difference = +this, - output = relativeTime(difference, !withSuffix, this.lang()); + var output = relativeTime(this, !withSuffix, this.localeData()); if (withSuffix) { - output = this.lang().pastFuture(difference, output); + output = this.localeData().pastFuture(+this, output); } - return this.lang().postformat(output); + return this.localeData().postformat(output); }, add : function (input, val) { @@ -40854,13 +44074,41 @@ return jQuery; }, as : function (units) { + var days, months; units = normalizeUnits(units); - return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); + + if (units === 'month' || units === 'year') { + days = this._days + this._milliseconds / 864e5; + months = this._months + daysToYears(days) * 12; + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(yearsToDays(this._months / 12)); + switch (units) { + case 'week': return days / 7 + this._milliseconds / 6048e5; + case 'day': return days + this._milliseconds / 864e5; + case 'hour': return days * 24 + this._milliseconds / 36e5; + case 'minute': return days * 24 * 60 + this._milliseconds / 6e4; + case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } }, lang : moment.fn.lang, + locale : moment.fn.locale, + + toIsoString : deprecate( + 'toIsoString() is deprecated. Please use toISOString() instead ' + + '(notice the capitals)', + function () { + return this.toISOString(); + } + ), - toIsoString : function () { + toISOString : function () { // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js var years = Math.abs(this.years()), months = Math.abs(this.months()), @@ -40884,41 +44132,60 @@ return jQuery; (hours ? hours + 'H' : '') + (minutes ? minutes + 'M' : '') + (seconds ? seconds + 'S' : ''); + }, + + localeData : function () { + return this._locale; } }); + moment.duration.fn.toString = moment.duration.fn.toISOString; + function makeDurationGetter(name) { moment.duration.fn[name] = function () { return this._data[name]; }; } - function makeDurationAsGetter(name, factor) { - moment.duration.fn['as' + name] = function () { - return +this / factor; - }; - } - for (i in unitMillisecondFactors) { - if (unitMillisecondFactors.hasOwnProperty(i)) { - makeDurationAsGetter(i, unitMillisecondFactors[i]); + if (hasOwnProp(unitMillisecondFactors, i)) { makeDurationGetter(i.toLowerCase()); } } - makeDurationAsGetter('Weeks', 6048e5); + moment.duration.fn.asMilliseconds = function () { + return this.as('ms'); + }; + moment.duration.fn.asSeconds = function () { + return this.as('s'); + }; + moment.duration.fn.asMinutes = function () { + return this.as('m'); + }; + moment.duration.fn.asHours = function () { + return this.as('h'); + }; + moment.duration.fn.asDays = function () { + return this.as('d'); + }; + moment.duration.fn.asWeeks = function () { + return this.as('weeks'); + }; moment.duration.fn.asMonths = function () { - return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; + return this.as('M'); + }; + moment.duration.fn.asYears = function () { + return this.as('y'); }; - /************************************ - Default Lang + Default Locale ************************************/ - // Set default language, other languages will inherit from English. - moment.lang('en', { + // Set default locale, other locale will inherit from English. + moment.locale('en', { + ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal : function (number) { var b = number % 10, output = (toInt(number % 100 / 10) === 1) ? 'th' : @@ -40929,61 +44196,52 @@ return jQuery; } }); - /* EMBED_LANGUAGES */ + /* EMBED_LOCALES */ /************************************ Exposing Moment ************************************/ - function makeGlobal(deprecate) { - var warned = false, local_moment = moment; + function makeGlobal(shouldDeprecate) { /*global ender:false */ if (typeof ender !== 'undefined') { return; } - // here, `this` means `window` in the browser, or `global` on the server - // add `moment` as a global object via a string identifier, - // for Closure Compiler "advanced" mode - if (deprecate) { - global.moment = function () { - if (!warned && console && console.warn) { - warned = true; - console.warn( - "Accessing Moment through the global scope is " + - "deprecated, and will be removed in an upcoming " + - "release."); - } - return local_moment.apply(null, arguments); - }; - extend(global.moment, local_moment); + oldGlobalMoment = globalScope.moment; + if (shouldDeprecate) { + globalScope.moment = deprecate( + 'Accessing Moment through the global scope is ' + + 'deprecated, and will be removed in an upcoming ' + + 'release.', + moment); } else { - global['moment'] = moment; + globalScope.moment = moment; } } // CommonJS module is defined if (hasModule) { module.exports = moment; - makeGlobal(true); - } else if (typeof define === "function" && define.amd) { - define("moment", function (require, exports, module) { - if (module.config && module.config() && module.config().noGlobal !== true) { - // If user provided noGlobal, he is aware of global - makeGlobal(module.config().noGlobal === undefined); + } else if (typeof define === 'function' && define.amd) { + define('moment', function (require, exports, module) { + if (module.config && module.config() && module.config().noGlobal === true) { + // release the global variable + globalScope.moment = oldGlobalMoment; } return moment; }); + makeGlobal(true); } else { makeGlobal(); } }).call(this); -},{}],42:[function(require,module,exports){ +},{}],55:[function(require,module,exports){ module.exports = require('./lib/'); -},{"./lib/":43}],43:[function(require,module,exports){ +},{"./lib/":56}],56:[function(require,module,exports){ /** * Module dependencies. @@ -41072,7 +44330,7 @@ exports.connect = lookup; exports.Manager = require('./manager'); exports.Socket = require('./socket'); -},{"./manager":44,"./socket":46,"./url":47,"debug":50,"socket.io-parser":81}],44:[function(require,module,exports){ +},{"./manager":57,"./socket":59,"./url":60,"debug":63,"socket.io-parser":97}],57:[function(require,module,exports){ /** * Module dependencies. @@ -41087,6 +44345,7 @@ var on = require('./on'); var bind = require('component-bind'); var object = require('object-component'); var debug = require('debug')('socket.io-client:manager'); +var indexOf = require('indexof'); /** * Module exports @@ -41121,7 +44380,7 @@ function Manager(uri, opts){ this.timeout(null == opts.timeout ? 20000 : opts.timeout); this.readyState = 'closed'; this.uri = uri; - this.connected = 0; + this.connected = []; this.attempts = 0; this.encoding = false; this.packetBuffer = []; @@ -41254,6 +44513,7 @@ Manager.prototype.connect = function(fn){ var socket = this.engine; var self = this; this.readyState = 'opening'; + this.skipReconnect = false; // emit `open` var openSub = on(socket, 'open', function() { @@ -41372,7 +44632,9 @@ Manager.prototype.socket = function(nsp){ this.nsps[nsp] = socket; var self = this; socket.on('connect', function(){ - self.connected++; + if (!~indexOf(self.connected, socket)) { + self.connected.push(socket); + } }); } return socket; @@ -41385,7 +44647,11 @@ Manager.prototype.socket = function(nsp){ */ Manager.prototype.destroy = function(socket){ - --this.connected || this.close(); + var index = indexOf(this.connected, socket); + if (~index) this.connected.splice(index, 1); + if (this.connected.length) return; + + this.close(); }; /** @@ -41453,7 +44719,8 @@ Manager.prototype.cleanup = function(){ Manager.prototype.close = Manager.prototype.disconnect = function(){ this.skipReconnect = true; - this.engine.close(); + this.readyState = 'closed'; + this.engine && this.engine.close(); }; /** @@ -41479,7 +44746,7 @@ Manager.prototype.onclose = function(reason){ */ Manager.prototype.reconnect = function(){ - if (this.reconnecting) return this; + if (this.reconnecting || this.skipReconnect) return this; var self = this; this.attempts++; @@ -41495,9 +44762,15 @@ Manager.prototype.reconnect = function(){ this.reconnecting = true; var timer = setTimeout(function(){ + if (self.skipReconnect) return; + debug('attempting reconnect'); self.emitAll('reconnect_attempt', self.attempts); self.emitAll('reconnecting', self.attempts); + + // check again for the case socket closed in above events + if (self.skipReconnect) return; + self.open(function(err){ if (err) { debug('reconnect attempt error'); @@ -41532,7 +44805,7 @@ Manager.prototype.onreconnect = function(){ this.emitAll('reconnect', attempt); }; -},{"./on":45,"./socket":46,"./url":47,"component-bind":48,"component-emitter":49,"debug":50,"engine.io-client":51,"object-component":78,"socket.io-parser":81}],45:[function(require,module,exports){ +},{"./on":58,"./socket":59,"./url":60,"component-bind":61,"component-emitter":62,"debug":63,"engine.io-client":64,"indexof":93,"object-component":94,"socket.io-parser":97}],58:[function(require,module,exports){ /** * Module exports. @@ -41558,7 +44831,7 @@ function on(obj, ev, fn) { }; } -},{}],46:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ /** * Module dependencies. @@ -41571,7 +44844,6 @@ var on = require('./on'); var bind = require('component-bind'); var debug = require('debug')('socket.io-client:socket'); var hasBin = require('has-binary'); -var indexOf = require('indexof'); /** * Module exports. @@ -41622,7 +44894,6 @@ function Socket(io, nsp){ this.sendBuffer = []; this.connected = false; this.disconnected = true; - this.subEvents(); } /** @@ -41638,6 +44909,8 @@ Emitter(Socket.prototype); */ Socket.prototype.subEvents = function() { + if (this.subs) return; + var io = this.io; this.subs = [ on(io, 'open', bind(this, 'onopen')), @@ -41647,15 +44920,16 @@ Socket.prototype.subEvents = function() { }; /** - * Called upon engine `open`. + * "Opens" the socket. * - * @api private + * @api public */ Socket.prototype.open = Socket.prototype.connect = function(){ if (this.connected) return this; + this.subEvents(); this.io.open(); // ensure open if ('open' == this.io.readyState) this.onopen(); return this; @@ -41724,7 +44998,7 @@ Socket.prototype.packet = function(packet){ }; /** - * "Opens" the socket. + * Called upon engine `open`. * * @api private */ @@ -41908,9 +45182,12 @@ Socket.prototype.ondisconnect = function(){ */ Socket.prototype.destroy = function(){ - // clean subscriptions to avoid reconnections - for (var i = 0; i < this.subs.length; i++) { - this.subs[i].destroy(); + if (this.subs) { + // clean subscriptions to avoid reconnections + for (var i = 0; i < this.subs.length; i++) { + this.subs[i].destroy(); + } + this.subs = null; } this.io.destroy(this); @@ -41925,22 +45202,23 @@ Socket.prototype.destroy = function(){ Socket.prototype.close = Socket.prototype.disconnect = function(){ - if (!this.connected) return this; - - debug('performing disconnect (%s)', this.nsp); - this.packet({ type: parser.DISCONNECT }); + if (this.connected) { + debug('performing disconnect (%s)', this.nsp); + this.packet({ type: parser.DISCONNECT }); + } // remove socket from pool this.destroy(); - // fire events - this.onclose('io client disconnect'); + if (this.connected) { + // fire events + this.onclose('io client disconnect'); + } return this; }; -},{"./on":45,"component-bind":48,"component-emitter":49,"debug":50,"has-binary":75,"indexof":77,"socket.io-parser":81,"to-array":85}],47:[function(require,module,exports){ -(function (global){ - +},{"./on":58,"component-bind":61,"component-emitter":62,"debug":63,"has-binary":91,"socket.io-parser":97,"to-array":101}],60:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /** * Module dependencies. */ @@ -41973,7 +45251,9 @@ function url(uri, loc){ // relative path support if ('string' == typeof uri) { if ('/' == uri.charAt(0)) { - if ('undefined' != typeof loc) { + if ('/' == uri.charAt(1)) { + uri = loc.protocol + uri; + } else { uri = loc.hostname + uri; } } @@ -42012,8 +45292,7 @@ function url(uri, loc){ return obj; } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"debug":50,"parseuri":79}],48:[function(require,module,exports){ +},{"debug":63,"parseuri":95}],61:[function(require,module,exports){ /** * Slice reference. */ @@ -42038,7 +45317,7 @@ module.exports = function(obj, fn){ } }; -},{}],49:[function(require,module,exports){ +},{}],62:[function(require,module,exports){ /** * Expose `Emitter`. @@ -42204,7 +45483,7 @@ Emitter.prototype.hasListeners = function(event){ return !! this.listeners(event).length; }; -},{}],50:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ /** * Expose `debug()` as the module. @@ -42343,11 +45622,11 @@ try { if (window.localStorage) debug.enable(localStorage.debug); } catch(e){} -},{}],51:[function(require,module,exports){ +},{}],64:[function(require,module,exports){ module.exports = require('./lib/'); -},{"./lib/":52}],52:[function(require,module,exports){ +},{"./lib/":65}],65:[function(require,module,exports){ module.exports = require('./socket'); @@ -42359,9 +45638,8 @@ module.exports = require('./socket'); */ module.exports.parser = require('engine.io-parser'); -},{"./socket":53,"engine.io-parser":62}],53:[function(require,module,exports){ -(function (global){ -/** +},{"./socket":66,"engine.io-parser":78}],66:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies. */ @@ -42626,14 +45904,13 @@ Socket.prototype.probe = function (name) { debug('probe transport "%s" pong', name); self.upgrading = true; self.emit('upgrading', transport); + if (!transport) return; Socket.priorWebsocketSuccess = 'websocket' == transport.name; debug('pausing current transport "%s"', self.transport.name); self.transport.pause(function () { if (failed) return; - if ('closed' == self.readyState || 'closing' == self.readyState) { - return; - } + if ('closed' == self.readyState) return; debug('changing transport and sending upgrade packet'); cleanup(); @@ -42915,6 +46192,10 @@ Socket.prototype.send = function (msg, fn) { */ Socket.prototype.sendPacket = function (type, data, fn) { + if ('closing' == this.readyState || 'closed' == this.readyState) { + return; + } + var packet = { type: type, data: data }; this.emit('packetCreate', packet); this.writeBuffer.push(packet); @@ -42930,9 +46211,41 @@ Socket.prototype.sendPacket = function (type, data, fn) { Socket.prototype.close = function () { if ('opening' == this.readyState || 'open' == this.readyState) { - this.onClose('forced close'); - debug('socket closing - telling transport to close'); - this.transport.close(); + this.readyState = 'closing'; + + var self = this; + + function close() { + self.onClose('forced close'); + debug('socket closing - telling transport to close'); + self.transport.close(); + } + + function cleanupAndClose() { + self.removeListener('upgrade', cleanupAndClose); + self.removeListener('upgradeError', cleanupAndClose); + close(); + } + + function waitForUpgrade() { + // wait for upgrade to finish since we can't send packets while pausing a transport + self.once('upgrade', cleanupAndClose); + self.once('upgradeError', cleanupAndClose); + } + + if (this.writeBuffer.length) { + this.once('drain', function() { + if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + }); + } else if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } } return this; @@ -42958,7 +46271,7 @@ Socket.prototype.onError = function (err) { */ Socket.prototype.onClose = function (reason, desc) { - if ('opening' == this.readyState || 'open' == this.readyState) { + if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) { debug('socket close with reason: "%s"', reason); var self = this; @@ -43010,8 +46323,7 @@ Socket.prototype.filterUpgrades = function (upgrades) { return filteredUpgrades; }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./transport":54,"./transports":55,"component-emitter":49,"debug":50,"engine.io-parser":62,"indexof":77,"parsejson":71,"parseqs":72,"parseuri":73}],54:[function(require,module,exports){ +},{"./transport":67,"./transports":68,"component-emitter":62,"debug":75,"engine.io-parser":78,"indexof":93,"parsejson":87,"parseqs":88,"parseuri":89}],67:[function(require,module,exports){ /** * Module dependencies. */ @@ -43163,9 +46475,8 @@ Transport.prototype.onClose = function () { this.emit('close'); }; -},{"component-emitter":49,"engine.io-parser":62}],55:[function(require,module,exports){ -(function (global){ -/** +},{"component-emitter":62,"engine.io-parser":78}],68:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies */ @@ -43219,10 +46530,8 @@ function polling(opts){ } } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling-jsonp":56,"./polling-xhr":57,"./websocket":59,"xmlhttprequest":60}],56:[function(require,module,exports){ -(function (global){ - +},{"./polling-jsonp":69,"./polling-xhr":70,"./websocket":72,"xmlhttprequest":73}],69:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /** * Module requirements. */ @@ -43297,7 +46606,7 @@ function JSONPPolling (opts) { if (global.document && global.addEventListener) { global.addEventListener('beforeunload', function () { if (self.script) self.script.onerror = empty; - }); + }, false); } } @@ -43328,6 +46637,7 @@ JSONPPolling.prototype.doClose = function () { if (this.form) { this.form.parentNode.removeChild(this.form); this.form = null; + this.iframe = null; } Polling.prototype.doClose.call(this); @@ -43455,10 +46765,8 @@ JSONPPolling.prototype.doWrite = function (data, fn) { } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling":58,"component-inherit":61}],57:[function(require,module,exports){ -(function (global){ -/** +},{"./polling":71,"component-inherit":74}],70:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module requirements. */ @@ -43747,7 +47055,7 @@ Request.prototype.onLoad = function(){ try { var contentType; try { - contentType = this.xhr.getResponseHeader('Content-Type'); + contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0]; } catch (e) {} if (contentType === 'application/octet-stream') { data = this.xhr.response; @@ -43798,7 +47106,7 @@ if (global.document) { if (global.attachEvent) { global.attachEvent('onunload', unloadHandler); } else if (global.addEventListener) { - global.addEventListener('beforeunload', unloadHandler); + global.addEventListener('beforeunload', unloadHandler, false); } } @@ -43810,8 +47118,7 @@ function unloadHandler() { } } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./polling":58,"component-emitter":49,"component-inherit":61,"debug":50,"xmlhttprequest":60}],58:[function(require,module,exports){ +},{"./polling":71,"component-emitter":62,"component-inherit":74,"debug":75,"xmlhttprequest":73}],71:[function(require,module,exports){ /** * Module dependencies. */ @@ -43834,7 +47141,7 @@ module.exports = Polling; var hasXHR2 = (function() { var XMLHttpRequest = require('xmlhttprequest'); - var xhr = new XMLHttpRequest({ agent: this.agent, xdomain: false }); + var xhr = new XMLHttpRequest({ xdomain: false }); return null != xhr.responseType; })(); @@ -44058,7 +47365,7 @@ Polling.prototype.uri = function(){ return schema + '://' + this.hostname + port + this.path + query; }; -},{"../transport":54,"component-inherit":61,"debug":50,"engine.io-parser":62,"parseqs":72,"xmlhttprequest":60}],59:[function(require,module,exports){ +},{"../transport":67,"component-inherit":74,"debug":75,"engine.io-parser":78,"parseqs":88,"xmlhttprequest":73}],72:[function(require,module,exports){ /** * Module dependencies. */ @@ -44289,7 +47596,7 @@ WS.prototype.check = function(){ return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name); }; -},{"../transport":54,"component-inherit":61,"debug":50,"engine.io-parser":62,"parseqs":72,"ws":74}],60:[function(require,module,exports){ +},{"../transport":67,"component-inherit":74,"debug":75,"engine.io-parser":78,"parseqs":88,"ws":90}],73:[function(require,module,exports){ // browser shim for xmlhttprequest module var hasCORS = require('has-cors'); @@ -44304,6 +47611,13 @@ module.exports = function(opts) { // https://github.com/Automattic/engine.io-client/pull/217 var enablesXDR = opts.enablesXDR; + // XMLHttpRequest can be disabled on IE + try { + if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) { + return new XMLHttpRequest(); + } + } catch (e) { } + // Use XDomainRequest for IE8 if enablesXDR is true // because loading bar keeps flashing when using jsonp-polling // https://github.com/yujiosaka/socke.io-ie8-loading-example @@ -44313,13 +47627,6 @@ module.exports = function(opts) { } } catch (e) { } - // XMLHttpRequest can be disabled on IE - try { - if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) { - return new XMLHttpRequest(); - } - } catch (e) { } - if (!xdomain) { try { return new ActiveXObject('Microsoft.XMLHTTP'); @@ -44327,7 +47634,7 @@ module.exports = function(opts) { } } -},{"has-cors":69}],61:[function(require,module,exports){ +},{"has-cors":85}],74:[function(require,module,exports){ module.exports = function(a, b){ var fn = function(){}; @@ -44335,9 +47642,469 @@ module.exports = function(a, b){ a.prototype = new fn; a.prototype.constructor = a; }; -},{}],62:[function(require,module,exports){ -(function (global){ +},{}],75:[function(require,module,exports){ + +/** + * This is the web browser implementation of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = require('./debug'); +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; + +/** + * Colors. + */ + +exports.colors = [ + 'lightseagreen', + 'forestgreen', + 'goldenrod', + 'dodgerblue', + 'darkorchid', + 'crimson' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +function useColors() { + // is webkit? http://stackoverflow.com/a/16459606/376773 + return ('WebkitAppearance' in document.documentElement.style) || + // is firebug? http://stackoverflow.com/a/398120/376773 + (window.console && (console.firebug || (console.exception && console.table))) || + // is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); +} + /** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +exports.formatters.j = function(v) { + return JSON.stringify(v); +}; + + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs() { + var args = arguments; + var useColors = this.useColors; + + args[0] = (useColors ? '%c' : '') + + this.namespace + + (useColors ? ' %c' : ' ') + + args[0] + + (useColors ? '%c ' : ' ') + + '+' + exports.humanize(this.diff); + + if (!useColors) return args; + + var c = 'color: ' + this.color; + args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); + + // the final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + var index = 0; + var lastC = 0; + args[0].replace(/%[a-z%]/g, function(match) { + if ('%%' === match) return; + index++; + if ('%c' === match) { + // we only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); + return args; +} + +/** + * Invokes `console.log()` when available. + * No-op when `console.log` is not a "function". + * + * @api public + */ + +function log() { + // This hackery is required for IE8, + // where the `console.log` function doesn't have 'apply' + return 'object' == typeof console + && 'function' == typeof console.log + && Function.prototype.apply.call(console.log, console, arguments); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + +function save(namespaces) { + try { + if (null == namespaces) { + localStorage.removeItem('debug'); + } else { + localStorage.debug = namespaces; + } + } catch(e) {} +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + var r; + try { + r = localStorage.debug; + } catch(e) {} + return r; +} + +/** + * Enable namespaces listed in `localStorage.debug` initially. + */ + +exports.enable(load()); + +},{"./debug":76}],76:[function(require,module,exports){ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + * + * Expose `debug()` as the module. + */ + +exports = module.exports = debug; +exports.coerce = coerce; +exports.disable = disable; +exports.enable = enable; +exports.enabled = enabled; +exports.humanize = require('ms'); + +/** + * The currently active debug mode names, and names to skip. + */ + +exports.names = []; +exports.skips = []; + +/** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lowercased letter, i.e. "n". + */ + +exports.formatters = {}; + +/** + * Previously assigned color. + */ + +var prevColor = 0; + +/** + * Previous log timestamp. + */ + +var prevTime; + +/** + * Select a color. + * + * @return {Number} + * @api private + */ + +function selectColor() { + return exports.colors[prevColor++ % exports.colors.length]; +} + +/** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + +function debug(namespace) { + + // define the `disabled` version + function disabled() { + } + disabled.enabled = false; + + // define the `enabled` version + function enabled() { + + var self = enabled; + + // set `diff` timestamp + var curr = +new Date(); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + // add the `color` if not set + if (null == self.useColors) self.useColors = exports.useColors(); + if (null == self.color && self.useColors) self.color = selectColor(); + + var args = Array.prototype.slice.call(arguments); + + args[0] = exports.coerce(args[0]); + + if ('string' !== typeof args[0]) { + // anything else let's inspect with %o + args = ['%o'].concat(args); + } + + // apply any `formatters` transformations + var index = 0; + args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { + // if we encounter an escaped % then don't increase the array index + if (match === '%%') return match; + index++; + var formatter = exports.formatters[format]; + if ('function' === typeof formatter) { + var val = args[index]; + match = formatter.call(self, val); + + // now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + if ('function' === typeof exports.formatArgs) { + args = exports.formatArgs.apply(self, args); + } + var logFn = enabled.log || exports.log || console.log.bind(console); + logFn.apply(self, args); + } + enabled.enabled = true; + + var fn = exports.enabled(namespace) ? enabled : disabled; + + fn.namespace = namespace; + + return fn; +} + +/** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + +function enable(namespaces) { + exports.save(namespaces); + + var split = (namespaces || '').split(/[\s,]+/); + var len = split.length; + + for (var i = 0; i < len; i++) { + if (!split[i]) continue; // ignore empty strings + namespaces = split[i].replace(/\*/g, '.*?'); + if (namespaces[0] === '-') { + exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + exports.names.push(new RegExp('^' + namespaces + '$')); + } + } +} + +/** + * Disable debug output. + * + * @api public + */ + +function disable() { + exports.enable(''); +} + +/** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + +function enabled(name) { + var i, len; + for (i = 0, len = exports.skips.length; i < len; i++) { + if (exports.skips[i].test(name)) { + return false; + } + } + for (i = 0, len = exports.names.length; i < len; i++) { + if (exports.names[i].test(name)) { + return true; + } + } + return false; +} + +/** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function coerce(val) { + if (val instanceof Error) return val.stack || val.message; + return val; +} + +},{"ms":77}],77:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @param {String|Number} val + * @param {Object} options + * @return {String|Number} + * @api public + */ + +module.exports = function(val, options){ + options = options || {}; + if ('string' == typeof val) return parse(val); + return options.long + ? long(val) + : short(val); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @param {String} str + * @return {Number} + * @api private + */ + +function parse(str) { + var match = /^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i.exec(str); + if (!match) return; + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 's': + return n * s; + case 'ms': + return n; + } +} + +/** + * Short format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function short(ms) { + if (ms >= d) return Math.round(ms / d) + 'd'; + if (ms >= h) return Math.round(ms / h) + 'h'; + if (ms >= m) return Math.round(ms / m) + 'm'; + if (ms >= s) return Math.round(ms / s) + 's'; + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private + */ + +function long(ms) { + return plural(ms, d, 'day') + || plural(ms, h, 'hour') + || plural(ms, m, 'minute') + || plural(ms, s, 'second') + || ms + ' ms'; +} + +/** + * Pluralization helper. + */ + +function plural(ms, n, name) { + if (ms < n) return; + if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; + return Math.ceil(ms / n) + ' ' + name + 's'; +} + +},{}],78:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Module dependencies. */ @@ -44904,8 +48671,7 @@ exports.decodePayloadAsBinary = function (data, binaryType, callback) { }); }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./keys":63,"after":64,"arraybuffer.slice":65,"base64-arraybuffer":66,"blob":67,"utf8":68}],63:[function(require,module,exports){ +},{"./keys":79,"after":80,"arraybuffer.slice":81,"base64-arraybuffer":82,"blob":83,"utf8":84}],79:[function(require,module,exports){ /** * Gets the keys for an object. @@ -44926,7 +48692,7 @@ module.exports = Object.keys || function keys (obj){ return arr; }; -},{}],64:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ module.exports = after function after(count, callback, err_cb) { @@ -44956,7 +48722,7 @@ function after(count, callback, err_cb) { function noop() {} -},{}],65:[function(require,module,exports){ +},{}],81:[function(require,module,exports){ /** * An abstraction for slicing an arraybuffer even when * ArrayBuffer.prototype.slice is not supported @@ -44987,7 +48753,7 @@ module.exports = function(arraybuffer, start, end) { return result.buffer; }; -},{}],66:[function(require,module,exports){ +},{}],82:[function(require,module,exports){ /* * base64-arraybuffer * https://github.com/niklasvh/base64-arraybuffer @@ -45048,9 +48814,8 @@ module.exports = function(arraybuffer, start, end) { }; })("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); -},{}],67:[function(require,module,exports){ -(function (global){ -/** +},{}],83:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * Create a blob builder even when vendor prefixes exist */ @@ -45100,10 +48865,8 @@ module.exports = (function() { } })(); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],68:[function(require,module,exports){ -(function (global){ -/*! http://mths.be/utf8js v2.0.0 by @mathias */ +},{}],84:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/*! http://mths.be/utf8js v2.0.0 by @mathias */ ;(function(root) { // Detect free variables `exports` @@ -45343,8 +49106,7 @@ module.exports = (function() { }(this)); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],69:[function(require,module,exports){ +},{}],85:[function(require,module,exports){ /** * Module dependencies. @@ -45369,7 +49131,7 @@ try { module.exports = false; } -},{"global":70}],70:[function(require,module,exports){ +},{"global":86}],86:[function(require,module,exports){ /** * Returns `this`. Execute this without a "context" (i.e. without it being @@ -45379,9 +49141,8 @@ try { module.exports = (function () { return this; })(); -},{}],71:[function(require,module,exports){ -(function (global){ -/** +},{}],87:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * JSON parse. * * @see Based on jQuery#parseJSON (MIT) and JSON2 @@ -45413,8 +49174,7 @@ module.exports = function parsejson(data) { return (new Function('return ' + data))(); } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],72:[function(require,module,exports){ +},{}],88:[function(require,module,exports){ /** * Compiles a querystring * Returns string representation of the object @@ -45453,7 +49213,7 @@ exports.decode = function(qs){ return qry; }; -},{}],73:[function(require,module,exports){ +},{}],89:[function(require,module,exports){ /** * Parses an URI * @@ -45494,7 +49254,7 @@ module.exports = function parseuri(str) { return uri; }; -},{}],74:[function(require,module,exports){ +},{}],90:[function(require,module,exports){ /** * Module dependencies. @@ -45539,9 +49299,8 @@ function ws(uri, protocols, opts) { if (WebSocket) ws.prototype = WebSocket.prototype; -},{}],75:[function(require,module,exports){ -(function (global){ - +},{}],91:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; /* * Module requirements. */ @@ -45600,13 +49359,12 @@ function hasBinary(data) { return _hasBinary(data); } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"isarray":76}],76:[function(require,module,exports){ +},{"isarray":92}],92:[function(require,module,exports){ module.exports = Array.isArray || function (arr) { return Object.prototype.toString.call(arr) == '[object Array]'; }; -},{}],77:[function(require,module,exports){ +},{}],93:[function(require,module,exports){ var indexOf = [].indexOf; @@ -45617,7 +49375,7 @@ module.exports = function(arr, obj){ } return -1; }; -},{}],78:[function(require,module,exports){ +},{}],94:[function(require,module,exports){ /** * HOP ref. @@ -45702,7 +49460,7 @@ exports.length = function(obj){ exports.isEmpty = function(obj){ return 0 == exports.length(obj); }; -},{}],79:[function(require,module,exports){ +},{}],95:[function(require,module,exports){ /** * Parses an URI * @@ -45729,9 +49487,8 @@ module.exports = function parseuri(str) { return uri; }; -},{}],80:[function(require,module,exports){ -(function (global){ -/*global Blob,File*/ +},{}],96:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/*global Blob,File*/ /** * Module requirements @@ -45873,8 +49630,7 @@ exports.removeBlobs = function(data, callback) { } }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./is-buffer":82,"isarray":83}],81:[function(require,module,exports){ +},{"./is-buffer":98,"isarray":99}],97:[function(require,module,exports){ /** * Module dependencies. @@ -46272,9 +50028,8 @@ function error(data){ }; } -},{"./binary":80,"./is-buffer":82,"component-emitter":49,"debug":50,"isarray":83,"json3":84}],82:[function(require,module,exports){ -(function (global){ - +},{"./binary":96,"./is-buffer":98,"component-emitter":62,"debug":63,"isarray":99,"json3":100}],98:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}; module.exports = isBuf; /** @@ -46288,10 +50043,9 @@ function isBuf(obj) { (global.ArrayBuffer && obj instanceof ArrayBuffer); } -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],83:[function(require,module,exports){ -module.exports=require(76) -},{}],84:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ +module.exports=require(92) +},{}],100:[function(require,module,exports){ /*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */ ;(function (window) { // Convenience aliases. @@ -47154,7 +50908,7 @@ module.exports=require(76) } }(this)); -},{}],85:[function(require,module,exports){ +},{}],101:[function(require,module,exports){ module.exports = toArray function toArray(list, index) { @@ -47169,7 +50923,7 @@ function toArray(list, index) { return array } -},{}],86:[function(require,module,exports){ +},{}],102:[function(require,module,exports){ var traverse = module.exports = function (obj) { return new Traverse(obj); }; @@ -47485,7 +51239,7 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { return key in obj; }; -},{}],87:[function(require,module,exports){ +},{}],103:[function(require,module,exports){ // Generated by CoffeeScript 1.7.1 (function() { var lang; @@ -47546,7 +51300,7 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{}],88:[function(require,module,exports){ +},{}],104:[function(require,module,exports){ // Generated by CoffeeScript 1.7.1 (function() { var deprecate, hasModule, makeTwix, @@ -48262,7 +52016,7 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{"./lang":87,"moment":41}],89:[function(require,module,exports){ +},{"./lang":103,"moment":54}],105:[function(require,module,exports){ // Underscore.js 1.5.2 // http://underscorejs.org // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors @@ -49540,11 +53294,11 @@ var hasOwnProperty = Object.hasOwnProperty || function (obj, key) { }).call(this); -},{}],90:[function(require,module,exports){ +},{}],106:[function(require,module,exports){ module.exports={ "name": "joola.sdk", "preferGlobal": false, - "version": "0.8.1", + "version": "0.8.2-develop", "author": "Joola ", "description": "joola's software development kit (SDK)", "engine": "node >= 0.10.x", @@ -49574,7 +53328,6 @@ module.exports={ "dependencies": { "async": "~0.2.10", "cloneextend": "^0.0.3", - "d3": "^3.4.13", "deep-extend": "^0.2.10", "eventemitter2": "~0.4.13", "jquery": "^2.1.1", @@ -49606,7 +53359,7 @@ module.exports={ "license": "GPL-3.0" } -},{}],91:[function(require,module,exports){ +},{}],107:[function(require,module,exports){ /** * @title joola/lib/sdk/common/api * @copyright (c) Joola Smart Solutions, Ltd. @@ -49912,7 +53665,7 @@ joola.events.on('rpc:done', function () { joola.usage = {currentCalls: 0}; joola.usage.currentCalls--; }); -},{"../index":99,"http":13,"https":17,"querystring":23,"url":32}],92:[function(require,module,exports){ +},{"../index":115,"http":31,"https":15,"querystring":16,"url":20}],108:[function(require,module,exports){ /** * joola * @@ -50032,7 +53785,7 @@ dispatch.buildstub = function (callback) { }; -},{"../../../build/temp/meta.json":1,"../index":99,"cloneextend":35}],93:[function(require,module,exports){ +},{"../../../build/temp/meta.json":1,"../index":115,"cloneextend":4}],109:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -50053,9 +53806,8 @@ _events._id = 'events'; module.exports = exports = _events; -},{"../index":99,"eventemitter2":37}],94:[function(require,module,exports){ -(function (global){ -/** +},{"../index":115,"eventemitter2":6}],110:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * @title joola * @overview the open-source data analytics framework * @copyright Joola Smart Solutions, Ltd. @@ -50081,10 +53833,8 @@ joola.timezone = function (tz) { return offset; }; -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../index":99}],95:[function(require,module,exports){ -(function (Buffer){ -/*jshint -W083 */ +},{"../index":115}],111:[function(require,module,exports){ +var Buffer=require("__browserify_Buffer").Buffer;/*jshint -W083 */ /** * @title joola @@ -50381,8 +54131,7 @@ common.formatDate = function (date) { return format(date, 'mmm dd, yyyy'); }; -}).call(this,require("buffer").Buffer) -},{"../index":99,"./modifiers":98,"buffer":3,"cloneextend":35,"crypto":7,"deep-extend":36,"traverse":86,"underscore":89,"util":34}],96:[function(require,module,exports){ +},{"../index":115,"./modifiers":114,"__browserify_Buffer":49,"cloneextend":4,"crypto":26,"deep-extend":5,"traverse":102,"underscore":105,"util":21}],112:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -50461,7 +54210,7 @@ logger.error = function (message, callback) { }; -},{"../index":99}],97:[function(require,module,exports){ +},{"../index":115}],113:[function(require,module,exports){ var memory = function () { this.content = {}; @@ -50496,7 +54245,7 @@ var memory = function () { }; module.exports = new memory(); -},{}],98:[function(require,module,exports){ +},{}],114:[function(require,module,exports){ /** * @title joola/lib/common/modifiers * @overview Includes different prototype modifiers used by joola @@ -50664,9 +54413,8 @@ String.prototype.commas = function () { parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); }; -},{}],99:[function(require,module,exports){ -(function (global){ -/** +},{}],115:[function(require,module,exports){ +var global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {};/** * @title joola * @overview the open-source data analytics framework * @copyright Joola Smart Solutions, Ltd. @@ -51007,8 +54755,7 @@ joola.on('ready', function () { var end = new Date().getTime(); }); -}).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./../../package.json":90,"./common/api":91,"./common/dispatch":92,"./common/events":93,"./common/globals":94,"./common/index":95,"./common/logger":96,"./common/memory":97,"./common/modifiers":98,"./viz/index":114,"querystring":23,"socket.io-client":42,"url":32}],100:[function(require,module,exports){ +},{"./../../package.json":106,"./common/api":107,"./common/dispatch":108,"./common/events":109,"./common/globals":110,"./common/index":111,"./common/logger":112,"./common/memory":113,"./common/modifiers":114,"./viz/index":130,"querystring":16,"socket.io-client":55,"url":20}],116:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -51631,7 +55378,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(BarTable, events.EventEmitter); -},{"../index":99,"events":12,"jquery":40,"underscore":89,"util":34}],101:[function(require,module,exports){ +},{"../index":115,"events":14,"jquery":53,"underscore":105,"util":21}],117:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -51674,14 +55421,19 @@ var Canvas = module.exports = function (options, callback) { }; this.prepareQuery = function (query, dates) { + var _query; if (!dates) dates = {}; - var _query = ce.extend({}, query); + if (Array.isArray(query)) + _query = [ce.extend({}, query[0])]; + else { + _query = ce.extend({}, query); + _query = [_query]; + } if (self.options.query) { - _query = joola.common._extend(ce.clone(self.options.query), _query); + _query[0] = joola.common._extend(ce.clone(self.options.query), _query[0]); } - if (!Array.isArray(_query)) - _query = [_query]; + if (_query[0].dimensions && _query[0].dimensions.length > 0 && _query[0].dimensions && _query[0].dimensions.length > 0) { _query[0].dimensions.forEach(function (dimension, i) { var key; @@ -51756,6 +55508,7 @@ var Canvas = module.exports = function (options, callback) { cquery.interval = self.options.datepicker._interval; _query = [_query[0], cquery]; } + return _query; }; @@ -51773,7 +55526,6 @@ var Canvas = module.exports = function (options, callback) { filters.push(filter); } }); - console.log('build filter', filters); return filters; }; @@ -51838,7 +55590,6 @@ var Canvas = module.exports = function (options, callback) { break; case 'bartable': new joola.viz.BarTable(viz).on('select', function (point, dimensionkey) { - console.log('selected'); if (Array.isArray(point)) point = point[0]; var filter = self.buildFilter(point, dimensionkey); @@ -51897,7 +55648,6 @@ var Canvas = module.exports = function (options, callback) { break; case 'bartable': new joola.viz.BarTable(viz).on('select', function (point, dimensionkey) { - console.log('selected'); if (Array.isArray(point)) point = point[0]; var filter = self.buildFilter(point, dimensionkey); @@ -51974,23 +55724,25 @@ var Canvas = module.exports = function (options, callback) { //here we go joola.viz.initialize(self, options || {}); - self.draw(); - joola.viz.onscreen.push(self); - if (!self.options.canvas) { - var elem = $$(self.options.$container).parent(); - if (elem.attr('jio-type') == 'canvas') { - self.options.canvas = $$(elem).Canvas(); + self.draw(null, function (err, ref) { + if (err) + return callback(err); + joola.viz.onscreen.push(self); + if (!self.options.canvas) { + var elem = $$(self.options.$container).parent(); + if (elem.attr('jio-type') == 'canvas') { + self.options.canvas = $$(elem).Canvas(); + } + } + if (self.options.canvas) { + self.options.canvas.addVisualization(self); } - } - if (self.options.canvas) { - self.options.canvas.addVisualization(self); - } - - //wrap up - self.initialized = true; - if (typeof callback === 'function') - return callback(null, self); + //wrap up + self.initialized = true; + if (typeof callback === 'function') + return callback(null, ref); + }); return self; }; @@ -52011,7 +55763,9 @@ joola.events.on('core.init.finish', function () { result = new joola.viz.Canvas(options, function (err, canvas) { if (err) throw new Error('Failed to initialize canvas.', err); - canvas.draw(options, callback); + //canvas.draw(options, callback); + if (callback) + return callback(null, canvas); }).options.$container; } else { @@ -52030,7 +55784,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Canvas, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],102:[function(require,module,exports){ +},{"../index":115,"cloneextend":4,"events":14,"jquery":53,"underscore":105,"util":21}],118:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -52234,6 +55988,7 @@ var DatePicker = module.exports = function (options, callback) { window[self.options.onDraw](self.options.container, self); var $container = self.options.$container; + $container.empty(); //self.options.$container.append(self.template()); var $table = $$('
' + '' + @@ -53114,7 +56869,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(DatePicker, events.EventEmitter); -},{"../index":99,"events":12,"jquery":40,"jquery-ui/datepicker":39,"underscore":89,"util":34}],103:[function(require,module,exports){ +},{"../index":115,"events":14,"jquery":53,"jquery-ui/datepicker":52,"underscore":105,"util":21}],119:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53407,7 +57162,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(DimensionPicker, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"util":34}],104:[function(require,module,exports){ +},{"../index":115,"cloneextend":4,"events":14,"jquery":53,"util":21}],120:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53524,7 +57279,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99,"jquery":40,"underscore":89}],105:[function(require,module,exports){ +},{"../index":115,"jquery":53,"underscore":105}],121:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53656,7 +57411,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99}],106:[function(require,module,exports){ +},{"../index":115}],122:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -53917,7 +57672,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Metric, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],107:[function(require,module,exports){ +},{"../index":115,"cloneextend":4,"events":14,"jquery":53,"underscore":105,"util":21}],123:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54204,7 +57959,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(MetricPicker, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"util":34}],108:[function(require,module,exports){ +},{"../index":115,"cloneextend":4,"events":14,"jquery":53,"util":21}],124:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54499,7 +58254,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99,"underscore":89}],109:[function(require,module,exports){ +},{"../index":115,"underscore":105}],125:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -54723,7 +58478,7 @@ Pie.template = function (options) { return html; }; -},{"../index":99,"underscore":89}],110:[function(require,module,exports){ +},{"../index":115,"underscore":105}],126:[function(require,module,exports){ /*jshint -W083 */ /** @@ -54943,7 +58698,7 @@ joola.events.on('core.init.finish', function () { }); -},{"../index":99,"underscore":89}],111:[function(require,module,exports){ +},{"../index":115,"underscore":105}],127:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -55198,7 +58953,7 @@ joola.events.on('core.init.finish', function () { }; } }); -},{"../index":99}],112:[function(require,module,exports){ +},{"../index":115}],128:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -55219,227 +58974,289 @@ var _ = require('underscore'); var Table = module.exports = function (options, callback) { - var self = this; + var self = this; - this.type = 'table'; - this.uuid = joola.common.uuid(); - this.initialized = false; - this.data = []; - this.sortIndex = -1; - this.options = { - container: null, - colors: [], - offcolors: [], - paging: { - currentPage: 1, - sizes: [10, 25, 50, 100, 250, 500, 1000], - currentSize: 10 - }, - template: '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - ' ' + - '
' + - '
' + - '
' + - '
' + - '
' + - ' ' + - ' ' + - '
' + - '
' + - '
' + - '
' + - '
' + - ' Page size: ' + - ' ' + - '
' + - '
' + - '
' + - ' ' + - '
', - query: null, - strings: { - loading: 'No data available.', - nodata: 'No data available.', - not_shown: 'Not shown' - }, - limit: 10, - headers: false, - include_not_shown: true, - summary: { - enabled: true, - placement: 'top' - } - }; - this.verify = function (options) { - if (!self.options) - return 'Failed to verify [options].'; - if (self.options.query) { - if (!Array.isArray(self.options.query)) - self.options.query = [self.options.query]; + this.type = 'table'; + this.uuid = joola.common.uuid(); + this.initialized = false; + this.data = []; + this.sortIndex = -1; + this.options = { + container: null, + colors: [], + offcolors: [], + paging: { + currentPage: 1, + sizes: [10, 25, 50, 100, 250, 500, 1000], + currentSize: 10 + }, + template: '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + ' ' + + '
' + + '
' + + '
' + + '
' + + ' ' + + ' ' + + ' ' + + '
' + + '
' + + '
' + + '
' + + '
' + + ' Page size: ' + + ' ' + + '
' + + '
' + + '
' + + ' ' + + '
', + query: null, + strings: { + loading: 'No data available.', + nodata: 'No data available.', + not_shown: 'Not shown' + }, + limit: 1000, + headers: false, + include_not_shown: true, + summary: { + enabled: true, + placement: 'top' + } + }; + this.verify = function (options) { + if (!self.options) + return 'Failed to verify [options].'; + if (self.options.query) { + if (!Array.isArray(self.options.query)) + self.options.query = [self.options.query]; - } - return null; - }; + } + return null; + }; - this.enter = function (data, alldata) { + this.enter = function (data, alldata) { - } - ; - this.exit = function (data, alldata) { + } + ; + this.exit = function (data, alldata) { - }; - this.update = function (data, alldata) { + }; + this.update = function (data, alldata) { - }; + }; - this.destroy = function () { - joola.viz.stop(self); - Object.keys(self.summaries).forEach(function (key, index) { - var summary = self.summaries[key]; - summary.destroy(); + this.destroy = function () { + joola.viz.stop(self); + Object.keys(self.summaries).forEach(function (key, index) { + var summary = self.summaries[key]; + summary.destroy(); + }); + + $$(self.options.container).find('table').empty(); + }; + + this.filter = function (data, filter) { + return _.filter(data, function (item) { + var found = false; + Object.keys(item.dimensions).forEach(function (key) { + if (item.dimensions[key].toLowerCase().indexOf(filter.toLowerCase()) > -1) + found = true; }); + return found; + }); + }; - $$(self.options.container).find('table').empty(); - }; + this.paint = function () { + var _query = self.options.query[0]; + var $table = $$($$(self.options.container).find('table')[0]); + var $search = $$($$(self.options.container).find('input.search')[0]); + var $tbody = $$($table.find('tbody')[0]); + if (self.data[0].length > 0 || (self.data.length > 1 && self.data[1].length > 0)) { + $tbody.find('tr.data-row').remove(); + } + else { - this.filter = function (data, filter) { - return _.filter(data, function (item) { - var found = false; - Object.keys(item.dimensions).forEach(function (key) { - if (item.dimensions[key].toLowerCase().indexOf(filter.toLowerCase()) > -1) - found = true; + } + + if (self.sortIndex === -1) { + self.sortIndex = self.options.query[0].dimensions.length + 1; + self.sortDir = 'desc'; + } + + var start = ((self.options.paging.currentPage - 1) * self.options.paging.currentSize) + 1; + var length = self.options.paging.currentSize; + var search, text; + if (self.data.length === 1) { + var _data; + var _total = []; + search = $search.val(); + if (search && search.length > 2) + _data = self.filter(self.data[0], search); + else + _data = self.data[0]; + self._data = []; + self._data[0] = _data.slice(0); + _data = _data.slice(start - 1, (start - 1) + length); + _data.forEach(function (point) { + //we have a simple row + var $tr = $$(''); + var lastIndex = 0; + _query.dimensions.forEach(function (d, di) { + lastIndex++; + var dimensionkey = d.key || d; + var $td = $$('' + point.dimensions[dimensionkey] + ''); + $td.find('.filter').on('click', function () { + self.emit('select', point, dimensionkey); + }); + if (di === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); + }); + $tbody.append($tr); + _query.metrics.forEach(function (m, mi) { + var metrickey = m.key || m; + var $td = $$('' + joola.common.formatMetric(point.metrics[metrickey], point.meta[metrickey]) + '' + + '' + + ''); + if (lastIndex + mi === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); }); - return found; }); - }; - - this.paint = function () { - var _query = self.options.query[0]; - var $table = $$($$(self.options.container).find('table')[0]); - var $search = $$($$(self.options.container).find('input.search')[0]); - var $tbody = $$($table.find('tbody')[0]); - if (self.data[0].length > 0 || (self.data.length > 1 && self.data[1].length > 0)) { - $tbody.find('tr.data-row').remove(); + } + else if (self.data.length === 2) { + var _comparequery = self.options.query[1]; + var base; + var compare; + search = $search.val(); + if (search && search.length > 2) { + base = self.filter(self.data[0], search); + compare = self.filter(self.data[1], search); } else { - + base = self.data[0]; + compare = self.data[1]; } + self._data = []; + self._data[0] = self.data[0].slice(0); + self._data[1] = self.data[1].slice(0); + base = base.slice(start - 1, (start - 1) + length); + var handled = []; + base.forEach(function (point, index) { + handled.push(point.key); + var $tr = $$(''); + var lastIndex = 0; + _query.dimensions.forEach(function (d, di) { + var dimensionkey = d.key || d; + var $td = $$('' + point.dimensions[dimensionkey] + ''); + lastIndex++; + if (di === self.sortIndex) + $td.addClass('sorted'); + $td.find('.filter').on('click', function () { + self.emit('select', point, dimensionkey); + }); + $tr.append($td); + }); + _query.metrics.forEach(function (m, mi) { + var $td = $$(''); + if (lastIndex + mi === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); + }); + $tbody.append($tr); - if (self.sortIndex === -1) { - self.sortIndex = self.options.query[0].dimensions.length + 1; - self.sortDir = 'desc'; - } + text = joola.common.formatDate(_query.timeframe.start) + ' - '; + text += joola.common.formatDate(_query.timeframe.end); + $tr = $$(''); + var $td = $$('' + text + ''); + $tr.append($td); - var start = ((self.options.paging.currentPage - 1) * self.options.paging.currentSize) + 1; - var length = self.options.paging.currentSize; - var search, text; - if (self.data.length === 1) { - var _data; - var _total = []; - search = $search.val(); - if (search && search.length > 2) - _data = self.filter(self.data[0], search); - else - _data = self.data[0]; - self._data = []; - self._data[0] = _data.slice(0); - _data = _data.slice(start - 1, (start - 1) + length); - _data.forEach(function (point) { - //we have a simple row - var $tr = $$(''); - var lastIndex = 0; - _query.dimensions.forEach(function (d, di) { - lastIndex++; - var dimensionkey = d.key || d; - var $td = $$('' + point.dimensions[dimensionkey] + ''); - $td.find('.filter').on('click', function () { - self.emit('select', point, dimensionkey); - }); - if (di === self.sortIndex) - $td.addClass('sorted'); - $tr.append($td); - }); - $tbody.append($tr); - _query.metrics.forEach(function (m, mi) { - var metrickey = m.key || m; - var $td = $$('' + joola.common.formatMetric(point.metrics[metrickey], point.meta[metrickey]) + '' + - '' + - ''); - if (lastIndex + mi === self.sortIndex) - $td.addClass('sorted'); - $tr.append($td); - }); + $tbody.append($tr); + lastIndex = _query.dimensions.length; + _query.metrics.forEach(function (m, mi) { + var metrickey = m.key || m; + var $td = $$('' + joola.common.formatMetric(point.metrics[metrickey], point.meta[metrickey]) + '' + + '' + + ''); + if (lastIndex + mi === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); }); - } - else if (self.data.length === 2) { - var _comparequery = self.options.query[1]; - var base; - var compare; - search = $search.val(); - if (search && search.length > 2) { - base = self.filter(self.data[0], search); - compare = self.filter(self.data[1], search); - } - else { - base = self.data[0]; - compare = self.data[1]; - } - self._data = []; - self._data[0] = self.data[0].slice(0); - self._data[1] = self.data[1].slice(0); - base = base.slice(start - 1, (start - 1) + length); - var handled = []; - base.forEach(function (point, index) { - handled.push(point.key); - var $tr = $$(''); - var lastIndex = 0; - _query.dimensions.forEach(function (d, di) { + + var comparePoint = compare[index]; + text = joola.common.formatDate(_comparequery.timeframe.start) + ' - '; + text += joola.common.formatDate(_comparequery.timeframe.end); + $tr = $$(''); + $td = $$('' + text + ''); + $tr.append($td); + + $tbody.append($tr); + _query.metrics.forEach(function (m, mi) { + var metrickey = m.key || m; + var $td = $$('' + (comparePoint ? joola.common.formatMetric(comparePoint.metrics[metrickey], comparePoint.meta[metrickey]) : 'N/A') + '' + + ''); + if (lastIndex + mi === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); + }); + + $tr = $$(''); + $td = $$('% Change'); + $tr.append($td); + + _query.metrics.forEach(function (m, mi) { + var metrickey = m.key || m; + var $td = $$('' + (point && comparePoint ? joola.common.percentageChange(comparePoint.metrics[metrickey], point.metrics[metrickey]) : 'N/A') + '%'); + if (lastIndex + mi === self.sortIndex) + $td.addClass('sorted'); + $tr.append($td); + }); + $tbody.append($tr); + }); + + compare.forEach(function (comparePoint, index) { + if (handled.indexOf(comparePoint.key) === -1) { + var $tr = $$(''); + _query.dimensions.forEach(function (d) { var dimensionkey = d.key || d; - var $td = $$('' + point.dimensions[dimensionkey] + ''); - lastIndex++; - if (di === self.sortIndex) - $td.addClass('sorted'); + var $td = $$('' + comparePoint.dimensions[dimensionkey] + ''); $td.find('.filter').on('click', function () { - self.emit('select', point, dimensionkey); + self.emit('select', comparePoint, dimensionkey); }); $tr.append($td); }); - _query.metrics.forEach(function (m, mi) { + _query.metrics.forEach(function (m) { var $td = $$(''); - if (lastIndex + mi === self.sortIndex) - $td.addClass('sorted'); $tr.append($td); }); $tbody.append($tr); text = joola.common.formatDate(_query.timeframe.start) + ' - '; text += joola.common.formatDate(_query.timeframe.end); - $tr = $$(''); + $tr = $$(''); var $td = $$('' + text + ''); $tr.append($td); $tbody.append($tr); - lastIndex = _query.dimensions.length; - _query.metrics.forEach(function (m, mi) { + _query.metrics.forEach(function (m) { var metrickey = m.key || m; - var $td = $$('' + joola.common.formatMetric(point.metrics[metrickey], point.meta[metrickey]) + '' + + var $td = $$('' + 'N/A' + '' + '' + ''); - if (lastIndex + mi === self.sortIndex) - $td.addClass('sorted'); $tr.append($td); }); - var comparePoint = compare[index]; text = joola.common.formatDate(_comparequery.timeframe.start) + ' - '; text += joola.common.formatDate(_comparequery.timeframe.end); $tr = $$(''); @@ -55447,555 +59264,494 @@ var Table = module.exports = function (options, callback) { $tr.append($td); $tbody.append($tr); - _query.metrics.forEach(function (m, mi) { + _query.metrics.forEach(function (m) { var metrickey = m.key || m; var $td = $$('' + (comparePoint ? joola.common.formatMetric(comparePoint.metrics[metrickey], comparePoint.meta[metrickey]) : 'N/A') + '' + ''); - if (lastIndex + mi === self.sortIndex) - $td.addClass('sorted'); $tr.append($td); }); - $tr = $$(''); + $tr = $$(''); $td = $$('% Change'); $tr.append($td); - _query.metrics.forEach(function (m, mi) { + _query.metrics.forEach(function (m) { var metrickey = m.key || m; - var $td = $$('' + (point && comparePoint ? joola.common.percentageChange(comparePoint.metrics[metrickey], point.metrics[metrickey]) : 'N/A') + '%'); - if (lastIndex + mi === self.sortIndex) - $td.addClass('sorted'); + var $td = $$('N/A'); $tr.append($td); }); $tbody.append($tr); - }); - - compare.forEach(function (comparePoint, index) { - if (handled.indexOf(comparePoint.key) === -1) { - var $tr = $$(''); - _query.dimensions.forEach(function (d) { - var dimensionkey = d.key || d; - var $td = $$('' + comparePoint.dimensions[dimensionkey] + ''); - $td.find('.filter').on('click', function () { - self.emit('select', comparePoint, dimensionkey); - }); - $tr.append($td); - }); - _query.metrics.forEach(function (m) { - var $td = $$(''); - $tr.append($td); - }); - $tbody.append($tr); - - text = joola.common.formatDate(_query.timeframe.start) + ' - '; - text += joola.common.formatDate(_query.timeframe.end); - $tr = $$(''); - var $td = $$('' + text + ''); - $tr.append($td); - - $tbody.append($tr); - _query.metrics.forEach(function (m) { - var metrickey = m.key || m; - var $td = $$('' + 'N/A' + '' + - '' + - ''); - $tr.append($td); - }); + } + }); + } - text = joola.common.formatDate(_comparequery.timeframe.start) + ' - '; - text += joola.common.formatDate(_comparequery.timeframe.end); - $tr = $$(''); - $td = $$('' + text + ''); - $tr.append($td); + self.handleHeaders(); + self.summarize(); + self.handlePaging(); + }; - $tbody.append($tr); - _query.metrics.forEach(function (m) { - var metrickey = m.key || m; - var $td = $$('' + (comparePoint ? joola.common.formatMetric(comparePoint.metrics[metrickey], comparePoint.meta[metrickey]) : 'N/A') + '' + - ''); - $tr.append($td); - }); + this.done = function () { + self.paint(); + }; - $tr = $$(''); - $td = $$('% Change'); - $tr.append($td); + this.handleHeaders = function () { + var lastIndex = 0; + self.options.query[0].dimensions.forEach(function (d, i) { + var name = d.name || d.key || d; + var $th = $$(self.options.$container.find('table th')[i]); + if (!$th.hasClass('dimension')) { + $th.after($th.clone(true)); + } + $th.find('.name').text(name); + if (!d.description) + $th.find('.icon-help').hide(); + else { + $th.find('.icon-help').show(); + $th.find('.icon-help span').text(d.description); + } + lastIndex++; + }); + self.options.query[0].metrics.forEach(function (m, i) { + var name = m.name || m.key || m; + var $th = $$(self.options.$container.find('table th')[i + lastIndex]); + if (!m.description) + $th.find('.icon-help').hide(); + else { + $th.find('.icon-help').show(); + $th.find('.icon-help span').text(m.description); + } + $th.find('.name').text(name); + }); - _query.metrics.forEach(function (m) { - var metrickey = m.key || m; - var $td = $$('N/A'); - $tr.append($td); + var $html = self.options.$container; + var $thead = $$($html.find('thead')); + var $head_tr = $$(''); + lastIndex = 0; + self.options.query[0].dimensions.forEach(function (d, di) { + lastIndex++; + var $th = $$(''); + $th.find('.name').text(d.name || d.key || d); + if (d.allowremove) { + $th.find('.icon-close').off('click'); + $th.find('.icon-close').on('click', function (e) { + e.stopPropagation(); + self.options.query.forEach(function (q) { + var index = -1; + q.dimensions.forEach(function (item, i) { + if (item.key === d.key) + index = i; }); - $tbody.append($tr); - } + if (index > -1) + q.dimensions.splice(index, 1); + }); + self.data = []; + self.options.paging.currentPage = 1; + self.sortIndex--; + self.handleMetricBoxes(); + joola.viz.initialize(self, self.options); }); } - - self.handleHeaders(); - self.summarize(); - self.handlePaging(); - }; - - this.done = function () { - self.paint(); - }; - - this.handleHeaders = function () { - var lastIndex = 0; - self.options.query[0].dimensions.forEach(function (d, i) { - var name = d.name || d.key || d; - var $th = $$(self.options.$container.find('table th')[i]); - if (!$th.hasClass('dimension')) { - $th.after($th.clone(true)); - } - $th.find('.name').text(name); - if (!d.description) - $th.find('.icon-help').hide(); - else { - $th.find('.icon-help').show(); - $th.find('.icon-help span').text(d.description); - } - lastIndex++; - }); - self.options.query[0].metrics.forEach(function (m, i) { - var name = m.name || m.key || m; - var $th = $$(self.options.$container.find('table th')[i + lastIndex]); - if (!m.description) - $th.find('.icon-help').hide(); - else { - $th.find('.icon-help').show(); - $th.find('.icon-help span').text(m.description); - } - $th.find('.name').text(name); + else + $th.find('.icon-close').remove(); + if (!d.description) + $th.find('.icon-help').hide(); + else { + $th.find('.icon-help').show(); + $th.find('.icon-help span').text(d.description); + } + $th.find('.icon-help').on('click', function (e) { + e.stopPropagation(); }); + $th.attr('data-sort-dir', null); + $th.attr('data-sort', null); + $th.find('.caret-sort').removeClass('icon-sort-desc'); + $th.find('.caret-sort').removeClass('icon-sort-asc'); + if (di === self.sortIndex) { + $th.attr('data-sort', true); + $th.attr('data-sort-dir', self.sortDir); + $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); + } + $th.on('click', function () { + self.sortIndex = di; + Object.keys(self.summaries).forEach(function (key, index) { + var summary = self.summaries[key]; + summary.options.$container.removeClass('sorted'); + }); - var $html = self.options.$container; - var $thead = $$($html.find('thead')); - var $head_tr = $$(''); - lastIndex = 0; - self.options.query[0].dimensions.forEach(function (d, di) { - lastIndex++; - var $th = $$(''); - $th.find('.name').text(d.name || d.key || d); - if (d.allowremove) { - $th.find('.icon-close').off('click'); - $th.find('.icon-close').on('click', function (e) { - e.stopPropagation(); - self.options.query.forEach(function (q) { - var index = -1; - q.dimensions.forEach(function (item, i) { - if (item.key === d.key) - index = i; - }); - if (index > -1) - q.dimensions.splice(index, 1); - }); - self.data = []; - self.options.paging.currentPage = 1; - self.sortIndex--; - self.handleMetricBoxes(); - joola.viz.initialize(self, self.options); - }); + self.data[0] = _.sortBy(self.data[0], function (item) { + return item.dimensions[d.key || d]; + }); + var sortDir = $th.attr('data-sort-dir') || 'desc'; + if (sortDir === 'desc') { + sortDir = 'asc'; } - else - $th.find('.icon-close').remove(); - if (!d.description) - $th.find('.icon-help').hide(); else { - $th.find('.icon-help').show(); - $th.find('.icon-help span').text(d.description); - } - $th.find('.icon-help').on('click', function (e) { - e.stopPropagation(); - }); - $th.attr('data-sort-dir', null); - $th.attr('data-sort', null); - $th.find('.caret-sort').removeClass('icon-sort-desc'); - $th.find('.caret-sort').removeClass('icon-sort-asc'); - if (di === self.sortIndex) { - $th.attr('data-sort', true); - $th.attr('data-sort-dir', self.sortDir); - $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); - } - $th.on('click', function () { - self.sortIndex = di; - Object.keys(self.summaries).forEach(function (key, index) { - var summary = self.summaries[key]; - summary.options.$container.removeClass('sorted'); - }); - self.data[0] = _.sortBy(self.data[0], function (item) { return item.dimensions[d.key || d]; }); - var sortDir = $th.attr('data-sort-dir') || 'desc'; - if (sortDir === 'desc') { - sortDir = 'asc'; - } - else { - self.data[0] = _.sortBy(self.data[0], function (item) { - return item.dimensions[d.key || d]; - }); - self.data[0].reverse(); - sortDir = 'desc'; - } - self.sortDir = sortDir; - $head_tr.find('th').attr('data-sort-dir', null); - $head_tr.find('th').attr('data-sort', null); - $head_tr.find('th .caret-sort').removeClass('icon-sort-desc'); - $head_tr.find('th .caret-sort').removeClass('icon-sort-asc'); - $th.attr('data-sort', true); - $th.attr('data-sort-dir', self.sortDir); - $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); - self.paint(); - }); - $head_tr.append($th); + self.data[0].reverse(); + sortDir = 'desc'; + } + self.sortDir = sortDir; + $head_tr.find('th').attr('data-sort-dir', null); + $head_tr.find('th').attr('data-sort', null); + $head_tr.find('th .caret-sort').removeClass('icon-sort-desc'); + $head_tr.find('th .caret-sort').removeClass('icon-sort-asc'); + $th.attr('data-sort', true); + $th.attr('data-sort-dir', self.sortDir); + $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); + self.paint(); }); - self.options.query[0].metrics.forEach(function (m, mi) { - var $th = $$(''); - $th.find('.name').text(m.name || m.key || m); - if (m.allowremove) { - $th.find('.icon-close').off('click'); - $th.find('.icon-close').on('click', function (e) { - e.stopPropagation(); - self.options.query.forEach(function (q) { - var index = -1; - q.metrics.forEach(function (item, i) { - if (item.key === m.key) - index = i; - }); - if (index > -1) - q.metrics.splice(index, 1); - }); - var _summaries = {}; - Object.keys(self.summaries).forEach(function (key) { - item = self.summaries[key]; - if ((item.options.query[0].metrics[0].key || item.options.query[0].metrics[0]) === m.key) { - } - else - _summaries[key] = self.summaries[key]; + $head_tr.append($th); + }); + self.options.query[0].metrics.forEach(function (m, mi) { + var $th = $$(''); + $th.find('.name').text(m.name || m.key || m); + if (m.allowremove) { + $th.find('.icon-close').off('click'); + $th.find('.icon-close').on('click', function (e) { + e.stopPropagation(); + self.options.query.forEach(function (q) { + var index = -1; + q.metrics.forEach(function (item, i) { + if (item.key === m.key) + index = i; }); - self.summaries = _summaries; - self.data = []; - self.options.paging.currentPage = 1; - self.sortIndex--; - self.handleMetricBoxes(); - joola.viz.initialize(self, self.options); + if (index > -1) + q.metrics.splice(index, 1); }); - } - else - $th.find('.icon-close').remove(); - if (!m.description) - $th.find('.icon-help').hide(); - else { - $th.find('.icon-help').show(); - $th.find('.icon-help span').text(m.description); - } - if (self.sortIndex === -1) { - self.sortIndex = lastIndex; - self.sortDir = 'desc'; - } - - $th.attr('data-sort-dir', null); - $th.attr('data-sort', null); - $th.find('.caret-sort').removeClass('icon-sort-desc'); - $th.find('.caret-sort').removeClass('icon-sort-asc'); - if (lastIndex + mi === self.sortIndex) { - $th.attr('data-sort', true); - $th.attr('data-sort-dir', self.sortDir); - $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); - } - - $th.on('click', function () { - self.sortIndex = lastIndex + mi; + var _summaries = {}; Object.keys(self.summaries).forEach(function (key) { - var summary = self.summaries[key]; - summary.options.$container.removeClass('sorted'); - if (key === (m.key || m)) - summary.options.$container.addClass('sorted'); - }); - self.data[0] = _.sortBy(self.data[0], function (item) { - return item.metrics[m.key || m]; + item = self.summaries[key]; + if ((item.options.query[0].metrics[0].key || item.options.query[0].metrics[0]) === m.key) { + } + else + _summaries[key] = self.summaries[key]; }); - var sortDir = $th.attr('data-sort-dir') || 'desc'; - if (sortDir === 'desc') { - sortDir = 'asc'; - } - else { - self.data[0] = _.sortBy(self.data[0], function (item) { - return item.metrics[m.key || m]; - }); - self.data[0].reverse(); - sortDir = 'desc'; - } - self.sortDir = sortDir; - $head_tr.find('th').attr('data-sort-dir', null); - $head_tr.find('th').attr('data-sort', null); - $head_tr.find('th .caret-sort').removeClass('icon-sort-desc'); - $head_tr.find('th .caret-sort').removeClass('icon-sort-asc'); - $th.attr('data-sort', true); - $th.attr('data-sort-dir', self.sortDir); - $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); - self.paint(); + self.summaries = _summaries; + self.data = []; + self.options.paging.currentPage = 1; + self.sortIndex--; + self.handleMetricBoxes(); + joola.viz.initialize(self, self.options); }); - $head_tr.append($th); - }); - $thead.html($head_tr); - $html.find('table tbody').before($thead); - }; - - this.handleMetricBoxes = function () { - var $html = self.options.$container; - var $tbody = $html.find('tbody'); - $tbody = $$($tbody); - var $metric_tr = $$(''); - var lastIndex = 0; - self.options.query[0].dimensions.forEach(function (d) { - var $td = $$(''); - $metric_tr.append($td); - lastIndex++; - }); + } + else + $th.find('.icon-close').remove(); + if (!m.description) + $th.find('.icon-help').hide(); + else { + $th.find('.icon-help').show(); + $th.find('.icon-help span').text(m.description); + } + if (self.sortIndex === -1) { + self.sortIndex = lastIndex; + self.sortDir = 'desc'; + } - var index = 0; - async.mapSeries(self.options.query[0].metrics, function (m, cb) { - var $td = $$(''); - $metric_tr.append($td); - var _query = ce.clone(self.options.query); - _query.forEach(function (q) { - q.dimensions = []; - q.metrics = [m]; - if (!q.filter) - q.filter = []; - if (q.filter.length > 0) { - var _q = ce.clone(q); - _q.filter = []; - _q.type = 'overall'; - _query.push(_q); - } - }); + $th.attr('data-sort-dir', null); + $th.attr('data-sort', null); + $th.find('.caret-sort').removeClass('icon-sort-desc'); + $th.find('.caret-sort').removeClass('icon-sort-asc'); + if (lastIndex + mi === self.sortIndex) { + $th.attr('data-sort', true); + $th.attr('data-sort-dir', self.sortDir); + $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); + } - if (!self.summaries) - self.summaries = {}; - self.summaries[m.key] = new joola.viz.Metric({ - container: $td.get(0), - css: lastIndex + index === self.sortIndex ? 'sorted' : '', - query: _query + $th.on('click', function () { + self.sortIndex = lastIndex + mi; + Object.keys(self.summaries).forEach(function (key) { + var summary = self.summaries[key]; + summary.options.$container.removeClass('sorted'); + if (key === (m.key || m)) + summary.options.$container.addClass('sorted'); }); - self.summaries[m.key].on('done', function () { - self.summaries[m.key].options.$container.addClass(lastIndex + index === self.sortIndex ? 'sorted' : ''); - self.summarize(); - return cb(null); + self.data[0] = _.sortBy(self.data[0], function (item) { + return item.metrics[m.key || m]; }); - index++; - }, function (err, results) { + var sortDir = $th.attr('data-sort-dir') || 'desc'; + if (sortDir === 'desc') { + sortDir = 'asc'; + } + else { + self.data[0] = _.sortBy(self.data[0], function (item) { + return item.metrics[m.key || m]; + }); + self.data[0].reverse(); + sortDir = 'desc'; + } + self.sortDir = sortDir; + $head_tr.find('th').attr('data-sort-dir', null); + $head_tr.find('th').attr('data-sort', null); + $head_tr.find('th .caret-sort').removeClass('icon-sort-desc'); + $head_tr.find('th .caret-sort').removeClass('icon-sort-asc'); + $th.attr('data-sort', true); + $th.attr('data-sort-dir', self.sortDir); + $th.find('.caret-sort').addClass('icon-sort-' + self.sortDir); + self.paint(); }); - if ($tbody.find('.metricboxes').length > 0) - $tbody.find('.metricboxes').replaceWith($metric_tr); - else - $$($tbody.find('tr.data-row')[0]).before($metric_tr); - }; + $head_tr.append($th); + }); + $thead.html($head_tr); + $html.find('table tbody').before($thead); + }; - this.handlePaging = function () { - var $showing = $$(self.options.$container.find('.showing')); - - var total = self._data[0].length; - var to = self.options.paging.currentPage * self.options.paging.currentSize; - if (to > total) - to = total; - var showingText = ((self.options.paging.currentPage - 1) * self.options.paging.currentSize + 1) + ' - ' + to + ' of ' + total; - - $showing.text(showingText); - - var $prev = $$(self.options.$container.find('.prev')); - var $next = $$(self.options.$container.find('.next')); - if (self.options.paging.currentPage > 1) { - $prev.removeClass('disabled'); - $prev.off('click'); - $prev.on('click', function () { - if (self.options.paging.currentPage > 1) { - self.options.paging.currentPage--; - self.paint(); - } - }); - } - else { - $prev.addClass('disabled'); - $prev.off('click'); - } - var nextIndex = ((self.options.paging.currentPage ) * self.options.paging.currentSize); - if (nextIndex < self._data[0].length) { - $next.removeClass('disabled'); - $next.off('click'); - $next.on('click', function () { - var nextIndex = ((self.options.paging.currentPage ) * self.options.paging.currentSize); - if (nextIndex < self._data[0].length) { - self.options.paging.currentPage++; - self.paint(); - } - }); - } - else { - $next.addClass('disabled'); - $next.off('click'); - } - }; + this.handleMetricBoxes = function () { + var $html = self.options.$container; + var $tbody = $html.find('tbody'); + $tbody = $$($tbody); + var $metric_tr = $$(''); + var lastIndex = 0; + self.options.query[0].dimensions.forEach(function (d) { + var $td = $$(''); + $metric_tr.append($td); + lastIndex++; + }); - this.sort = function () { + var index = 0; + async.mapSeries(self.options.query[0].metrics, function (m, cb) { + var $td = $$(''); + $metric_tr.append($td); + var _query = ce.clone(self.options.query); + _query.forEach(function (q) { + q.dimensions = []; + q.metrics = [m]; + if (!q.filter) + q.filter = []; + if (q.filter.length > 0) { + var _q = ce.clone(q); + _q.filter = []; + _q.type = 'overall'; + _query.push(_q); + } + }); - }; + if (!self.summaries) + self.summaries = {}; + self.summaries[m.key] = new joola.viz.Metric({ + container: $td.get(0), + css: lastIndex + index === self.sortIndex ? 'sorted' : '', + query: _query + }); + self.summaries[m.key].on('done', function () { + self.summaries[m.key].options.$container.addClass(lastIndex + index === self.sortIndex ? 'sorted' : ''); + self.summarize(); + return cb(null); + }); + index++; + }, function (err, results) { + }); + if ($tbody.find('.metricboxes').length > 0) + $tbody.find('.metricboxes').replaceWith($metric_tr); + else + $$($tbody.find('tr.data-row')[0]).before($metric_tr); + }; - this.summarize = function () { - Object.keys(self.summaries).forEach(function (key, mindex) { - var ref = self.summaries[key]; - var m = self.options.query[0].metrics[mindex]; - - if ((m.aggregation || 'sum') === 'sum' && ref.data.length > 0) { - var total, comparetotal; - if (ref.data[0].length > 0) - total = ref.data[0][0].metrics[m.key]; - if (ref.data.length > 1 && ref.data[1].length > 0 && ref.data[1].type !== 'overall') { - comparetotal = ref.data[1][0].metrics[m.key]; - } - var $summaries = $$('.value.metric[data-key="' + m.key + '"]'); - $summaries.each(function (index, summary) { - var $summary = $$(summary); - var value = $summary.attr('data-value'); - if (value === 'N/A') { - $summary.find('span.summary').text(' (N/A)'); - } - else { - if ($summary.hasClass('compare')) - value = (value / comparetotal * 100).toFixed(2) + '%'; - else - value = (value / total * 100).toFixed(2) + '%'; - $summary.find('span.summary').text(' (' + value + ')'); - } - }); + this.handlePaging = function () { + var $showing = $$(self.options.$container.find('.showing')); + + var total = self._data[0].length; + var to = self.options.paging.currentPage * self.options.paging.currentSize; + if (to > total) + to = total; + var showingText = ((self.options.paging.currentPage - 1) * self.options.paging.currentSize + 1) + ' - ' + to + ' of ' + total; + + $showing.text(showingText); + + var $prev = $$(self.options.$container.find('.prev')); + var $next = $$(self.options.$container.find('.next')); + if (self.options.paging.currentPage > 1) { + $prev.removeClass('disabled'); + $prev.off('click'); + $prev.on('click', function () { + if (self.options.paging.currentPage > 1) { + self.options.paging.currentPage--; + self.paint(); } }); - }; + } + else { + $prev.addClass('disabled'); + $prev.off('click'); + } + var nextIndex = ((self.options.paging.currentPage ) * self.options.paging.currentSize); + if (nextIndex < self._data[0].length) { + $next.removeClass('disabled'); + $next.off('click'); + $next.on('click', function () { + var nextIndex = ((self.options.paging.currentPage ) * self.options.paging.currentSize); + if (nextIndex < self._data[0].length) { + self.options.paging.currentPage++; + self.paint(); + } + }); + } + else { + $next.addClass('disabled'); + $next.off('click'); + } + }; - this.draw = function (options) { - //we draw the template into the container - var $html = $$(self.options.template); - $$(self.options.container).html($html); - if (self.options.caption) - $$(self.options.container).find('.table-caption').text(self.options.caption); - //visualization specific drawing - if (self.options.pickers && self.options.pickers.primary && self.options.pickers.primary.enabled) { - var $primary_dimension_picker = $$($html.find('.primary-dimension-picker')); - self.options.pickers.primary.css = 'table-picker'; - self.options.pickers.primary.container = $primary_dimension_picker.get(0); - var dimension = self.options.query[0].dimensions[0]; - if (!dimension.key) - dimension = {key: dimension}; - if (!dimension.collection) - dimension.collection = self.options.query[0].collection; - self.options.pickers.primary.selected = dimension; - self.options.pickers.primary.disabled = self.options.query[0].dimensions; - self.options.pickers.primary.prefix = 'Primary dimension: '; - self.primary_dimension_picker = new joola.viz.DimensionPicker(self.options.pickers.primary).on('change', function (dimension) { - self.options.query.forEach(function (q) { - if (dimension) - q.dimensions[0] = dimension; + this.sort = function () { + + }; + + this.summarize = function () { + Object.keys(self.summaries).forEach(function (key, mindex) { + var ref = self.summaries[key]; + var m = self.options.query[0].metrics[mindex]; + + if ((m.aggregation || 'sum') === 'sum' && ref.data.length > 0) { + var total, comparetotal; + if (ref.data[0].length > 0) + total = ref.data[0][0].metrics[m.key]; + if (ref.data.length > 1 && ref.data[1].length > 0 && ref.data[1].type !== 'overall') { + comparetotal = ref.data[1][0].metrics[m.key]; + } + var $summaries = $$('.value.metric[data-key="' + m.key + '"]'); + $summaries.each(function (index, summary) { + var $summary = $$(summary); + var value = $summary.attr('data-value'); + if (value === 'N/A') { + $summary.find('span.summary').text(' (N/A)'); + } + else { + if ($summary.hasClass('compare')) + value = (value / comparetotal * 100).toFixed(2) + '%'; else - q.dimensions.splice(0, 1); - }); - self.options.paging.currentPage = 1; - self.data = []; - joola.viz.initialize(self, self.options); + value = (value / total * 100).toFixed(2) + '%'; + $summary.find('span.summary').text(' (' + value + ')'); + } }); } - if (self.options.pickers && self.options.pickers.add_dimension && self.options.pickers.add_dimension.enabled) { - var $add_dimension_picker = $$($html.find('.add-dimension-picker')); - self.options.pickers.add_dimension.css = 'table-picker'; - self.options.pickers.add_dimension.container = $add_dimension_picker.get(0); - self.options.pickers.add_dimension.caption = self.options.pickers.add_dimension.caption || 'Add dimension...'; - self.options.pickers.add_dimension.disabled = self.options.query[0].dimensions; - self.add_dimension_picker = new joola.viz.DimensionPicker(self.options.pickers.add_dimension).on('change', function (dimension) { - self.options.query.forEach(function (q) { - if (dimension) { - dimension.allowremove = true; - q.dimensions.push(dimension); - } - }); - self.data = []; - self.options.paging.currentPage = 1; - self.sortIndex++; - self.handleMetricBoxes(); - joola.viz.initialize(self, self.options); + }); + }; + + this.draw = function (options) { + //we draw the template into the container + var $html = $$(self.options.template); + $$(self.options.container).html($html); + if (self.options.caption) + $$(self.options.container).find('.table-caption').text(self.options.caption); + //visualization specific drawing + if (self.options.pickers && self.options.pickers.primary && self.options.pickers.primary.enabled) { + var $primary_dimension_picker = $$($html.find('.primary-dimension-picker')); + self.options.pickers.primary.css = 'table-picker'; + self.options.pickers.primary.container = $primary_dimension_picker.get(0); + var dimension = self.options.query[0].dimensions[0]; + if (!dimension.key) + dimension = {key: dimension}; + if (!dimension.collection) + dimension.collection = self.options.query[0].collection; + self.options.pickers.primary.selected = dimension; + self.options.pickers.primary.disabled = self.options.query[0].dimensions; + self.options.pickers.primary.prefix = 'Primary dimension: '; + self.primary_dimension_picker = new joola.viz.DimensionPicker(self.options.pickers.primary).on('change', function (dimension) { + self.options.query.forEach(function (q) { + if (dimension) + q.dimensions[0] = dimension; + else + q.dimensions.splice(0, 1); }); - } - if (self.options.pickers && self.options.pickers.add_metric && self.options.pickers.add_metric.enabled) { - var $add_metric_picker = $$($html.find('.add-metric-picker')); - self.options.pickers.add_metric.css = 'table-picker'; - self.options.pickers.add_metric.container = $add_metric_picker.get(0); - self.options.pickers.add_metric.caption = self.options.pickers.add_metric.caption || 'Add metric...'; - self.options.pickers.add_metric.disabled = self.options.query[0].metrics; - self.add_metric_picker = new joola.viz.MetricPicker(self.options.pickers.add_metric).on('change', function (metric) { - self.options.query.forEach(function (q) { - if (metric) { - metric.allowremove = true; - q.metrics.push(metric); - } - }); - self.data = []; - self.options.paging.currentPage = 1; - self.sortIndex++; - self.handleMetricBoxes(); - joola.viz.initialize(self, self.options); + self.options.paging.currentPage = 1; + self.data = []; + joola.viz.initialize(self, self.options); + }); + } + if (self.options.pickers && self.options.pickers.add_dimension && self.options.pickers.add_dimension.enabled) { + var $add_dimension_picker = $$($html.find('.add-dimension-picker')); + self.options.pickers.add_dimension.css = 'table-picker'; + self.options.pickers.add_dimension.container = $add_dimension_picker.get(0); + self.options.pickers.add_dimension.caption = self.options.pickers.add_dimension.caption || 'Add dimension...'; + self.options.pickers.add_dimension.disabled = self.options.query[0].dimensions; + self.add_dimension_picker = new joola.viz.DimensionPicker(self.options.pickers.add_dimension).on('change', function (dimension) { + self.options.query.forEach(function (q) { + if (dimension) { + dimension.allowremove = true; + q.dimensions.push(dimension); + } }); - } - var $thead = $$($html.find('thead')); - $html.find('table').append($thead); - - var $tbody = $html.find('tbody'); - $tbody = $$($tbody); - $tbody.empty(); - - var $metric_tr = $$(''); - $tbody.append($metric_tr); - self.handleHeaders(); - self.handleMetricBoxes(); - var $tr = $$(''); - var $td = $$('' + self.options.strings.loading + ''); - $tr.append($td); - $tbody.append($tr); - $html.find('table').append($tbody); - - var $pageSize = $$($html.find('.page-size select')); - self.options.paging.sizes.forEach(function (size) { - var $option = $$(''); - $pageSize.append($option); + self.data = []; + self.options.paging.currentPage = 1; + self.sortIndex++; + self.handleMetricBoxes(); + joola.viz.initialize(self, self.options); }); - $pageSize.on('change', function () { + } + if (self.options.pickers && self.options.pickers.add_metric && self.options.pickers.add_metric.enabled) { + var $add_metric_picker = $$($html.find('.add-metric-picker')); + self.options.pickers.add_metric.css = 'table-picker'; + self.options.pickers.add_metric.container = $add_metric_picker.get(0); + self.options.pickers.add_metric.caption = self.options.pickers.add_metric.caption || 'Add metric...'; + self.options.pickers.add_metric.disabled = self.options.query[0].metrics; + self.add_metric_picker = new joola.viz.MetricPicker(self.options.pickers.add_metric).on('change', function (metric) { + self.options.query.forEach(function (q) { + if (metric) { + metric.allowremove = true; + q.metrics.push(metric); + } + }); + self.data = []; self.options.paging.currentPage = 1; - self.options.paging.currentSize = parseInt($pageSize.val(), 10); - self.paint(); + self.sortIndex++; + self.handleMetricBoxes(); + joola.viz.initialize(self, self.options); }); + } + var $thead = $$($html.find('thead')); + $html.find('table').append($thead); - var $search = $$($html.find('input.search')); - $search.on('keyup', function () { - if ($search.val().length > 2) - self.options.paging.currentPage = 1; - self.paint(); - }); - }; + var $tbody = $html.find('tbody'); + $tbody = $$($tbody); + $tbody.empty(); + + var $metric_tr = $$(''); + $tbody.append($metric_tr); + self.handleHeaders(); + self.handleMetricBoxes(); + var $tr = $$(''); + var $td = $$('' + self.options.strings.loading + ''); + $tr.append($td); + $tbody.append($tr); + $html.find('table').append($tbody); - if (options && options.query && !Array.isArray(options.query)) - options.query = [options.query]; + var $pageSize = $$($html.find('.page-size select')); + self.options.paging.sizes.forEach(function (size) { + var $option = $$(''); + $pageSize.append($option); + }); + $pageSize.on('change', function () { + self.options.paging.currentPage = 1; + self.options.paging.currentSize = parseInt($pageSize.val(), 10); + self.paint(); + }); - options.query[0].sort = [ - [options.query[0].metrics[0].key || options.query[0].metrics[0], 'DESC'] - ]; -//we call the core initialize option - joola.viz.initialize(self, options || {}); + var $search = $$($html.find('input.search')); + $search.on('keyup', function () { + if ($search.val().length > 2) + self.options.paging.currentPage = 1; + self.paint(); + }); + }; - if (self.options.colors.length === 0) - self.options.colors = joola.colors; - if (self.options.offcolors.length === 0) - self.options.offcolors = joola.offcolors; + if (options && options.query && !Array.isArray(options.query)) + options.query = [options.query]; - self.draw(); + options.query[0].sort = [ + [options.query[0].metrics[0].key || options.query[0].metrics[0], 'DESC'] + ]; +//we call the core initialize option + joola.viz.initialize(self, options || {}); + + if (self.options.colors.length === 0) + self.options.colors = joola.colors; + if (self.options.offcolors.length === 0) + self.options.offcolors = joola.offcolors; + self.draw(null, function (err, ref) { + if (err) + return callback(err); joola.viz.onscreen.push(self); if (!self.options.canvas) { var elem = $$(self.options.$container).parent(); @@ -56007,14 +59763,13 @@ var Table = module.exports = function (options, callback) { self.options.canvas.addVisualization(self); } -//wrap up + //wrap up self.initialized = true; if (typeof callback === 'function') - return callback(null, self); - - return self; - } - ; + return callback(null, ref); + }); + return self; +}; joola.events.on('core.init.finish', function () { var found; @@ -56048,6 +59803,8 @@ joola.events.on('core.init.finish', function () { result = new joola.viz.Table(options, function (err, table) { if (err) throw err; + if (callback) + return callback(null, table); }).options.$container; } else { @@ -56066,7 +59823,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Table, events.EventEmitter); -},{"../index":99,"async":2,"cloneextend":35,"events":12,"jquery":40,"underscore":89,"util":34}],113:[function(require,module,exports){ +},{"../index":115,"async":3,"cloneextend":4,"events":14,"jquery":53,"underscore":105,"util":21}],129:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -56444,6 +60201,7 @@ var Timeline = module.exports = function (options, callback) { this.draw = function (options, callback) { self.chartOptions = joola.common._mixin({}, self.options.chart); + self.options.$container.empty(); self.options.$container.append(self.options.template || self.template()); self.options.$container.find('.caption').text(self.options.caption || ''); @@ -56676,23 +60434,25 @@ var Timeline = module.exports = function (options, callback) { //we call the core initialize option joola.viz.initialize(self, options || {}); - self.draw(); - joola.viz.onscreen.push(self); - if (!self.options.canvas) { - var elem = $$(self.options.$container).parent(); - if (elem.attr('jio-type') == 'canvas') { - self.options.canvas = $$(elem).Canvas(); + self.draw(null, function (err, ref) { + if (err) + return callback(err); + joola.viz.onscreen.push(self); + if (!self.options.canvas) { + var elem = $$(self.options.$container).parent(); + if (elem.attr('jio-type') == 'canvas') { + self.options.canvas = $$(elem).Canvas(); + } + } + if (self.options.canvas) { + self.options.canvas.addVisualization(self); } - } - if (self.options.canvas) { - self.options.canvas.addVisualization(self); - } - - //wrap up - self.initialized = true; - if (typeof callback === 'function') - return callback(null, self); + //wrap up + self.initialized = true; + if (typeof callback === 'function') + return callback(null, ref); + }); return self; }; @@ -56726,7 +60486,10 @@ joola.events.on('core.init.finish', function () { result = new joola.viz.Timeline(options, function (err, timeline) { if (err) throw err; - timeline.draw(options, callback); + //timeline.draw(options, callback); + if (callback) + return callback(null, timeline); + }).options.$container; } else { @@ -56745,7 +60508,7 @@ joola.events.on('core.init.finish', function () { }); util.inherits(Timeline, events.EventEmitter); -},{"../index":99,"cloneextend":35,"events":12,"jquery":40,"moment":41,"twix":88,"underscore":89,"util":34}],114:[function(require,module,exports){ +},{"../index":115,"cloneextend":4,"events":14,"jquery":53,"moment":54,"twix":104,"underscore":105,"util":21}],130:[function(require,module,exports){ /** * @title joola * @overview the open-source data analytics framework @@ -56852,6 +60615,7 @@ viz.initialize = function (self, options, callback) { } } if (self.options.query) { + console.log('qqq', self.options.query); viz.fetch(self, self.options.query, function () { if (callback && typeof callback === 'function') return callback(null, self); @@ -57128,4 +60892,6 @@ viz.destroy = function (self, vizOptions) { } }); });*/ -},{"../index":99,"./BarTable":100,"./Canvas":101,"./DatePicker":102,"./DimensionPicker":103,"./FilterBox":104,"./Geo":105,"./Metric":106,"./MetricPicker":107,"./MiniTable":108,"./Pie":109,"./PunchCard":110,"./Sparkline":111,"./Table":112,"./Timeline":113,"async":2,"cloneextend":35,"jquery":40,"underscore":89}]},{},[99]) \ No newline at end of file +},{"../index":115,"./BarTable":116,"./Canvas":117,"./DatePicker":118,"./DimensionPicker":119,"./FilterBox":120,"./Geo":121,"./Metric":122,"./MetricPicker":123,"./MiniTable":124,"./Pie":125,"./PunchCard":126,"./Sparkline":127,"./Table":128,"./Timeline":129,"async":3,"cloneextend":4,"jquery":53,"underscore":105}]},{},[2,115]) +//@ sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9idWlsZC90ZW1wL21ldGEuanNvbiIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9idWlsZC90ZW1wL3ZlbmRvci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvYXN5bmMvbGliL2FzeW5jLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9jbG9uZWV4dGVuZC9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZGVlcC1leHRlbmQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2V2ZW50ZW1pdHRlcjIvbGliL2V2ZW50ZW1pdHRlcjIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vX3NoaW1zLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL19zdHJlYW1fZHVwbGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL19zdHJlYW1fcGFzc3Rocm91Z2guanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vX3N0cmVhbV9yZWFkYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9fc3RyZWFtX3RyYW5zZm9ybS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9fc3RyZWFtX3dyaXRhYmxlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL2Fzc2VydC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi9ldmVudHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vaHR0cHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vcXVlcnlzdHJpbmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vc3RyZWFtLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL3N0cmluZ19kZWNvZGVyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9idWlsdGluL3RpbWVycy5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvYnVpbHRpbi91cmwuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL2J1aWx0aW4vdXRpbC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItYnVpbHRpbnMvbm9kZV9tb2R1bGVzL2J1ZmZlci1icm93c2VyaWZ5L2J1ZmZlcl9pZWVlNzU0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvYnVmZmVyLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9idWZmZXItYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9oZWxwZXJzLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvY3J5cHRvLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9tZDUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9ybmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9jcnlwdG8tYnJvd3NlcmlmeS9zaGEyNTYuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3JlcXVlc3QuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLWJ1aWx0aW5zL25vZGVfbW9kdWxlcy9odHRwLWJyb3dzZXJpZnkvbGliL3Jlc3BvbnNlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1idWlsdGlucy9ub2RlX21vZHVsZXMvaHR0cC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9CYXNlNjQvYmFzZTY0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL25vZGVfbW9kdWxlcy90by11dGY4L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9ub2RlX21vZHVsZXMvYm9wcy90eXBlZGFycmF5L2NvcHkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvY3JlYXRlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9ncnVudC13YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvY29uY2F0LXN0cmVhbS9ub2RlX21vZHVsZXMvYm9wcy90eXBlZGFycmF5L2Zyb20uanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvaXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvam9pbi5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS9tYXBwZWQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9jb25jYXQtc3RyZWFtL25vZGVfbW9kdWxlcy9ib3BzL3R5cGVkYXJyYXkvcmVhZC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS9zdWJhcnJheS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS90by5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2NvbmNhdC1zdHJlYW0vbm9kZV9tb2R1bGVzL2JvcHMvdHlwZWRhcnJheS93cml0ZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvZ3J1bnQtd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2luc2VydC1tb2R1bGUtZ2xvYmFscy9idWZmZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2dydW50LXdhdGNoaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9pbnNlcnQtbW9kdWxlLWdsb2JhbHMvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvanF1ZXJ5LXVpL2NvcmUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL2pxdWVyeS11aS9kYXRlcGlja2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9qcXVlcnkvZGlzdC9qcXVlcnkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL21vbWVudC9tb21lbnQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbGliL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9tYW5hZ2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi9vbi5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9saWIvc29ja2V0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L2xpYi91cmwuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2NvbXBvbmVudC1iaW5kL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9jb21wb25lbnQtZW1pdHRlci9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZGVidWcvZGVidWcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi9zb2NrZXQuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9saWIvdHJhbnNwb3J0cy9wb2xsaW5nLWpzb25wLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcteGhyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi90cmFuc3BvcnRzL3BvbGxpbmcuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbGliL3RyYW5zcG9ydHMvd2Vic29ja2V0LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L2xpYi94bWxodHRwcmVxdWVzdC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvY29tcG9uZW50LWluaGVyaXQvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2RlYnVnL2Jyb3dzZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2RlYnVnL2RlYnVnLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9kZWJ1Zy9ub2RlX21vZHVsZXMvbXMvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2Jyb3dzZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbGliL2tleXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2FmdGVyL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9lbmdpbmUuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9hcnJheWJ1ZmZlci5zbGljZS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLXBhcnNlci9ub2RlX21vZHVsZXMvYmFzZTY0LWFycmF5YnVmZmVyL2xpYi9iYXNlNjQtYXJyYXlidWZmZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL2Jsb2IvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1wYXJzZXIvbm9kZV9tb2R1bGVzL3V0ZjgvdXRmOC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvaGFzLWNvcnMvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2hhcy1jb3JzL25vZGVfbW9kdWxlcy9nbG9iYWwvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3BhcnNlanNvbi9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvcGFyc2Vxcy9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvZW5naW5lLmlvLWNsaWVudC9ub2RlX21vZHVsZXMvcGFyc2V1cmkvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL2VuZ2luZS5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3dzL2xpYi9icm93c2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9oYXMtYmluYXJ5L25vZGVfbW9kdWxlcy9pc2FycmF5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9pbmRleG9mL2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9vYmplY3QtY29tcG9uZW50L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9wYXJzZXVyaS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvc29ja2V0LmlvLWNsaWVudC9ub2RlX21vZHVsZXMvc29ja2V0LmlvLXBhcnNlci9iaW5hcnkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1wYXJzZXIvaXMtYnVmZmVyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tY2xpZW50L25vZGVfbW9kdWxlcy9zb2NrZXQuaW8tcGFyc2VyL25vZGVfbW9kdWxlcy9qc29uMy9saWIvanNvbjMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvbm9kZV9tb2R1bGVzL3NvY2tldC5pby1jbGllbnQvbm9kZV9tb2R1bGVzL3RvLWFycmF5L2luZGV4LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL25vZGVfbW9kdWxlcy90cmF2ZXJzZS9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdHdpeC9iaW4vbGFuZy5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdHdpeC9iaW4vdHdpeC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9ub2RlX21vZHVsZXMvdW5kZXJzY29yZS91bmRlcnNjb3JlLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3BhY2thZ2UuanNvbiIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL2NvbW1vbi9hcGkuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vZGlzcGF0Y2guanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vZXZlbnRzLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvY29tbW9uL2dsb2JhbHMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vaW5kZXguanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9jb21tb24vbG9nZ2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvY29tbW9uL21lbW9yeS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL2NvbW1vbi9tb2RpZmllcnMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi9pbmRleC5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9CYXJUYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9DYW52YXMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovRGF0ZVBpY2tlci5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9EaW1lbnNpb25QaWNrZXIuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovRmlsdGVyQm94LmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L0dlby5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9NZXRyaWMuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovTWV0cmljUGlja2VyLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L01pbmlUYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9QaWUuanMiLCIvaG9tZS9pdGF5L2Rldi9qb29sYS5zZGsvc3JjL2xpYi92aXovUHVuY2hDYXJkLmpzIiwiL2hvbWUvaXRheS9kZXYvam9vbGEuc2RrL3NyYy9saWIvdml6L1NwYXJrbGluZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9UYWJsZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9UaW1lbGluZS5qcyIsIi9ob21lL2l0YXkvZGV2L2pvb2xhLnNkay9zcmMvbGliL3Zpei9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwNmpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzk3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDelBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3akJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2NUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9oQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwbUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BEQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzEwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ovREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0K1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4M0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzcUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDck1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdGpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9PQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNVlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3MUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1dkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25TQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25RQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3AyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHM9e1widXNlcnNcIjp7XCJsaXN0XCI6e1wibmFtZVwiOlwiL3VzZXJzL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSB1c2Vyc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOmxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczpsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZ2V0XCI6e1wibmFtZVwiOlwiL3VzZXJzL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgdXNlcnMgYnkgdXNlcm5hbWVcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwidXNlcm5hbWVcIl0sXCJfcHJvdG9cIjp7XCJ1c2VybmFtZVwiOntcIm5hbWVcIjpcInVzZXJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyB1c2VybmFtZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGlzcGxheU5hbWVcIjp7XCJuYW1lXCI6XCJkaXNwbGF5TmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaXNwbGF5bmFtZSBvZiB0aGUgdXNlclwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJwYXNzd29yZFwiOntcIm5hbWVcIjpcInBhc3N3b3JkXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBwYXNzd29yZFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJyb2xlc1wiOntcIm5hbWVcIjpcInJvbGVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyByb2xlc1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBmaWx0ZXJcIixcInR5cGVcIjpcImFycmF5XCIsXCJkZWZhdWx0XCI6W10sXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwiQVBJVG9rZW5cIjp7XCJuYW1lXCI6XCJBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgQVBJIFRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwid29ya3NwYWNlXCI6e1wibmFtZVwiOlwid29ya3NwYWNlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBXb3Jrc3BhY2VcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgY3VycmVudCBzZWN1cml0eSB0b2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1widXNlcnM6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZ2V0QnlUb2tlblwiOntcIm5hbWVcIjpcIi91c2Vycy9nZXRCeVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyB1c2VyIGJ5IHRva2VuXCIsXCJpbnB1dHNcIjpbXCJ0b2tlblwiXSxcIl9wcm90b1wiOntcInVzZXJuYW1lXCI6e1wibmFtZVwiOlwidXNlcm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHVzZXJuYW1lXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkaXNwbGF5TmFtZVwiOntcIm5hbWVcIjpcImRpc3BsYXlOYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpc3BsYXluYW1lIG9mIHRoZSB1c2VyXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInBhc3N3b3JkXCI6e1wibmFtZVwiOlwicGFzc3dvcmRcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHBhc3N3b3JkXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcInJvbGVzXCI6e1wibmFtZVwiOlwicm9sZXNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHJvbGVzXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGZpbHRlclwiLFwidHlwZVwiOlwiYXJyYXlcIixcImRlZmF1bHRcIjpbXSxcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJBUElUb2tlblwiOntcIm5hbWVcIjpcIkFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBBUEkgVG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJ3b3Jrc3BhY2VcIjp7XCJuYW1lXCI6XCJ3b3Jrc3BhY2VcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIFdvcmtzcGFjZVwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJ0b2tlblwiOntcIm5hbWVcIjpcInRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBjdXJyZW50IHNlY3VyaXR5IHRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJndWVzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmdldEJ5VG9rZW5cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJhZGRcIjp7XCJuYW1lXCI6XCIvdXNlcnMvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgdXNlclwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJ1c2VyXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmFkZFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInBhdGNoXCI6e1wibmFtZVwiOlwiL3VzZXJzL3BhdGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwYXRjaCBhbiBleGlzdGluZyB1c2VyXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcInVzZXJuYW1lXCIsXCJ1c2VyXCJdLFwiX3Byb3RvXCI6e1widXNlcm5hbWVcIjp7XCJuYW1lXCI6XCJ1c2VybmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgdXNlcm5hbWVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRpc3BsYXlOYW1lXCI6e1wibmFtZVwiOlwiZGlzcGxheU5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGlzcGxheW5hbWUgb2YgdGhlIHVzZXJcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwicGFzc3dvcmRcIjp7XCJuYW1lXCI6XCJwYXNzd29yZFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgcGFzc3dvcmRcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwicm9sZXNcIjp7XCJuYW1lXCI6XCJyb2xlc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3Mgcm9sZXNcIixcInJlcXVpcmVkXCI6dHJ1ZSxcInByaXZhdGVcIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgZmlsdGVyXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwiZGVmYXVsdFwiOltdLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIkFQSVRva2VuXCI6e1wibmFtZVwiOlwiQVBJVG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIEFQSSBUb2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlfSxcIndvcmtzcGFjZVwiOntcIm5hbWVcIjpcIndvcmtzcGFjZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgV29ya3NwYWNlXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInRva2VuXCI6e1wibmFtZVwiOlwidG9rZW5cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGN1cnJlbnQgc2VjdXJpdHkgdG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOnBhdGNoXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvdXNlcnMvZGVsZXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBkZWxldGUgYW4gZXhpc3RpbmcgdXNlclwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJ1c2VyXCJdLFwiX3Byb3RvXCI6bnVsbCxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInVzZXJzOmRlbGV0ZVwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmRlbGV0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImF1dGhlbnRpY2F0ZVwiOntcIm5hbWVcIjpcIi91c2Vycy9hdXRoZW50aWNhdGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGF1dGhlbnRpY2F0ZSB1c2Vyc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJ1c2VybmFtZVwiLFwicGFzc3dvcmRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJndWVzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOmF1dGhlbnRpY2F0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInZlcmlmeUFQSVRva2VuXCI6e1wibmFtZVwiOlwiL3VzZXJzL3ZlcmlmeUFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiSSB2ZXJpZnkgQVBJIHRva2Vuc1wiLFwiaW5wdXRzXCI6W1widG9rZW5cIl0sXCJfcHJvdG9cIjp7XCJ1c2VybmFtZVwiOntcIm5hbWVcIjpcInVzZXJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyB1c2VybmFtZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGlzcGxheU5hbWVcIjp7XCJuYW1lXCI6XCJkaXNwbGF5TmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaXNwbGF5bmFtZSBvZiB0aGUgdXNlclwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJwYXNzd29yZFwiOntcIm5hbWVcIjpcInBhc3N3b3JkXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBwYXNzd29yZFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJyb2xlc1wiOntcIm5hbWVcIjpcInJvbGVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyByb2xlc1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBmaWx0ZXJcIixcInR5cGVcIjpcImFycmF5XCIsXCJkZWZhdWx0XCI6W10sXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwiQVBJVG9rZW5cIjp7XCJuYW1lXCI6XCJBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgQVBJIFRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwid29ya3NwYWNlXCI6e1wibmFtZVwiOlwid29ya3NwYWNlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBXb3Jrc3BhY2VcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgY3VycmVudCBzZWN1cml0eSB0b2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZ3Vlc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2Vyczp2ZXJpZnlBUElUb2tlblwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdlbmVyYXRlVG9rZW5cIjp7XCJuYW1lXCI6XCIvdXNlcnMvZ2VuZXJhdGVUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2VuZXJhdGUgdG9rZW5zIGZvciB1c2Vyc1wiLFwiaW5wdXRzXCI6W1widXNlclwiXSxcIl9wcm90b1wiOntcInVzZXJcIjp7XCJuYW1lXCI6XCJ1c2VyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIgYXNzb3NpY2F0ZWQgd2l0aCB0aGUgdG9rZW5cIixcInR5cGVcIjpcIm9iamVjdFwiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0b2tlbiBpdHNlbGZcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJfXCI6e1wibmFtZVwiOlwiX1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0b2tlbiBpdHNlbGZcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJ0aW1lc3RhbXBcIjp7XCJuYW1lXCI6XCJ0aW1lc3RhbXBcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdG9rZW4gZ2VuZXJhdGlvbiB0aW1lc3RhbXBcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJsYXN0XCI6e1wibmFtZVwiOlwibGFzdFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0b2tlbiBsYXN0IHVzYWdlIHRpbWVzdGFtcFwiLFwicmVxdWlyZWRcIjp0cnVlfSxcImV4cGlyZXNcIjp7XCJuYW1lXCI6XCJleHBpcmVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHRva2VuIGV4cGlyeSB0aW1lc3RhbXBcIixcInR5cGVcIjpcImludFwiLFwicmVxdWlyZWRcIjp0cnVlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ1c2VyczpnZW5lcmF0ZVRva2VuXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwidXNlcnM6Z2VuZXJhdGVUb2tlblwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInZhbGlkYXRlVG9rZW5cIjp7XCJuYW1lXCI6XCIvdXNlcnMvdmFsaWRhdGVUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgdmFsaWRhdGUgdG9rZW5zIGZvciB1c2Vyc1wiLFwiaW5wdXRzXCI6W1widG9rZW5cIl0sXCJfcHJvdG9cIjp7XCJ1c2VybmFtZVwiOntcIm5hbWVcIjpcInVzZXJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyB1c2VybmFtZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGlzcGxheU5hbWVcIjp7XCJuYW1lXCI6XCJkaXNwbGF5TmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaXNwbGF5bmFtZSBvZiB0aGUgdXNlclwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJwYXNzd29yZFwiOntcIm5hbWVcIjpcInBhc3N3b3JkXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBwYXNzd29yZFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcInByaXZhdGVcIjp0cnVlLFwiaGlkZGVuXCI6dHJ1ZX0sXCJyb2xlc1wiOntcIm5hbWVcIjpcInJvbGVzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyByb2xlc1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBmaWx0ZXJcIixcInR5cGVcIjpcImFycmF5XCIsXCJkZWZhdWx0XCI6W10sXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwiQVBJVG9rZW5cIjp7XCJuYW1lXCI6XCJBUElUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgQVBJIFRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWV9LFwid29ya3NwYWNlXCI6e1wibmFtZVwiOlwid29ya3NwYWNlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBXb3Jrc3BhY2VcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwidG9rZW5cIjp7XCJuYW1lXCI6XCJ0b2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB1c2VyJ3MgY3VycmVudCBzZWN1cml0eSB0b2tlblwiLFwicmVxdWlyZWRcIjpmYWxzZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1widXNlcnM6dmFsaWRhdGVUb2tlblwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInVzZXJzOnZhbGlkYXRlVG9rZW5cIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJleHBpcmVUb2tlblwiOntcIm5hbWVcIjpcIi91c2Vycy9leHBpcmVUb2tlblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZXhwaXJlIHRva2VucyBmb3IgdXNlcnNcIixcImlucHV0c1wiOltcInRva2VuXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1widXNlcnM6ZXhwaXJlVG9rZW5cIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczpleHBpcmVUb2tlblwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInBlcm1pc3Npb25zXCI6e1wibmFtZVwiOlwiL3VzZXJzL3Blcm1pc3Npb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgdGhlIHVzZXIncyBwZXJtaXNzaW9uc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJ1c2VyXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1widXNlcnM6cGVybWlzc2lvbnNcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ1c2VyczpwZXJtaXNzaW9uc1wiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJ3b3Jrc3BhY2VzXCI6e1wibGlzdFwiOntcIm5hbWVcIjpcIi93b3Jrc3BhY2VzL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSB3b3Jrc3BhY2VzXCIsXCJpbnB1dHNcIjpbXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBrZXkgb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwibmFtZVwiOntcIm5hbWVcIjpcIm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbmFtZSBvZiB0aGUgd29ya3NwYWNlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgd29ya3NwYWNlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIndvcmtzcGFjZXM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIndvcmtzcGFjZXM6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi93b3Jrc3BhY2VzL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgd29ya3NwYWNlIGJ5IGtleWBcIixcImlucHV0c1wiOltcImtleVwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBrZXkgb2YgdGhlIHdvcmtzcGFjZVwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwibmFtZVwiOntcIm5hbWVcIjpcIm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbmFtZSBvZiB0aGUgd29ya3NwYWNlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgd29ya3NwYWNlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIndvcmtzcGFjZXM6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwid29ya3NwYWNlczpnZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJhZGRcIjp7XCJuYW1lXCI6XCIvd29ya3NwYWNlcy9hZGRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGFkZCBhIG5ldyB1c2VyXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ3b3Jrc3BhY2VzOmFkZFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIndvcmtzcGFjZXM6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvd29ya3NwYWNlcy9wYXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcGF0Y2ggYW4gZXhpc3Rpbmcgd29ya3NwYWNlXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcInBheWxvYWRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJ3b3Jrc3BhY2VzOnBhdGNoXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwid29ya3NwYWNlczpwYXRjaFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImRlbGV0ZVwiOntcIm5hbWVcIjpcIi93b3Jrc3BhY2VzL2RlbGV0ZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZGVsZXRlIGFuIGV4aXN0aW5nIHdvcmtzcGFjZVwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wid29ya3NwYWNlczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJ3b3Jrc3BhY2VzOmRlbGV0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJyb2xlc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvcm9sZXMvbGlzdFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbGlzdCBhbGwgYXZhaWxhYmxlIHJvbGVzXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUga2V5IG9mIHRoZSByb2xlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJwZXJtaXNzaW9uc1wiOntcIm5hbWVcIjpcInBlcm1pc3Npb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBwZXJtaXNzaW9ucyBhc3Nvc2NpYXRlZCB3aXRoIHRoaXMgcm9sZVwiLFwicmVxdWlyZWRcIjp0cnVlLFwiZGVmYXVsdFwiOltdLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBmaWx0ZXJzIGZvciB0aGUgc3BlY2lmaWVkIHJvbGVcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6W10sXCJwcml2YXRlXCI6dHJ1ZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicm9sZXM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInJvbGVzOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvcm9sZXMvZ2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyByb2xlIGJ5IG5hbWVgXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcIm5hbWVcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUga2V5IG9mIHRoZSByb2xlXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJwZXJtaXNzaW9uc1wiOntcIm5hbWVcIjpcInBlcm1pc3Npb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBwZXJtaXNzaW9ucyBhc3Nvc2NpYXRlZCB3aXRoIHRoaXMgcm9sZVwiLFwicmVxdWlyZWRcIjp0cnVlLFwiZGVmYXVsdFwiOltdLFwicHJpdmF0ZVwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiTGlzdCBvZiBmaWx0ZXJzIGZvciB0aGUgc3BlY2lmaWVkIHJvbGVcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6W10sXCJwcml2YXRlXCI6dHJ1ZX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicm9sZXM6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicm9sZXM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL3JvbGVzL2FkZFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgYWRkIGEgbmV3IHVzZXJcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwicm9sZVwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBrZXkgb2YgdGhlIHJvbGVcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcInBlcm1pc3Npb25zXCI6e1wibmFtZVwiOlwicGVybWlzc2lvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJMaXN0IG9mIHBlcm1pc3Npb25zIGFzc29zY2lhdGVkIHdpdGggdGhpcyByb2xlXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJkZWZhdWx0XCI6W10sXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJMaXN0IG9mIGZpbHRlcnMgZm9yIHRoZSBzcGVjaWZpZWQgcm9sZVwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpbXSxcInByaXZhdGVcIjp0cnVlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJyb2xlczphZGRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJyb2xlczphZGRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJwYXRjaFwiOntcIm5hbWVcIjpcIi9yb2xlcy9wYXRjaFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcGF0Y2ggYW4gZXhpc3Rpbmcgcm9sZVwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJyb2xlXCIsXCJwYXlsb2FkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicm9sZXM6cGF0Y2hcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJyb2xlczpwYXRjaFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImRlbGV0ZVwiOntcIm5hbWVcIjpcIi9yb2xlcy9kZWxldGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGRlbGV0ZSBhbiBleGlzdGluZyByb2xlXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcInJvbGVcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJyb2xlczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJyb2xlczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwicGVybWlzc2lvbnNcIjp7XCJsaXN0XCI6e1wibmFtZVwiOlwiL3Blcm1pc3Npb25zL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSBwZXJtaXNzaW9uc1wiLFwiaW5wdXRzXCI6W10sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJwZXJtaXNzaW9uczpsaXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicGVybWlzc2lvbnM6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi9wZXJtaXNzaW9ucy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIHBlcm1pc3Npb24gYnkgbmFtZWBcIixcImlucHV0c1wiOltcIm5hbWVcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJwZXJtaXNzaW9uczpnZXRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJwZXJtaXNzaW9uczpnZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwic3lzdGVtXCI6e1widmVyc2lvblwiOntcIm5hbWVcIjpcIi9zeXN0ZW0vdmVyc2lvblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHJpbnQgb3V0IHRoZSB2ZXJzaW9uXCIsXCJ2ZXJiXCI6XCJHRVRcIixcImlucHV0c1wiOltdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOnZlcnNpb25cIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06dmVyc2lvblwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcIm5vZGVVSURcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL25vZGVVSURcIixcImRlc2NyaXB0aW9uXCI6XCJJIHByaW50IG91dCB0aGUgbm9kZSB1dWlkXCIsXCJ2ZXJiXCI6XCJHRVRcIixcImlucHV0c1wiOltdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOm5vZGV1aWRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06bm9kZXVpZFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcIndob2FtaVwiOntcIm5hbWVcIjpcIi9hcGkvc3lzdGVtL3dob2FtaVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHJpbnQgb3V0IHRoZSB1c2VyIGRldGFpbHNcIixcIl9wcm90b1wiOntcInVzZXJuYW1lXCI6e1wibmFtZVwiOlwidXNlcm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHVzZXJuYW1lXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkaXNwbGF5TmFtZVwiOntcIm5hbWVcIjpcImRpc3BsYXlOYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpc3BsYXluYW1lIG9mIHRoZSB1c2VyXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcInBhc3N3b3JkXCI6e1wibmFtZVwiOlwicGFzc3dvcmRcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHBhc3N3b3JkXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcInJvbGVzXCI6e1wibmFtZVwiOlwicm9sZXNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIHJvbGVzXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZX0sXCJmaWx0ZXJcIjp7XCJuYW1lXCI6XCJmaWx0ZXJcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIGZpbHRlclwiLFwidHlwZVwiOlwiYXJyYXlcIixcImRlZmF1bHRcIjpbXSxcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJBUElUb2tlblwiOntcIm5hbWVcIjpcIkFQSVRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBBUEkgVG9rZW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJwcml2YXRlXCI6dHJ1ZX0sXCJ3b3Jrc3BhY2VcIjp7XCJuYW1lXCI6XCJ3b3Jrc3BhY2VcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdXNlcidzIFdvcmtzcGFjZVwiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJ0b2tlblwiOntcIm5hbWVcIjpcInRva2VuXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHVzZXIncyBjdXJyZW50IHNlY3VyaXR5IHRva2VuXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTp3aG9hbWlcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06d2hvYW1pXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYmxhY2tsaXN0XCI6e1wibmFtZVwiOlwiL3N5c3RlbS9ibGFja2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGJsYWNrbGlzdCBhbiBJUFwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXCJpcFwiLFwiYmxhY2tsaXN0XCJdLFwib3B0aW9uYWxcIjpbXCJ0dGxcIl19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOmJsYWNrbGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInN5c3RlbTpibGFja2xpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJub2RlRGV0YWlsc1wiOntcIm5hbWVcIjpcIi9zeXN0ZW0vbm9kZURldGFpbHNcIixcImRlc2NyaXB0aW9uXCI6XCJJIHByaW50IGRldGFpbHMgb24gdGhpcyBub2RlXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltdLFwib3B0aW9uYWxcIjpbXCJ1aWRcIl19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOm5vZGVkZXRhaWxzXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwic3lzdGVtOm5vZGVkZXRhaWxzXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiY29ubmVjdGVkQ2xpZW50c1wiOntcIm5hbWVcIjpcIi9zeXN0ZW0vY29ubmVjdGVkQ2xpZW50c1wiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHJpbnQgZGV0YWlscyBvbiBhbGwgY29ubmVjdGVkIGNsaWVudHMgdG8gdGhpcyBub2RlXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltdLFwib3B0aW9uYWxcIjpbXCJ1aWRcIl19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOmNvbm5lY3RlZGNsaWVudHNcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06Y29ubmVjdGVkY2xpZW50c1wiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcIm5vZGVMaXN0XCI6e1wibmFtZVwiOlwiL3N5c3RlbS9ub2RlTGlzdFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbGlzdCBhbGwgcmVnaXN0ZXJlZCBub2Rlc1wiLFwiaW5wdXRzXCI6W10sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJzeXN0ZW06bm9kZWxpc3RcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzeXN0ZW06bm9kZWxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJyb3VuZFRyaXBcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL3JvdW5kVHJpcFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZXhlY3V0ZSBhIHJvdW5kdHJpcCBvZiBhIHBheWxvYWQgYW5kIHJldHVybiB0aGUgdGltZSBpbiBtc1wiLFwiaW5wdXRzXCI6W1wic3RhcnRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJzeXN0ZW06cm91bmR0cmlwXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicm91bmR0cmlwXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX0sXCJfcm91dGVcIjpudWxsfSxcInRlcm1pbmF0ZVwiOntcIm5hbWVcIjpcIi9zeXN0ZW0vdGVybWluYXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSB0ZXJtaW5hdGUgYSBub2RlXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltdLFwib3B0aW9uYWxcIjpbXCJ1aWRcIl19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wic3lzdGVtOnRlcm1pbmF0ZVwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcInRlcm1pbmF0ZVwiLFwibGltaXRcIjotMSxcImNyaXRlcmlhXCI6XCJub3RtZVwifSxcIl9yb3V0ZVwiOm51bGx9LFwic3RhcnRXZWJTZXJ2ZXJcIjp7XCJuYW1lXCI6XCIvc3lzdGVtL3N0YXJ0V2ViU2VydmVyXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBzdGFydCBhIFdlYlNlcnZlciBvbiBhIG5vZGVcIixcImlucHV0c1wiOltcIm5vZGVcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJzeXN0ZW06c3RhcnRXZWJTZXJ2ZXJcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJzdGFydFdlYlNlcnZlclwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9LFwiX3JvdXRlXCI6bnVsbH0sXCJwdXJnZUNhY2hlXCI6e1wibmFtZVwiOlwiL3N5c3RlbS9wdXJnZUNhY2hlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwdXJnZSB0aGUgY2FjaGVcIixcImlucHV0c1wiOntcInJlcXVpcmVkXCI6W10sXCJvcHRpb25hbFwiOltdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcInN5c3RlbTpwdXJnZUNhY2hlXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicHVyZ2VDYWNoZVwiLFwibGltaXRcIjotMSxcImNyaXRlcmlhXCI6XCJub3RtZVwifSxcIl9yb3V0ZVwiOm51bGx9fSxcImJlYWNvblwiOntcImluc2VydFwiOntcIm5hbWVcIjpcIi9iZWFjb24vaW5zZXJ0XCIsXCJkZXNjcmlwdGlvblwiOlwiXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwiZG9jdW1lbnRcIl0sXCJvcHRpb25hbFwiOltcIm9wdGlvbnNcIl19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiYmVhY29uOmluc2VydFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImJlYWNvbjppbnNlcnRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwicXVlcnlcIjp7XCJzdG9wXCI6e1wibmFtZVwiOlwiL3F1ZXJ5L3N0b3BcIixcImRlc2NyaXB0aW9uXCI6XCJcIixcImlucHV0c1wiOltcInF1ZXJ5dG9rZW5cIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJxdWVyeTpzdG9wXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwicXVlcnk6c3RvcFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImZldGNoXCI6e1wibmFtZVwiOlwiL3F1ZXJ5L2ZldGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiXCIsXCJpbnB1dHNcIjpbXCJvcHRpb25zXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wicXVlcnk6ZmV0Y2hcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJxdWVyeTpmZXRjaFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJjb2xsZWN0aW9uc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvbGlzdFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbGlzdCBhbGwgYXZhaWxhYmxlIGNvbGxlY3Rpb25zXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgaWQgb2YgdGhlIGNvbGxlY3Rpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGNvbGxlY3Rpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInN0cm9uZ1R5cGVkXCI6e1wibmFtZVwiOlwic3Ryb25nVHlwZWRcIixcImRlc2NyaXB0aW9uXCI6XCJJcyB0aGUgY29sbGVjdGlvbiBzdHJvbmcgdHlwZWRcIixcInR5cGVcIjpcImJvb2xlYW5cIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6ZmFsc2V9LFwiZGltZW5zaW9uc1wiOntcIm5hbWVcIjpcImRpbWVuc2lvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbidzIGRpbWVuc2lvbnNcIixcInR5cGVcIjpcImFycmF5XCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOltdfSxcIm1ldHJpY3NcIjp7XCJuYW1lXCI6XCJtZXRyaWNzXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24ncyBtZXRyaWNzXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpbXX19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY29sbGVjdGlvbnM6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOmxpc3RcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJnZXRcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvZ2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyBjb2xsZWN0aW9uIGJ5IGlkYFwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJpZFwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBpZCBvZiB0aGUgY29sbGVjdGlvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgY29sbGVjdGlvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwic3Ryb25nVHlwZWRcIjp7XCJuYW1lXCI6XCJzdHJvbmdUeXBlZFwiLFwiZGVzY3JpcHRpb25cIjpcIklzIHRoZSBjb2xsZWN0aW9uIHN0cm9uZyB0eXBlZFwiLFwidHlwZVwiOlwiYm9vbGVhblwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpmYWxzZX0sXCJkaW1lbnNpb25zXCI6e1wibmFtZVwiOlwiZGltZW5zaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBjb2xsZWN0aW9uJ3MgZGltZW5zaW9uc1wiLFwidHlwZVwiOlwiYXJyYXlcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6W119LFwibWV0cmljc1wiOntcIm5hbWVcIjpcIm1ldHJpY3NcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbidzIG1ldHJpY3NcIixcInR5cGVcIjpcImFycmF5XCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOltdfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb2xsZWN0aW9uczpnZXRcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjb2xsZWN0aW9uczpnZXRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJhZGRcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgY29sbGVjdGlvblwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjb2xsZWN0aW9uXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY29sbGVjdGlvbnM6YWRkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29sbGVjdGlvbnM6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvcGF0Y2hcIixcImRlc2NyaXB0aW9uXCI6XCJJIHBhdGNoIGFuIGV4aXN0aW5nIGNvbGxlY3Rpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwicGF5bG9hZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOnBhdGNoXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29sbGVjdGlvbnM6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvY29sbGVjdGlvbnMvZGVsZXRlXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBkZWxldGUgYW4gZXhpc3RpbmcgY29sbGVjdGlvblwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJpZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOmRlbGV0ZVwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNvbGxlY3Rpb25zOmRlbGV0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInN0YXRzXCI6e1wibmFtZVwiOlwiL2NvbGxlY3Rpb25zL3N0YXRzXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwcm92aWRlIHN0YXRzIGFib3V0IGEgY29sbGVjdGlvblwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJpZFwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOnN0YXRzXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29sbGVjdGlvbnM6c3RhdHNcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJtZXRhZGF0YVwiOntcIm5hbWVcIjpcIi9jb2xsZWN0aW9ucy9tZXRhZGF0YVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgcHJvdmlkZSBtZXRhZGF0YSBpbmZvcm1hdGlvbiBmb3IgYSBkb2N1bWVudFwiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXCJ3b3Jrc3BhY2VcIixcImRvY3VtZW50XCJdLFwib3B0aW9uYWxcIjpbXCJjb2xsZWN0aW9uXCJdfSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNvbGxlY3Rpb25zOm1ldGFkYXRhXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29sbGVjdGlvbnM6bWV0YWRhdGFcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwiZGltZW5zaW9uc1wiOntcImxpc3RcIjp7XCJuYW1lXCI6XCIvZGltZW5zaW9ucy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgZGltZW5zaW9uc1wiLFwiaW5wdXRzXCI6e1wicmVxdWlyZWRcIjpbXCJ3b3Jrc3BhY2VcIl0sXCJvcHRpb25hbFwiOltcImNvbGxlY3Rpb25cIl19LFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJ0eXBlXCI6e1wibmFtZVwiOlwidHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0eXBlIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcImRhdGF0eXBlXCI6e1wibmFtZVwiOlwiZGF0YXR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGF0YXR5cGUgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwic3RyaW5nXCJ9LFwiY29sbGVjdGlvblwiOntcIm5hbWVcIjpcImNvbGxlY3Rpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbiBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn19LFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZGltZW5zaW9uczpsaXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiZGltZW5zaW9uczpsaXN0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZ2V0XCI6e1wibmFtZVwiOlwiL2RpbWVuc2lvbnMvZ2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBnZXQgYSBzcGVjaWZpYyBkaW1lbnNpb24gYnkga2V5YFwiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjb2xsZWN0aW9uXCIsXCJrZXlcIl0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgaWQgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwibmFtZVwiOntcIm5hbWVcIjpcIm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbmFtZSBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkZXNjcmlwdGlvblwiOntcIm5hbWVcIjpcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInR5cGVcIjp7XCJuYW1lXCI6XCJ0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHR5cGUgb2YgdGhlIGRpbWVuc2lvblwiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwiZGF0YXR5cGVcIjp7XCJuYW1lXCI6XCJkYXRhdHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkYXRhdHlwZSBvZiB0aGUgZGltZW5zaW9uXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJzdHJpbmdcIn0sXCJjb2xsZWN0aW9uXCI6e1wibmFtZVwiOlwiY29sbGVjdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBjb2xsZWN0aW9uIG9mIHRoZSBkaW1lbnNpb25cIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJkaW1lbnNpb25zOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImRpbWVuc2lvbnM6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL2RpbWVuc2lvbnMvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgZGltZW5zaW9uXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcImRpbWVuc2lvblwiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImRpbWVuc2lvbnM6YWRkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiZGltZW5zaW9uczphZGRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJwYXRjaFwiOntcIm5hbWVcIjpcIi9kaW1lbnNpb25zL3BhdGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwYXRjaCBhbiBleGlzdGluZyBkaW1lbnNpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwiZGltZW5zaW9uXCIsXCJwYXlsb2FkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZGltZW5zaW9uczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImRpbWVuc2lvbnM6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvZGltZW5zaW9ucy9kZWxldGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGRlbGV0ZSBhbiBleGlzdGluZyBkaW1lbnNpb25cIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwiZGltZW5zaW9uXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiZGltZW5zaW9uczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJkaW1lbnNpb25zOmRlbGV0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJtZXRyaWNzXCI6e1wibGlzdFwiOntcIm5hbWVcIjpcIi9tZXRyaWNzL2xpc3RcIixcImRlc2NyaXB0aW9uXCI6XCJJIGxpc3QgYWxsIGF2YWlsYWJsZSBtZXRyaWNzXCIsXCJpbnB1dHNcIjp7XCJyZXF1aXJlZFwiOltcIndvcmtzcGFjZVwiXSxcIm9wdGlvbmFsXCI6W1wiY29sbGVjdGlvblwiXX0sXCJfcHJvdG9cIjp7XCJrZXlcIjp7XCJuYW1lXCI6XCJrZXlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgaWQgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwibmFtZVwiOntcIm5hbWVcIjpcIm5hbWVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbmFtZSBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkZXNjcmlwdGlvblwiOntcIm5hbWVcIjpcImRlc2NyaXB0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRlc2NyaXB0aW9uIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInR5cGVcIjp7XCJuYW1lXCI6XCJ0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHR5cGUgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWUsXCJwcml2YXRlXCI6dHJ1ZSxcImhpZGRlblwiOnRydWV9LFwiZmlsdGVyXCI6e1wibmFtZVwiOlwiZmlsdGVyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGZpbHRlciBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJhcnJheVwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcImRhdGF0eXBlXCI6e1wibmFtZVwiOlwiZGF0YXR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGF0YXR5cGUgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwiYWdncmVnYXRpb25cIjp7XCJuYW1lXCI6XCJhZ2dyZWdhdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBhZ2dyZWdhdGlvbiBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJwcmVmaXhcIjp7XCJuYW1lXCI6XCJwcmVmaXhcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgcHJlZml4IG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcInN1ZmZpeFwiOntcIm5hbWVcIjpcInN1ZmZpeFwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBzdWZmaXggb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwiZGVjaW1hbHNcIjp7XCJuYW1lXCI6XCJkZWNpbWFsc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXMgdG8gc2hvd1wiLFwidHlwZVwiOlwiaW50XCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOjB9LFwiZm9ybXVsYVwiOntcIm5hbWVcIjpcImZvcm11bGFcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZm9ybXVsYSBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJvYmplY3RcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwiY29sbGVjdGlvblwiOntcIm5hbWVcIjpcImNvbGxlY3Rpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY29sbGVjdGlvbiBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9LFwiY2F0ZWdvcnlcIjp7XCJuYW1lXCI6XCJjYXRlZ29yeVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBjYXRlZ29yeSBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2V9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIm1ldHJpY3M6bGlzdFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIm1ldHJpY3M6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi9tZXRyaWNzL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgbWV0cmljIGJ5IGtleWBcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwia2V5XCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJ0eXBlXCI6e1wibmFtZVwiOlwidHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0eXBlIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlLFwicHJpdmF0ZVwiOnRydWUsXCJoaWRkZW5cIjp0cnVlfSxcImZpbHRlclwiOntcIm5hbWVcIjpcImZpbHRlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBmaWx0ZXIgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwiYXJyYXlcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJkYXRhdHlwZVwiOntcIm5hbWVcIjpcImRhdGF0eXBlXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRhdGF0eXBlIG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcImFnZ3JlZ2F0aW9uXCI6e1wibmFtZVwiOlwiYWdncmVnYXRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgYWdncmVnYXRpb24gb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwicHJlZml4XCI6e1wibmFtZVwiOlwicHJlZml4XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHByZWZpeCBvZiB0aGUgbWV0cmljXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJzdWZmaXhcIjp7XCJuYW1lXCI6XCJzdWZmaXhcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgc3VmZml4IG9mIHRoZSBtZXRyaWNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjpcIlwifSxcImRlY2ltYWxzXCI6e1wibmFtZVwiOlwiZGVjaW1hbHNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIHNob3dcIixcInR5cGVcIjpcImludFwiLFwicmVxdWlyZWRcIjpmYWxzZSxcImRlZmF1bHRcIjowfSxcImZvcm11bGFcIjp7XCJuYW1lXCI6XCJmb3JtdWxhXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGZvcm11bGEgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwib2JqZWN0XCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImNvbGxlY3Rpb25cIjp7XCJuYW1lXCI6XCJjb2xsZWN0aW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGNvbGxlY3Rpb24gb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcImNhdGVnb3J5XCI6e1wibmFtZVwiOlwiY2F0ZWdvcnlcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgY2F0ZWdvcnkgb2YgdGhlIG1ldHJpY1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJtZXRyaWNzOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIm1ldHJpY3M6Z2V0XCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiYWRkXCI6e1wibmFtZVwiOlwiL21ldHJpY3MvYWRkXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBhZGQgYSBuZXcgbWV0cmljXCIsXCJpbnB1dHNcIjpbXCJ3b3Jrc3BhY2VcIixcImNvbGxlY3Rpb25cIixcIm1ldHJpY1wiXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcIm1ldHJpY3M6YWRkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwibWV0cmljczphZGRcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJwYXRjaFwiOntcIm5hbWVcIjpcIi9tZXRyaWNzL3BhdGNoXCIsXCJkZXNjcmlwdGlvblwiOlwiSSBwYXRjaCBhbiBleGlzdGluZyBtZXRyaWNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwibWV0cmljXCIsXCJwYXlsb2FkXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wibWV0cmljczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcIm1ldHJpY3M6cGF0Y2hcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX0sXCJkZWxldGVcIjp7XCJuYW1lXCI6XCIvbWV0cmljcy9kZWxldGVcIixcImRlc2NyaXB0aW9uXCI6XCJJIGRlbGV0ZSBhbiBleGlzdGluZyBtZXRyaWNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY29sbGVjdGlvblwiLFwibWV0cmljXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wibWV0cmljczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJtZXRyaWNzOmRlbGV0ZVwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJjb25maWdcIjp7XCJnZXRcIjp7XCJuYW1lXCI6XCIvY29uZmlnL2dldFwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZ2V0IGEgc3BlY2lmaWMgY29uZmlnIGJ5IG5hbWVgXCIsXCJpbnB1dHNcIjpbXCJrZXlcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb25maWc6Z2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29uZmlnOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcInNldFwiOntcIm5hbWVcIjpcIi9jb25maWcvc2V0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBzZXQgYSBuZXcgY29uZmlnIGtleVwiLFwiaW5wdXRzXCI6W1wia2V5XCIsXCJ2YWxcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjb25maWc6c2V0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY29uZmlnOnNldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fX0sXCJhbGVydHNcIjp7fSxcImNhbnZhc2VzXCI6e1wibGlzdFwiOntcIm5hbWVcIjpcIi9jYW52YXNlcy9saXN0XCIsXCJkZXNjcmlwdGlvblwiOlwiSSBsaXN0IGFsbCBhdmFpbGFibGUgY2FudmFzZXNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiXSxcIl9wcm90b1wiOntcImtleVwiOntcIm5hbWVcIjpcImtleVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBpZCBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJ2ZXJzaW9uXCI6e1wibmFtZVwiOlwidmVyc2lvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB2ZXJzaW9uIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjpmYWxzZX0sXCJuYW1lXCI6e1wibmFtZVwiOlwibmFtZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBuYW1lIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRlc2NyaXB0aW9uXCI6e1wibmFtZVwiOlwiZGVzY3JpcHRpb25cIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgZGVzY3JpcHRpb24gb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlLFwiZGVmYXVsdFwiOlwiXCJ9LFwidHlwZVwiOntcIm5hbWVcIjpcInR5cGVcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdHlwZSBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6dHJ1ZX0sXCJkYXRlcGlja2VyXCI6e1wibmFtZVwiOlwiZGF0ZXBpY2tlclwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkYXRlcGlja2VyIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wifSxcInZpc3VhbGl6YXRpb25zXCI6e1wibmFtZVwiOlwidmlzdWFsaXphdGlvbnNcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgdmlzdWFsaXphdGlvbnMgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwiYXJyYXlcIn0sXCJkaW1lbnNpb25zXCI6e1wibmFtZVwiOlwiZGltZW5zaW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkaW1lbnNpb25zIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcImFycmF5XCJ9LFwibWV0cmljc1wiOntcIm5hbWVcIjpcIm1ldHJpY3NcIixcImRlc2NyaXB0aW9uXCI6XCJUaGUgbWV0cmljcyBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJhcnJheVwifX0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjYW52YXNlczpsaXN0XCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY2FudmFzZXM6bGlzdFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImdldFwiOntcIm5hbWVcIjpcIi9jYW52YXNlcy9nZXRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGdldCBhIHNwZWNpZmljIGNhbnZhcyBieSBrZXlcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwia2V5XCJdLFwiX3Byb3RvXCI6e1wia2V5XCI6e1wibmFtZVwiOlwia2V5XCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGlkIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcInZlcnNpb25cIjp7XCJuYW1lXCI6XCJ2ZXJzaW9uXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIHZlcnNpb24gb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOmZhbHNlfSxcIm5hbWVcIjp7XCJuYW1lXCI6XCJuYW1lXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIG5hbWUgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCIsXCJyZXF1aXJlZFwiOnRydWV9LFwiZGVzY3JpcHRpb25cIjp7XCJuYW1lXCI6XCJkZXNjcmlwdGlvblwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJzdHJpbmdcIixcInJlcXVpcmVkXCI6ZmFsc2UsXCJkZWZhdWx0XCI6XCJcIn0sXCJ0eXBlXCI6e1wibmFtZVwiOlwidHlwZVwiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB0eXBlIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcInN0cmluZ1wiLFwicmVxdWlyZWRcIjp0cnVlfSxcImRhdGVwaWNrZXJcIjp7XCJuYW1lXCI6XCJkYXRlcGlja2VyXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRhdGVwaWNrZXIgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwic3RyaW5nXCJ9LFwidmlzdWFsaXphdGlvbnNcIjp7XCJuYW1lXCI6XCJ2aXN1YWxpemF0aW9uc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSB2aXN1YWxpemF0aW9ucyBvZiB0aGUgY2FudmFzXCIsXCJ0eXBlXCI6XCJhcnJheVwifSxcImRpbWVuc2lvbnNcIjp7XCJuYW1lXCI6XCJkaW1lbnNpb25zXCIsXCJkZXNjcmlwdGlvblwiOlwiVGhlIGRpbWVuc2lvbnMgb2YgdGhlIGNhbnZhc1wiLFwidHlwZVwiOlwiYXJyYXlcIn0sXCJtZXRyaWNzXCI6e1wibmFtZVwiOlwibWV0cmljc1wiLFwiZGVzY3JpcHRpb25cIjpcIlRoZSBtZXRyaWNzIG9mIHRoZSBjYW52YXNcIixcInR5cGVcIjpcImFycmF5XCJ9fSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImNhbnZhc2VzOmdldFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNhbnZhc2VzOmdldFwiLFwiY3JpdGVyaWFcIjpcIm5vdG1lXCIsXCJsaW1pdFwiOjF9fSxcImFkZFwiOntcIm5hbWVcIjpcIi9jYW52YXNlcy9hZGRcIixcImRlc2NyaXB0aW9uXCI6XCJJIGFkZCBhIG5ldyBjYW52YXNcIixcImlucHV0c1wiOltcIndvcmtzcGFjZVwiLFwiY2FudmFzXCJdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wiY2FudmFzZXM6YWRkXCJdLFwiX2Rpc3BhdGNoXCI6e1wibWVzc2FnZVwiOlwiY2FudmFzZXM6YWRkXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwicGF0Y2hcIjp7XCJuYW1lXCI6XCIvY2FudmFzZXMvcGF0Y2hcIixcImRlc2NyaXB0aW9uXCI6XCJJIHBhdGNoIGFuIGV4aXN0aW5nIGNhbnZhc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjYW52YXNcIixcInBheWxvYWRcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjYW52YXNlczpwYXRjaFwiXSxcIl9kaXNwYXRjaFwiOntcIm1lc3NhZ2VcIjpcImNhbnZhc2VzOnBhdGNoXCIsXCJjcml0ZXJpYVwiOlwibm90bWVcIixcImxpbWl0XCI6MX19LFwiZGVsZXRlXCI6e1wibmFtZVwiOlwiL2NhbnZhc2VzL2RlbGV0ZVwiLFwiZGVzY3JpcHRpb25cIjpcIkkgZGVsZXRlIGFuIGV4aXN0aW5nIGNhbnZhc1wiLFwiaW5wdXRzXCI6W1wid29ya3NwYWNlXCIsXCJjYW52YXNcIl0sXCJfb3V0cHV0RXhhbXBsZVwiOnt9LFwiX3Blcm1pc3Npb25cIjpbXCJjYW52YXNlczpkZWxldGVcIl0sXCJfZGlzcGF0Y2hcIjp7XCJtZXNzYWdlXCI6XCJjYW52YXNlczpkZWxldGVcIixcImNyaXRlcmlhXCI6XCJub3RtZVwiLFwibGltaXRcIjoxfX19LFwidGVzdFwiOntcIndpdGhwZXJtaXNzaW9uXCI6e1wibmFtZVwiOlwiL3Rlc3Qvd2l0aHBlcm1pc3Npb25cIixcImRlc2NyaXB0aW9uXCI6XCJJIG1ha2Ugc3VyZSB0aGF0IHRlc3RzIHJ1biBmaW5lXCIsXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltcImd1ZXN0XCJdfSxcIm5vcGVybWlzc2lvblwiOntcIm5hbWVcIjpcIi90ZXN0L25vcGVybWlzc2lvblwiLFwiZGVzY3JpcHRpb25cIjpcIkkgbWFrZSBzdXJlIHRoYXQgdGVzdHMgcnVuIGZpbmVcIixcImlucHV0c1wiOltdLFwiX291dHB1dEV4YW1wbGVcIjp7fSxcIl9wZXJtaXNzaW9uXCI6W1wibWFuYWdlX3N5c3RlbVwiXX0sXCJjcmVhdGV0ZXN0ZXJyb3JcIjp7XCJuYW1lXCI6XCIvdGVzdC9jcmVhdGV0ZXN0ZXJyb3JcIixcImRlc2NyaXB0aW9uXCI6XCJJIG1ha2Ugc3VyZSB0aGF0IHRlc3RzIHJ1biBmaW5lXCIsXCJpbnB1dHNcIjpbXSxcIl9vdXRwdXRFeGFtcGxlXCI6e30sXCJfcGVybWlzc2lvblwiOltdfX19IiwiLy8gPT1DbG9zdXJlQ29tcGlsZXI9PVxuLy8gQGNvbXBpbGF0aW9uX2xldmVsIFNJTVBMRV9PUFRJTUlaQVRJT05TXG5cbi8qKlxuICogQGxpY2Vuc2UgSGlnaGNoYXJ0cyBKUyB2NC4wLjQgKDIwMTQtMDktMDIpXG4gKlxuICogKGMpIDIwMDktMjAxNCBUb3JzdGVpbiBIb25zaVxuICpcbiAqIExpY2Vuc2U6IHd3dy5oaWdoY2hhcnRzLmNvbS9saWNlbnNlXG4gKi9cblxuLy8gSlNMaW50IG9wdGlvbnM6XG4vKmdsb2JhbCBIaWdoY2hhcnRzLCBIaWdoY2hhcnRzQWRhcHRlciwgZG9jdW1lbnQsIHdpbmRvdywgbmF2aWdhdG9yLCBzZXRJbnRlcnZhbCwgY2xlYXJJbnRlcnZhbCwgY2xlYXJUaW1lb3V0LCBzZXRUaW1lb3V0LCBsb2NhdGlvbiwgalF1ZXJ5LCAkLCBjb25zb2xlLCBlYWNoLCBncmVwICovXG4vKmpzbGludCBhc3M6IHRydWUsIHNsb3BweTogdHJ1ZSwgZm9yaW46IHRydWUsIHBsdXNwbHVzOiB0cnVlLCBub21lbjogdHJ1ZSwgdmFyczogdHJ1ZSwgcmVnZXhwOiB0cnVlLCBuZXdjYXA6IHRydWUsIGJyb3dzZXI6IHRydWUsIGNvbnRpbnVlOiB0cnVlLCB3aGl0ZTogdHJ1ZSAqL1xuKGZ1bmN0aW9uICgpIHtcbi8vIGVuY2Fwc3VsYXRlZCB2YXJpYWJsZXNcbnZhciBVTkRFRklORUQsXG5cdGRvYyA9IGRvY3VtZW50LFxuXHR3aW4gPSB3aW5kb3csXG5cdG1hdGggPSBNYXRoLFxuXHRtYXRoUm91bmQgPSBtYXRoLnJvdW5kLFxuXHRtYXRoRmxvb3IgPSBtYXRoLmZsb29yLFxuXHRtYXRoQ2VpbCA9IG1hdGguY2VpbCxcblx0bWF0aE1heCA9IG1hdGgubWF4LFxuXHRtYXRoTWluID0gbWF0aC5taW4sXG5cdG1hdGhBYnMgPSBtYXRoLmFicyxcblx0bWF0aENvcyA9IG1hdGguY29zLFxuXHRtYXRoU2luID0gbWF0aC5zaW4sXG5cdG1hdGhQSSA9IG1hdGguUEksXG5cdGRlZzJyYWQgPSBtYXRoUEkgKiAyIC8gMzYwLFxuXG5cblx0Ly8gc29tZSB2YXJpYWJsZXNcblx0dXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudCxcblx0aXNPcGVyYSA9IHdpbi5vcGVyYSxcblx0aXNJRSA9IC9tc2llL2kudGVzdCh1c2VyQWdlbnQpICYmICFpc09wZXJhLFxuXHRkb2NNb2RlOCA9IGRvYy5kb2N1bWVudE1vZGUgPT09IDgsXG5cdGlzV2ViS2l0ID0gL0FwcGxlV2ViS2l0Ly50ZXN0KHVzZXJBZ2VudCksXG5cdGlzRmlyZWZveCA9IC9GaXJlZm94Ly50ZXN0KHVzZXJBZ2VudCksXG5cdGlzVG91Y2hEZXZpY2UgPSAvKE1vYmlsZXxBbmRyb2lkfFdpbmRvd3MgUGhvbmUpLy50ZXN0KHVzZXJBZ2VudCksXG5cdFNWR19OUyA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG5cdGhhc1NWRyA9ICEhZG9jLmNyZWF0ZUVsZW1lbnROUyAmJiAhIWRvYy5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnc3ZnJykuY3JlYXRlU1ZHUmVjdCxcblx0aGFzQmlkaUJ1ZyA9IGlzRmlyZWZveCAmJiBwYXJzZUludCh1c2VyQWdlbnQuc3BsaXQoJ0ZpcmVmb3gvJylbMV0sIDEwKSA8IDQsIC8vIGlzc3VlICMzOFxuXHR1c2VDYW5WRyA9ICFoYXNTVkcgJiYgIWlzSUUgJiYgISFkb2MuY3JlYXRlRWxlbWVudCgnY2FudmFzJykuZ2V0Q29udGV4dCxcblx0UmVuZGVyZXIsXG5cdGhhc1RvdWNoLFxuXHRzeW1ib2xTaXplcyA9IHt9LFxuXHRpZENvdW50ZXIgPSAwLFxuXHRnYXJiYWdlQmluLFxuXHRkZWZhdWx0T3B0aW9ucyxcblx0ZGF0ZUZvcm1hdCwgLy8gZnVuY3Rpb25cblx0Z2xvYmFsQW5pbWF0aW9uLFxuXHRwYXRoQW5pbSxcblx0dGltZVVuaXRzLFxuXHRlcnJvcixcblx0bm9vcCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIFVOREVGSU5FRDsgfSxcblx0Y2hhcnRzID0gW10sXG5cdGNoYXJ0Q291bnQgPSAwLFxuXHRQUk9EVUNUID0gJ0hpZ2hjaGFydHMnLFxuXHRWRVJTSU9OID0gJzQuMC40JyxcblxuXHQvLyBzb21lIGNvbnN0YW50cyBmb3IgZnJlcXVlbnRseSB1c2VkIHN0cmluZ3Ncblx0RElWID0gJ2RpdicsXG5cdEFCU09MVVRFID0gJ2Fic29sdXRlJyxcblx0UkVMQVRJVkUgPSAncmVsYXRpdmUnLFxuXHRISURERU4gPSAnaGlkZGVuJyxcblx0UFJFRklYID0gJ2hpZ2hjaGFydHMtJyxcblx0VklTSUJMRSA9ICd2aXNpYmxlJyxcblx0UFggPSAncHgnLFxuXHROT05FID0gJ25vbmUnLFxuXHRNID0gJ00nLFxuXHRMID0gJ0wnLFxuXHRudW1SZWdleCA9IC9eWzAtOV0rJC8sXG5cdE5PUk1BTF9TVEFURSA9ICcnLFxuXHRIT1ZFUl9TVEFURSA9ICdob3ZlcicsXG5cdFNFTEVDVF9TVEFURSA9ICdzZWxlY3QnLFxuXHRcblx0Ly8gT2JqZWN0IGZvciBleHRlbmRpbmcgQXhpc1xuXHRBeGlzUGxvdExpbmVPckJhbmRFeHRlbnNpb24sXG5cblx0Ly8gY29uc3RhbnRzIGZvciBhdHRyaWJ1dGVzXG5cdFNUUk9LRV9XSURUSCA9ICdzdHJva2Utd2lkdGgnLFxuXG5cdC8vIHRpbWUgbWV0aG9kcywgY2hhbmdlZCBiYXNlZCBvbiB3aGV0aGVyIG9yIG5vdCBVVEMgaXMgdXNlZFxuXHREYXRlLCAgLy8gQWxsb3cgdXNpbmcgYSBkaWZmZXJlbnQgRGF0ZSBjbGFzc1xuXHRtYWtlVGltZSxcblx0dGltZXpvbmVPZmZzZXQsXG5cdGdldE1pbnV0ZXMsXG5cdGdldEhvdXJzLFxuXHRnZXREYXksXG5cdGdldERhdGUsXG5cdGdldE1vbnRoLFxuXHRnZXRGdWxsWWVhcixcblx0c2V0TWludXRlcyxcblx0c2V0SG91cnMsXG5cdHNldERhdGUsXG5cdHNldE1vbnRoLFxuXHRzZXRGdWxsWWVhcixcblxuXG5cdC8vIGxvb2t1cCBvdmVyIHRoZSB0eXBlcyBhbmQgdGhlIGFzc29jaWF0ZWQgY2xhc3Nlc1xuXHRzZXJpZXNUeXBlcyA9IHt9LFxuXHRIaWdoY2hhcnRzO1xuXG4vLyBUaGUgSGlnaGNoYXJ0cyBuYW1lc3BhY2VcbmlmICh3aW4uSGlnaGNoYXJ0cykge1xuXHRlcnJvcigxNiwgdHJ1ZSk7XG59IGVsc2Uge1xuXHRIaWdoY2hhcnRzID0gd2luLkhpZ2hjaGFydHMgPSB7fTtcbn1cbi8qKlxuICogRXh0ZW5kIGFuIG9iamVjdCB3aXRoIHRoZSBtZW1iZXJzIG9mIGFub3RoZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBhIFRoZSBvYmplY3QgdG8gYmUgZXh0ZW5kZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBiIFRoZSBvYmplY3QgdG8gYWRkIHRvIHRoZSBmaXJzdCBvbmVcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKGEsIGIpIHtcblx0dmFyIG47XG5cdGlmICghYSkge1xuXHRcdGEgPSB7fTtcblx0fVxuXHRmb3IgKG4gaW4gYikge1xuXHRcdGFbbl0gPSBiW25dO1xuXHR9XG5cdHJldHVybiBhO1xufVxuXHRcbi8qKlxuICogRGVlcCBtZXJnZSB0d28gb3IgbW9yZSBvYmplY3RzIGFuZCByZXR1cm4gYSB0aGlyZCBvYmplY3QuIElmIHRoZSBmaXJzdCBhcmd1bWVudCBpc1xuICogdHJ1ZSwgdGhlIGNvbnRlbnRzIG9mIHRoZSBzZWNvbmQgb2JqZWN0IGlzIGNvcGllZCBpbnRvIHRoZSBmaXJzdCBvYmplY3QuXG4gKiBQcmV2aW91c2x5IHRoaXMgZnVuY3Rpb24gcmVkaXJlY3RlZCB0byBqUXVlcnkuZXh0ZW5kKHRydWUpLCBidXQgdGhpcyBoYWQgdHdvIGxpbWl0YXRpb25zLlxuICogRmlyc3QsIGl0IGRlZXAgbWVyZ2VkIGFycmF5cywgd2hpY2ggbGVhZCB0byB3b3JrYXJvdW5kcyBpbiBIaWdoY2hhcnRzLiBTZWNvbmQsXG4gKiBpdCBjb3BpZWQgcHJvcGVydGllcyBmcm9tIGV4dGVuZGVkIHByb3RvdHlwZXMuIFxuICovXG5mdW5jdGlvbiBtZXJnZSgpIHtcblx0dmFyIGksXG5cdFx0YXJncyA9IGFyZ3VtZW50cyxcblx0XHRsZW4sXG5cdFx0cmV0ID0ge30sXG5cdFx0ZG9Db3B5ID0gZnVuY3Rpb24gKGNvcHksIG9yaWdpbmFsKSB7XG5cdFx0XHR2YXIgdmFsdWUsIGtleTtcblxuXHRcdFx0Ly8gQW4gb2JqZWN0IGlzIHJlcGxhY2luZyBhIHByaW1pdGl2ZVxuXHRcdFx0aWYgKHR5cGVvZiBjb3B5ICE9PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRjb3B5ID0ge307XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoa2V5IGluIG9yaWdpbmFsKSB7XG5cdFx0XHRcdGlmIChvcmlnaW5hbC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBvcmlnaW5hbFtrZXldO1xuXG5cdFx0XHRcdFx0Ly8gQ29weSB0aGUgY29udGVudHMgb2Ygb2JqZWN0cywgYnV0IG5vdCBhcnJheXMgb3IgRE9NIG5vZGVzXG5cdFx0XHRcdFx0aWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSAhPT0gJ1tvYmplY3QgQXJyYXldJ1xuXHRcdFx0XHRcdFx0XHQmJiBrZXkgIT09ICdyZW5kZXJUbycgJiYgdHlwZW9mIHZhbHVlLm5vZGVUeXBlICE9PSAnbnVtYmVyJykge1xuXHRcdFx0XHRcdFx0Y29weVtrZXldID0gZG9Db3B5KGNvcHlba2V5XSB8fCB7fSwgdmFsdWUpO1xuXHRcdFx0XHRcblx0XHRcdFx0XHQvLyBQcmltaXRpdmVzIGFuZCBhcnJheXMgYXJlIGNvcGllZCBvdmVyIGRpcmVjdGx5XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGNvcHlba2V5XSA9IG9yaWdpbmFsW2tleV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gY29weTtcblx0XHR9O1xuXG5cdC8vIElmIGZpcnN0IGFyZ3VtZW50IGlzIHRydWUsIGNvcHkgaW50byB0aGUgZXhpc3Rpbmcgb2JqZWN0LiBVc2VkIGluIHNldE9wdGlvbnMuXG5cdGlmIChhcmdzWzBdID09PSB0cnVlKSB7XG5cdFx0cmV0ID0gYXJnc1sxXTtcblx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMik7XG5cdH1cblxuXHQvLyBGb3IgZWFjaCBhcmd1bWVudCwgZXh0ZW5kIHRoZSByZXR1cm5cblx0bGVuID0gYXJncy5sZW5ndGg7XG5cdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdHJldCA9IGRvQ29weShyZXQsIGFyZ3NbaV0pO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn1cblxuLyoqXG4gKiBTaG9ydGN1dCBmb3IgcGFyc2VJbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBzXG4gKiBAcGFyYW0ge051bWJlcn0gbWFnIE1hZ25pdHVkZVxuICovXG5mdW5jdGlvbiBwSW50KHMsIG1hZykge1xuXHRyZXR1cm4gcGFyc2VJbnQocywgbWFnIHx8IDEwKTtcbn1cblxuLyoqXG4gKiBDaGVjayBmb3Igc3RyaW5nXG4gKiBAcGFyYW0ge09iamVjdH0gc1xuICovXG5mdW5jdGlvbiBpc1N0cmluZyhzKSB7XG5cdHJldHVybiB0eXBlb2YgcyA9PT0gJ3N0cmluZyc7XG59XG5cbi8qKlxuICogQ2hlY2sgZm9yIG9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICovXG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcblx0cmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jztcbn1cblxuLyoqXG4gKiBDaGVjayBmb3IgYXJyYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuZnVuY3Rpb24gaXNBcnJheShvYmopIHtcblx0cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuXG4vKipcbiAqIENoZWNrIGZvciBudW1iZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBuXG4gKi9cbmZ1bmN0aW9uIGlzTnVtYmVyKG4pIHtcblx0cmV0dXJuIHR5cGVvZiBuID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gbG9nMmxpbihudW0pIHtcblx0cmV0dXJuIG1hdGgubG9nKG51bSkgLyBtYXRoLkxOMTA7XG59XG5mdW5jdGlvbiBsaW4ybG9nKG51bSkge1xuXHRyZXR1cm4gbWF0aC5wb3coMTAsIG51bSk7XG59XG5cbi8qKlxuICogUmVtb3ZlIGxhc3Qgb2NjdXJlbmNlIG9mIGFuIGl0ZW0gZnJvbSBhbiBhcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0ge01peGVkfSBpdGVtXG4gKi9cbmZ1bmN0aW9uIGVyYXNlKGFyciwgaXRlbSkge1xuXHR2YXIgaSA9IGFyci5sZW5ndGg7XG5cdHdoaWxlIChpLS0pIHtcblx0XHRpZiAoYXJyW2ldID09PSBpdGVtKSB7XG5cdFx0XHRhcnIuc3BsaWNlKGksIDEpO1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cdC8vcmV0dXJuIGFycjtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIG9iamVjdCBpcyBub3QgbnVsbCBvciB1bmRlZmluZWQuIExpa2UgTW9vVG9vbHMnICQuZGVmaW5lZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuZnVuY3Rpb24gZGVmaW5lZChvYmopIHtcblx0cmV0dXJuIG9iaiAhPT0gVU5ERUZJTkVEICYmIG9iaiAhPT0gbnVsbDtcbn1cblxuLyoqXG4gKiBTZXQgb3IgZ2V0IGFuIGF0dHJpYnV0ZSBvciBhbiBvYmplY3Qgb2YgYXR0cmlidXRlcy4gQ2FuJ3QgdXNlIGpRdWVyeSBhdHRyIGJlY2F1c2VcbiAqIGl0IGF0dGVtcHRzIHRvIHNldCBleHBhbmRvIHByb3BlcnRpZXMgb24gdGhlIFNWRyBlbGVtZW50LCB3aGljaCBpcyBub3QgYWxsb3dlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZWxlbSBUaGUgRE9NIGVsZW1lbnQgdG8gcmVjZWl2ZSB0aGUgYXR0cmlidXRlKHMpXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IHByb3AgVGhlIHByb3BlcnR5IG9yIGFuIGFiamVjdCBvZiBrZXktdmFsdWUgcGFpcnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSBUaGUgdmFsdWUgaWYgYSBzaW5nbGUgcHJvcGVydHkgaXMgc2V0XG4gKi9cbmZ1bmN0aW9uIGF0dHIoZWxlbSwgcHJvcCwgdmFsdWUpIHtcblx0dmFyIGtleSxcblx0XHRyZXQ7XG5cblx0Ly8gaWYgdGhlIHByb3AgaXMgYSBzdHJpbmdcblx0aWYgKGlzU3RyaW5nKHByb3ApKSB7XG5cdFx0Ly8gc2V0IHRoZSB2YWx1ZVxuXHRcdGlmIChkZWZpbmVkKHZhbHVlKSkge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUocHJvcCwgdmFsdWUpO1xuXG5cdFx0Ly8gZ2V0IHRoZSB2YWx1ZVxuXHRcdH0gZWxzZSBpZiAoZWxlbSAmJiBlbGVtLmdldEF0dHJpYnV0ZSkgeyAvLyBlbGVtIG5vdCBkZWZpbmVkIHdoZW4gcHJpbnRpbmcgcGllIGRlbW8uLi5cblx0XHRcdHJldCA9IGVsZW0uZ2V0QXR0cmlidXRlKHByb3ApO1xuXHRcdH1cblxuXHQvLyBlbHNlIGlmIHByb3AgaXMgZGVmaW5lZCwgaXQgaXMgYSBoYXNoIG9mIGtleS92YWx1ZSBwYWlyc1xuXHR9IGVsc2UgaWYgKGRlZmluZWQocHJvcCkgJiYgaXNPYmplY3QocHJvcCkpIHtcblx0XHRmb3IgKGtleSBpbiBwcm9wKSB7XG5cdFx0XHRlbGVtLnNldEF0dHJpYnV0ZShrZXksIHByb3Bba2V5XSk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiByZXQ7XG59XG4vKipcbiAqIENoZWNrIGlmIGFuIGVsZW1lbnQgaXMgYW4gYXJyYXksIGFuZCBpZiBub3QsIG1ha2UgaXQgaW50byBhbiBhcnJheS4gTGlrZVxuICogTW9vVG9vbHMnICQuc3BsYXQuXG4gKi9cbmZ1bmN0aW9uIHNwbGF0KG9iaikge1xuXHRyZXR1cm4gaXNBcnJheShvYmopID8gb2JqIDogW29ial07XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGZpcnN0IHZhbHVlIHRoYXQgaXMgZGVmaW5lZC4gTGlrZSBNb29Ub29scycgJC5waWNrLlxuICovXG5mdW5jdGlvbiBwaWNrKCkge1xuXHR2YXIgYXJncyA9IGFyZ3VtZW50cyxcblx0XHRpLFxuXHRcdGFyZyxcblx0XHRsZW5ndGggPSBhcmdzLmxlbmd0aDtcblx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0YXJnID0gYXJnc1tpXTtcblx0XHRpZiAoYXJnICE9PSBVTkRFRklORUQgJiYgYXJnICE9PSBudWxsKSB7XG5cdFx0XHRyZXR1cm4gYXJnO1xuXHRcdH1cblx0fVxufVxuXG4vKipcbiAqIFNldCBDU1Mgb24gYSBnaXZlbiBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gZWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBzdHlsZXMgU3R5bGUgb2JqZWN0IHdpdGggY2FtZWwgY2FzZSBwcm9wZXJ0eSBuYW1lc1xuICovXG5mdW5jdGlvbiBjc3MoZWwsIHN0eWxlcykge1xuXHRpZiAoaXNJRSAmJiAhaGFzU1ZHKSB7IC8vICMyNjg2XG5cdFx0aWYgKHN0eWxlcyAmJiBzdHlsZXMub3BhY2l0eSAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRzdHlsZXMuZmlsdGVyID0gJ2FscGhhKG9wYWNpdHk9JyArIChzdHlsZXMub3BhY2l0eSAqIDEwMCkgKyAnKSc7XG5cdFx0fVxuXHR9XG5cdGV4dGVuZChlbC5zdHlsZSwgc3R5bGVzKTtcbn1cblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNyZWF0ZSBlbGVtZW50IHdpdGggYXR0cmlidXRlcyBhbmQgc3R5bGVzXG4gKiBAcGFyYW0ge09iamVjdH0gdGFnXG4gKiBAcGFyYW0ge09iamVjdH0gYXR0cmlic1xuICogQHBhcmFtIHtPYmplY3R9IHN0eWxlc1xuICogQHBhcmFtIHtPYmplY3R9IHBhcmVudFxuICogQHBhcmFtIHtPYmplY3R9IG5vcGFkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodGFnLCBhdHRyaWJzLCBzdHlsZXMsIHBhcmVudCwgbm9wYWQpIHtcblx0dmFyIGVsID0gZG9jLmNyZWF0ZUVsZW1lbnQodGFnKTtcblx0aWYgKGF0dHJpYnMpIHtcblx0XHRleHRlbmQoZWwsIGF0dHJpYnMpO1xuXHR9XG5cdGlmIChub3BhZCkge1xuXHRcdGNzcyhlbCwge3BhZGRpbmc6IDAsIGJvcmRlcjogTk9ORSwgbWFyZ2luOiAwfSk7XG5cdH1cblx0aWYgKHN0eWxlcykge1xuXHRcdGNzcyhlbCwgc3R5bGVzKTtcblx0fVxuXHRpZiAocGFyZW50KSB7XG5cdFx0cGFyZW50LmFwcGVuZENoaWxkKGVsKTtcblx0fVxuXHRyZXR1cm4gZWw7XG59XG5cbi8qKlxuICogRXh0ZW5kIGEgcHJvdG90eXBlZCBjbGFzcyBieSBuZXcgbWVtYmVyc1xuICogQHBhcmFtIHtPYmplY3R9IHBhcmVudFxuICogQHBhcmFtIHtPYmplY3R9IG1lbWJlcnNcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kQ2xhc3MocGFyZW50LCBtZW1iZXJzKSB7XG5cdHZhciBvYmplY3QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBVTkRFRklORUQ7IH07XG5cdG9iamVjdC5wcm90b3R5cGUgPSBuZXcgcGFyZW50KCk7XG5cdGV4dGVuZChvYmplY3QucHJvdG90eXBlLCBtZW1iZXJzKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxuLyoqXG4gKiBGb3JtYXQgYSBudW1iZXIgYW5kIHJldHVybiBhIHN0cmluZyBiYXNlZCBvbiBpbnB1dCBzZXR0aW5nc1xuICogQHBhcmFtIHtOdW1iZXJ9IG51bWJlciBUaGUgaW5wdXQgbnVtYmVyIHRvIGZvcm1hdFxuICogQHBhcmFtIHtOdW1iZXJ9IGRlY2ltYWxzIFRoZSBhbW91bnQgb2YgZGVjaW1hbHNcbiAqIEBwYXJhbSB7U3RyaW5nfSBkZWNQb2ludCBUaGUgZGVjaW1hbCBwb2ludCwgZGVmYXVsdHMgdG8gdGhlIG9uZSBnaXZlbiBpbiB0aGUgbGFuZyBvcHRpb25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdGhvdXNhbmRzU2VwIFRoZSB0aG91c2FuZHMgc2VwYXJhdG9yLCBkZWZhdWx0cyB0byB0aGUgb25lIGdpdmVuIGluIHRoZSBsYW5nIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gbnVtYmVyRm9ybWF0KG51bWJlciwgZGVjaW1hbHMsIGRlY1BvaW50LCB0aG91c2FuZHNTZXApIHtcblx0dmFyIGV4dGVybmFsRm4gPSBIaWdoY2hhcnRzLm51bWJlckZvcm1hdCxcblx0XHRsYW5nID0gZGVmYXVsdE9wdGlvbnMubGFuZyxcblx0XHQvLyBodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldC90ZWNoYmxvZy9hcnRpY2xlL2phdmFzY3JpcHRfZXF1aXZhbGVudF9mb3JfcGhwc19udW1iZXJfZm9ybWF0L1xuXHRcdG4gPSArbnVtYmVyIHx8IDAsXG5cdFx0YyA9IGRlY2ltYWxzID09PSAtMSA/XG5cdFx0XHQobi50b1N0cmluZygpLnNwbGl0KCcuJylbMV0gfHwgJycpLmxlbmd0aCA6IC8vIHByZXNlcnZlIGRlY2ltYWxzXG5cdFx0XHQoaXNOYU4oZGVjaW1hbHMgPSBtYXRoQWJzKGRlY2ltYWxzKSkgPyAyIDogZGVjaW1hbHMpLFxuXHRcdGQgPSBkZWNQb2ludCA9PT0gdW5kZWZpbmVkID8gbGFuZy5kZWNpbWFsUG9pbnQgOiBkZWNQb2ludCxcblx0XHR0ID0gdGhvdXNhbmRzU2VwID09PSB1bmRlZmluZWQgPyBsYW5nLnRob3VzYW5kc1NlcCA6IHRob3VzYW5kc1NlcCxcblx0XHRzID0gbiA8IDAgPyBcIi1cIiA6IFwiXCIsXG5cdFx0aSA9IFN0cmluZyhwSW50KG4gPSBtYXRoQWJzKG4pLnRvRml4ZWQoYykpKSxcblx0XHRqID0gaS5sZW5ndGggPiAzID8gaS5sZW5ndGggJSAzIDogMDtcblxuXHRyZXR1cm4gZXh0ZXJuYWxGbiAhPT0gbnVtYmVyRm9ybWF0ID8gXG5cdFx0ZXh0ZXJuYWxGbihudW1iZXIsIGRlY2ltYWxzLCBkZWNQb2ludCwgdGhvdXNhbmRzU2VwKSA6XG5cdFx0KHMgKyAoaiA/IGkuc3Vic3RyKDAsIGopICsgdCA6IFwiXCIpICsgaS5zdWJzdHIoaikucmVwbGFjZSgvKFxcZHszfSkoPz1cXGQpL2csIFwiJDFcIiArIHQpICtcblx0XHRcdChjID8gZCArIG1hdGhBYnMobiAtIGkpLnRvRml4ZWQoYykuc2xpY2UoMikgOiBcIlwiKSk7XG59XG5cbi8qKlxuICogUGFkIGEgc3RyaW5nIHRvIGEgZ2l2ZW4gbGVuZ3RoIGJ5IGFkZGluZyAwIHRvIHRoZSBiZWdpbm5pbmdcbiAqIEBwYXJhbSB7TnVtYmVyfSBudW1iZXJcbiAqIEBwYXJhbSB7TnVtYmVyfSBsZW5ndGhcbiAqL1xuZnVuY3Rpb24gcGFkKG51bWJlciwgbGVuZ3RoKSB7XG5cdC8vIENyZWF0ZSBhbiBhcnJheSBvZiB0aGUgcmVtYWluaW5nIGxlbmd0aCArMSBhbmQgam9pbiBpdCB3aXRoIDAnc1xuXHRyZXR1cm4gbmV3IEFycmF5KChsZW5ndGggfHwgMikgKyAxIC0gU3RyaW5nKG51bWJlcikubGVuZ3RoKS5qb2luKDApICsgbnVtYmVyO1xufVxuXG4vKipcbiAqIFdyYXAgYSBtZXRob2Qgd2l0aCBleHRlbmRlZCBmdW5jdGlvbmFsaXR5LCBwcmVzZXJ2aW5nIHRoZSBvcmlnaW5hbCBmdW5jdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgY29udGV4dCBvYmplY3QgdGhhdCB0aGUgbWV0aG9kIGJlbG9uZ3MgdG8gXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QgdG8gZXh0ZW5kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIEEgd3JhcHBlciBmdW5jdGlvbiBjYWxsYmFjay4gVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCB0aGUgc2FtZSBhcmd1bWVudHNcbiAqIGFzIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiwgZXhjZXB0IHRoYXQgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uIGlzIHVuc2hpZnRlZCBhbmQgcGFzc2VkIGFzIHRoZSBmaXJzdCBcbiAqIGFyZ3VtZW50LiBcbiAqL1xuZnVuY3Rpb24gd3JhcChvYmosIG1ldGhvZCwgZnVuYykge1xuXHR2YXIgcHJvY2VlZCA9IG9ialttZXRob2RdO1xuXHRvYmpbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdFx0YXJncy51bnNoaWZ0KHByb2NlZWQpO1xuXHRcdHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHR9O1xufVxuXG4vKipcbiAqIEJhc2VkIG9uIGh0dHA6Ly93d3cucGhwLm5ldC9tYW51YWwvZW4vZnVuY3Rpb24uc3RyZnRpbWUucGhwXG4gKiBAcGFyYW0ge1N0cmluZ30gZm9ybWF0XG4gKiBAcGFyYW0ge051bWJlcn0gdGltZXN0YW1wXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGNhcGl0YWxpemVcbiAqL1xuZGF0ZUZvcm1hdCA9IGZ1bmN0aW9uIChmb3JtYXQsIHRpbWVzdGFtcCwgY2FwaXRhbGl6ZSkge1xuXHRpZiAoIWRlZmluZWQodGltZXN0YW1wKSB8fCBpc05hTih0aW1lc3RhbXApKSB7XG5cdFx0cmV0dXJuICdJbnZhbGlkIGRhdGUnO1xuXHR9XG5cdGZvcm1hdCA9IHBpY2soZm9ybWF0LCAnJVktJW0tJWQgJUg6JU06JVMnKTtcblxuXHR2YXIgZGF0ZSA9IG5ldyBEYXRlKHRpbWVzdGFtcCAtIHRpbWV6b25lT2Zmc2V0KSxcblx0XHRrZXksIC8vIHVzZWQgaW4gZm9yIGNvbnN0dWN0IGJlbG93XG5cdFx0Ly8gZ2V0IHRoZSBiYXNpYyB0aW1lIHZhbHVlc1xuXHRcdGhvdXJzID0gZGF0ZVtnZXRIb3Vyc10oKSxcblx0XHRkYXkgPSBkYXRlW2dldERheV0oKSxcblx0XHRkYXlPZk1vbnRoID0gZGF0ZVtnZXREYXRlXSgpLFxuXHRcdG1vbnRoID0gZGF0ZVtnZXRNb250aF0oKSxcblx0XHRmdWxsWWVhciA9IGRhdGVbZ2V0RnVsbFllYXJdKCksXG5cdFx0bGFuZyA9IGRlZmF1bHRPcHRpb25zLmxhbmcsXG5cdFx0bGFuZ1dlZWtkYXlzID0gbGFuZy53ZWVrZGF5cyxcblxuXHRcdC8vIExpc3QgYWxsIGZvcm1hdCBrZXlzLiBDdXN0b20gZm9ybWF0cyBjYW4gYmUgYWRkZWQgZnJvbSB0aGUgb3V0c2lkZS4gXG5cdFx0cmVwbGFjZW1lbnRzID0gZXh0ZW5kKHtcblxuXHRcdFx0Ly8gRGF5XG5cdFx0XHQnYSc6IGxhbmdXZWVrZGF5c1tkYXldLnN1YnN0cigwLCAzKSwgLy8gU2hvcnQgd2Vla2RheSwgbGlrZSAnTW9uJ1xuXHRcdFx0J0EnOiBsYW5nV2Vla2RheXNbZGF5XSwgLy8gTG9uZyB3ZWVrZGF5LCBsaWtlICdNb25kYXknXG5cdFx0XHQnZCc6IHBhZChkYXlPZk1vbnRoKSwgLy8gVHdvIGRpZ2l0IGRheSBvZiB0aGUgbW9udGgsIDAxIHRvIDMxXG5cdFx0XHQnZSc6IGRheU9mTW9udGgsIC8vIERheSBvZiB0aGUgbW9udGgsIDEgdGhyb3VnaCAzMVxuXG5cdFx0XHQvLyBXZWVrIChub25lIGltcGxlbWVudGVkKVxuXHRcdFx0Ly8nVyc6IHdlZWtOdW1iZXIoKSxcblxuXHRcdFx0Ly8gTW9udGhcblx0XHRcdCdiJzogbGFuZy5zaG9ydE1vbnRoc1ttb250aF0sIC8vIFNob3J0IG1vbnRoLCBsaWtlICdKYW4nXG5cdFx0XHQnQic6IGxhbmcubW9udGhzW21vbnRoXSwgLy8gTG9uZyBtb250aCwgbGlrZSAnSmFudWFyeSdcblx0XHRcdCdtJzogcGFkKG1vbnRoICsgMSksIC8vIFR3byBkaWdpdCBtb250aCBudW1iZXIsIDAxIHRocm91Z2ggMTJcblxuXHRcdFx0Ly8gWWVhclxuXHRcdFx0J3knOiBmdWxsWWVhci50b1N0cmluZygpLnN1YnN0cigyLCAyKSwgLy8gVHdvIGRpZ2l0cyB5ZWFyLCBsaWtlIDA5IGZvciAyMDA5XG5cdFx0XHQnWSc6IGZ1bGxZZWFyLCAvLyBGb3VyIGRpZ2l0cyB5ZWFyLCBsaWtlIDIwMDlcblxuXHRcdFx0Ly8gVGltZVxuXHRcdFx0J0gnOiBwYWQoaG91cnMpLCAvLyBUd28gZGlnaXRzIGhvdXJzIGluIDI0aCBmb3JtYXQsIDAwIHRocm91Z2ggMjNcblx0XHRcdCdJJzogcGFkKChob3VycyAlIDEyKSB8fCAxMiksIC8vIFR3byBkaWdpdHMgaG91cnMgaW4gMTJoIGZvcm1hdCwgMDAgdGhyb3VnaCAxMVxuXHRcdFx0J2wnOiAoaG91cnMgJSAxMikgfHwgMTIsIC8vIEhvdXJzIGluIDEyaCBmb3JtYXQsIDEgdGhyb3VnaCAxMlxuXHRcdFx0J00nOiBwYWQoZGF0ZVtnZXRNaW51dGVzXSgpKSwgLy8gVHdvIGRpZ2l0cyBtaW51dGVzLCAwMCB0aHJvdWdoIDU5XG5cdFx0XHQncCc6IGhvdXJzIDwgMTIgPyAnQU0nIDogJ1BNJywgLy8gVXBwZXIgY2FzZSBBTSBvciBQTVxuXHRcdFx0J1AnOiBob3VycyA8IDEyID8gJ2FtJyA6ICdwbScsIC8vIExvd2VyIGNhc2UgQU0gb3IgUE1cblx0XHRcdCdTJzogcGFkKGRhdGUuZ2V0U2Vjb25kcygpKSwgLy8gVHdvIGRpZ2l0cyBzZWNvbmRzLCAwMCB0aHJvdWdoICA1OVxuXHRcdFx0J0wnOiBwYWQobWF0aFJvdW5kKHRpbWVzdGFtcCAlIDEwMDApLCAzKSAvLyBNaWxsaXNlY29uZHMgKG5hbWluZyBmcm9tIFJ1YnkpXG5cdFx0fSwgSGlnaGNoYXJ0cy5kYXRlRm9ybWF0cyk7XG5cblxuXHQvLyBkbyB0aGUgcmVwbGFjZXNcblx0Zm9yIChrZXkgaW4gcmVwbGFjZW1lbnRzKSB7XG5cdFx0d2hpbGUgKGZvcm1hdC5pbmRleE9mKCclJyArIGtleSkgIT09IC0xKSB7IC8vIHJlZ2V4IHdvdWxkIGRvIGl0IGluIG9uZSBsaW5lLCBidXQgdGhpcyBpcyBmYXN0ZXJcblx0XHRcdGZvcm1hdCA9IGZvcm1hdC5yZXBsYWNlKCclJyArIGtleSwgdHlwZW9mIHJlcGxhY2VtZW50c1trZXldID09PSAnZnVuY3Rpb24nID8gcmVwbGFjZW1lbnRzW2tleV0odGltZXN0YW1wKSA6IHJlcGxhY2VtZW50c1trZXldKTtcblx0XHR9XG5cdH1cblxuXHQvLyBPcHRpb25hbGx5IGNhcGl0YWxpemUgdGhlIHN0cmluZyBhbmQgcmV0dXJuXG5cdHJldHVybiBjYXBpdGFsaXplID8gZm9ybWF0LnN1YnN0cigwLCAxKS50b1VwcGVyQ2FzZSgpICsgZm9ybWF0LnN1YnN0cigxKSA6IGZvcm1hdDtcbn07XG5cbi8qKiBcbiAqIEZvcm1hdCBhIHNpbmdsZSB2YXJpYWJsZS4gU2ltaWxhciB0byBzcHJpbnRmLCB3aXRob3V0IHRoZSAlIHByZWZpeC5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0U2luZ2xlKGZvcm1hdCwgdmFsKSB7XG5cdHZhciBmbG9hdFJlZ2V4ID0gL2YkLyxcblx0XHRkZWNSZWdleCA9IC9cXC4oWzAtOV0pLyxcblx0XHRsYW5nID0gZGVmYXVsdE9wdGlvbnMubGFuZyxcblx0XHRkZWNpbWFscztcblxuXHRpZiAoZmxvYXRSZWdleC50ZXN0KGZvcm1hdCkpIHsgLy8gZmxvYXRcblx0XHRkZWNpbWFscyA9IGZvcm1hdC5tYXRjaChkZWNSZWdleCk7XG5cdFx0ZGVjaW1hbHMgPSBkZWNpbWFscyA/IGRlY2ltYWxzWzFdIDogLTE7XG5cdFx0aWYgKHZhbCAhPT0gbnVsbCkge1xuXHRcdFx0dmFsID0gbnVtYmVyRm9ybWF0KFxuXHRcdFx0XHR2YWwsXG5cdFx0XHRcdGRlY2ltYWxzLFxuXHRcdFx0XHRsYW5nLmRlY2ltYWxQb2ludCxcblx0XHRcdFx0Zm9ybWF0LmluZGV4T2YoJywnKSA+IC0xID8gbGFuZy50aG91c2FuZHNTZXAgOiAnJ1xuXHRcdFx0KTtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0dmFsID0gZGF0ZUZvcm1hdChmb3JtYXQsIHZhbCk7XG5cdH1cblx0cmV0dXJuIHZhbDtcbn1cblxuLyoqXG4gKiBGb3JtYXQgYSBzdHJpbmcgYWNjb3JkaW5nIHRvIGEgc3Vic2V0IG9mIHRoZSBydWxlcyBvZiBQeXRob24ncyBTdHJpbmcuZm9ybWF0IG1ldGhvZC5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0KHN0ciwgY3R4KSB7XG5cdHZhciBzcGxpdHRlciA9ICd7Jyxcblx0XHRpc0luc2lkZSA9IGZhbHNlLFxuXHRcdHNlZ21lbnQsXG5cdFx0dmFsdWVBbmRGb3JtYXQsXG5cdFx0cGF0aCxcblx0XHRpLFxuXHRcdGxlbixcblx0XHRyZXQgPSBbXSxcblx0XHR2YWwsXG5cdFx0aW5kZXg7XG5cdFxuXHR3aGlsZSAoKGluZGV4ID0gc3RyLmluZGV4T2Yoc3BsaXR0ZXIpKSAhPT0gLTEpIHtcblx0XHRcblx0XHRzZWdtZW50ID0gc3RyLnNsaWNlKDAsIGluZGV4KTtcblx0XHRpZiAoaXNJbnNpZGUpIHsgLy8gd2UncmUgb24gdGhlIGNsb3NpbmcgYnJhY2tldCBsb29raW5nIGJhY2tcblx0XHRcdFxuXHRcdFx0dmFsdWVBbmRGb3JtYXQgPSBzZWdtZW50LnNwbGl0KCc6Jyk7XG5cdFx0XHRwYXRoID0gdmFsdWVBbmRGb3JtYXQuc2hpZnQoKS5zcGxpdCgnLicpOyAvLyBnZXQgZmlyc3QgYW5kIGxlYXZlIGZvcm1hdFxuXHRcdFx0bGVuID0gcGF0aC5sZW5ndGg7XG5cdFx0XHR2YWwgPSBjdHg7XG5cblx0XHRcdC8vIEFzc2lnbiBkZWVwZXIgcGF0aHNcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0XHR2YWwgPSB2YWxbcGF0aFtpXV07XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZvcm1hdCB0aGUgcmVwbGFjZW1lbnRcblx0XHRcdGlmICh2YWx1ZUFuZEZvcm1hdC5sZW5ndGgpIHtcblx0XHRcdFx0dmFsID0gZm9ybWF0U2luZ2xlKHZhbHVlQW5kRm9ybWF0LmpvaW4oJzonKSwgdmFsKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUHVzaCB0aGUgcmVzdWx0IGFuZCBhZHZhbmNlIHRoZSBjdXJzb3Jcblx0XHRcdHJldC5wdXNoKHZhbCk7XG5cdFx0XHRcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0LnB1c2goc2VnbWVudCk7XG5cdFx0XHRcblx0XHR9XG5cdFx0c3RyID0gc3RyLnNsaWNlKGluZGV4ICsgMSk7IC8vIHRoZSByZXN0XG5cdFx0aXNJbnNpZGUgPSAhaXNJbnNpZGU7IC8vIHRvZ2dsZVxuXHRcdHNwbGl0dGVyID0gaXNJbnNpZGUgPyAnfScgOiAneyc7IC8vIG5vdyBsb29rIGZvciBuZXh0IG1hdGNoaW5nIGJyYWNrZXRcblx0fVxuXHRyZXQucHVzaChzdHIpO1xuXHRyZXR1cm4gcmV0LmpvaW4oJycpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgbWFnbml0dWRlIG9mIGEgbnVtYmVyXG4gKi9cbmZ1bmN0aW9uIGdldE1hZ25pdHVkZShudW0pIHtcblx0cmV0dXJuIG1hdGgucG93KDEwLCBtYXRoRmxvb3IobWF0aC5sb2cobnVtKSAvIG1hdGguTE4xMCkpO1xufVxuXG4vKipcbiAqIFRha2UgYW4gaW50ZXJ2YWwgYW5kIG5vcm1hbGl6ZSBpdCB0byBtdWx0aXBsZXMgb2YgMSwgMiwgMi41IGFuZCA1XG4gKiBAcGFyYW0ge051bWJlcn0gaW50ZXJ2YWxcbiAqIEBwYXJhbSB7QXJyYXl9IG11bHRpcGxlc1xuICogQHBhcmFtIHtOdW1iZXJ9IG1hZ25pdHVkZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplVGlja0ludGVydmFsKGludGVydmFsLCBtdWx0aXBsZXMsIG1hZ25pdHVkZSwgYWxsb3dEZWNpbWFscykge1xuXHR2YXIgbm9ybWFsaXplZCwgaTtcblxuXHQvLyByb3VuZCB0byBhIHRlbmZvbGQgb2YgMSwgMiwgMi41IG9yIDVcblx0bWFnbml0dWRlID0gcGljayhtYWduaXR1ZGUsIDEpO1xuXHRub3JtYWxpemVkID0gaW50ZXJ2YWwgLyBtYWduaXR1ZGU7XG5cblx0Ly8gbXVsdGlwbGVzIGZvciBhIGxpbmVhciBzY2FsZVxuXHRpZiAoIW11bHRpcGxlcykge1xuXHRcdG11bHRpcGxlcyA9IFsxLCAyLCAyLjUsIDUsIDEwXTtcblxuXHRcdC8vIHRoZSBhbGxvd0RlY2ltYWxzIG9wdGlvblxuXHRcdGlmIChhbGxvd0RlY2ltYWxzID09PSBmYWxzZSkge1xuXHRcdFx0aWYgKG1hZ25pdHVkZSA9PT0gMSkge1xuXHRcdFx0XHRtdWx0aXBsZXMgPSBbMSwgMiwgNSwgMTBdO1xuXHRcdFx0fSBlbHNlIGlmIChtYWduaXR1ZGUgPD0gMC4xKSB7XG5cdFx0XHRcdG11bHRpcGxlcyA9IFsxIC8gbWFnbml0dWRlXTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBub3JtYWxpemUgdGhlIGludGVydmFsIHRvIHRoZSBuZWFyZXN0IG11bHRpcGxlXG5cdGZvciAoaSA9IDA7IGkgPCBtdWx0aXBsZXMubGVuZ3RoOyBpKyspIHtcblx0XHRpbnRlcnZhbCA9IG11bHRpcGxlc1tpXTtcblx0XHRpZiAobm9ybWFsaXplZCA8PSAobXVsdGlwbGVzW2ldICsgKG11bHRpcGxlc1tpICsgMV0gfHwgbXVsdGlwbGVzW2ldKSkgLyAyKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHQvLyBtdWx0aXBseSBiYWNrIHRvIHRoZSBjb3JyZWN0IG1hZ25pdHVkZVxuXHRpbnRlcnZhbCAqPSBtYWduaXR1ZGU7XG5cblx0cmV0dXJuIGludGVydmFsO1xufVxuXG5cbi8qKlxuICogVXRpbGl0eSBtZXRob2QgdGhhdCBzb3J0cyBhbiBvYmplY3QgYXJyYXkgYW5kIGtlZXBpbmcgdGhlIG9yZGVyIG9mIGVxdWFsIGl0ZW1zLlxuICogRUNNQSBzY3JpcHQgc3RhbmRhcmQgZG9lcyBub3Qgc3BlY2lmeSB0aGUgYmVoYXZpb3VyIHdoZW4gaXRlbXMgYXJlIGVxdWFsLlxuICovXG5mdW5jdGlvbiBzdGFibGVTb3J0KGFyciwgc29ydEZ1bmN0aW9uKSB7XG5cdHZhciBsZW5ndGggPSBhcnIubGVuZ3RoLFxuXHRcdHNvcnRWYWx1ZSxcblx0XHRpO1xuXG5cdC8vIEFkZCBpbmRleCB0byBlYWNoIGl0ZW1cblx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0YXJyW2ldLnNzX2kgPSBpOyAvLyBzdGFibGUgc29ydCBpbmRleFxuXHR9XG5cblx0YXJyLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcblx0XHRzb3J0VmFsdWUgPSBzb3J0RnVuY3Rpb24oYSwgYik7XG5cdFx0cmV0dXJuIHNvcnRWYWx1ZSA9PT0gMCA/IGEuc3NfaSAtIGIuc3NfaSA6IHNvcnRWYWx1ZTtcblx0fSk7XG5cblx0Ly8gUmVtb3ZlIGluZGV4IGZyb20gaXRlbXNcblx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG5cdFx0ZGVsZXRlIGFycltpXS5zc19pOyAvLyBzdGFibGUgc29ydCBpbmRleFxuXHR9XG59XG5cbi8qKlxuICogTm9uLXJlY3Vyc2l2ZSBtZXRob2QgdG8gZmluZCB0aGUgbG93ZXN0IG1lbWJlciBvZiBhbiBhcnJheS4gTWF0aC5taW4gcmFpc2VzIGEgbWF4aW11bVxuICogY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkIGVycm9yIGluIENocm9tZSB3aGVuIHRyeWluZyB0byBhcHBseSBtb3JlIHRoYW4gMTUwLjAwMCBwb2ludHMuIFRoaXNcbiAqIG1ldGhvZCBpcyBzbGlnaHRseSBzbG93ZXIsIGJ1dCBzYWZlLlxuICovXG5mdW5jdGlvbiBhcnJheU1pbihkYXRhKSB7XG5cdHZhciBpID0gZGF0YS5sZW5ndGgsXG5cdFx0bWluID0gZGF0YVswXTtcblxuXHR3aGlsZSAoaS0tKSB7XG5cdFx0aWYgKGRhdGFbaV0gPCBtaW4pIHtcblx0XHRcdG1pbiA9IGRhdGFbaV07XG5cdFx0fVxuXHR9XG5cdHJldHVybiBtaW47XG59XG5cbi8qKlxuICogTm9uLXJlY3Vyc2l2ZSBtZXRob2QgdG8gZmluZCB0aGUgbG93ZXN0IG1lbWJlciBvZiBhbiBhcnJheS4gTWF0aC5taW4gcmFpc2VzIGEgbWF4aW11bVxuICogY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkIGVycm9yIGluIENocm9tZSB3aGVuIHRyeWluZyB0byBhcHBseSBtb3JlIHRoYW4gMTUwLjAwMCBwb2ludHMuIFRoaXNcbiAqIG1ldGhvZCBpcyBzbGlnaHRseSBzbG93ZXIsIGJ1dCBzYWZlLlxuICovXG5mdW5jdGlvbiBhcnJheU1heChkYXRhKSB7XG5cdHZhciBpID0gZGF0YS5sZW5ndGgsXG5cdFx0bWF4ID0gZGF0YVswXTtcblxuXHR3aGlsZSAoaS0tKSB7XG5cdFx0aWYgKGRhdGFbaV0gPiBtYXgpIHtcblx0XHRcdG1heCA9IGRhdGFbaV07XG5cdFx0fVxuXHR9XG5cdHJldHVybiBtYXg7XG59XG5cbi8qKlxuICogVXRpbGl0eSBtZXRob2QgdGhhdCBkZXN0cm95cyBhbnkgU1ZHRWxlbWVudCBvciBWTUxFbGVtZW50IHRoYXQgYXJlIHByb3BlcnRpZXMgb24gdGhlIGdpdmVuIG9iamVjdC5cbiAqIEl0IGxvb3BzIGFsbCBwcm9wZXJ0aWVzIGFuZCBpbnZva2VzIGRlc3Ryb3kgaWYgdGhlcmUgaXMgYSBkZXN0cm95IG1ldGhvZC4gVGhlIHByb3BlcnR5IGlzXG4gKiB0aGVuIGRlbGV0ZSdlZC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBUaGUgb2JqZWN0IHRvIGRlc3Ryb3kgcHJvcGVydGllcyBvblxuICogQHBhcmFtIHtPYmplY3R9IEV4Y2VwdGlvbiwgZG8gbm90IGRlc3Ryb3kgdGhpcyBwcm9wZXJ0eSwgb25seSBkZWxldGUgaXQuXG4gKi9cbmZ1bmN0aW9uIGRlc3Ryb3lPYmplY3RQcm9wZXJ0aWVzKG9iaiwgZXhjZXB0KSB7XG5cdHZhciBuO1xuXHRmb3IgKG4gaW4gb2JqKSB7XG5cdFx0Ly8gSWYgdGhlIG9iamVjdCBpcyBub24tbnVsbCBhbmQgZGVzdHJveSBpcyBkZWZpbmVkXG5cdFx0aWYgKG9ialtuXSAmJiBvYmpbbl0gIT09IGV4Y2VwdCAmJiBvYmpbbl0uZGVzdHJveSkge1xuXHRcdFx0Ly8gSW52b2tlIHRoZSBkZXN0cm95XG5cdFx0XHRvYmpbbl0uZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdC8vIERlbGV0ZSB0aGUgcHJvcGVydHkgZnJvbSB0aGUgb2JqZWN0LlxuXHRcdGRlbGV0ZSBvYmpbbl07XG5cdH1cbn1cblxuXG4vKipcbiAqIERpc2NhcmQgYW4gZWxlbWVudCBieSBtb3ZpbmcgaXQgdG8gdGhlIGJpbiBhbmQgZGVsZXRlXG4gKiBAcGFyYW0ge09iamVjdH0gVGhlIEhUTUwgbm9kZSB0byBkaXNjYXJkXG4gKi9cbmZ1bmN0aW9uIGRpc2NhcmRFbGVtZW50KGVsZW1lbnQpIHtcblx0Ly8gY3JlYXRlIGEgZ2FyYmFnZSBiaW4gZWxlbWVudCwgbm90IHBhcnQgb2YgdGhlIERPTVxuXHRpZiAoIWdhcmJhZ2VCaW4pIHtcblx0XHRnYXJiYWdlQmluID0gY3JlYXRlRWxlbWVudChESVYpO1xuXHR9XG5cblx0Ly8gbW92ZSB0aGUgbm9kZSBhbmQgZW1wdHkgYmluXG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Z2FyYmFnZUJpbi5hcHBlbmRDaGlsZChlbGVtZW50KTtcblx0fVxuXHRnYXJiYWdlQmluLmlubmVySFRNTCA9ICcnO1xufVxuXG4vKipcbiAqIFByb3ZpZGUgZXJyb3IgbWVzc2FnZXMgZm9yIGRlYnVnZ2luZywgd2l0aCBsaW5rcyB0byBvbmxpbmUgZXhwbGFuYXRpb24gXG4gKi9cbmVycm9yID0gZnVuY3Rpb24gKGNvZGUsIHN0b3ApIHtcblx0dmFyIG1zZyA9ICdIaWdoY2hhcnRzIGVycm9yICMnICsgY29kZSArICc6IHd3dy5oaWdoY2hhcnRzLmNvbS9lcnJvcnMvJyArIGNvZGU7XG5cdGlmIChzdG9wKSB7XG5cdFx0dGhyb3cgbXNnO1xuXHR9XG5cdC8vIGVsc2UgLi4uXG5cdGlmICh3aW4uY29uc29sZSkge1xuXHRcdGNvbnNvbGUubG9nKG1zZyk7XG5cdH1cbn07XG5cbi8qKlxuICogRml4IEpTIHJvdW5kIG9mZiBmbG9hdCBlcnJvcnNcbiAqIEBwYXJhbSB7TnVtYmVyfSBudW1cbiAqL1xuZnVuY3Rpb24gY29ycmVjdEZsb2F0KG51bSkge1xuXHRyZXR1cm4gcGFyc2VGbG9hdChcblx0XHRudW0udG9QcmVjaXNpb24oMTQpXG5cdCk7XG59XG5cbi8qKlxuICogU2V0IHRoZSBnbG9iYWwgYW5pbWF0aW9uIHRvIGVpdGhlciBhIGdpdmVuIHZhbHVlLCBvciBmYWxsIGJhY2sgdG8gdGhlXG4gKiBnaXZlbiBjaGFydCdzIGFuaW1hdGlvbiBvcHRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBhbmltYXRpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBjaGFydFxuICovXG5mdW5jdGlvbiBzZXRBbmltYXRpb24oYW5pbWF0aW9uLCBjaGFydCkge1xuXHRnbG9iYWxBbmltYXRpb24gPSBwaWNrKGFuaW1hdGlvbiwgY2hhcnQuYW5pbWF0aW9uKTtcbn1cblxuLyoqXG4gKiBUaGUgdGltZSB1bml0IGxvb2t1cFxuICovXG50aW1lVW5pdHMgPSB7XG5cdG1pbGxpc2Vjb25kOiAxLFxuXHRzZWNvbmQ6IDEwMDAsXG5cdG1pbnV0ZTogNjAwMDAsXG5cdGhvdXI6IDM2MDAwMDAsXG5cdGRheTogMjQgKiAzNjAwMDAwLFxuXHR3ZWVrOiA3ICogMjQgKiAzNjAwMDAwLFxuXHRtb250aDogMzEgKiAyNCAqIDM2MDAwMDAsXG5cdHllYXI6IDMxNTU2OTUyMDAwXG59O1xuLyoqXG4gKiBQYXRoIGludGVycG9sYXRpb24gYWxnb3JpdGhtIHVzZWQgYWNyb3NzIGFkYXB0ZXJzXG4gKi9cbnBhdGhBbmltID0ge1xuXHQvKipcblx0ICogUHJlcGFyZSBzdGFydCBhbmQgZW5kIHZhbHVlcyBzbyB0aGF0IHRoZSBwYXRoIGNhbiBiZSBhbmltYXRlZCBvbmUgdG8gb25lXG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAoZWxlbSwgZnJvbUQsIHRvRCkge1xuXHRcdGZyb21EID0gZnJvbUQgfHwgJyc7XG5cdFx0dmFyIHNoaWZ0ID0gZWxlbS5zaGlmdCxcblx0XHRcdGJlemllciA9IGZyb21ELmluZGV4T2YoJ0MnKSA+IC0xLFxuXHRcdFx0bnVtUGFyYW1zID0gYmV6aWVyID8gNyA6IDMsXG5cdFx0XHRlbmRMZW5ndGgsXG5cdFx0XHRzbGljZSxcblx0XHRcdGksXG5cdFx0XHRzdGFydCA9IGZyb21ELnNwbGl0KCcgJyksXG5cdFx0XHRlbmQgPSBbXS5jb25jYXQodG9EKSwgLy8gY29weVxuXHRcdFx0c3RhcnRCYXNlTGluZSxcblx0XHRcdGVuZEJhc2VMaW5lLFxuXHRcdFx0c2l4aWZ5ID0gZnVuY3Rpb24gKGFycikgeyAvLyBpbiBzcGxpbmVzIG1ha2UgbW92ZSBwb2ludHMgaGF2ZSBzaXggcGFyYW1ldGVycyBsaWtlIGJlemllciBjdXJ2ZXNcblx0XHRcdFx0aSA9IGFyci5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0XHRpZiAoYXJyW2ldID09PSBNKSB7XG5cdFx0XHRcdFx0XHRhcnIuc3BsaWNlKGkgKyAxLCAwLCBhcnJbaSArIDFdLCBhcnJbaSArIDJdLCBhcnJbaSArIDFdLCBhcnJbaSArIDJdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRpZiAoYmV6aWVyKSB7XG5cdFx0XHRzaXhpZnkoc3RhcnQpO1xuXHRcdFx0c2l4aWZ5KGVuZCk7XG5cdFx0fVxuXG5cdFx0Ly8gcHVsbCBvdXQgdGhlIGJhc2UgbGluZXMgYmVmb3JlIHBhZGRpbmdcblx0XHRpZiAoZWxlbS5pc0FyZWEpIHtcblx0XHRcdHN0YXJ0QmFzZUxpbmUgPSBzdGFydC5zcGxpY2Uoc3RhcnQubGVuZ3RoIC0gNiwgNik7XG5cdFx0XHRlbmRCYXNlTGluZSA9IGVuZC5zcGxpY2UoZW5kLmxlbmd0aCAtIDYsIDYpO1xuXHRcdH1cblxuXHRcdC8vIGlmIHNoaWZ0aW5nIHBvaW50cywgcHJlcGVuZCBhIGR1bW15IHBvaW50IHRvIHRoZSBlbmQgcGF0aFxuXHRcdGlmIChzaGlmdCA8PSBlbmQubGVuZ3RoIC8gbnVtUGFyYW1zICYmIHN0YXJ0Lmxlbmd0aCA9PT0gZW5kLmxlbmd0aCkge1xuXHRcdFx0d2hpbGUgKHNoaWZ0LS0pIHtcblx0XHRcdFx0ZW5kID0gW10uY29uY2F0KGVuZCkuc3BsaWNlKDAsIG51bVBhcmFtcykuY29uY2F0KGVuZCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGVsZW0uc2hpZnQgPSAwOyAvLyByZXNldCBmb3IgZm9sbG93aW5nIGFuaW1hdGlvbnNcblxuXHRcdC8vIGNvcHkgYW5kIGFwcGVuZCBsYXN0IHBvaW50IHVudGlsIHRoZSBsZW5ndGggbWF0Y2hlcyB0aGUgZW5kIGxlbmd0aFxuXHRcdGlmIChzdGFydC5sZW5ndGgpIHtcblx0XHRcdGVuZExlbmd0aCA9IGVuZC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoc3RhcnQubGVuZ3RoIDwgZW5kTGVuZ3RoKSB7XG5cblx0XHRcdFx0Ly9iZXppZXIgJiYgc2l4aWZ5KHN0YXJ0KTtcblx0XHRcdFx0c2xpY2UgPSBbXS5jb25jYXQoc3RhcnQpLnNwbGljZShzdGFydC5sZW5ndGggLSBudW1QYXJhbXMsIG51bVBhcmFtcyk7XG5cdFx0XHRcdGlmIChiZXppZXIpIHsgLy8gZGlzYWJsZSBmaXJzdCBjb250cm9sIHBvaW50XG5cdFx0XHRcdFx0c2xpY2VbbnVtUGFyYW1zIC0gNl0gPSBzbGljZVtudW1QYXJhbXMgLSAyXTtcblx0XHRcdFx0XHRzbGljZVtudW1QYXJhbXMgLSA1XSA9IHNsaWNlW251bVBhcmFtcyAtIDFdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHN0YXJ0ID0gc3RhcnQuY29uY2F0KHNsaWNlKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoc3RhcnRCYXNlTGluZSkgeyAvLyBhcHBlbmQgdGhlIGJhc2UgbGluZXMgZm9yIGFyZWFzXG5cdFx0XHRzdGFydCA9IHN0YXJ0LmNvbmNhdChzdGFydEJhc2VMaW5lKTtcblx0XHRcdGVuZCA9IGVuZC5jb25jYXQoZW5kQmFzZUxpbmUpO1xuXHRcdH1cblx0XHRyZXR1cm4gW3N0YXJ0LCBlbmRdO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbnRlcnBvbGF0ZSBlYWNoIHZhbHVlIG9mIHRoZSBwYXRoIGFuZCByZXR1cm4gdGhlIGFycmF5XG5cdCAqL1xuXHRzdGVwOiBmdW5jdGlvbiAoc3RhcnQsIGVuZCwgcG9zLCBjb21wbGV0ZSkge1xuXHRcdHZhciByZXQgPSBbXSxcblx0XHRcdGkgPSBzdGFydC5sZW5ndGgsXG5cdFx0XHRzdGFydFZhbDtcblxuXHRcdGlmIChwb3MgPT09IDEpIHsgLy8gbGFuZCBvbiB0aGUgZmluYWwgcGF0aCB3aXRob3V0IGFkanVzdG1lbnQgcG9pbnRzIGFwcGVuZGVkIGluIHRoZSBlbmRzXG5cdFx0XHRyZXQgPSBjb21wbGV0ZTtcblxuXHRcdH0gZWxzZSBpZiAoaSA9PT0gZW5kLmxlbmd0aCAmJiBwb3MgPCAxKSB7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdHN0YXJ0VmFsID0gcGFyc2VGbG9hdChzdGFydFtpXSk7XG5cdFx0XHRcdHJldFtpXSA9XG5cdFx0XHRcdFx0aXNOYU4oc3RhcnRWYWwpID8gLy8gYSBsZXR0ZXIgaW5zdHJ1Y3Rpb24gbGlrZSBNIG9yIExcblx0XHRcdFx0XHRcdHN0YXJ0W2ldIDpcblx0XHRcdFx0XHRcdHBvcyAqIChwYXJzZUZsb2F0KGVuZFtpXSAtIHN0YXJ0VmFsKSkgKyBzdGFydFZhbDtcblxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7IC8vIGlmIGFuaW1hdGlvbiBpcyBmaW5pc2hlZCBvciBsZW5ndGggbm90IG1hdGNoaW5nLCBsYW5kIG9uIHJpZ2h0IHZhbHVlXG5cdFx0XHRyZXQgPSBlbmQ7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH1cbn07XG5cbihmdW5jdGlvbiAoJCkge1xuXHQvKipcblx0ICogVGhlIGRlZmF1bHQgSGlnaGNoYXJ0c0FkYXB0ZXIgZm9yIGpRdWVyeVxuXHQgKi9cblx0d2luLkhpZ2hjaGFydHNBZGFwdGVyID0gd2luLkhpZ2hjaGFydHNBZGFwdGVyIHx8ICgkICYmIHtcblx0XHRcblx0XHQvKipcblx0XHQgKiBJbml0aWFsaXplIHRoZSBhZGFwdGVyIGJ5IGFwcGx5aW5nIHNvbWUgZXh0ZW5zaW9ucyB0byBqUXVlcnlcblx0XHQgKi9cblx0XHRpbml0OiBmdW5jdGlvbiAocGF0aEFuaW0pIHtcblx0XHRcdFxuXHRcdFx0Ly8gZXh0ZW5kIHRoZSBhbmltYXRlIGZ1bmN0aW9uIHRvIGFsbG93IFNWRyBhbmltYXRpb25zXG5cdFx0XHR2YXIgRnggPSAkLmZ4O1xuXHRcdFx0XG5cdFx0XHQvKmpzbGludCB1bnBhcmFtOiB0cnVlKi8vKiBhbGxvdyB1bnVzZWQgcGFyYW0geCBpbiB0aGlzIGZ1bmN0aW9uICovXG5cdFx0XHQkLmV4dGVuZCgkLmVhc2luZywge1xuXHRcdFx0XHRlYXNlT3V0UXVhZDogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGQpIHtcblx0XHRcdFx0XHRyZXR1cm4gLWMgKiAodCAvPSBkKSAqICh0IC0gMikgKyBiO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdC8qanNsaW50IHVucGFyYW06IGZhbHNlKi9cblx0XHRcblx0XHRcdC8vIGV4dGVuZCBzb21lIG1ldGhvZHMgdG8gY2hlY2sgZm9yIGVsZW0uYXR0ciwgd2hpY2ggbWVhbnMgaXQgaXMgYSBIaWdoY2hhcnRzIFNWRyBvYmplY3Rcblx0XHRcdCQuZWFjaChbJ2N1cicsICdfZGVmYXVsdCcsICd3aWR0aCcsICdoZWlnaHQnLCAnb3BhY2l0eSddLCBmdW5jdGlvbiAoaSwgZm4pIHtcblx0XHRcdFx0dmFyIG9iaiA9IEZ4LnN0ZXAsXG5cdFx0XHRcdFx0YmFzZTtcblx0XHRcdFx0XHRcblx0XHRcdFx0Ly8gSGFuZGxlIGRpZmZlcmVudCBwYXJlbnQgb2JqZWN0c1xuXHRcdFx0XHRpZiAoZm4gPT09ICdjdXInKSB7XG5cdFx0XHRcdFx0b2JqID0gRngucHJvdG90eXBlOyAvLyAnY3VyJywgdGhlIGdldHRlciwgcmVsYXRlcyB0byBGeC5wcm90b3R5cGVcblx0XHRcdFx0XG5cdFx0XHRcdH0gZWxzZSBpZiAoZm4gPT09ICdfZGVmYXVsdCcgJiYgJC5Ud2VlbikgeyAvLyBqUXVlcnkgMS44IG1vZGVsXG5cdFx0XHRcdFx0b2JqID0gJC5Ud2Vlbi5wcm9wSG9va3NbZm5dO1xuXHRcdFx0XHRcdGZuID0gJ3NldCc7XG5cdFx0XHRcdH1cblx0XHRcblx0XHRcdFx0Ly8gT3ZlcndyaXRlIHRoZSBtZXRob2Rcblx0XHRcdFx0YmFzZSA9IG9ialtmbl07XG5cdFx0XHRcdGlmIChiYXNlKSB7IC8vIHN0ZXAud2lkdGggYW5kIHN0ZXAuaGVpZ2h0IGRvbid0IGV4aXN0IGluIGpRdWVyeSA8IDEuN1xuXHRcdFxuXHRcdFx0XHRcdC8vIGNyZWF0ZSB0aGUgZXh0ZW5kZWQgZnVuY3Rpb24gcmVwbGFjZW1lbnRcblx0XHRcdFx0XHRvYmpbZm5dID0gZnVuY3Rpb24gKGZ4KSB7XG5cblx0XHRcdFx0XHRcdHZhciBlbGVtO1xuXHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHQvLyBGeC5wcm90b3R5cGUuY3VyIGRvZXMgbm90IHVzZSBmeCBhcmd1bWVudFxuXHRcdFx0XHRcdFx0ZnggPSBpID8gZnggOiB0aGlzO1xuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBydW4gYW5pbWF0aW9ucyBvbiB0ZXh0dWFsIHByb3BlcnRpZXMgbGlrZSBhbGlnbiAoIzE4MjEpXG5cdFx0XHRcdFx0XHRpZiAoZngucHJvcCA9PT0gJ2FsaWduJykge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHR9XG5cdFx0XG5cdFx0XHRcdFx0XHQvLyBzaG9ydGN1dFxuXHRcdFx0XHRcdFx0ZWxlbSA9IGZ4LmVsZW07XG5cdFx0XG5cdFx0XHRcdFx0XHQvLyBGeC5wcm90b3R5cGUuY3VyIHJldHVybnMgdGhlIGN1cnJlbnQgdmFsdWUuIFRoZSBvdGhlciBvbmVzIGFyZSBzZXR0ZXJzXG5cdFx0XHRcdFx0XHQvLyBhbmQgcmV0dXJuaW5nIGEgdmFsdWUgaGFzIG5vIGVmZmVjdC5cblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLmF0dHIgPyAvLyBpcyBTVkcgZWxlbWVudCB3cmFwcGVyXG5cdFx0XHRcdFx0XHRcdGVsZW0uYXR0cihmeC5wcm9wLCBmbiA9PT0gJ2N1cicgPyBVTkRFRklORUQgOiBmeC5ub3cpIDogLy8gYXBwbHkgdGhlIFNWRyB3cmFwcGVyJ3MgbWV0aG9kXG5cdFx0XHRcdFx0XHRcdGJhc2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gdXNlIGpRdWVyeSdzIGJ1aWx0LWluIG1ldGhvZFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBFeHRlbmQgdGhlIG9wYWNpdHkgZ2V0dGVyLCBuZWVkZWQgZm9yIGZhZGluZyBvcGFjaXR5IHdpdGggSUU5IGFuZCBqUXVlcnkgMS4xMCtcblx0XHRcdHdyYXAoJC5jc3NIb29rcy5vcGFjaXR5LCAnZ2V0JywgZnVuY3Rpb24gKHByb2NlZWQsIGVsZW0sIGNvbXB1dGVkKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmF0dHIgPyAoZWxlbS5vcGFjaXR5IHx8IDApIDogcHJvY2VlZC5jYWxsKHRoaXMsIGVsZW0sIGNvbXB1dGVkKTtcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHQvLyBEZWZpbmUgdGhlIHNldHRlciBmdW5jdGlvbiBmb3IgZCAocGF0aCBkZWZpbml0aW9ucylcblx0XHRcdHRoaXMuYWRkQW5pbVNldHRlcignZCcsIGZ1bmN0aW9uIChmeCkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IGZ4LmVsZW0sXG5cdFx0XHRcdFx0ZW5kcztcblx0XHRcblx0XHRcdFx0Ly8gTm9ybWFsbHkgc3RhcnQgYW5kIGVuZCBzaG91bGQgYmUgc2V0IGluIHN0YXRlID09IDAsIGJ1dCBzb21ldGltZXMsXG5cdFx0XHRcdC8vIGZvciByZWFzb25zIHVua25vd24sIHRoaXMgZG9lc24ndCBoYXBwZW4uIFBlcmhhcHMgc3RhdGUgPT0gMCBpcyBza2lwcGVkXG5cdFx0XHRcdC8vIGluIHRoZXNlIGNhc2VzXG5cdFx0XHRcdGlmICghZnguc3RhcnRlZCkge1xuXHRcdFx0XHRcdGVuZHMgPSBwYXRoQW5pbS5pbml0KGVsZW0sIGVsZW0uZCwgZWxlbS50b0QpO1xuXHRcdFx0XHRcdGZ4LnN0YXJ0ID0gZW5kc1swXTtcblx0XHRcdFx0XHRmeC5lbmQgPSBlbmRzWzFdO1xuXHRcdFx0XHRcdGZ4LnN0YXJ0ZWQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XG5cdFx0XHRcdC8vIEludGVycG9sYXRlIGVhY2ggdmFsdWUgb2YgdGhlIHBhdGhcblx0XHRcdFx0ZWxlbS5hdHRyKCdkJywgcGF0aEFuaW0uc3RlcChmeC5zdGFydCwgZnguZW5kLCBmeC5wb3MsIGVsZW0udG9EKSk7XG5cdFx0XHR9KTtcblx0XHRcdFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBVdGlsaXR5IGZvciBpdGVyYXRpbmcgb3ZlciBhbiBhcnJheS4gUGFyYW1ldGVycyBhcmUgcmV2ZXJzZWQgY29tcGFyZWQgdG8galF1ZXJ5LlxuXHRcdFx0ICogQHBhcmFtIHtBcnJheX0gYXJyXG5cdFx0XHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLmVhY2ggPSBBcnJheS5wcm90b3R5cGUuZm9yRWFjaCA/XG5cdFx0XHRcdGZ1bmN0aW9uIChhcnIsIGZuKSB7IC8vIG1vZGVybiBicm93c2Vyc1xuXHRcdFx0XHRcdHJldHVybiBBcnJheS5wcm90b3R5cGUuZm9yRWFjaC5jYWxsKGFyciwgZm4pO1xuXHRcdFx0XHRcdFxuXHRcdFx0XHR9IDogXG5cdFx0XHRcdGZ1bmN0aW9uIChhcnIsIGZuKSB7IC8vIGxlZ2FjeVxuXHRcdFx0XHRcdHZhciBpLCBcblx0XHRcdFx0XHRcdGxlbiA9IGFyci5sZW5ndGg7XG5cdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdFx0XHRpZiAoZm4uY2FsbChhcnJbaV0sIGFycltpXSwgaSwgYXJyKSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0XG5cdFx0XHQvKipcblx0XHRcdCAqIFJlZ2lzdGVyIEhpZ2hjaGFydHMgYXMgYSBwbHVnaW4gaW4gdGhlIHJlc3BlY3RpdmUgZnJhbWV3b3JrXG5cdFx0XHQgKi9cblx0XHRcdCQuZm4uaGlnaGNoYXJ0cyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dmFyIGNvbnN0ciA9ICdDaGFydCcsIC8vIGRlZmF1bHQgY29uc3RydWN0b3Jcblx0XHRcdFx0XHRhcmdzID0gYXJndW1lbnRzLFxuXHRcdFx0XHRcdG9wdGlvbnMsXG5cdFx0XHRcdFx0cmV0LFxuXHRcdFx0XHRcdGNoYXJ0O1xuXG5cdFx0XHRcdGlmICh0aGlzWzBdKSB7XG5cblx0XHRcdFx0XHRpZiAoaXNTdHJpbmcoYXJnc1swXSkpIHtcblx0XHRcdFx0XHRcdGNvbnN0ciA9IGFyZ3NbMF07XG5cdFx0XHRcdFx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSk7IFxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRvcHRpb25zID0gYXJnc1swXTtcblxuXHRcdFx0XHRcdC8vIENyZWF0ZSB0aGUgY2hhcnRcblx0XHRcdFx0XHRpZiAob3B0aW9ucyAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdFx0XHQvKmpzbGludCB1bnVzZWQ6ZmFsc2UqL1xuXHRcdFx0XHRcdFx0b3B0aW9ucy5jaGFydCA9IG9wdGlvbnMuY2hhcnQgfHwge307XG5cdFx0XHRcdFx0XHRvcHRpb25zLmNoYXJ0LnJlbmRlclRvID0gdGhpc1swXTtcblx0XHRcdFx0XHRcdGNoYXJ0ID0gbmV3IEhpZ2hjaGFydHNbY29uc3RyXShvcHRpb25zLCBhcmdzWzFdKTtcblx0XHRcdFx0XHRcdHJldCA9IHRoaXM7XG5cdFx0XHRcdFx0XHQvKmpzbGludCB1bnVzZWQ6dHJ1ZSovXG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gV2hlbiBjYWxsZWQgd2l0aG91dCBwYXJhbWV0ZXJzIG9yIHdpdGggdGhlIHJldHVybiBhcmd1bWVudCwgZ2V0IGEgcHJlZGVmaW5lZCBjaGFydFxuXHRcdFx0XHRcdGlmIChvcHRpb25zID09PSBVTkRFRklORUQpIHtcblx0XHRcdFx0XHRcdHJldCA9IGNoYXJ0c1thdHRyKHRoaXNbMF0sICdkYXRhLWhpZ2hjaGFydHMtY2hhcnQnKV07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fTtcblxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBBZGQgYW4gYW5pbWF0aW9uIHNldHRlciBmb3IgYSBzcGVjaWZpYyBwcm9wZXJ0eVxuXHRcdCAqL1xuXHRcdGFkZEFuaW1TZXR0ZXI6IGZ1bmN0aW9uIChwcm9wLCBzZXR0ZXIpIHtcblx0XHRcdC8vIGpRdWVyeSAxLjggc3R5bGVcblx0XHRcdGlmICgkLlR3ZWVuKSB7XG5cdFx0XHRcdCQuVHdlZW4ucHJvcEhvb2tzW3Byb3BdID0ge1xuXHRcdFx0XHRcdHNldDogc2V0dGVyXG5cdFx0XHRcdH07XG5cdFx0XHQvLyBwcmUgMS44XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQkLmZ4LnN0ZXBbcHJvcF0gPSBzZXR0ZXI7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRcblx0XHQvKipcblx0XHQgKiBEb3dubG9hZHMgYSBzY3JpcHQgYW5kIGV4ZWN1dGVzIGEgY2FsbGJhY2sgd2hlbiBkb25lLlxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBzY3JpcHRMb2NhdGlvblxuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG5cdFx0ICovXG5cdFx0Z2V0U2NyaXB0OiAkLmdldFNjcmlwdCxcblx0XHRcblx0XHQvKipcblx0XHQgKiBSZXR1cm4gdGhlIGluZGV4IG9mIGFuIGl0ZW0gaW4gYW4gYXJyYXksIG9yIC0xIGlmIG5vdCBmb3VuZFxuXHRcdCAqL1xuXHRcdGluQXJyYXk6ICQuaW5BcnJheSxcblx0XHRcblx0XHQvKipcblx0XHQgKiBBIGRpcmVjdCBsaW5rIHRvIGpRdWVyeSBtZXRob2RzLiBNb29Ub29scyBhbmQgUHJvdG90eXBlIGFkYXB0ZXJzIG11c3QgYmUgaW1wbGVtZW50ZWQgZm9yIGVhY2ggY2FzZSBvZiBtZXRob2QuXG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IGVsZW0gVGhlIEhUTUwgZWxlbWVudFxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSBtZXRob2QgV2hpY2ggbWV0aG9kIHRvIHJ1biBvbiB0aGUgd3JhcHBlZCBlbGVtZW50XG5cdFx0ICovXG5cdFx0YWRhcHRlclJ1bjogZnVuY3Rpb24gKGVsZW0sIG1ldGhvZCkge1xuXHRcdFx0cmV0dXJuICQoZWxlbSlbbWV0aG9kXSgpO1xuXHRcdH0sXG5cdFxuXHRcdC8qKlxuXHRcdCAqIEZpbHRlciBhbiBhcnJheVxuXHRcdCAqL1xuXHRcdGdyZXA6ICQuZ3JlcCxcblx0XG5cdFx0LyoqXG5cdFx0ICogTWFwIGFuIGFycmF5XG5cdFx0ICogQHBhcmFtIHtBcnJheX0gYXJyXG5cdFx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cblx0XHQgKi9cblx0XHRtYXA6IGZ1bmN0aW9uIChhcnIsIGZuKSB7XG5cdFx0XHQvL3JldHVybiBqUXVlcnkubWFwKGFyciwgZm4pO1xuXHRcdFx0dmFyIHJlc3VsdHMgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdGxlbiA9IGFyci5sZW5ndGg7XG5cdFx0XHRmb3IgKDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHRcdHJlc3VsdHNbaV0gPSBmbi5jYWxsKGFycltpXSwgYXJyW2ldLCBpLCBhcnIpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFxuXHRcdH0sXG5cdFxuXHRcdC8qKlxuXHRcdCAqIEdldCB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byB0aGUgdG9wIGxlZnQgb2YgdGhlIHBhZ2Vcblx0XHQgKi9cblx0XHRvZmZzZXQ6IGZ1bmN0aW9uIChlbCkge1xuXHRcdFx0cmV0dXJuICQoZWwpLm9mZnNldCgpO1xuXHRcdH0sXG5cdFxuXHRcdC8qKlxuXHRcdCAqIEFkZCBhbiBldmVudCBsaXN0ZW5lclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBlbCBBIEhUTUwgZWxlbWVudCBvciBjdXN0b20gb2JqZWN0XG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IFRoZSBldmVudCB0eXBlXG5cdFx0ICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGV2ZW50IGhhbmRsZXJcblx0XHQgKi9cblx0XHRhZGRFdmVudDogZnVuY3Rpb24gKGVsLCBldmVudCwgZm4pIHtcblx0XHRcdCQoZWwpLmJpbmQoZXZlbnQsIGZuKTtcblx0XHR9LFxuXHRcblx0XHQvKipcblx0XHQgKiBSZW1vdmUgZXZlbnQgYWRkZWQgd2l0aCBhZGRFdmVudFxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBlbCBUaGUgb2JqZWN0XG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZSBUaGUgZXZlbnQgdHlwZS4gTGVhdmUgYmxhbmsgdG8gcmVtb3ZlIGFsbCBldmVudHMuXG5cdFx0ICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgZnVuY3Rpb24gdG8gcmVtb3ZlXG5cdFx0ICovXG5cdFx0cmVtb3ZlRXZlbnQ6IGZ1bmN0aW9uIChlbCwgZXZlbnRUeXBlLCBoYW5kbGVyKSB7XG5cdFx0XHQvLyB3b3JrYXJvdW5kIGZvciBqUXVlcnkgaXNzdWUgd2l0aCB1bmJpbmRpbmcgY3VzdG9tIGV2ZW50czpcblx0XHRcdC8vIGh0dHA6Ly9mb3J1bS5qUXVlcnkuY29tL3RvcGljL2phdmFzY3JpcHQtZXJyb3Itd2hlbi11bmJpbmRpbmctYS1jdXN0b20tZXZlbnQtdXNpbmctalF1ZXJ5LTEtNC0yXG5cdFx0XHR2YXIgZnVuYyA9IGRvYy5yZW1vdmVFdmVudExpc3RlbmVyID8gJ3JlbW92ZUV2ZW50TGlzdGVuZXInIDogJ2RldGFjaEV2ZW50Jztcblx0XHRcdGlmIChkb2NbZnVuY10gJiYgZWwgJiYgIWVsW2Z1bmNdKSB7XG5cdFx0XHRcdGVsW2Z1bmNdID0gZnVuY3Rpb24gKCkge307XG5cdFx0XHR9XG5cdFxuXHRcdFx0JChlbCkudW5iaW5kKGV2ZW50VHlwZSwgaGFuZGxlcik7XG5cdFx0fSxcblx0XG5cdFx0LyoqXG5cdFx0ICogRmlyZSBhbiBldmVudCBvbiBhIGN1c3RvbSBvYmplY3Rcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gZWxcblx0XHQgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudEFyZ3VtZW50c1xuXHRcdCAqIEBwYXJhbSB7RnVuY3Rpb259IGRlZmF1bHRGdW5jdGlvblxuXHRcdCAqL1xuXHRcdGZpcmVFdmVudDogZnVuY3Rpb24gKGVsLCB0eXBlLCBldmVudEFyZ3VtZW50cywgZGVmYXVsdEZ1bmN0aW9uKSB7XG5cdFx0XHR2YXIgZXZlbnQgPSAkLkV2ZW50KHR5cGUpLFxuXHRcdFx0XHRkZXRhY2hlZFR5cGUgPSAnZGV0YWNoZWQnICsgdHlwZSxcblx0XHRcdFx0ZGVmYXVsdFByZXZlbnRlZDtcblx0XG5cdFx0XHQvLyBSZW1vdmUgd2FybmluZ3MgaW4gQ2hyb21lIHdoZW4gYWNjZXNzaW5nIHJldHVyblZhbHVlICgjMjc5MCksIGxheWVyWCBhbmQgbGF5ZXJZLiBBbHRob3VnaCBIaWdoY2hhcnRzXG5cdFx0XHQvLyBuZXZlciB1c2VzIHRoZXNlIHByb3BlcnRpZXMsIENocm9tZSBpbmNsdWRlcyB0aGVtIGluIHRoZSBkZWZhdWx0IGNsaWNrIGV2ZW50IGFuZFxuXHRcdFx0Ly8gcmFpc2VzIHRoZSB3YXJuaW5nIHdoZW4gdGhleSBhcmUgY29waWVkIG92ZXIgaW4gdGhlIGV4dGVuZCBzdGF0ZW1lbnQgYmVsb3cuXG5cdFx0XHQvL1xuXHRcdFx0Ly8gVG8gYXZvaWQgcHJvYmxlbXMgaW4gSUUgKHNlZSAjMTAxMCkgd2hlcmUgd2UgY2Fubm90IGRlbGV0ZSB0aGUgcHJvcGVydGllcyBhbmQgYXZvaWRcblx0XHRcdC8vIHRlc3RpbmcgaWYgdGhleSBhcmUgdGhlcmUgKHdhcm5pbmcgaW4gY2hyb21lKSB0aGUgb25seSBvcHRpb24gaXMgdG8gdGVzdCBpZiBydW5uaW5nIElFLlxuXHRcdFx0aWYgKCFpc0lFICYmIGV2ZW50QXJndW1lbnRzKSB7XG5cdFx0XHRcdGRlbGV0ZSBldmVudEFyZ3VtZW50cy5sYXllclg7XG5cdFx0XHRcdGRlbGV0ZSBldmVudEFyZ3VtZW50cy5sYXllclk7XG5cdFx0XHRcdGRlbGV0ZSBldmVudEFyZ3VtZW50cy5yZXR1cm5WYWx1ZTtcblx0XHRcdH1cblx0XG5cdFx0XHRleHRlbmQoZXZlbnQsIGV2ZW50QXJndW1lbnRzKTtcblx0XG5cdFx0XHQvLyBQcmV2ZW50IGpRdWVyeSBmcm9tIHRyaWdnZXJpbmcgdGhlIG9iamVjdCBtZXRob2QgdGhhdCBpcyBuYW1lZCB0aGVcblx0XHRcdC8vIHNhbWUgYXMgdGhlIGV2ZW50LiBGb3IgZXhhbXBsZSwgaWYgdGhlIGV2ZW50IGlzICdzZWxlY3QnLCBqUXVlcnlcblx0XHRcdC8vIGF0dGVtcHRzIGNhbGxpbmcgZWwuc2VsZWN0IGFuZCBpdCBnb2VzIGludG8gYSBsb29wLlxuXHRcdFx0aWYgKGVsW3R5cGVdKSB7XG5cdFx0XHRcdGVsW2RldGFjaGVkVHlwZV0gPSBlbFt0eXBlXTtcblx0XHRcdFx0ZWxbdHlwZV0gPSBudWxsO1xuXHRcdFx0fVxuXHRcblx0XHRcdC8vIFdyYXAgcHJldmVudERlZmF1bHQgYW5kIHN0b3BQcm9wYWdhdGlvbiBpbiB0cnkvY2F0Y2ggYmxvY2tzIGluXG5cdFx0XHQvLyBvcmRlciB0byBwcmV2ZW50IEpTIGVycm9ycyB3aGVuIGNhbmNlbGxpbmcgZXZlbnRzIG9uIG5vbi1ET01cblx0XHRcdC8vIG9iamVjdHMuICM2MTUuXG5cdFx0XHQvKmpzbGludCB1bnBhcmFtOiB0cnVlKi9cblx0XHRcdCQuZWFjaChbJ3ByZXZlbnREZWZhdWx0JywgJ3N0b3BQcm9wYWdhdGlvbiddLCBmdW5jdGlvbiAoaSwgZm4pIHtcblx0XHRcdFx0dmFyIGJhc2UgPSBldmVudFtmbl07XG5cdFx0XHRcdGV2ZW50W2ZuXSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0YmFzZS5jYWxsKGV2ZW50KTtcblx0XHRcdFx0XHR9IGNhdGNoIChlKSB7XG5cdFx0XHRcdFx0XHRpZiAoZm4gPT09ICdwcmV2ZW50RGVmYXVsdCcpIHtcblx0XHRcdFx0XHRcdFx0ZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0fSk7XG5cdFx0XHQvKmpzbGludCB1bnBhcmFtOiBmYWxzZSovXG5cdFxuXHRcdFx0Ly8gdHJpZ2dlciBpdFxuXHRcdFx0JChlbCkudHJpZ2dlcihldmVudCk7XG5cdFxuXHRcdFx0Ly8gYXR0YWNoIHRoZSBtZXRob2Rcblx0XHRcdGlmIChlbFtkZXRhY2hlZFR5cGVdKSB7XG5cdFx0XHRcdGVsW3R5cGVdID0gZWxbZGV0YWNoZWRUeXBlXTtcblx0XHRcdFx0ZWxbZGV0YWNoZWRUeXBlXSA9IG51bGw7XG5cdFx0XHR9XG5cdFxuXHRcdFx0aWYgKGRlZmF1bHRGdW5jdGlvbiAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgJiYgIWRlZmF1bHRQcmV2ZW50ZWQpIHtcblx0XHRcdFx0ZGVmYXVsdEZ1bmN0aW9uKGV2ZW50KTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdFxuXHRcdC8qKlxuXHRcdCAqIEV4dGVuc2lvbiBtZXRob2QgbmVlZGVkIGZvciBNb29Ub29sc1xuXHRcdCAqL1xuXHRcdHdhc2hNb3VzZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0dmFyIHJldCA9IGUub3JpZ2luYWxFdmVudCB8fCBlO1xuXHRcdFx0XG5cdFx0XHQvLyBjb21wdXRlZCBieSBqUXVlcnksIG5lZWRlZCBieSBJRThcblx0XHRcdGlmIChyZXQucGFnZVggPT09IFVOREVGSU5FRCkgeyAvLyAjMTIzNlxuXHRcdFx0XHRyZXQucGFnZVggPSBlLnBhZ2VYO1xuXHRcdFx0XHRyZXQucGFnZVkgPSBlLnBhZ2VZO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0sXG5cdFxuXHRcdC8qKlxuXHRcdCAqIEFuaW1hdGUgYSBIVE1MIGVsZW1lbnQgb3IgU1ZHIGVsZW1lbnQgd3JhcHBlclxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBlbFxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXNcblx0XHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBqUXVlcnktbGlrZSBhbmltYXRpb24gb3B0aW9uczogZHVyYXRpb24sIGVhc2luZywgY2FsbGJhY2tcblx0XHQgKi9cblx0XHRhbmltYXRlOiBmdW5jdGlvbiAoZWwsIHBhcmFtcywgb3B0aW9ucykge1xuXHRcdFx0dmFyICRlbCA9ICQoZWwpO1xuXHRcdFx0aWYgKCFlbC5zdHlsZSkge1xuXHRcdFx0XHRlbC5zdHlsZSA9IHt9OyAvLyAjMTg4MVxuXHRcdFx0fVxuXHRcdFx0aWYgKHBhcmFtcy5kKSB7XG5cdFx0XHRcdGVsLnRvRCA9IHBhcmFtcy5kOyAvLyBrZWVwIHRoZSBhcnJheSBmb3JtIGZvciBwYXRocywgdXNlZCBpbiAkLmZ4LnN0ZXAuZFxuXHRcdFx0XHRwYXJhbXMuZCA9IDE7IC8vIGJlY2F1c2UgaW4galF1ZXJ5LCBhbmltYXRpbmcgdG8gYW4gYXJyYXkgaGFzIGEgZGlmZmVyZW50IG1lYW5pbmdcblx0XHRcdH1cblx0XG5cdFx0XHQkZWwuc3RvcCgpO1xuXHRcdFx0aWYgKHBhcmFtcy5vcGFjaXR5ICE9PSBVTkRFRklORUQgJiYgZWwuYXR0cikge1xuXHRcdFx0XHRwYXJhbXMub3BhY2l0eSArPSAncHgnOyAvLyBmb3JjZSBqUXVlcnkgdG8gdXNlIHNhbWUgbG9naWMgYXMgd2lkdGggYW5kIGhlaWdodCAoIzIxNjEpXG5cdFx0XHR9XG5cdFx0XHRlbC5oYXNBbmltID0gMTsgLy8gIzMzNDJcblx0XHRcdCRlbC5hbmltYXRlKHBhcmFtcywgb3B0aW9ucyk7XG5cdFxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogU3RvcCBydW5uaW5nIGFuaW1hdGlvblxuXHRcdCAqL1xuXHRcdHN0b3A6IGZ1bmN0aW9uIChlbCkge1xuXHRcdFx0aWYgKGVsLmhhc0FuaW0pIHsgLy8gIzMzNDIsIG1lbW9yeSBsZWFrIG9uIGNhbGxpbmcgJChlbCkgZnJvbSBkZXN0cm95XG5cdFx0XHRcdCQoZWwpLnN0b3AoKTtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xufSh3aW4ualF1ZXJ5KSk7XG5cblxuLy8gY2hlY2sgZm9yIGEgY3VzdG9tIEhpZ2hjaGFydHNBZGFwdGVyIGRlZmluZWQgcHJpb3IgdG8gdGhpcyBmaWxlXG52YXIgZ2xvYmFsQWRhcHRlciA9IHdpbi5IaWdoY2hhcnRzQWRhcHRlcixcblx0YWRhcHRlciA9IGdsb2JhbEFkYXB0ZXIgfHwge307XG5cdFxuLy8gSW5pdGlhbGl6ZSB0aGUgYWRhcHRlclxuaWYgKGdsb2JhbEFkYXB0ZXIpIHtcblx0Z2xvYmFsQWRhcHRlci5pbml0LmNhbGwoZ2xvYmFsQWRhcHRlciwgcGF0aEFuaW0pO1xufVxuXG5cbi8vIFV0aWxpdHkgZnVuY3Rpb25zLiBJZiB0aGUgSGlnaGNoYXJ0c0FkYXB0ZXIgaXMgbm90IGRlZmluZWQsIGFkYXB0ZXIgaXMgYW4gZW1wdHkgb2JqZWN0XG4vLyBhbmQgYWxsIHRoZSB1dGlsaXR5IGZ1bmN0aW9ucyB3aWxsIGJlIG51bGwuIEluIHRoYXQgY2FzZSB0aGV5IGFyZSBwb3B1bGF0ZWQgYnkgdGhlXG4vLyBkZWZhdWx0IGFkYXB0ZXJzIGJlbG93LlxudmFyIGFkYXB0ZXJSdW4gPSBhZGFwdGVyLmFkYXB0ZXJSdW4sXG5cdGdldFNjcmlwdCA9IGFkYXB0ZXIuZ2V0U2NyaXB0LFxuXHRpbkFycmF5ID0gYWRhcHRlci5pbkFycmF5LFxuXHRlYWNoID0gYWRhcHRlci5lYWNoLFxuXHRncmVwID0gYWRhcHRlci5ncmVwLFxuXHRvZmZzZXQgPSBhZGFwdGVyLm9mZnNldCxcblx0bWFwID0gYWRhcHRlci5tYXAsXG5cdGFkZEV2ZW50ID0gYWRhcHRlci5hZGRFdmVudCxcblx0cmVtb3ZlRXZlbnQgPSBhZGFwdGVyLnJlbW92ZUV2ZW50LFxuXHRmaXJlRXZlbnQgPSBhZGFwdGVyLmZpcmVFdmVudCxcblx0d2FzaE1vdXNlRXZlbnQgPSBhZGFwdGVyLndhc2hNb3VzZUV2ZW50LFxuXHRhbmltYXRlID0gYWRhcHRlci5hbmltYXRlLFxuXHRzdG9wID0gYWRhcHRlci5zdG9wO1xuXG5cblxuLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogSGFuZGxlIHRoZSBvcHRpb25zICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xudmFyXG5cbmRlZmF1bHRMYWJlbE9wdGlvbnMgPSB7XG5cdGVuYWJsZWQ6IHRydWUsXG5cdC8vIHJvdGF0aW9uOiAwLFxuXHQvLyBhbGlnbjogJ2NlbnRlcicsXG5cdHg6IDAsXG5cdHk6IDE1LFxuXHQvKmZvcm1hdHRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLnZhbHVlO1xuXHR9LCovXG5cdHN0eWxlOiB7XG5cdFx0Y29sb3I6ICcjNjA2MDYwJyxcblx0XHRjdXJzb3I6ICdkZWZhdWx0Jyxcblx0XHRmb250U2l6ZTogJzExcHgnXG5cdH1cbn07XG5cbmRlZmF1bHRPcHRpb25zID0ge1xuXHRjb2xvcnM6IFsnIzdjYjVlYycsICcjNDM0MzQ4JywgJyM5MGVkN2QnLCAnI2Y3YTM1YycsIFxuXHRcdCAgICAnIzgwODVlOScsICcjZjE1YzgwJywgJyNlNGQzNTQnLCAnIzgwODVlOCcsICcjOGQ0NjUzJywgJyM5MWU4ZTEnXSxcblx0c3ltYm9sczogWydjaXJjbGUnLCAnZGlhbW9uZCcsICdzcXVhcmUnLCAndHJpYW5nbGUnLCAndHJpYW5nbGUtZG93biddLFxuXHRsYW5nOiB7XG5cdFx0bG9hZGluZzogJ0xvYWRpbmcuLi4nLFxuXHRcdG1vbnRoczogWydKYW51YXJ5JywgJ0ZlYnJ1YXJ5JywgJ01hcmNoJywgJ0FwcmlsJywgJ01heScsICdKdW5lJywgJ0p1bHknLFxuXHRcdFx0XHQnQXVndXN0JywgJ1NlcHRlbWJlcicsICdPY3RvYmVyJywgJ05vdmVtYmVyJywgJ0RlY2VtYmVyJ10sXG5cdFx0c2hvcnRNb250aHM6IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXSxcblx0XHR3ZWVrZGF5czogWydTdW5kYXknLCAnTW9uZGF5JywgJ1R1ZXNkYXknLCAnV2VkbmVzZGF5JywgJ1RodXJzZGF5JywgJ0ZyaWRheScsICdTYXR1cmRheSddLFxuXHRcdGRlY2ltYWxQb2ludDogJy4nLFxuXHRcdG51bWVyaWNTeW1ib2xzOiBbJ2snLCAnTScsICdHJywgJ1QnLCAnUCcsICdFJ10sIC8vIFNJIHByZWZpeGVzIHVzZWQgaW4gYXhpcyBsYWJlbHNcblx0XHRyZXNldFpvb206ICdSZXNldCB6b29tJyxcblx0XHRyZXNldFpvb21UaXRsZTogJ1Jlc2V0IHpvb20gbGV2ZWwgMToxJyxcblx0XHR0aG91c2FuZHNTZXA6ICcsJ1xuXHR9LFxuXHRnbG9iYWw6IHtcblx0XHR1c2VVVEM6IHRydWUsXG5cdFx0Ly90aW1lem9uZU9mZnNldDogMCxcblx0XHRjYW52YXNUb29sc1VSTDogJ2h0dHA6Ly9jb2RlLmhpZ2hjaGFydHMuY29tLzQuMC40L21vZHVsZXMvY2FudmFzLXRvb2xzLmpzJyxcblx0XHRWTUxSYWRpYWxHcmFkaWVudFVSTDogJ2h0dHA6Ly9jb2RlLmhpZ2hjaGFydHMuY29tLzQuMC40L2dmeC92bWwtcmFkaWFsLWdyYWRpZW50LnBuZydcblx0fSxcblx0Y2hhcnQ6IHtcblx0XHQvL2FuaW1hdGlvbjogdHJ1ZSxcblx0XHQvL2FsaWduVGlja3M6IGZhbHNlLFxuXHRcdC8vcmVmbG93OiB0cnVlLFxuXHRcdC8vY2xhc3NOYW1lOiBudWxsLFxuXHRcdC8vZXZlbnRzOiB7IGxvYWQsIHNlbGVjdGlvbiB9LFxuXHRcdC8vbWFyZ2luOiBbbnVsbF0sXG5cdFx0Ly9tYXJnaW5Ub3A6IG51bGwsXG5cdFx0Ly9tYXJnaW5SaWdodDogbnVsbCxcblx0XHQvL21hcmdpbkJvdHRvbTogbnVsbCxcblx0XHQvL21hcmdpbkxlZnQ6IG51bGwsXG5cdFx0Ym9yZGVyQ29sb3I6ICcjNDU3MkE3Jyxcblx0XHQvL2JvcmRlcldpZHRoOiAwLFxuXHRcdGJvcmRlclJhZGl1czogMCxcblx0XHRkZWZhdWx0U2VyaWVzVHlwZTogJ2xpbmUnLFxuXHRcdGlnbm9yZUhpZGRlblNlcmllczogdHJ1ZSxcblx0XHQvL2ludmVydGVkOiBmYWxzZSxcblx0XHQvL3NoYWRvdzogZmFsc2UsXG5cdFx0c3BhY2luZzogWzEwLCAxMCwgMTUsIDEwXSxcblx0XHQvL3NwYWNpbmdUb3A6IDEwLFxuXHRcdC8vc3BhY2luZ1JpZ2h0OiAxMCxcblx0XHQvL3NwYWNpbmdCb3R0b206IDE1LFxuXHRcdC8vc3BhY2luZ0xlZnQ6IDEwLFxuXHRcdC8vc3R5bGU6IHtcblx0XHQvL1x0Zm9udEZhbWlseTogJ1wiTHVjaWRhIEdyYW5kZVwiLCBcIkx1Y2lkYSBTYW5zIFVuaWNvZGVcIiwgVmVyZGFuYSwgQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZicsIC8vIGRlZmF1bHQgZm9udFxuXHRcdC8vXHRmb250U2l6ZTogJzEycHgnXG5cdFx0Ly99LFxuXHRcdGJhY2tncm91bmRDb2xvcjogJyNGRkZGRkYnLFxuXHRcdC8vcGxvdEJhY2tncm91bmRDb2xvcjogbnVsbCxcblx0XHRwbG90Qm9yZGVyQ29sb3I6ICcjQzBDMEMwJyxcblx0XHQvL3Bsb3RCb3JkZXJXaWR0aDogMCxcblx0XHQvL3Bsb3RTaGFkb3c6IGZhbHNlLFxuXHRcdC8vem9vbVR5cGU6ICcnXG5cdFx0cmVzZXRab29tQnV0dG9uOiB7XG5cdFx0XHR0aGVtZToge1xuXHRcdFx0XHR6SW5kZXg6IDIwXG5cdFx0XHR9LFxuXHRcdFx0cG9zaXRpb246IHtcblx0XHRcdFx0YWxpZ246ICdyaWdodCcsXG5cdFx0XHRcdHg6IC0xMCxcblx0XHRcdFx0Ly92ZXJ0aWNhbEFsaWduOiAndG9wJyxcblx0XHRcdFx0eTogMTBcblx0XHRcdH1cblx0XHRcdC8vIHJlbGF0aXZlVG86ICdwbG90J1xuXHRcdH1cblx0fSxcblx0dGl0bGU6IHtcblx0XHR0ZXh0OiAnQ2hhcnQgdGl0bGUnLFxuXHRcdGFsaWduOiAnY2VudGVyJyxcblx0XHQvLyBmbG9hdGluZzogZmFsc2UsXG5cdFx0bWFyZ2luOiAxNSxcblx0XHQvLyB4OiAwLFxuXHRcdC8vIHZlcnRpY2FsQWxpZ246ICd0b3AnLFxuXHRcdC8vIHk6IG51bGwsXG5cdFx0c3R5bGU6IHtcblx0XHRcdGNvbG9yOiAnIzMzMzMzMycsXG5cdFx0XHRmb250U2l6ZTogJzE4cHgnXG5cdFx0fVxuXG5cdH0sXG5cdHN1YnRpdGxlOiB7XG5cdFx0dGV4dDogJycsXG5cdFx0YWxpZ246ICdjZW50ZXInLFxuXHRcdC8vIGZsb2F0aW5nOiBmYWxzZVxuXHRcdC8vIHg6IDAsXG5cdFx0Ly8gdmVydGljYWxBbGlnbjogJ3RvcCcsXG5cdFx0Ly8geTogbnVsbCxcblx0XHRzdHlsZToge1xuXHRcdFx0Y29sb3I6ICcjNTU1NTU1J1xuXHRcdH1cblx0fSxcblxuXHRwbG90T3B0aW9uczoge1xuXHRcdGxpbmU6IHsgLy8gYmFzZSBzZXJpZXMgb3B0aW9uc1xuXHRcdFx0YWxsb3dQb2ludFNlbGVjdDogZmFsc2UsXG5cdFx0XHRzaG93Q2hlY2tib3g6IGZhbHNlLFxuXHRcdFx0YW5pbWF0aW9uOiB7XG5cdFx0XHRcdGR1cmF0aW9uOiAxMDAwXG5cdFx0XHR9LFxuXHRcdFx0Ly9jb25uZWN0TnVsbHM6IGZhbHNlLFxuXHRcdFx0Ly9jdXJzb3I6ICdkZWZhdWx0Jyxcblx0XHRcdC8vY2xpcDogdHJ1ZSxcblx0XHRcdC8vZGFzaFN0eWxlOiBudWxsLFxuXHRcdFx0Ly9lbmFibGVNb3VzZVRyYWNraW5nOiB0cnVlLFxuXHRcdFx0ZXZlbnRzOiB7fSxcblx0XHRcdC8vbGVnZW5kSW5kZXg6IDAsXG5cdFx0XHQvL2xpbmVjYXA6ICdyb3VuZCcsXG5cdFx0XHRsaW5lV2lkdGg6IDIsXG5cdFx0XHQvL3NoYWRvdzogZmFsc2UsXG5cdFx0XHQvLyBzdGFja2luZzogbnVsbCxcblx0XHRcdG1hcmtlcjoge1xuXHRcdFx0XHQvL2VuYWJsZWQ6IHRydWUsXG5cdFx0XHRcdC8vc3ltYm9sOiBudWxsLFxuXHRcdFx0XHRsaW5lV2lkdGg6IDAsXG5cdFx0XHRcdHJhZGl1czogNCxcblx0XHRcdFx0bGluZUNvbG9yOiAnI0ZGRkZGRicsXG5cdFx0XHRcdC8vZmlsbENvbG9yOiBudWxsLFxuXHRcdFx0XHRzdGF0ZXM6IHsgLy8gc3RhdGVzIGZvciBhIHNpbmdsZSBwb2ludFxuXHRcdFx0XHRcdGhvdmVyOiB7XG5cdFx0XHRcdFx0XHRlbmFibGVkOiB0cnVlLFxuXHRcdFx0XHRcdFx0bGluZVdpZHRoUGx1czogMSxcblx0XHRcdFx0XHRcdHJhZGl1c1BsdXM6IDJcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHNlbGVjdDoge1xuXHRcdFx0XHRcdFx0ZmlsbENvbG9yOiAnI0ZGRkZGRicsXG5cdFx0XHRcdFx0XHRsaW5lQ29sb3I6ICcjMDAwMDAwJyxcblx0XHRcdFx0XHRcdGxpbmVXaWR0aDogMlxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHBvaW50OiB7XG5cdFx0XHRcdGV2ZW50czoge31cblx0XHRcdH0sXG5cdFx0XHRkYXRhTGFiZWxzOiBtZXJnZShkZWZhdWx0TGFiZWxPcHRpb25zLCB7XG5cdFx0XHRcdGFsaWduOiAnY2VudGVyJyxcblx0XHRcdFx0Ly9kZWZlcjogdHJ1ZSxcblx0XHRcdFx0ZW5hYmxlZDogZmFsc2UsXG5cdFx0XHRcdGZvcm1hdHRlcjogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdHJldHVybiB0aGlzLnkgPT09IG51bGwgPyAnJyA6IG51bWJlckZvcm1hdCh0aGlzLnksIC0xKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0dmVydGljYWxBbGlnbjogJ2JvdHRvbScsIC8vIGFib3ZlIHNpbmd1bGFyIHBvaW50XG5cdFx0XHRcdHk6IDBcblx0XHRcdFx0Ly8gYmFja2dyb3VuZENvbG9yOiB1bmRlZmluZWQsXG5cdFx0XHRcdC8vIGJvcmRlckNvbG9yOiB1bmRlZmluZWQsXG5cdFx0XHRcdC8vIGJvcmRlclJhZGl1czogdW5kZWZpbmVkLFxuXHRcdFx0XHQvLyBib3JkZXJXaWR0aDogdW5kZWZpbmVkLFxuXHRcdFx0XHQvLyBwYWRkaW5nOiAzLFxuXHRcdFx0XHQvLyBzaGFkb3c6IGZhbHNlXG5cdFx0XHR9KSxcblx0XHRcdGNyb3BUaHJlc2hvbGQ6IDMwMCwgLy8gZHJhdyBwb2ludHMgb3V0c2lkZSB0aGUgcGxvdCBhcmVhIHdoZW4gdGhlIG51bWJlciBvZiBwb2ludHMgaXMgbGVzcyB0aGFuIHRoaXNcblx0XHRcdHBvaW50UmFuZ2U6IDAsXG5cdFx0XHQvL3BvaW50U3RhcnQ6IDAsXG5cdFx0XHQvL3BvaW50SW50ZXJ2YWw6IDEsXG5cdFx0XHQvL3Nob3dJbkxlZ2VuZDogbnVsbCwgLy8gYXV0bzogdHJ1ZSBmb3Igc3RhbmRhbG9uZSBzZXJpZXMsIGZhbHNlIGZvciBsaW5rZWQgc2VyaWVzXG5cdFx0XHRzdGF0ZXM6IHsgLy8gc3RhdGVzIGZvciB0aGUgZW50aXJlIHNlcmllc1xuXHRcdFx0XHRob3Zlcjoge1xuXHRcdFx0XHRcdC8vZW5hYmxlZDogZmFsc2UsXG5cdFx0XHRcdFx0bGluZVdpZHRoUGx1czogMSxcblx0XHRcdFx0XHRtYXJrZXI6IHtcblx0XHRcdFx0XHRcdC8vIGxpbmVXaWR0aDogYmFzZSArIDEsXG5cdFx0XHRcdFx0XHQvLyByYWRpdXM6IGJhc2UgKyAxXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRoYWxvOiB7XG5cdFx0XHRcdFx0XHRzaXplOiAxMCxcblx0XHRcdFx0XHRcdG9wYWNpdHk6IDAuMjVcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHNlbGVjdDoge1xuXHRcdFx0XHRcdG1hcmtlcjoge31cblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHN0aWNreVRyYWNraW5nOiB0cnVlLFxuXHRcdFx0Ly90b29sdGlwOiB7XG5cdFx0XHRcdC8vcG9pbnRGb3JtYXQ6ICc8c3BhbiBzdHlsZT1cImNvbG9yOntzZXJpZXMuY29sb3J9XCI+XFx1MjVDRjwvc3Bhbj4ge3Nlcmllcy5uYW1lfTogPGI+e3BvaW50Lnl9PC9iPidcblx0XHRcdFx0Ly92YWx1ZURlY2ltYWxzOiBudWxsLFxuXHRcdFx0XHQvL3hEYXRlRm9ybWF0OiAnJUEsICViICVlLCAlWScsXG5cdFx0XHRcdC8vdmFsdWVQcmVmaXg6ICcnLFxuXHRcdFx0XHQvL3lTdWZmaXg6ICcnXHRcdFx0XHRcblx0XHRcdC8vfVxuXHRcdFx0dHVyYm9UaHJlc2hvbGQ6IDEwMDBcblx0XHRcdC8vIHpJbmRleDogbnVsbFxuXHRcdH1cblx0fSxcblx0bGFiZWxzOiB7XG5cdFx0Ly9pdGVtczogW10sXG5cdFx0c3R5bGU6IHtcblx0XHRcdC8vZm9udDogZGVmYXVsdEZvbnQsXG5cdFx0XHRwb3NpdGlvbjogQUJTT0xVVEUsXG5cdFx0XHRjb2xvcjogJyMzRTU3NkYnXG5cdFx0fVxuXHR9LFxuXHRsZWdlbmQ6IHtcblx0XHRlbmFibGVkOiB0cnVlLFxuXHRcdGFsaWduOiAnY2VudGVyJyxcblx0XHQvL2Zsb2F0aW5nOiBmYWxzZSxcblx0XHRsYXlvdXQ6ICdob3Jpem9udGFsJyxcblx0XHRsYWJlbEZvcm1hdHRlcjogZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIHRoaXMubmFtZTtcblx0XHR9LFxuXHRcdC8vYm9yZGVyV2lkdGg6IDAsXG5cdFx0Ym9yZGVyQ29sb3I6ICcjOTA5MDkwJyxcblx0XHRib3JkZXJSYWRpdXM6IDAsXG5cdFx0bmF2aWdhdGlvbjoge1xuXHRcdFx0Ly8gYW5pbWF0aW9uOiB0cnVlLFxuXHRcdFx0YWN0aXZlQ29sb3I6ICcjMjc0YjZkJyxcblx0XHRcdC8vIGFycm93U2l6ZTogMTJcblx0XHRcdGluYWN0aXZlQ29sb3I6ICcjQ0NDJ1xuXHRcdFx0Ly8gc3R5bGU6IHt9IC8vIHRleHQgc3R5bGVzXG5cdFx0fSxcblx0XHQvLyBtYXJnaW46IDIwLFxuXHRcdC8vIHJldmVyc2VkOiBmYWxzZSxcblx0XHRzaGFkb3c6IGZhbHNlLFxuXHRcdC8vIGJhY2tncm91bmRDb2xvcjogbnVsbCxcblx0XHQvKnN0eWxlOiB7XG5cdFx0XHRwYWRkaW5nOiAnNXB4J1xuXHRcdH0sKi9cblx0XHRpdGVtU3R5bGU6IHtcdFx0XHRcblx0XHRcdGNvbG9yOiAnIzMzMzMzMycsXG5cdFx0XHRmb250U2l6ZTogJzEycHgnLFxuXHRcdFx0Zm9udFdlaWdodDogJ2JvbGQnXG5cdFx0fSxcblx0XHRpdGVtSG92ZXJTdHlsZToge1xuXHRcdFx0Ly9jdXJzb3I6ICdwb2ludGVyJywgcmVtb3ZlZCBhcyBvZiAjNjAxXG5cdFx0XHRjb2xvcjogJyMwMDAnXG5cdFx0fSxcblx0XHRpdGVtSGlkZGVuU3R5bGU6IHtcblx0XHRcdGNvbG9yOiAnI0NDQydcblx0XHR9LFxuXHRcdGl0ZW1DaGVja2JveFN0eWxlOiB7XG5cdFx0XHRwb3NpdGlvbjogQUJTT0xVVEUsXG5cdFx0XHR3aWR0aDogJzEzcHgnLCAvLyBmb3IgSUUgcHJlY2lzaW9uXG5cdFx0XHRoZWlnaHQ6ICcxM3B4J1xuXHRcdH0sXG5cdFx0Ly8gaXRlbVdpZHRoOiB1bmRlZmluZWQsXG5cdFx0Ly8gc3ltYm9sUmFkaXVzOiAwLFxuXHRcdC8vIHN5bWJvbFdpZHRoOiAxNixcblx0XHRzeW1ib2xQYWRkaW5nOiA1LFxuXHRcdHZlcnRpY2FsQWxpZ246ICdib3R0b20nLFxuXHRcdC8vIHdpZHRoOiB1bmRlZmluZWQsXG5cdFx0eDogMCxcblx0XHR5OiAwLFxuXHRcdHRpdGxlOiB7XG5cdFx0XHQvL3RleHQ6IG51bGwsXG5cdFx0XHRzdHlsZToge1xuXHRcdFx0XHRmb250V2VpZ2h0OiAnYm9sZCdcblx0XHRcdH1cblx0XHR9XHRcdFx0XG5cdH0sXG5cblx0bG9hZGluZzoge1xuXHRcdC8vIGhpZGVEdXJhdGlvbjogMTAwLFxuXHRcdGxhYmVsU3R5bGU6IHtcblx0XHRcdGZvbnRXZWlnaHQ6ICdib2xkJyxcblx0XHRcdHBvc2l0aW9uOiBSRUxBVElWRSxcblx0XHRcdHRvcDogJzQ1JSdcblx0XHR9LFxuXHRcdC8vIHNob3dEdXJhdGlvbjogMCxcblx0XHRzdHlsZToge1xuXHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0YmFja2dyb3VuZENvbG9yOiAnd2hpdGUnLFxuXHRcdFx0b3BhY2l0eTogMC41LFxuXHRcdFx0dGV4dEFsaWduOiAnY2VudGVyJ1xuXHRcdH1cblx0fSxcblxuXHR0b29sdGlwOiB7XG5cdFx0ZW5hYmxlZDogdHJ1ZSxcblx0XHRhbmltYXRpb246IGhhc1NWRyxcblx0XHQvL2Nyb3NzaGFpcnM6IG51bGwsXG5cdFx0YmFja2dyb3VuZENvbG9yOiAncmdiYSgyNDksIDI0OSwgMjQ5LCAuODUpJyxcblx0XHRib3JkZXJXaWR0aDogMSxcblx0XHRib3JkZXJSYWRpdXM6IDMsXG5cdFx0ZGF0ZVRpbWVMYWJlbEZvcm1hdHM6IHsgXG5cdFx0XHRtaWxsaXNlY29uZDogJyVBLCAlYiAlZSwgJUg6JU06JVMuJUwnLFxuXHRcdFx0c2Vjb25kOiAnJUEsICViICVlLCAlSDolTTolUycsXG5cdFx0XHRtaW51dGU6ICclQSwgJWIgJWUsICVIOiVNJyxcblx0XHRcdGhvdXI6ICclQSwgJWIgJWUsICVIOiVNJyxcblx0XHRcdGRheTogJyVBLCAlYiAlZSwgJVknLFxuXHRcdFx0d2VlazogJ1dlZWsgZnJvbSAlQSwgJWIgJWUsICVZJyxcblx0XHRcdG1vbnRoOiAnJUIgJVknLFxuXHRcdFx0eWVhcjogJyVZJ1xuXHRcdH0sXG5cdFx0Ly9mb3JtYXR0ZXI6IGRlZmF1bHRGb3JtYXR0ZXIsXG5cdFx0aGVhZGVyRm9ybWF0OiAnPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEwcHhcIj57cG9pbnQua2V5fTwvc3Bhbj48YnIvPicsXG5cdFx0cG9pbnRGb3JtYXQ6ICc8c3BhbiBzdHlsZT1cImNvbG9yOntzZXJpZXMuY29sb3J9XCI+XFx1MjVDRjwvc3Bhbj4ge3Nlcmllcy5uYW1lfTogPGI+e3BvaW50Lnl9PC9iPjxici8+Jyxcblx0XHRzaGFkb3c6IHRydWUsXG5cdFx0Ly9zaGFwZTogJ2NhbGxvdXQnLFxuXHRcdC8vc2hhcmVkOiBmYWxzZSxcblx0XHRzbmFwOiBpc1RvdWNoRGV2aWNlID8gMjUgOiAxMCxcblx0XHRzdHlsZToge1xuXHRcdFx0Y29sb3I6ICcjMzMzMzMzJyxcblx0XHRcdGN1cnNvcjogJ2RlZmF1bHQnLFxuXHRcdFx0Zm9udFNpemU6ICcxMnB4Jyxcblx0XHRcdHBhZGRpbmc6ICc4cHgnLFxuXHRcdFx0d2hpdGVTcGFjZTogJ25vd3JhcCdcblx0XHR9XG5cdFx0Ly94RGF0ZUZvcm1hdDogJyVBLCAlYiAlZSwgJVknLFxuXHRcdC8vdmFsdWVEZWNpbWFsczogbnVsbCxcblx0XHQvL3ZhbHVlUHJlZml4OiAnJyxcblx0XHQvL3ZhbHVlU3VmZml4OiAnJ1xuXHR9LFxuXG5cdGNyZWRpdHM6IHtcblx0XHRlbmFibGVkOiB0cnVlLFxuXHRcdHRleHQ6ICdIaWdoY2hhcnRzLmNvbScsXG5cdFx0aHJlZjogJ2h0dHA6Ly93d3cuaGlnaGNoYXJ0cy5jb20nLFxuXHRcdHBvc2l0aW9uOiB7XG5cdFx0XHRhbGlnbjogJ3JpZ2h0Jyxcblx0XHRcdHg6IC0xMCxcblx0XHRcdHZlcnRpY2FsQWxpZ246ICdib3R0b20nLFxuXHRcdFx0eTogLTVcblx0XHR9LFxuXHRcdHN0eWxlOiB7XG5cdFx0XHRjdXJzb3I6ICdwb2ludGVyJyxcblx0XHRcdGNvbG9yOiAnIzkwOTA5MCcsXG5cdFx0XHRmb250U2l6ZTogJzlweCdcblx0XHR9XG5cdH1cbn07XG5cblxuXG5cbi8vIFNlcmllcyBkZWZhdWx0c1xudmFyIGRlZmF1bHRQbG90T3B0aW9ucyA9IGRlZmF1bHRPcHRpb25zLnBsb3RPcHRpb25zLFxuXHRkZWZhdWx0U2VyaWVzT3B0aW9ucyA9IGRlZmF1bHRQbG90T3B0aW9ucy5saW5lO1xuXG4vLyBzZXQgdGhlIGRlZmF1bHQgdGltZSBtZXRob2RzXG5zZXRUaW1lTWV0aG9kcygpO1xuXG5cblxuLyoqXG4gKiBTZXQgdGhlIHRpbWUgbWV0aG9kcyBnbG9iYWxseSBiYXNlZCBvbiB0aGUgdXNlVVRDIG9wdGlvbi4gVGltZSBtZXRob2QgY2FuIGJlIGVpdGhlclxuICogbG9jYWwgdGltZSBvciBVVEMgKGRlZmF1bHQpLlxuICovXG5mdW5jdGlvbiBzZXRUaW1lTWV0aG9kcygpIHtcblx0dmFyIHVzZVVUQyA9IGRlZmF1bHRPcHRpb25zLmdsb2JhbC51c2VVVEMsXG5cdFx0R0VUID0gdXNlVVRDID8gJ2dldFVUQycgOiAnZ2V0Jyxcblx0XHRTRVQgPSB1c2VVVEMgPyAnc2V0VVRDJyA6ICdzZXQnO1xuXG5cblx0RGF0ZSA9IGRlZmF1bHRPcHRpb25zLmdsb2JhbC5EYXRlIHx8IHdpbmRvdy5EYXRlO1xuXHR0aW1lem9uZU9mZnNldCA9ICgodXNlVVRDICYmIGRlZmF1bHRPcHRpb25zLmdsb2JhbC50aW1lem9uZU9mZnNldCkgfHwgMCkgKiA2MDAwMDtcblx0bWFrZVRpbWUgPSB1c2VVVEMgPyBEYXRlLlVUQyA6IGZ1bmN0aW9uICh5ZWFyLCBtb250aCwgZGF0ZSwgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMpIHtcblx0XHRyZXR1cm4gbmV3IERhdGUoXG5cdFx0XHR5ZWFyLFxuXHRcdFx0bW9udGgsXG5cdFx0XHRwaWNrKGRhdGUsIDEpLFxuXHRcdFx0cGljayhob3VycywgMCksXG5cdFx0XHRwaWNrKG1pbnV0ZXMsIDApLFxuXHRcdFx0cGljayhzZWNvbmRzLCAwKVxuXHRcdCkuZ2V0VGltZSgpO1xuXHR9O1xuXHRnZXRNaW51dGVzID0gIEdFVCArICdNaW51dGVzJztcblx0Z2V0SG91cnMgPSAgICBHRVQgKyAnSG91cnMnO1xuXHRnZXREYXkgPSAgICAgIEdFVCArICdEYXknO1xuXHRnZXREYXRlID0gICAgIEdFVCArICdEYXRlJztcblx0Z2V0TW9udGggPSAgICBHRVQgKyAnTW9udGgnO1xuXHRnZXRGdWxsWWVhciA9IEdFVCArICdGdWxsWWVhcic7XG5cdHNldE1pbnV0ZXMgPSAgU0VUICsgJ01pbnV0ZXMnO1xuXHRzZXRIb3VycyA9ICAgIFNFVCArICdIb3Vycyc7XG5cdHNldERhdGUgPSAgICAgU0VUICsgJ0RhdGUnO1xuXHRzZXRNb250aCA9ICAgIFNFVCArICdNb250aCc7XG5cdHNldEZ1bGxZZWFyID0gU0VUICsgJ0Z1bGxZZWFyJztcblxufVxuXG4vKipcbiAqIE1lcmdlIHRoZSBkZWZhdWx0IG9wdGlvbnMgd2l0aCBjdXN0b20gb3B0aW9ucyBhbmQgcmV0dXJuIHRoZSBuZXcgb3B0aW9ucyBzdHJ1Y3R1cmVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBuZXcgY3VzdG9tIG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gc2V0T3B0aW9ucyhvcHRpb25zKSB7XG5cdFxuXHQvLyBDb3B5IGluIHRoZSBkZWZhdWx0IG9wdGlvbnNcblx0ZGVmYXVsdE9wdGlvbnMgPSBtZXJnZSh0cnVlLCBkZWZhdWx0T3B0aW9ucywgb3B0aW9ucyk7XG5cdFxuXHQvLyBBcHBseSBVVENcblx0c2V0VGltZU1ldGhvZHMoKTtcblxuXHRyZXR1cm4gZGVmYXVsdE9wdGlvbnM7XG59XG5cbi8qKlxuICogR2V0IHRoZSB1cGRhdGVkIGRlZmF1bHQgb3B0aW9ucy4gVW50aWwgMy4wLjcsIG1lcmVseSBleHBvc2luZyBkZWZhdWx0T3B0aW9ucyBmb3Igb3V0c2lkZSBtb2R1bGVzXG4gKiB3YXNuJ3QgZW5vdWdoIGJlY2F1c2UgdGhlIHNldE9wdGlvbnMgbWV0aG9kIGNyZWF0ZWQgYSBuZXcgb2JqZWN0LlxuICovXG5mdW5jdGlvbiBnZXRPcHRpb25zKCkge1xuXHRyZXR1cm4gZGVmYXVsdE9wdGlvbnM7XG59XG5cblxuLyoqXG4gKiBIYW5kbGUgY29sb3Igb3BlcmF0aW9ucy4gVGhlIG9iamVjdCBtZXRob2RzIGFyZSBjaGFpbmFibGUuXG4gKiBAcGFyYW0ge1N0cmluZ30gaW5wdXQgVGhlIGlucHV0IGNvbG9yIGluIGVpdGhlciByYmdhIG9yIGhleCBmb3JtYXRcbiAqL1xudmFyIHJnYmFSZWdFeCA9IC9yZ2JhXFwoXFxzKihbMC05XXsxLDN9KVxccyosXFxzKihbMC05XXsxLDN9KVxccyosXFxzKihbMC05XXsxLDN9KVxccyosXFxzKihbMC05XT8oPzpcXC5bMC05XSspPylcXHMqXFwpLyxcblx0aGV4UmVnRXggPSAvIyhbYS1mQS1GMC05XXsyfSkoW2EtZkEtRjAtOV17Mn0pKFthLWZBLUYwLTldezJ9KS8sXG5cdHJnYlJlZ0V4ID0gL3JnYlxcKFxccyooWzAtOV17MSwzfSlcXHMqLFxccyooWzAtOV17MSwzfSlcXHMqLFxccyooWzAtOV17MSwzfSlcXHMqXFwpLztcblxudmFyIENvbG9yID0gZnVuY3Rpb24gKGlucHV0KSB7XG5cdC8vIGRlY2xhcmUgdmFyaWFibGVzXG5cdHZhciByZ2JhID0gW10sIHJlc3VsdCwgc3RvcHM7XG5cblx0LyoqXG5cdCAqIFBhcnNlIHRoZSBpbnB1dCBjb2xvciB0byByZ2JhIGFycmF5XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dFxuXHQgKi9cblx0ZnVuY3Rpb24gaW5pdChpbnB1dCkge1xuXG5cdFx0Ly8gR3JhZGllbnRzXG5cdFx0aWYgKGlucHV0ICYmIGlucHV0LnN0b3BzKSB7XG5cdFx0XHRzdG9wcyA9IG1hcChpbnB1dC5zdG9wcywgZnVuY3Rpb24gKHN0b3ApIHtcblx0XHRcdFx0cmV0dXJuIENvbG9yKHN0b3BbMV0pO1xuXHRcdFx0fSk7XG5cblx0XHQvLyBTb2xpZCBjb2xvcnNcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gcmdiYVxuXHRcdFx0cmVzdWx0ID0gcmdiYVJlZ0V4LmV4ZWMoaW5wdXQpO1xuXHRcdFx0aWYgKHJlc3VsdCkge1xuXHRcdFx0XHRyZ2JhID0gW3BJbnQocmVzdWx0WzFdKSwgcEludChyZXN1bHRbMl0pLCBwSW50KHJlc3VsdFszXSksIHBhcnNlRmxvYXQocmVzdWx0WzRdLCAxMCldO1xuXHRcdFx0fSBlbHNlIHsgXG5cdFx0XHRcdC8vIGhleFxuXHRcdFx0XHRyZXN1bHQgPSBoZXhSZWdFeC5leGVjKGlucHV0KTtcblx0XHRcdFx0aWYgKHJlc3VsdCkge1xuXHRcdFx0XHRcdHJnYmEgPSBbcEludChyZXN1bHRbMV0sIDE2KSwgcEludChyZXN1bHRbMl0sIDE2KSwgcEludChyZXN1bHRbM10sIDE2KSwgMV07XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gcmdiXG5cdFx0XHRcdFx0cmVzdWx0ID0gcmdiUmVnRXguZXhlYyhpbnB1dCk7XG5cdFx0XHRcdFx0aWYgKHJlc3VsdCkge1xuXHRcdFx0XHRcdFx0cmdiYSA9IFtwSW50KHJlc3VsdFsxXSksIHBJbnQocmVzdWx0WzJdKSwgcEludChyZXN1bHRbM10pLCAxXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XHRcdFxuXG5cdH1cblx0LyoqXG5cdCAqIFJldHVybiB0aGUgY29sb3IgYSBzcGVjaWZpZWQgZm9ybWF0XG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBmb3JtYXRcblx0ICovXG5cdGZ1bmN0aW9uIGdldChmb3JtYXQpIHtcblx0XHR2YXIgcmV0O1xuXG5cdFx0aWYgKHN0b3BzKSB7XG5cdFx0XHRyZXQgPSBtZXJnZShpbnB1dCk7XG5cdFx0XHRyZXQuc3RvcHMgPSBbXS5jb25jYXQocmV0LnN0b3BzKTtcblx0XHRcdGVhY2goc3RvcHMsIGZ1bmN0aW9uIChzdG9wLCBpKSB7XG5cdFx0XHRcdHJldC5zdG9wc1tpXSA9IFtyZXQuc3RvcHNbaV1bMF0sIHN0b3AuZ2V0KGZvcm1hdCldO1xuXHRcdFx0fSk7XG5cblx0XHQvLyBpdCdzIE5hTiBpZiBncmFkaWVudCBjb2xvcnMgb24gYSBjb2x1bW4gY2hhcnRcblx0XHR9IGVsc2UgaWYgKHJnYmEgJiYgIWlzTmFOKHJnYmFbMF0pKSB7XG5cdFx0XHRpZiAoZm9ybWF0ID09PSAncmdiJykge1xuXHRcdFx0XHRyZXQgPSAncmdiKCcgKyByZ2JhWzBdICsgJywnICsgcmdiYVsxXSArICcsJyArIHJnYmFbMl0gKyAnKSc7XG5cdFx0XHR9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2EnKSB7XG5cdFx0XHRcdHJldCA9IHJnYmFbM107XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXQgPSAncmdiYSgnICsgcmdiYS5qb2luKCcsJykgKyAnKSc7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldCA9IGlucHV0O1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9XG5cblx0LyoqXG5cdCAqIEJyaWdodGVuIHRoZSBjb2xvclxuXHQgKiBAcGFyYW0ge051bWJlcn0gYWxwaGFcblx0ICovXG5cdGZ1bmN0aW9uIGJyaWdodGVuKGFscGhhKSB7XG5cdFx0aWYgKHN0b3BzKSB7XG5cdFx0XHRlYWNoKHN0b3BzLCBmdW5jdGlvbiAoc3RvcCkge1xuXHRcdFx0XHRzdG9wLmJyaWdodGVuKGFscGhhKTtcblx0XHRcdH0pO1xuXHRcdFxuXHRcdH0gZWxzZSBpZiAoaXNOdW1iZXIoYWxwaGEpICYmIGFscGhhICE9PSAwKSB7XG5cdFx0XHR2YXIgaTtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHtcblx0XHRcdFx0cmdiYVtpXSArPSBwSW50KGFscGhhICogMjU1KTtcblxuXHRcdFx0XHRpZiAocmdiYVtpXSA8IDApIHtcblx0XHRcdFx0XHRyZ2JhW2ldID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAocmdiYVtpXSA+IDI1NSkge1xuXHRcdFx0XHRcdHJnYmFbaV0gPSAyNTU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblx0LyoqXG5cdCAqIFNldCB0aGUgY29sb3IncyBvcGFjaXR5IHRvIGEgZ2l2ZW4gYWxwaGEgdmFsdWVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGFscGhhXG5cdCAqL1xuXHRmdW5jdGlvbiBzZXRPcGFjaXR5KGFscGhhKSB7XG5cdFx0cmdiYVszXSA9IGFscGhhO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0Ly8gaW5pdGlhbGl6ZTogcGFyc2UgdGhlIGlucHV0XG5cdGluaXQoaW5wdXQpO1xuXG5cdC8vIHB1YmxpYyBtZXRob2RzXG5cdHJldHVybiB7XG5cdFx0Z2V0OiBnZXQsXG5cdFx0YnJpZ2h0ZW46IGJyaWdodGVuLFxuXHRcdHJnYmE6IHJnYmEsXG5cdFx0c2V0T3BhY2l0eTogc2V0T3BhY2l0eVxuXHR9O1xufTtcblxuXG4vKipcbiAqIEEgd3JhcHBlciBvYmplY3QgZm9yIFNWRyBlbGVtZW50c1xuICovXG5mdW5jdGlvbiBTVkdFbGVtZW50KCkge31cblxuU1ZHRWxlbWVudC5wcm90b3R5cGUgPSB7XG5cdFxuXHQvLyBEZWZhdWx0IGJhc2UgZm9yIGFuaW1hdGlvblxuXHRvcGFjaXR5OiAxLFxuXHQvLyBGb3IgbGFiZWxzLCB0aGVzZSBDU1MgcHJvcGVydGllcyBhcmUgYXBwbGllZCB0byB0aGUgPHRleHQ+IG5vZGUgZGlyZWN0bHlcblx0dGV4dFByb3BzOiBbJ2ZvbnRTaXplJywgJ2ZvbnRXZWlnaHQnLCAnZm9udEZhbWlseScsICdjb2xvcicsIFxuXHRcdCdsaW5lSGVpZ2h0JywgJ3dpZHRoJywgJ3RleHREZWNvcmF0aW9uJywgJ3RleHRTaGFkb3cnLCAnSGNUZXh0U3Ryb2tlJ10sXG5cdFxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgU1ZHIHJlbmRlcmVyXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSByZW5kZXJlclxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbm9kZU5hbWVcblx0ICovXG5cdGluaXQ6IGZ1bmN0aW9uIChyZW5kZXJlciwgbm9kZU5hbWUpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXM7XG5cdFx0d3JhcHBlci5lbGVtZW50ID0gbm9kZU5hbWUgPT09ICdzcGFuJyA/XG5cdFx0XHRjcmVhdGVFbGVtZW50KG5vZGVOYW1lKSA6XG5cdFx0XHRkb2MuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgbm9kZU5hbWUpO1xuXHRcdHdyYXBwZXIucmVuZGVyZXIgPSByZW5kZXJlcjtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBBbmltYXRlIGEgZ2l2ZW4gYXR0cmlidXRlXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXNcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG9wdGlvbnMgVGhlIHNhbWUgb3B0aW9ucyBhcyBpbiBqUXVlcnkgYW5pbWF0aW9uXG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbXBsZXRlIEZ1bmN0aW9uIHRvIHBlcmZvcm0gYXQgdGhlIGVuZCBvZiBhbmltYXRpb25cblx0ICovXG5cdGFuaW1hdGU6IGZ1bmN0aW9uIChwYXJhbXMsIG9wdGlvbnMsIGNvbXBsZXRlKSB7XG5cdFx0dmFyIGFuaW1PcHRpb25zID0gcGljayhvcHRpb25zLCBnbG9iYWxBbmltYXRpb24sIHRydWUpO1xuXHRcdHN0b3AodGhpcyk7IC8vIHN0b3AgcmVnYXJkbGVzcyBvZiBhbmltYXRpb24gYWN0dWFsbHkgcnVubmluZywgb3IgcmV2ZXJ0aW5nIHRvIC5hdHRyICgjNjA3KVxuXHRcdGlmIChhbmltT3B0aW9ucykge1xuXHRcdFx0YW5pbU9wdGlvbnMgPSBtZXJnZShhbmltT3B0aW9ucywge30pOyAvLyMyNjI1XG5cdFx0XHRpZiAoY29tcGxldGUpIHsgLy8gYWxsb3dzIHVzaW5nIGEgY2FsbGJhY2sgd2l0aCB0aGUgZ2xvYmFsIGFuaW1hdGlvbiB3aXRob3V0IG92ZXJ3cml0aW5nIGl0XG5cdFx0XHRcdGFuaW1PcHRpb25zLmNvbXBsZXRlID0gY29tcGxldGU7XG5cdFx0XHR9XG5cdFx0XHRhbmltYXRlKHRoaXMsIHBhcmFtcywgYW5pbU9wdGlvbnMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmF0dHIocGFyYW1zKTtcblx0XHRcdGlmIChjb21wbGV0ZSkge1xuXHRcdFx0XHRjb21wbGV0ZSgpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogQnVpbGQgYW4gU1ZHIGdyYWRpZW50IG91dCBvZiBhIGNvbW1vbiBKYXZhU2NyaXB0IGNvbmZpZ3VyYXRpb24gb2JqZWN0XG5cdCAqL1xuXHRjb2xvckdyYWRpZW50OiBmdW5jdGlvbiAoY29sb3IsIHByb3AsIGVsZW0pIHtcblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLnJlbmRlcmVyLFxuXHRcdFx0Y29sb3JPYmplY3QsXG5cdFx0XHRncmFkTmFtZSxcblx0XHRcdGdyYWRBdHRyLFxuXHRcdFx0Z3JhZGllbnRzLFxuXHRcdFx0Z3JhZGllbnRPYmplY3QsXG5cdFx0XHRzdG9wcyxcblx0XHRcdHN0b3BDb2xvcixcblx0XHRcdHN0b3BPcGFjaXR5LFxuXHRcdFx0cmFkaWFsUmVmZXJlbmNlLFxuXHRcdFx0bixcblx0XHRcdGlkLFxuXHRcdFx0a2V5ID0gW107XG5cblx0XHQvLyBBcHBseSBsaW5lYXIgb3IgcmFkaWFsIGdyYWRpZW50c1xuXHRcdGlmIChjb2xvci5saW5lYXJHcmFkaWVudCkge1xuXHRcdFx0Z3JhZE5hbWUgPSAnbGluZWFyR3JhZGllbnQnO1xuXHRcdH0gZWxzZSBpZiAoY29sb3IucmFkaWFsR3JhZGllbnQpIHtcblx0XHRcdGdyYWROYW1lID0gJ3JhZGlhbEdyYWRpZW50Jztcblx0XHR9XG5cblx0XHRpZiAoZ3JhZE5hbWUpIHtcblx0XHRcdGdyYWRBdHRyID0gY29sb3JbZ3JhZE5hbWVdO1xuXHRcdFx0Z3JhZGllbnRzID0gcmVuZGVyZXIuZ3JhZGllbnRzO1xuXHRcdFx0c3RvcHMgPSBjb2xvci5zdG9wcztcblx0XHRcdHJhZGlhbFJlZmVyZW5jZSA9IGVsZW0ucmFkaWFsUmVmZXJlbmNlO1xuXG5cdFx0XHQvLyBLZWVwIDwgMi4yIGtvbXBhdGliaWxpdHlcblx0XHRcdGlmIChpc0FycmF5KGdyYWRBdHRyKSkge1xuXHRcdFx0XHRjb2xvcltncmFkTmFtZV0gPSBncmFkQXR0ciA9IHtcblx0XHRcdFx0XHR4MTogZ3JhZEF0dHJbMF0sXG5cdFx0XHRcdFx0eTE6IGdyYWRBdHRyWzFdLFxuXHRcdFx0XHRcdHgyOiBncmFkQXR0clsyXSxcblx0XHRcdFx0XHR5MjogZ3JhZEF0dHJbM10sXG5cdFx0XHRcdFx0Z3JhZGllbnRVbml0czogJ3VzZXJTcGFjZU9uVXNlJ1xuXHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb3JyZWN0IHRoZSByYWRpYWwgZ3JhZGllbnQgZm9yIHRoZSByYWRpYWwgcmVmZXJlbmNlIHN5c3RlbVxuXHRcdFx0aWYgKGdyYWROYW1lID09PSAncmFkaWFsR3JhZGllbnQnICYmIHJhZGlhbFJlZmVyZW5jZSAmJiAhZGVmaW5lZChncmFkQXR0ci5ncmFkaWVudFVuaXRzKSkge1xuXHRcdFx0XHRncmFkQXR0ciA9IG1lcmdlKGdyYWRBdHRyLCB7XG5cdFx0XHRcdFx0Y3g6IChyYWRpYWxSZWZlcmVuY2VbMF0gLSByYWRpYWxSZWZlcmVuY2VbMl0gLyAyKSArIGdyYWRBdHRyLmN4ICogcmFkaWFsUmVmZXJlbmNlWzJdLFxuXHRcdFx0XHRcdGN5OiAocmFkaWFsUmVmZXJlbmNlWzFdIC0gcmFkaWFsUmVmZXJlbmNlWzJdIC8gMikgKyBncmFkQXR0ci5jeSAqIHJhZGlhbFJlZmVyZW5jZVsyXSxcblx0XHRcdFx0XHRyOiBncmFkQXR0ci5yICogcmFkaWFsUmVmZXJlbmNlWzJdLFxuXHRcdFx0XHRcdGdyYWRpZW50VW5pdHM6ICd1c2VyU3BhY2VPblVzZSdcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEJ1aWxkIHRoZSB1bmlxdWUga2V5IHRvIGRldGVjdCB3aGV0aGVyIHdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGVsZW1lbnQgKCMxMjgyKVxuXHRcdFx0Zm9yIChuIGluIGdyYWRBdHRyKSB7XG5cdFx0XHRcdGlmIChuICE9PSAnaWQnKSB7XG5cdFx0XHRcdFx0a2V5LnB1c2gobiwgZ3JhZEF0dHJbbl0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRmb3IgKG4gaW4gc3RvcHMpIHtcblx0XHRcdFx0a2V5LnB1c2goc3RvcHNbbl0pO1xuXHRcdFx0fVxuXHRcdFx0a2V5ID0ga2V5LmpvaW4oJywnKTtcblxuXHRcdFx0Ly8gQ2hlY2sgaWYgYSBncmFkaWVudCBvYmplY3Qgd2l0aCB0aGUgc2FtZSBjb25maWcgb2JqZWN0IGlzIGNyZWF0ZWQgd2l0aGluIHRoaXMgcmVuZGVyZXJcblx0XHRcdGlmIChncmFkaWVudHNba2V5XSkge1xuXHRcdFx0XHRpZCA9IGdyYWRpZW50c1trZXldLmF0dHIoJ2lkJyk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBpZCBhbmQgY3JlYXRlIHRoZSBlbGVtZW50XG5cdFx0XHRcdGdyYWRBdHRyLmlkID0gaWQgPSBQUkVGSVggKyBpZENvdW50ZXIrKztcblx0XHRcdFx0Z3JhZGllbnRzW2tleV0gPSBncmFkaWVudE9iamVjdCA9IHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoZ3JhZE5hbWUpXG5cdFx0XHRcdFx0LmF0dHIoZ3JhZEF0dHIpXG5cdFx0XHRcdFx0LmFkZChyZW5kZXJlci5kZWZzKTtcblxuXG5cdFx0XHRcdC8vIFRoZSBncmFkaWVudCBuZWVkcyB0byBrZWVwIGEgbGlzdCBvZiBzdG9wcyB0byBiZSBhYmxlIHRvIGRlc3Ryb3kgdGhlbVxuXHRcdFx0XHRncmFkaWVudE9iamVjdC5zdG9wcyA9IFtdO1xuXHRcdFx0XHRlYWNoKHN0b3BzLCBmdW5jdGlvbiAoc3RvcCkge1xuXHRcdFx0XHRcdHZhciBzdG9wT2JqZWN0O1xuXHRcdFx0XHRcdGlmIChzdG9wWzFdLmluZGV4T2YoJ3JnYmEnKSA9PT0gMCkge1xuXHRcdFx0XHRcdFx0Y29sb3JPYmplY3QgPSBDb2xvcihzdG9wWzFdKTtcblx0XHRcdFx0XHRcdHN0b3BDb2xvciA9IGNvbG9yT2JqZWN0LmdldCgncmdiJyk7XG5cdFx0XHRcdFx0XHRzdG9wT3BhY2l0eSA9IGNvbG9yT2JqZWN0LmdldCgnYScpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzdG9wQ29sb3IgPSBzdG9wWzFdO1xuXHRcdFx0XHRcdFx0c3RvcE9wYWNpdHkgPSAxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRzdG9wT2JqZWN0ID0gcmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnc3RvcCcpLmF0dHIoe1xuXHRcdFx0XHRcdFx0b2Zmc2V0OiBzdG9wWzBdLFxuXHRcdFx0XHRcdFx0J3N0b3AtY29sb3InOiBzdG9wQ29sb3IsXG5cdFx0XHRcdFx0XHQnc3RvcC1vcGFjaXR5Jzogc3RvcE9wYWNpdHlcblx0XHRcdFx0XHR9KS5hZGQoZ3JhZGllbnRPYmplY3QpO1xuXG5cdFx0XHRcdFx0Ly8gQWRkIHRoZSBzdG9wIGVsZW1lbnQgdG8gdGhlIGdyYWRpZW50XG5cdFx0XHRcdFx0Z3JhZGllbnRPYmplY3Quc3RvcHMucHVzaChzdG9wT2JqZWN0KTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgcmVmZXJlbmNlIHRvIHRoZSBncmFkaWVudCBvYmplY3Rcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKHByb3AsICd1cmwoJyArIHJlbmRlcmVyLnVybCArICcjJyArIGlkICsgJyknKTtcblx0XHR9IFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgb3IgZ2V0IGEgZ2l2ZW4gYXR0cmlidXRlXG5cdCAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gaGFzaFxuXHQgKiBAcGFyYW0ge01peGVkfFVuZGVmaW5lZH0gdmFsXG5cdCAqL1xuXHRhdHRyOiBmdW5jdGlvbiAoaGFzaCwgdmFsKSB7XG5cdFx0dmFyIGtleSxcblx0XHRcdHZhbHVlLFxuXHRcdFx0ZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcblx0XHRcdGhhc1NldFN5bWJvbFNpemUsXG5cdFx0XHRyZXQgPSB0aGlzLFxuXHRcdFx0c2tpcEF0dHI7XG5cblx0XHQvLyBzaW5nbGUga2V5LXZhbHVlIHBhaXJcblx0XHRpZiAodHlwZW9mIGhhc2ggPT09ICdzdHJpbmcnICYmIHZhbCAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRrZXkgPSBoYXNoO1xuXHRcdFx0aGFzaCA9IHt9O1xuXHRcdFx0aGFzaFtrZXldID0gdmFsO1xuXHRcdH1cblxuXHRcdC8vIHVzZWQgYXMgYSBnZXR0ZXI6IGZpcnN0IGFyZ3VtZW50IGlzIGEgc3RyaW5nLCBzZWNvbmQgaXMgdW5kZWZpbmVkXG5cdFx0aWYgKHR5cGVvZiBoYXNoID09PSAnc3RyaW5nJykge1xuXHRcdFx0cmV0ID0gKHRoaXNbaGFzaCArICdHZXR0ZXInXSB8fCB0aGlzLl9kZWZhdWx0R2V0dGVyKS5jYWxsKHRoaXMsIGhhc2gsIGVsZW1lbnQpO1xuXHRcdFxuXHRcdC8vIHNldHRlclxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGZvciAoa2V5IGluIGhhc2gpIHtcblx0XHRcdFx0dmFsdWUgPSBoYXNoW2tleV07XG5cdFx0XHRcdHNraXBBdHRyID0gZmFsc2U7XG5cblxuXG5cdFx0XHRcdGlmICh0aGlzLnN5bWJvbE5hbWUgJiYgL14oeHx5fHdpZHRofGhlaWdodHxyfHN0YXJ0fGVuZHxpbm5lclJ8YW5jaG9yWHxhbmNob3JZKS8udGVzdChrZXkpKSB7XG5cdFx0XHRcdFx0aWYgKCFoYXNTZXRTeW1ib2xTaXplKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnN5bWJvbEF0dHIoaGFzaCk7XG5cdFx0XHRcdFx0XHRoYXNTZXRTeW1ib2xTaXplID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0c2tpcEF0dHIgPSB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKHRoaXMucm90YXRpb24gJiYgKGtleSA9PT0gJ3gnIHx8IGtleSA9PT0gJ3knKSkge1xuXHRcdFx0XHRcdHRoaXMuZG9UcmFuc2Zvcm0gPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRpZiAoIXNraXBBdHRyKSB7XG5cdFx0XHRcdFx0KHRoaXNba2V5ICsgJ1NldHRlciddIHx8IHRoaXMuX2RlZmF1bHRTZXR0ZXIpLmNhbGwodGhpcywgdmFsdWUsIGtleSwgZWxlbWVudCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBMZXQgdGhlIHNoYWRvdyBmb2xsb3cgdGhlIG1haW4gZWxlbWVudFxuXHRcdFx0XHRpZiAodGhpcy5zaGFkb3dzICYmIC9eKHdpZHRofGhlaWdodHx2aXNpYmlsaXR5fHh8eXxkfHRyYW5zZm9ybXxjeHxjeXxyKSQvLnRlc3Qoa2V5KSkge1xuXHRcdFx0XHRcdHRoaXMudXBkYXRlU2hhZG93cyhrZXksIHZhbHVlKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBVcGRhdGUgdHJhbnNmb3JtLiBEbyB0aGlzIG91dHNpZGUgdGhlIGxvb3AgdG8gcHJldmVudCByZWR1bmRhbnQgdXBkYXRpbmcgZm9yIGJhdGNoIHNldHRpbmdcblx0XHRcdC8vIG9mIGF0dHJpYnV0ZXMuXG5cdFx0XHRpZiAodGhpcy5kb1RyYW5zZm9ybSkge1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVRyYW5zZm9ybSgpO1xuXHRcdFx0XHR0aGlzLmRvVHJhbnNmb3JtID0gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdHVwZGF0ZVNoYWRvd3M6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdFx0dmFyIHNoYWRvd3MgPSB0aGlzLnNoYWRvd3MsXG5cdFx0XHRpID0gc2hhZG93cy5sZW5ndGg7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0c2hhZG93c1tpXS5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcdGtleSxcblx0XHRcdFx0a2V5ID09PSAnaGVpZ2h0JyA/XG5cdFx0XHRcdFx0bWF0aE1heCh2YWx1ZSAtIChzaGFkb3dzW2ldLmN1dEhlaWdodCB8fCAwKSwgMCkgOlxuXHRcdFx0XHRcdGtleSA9PT0gJ2QnID8gdGhpcy5kIDogdmFsdWVcblx0XHRcdCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgYSBjbGFzcyBuYW1lIHRvIGFuIGVsZW1lbnRcblx0ICovXG5cdGFkZENsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG5cdFx0dmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQsXG5cdFx0XHRjdXJyZW50Q2xhc3NOYW1lID0gYXR0cihlbGVtZW50LCAnY2xhc3MnKSB8fCAnJztcblxuXHRcdGlmIChjdXJyZW50Q2xhc3NOYW1lLmluZGV4T2YoY2xhc3NOYW1lKSA9PT0gLTEpIHtcblx0XHRcdGF0dHIoZWxlbWVudCwgJ2NsYXNzJywgY3VycmVudENsYXNzTmFtZSArICcgJyArIGNsYXNzTmFtZSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXHQvKiBoYXNDbGFzcyBhbmQgcmVtb3ZlQ2xhc3MgYXJlIG5vdCAoeWV0KSBuZWVkZWRcblx0aGFzQ2xhc3M6IGZ1bmN0aW9uIChjbGFzc05hbWUpIHtcblx0XHRyZXR1cm4gYXR0cih0aGlzLmVsZW1lbnQsICdjbGFzcycpLmluZGV4T2YoY2xhc3NOYW1lKSAhPT0gLTE7XG5cdH0sXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XG5cdFx0YXR0cih0aGlzLmVsZW1lbnQsICdjbGFzcycsIGF0dHIodGhpcy5lbGVtZW50LCAnY2xhc3MnKS5yZXBsYWNlKGNsYXNzTmFtZSwgJycpKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblx0Ki9cblxuXHQvKipcblx0ICogSWYgb25lIG9mIHRoZSBzeW1ib2wgc2l6ZSBhZmZlY3RpbmcgcGFyYW1ldGVycyBhcmUgY2hhbmdlZCxcblx0ICogY2hlY2sgYWxsIHRoZSBvdGhlcnMgb25seSBvbmNlIGZvciBlYWNoIGNhbGwgdG8gYW4gZWxlbWVudCdzXG5cdCAqIC5hdHRyKCkgbWV0aG9kXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBoYXNoXG5cdCAqL1xuXHRzeW1ib2xBdHRyOiBmdW5jdGlvbiAoaGFzaCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcztcblxuXHRcdGVhY2goWyd4JywgJ3knLCAncicsICdzdGFydCcsICdlbmQnLCAnd2lkdGgnLCAnaGVpZ2h0JywgJ2lubmVyUicsICdhbmNob3JYJywgJ2FuY2hvclknXSwgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0d3JhcHBlcltrZXldID0gcGljayhoYXNoW2tleV0sIHdyYXBwZXJba2V5XSk7XG5cdFx0fSk7XG5cblx0XHR3cmFwcGVyLmF0dHIoe1xuXHRcdFx0ZDogd3JhcHBlci5yZW5kZXJlci5zeW1ib2xzW3dyYXBwZXIuc3ltYm9sTmFtZV0oXG5cdFx0XHRcdHdyYXBwZXIueCxcblx0XHRcdFx0d3JhcHBlci55LFxuXHRcdFx0XHR3cmFwcGVyLndpZHRoLFxuXHRcdFx0XHR3cmFwcGVyLmhlaWdodCxcblx0XHRcdFx0d3JhcHBlclxuXHRcdFx0KVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBcHBseSBhIGNsaXBwaW5nIHBhdGggdG8gdGhpcyBvYmplY3Rcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlkXG5cdCAqL1xuXHRjbGlwOiBmdW5jdGlvbiAoY2xpcFJlY3QpIHtcblx0XHRyZXR1cm4gdGhpcy5hdHRyKCdjbGlwLXBhdGgnLCBjbGlwUmVjdCA/ICd1cmwoJyArIHRoaXMucmVuZGVyZXIudXJsICsgJyMnICsgY2xpcFJlY3QuaWQgKyAnKScgOiBOT05FKTtcblx0fSxcblxuXHQvKipcblx0ICogQ2FsY3VsYXRlIHRoZSBjb29yZGluYXRlcyBuZWVkZWQgZm9yIGRyYXdpbmcgYSByZWN0YW5nbGUgY3Jpc3BseSBhbmQgcmV0dXJuIHRoZVxuXHQgKiBjYWxjdWxhdGVkIGF0dHJpYnV0ZXNcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHN0cm9rZVdpZHRoXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqL1xuXHRjcmlzcDogZnVuY3Rpb24gKHJlY3QpIHtcblxuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdGtleSxcblx0XHRcdGF0dHJpYnMgPSB7fSxcblx0XHRcdG5vcm1hbGl6ZXIsXG5cdFx0XHRzdHJva2VXaWR0aCA9IHJlY3Quc3Ryb2tlV2lkdGggfHwgd3JhcHBlci5zdHJva2VXaWR0aCB8fCAwO1xuXG5cdFx0bm9ybWFsaXplciA9IG1hdGhSb3VuZChzdHJva2VXaWR0aCkgJSAyIC8gMjsgLy8gbWF0aFJvdW5kIGJlY2F1c2Ugc3Ryb2tlV2lkdGggY2FuIHNvbWV0aW1lcyBoYXZlIHJvdW5kb2ZmIGVycm9yc1xuXG5cdFx0Ly8gbm9ybWFsaXplIGZvciBjcmlzcCBlZGdlc1xuXHRcdHJlY3QueCA9IG1hdGhGbG9vcihyZWN0LnggfHwgd3JhcHBlci54IHx8IDApICsgbm9ybWFsaXplcjtcblx0XHRyZWN0LnkgPSBtYXRoRmxvb3IocmVjdC55IHx8IHdyYXBwZXIueSB8fCAwKSArIG5vcm1hbGl6ZXI7XG5cdFx0cmVjdC53aWR0aCA9IG1hdGhGbG9vcigocmVjdC53aWR0aCB8fCB3cmFwcGVyLndpZHRoIHx8IDApIC0gMiAqIG5vcm1hbGl6ZXIpO1xuXHRcdHJlY3QuaGVpZ2h0ID0gbWF0aEZsb29yKChyZWN0LmhlaWdodCB8fCB3cmFwcGVyLmhlaWdodCB8fCAwKSAtIDIgKiBub3JtYWxpemVyKTtcblx0XHRyZWN0LnN0cm9rZVdpZHRoID0gc3Ryb2tlV2lkdGg7XG5cblx0XHRmb3IgKGtleSBpbiByZWN0KSB7XG5cdFx0XHRpZiAod3JhcHBlcltrZXldICE9PSByZWN0W2tleV0pIHsgLy8gb25seSBzZXQgYXR0cmlidXRlIGlmIGNoYW5nZWRcblx0XHRcdFx0d3JhcHBlcltrZXldID0gYXR0cmlic1trZXldID0gcmVjdFtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBhdHRyaWJzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgc3R5bGVzIGZvciB0aGUgZWxlbWVudFxuXHQgKiBAcGFyYW0ge09iamVjdH0gc3R5bGVzXG5cdCAqL1xuXHRjc3M6IGZ1bmN0aW9uIChzdHlsZXMpIHtcblx0XHR2YXIgZWxlbVdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0b2xkU3R5bGVzID0gZWxlbVdyYXBwZXIuc3R5bGVzLFxuXHRcdFx0bmV3U3R5bGVzID0ge30sXG5cdFx0XHRlbGVtID0gZWxlbVdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHRleHRXaWR0aCxcblx0XHRcdG4sXG5cdFx0XHRzZXJpYWxpemVkQ3NzID0gJycsXG5cdFx0XHRoeXBoZW5hdGUsXG5cdFx0XHRoYXNOZXcgPSAhb2xkU3R5bGVzO1xuXG5cdFx0Ly8gY29udmVydCBsZWdhY3lcblx0XHRpZiAoc3R5bGVzICYmIHN0eWxlcy5jb2xvcikge1xuXHRcdFx0c3R5bGVzLmZpbGwgPSBzdHlsZXMuY29sb3I7XG5cdFx0fVxuXG5cdFx0Ly8gRmlsdGVyIG91dCBleGlzdGluZyBzdHlsZXMgdG8gaW5jcmVhc2UgcGVyZm9ybWFuY2UgKCMyNjQwKVxuXHRcdGlmIChvbGRTdHlsZXMpIHtcblx0XHRcdGZvciAobiBpbiBzdHlsZXMpIHtcblx0XHRcdFx0aWYgKHN0eWxlc1tuXSAhPT0gb2xkU3R5bGVzW25dKSB7XG5cdFx0XHRcdFx0bmV3U3R5bGVzW25dID0gc3R5bGVzW25dO1xuXHRcdFx0XHRcdGhhc05ldyA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKGhhc05ldykge1xuXHRcdFx0dGV4dFdpZHRoID0gZWxlbVdyYXBwZXIudGV4dFdpZHRoID0gc3R5bGVzICYmIHN0eWxlcy53aWR0aCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICd0ZXh0JyAmJiBwSW50KHN0eWxlcy53aWR0aCk7XG5cblx0XHRcdC8vIE1lcmdlIHRoZSBuZXcgc3R5bGVzIHdpdGggdGhlIG9sZCBvbmVzXG5cdFx0XHRpZiAob2xkU3R5bGVzKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGV4dGVuZChcblx0XHRcdFx0XHRvbGRTdHlsZXMsXG5cdFx0XHRcdFx0bmV3U3R5bGVzXG5cdFx0XHRcdCk7XG5cdFx0XHR9XHRcdFxuXG5cdFx0XHQvLyBzdG9yZSBvYmplY3Rcblx0XHRcdGVsZW1XcmFwcGVyLnN0eWxlcyA9IHN0eWxlcztcblxuXHRcdFx0aWYgKHRleHRXaWR0aCAmJiAodXNlQ2FuVkcgfHwgKCFoYXNTVkcgJiYgZWxlbVdyYXBwZXIucmVuZGVyZXIuZm9yRXhwb3J0KSkpIHtcblx0XHRcdFx0ZGVsZXRlIHN0eWxlcy53aWR0aDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gc2VyaWFsaXplIGFuZCBzZXQgc3R5bGUgYXR0cmlidXRlXG5cdFx0XHRpZiAoaXNJRSAmJiAhaGFzU1ZHKSB7XG5cdFx0XHRcdGNzcyhlbGVtV3JhcHBlci5lbGVtZW50LCBzdHlsZXMpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Lypqc2xpbnQgdW5wYXJhbTogdHJ1ZSovXG5cdFx0XHRcdGh5cGhlbmF0ZSA9IGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiAnLScgKyBiLnRvTG93ZXJDYXNlKCk7IH07XG5cdFx0XHRcdC8qanNsaW50IHVucGFyYW06IGZhbHNlKi9cblx0XHRcdFx0Zm9yIChuIGluIHN0eWxlcykge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZWRDc3MgKz0gbi5yZXBsYWNlKC8oW0EtWl0pL2csIGh5cGhlbmF0ZSkgKyAnOicgKyBzdHlsZXNbbl0gKyAnOyc7XG5cdFx0XHRcdH1cblx0XHRcdFx0YXR0cihlbGVtLCAnc3R5bGUnLCBzZXJpYWxpemVkQ3NzKTsgLy8gIzE4ODFcblx0XHRcdH1cblxuXG5cdFx0XHQvLyByZS1idWlsZCB0ZXh0XG5cdFx0XHRpZiAodGV4dFdpZHRoICYmIGVsZW1XcmFwcGVyLmFkZGVkKSB7XG5cdFx0XHRcdGVsZW1XcmFwcGVyLnJlbmRlcmVyLmJ1aWxkVGV4dChlbGVtV3JhcHBlcik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVsZW1XcmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgYW4gZXZlbnQgbGlzdGVuZXJcblx0ICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZVxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG5cdCAqL1xuXHRvbjogZnVuY3Rpb24gKGV2ZW50VHlwZSwgaGFuZGxlcikge1xuXHRcdHZhciBzdmdFbGVtZW50ID0gdGhpcyxcblx0XHRcdGVsZW1lbnQgPSBzdmdFbGVtZW50LmVsZW1lbnQ7XG5cdFx0XG5cdFx0Ly8gdG91Y2hcblx0XHRpZiAoaGFzVG91Y2ggJiYgZXZlbnRUeXBlID09PSAnY2xpY2snKSB7XG5cdFx0XHRlbGVtZW50Lm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChlKSB7XHRcdFx0XG5cdFx0XHRcdHN2Z0VsZW1lbnQudG91Y2hFdmVudEZpcmVkID0gRGF0ZS5ub3coKTtcdFx0XHRcdFxuXHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdGhhbmRsZXIuY2FsbChlbGVtZW50LCBlKTtcblx0XHRcdH07XG5cdFx0XHRlbGVtZW50Lm9uY2xpY2sgPSBmdW5jdGlvbiAoZSkge1x0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFxuXHRcdFx0XHRpZiAodXNlckFnZW50LmluZGV4T2YoJ0FuZHJvaWQnKSA9PT0gLTEgfHwgRGF0ZS5ub3coKSAtIChzdmdFbGVtZW50LnRvdWNoRXZlbnRGaXJlZCB8fCAwKSA+IDExMDApIHsgLy8gIzIyNjlcblx0XHRcdFx0XHRoYW5kbGVyLmNhbGwoZWxlbWVudCwgZSk7XG5cdFx0XHRcdH1cblx0XHRcdH07XHRcdFx0XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIHNpbXBsZXN0IHBvc3NpYmxlIGV2ZW50IG1vZGVsIGZvciBpbnRlcm5hbCB1c2Vcblx0XHRcdGVsZW1lbnRbJ29uJyArIGV2ZW50VHlwZV0gPSBoYW5kbGVyO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBjb29yZGluYXRlcyBuZWVkZWQgdG8gZHJhdyBhIGNvbnNpc3RlbnQgcmFkaWFsIGdyYWRpZW50IGFjcm9zc1xuXHQgKiBwaWUgc2xpY2VzIHJlZ2FyZGxlc3Mgb2YgcG9zaXRpb25pbmcgaW5zaWRlIHRoZSBjaGFydC4gVGhlIGZvcm1hdCBpc1xuXHQgKiBbY2VudGVyWCwgY2VudGVyWSwgZGlhbWV0ZXJdIGluIHBpeGVscy5cblx0ICovXG5cdHNldFJhZGlhbFJlZmVyZW5jZTogZnVuY3Rpb24gKGNvb3JkaW5hdGVzKSB7XG5cdFx0dGhpcy5lbGVtZW50LnJhZGlhbFJlZmVyZW5jZSA9IGNvb3JkaW5hdGVzO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBNb3ZlIGFuIG9iamVjdCBhbmQgaXRzIGNoaWxkcmVuIGJ5IHggYW5kIHkgdmFsdWVzXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqL1xuXHR0cmFuc2xhdGU6IGZ1bmN0aW9uICh4LCB5KSB7XG5cdFx0cmV0dXJuIHRoaXMuYXR0cih7XG5cdFx0XHR0cmFuc2xhdGVYOiB4LFxuXHRcdFx0dHJhbnNsYXRlWTogeVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbnZlcnQgYSBncm91cCwgcm90YXRlIGFuZCBmbGlwXG5cdCAqL1xuXHRpbnZlcnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXM7XG5cdFx0d3JhcHBlci5pbnZlcnRlZCA9IHRydWU7XG5cdFx0d3JhcHBlci51cGRhdGVUcmFuc2Zvcm0oKTtcblx0XHRyZXR1cm4gd3JhcHBlcjtcblx0fSxcblxuXHQvKipcblx0ICogUHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIHRoZSB0cmFuc2Zvcm0gYXR0cmlidXRlIGJhc2VkIG9uIGludGVybmFsXG5cdCAqIHByb3BlcnRpZXNcblx0ICovXG5cdHVwZGF0ZVRyYW5zZm9ybTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdHRyYW5zbGF0ZVggPSB3cmFwcGVyLnRyYW5zbGF0ZVggfHwgMCxcblx0XHRcdHRyYW5zbGF0ZVkgPSB3cmFwcGVyLnRyYW5zbGF0ZVkgfHwgMCxcblx0XHRcdHNjYWxlWCA9IHdyYXBwZXIuc2NhbGVYLFxuXHRcdFx0c2NhbGVZID0gd3JhcHBlci5zY2FsZVksXG5cdFx0XHRpbnZlcnRlZCA9IHdyYXBwZXIuaW52ZXJ0ZWQsXG5cdFx0XHRyb3RhdGlvbiA9IHdyYXBwZXIucm90YXRpb24sXG5cdFx0XHRlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0dHJhbnNmb3JtO1xuXG5cdFx0Ly8gZmxpcHBpbmcgYWZmZWN0cyB0cmFuc2xhdGUgYXMgYWRqdXN0bWVudCBmb3IgZmxpcHBpbmcgYXJvdW5kIHRoZSBncm91cCdzIGF4aXNcblx0XHRpZiAoaW52ZXJ0ZWQpIHtcblx0XHRcdHRyYW5zbGF0ZVggKz0gd3JhcHBlci5hdHRyKCd3aWR0aCcpO1xuXHRcdFx0dHJhbnNsYXRlWSArPSB3cmFwcGVyLmF0dHIoJ2hlaWdodCcpO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRyYW5zbGF0ZS4gTmVhcmx5IGFsbCB0cmFuc2Zvcm1lZCBlbGVtZW50cyBoYXZlIHRyYW5zbGF0aW9uLCBzbyBpbnN0ZWFkXG5cdFx0Ly8gb2YgY2hlY2tpbmcgZm9yIHRyYW5zbGF0ZSA9IDAsIGRvIGl0IGFsd2F5cyAoIzE3NjcsICMxODQ2KS5cblx0XHR0cmFuc2Zvcm0gPSBbJ3RyYW5zbGF0ZSgnICsgdHJhbnNsYXRlWCArICcsJyArIHRyYW5zbGF0ZVkgKyAnKSddO1xuXG5cdFx0Ly8gYXBwbHkgcm90YXRpb25cblx0XHRpZiAoaW52ZXJ0ZWQpIHtcblx0XHRcdHRyYW5zZm9ybS5wdXNoKCdyb3RhdGUoOTApIHNjYWxlKC0xLDEpJyk7XG5cdFx0fSBlbHNlIGlmIChyb3RhdGlvbikgeyAvLyB0ZXh0IHJvdGF0aW9uXG5cdFx0XHR0cmFuc2Zvcm0ucHVzaCgncm90YXRlKCcgKyByb3RhdGlvbiArICcgJyArIChlbGVtZW50LmdldEF0dHJpYnV0ZSgneCcpIHx8IDApICsgJyAnICsgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd5JykgfHwgMCkgKyAnKScpO1xuXHRcdH1cblxuXHRcdC8vIGFwcGx5IHNjYWxlXG5cdFx0aWYgKGRlZmluZWQoc2NhbGVYKSB8fCBkZWZpbmVkKHNjYWxlWSkpIHtcblx0XHRcdHRyYW5zZm9ybS5wdXNoKCdzY2FsZSgnICsgcGljayhzY2FsZVgsIDEpICsgJyAnICsgcGljayhzY2FsZVksIDEpICsgJyknKTtcblx0XHR9XG5cblx0XHRpZiAodHJhbnNmb3JtLmxlbmd0aCkge1xuXHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIHRyYW5zZm9ybS5qb2luKCcgJykpO1xuXHRcdH1cblx0fSxcblx0LyoqXG5cdCAqIEJyaW5nIHRoZSBlbGVtZW50IHRvIHRoZSBmcm9udFxuXHQgKi9cblx0dG9Gcm9udDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXHRcdGVsZW1lbnQucGFyZW50Tm9kZS5hcHBlbmRDaGlsZChlbGVtZW50KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXG5cdC8qKlxuXHQgKiBCcmVhayBkb3duIGFsaWdubWVudCBvcHRpb25zIGxpa2UgYWxpZ24sIHZlcnRpY2FsQWxpZ24sIHggYW5kIHlcblx0ICogdG8geCBhbmQgeSByZWxhdGl2ZSB0byB0aGUgY2hhcnQuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBhbGlnbk9wdGlvbnNcblx0ICogQHBhcmFtIHtCb29sZWFufSBhbGlnbkJ5VHJhbnNsYXRlXG5cdCAqIEBwYXJhbSB7U3RyaW5nW09iamVjdH0gYm94IFRoZSBib3ggdG8gYWxpZ24gdG8sIG5lZWRzIGEgd2lkdGggYW5kIGhlaWdodC4gV2hlbiB0aGVcblx0ICogICAgICAgIGJveCBpcyBhIHN0cmluZywgaXQgcmVmZXJzIHRvIGFuIG9iamVjdCBpbiB0aGUgUmVuZGVyZXIuIEZvciBleGFtcGxlLCB3aGVuXG5cdCAqICAgICAgICBib3ggaXMgJ3NwYWNpbmdCb3gnLCBpdCByZWZlcnMgdG8gUmVuZGVyZXIuc3BhY2luZ0JveCB3aGljaCBob2xkcyB3aWR0aCwgaGVpZ2h0XG5cdCAqICAgICAgICB4IGFuZCB5IHByb3BlcnRpZXMuXG5cdCAqXG5cdCAqL1xuXHRhbGlnbjogZnVuY3Rpb24gKGFsaWduT3B0aW9ucywgYWxpZ25CeVRyYW5zbGF0ZSwgYm94KSB7XG5cdFx0dmFyIGFsaWduLFxuXHRcdFx0dkFsaWduLFxuXHRcdFx0eCxcblx0XHRcdHksXG5cdFx0XHRhdHRyaWJzID0ge30sXG5cdFx0XHRhbGlnblRvLFxuXHRcdFx0cmVuZGVyZXIgPSB0aGlzLnJlbmRlcmVyLFxuXHRcdFx0YWxpZ25lZE9iamVjdHMgPSByZW5kZXJlci5hbGlnbmVkT2JqZWN0cztcblxuXHRcdC8vIEZpcnN0IGNhbGwgb24gaW5zdGFuY2lhdGVcblx0XHRpZiAoYWxpZ25PcHRpb25zKSB7XG5cdFx0XHR0aGlzLmFsaWduT3B0aW9ucyA9IGFsaWduT3B0aW9ucztcblx0XHRcdHRoaXMuYWxpZ25CeVRyYW5zbGF0ZSA9IGFsaWduQnlUcmFuc2xhdGU7XG5cdFx0XHRpZiAoIWJveCB8fCBpc1N0cmluZyhib3gpKSB7IC8vIGJveGVzIG90aGVyIHRoYW4gcmVuZGVyZXIgaGFuZGxlIHRoaXMgaW50ZXJuYWxseVxuXHRcdFx0XHR0aGlzLmFsaWduVG8gPSBhbGlnblRvID0gYm94IHx8ICdyZW5kZXJlcic7XG5cdFx0XHRcdGVyYXNlKGFsaWduZWRPYmplY3RzLCB0aGlzKTsgLy8gcHJldmVudCBkdXBsaWNhdGVzLCBsaWtlIGxlZ2VuZEdyb3VwIGFmdGVyIHJlc2l6ZVxuXHRcdFx0XHRhbGlnbmVkT2JqZWN0cy5wdXNoKHRoaXMpO1xuXHRcdFx0XHRib3ggPSBudWxsOyAvLyByZWFzc2lnbiBpdCBiZWxvd1xuXHRcdFx0fVxuXG5cdFx0Ly8gV2hlbiBjYWxsZWQgb24gcmVzaXplLCBubyBhcmd1bWVudHMgYXJlIHN1cHBsaWVkXG5cdFx0fSBlbHNlIHtcblx0XHRcdGFsaWduT3B0aW9ucyA9IHRoaXMuYWxpZ25PcHRpb25zO1xuXHRcdFx0YWxpZ25CeVRyYW5zbGF0ZSA9IHRoaXMuYWxpZ25CeVRyYW5zbGF0ZTtcblx0XHRcdGFsaWduVG8gPSB0aGlzLmFsaWduVG87XG5cdFx0fVxuXG5cdFx0Ym94ID0gcGljayhib3gsIHJlbmRlcmVyW2FsaWduVG9dLCByZW5kZXJlcik7XG5cblx0XHQvLyBBc3NpZ24gdmFyaWFibGVzXG5cdFx0YWxpZ24gPSBhbGlnbk9wdGlvbnMuYWxpZ247XG5cdFx0dkFsaWduID0gYWxpZ25PcHRpb25zLnZlcnRpY2FsQWxpZ247XG5cdFx0eCA9IChib3gueCB8fCAwKSArIChhbGlnbk9wdGlvbnMueCB8fCAwKTsgLy8gZGVmYXVsdDogbGVmdCBhbGlnblxuXHRcdHkgPSAoYm94LnkgfHwgMCkgKyAoYWxpZ25PcHRpb25zLnkgfHwgMCk7IC8vIGRlZmF1bHQ6IHRvcCBhbGlnblxuXG5cdFx0Ly8gQWxpZ25cblx0XHRpZiAoYWxpZ24gPT09ICdyaWdodCcgfHwgYWxpZ24gPT09ICdjZW50ZXInKSB7XG5cdFx0XHR4ICs9IChib3gud2lkdGggLSAoYWxpZ25PcHRpb25zLndpZHRoIHx8IDApKSAvXG5cdFx0XHRcdFx0eyByaWdodDogMSwgY2VudGVyOiAyIH1bYWxpZ25dO1xuXHRcdH1cblx0XHRhdHRyaWJzW2FsaWduQnlUcmFuc2xhdGUgPyAndHJhbnNsYXRlWCcgOiAneCddID0gbWF0aFJvdW5kKHgpO1xuXG5cblx0XHQvLyBWZXJ0aWNhbCBhbGlnblxuXHRcdGlmICh2QWxpZ24gPT09ICdib3R0b20nIHx8IHZBbGlnbiA9PT0gJ21pZGRsZScpIHtcblx0XHRcdHkgKz0gKGJveC5oZWlnaHQgLSAoYWxpZ25PcHRpb25zLmhlaWdodCB8fCAwKSkgL1xuXHRcdFx0XHRcdCh7IGJvdHRvbTogMSwgbWlkZGxlOiAyIH1bdkFsaWduXSB8fCAxKTtcblxuXHRcdH1cblx0XHRhdHRyaWJzW2FsaWduQnlUcmFuc2xhdGUgPyAndHJhbnNsYXRlWScgOiAneSddID0gbWF0aFJvdW5kKHkpO1xuXG5cdFx0Ly8gQW5pbWF0ZSBvbmx5IGlmIGFscmVhZHkgcGxhY2VkXG5cdFx0dGhpc1t0aGlzLnBsYWNlZCA/ICdhbmltYXRlJyA6ICdhdHRyJ10oYXR0cmlicyk7XG5cdFx0dGhpcy5wbGFjZWQgPSB0cnVlO1xuXHRcdHRoaXMuYWxpZ25BdHRyID0gYXR0cmlicztcblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGJvdW5kaW5nIGJveCAod2lkdGgsIGhlaWdodCwgeCBhbmQgeSkgZm9yIHRoZSBlbGVtZW50XG5cdCAqL1xuXHRnZXRCQm94OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0YkJveCA9IHdyYXBwZXIuYkJveCxcblx0XHRcdHJlbmRlcmVyID0gd3JhcHBlci5yZW5kZXJlcixcblx0XHRcdHdpZHRoLFxuXHRcdFx0aGVpZ2h0LFxuXHRcdFx0cm90YXRpb24gPSB3cmFwcGVyLnJvdGF0aW9uLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHN0eWxlcyA9IHdyYXBwZXIuc3R5bGVzLFxuXHRcdFx0cmFkID0gcm90YXRpb24gKiBkZWcycmFkLFxuXHRcdFx0dGV4dFN0ciA9IHdyYXBwZXIudGV4dFN0cixcblx0XHRcdGNhY2hlS2V5O1xuXG5cdFx0Ly8gU2luY2UgbnVtYmVycyBhcmUgbW9ub3NwYWNlZCwgYW5kIG51bWVyaWNhbCBsYWJlbHMgYXBwZWFyIGEgbG90IGluIGEgY2hhcnQsXG5cdFx0Ly8gd2UgYXNzdW1lIHRoYXQgYSBsYWJlbCBvZiBuIGNoYXJhY3RlcnMgaGFzIHRoZSBzYW1lIGJvdW5kaW5nIGJveCBhcyBvdGhlcnMgXG5cdFx0Ly8gb2YgdGhlIHNhbWUgbGVuZ3RoLlxuXHRcdGlmICh0ZXh0U3RyID09PSAnJyB8fCBudW1SZWdleC50ZXN0KHRleHRTdHIpKSB7XG5cdFx0XHRjYWNoZUtleSA9ICdudW0uJyArIHRleHRTdHIudG9TdHJpbmcoKS5sZW5ndGggKyAoc3R5bGVzID8gKCd8JyArIHN0eWxlcy5mb250U2l6ZSArICd8JyArIHN0eWxlcy5mb250RmFtaWx5KSA6ICcnKTtcblxuXHRcdH0gLy9lbHNlIHsgLy8gVGhpcyBjb2RlIGJsb2NrIG1hZGUgZGVtby93YXRlcmZhbGwgZmFpbCwgcmVsYXRlZCB0byBidWlsZFRleHRcblx0XHRcdC8vIENhY2hpbmcgYWxsIHN0cmluZ3MgcmVkdWNlcyByZW5kZXJpbmcgdGltZSBieSA0LTUlLiBcblx0XHRcdC8vIFRPRE86IENoZWNrIGhvdyB0aGlzIGFmZmVjdHMgcGxhY2VzIHdoZXJlIGJCb3ggaXMgZm91bmQgb24gdGhlIGVsZW1lbnRcblx0XHRcdC8vY2FjaGVLZXkgPSB0ZXh0U3RyICsgKHN0eWxlcyA/ICgnfCcgKyBzdHlsZXMuZm9udFNpemUgKyAnfCcgKyBzdHlsZXMuZm9udEZhbWlseSkgOiAnJyk7XG5cdFx0Ly99XG5cdFx0aWYgKGNhY2hlS2V5KSB7XG5cdFx0XHRiQm94ID0gcmVuZGVyZXIuY2FjaGVbY2FjaGVLZXldO1xuXHRcdH1cblxuXHRcdC8vIE5vIGNhY2hlIGZvdW5kXG5cdFx0aWYgKCFiQm94KSB7XG5cblx0XHRcdC8vIFNWRyBlbGVtZW50c1xuXHRcdFx0aWYgKGVsZW1lbnQubmFtZXNwYWNlVVJJID09PSBTVkdfTlMgfHwgcmVuZGVyZXIuZm9yRXhwb3J0KSB7XG5cdFx0XHRcdHRyeSB7IC8vIEZhaWxzIGluIEZpcmVmb3ggaWYgdGhlIGNvbnRhaW5lciBoYXMgZGlzcGxheTogbm9uZS5cblxuXHRcdFx0XHRcdGJCb3ggPSBlbGVtZW50LmdldEJCb3ggP1xuXHRcdFx0XHRcdFx0Ly8gU1ZHOiB1c2UgZXh0ZW5kIGJlY2F1c2UgSUU5IGlzIG5vdCBhbGxvd2VkIHRvIGNoYW5nZSB3aWR0aCBhbmQgaGVpZ2h0IGluIGNhc2Vcblx0XHRcdFx0XHRcdC8vIG9mIHJvdGF0aW9uIChiZWxvdylcblx0XHRcdFx0XHRcdGV4dGVuZCh7fSwgZWxlbWVudC5nZXRCQm94KCkpIDpcblx0XHRcdFx0XHRcdC8vIENhbnZhcyByZW5kZXJlciBhbmQgbGVnYWN5IElFIGluIGV4cG9ydCBtb2RlXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdHdpZHRoOiBlbGVtZW50Lm9mZnNldFdpZHRoLFxuXHRcdFx0XHRcdFx0XHRoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0XG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9IGNhdGNoIChlKSB7fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBiQm94IGlzIG5vdCBzZXQsIHRoZSB0cnktY2F0Y2ggYmxvY2sgYWJvdmUgZmFpbGVkLiBUaGUgb3RoZXIgY29uZGl0aW9uXG5cdFx0XHRcdC8vIGlzIGZvciBPcGVyYSB0aGF0IHJldHVybnMgYSB3aWR0aCBvZiAtSW5maW5pdHkgb24gaGlkZGVuIGVsZW1lbnRzLlxuXHRcdFx0XHRpZiAoIWJCb3ggfHwgYkJveC53aWR0aCA8IDApIHtcblx0XHRcdFx0XHRiQm94ID0geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG5cdFx0XHRcdH1cblxuXG5cdFx0XHQvLyBWTUwgUmVuZGVyZXIgb3IgdXNlSFRNTCB3aXRoaW4gU1ZHXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGJCb3ggPSB3cmFwcGVyLmh0bWxHZXRCQm94KCk7XG5cblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJ1ZSBTVkcgZWxlbWVudHMgYXMgd2VsbCBhcyBIVE1MIGVsZW1lbnRzIGluIG1vZGVybiBicm93c2VycyB1c2luZyB0aGUgLnVzZUhUTUwgb3B0aW9uXG5cdFx0XHQvLyBuZWVkIHRvIGNvbXBlbnNhdGVkIGZvciByb3RhdGlvblxuXHRcdFx0aWYgKHJlbmRlcmVyLmlzU1ZHKSB7XG5cdFx0XHRcdHdpZHRoID0gYkJveC53aWR0aDtcblx0XHRcdFx0aGVpZ2h0ID0gYkJveC5oZWlnaHQ7XG5cblx0XHRcdFx0Ly8gV29ya2Fyb3VuZCBmb3Igd3JvbmcgYm91bmRpbmcgYm94IGluIElFOSBhbmQgSUUxMCAoIzExMDEsICMxNTA1LCAjMTY2OSwgIzI1NjgpXG5cdFx0XHRcdGlmIChpc0lFICYmIHN0eWxlcyAmJiBzdHlsZXMuZm9udFNpemUgPT09ICcxMXB4JyAmJiBoZWlnaHQudG9QcmVjaXNpb24oMykgPT09ICcxNi45Jykge1xuXHRcdFx0XHRcdGJCb3guaGVpZ2h0ID0gaGVpZ2h0ID0gMTQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGp1c3QgZm9yIHJvdGF0ZWQgdGV4dFxuXHRcdFx0XHRpZiAocm90YXRpb24pIHtcblx0XHRcdFx0XHRiQm94LndpZHRoID0gbWF0aEFicyhoZWlnaHQgKiBtYXRoU2luKHJhZCkpICsgbWF0aEFicyh3aWR0aCAqIG1hdGhDb3MocmFkKSk7XG5cdFx0XHRcdFx0YkJveC5oZWlnaHQgPSBtYXRoQWJzKGhlaWdodCAqIG1hdGhDb3MocmFkKSkgKyBtYXRoQWJzKHdpZHRoICogbWF0aFNpbihyYWQpKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBDYWNoZSBpdFxuXHRcdFx0d3JhcHBlci5iQm94ID0gYkJveDtcblx0XHRcdGlmIChjYWNoZUtleSkge1xuXHRcdFx0XHRyZW5kZXJlci5jYWNoZVtjYWNoZUtleV0gPSBiQm94O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gYkJveDtcblx0fSxcblxuXHQvKipcblx0ICogU2hvdyB0aGUgZWxlbWVudFxuXHQgKi9cblx0c2hvdzogZnVuY3Rpb24gKGluaGVyaXQpIHtcblx0XHQvLyBJRTktMTEgZG9lc24ndCBoYW5kbGUgdmlzaWJpbHR5OmluaGVyaXQgd2VsbCwgc28gd2UgcmVtb3ZlIHRoZSBhdHRyaWJ1dGUgaW5zdGVhZCAoIzI4ODEpXG5cdFx0aWYgKGluaGVyaXQgJiYgdGhpcy5lbGVtZW50Lm5hbWVzcGFjZVVSSSA9PT0gU1ZHX05TKSB7XG5cdFx0XHR0aGlzLmVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCd2aXNpYmlsaXR5Jyk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuYXR0cih7IHZpc2liaWxpdHk6IGluaGVyaXQgPyAnaW5oZXJpdCcgOiBWSVNJQkxFIH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogSGlkZSB0aGUgZWxlbWVudFxuXHQgKi9cblx0aGlkZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLmF0dHIoeyB2aXNpYmlsaXR5OiBISURERU4gfSk7XG5cdH0sXG5cblx0ZmFkZU91dDogZnVuY3Rpb24gKGR1cmF0aW9uKSB7XG5cdFx0dmFyIGVsZW1XcmFwcGVyID0gdGhpcztcblx0XHRlbGVtV3JhcHBlci5hbmltYXRlKHtcblx0XHRcdG9wYWNpdHk6IDBcblx0XHR9LCB7XG5cdFx0XHRkdXJhdGlvbjogZHVyYXRpb24gfHwgMTUwLFxuXHRcdFx0Y29tcGxldGU6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0ZWxlbVdyYXBwZXIuYXR0cih7IHk6IC05OTk5IH0pOyAvLyAjMzA4OCwgYXNzdW1pbmcgd2UncmUgb25seSB1c2luZyB0aGlzIGZvciB0b29sdGlwc1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgdGhlIGVsZW1lbnRcblx0ICogQHBhcmFtIHtPYmplY3R8VW5kZWZpbmVkfSBwYXJlbnQgQ2FuIGJlIGFuIGVsZW1lbnQsIGFuIGVsZW1lbnQgd3JhcHBlciBvciB1bmRlZmluZWRcblx0ICogICAgdG8gYXBwZW5kIHRoZSBlbGVtZW50IHRvIHRoZSByZW5kZXJlci5ib3guXG5cdCAqL1xuXHRhZGQ6IGZ1bmN0aW9uIChwYXJlbnQpIHtcblxuXHRcdHZhciByZW5kZXJlciA9IHRoaXMucmVuZGVyZXIsXG5cdFx0XHRwYXJlbnRXcmFwcGVyID0gcGFyZW50IHx8IHJlbmRlcmVyLFxuXHRcdFx0cGFyZW50Tm9kZSA9IHBhcmVudFdyYXBwZXIuZWxlbWVudCB8fCByZW5kZXJlci5ib3gsXG5cdFx0XHRjaGlsZE5vZGVzLFxuXHRcdFx0ZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcblx0XHRcdHpJbmRleCA9IHRoaXMuekluZGV4LFxuXHRcdFx0b3RoZXJFbGVtZW50LFxuXHRcdFx0b3RoZXJaSW5kZXgsXG5cdFx0XHRpLFxuXHRcdFx0aW5zZXJ0ZWQ7XG5cblx0XHRpZiAocGFyZW50KSB7XG5cdFx0XHR0aGlzLnBhcmVudEdyb3VwID0gcGFyZW50O1xuXHRcdH1cblxuXHRcdC8vIG1hcmsgYXMgaW52ZXJ0ZWRcblx0XHR0aGlzLnBhcmVudEludmVydGVkID0gcGFyZW50ICYmIHBhcmVudC5pbnZlcnRlZDtcblxuXHRcdC8vIGJ1aWxkIGZvcm1hdHRlZCB0ZXh0XG5cdFx0aWYgKHRoaXMudGV4dFN0ciAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZW5kZXJlci5idWlsZFRleHQodGhpcyk7XG5cdFx0fVxuXG5cdFx0Ly8gbWFyayB0aGUgY29udGFpbmVyIGFzIGhhdmluZyB6IGluZGV4ZWQgY2hpbGRyZW5cblx0XHRpZiAoekluZGV4KSB7XG5cdFx0XHRwYXJlbnRXcmFwcGVyLmhhbmRsZVogPSB0cnVlO1xuXHRcdFx0ekluZGV4ID0gcEludCh6SW5kZXgpO1xuXHRcdH1cblxuXHRcdC8vIGluc2VydCBhY2NvcmRpbmcgdG8gdGhpcyBhbmQgb3RoZXIgZWxlbWVudHMnIHpJbmRleFxuXHRcdGlmIChwYXJlbnRXcmFwcGVyLmhhbmRsZVopIHsgLy8gdGhpcyBlbGVtZW50IG9yIGFueSBvZiBpdHMgc2libGluZ3MgaGFzIGEgeiBpbmRleFxuXHRcdFx0Y2hpbGROb2RlcyA9IHBhcmVudE5vZGUuY2hpbGROb2Rlcztcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBjaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdG90aGVyRWxlbWVudCA9IGNoaWxkTm9kZXNbaV07XG5cdFx0XHRcdG90aGVyWkluZGV4ID0gYXR0cihvdGhlckVsZW1lbnQsICd6SW5kZXgnKTtcblx0XHRcdFx0aWYgKG90aGVyRWxlbWVudCAhPT0gZWxlbWVudCAmJiAoXG5cdFx0XHRcdFx0XHQvLyBpbnNlcnQgYmVmb3JlIHRoZSBmaXJzdCBlbGVtZW50IHdpdGggYSBoaWdoZXIgekluZGV4XG5cdFx0XHRcdFx0XHRwSW50KG90aGVyWkluZGV4KSA+IHpJbmRleCB8fFxuXHRcdFx0XHRcdFx0Ly8gaWYgbm8gekluZGV4IGdpdmVuLCBpbnNlcnQgYmVmb3JlIHRoZSBmaXJzdCBlbGVtZW50IHdpdGggYSB6SW5kZXhcblx0XHRcdFx0XHRcdCghZGVmaW5lZCh6SW5kZXgpICYmIGRlZmluZWQob3RoZXJaSW5kZXgpKVxuXG5cdFx0XHRcdFx0XHQpKSB7XG5cdFx0XHRcdFx0cGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgb3RoZXJFbGVtZW50KTtcblx0XHRcdFx0XHRpbnNlcnRlZCA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBkZWZhdWx0OiBhcHBlbmQgYXQgdGhlIGVuZFxuXHRcdGlmICghaW5zZXJ0ZWQpIHtcblx0XHRcdHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0fVxuXG5cdFx0Ly8gbWFyayBhcyBhZGRlZFxuXHRcdHRoaXMuYWRkZWQgPSB0cnVlO1xuXG5cdFx0Ly8gZmlyZSBhbiBldmVudCBmb3IgaW50ZXJuYWwgaG9va3Ncblx0XHRpZiAodGhpcy5vbkFkZCkge1xuXHRcdFx0dGhpcy5vbkFkZCgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgY2hpbGQgZWl0aGVyIGJ5IHJlbW92ZUNoaWxkIG9yIG1vdmUgdG8gZ2FyYmFnZUJpbi5cblx0ICogSXNzdWUgNDkwOyBpbiBWTUwgcmVtb3ZlQ2hpbGQgcmVzdWx0cyBpbiBPcnBoYW5lZCBub2RlcyBhY2NvcmRpbmcgdG8gc0lFdmUsIGRpc2NhcmRFbGVtZW50IGRvZXMgbm90LlxuXHQgKi9cblx0c2FmZVJlbW92ZUNoaWxkOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuXHRcdHZhciBwYXJlbnROb2RlID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXHRcdGlmIChwYXJlbnROb2RlKSB7XG5cdFx0XHRwYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveSB0aGUgZWxlbWVudCBhbmQgZWxlbWVudCB3cmFwcGVyXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0ZWxlbWVudCA9IHdyYXBwZXIuZWxlbWVudCB8fCB7fSxcblx0XHRcdHNoYWRvd3MgPSB3cmFwcGVyLnNoYWRvd3MsXG5cdFx0XHRwYXJlbnRUb0NsZWFuID0gd3JhcHBlci5yZW5kZXJlci5pc1NWRyAmJiBlbGVtZW50Lm5vZGVOYW1lID09PSAnU1BBTicgJiYgd3JhcHBlci5wYXJlbnRHcm91cCxcblx0XHRcdGdyYW5kUGFyZW50LFxuXHRcdFx0a2V5LFxuXHRcdFx0aTtcblxuXHRcdC8vIHJlbW92ZSBldmVudHNcblx0XHRlbGVtZW50Lm9uY2xpY2sgPSBlbGVtZW50Lm9ubW91c2VvdXQgPSBlbGVtZW50Lm9ubW91c2VvdmVyID0gZWxlbWVudC5vbm1vdXNlbW92ZSA9IGVsZW1lbnQucG9pbnQgPSBudWxsO1xuXHRcdHN0b3Aod3JhcHBlcik7IC8vIHN0b3AgcnVubmluZyBhbmltYXRpb25zXG5cblx0XHRpZiAod3JhcHBlci5jbGlwUGF0aCkge1xuXHRcdFx0d3JhcHBlci5jbGlwUGF0aCA9IHdyYXBwZXIuY2xpcFBhdGguZGVzdHJveSgpO1xuXHRcdH1cblxuXHRcdC8vIERlc3Ryb3kgc3RvcHMgaW4gY2FzZSB0aGlzIGlzIGEgZ3JhZGllbnQgb2JqZWN0XG5cdFx0aWYgKHdyYXBwZXIuc3RvcHMpIHtcblx0XHRcdGZvciAoaSA9IDA7IGkgPCB3cmFwcGVyLnN0b3BzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHdyYXBwZXIuc3RvcHNbaV0gPSB3cmFwcGVyLnN0b3BzW2ldLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHRcdHdyYXBwZXIuc3RvcHMgPSBudWxsO1xuXHRcdH1cblxuXHRcdC8vIHJlbW92ZSBlbGVtZW50XG5cdFx0d3JhcHBlci5zYWZlUmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG5cblx0XHQvLyBkZXN0cm95IHNoYWRvd3Ncblx0XHRpZiAoc2hhZG93cykge1xuXHRcdFx0ZWFjaChzaGFkb3dzLCBmdW5jdGlvbiAoc2hhZG93KSB7XG5cdFx0XHRcdHdyYXBwZXIuc2FmZVJlbW92ZUNoaWxkKHNoYWRvdyk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvLyBJbiBjYXNlIG9mIHVzZUhUTUwsIGNsZWFuIHVwIGVtcHR5IGNvbnRhaW5lcnMgZW11bGF0aW5nIFNWRyBncm91cHMgKCMxOTYwLCAjMjM5MywgIzI2OTcpLlxuXHRcdHdoaWxlIChwYXJlbnRUb0NsZWFuICYmIHBhcmVudFRvQ2xlYW4uZGl2ICYmIHBhcmVudFRvQ2xlYW4uZGl2LmNoaWxkTm9kZXMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRncmFuZFBhcmVudCA9IHBhcmVudFRvQ2xlYW4ucGFyZW50R3JvdXA7XG5cdFx0XHR3cmFwcGVyLnNhZmVSZW1vdmVDaGlsZChwYXJlbnRUb0NsZWFuLmRpdik7XG5cdFx0XHRkZWxldGUgcGFyZW50VG9DbGVhbi5kaXY7XG5cdFx0XHRwYXJlbnRUb0NsZWFuID0gZ3JhbmRQYXJlbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gcmVtb3ZlIGZyb20gYWxpZ25PYmplY3RzXG5cdFx0aWYgKHdyYXBwZXIuYWxpZ25Ubykge1xuXHRcdFx0ZXJhc2Uod3JhcHBlci5yZW5kZXJlci5hbGlnbmVkT2JqZWN0cywgd3JhcHBlcik7XG5cdFx0fVxuXG5cdFx0Zm9yIChrZXkgaW4gd3JhcHBlcikge1xuXHRcdFx0ZGVsZXRlIHdyYXBwZXJba2V5XTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbnVsbDtcblx0fSxcblxuXHQvKipcblx0ICogQWRkIGEgc2hhZG93IHRvIHRoZSBlbGVtZW50LiBNdXN0IGJlIGRvbmUgYWZ0ZXIgdGhlIGVsZW1lbnQgaXMgYWRkZWQgdG8gdGhlIERPTVxuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBzaGFkb3dPcHRpb25zXG5cdCAqL1xuXHRzaGFkb3c6IGZ1bmN0aW9uIChzaGFkb3dPcHRpb25zLCBncm91cCwgY3V0T2ZmKSB7XG5cdFx0dmFyIHNoYWRvd3MgPSBbXSxcblx0XHRcdGksXG5cdFx0XHRzaGFkb3csXG5cdFx0XHRlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuXHRcdFx0c3Ryb2tlV2lkdGgsXG5cdFx0XHRzaGFkb3dXaWR0aCxcblx0XHRcdHNoYWRvd0VsZW1lbnRPcGFjaXR5LFxuXG5cdFx0XHQvLyBjb21wZW5zYXRlIGZvciBpbnZlcnRlZCBwbG90IGFyZWFcblx0XHRcdHRyYW5zZm9ybTtcblxuXG5cdFx0aWYgKHNoYWRvd09wdGlvbnMpIHtcblx0XHRcdHNoYWRvd1dpZHRoID0gcGljayhzaGFkb3dPcHRpb25zLndpZHRoLCAzKTtcblx0XHRcdHNoYWRvd0VsZW1lbnRPcGFjaXR5ID0gKHNoYWRvd09wdGlvbnMub3BhY2l0eSB8fCAwLjE1KSAvIHNoYWRvd1dpZHRoO1xuXHRcdFx0dHJhbnNmb3JtID0gdGhpcy5wYXJlbnRJbnZlcnRlZCA/XG5cdFx0XHRcdCcoLTEsLTEpJyA6XG5cdFx0XHRcdCcoJyArIHBpY2soc2hhZG93T3B0aW9ucy5vZmZzZXRYLCAxKSArICcsICcgKyBwaWNrKHNoYWRvd09wdGlvbnMub2Zmc2V0WSwgMSkgKyAnKSc7XG5cdFx0XHRmb3IgKGkgPSAxOyBpIDw9IHNoYWRvd1dpZHRoOyBpKyspIHtcblx0XHRcdFx0c2hhZG93ID0gZWxlbWVudC5jbG9uZU5vZGUoMCk7XG5cdFx0XHRcdHN0cm9rZVdpZHRoID0gKHNoYWRvd1dpZHRoICogMikgKyAxIC0gKDIgKiBpKTtcblx0XHRcdFx0YXR0cihzaGFkb3csIHtcblx0XHRcdFx0XHQnaXNTaGFkb3cnOiAndHJ1ZScsXG5cdFx0XHRcdFx0J3N0cm9rZSc6IHNoYWRvd09wdGlvbnMuY29sb3IgfHwgJ2JsYWNrJyxcblx0XHRcdFx0XHQnc3Ryb2tlLW9wYWNpdHknOiBzaGFkb3dFbGVtZW50T3BhY2l0eSAqIGksXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IHN0cm9rZVdpZHRoLFxuXHRcdFx0XHRcdCd0cmFuc2Zvcm0nOiAndHJhbnNsYXRlJyArIHRyYW5zZm9ybSxcblx0XHRcdFx0XHQnZmlsbCc6IE5PTkVcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGlmIChjdXRPZmYpIHtcblx0XHRcdFx0XHRhdHRyKHNoYWRvdywgJ2hlaWdodCcsIG1hdGhNYXgoYXR0cihzaGFkb3csICdoZWlnaHQnKSAtIHN0cm9rZVdpZHRoLCAwKSk7XG5cdFx0XHRcdFx0c2hhZG93LmN1dEhlaWdodCA9IHN0cm9rZVdpZHRoO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGdyb3VwKSB7XG5cdFx0XHRcdFx0Z3JvdXAuZWxlbWVudC5hcHBlbmRDaGlsZChzaGFkb3cpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2hhZG93LCBlbGVtZW50KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHNoYWRvd3MucHVzaChzaGFkb3cpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNoYWRvd3MgPSBzaGFkb3dzO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9LFxuXG5cdHhHZXR0ZXI6IGZ1bmN0aW9uIChrZXkpIHtcblx0XHRpZiAodGhpcy5lbGVtZW50Lm5vZGVOYW1lID09PSAnY2lyY2xlJykge1xuXHRcdFx0a2V5ID0geyB4OiAnY3gnLCB5OiAnY3knIH1ba2V5XSB8fCBrZXk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLl9kZWZhdWx0R2V0dGVyKGtleSk7XG5cdH0sXG5cblx0LyoqIFxuXHQgKiBHZXQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgYW4gYXR0cmlidXRlIG9yIHBzZXVkbyBhdHRyaWJ1dGUsIHVzZWQgbWFpbmx5XG5cdCAqIGZvciBhbmltYXRpb24uXG5cdCAqL1xuXHRfZGVmYXVsdEdldHRlcjogZnVuY3Rpb24gKGtleSkge1xuXHRcdHZhciByZXQgPSBwaWNrKHRoaXNba2V5XSwgdGhpcy5lbGVtZW50ID8gdGhpcy5lbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpIDogbnVsbCwgMCk7XG5cblx0XHRpZiAoL15bXFwtMC05XFwuXSskLy50ZXN0KHJldCkpIHsgLy8gaXMgbnVtZXJpY2FsXG5cdFx0XHRyZXQgPSBwYXJzZUZsb2F0KHJldCk7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblxuXHRkU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdGlmICh2YWx1ZSAmJiB2YWx1ZS5qb2luKSB7IC8vIGpvaW4gcGF0aFxuXHRcdFx0dmFsdWUgPSB2YWx1ZS5qb2luKCcgJyk7XG5cdFx0fVxuXHRcdGlmICgvKE5hTnwgezJ9fF4kKS8udGVzdCh2YWx1ZSkpIHtcblx0XHRcdHZhbHVlID0gJ00gMCAwJztcblx0XHR9XG5cdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG5cblx0XHR0aGlzW2tleV0gPSB2YWx1ZTtcblx0fSxcblx0ZGFzaHN0eWxlU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHR2YXIgaTtcblx0XHR2YWx1ZSA9IHZhbHVlICYmIHZhbHVlLnRvTG93ZXJDYXNlKCk7XG5cdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlXG5cdFx0XHRcdC5yZXBsYWNlKCdzaG9ydGRhc2hkb3Rkb3QnLCAnMywxLDEsMSwxLDEsJylcblx0XHRcdFx0LnJlcGxhY2UoJ3Nob3J0ZGFzaGRvdCcsICczLDEsMSwxJylcblx0XHRcdFx0LnJlcGxhY2UoJ3Nob3J0ZG90JywgJzEsMSwnKVxuXHRcdFx0XHQucmVwbGFjZSgnc2hvcnRkYXNoJywgJzMsMSwnKVxuXHRcdFx0XHQucmVwbGFjZSgnbG9uZ2Rhc2gnLCAnOCwzLCcpXG5cdFx0XHRcdC5yZXBsYWNlKC9kb3QvZywgJzEsMywnKVxuXHRcdFx0XHQucmVwbGFjZSgnZGFzaCcsICc0LDMsJylcblx0XHRcdFx0LnJlcGxhY2UoLywkLywgJycpXG5cdFx0XHRcdC5zcGxpdCgnLCcpOyAvLyBlbmRpbmcgY29tbWFcblxuXHRcdFx0aSA9IHZhbHVlLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0dmFsdWVbaV0gPSBwSW50KHZhbHVlW2ldKSAqIHRoaXNbJ3N0cm9rZS13aWR0aCddO1xuXHRcdFx0fVxuXHRcdFx0dmFsdWUgPSB2YWx1ZS5qb2luKCcsJylcblx0XHRcdFx0LnJlcGxhY2UoJ05hTicsICdub25lJyk7IC8vICMzMjI2XG5cdFx0XHR0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdHJva2UtZGFzaGFycmF5JywgdmFsdWUpO1xuXHRcdH1cblx0fSxcblx0YWxpZ25TZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdHRoaXMuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RleHQtYW5jaG9yJywgeyBsZWZ0OiAnc3RhcnQnLCBjZW50ZXI6ICdtaWRkbGUnLCByaWdodDogJ2VuZCcgfVt2YWx1ZV0pO1xuXHR9LFxuXHRvcGFjaXR5U2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdHRoaXNba2V5XSA9IHZhbHVlO1xuXHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHR9LFxuXHR0aXRsZVNldHRlcjogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0dmFyIHRpdGxlTm9kZSA9IHRoaXMuZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGl0bGUnKVswXTtcblx0XHRpZiAoIXRpdGxlTm9kZSkge1xuXHRcdFx0dGl0bGVOb2RlID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICd0aXRsZScpO1xuXHRcdFx0dGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKHRpdGxlTm9kZSk7XG5cdFx0fVxuXHRcdHRpdGxlTm9kZS50ZXh0Q29udGVudCA9IHBpY2sodmFsdWUsICcnKS5yZXBsYWNlKC88W14+XSo+L2csICcnKTsgLy8gIzMyNzZcblx0fSxcblx0dGV4dFNldHRlcjogZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0aWYgKHZhbHVlICE9PSB0aGlzLnRleHRTdHIpIHtcblx0XHRcdC8vIERlbGV0ZSBiQm94IG1lbW8gd2hlbiB0aGUgdGV4dCBjaGFuZ2VzXG5cdFx0XHRkZWxldGUgdGhpcy5iQm94O1xuXHRcdFxuXHRcdFx0dGhpcy50ZXh0U3RyID0gdmFsdWU7XG5cdFx0XHRpZiAodGhpcy5hZGRlZCkge1xuXHRcdFx0XHR0aGlzLnJlbmRlcmVyLmJ1aWxkVGV4dCh0aGlzKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGZpbGxTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHRcdH0gZWxzZSBpZiAodmFsdWUpIHtcblx0XHRcdHRoaXMuY29sb3JHcmFkaWVudCh2YWx1ZSwga2V5LCBlbGVtZW50KTtcblx0XHR9XG5cdH0sXG5cdHpJbmRleFNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKTtcblx0XHR0aGlzW2tleV0gPSB2YWx1ZTtcblx0fSxcblx0X2RlZmF1bHRTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG5cdH1cbn07XG5cbi8vIFNvbWUgc2hhcmVkIHNldHRlcnMgYW5kIGdldHRlcnNcblNWR0VsZW1lbnQucHJvdG90eXBlLnlHZXR0ZXIgPSBTVkdFbGVtZW50LnByb3RvdHlwZS54R2V0dGVyO1xuU1ZHRWxlbWVudC5wcm90b3R5cGUudHJhbnNsYXRlWFNldHRlciA9IFNWR0VsZW1lbnQucHJvdG90eXBlLnRyYW5zbGF0ZVlTZXR0ZXIgPSBcblx0XHRTVkdFbGVtZW50LnByb3RvdHlwZS5yb3RhdGlvblNldHRlciA9IFNWR0VsZW1lbnQucHJvdG90eXBlLnZlcnRpY2FsQWxpZ25TZXR0ZXIgPSBcblx0XHRTVkdFbGVtZW50LnByb3RvdHlwZS5zY2FsZVhTZXR0ZXIgPSBTVkdFbGVtZW50LnByb3RvdHlwZS5zY2FsZVlTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHR0aGlzW2tleV0gPSB2YWx1ZTtcblx0dGhpcy5kb1RyYW5zZm9ybSA9IHRydWU7XG59O1xuXG4vLyBXZWJLaXQgYW5kIEJhdGlrIGhhdmUgcHJvYmxlbXMgd2l0aCBhIHN0cm9rZS13aWR0aCBvZiB6ZXJvLCBzbyBpbiB0aGlzIGNhc2Ugd2UgcmVtb3ZlIHRoZSBcbi8vIHN0cm9rZSBhdHRyaWJ1dGUgYWx0b2dldGhlci4gIzEyNzAsICMxMzY5LCAjMzA2NSwgIzMwNzIuXG5TVkdFbGVtZW50LnByb3RvdHlwZVsnc3Ryb2tlLXdpZHRoU2V0dGVyJ10gPSBTVkdFbGVtZW50LnByb3RvdHlwZS5zdHJva2VTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHR0aGlzW2tleV0gPSB2YWx1ZTtcblx0Ly8gT25seSBhcHBseSB0aGUgc3Ryb2tlIGF0dHJpYnV0ZSBpZiB0aGUgc3Ryb2tlIHdpZHRoIGlzIGRlZmluZWQgYW5kIGxhcmdlciB0aGFuIDBcblx0aWYgKHRoaXMuc3Ryb2tlICYmIHRoaXNbJ3N0cm9rZS13aWR0aCddKSB7XG5cdFx0dGhpcy5zdHJva2VXaWR0aCA9IHRoaXNbJ3N0cm9rZS13aWR0aCddO1xuXHRcdFNWR0VsZW1lbnQucHJvdG90eXBlLmZpbGxTZXR0ZXIuY2FsbCh0aGlzLCB0aGlzLnN0cm9rZSwgJ3N0cm9rZScsIGVsZW1lbnQpOyAvLyB1c2UgcHJvdG90eXBlIGFzIGluc3RhbmNlIG1heSBiZSBvdmVycmlkZGVuXG5cdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIHRoaXNbJ3N0cm9rZS13aWR0aCddKTtcblx0XHR0aGlzLmhhc1N0cm9rZSA9IHRydWU7XG5cdH0gZWxzZSBpZiAoa2V5ID09PSAnc3Ryb2tlLXdpZHRoJyAmJiB2YWx1ZSA9PT0gMCAmJiB0aGlzLmhhc1N0cm9rZSkge1xuXHRcdGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdzdHJva2UnKTtcblx0XHR0aGlzLmhhc1N0cm9rZSA9IGZhbHNlO1xuXHR9XG59O1xuXG5cbi8qKlxuICogVGhlIGRlZmF1bHQgU1ZHIHJlbmRlcmVyXG4gKi9cbnZhciBTVkdSZW5kZXJlciA9IGZ1bmN0aW9uICgpIHtcblx0dGhpcy5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuU1ZHUmVuZGVyZXIucHJvdG90eXBlID0ge1xuXHRFbGVtZW50OiBTVkdFbGVtZW50LFxuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBTVkdSZW5kZXJlclxuXHQgKiBAcGFyYW0ge09iamVjdH0gY29udGFpbmVyXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gZm9yRXhwb3J0XG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAoY29udGFpbmVyLCB3aWR0aCwgaGVpZ2h0LCBzdHlsZSwgZm9yRXhwb3J0KSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcyxcblx0XHRcdGxvYyA9IGxvY2F0aW9uLFxuXHRcdFx0Ym94V3JhcHBlcixcblx0XHRcdGVsZW1lbnQsXG5cdFx0XHRkZXNjO1xuXG5cdFx0Ym94V3JhcHBlciA9IHJlbmRlcmVyLmNyZWF0ZUVsZW1lbnQoJ3N2ZycpXG5cdFx0XHQuYXR0cih7XG5cdFx0XHRcdHZlcnNpb246ICcxLjEnXG5cdFx0XHR9KVxuXHRcdFx0LmNzcyh0aGlzLmdldFN0eWxlKHN0eWxlKSk7XG5cdFx0ZWxlbWVudCA9IGJveFdyYXBwZXIuZWxlbWVudDtcblx0XHRjb250YWluZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cblx0XHQvLyBGb3IgYnJvd3NlcnMgb3RoZXIgdGhhbiBJRSwgYWRkIHRoZSBuYW1lc3BhY2UgYXR0cmlidXRlICgjMTk3OClcblx0XHRpZiAoY29udGFpbmVyLmlubmVySFRNTC5pbmRleE9mKCd4bWxucycpID09PSAtMSkge1xuXHRcdFx0YXR0cihlbGVtZW50LCAneG1sbnMnLCBTVkdfTlMpO1xuXHRcdH1cblxuXHRcdC8vIG9iamVjdCBwcm9wZXJ0aWVzXG5cdFx0cmVuZGVyZXIuaXNTVkcgPSB0cnVlO1xuXHRcdHJlbmRlcmVyLmJveCA9IGVsZW1lbnQ7XG5cdFx0cmVuZGVyZXIuYm94V3JhcHBlciA9IGJveFdyYXBwZXI7XG5cdFx0cmVuZGVyZXIuYWxpZ25lZE9iamVjdHMgPSBbXTtcblxuXHRcdC8vIFBhZ2UgdXJsIHVzZWQgZm9yIGludGVybmFsIHJlZmVyZW5jZXMuICMyNCwgIzY3MiwgIzEwNzBcblx0XHRyZW5kZXJlci51cmwgPSAoaXNGaXJlZm94IHx8IGlzV2ViS2l0KSAmJiBkb2MuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2Jhc2UnKS5sZW5ndGggP1xuXHRcdFx0bG9jLmhyZWZcblx0XHRcdFx0LnJlcGxhY2UoLyMuKj8kLywgJycpIC8vIHJlbW92ZSB0aGUgaGFzaFxuXHRcdFx0XHQucmVwbGFjZSgvKFtcXCgnXFwpXSkvZywgJ1xcXFwkMScpIC8vIGVzY2FwZSBwYXJhbnRoZXNlcyBhbmQgcXVvdGVzXG5cdFx0XHRcdC5yZXBsYWNlKC8gL2csICclMjAnKSA6IC8vIHJlcGxhY2Ugc3BhY2VzIChuZWVkZWQgZm9yIFNhZmFyaSBvbmx5KVxuXHRcdFx0Jyc7XG5cblx0XHQvLyBBZGQgZGVzY3JpcHRpb25cblx0XHRkZXNjID0gdGhpcy5jcmVhdGVFbGVtZW50KCdkZXNjJykuYWRkKCk7XG5cdFx0ZGVzYy5lbGVtZW50LmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZSgnQ3JlYXRlZCB3aXRoICcgKyBQUk9EVUNUICsgJyAnICsgVkVSU0lPTikpO1xuXG5cblx0XHRyZW5kZXJlci5kZWZzID0gdGhpcy5jcmVhdGVFbGVtZW50KCdkZWZzJykuYWRkKCk7XG5cdFx0cmVuZGVyZXIuZm9yRXhwb3J0ID0gZm9yRXhwb3J0O1xuXHRcdHJlbmRlcmVyLmdyYWRpZW50cyA9IHt9OyAvLyBPYmplY3Qgd2hlcmUgZ3JhZGllbnQgU3ZnRWxlbWVudHMgYXJlIHN0b3JlZFxuXHRcdHJlbmRlcmVyLmNhY2hlID0ge307IC8vIENhY2hlIGZvciBudW1lcmljYWwgYm91bmRpbmcgYm94ZXNcblxuXHRcdHJlbmRlcmVyLnNldFNpemUod2lkdGgsIGhlaWdodCwgZmFsc2UpO1xuXG5cblxuXHRcdC8vIElzc3VlIDExMCB3b3JrYXJvdW5kOlxuXHRcdC8vIEluIEZpcmVmb3gsIGlmIGEgZGl2IGlzIHBvc2l0aW9uZWQgYnkgcGVyY2VudGFnZSwgaXRzIHBpeGVsIHBvc2l0aW9uIG1heSBsYW5kXG5cdFx0Ly8gYmV0d2VlbiBwaXhlbHMuIFRoZSBjb250YWluZXIgaXRzZWxmIGRvZXNuJ3QgZGlzcGxheSB0aGlzLCBidXQgYW4gU1ZHIGVsZW1lbnRcblx0XHQvLyBpbnNpZGUgdGhpcyBjb250YWluZXIgd2lsbCBiZSBkcmF3biBhdCBzdWJwaXhlbCBwcmVjaXNpb24uIEluIG9yZGVyIHRvIGRyYXdcblx0XHQvLyBzaGFycCBsaW5lcywgdGhpcyBtdXN0IGJlIGNvbXBlbnNhdGVkIGZvci4gVGhpcyBkb2Vzbid0IHNlZW0gdG8gd29yayBpbnNpZGVcblx0XHQvLyBpZnJhbWVzIHRob3VnaCAobGlrZSBpbiBqc0ZpZGRsZSkuXG5cdFx0dmFyIHN1YlBpeGVsRml4LCByZWN0O1xuXHRcdGlmIChpc0ZpcmVmb3ggJiYgY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCkge1xuXHRcdFx0cmVuZGVyZXIuc3ViUGl4ZWxGaXggPSBzdWJQaXhlbEZpeCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0Y3NzKGNvbnRhaW5lciwgeyBsZWZ0OiAwLCB0b3A6IDAgfSk7XG5cdFx0XHRcdHJlY3QgPSBjb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0XHRcdGNzcyhjb250YWluZXIsIHtcblx0XHRcdFx0XHRsZWZ0OiAobWF0aENlaWwocmVjdC5sZWZ0KSAtIHJlY3QubGVmdCkgKyBQWCxcblx0XHRcdFx0XHR0b3A6IChtYXRoQ2VpbChyZWN0LnRvcCkgLSByZWN0LnRvcCkgKyBQWFxuXHRcdFx0XHR9KTtcblx0XHRcdH07XG5cblx0XHRcdC8vIHJ1biB0aGUgZml4IG5vd1xuXHRcdFx0c3ViUGl4ZWxGaXgoKTtcblxuXHRcdFx0Ly8gcnVuIGl0IG9uIHJlc2l6ZVxuXHRcdFx0YWRkRXZlbnQod2luLCAncmVzaXplJywgc3ViUGl4ZWxGaXgpO1xuXHRcdH1cblx0fSxcblxuXHRnZXRTdHlsZTogZnVuY3Rpb24gKHN0eWxlKSB7XG5cdFx0cmV0dXJuICh0aGlzLnN0eWxlID0gZXh0ZW5kKHtcblx0XHRcdGZvbnRGYW1pbHk6ICdcIkx1Y2lkYSBHcmFuZGVcIiwgXCJMdWNpZGEgU2FucyBVbmljb2RlXCIsIEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWYnLCAvLyBkZWZhdWx0IGZvbnRcblx0XHRcdGZvbnRTaXplOiAnMTJweCdcblx0XHR9LCBzdHlsZSkpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXRlY3Qgd2hldGhlciB0aGUgcmVuZGVyZXIgaXMgaGlkZGVuLiBUaGlzIGhhcHBlbnMgd2hlbiBvbmUgb2YgdGhlIHBhcmVudCBlbGVtZW50c1xuXHQgKiBoYXMgZGlzcGxheTogbm9uZS4gIzYwOC5cblx0ICovXG5cdGlzSGlkZGVuOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuICF0aGlzLmJveFdyYXBwZXIuZ2V0QkJveCgpLndpZHRoO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95cyB0aGUgcmVuZGVyZXIgYW5kIGl0cyBhbGxvY2F0ZWQgbWVtYmVycy5cblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0cmVuZGVyZXJEZWZzID0gcmVuZGVyZXIuZGVmcztcblx0XHRyZW5kZXJlci5ib3ggPSBudWxsO1xuXHRcdHJlbmRlcmVyLmJveFdyYXBwZXIgPSByZW5kZXJlci5ib3hXcmFwcGVyLmRlc3Ryb3koKTtcblxuXHRcdC8vIENhbGwgZGVzdHJveSBvbiBhbGwgZ3JhZGllbnQgZWxlbWVudHNcblx0XHRkZXN0cm95T2JqZWN0UHJvcGVydGllcyhyZW5kZXJlci5ncmFkaWVudHMgfHwge30pO1xuXHRcdHJlbmRlcmVyLmdyYWRpZW50cyA9IG51bGw7XG5cblx0XHQvLyBEZWZzIGFyZSBudWxsIGluIFZNTFJlbmRlcmVyXG5cdFx0Ly8gT3RoZXJ3aXNlLCBkZXN0cm95IHRoZW0gaGVyZS5cblx0XHRpZiAocmVuZGVyZXJEZWZzKSB7XG5cdFx0XHRyZW5kZXJlci5kZWZzID0gcmVuZGVyZXJEZWZzLmRlc3Ryb3koKTtcblx0XHR9XG5cblx0XHQvLyBSZW1vdmUgc3ViIHBpeGVsIGZpeCBoYW5kbGVyXG5cdFx0Ly8gV2UgbmVlZCB0byBjaGVjayB0aGF0IHRoZXJlIGlzIGEgaGFuZGxlciwgb3RoZXJ3aXNlIGFsbCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCBmb3IgZXZlbnQgJ3Jlc2l6ZScgYXJlIHJlbW92ZWRcblx0XHQvLyBTZWUgaXNzdWUgIzk4MlxuXHRcdGlmIChyZW5kZXJlci5zdWJQaXhlbEZpeCkge1xuXHRcdFx0cmVtb3ZlRXZlbnQod2luLCAncmVzaXplJywgcmVuZGVyZXIuc3ViUGl4ZWxGaXgpO1xuXHRcdH1cblxuXHRcdHJlbmRlcmVyLmFsaWduZWRPYmplY3RzID0gbnVsbDtcblxuXHRcdHJldHVybiBudWxsO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYSB3cmFwcGVyIGZvciBhbiBTVkcgZWxlbWVudFxuXHQgKiBAcGFyYW0ge09iamVjdH0gbm9kZU5hbWVcblx0ICovXG5cdGNyZWF0ZUVsZW1lbnQ6IGZ1bmN0aW9uIChub2RlTmFtZSkge1xuXHRcdHZhciB3cmFwcGVyID0gbmV3IHRoaXMuRWxlbWVudCgpO1xuXHRcdHdyYXBwZXIuaW5pdCh0aGlzLCBub2RlTmFtZSk7XG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIER1bW15IGZ1bmN0aW9uIGZvciB1c2UgaW4gY2FudmFzIHJlbmRlcmVyXG5cdCAqL1xuXHRkcmF3OiBmdW5jdGlvbiAoKSB7fSxcblxuXHQvKipcblx0ICogUGFyc2UgYSBzaW1wbGUgSFRNTCBzdHJpbmcgaW50byBTVkcgdHNwYW5zXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB0ZXh0Tm9kZSBUaGUgcGFyZW50IHRleHQgU1ZHIG5vZGVcblx0ICovXG5cdGJ1aWxkVGV4dDogZnVuY3Rpb24gKHdyYXBwZXIpIHtcblx0XHR2YXIgdGV4dE5vZGUgPSB3cmFwcGVyLmVsZW1lbnQsXG5cdFx0XHRyZW5kZXJlciA9IHRoaXMsXG5cdFx0XHRmb3JFeHBvcnQgPSByZW5kZXJlci5mb3JFeHBvcnQsXG5cdFx0XHR0ZXh0U3RyID0gcGljayh3cmFwcGVyLnRleHRTdHIsICcnKS50b1N0cmluZygpLFxuXHRcdFx0aGFzTWFya3VwID0gdGV4dFN0ci5pbmRleE9mKCc8JykgIT09IC0xLFxuXHRcdFx0bGluZXMsXG5cdFx0XHRjaGlsZE5vZGVzID0gdGV4dE5vZGUuY2hpbGROb2Rlcyxcblx0XHRcdHN0eWxlUmVnZXgsXG5cdFx0XHRocmVmUmVnZXgsXG5cdFx0XHRwYXJlbnRYID0gYXR0cih0ZXh0Tm9kZSwgJ3gnKSxcblx0XHRcdHRleHRTdHlsZXMgPSB3cmFwcGVyLnN0eWxlcyxcblx0XHRcdHdpZHRoID0gd3JhcHBlci50ZXh0V2lkdGgsXG5cdFx0XHR0ZXh0TGluZUhlaWdodCA9IHRleHRTdHlsZXMgJiYgdGV4dFN0eWxlcy5saW5lSGVpZ2h0LFxuXHRcdFx0dGV4dFN0cm9rZSA9IHRleHRTdHlsZXMgJiYgdGV4dFN0eWxlcy5IY1RleHRTdHJva2UsXG5cdFx0XHRpID0gY2hpbGROb2Rlcy5sZW5ndGgsXG5cdFx0XHRnZXRMaW5lSGVpZ2h0ID0gZnVuY3Rpb24gKHRzcGFuKSB7XG5cdFx0XHRcdHJldHVybiB0ZXh0TGluZUhlaWdodCA/IFxuXHRcdFx0XHRcdHBJbnQodGV4dExpbmVIZWlnaHQpIDpcblx0XHRcdFx0XHRyZW5kZXJlci5mb250TWV0cmljcyhcblx0XHRcdFx0XHRcdC8ocHh8ZW0pJC8udGVzdCh0c3BhbiAmJiB0c3Bhbi5zdHlsZS5mb250U2l6ZSkgP1xuXHRcdFx0XHRcdFx0XHR0c3Bhbi5zdHlsZS5mb250U2l6ZSA6XG5cdFx0XHRcdFx0XHRcdCgodGV4dFN0eWxlcyAmJiB0ZXh0U3R5bGVzLmZvbnRTaXplKSB8fCByZW5kZXJlci5zdHlsZS5mb250U2l6ZSB8fCAxMiksXG5cdFx0XHRcdFx0XHR0c3BhblxuXHRcdFx0XHRcdCkuaDtcblx0XHRcdH07XG5cblx0XHQvLy8gcmVtb3ZlIG9sZCB0ZXh0XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0dGV4dE5vZGUucmVtb3ZlQ2hpbGQoY2hpbGROb2Rlc1tpXSk7XG5cdFx0fVxuXG5cdFx0Ly8gU2tpcCB0c3BhbnMsIGFkZCB0ZXh0IGRpcmVjdGx5IHRvIHRleHQgbm9kZS4gVGhlIGZvcmNlVFNwYW4gaXMgYSBob29rIFxuXHRcdC8vIHVzZWQgaW4gdGV4dCBvdXRsaW5lIGhhY2suXG5cdFx0aWYgKCFoYXNNYXJrdXAgJiYgIXRleHRTdHJva2UgJiYgdGV4dFN0ci5pbmRleE9mKCcgJykgPT09IC0xKSB7XG5cdFx0XHR0ZXh0Tm9kZS5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUodGV4dFN0cikpO1xuXHRcdFx0cmV0dXJuO1xuXG5cdFx0Ly8gQ29tcGxleCBzdHJpbmdzLCBhZGQgbW9yZSBsb2dpY1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdHN0eWxlUmVnZXggPSAvPC4qc3R5bGU9XCIoW15cIl0rKVwiLio+Lztcblx0XHRcdGhyZWZSZWdleCA9IC88LipocmVmPVwiKGh0dHBbXlwiXSspXCIuKj4vO1xuXG5cdFx0XHRpZiAod2lkdGggJiYgIXdyYXBwZXIuYWRkZWQpIHtcblx0XHRcdFx0dGhpcy5ib3guYXBwZW5kQ2hpbGQodGV4dE5vZGUpOyAvLyBhdHRhY2ggaXQgdG8gdGhlIERPTSB0byByZWFkIG9mZnNldCB3aWR0aFxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaGFzTWFya3VwKSB7XG5cdFx0XHRcdGxpbmVzID0gdGV4dFN0clxuXHRcdFx0XHRcdC5yZXBsYWNlKC88KGJ8c3Ryb25nKT4vZywgJzxzcGFuIHN0eWxlPVwiZm9udC13ZWlnaHQ6Ym9sZFwiPicpXG5cdFx0XHRcdFx0LnJlcGxhY2UoLzwoaXxlbSk+L2csICc8c3BhbiBzdHlsZT1cImZvbnQtc3R5bGU6aXRhbGljXCI+Jylcblx0XHRcdFx0XHQucmVwbGFjZSgvPGEvZywgJzxzcGFuJylcblx0XHRcdFx0XHQucmVwbGFjZSgvPFxcLyhifHN0cm9uZ3xpfGVtfGEpPi9nLCAnPC9zcGFuPicpXG5cdFx0XHRcdFx0LnNwbGl0KC88YnIuKj8+L2cpO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRsaW5lcyA9IFt0ZXh0U3RyXTtcblx0XHRcdH1cblxuXG5cdFx0XHQvLyByZW1vdmUgZW1wdHkgbGluZSBhdCBlbmRcblx0XHRcdGlmIChsaW5lc1tsaW5lcy5sZW5ndGggLSAxXSA9PT0gJycpIHtcblx0XHRcdFx0bGluZXMucG9wKCk7XG5cdFx0XHR9XG5cblx0XHRcdFxuXHRcdFx0Ly8gYnVpbGQgdGhlIGxpbmVzXG5cdFx0XHRlYWNoKGxpbmVzLCBmdW5jdGlvbiAobGluZSwgbGluZU5vKSB7XG5cdFx0XHRcdHZhciBzcGFucywgc3Bhbk5vID0gMDtcblxuXHRcdFx0XHRsaW5lID0gbGluZS5yZXBsYWNlKC88c3Bhbi9nLCAnfHx8PHNwYW4nKS5yZXBsYWNlKC88XFwvc3Bhbj4vZywgJzwvc3Bhbj58fHwnKTtcblx0XHRcdFx0c3BhbnMgPSBsaW5lLnNwbGl0KCd8fHwnKTtcblxuXHRcdFx0XHRlYWNoKHNwYW5zLCBmdW5jdGlvbiAoc3Bhbikge1xuXHRcdFx0XHRcdGlmIChzcGFuICE9PSAnJyB8fCBzcGFucy5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0XHRcdHZhciBhdHRyaWJ1dGVzID0ge30sXG5cdFx0XHRcdFx0XHRcdHRzcGFuID0gZG9jLmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICd0c3BhbicpLFxuXHRcdFx0XHRcdFx0XHRzcGFuU3R5bGU7IC8vICMzOTBcblx0XHRcdFx0XHRcdGlmIChzdHlsZVJlZ2V4LnRlc3Qoc3BhbikpIHtcblx0XHRcdFx0XHRcdFx0c3BhblN0eWxlID0gc3Bhbi5tYXRjaChzdHlsZVJlZ2V4KVsxXS5yZXBsYWNlKC8oO3wgfF4pY29sb3IoWyA6XSkvLCAnJDFmaWxsJDInKTtcblx0XHRcdFx0XHRcdFx0YXR0cih0c3BhbiwgJ3N0eWxlJywgc3BhblN0eWxlKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmIChocmVmUmVnZXgudGVzdChzcGFuKSAmJiAhZm9yRXhwb3J0KSB7IC8vIE5vdCBmb3IgZXhwb3J0IC0gIzE1Mjlcblx0XHRcdFx0XHRcdFx0YXR0cih0c3BhbiwgJ29uY2xpY2snLCAnbG9jYXRpb24uaHJlZj1cXFwiJyArIHNwYW4ubWF0Y2goaHJlZlJlZ2V4KVsxXSArICdcXFwiJyk7XG5cdFx0XHRcdFx0XHRcdGNzcyh0c3BhbiwgeyBjdXJzb3I6ICdwb2ludGVyJyB9KTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0c3BhbiA9IChzcGFuLnJlcGxhY2UoLzwoLnxcXG4pKj8+L2csICcnKSB8fCAnICcpXG5cdFx0XHRcdFx0XHRcdC5yZXBsYWNlKC8mbHQ7L2csICc8Jylcblx0XHRcdFx0XHRcdFx0LnJlcGxhY2UoLyZndDsvZywgJz4nKTtcblxuXHRcdFx0XHRcdFx0Ly8gTmVzdGVkIHRhZ3MgYXJlbid0IHN1cHBvcnRlZCwgYW5kIGNhdXNlIGNyYXNoIGluIFNhZmFyaSAoIzE1OTYpXG5cdFx0XHRcdFx0XHRpZiAoc3BhbiAhPT0gJyAnKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gYWRkIHRoZSB0ZXh0IG5vZGVcblx0XHRcdFx0XHRcdFx0dHNwYW4uYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKHNwYW4pKTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIXNwYW5ObykgeyAvLyBmaXJzdCBzcGFuIGluIGEgbGluZSwgYWxpZ24gaXQgdG8gdGhlIGxlZnRcblx0XHRcdFx0XHRcdFx0XHRpZiAobGluZU5vICYmIHBhcmVudFggIT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGF0dHJpYnV0ZXMueCA9IHBhcmVudFg7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGF0dHJpYnV0ZXMuZHggPSAwOyAvLyAjMTZcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIGFkZCBhdHRyaWJ1dGVzXG5cdFx0XHRcdFx0XHRcdGF0dHIodHNwYW4sIGF0dHJpYnV0ZXMpO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFwcGVuZCBpdFxuXHRcdFx0XHRcdFx0XHR0ZXh0Tm9kZS5hcHBlbmRDaGlsZCh0c3Bhbik7XG5cblx0XHRcdFx0XHRcdFx0Ly8gZmlyc3Qgc3BhbiBvbiBzdWJzZXF1ZW50IGxpbmUsIGFkZCB0aGUgbGluZSBoZWlnaHRcblx0XHRcdFx0XHRcdFx0aWYgKCFzcGFuTm8gJiYgbGluZU5vKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBhbGxvdyBnZXR0aW5nIHRoZSByaWdodCBvZmZzZXQgaGVpZ2h0IGluIGV4cG9ydGluZyBpbiBJRVxuXHRcdFx0XHRcdFx0XHRcdGlmICghaGFzU1ZHICYmIGZvckV4cG9ydCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3NzKHRzcGFuLCB7IGRpc3BsYXk6ICdibG9jaycgfSk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU2V0IHRoZSBsaW5lIGhlaWdodCBiYXNlZCBvbiB0aGUgZm9udCBzaXplIG9mIGVpdGhlclxuXHRcdFx0XHRcdFx0XHRcdC8vIHRoZSB0ZXh0IGVsZW1lbnQgb3IgdGhlIHRzcGFuIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRhdHRyKFxuXHRcdFx0XHRcdFx0XHRcdFx0dHNwYW4sXG5cdFx0XHRcdFx0XHRcdFx0XHQnZHknLFxuXHRcdFx0XHRcdFx0XHRcdFx0Z2V0TGluZUhlaWdodCh0c3Bhbilcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Ly8gY2hlY2sgd2lkdGggYW5kIGFwcGx5IHNvZnQgYnJlYWtzXG5cdFx0XHRcdFx0XHRcdGlmICh3aWR0aCkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciB3b3JkcyA9IHNwYW4ucmVwbGFjZSgvKFteXFxeXSktL2csICckMS0gJykuc3BsaXQoJyAnKSwgLy8gIzEyNzNcblx0XHRcdFx0XHRcdFx0XHRcdGhhc1doaXRlU3BhY2UgPSBzcGFucy5sZW5ndGggPiAxIHx8ICh3b3Jkcy5sZW5ndGggPiAxICYmIHRleHRTdHlsZXMud2hpdGVTcGFjZSAhPT0gJ25vd3JhcCcpLFxuXHRcdFx0XHRcdFx0XHRcdFx0dG9vTG9uZyxcblx0XHRcdFx0XHRcdFx0XHRcdGFjdHVhbFdpZHRoLFxuXHRcdFx0XHRcdFx0XHRcdFx0aGNIZWlnaHQgPSB0ZXh0U3R5bGVzLkhjSGVpZ2h0LFxuXHRcdFx0XHRcdFx0XHRcdFx0cmVzdCA9IFtdLFxuXHRcdFx0XHRcdFx0XHRcdFx0ZHkgPSBnZXRMaW5lSGVpZ2h0KHRzcGFuKSxcblx0XHRcdFx0XHRcdFx0XHRcdHNvZnRMaW5lTm8gPSAxLFxuXHRcdFx0XHRcdFx0XHRcdFx0YkJveDtcblxuXHRcdFx0XHRcdFx0XHRcdHdoaWxlIChoYXNXaGl0ZVNwYWNlICYmICh3b3Jkcy5sZW5ndGggfHwgcmVzdC5sZW5ndGgpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRkZWxldGUgd3JhcHBlci5iQm94OyAvLyBkZWxldGUgY2FjaGVcblx0XHRcdFx0XHRcdFx0XHRcdGJCb3ggPSB3cmFwcGVyLmdldEJCb3goKTtcblx0XHRcdFx0XHRcdFx0XHRcdGFjdHVhbFdpZHRoID0gYkJveC53aWR0aDtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gT2xkIElFIGNhbm5vdCBtZWFzdXJlIHRoZSBhY3R1YWxXaWR0aCBmb3IgU1ZHIGVsZW1lbnRzICgjMjMxNClcblx0XHRcdFx0XHRcdFx0XHRcdGlmICghaGFzU1ZHICYmIHJlbmRlcmVyLmZvckV4cG9ydCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRhY3R1YWxXaWR0aCA9IHJlbmRlcmVyLm1lYXN1cmVTcGFuV2lkdGgodHNwYW4uZmlyc3RDaGlsZC5kYXRhLCB3cmFwcGVyLnN0eWxlcyk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdHRvb0xvbmcgPSBhY3R1YWxXaWR0aCA+IHdpZHRoO1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCF0b29Mb25nIHx8IHdvcmRzLmxlbmd0aCA9PT0gMSkgeyAvLyBuZXcgbGluZSBuZWVkZWRcblx0XHRcdFx0XHRcdFx0XHRcdFx0d29yZHMgPSByZXN0O1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXN0ID0gW107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICh3b3Jkcy5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzb2Z0TGluZU5vKys7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKGhjSGVpZ2h0ICYmIHNvZnRMaW5lTm8gKiBkeSA+IGhjSGVpZ2h0KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR3b3JkcyA9IFsnLi4uJ107XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR3cmFwcGVyLmF0dHIoJ3RpdGxlJywgd3JhcHBlci50ZXh0U3RyKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0c3BhbiA9IGRvYy5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAndHNwYW4nKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGF0dHIodHNwYW4sIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZHk6IGR5LFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR4OiBwYXJlbnRYXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmIChzcGFuU3R5bGUpIHsgLy8gIzM5MFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhdHRyKHRzcGFuLCAnc3R5bGUnLCBzcGFuU3R5bGUpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0dGV4dE5vZGUuYXBwZW5kQ2hpbGQodHNwYW4pO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoYWN0dWFsV2lkdGggPiB3aWR0aCkgeyAvLyBhIHNpbmdsZSB3b3JkIGlzIHByZXNzaW5nIGl0IG91dFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHdpZHRoID0gYWN0dWFsV2lkdGg7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7IC8vIGFwcGVuZCB0byBleGlzdGluZyBsaW5lIHRzcGFuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRzcGFuLnJlbW92ZUNoaWxkKHRzcGFuLmZpcnN0Q2hpbGQpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXN0LnVuc2hpZnQod29yZHMucG9wKCkpO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKHdvcmRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0c3Bhbi5hcHBlbmRDaGlsZChkb2MuY3JlYXRlVGV4dE5vZGUod29yZHMuam9pbignICcpLnJlcGxhY2UoLy0gL2csICctJykpKTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRzcGFuTm8rKztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYSBidXR0b24gd2l0aCBwcmVzZXQgc3RhdGVzXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSB0ZXh0XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBub3JtYWxTdGF0ZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gaG92ZXJTdGF0ZVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcHJlc3NlZFN0YXRlXG5cdCAqL1xuXHRidXR0b246IGZ1bmN0aW9uICh0ZXh0LCB4LCB5LCBjYWxsYmFjaywgbm9ybWFsU3RhdGUsIGhvdmVyU3RhdGUsIHByZXNzZWRTdGF0ZSwgZGlzYWJsZWRTdGF0ZSwgc2hhcGUpIHtcblx0XHR2YXIgbGFiZWwgPSB0aGlzLmxhYmVsKHRleHQsIHgsIHksIHNoYXBlLCBudWxsLCBudWxsLCBudWxsLCBudWxsLCAnYnV0dG9uJyksXG5cdFx0XHRjdXJTdGF0ZSA9IDAsXG5cdFx0XHRzdGF0ZU9wdGlvbnMsXG5cdFx0XHRzdGF0ZVN0eWxlLFxuXHRcdFx0bm9ybWFsU3R5bGUsXG5cdFx0XHRob3ZlclN0eWxlLFxuXHRcdFx0cHJlc3NlZFN0eWxlLFxuXHRcdFx0ZGlzYWJsZWRTdHlsZSxcblx0XHRcdHZlcnRpY2FsR3JhZGllbnQgPSB7IHgxOiAwLCB5MTogMCwgeDI6IDAsIHkyOiAxIH07XG5cblx0XHQvLyBOb3JtYWwgc3RhdGUgLSBwcmVwYXJlIHRoZSBhdHRyaWJ1dGVzXG5cdFx0bm9ybWFsU3RhdGUgPSBtZXJnZSh7XG5cdFx0XHQnc3Ryb2tlLXdpZHRoJzogMSxcblx0XHRcdHN0cm9rZTogJyNDQ0NDQ0MnLFxuXHRcdFx0ZmlsbDoge1xuXHRcdFx0XHRsaW5lYXJHcmFkaWVudDogdmVydGljYWxHcmFkaWVudCxcblx0XHRcdFx0c3RvcHM6IFtcblx0XHRcdFx0XHRbMCwgJyNGRUZFRkUnXSxcblx0XHRcdFx0XHRbMSwgJyNGNkY2RjYnXVxuXHRcdFx0XHRdXG5cdFx0XHR9LFxuXHRcdFx0cjogMixcblx0XHRcdHBhZGRpbmc6IDUsXG5cdFx0XHRzdHlsZToge1xuXHRcdFx0XHRjb2xvcjogJ2JsYWNrJ1xuXHRcdFx0fVxuXHRcdH0sIG5vcm1hbFN0YXRlKTtcblx0XHRub3JtYWxTdHlsZSA9IG5vcm1hbFN0YXRlLnN0eWxlO1xuXHRcdGRlbGV0ZSBub3JtYWxTdGF0ZS5zdHlsZTtcblxuXHRcdC8vIEhvdmVyIHN0YXRlXG5cdFx0aG92ZXJTdGF0ZSA9IG1lcmdlKG5vcm1hbFN0YXRlLCB7XG5cdFx0XHRzdHJva2U6ICcjNjhBJyxcblx0XHRcdGZpbGw6IHtcblx0XHRcdFx0bGluZWFyR3JhZGllbnQ6IHZlcnRpY2FsR3JhZGllbnQsXG5cdFx0XHRcdHN0b3BzOiBbXG5cdFx0XHRcdFx0WzAsICcjRkZGJ10sXG5cdFx0XHRcdFx0WzEsICcjQUNGJ11cblx0XHRcdFx0XVxuXHRcdFx0fVxuXHRcdH0sIGhvdmVyU3RhdGUpO1xuXHRcdGhvdmVyU3R5bGUgPSBob3ZlclN0YXRlLnN0eWxlO1xuXHRcdGRlbGV0ZSBob3ZlclN0YXRlLnN0eWxlO1xuXG5cdFx0Ly8gUHJlc3NlZCBzdGF0ZVxuXHRcdHByZXNzZWRTdGF0ZSA9IG1lcmdlKG5vcm1hbFN0YXRlLCB7XG5cdFx0XHRzdHJva2U6ICcjNjhBJyxcblx0XHRcdGZpbGw6IHtcblx0XHRcdFx0bGluZWFyR3JhZGllbnQ6IHZlcnRpY2FsR3JhZGllbnQsXG5cdFx0XHRcdHN0b3BzOiBbXG5cdFx0XHRcdFx0WzAsICcjOUJEJ10sXG5cdFx0XHRcdFx0WzEsICcjQ0RGJ11cblx0XHRcdFx0XVxuXHRcdFx0fVxuXHRcdH0sIHByZXNzZWRTdGF0ZSk7XG5cdFx0cHJlc3NlZFN0eWxlID0gcHJlc3NlZFN0YXRlLnN0eWxlO1xuXHRcdGRlbGV0ZSBwcmVzc2VkU3RhdGUuc3R5bGU7XG5cblx0XHQvLyBEaXNhYmxlZCBzdGF0ZVxuXHRcdGRpc2FibGVkU3RhdGUgPSBtZXJnZShub3JtYWxTdGF0ZSwge1xuXHRcdFx0c3R5bGU6IHtcblx0XHRcdFx0Y29sb3I6ICcjQ0NDJ1xuXHRcdFx0fVxuXHRcdH0sIGRpc2FibGVkU3RhdGUpO1xuXHRcdGRpc2FibGVkU3R5bGUgPSBkaXNhYmxlZFN0YXRlLnN0eWxlO1xuXHRcdGRlbGV0ZSBkaXNhYmxlZFN0YXRlLnN0eWxlO1xuXG5cdFx0Ly8gQWRkIHRoZSBldmVudHMuIElFOSBhbmQgSUUxMCBuZWVkIG1vdXNlb3ZlciBhbmQgbW91c2VvdXQgdG8gZnVuY2l0b24gKCM2NjcpLlxuXHRcdGFkZEV2ZW50KGxhYmVsLmVsZW1lbnQsIGlzSUUgPyAnbW91c2VvdmVyJyA6ICdtb3VzZWVudGVyJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKGN1clN0YXRlICE9PSAzKSB7XG5cdFx0XHRcdGxhYmVsLmF0dHIoaG92ZXJTdGF0ZSlcblx0XHRcdFx0XHQuY3NzKGhvdmVyU3R5bGUpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdGFkZEV2ZW50KGxhYmVsLmVsZW1lbnQsIGlzSUUgPyAnbW91c2VvdXQnIDogJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpZiAoY3VyU3RhdGUgIT09IDMpIHtcblx0XHRcdFx0c3RhdGVPcHRpb25zID0gW25vcm1hbFN0YXRlLCBob3ZlclN0YXRlLCBwcmVzc2VkU3RhdGVdW2N1clN0YXRlXTtcblx0XHRcdFx0c3RhdGVTdHlsZSA9IFtub3JtYWxTdHlsZSwgaG92ZXJTdHlsZSwgcHJlc3NlZFN0eWxlXVtjdXJTdGF0ZV07XG5cdFx0XHRcdGxhYmVsLmF0dHIoc3RhdGVPcHRpb25zKVxuXHRcdFx0XHRcdC5jc3Moc3RhdGVTdHlsZSk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRsYWJlbC5zZXRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSkge1xuXHRcdFx0bGFiZWwuc3RhdGUgPSBjdXJTdGF0ZSA9IHN0YXRlO1xuXHRcdFx0aWYgKCFzdGF0ZSkge1xuXHRcdFx0XHRsYWJlbC5hdHRyKG5vcm1hbFN0YXRlKVxuXHRcdFx0XHRcdC5jc3Mobm9ybWFsU3R5bGUpO1xuXHRcdFx0fSBlbHNlIGlmIChzdGF0ZSA9PT0gMikge1xuXHRcdFx0XHRsYWJlbC5hdHRyKHByZXNzZWRTdGF0ZSlcblx0XHRcdFx0XHQuY3NzKHByZXNzZWRTdHlsZSk7XG5cdFx0XHR9IGVsc2UgaWYgKHN0YXRlID09PSAzKSB7XG5cdFx0XHRcdGxhYmVsLmF0dHIoZGlzYWJsZWRTdGF0ZSlcblx0XHRcdFx0XHQuY3NzKGRpc2FibGVkU3R5bGUpO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHRyZXR1cm4gbGFiZWxcblx0XHRcdC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChjdXJTdGF0ZSAhPT0gMykge1xuXHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwobGFiZWwpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LmF0dHIobm9ybWFsU3RhdGUpXG5cdFx0XHQuY3NzKGV4dGVuZCh7IGN1cnNvcjogJ2RlZmF1bHQnIH0sIG5vcm1hbFN0eWxlKSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIE1ha2UgYSBzdHJhaWdodCBsaW5lIGNyaXNwZXIgYnkgbm90IHNwaWxsaW5nIG91dCB0byBuZWlnaGJvdXIgcGl4ZWxzXG5cdCAqIEBwYXJhbSB7QXJyYXl9IHBvaW50c1xuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICovXG5cdGNyaXNwTGluZTogZnVuY3Rpb24gKHBvaW50cywgd2lkdGgpIHtcblx0XHQvLyBwb2ludHMgZm9ybWF0OiBbTSwgMCwgMCwgTCwgMTAwLCAwXVxuXHRcdC8vIG5vcm1hbGl6ZSB0byBhIGNyaXNwIGxpbmVcblx0XHRpZiAocG9pbnRzWzFdID09PSBwb2ludHNbNF0pIHtcblx0XHRcdC8vIFN1YnN0cmFjdCBkdWUgdG8gIzExMjkuIE5vdyBib3R0b20gYW5kIGxlZnQgYXhpcyBncmlkbGluZXMgYmVoYXZlIHRoZSBzYW1lLlxuXHRcdFx0cG9pbnRzWzFdID0gcG9pbnRzWzRdID0gbWF0aFJvdW5kKHBvaW50c1sxXSkgLSAod2lkdGggJSAyIC8gMik7XG5cdFx0fVxuXHRcdGlmIChwb2ludHNbMl0gPT09IHBvaW50c1s1XSkge1xuXHRcdFx0cG9pbnRzWzJdID0gcG9pbnRzWzVdID0gbWF0aFJvdW5kKHBvaW50c1syXSkgKyAod2lkdGggJSAyIC8gMik7XG5cdFx0fVxuXHRcdHJldHVybiBwb2ludHM7XG5cdH0sXG5cblxuXHQvKipcblx0ICogRHJhdyBhIHBhdGhcblx0ICogQHBhcmFtIHtBcnJheX0gcGF0aCBBbiBTVkcgcGF0aCBpbiBhcnJheSBmb3JtXG5cdCAqL1xuXHRwYXRoOiBmdW5jdGlvbiAocGF0aCkge1xuXHRcdHZhciBhdHRyID0ge1xuXHRcdFx0ZmlsbDogTk9ORVxuXHRcdH07XG5cdFx0aWYgKGlzQXJyYXkocGF0aCkpIHtcblx0XHRcdGF0dHIuZCA9IHBhdGg7XG5cdFx0fSBlbHNlIGlmIChpc09iamVjdChwYXRoKSkgeyAvLyBhdHRyaWJ1dGVzXG5cdFx0XHRleHRlbmQoYXR0ciwgcGF0aCk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmNyZWF0ZUVsZW1lbnQoJ3BhdGgnKS5hdHRyKGF0dHIpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IGFuZCByZXR1cm4gYW4gU1ZHIGNpcmNsZVxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBUaGUgeCBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge051bWJlcn0geSBUaGUgeSBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge051bWJlcn0gciBUaGUgcmFkaXVzXG5cdCAqL1xuXHRjaXJjbGU6IGZ1bmN0aW9uICh4LCB5LCByKSB7XG5cdFx0dmFyIGF0dHIgPSBpc09iamVjdCh4KSA/XG5cdFx0XHR4IDpcblx0XHRcdHtcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdFx0cjogclxuXHRcdFx0fSxcblx0XHRcdHdyYXBwZXIgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ2NpcmNsZScpO1xuXG5cdFx0d3JhcHBlci54U2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHR0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKCdjeCcsIHZhbHVlKTtcblx0XHR9O1xuXHRcdHdyYXBwZXIueVNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0dGhpcy5lbGVtZW50LnNldEF0dHJpYnV0ZSgnY3knLCB2YWx1ZSk7XG5cdFx0fTtcblx0XHRyZXR1cm4gd3JhcHBlci5hdHRyKGF0dHIpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IGFuZCByZXR1cm4gYW4gYXJjXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4IFggcG9zaXRpb25cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHkgWSBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge051bWJlcn0gciBSYWRpdXNcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGlubmVyUiBJbm5lciByYWRpdXMgbGlrZSB1c2VkIGluIGRvbnV0IGNoYXJ0c1xuXHQgKiBAcGFyYW0ge051bWJlcn0gc3RhcnQgU3RhcnRpbmcgYW5nbGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGVuZCBFbmRpbmcgYW5nbGVcblx0ICovXG5cdGFyYzogZnVuY3Rpb24gKHgsIHksIHIsIGlubmVyUiwgc3RhcnQsIGVuZCkge1xuXHRcdHZhciBhcmM7XG5cblx0XHRpZiAoaXNPYmplY3QoeCkpIHtcblx0XHRcdHkgPSB4Lnk7XG5cdFx0XHRyID0geC5yO1xuXHRcdFx0aW5uZXJSID0geC5pbm5lclI7XG5cdFx0XHRzdGFydCA9IHguc3RhcnQ7XG5cdFx0XHRlbmQgPSB4LmVuZDtcblx0XHRcdHggPSB4Lng7XG5cdFx0fVxuXG5cdFx0Ly8gQXJjcyBhcmUgZGVmaW5lZCBhcyBzeW1ib2xzIGZvciB0aGUgYWJpbGl0eSB0byBzZXRcblx0XHQvLyBhdHRyaWJ1dGVzIGluIGF0dHIgYW5kIGFuaW1hdGVcblx0XHRhcmMgPSB0aGlzLnN5bWJvbCgnYXJjJywgeCB8fCAwLCB5IHx8IDAsIHIgfHwgMCwgciB8fCAwLCB7XG5cdFx0XHRpbm5lclI6IGlubmVyUiB8fCAwLFxuXHRcdFx0c3RhcnQ6IHN0YXJ0IHx8IDAsXG5cdFx0XHRlbmQ6IGVuZCB8fCAwXG5cdFx0fSk7XG5cdFx0YXJjLnIgPSByOyAvLyAjOTU5XG5cdFx0cmV0dXJuIGFyYztcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyBhbmQgcmV0dXJuIGEgcmVjdGFuZ2xlXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4IExlZnQgcG9zaXRpb25cblx0ICogQHBhcmFtIHtOdW1iZXJ9IHkgVG9wIHBvc2l0aW9uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSByIEJvcmRlciBjb3JuZXIgcmFkaXVzXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBzdHJva2VXaWR0aCBBIHN0cm9rZSB3aWR0aCBjYW4gYmUgc3VwcGxpZWQgdG8gYWxsb3cgY3Jpc3AgZHJhd2luZ1xuXHQgKi9cblx0cmVjdDogZnVuY3Rpb24gKHgsIHksIHdpZHRoLCBoZWlnaHQsIHIsIHN0cm9rZVdpZHRoKSB7XG5cblx0XHRyID0gaXNPYmplY3QoeCkgPyB4LnIgOiByO1xuXG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ3JlY3QnKSxcblx0XHRcdGF0dHJpYnMgPSBpc09iamVjdCh4KSA/IHggOiB4ID09PSBVTkRFRklORUQgPyB7fSA6IHtcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdFx0d2lkdGg6IG1hdGhNYXgod2lkdGgsIDApLFxuXHRcdFx0XHRoZWlnaHQ6IG1hdGhNYXgoaGVpZ2h0LCAwKVxuXHRcdFx0fTtcblxuXHRcdGlmIChzdHJva2VXaWR0aCAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRhdHRyaWJzLnN0cm9rZVdpZHRoID0gc3Ryb2tlV2lkdGg7XG5cdFx0XHRhdHRyaWJzID0gd3JhcHBlci5jcmlzcChhdHRyaWJzKTtcblx0XHR9XG5cblx0XHRpZiAocikge1xuXHRcdFx0YXR0cmlicy5yID0gcjtcblx0XHR9XG5cblx0XHR3cmFwcGVyLnJTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdGF0dHIodGhpcy5lbGVtZW50LCB7XG5cdFx0XHRcdHJ4OiB2YWx1ZSxcblx0XHRcdFx0cnk6IHZhbHVlXG5cdFx0XHR9KTtcblx0XHR9O1xuXHRcdFxuXHRcdHJldHVybiB3cmFwcGVyLmF0dHIoYXR0cmlicyk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlc2l6ZSB0aGUgYm94IGFuZCByZS1hbGlnbiBhbGwgYWxpZ25lZCBlbGVtZW50c1xuXHQgKiBAcGFyYW0ge09iamVjdH0gd2lkdGhcblx0ICogQHBhcmFtIHtPYmplY3R9IGhlaWdodFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IGFuaW1hdGVcblx0ICpcblx0ICovXG5cdHNldFNpemU6IGZ1bmN0aW9uICh3aWR0aCwgaGVpZ2h0LCBhbmltYXRlKSB7XG5cdFx0dmFyIHJlbmRlcmVyID0gdGhpcyxcblx0XHRcdGFsaWduZWRPYmplY3RzID0gcmVuZGVyZXIuYWxpZ25lZE9iamVjdHMsXG5cdFx0XHRpID0gYWxpZ25lZE9iamVjdHMubGVuZ3RoO1xuXG5cdFx0cmVuZGVyZXIud2lkdGggPSB3aWR0aDtcblx0XHRyZW5kZXJlci5oZWlnaHQgPSBoZWlnaHQ7XG5cblx0XHRyZW5kZXJlci5ib3hXcmFwcGVyW3BpY2soYW5pbWF0ZSwgdHJ1ZSkgPyAnYW5pbWF0ZScgOiAnYXR0ciddKHtcblx0XHRcdHdpZHRoOiB3aWR0aCxcblx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0fSk7XG5cblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRhbGlnbmVkT2JqZWN0c1tpXS5hbGlnbigpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIGEgZ3JvdXBcblx0ICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgVGhlIGdyb3VwIHdpbGwgYmUgZ2l2ZW4gYSBjbGFzcyBuYW1lIG9mICdoaWdoY2hhcnRzLXtuYW1lfScuXG5cdCAqICAgICBUaGlzIGNhbiBiZSB1c2VkIGZvciBzdHlsaW5nIGFuZCBzY3JpcHRpbmcuXG5cdCAqL1xuXHRnOiBmdW5jdGlvbiAobmFtZSkge1xuXHRcdHZhciBlbGVtID0gdGhpcy5jcmVhdGVFbGVtZW50KCdnJyk7XG5cdFx0cmV0dXJuIGRlZmluZWQobmFtZSkgPyBlbGVtLmF0dHIoeyAnY2xhc3MnOiBQUkVGSVggKyBuYW1lIH0pIDogZWxlbTtcblx0fSxcblxuXHQvKipcblx0ICogRGlzcGxheSBhbiBpbWFnZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3JjXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqL1xuXHRpbWFnZTogZnVuY3Rpb24gKHNyYywgeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXHRcdHZhciBhdHRyaWJzID0ge1xuXHRcdFx0XHRwcmVzZXJ2ZUFzcGVjdFJhdGlvOiBOT05FXG5cdFx0XHR9LFxuXHRcdFx0ZWxlbVdyYXBwZXI7XG5cblx0XHQvLyBvcHRpb25hbCBwcm9wZXJ0aWVzXG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRleHRlbmQoYXR0cmlicywge1xuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogd2lkdGgsXG5cdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRlbGVtV3JhcHBlciA9IHRoaXMuY3JlYXRlRWxlbWVudCgnaW1hZ2UnKS5hdHRyKGF0dHJpYnMpO1xuXG5cdFx0Ly8gc2V0IHRoZSBocmVmIGluIHRoZSB4bGluayBuYW1lc3BhY2Vcblx0XHRpZiAoZWxlbVdyYXBwZXIuZWxlbWVudC5zZXRBdHRyaWJ1dGVOUykge1xuXHRcdFx0ZWxlbVdyYXBwZXIuZWxlbWVudC5zZXRBdHRyaWJ1dGVOUygnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaycsXG5cdFx0XHRcdCdocmVmJywgc3JjKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gY291bGQgYmUgZXhwb3J0aW5nIGluIElFXG5cdFx0XHQvLyB1c2luZyBocmVmIHRocm93cyBcIm5vdCBzdXBwb3J0ZWRcIiBpbiBpZTcgYW5kIHVuZGVyLCByZXF1cmllcyByZWdleCBzaGltIHRvIGZpeCBsYXRlclxuXHRcdFx0ZWxlbVdyYXBwZXIuZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2hjLXN2Zy1ocmVmJywgc3JjKTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW1XcmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IGEgc3ltYm9sIG91dCBvZiBwcmUtZGVmaW5lZCBzaGFwZSBwYXRocyBmcm9tIHRoZSBuYW1lc3BhY2UgJ3N5bWJvbCcgb2JqZWN0LlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gc3ltYm9sXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB4XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB5XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSByYWRpdXNcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcblx0ICovXG5cdHN5bWJvbDogZnVuY3Rpb24gKHN5bWJvbCwgeCwgeSwgd2lkdGgsIGhlaWdodCwgb3B0aW9ucykge1xuXG5cdFx0dmFyIG9iaixcblxuXHRcdFx0Ly8gZ2V0IHRoZSBzeW1ib2wgZGVmaW5pdGlvbiBmdW5jdGlvblxuXHRcdFx0c3ltYm9sRm4gPSB0aGlzLnN5bWJvbHNbc3ltYm9sXSxcblxuXHRcdFx0Ly8gY2hlY2sgaWYgdGhlcmUncyBhIHBhdGggZGVmaW5lZCBmb3IgdGhpcyBzeW1ib2xcblx0XHRcdHBhdGggPSBzeW1ib2xGbiAmJiBzeW1ib2xGbihcblx0XHRcdFx0bWF0aFJvdW5kKHgpLFxuXHRcdFx0XHRtYXRoUm91bmQoeSksXG5cdFx0XHRcdHdpZHRoLFxuXHRcdFx0XHRoZWlnaHQsXG5cdFx0XHRcdG9wdGlvbnNcblx0XHRcdCksXG5cblx0XHRcdGltYWdlRWxlbWVudCxcblx0XHRcdGltYWdlUmVnZXggPSAvXnVybFxcKCguKj8pXFwpJC8sXG5cdFx0XHRpbWFnZVNyYyxcblx0XHRcdGltYWdlU2l6ZSxcblx0XHRcdGNlbnRlckltYWdlO1xuXG5cdFx0aWYgKHBhdGgpIHtcblxuXHRcdFx0b2JqID0gdGhpcy5wYXRoKHBhdGgpO1xuXHRcdFx0Ly8gZXhwYW5kbyBwcm9wZXJ0aWVzIGZvciB1c2UgaW4gYW5pbWF0ZSBhbmQgYXR0clxuXHRcdFx0ZXh0ZW5kKG9iaiwge1xuXHRcdFx0XHRzeW1ib2xOYW1lOiBzeW1ib2wsXG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHksXG5cdFx0XHRcdHdpZHRoOiB3aWR0aCxcblx0XHRcdFx0aGVpZ2h0OiBoZWlnaHRcblx0XHRcdH0pO1xuXHRcdFx0aWYgKG9wdGlvbnMpIHtcblx0XHRcdFx0ZXh0ZW5kKG9iaiwgb3B0aW9ucyk7XG5cdFx0XHR9XG5cblxuXHRcdC8vIGltYWdlIHN5bWJvbHNcblx0XHR9IGVsc2UgaWYgKGltYWdlUmVnZXgudGVzdChzeW1ib2wpKSB7XG5cblx0XHRcdC8vIE9uIGltYWdlIGxvYWQsIHNldCB0aGUgc2l6ZSBhbmQgcG9zaXRpb25cblx0XHRcdGNlbnRlckltYWdlID0gZnVuY3Rpb24gKGltZywgc2l6ZSkge1xuXHRcdFx0XHRpZiAoaW1nLmVsZW1lbnQpIHsgLy8gaXQgbWF5IGJlIGRlc3Ryb3llZCBpbiB0aGUgbWVhbnRpbWUgKCMxMzkwKVxuXHRcdFx0XHRcdGltZy5hdHRyKHtcblx0XHRcdFx0XHRcdHdpZHRoOiBzaXplWzBdLFxuXHRcdFx0XHRcdFx0aGVpZ2h0OiBzaXplWzFdXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRpZiAoIWltZy5hbGlnbkJ5VHJhbnNsYXRlKSB7IC8vICMxODVcblx0XHRcdFx0XHRcdGltZy50cmFuc2xhdGUoXG5cdFx0XHRcdFx0XHRcdG1hdGhSb3VuZCgod2lkdGggLSBzaXplWzBdKSAvIDIpLCAvLyAjMTM3OFxuXHRcdFx0XHRcdFx0XHRtYXRoUm91bmQoKGhlaWdodCAtIHNpemVbMV0pIC8gMilcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0XHRpbWFnZVNyYyA9IHN5bWJvbC5tYXRjaChpbWFnZVJlZ2V4KVsxXTtcblx0XHRcdGltYWdlU2l6ZSA9IHN5bWJvbFNpemVzW2ltYWdlU3JjXSB8fCAob3B0aW9ucyAmJiBvcHRpb25zLndpZHRoICYmIG9wdGlvbnMuaGVpZ2h0ICYmIFtvcHRpb25zLndpZHRoLCBvcHRpb25zLmhlaWdodF0pO1xuXG5cdFx0XHQvLyBJcmVhdGUgdGhlIGltYWdlIHN5bmNocm9ub3VzbHksIGFkZCBhdHRyaWJzIGFzeW5jXG5cdFx0XHRvYmogPSB0aGlzLmltYWdlKGltYWdlU3JjKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0eDogeCxcblx0XHRcdFx0XHR5OiB5XG5cdFx0XHRcdH0pO1xuXHRcdFx0b2JqLmlzSW1nID0gdHJ1ZTtcblxuXHRcdFx0aWYgKGltYWdlU2l6ZSkge1xuXHRcdFx0XHRjZW50ZXJJbWFnZShvYmosIGltYWdlU2l6ZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBJbml0aWFsaXplIGltYWdlIHRvIGJlIDAgc2l6ZSBzbyBleHBvcnQgd2lsbCBzdGlsbCBmdW5jdGlvbiBpZiB0aGVyZSdzIG5vIGNhY2hlZCBzaXplcy5cblx0XHRcdFx0b2JqLmF0dHIoeyB3aWR0aDogMCwgaGVpZ2h0OiAwIH0pO1xuXG5cdFx0XHRcdC8vIENyZWF0ZSBhIGR1bW15IEphdmFTY3JpcHQgaW1hZ2UgdG8gZ2V0IHRoZSB3aWR0aCBhbmQgaGVpZ2h0LiBEdWUgdG8gYSBidWcgaW4gSUUgPCA4LFxuXHRcdFx0XHQvLyB0aGUgY3JlYXRlZCBlbGVtZW50IG11c3QgYmUgYXNzaWduZWQgdG8gYSB2YXJpYWJsZSBpbiBvcmRlciB0byBsb2FkICgjMjkyKS5cblx0XHRcdFx0aW1hZ2VFbGVtZW50ID0gY3JlYXRlRWxlbWVudCgnaW1nJywge1xuXHRcdFx0XHRcdG9ubG9hZDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0Y2VudGVySW1hZ2Uob2JqLCBzeW1ib2xTaXplc1tpbWFnZVNyY10gPSBbdGhpcy53aWR0aCwgdGhpcy5oZWlnaHRdKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdHNyYzogaW1hZ2VTcmNcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvKipcblx0ICogQW4gZXh0ZW5kYWJsZSBjb2xsZWN0aW9uIG9mIGZ1bmN0aW9ucyBmb3IgZGVmaW5pbmcgc3ltYm9sIHBhdGhzLlxuXHQgKi9cblx0c3ltYm9sczoge1xuXHRcdCdjaXJjbGUnOiBmdW5jdGlvbiAoeCwgeSwgdywgaCkge1xuXHRcdFx0dmFyIGNwdyA9IDAuMTY2ICogdztcblx0XHRcdHJldHVybiBbXG5cdFx0XHRcdE0sIHggKyB3IC8gMiwgeSxcblx0XHRcdFx0J0MnLCB4ICsgdyArIGNwdywgeSwgeCArIHcgKyBjcHcsIHkgKyBoLCB4ICsgdyAvIDIsIHkgKyBoLFxuXHRcdFx0XHQnQycsIHggLSBjcHcsIHkgKyBoLCB4IC0gY3B3LCB5LCB4ICsgdyAvIDIsIHksXG5cdFx0XHRcdCdaJ1xuXHRcdFx0XTtcblx0XHR9LFxuXG5cdFx0J3NxdWFyZSc6IGZ1bmN0aW9uICh4LCB5LCB3LCBoKSB7XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRNLCB4LCB5LFxuXHRcdFx0XHRMLCB4ICsgdywgeSxcblx0XHRcdFx0eCArIHcsIHkgKyBoLFxuXHRcdFx0XHR4LCB5ICsgaCxcblx0XHRcdFx0J1onXG5cdFx0XHRdO1xuXHRcdH0sXG5cblx0XHQndHJpYW5nbGUnOiBmdW5jdGlvbiAoeCwgeSwgdywgaCkge1xuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0TSwgeCArIHcgLyAyLCB5LFxuXHRcdFx0XHRMLCB4ICsgdywgeSArIGgsXG5cdFx0XHRcdHgsIHkgKyBoLFxuXHRcdFx0XHQnWidcblx0XHRcdF07XG5cdFx0fSxcblxuXHRcdCd0cmlhbmdsZS1kb3duJzogZnVuY3Rpb24gKHgsIHksIHcsIGgpIHtcblx0XHRcdHJldHVybiBbXG5cdFx0XHRcdE0sIHgsIHksXG5cdFx0XHRcdEwsIHggKyB3LCB5LFxuXHRcdFx0XHR4ICsgdyAvIDIsIHkgKyBoLFxuXHRcdFx0XHQnWidcblx0XHRcdF07XG5cdFx0fSxcblx0XHQnZGlhbW9uZCc6IGZ1bmN0aW9uICh4LCB5LCB3LCBoKSB7XG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRNLCB4ICsgdyAvIDIsIHksXG5cdFx0XHRcdEwsIHggKyB3LCB5ICsgaCAvIDIsXG5cdFx0XHRcdHggKyB3IC8gMiwgeSArIGgsXG5cdFx0XHRcdHgsIHkgKyBoIC8gMixcblx0XHRcdFx0J1onXG5cdFx0XHRdO1xuXHRcdH0sXG5cdFx0J2FyYyc6IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCBvcHRpb25zKSB7XG5cdFx0XHR2YXIgc3RhcnQgPSBvcHRpb25zLnN0YXJ0LFxuXHRcdFx0XHRyYWRpdXMgPSBvcHRpb25zLnIgfHwgdyB8fCBoLFxuXHRcdFx0XHRlbmQgPSBvcHRpb25zLmVuZCAtIDAuMDAxLCAvLyB0byBwcmV2ZW50IGNvcyBhbmQgc2luIG9mIHN0YXJ0IGFuZCBlbmQgZnJvbSBiZWNvbWluZyBlcXVhbCBvbiAzNjAgYXJjcyAocmVsYXRlZDogIzE1NjEpXG5cdFx0XHRcdGlubmVyUmFkaXVzID0gb3B0aW9ucy5pbm5lclIsXG5cdFx0XHRcdG9wZW4gPSBvcHRpb25zLm9wZW4sXG5cdFx0XHRcdGNvc1N0YXJ0ID0gbWF0aENvcyhzdGFydCksXG5cdFx0XHRcdHNpblN0YXJ0ID0gbWF0aFNpbihzdGFydCksXG5cdFx0XHRcdGNvc0VuZCA9IG1hdGhDb3MoZW5kKSxcblx0XHRcdFx0c2luRW5kID0gbWF0aFNpbihlbmQpLFxuXHRcdFx0XHRsb25nQXJjID0gb3B0aW9ucy5lbmQgLSBzdGFydCA8IG1hdGhQSSA/IDAgOiAxO1xuXG5cdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRNLFxuXHRcdFx0XHR4ICsgcmFkaXVzICogY29zU3RhcnQsXG5cdFx0XHRcdHkgKyByYWRpdXMgKiBzaW5TdGFydCxcblx0XHRcdFx0J0EnLCAvLyBhcmNUb1xuXHRcdFx0XHRyYWRpdXMsIC8vIHggcmFkaXVzXG5cdFx0XHRcdHJhZGl1cywgLy8geSByYWRpdXNcblx0XHRcdFx0MCwgLy8gc2xhbnRpbmdcblx0XHRcdFx0bG9uZ0FyYywgLy8gbG9uZyBvciBzaG9ydCBhcmNcblx0XHRcdFx0MSwgLy8gY2xvY2t3aXNlXG5cdFx0XHRcdHggKyByYWRpdXMgKiBjb3NFbmQsXG5cdFx0XHRcdHkgKyByYWRpdXMgKiBzaW5FbmQsXG5cdFx0XHRcdG9wZW4gPyBNIDogTCxcblx0XHRcdFx0eCArIGlubmVyUmFkaXVzICogY29zRW5kLFxuXHRcdFx0XHR5ICsgaW5uZXJSYWRpdXMgKiBzaW5FbmQsXG5cdFx0XHRcdCdBJywgLy8gYXJjVG9cblx0XHRcdFx0aW5uZXJSYWRpdXMsIC8vIHggcmFkaXVzXG5cdFx0XHRcdGlubmVyUmFkaXVzLCAvLyB5IHJhZGl1c1xuXHRcdFx0XHQwLCAvLyBzbGFudGluZ1xuXHRcdFx0XHRsb25nQXJjLCAvLyBsb25nIG9yIHNob3J0IGFyY1xuXHRcdFx0XHQwLCAvLyBjbG9ja3dpc2Vcblx0XHRcdFx0eCArIGlubmVyUmFkaXVzICogY29zU3RhcnQsXG5cdFx0XHRcdHkgKyBpbm5lclJhZGl1cyAqIHNpblN0YXJ0LFxuXG5cdFx0XHRcdG9wZW4gPyAnJyA6ICdaJyAvLyBjbG9zZVxuXHRcdFx0XTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQ2FsbG91dCBzaGFwZSB1c2VkIGZvciBkZWZhdWx0IHRvb2x0aXBzLCBhbHNvIHVzZWQgZm9yIHJvdW5kZWQgcmVjdGFuZ2xlcyBpbiBWTUxcblx0XHQgKi9cblx0XHRjYWxsb3V0OiBmdW5jdGlvbiAoeCwgeSwgdywgaCwgb3B0aW9ucykge1xuXHRcdFx0dmFyIGFycm93TGVuZ3RoID0gNixcblx0XHRcdFx0aGFsZkRpc3RhbmNlID0gNixcblx0XHRcdFx0ciA9IG1hdGhNaW4oKG9wdGlvbnMgJiYgb3B0aW9ucy5yKSB8fCAwLCB3LCBoKSxcblx0XHRcdFx0c2FmZURpc3RhbmNlID0gciArIGhhbGZEaXN0YW5jZSxcblx0XHRcdFx0YW5jaG9yWCA9IG9wdGlvbnMgJiYgb3B0aW9ucy5hbmNob3JYLFxuXHRcdFx0XHRhbmNob3JZID0gb3B0aW9ucyAmJiBvcHRpb25zLmFuY2hvclksXG5cdFx0XHRcdHBhdGgsXG5cdFx0XHRcdG5vcm1hbGl6ZXIgPSBtYXRoUm91bmQob3B0aW9ucy5zdHJva2VXaWR0aCB8fCAwKSAlIDIgLyAyOyAvLyBtYXRoUm91bmQgYmVjYXVzZSBzdHJva2VXaWR0aCBjYW4gc29tZXRpbWVzIGhhdmUgcm91bmRvZmYgZXJyb3JzO1xuXG5cdFx0XHR4ICs9IG5vcm1hbGl6ZXI7XG5cdFx0XHR5ICs9IG5vcm1hbGl6ZXI7XG5cdFx0XHRwYXRoID0gW1xuXHRcdFx0XHQnTScsIHggKyByLCB5LCBcblx0XHRcdFx0J0wnLCB4ICsgdyAtIHIsIHksIC8vIHRvcCBzaWRlXG5cdFx0XHRcdCdDJywgeCArIHcsIHksIHggKyB3LCB5LCB4ICsgdywgeSArIHIsIC8vIHRvcC1yaWdodCBjb3JuZXJcblx0XHRcdFx0J0wnLCB4ICsgdywgeSArIGggLSByLCAvLyByaWdodCBzaWRlXG5cdFx0XHRcdCdDJywgeCArIHcsIHkgKyBoLCB4ICsgdywgeSArIGgsIHggKyB3IC0gciwgeSArIGgsIC8vIGJvdHRvbS1yaWdodCBjb3JuZXJcblx0XHRcdFx0J0wnLCB4ICsgciwgeSArIGgsIC8vIGJvdHRvbSBzaWRlXG5cdFx0XHRcdCdDJywgeCwgeSArIGgsIHgsIHkgKyBoLCB4LCB5ICsgaCAtIHIsIC8vIGJvdHRvbS1sZWZ0IGNvcm5lclxuXHRcdFx0XHQnTCcsIHgsIHkgKyByLCAvLyBsZWZ0IHNpZGVcblx0XHRcdFx0J0MnLCB4LCB5LCB4LCB5LCB4ICsgciwgeSAvLyB0b3AtcmlnaHQgY29ybmVyXG5cdFx0XHRdO1xuXHRcdFx0XG5cdFx0XHRpZiAoYW5jaG9yWCAmJiBhbmNob3JYID4gdyAmJiBhbmNob3JZID4geSArIHNhZmVEaXN0YW5jZSAmJiBhbmNob3JZIDwgeSArIGggLSBzYWZlRGlzdGFuY2UpIHsgLy8gcmVwbGFjZSByaWdodCBzaWRlXG5cdFx0XHRcdHBhdGguc3BsaWNlKDEzLCAzLFxuXHRcdFx0XHRcdCdMJywgeCArIHcsIGFuY2hvclkgLSBoYWxmRGlzdGFuY2UsIFxuXHRcdFx0XHRcdHggKyB3ICsgYXJyb3dMZW5ndGgsIGFuY2hvclksXG5cdFx0XHRcdFx0eCArIHcsIGFuY2hvclkgKyBoYWxmRGlzdGFuY2UsXG5cdFx0XHRcdFx0eCArIHcsIHkgKyBoIC0gclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIGlmIChhbmNob3JYICYmIGFuY2hvclggPCAwICYmIGFuY2hvclkgPiB5ICsgc2FmZURpc3RhbmNlICYmIGFuY2hvclkgPCB5ICsgaCAtIHNhZmVEaXN0YW5jZSkgeyAvLyByZXBsYWNlIGxlZnQgc2lkZVxuXHRcdFx0XHRwYXRoLnNwbGljZSgzMywgMywgXG5cdFx0XHRcdFx0J0wnLCB4LCBhbmNob3JZICsgaGFsZkRpc3RhbmNlLCBcblx0XHRcdFx0XHR4IC0gYXJyb3dMZW5ndGgsIGFuY2hvclksXG5cdFx0XHRcdFx0eCwgYW5jaG9yWSAtIGhhbGZEaXN0YW5jZSxcblx0XHRcdFx0XHR4LCB5ICsgclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIGlmIChhbmNob3JZICYmIGFuY2hvclkgPiBoICYmIGFuY2hvclggPiB4ICsgc2FmZURpc3RhbmNlICYmIGFuY2hvclggPCB4ICsgdyAtIHNhZmVEaXN0YW5jZSkgeyAvLyByZXBsYWNlIGJvdHRvbVxuXHRcdFx0XHRwYXRoLnNwbGljZSgyMywgMyxcblx0XHRcdFx0XHQnTCcsIGFuY2hvclggKyBoYWxmRGlzdGFuY2UsIHkgKyBoLFxuXHRcdFx0XHRcdGFuY2hvclgsIHkgKyBoICsgYXJyb3dMZW5ndGgsXG5cdFx0XHRcdFx0YW5jaG9yWCAtIGhhbGZEaXN0YW5jZSwgeSArIGgsXG5cdFx0XHRcdFx0eCArIHIsIHkgKyBoXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2UgaWYgKGFuY2hvclkgJiYgYW5jaG9yWSA8IDAgJiYgYW5jaG9yWCA+IHggKyBzYWZlRGlzdGFuY2UgJiYgYW5jaG9yWCA8IHggKyB3IC0gc2FmZURpc3RhbmNlKSB7IC8vIHJlcGxhY2UgdG9wXG5cdFx0XHRcdHBhdGguc3BsaWNlKDMsIDMsXG5cdFx0XHRcdFx0J0wnLCBhbmNob3JYIC0gaGFsZkRpc3RhbmNlLCB5LFxuXHRcdFx0XHRcdGFuY2hvclgsIHkgLSBhcnJvd0xlbmd0aCxcblx0XHRcdFx0XHRhbmNob3JYICsgaGFsZkRpc3RhbmNlLCB5LFxuXHRcdFx0XHRcdHcgLSByLCB5XG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcGF0aDtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlZmluZSBhIGNsaXBwaW5nIHJlY3RhbmdsZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gaWRcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHdpZHRoXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBoZWlnaHRcblx0ICovXG5cdGNsaXBSZWN0OiBmdW5jdGlvbiAoeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXHRcdHZhciB3cmFwcGVyLFxuXHRcdFx0aWQgPSBQUkVGSVggKyBpZENvdW50ZXIrKyxcblxuXHRcdFx0Y2xpcFBhdGggPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ2NsaXBQYXRoJykuYXR0cih7XG5cdFx0XHRcdGlkOiBpZFxuXHRcdFx0fSkuYWRkKHRoaXMuZGVmcyk7XG5cblx0XHR3cmFwcGVyID0gdGhpcy5yZWN0KHgsIHksIHdpZHRoLCBoZWlnaHQsIDApLmFkZChjbGlwUGF0aCk7XG5cdFx0d3JhcHBlci5pZCA9IGlkO1xuXHRcdHdyYXBwZXIuY2xpcFBhdGggPSBjbGlwUGF0aDtcblxuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9LFxuXG5cblx0XG5cblxuXHQvKipcblx0ICogQWRkIHRleHQgdG8gdGhlIFNWRyBvYmplY3Rcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0clxuXHQgKiBAcGFyYW0ge051bWJlcn0geCBMZWZ0IHBvc2l0aW9uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5IFRvcCBwb3NpdGlvblxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHVzZUhUTUwgVXNlIEhUTUwgdG8gcmVuZGVyIHRoZSB0ZXh0XG5cdCAqL1xuXHR0ZXh0OiBmdW5jdGlvbiAoc3RyLCB4LCB5LCB1c2VIVE1MKSB7XG5cblx0XHQvLyBkZWNsYXJlIHZhcmlhYmxlc1xuXHRcdHZhciByZW5kZXJlciA9IHRoaXMsXG5cdFx0XHRmYWtlU1ZHID0gdXNlQ2FuVkcgfHwgKCFoYXNTVkcgJiYgcmVuZGVyZXIuZm9yRXhwb3J0KSxcblx0XHRcdHdyYXBwZXIsXG5cdFx0XHRhdHRyID0ge307XG5cblx0XHRpZiAodXNlSFRNTCAmJiAhcmVuZGVyZXIuZm9yRXhwb3J0KSB7XG5cdFx0XHRyZXR1cm4gcmVuZGVyZXIuaHRtbChzdHIsIHgsIHkpO1xuXHRcdH1cblxuXHRcdGF0dHIueCA9IE1hdGgucm91bmQoeCB8fCAwKTsgLy8gWCBpcyBhbHdheXMgbmVlZGVkIGZvciBsaW5lLXdyYXAgbG9naWNcblx0XHRpZiAoeSkge1xuXHRcdFx0YXR0ci55ID0gTWF0aC5yb3VuZCh5KTtcblx0XHR9XG5cdFx0aWYgKHN0ciB8fCBzdHIgPT09IDApIHtcblx0XHRcdGF0dHIudGV4dCA9IHN0cjtcblx0XHR9XG5cblx0XHR3cmFwcGVyID0gcmVuZGVyZXIuY3JlYXRlRWxlbWVudCgndGV4dCcpXG5cdFx0XHQuYXR0cihhdHRyKTtcblxuXHRcdC8vIFByZXZlbnQgd3JhcHBpbmcgZnJvbSBjcmVhdGluZyBmYWxzZSBvZmZzZXRXaWR0aHMgaW4gZXhwb3J0IGluIGxlZ2FjeSBJRSAoIzEwNzksICMxMDYzKVxuXHRcdGlmIChmYWtlU1ZHKSB7XG5cdFx0XHR3cmFwcGVyLmNzcyh7XG5cdFx0XHRcdHBvc2l0aW9uOiBBQlNPTFVURVxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCF1c2VIVE1MKSB7XG5cdFx0XHR3cmFwcGVyLnhTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdFx0XHR2YXIgdHNwYW5zID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgndHNwYW4nKSxcblx0XHRcdFx0XHR0c3Bhbixcblx0XHRcdFx0XHRwYXJlbnRWYWwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShrZXkpLFxuXHRcdFx0XHRcdGk7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCB0c3BhbnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHR0c3BhbiA9IHRzcGFuc1tpXTtcblx0XHRcdFx0XHQvLyBJZiB0aGUgeCB2YWx1ZXMgYXJlIGVxdWFsLCB0aGUgdHNwYW4gcmVwcmVzZW50cyBhIGxpbmVicmVha1xuXHRcdFx0XHRcdGlmICh0c3Bhbi5nZXRBdHRyaWJ1dGUoa2V5KSA9PT0gcGFyZW50VmFsKSB7XG5cdFx0XHRcdFx0XHR0c3Bhbi5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFV0aWxpdHkgdG8gcmV0dXJuIHRoZSBiYXNlbGluZSBvZmZzZXQgYW5kIHRvdGFsIGxpbmUgaGVpZ2h0IGZyb20gdGhlIGZvbnQgc2l6ZVxuXHQgKi9cblx0Zm9udE1ldHJpY3M6IGZ1bmN0aW9uIChmb250U2l6ZSwgZWxlbSkge1xuXHRcdGZvbnRTaXplID0gZm9udFNpemUgfHwgdGhpcy5zdHlsZS5mb250U2l6ZTtcblx0XHRpZiAoZWxlbSAmJiB3aW4uZ2V0Q29tcHV0ZWRTdHlsZSkge1xuXHRcdFx0ZWxlbSA9IGVsZW0uZWxlbWVudCB8fCBlbGVtOyAvLyBTVkdFbGVtZW50XG5cdFx0XHRmb250U2l6ZSA9IHdpbi5nZXRDb21wdXRlZFN0eWxlKGVsZW0sIFwiXCIpLmZvbnRTaXplO1xuXHRcdH1cblx0XHRmb250U2l6ZSA9IC9weC8udGVzdChmb250U2l6ZSkgPyBwSW50KGZvbnRTaXplKSA6IC9lbS8udGVzdChmb250U2l6ZSkgPyBwYXJzZUZsb2F0KGZvbnRTaXplKSAqIDEyIDogMTI7XG5cblx0XHQvLyBFbXBpcmljYWwgdmFsdWVzIGZvdW5kIGJ5IGNvbXBhcmluZyBmb250IHNpemUgYW5kIGJvdW5kaW5nIGJveCBoZWlnaHQuXG5cdFx0Ly8gQXBwbGllcyB0byB0aGUgZGVmYXVsdCBmb250IGZhbWlseS4gaHR0cDovL2pzZmlkZGxlLm5ldC9oaWdoY2hhcnRzLzd4dm43L1xuXHRcdHZhciBsaW5lSGVpZ2h0ID0gZm9udFNpemUgPCAyNCA/IGZvbnRTaXplICsgNCA6IG1hdGhSb3VuZChmb250U2l6ZSAqIDEuMiksXG5cdFx0XHRiYXNlbGluZSA9IG1hdGhSb3VuZChsaW5lSGVpZ2h0ICogMC44KTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRoOiBsaW5lSGVpZ2h0LFxuXHRcdFx0YjogYmFzZWxpbmUsXG5cdFx0XHRmOiBmb250U2l6ZVxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkZCBhIGxhYmVsLCBhIHRleHQgaXRlbSB0aGF0IGNhbiBob2xkIGEgY29sb3JlZCBvciBncmFkaWVudCBiYWNrZ3JvdW5kXG5cdCAqIGFzIHdlbGwgYXMgYSBib3JkZXIgYW5kIHNoYWRvdy5cblx0ICogQHBhcmFtIHtzdHJpbmd9IHN0clxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc2hhcGVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGFuY2hvclggSW4gY2FzZSB0aGUgc2hhcGUgaGFzIGEgcG9pbnRlciwgbGlrZSBhIGZsYWcsIHRoaXMgaXMgdGhlXG5cdCAqICAgIGNvb3JkaW5hdGVzIGl0IHNob3VsZCBiZSBwaW5uZWQgdG9cblx0ICogQHBhcmFtIHtOdW1iZXJ9IGFuY2hvcllcblx0ICogQHBhcmFtIHtCb29sZWFufSBiYXNlbGluZSBXaGV0aGVyIHRvIHBvc2l0aW9uIHRoZSBsYWJlbCByZWxhdGl2ZSB0byB0aGUgdGV4dCBiYXNlbGluZSxcblx0ICogICAgbGlrZSByZW5kZXJlci50ZXh0LCBvciB0byB0aGUgdXBwZXIgYm9yZGVyIG9mIHRoZSByZWN0YW5nbGUuXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBjbGFzc05hbWUgQ2xhc3MgbmFtZSBmb3IgdGhlIGdyb3VwXG5cdCAqL1xuXHRsYWJlbDogZnVuY3Rpb24gKHN0ciwgeCwgeSwgc2hhcGUsIGFuY2hvclgsIGFuY2hvclksIHVzZUhUTUwsIGJhc2VsaW5lLCBjbGFzc05hbWUpIHtcblxuXHRcdHZhciByZW5kZXJlciA9IHRoaXMsXG5cdFx0XHR3cmFwcGVyID0gcmVuZGVyZXIuZyhjbGFzc05hbWUpLFxuXHRcdFx0dGV4dCA9IHJlbmRlcmVyLnRleHQoJycsIDAsIDAsIHVzZUhUTUwpXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHR6SW5kZXg6IDFcblx0XHRcdFx0fSksXG5cdFx0XHRcdC8vLmFkZCh3cmFwcGVyKSxcblx0XHRcdGJveCxcblx0XHRcdGJCb3gsXG5cdFx0XHRhbGlnbkZhY3RvciA9IDAsXG5cdFx0XHRwYWRkaW5nID0gMyxcblx0XHRcdHBhZGRpbmdMZWZ0ID0gMCxcblx0XHRcdHdpZHRoLFxuXHRcdFx0aGVpZ2h0LFxuXHRcdFx0d3JhcHBlclgsXG5cdFx0XHR3cmFwcGVyWSxcblx0XHRcdGNyaXNwQWRqdXN0ID0gMCxcblx0XHRcdGRlZmVycmVkQXR0ciA9IHt9LFxuXHRcdFx0YmFzZWxpbmVPZmZzZXQsXG5cdFx0XHRuZWVkc0JveDtcblxuXHRcdC8qKlxuXHRcdCAqIFRoaXMgZnVuY3Rpb24gcnVucyBhZnRlciB0aGUgbGFiZWwgaXMgYWRkZWQgdG8gdGhlIERPTSAod2hlbiB0aGUgYm91bmRpbmcgYm94IGlzXG5cdFx0ICogYXZhaWxhYmxlKSwgYW5kIGFmdGVyIHRoZSB0ZXh0IG9mIHRoZSBsYWJlbCBpcyB1cGRhdGVkIHRvIGRldGVjdCB0aGUgbmV3IGJvdW5kaW5nXG5cdFx0ICogYm94IGFuZCByZWZsZWN0IGl0IGluIHRoZSBib3JkZXIgYm94LlxuXHRcdCAqL1xuXHRcdGZ1bmN0aW9uIHVwZGF0ZUJveFNpemUoKSB7XG5cdFx0XHR2YXIgYm94WCxcblx0XHRcdFx0Ym94WSxcblx0XHRcdFx0c3R5bGUgPSB0ZXh0LmVsZW1lbnQuc3R5bGU7XG5cblx0XHRcdGJCb3ggPSAod2lkdGggPT09IHVuZGVmaW5lZCB8fCBoZWlnaHQgPT09IHVuZGVmaW5lZCB8fCB3cmFwcGVyLnN0eWxlcy50ZXh0QWxpZ24pICYmIHRleHQudGV4dFN0ciAmJiBcblx0XHRcdFx0dGV4dC5nZXRCQm94KCk7XG5cdFx0XHR3cmFwcGVyLndpZHRoID0gKHdpZHRoIHx8IGJCb3gud2lkdGggfHwgMCkgKyAyICogcGFkZGluZyArIHBhZGRpbmdMZWZ0O1xuXHRcdFx0d3JhcHBlci5oZWlnaHQgPSAoaGVpZ2h0IHx8IGJCb3guaGVpZ2h0IHx8IDApICsgMiAqIHBhZGRpbmc7XG5cblx0XHRcdC8vIHVwZGF0ZSB0aGUgbGFiZWwtc2NvcGVkIHkgb2Zmc2V0XG5cdFx0XHRiYXNlbGluZU9mZnNldCA9IHBhZGRpbmcgKyByZW5kZXJlci5mb250TWV0cmljcyhzdHlsZSAmJiBzdHlsZS5mb250U2l6ZSwgdGV4dCkuYjtcblxuXHRcdFx0XG5cdFx0XHRpZiAobmVlZHNCb3gpIHtcblxuXHRcdFx0XHQvLyBjcmVhdGUgdGhlIGJvcmRlciBib3ggaWYgaXQgaXMgbm90IGFscmVhZHkgcHJlc2VudFxuXHRcdFx0XHRpZiAoIWJveCkge1xuXHRcdFx0XHRcdGJveFggPSBtYXRoUm91bmQoLWFsaWduRmFjdG9yICogcGFkZGluZyk7XG5cdFx0XHRcdFx0Ym94WSA9IGJhc2VsaW5lID8gLWJhc2VsaW5lT2Zmc2V0IDogMDtcblxuXHRcdFx0XHRcdHdyYXBwZXIuYm94ID0gYm94ID0gc2hhcGUgP1xuXHRcdFx0XHRcdFx0cmVuZGVyZXIuc3ltYm9sKHNoYXBlLCBib3hYLCBib3hZLCB3cmFwcGVyLndpZHRoLCB3cmFwcGVyLmhlaWdodCwgZGVmZXJyZWRBdHRyKSA6XG5cdFx0XHRcdFx0XHRyZW5kZXJlci5yZWN0KGJveFgsIGJveFksIHdyYXBwZXIud2lkdGgsIHdyYXBwZXIuaGVpZ2h0LCAwLCBkZWZlcnJlZEF0dHJbU1RST0tFX1dJRFRIXSk7XG5cdFx0XHRcdFx0Ym94LmF0dHIoJ2ZpbGwnLCBOT05FKS5hZGQod3JhcHBlcik7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBhcHBseSB0aGUgYm94IGF0dHJpYnV0ZXNcblx0XHRcdFx0aWYgKCFib3guaXNJbWcpIHsgLy8gIzE2MzBcblx0XHRcdFx0XHRib3guYXR0cihleHRlbmQoe1xuXHRcdFx0XHRcdFx0d2lkdGg6IG1hdGhSb3VuZCh3cmFwcGVyLndpZHRoKSxcblx0XHRcdFx0XHRcdGhlaWdodDogbWF0aFJvdW5kKHdyYXBwZXIuaGVpZ2h0KVxuXHRcdFx0XHRcdH0sIGRlZmVycmVkQXR0cikpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRlZmVycmVkQXR0ciA9IG51bGw7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogVGhpcyBmdW5jdGlvbiBydW5zIGFmdGVyIHNldHRpbmcgdGV4dCBvciBwYWRkaW5nLCBidXQgb25seSBpZiBwYWRkaW5nIGlzIGNoYW5nZWRcblx0XHQgKi9cblx0XHRmdW5jdGlvbiB1cGRhdGVUZXh0UGFkZGluZygpIHtcblx0XHRcdHZhciBzdHlsZXMgPSB3cmFwcGVyLnN0eWxlcyxcblx0XHRcdFx0dGV4dEFsaWduID0gc3R5bGVzICYmIHN0eWxlcy50ZXh0QWxpZ24sXG5cdFx0XHRcdHggPSBwYWRkaW5nTGVmdCArIHBhZGRpbmcgKiAoMSAtIGFsaWduRmFjdG9yKSxcblx0XHRcdFx0eTtcblxuXHRcdFx0Ly8gZGV0ZXJtaW4geSBiYXNlZCBvbiB0aGUgYmFzZWxpbmVcblx0XHRcdHkgPSBiYXNlbGluZSA/IDAgOiBiYXNlbGluZU9mZnNldDtcblxuXHRcdFx0Ly8gY29tcGVuc2F0ZSBmb3IgYWxpZ25tZW50XG5cdFx0XHRpZiAoZGVmaW5lZCh3aWR0aCkgJiYgYkJveCAmJiAodGV4dEFsaWduID09PSAnY2VudGVyJyB8fCB0ZXh0QWxpZ24gPT09ICdyaWdodCcpKSB7XG5cdFx0XHRcdHggKz0geyBjZW50ZXI6IDAuNSwgcmlnaHQ6IDEgfVt0ZXh0QWxpZ25dICogKHdpZHRoIC0gYkJveC53aWR0aCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHVwZGF0ZSBpZiBhbnl0aGluZyBjaGFuZ2VkXG5cdFx0XHRpZiAoeCAhPT0gdGV4dC54IHx8IHkgIT09IHRleHQueSkge1xuXHRcdFx0XHR0ZXh0LmF0dHIoJ3gnLCB4KTtcblx0XHRcdFx0aWYgKHkgIT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRcdHRleHQuYXR0cigneScsIHkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlY29yZCBjdXJyZW50IHZhbHVlc1xuXHRcdFx0dGV4dC54ID0geDtcblx0XHRcdHRleHQueSA9IHk7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogU2V0IGEgYm94IGF0dHJpYnV0ZSwgb3IgZGVmZXIgaXQgaWYgdGhlIGJveCBpcyBub3QgeWV0IGNyZWF0ZWRcblx0XHQgKiBAcGFyYW0ge09iamVjdH0ga2V5XG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IHZhbHVlXG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gYm94QXR0cihrZXksIHZhbHVlKSB7XG5cdFx0XHRpZiAoYm94KSB7XG5cdFx0XHRcdGJveC5hdHRyKGtleSwgdmFsdWUpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVmZXJyZWRBdHRyW2tleV0gPSB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBBZnRlciB0aGUgdGV4dCBlbGVtZW50IGlzIGFkZGVkLCBnZXQgdGhlIGRlc2lyZWQgc2l6ZSBvZiB0aGUgYm9yZGVyIGJveFxuXHRcdCAqIGFuZCBhZGQgaXQgYmVmb3JlIHRoZSB0ZXh0IGluIHRoZSBET00uXG5cdFx0ICovXG5cdFx0d3JhcHBlci5vbkFkZCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHRleHQuYWRkKHdyYXBwZXIpO1xuXHRcdFx0d3JhcHBlci5hdHRyKHtcblx0XHRcdFx0dGV4dDogKHN0ciB8fCBzdHIgPT09IDApID8gc3RyIDogJycsIC8vIGFsaWdubWVudCBpcyBhdmFpbGFibGUgbm93IC8vICMzMjk1OiAwIG5vdCByZW5kZXJlZCBpZiBnaXZlbiBhcyBhIHZhbHVlXG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHlcblx0XHRcdH0pO1xuXG5cdFx0XHRpZiAoYm94ICYmIGRlZmluZWQoYW5jaG9yWCkpIHtcblx0XHRcdFx0d3JhcHBlci5hdHRyKHtcblx0XHRcdFx0XHRhbmNob3JYOiBhbmNob3JYLFxuXHRcdFx0XHRcdGFuY2hvclk6IGFuY2hvcllcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdC8qXG5cdFx0ICogQWRkIHNwZWNpZmljIGF0dHJpYnV0ZSBzZXR0ZXJzLlxuXHRcdCAqL1xuXG5cdFx0Ly8gb25seSBjaGFuZ2UgbG9jYWwgdmFyaWFibGVzXG5cdFx0d3JhcHBlci53aWR0aFNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0d2lkdGggPSB2YWx1ZTtcblx0XHR9O1xuXHRcdHdyYXBwZXIuaGVpZ2h0U2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRoZWlnaHQgPSB2YWx1ZTtcblx0XHR9O1xuXHRcdHdyYXBwZXIucGFkZGluZ1NldHRlciA9ICBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdGlmIChkZWZpbmVkKHZhbHVlKSAmJiB2YWx1ZSAhPT0gcGFkZGluZykge1xuXHRcdFx0XHRwYWRkaW5nID0gdmFsdWU7XG5cdFx0XHRcdHVwZGF0ZVRleHRQYWRkaW5nKCk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHR3cmFwcGVyLnBhZGRpbmdMZWZ0U2V0dGVyID0gIGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0aWYgKGRlZmluZWQodmFsdWUpICYmIHZhbHVlICE9PSBwYWRkaW5nTGVmdCkge1xuXHRcdFx0XHRwYWRkaW5nTGVmdCA9IHZhbHVlO1xuXHRcdFx0XHR1cGRhdGVUZXh0UGFkZGluZygpO1xuXHRcdFx0fVxuXHRcdH07XG5cblxuXHRcdC8vIGNoYW5nZSBsb2NhbCB2YXJpYWJsZSBhbmQgcHJldmVudCBzZXR0aW5nIGF0dHJpYnV0ZSBvbiB0aGUgZ3JvdXBcblx0XHR3cmFwcGVyLmFsaWduU2V0dGVyID0gZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRhbGlnbkZhY3RvciA9IHsgbGVmdDogMCwgY2VudGVyOiAwLjUsIHJpZ2h0OiAxIH1bdmFsdWVdO1xuXHRcdH07XG5cblx0XHQvLyBhcHBseSB0aGVzZSB0byB0aGUgYm94IGFuZCB0aGUgdGV4dCBhbGlrZVxuXHRcdHdyYXBwZXIudGV4dFNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0aWYgKHZhbHVlICE9PSBVTkRFRklORUQpIHtcblx0XHRcdFx0dGV4dC50ZXh0U2V0dGVyKHZhbHVlKTtcblx0XHRcdH1cblx0XHRcdHVwZGF0ZUJveFNpemUoKTtcblx0XHRcdHVwZGF0ZVRleHRQYWRkaW5nKCk7XG5cdFx0fTtcblxuXHRcdC8vIGFwcGx5IHRoZXNlIHRvIHRoZSBib3ggYnV0IG5vdCB0byB0aGUgdGV4dFxuXHRcdHdyYXBwZXJbJ3N0cm9rZS13aWR0aFNldHRlciddID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHRcdGlmICh2YWx1ZSkge1xuXHRcdFx0XHRuZWVkc0JveCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHRjcmlzcEFkanVzdCA9IHZhbHVlICUgMiAvIDI7XG5cdFx0XHRib3hBdHRyKGtleSwgdmFsdWUpO1xuXHRcdH07XG5cdFx0d3JhcHBlci5zdHJva2VTZXR0ZXIgPSB3cmFwcGVyLmZpbGxTZXR0ZXIgPSB3cmFwcGVyLnJTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0aWYgKGtleSA9PT0gJ2ZpbGwnICYmIHZhbHVlKSB7XG5cdFx0XHRcdG5lZWRzQm94ID0gdHJ1ZTtcblx0XHRcdH1cblx0XHRcdGJveEF0dHIoa2V5LCB2YWx1ZSk7XG5cdFx0fTtcblx0XHR3cmFwcGVyLmFuY2hvclhTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0YW5jaG9yWCA9IHZhbHVlO1xuXHRcdFx0Ym94QXR0cihrZXksIHZhbHVlICsgY3Jpc3BBZGp1c3QgLSB3cmFwcGVyWCk7XG5cdFx0fTtcblx0XHR3cmFwcGVyLmFuY2hvcllTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuXHRcdFx0YW5jaG9yWSA9IHZhbHVlO1xuXHRcdFx0Ym94QXR0cihrZXksIHZhbHVlIC0gd3JhcHBlclkpO1xuXHRcdH07XG5cblx0XHQvLyByZW5hbWUgYXR0cmlidXRlc1xuXHRcdHdyYXBwZXIueFNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdFx0d3JhcHBlci54ID0gdmFsdWU7IC8vIGZvciBhbmltYXRpb24gZ2V0dGVyXG5cdFx0XHRpZiAoYWxpZ25GYWN0b3IpIHtcblx0XHRcdFx0dmFsdWUgLT0gYWxpZ25GYWN0b3IgKiAoKHdpZHRoIHx8IGJCb3gud2lkdGgpICsgcGFkZGluZyk7XG5cdFx0XHR9XG5cdFx0XHR3cmFwcGVyWCA9IG1hdGhSb3VuZCh2YWx1ZSk7XG5cdFx0XHR3cmFwcGVyLmF0dHIoJ3RyYW5zbGF0ZVgnLCB3cmFwcGVyWCk7XG5cdFx0fTtcblx0XHR3cmFwcGVyLnlTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdHdyYXBwZXJZID0gd3JhcHBlci55ID0gbWF0aFJvdW5kKHZhbHVlKTtcblx0XHRcdHdyYXBwZXIuYXR0cigndHJhbnNsYXRlWScsIHdyYXBwZXJZKTtcblx0XHR9O1xuXG5cdFx0Ly8gUmVkaXJlY3QgY2VydGFpbiBtZXRob2RzIHRvIGVpdGhlciB0aGUgYm94IG9yIHRoZSB0ZXh0XG5cdFx0dmFyIGJhc2VDc3MgPSB3cmFwcGVyLmNzcztcblx0XHRyZXR1cm4gZXh0ZW5kKHdyYXBwZXIsIHtcblx0XHRcdC8qKlxuXHRcdFx0ICogUGljayB1cCBzb21lIHByb3BlcnRpZXMgYW5kIGFwcGx5IHRoZW0gdG8gdGhlIHRleHQgaW5zdGVhZCBvZiB0aGUgd3JhcHBlclxuXHRcdFx0ICovXG5cdFx0XHRjc3M6IGZ1bmN0aW9uIChzdHlsZXMpIHtcblx0XHRcdFx0aWYgKHN0eWxlcykge1xuXHRcdFx0XHRcdHZhciB0ZXh0U3R5bGVzID0ge307XG5cdFx0XHRcdFx0c3R5bGVzID0gbWVyZ2Uoc3R5bGVzKTsgLy8gY3JlYXRlIGEgY29weSB0byBhdm9pZCBhbHRlcmluZyB0aGUgb3JpZ2luYWwgb2JqZWN0ICgjNTM3KVxuXHRcdFx0XHRcdGVhY2god3JhcHBlci50ZXh0UHJvcHMsIGZ1bmN0aW9uIChwcm9wKSB7XG5cdFx0XHRcdFx0XHRpZiAoc3R5bGVzW3Byb3BdICE9PSBVTkRFRklORUQpIHtcblx0XHRcdFx0XHRcdFx0dGV4dFN0eWxlc1twcm9wXSA9IHN0eWxlc1twcm9wXTtcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIHN0eWxlc1twcm9wXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR0ZXh0LmNzcyh0ZXh0U3R5bGVzKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gYmFzZUNzcy5jYWxsKHdyYXBwZXIsIHN0eWxlcyk7XG5cdFx0XHR9LFxuXHRcdFx0LyoqXG5cdFx0XHQgKiBSZXR1cm4gdGhlIGJvdW5kaW5nIGJveCBvZiB0aGUgYm94LCBub3QgdGhlIGdyb3VwXG5cdFx0XHQgKi9cblx0XHRcdGdldEJCb3g6IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHR3aWR0aDogYkJveC53aWR0aCArIDIgKiBwYWRkaW5nLFxuXHRcdFx0XHRcdGhlaWdodDogYkJveC5oZWlnaHQgKyAyICogcGFkZGluZyxcblx0XHRcdFx0XHR4OiBiQm94LnggLSBwYWRkaW5nLFxuXHRcdFx0XHRcdHk6IGJCb3gueSAtIHBhZGRpbmdcblx0XHRcdFx0fTtcblx0XHRcdH0sXG5cdFx0XHQvKipcblx0XHRcdCAqIEFwcGx5IHRoZSBzaGFkb3cgdG8gdGhlIGJveFxuXHRcdFx0ICovXG5cdFx0XHRzaGFkb3c6IGZ1bmN0aW9uIChiKSB7XG5cdFx0XHRcdGlmIChib3gpIHtcblx0XHRcdFx0XHRib3guc2hhZG93KGIpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB3cmFwcGVyO1xuXHRcdFx0fSxcblx0XHRcdC8qKlxuXHRcdFx0ICogRGVzdHJveSBhbmQgcmVsZWFzZSBtZW1vcnkuXG5cdFx0XHQgKi9cblx0XHRcdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0XHQvLyBBZGRlZCBieSBidXR0b24gaW1wbGVtZW50YXRpb25cblx0XHRcdFx0cmVtb3ZlRXZlbnQod3JhcHBlci5lbGVtZW50LCAnbW91c2VlbnRlcicpO1xuXHRcdFx0XHRyZW1vdmVFdmVudCh3cmFwcGVyLmVsZW1lbnQsICdtb3VzZWxlYXZlJyk7XG5cblx0XHRcdFx0aWYgKHRleHQpIHtcblx0XHRcdFx0XHR0ZXh0ID0gdGV4dC5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGJveCkge1xuXHRcdFx0XHRcdGJveCA9IGJveC5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8gQ2FsbCBiYXNlIGltcGxlbWVudGF0aW9uIHRvIGRlc3Ryb3kgdGhlIHJlc3Rcblx0XHRcdFx0U1ZHRWxlbWVudC5wcm90b3R5cGUuZGVzdHJveS5jYWxsKHdyYXBwZXIpO1xuXG5cdFx0XHRcdC8vIFJlbGVhc2UgbG9jYWwgcG9pbnRlcnMgKCMxMjk4KVxuXHRcdFx0XHR3cmFwcGVyID0gcmVuZGVyZXIgPSB1cGRhdGVCb3hTaXplID0gdXBkYXRlVGV4dFBhZGRpbmcgPSBib3hBdHRyID0gbnVsbDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufTsgLy8gZW5kIFNWR1JlbmRlcmVyXG5cblxuLy8gZ2VuZXJhbCByZW5kZXJlclxuUmVuZGVyZXIgPSBTVkdSZW5kZXJlcjtcbi8vIGV4dGVuZCBTdmdFbGVtZW50IGZvciB1c2VIVE1MIG9wdGlvblxuZXh0ZW5kKFNWR0VsZW1lbnQucHJvdG90eXBlLCB7XG5cdC8qKlxuXHQgKiBBcHBseSBDU1MgdG8gSFRNTCBlbGVtZW50cy4gVGhpcyBpcyB1c2VkIGluIHRleHQgd2l0aGluIFNWRyByZW5kZXJpbmcgYW5kXG5cdCAqIGJ5IHRoZSBWTUwgcmVuZGVyZXJcblx0ICovXG5cdGh0bWxDc3M6IGZ1bmN0aW9uIChzdHlsZXMpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHRlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0dGV4dFdpZHRoID0gc3R5bGVzICYmIGVsZW1lbnQudGFnTmFtZSA9PT0gJ1NQQU4nICYmIHN0eWxlcy53aWR0aDtcblxuXHRcdGlmICh0ZXh0V2lkdGgpIHtcblx0XHRcdGRlbGV0ZSBzdHlsZXMud2lkdGg7XG5cdFx0XHR3cmFwcGVyLnRleHRXaWR0aCA9IHRleHRXaWR0aDtcblx0XHRcdHdyYXBwZXIudXBkYXRlVHJhbnNmb3JtKCk7XG5cdFx0fVxuXG5cdFx0d3JhcHBlci5zdHlsZXMgPSBleHRlbmQod3JhcHBlci5zdHlsZXMsIHN0eWxlcyk7XG5cdFx0Y3NzKHdyYXBwZXIuZWxlbWVudCwgc3R5bGVzKTtcblxuXHRcdHJldHVybiB3cmFwcGVyO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBWTUwgYW5kIHVzZUhUTUwgbWV0aG9kIGZvciBjYWxjdWxhdGluZyB0aGUgYm91bmRpbmcgYm94IGJhc2VkIG9uIG9mZnNldHNcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWZyZXNoIFdoZXRoZXIgdG8gZm9yY2UgYSBmcmVzaCB2YWx1ZSBmcm9tIHRoZSBET00gb3IgdG9cblx0ICogdXNlIHRoZSBjYWNoZWQgdmFsdWVcblx0ICpcblx0ICogQHJldHVybiB7T2JqZWN0fSBBIGhhc2ggY29udGFpbmluZyB2YWx1ZXMgZm9yIHgsIHksIHdpZHRoIGFuZCBoZWlnaHRcblx0ICovXG5cblx0aHRtbEdldEJCb3g6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgd3JhcHBlciA9IHRoaXMsXG5cdFx0XHRlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0YkJveCA9IHdyYXBwZXIuYkJveDtcblxuXHRcdC8vIGZha2luZyBnZXRCQm94IGluIGV4cG9ydGVkIFNWRyBpbiBsZWdhY3kgSUVcblx0XHRpZiAoIWJCb3gpIHtcblx0XHRcdC8vIGZha2luZyBnZXRCQm94IGluIGV4cG9ydGVkIFNWRyBpbiBsZWdhY3kgSUUgKGlzIHRoaXMgYSBkdXBsaWNhdGUgb2YgdGhlIGZpeCBmb3IgIzEwNzk/KVxuXHRcdFx0aWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICd0ZXh0Jykge1xuXHRcdFx0XHRlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gQUJTT0xVVEU7XG5cdFx0XHR9XG5cblx0XHRcdGJCb3ggPSB3cmFwcGVyLmJCb3ggPSB7XG5cdFx0XHRcdHg6IGVsZW1lbnQub2Zmc2V0TGVmdCxcblx0XHRcdFx0eTogZWxlbWVudC5vZmZzZXRUb3AsXG5cdFx0XHRcdHdpZHRoOiBlbGVtZW50Lm9mZnNldFdpZHRoLFxuXHRcdFx0XHRoZWlnaHQ6IGVsZW1lbnQub2Zmc2V0SGVpZ2h0XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdHJldHVybiBiQm94O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBWTUwgb3ZlcnJpZGUgcHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIGVsZW1lbnRzIGJhc2VkIG9uIGludGVybmFsXG5cdCAqIHByb3BlcnRpZXMgYmFzZWQgb24gU1ZHIHRyYW5zZm9ybVxuXHQgKi9cblx0aHRtbFVwZGF0ZVRyYW5zZm9ybTogZnVuY3Rpb24gKCkge1xuXHRcdC8vIGFsaWduaW5nIG5vbiBhZGRlZCBlbGVtZW50cyBpcyBleHBlbnNpdmVcblx0XHRpZiAoIXRoaXMuYWRkZWQpIHtcblx0XHRcdHRoaXMuYWxpZ25PbkFkZCA9IHRydWU7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0cmVuZGVyZXIgPSB3cmFwcGVyLnJlbmRlcmVyLFxuXHRcdFx0ZWxlbSA9IHdyYXBwZXIuZWxlbWVudCxcblx0XHRcdHRyYW5zbGF0ZVggPSB3cmFwcGVyLnRyYW5zbGF0ZVggfHwgMCxcblx0XHRcdHRyYW5zbGF0ZVkgPSB3cmFwcGVyLnRyYW5zbGF0ZVkgfHwgMCxcblx0XHRcdHggPSB3cmFwcGVyLnggfHwgMCxcblx0XHRcdHkgPSB3cmFwcGVyLnkgfHwgMCxcblx0XHRcdGFsaWduID0gd3JhcHBlci50ZXh0QWxpZ24gfHwgJ2xlZnQnLFxuXHRcdFx0YWxpZ25Db3JyZWN0aW9uID0geyBsZWZ0OiAwLCBjZW50ZXI6IDAuNSwgcmlnaHQ6IDEgfVthbGlnbl0sXG5cdFx0XHRzaGFkb3dzID0gd3JhcHBlci5zaGFkb3dzO1xuXG5cdFx0Ly8gYXBwbHkgdHJhbnNsYXRlXG5cdFx0Y3NzKGVsZW0sIHtcblx0XHRcdG1hcmdpbkxlZnQ6IHRyYW5zbGF0ZVgsXG5cdFx0XHRtYXJnaW5Ub3A6IHRyYW5zbGF0ZVlcblx0XHR9KTtcblx0XHRpZiAoc2hhZG93cykgeyAvLyB1c2VkIGluIGxhYmVscy90b29sdGlwXG5cdFx0XHRlYWNoKHNoYWRvd3MsIGZ1bmN0aW9uIChzaGFkb3cpIHtcblx0XHRcdFx0Y3NzKHNoYWRvdywge1xuXHRcdFx0XHRcdG1hcmdpbkxlZnQ6IHRyYW5zbGF0ZVggKyAxLFxuXHRcdFx0XHRcdG1hcmdpblRvcDogdHJhbnNsYXRlWSArIDFcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvLyBhcHBseSBpbnZlcnNpb25cblx0XHRpZiAod3JhcHBlci5pbnZlcnRlZCkgeyAvLyB3cmFwcGVyIGlzIGEgZ3JvdXBcblx0XHRcdGVhY2goZWxlbS5jaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHtcblx0XHRcdFx0cmVuZGVyZXIuaW52ZXJ0Q2hpbGQoY2hpbGQsIGVsZW0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKGVsZW0udGFnTmFtZSA9PT0gJ1NQQU4nKSB7XG5cblx0XHRcdHZhciB3aWR0aCxcblx0XHRcdFx0cm90YXRpb24gPSB3cmFwcGVyLnJvdGF0aW9uLFxuXHRcdFx0XHRiYXNlbGluZSxcblx0XHRcdFx0dGV4dFdpZHRoID0gcEludCh3cmFwcGVyLnRleHRXaWR0aCksXG5cdFx0XHRcdGN1cnJlbnRUZXh0VHJhbnNmb3JtID0gW3JvdGF0aW9uLCBhbGlnbiwgZWxlbS5pbm5lckhUTUwsIHdyYXBwZXIudGV4dFdpZHRoXS5qb2luKCcsJyk7XG5cblx0XHRcdGlmIChjdXJyZW50VGV4dFRyYW5zZm9ybSAhPT0gd3JhcHBlci5jVFQpIHsgLy8gZG8gdGhlIGNhbGN1bGF0aW9ucyBhbmQgRE9NIGFjY2VzcyBvbmx5IGlmIHByb3BlcnRpZXMgY2hhbmdlZFxuXG5cblx0XHRcdFx0YmFzZWxpbmUgPSByZW5kZXJlci5mb250TWV0cmljcyhlbGVtLnN0eWxlLmZvbnRTaXplKS5iO1xuXG5cdFx0XHRcdC8vIFJlbmRlcmVyIHNwZWNpZmljIGhhbmRsaW5nIG9mIHNwYW4gcm90YXRpb25cblx0XHRcdFx0aWYgKGRlZmluZWQocm90YXRpb24pKSB7XG5cdFx0XHRcdFx0d3JhcHBlci5zZXRTcGFuUm90YXRpb24ocm90YXRpb24sIGFsaWduQ29ycmVjdGlvbiwgYmFzZWxpbmUpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0d2lkdGggPSBwaWNrKHdyYXBwZXIuZWxlbVdpZHRoLCBlbGVtLm9mZnNldFdpZHRoKTtcblxuXHRcdFx0XHQvLyBVcGRhdGUgdGV4dFdpZHRoXG5cdFx0XHRcdGlmICh3aWR0aCA+IHRleHRXaWR0aCAmJiAvWyBcXC1dLy50ZXN0KGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lclRleHQpKSB7IC8vICM5ODMsICMxMjU0XG5cdFx0XHRcdFx0Y3NzKGVsZW0sIHtcblx0XHRcdFx0XHRcdHdpZHRoOiB0ZXh0V2lkdGggKyBQWCxcblx0XHRcdFx0XHRcdGRpc3BsYXk6ICdibG9jaycsXG5cdFx0XHRcdFx0XHR3aGl0ZVNwYWNlOiAnbm9ybWFsJ1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHdpZHRoID0gdGV4dFdpZHRoO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0d3JhcHBlci5nZXRTcGFuQ29ycmVjdGlvbih3aWR0aCwgYmFzZWxpbmUsIGFsaWduQ29ycmVjdGlvbiwgcm90YXRpb24sIGFsaWduKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gYXBwbHkgcG9zaXRpb24gd2l0aCBjb3JyZWN0aW9uXG5cdFx0XHRjc3MoZWxlbSwge1xuXHRcdFx0XHRsZWZ0OiAoeCArICh3cmFwcGVyLnhDb3JyIHx8IDApKSArIFBYLFxuXHRcdFx0XHR0b3A6ICh5ICsgKHdyYXBwZXIueUNvcnIgfHwgMCkpICsgUFhcblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBmb3JjZSByZWZsb3cgaW4gd2Via2l0IHRvIGFwcGx5IHRoZSBsZWZ0IGFuZCB0b3Agb24gdXNlSFRNTCBlbGVtZW50ICgjMTI0OSlcblx0XHRcdGlmIChpc1dlYktpdCkge1xuXHRcdFx0XHRiYXNlbGluZSA9IGVsZW0ub2Zmc2V0SGVpZ2h0OyAvLyBhc3NpZ25lZCB0byBiYXNlbGluZSBmb3IgSlNMaW50IHB1cnBvc2Vcblx0XHRcdH1cblxuXHRcdFx0Ly8gcmVjb3JkIGN1cnJlbnQgdGV4dCB0cmFuc2Zvcm1cblx0XHRcdHdyYXBwZXIuY1RUID0gY3VycmVudFRleHRUcmFuc2Zvcm07XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHJvdGF0aW9uIG9mIGFuIGluZGl2aWR1YWwgSFRNTCBzcGFuXG5cdCAqL1xuXHRzZXRTcGFuUm90YXRpb246IGZ1bmN0aW9uIChyb3RhdGlvbiwgYWxpZ25Db3JyZWN0aW9uLCBiYXNlbGluZSkge1xuXHRcdHZhciByb3RhdGlvblN0eWxlID0ge30sXG5cdFx0XHRjc3NUcmFuc2Zvcm1LZXkgPSBpc0lFID8gJy1tcy10cmFuc2Zvcm0nIDogaXNXZWJLaXQgPyAnLXdlYmtpdC10cmFuc2Zvcm0nIDogaXNGaXJlZm94ID8gJ01velRyYW5zZm9ybScgOiBpc09wZXJhID8gJy1vLXRyYW5zZm9ybScgOiAnJztcblxuXHRcdHJvdGF0aW9uU3R5bGVbY3NzVHJhbnNmb3JtS2V5XSA9IHJvdGF0aW9uU3R5bGUudHJhbnNmb3JtID0gJ3JvdGF0ZSgnICsgcm90YXRpb24gKyAnZGVnKSc7XG5cdFx0cm90YXRpb25TdHlsZVtjc3NUcmFuc2Zvcm1LZXkgKyAoaXNGaXJlZm94ID8gJ09yaWdpbicgOiAnLW9yaWdpbicpXSA9IHJvdGF0aW9uU3R5bGUudHJhbnNmb3JtT3JpZ2luID0gKGFsaWduQ29ycmVjdGlvbiAqIDEwMCkgKyAnJSAnICsgYmFzZWxpbmUgKyAncHgnO1xuXHRcdGNzcyh0aGlzLmVsZW1lbnQsIHJvdGF0aW9uU3R5bGUpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGNvcnJlY3Rpb24gaW4gWCBhbmQgWSBwb3NpdGlvbmluZyBhcyB0aGUgZWxlbWVudCBpcyByb3RhdGVkLlxuXHQgKi9cblx0Z2V0U3BhbkNvcnJlY3Rpb246IGZ1bmN0aW9uICh3aWR0aCwgYmFzZWxpbmUsIGFsaWduQ29ycmVjdGlvbikge1xuXHRcdHRoaXMueENvcnIgPSAtd2lkdGggKiBhbGlnbkNvcnJlY3Rpb247XG5cdFx0dGhpcy55Q29yciA9IC1iYXNlbGluZTtcblx0fVxufSk7XG5cbi8vIEV4dGVuZCBTdmdSZW5kZXJlciBmb3IgdXNlSFRNTCBvcHRpb24uXG5leHRlbmQoU1ZHUmVuZGVyZXIucHJvdG90eXBlLCB7XG5cdC8qKlxuXHQgKiBDcmVhdGUgSFRNTCB0ZXh0IG5vZGUuIFRoaXMgaXMgdXNlZCBieSB0aGUgVk1MIHJlbmRlcmVyIGFzIHdlbGwgYXMgdGhlIFNWR1xuXHQgKiByZW5kZXJlciB0aHJvdWdoIHRoZSB1c2VIVE1MIG9wdGlvbi5cblx0ICpcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0clxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKi9cblx0aHRtbDogZnVuY3Rpb24gKHN0ciwgeCwgeSkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcy5jcmVhdGVFbGVtZW50KCdzcGFuJyksXG5cdFx0XHRlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0cmVuZGVyZXIgPSB3cmFwcGVyLnJlbmRlcmVyO1xuXG5cdFx0Ly8gVGV4dCBzZXR0ZXJcblx0XHR3cmFwcGVyLnRleHRTZXR0ZXIgPSBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHRcdGlmICh2YWx1ZSAhPT0gZWxlbWVudC5pbm5lckhUTUwpIHtcblx0XHRcdFx0ZGVsZXRlIHRoaXMuYkJveDtcblx0XHRcdH1cblx0XHRcdGVsZW1lbnQuaW5uZXJIVE1MID0gdGhpcy50ZXh0U3RyID0gdmFsdWU7XG5cdFx0fTtcblxuXHRcdC8vIFZhcmlvdXMgc2V0dGVycyB3aGljaCByZWx5IG9uIHVwZGF0ZSB0cmFuc2Zvcm1cblx0XHR3cmFwcGVyLnhTZXR0ZXIgPSB3cmFwcGVyLnlTZXR0ZXIgPSB3cmFwcGVyLmFsaWduU2V0dGVyID0gd3JhcHBlci5yb3RhdGlvblNldHRlciA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0XHRpZiAoa2V5ID09PSAnYWxpZ24nKSB7XG5cdFx0XHRcdGtleSA9ICd0ZXh0QWxpZ24nOyAvLyBEbyBub3Qgb3ZlcndyaXRlIHRoZSBTVkdFbGVtZW50LmFsaWduIG1ldGhvZC4gU2FtZSBhcyBWTUwuXG5cdFx0XHR9XG5cdFx0XHR3cmFwcGVyW2tleV0gPSB2YWx1ZTtcblx0XHRcdHdyYXBwZXIuaHRtbFVwZGF0ZVRyYW5zZm9ybSgpO1xuXHRcdH07XG5cblx0XHQvLyBTZXQgdGhlIGRlZmF1bHQgYXR0cmlidXRlc1xuXHRcdHdyYXBwZXIuYXR0cih7XG5cdFx0XHRcdHRleHQ6IHN0cixcblx0XHRcdFx0eDogbWF0aFJvdW5kKHgpLFxuXHRcdFx0XHR5OiBtYXRoUm91bmQoeSlcblx0XHRcdH0pXG5cdFx0XHQuY3NzKHtcblx0XHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0XHR3aGl0ZVNwYWNlOiAnbm93cmFwJyxcblx0XHRcdFx0Zm9udEZhbWlseTogdGhpcy5zdHlsZS5mb250RmFtaWx5LFxuXHRcdFx0XHRmb250U2l6ZTogdGhpcy5zdHlsZS5mb250U2l6ZVxuXHRcdFx0fSk7XG5cblx0XHQvLyBVc2UgdGhlIEhUTUwgc3BlY2lmaWMgLmNzcyBtZXRob2Rcblx0XHR3cmFwcGVyLmNzcyA9IHdyYXBwZXIuaHRtbENzcztcblxuXHRcdC8vIFRoaXMgaXMgc3BlY2lmaWMgZm9yIEhUTUwgd2l0aGluIFNWR1xuXHRcdGlmIChyZW5kZXJlci5pc1NWRykge1xuXHRcdFx0d3JhcHBlci5hZGQgPSBmdW5jdGlvbiAoc3ZnR3JvdXBXcmFwcGVyKSB7XG5cblx0XHRcdFx0dmFyIGh0bWxHcm91cCxcblx0XHRcdFx0XHRjb250YWluZXIgPSByZW5kZXJlci5ib3gucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRwYXJlbnRHcm91cCxcblx0XHRcdFx0XHRwYXJlbnRzID0gW107XG5cblx0XHRcdFx0dGhpcy5wYXJlbnRHcm91cCA9IHN2Z0dyb3VwV3JhcHBlcjtcblxuXHRcdFx0XHQvLyBDcmVhdGUgYSBtb2NrIGdyb3VwIHRvIGhvbGQgdGhlIEhUTUwgZWxlbWVudHNcblx0XHRcdFx0aWYgKHN2Z0dyb3VwV3JhcHBlcikge1xuXHRcdFx0XHRcdGh0bWxHcm91cCA9IHN2Z0dyb3VwV3JhcHBlci5kaXY7XG5cdFx0XHRcdFx0aWYgKCFodG1sR3JvdXApIHtcblxuXHRcdFx0XHRcdFx0Ly8gUmVhZCB0aGUgcGFyZW50IGNoYWluIGludG8gYW4gYXJyYXkgYW5kIHJlYWQgZnJvbSB0b3AgZG93blxuXHRcdFx0XHRcdFx0cGFyZW50R3JvdXAgPSBzdmdHcm91cFdyYXBwZXI7XG5cdFx0XHRcdFx0XHR3aGlsZSAocGFyZW50R3JvdXApIHtcblxuXHRcdFx0XHRcdFx0XHRwYXJlbnRzLnB1c2gocGFyZW50R3JvdXApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIE1vdmUgdXAgdG8gdGhlIG5leHQgcGFyZW50IGdyb3VwXG5cdFx0XHRcdFx0XHRcdHBhcmVudEdyb3VwID0gcGFyZW50R3JvdXAucGFyZW50R3JvdXA7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEVuc3VyZSBkeW5hbWljYWxseSB1cGRhdGluZyBwb3NpdGlvbiB3aGVuIGFueSBwYXJlbnQgaXMgdHJhbnNsYXRlZFxuXHRcdFx0XHRcdFx0ZWFjaChwYXJlbnRzLnJldmVyc2UoKSwgZnVuY3Rpb24gKHBhcmVudEdyb3VwKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBodG1sR3JvdXBTdHlsZTtcblxuXHRcdFx0XHRcdFx0XHQvLyBDcmVhdGUgYSBIVE1MIGRpdiBhbmQgYXBwZW5kIGl0IHRvIHRoZSBwYXJlbnQgZGl2IHRvIGVtdWxhdGVcblx0XHRcdFx0XHRcdFx0Ly8gdGhlIFNWRyBncm91cCBzdHJ1Y3R1cmVcblx0XHRcdFx0XHRcdFx0aHRtbEdyb3VwID0gcGFyZW50R3JvdXAuZGl2ID0gcGFyZW50R3JvdXAuZGl2IHx8IGNyZWF0ZUVsZW1lbnQoRElWLCB7XG5cdFx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lOiBhdHRyKHBhcmVudEdyb3VwLmVsZW1lbnQsICdjbGFzcycpXG5cdFx0XHRcdFx0XHRcdH0sIHtcblx0XHRcdFx0XHRcdFx0XHRwb3NpdGlvbjogQUJTT0xVVEUsXG5cdFx0XHRcdFx0XHRcdFx0bGVmdDogKHBhcmVudEdyb3VwLnRyYW5zbGF0ZVggfHwgMCkgKyBQWCxcblx0XHRcdFx0XHRcdFx0XHR0b3A6IChwYXJlbnRHcm91cC50cmFuc2xhdGVZIHx8IDApICsgUFhcblx0XHRcdFx0XHRcdFx0fSwgaHRtbEdyb3VwIHx8IGNvbnRhaW5lcik7IC8vIHRoZSB0b3AgZ3JvdXAgaXMgYXBwZW5kZWQgdG8gY29udGFpbmVyXG5cblx0XHRcdFx0XHRcdFx0Ly8gU2hvcnRjdXRcblx0XHRcdFx0XHRcdFx0aHRtbEdyb3VwU3R5bGUgPSBodG1sR3JvdXAuc3R5bGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU2V0IGxpc3RlbmVycyB0byB1cGRhdGUgdGhlIEhUTUwgZGl2J3MgcG9zaXRpb24gd2hlbmV2ZXIgdGhlIFNWRyBncm91cFxuXHRcdFx0XHRcdFx0XHQvLyBwb3NpdGlvbiBpcyBjaGFuZ2VkXG5cdFx0XHRcdFx0XHRcdGV4dGVuZChwYXJlbnRHcm91cCwge1xuXHRcdFx0XHRcdFx0XHRcdHRyYW5zbGF0ZVhTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRodG1sR3JvdXBTdHlsZS5sZWZ0ID0gdmFsdWUgKyBQWDtcblx0XHRcdFx0XHRcdFx0XHRcdHBhcmVudEdyb3VwW2tleV0gPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0XHRcdHBhcmVudEdyb3VwLmRvVHJhbnNmb3JtID0gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHRcdHRyYW5zbGF0ZVlTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRodG1sR3JvdXBTdHlsZS50b3AgPSB2YWx1ZSArIFBYO1xuXHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50R3JvdXBba2V5XSA9IHZhbHVlO1xuXHRcdFx0XHRcdFx0XHRcdFx0cGFyZW50R3JvdXAuZG9UcmFuc2Zvcm0gPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcdFx0dmlzaWJpbGl0eVNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHRcdFx0XHRcdFx0XHRcdGh0bWxHcm91cFN0eWxlW2tleV0gPSB2YWx1ZTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aHRtbEdyb3VwID0gY29udGFpbmVyO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aHRtbEdyb3VwLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXG5cdFx0XHRcdC8vIFNoYXJlZCB3aXRoIFZNTDpcblx0XHRcdFx0d3JhcHBlci5hZGRlZCA9IHRydWU7XG5cdFx0XHRcdGlmICh3cmFwcGVyLmFsaWduT25BZGQpIHtcblx0XHRcdFx0XHR3cmFwcGVyLmh0bWxVcGRhdGVUcmFuc2Zvcm0oKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB3cmFwcGVyO1xuXHRcdFx0fTtcblx0XHR9XG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH1cbn0pO1xuXG4vKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBTVEFSVCBPRiBJTlRFUk5FVCBFWFBMT1JFUiA8PSA4IFNQRUNJRklDIENPREUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKiBGb3IgYXBwbGljYXRpb25zIGFuZCB3ZWJzaXRlcyB0aGF0IGRvbid0IG5lZWQgSUUgc3VwcG9ydCwgbGlrZSBwbGF0Zm9ybSAgICAqXG4gKiB0YXJnZXRlZCBtb2JpbGUgYXBwcyBhbmQgd2ViIGFwcHMsIHRoaXMgY29kZSBjYW4gYmUgcmVtb3ZlZC4gICAgICAgICAgICAgICAqXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbi8qKlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBWTUxSZW5kZXJlciwgVk1MRWxlbWVudDtcbmlmICghaGFzU1ZHICYmICF1c2VDYW5WRykge1xuXG4vKipcbiAqIFRoZSBWTUwgZWxlbWVudCB3cmFwcGVyLlxuICovXG5WTUxFbGVtZW50ID0ge1xuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIGEgbmV3IFZNTCBlbGVtZW50IHdyYXBwZXIuIEl0IGJ1aWxkcyB0aGUgbWFya3VwIGFzIGEgc3RyaW5nXG5cdCAqIHRvIG1pbmltaXplIERPTSB0cmFmZmljLlxuXHQgKiBAcGFyYW0ge09iamVjdH0gcmVuZGVyZXJcblx0ICogQHBhcmFtIHtPYmplY3R9IG5vZGVOYW1lXG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAocmVuZGVyZXIsIG5vZGVOYW1lKSB7XG5cdFx0dmFyIHdyYXBwZXIgPSB0aGlzLFxuXHRcdFx0bWFya3VwID0gIFsnPCcsIG5vZGVOYW1lLCAnIGZpbGxlZD1cImZcIiBzdHJva2VkPVwiZlwiJ10sXG5cdFx0XHRzdHlsZSA9IFsncG9zaXRpb246ICcsIEFCU09MVVRFLCAnOyddLFxuXHRcdFx0aXNEaXYgPSBub2RlTmFtZSA9PT0gRElWO1xuXG5cdFx0Ly8gZGl2cyBhbmQgc2hhcGVzIG5lZWQgc2l6ZVxuXHRcdGlmIChub2RlTmFtZSA9PT0gJ3NoYXBlJyB8fCBpc0Rpdikge1xuXHRcdFx0c3R5bGUucHVzaCgnbGVmdDowO3RvcDowO3dpZHRoOjFweDtoZWlnaHQ6MXB4OycpO1xuXHRcdH1cblx0XHRzdHlsZS5wdXNoKCd2aXNpYmlsaXR5OiAnLCBpc0RpdiA/IEhJRERFTiA6IFZJU0lCTEUpO1xuXG5cdFx0bWFya3VwLnB1c2goJyBzdHlsZT1cIicsIHN0eWxlLmpvaW4oJycpLCAnXCIvPicpO1xuXG5cdFx0Ly8gY3JlYXRlIGVsZW1lbnQgd2l0aCBkZWZhdWx0IGF0dHJpYnV0ZXMgYW5kIHN0eWxlXG5cdFx0aWYgKG5vZGVOYW1lKSB7XG5cdFx0XHRtYXJrdXAgPSBpc0RpdiB8fCBub2RlTmFtZSA9PT0gJ3NwYW4nIHx8IG5vZGVOYW1lID09PSAnaW1nJyA/XG5cdFx0XHRcdG1hcmt1cC5qb2luKCcnKVxuXHRcdFx0XHQ6IHJlbmRlcmVyLnByZXBWTUwobWFya3VwKTtcblx0XHRcdHdyYXBwZXIuZWxlbWVudCA9IGNyZWF0ZUVsZW1lbnQobWFya3VwKTtcblx0XHR9XG5cblx0XHR3cmFwcGVyLnJlbmRlcmVyID0gcmVuZGVyZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkZCB0aGUgbm9kZSB0byB0aGUgZ2l2ZW4gcGFyZW50XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnRcblx0ICovXG5cdGFkZDogZnVuY3Rpb24gKHBhcmVudCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdHJlbmRlcmVyID0gd3JhcHBlci5yZW5kZXJlcixcblx0XHRcdGVsZW1lbnQgPSB3cmFwcGVyLmVsZW1lbnQsXG5cdFx0XHRib3ggPSByZW5kZXJlci5ib3gsXG5cdFx0XHRpbnZlcnRlZCA9IHBhcmVudCAmJiBwYXJlbnQuaW52ZXJ0ZWQsXG5cblx0XHRcdC8vIGdldCB0aGUgcGFyZW50IG5vZGVcblx0XHRcdHBhcmVudE5vZGUgPSBwYXJlbnQgP1xuXHRcdFx0XHRwYXJlbnQuZWxlbWVudCB8fCBwYXJlbnQgOlxuXHRcdFx0XHRib3g7XG5cblxuXHRcdC8vIGlmIHRoZSBwYXJlbnQgZ3JvdXAgaXMgaW52ZXJ0ZWQsIGFwcGx5IGludmVyc2lvbiBvbiBhbGwgY2hpbGRyZW5cblx0XHRpZiAoaW52ZXJ0ZWQpIHsgLy8gb25seSBvbiBncm91cHNcblx0XHRcdHJlbmRlcmVyLmludmVydENoaWxkKGVsZW1lbnQsIHBhcmVudE5vZGUpO1xuXHRcdH1cblxuXHRcdC8vIGFwcGVuZCBpdFxuXHRcdHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cblx0XHQvLyBhbGlnbiB0ZXh0IGFmdGVyIGFkZGluZyB0byBiZSBhYmxlIHRvIHJlYWQgb2Zmc2V0XG5cdFx0d3JhcHBlci5hZGRlZCA9IHRydWU7XG5cdFx0aWYgKHdyYXBwZXIuYWxpZ25PbkFkZCAmJiAhd3JhcHBlci5kZWZlclVwZGF0ZVRyYW5zZm9ybSkge1xuXHRcdFx0d3JhcHBlci51cGRhdGVUcmFuc2Zvcm0oKTtcblx0XHR9XG5cblx0XHQvLyBmaXJlIGFuIGV2ZW50IGZvciBpbnRlcm5hbCBob29rc1xuXHRcdGlmICh3cmFwcGVyLm9uQWRkKSB7XG5cdFx0XHR3cmFwcGVyLm9uQWRkKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHdyYXBwZXI7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFZNTCBhbHdheXMgdXNlcyBodG1sVXBkYXRlVHJhbnNmb3JtXG5cdCAqL1xuXHR1cGRhdGVUcmFuc2Zvcm06IFNWR0VsZW1lbnQucHJvdG90eXBlLmh0bWxVcGRhdGVUcmFuc2Zvcm0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgcm90YXRpb24gb2YgYSBzcGFuIHdpdGggb2xkSUUncyBmaWx0ZXJcblx0ICovXG5cdHNldFNwYW5Sb3RhdGlvbjogZnVuY3Rpb24gKCkge1xuXHRcdC8vIEFkanVzdCBmb3IgYWxpZ25tZW50IGFuZCByb3RhdGlvbi4gUm90YXRpb24gb2YgdXNlSFRNTCBjb250ZW50IGlzIG5vdCB5ZXQgaW1wbGVtZW50ZWRcblx0XHQvLyBidXQgaXQgY2FuIHByb2JhYmx5IGJlIGltcGxlbWVudGVkIGZvciBGaXJlZm94IDMuNSsgb24gdXNlciByZXF1ZXN0LiBGRjMuNStcblx0XHQvLyBoYXMgc3VwcG9ydCBmb3IgQ1NTMyB0cmFuc2Zvcm0uIFRoZSBnZXRCQm94IG1ldGhvZCBhbHNvIG5lZWRzIHRvIGJlIHVwZGF0ZWRcblx0XHQvLyB0byBjb21wZW5zYXRlIGZvciB0aGUgcm90YXRpb24sIGxpa2UgaXQgY3VycmVudGx5IGRvZXMgZm9yIFNWRy5cblx0XHQvLyBUZXN0IGNhc2U6IGh0dHA6Ly9qc2ZpZGRsZS5uZXQvaGlnaGNoYXJ0cy9ZYnQ0NC9cblxuXHRcdHZhciByb3RhdGlvbiA9IHRoaXMucm90YXRpb24sXG5cdFx0XHRjb3N0aGV0YSA9IG1hdGhDb3Mocm90YXRpb24gKiBkZWcycmFkKSxcblx0XHRcdHNpbnRoZXRhID0gbWF0aFNpbihyb3RhdGlvbiAqIGRlZzJyYWQpO1xuXHRcdFx0XHRcdFxuXHRcdGNzcyh0aGlzLmVsZW1lbnQsIHtcblx0XHRcdGZpbHRlcjogcm90YXRpb24gPyBbJ3Byb2dpZDpEWEltYWdlVHJhbnNmb3JtLk1pY3Jvc29mdC5NYXRyaXgoTTExPScsIGNvc3RoZXRhLFxuXHRcdFx0XHQnLCBNMTI9JywgLXNpbnRoZXRhLCAnLCBNMjE9Jywgc2ludGhldGEsICcsIE0yMj0nLCBjb3N0aGV0YSxcblx0XHRcdFx0Jywgc2l6aW5nTWV0aG9kPVxcJ2F1dG8gZXhwYW5kXFwnKSddLmpvaW4oJycpIDogTk9ORVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHBvc2l0aW9uaW5nIGNvcnJlY3Rpb24gZm9yIHRoZSBzcGFuIGFmdGVyIHJvdGF0aW5nLiBcblx0ICovXG5cdGdldFNwYW5Db3JyZWN0aW9uOiBmdW5jdGlvbiAod2lkdGgsIGJhc2VsaW5lLCBhbGlnbkNvcnJlY3Rpb24sIHJvdGF0aW9uLCBhbGlnbikge1xuXG5cdFx0dmFyIGNvc3RoZXRhID0gcm90YXRpb24gPyBtYXRoQ29zKHJvdGF0aW9uICogZGVnMnJhZCkgOiAxLFxuXHRcdFx0c2ludGhldGEgPSByb3RhdGlvbiA/IG1hdGhTaW4ocm90YXRpb24gKiBkZWcycmFkKSA6IDAsXG5cdFx0XHRoZWlnaHQgPSBwaWNrKHRoaXMuZWxlbUhlaWdodCwgdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodCksXG5cdFx0XHRxdWFkLFxuXHRcdFx0bm9uTGVmdCA9IGFsaWduICYmIGFsaWduICE9PSAnbGVmdCc7XG5cblx0XHQvLyBjb3JyZWN0IHggYW5kIHlcblx0XHR0aGlzLnhDb3JyID0gY29zdGhldGEgPCAwICYmIC13aWR0aDtcblx0XHR0aGlzLnlDb3JyID0gc2ludGhldGEgPCAwICYmIC1oZWlnaHQ7XG5cblx0XHQvLyBjb3JyZWN0IGZvciBiYXNlbGluZSBhbmQgY29ybmVycyBzcGlsbGluZyBvdXQgYWZ0ZXIgcm90YXRpb25cblx0XHRxdWFkID0gY29zdGhldGEgKiBzaW50aGV0YSA8IDA7XG5cdFx0dGhpcy54Q29yciArPSBzaW50aGV0YSAqIGJhc2VsaW5lICogKHF1YWQgPyAxIC0gYWxpZ25Db3JyZWN0aW9uIDogYWxpZ25Db3JyZWN0aW9uKTtcblx0XHR0aGlzLnlDb3JyIC09IGNvc3RoZXRhICogYmFzZWxpbmUgKiAocm90YXRpb24gPyAocXVhZCA/IGFsaWduQ29ycmVjdGlvbiA6IDEgLSBhbGlnbkNvcnJlY3Rpb24pIDogMSk7XG5cdFx0Ly8gY29ycmVjdCBmb3IgdGhlIGxlbmd0aC9oZWlnaHQgb2YgdGhlIHRleHRcblx0XHRpZiAobm9uTGVmdCkge1xuXHRcdFx0dGhpcy54Q29yciAtPSB3aWR0aCAqIGFsaWduQ29ycmVjdGlvbiAqIChjb3N0aGV0YSA8IDAgPyAtMSA6IDEpO1xuXHRcdFx0aWYgKHJvdGF0aW9uKSB7XG5cdFx0XHRcdHRoaXMueUNvcnIgLT0gaGVpZ2h0ICogYWxpZ25Db3JyZWN0aW9uICogKHNpbnRoZXRhIDwgMCA/IC0xIDogMSk7XG5cdFx0XHR9XG5cdFx0XHRjc3ModGhpcy5lbGVtZW50LCB7XG5cdFx0XHRcdHRleHRBbGlnbjogYWxpZ25cblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQ29udmVydHMgYSBzdWJzZXQgb2YgYW4gU1ZHIHBhdGggZGVmaW5pdGlvbiB0byBpdHMgVk1MIGNvdW50ZXJwYXJ0LiBUYWtlcyBhbiBhcnJheVxuXHQgKiBhcyB0aGUgcGFyYW1ldGVyIGFuZCByZXR1cm5zIGEgc3RyaW5nLlxuXHQgKi9cblx0cGF0aFRvVk1MOiBmdW5jdGlvbiAodmFsdWUpIHtcblx0XHQvLyBjb252ZXJ0IHBhdGhzXG5cdFx0dmFyIGkgPSB2YWx1ZS5sZW5ndGgsXG5cdFx0XHRwYXRoID0gW107XG5cblx0XHR3aGlsZSAoaS0tKSB7XG5cblx0XHRcdC8vIE11bHRpcGx5IGJ5IDEwIHRvIGFsbG93IHN1YnBpeGVsIHByZWNpc2lvbi5cblx0XHRcdC8vIFN1YnN0cmFjdGluZyBoYWxmIGEgcGl4ZWwgc2VlbXMgdG8gbWFrZSB0aGUgY29vcmRpbmF0ZXNcblx0XHRcdC8vIGFsaWduIHdpdGggU1ZHLCBidXQgdGhpcyBoYXNuJ3QgYmVlbiB0ZXN0ZWQgdGhvcm91Z2hseVxuXHRcdFx0aWYgKGlzTnVtYmVyKHZhbHVlW2ldKSkge1xuXHRcdFx0XHRwYXRoW2ldID0gbWF0aFJvdW5kKHZhbHVlW2ldICogMTApIC0gNTtcblx0XHRcdH0gZWxzZSBpZiAodmFsdWVbaV0gPT09ICdaJykgeyAvLyBjbG9zZSB0aGUgcGF0aFxuXHRcdFx0XHRwYXRoW2ldID0gJ3gnO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cGF0aFtpXSA9IHZhbHVlW2ldO1xuXG5cdFx0XHRcdC8vIFdoZW4gdGhlIHN0YXJ0IFggYW5kIGVuZCBYIGNvb3JkaW5hdGVzIG9mIGFuIGFyYyBhcmUgdG9vIGNsb3NlLFxuXHRcdFx0XHQvLyB0aGV5IGFyZSByb3VuZGVkIHRvIHRoZSBzYW1lIHZhbHVlIGFib3ZlLiBJbiB0aGlzIGNhc2UsIHN1YnN0cmFjdCBvciBcblx0XHRcdFx0Ly8gYWRkIDEgZnJvbSB0aGUgZW5kIFggYW5kIFkgcG9zaXRpb25zLiAjMTg2LCAjNzYwLCAjMTM3MSwgIzE0MTAuXG5cdFx0XHRcdGlmICh2YWx1ZS5pc0FyYyAmJiAodmFsdWVbaV0gPT09ICd3YScgfHwgdmFsdWVbaV0gPT09ICdhdCcpKSB7XG5cdFx0XHRcdFx0Ly8gU3RhcnQgYW5kIGVuZCBYXG5cdFx0XHRcdFx0aWYgKHBhdGhbaSArIDVdID09PSBwYXRoW2kgKyA3XSkge1xuXHRcdFx0XHRcdFx0cGF0aFtpICsgN10gKz0gdmFsdWVbaSArIDddID4gdmFsdWVbaSArIDVdID8gMSA6IC0xO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHQvLyBTdGFydCBhbmQgZW5kIFlcblx0XHRcdFx0XHRpZiAocGF0aFtpICsgNl0gPT09IHBhdGhbaSArIDhdKSB7XG5cdFx0XHRcdFx0XHRwYXRoW2kgKyA4XSArPSB2YWx1ZVtpICsgOF0gPiB2YWx1ZVtpICsgNl0gPyAxIDogLTE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0XG5cdFx0Ly8gTG9vcCB1cCBhZ2FpbiB0byBoYW5kbGUgcGF0aCBzaG9ydGN1dHMgKCMyMTMyKVxuXHRcdC8qd2hpbGUgKGkrKyA8IHBhdGgubGVuZ3RoKSB7XG5cdFx0XHRpZiAocGF0aFtpXSA9PT0gJ0gnKSB7IC8vIGhvcml6b250YWwgbGluZSB0b1xuXHRcdFx0XHRwYXRoW2ldID0gJ0wnO1xuXHRcdFx0XHRwYXRoLnNwbGljZShpICsgMiwgMCwgcGF0aFtpIC0gMV0pO1xuXHRcdFx0fSBlbHNlIGlmIChwYXRoW2ldID09PSAnVicpIHsgLy8gdmVydGljYWwgbGluZSB0b1xuXHRcdFx0XHRwYXRoW2ldID0gJ0wnO1xuXHRcdFx0XHRwYXRoLnNwbGljZShpICsgMSwgMCwgcGF0aFtpIC0gMl0pO1xuXHRcdFx0fVxuXHRcdH0qL1xuXHRcdHJldHVybiBwYXRoLmpvaW4oJyAnKSB8fCAneCc7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgZWxlbWVudCdzIGNsaXBwaW5nIHRvIGEgcHJlZGVmaW5lZCByZWN0YW5nbGVcblx0ICpcblx0ICogQHBhcmFtIHtTdHJpbmd9IGlkIFRoZSBpZCBvZiB0aGUgY2xpcCByZWN0YW5nbGVcblx0ICovXG5cdGNsaXA6IGZ1bmN0aW9uIChjbGlwUmVjdCkge1xuXHRcdHZhciB3cmFwcGVyID0gdGhpcyxcblx0XHRcdGNsaXBNZW1iZXJzLFxuXHRcdFx0Y3NzUmV0O1xuXG5cdFx0aWYgKGNsaXBSZWN0KSB7XG5cdFx0XHRjbGlwTWVtYmVycyA9IGNsaXBSZWN0Lm1lbWJlcnM7XG5cdFx0XHRlcmFzZShjbGlwTWVtYmVycywgd3JhcHBlcik7IC8vIEVuc3VyZSB1bmlxdWUgbGlzdCBvZiBlbGVtZW50cyAoIzEyNTgpXG5cdFx0XHRjbGlwTWVtYmVycy5wdXNoKHdyYXBwZXIpO1xuXHRcdFx0d3JhcHBlci5kZXN0cm95Q2xpcCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0ZXJhc2UoY2xpcE1lbWJlcnMsIHdyYXBwZXIpO1xuXHRcdFx0fTtcblx0XHRcdGNzc1JldCA9IGNsaXBSZWN0LmdldENTUyh3cmFwcGVyKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAod3JhcHBlci5kZXN0cm95Q2xpcCkge1xuXHRcdFx0XHR3cmFwcGVyLmRlc3Ryb3lDbGlwKCk7XG5cdFx0XHR9XG5cdFx0XHRjc3NSZXQgPSB7IGNsaXA6IGRvY01vZGU4ID8gJ2luaGVyaXQnIDogJ3JlY3QoYXV0byknIH07IC8vICMxMjE0XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHdyYXBwZXIuY3NzKGNzc1JldCk7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHN0eWxlcyBmb3IgdGhlIGVsZW1lbnRcblx0ICogQHBhcmFtIHtPYmplY3R9IHN0eWxlc1xuXHQgKi9cblx0Y3NzOiBTVkdFbGVtZW50LnByb3RvdHlwZS5odG1sQ3NzLFxuXG5cdC8qKlxuXHQgKiBSZW1vdmVzIGEgY2hpbGQgZWl0aGVyIGJ5IHJlbW92ZUNoaWxkIG9yIG1vdmUgdG8gZ2FyYmFnZUJpbi5cblx0ICogSXNzdWUgNDkwOyBpbiBWTUwgcmVtb3ZlQ2hpbGQgcmVzdWx0cyBpbiBPcnBoYW5lZCBub2RlcyBhY2NvcmRpbmcgdG8gc0lFdmUsIGRpc2NhcmRFbGVtZW50IGRvZXMgbm90LlxuXHQgKi9cblx0c2FmZVJlbW92ZUNoaWxkOiBmdW5jdGlvbiAoZWxlbWVudCkge1xuXHRcdC8vIGRpc2NhcmRFbGVtZW50IHdpbGwgZGV0YWNoIHRoZSBub2RlIGZyb20gaXRzIHBhcmVudCBiZWZvcmUgYXR0YWNoaW5nIGl0XG5cdFx0Ly8gdG8gdGhlIGdhcmJhZ2UgYmluLiBUaGVyZWZvcmUgaXQgaXMgaW1wb3J0YW50IHRoYXQgdGhlIG5vZGUgaXMgYXR0YWNoZWQgYW5kIGhhdmUgcGFyZW50LlxuXHRcdGlmIChlbGVtZW50LnBhcmVudE5vZGUpIHtcblx0XHRcdGRpc2NhcmRFbGVtZW50KGVsZW1lbnQpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRXh0ZW5kIGVsZW1lbnQuZGVzdHJveSBieSByZW1vdmluZyBpdCBmcm9tIHRoZSBjbGlwIG1lbWJlcnMgYXJyYXlcblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAodGhpcy5kZXN0cm95Q2xpcCkge1xuXHRcdFx0dGhpcy5kZXN0cm95Q2xpcCgpO1xuXHRcdH1cblxuXHRcdHJldHVybiBTVkdFbGVtZW50LnByb3RvdHlwZS5kZXN0cm95LmFwcGx5KHRoaXMpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBZGQgYW4gZXZlbnQgbGlzdGVuZXIuIFZNTCBvdmVycmlkZSBmb3Igbm9ybWFsaXppbmcgZXZlbnQgcGFyYW1ldGVycy5cblx0ICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZVxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyXG5cdCAqL1xuXHRvbjogZnVuY3Rpb24gKGV2ZW50VHlwZSwgaGFuZGxlcikge1xuXHRcdC8vIHNpbXBsZXN0IHBvc3NpYmxlIGV2ZW50IG1vZGVsIGZvciBpbnRlcm5hbCB1c2Vcblx0XHR0aGlzLmVsZW1lbnRbJ29uJyArIGV2ZW50VHlwZV0gPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHR2YXIgZXZ0ID0gd2luLmV2ZW50O1xuXHRcdFx0ZXZ0LnRhcmdldCA9IGV2dC5zcmNFbGVtZW50O1xuXHRcdFx0aGFuZGxlcihldnQpO1xuXHRcdH07XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEluIHN0YWNrZWQgY29sdW1ucywgY3V0IG9mZiB0aGUgc2hhZG93cyBzbyB0aGF0IHRoZXkgZG9uJ3Qgb3ZlcmxhcFxuXHQgKi9cblx0Y3V0T2ZmUGF0aDogZnVuY3Rpb24gKHBhdGgsIGxlbmd0aCkge1xuXG5cdFx0dmFyIGxlbjtcblxuXHRcdHBhdGggPSBwYXRoLnNwbGl0KC9bICxdLyk7XG5cdFx0bGVuID0gcGF0aC5sZW5ndGg7XG5cblx0XHRpZiAobGVuID09PSA5IHx8IGxlbiA9PT0gMTEpIHtcblx0XHRcdHBhdGhbbGVuIC0gNF0gPSBwYXRoW2xlbiAtIDJdID0gcEludChwYXRoW2xlbiAtIDJdKSAtIDEwICogbGVuZ3RoO1xuXHRcdH1cblx0XHRyZXR1cm4gcGF0aC5qb2luKCcgJyk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFwcGx5IGEgZHJvcCBzaGFkb3cgYnkgY29weWluZyBlbGVtZW50cyBhbmQgZ2l2aW5nIHRoZW0gZGlmZmVyZW50IHN0cm9rZXNcblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gc2hhZG93T3B0aW9uc1xuXHQgKi9cblx0c2hhZG93OiBmdW5jdGlvbiAoc2hhZG93T3B0aW9ucywgZ3JvdXAsIGN1dE9mZikge1xuXHRcdHZhciBzaGFkb3dzID0gW10sXG5cdFx0XHRpLFxuXHRcdFx0ZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcblx0XHRcdHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlcixcblx0XHRcdHNoYWRvdyxcblx0XHRcdGVsZW1TdHlsZSA9IGVsZW1lbnQuc3R5bGUsXG5cdFx0XHRtYXJrdXAsXG5cdFx0XHRwYXRoID0gZWxlbWVudC5wYXRoLFxuXHRcdFx0c3Ryb2tlV2lkdGgsXG5cdFx0XHRtb2RpZmllZFBhdGgsXG5cdFx0XHRzaGFkb3dXaWR0aCxcblx0XHRcdHNoYWRvd0VsZW1lbnRPcGFjaXR5O1xuXG5cdFx0Ly8gc29tZSB0aW1lcyBlbXB0eSBwYXRocyBhcmUgbm90IHN0cmluZ3Ncblx0XHRpZiAocGF0aCAmJiB0eXBlb2YgcGF0aC52YWx1ZSAhPT0gJ3N0cmluZycpIHtcblx0XHRcdHBhdGggPSAneCc7XG5cdFx0fVxuXHRcdG1vZGlmaWVkUGF0aCA9IHBhdGg7XG5cblx0XHRpZiAoc2hhZG93T3B0aW9ucykge1xuXHRcdFx0c2hhZG93V2lkdGggPSBwaWNrKHNoYWRvd09wdGlvbnMud2lkdGgsIDMpO1xuXHRcdFx0c2hhZG93RWxlbWVudE9wYWNpdHkgPSAoc2hhZG93T3B0aW9ucy5vcGFjaXR5IHx8IDAuMTUpIC8gc2hhZG93V2lkdGg7XG5cdFx0XHRmb3IgKGkgPSAxOyBpIDw9IDM7IGkrKykge1xuXG5cdFx0XHRcdHN0cm9rZVdpZHRoID0gKHNoYWRvd1dpZHRoICogMikgKyAxIC0gKDIgKiBpKTtcblxuXHRcdFx0XHQvLyBDdXQgb2ZmIHNoYWRvd3MgZm9yIHN0YWNrZWQgY29sdW1uIGl0ZW1zXG5cdFx0XHRcdGlmIChjdXRPZmYpIHtcblx0XHRcdFx0XHRtb2RpZmllZFBhdGggPSB0aGlzLmN1dE9mZlBhdGgocGF0aC52YWx1ZSwgc3Ryb2tlV2lkdGggKyAwLjUpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0bWFya3VwID0gWyc8c2hhcGUgaXNTaGFkb3c9XCJ0cnVlXCIgc3Ryb2tld2VpZ2h0PVwiJywgc3Ryb2tlV2lkdGgsXG5cdFx0XHRcdFx0J1wiIGZpbGxlZD1cImZhbHNlXCIgcGF0aD1cIicsIG1vZGlmaWVkUGF0aCxcblx0XHRcdFx0XHQnXCIgY29vcmRzaXplPVwiMTAgMTBcIiBzdHlsZT1cIicsIGVsZW1lbnQuc3R5bGUuY3NzVGV4dCwgJ1wiIC8+J107XG5cblx0XHRcdFx0c2hhZG93ID0gY3JlYXRlRWxlbWVudChyZW5kZXJlci5wcmVwVk1MKG1hcmt1cCksXG5cdFx0XHRcdFx0bnVsbCwge1xuXHRcdFx0XHRcdFx0bGVmdDogcEludChlbGVtU3R5bGUubGVmdCkgKyBwaWNrKHNoYWRvd09wdGlvbnMub2Zmc2V0WCwgMSksXG5cdFx0XHRcdFx0XHR0b3A6IHBJbnQoZWxlbVN0eWxlLnRvcCkgKyBwaWNrKHNoYWRvd09wdGlvbnMub2Zmc2V0WSwgMSlcblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cdFx0XHRcdGlmIChjdXRPZmYpIHtcblx0XHRcdFx0XHRzaGFkb3cuY3V0T2ZmID0gc3Ryb2tlV2lkdGggKyAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gYXBwbHkgdGhlIG9wYWNpdHlcblx0XHRcdFx0bWFya3VwID0gWyc8c3Ryb2tlIGNvbG9yPVwiJywgc2hhZG93T3B0aW9ucy5jb2xvciB8fCAnYmxhY2snLCAnXCIgb3BhY2l0eT1cIicsIHNoYWRvd0VsZW1lbnRPcGFjaXR5ICogaSwgJ1wiLz4nXTtcblx0XHRcdFx0Y3JlYXRlRWxlbWVudChyZW5kZXJlci5wcmVwVk1MKG1hcmt1cCksIG51bGwsIG51bGwsIHNoYWRvdyk7XG5cblxuXHRcdFx0XHQvLyBpbnNlcnQgaXRcblx0XHRcdFx0aWYgKGdyb3VwKSB7XG5cdFx0XHRcdFx0Z3JvdXAuZWxlbWVudC5hcHBlbmRDaGlsZChzaGFkb3cpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2hhZG93LCBlbGVtZW50KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIHJlY29yZCBpdFxuXHRcdFx0XHRzaGFkb3dzLnB1c2goc2hhZG93KTtcblxuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNoYWRvd3MgPSBzaGFkb3dzO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblx0dXBkYXRlU2hhZG93czogbm9vcCwgLy8gVXNlZCBpbiBTVkcgb25seVxuXG5cdHNldEF0dHI6IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XG5cdFx0aWYgKGRvY01vZGU4KSB7IC8vIElFOCBzZXRBdHRyaWJ1dGUgYnVnXG5cdFx0XHR0aGlzLmVsZW1lbnRba2V5XSA9IHZhbHVlO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmVsZW1lbnQuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpO1xuXHRcdH1cblx0fSxcblx0Y2xhc3NTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSkge1xuXHRcdC8vIElFOCBTdGFuZGFyZHMgbW9kZSBoYXMgcHJvYmxlbXMgcmV0cmlldmluZyB0aGUgY2xhc3NOYW1lIHVubGVzcyBzZXQgbGlrZSB0aGlzXG5cdFx0dGhpcy5lbGVtZW50LmNsYXNzTmFtZSA9IHZhbHVlO1xuXHR9LFxuXHRkYXNoc3R5bGVTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0dmFyIHN0cm9rZUVsZW0gPSBlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzdHJva2UnKVswXSB8fFxuXHRcdFx0Y3JlYXRlRWxlbWVudCh0aGlzLnJlbmRlcmVyLnByZXBWTUwoWyc8c3Ryb2tlLz4nXSksIG51bGwsIG51bGwsIGVsZW1lbnQpO1xuXHRcdHN0cm9rZUVsZW1ba2V5XSA9IHZhbHVlIHx8ICdzb2xpZCc7XG5cdFx0dGhpc1trZXldID0gdmFsdWU7IC8qIGJlY2F1c2UgY2hhbmdpbmcgc3Ryb2tlLXdpZHRoIHdpbGwgY2hhbmdlIHRoZSBkYXNoIGxlbmd0aFxuXHRcdFx0YW5kIGNhdXNlIGFuIGVwaWxlcHRpYyBlZmZlY3QgKi9cblx0fSxcblx0ZFNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHR2YXIgaSxcblx0XHRcdHNoYWRvd3MgPSB0aGlzLnNoYWRvd3M7XG5cdFx0dmFsdWUgPSB2YWx1ZSB8fCBbXTtcblx0XHR0aGlzLmQgPSB2YWx1ZS5qb2luICYmIHZhbHVlLmpvaW4oJyAnKTsgLy8gdXNlZCBpbiBnZXR0ZXIgZm9yIGFuaW1hdGlvblxuXG5cdFx0ZWxlbWVudC5wYXRoID0gdmFsdWUgPSB0aGlzLnBhdGhUb1ZNTCh2YWx1ZSk7XG5cblx0XHQvLyB1cGRhdGUgc2hhZG93c1xuXHRcdGlmIChzaGFkb3dzKSB7XG5cdFx0XHRpID0gc2hhZG93cy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdHNoYWRvd3NbaV0ucGF0aCA9IHNoYWRvd3NbaV0uY3V0T2ZmID8gdGhpcy5jdXRPZmZQYXRoKHZhbHVlLCBzaGFkb3dzW2ldLmN1dE9mZikgOiB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dGhpcy5zZXRBdHRyKGtleSwgdmFsdWUpO1xuXHR9LFxuXHRmaWxsU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdHZhciBub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWU7XG5cdFx0aWYgKG5vZGVOYW1lID09PSAnU1BBTicpIHsgLy8gdGV4dCBjb2xvclxuXHRcdFx0ZWxlbWVudC5zdHlsZS5jb2xvciA9IHZhbHVlO1xuXHRcdH0gZWxzZSBpZiAobm9kZU5hbWUgIT09ICdJTUcnKSB7IC8vICMxMzM2XG5cdFx0XHRlbGVtZW50LmZpbGxlZCA9IHZhbHVlICE9PSBOT05FO1xuXHRcdFx0dGhpcy5zZXRBdHRyKCdmaWxsY29sb3InLCB0aGlzLnJlbmRlcmVyLmNvbG9yKHZhbHVlLCBlbGVtZW50LCBrZXksIHRoaXMpKTtcblx0XHR9XG5cdH0sXG5cdG9wYWNpdHlTZXR0ZXI6IG5vb3AsIC8vIERvbid0IGJvdGhlciAtIGFuaW1hdGlvbiBpcyB0b28gc2xvdyBhbmQgZmlsdGVycyBpbnRyb2R1Y2UgYXJ0aWZhY3RzXG5cdHJvdGF0aW9uU2V0dGVyOiBmdW5jdGlvbiAodmFsdWUsIGtleSwgZWxlbWVudCkge1xuXHRcdHZhciBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7XG5cdFx0dGhpc1trZXldID0gc3R5bGVba2V5XSA9IHZhbHVlOyAvLyBzdHlsZSBpcyBmb3IgIzE4NzNcblxuXHRcdC8vIENvcnJlY3Rpb24gZm9yIHRoZSAxeDEgc2l6ZSBvZiB0aGUgc2hhcGUgY29udGFpbmVyLiBVc2VkIGluIGdhdWdlIG5lZWRsZXMuXG5cdFx0c3R5bGUubGVmdCA9IC1tYXRoUm91bmQobWF0aFNpbih2YWx1ZSAqIGRlZzJyYWQpICsgMSkgKyBQWDtcblx0XHRzdHlsZS50b3AgPSBtYXRoUm91bmQobWF0aENvcyh2YWx1ZSAqIGRlZzJyYWQpKSArIFBYO1xuXHR9LFxuXHRzdHJva2VTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0dGhpcy5zZXRBdHRyKCdzdHJva2Vjb2xvcicsIHRoaXMucmVuZGVyZXIuY29sb3IodmFsdWUsIGVsZW1lbnQsIGtleSkpO1xuXHR9LFxuXHQnc3Ryb2tlLXdpZHRoU2V0dGVyJzogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHRlbGVtZW50LnN0cm9rZWQgPSAhIXZhbHVlOyAvLyBWTUwgXCJzdHJva2VkXCIgYXR0cmlidXRlXG5cdFx0dGhpc1trZXldID0gdmFsdWU7IC8vIHVzZWQgaW4gZ2V0dGVyLCBpc3N1ZSAjMTEzXG5cdFx0aWYgKGlzTnVtYmVyKHZhbHVlKSkge1xuXHRcdFx0dmFsdWUgKz0gUFg7XG5cdFx0fVxuXHRcdHRoaXMuc2V0QXR0cignc3Ryb2tld2VpZ2h0JywgdmFsdWUpO1xuXHR9LFxuXHR0aXRsZVNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcblx0XHR0aGlzLnNldEF0dHIoa2V5LCB2YWx1ZSk7XG5cdH0sXG5cdHZpc2liaWxpdHlTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cblx0XHQvLyBIYW5kbGUgaW5oZXJpdGVkIHZpc2liaWxpdHlcblx0XHRpZiAodmFsdWUgPT09ICdpbmhlcml0Jykge1xuXHRcdFx0dmFsdWUgPSBWSVNJQkxFO1xuXHRcdH1cblx0XHRcblx0XHQvLyBMZXQgdGhlIHNoYWRvdyBmb2xsb3cgdGhlIG1haW4gZWxlbWVudFxuXHRcdGlmICh0aGlzLnNoYWRvd3MpIHtcblx0XHRcdGVhY2godGhpcy5zaGFkb3dzLCBmdW5jdGlvbiAoc2hhZG93KSB7XG5cdFx0XHRcdHNoYWRvdy5zdHlsZVtrZXldID0gdmFsdWU7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHQvLyBJbnN0ZWFkIG9mIHRvZ2dsaW5nIHRoZSB2aXNpYmlsaXR5IENTUyBwcm9wZXJ0eSwgbW92ZSB0aGUgZGl2IG91dCBvZiB0aGUgdmlld3BvcnQuXG5cdFx0Ly8gVGhpcyB3b3JrcyBhcm91bmQgIzYxIGFuZCAjNTg2XG5cdFx0aWYgKGVsZW1lbnQubm9kZU5hbWUgPT09ICdESVYnKSB7XG5cdFx0XHR2YWx1ZSA9IHZhbHVlID09PSBISURERU4gPyAnLTk5OWVtJyA6IDA7XG5cblx0XHRcdC8vIEluIG9yZGVyIHRvIHJlZHJhdywgSUU3IG5lZWRzIHRoZSBkaXYgdG8gYmUgdmlzaWJsZSB3aGVuIHR1Y2tlZCBhd2F5XG5cdFx0XHQvLyBvdXRzaWRlIHRoZSB2aWV3cG9ydC4gU28gdGhlIHZpc2liaWxpdHkgaXMgYWN0dWFsbHkgb3Bwb3NpdGUgb2Zcblx0XHRcdC8vIHRoZSBleHBlY3RlZCB2YWx1ZS4gVGhpcyBhcHBsaWVzIHRvIHRoZSB0b29sdGlwIG9ubHkuXG5cdFx0XHRpZiAoIWRvY01vZGU4KSB7XG5cdFx0XHRcdGVsZW1lbnQuc3R5bGVba2V5XSA9IHZhbHVlID8gVklTSUJMRSA6IEhJRERFTjtcblx0XHRcdH1cblx0XHRcdGtleSA9ICd0b3AnO1xuXHRcdH1cblx0XHRlbGVtZW50LnN0eWxlW2tleV0gPSB2YWx1ZTtcblx0fSxcblx0eFNldHRlcjogZnVuY3Rpb24gKHZhbHVlLCBrZXksIGVsZW1lbnQpIHtcblx0XHR0aGlzW2tleV0gPSB2YWx1ZTsgLy8gdXNlZCBpbiBnZXR0ZXJcblxuXHRcdGlmIChrZXkgPT09ICd4Jykge1xuXHRcdFx0a2V5ID0gJ2xlZnQnO1xuXHRcdH0gZWxzZSBpZiAoa2V5ID09PSAneScpIHtcblx0XHRcdGtleSA9ICd0b3AnO1xuXHRcdH0vKiBlbHNlIHtcblx0XHRcdHZhbHVlID0gbWF0aE1heCgwLCB2YWx1ZSk7IC8vIGRvbid0IHNldCB3aWR0aCBvciBoZWlnaHQgYmVsb3cgemVybyAoIzMxMSlcblx0XHR9Ki9cblxuXHRcdC8vIGNsaXBwaW5nIHJlY3RhbmdsZSBzcGVjaWFsXG5cdFx0aWYgKHRoaXMudXBkYXRlQ2xpcHBpbmcpIHtcblx0XHRcdHRoaXNba2V5XSA9IHZhbHVlOyAvLyB0aGUga2V5IGlzIG5vdyAnbGVmdCcgb3IgJ3RvcCcgZm9yICd4JyBhbmQgJ3knXG5cdFx0XHR0aGlzLnVwZGF0ZUNsaXBwaW5nKCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIG5vcm1hbFxuXHRcdFx0ZWxlbWVudC5zdHlsZVtrZXldID0gdmFsdWU7XG5cdFx0fVxuXHR9LFxuXHR6SW5kZXhTZXR0ZXI6IGZ1bmN0aW9uICh2YWx1ZSwga2V5LCBlbGVtZW50KSB7XG5cdFx0ZWxlbWVudC5zdHlsZVtrZXldID0gdmFsdWU7XG5cdH1cbn07XG5IaWdoY2hhcnRzLlZNTEVsZW1lbnQgPSBWTUxFbGVtZW50ID0gZXh0ZW5kQ2xhc3MoU1ZHRWxlbWVudCwgVk1MRWxlbWVudCk7XG5cbi8vIFNvbWUgc2hhcmVkIHNldHRlcnNcblZNTEVsZW1lbnQucHJvdG90eXBlLnlTZXR0ZXIgPVxuXHRWTUxFbGVtZW50LnByb3RvdHlwZS53aWR0aFNldHRlciA9IFxuXHRWTUxFbGVtZW50LnByb3RvdHlwZS5oZWlnaHRTZXR0ZXIgPSBcblx0Vk1MRWxlbWVudC5wcm90b3R5cGUueFNldHRlcjtcblxuXG4vKipcbiAqIFRoZSBWTUwgcmVuZGVyZXJcbiAqL1xudmFyIFZNTFJlbmRlcmVyRXh0ZW5zaW9uID0geyAvLyBpbmhlcml0IFNWR1JlbmRlcmVyXG5cblx0RWxlbWVudDogVk1MRWxlbWVudCxcblx0aXNJRTg6IHVzZXJBZ2VudC5pbmRleE9mKCdNU0lFIDguMCcpID4gLTEsXG5cblxuXHQvKipcblx0ICogSW5pdGlhbGl6ZSB0aGUgVk1MUmVuZGVyZXJcblx0ICogQHBhcmFtIHtPYmplY3R9IGNvbnRhaW5lclxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGNvbnRhaW5lciwgd2lkdGgsIGhlaWdodCwgc3R5bGUpIHtcblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0Ym94V3JhcHBlcixcblx0XHRcdGJveCxcblx0XHRcdGNzcztcblxuXHRcdHJlbmRlcmVyLmFsaWduZWRPYmplY3RzID0gW107XG5cblx0XHRib3hXcmFwcGVyID0gcmVuZGVyZXIuY3JlYXRlRWxlbWVudChESVYpXG5cdFx0XHQuY3NzKGV4dGVuZCh0aGlzLmdldFN0eWxlKHN0eWxlKSwgeyBwb3NpdGlvbjogUkVMQVRJVkV9KSk7XG5cdFx0Ym94ID0gYm94V3JhcHBlci5lbGVtZW50O1xuXHRcdGNvbnRhaW5lci5hcHBlbmRDaGlsZChib3hXcmFwcGVyLmVsZW1lbnQpO1xuXG5cblx0XHQvLyBnZW5lcmF0ZSB0aGUgY29udGFpbmluZyBib3hcblx0XHRyZW5kZXJlci5pc1ZNTCA9IHRydWU7XG5cdFx0cmVuZGVyZXIuYm94ID0gYm94O1xuXHRcdHJlbmRlcmVyLmJveFdyYXBwZXIgPSBib3hXcmFwcGVyO1xuXHRcdHJlbmRlcmVyLmNhY2hlID0ge307XG5cblxuXHRcdHJlbmRlcmVyLnNldFNpemUod2lkdGgsIGhlaWdodCwgZmFsc2UpO1xuXG5cdFx0Ly8gVGhlIG9ubHkgd2F5IHRvIG1ha2UgSUU2IGFuZCBJRTcgcHJpbnQgaXMgdG8gdXNlIGEgZ2xvYmFsIG5hbWVzcGFjZS4gSG93ZXZlcixcblx0XHQvLyB3aXRoIElFOCB0aGUgb25seSB3YXkgdG8gbWFrZSB0aGUgZHluYW1pYyBzaGFwZXMgdmlzaWJsZSBpbiBzY3JlZW4gYW5kIHByaW50IG1vZGVcblx0XHQvLyBzZWVtcyB0byBiZSB0byBhZGQgdGhlIHhtbG5zIGF0dHJpYnV0ZSBhbmQgdGhlIGJlaGF2aW91ciBzdHlsZSBpbmxpbmUuXG5cdFx0aWYgKCFkb2MubmFtZXNwYWNlcy5oY3YpIHtcblxuXHRcdFx0ZG9jLm5hbWVzcGFjZXMuYWRkKCdoY3YnLCAndXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwnKTtcblxuXHRcdFx0Ly8gU2V0dXAgZGVmYXVsdCBDU1MgKCMyMTUzLCAjMjM2OCwgIzIzODQpXG5cdFx0XHRjc3MgPSAnaGN2XFxcXDpmaWxsLCBoY3ZcXFxcOnBhdGgsIGhjdlxcXFw6c2hhcGUsIGhjdlxcXFw6c3Ryb2tlJyArXG5cdFx0XHRcdCd7IGJlaGF2aW9yOnVybCgjZGVmYXVsdCNWTUwpOyBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IH0gJztcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRvYy5jcmVhdGVTdHlsZVNoZWV0KCkuY3NzVGV4dCA9IGNzcztcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0ZG9jLnN0eWxlU2hlZXRzWzBdLmNzc1RleHQgKz0gY3NzO1xuXHRcdFx0fVxuXG5cdFx0fVxuXHR9LFxuXG5cblx0LyoqXG5cdCAqIERldGVjdCB3aGV0aGVyIHRoZSByZW5kZXJlciBpcyBoaWRkZW4uIFRoaXMgaGFwcGVucyB3aGVuIG9uZSBvZiB0aGUgcGFyZW50IGVsZW1lbnRzXG5cdCAqIGhhcyBkaXNwbGF5OiBub25lXG5cdCAqL1xuXHRpc0hpZGRlbjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAhdGhpcy5ib3gub2Zmc2V0V2lkdGg7XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlZmluZSBhIGNsaXBwaW5nIHJlY3RhbmdsZS4gSW4gVk1MIGl0IGlzIGFjY29tcGxpc2hlZCBieSBzdG9yaW5nIHRoZSB2YWx1ZXNcblx0ICogZm9yIHNldHRpbmcgdGhlIENTUyBzdHlsZSB0byBhbGwgYXNzb2NpYXRlZCBtZW1iZXJzLlxuXHQgKlxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKiBAcGFyYW0ge051bWJlcn0gd2lkdGhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGhlaWdodFxuXHQgKi9cblx0Y2xpcFJlY3Q6IGZ1bmN0aW9uICh4LCB5LCB3aWR0aCwgaGVpZ2h0KSB7XG5cblx0XHQvLyBjcmVhdGUgYSBkdW1teSBlbGVtZW50XG5cdFx0dmFyIGNsaXBSZWN0ID0gdGhpcy5jcmVhdGVFbGVtZW50KCksXG5cdFx0XHRpc09iaiA9IGlzT2JqZWN0KHgpO1xuXG5cdFx0Ly8gbWltaWMgYSByZWN0YW5nbGUgd2l0aCBpdHMgc3R5bGUgb2JqZWN0IGZvciBhdXRvbWF0aWMgdXBkYXRpbmcgaW4gYXR0clxuXHRcdHJldHVybiBleHRlbmQoY2xpcFJlY3QsIHtcblx0XHRcdG1lbWJlcnM6IFtdLFxuXHRcdFx0bGVmdDogKGlzT2JqID8geC54IDogeCkgKyAxLFxuXHRcdFx0dG9wOiAoaXNPYmogPyB4LnkgOiB5KSArIDEsXG5cdFx0XHR3aWR0aDogKGlzT2JqID8geC53aWR0aCA6IHdpZHRoKSAtIDEsXG5cdFx0XHRoZWlnaHQ6IChpc09iaiA/IHguaGVpZ2h0IDogaGVpZ2h0KSAtIDEsXG5cdFx0XHRnZXRDU1M6IGZ1bmN0aW9uICh3cmFwcGVyKSB7XG5cdFx0XHRcdHZhciBlbGVtZW50ID0gd3JhcHBlci5lbGVtZW50LFxuXHRcdFx0XHRcdG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZSxcblx0XHRcdFx0XHRpc1NoYXBlID0gbm9kZU5hbWUgPT09ICdzaGFwZScsXG5cdFx0XHRcdFx0aW52ZXJ0ZWQgPSB3cmFwcGVyLmludmVydGVkLFxuXHRcdFx0XHRcdHJlY3QgPSB0aGlzLFxuXHRcdFx0XHRcdHRvcCA9IHJlY3QudG9wIC0gKGlzU2hhcGUgPyBlbGVtZW50Lm9mZnNldFRvcCA6IDApLFxuXHRcdFx0XHRcdGxlZnQgPSByZWN0LmxlZnQsXG5cdFx0XHRcdFx0cmlnaHQgPSBsZWZ0ICsgcmVjdC53aWR0aCxcblx0XHRcdFx0XHRib3R0b20gPSB0b3AgKyByZWN0LmhlaWdodCxcblx0XHRcdFx0XHRyZXQgPSB7XG5cdFx0XHRcdFx0XHRjbGlwOiAncmVjdCgnICtcblx0XHRcdFx0XHRcdFx0bWF0aFJvdW5kKGludmVydGVkID8gbGVmdCA6IHRvcCkgKyAncHgsJyArXG5cdFx0XHRcdFx0XHRcdG1hdGhSb3VuZChpbnZlcnRlZCA/IGJvdHRvbSA6IHJpZ2h0KSArICdweCwnICtcblx0XHRcdFx0XHRcdFx0bWF0aFJvdW5kKGludmVydGVkID8gcmlnaHQgOiBib3R0b20pICsgJ3B4LCcgK1xuXHRcdFx0XHRcdFx0XHRtYXRoUm91bmQoaW52ZXJ0ZWQgPyB0b3AgOiBsZWZ0KSArICdweCknXG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBpc3N1ZSA3NCB3b3JrYXJvdW5kXG5cdFx0XHRcdGlmICghaW52ZXJ0ZWQgJiYgZG9jTW9kZTggJiYgbm9kZU5hbWUgPT09ICdESVYnKSB7XG5cdFx0XHRcdFx0ZXh0ZW5kKHJldCwge1xuXHRcdFx0XHRcdFx0d2lkdGg6IHJpZ2h0ICsgUFgsXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IGJvdHRvbSArIFBYXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIHVzZWQgaW4gYXR0ciBhbmQgYW5pbWF0aW9uIHRvIHVwZGF0ZSB0aGUgY2xpcHBpbmcgb2YgYWxsIG1lbWJlcnNcblx0XHRcdHVwZGF0ZUNsaXBwaW5nOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGVhY2goY2xpcFJlY3QubWVtYmVycywgZnVuY3Rpb24gKG1lbWJlcikge1xuXHRcdFx0XHRcdGlmIChtZW1iZXIuZWxlbWVudCkgeyAvLyBEZWxldGVkIHNlcmllcywgbGlrZSBpbiBzdG9jay9tZW1iZXJzL3Nlcmllcy1yZW1vdmUgZGVtby4gU2hvdWxkIGJlIHJlbW92ZWQgZnJvbSBtZW1iZXJzLCBidXQgdGhpcyB3aWxsIGRvLlxuXHRcdFx0XHRcdFx0bWVtYmVyLmNzcyhjbGlwUmVjdC5nZXRDU1MobWVtYmVyKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHR9LFxuXG5cblx0LyoqXG5cdCAqIFRha2UgYSBjb2xvciBhbmQgcmV0dXJuIGl0IGlmIGl0J3MgYSBzdHJpbmcsIG1ha2UgaXQgYSBncmFkaWVudCBpZiBpdCdzIGFcblx0ICogZ3JhZGllbnQgY29uZmlndXJhdGlvbiBvYmplY3QsIGFuZCBhcHBseSBvcGFjaXR5LlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gY29sb3IgVGhlIGNvbG9yIG9yIGNvbmZpZyBvYmplY3Rcblx0ICovXG5cdGNvbG9yOiBmdW5jdGlvbiAoY29sb3IsIGVsZW0sIHByb3AsIHdyYXBwZXIpIHtcblx0XHR2YXIgcmVuZGVyZXIgPSB0aGlzLFxuXHRcdFx0Y29sb3JPYmplY3QsXG5cdFx0XHRyZWdleFJnYmEgPSAvXnJnYmEvLFxuXHRcdFx0bWFya3VwLFxuXHRcdFx0ZmlsbFR5cGUsXG5cdFx0XHRyZXQgPSBOT05FO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGxpbmVhciBvciByYWRpYWwgZ3JhZGllbnRcblx0XHRpZiAoY29sb3IgJiYgY29sb3IubGluZWFyR3JhZGllbnQpIHtcblx0XHRcdGZpbGxUeXBlID0gJ2dyYWRpZW50Jztcblx0XHR9IGVsc2UgaWYgKGNvbG9yICYmIGNvbG9yLnJhZGlhbEdyYWRpZW50KSB7XG5cdFx0XHRmaWxsVHlwZSA9ICdwYXR0ZXJuJztcblx0XHR9XG5cblxuXHRcdGlmIChmaWxsVHlwZSkge1xuXG5cdFx0XHR2YXIgc3RvcENvbG9yLFxuXHRcdFx0XHRzdG9wT3BhY2l0eSxcblx0XHRcdFx0Z3JhZGllbnQgPSBjb2xvci5saW5lYXJHcmFkaWVudCB8fCBjb2xvci5yYWRpYWxHcmFkaWVudCxcblx0XHRcdFx0eDEsXG5cdFx0XHRcdHkxLFxuXHRcdFx0XHR4Mixcblx0XHRcdFx0eTIsXG5cdFx0XHRcdG9wYWNpdHkxLFxuXHRcdFx0XHRvcGFjaXR5Mixcblx0XHRcdFx0Y29sb3IxLFxuXHRcdFx0XHRjb2xvcjIsXG5cdFx0XHRcdGZpbGxBdHRyID0gJycsXG5cdFx0XHRcdHN0b3BzID0gY29sb3Iuc3RvcHMsXG5cdFx0XHRcdGZpcnN0U3RvcCxcblx0XHRcdFx0bGFzdFN0b3AsXG5cdFx0XHRcdGNvbG9ycyA9IFtdLFxuXHRcdFx0XHRhZGRGaWxsTm9kZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHQvLyBBZGQgdGhlIGZpbGwgc3Vibm9kZS4gV2hlbiBjb2xvcnMgYXR0cmlidXRlIGlzIHVzZWQsIHRoZSBtZWFuaW5ncyBvZiBvcGFjaXR5IGFuZCBvOm9wYWNpdHkyXG5cdFx0XHRcdFx0Ly8gYXJlIHJldmVyc2VkLlxuXHRcdFx0XHRcdG1hcmt1cCA9IFsnPGZpbGwgY29sb3JzPVwiJyArIGNvbG9ycy5qb2luKCcsJykgKyAnXCIgb3BhY2l0eT1cIicsIG9wYWNpdHkyLCAnXCIgbzpvcGFjaXR5Mj1cIicsIG9wYWNpdHkxLFxuXHRcdFx0XHRcdFx0J1wiIHR5cGU9XCInLCBmaWxsVHlwZSwgJ1wiICcsIGZpbGxBdHRyLCAnZm9jdXM9XCIxMDAlXCIgbWV0aG9kPVwiYW55XCIgLz4nXTtcblx0XHRcdFx0XHRjcmVhdGVFbGVtZW50KHJlbmRlcmVyLnByZXBWTUwobWFya3VwKSwgbnVsbCwgbnVsbCwgZWxlbSk7XG5cdFx0XHRcdH07XG5cblx0XHRcdC8vIEV4dGVuZCBmcm9tIDAgdG8gMVxuXHRcdFx0Zmlyc3RTdG9wID0gc3RvcHNbMF07XG5cdFx0XHRsYXN0U3RvcCA9IHN0b3BzW3N0b3BzLmxlbmd0aCAtIDFdO1xuXHRcdFx0aWYgKGZpcnN0U3RvcFswXSA+IDApIHtcblx0XHRcdFx0c3RvcHMudW5zaGlmdChbXG5cdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRmaXJzdFN0b3BbMV1cblx0XHRcdFx0XSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAobGFzdFN0b3BbMF0gPCAxKSB7XG5cdFx0XHRcdHN0b3BzLnB1c2goW1xuXHRcdFx0XHRcdDEsXG5cdFx0XHRcdFx0bGFzdFN0b3BbMV1cblx0XHRcdFx0XSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbXB1dGUgdGhlIHN0b3BzXG5cdFx0XHRlYWNoKHN0b3BzLCBmdW5jdGlvbiAoc3RvcCwgaSkge1xuXHRcdFx0XHRpZiAocmVnZXhSZ2JhLnRlc3Qoc3RvcFsxXSkpIHtcblx0XHRcdFx0XHRjb2xvck9iamVjdCA9IENvbG9yKHN0b3BbMV0pO1xuXHRcdFx0XHRcdHN0b3BDb2xvciA9IGNvbG9yT2JqZWN0LmdldCgncmdiJyk7XG5cdFx0XHRcdFx0c3RvcE9wYWNpdHkgPSBjb2xvck9iamVjdC5nZXQoJ2EnKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdG9wQ29sb3IgPSBzdG9wWzFdO1xuXHRcdFx0XHRcdHN0b3BPcGFjaXR5ID0gMTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEJ1aWxkIHRoZSBjb2xvciBhdHRyaWJ1dGVcblx0XHRcdFx0Y29sb3JzLnB1c2goKHN0b3BbMF0gKiAxMDApICsgJyUgJyArIHN0b3BDb2xvcik7XG5cblx0XHRcdFx0Ly8gT25seSBzdGFydCBhbmQgZW5kIG9wYWNpdGllcyBhcmUgYWxsb3dlZCwgc28gd2UgdXNlIHRoZSBmaXJzdCBhbmQgdGhlIGxhc3Rcblx0XHRcdFx0aWYgKCFpKSB7XG5cdFx0XHRcdFx0b3BhY2l0eTEgPSBzdG9wT3BhY2l0eTtcblx0XHRcdFx0XHRjb2xvcjIgPSBzdG9wQ29sb3I7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b3BhY2l0eTIgPSBzdG9wT3BhY2l0eTtcblx0XHRcdFx0XHRjb2xvcjEgPSBzdG9wQ29sb3I7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBBcHBseSB0aGUgZ3JhZGllbnQgdG8gZmlsbHMgb25seS5cblx0XHRcdGlmIChwcm9wID09PSAnZmlsbCcpIHtcblxuXHRcdFx0XHQvLyBIYW5kbGUgbGluZWFyIGdyYWRpZW50IGFuZ2xlXG5cdFx0XHRcdGlmIChmaWxsVHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuXHRcdFx0XHRcdHgxID0gZ3JhZGllbnQueDEgfHwgZ3JhZGllbnRbMF0gfHwgMDtcblx0XHRcdFx0XHR5MSA9IGdyYWRpZW50LnkxIHx8IGdyYWRpZW50WzFdIHx8IDA7XG5cdFx0XHRcdFx0eDIgPSBncmFkaWVudC54MiB8fCBncmFkaWVudFsyXSB8fCAwO1xuXHRcdFx0XHRcdHkyID0gZ3JhZGllbnQueTIgfHwgZ3JhZGllbnRbM10gfHwgMDtcblx0XHRcdFx0XHRmaWxsQXR0ciA9ICdhbmdsZT1cIicgKyAoOTAgIC0gbWF0aC5hdGFuKFxuXHRcdFx0XHRcdFx0KHkyIC0geTEpIC8gLy8geSB2ZWN0b3Jcblx0XHRcdFx0XHRcdCh4MiAtIHgxKSAvLyB4IHZlY3RvclxuXHRcdFx0XHRcdFx0KSAqIDE4MCAvIG1hdGhQSSkgKyAnXCInO1xuXG5cdFx0XHRcdFx0YWRkRmlsbE5vZGUoKTtcblxuXHRcdFx0XHQvLyBSYWRpYWwgKGNpcmN1bGFyKSBncmFkaWVudFxuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0dmFyIHIgPSBncmFkaWVudC5yLFxuXHRcdFx0XHRcdFx0c2l6ZXggPSByICogMixcblx0XHRcdFx0XHRcdHNpemV5ID0gciAqIDIsXG5cdFx0XHRcdFx0XHRjeCA9IGdyYWRpZW50LmN4LFxuXHRcdFx0XHRcdFx0Y3kgPSBncmFkaWVudC5jeSxcblx0XHRcdFx0XHRcdHJhZGlhbFJlZmVyZW5jZSA9IGVsZW0ucmFkaWFsUmVmZXJlbmNlLFxuXHRcdFx0XHRcdFx0YkJveCxcblx0XHRcdFx0XHRcdGFwcGx5UmFkaWFsR3JhZGllbnQgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0XHRcdGlmIChyYWRpYWxSZWZlcmVuY2UpIHtcblx0XHRcdFx0XHRcdFx0XHRiQm94ID0gd3JhcHBlci5nZXRCQm94KCk7XG5cdFx0XHRcdFx0XHRcdFx0Y3ggKz0gKHJhZGlhbFJlZmVyZW5jZVswXSAtIGJCb3gueCkgLyBiQm94LndpZHRoIC0gMC41O1xuXHRcdFx0XHRcdFx0XHRcdGN5ICs9IChyYWRpYWxSZWZlcmVuY2VbMV0gLSBiQm94LnkpIC8gYkJveC5oZWlnaHQgLSAwLjU7XG5cdFx0XHRcdFx0XHRcdFx0c2l6ZXggKj0gcmFkaWFsUmVmZXJlbmNlWzJdIC8gYkJveC53aWR0aDtcblx0XHRcdFx0XHRcdFx0XHRzaXpleSAqPSByYWRpYWxSZWZlcmVuY2VbMl0gLyBiQm94LmhlaWdodDtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRmaWxsQXR0ciA9ICdzcmM9XCInICsgZGVmYXVsdE9wdGlvbnMuZ2xvYmFsLlZNTFJhZGlhbEdyYWRpZW50VVJMICsgJ1wiICcgK1xuXHRcdFx0XHRcdFx0XHRcdCdzaXplPVwiJyArIHNpemV4ICsgJywnICsgc2l6ZXkgKyAnXCIgJyArXG5cdFx0XHRcdFx0XHRcdFx0J29yaWdpbj1cIjAuNSwwLjVcIiAnICtcblx0XHRcdFx0XHRcdFx0XHQncG9zaXRpb249XCInICsgY3ggKyAnLCcgKyBjeSArICdcIiAnICtcblx0XHRcdFx0XHRcdFx0XHQnY29sb3IyPVwiJyArIGNvbG9yMiArICdcIiAnO1xuXG5cdFx0XHRcdFx0XHRcdGFkZEZpbGxOb2RlKCk7XG5cdFx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0Ly8gQXBwbHkgcmFkaWFsIGdyYWRpZW50XG5cdFx0XHRcdFx0aWYgKHdyYXBwZXIuYWRkZWQpIHtcblx0XHRcdFx0XHRcdGFwcGx5UmFkaWFsR3JhZGllbnQoKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gV2UgbmVlZCB0byBrbm93IHRoZSBib3VuZGluZyBib3ggdG8gZ2V0IHRoZSBzaXplIGFuZCBwb3NpdGlvbiByaWdodFxuXHRcdFx0XHRcdFx0d3JhcHBlci5vbkFkZCA9IGFwcGx5UmFkaWFsR3JhZGllbnQ7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gVGhlIGZpbGwgZWxlbWVudCdzIGNvbG9yIGF0dHJpYnV0ZSBpcyBicm9rZW4gaW4gSUU4IHN0YW5kYXJkcyBtb2RlLCBzbyB3ZVxuXHRcdFx0XHRcdC8vIG5lZWQgdG8gc2V0IHRoZSBwYXJlbnQgc2hhcGUncyBmaWxsY29sb3IgYXR0cmlidXRlIGluc3RlYWQuXG5cdFx0XHRcdFx0cmV0ID0gY29sb3IxO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEdyYWRpZW50cyBhcmUgbm90IHN1cHBvcnRlZCBmb3IgVk1MIHN0cm9rZSwgcmV0dXJuIHRoZSBmaXJzdCBjb2xvci4gIzcyMi5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldCA9IHN0b3BDb2xvcjtcblx0XHRcdH1cblxuXHRcdC8vIGlmIHRoZSBjb2xvciBpcyBhbiByZ2JhIGNvbG9yLCBzcGxpdCBpdCBhbmQgYWRkIGEgZmlsbCBub2RlXG5cdFx0Ly8gdG8gaG9sZCB0aGUgb3BhY2l0eSBjb21wb25lbnRcblx0XHR9IGVsc2UgaWYgKHJlZ2V4UmdiYS50ZXN0KGNvbG9yKSAmJiBlbGVtLnRhZ05hbWUgIT09ICdJTUcnKSB7XG5cblx0XHRcdGNvbG9yT2JqZWN0ID0gQ29sb3IoY29sb3IpO1xuXG5cdFx0XHRtYXJrdXAgPSBbJzwnLCBwcm9wLCAnIG9wYWNpdHk9XCInLCBjb2xvck9iamVjdC5nZXQoJ2EnKSwgJ1wiLz4nXTtcblx0XHRcdGNyZWF0ZUVsZW1lbnQodGhpcy5wcmVwVk1MKG1hcmt1cCksIG51bGwsIG51bGwsIGVsZW0pO1xuXG5cdFx0XHRyZXQgPSBjb2xvck9iamVjdC5nZXQoJ3JnYicpO1xuXG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIHByb3BOb2RlcyA9IGVsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUocHJvcCk7IC8vICdzdHJva2UnIG9yICdmaWxsJyBub2RlXG5cdFx0XHRpZiAocHJvcE5vZGVzLmxlbmd0aCkge1xuXHRcdFx0XHRwcm9wTm9kZXNbMF0ub3BhY2l0eSA9IDE7XG5cdFx0XHRcdHByb3BOb2Rlc1swXS50eXBlID0gJ3NvbGlkJztcblx0XHRcdH1cblx0XHRcdHJldCA9IGNvbG9yO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRha2UgYSBWTUwgc3RyaW5nIGFuZCBwcmVwYXJlIGl0IGZvciBlaXRoZXIgSUU4IG9yIElFNi9JRTcuXG5cdCAqIEBwYXJhbSB7QXJyYXl9IG1hcmt1cCBBIHN0cmluZyBhcnJheSBvZiB0aGUgVk1MIG1hcmt1cCB0byBwcmVwYXJlXG5cdCAqL1xuXHRwcmVwVk1MOiBmdW5jdGlvbiAobWFya3VwKSB7XG5cdFx0dmFyIHZtbFN0eWxlID0gJ2Rpc3BsYXk6aW5saW5lLWJsb2NrO2JlaGF2aW9yOnVybCgjZGVmYXVsdCNWTUwpOycsXG5cdFx0XHRpc0lFOCA9IHRoaXMuaXNJRTg7XG5cblx0XHRtYXJrdXAgPSBtYXJrdXAuam9pbignJyk7XG5cblx0XHRpZiAoaXNJRTgpIHsgLy8gYWRkIHhtbG5zIGFuZCBzdHlsZSBpbmxpbmVcblx0XHRcdG1hcmt1cCA9IG1hcmt1cC5yZXBsYWNlKCcvPicsICcgeG1sbnM9XCJ1cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnZtbFwiIC8+Jyk7XG5cdFx0XHRpZiAobWFya3VwLmluZGV4T2YoJ3N0eWxlPVwiJykgPT09IC0xKSB7XG5cdFx0XHRcdG1hcmt1cCA9IG1hcmt1cC5yZXBsYWNlKCcvPicsICcgc3R5bGU9XCInICsgdm1sU3R5bGUgKyAnXCIgLz4nKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1hcmt1cCA9IG1hcmt1cC5yZXBsYWNlKCdzdHlsZT1cIicsICdzdHlsZT1cIicgKyB2bWxTdHlsZSk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgeyAvLyBhZGQgbmFtZXNwYWNlXG5cdFx0XHRtYXJrdXAgPSBtYXJrdXAucmVwbGFjZSgnPCcsICc8aGN2OicpO1xuXHRcdH1cblxuXHRcdHJldHVybiBtYXJrdXA7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZSByb3RhdGVkIGFuZCBhbGlnbmVkIHRleHRcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0clxuXHQgKiBAcGFyYW0ge051bWJlcn0geFxuXHQgKiBAcGFyYW0ge051bWJlcn0geVxuXHQgKi9cblx0dGV4dDogU1ZHUmVuZGVyZXIucHJvdG90eXBlLmh0bWwsXG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhbmQgcmV0dXJuIGEgcGF0aCBlbGVtZW50XG5cdCAqIEBwYXJhbSB7QXJyYXl9IHBhdGhcblx0ICovXG5cdHBhdGg6IGZ1bmN0aW9uIChwYXRoKSB7XG5cdFx0dmFyIGF0dHIgPSB7XG5cdFx0XHQvLyBzdWJwaXhlbCBwcmVjaXNpb24gZG93biB0byAwLjEgKHdpZHRoIGFuZCBoZWlnaHQgPSAxcHgpXG5cdFx0XHRjb29yZHNpemU6ICcxMCAxMCdcblx0XHR9O1xuXHRcdGlmIChpc0FycmF5KHBhdGgpKSB7XG5cdFx0XHRhdHRyLmQgPSBwYXRoO1xuXHRcdH0gZWxzZSBpZiAoaXNPYmplY3QocGF0aCkpIHsgLy8gYXR0cmlidXRlc1xuXHRcdFx0ZXh0ZW5kKGF0dHIsIHBhdGgpO1xuXHRcdH1cblx0XHQvLyBjcmVhdGUgdGhlIHNoYXBlXG5cdFx0cmV0dXJuIHRoaXMuY3JlYXRlRWxlbWVudCgnc2hhcGUnKS5hdHRyKGF0dHIpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgYW5kIHJldHVybiBhIGNpcmNsZSBlbGVtZW50LiBJbiBWTUwgY2lyY2xlcyBhcmUgaW1wbGVtZW50ZWQgYXNcblx0ICogc2hhcGVzLCB3aGljaCBpcyBmYXN0ZXIgdGhhbiB2Om92YWxcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHhcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0ICogQHBhcmFtIHtOdW1iZXJ9IHJcblx0ICovXG5cdGNpcmNsZTogZnVuY3Rpb24gKHgsIHksIHIpIHtcblx0XHR2YXIgY2lyY2xlID0gdGhpcy5zeW1ib2woJ2NpcmNsZScpO1xuXHRcdGlmIChpc09iamVjdCh4KSkge1xuXHRcdFx0ciA9IHgucjtcblx0XHRcdHkgPSB4Lnk7XG5cdFx0XHR4ID0geC54O1xuXHRcdH1cblx0XHRjaXJjbGUuaXNDaXJjbGUgPSB0cnVlOyAvLyBDYXVzZXMgeCBhbmQgeSB0byBtZWFuIGNlbnRlciAoIzE2ODIpXG5cdFx0Y2lyY2xlLnIgPSByO1xuXHRcdHJldHVybiBjaXJjbGUuYXR0cih7IHg6IHgsIHk6IHkgfSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIGdyb3VwIHVzaW5nIGFuIG91dGVyIGRpdiBhbmQgYW4gaW5uZXIgdjpncm91cCB0byBhbGxvdyByb3RhdGluZ1xuXHQgKiBhbmQgZmxpcHBpbmcuIEEgc2ltcGxlIHY6Z3JvdXAgd291bGQgaGF2ZSBwcm9ibGVtcyB3aXRoIHBvc2l0aW9uaW5nXG5cdCAqIGNoaWxkIEhUTUwgZWxlbWVudHMgYW5kIENTUyBjbGlwLlxuXHQgKlxuXHQgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgZ3JvdXBcblx0ICovXG5cdGc6IGZ1bmN0aW9uIChuYW1lKSB7XG5cdFx0dmFyIHdyYXBwZXIsXG5cdFx0XHRhdHRyaWJzO1xuXG5cdFx0Ly8gc2V0IHRoZSBjbGFzcyBuYW1lXG5cdFx0aWYgKG5hbWUpIHtcblx0XHRcdGF0dHJpYnMgPSB7ICdjbGFzc05hbWUnOiBQUkVGSVggKyBuYW1lLCAnY2xhc3MnOiBQUkVGSVggKyBuYW1lIH07XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIGRpdiB0byBob2xkIEhUTUwgYW5kIGNsaXBwaW5nXG5cdFx0d3JhcHBlciA9IHRoaXMuY3JlYXRlRWxlbWVudChESVYpLmF0dHIoYXR0cmlicyk7XG5cblx0XHRyZXR1cm4gd3JhcHBlcjtcblx0fSxcblxuXHQvKipcblx0ICogVk1MIG92ZXJyaWRlIHRvIGNyZWF0ZSBhIHJlZ3VsYXIgSFRNTCBpbWFnZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3JjXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqL1xuXHRpbWFnZTogZnVuY3Rpb24gKHNyYywgeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXHRcdHZhciBvYmogPSB0aGlzLmNyZWF0ZUVsZW1lbnQoJ2ltZycpXG5cdFx0XHQuYXR0cih7IHNyYzogc3JjIH0pO1xuXG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRvYmouYXR0cih7XG5cdFx0XHRcdHg6IHgsXG5cdFx0XHRcdHk6IHksXG5cdFx0XHRcdHdpZHRoOiB3aWR0aCxcblx0XHRcdFx0aGVpZ2h0OiBoZWlnaHRcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBGb3IgcmVjdGFuZ2xlcywgVk1MIHVzZXMgYSBzaGFwZSBmb3IgcmVjdCB0byBvdmVyY29tZSBidWdzIGFuZCByb3RhdGlvbiBwcm9ibGVtc1xuXHQgKi9cblx0Y3JlYXRlRWxlbWVudDogZnVuY3Rpb24gKG5vZGVOYW1lKSB7XG5cdFx0cmV0dXJuIG5vZGVOYW1lID09PSAncmVjdCcgPyB0aGlzLnN5bWJvbChub2RlTmFtZSkgOiBTVkdSZW5kZXJlci5wcm90b3R5cGUuY3JlYXRlRWxlbWVudC5jYWxsKHRoaXMsIG5vZGVOYW1lKTtcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbiB0aGUgVk1MIHJlbmRlcmVyLCBlYWNoIGNoaWxkIG9mIGFuIGludmVydGVkIGRpdiAoZ3JvdXApIGlzIGludmVydGVkXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBwYXJlbnROb2RlXG5cdCAqL1xuXHRpbnZlcnRDaGlsZDogZnVuY3Rpb24gKGVsZW1lbnQsIHBhcmVudE5vZGUpIHtcblx0XHR2YXIgcmVuID0gdGhpcyxcblx0XHRcdHBhcmVudFN0eWxlID0gcGFyZW50Tm9kZS5zdHlsZSxcblx0XHRcdGltZ1N0eWxlID0gZWxlbWVudC50YWdOYW1lID09PSAnSU1HJyAmJiBlbGVtZW50LnN0eWxlOyAvLyAjMTExMVxuXG5cdFx0Y3NzKGVsZW1lbnQsIHtcblx0XHRcdGZsaXA6ICd4Jyxcblx0XHRcdGxlZnQ6IHBJbnQocGFyZW50U3R5bGUud2lkdGgpIC0gKGltZ1N0eWxlID8gcEludChpbWdTdHlsZS50b3ApIDogMSksXG5cdFx0XHR0b3A6IHBJbnQocGFyZW50U3R5bGUuaGVpZ2h0KSAtIChpbWdTdHlsZSA/IHBJbnQoaW1nU3R5bGUubGVmdCkgOiAxKSxcblx0XHRcdHJvdGF0aW9uOiAtOTBcblx0XHR9KTtcblxuXHRcdC8vIFJlY3Vyc2l2ZWx5IGludmVydCBjaGlsZCBlbGVtZW50cywgbmVlZGVkIGZvciBuZXN0ZWQgY29tcG9zaXRlIHNoYXBlcyBsaWtlIGJveCBwbG90cyBhbmQgZXJyb3IgYmFycy4gIzE2ODAsICMxODA2LlxuXHRcdGVhY2goZWxlbWVudC5jaGlsZE5vZGVzLCBmdW5jdGlvbiAoY2hpbGQpIHtcblx0XHRcdHJlbi5pbnZlcnRDaGlsZChjaGlsZCwgZWxlbWVudCk7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFN5bWJvbCBkZWZpbml0aW9ucyB0aGF0IG92ZXJyaWRlIHRoZSBwYXJlbnQgU1ZHIHJlbmRlcmVyJ3Mgc3ltYm9sc1xuXHQgKlxuXHQgKi9cblx0c3ltYm9sczoge1xuXHRcdC8vIFZNTCBzcGVjaWZpYyBhcmMgZnVuY3Rpb25cblx0XHRhcmM6IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCBvcHRpb25zKSB7XG5cdFx0XHR2YXIgc3RhcnQgPSBvcHRpb25zLnN0YXJ0LFxuXHRcdFx0XHRlbmQgPSBvcHRpb25zLmVuZCxcblx0XHRcdFx0cmFkaXVzID0gb3B0aW9ucy5yIHx8IHcgfHwgaCxcblx0XHRcdFx0aW5uZXJSYWRpdXMgPSBvcHRpb25zLmlubmVyUixcblx0XHRcdFx0Y29zU3RhcnQgPSBtYXRoQ29zKHN0YXJ0KSxcblx0XHRcdFx0c2luU3RhcnQgPSBtYXRoU2luKHN0YXJ0KSxcblx0XHRcdFx0Y29zRW5kID0gbWF0aENvcyhlbmQpLFxuXHRcdFx0XHRzaW5FbmQgPSBtYXRoU2luKGVuZCksXG5cdFx0XHRcdHJldDtcblxuXHRcdFx0aWYgKGVuZCAtIHN0YXJ0ID09PSAwKSB7IC8vIG5vIGFuZ2xlLCBkb24ndCBzaG93IGl0LlxuXHRcdFx0XHRyZXR1cm4gWyd4J107XG5cdFx0XHR9XG5cblx0XHRcdHJldCA9IFtcblx0XHRcdFx0J3dhJywgLy8gY2xvY2t3aXNlIGFyYyB0b1xuXHRcdFx0XHR4IC0gcmFkaXVzLCAvLyBsZWZ0XG5cdFx0XHRcdHkgLSByYWRpdXMsIC8vIHRvcFxuXHRcdFx0XHR4ICsgcmFkaXVzLCAvLyByaWdodFxuXHRcdFx0XHR5ICsgcmFkaXVzLCAvLyBib3R0b21cblx0XHRcdFx0eCArIHJhZGl1cyAqIGNvc1N0YXJ0LCAvLyBzdGFydCB4XG5cdFx0XHRcdHkgKyByYWRpdXMgKiBzaW5TdGFydCwgLy8gc3RhcnQgeVxuXHRcdFx0XHR4ICsgcmFkaXVzICogY29zRW5kLCAvLyBlbmQgeFxuXHRcdFx0XHR5ICsgcmFkaXVzICogc2luRW5kICAvLyBlbmQgeVxuXHRcdFx0XTtcblxuXHRcdFx0aWYgKG9wdGlvbnMub3BlbiAmJiAhaW5uZXJSYWRpdXMpIHtcblx0XHRcdFx0cmV0LnB1c2goXG5cdFx0XHRcdFx0J2UnLFxuXHRcdFx0XHRcdE0sXG5cdFx0XHRcdFx0eCwvLyAtIGlubmVyUmFkaXVzLFxuXHRcdFx0XHRcdHkvLyAtIGlubmVyUmFkaXVzXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cblx0XHRcdHJldC5wdXNoKFxuXHRcdFx0XHQnYXQnLCAvLyBhbnRpIGNsb2Nrd2lzZSBhcmMgdG9cblx0XHRcdFx0eCAtIGlubmVyUmFkaXVzLCAvLyBsZWZ0XG5cdFx0XHRcdHkgLSBpbm5lclJhZGl1cywgLy8gdG9wXG5cdFx0XHRcdHggKyBpbm5lclJhZGl1cywgLy8gcmlnaHRcblx0XHRcdFx0eSArIGlubmVyUmFkaXVzLCAvLyBib3R0b21cblx0XHRcdFx0eCArIGlubmVyUmFkaXVzICogY29zRW5kLCAvLyBzdGFydCB4XG5cdFx0XHRcdHkgKyBpbm5lclJhZGl1cyAqIHNpbkVuZCwgLy8gc3RhcnQgeVxuXHRcdFx0XHR4ICsgaW5uZXJSYWRpdXMgKiBjb3NTdGFydCwgLy8gZW5kIHhcblx0XHRcdFx0eSArIGlubmVyUmFkaXVzICogc2luU3RhcnQsIC8vIGVuZCB5XG5cdFx0XHRcdCd4JywgLy8gZmluaXNoIHBhdGhcblx0XHRcdFx0J2UnIC8vIGNsb3NlXG5cdFx0XHQpO1xuXG5cdFx0XHRyZXQuaXNBcmMgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdH0sXG5cdFx0Ly8gQWRkIGNpcmNsZSBzeW1ib2wgcGF0aC4gVGhpcyBwZXJmb3JtcyBzaWduaWZpY2FudGx5IGZhc3RlciB0aGFuIHY6b3ZhbC5cblx0XHRjaXJjbGU6IGZ1bmN0aW9uICh4LCB5LCB3LCBoLCB3cmFwcGVyKSB7XG5cblx0XHRcdGlmICh3cmFwcGVyKSB7XG5cdFx0XHRcdHcgPSBoID0gMiAqIHdyYXBwZXIucjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2VudGVyIGNvcnJlY3Rpb24sICMxNjgyXG5cdFx0XHRpZiAod3JhcHBlciAmJiB3cmFwcGVyLmlzQ2lyY2xlKSB7XG5cdFx0XHRcdHggLT0gdyAvIDI7XG5cdFx0XHRcdHkgLT0gaCAvIDI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHVybiB0aGUgcGF0aFxuXHRcdFx0cmV0dXJuIFtcblx0XHRcdFx0J3dhJywgLy8gY2xvY2t3aXNlYXJjdG9cblx0XHRcdFx0eCwgLy8gbGVmdFxuXHRcdFx0XHR5LCAvLyB0b3Bcblx0XHRcdFx0eCArIHcsIC8vIHJpZ2h0XG5cdFx0XHRcdHkgKyBoLCAvLyBib3R0b21cblx0XHRcdFx0eCArIHcsIC8vIHN0YXJ0IHhcblx0XHRcdFx0eSArIGggLyAyLCAgICAgLy8gc3RhcnQgeVxuXHRcdFx0XHR4ICsgdywgLy8gZW5kIHhcblx0XHRcdFx0eSArIGggLyAyLCAgICAgLy8gZW5kIHlcblx0XHRcdFx0Ly8neCcsIC8vIGZpbmlzaCBwYXRoXG5cdFx0XHRcdCdlJyAvLyBjbG9zZVxuXHRcdFx0XTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIEFkZCByZWN0YW5nbGUgc3ltYm9sIHBhdGggd2hpY2ggZWFzZXMgcm90YXRpb24gYW5kIG9taXRzIGFyY3NpemUgcHJvYmxlbXNcblx0XHQgKiBjb21wYXJlZCB0byB0aGUgYnVpbHQtaW4gVk1MIHJvdW5kcmVjdCBzaGFwZS4gV2hlbiBib3JkZXJzIGFyZSBub3Qgcm91bmRlZCxcblx0XHQgKiB1c2UgdGhlIHNpbXBsZXIgc3F1YXJlIHBhdGgsIGVsc2UgdXNlIHRoZSBjYWxsb3V0IHBhdGggd2l0aG91dCB0aGUgYXJyb3cuXG5cdFx0ICovXG5cdFx0cmVjdDogZnVuY3Rpb24gKHgsIHksIHcsIGgsIG9wdGlvbnMpIHtcblx0XHRcdHJldHVybiBTVkdSZW5kZXJlci5wcm90b3R5cGUuc3ltYm9sc1tcblx0XHRcdFx0IWRlZmluZWQob3B0aW9ucykgfHwgIW9wdGlvbnMuciA/ICdzcXVhcmUnIDogJ2NhbGxvdXQnXG5cdFx0XHRdLmNhbGwoMCwgeCwgeSwgdywgaCwgb3B0aW9ucyk7XG5cdFx0fVxuXHR9XG59O1xuSGlnaGNoYXJ0cy5WTUxSZW5kZXJlciA9IFZNTFJlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuXHR0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn07XG5WTUxSZW5kZXJlci5wcm90b3R5cGUgPSBtZXJnZShTVkdSZW5kZXJlci5wcm90b3R5cGUsIFZNTFJlbmRlcmVyRXh0ZW5zaW9uKTtcblxuXHQvLyBnZW5lcmFsIHJlbmRlcmVyXG5cdFJlbmRlcmVyID0gVk1MUmVuZGVyZXI7XG59XG5cbi8vIFRoaXMgbWV0aG9kIGlzIHVzZWQgd2l0aCBleHBvcnRpbmcgaW4gb2xkIElFLCB3aGVuIGVtdWxhdGluZyBTVkcgKHNlZSAjMjMxNClcblNWR1JlbmRlcmVyLnByb3RvdHlwZS5tZWFzdXJlU3BhbldpZHRoID0gZnVuY3Rpb24gKHRleHQsIHN0eWxlcykge1xuXHR2YXIgbWVhc3VyaW5nU3BhbiA9IGRvYy5jcmVhdGVFbGVtZW50KCdzcGFuJyksXG5cdFx0b2Zmc2V0V2lkdGgsXG5cdHRleHROb2RlID0gZG9jLmNyZWF0ZVRleHROb2RlKHRleHQpO1xuXG5cdG1lYXN1cmluZ1NwYW4uYXBwZW5kQ2hpbGQodGV4dE5vZGUpO1xuXHRjc3MobWVhc3VyaW5nU3Bhbiwgc3R5bGVzKTtcblx0dGhpcy5ib3guYXBwZW5kQ2hpbGQobWVhc3VyaW5nU3Bhbik7XG5cdG9mZnNldFdpZHRoID0gbWVhc3VyaW5nU3Bhbi5vZmZzZXRXaWR0aDtcblx0ZGlzY2FyZEVsZW1lbnQobWVhc3VyaW5nU3Bhbik7IC8vICMyNDYzXG5cdHJldHVybiBvZmZzZXRXaWR0aDtcbn07XG5cblxuLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogRU5EIE9GIElOVEVSTkVUIEVYUExPUkVSIDw9IDggU1BFQ0lGSUMgQ09ERSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogU1RBUlQgT0YgQU5EUk9JRCA8IDMgU1BFQ0lGSUMgQ09ERS4gVEhJUyBDQU4gQkUgUkVNT1ZFRCBJRiBZT1UnUkUgTk9UICAgICAgKlxuICogVEFSR0VUSU5HIFRIQVQgU1lTVEVNLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xudmFyIENhblZHUmVuZGVyZXIsXG5cdENhblZHQ29udHJvbGxlcjtcblxuaWYgKHVzZUNhblZHKSB7XG5cdC8qKlxuXHQgKiBUaGUgQ2FuVkdSZW5kZXJlciBpcyBlbXB0eSBmcm9tIHN0YXJ0IHRvIGtlZXAgdGhlIHNvdXJjZSBmb290cHJpbnQgc21hbGwuXG5cdCAqIFdoZW4gcmVxdWVzdGVkLCB0aGUgQ2FuVkdDb250cm9sbGVyIGRvd25sb2FkcyB0aGUgcmVzdCBvZiB0aGUgc291cmNlIHBhY2thZ2VkXG5cdCAqIHRvZ2V0aGVyIHdpdGggdGhlIGNhbnZnIGxpYnJhcnkuXG5cdCAqL1xuXHRIaWdoY2hhcnRzLkNhblZHUmVuZGVyZXIgPSBDYW5WR1JlbmRlcmVyID0gZnVuY3Rpb24gKCkge1xuXHRcdC8vIE92ZXJyaWRlIHRoZSBnbG9iYWwgU1ZHIG5hbWVzcGFjZSB0byBmYWtlIFNWRy9IVE1MIHRoYXQgYWNjZXB0cyBDU1Ncblx0XHRTVkdfTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCc7XG5cdH07XG5cblx0LyoqXG5cdCAqIFN0YXJ0IHdpdGggYW4gZW1wdHkgc3ltYm9scyBvYmplY3QuIFRoaXMgaXMgbmVlZGVkIHdoZW4gZXhwb3J0aW5nIGlzIHVzZWQgKGV4cG9ydGluZy5zcmMuanMgd2lsbCBhZGQgYSBmZXcgc3ltYm9scyksIGJ1dCBcblx0ICogdGhlIGltcGxlbWVudGF0aW9uIGZyb20gU3ZnUmVuZGVyZXIgd2lsbCBub3QgYmUgbWVyZ2VkIGluIHVudGlsIGZpcnN0IHJlbmRlci5cblx0ICovXG5cdENhblZHUmVuZGVyZXIucHJvdG90eXBlLnN5bWJvbHMgPSB7fTtcblxuXHQvKipcblx0ICogSGFuZGxlcyBvbiBkZW1hbmQgZG93bmxvYWQgb2YgY2FudmcgcmVuZGVyaW5nIHN1cHBvcnQuXG5cdCAqL1xuXHRDYW5WR0NvbnRyb2xsZXIgPSAoZnVuY3Rpb24gKCkge1xuXHRcdC8vIExpc3Qgb2YgcmVuZGVyZXJpbmcgY2FsbHNcblx0XHR2YXIgZGVmZXJyZWRSZW5kZXJDYWxscyA9IFtdO1xuXG5cdFx0LyoqXG5cdFx0ICogV2hlbiBkb3dubG9hZGVkLCB3ZSBhcmUgcmVhZHkgdG8gZHJhdyBkZWZlcnJlZCBjaGFydHMuXG5cdFx0ICovXG5cdFx0ZnVuY3Rpb24gZHJhd0RlZmVycmVkKCkge1xuXHRcdFx0dmFyIGNhbGxMZW5ndGggPSBkZWZlcnJlZFJlbmRlckNhbGxzLmxlbmd0aCxcblx0XHRcdFx0Y2FsbEluZGV4O1xuXG5cdFx0XHQvLyBEcmF3IGFsbCBwZW5kaW5nIHJlbmRlciBjYWxsc1xuXHRcdFx0Zm9yIChjYWxsSW5kZXggPSAwOyBjYWxsSW5kZXggPCBjYWxsTGVuZ3RoOyBjYWxsSW5kZXgrKykge1xuXHRcdFx0XHRkZWZlcnJlZFJlbmRlckNhbGxzW2NhbGxJbmRleF0oKTtcblx0XHRcdH1cblx0XHRcdC8vIENsZWFyIHRoZSBsaXN0XG5cdFx0XHRkZWZlcnJlZFJlbmRlckNhbGxzID0gW107XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHB1c2g6IGZ1bmN0aW9uIChmdW5jLCBzY3JpcHRMb2NhdGlvbikge1xuXHRcdFx0XHQvLyBPbmx5IGdldCB0aGUgc2NyaXB0IG9uY2Vcblx0XHRcdFx0aWYgKGRlZmVycmVkUmVuZGVyQ2FsbHMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdFx0Z2V0U2NyaXB0KHNjcmlwdExvY2F0aW9uLCBkcmF3RGVmZXJyZWQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIFJlZ2lzdGVyIHJlbmRlciBjYWxsXG5cdFx0XHRcdGRlZmVycmVkUmVuZGVyQ2FsbHMucHVzaChmdW5jKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9KCkpO1xuXG5cdFJlbmRlcmVyID0gQ2FuVkdSZW5kZXJlcjtcbn0gLy8gZW5kIENhblZHUmVuZGVyZXJcblxuLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogRU5EIE9GIEFORFJPSUQgPCAzIFNQRUNJRklDIENPREUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIFRoZSBUaWNrIGNsYXNzXG4gKi9cbmZ1bmN0aW9uIFRpY2soYXhpcywgcG9zLCB0eXBlLCBub0xhYmVsKSB7XG5cdHRoaXMuYXhpcyA9IGF4aXM7XG5cdHRoaXMucG9zID0gcG9zO1xuXHR0aGlzLnR5cGUgPSB0eXBlIHx8ICcnO1xuXHR0aGlzLmlzTmV3ID0gdHJ1ZTtcblxuXHRpZiAoIXR5cGUgJiYgIW5vTGFiZWwpIHtcblx0XHR0aGlzLmFkZExhYmVsKCk7XG5cdH1cbn1cblxuVGljay5wcm90b3R5cGUgPSB7XG5cdC8qKlxuXHQgKiBXcml0ZSB0aGUgdGljayBsYWJlbFxuXHQgKi9cblx0YWRkTGFiZWw6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgdGljayA9IHRoaXMsXG5cdFx0XHRheGlzID0gdGljay5heGlzLFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdGhvcml6ID0gYXhpcy5ob3Jpeixcblx0XHRcdGNhdGVnb3JpZXMgPSBheGlzLmNhdGVnb3JpZXMsXG5cdFx0XHRuYW1lcyA9IGF4aXMubmFtZXMsXG5cdFx0XHRwb3MgPSB0aWNrLnBvcyxcblx0XHRcdGxhYmVsT3B0aW9ucyA9IG9wdGlvbnMubGFiZWxzLFxuXHRcdFx0cm90YXRpb24gPSBsYWJlbE9wdGlvbnMucm90YXRpb24sXG5cdFx0XHRzdHIsXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy50aWNrUG9zaXRpb25zLFxuXHRcdFx0d2lkdGggPSAoaG9yaXogJiYgY2F0ZWdvcmllcyAmJlxuXHRcdFx0XHQhbGFiZWxPcHRpb25zLnN0ZXAgJiYgIWxhYmVsT3B0aW9ucy5zdGFnZ2VyTGluZXMgJiZcblx0XHRcdFx0IWxhYmVsT3B0aW9ucy5yb3RhdGlvbiAmJlxuXHRcdFx0XHRjaGFydC5wbG90V2lkdGggLyB0aWNrUG9zaXRpb25zLmxlbmd0aCkgfHxcblx0XHRcdFx0KCFob3JpeiAmJiAoY2hhcnQubWFyZ2luWzNdIHx8IGNoYXJ0LmNoYXJ0V2lkdGggKiAwLjMzKSksIC8vICMxNTgwLCAjMTkzMVxuXHRcdFx0aXNGaXJzdCA9IHBvcyA9PT0gdGlja1Bvc2l0aW9uc1swXSxcblx0XHRcdGlzTGFzdCA9IHBvcyA9PT0gdGlja1Bvc2l0aW9uc1t0aWNrUG9zaXRpb25zLmxlbmd0aCAtIDFdLFxuXHRcdFx0Y3NzLFxuXHRcdFx0YXR0cixcblx0XHRcdHZhbHVlID0gY2F0ZWdvcmllcyA/XG5cdFx0XHRcdHBpY2soY2F0ZWdvcmllc1twb3NdLCBuYW1lc1twb3NdLCBwb3MpIDpcblx0XHRcdFx0cG9zLFxuXHRcdFx0bGFiZWwgPSB0aWNrLmxhYmVsLFxuXHRcdFx0dGlja1Bvc2l0aW9uSW5mbyA9IHRpY2tQb3NpdGlvbnMuaW5mbyxcblx0XHRcdGRhdGVUaW1lTGFiZWxGb3JtYXQ7XG5cblx0XHQvLyBTZXQgdGhlIGRhdGV0aW1lIGxhYmVsIGZvcm1hdC4gSWYgYSBoaWdoZXIgcmFuayBpcyBzZXQgZm9yIHRoaXMgcG9zaXRpb24sIHVzZSB0aGF0LiBJZiBub3QsXG5cdFx0Ly8gdXNlIHRoZSBnZW5lcmFsIGZvcm1hdC5cblx0XHRpZiAoYXhpcy5pc0RhdGV0aW1lQXhpcyAmJiB0aWNrUG9zaXRpb25JbmZvKSB7XG5cdFx0XHRkYXRlVGltZUxhYmVsRm9ybWF0ID0gb3B0aW9ucy5kYXRlVGltZUxhYmVsRm9ybWF0c1t0aWNrUG9zaXRpb25JbmZvLmhpZ2hlclJhbmtzW3Bvc10gfHwgdGlja1Bvc2l0aW9uSW5mby51bml0TmFtZV07XG5cdFx0fVxuXHRcdC8vIHNldCBwcm9wZXJ0aWVzIGZvciBhY2Nlc3MgaW4gcmVuZGVyIG1ldGhvZFxuXHRcdHRpY2suaXNGaXJzdCA9IGlzRmlyc3Q7XG5cdFx0dGljay5pc0xhc3QgPSBpc0xhc3Q7XG5cblx0XHQvLyBnZXQgdGhlIHN0cmluZ1xuXHRcdHN0ciA9IGF4aXMubGFiZWxGb3JtYXR0ZXIuY2FsbCh7XG5cdFx0XHRheGlzOiBheGlzLFxuXHRcdFx0Y2hhcnQ6IGNoYXJ0LFxuXHRcdFx0aXNGaXJzdDogaXNGaXJzdCxcblx0XHRcdGlzTGFzdDogaXNMYXN0LFxuXHRcdFx0ZGF0ZVRpbWVMYWJlbEZvcm1hdDogZGF0ZVRpbWVMYWJlbEZvcm1hdCxcblx0XHRcdHZhbHVlOiBheGlzLmlzTG9nID8gY29ycmVjdEZsb2F0KGxpbjJsb2codmFsdWUpKSA6IHZhbHVlXG5cdFx0fSk7XG5cblx0XHQvLyBwcmVwYXJlIENTU1xuXHRcdGNzcyA9IHdpZHRoICYmIHsgd2lkdGg6IG1hdGhNYXgoMSwgbWF0aFJvdW5kKHdpZHRoIC0gMiAqIChsYWJlbE9wdGlvbnMucGFkZGluZyB8fCAxMCkpKSArIFBYIH07XG5cdFx0XG5cdFx0Ly8gZmlyc3QgY2FsbFxuXHRcdGlmICghZGVmaW5lZChsYWJlbCkpIHtcblx0XHRcdGF0dHIgPSB7XG5cdFx0XHRcdGFsaWduOiBheGlzLmxhYmVsQWxpZ25cblx0XHRcdH07XG5cdFx0XHRpZiAoaXNOdW1iZXIocm90YXRpb24pKSB7XG5cdFx0XHRcdGF0dHIucm90YXRpb24gPSByb3RhdGlvbjtcblx0XHRcdH1cblx0XHRcdGlmICh3aWR0aCAmJiBsYWJlbE9wdGlvbnMuZWxsaXBzaXMpIHtcblx0XHRcdFx0Y3NzLkhjSGVpZ2h0ID0gYXhpcy5sZW4gLyB0aWNrUG9zaXRpb25zLmxlbmd0aDtcblx0XHRcdH1cblxuXHRcdFx0dGljay5sYWJlbCA9IGxhYmVsID1cblx0XHRcdFx0ZGVmaW5lZChzdHIpICYmIGxhYmVsT3B0aW9ucy5lbmFibGVkID9cblx0XHRcdFx0XHRjaGFydC5yZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRcdFx0XHRzdHIsXG5cdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdGxhYmVsT3B0aW9ucy51c2VIVE1MXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQuYXR0cihhdHRyKVxuXHRcdFx0XHRcdFx0Ly8gd2l0aG91dCBwb3NpdGlvbiBhYnNvbHV0ZSwgSUUgZXhwb3J0IHNvbWV0aW1lcyBpcyB3cm9uZ1xuXHRcdFx0XHRcdFx0LmNzcyhleHRlbmQoY3NzLCBsYWJlbE9wdGlvbnMuc3R5bGUpKVxuXHRcdFx0XHRcdFx0LmFkZChheGlzLmxhYmVsR3JvdXApIDpcblx0XHRcdFx0XHRudWxsO1xuXG5cdFx0XHQvLyBTZXQgdGhlIHRpY2sgYmFzZWxpbmUgYW5kIGNvcnJlY3QgZm9yIHJvdGF0aW9uICgjMTc2NClcblx0XHRcdGF4aXMudGlja0Jhc2VsaW5lID0gY2hhcnQucmVuZGVyZXIuZm9udE1ldHJpY3MobGFiZWxPcHRpb25zLnN0eWxlLmZvbnRTaXplLCBsYWJlbCkuYjtcblx0XHRcdGlmIChyb3RhdGlvbiAmJiBheGlzLnNpZGUgPT09IDIpIHtcblx0XHRcdFx0YXhpcy50aWNrQmFzZWxpbmUgKj0gbWF0aENvcyhyb3RhdGlvbiAqIGRlZzJyYWQpO1xuXHRcdFx0fVxuXG5cblx0XHQvLyB1cGRhdGVcblx0XHR9IGVsc2UgaWYgKGxhYmVsKSB7XG5cdFx0XHRsYWJlbC5hdHRyKHtcblx0XHRcdFx0XHR0ZXh0OiBzdHJcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNzcyhjc3MpO1xuXHRcdH1cblx0XHR0aWNrLnlPZmZzZXQgPSBsYWJlbCA/IHBpY2sobGFiZWxPcHRpb25zLnksIGF4aXMudGlja0Jhc2VsaW5lICsgKGF4aXMuc2lkZSA9PT0gMiA/IDggOiAtKGxhYmVsLmdldEJCb3goKS5oZWlnaHQgLyAyKSkpIDogMDtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBvZmZzZXQgaGVpZ2h0IG9yIHdpZHRoIG9mIHRoZSBsYWJlbFxuXHQgKi9cblx0Z2V0TGFiZWxTaXplOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGxhYmVsID0gdGhpcy5sYWJlbCxcblx0XHRcdGF4aXMgPSB0aGlzLmF4aXM7XG5cdFx0cmV0dXJuIGxhYmVsID9cblx0XHRcdGxhYmVsLmdldEJCb3goKVtheGlzLmhvcml6ID8gJ2hlaWdodCcgOiAnd2lkdGgnXSA6XG5cdFx0XHQwO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBGaW5kIGhvdyBmYXIgdGhlIGxhYmVscyBleHRlbmQgdG8gdGhlIHJpZ2h0IGFuZCBsZWZ0IG9mIHRoZSB0aWNrJ3MgeCBwb3NpdGlvbi4gVXNlZCBmb3IgYW50aS1jb2xsaXNpb25cblx0ICogZGV0ZWN0aW9uIHdpdGggb3ZlcmZsb3cgbG9naWMuXG5cdCAqL1xuXHRnZXRMYWJlbFNpZGVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGJCb3ggPSB0aGlzLmxhYmVsLmdldEJCb3goKSxcblx0XHRcdGF4aXMgPSB0aGlzLmF4aXMsXG5cdFx0XHRob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHRvcHRpb25zID0gYXhpcy5vcHRpb25zLFxuXHRcdFx0bGFiZWxPcHRpb25zID0gb3B0aW9ucy5sYWJlbHMsXG5cdFx0XHRzaXplID0gaG9yaXogPyBiQm94LndpZHRoIDogYkJveC5oZWlnaHQsXG5cdFx0XHRsZWZ0U2lkZSA9IGhvcml6ID9cblx0XHRcdFx0bGFiZWxPcHRpb25zLnggLSBzaXplICogeyBsZWZ0OiAwLCBjZW50ZXI6IDAuNSwgcmlnaHQ6IDEgfVtheGlzLmxhYmVsQWxpZ25dIDpcblx0XHRcdFx0MCxcblx0XHRcdHJpZ2h0U2lkZSA9IGhvcml6ID9cblx0XHRcdFx0c2l6ZSArIGxlZnRTaWRlIDpcblx0XHRcdFx0c2l6ZTtcblxuXHRcdHJldHVybiBbbGVmdFNpZGUsIHJpZ2h0U2lkZV07XG5cdH0sXG5cblx0LyoqXG5cdCAqIEhhbmRsZSB0aGUgbGFiZWwgb3ZlcmZsb3cgYnkgYWRqdXN0aW5nIHRoZSBsYWJlbHMgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0IGVkZ2UsIG9yXG5cdCAqIGhpZGUgdGhlbSBpZiB0aGV5IGNvbGxpZGUgaW50byB0aGUgbmVpZ2hib3VyIGxhYmVsLlxuXHQgKi9cblx0aGFuZGxlT3ZlcmZsb3c6IGZ1bmN0aW9uIChpbmRleCwgeHkpIHtcblx0XHR2YXIgc2hvdyA9IHRydWUsXG5cdFx0XHRheGlzID0gdGhpcy5heGlzLFxuXHRcdFx0aXNGaXJzdCA9IHRoaXMuaXNGaXJzdCxcblx0XHRcdGlzTGFzdCA9IHRoaXMuaXNMYXN0LFxuXHRcdFx0aG9yaXogPSBheGlzLmhvcml6LFxuXHRcdFx0cHhQb3MgPSBob3JpeiA/IHh5LnggOiB4eS55LFxuXHRcdFx0cmV2ZXJzZWQgPSBheGlzLnJldmVyc2VkLFxuXHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMudGlja1Bvc2l0aW9ucyxcblx0XHRcdHNpZGVzID0gdGhpcy5nZXRMYWJlbFNpZGVzKCksXG5cdFx0XHRsZWZ0U2lkZSA9IHNpZGVzWzBdLFxuXHRcdFx0cmlnaHRTaWRlID0gc2lkZXNbMV0sXG5cdFx0XHRheGlzTGVmdCxcblx0XHRcdGF4aXNSaWdodCxcblx0XHRcdG5laWdoYm91cixcblx0XHRcdG5laWdoYm91ckVkZ2UsXG5cdFx0XHRsaW5lID0gdGhpcy5sYWJlbC5saW5lLFxuXHRcdFx0bGluZUluZGV4ID0gbGluZSB8fCAwLFxuXHRcdFx0bGFiZWxFZGdlID0gYXhpcy5sYWJlbEVkZ2UsXG5cdFx0XHRqdXN0aWZ5TGFiZWwgPSBheGlzLmp1c3RpZnlMYWJlbHMgJiYgKGlzRmlyc3QgfHwgaXNMYXN0KSxcblx0XHRcdGp1c3RpZnlUb1Bsb3Q7XG5cblx0XHQvLyBIaWRlIGl0IGlmIGl0IG5vdyBvdmVybGFwcyB0aGUgbmVpZ2hib3VyIGxhYmVsXG5cdFx0aWYgKGxhYmVsRWRnZVtsaW5lSW5kZXhdID09PSBVTkRFRklORUQgfHwgcHhQb3MgKyBsZWZ0U2lkZSA+IGxhYmVsRWRnZVtsaW5lSW5kZXhdKSB7XG5cdFx0XHRsYWJlbEVkZ2VbbGluZUluZGV4XSA9IHB4UG9zICsgcmlnaHRTaWRlO1xuXG5cdFx0fSBlbHNlIGlmICghanVzdGlmeUxhYmVsKSB7XG5cdFx0XHRzaG93ID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKGp1c3RpZnlMYWJlbCkge1xuXHRcdFx0anVzdGlmeVRvUGxvdCA9IGF4aXMuanVzdGlmeVRvUGxvdDtcblx0XHRcdGF4aXNMZWZ0ID0ganVzdGlmeVRvUGxvdCA/IGF4aXMucG9zIDogMDtcblx0XHRcdGF4aXNSaWdodCA9IGp1c3RpZnlUb1Bsb3QgPyBheGlzTGVmdCArIGF4aXMubGVuIDogYXhpcy5jaGFydC5jaGFydFdpZHRoO1xuXG5cdFx0XHQvLyBGaW5kIHRoZSBmaXJzdGggbmVpZ2hib3VyIG9uIHRoZSBzYW1lIGxpbmVcblx0XHRcdGRvIHtcblx0XHRcdFx0aW5kZXggKz0gKGlzRmlyc3QgPyAxIDogLTEpO1xuXHRcdFx0XHRuZWlnaGJvdXIgPSBheGlzLnRpY2tzW3RpY2tQb3NpdGlvbnNbaW5kZXhdXTtcblx0XHRcdH0gd2hpbGUgKHRpY2tQb3NpdGlvbnNbaW5kZXhdICYmICghbmVpZ2hib3VyIHx8ICFuZWlnaGJvdXIubGFiZWwgfHwgbmVpZ2hib3VyLmxhYmVsLmxpbmUgIT09IGxpbmUpKTsgLy8gIzMwNDRcblxuXHRcdFx0bmVpZ2hib3VyRWRnZSA9IG5laWdoYm91ciAmJiBuZWlnaGJvdXIubGFiZWwueHkgJiYgbmVpZ2hib3VyLmxhYmVsLnh5LnggKyBuZWlnaGJvdXIuZ2V0TGFiZWxTaWRlcygpW2lzRmlyc3QgPyAwIDogMV07XG5cblx0XHRcdGlmICgoaXNGaXJzdCAmJiAhcmV2ZXJzZWQpIHx8IChpc0xhc3QgJiYgcmV2ZXJzZWQpKSB7XG5cdFx0XHRcdC8vIElzIHRoZSBsYWJlbCBzcGlsbGluZyBvdXQgdG8gdGhlIGxlZnQgb2YgdGhlIHBsb3QgYXJlYT9cblx0XHRcdFx0aWYgKHB4UG9zICsgbGVmdFNpZGUgPCBheGlzTGVmdCkge1xuXG5cdFx0XHRcdFx0Ly8gQWxpZ24gaXQgdG8gcGxvdCBsZWZ0XG5cdFx0XHRcdFx0cHhQb3MgPSBheGlzTGVmdCAtIGxlZnRTaWRlO1xuXG5cdFx0XHRcdFx0Ly8gSGlkZSBpdCBpZiBpdCBub3cgb3ZlcmxhcHMgdGhlIG5laWdoYm91ciBsYWJlbFxuXHRcdFx0XHRcdGlmIChuZWlnaGJvdXIgJiYgcHhQb3MgKyByaWdodFNpZGUgPiBuZWlnaGJvdXJFZGdlKSB7XG5cdFx0XHRcdFx0XHRzaG93ID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIElzIHRoZSBsYWJlbCBzcGlsbGluZyBvdXQgdG8gdGhlIHJpZ2h0IG9mIHRoZSBwbG90IGFyZWE/XG5cdFx0XHRcdGlmIChweFBvcyArIHJpZ2h0U2lkZSA+IGF4aXNSaWdodCkge1xuXG5cdFx0XHRcdFx0Ly8gQWxpZ24gaXQgdG8gcGxvdCByaWdodFxuXHRcdFx0XHRcdHB4UG9zID0gYXhpc1JpZ2h0IC0gcmlnaHRTaWRlO1xuXG5cdFx0XHRcdFx0Ly8gSGlkZSBpdCBpZiBpdCBub3cgb3ZlcmxhcHMgdGhlIG5laWdoYm91ciBsYWJlbFxuXHRcdFx0XHRcdGlmIChuZWlnaGJvdXIgJiYgcHhQb3MgKyBsZWZ0U2lkZSA8IG5laWdoYm91ckVkZ2UpIHtcblx0XHRcdFx0XHRcdHNob3cgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIG1vZGlmaWVkIHggcG9zaXRpb24gb2YgdGhlIGxhYmVsXG5cdFx0XHR4eS54ID0gcHhQb3M7XG5cdFx0fVxuXHRcdHJldHVybiBzaG93O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHggYW5kIHkgcG9zaXRpb24gZm9yIHRpY2tzIGFuZCBsYWJlbHNcblx0ICovXG5cdGdldFBvc2l0aW9uOiBmdW5jdGlvbiAoaG9yaXosIHBvcywgdGlja21hcmtPZmZzZXQsIG9sZCkge1xuXHRcdHZhciBheGlzID0gdGhpcy5heGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0Y0hlaWdodCA9IChvbGQgJiYgY2hhcnQub2xkQ2hhcnRIZWlnaHQpIHx8IGNoYXJ0LmNoYXJ0SGVpZ2h0O1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IGhvcml6ID9cblx0XHRcdFx0YXhpcy50cmFuc2xhdGUocG9zICsgdGlja21hcmtPZmZzZXQsIG51bGwsIG51bGwsIG9sZCkgKyBheGlzLnRyYW5zQiA6XG5cdFx0XHRcdGF4aXMubGVmdCArIGF4aXMub2Zmc2V0ICsgKGF4aXMub3Bwb3NpdGUgPyAoKG9sZCAmJiBjaGFydC5vbGRDaGFydFdpZHRoKSB8fCBjaGFydC5jaGFydFdpZHRoKSAtIGF4aXMucmlnaHQgLSBheGlzLmxlZnQgOiAwKSxcblxuXHRcdFx0eTogaG9yaXogP1xuXHRcdFx0XHRjSGVpZ2h0IC0gYXhpcy5ib3R0b20gKyBheGlzLm9mZnNldCAtIChheGlzLm9wcG9zaXRlID8gYXhpcy5oZWlnaHQgOiAwKSA6XG5cdFx0XHRcdGNIZWlnaHQgLSBheGlzLnRyYW5zbGF0ZShwb3MgKyB0aWNrbWFya09mZnNldCwgbnVsbCwgbnVsbCwgb2xkKSAtIGF4aXMudHJhbnNCXG5cdFx0fTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHgsIHkgcG9zaXRpb24gb2YgdGhlIHRpY2sgbGFiZWxcblx0ICovXG5cdGdldExhYmVsUG9zaXRpb246IGZ1bmN0aW9uICh4LCB5LCBsYWJlbCwgaG9yaXosIGxhYmVsT3B0aW9ucywgdGlja21hcmtPZmZzZXQsIGluZGV4LCBzdGVwKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLmF4aXMsXG5cdFx0XHR0cmFuc0EgPSBheGlzLnRyYW5zQSxcblx0XHRcdHJldmVyc2VkID0gYXhpcy5yZXZlcnNlZCxcblx0XHRcdHN0YWdnZXJMaW5lcyA9IGF4aXMuc3RhZ2dlckxpbmVzO1xuXG5cdFx0eCA9IHggKyBsYWJlbE9wdGlvbnMueCAtICh0aWNrbWFya09mZnNldCAmJiBob3JpeiA/XG5cdFx0XHR0aWNrbWFya09mZnNldCAqIHRyYW5zQSAqIChyZXZlcnNlZCA/IC0xIDogMSkgOiAwKTtcblx0XHR5ID0geSArIHRoaXMueU9mZnNldCAtICh0aWNrbWFya09mZnNldCAmJiAhaG9yaXogP1xuXHRcdFx0dGlja21hcmtPZmZzZXQgKiB0cmFuc0EgKiAocmV2ZXJzZWQgPyAxIDogLTEpIDogMCk7XG5cblx0XHQvLyBDb3JyZWN0IGZvciBzdGFnZ2VyZWQgbGFiZWxzXG5cdFx0aWYgKHN0YWdnZXJMaW5lcykge1xuXHRcdFx0bGFiZWwubGluZSA9IChpbmRleCAvIChzdGVwIHx8IDEpICUgc3RhZ2dlckxpbmVzKTtcblx0XHRcdHkgKz0gbGFiZWwubGluZSAqIChheGlzLmxhYmVsT2Zmc2V0IC8gc3RhZ2dlckxpbmVzKTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0eDogeCxcblx0XHRcdHk6IHlcblx0XHR9O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBFeHRlbmRpYmxlIG1ldGhvZCB0byByZXR1cm4gdGhlIHBhdGggb2YgdGhlIG1hcmtlclxuXHQgKi9cblx0Z2V0TWFya1BhdGg6IGZ1bmN0aW9uICh4LCB5LCB0aWNrTGVuZ3RoLCB0aWNrV2lkdGgsIGhvcml6LCByZW5kZXJlcikge1xuXHRcdHJldHVybiByZW5kZXJlci5jcmlzcExpbmUoW1xuXHRcdFx0XHRNLFxuXHRcdFx0XHR4LFxuXHRcdFx0XHR5LFxuXHRcdFx0XHRMLFxuXHRcdFx0XHR4ICsgKGhvcml6ID8gMCA6IC10aWNrTGVuZ3RoKSxcblx0XHRcdFx0eSArIChob3JpeiA/IHRpY2tMZW5ndGggOiAwKVxuXHRcdFx0XSwgdGlja1dpZHRoKTtcblx0fSxcblxuXHQvKipcblx0ICogUHV0IGV2ZXJ5dGhpbmcgaW4gcGxhY2Vcblx0ICpcblx0ICogQHBhcmFtIGluZGV4IHtOdW1iZXJ9XG5cdCAqIEBwYXJhbSBvbGQge0Jvb2xlYW59IFVzZSBvbGQgY29vcmRpbmF0ZXMgdG8gcHJlcGFyZSBhbiBhbmltYXRpb24gaW50byBuZXcgcG9zaXRpb25cblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKGluZGV4LCBvbGQsIG9wYWNpdHkpIHtcblx0XHR2YXIgdGljayA9IHRoaXMsXG5cdFx0XHRheGlzID0gdGljay5heGlzLFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHR0eXBlID0gdGljay50eXBlLFxuXHRcdFx0bGFiZWwgPSB0aWNrLmxhYmVsLFxuXHRcdFx0cG9zID0gdGljay5wb3MsXG5cdFx0XHRsYWJlbE9wdGlvbnMgPSBvcHRpb25zLmxhYmVscyxcblx0XHRcdGdyaWRMaW5lID0gdGljay5ncmlkTGluZSxcblx0XHRcdGdyaWRQcmVmaXggPSB0eXBlID8gdHlwZSArICdHcmlkJyA6ICdncmlkJyxcblx0XHRcdHRpY2tQcmVmaXggPSB0eXBlID8gdHlwZSArICdUaWNrJyA6ICd0aWNrJyxcblx0XHRcdGdyaWRMaW5lV2lkdGggPSBvcHRpb25zW2dyaWRQcmVmaXggKyAnTGluZVdpZHRoJ10sXG5cdFx0XHRncmlkTGluZUNvbG9yID0gb3B0aW9uc1tncmlkUHJlZml4ICsgJ0xpbmVDb2xvciddLFxuXHRcdFx0ZGFzaFN0eWxlID0gb3B0aW9uc1tncmlkUHJlZml4ICsgJ0xpbmVEYXNoU3R5bGUnXSxcblx0XHRcdHRpY2tMZW5ndGggPSBvcHRpb25zW3RpY2tQcmVmaXggKyAnTGVuZ3RoJ10sXG5cdFx0XHR0aWNrV2lkdGggPSBvcHRpb25zW3RpY2tQcmVmaXggKyAnV2lkdGgnXSB8fCAwLFxuXHRcdFx0dGlja0NvbG9yID0gb3B0aW9uc1t0aWNrUHJlZml4ICsgJ0NvbG9yJ10sXG5cdFx0XHR0aWNrUG9zaXRpb24gPSBvcHRpb25zW3RpY2tQcmVmaXggKyAnUG9zaXRpb24nXSxcblx0XHRcdGdyaWRMaW5lUGF0aCxcblx0XHRcdG1hcmsgPSB0aWNrLm1hcmssXG5cdFx0XHRtYXJrUGF0aCxcblx0XHRcdHN0ZXAgPSBsYWJlbE9wdGlvbnMuc3RlcCxcblx0XHRcdGF0dHJpYnMsXG5cdFx0XHRzaG93ID0gdHJ1ZSxcblx0XHRcdHRpY2ttYXJrT2Zmc2V0ID0gYXhpcy50aWNrbWFya09mZnNldCxcblx0XHRcdHh5ID0gdGljay5nZXRQb3NpdGlvbihob3JpeiwgcG9zLCB0aWNrbWFya09mZnNldCwgb2xkKSxcblx0XHRcdHggPSB4eS54LFxuXHRcdFx0eSA9IHh5LnksXG5cdFx0XHRyZXZlcnNlQ3Jpc3AgPSAoKGhvcml6ICYmIHggPT09IGF4aXMucG9zICsgYXhpcy5sZW4pIHx8ICghaG9yaXogJiYgeSA9PT0gYXhpcy5wb3MpKSA/IC0xIDogMTsgLy8gIzE0ODAsICMxNjg3XG5cblx0XHRvcGFjaXR5ID0gcGljayhvcGFjaXR5LCAxKTtcblx0XHR0aGlzLmlzQWN0aXZlID0gdHJ1ZTtcblxuXHRcdC8vIGNyZWF0ZSB0aGUgZ3JpZCBsaW5lXG5cdFx0aWYgKGdyaWRMaW5lV2lkdGgpIHtcblx0XHRcdGdyaWRMaW5lUGF0aCA9IGF4aXMuZ2V0UGxvdExpbmVQYXRoKHBvcyArIHRpY2ttYXJrT2Zmc2V0LCBncmlkTGluZVdpZHRoICogcmV2ZXJzZUNyaXNwLCBvbGQsIHRydWUpO1xuXG5cdFx0XHRpZiAoZ3JpZExpbmUgPT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRhdHRyaWJzID0ge1xuXHRcdFx0XHRcdHN0cm9rZTogZ3JpZExpbmVDb2xvcixcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogZ3JpZExpbmVXaWR0aFxuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAoZGFzaFN0eWxlKSB7XG5cdFx0XHRcdFx0YXR0cmlicy5kYXNoc3R5bGUgPSBkYXNoU3R5bGU7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCF0eXBlKSB7XG5cdFx0XHRcdFx0YXR0cmlicy56SW5kZXggPSAxO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChvbGQpIHtcblx0XHRcdFx0XHRhdHRyaWJzLm9wYWNpdHkgPSAwO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRpY2suZ3JpZExpbmUgPSBncmlkTGluZSA9XG5cdFx0XHRcdFx0Z3JpZExpbmVXaWR0aCA/XG5cdFx0XHRcdFx0XHRyZW5kZXJlci5wYXRoKGdyaWRMaW5lUGF0aClcblx0XHRcdFx0XHRcdFx0LmF0dHIoYXR0cmlicykuYWRkKGF4aXMuZ3JpZEdyb3VwKSA6XG5cdFx0XHRcdFx0XHRudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGUgcGFyYW1ldGVyICdvbGQnIGlzIHNldCwgdGhlIGN1cnJlbnQgY2FsbCB3aWxsIGJlIGZvbGxvd2VkXG5cdFx0XHQvLyBieSBhbm90aGVyIGNhbGwsIHRoZXJlZm9yZSBkbyBub3QgZG8gYW55IGFuaW1hdGlvbnMgdGhpcyB0aW1lXG5cdFx0XHRpZiAoIW9sZCAmJiBncmlkTGluZSAmJiBncmlkTGluZVBhdGgpIHtcblx0XHRcdFx0Z3JpZExpbmVbdGljay5pc05ldyA/ICdhdHRyJyA6ICdhbmltYXRlJ10oe1xuXHRcdFx0XHRcdGQ6IGdyaWRMaW5lUGF0aCxcblx0XHRcdFx0XHRvcGFjaXR5OiBvcGFjaXR5XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGNyZWF0ZSB0aGUgdGljayBtYXJrXG5cdFx0aWYgKHRpY2tXaWR0aCAmJiB0aWNrTGVuZ3RoKSB7XG5cblx0XHRcdC8vIG5lZ2F0ZSB0aGUgbGVuZ3RoXG5cdFx0XHRpZiAodGlja1Bvc2l0aW9uID09PSAnaW5zaWRlJykge1xuXHRcdFx0XHR0aWNrTGVuZ3RoID0gLXRpY2tMZW5ndGg7XG5cdFx0XHR9XG5cdFx0XHRpZiAoYXhpcy5vcHBvc2l0ZSkge1xuXHRcdFx0XHR0aWNrTGVuZ3RoID0gLXRpY2tMZW5ndGg7XG5cdFx0XHR9XG5cblx0XHRcdG1hcmtQYXRoID0gdGljay5nZXRNYXJrUGF0aCh4LCB5LCB0aWNrTGVuZ3RoLCB0aWNrV2lkdGggKiByZXZlcnNlQ3Jpc3AsIGhvcml6LCByZW5kZXJlcik7XG5cdFx0XHRpZiAobWFyaykgeyAvLyB1cGRhdGluZ1xuXHRcdFx0XHRtYXJrLmFuaW1hdGUoe1xuXHRcdFx0XHRcdGQ6IG1hcmtQYXRoLFxuXHRcdFx0XHRcdG9wYWNpdHk6IG9wYWNpdHlcblx0XHRcdFx0fSk7XG5cdFx0XHR9IGVsc2UgeyAvLyBmaXJzdCB0aW1lXG5cdFx0XHRcdHRpY2subWFyayA9IHJlbmRlcmVyLnBhdGgoXG5cdFx0XHRcdFx0bWFya1BhdGhcblx0XHRcdFx0KS5hdHRyKHtcblx0XHRcdFx0XHRzdHJva2U6IHRpY2tDb2xvcixcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogdGlja1dpZHRoLFxuXHRcdFx0XHRcdG9wYWNpdHk6IG9wYWNpdHlcblx0XHRcdFx0fSkuYWRkKGF4aXMuYXhpc0dyb3VwKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyB0aGUgbGFiZWwgaXMgY3JlYXRlZCBvbiBpbml0IC0gbm93IG1vdmUgaXQgaW50byBwbGFjZVxuXHRcdGlmIChsYWJlbCAmJiAhaXNOYU4oeCkpIHtcblx0XHRcdGxhYmVsLnh5ID0geHkgPSB0aWNrLmdldExhYmVsUG9zaXRpb24oeCwgeSwgbGFiZWwsIGhvcml6LCBsYWJlbE9wdGlvbnMsIHRpY2ttYXJrT2Zmc2V0LCBpbmRleCwgc3RlcCk7XG5cblx0XHRcdC8vIEFwcGx5IHNob3cgZmlyc3QgYW5kIHNob3cgbGFzdC4gSWYgdGhlIHRpY2sgaXMgYm90aCBmaXJzdCBhbmQgbGFzdCwgaXQgaXNcblx0XHRcdC8vIGEgc2luZ2xlIGNlbnRlcmVkIHRpY2ssIGluIHdoaWNoIGNhc2Ugd2Ugc2hvdyB0aGUgbGFiZWwgYW55d2F5ICgjMjEwMCkuXG5cdFx0XHRpZiAoKHRpY2suaXNGaXJzdCAmJiAhdGljay5pc0xhc3QgJiYgIXBpY2sob3B0aW9ucy5zaG93Rmlyc3RMYWJlbCwgMSkpIHx8XG5cdFx0XHRcdFx0KHRpY2suaXNMYXN0ICYmICF0aWNrLmlzRmlyc3QgJiYgIXBpY2sob3B0aW9ucy5zaG93TGFzdExhYmVsLCAxKSkpIHtcblx0XHRcdFx0c2hvdyA9IGZhbHNlO1xuXG5cdFx0XHQvLyBIYW5kbGUgbGFiZWwgb3ZlcmZsb3cgYW5kIHNob3cgb3IgaGlkZSBhY2NvcmRpbmdseVxuXHRcdFx0fSBlbHNlIGlmICghYXhpcy5pc1JhZGlhbCAmJiAhbGFiZWxPcHRpb25zLnN0ZXAgJiYgIWxhYmVsT3B0aW9ucy5yb3RhdGlvbiAmJiAhb2xkICYmIG9wYWNpdHkgIT09IDApIHtcblx0XHRcdFx0c2hvdyA9IHRpY2suaGFuZGxlT3ZlcmZsb3coaW5kZXgsIHh5KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gYXBwbHkgc3RlcFxuXHRcdFx0aWYgKHN0ZXAgJiYgaW5kZXggJSBzdGVwKSB7XG5cdFx0XHRcdC8vIHNob3cgdGhvc2UgaW5kaWNlcyBkaXZpZGFibGUgYnkgc3RlcFxuXHRcdFx0XHRzaG93ID0gZmFsc2U7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgbmV3IHBvc2l0aW9uLCBhbmQgc2hvdyBvciBoaWRlXG5cdFx0XHRpZiAoc2hvdyAmJiAhaXNOYU4oeHkueSkpIHtcblx0XHRcdFx0eHkub3BhY2l0eSA9IG9wYWNpdHk7XG5cdFx0XHRcdGxhYmVsW3RpY2suaXNOZXcgPyAnYXR0cicgOiAnYW5pbWF0ZSddKHh5KTtcblx0XHRcdFx0dGljay5pc05ldyA9IGZhbHNlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bGFiZWwuYXR0cigneScsIC05OTk5KTsgLy8gIzEzMzhcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3RydWN0b3IgZm9yIHRoZSB0aWNrIHByb3RvdHlwZVxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdGRlc3Ryb3lPYmplY3RQcm9wZXJ0aWVzKHRoaXMsIHRoaXMuYXhpcyk7XG5cdH1cbn07XG5cbi8qKlxuICogVGhlIG9iamVjdCB3cmFwcGVyIGZvciBwbG90IGxpbmVzIGFuZCBwbG90IGJhbmRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5IaWdoY2hhcnRzLlBsb3RMaW5lT3JCYW5kID0gZnVuY3Rpb24gKGF4aXMsIG9wdGlvbnMpIHtcblx0dGhpcy5heGlzID0gYXhpcztcblxuXHRpZiAob3B0aW9ucykge1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5pZCA9IG9wdGlvbnMuaWQ7XG5cdH1cbn07XG5cbkhpZ2hjaGFydHMuUGxvdExpbmVPckJhbmQucHJvdG90eXBlID0ge1xuXHRcblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgcGxvdCBsaW5lIG9yIHBsb3QgYmFuZC4gSWYgaXQgaXMgYWxyZWFkeSBleGlzdGluZyxcblx0ICogbW92ZSBpdC5cblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBwbG90TGluZSA9IHRoaXMsXG5cdFx0XHRheGlzID0gcGxvdExpbmUuYXhpcyxcblx0XHRcdGhvcml6ID0gYXhpcy5ob3Jpeixcblx0XHRcdGhhbGZQb2ludFJhbmdlID0gKGF4aXMucG9pbnRSYW5nZSB8fCAwKSAvIDIsXG5cdFx0XHRvcHRpb25zID0gcGxvdExpbmUub3B0aW9ucyxcblx0XHRcdG9wdGlvbnNMYWJlbCA9IG9wdGlvbnMubGFiZWwsXG5cdFx0XHRsYWJlbCA9IHBsb3RMaW5lLmxhYmVsLFxuXHRcdFx0d2lkdGggPSBvcHRpb25zLndpZHRoLFxuXHRcdFx0dG8gPSBvcHRpb25zLnRvLFxuXHRcdFx0ZnJvbSA9IG9wdGlvbnMuZnJvbSxcblx0XHRcdGlzQmFuZCA9IGRlZmluZWQoZnJvbSkgJiYgZGVmaW5lZCh0byksXG5cdFx0XHR2YWx1ZSA9IG9wdGlvbnMudmFsdWUsXG5cdFx0XHRkYXNoU3R5bGUgPSBvcHRpb25zLmRhc2hTdHlsZSxcblx0XHRcdHN2Z0VsZW0gPSBwbG90TGluZS5zdmdFbGVtLFxuXHRcdFx0cGF0aCA9IFtdLFxuXHRcdFx0YWRkRXZlbnQsXG5cdFx0XHRldmVudFR5cGUsXG5cdFx0XHR4cyxcblx0XHRcdHlzLFxuXHRcdFx0eCxcblx0XHRcdHksXG5cdFx0XHRjb2xvciA9IG9wdGlvbnMuY29sb3IsXG5cdFx0XHR6SW5kZXggPSBvcHRpb25zLnpJbmRleCxcblx0XHRcdGV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzLFxuXHRcdFx0YXR0cmlicyA9IHt9LFxuXHRcdFx0cmVuZGVyZXIgPSBheGlzLmNoYXJ0LnJlbmRlcmVyO1xuXG5cdFx0Ly8gbG9nYXJpdGhtaWMgY29udmVyc2lvblxuXHRcdGlmIChheGlzLmlzTG9nKSB7XG5cdFx0XHRmcm9tID0gbG9nMmxpbihmcm9tKTtcblx0XHRcdHRvID0gbG9nMmxpbih0byk7XG5cdFx0XHR2YWx1ZSA9IGxvZzJsaW4odmFsdWUpO1xuXHRcdH1cblxuXHRcdC8vIHBsb3QgbGluZVxuXHRcdGlmICh3aWR0aCkge1xuXHRcdFx0cGF0aCA9IGF4aXMuZ2V0UGxvdExpbmVQYXRoKHZhbHVlLCB3aWR0aCk7XG5cdFx0XHRhdHRyaWJzID0ge1xuXHRcdFx0XHRzdHJva2U6IGNvbG9yLFxuXHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogd2lkdGhcblx0XHRcdH07XG5cdFx0XHRpZiAoZGFzaFN0eWxlKSB7XG5cdFx0XHRcdGF0dHJpYnMuZGFzaHN0eWxlID0gZGFzaFN0eWxlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoaXNCYW5kKSB7IC8vIHBsb3QgYmFuZFxuXHRcdFx0XG5cdFx0XHQvLyBrZWVwIHdpdGhpbiBwbG90IGFyZWFcblx0XHRcdGZyb20gPSBtYXRoTWF4KGZyb20sIGF4aXMubWluIC0gaGFsZlBvaW50UmFuZ2UpO1xuXHRcdFx0dG8gPSBtYXRoTWluKHRvLCBheGlzLm1heCArIGhhbGZQb2ludFJhbmdlKTtcblx0XHRcdFxuXHRcdFx0cGF0aCA9IGF4aXMuZ2V0UGxvdEJhbmRQYXRoKGZyb20sIHRvLCBvcHRpb25zKTtcblx0XHRcdGlmIChjb2xvcikge1xuXHRcdFx0XHRhdHRyaWJzLmZpbGwgPSBjb2xvcjtcblx0XHRcdH1cblx0XHRcdGlmIChvcHRpb25zLmJvcmRlcldpZHRoKSB7XG5cdFx0XHRcdGF0dHJpYnMuc3Ryb2tlID0gb3B0aW9ucy5ib3JkZXJDb2xvcjtcblx0XHRcdFx0YXR0cmlic1snc3Ryb2tlLXdpZHRoJ10gPSBvcHRpb25zLmJvcmRlcldpZHRoO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdC8vIHpJbmRleFxuXHRcdGlmIChkZWZpbmVkKHpJbmRleCkpIHtcblx0XHRcdGF0dHJpYnMuekluZGV4ID0gekluZGV4O1xuXHRcdH1cblxuXHRcdC8vIGNvbW1vbiBmb3IgbGluZXMgYW5kIGJhbmRzXG5cdFx0aWYgKHN2Z0VsZW0pIHtcblx0XHRcdGlmIChwYXRoKSB7XG5cdFx0XHRcdHN2Z0VsZW0uYW5pbWF0ZSh7XG5cdFx0XHRcdFx0ZDogcGF0aFxuXHRcdFx0XHR9LCBudWxsLCBzdmdFbGVtLm9uR2V0UGF0aCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzdmdFbGVtLmhpZGUoKTtcblx0XHRcdFx0c3ZnRWxlbS5vbkdldFBhdGggPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0c3ZnRWxlbS5zaG93KCk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmIChsYWJlbCkge1xuXHRcdFx0XHRcdHBsb3RMaW5lLmxhYmVsID0gbGFiZWwgPSBsYWJlbC5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKHBhdGggJiYgcGF0aC5sZW5ndGgpIHtcblx0XHRcdHBsb3RMaW5lLnN2Z0VsZW0gPSBzdmdFbGVtID0gcmVuZGVyZXIucGF0aChwYXRoKVxuXHRcdFx0XHQuYXR0cihhdHRyaWJzKS5hZGQoKTtcblxuXHRcdFx0Ly8gZXZlbnRzXG5cdFx0XHRpZiAoZXZlbnRzKSB7XG5cdFx0XHRcdGFkZEV2ZW50ID0gZnVuY3Rpb24gKGV2ZW50VHlwZSkge1xuXHRcdFx0XHRcdHN2Z0VsZW0ub24oZXZlbnRUeXBlLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRcdFx0ZXZlbnRzW2V2ZW50VHlwZV0uYXBwbHkocGxvdExpbmUsIFtlXSk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdGZvciAoZXZlbnRUeXBlIGluIGV2ZW50cykge1xuXHRcdFx0XHRcdGFkZEV2ZW50KGV2ZW50VHlwZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyB0aGUgcGxvdCBiYW5kL2xpbmUgbGFiZWxcblx0XHRpZiAob3B0aW9uc0xhYmVsICYmIGRlZmluZWQob3B0aW9uc0xhYmVsLnRleHQpICYmIHBhdGggJiYgcGF0aC5sZW5ndGggJiYgYXhpcy53aWR0aCA+IDAgJiYgYXhpcy5oZWlnaHQgPiAwKSB7XG5cdFx0XHQvLyBhcHBseSBkZWZhdWx0c1xuXHRcdFx0b3B0aW9uc0xhYmVsID0gbWVyZ2Uoe1xuXHRcdFx0XHRhbGlnbjogaG9yaXogJiYgaXNCYW5kICYmICdjZW50ZXInLFxuXHRcdFx0XHR4OiBob3JpeiA/ICFpc0JhbmQgJiYgNCA6IDEwLFxuXHRcdFx0XHR2ZXJ0aWNhbEFsaWduIDogIWhvcml6ICYmIGlzQmFuZCAmJiAnbWlkZGxlJyxcblx0XHRcdFx0eTogaG9yaXogPyBpc0JhbmQgPyAxNiA6IDEwIDogaXNCYW5kID8gNiA6IC00LFxuXHRcdFx0XHRyb3RhdGlvbjogaG9yaXogJiYgIWlzQmFuZCAmJiA5MFxuXHRcdFx0fSwgb3B0aW9uc0xhYmVsKTtcblxuXHRcdFx0Ly8gYWRkIHRoZSBTVkcgZWxlbWVudFxuXHRcdFx0aWYgKCFsYWJlbCkge1xuXHRcdFx0XHRhdHRyaWJzID0ge1xuXHRcdFx0XHRcdGFsaWduOiBvcHRpb25zTGFiZWwudGV4dEFsaWduIHx8IG9wdGlvbnNMYWJlbC5hbGlnbixcblx0XHRcdFx0XHRyb3RhdGlvbjogb3B0aW9uc0xhYmVsLnJvdGF0aW9uXG5cdFx0XHRcdH07XG5cdFx0XHRcdGlmIChkZWZpbmVkKHpJbmRleCkpIHtcblx0XHRcdFx0XHRhdHRyaWJzLnpJbmRleCA9IHpJbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0XHRwbG90TGluZS5sYWJlbCA9IGxhYmVsID0gcmVuZGVyZXIudGV4dChcblx0XHRcdFx0XHRcdG9wdGlvbnNMYWJlbC50ZXh0LFxuXHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRvcHRpb25zTGFiZWwudXNlSFRNTFxuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuYXR0cihhdHRyaWJzKVxuXHRcdFx0XHRcdC5jc3Mob3B0aW9uc0xhYmVsLnN0eWxlKVxuXHRcdFx0XHRcdC5hZGQoKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gZ2V0IHRoZSBib3VuZGluZyBib3ggYW5kIGFsaWduIHRoZSBsYWJlbFxuXHRcdFx0Ly8gIzMwMDAgY2hhbmdlZCB0byBiZXR0ZXIgaGFuZGxlIGNob2ljZSBiZXR3ZWVuIHBsb3RiYW5kIG9yIHBsb3RsaW5lXG5cdFx0XHR4cyA9IFtwYXRoWzFdLCBwYXRoWzRdLCAoaXNCYW5kID8gcGF0aFs2XSA6IHBhdGhbMV0pXTtcblx0XHRcdHlzID0gW3BhdGhbMl0sIHBhdGhbNV0sIChpc0JhbmQgPyBwYXRoWzddIDogcGF0aFsyXSldO1xuXHRcdFx0eCA9IGFycmF5TWluKHhzKTtcblx0XHRcdHkgPSBhcnJheU1pbih5cyk7XG5cblx0XHRcdGxhYmVsLmFsaWduKG9wdGlvbnNMYWJlbCwgZmFsc2UsIHtcblx0XHRcdFx0eDogeCxcblx0XHRcdFx0eTogeSxcblx0XHRcdFx0d2lkdGg6IGFycmF5TWF4KHhzKSAtIHgsXG5cdFx0XHRcdGhlaWdodDogYXJyYXlNYXgoeXMpIC0geVxuXHRcdFx0fSk7XG5cdFx0XHRsYWJlbC5zaG93KCk7XG5cblx0XHR9IGVsc2UgaWYgKGxhYmVsKSB7IC8vIG1vdmUgb3V0IG9mIHNpZ2h0XG5cdFx0XHRsYWJlbC5oaWRlKCk7XG5cdFx0fVxuXG5cdFx0Ly8gY2hhaW5hYmxlXG5cdFx0cmV0dXJuIHBsb3RMaW5lO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgdGhlIHBsb3QgbGluZSBvciBiYW5kXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0Ly8gcmVtb3ZlIGl0IGZyb20gdGhlIGxvb2t1cFxuXHRcdGVyYXNlKHRoaXMuYXhpcy5wbG90TGluZXNBbmRCYW5kcywgdGhpcyk7XG5cdFx0XG5cdFx0ZGVsZXRlIHRoaXMuYXhpcztcblx0XHRkZXN0cm95T2JqZWN0UHJvcGVydGllcyh0aGlzKTtcblx0fVxufTtcblxuLyoqXG4gKiBPYmplY3Qgd2l0aCBtZW1iZXJzIGZvciBleHRlbmRpbmcgdGhlIEF4aXMgcHJvdG90eXBlXG4gKi9cblxuQXhpc1Bsb3RMaW5lT3JCYW5kRXh0ZW5zaW9uID0ge1xuXG5cdC8qKlxuXHQgKiBDcmVhdGUgdGhlIHBhdGggZm9yIGEgcGxvdCBiYW5kXG5cdCAqLyBcblx0Z2V0UGxvdEJhbmRQYXRoOiBmdW5jdGlvbiAoZnJvbSwgdG8pIHtcblx0XHR2YXIgdG9QYXRoID0gdGhpcy5nZXRQbG90TGluZVBhdGgodG8pLFxuXHRcdFx0cGF0aCA9IHRoaXMuZ2V0UGxvdExpbmVQYXRoKGZyb20pO1xuXG5cdFx0aWYgKHBhdGggJiYgdG9QYXRoKSB7XG5cdFx0XHRwYXRoLnB1c2goXG5cdFx0XHRcdHRvUGF0aFs0XSxcblx0XHRcdFx0dG9QYXRoWzVdLFxuXHRcdFx0XHR0b1BhdGhbMV0sXG5cdFx0XHRcdHRvUGF0aFsyXVxuXHRcdFx0KTtcblx0XHR9IGVsc2UgeyAvLyBvdXRzaWRlIHRoZSBheGlzIGFyZWFcblx0XHRcdHBhdGggPSBudWxsO1xuXHRcdH1cblx0XHRcblx0XHRyZXR1cm4gcGF0aDtcblx0fSxcblxuXHRhZGRQbG90QmFuZDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0XHRyZXR1cm4gdGhpcy5hZGRQbG90QmFuZE9yTGluZShvcHRpb25zLCAncGxvdEJhbmRzJyk7XG5cdH0sXG5cdFxuXHRhZGRQbG90TGluZTogZnVuY3Rpb24gKG9wdGlvbnMpIHtcblx0XHRyZXR1cm4gdGhpcy5hZGRQbG90QmFuZE9yTGluZShvcHRpb25zLCAncGxvdExpbmVzJyk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkZCBhIHBsb3QgYmFuZCBvciBwbG90IGxpbmUgYWZ0ZXIgcmVuZGVyIHRpbWVcblx0ICpcblx0ICogQHBhcmFtIG9wdGlvbnMge09iamVjdH0gVGhlIHBsb3RCYW5kIG9yIHBsb3RMaW5lIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG5cdCAqL1xuXHRhZGRQbG90QmFuZE9yTGluZTogZnVuY3Rpb24gKG9wdGlvbnMsIGNvbGwpIHtcblx0XHR2YXIgb2JqID0gbmV3IEhpZ2hjaGFydHMuUGxvdExpbmVPckJhbmQodGhpcywgb3B0aW9ucykucmVuZGVyKCksXG5cdFx0XHR1c2VyT3B0aW9ucyA9IHRoaXMudXNlck9wdGlvbnM7XG5cblx0XHRpZiAob2JqKSB7IC8vICMyMTg5XG5cdFx0XHQvLyBBZGQgaXQgdG8gdGhlIHVzZXIgb3B0aW9ucyBmb3IgZXhwb3J0aW5nIGFuZCBBeGlzLnVwZGF0ZVxuXHRcdFx0aWYgKGNvbGwpIHtcblx0XHRcdFx0dXNlck9wdGlvbnNbY29sbF0gPSB1c2VyT3B0aW9uc1tjb2xsXSB8fCBbXTtcblx0XHRcdFx0dXNlck9wdGlvbnNbY29sbF0ucHVzaChvcHRpb25zKTsgXG5cdFx0XHR9XG5cdFx0XHR0aGlzLnBsb3RMaW5lc0FuZEJhbmRzLnB1c2gob2JqKTsgXG5cdFx0fVxuXHRcdFxuXHRcdHJldHVybiBvYmo7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbW92ZSBhIHBsb3QgYmFuZCBvciBwbG90IGxpbmUgZnJvbSB0aGUgY2hhcnQgYnkgaWRcblx0ICogQHBhcmFtIHtPYmplY3R9IGlkXG5cdCAqL1xuXHRyZW1vdmVQbG90QmFuZE9yTGluZTogZnVuY3Rpb24gKGlkKSB7XG5cdFx0dmFyIHBsb3RMaW5lc0FuZEJhbmRzID0gdGhpcy5wbG90TGluZXNBbmRCYW5kcyxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHR1c2VyT3B0aW9ucyA9IHRoaXMudXNlck9wdGlvbnMsXG5cdFx0XHRpID0gcGxvdExpbmVzQW5kQmFuZHMubGVuZ3RoO1xuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdGlmIChwbG90TGluZXNBbmRCYW5kc1tpXS5pZCA9PT0gaWQpIHtcblx0XHRcdFx0cGxvdExpbmVzQW5kQmFuZHNbaV0uZGVzdHJveSgpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRlYWNoKFtvcHRpb25zLnBsb3RMaW5lcyB8fCBbXSwgdXNlck9wdGlvbnMucGxvdExpbmVzIHx8IFtdLCBvcHRpb25zLnBsb3RCYW5kcyB8fCBbXSwgdXNlck9wdGlvbnMucGxvdEJhbmRzIHx8IFtdXSwgZnVuY3Rpb24gKGFycikge1xuXHRcdFx0aSA9IGFyci5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdGlmIChhcnJbaV0uaWQgPT09IGlkKSB7XG5cdFx0XHRcdFx0ZXJhc2UoYXJyLCBhcnJbaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGF4aXMgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gY2hhcnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbmZ1bmN0aW9uIEF4aXMoKSB7XG5cdHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufVxuXG5BeGlzLnByb3RvdHlwZSA9IHtcblxuXHQvKipcblx0ICogRGVmYXVsdCBvcHRpb25zIGZvciB0aGUgWCBheGlzIC0gdGhlIFkgYXhpcyBoYXMgZXh0ZW5kZWQgZGVmYXVsdHNcblx0ICovXG5cdGRlZmF1bHRPcHRpb25zOiB7XG5cdFx0Ly8gYWxsb3dEZWNpbWFsczogbnVsbCxcblx0XHQvLyBhbHRlcm5hdGVHcmlkQ29sb3I6IG51bGwsXG5cdFx0Ly8gY2F0ZWdvcmllczogW10sXG5cdFx0ZGF0ZVRpbWVMYWJlbEZvcm1hdHM6IHtcblx0XHRcdG1pbGxpc2Vjb25kOiAnJUg6JU06JVMuJUwnLFxuXHRcdFx0c2Vjb25kOiAnJUg6JU06JVMnLFxuXHRcdFx0bWludXRlOiAnJUg6JU0nLFxuXHRcdFx0aG91cjogJyVIOiVNJyxcblx0XHRcdGRheTogJyVlLiAlYicsXG5cdFx0XHR3ZWVrOiAnJWUuICViJyxcblx0XHRcdG1vbnRoOiAnJWIgXFwnJXknLFxuXHRcdFx0eWVhcjogJyVZJ1xuXHRcdH0sXG5cdFx0ZW5kT25UaWNrOiBmYWxzZSxcblx0XHRncmlkTGluZUNvbG9yOiAnI0MwQzBDMCcsXG5cdFx0Ly8gZ3JpZExpbmVEYXNoU3R5bGU6ICdzb2xpZCcsXG5cdFx0Ly8gZ3JpZExpbmVXaWR0aDogMCxcblx0XHQvLyByZXZlcnNlZDogZmFsc2UsXG5cblx0XHRsYWJlbHM6IGRlZmF1bHRMYWJlbE9wdGlvbnMsXG5cdFx0XHQvLyB7IHN0ZXA6IG51bGwgfSxcblx0XHRsaW5lQ29sb3I6ICcjQzBEMEUwJyxcblx0XHRsaW5lV2lkdGg6IDEsXG5cdFx0Ly9saW5rZWRUbzogbnVsbCxcblx0XHQvL21heDogdW5kZWZpbmVkLFxuXHRcdC8vbWluOiB1bmRlZmluZWQsXG5cdFx0bWluUGFkZGluZzogMC4wMSxcblx0XHRtYXhQYWRkaW5nOiAwLjAxLFxuXHRcdC8vbWluUmFuZ2U6IG51bGwsXG5cdFx0bWlub3JHcmlkTGluZUNvbG9yOiAnI0UwRTBFMCcsXG5cdFx0Ly8gbWlub3JHcmlkTGluZURhc2hTdHlsZTogbnVsbCxcblx0XHRtaW5vckdyaWRMaW5lV2lkdGg6IDEsXG5cdFx0bWlub3JUaWNrQ29sb3I6ICcjQTBBMEEwJyxcblx0XHQvL21pbm9yVGlja0ludGVydmFsOiBudWxsLFxuXHRcdG1pbm9yVGlja0xlbmd0aDogMixcblx0XHRtaW5vclRpY2tQb3NpdGlvbjogJ291dHNpZGUnLCAvLyBpbnNpZGUgb3Igb3V0c2lkZVxuXHRcdC8vbWlub3JUaWNrV2lkdGg6IDAsXG5cdFx0Ly9vcHBvc2l0ZTogZmFsc2UsXG5cdFx0Ly9vZmZzZXQ6IDAsXG5cdFx0Ly9wbG90QmFuZHM6IFt7XG5cdFx0Ly9cdGV2ZW50czoge30sXG5cdFx0Ly9cdHpJbmRleDogMSxcblx0XHQvL1x0bGFiZWxzOiB7IGFsaWduLCB4LCB2ZXJ0aWNhbEFsaWduLCB5LCBzdHlsZSwgcm90YXRpb24sIHRleHRBbGlnbiB9XG5cdFx0Ly99XSxcblx0XHQvL3Bsb3RMaW5lczogW3tcblx0XHQvL1x0ZXZlbnRzOiB7fVxuXHRcdC8vICBkYXNoU3R5bGU6IHt9XG5cdFx0Ly9cdHpJbmRleDpcblx0XHQvL1x0bGFiZWxzOiB7IGFsaWduLCB4LCB2ZXJ0aWNhbEFsaWduLCB5LCBzdHlsZSwgcm90YXRpb24sIHRleHRBbGlnbiB9XG5cdFx0Ly99XSxcblx0XHQvL3JldmVyc2VkOiBmYWxzZSxcblx0XHQvLyBzaG93Rmlyc3RMYWJlbDogdHJ1ZSxcblx0XHQvLyBzaG93TGFzdExhYmVsOiB0cnVlLFxuXHRcdHN0YXJ0T2ZXZWVrOiAxLFxuXHRcdHN0YXJ0T25UaWNrOiBmYWxzZSxcblx0XHR0aWNrQ29sb3I6ICcjQzBEMEUwJyxcblx0XHQvL3RpY2tJbnRlcnZhbDogbnVsbCxcblx0XHR0aWNrTGVuZ3RoOiAxMCxcblx0XHR0aWNrbWFya1BsYWNlbWVudDogJ2JldHdlZW4nLCAvLyBvbiBvciBiZXR3ZWVuXG5cdFx0dGlja1BpeGVsSW50ZXJ2YWw6IDEwMCxcblx0XHR0aWNrUG9zaXRpb246ICdvdXRzaWRlJyxcblx0XHR0aWNrV2lkdGg6IDEsXG5cdFx0dGl0bGU6IHtcblx0XHRcdC8vdGV4dDogbnVsbCxcblx0XHRcdGFsaWduOiAnbWlkZGxlJywgLy8gbG93LCBtaWRkbGUgb3IgaGlnaFxuXHRcdFx0Ly9tYXJnaW46IDAgZm9yIGhvcml6b250YWwsIDEwIGZvciB2ZXJ0aWNhbCBheGVzLFxuXHRcdFx0Ly9yb3RhdGlvbjogMCxcblx0XHRcdC8vc2lkZTogJ291dHNpZGUnLFxuXHRcdFx0c3R5bGU6IHtcblx0XHRcdFx0Y29sb3I6ICcjNzA3MDcwJ1xuXHRcdFx0fVxuXHRcdFx0Ly94OiAwLFxuXHRcdFx0Ly95OiAwXG5cdFx0fSxcblx0XHR0eXBlOiAnbGluZWFyJyAvLyBsaW5lYXIsIGxvZ2FyaXRobWljIG9yIGRhdGV0aW1lXG5cdH0sXG5cblx0LyoqXG5cdCAqIFRoaXMgb3B0aW9ucyBzZXQgZXh0ZW5kcyB0aGUgZGVmYXVsdE9wdGlvbnMgZm9yIFkgYXhlc1xuXHQgKi9cblx0ZGVmYXVsdFlBeGlzT3B0aW9uczoge1xuXHRcdGVuZE9uVGljazogdHJ1ZSxcblx0XHRncmlkTGluZVdpZHRoOiAxLFxuXHRcdHRpY2tQaXhlbEludGVydmFsOiA3Mixcblx0XHRzaG93TGFzdExhYmVsOiB0cnVlLFxuXHRcdGxhYmVsczoge1xuXHRcdFx0eDogLTgsXG5cdFx0XHR5OiAzXG5cdFx0fSxcblx0XHRsaW5lV2lkdGg6IDAsXG5cdFx0bWF4UGFkZGluZzogMC4wNSxcblx0XHRtaW5QYWRkaW5nOiAwLjA1LFxuXHRcdHN0YXJ0T25UaWNrOiB0cnVlLFxuXHRcdHRpY2tXaWR0aDogMCxcblx0XHR0aXRsZToge1xuXHRcdFx0cm90YXRpb246IDI3MCxcblx0XHRcdHRleHQ6ICdWYWx1ZXMnXG5cdFx0fSxcblx0XHRzdGFja0xhYmVsczoge1xuXHRcdFx0ZW5hYmxlZDogZmFsc2UsXG5cdFx0XHQvL2FsaWduOiBkeW5hbWljLFxuXHRcdFx0Ly95OiBkeW5hbWljLFxuXHRcdFx0Ly94OiBkeW5hbWljLFxuXHRcdFx0Ly92ZXJ0aWNhbEFsaWduOiBkeW5hbWljLFxuXHRcdFx0Ly90ZXh0QWxpZ246IGR5bmFtaWMsXG5cdFx0XHQvL3JvdGF0aW9uOiAwLFxuXHRcdFx0Zm9ybWF0dGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHJldHVybiBudW1iZXJGb3JtYXQodGhpcy50b3RhbCwgLTEpO1xuXHRcdFx0fSxcblx0XHRcdHN0eWxlOiBkZWZhdWx0TGFiZWxPcHRpb25zLnN0eWxlXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGVzZSBvcHRpb25zIGV4dGVuZCB0aGUgZGVmYXVsdE9wdGlvbnMgZm9yIGxlZnQgYXhlc1xuXHQgKi9cblx0ZGVmYXVsdExlZnRBeGlzT3B0aW9uczoge1xuXHRcdGxhYmVsczoge1xuXHRcdFx0eDogLTE1LFxuXHRcdFx0eTogbnVsbFxuXHRcdH0sXG5cdFx0dGl0bGU6IHtcblx0XHRcdHJvdGF0aW9uOiAyNzBcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRoZXNlIG9wdGlvbnMgZXh0ZW5kIHRoZSBkZWZhdWx0T3B0aW9ucyBmb3IgcmlnaHQgYXhlc1xuXHQgKi9cblx0ZGVmYXVsdFJpZ2h0QXhpc09wdGlvbnM6IHtcblx0XHRsYWJlbHM6IHtcblx0XHRcdHg6IDE1LFxuXHRcdFx0eTogbnVsbFxuXHRcdH0sXG5cdFx0dGl0bGU6IHtcblx0XHRcdHJvdGF0aW9uOiA5MFxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogVGhlc2Ugb3B0aW9ucyBleHRlbmQgdGhlIGRlZmF1bHRPcHRpb25zIGZvciBib3R0b20gYXhlc1xuXHQgKi9cblx0ZGVmYXVsdEJvdHRvbUF4aXNPcHRpb25zOiB7XG5cdFx0bGFiZWxzOiB7XG5cdFx0XHR4OiAwLFxuXHRcdFx0eTogbnVsbCAvLyBiYXNlZCBvbiBmb250IHNpemVcblx0XHRcdC8vIG92ZXJmbG93OiB1bmRlZmluZWQsXG5cdFx0XHQvLyBzdGFnZ2VyTGluZXM6IG51bGxcblx0XHR9LFxuXHRcdHRpdGxlOiB7XG5cdFx0XHRyb3RhdGlvbjogMFxuXHRcdH1cblx0fSxcblx0LyoqXG5cdCAqIFRoZXNlIG9wdGlvbnMgZXh0ZW5kIHRoZSBkZWZhdWx0T3B0aW9ucyBmb3IgbGVmdCBheGVzXG5cdCAqL1xuXHRkZWZhdWx0VG9wQXhpc09wdGlvbnM6IHtcblx0XHRsYWJlbHM6IHtcblx0XHRcdHg6IDAsXG5cdFx0XHR5OiAtMTVcblx0XHRcdC8vIG92ZXJmbG93OiB1bmRlZmluZWRcblx0XHRcdC8vIHN0YWdnZXJMaW5lczogbnVsbFxuXHRcdH0sXG5cdFx0dGl0bGU6IHtcblx0XHRcdHJvdGF0aW9uOiAwXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBheGlzXG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAoY2hhcnQsIHVzZXJPcHRpb25zKSB7XG5cblxuXHRcdHZhciBpc1hBeGlzID0gdXNlck9wdGlvbnMuaXNYLFxuXHRcdFx0YXhpcyA9IHRoaXM7XG5cblx0XHQvLyBGbGFnLCBpcyB0aGUgYXhpcyBob3Jpem9udGFsXG5cdFx0YXhpcy5ob3JpeiA9IGNoYXJ0LmludmVydGVkID8gIWlzWEF4aXMgOiBpc1hBeGlzO1xuXG5cdFx0Ly8gRmxhZywgaXNYQXhpc1xuXHRcdGF4aXMuaXNYQXhpcyA9IGlzWEF4aXM7XG5cdFx0YXhpcy5jb2xsID0gaXNYQXhpcyA/ICd4QXhpcycgOiAneUF4aXMnO1xuXG5cdFx0YXhpcy5vcHBvc2l0ZSA9IHVzZXJPcHRpb25zLm9wcG9zaXRlOyAvLyBuZWVkZWQgaW4gc2V0T3B0aW9uc1xuXHRcdGF4aXMuc2lkZSA9IHVzZXJPcHRpb25zLnNpZGUgfHwgKGF4aXMuaG9yaXogP1xuXHRcdFx0XHQoYXhpcy5vcHBvc2l0ZSA/IDAgOiAyKSA6IC8vIHRvcCA6IGJvdHRvbVxuXHRcdFx0XHQoYXhpcy5vcHBvc2l0ZSA/IDEgOiAzKSk7ICAvLyByaWdodCA6IGxlZnRcblxuXHRcdGF4aXMuc2V0T3B0aW9ucyh1c2VyT3B0aW9ucyk7XG5cblxuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0dHlwZSA9IG9wdGlvbnMudHlwZSxcblx0XHRcdGlzRGF0ZXRpbWVBeGlzID0gdHlwZSA9PT0gJ2RhdGV0aW1lJztcblxuXHRcdGF4aXMubGFiZWxGb3JtYXR0ZXIgPSBvcHRpb25zLmxhYmVscy5mb3JtYXR0ZXIgfHwgYXhpcy5kZWZhdWx0TGFiZWxGb3JtYXR0ZXI7IC8vIGNhbiBiZSBvdmVyd3JpdHRlbiBieSBkeW5hbWljIGZvcm1hdFxuXG5cblx0XHQvLyBGbGFnLCBzdGFnZ2VyIGxpbmVzIG9yIG5vdFxuXHRcdGF4aXMudXNlck9wdGlvbnMgPSB1c2VyT3B0aW9ucztcblxuXHRcdC8vYXhpcy5heGlzVGl0bGVNYXJnaW4gPSBVTkRFRklORUQsLy8gPSBvcHRpb25zLnRpdGxlLm1hcmdpbixcblx0XHRheGlzLm1pblBpeGVsUGFkZGluZyA9IDA7XG5cdFx0Ly9heGlzLmlnbm9yZU1pblBhZGRpbmcgPSBVTkRFRklORUQ7IC8vIGNhbiBiZSBzZXQgdG8gdHJ1ZSBieSBhIGNvbHVtbiBvciBiYXIgc2VyaWVzXG5cdFx0Ly9heGlzLmlnbm9yZU1heFBhZGRpbmcgPSBVTkRFRklORUQ7XG5cblx0XHRheGlzLmNoYXJ0ID0gY2hhcnQ7XG5cdFx0YXhpcy5yZXZlcnNlZCA9IG9wdGlvbnMucmV2ZXJzZWQ7XG5cdFx0YXhpcy56b29tRW5hYmxlZCA9IG9wdGlvbnMuem9vbUVuYWJsZWQgIT09IGZhbHNlO1xuXG5cdFx0Ly8gSW5pdGlhbCBjYXRlZ29yaWVzXG5cdFx0YXhpcy5jYXRlZ29yaWVzID0gb3B0aW9ucy5jYXRlZ29yaWVzIHx8IHR5cGUgPT09ICdjYXRlZ29yeSc7XG5cdFx0YXhpcy5uYW1lcyA9IFtdO1xuXG5cdFx0Ly8gRWxlbWVudHNcblx0XHQvL2F4aXMuYXhpc0dyb3VwID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5ncmlkR3JvdXAgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLmF4aXNUaXRsZSA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMuYXhpc0xpbmUgPSBVTkRFRklORUQ7XG5cblx0XHQvLyBTaG9ydGhhbmQgdHlwZXNcblx0XHRheGlzLmlzTG9nID0gdHlwZSA9PT0gJ2xvZ2FyaXRobWljJztcblx0XHRheGlzLmlzRGF0ZXRpbWVBeGlzID0gaXNEYXRldGltZUF4aXM7XG5cblx0XHQvLyBGbGFnLCBpZiBheGlzIGlzIGxpbmtlZCB0byBhbm90aGVyIGF4aXNcblx0XHRheGlzLmlzTGlua2VkID0gZGVmaW5lZChvcHRpb25zLmxpbmtlZFRvKTtcblx0XHQvLyBMaW5rZWQgYXhpcy5cblx0XHQvL2F4aXMubGlua2VkUGFyZW50ID0gVU5ERUZJTkVEO1xuXG5cdFx0Ly8gVGljayBwb3NpdGlvbnNcblx0XHQvL2F4aXMudGlja1Bvc2l0aW9ucyA9IFVOREVGSU5FRDsgLy8gYXJyYXkgY29udGFpbmluZyBwcmVkZWZpbmVkIHBvc2l0aW9uc1xuXHRcdC8vIFRpY2sgaW50ZXJ2YWxzXG5cdFx0Ly9heGlzLnRpY2tJbnRlcnZhbCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMubWlub3JUaWNrSW50ZXJ2YWwgPSBVTkRFRklORUQ7XG5cblx0XHRheGlzLnRpY2ttYXJrT2Zmc2V0ID0gKGF4aXMuY2F0ZWdvcmllcyAmJiBvcHRpb25zLnRpY2ttYXJrUGxhY2VtZW50ID09PSAnYmV0d2VlbicgJiYgXG5cdFx0XHRwaWNrKG9wdGlvbnMudGlja0ludGVydmFsLCAxKSA9PT0gMSkgPyAwLjUgOiAwOyAvLyAjMzIwMlxuXG5cdFx0Ly8gTWFqb3IgdGlja3Ncblx0XHRheGlzLnRpY2tzID0ge307XG5cdFx0YXhpcy5sYWJlbEVkZ2UgPSBbXTtcblx0XHQvLyBNaW5vciB0aWNrc1xuXHRcdGF4aXMubWlub3JUaWNrcyA9IHt9O1xuXHRcdC8vYXhpcy50aWNrQW1vdW50ID0gVU5ERUZJTkVEO1xuXG5cdFx0Ly8gTGlzdCBvZiBwbG90TGluZXMvQmFuZHNcblx0XHRheGlzLnBsb3RMaW5lc0FuZEJhbmRzID0gW107XG5cblx0XHQvLyBBbHRlcm5hdGUgYmFuZHNcblx0XHRheGlzLmFsdGVybmF0ZUJhbmRzID0ge307XG5cblx0XHQvLyBBeGlzIG1ldHJpY3Ncblx0XHQvL2F4aXMubGVmdCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMudG9wID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy53aWR0aCA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMuaGVpZ2h0ID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5ib3R0b20gPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLnJpZ2h0ID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy50cmFuc0EgPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLnRyYW5zQiA9IFVOREVGSU5FRDtcblx0XHQvL2F4aXMub2xkVHJhbnNBID0gVU5ERUZJTkVEO1xuXHRcdGF4aXMubGVuID0gMDtcblx0XHQvL2F4aXMub2xkTWluID0gVU5ERUZJTkVEO1xuXHRcdC8vYXhpcy5vbGRNYXggPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLm9sZFVzZXJNaW4gPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLm9sZFVzZXJNYXggPSBVTkRFRklORUQ7XG5cdFx0Ly9heGlzLm9sZEF4aXNMZW5ndGggPSBVTkRFRklORUQ7XG5cdFx0YXhpcy5taW5SYW5nZSA9IGF4aXMudXNlck1pblJhbmdlID0gb3B0aW9ucy5taW5SYW5nZSB8fCBvcHRpb25zLm1heFpvb207XG5cdFx0YXhpcy5yYW5nZSA9IG9wdGlvbnMucmFuZ2U7XG5cdFx0YXhpcy5vZmZzZXQgPSBvcHRpb25zLm9mZnNldCB8fCAwO1xuXG5cblx0XHQvLyBEaWN0aW9uYXJ5IGZvciBzdGFja3Ncblx0XHRheGlzLnN0YWNrcyA9IHt9O1xuXHRcdGF4aXMub2xkU3RhY2tzID0ge307XG5cdFx0XG5cdFx0Ly8gTWluIGFuZCBtYXggaW4gdGhlIGRhdGFcblx0XHQvL2F4aXMuZGF0YU1pbiA9IFVOREVGSU5FRCxcblx0XHQvL2F4aXMuZGF0YU1heCA9IFVOREVGSU5FRCxcblxuXHRcdC8vIFRoZSBheGlzIHJhbmdlXG5cdFx0YXhpcy5tYXggPSBudWxsO1xuXHRcdGF4aXMubWluID0gbnVsbDtcblxuXHRcdC8vIFVzZXIgc2V0IG1pbiBhbmQgbWF4XG5cdFx0Ly9heGlzLnVzZXJNaW4gPSBVTkRFRklORUQsXG5cdFx0Ly9heGlzLnVzZXJNYXggPSBVTkRFRklORUQsXG5cblx0XHQvLyBDcm9zc2hhaXIgb3B0aW9uc1xuXHRcdGF4aXMuY3Jvc3NoYWlyID0gcGljayhvcHRpb25zLmNyb3NzaGFpciwgc3BsYXQoY2hhcnQub3B0aW9ucy50b29sdGlwLmNyb3NzaGFpcnMpW2lzWEF4aXMgPyAwIDogMV0sIGZhbHNlKTtcblx0XHQvLyBSdW4gQXhpc1xuXG5cdFx0dmFyIGV2ZW50VHlwZSxcblx0XHRcdGV2ZW50cyA9IGF4aXMub3B0aW9ucy5ldmVudHM7XG5cblx0XHQvLyBSZWdpc3RlclxuXHRcdGlmIChpbkFycmF5KGF4aXMsIGNoYXJ0LmF4ZXMpID09PSAtMSkgeyAvLyBkb24ndCBhZGQgaXQgYWdhaW4gb24gQXhpcy51cGRhdGUoKVxuXHRcdFx0aWYgKGlzWEF4aXMgJiYgIXRoaXMuaXNDb2xvckF4aXMpIHsgLy8gIzI3MTNcblx0XHRcdFx0Y2hhcnQuYXhlcy5zcGxpY2UoY2hhcnQueEF4aXMubGVuZ3RoLCAwLCBheGlzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNoYXJ0LmF4ZXMucHVzaChheGlzKTtcblx0XHRcdH1cblxuXHRcdFx0Y2hhcnRbYXhpcy5jb2xsXS5wdXNoKGF4aXMpO1xuXHRcdH1cblxuXHRcdGF4aXMuc2VyaWVzID0gYXhpcy5zZXJpZXMgfHwgW107IC8vIHBvcHVsYXRlZCBieSBTZXJpZXNcblxuXHRcdC8vIGludmVydGVkIGNoYXJ0cyBoYXZlIHJldmVyc2VkIHhBeGVzIGFzIGRlZmF1bHRcblx0XHRpZiAoY2hhcnQuaW52ZXJ0ZWQgJiYgaXNYQXhpcyAmJiBheGlzLnJldmVyc2VkID09PSBVTkRFRklORUQpIHtcblx0XHRcdGF4aXMucmV2ZXJzZWQgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGF4aXMucmVtb3ZlUGxvdEJhbmQgPSBheGlzLnJlbW92ZVBsb3RCYW5kT3JMaW5lO1xuXHRcdGF4aXMucmVtb3ZlUGxvdExpbmUgPSBheGlzLnJlbW92ZVBsb3RCYW5kT3JMaW5lO1xuXG5cblx0XHQvLyByZWdpc3RlciBldmVudCBsaXN0ZW5lcnNcblx0XHRmb3IgKGV2ZW50VHlwZSBpbiBldmVudHMpIHtcblx0XHRcdGFkZEV2ZW50KGF4aXMsIGV2ZW50VHlwZSwgZXZlbnRzW2V2ZW50VHlwZV0pO1xuXHRcdH1cblxuXHRcdC8vIGV4dGVuZCBsb2dhcml0aG1pYyBheGlzXG5cdFx0aWYgKGF4aXMuaXNMb2cpIHtcblx0XHRcdGF4aXMudmFsMmxpbiA9IGxvZzJsaW47XG5cdFx0XHRheGlzLmxpbjJ2YWwgPSBsaW4ybG9nO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogTWVyZ2UgYW5kIHNldCBvcHRpb25zXG5cdCAqL1xuXHRzZXRPcHRpb25zOiBmdW5jdGlvbiAodXNlck9wdGlvbnMpIHtcblx0XHR0aGlzLm9wdGlvbnMgPSBtZXJnZShcblx0XHRcdHRoaXMuZGVmYXVsdE9wdGlvbnMsXG5cdFx0XHR0aGlzLmlzWEF4aXMgPyB7fSA6IHRoaXMuZGVmYXVsdFlBeGlzT3B0aW9ucyxcblx0XHRcdFt0aGlzLmRlZmF1bHRUb3BBeGlzT3B0aW9ucywgdGhpcy5kZWZhdWx0UmlnaHRBeGlzT3B0aW9ucyxcblx0XHRcdFx0dGhpcy5kZWZhdWx0Qm90dG9tQXhpc09wdGlvbnMsIHRoaXMuZGVmYXVsdExlZnRBeGlzT3B0aW9uc11bdGhpcy5zaWRlXSxcblx0XHRcdG1lcmdlKFxuXHRcdFx0XHRkZWZhdWx0T3B0aW9uc1t0aGlzLmNvbGxdLCAvLyBpZiBzZXQgaW4gc2V0T3B0aW9ucyAoIzEwNTMpXG5cdFx0XHRcdHVzZXJPcHRpb25zXG5cdFx0XHQpXG5cdFx0KTtcblx0fSxcblxuXHQvKipcblx0ICogVGhlIGRlZmF1bHQgbGFiZWwgZm9ybWF0dGVyLiBUaGUgY29udGV4dCBpcyBhIHNwZWNpYWwgY29uZmlnIG9iamVjdCBmb3IgdGhlIGxhYmVsLlxuXHQgKi9cblx0ZGVmYXVsdExhYmVsRm9ybWF0dGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLmF4aXMsXG5cdFx0XHR2YWx1ZSA9IHRoaXMudmFsdWUsXG5cdFx0XHRjYXRlZ29yaWVzID0gYXhpcy5jYXRlZ29yaWVzLFxuXHRcdFx0ZGF0ZVRpbWVMYWJlbEZvcm1hdCA9IHRoaXMuZGF0ZVRpbWVMYWJlbEZvcm1hdCxcblx0XHRcdG51bWVyaWNTeW1ib2xzID0gZGVmYXVsdE9wdGlvbnMubGFuZy5udW1lcmljU3ltYm9scyxcblx0XHRcdGkgPSBudW1lcmljU3ltYm9scyAmJiBudW1lcmljU3ltYm9scy5sZW5ndGgsXG5cdFx0XHRtdWx0aSxcblx0XHRcdHJldCxcblx0XHRcdGZvcm1hdE9wdGlvbiA9IGF4aXMub3B0aW9ucy5sYWJlbHMuZm9ybWF0LFxuXG5cdFx0XHQvLyBtYWtlIHN1cmUgdGhlIHNhbWUgc3ltYm9sIGlzIGFkZGVkIGZvciBhbGwgbGFiZWxzIG9uIGEgbGluZWFyIGF4aXNcblx0XHRcdG51bWVyaWNTeW1ib2xEZXRlY3RvciA9IGF4aXMuaXNMb2cgPyB2YWx1ZSA6IGF4aXMudGlja0ludGVydmFsO1xuXG5cdFx0aWYgKGZvcm1hdE9wdGlvbikge1xuXHRcdFx0cmV0ID0gZm9ybWF0KGZvcm1hdE9wdGlvbiwgdGhpcyk7XG5cblx0XHR9IGVsc2UgaWYgKGNhdGVnb3JpZXMpIHtcblx0XHRcdHJldCA9IHZhbHVlO1xuXG5cdFx0fSBlbHNlIGlmIChkYXRlVGltZUxhYmVsRm9ybWF0KSB7IC8vIGRhdGV0aW1lIGF4aXNcblx0XHRcdHJldCA9IGRhdGVGb3JtYXQoZGF0ZVRpbWVMYWJlbEZvcm1hdCwgdmFsdWUpO1xuXG5cdFx0fSBlbHNlIGlmIChpICYmIG51bWVyaWNTeW1ib2xEZXRlY3RvciA+PSAxMDAwKSB7XG5cdFx0XHQvLyBEZWNpZGUgd2hldGhlciB3ZSBzaG91bGQgYWRkIGEgbnVtZXJpYyBzeW1ib2wgbGlrZSBrICh0aG91c2FuZHMpIG9yIE0gKG1pbGxpb25zKS5cblx0XHRcdC8vIElmIHdlIGFyZSB0byBlbmFibGUgdGhpcyBpbiB0b29sdGlwIG9yIG90aGVyIHBsYWNlcyBhcyB3ZWxsLCB3ZSBjYW4gbW92ZSB0aGlzXG5cdFx0XHQvLyBsb2dpYyB0byB0aGUgbnVtYmVyRm9ybWF0dGVyIGFuZCBlbmFibGUgaXQgYnkgYSBwYXJhbWV0ZXIuXG5cdFx0XHR3aGlsZSAoaS0tICYmIHJldCA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdG11bHRpID0gTWF0aC5wb3coMTAwMCwgaSArIDEpO1xuXHRcdFx0XHRpZiAobnVtZXJpY1N5bWJvbERldGVjdG9yID49IG11bHRpICYmIG51bWVyaWNTeW1ib2xzW2ldICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0cmV0ID0gbnVtYmVyRm9ybWF0KHZhbHVlIC8gbXVsdGksIC0xKSArIG51bWVyaWNTeW1ib2xzW2ldO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHJldCA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRpZiAobWF0aEFicyh2YWx1ZSkgPj0gMTAwMDApIHsgLy8gYWRkIHRob3VzYW5kcyBzZXBhcmF0b3JzXG5cdFx0XHRcdHJldCA9IG51bWJlckZvcm1hdCh2YWx1ZSwgMCk7XG5cblx0XHRcdH0gZWxzZSB7IC8vIHNtYWxsIG51bWJlcnNcblx0XHRcdFx0cmV0ID0gbnVtYmVyRm9ybWF0KHZhbHVlLCAtMSwgVU5ERUZJTkVELCAnJyk7IC8vICMyNDY2XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGZvciB0aGUgc2VyaWVzIG9mIGVhY2ggYXhpc1xuXHQgKi9cblx0Z2V0U2VyaWVzRXh0cmVtZXM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQ7XG5cblx0XHRheGlzLmhhc1Zpc2libGVTZXJpZXMgPSBmYWxzZTtcblxuXHRcdC8vIFJlc2V0IHByb3BlcnRpZXMgaW4gY2FzZSB3ZSdyZSByZWRyYXdpbmcgKCMzMzUzKVxuXHRcdGF4aXMuZGF0YU1pbiA9IGF4aXMuZGF0YU1heCA9IGF4aXMuaWdub3JlTWluUGFkZGluZyA9IGF4aXMuaWdub3JlTWF4UGFkZGluZyA9IG51bGw7XG5cdFx0XG5cdFx0aWYgKGF4aXMuYnVpbGRTdGFja3MpIHtcblx0XHRcdGF4aXMuYnVpbGRTdGFja3MoKTtcblx0XHR9XG5cblx0XHQvLyBsb29wIHRocm91Z2ggdGhpcyBheGlzJyBzZXJpZXNcblx0XHRlYWNoKGF4aXMuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cblx0XHRcdGlmIChzZXJpZXMudmlzaWJsZSB8fCAhY2hhcnQub3B0aW9ucy5jaGFydC5pZ25vcmVIaWRkZW5TZXJpZXMpIHtcblxuXHRcdFx0XHR2YXIgc2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0XHRcdHhEYXRhLFxuXHRcdFx0XHRcdHRocmVzaG9sZCA9IHNlcmllc09wdGlvbnMudGhyZXNob2xkLFxuXHRcdFx0XHRcdHNlcmllc0RhdGFNaW4sXG5cdFx0XHRcdFx0c2VyaWVzRGF0YU1heDtcblxuXHRcdFx0XHRheGlzLmhhc1Zpc2libGVTZXJpZXMgPSB0cnVlO1xuXG5cdFx0XHRcdC8vIFZhbGlkYXRlIHRocmVzaG9sZCBpbiBsb2dhcml0aG1pYyBheGVzXG5cdFx0XHRcdGlmIChheGlzLmlzTG9nICYmIHRocmVzaG9sZCA8PSAwKSB7XG5cdFx0XHRcdFx0dGhyZXNob2xkID0gbnVsbDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkYXRhTWluIGFuZCBkYXRhTWF4IGZvciBYIGF4ZXNcblx0XHRcdFx0aWYgKGF4aXMuaXNYQXhpcykge1xuXHRcdFx0XHRcdHhEYXRhID0gc2VyaWVzLnhEYXRhO1xuXHRcdFx0XHRcdGlmICh4RGF0YS5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdGF4aXMuZGF0YU1pbiA9IG1hdGhNaW4ocGljayhheGlzLmRhdGFNaW4sIHhEYXRhWzBdKSwgYXJyYXlNaW4oeERhdGEpKTtcblx0XHRcdFx0XHRcdGF4aXMuZGF0YU1heCA9IG1hdGhNYXgocGljayhheGlzLmRhdGFNYXgsIHhEYXRhWzBdKSwgYXJyYXlNYXgoeERhdGEpKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gR2V0IGRhdGFNaW4gYW5kIGRhdGFNYXggZm9yIFkgYXhlcywgYXMgd2VsbCBhcyBoYW5kbGUgc3RhY2tpbmcgYW5kIHByb2Nlc3NlZCBkYXRhXG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHQvLyBHZXQgdGhpcyBwYXJ0aWN1bGFyIHNlcmllcyBleHRyZW1lc1xuXHRcdFx0XHRcdHNlcmllcy5nZXRFeHRyZW1lcygpO1xuXHRcdFx0XHRcdHNlcmllc0RhdGFNYXggPSBzZXJpZXMuZGF0YU1heDtcblx0XHRcdFx0XHRzZXJpZXNEYXRhTWluID0gc2VyaWVzLmRhdGFNaW47XG5cblx0XHRcdFx0XHQvLyBHZXQgdGhlIGRhdGFNaW4gYW5kIGRhdGFNYXggc28gZmFyLiBJZiBwZXJjZW50YWdlIGlzIHVzZWQsIHRoZSBtaW4gYW5kIG1heCBhcmVcblx0XHRcdFx0XHQvLyBhbHdheXMgMCBhbmQgMTAwLiBJZiBzZXJpZXNEYXRhTWluIGFuZCBzZXJpZXNEYXRhTWF4IGlzIG51bGwsIHRoZW4gc2VyaWVzXG5cdFx0XHRcdFx0Ly8gZG9lc24ndCBoYXZlIGFjdGl2ZSB5IGRhdGEsIHdlIGNvbnRpbnVlIHdpdGggbnVsbHNcblx0XHRcdFx0XHRpZiAoZGVmaW5lZChzZXJpZXNEYXRhTWluKSAmJiBkZWZpbmVkKHNlcmllc0RhdGFNYXgpKSB7XG5cdFx0XHRcdFx0XHRheGlzLmRhdGFNaW4gPSBtYXRoTWluKHBpY2soYXhpcy5kYXRhTWluLCBzZXJpZXNEYXRhTWluKSwgc2VyaWVzRGF0YU1pbik7XG5cdFx0XHRcdFx0XHRheGlzLmRhdGFNYXggPSBtYXRoTWF4KHBpY2soYXhpcy5kYXRhTWF4LCBzZXJpZXNEYXRhTWF4KSwgc2VyaWVzRGF0YU1heCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gQWRqdXN0IHRvIHRocmVzaG9sZFxuXHRcdFx0XHRcdGlmIChkZWZpbmVkKHRocmVzaG9sZCkpIHtcblx0XHRcdFx0XHRcdGlmIChheGlzLmRhdGFNaW4gPj0gdGhyZXNob2xkKSB7XG5cdFx0XHRcdFx0XHRcdGF4aXMuZGF0YU1pbiA9IHRocmVzaG9sZDtcblx0XHRcdFx0XHRcdFx0YXhpcy5pZ25vcmVNaW5QYWRkaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoYXhpcy5kYXRhTWF4IDwgdGhyZXNob2xkKSB7XG5cdFx0XHRcdFx0XHRcdGF4aXMuZGF0YU1heCA9IHRocmVzaG9sZDtcblx0XHRcdFx0XHRcdFx0YXhpcy5pZ25vcmVNYXhQYWRkaW5nID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogVHJhbnNsYXRlIGZyb20gYXhpcyB2YWx1ZSB0byBwaXhlbCBwb3NpdGlvbiBvbiB0aGUgY2hhcnQsIG9yIGJhY2tcblx0ICpcblx0ICovXG5cdHRyYW5zbGF0ZTogZnVuY3Rpb24gKHZhbCwgYmFja3dhcmRzLCBjdnNDb29yZCwgb2xkLCBoYW5kbGVMb2csIHBvaW50UGxhY2VtZW50KSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0c2lnbiA9IDEsXG5cdFx0XHRjdnNPZmZzZXQgPSAwLFxuXHRcdFx0bG9jYWxBID0gb2xkID8gYXhpcy5vbGRUcmFuc0EgOiBheGlzLnRyYW5zQSxcblx0XHRcdGxvY2FsTWluID0gb2xkID8gYXhpcy5vbGRNaW4gOiBheGlzLm1pbixcblx0XHRcdHJldHVyblZhbHVlLFxuXHRcdFx0bWluUGl4ZWxQYWRkaW5nID0gYXhpcy5taW5QaXhlbFBhZGRpbmcsXG5cdFx0XHRwb3N0VHJhbnNsYXRlID0gKGF4aXMub3B0aW9ucy5vcmRpbmFsIHx8IChheGlzLmlzTG9nICYmIGhhbmRsZUxvZykpICYmIGF4aXMubGluMnZhbDtcblxuXHRcdGlmICghbG9jYWxBKSB7XG5cdFx0XHRsb2NhbEEgPSBheGlzLnRyYW5zQTtcblx0XHR9XG5cblx0XHQvLyBJbiB2ZXJ0aWNhbCBheGVzLCB0aGUgY2FudmFzIGNvb3JkaW5hdGVzIHN0YXJ0IGZyb20gMCBhdCB0aGUgdG9wIGxpa2UgaW5cblx0XHQvLyBTVkcuXG5cdFx0aWYgKGN2c0Nvb3JkKSB7XG5cdFx0XHRzaWduICo9IC0xOyAvLyBjYW52YXMgY29vcmRpbmF0ZXMgaW52ZXJ0cyB0aGUgdmFsdWVcblx0XHRcdGN2c09mZnNldCA9IGF4aXMubGVuO1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSByZXZlcnNlZCBheGlzXG5cdFx0aWYgKGF4aXMucmV2ZXJzZWQpIHtcblx0XHRcdHNpZ24gKj0gLTE7XG5cdFx0XHRjdnNPZmZzZXQgLT0gc2lnbiAqIChheGlzLnNlY3RvciB8fCBheGlzLmxlbik7XG5cdFx0fVxuXG5cdFx0Ly8gRnJvbSBwaXhlbHMgdG8gdmFsdWVcblx0XHRpZiAoYmFja3dhcmRzKSB7IC8vIHJldmVyc2UgdHJhbnNsYXRpb25cblxuXHRcdFx0dmFsID0gdmFsICogc2lnbiArIGN2c09mZnNldDtcblx0XHRcdHZhbCAtPSBtaW5QaXhlbFBhZGRpbmc7XG5cdFx0XHRyZXR1cm5WYWx1ZSA9IHZhbCAvIGxvY2FsQSArIGxvY2FsTWluOyAvLyBmcm9tIGNoYXJ0IHBpeGVsIHRvIHZhbHVlXG5cdFx0XHRpZiAocG9zdFRyYW5zbGF0ZSkgeyAvLyBsb2cgYW5kIG9yZGluYWwgYXhlc1xuXHRcdFx0XHRyZXR1cm5WYWx1ZSA9IGF4aXMubGluMnZhbChyZXR1cm5WYWx1ZSk7XG5cdFx0XHR9XG5cblx0XHQvLyBGcm9tIHZhbHVlIHRvIHBpeGVsc1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAocG9zdFRyYW5zbGF0ZSkgeyAvLyBsb2cgYW5kIG9yZGluYWwgYXhlc1xuXHRcdFx0XHR2YWwgPSBheGlzLnZhbDJsaW4odmFsKTtcblx0XHRcdH1cblx0XHRcdGlmIChwb2ludFBsYWNlbWVudCA9PT0gJ2JldHdlZW4nKSB7XG5cdFx0XHRcdHBvaW50UGxhY2VtZW50ID0gMC41O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuVmFsdWUgPSBzaWduICogKHZhbCAtIGxvY2FsTWluKSAqIGxvY2FsQSArIGN2c09mZnNldCArIChzaWduICogbWluUGl4ZWxQYWRkaW5nKSArXG5cdFx0XHRcdChpc051bWJlcihwb2ludFBsYWNlbWVudCkgPyBsb2NhbEEgKiBwb2ludFBsYWNlbWVudCAqIGF4aXMucG9pbnRSYW5nZSA6IDApO1xuXHRcdH1cblxuXHRcdHJldHVybiByZXR1cm5WYWx1ZTtcblx0fSxcblxuXHQvKipcblx0ICogVXRpbGl0eSBtZXRob2QgdG8gdHJhbnNsYXRlIGFuIGF4aXMgdmFsdWUgdG8gcGl4ZWwgcG9zaXRpb24uXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB2YWx1ZSBBIHZhbHVlIGluIHRlcm1zIG9mIGF4aXMgdW5pdHNcblx0ICogQHBhcmFtIHtCb29sZWFufSBwYW5lQ29vcmRpbmF0ZXMgV2hldGhlciB0byByZXR1cm4gdGhlIHBpeGVsIGNvb3JkaW5hdGUgcmVsYXRpdmUgdG8gdGhlIGNoYXJ0XG5cdCAqICAgICAgICBvciBqdXN0IHRoZSBheGlzL3BhbmUgaXRzZWxmLlxuXHQgKi9cblx0dG9QaXhlbHM6IGZ1bmN0aW9uICh2YWx1ZSwgcGFuZUNvb3JkaW5hdGVzKSB7XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNsYXRlKHZhbHVlLCBmYWxzZSwgIXRoaXMuaG9yaXosIG51bGwsIHRydWUpICsgKHBhbmVDb29yZGluYXRlcyA/IDAgOiB0aGlzLnBvcyk7XG5cdH0sXG5cblx0Lypcblx0ICogVXRpbGl0eSBtZXRob2QgdG8gdHJhbnNsYXRlIGEgcGl4ZWwgcG9zaXRpb24gaW4gdG8gYW4gYXhpcyB2YWx1ZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gcGl4ZWwgVGhlIHBpeGVsIHZhbHVlIGNvb3JkaW5hdGVcblx0ICogQHBhcmFtIHtCb29sZWFufSBwYW5lQ29vcmRpYW50ZXMgV2hldGhlciB0aGUgaW5wdXQgcGl4ZWwgaXMgcmVsYXRpdmUgdG8gdGhlIGNoYXJ0IG9yIGp1c3QgdGhlXG5cdCAqICAgICAgICBheGlzL3BhbmUgaXRzZWxmLlxuXHQgKi9cblx0dG9WYWx1ZTogZnVuY3Rpb24gKHBpeGVsLCBwYW5lQ29vcmRpbmF0ZXMpIHtcblx0XHRyZXR1cm4gdGhpcy50cmFuc2xhdGUocGl4ZWwgLSAocGFuZUNvb3JkaW5hdGVzID8gMCA6IHRoaXMucG9zKSwgdHJ1ZSwgIXRoaXMuaG9yaXosIG51bGwsIHRydWUpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDcmVhdGUgdGhlIHBhdGggZm9yIGEgcGxvdCBsaW5lIHRoYXQgZ29lcyBmcm9tIHRoZSBnaXZlbiB2YWx1ZSBvblxuXHQgKiB0aGlzIGF4aXMsIGFjcm9zcyB0aGUgcGxvdCB0byB0aGUgb3Bwb3NpdGUgc2lkZVxuXHQgKiBAcGFyYW0ge051bWJlcn0gdmFsdWVcblx0ICogQHBhcmFtIHtOdW1iZXJ9IGxpbmVXaWR0aCBVc2VkIGZvciBjYWxjdWxhdGlvbiBjcmlzcCBsaW5lXG5cdCAqIEBwYXJhbSB7TnVtYmVyXSBvbGQgVXNlIG9sZCBjb29yZGluYXRlcyAoZm9yIHJlc2l6aW5nIGFuZCByZXNjYWxpbmcpXG5cdCAqL1xuXHRnZXRQbG90TGluZVBhdGg6IGZ1bmN0aW9uICh2YWx1ZSwgbGluZVdpZHRoLCBvbGQsIGZvcmNlLCB0cmFuc2xhdGVkVmFsdWUpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0XHRheGlzTGVmdCA9IGF4aXMubGVmdCxcblx0XHRcdGF4aXNUb3AgPSBheGlzLnRvcCxcblx0XHRcdHgxLFxuXHRcdFx0eTEsXG5cdFx0XHR4Mixcblx0XHRcdHkyLFxuXHRcdFx0Y0hlaWdodCA9IChvbGQgJiYgY2hhcnQub2xkQ2hhcnRIZWlnaHQpIHx8IGNoYXJ0LmNoYXJ0SGVpZ2h0LFxuXHRcdFx0Y1dpZHRoID0gKG9sZCAmJiBjaGFydC5vbGRDaGFydFdpZHRoKSB8fCBjaGFydC5jaGFydFdpZHRoLFxuXHRcdFx0c2tpcCxcblx0XHRcdHRyYW5zQiA9IGF4aXMudHJhbnNCO1xuXG5cdFx0dHJhbnNsYXRlZFZhbHVlID0gcGljayh0cmFuc2xhdGVkVmFsdWUsIGF4aXMudHJhbnNsYXRlKHZhbHVlLCBudWxsLCBudWxsLCBvbGQpKTtcblx0XHR4MSA9IHgyID0gbWF0aFJvdW5kKHRyYW5zbGF0ZWRWYWx1ZSArIHRyYW5zQik7XG5cdFx0eTEgPSB5MiA9IG1hdGhSb3VuZChjSGVpZ2h0IC0gdHJhbnNsYXRlZFZhbHVlIC0gdHJhbnNCKTtcblxuXHRcdGlmIChpc05hTih0cmFuc2xhdGVkVmFsdWUpKSB7IC8vIG5vIG1pbiBvciBtYXhcblx0XHRcdHNraXAgPSB0cnVlO1xuXG5cdFx0fSBlbHNlIGlmIChheGlzLmhvcml6KSB7XG5cdFx0XHR5MSA9IGF4aXNUb3A7XG5cdFx0XHR5MiA9IGNIZWlnaHQgLSBheGlzLmJvdHRvbTtcblx0XHRcdGlmICh4MSA8IGF4aXNMZWZ0IHx8IHgxID4gYXhpc0xlZnQgKyBheGlzLndpZHRoKSB7XG5cdFx0XHRcdHNraXAgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR4MSA9IGF4aXNMZWZ0O1xuXHRcdFx0eDIgPSBjV2lkdGggLSBheGlzLnJpZ2h0O1xuXG5cdFx0XHRpZiAoeTEgPCBheGlzVG9wIHx8IHkxID4gYXhpc1RvcCArIGF4aXMuaGVpZ2h0KSB7XG5cdFx0XHRcdHNraXAgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gc2tpcCAmJiAhZm9yY2UgP1xuXHRcdFx0bnVsbCA6XG5cdFx0XHRjaGFydC5yZW5kZXJlci5jcmlzcExpbmUoW00sIHgxLCB5MSwgTCwgeDIsIHkyXSwgbGluZVdpZHRoIHx8IDEpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHRpY2sgcG9zaXRpb25zIG9mIGEgbGluZWFyIGF4aXMgdG8gcm91bmQgdmFsdWVzIGxpa2Ugd2hvbGUgdGVucyBvciBldmVyeSBmaXZlLlxuXHQgKi9cblx0Z2V0TGluZWFyVGlja1Bvc2l0aW9uczogZnVuY3Rpb24gKHRpY2tJbnRlcnZhbCwgbWluLCBtYXgpIHtcblx0XHR2YXIgcG9zLFxuXHRcdFx0bGFzdFBvcyxcblx0XHRcdHJvdW5kZWRNaW4gPSBjb3JyZWN0RmxvYXQobWF0aEZsb29yKG1pbiAvIHRpY2tJbnRlcnZhbCkgKiB0aWNrSW50ZXJ2YWwpLFxuXHRcdFx0cm91bmRlZE1heCA9IGNvcnJlY3RGbG9hdChtYXRoQ2VpbChtYXggLyB0aWNrSW50ZXJ2YWwpICogdGlja0ludGVydmFsKSxcblx0XHRcdHRpY2tQb3NpdGlvbnMgPSBbXTtcblxuXHRcdC8vIEZvciBzaW5nbGUgcG9pbnRzLCBhZGQgYSB0aWNrIHJlZ2FyZGxlc3Mgb2YgdGhlIHJlbGF0aXZlIHBvc2l0aW9uICgjMjY2Milcblx0XHRpZiAobWluID09PSBtYXggJiYgaXNOdW1iZXIobWluKSkge1xuXHRcdFx0cmV0dXJuIFttaW5dO1xuXHRcdH1cblxuXHRcdC8vIFBvcHVsYXRlIHRoZSBpbnRlcm1lZGlhdGUgdmFsdWVzXG5cdFx0cG9zID0gcm91bmRlZE1pbjtcblx0XHR3aGlsZSAocG9zIDw9IHJvdW5kZWRNYXgpIHtcblxuXHRcdFx0Ly8gUGxhY2UgdGhlIHRpY2sgb24gdGhlIHJvdW5kZWQgdmFsdWVcblx0XHRcdHRpY2tQb3NpdGlvbnMucHVzaChwb3MpO1xuXG5cdFx0XHQvLyBBbHdheXMgYWRkIHRoZSByYXcgdGlja0ludGVydmFsLCBub3QgdGhlIGNvcnJlY3RlZCBvbmUuXG5cdFx0XHRwb3MgPSBjb3JyZWN0RmxvYXQocG9zICsgdGlja0ludGVydmFsKTtcblxuXHRcdFx0Ly8gSWYgdGhlIGludGVydmFsIGlzIG5vdCBiaWcgZW5vdWdoIGluIHRoZSBjdXJyZW50IG1pbiAtIG1heCByYW5nZSB0byBhY3R1YWxseSBpbmNyZWFzZVxuXHRcdFx0Ly8gdGhlIGxvb3AgdmFyaWFibGUsIHdlIG5lZWQgdG8gYnJlYWsgb3V0IHRvIHByZXZlbnQgZW5kbGVzcyBsb29wLiBJc3N1ZSAjNjE5XG5cdFx0XHRpZiAocG9zID09PSBsYXN0UG9zKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZWNvcmQgdGhlIGxhc3QgdmFsdWVcblx0XHRcdGxhc3RQb3MgPSBwb3M7XG5cdFx0fVxuXHRcdHJldHVybiB0aWNrUG9zaXRpb25zO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gdGhlIG1pbm9yIHRpY2sgcG9zaXRpb25zLiBGb3IgbG9nYXJpdGhtaWMgYXhlcywgcmV1c2UgdGhlIHNhbWUgbG9naWNcblx0ICogYXMgZm9yIG1ham9yIHRpY2tzLlxuXHQgKi9cblx0Z2V0TWlub3JUaWNrUG9zaXRpb25zOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLnRpY2tQb3NpdGlvbnMsXG5cdFx0XHRtaW5vclRpY2tJbnRlcnZhbCA9IGF4aXMubWlub3JUaWNrSW50ZXJ2YWwsXG5cdFx0XHRtaW5vclRpY2tQb3NpdGlvbnMgPSBbXSxcblx0XHRcdHBvcyxcblx0XHRcdGksXG5cdFx0XHRsZW47XG5cblx0XHRpZiAoYXhpcy5pc0xvZykge1xuXHRcdFx0bGVuID0gdGlja1Bvc2l0aW9ucy5sZW5ndGg7XG5cdFx0XHRmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdFx0bWlub3JUaWNrUG9zaXRpb25zID0gbWlub3JUaWNrUG9zaXRpb25zLmNvbmNhdChcblx0XHRcdFx0XHRheGlzLmdldExvZ1RpY2tQb3NpdGlvbnMobWlub3JUaWNrSW50ZXJ2YWwsIHRpY2tQb3NpdGlvbnNbaSAtIDFdLCB0aWNrUG9zaXRpb25zW2ldLCB0cnVlKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoYXhpcy5pc0RhdGV0aW1lQXhpcyAmJiBvcHRpb25zLm1pbm9yVGlja0ludGVydmFsID09PSAnYXV0bycpIHsgLy8gIzEzMTRcblx0XHRcdG1pbm9yVGlja1Bvc2l0aW9ucyA9IG1pbm9yVGlja1Bvc2l0aW9ucy5jb25jYXQoXG5cdFx0XHRcdGF4aXMuZ2V0VGltZVRpY2tzKFxuXHRcdFx0XHRcdGF4aXMubm9ybWFsaXplVGltZVRpY2tJbnRlcnZhbChtaW5vclRpY2tJbnRlcnZhbCksXG5cdFx0XHRcdFx0YXhpcy5taW4sXG5cdFx0XHRcdFx0YXhpcy5tYXgsXG5cdFx0XHRcdFx0b3B0aW9ucy5zdGFydE9mV2Vla1xuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdFx0aWYgKG1pbm9yVGlja1Bvc2l0aW9uc1swXSA8IGF4aXMubWluKSB7XG5cdFx0XHRcdG1pbm9yVGlja1Bvc2l0aW9ucy5zaGlmdCgpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKHBvcyA9IGF4aXMubWluICsgKHRpY2tQb3NpdGlvbnNbMF0gLSBheGlzLm1pbikgJSBtaW5vclRpY2tJbnRlcnZhbDsgcG9zIDw9IGF4aXMubWF4OyBwb3MgKz0gbWlub3JUaWNrSW50ZXJ2YWwpIHtcblx0XHRcdFx0bWlub3JUaWNrUG9zaXRpb25zLnB1c2gocG9zKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG1pbm9yVGlja1Bvc2l0aW9ucztcblx0fSxcblxuXHQvKipcblx0ICogQWRqdXN0IHRoZSBtaW4gYW5kIG1heCBmb3IgdGhlIG1pbmltdW0gcmFuZ2UuIEtlZXAgaW4gbWluZCB0aGF0IHRoZSBzZXJpZXMgZGF0YSBpc1xuXHQgKiBub3QgeWV0IHByb2Nlc3NlZCwgc28gd2UgZG9uJ3QgaGF2ZSBpbmZvcm1hdGlvbiBvbiBkYXRhIGNyb3BwaW5nIGFuZCBncm91cGluZywgb3Jcblx0ICogdXBkYXRlZCBheGlzLnBvaW50UmFuZ2Ugb3Igc2VyaWVzLnBvaW50UmFuZ2UuIFRoZSBkYXRhIGNhbid0IGJlIHByb2Nlc3NlZCB1bnRpbFxuXHQgKiB3ZSBoYXZlIGZpbmFsbHkgZXN0YWJsaXNoZWQgbWluIGFuZCBtYXguXG5cdCAqL1xuXHRhZGp1c3RGb3JNaW5SYW5nZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHRtaW4gPSBheGlzLm1pbixcblx0XHRcdG1heCA9IGF4aXMubWF4LFxuXHRcdFx0em9vbU9mZnNldCxcblx0XHRcdHNwYWNlQXZhaWxhYmxlID0gYXhpcy5kYXRhTWF4IC0gYXhpcy5kYXRhTWluID49IGF4aXMubWluUmFuZ2UsXG5cdFx0XHRjbG9zZXN0RGF0YVJhbmdlLFxuXHRcdFx0aSxcblx0XHRcdGRpc3RhbmNlLFxuXHRcdFx0eERhdGEsXG5cdFx0XHRsb29wTGVuZ3RoLFxuXHRcdFx0bWluQXJncyxcblx0XHRcdG1heEFyZ3M7XG5cblx0XHQvLyBTZXQgdGhlIGF1dG9tYXRpYyBtaW5pbXVtIHJhbmdlIGJhc2VkIG9uIHRoZSBjbG9zZXN0IHBvaW50IGRpc3RhbmNlXG5cdFx0aWYgKGF4aXMuaXNYQXhpcyAmJiBheGlzLm1pblJhbmdlID09PSBVTkRFRklORUQgJiYgIWF4aXMuaXNMb2cpIHtcblxuXHRcdFx0aWYgKGRlZmluZWQob3B0aW9ucy5taW4pIHx8IGRlZmluZWQob3B0aW9ucy5tYXgpKSB7XG5cdFx0XHRcdGF4aXMubWluUmFuZ2UgPSBudWxsOyAvLyBkb24ndCBkbyB0aGlzIGFnYWluXG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gRmluZCB0aGUgY2xvc2VzdCBkaXN0YW5jZSBiZXR3ZWVuIHJhdyBkYXRhIHBvaW50cywgYXMgb3Bwb3NlZCB0b1xuXHRcdFx0XHQvLyBjbG9zZXN0UG9pbnRSYW5nZSB0aGF0IGFwcGxpZXMgdG8gcHJvY2Vzc2VkIHBvaW50cyAoY3JvcHBlZCBhbmQgZ3JvdXBlZClcblx0XHRcdFx0ZWFjaChheGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0XHRcdHhEYXRhID0gc2VyaWVzLnhEYXRhO1xuXHRcdFx0XHRcdGxvb3BMZW5ndGggPSBzZXJpZXMueEluY3JlbWVudCA/IDEgOiB4RGF0YS5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdGZvciAoaSA9IGxvb3BMZW5ndGg7IGkgPiAwOyBpLS0pIHtcblx0XHRcdFx0XHRcdGRpc3RhbmNlID0geERhdGFbaV0gLSB4RGF0YVtpIC0gMV07XG5cdFx0XHRcdFx0XHRpZiAoY2xvc2VzdERhdGFSYW5nZSA9PT0gVU5ERUZJTkVEIHx8IGRpc3RhbmNlIDwgY2xvc2VzdERhdGFSYW5nZSkge1xuXHRcdFx0XHRcdFx0XHRjbG9zZXN0RGF0YVJhbmdlID0gZGlzdGFuY2U7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0YXhpcy5taW5SYW5nZSA9IG1hdGhNaW4oY2xvc2VzdERhdGFSYW5nZSAqIDUsIGF4aXMuZGF0YU1heCAtIGF4aXMuZGF0YU1pbik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaWYgbWluUmFuZ2UgaXMgZXhjZWVkZWQsIGFkanVzdFxuXHRcdGlmIChtYXggLSBtaW4gPCBheGlzLm1pblJhbmdlKSB7XG5cdFx0XHR2YXIgbWluUmFuZ2UgPSBheGlzLm1pblJhbmdlO1xuXHRcdFx0em9vbU9mZnNldCA9IChtaW5SYW5nZSAtIG1heCArIG1pbikgLyAyO1xuXG5cdFx0XHQvLyBpZiBtaW4gYW5kIG1heCBvcHRpb25zIGhhdmUgYmVlbiBzZXQsIGRvbid0IGdvIGJleW9uZCBpdFxuXHRcdFx0bWluQXJncyA9IFttaW4gLSB6b29tT2Zmc2V0LCBwaWNrKG9wdGlvbnMubWluLCBtaW4gLSB6b29tT2Zmc2V0KV07XG5cdFx0XHRpZiAoc3BhY2VBdmFpbGFibGUpIHsgLy8gaWYgc3BhY2UgaXMgYXZhaWxhYmxlLCBzdGF5IHdpdGhpbiB0aGUgZGF0YSByYW5nZVxuXHRcdFx0XHRtaW5BcmdzWzJdID0gYXhpcy5kYXRhTWluO1xuXHRcdFx0fVxuXHRcdFx0bWluID0gYXJyYXlNYXgobWluQXJncyk7XG5cblx0XHRcdG1heEFyZ3MgPSBbbWluICsgbWluUmFuZ2UsIHBpY2sob3B0aW9ucy5tYXgsIG1pbiArIG1pblJhbmdlKV07XG5cdFx0XHRpZiAoc3BhY2VBdmFpbGFibGUpIHsgLy8gaWYgc3BhY2UgaXMgYXZhaWxhYmUsIHN0YXkgd2l0aGluIHRoZSBkYXRhIHJhbmdlXG5cdFx0XHRcdG1heEFyZ3NbMl0gPSBheGlzLmRhdGFNYXg7XG5cdFx0XHR9XG5cblx0XHRcdG1heCA9IGFycmF5TWluKG1heEFyZ3MpO1xuXG5cdFx0XHQvLyBub3cgaWYgdGhlIG1heCBpcyBhZGp1c3RlZCwgYWRqdXN0IHRoZSBtaW4gYmFja1xuXHRcdFx0aWYgKG1heCAtIG1pbiA8IG1pblJhbmdlKSB7XG5cdFx0XHRcdG1pbkFyZ3NbMF0gPSBtYXggLSBtaW5SYW5nZTtcblx0XHRcdFx0bWluQXJnc1sxXSA9IHBpY2sob3B0aW9ucy5taW4sIG1heCAtIG1pblJhbmdlKTtcblx0XHRcdFx0bWluID0gYXJyYXlNYXgobWluQXJncyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVjb3JkIG1vZGlmaWVkIGV4dHJlbWVzXG5cdFx0YXhpcy5taW4gPSBtaW47XG5cdFx0YXhpcy5tYXggPSBtYXg7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFVwZGF0ZSB0cmFuc2xhdGlvbiBpbmZvcm1hdGlvblxuXHQgKi9cblx0c2V0QXhpc1RyYW5zbGF0aW9uOiBmdW5jdGlvbiAoc2F2ZU9sZCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdHJhbmdlID0gYXhpcy5tYXggLSBheGlzLm1pbixcblx0XHRcdHBvaW50UmFuZ2UgPSBheGlzLmF4aXNQb2ludFJhbmdlIHx8IDAsXG5cdFx0XHRjbG9zZXN0UG9pbnRSYW5nZSxcblx0XHRcdG1pblBvaW50T2Zmc2V0ID0gMCxcblx0XHRcdHBvaW50UmFuZ2VQYWRkaW5nID0gMCxcblx0XHRcdGxpbmtlZFBhcmVudCA9IGF4aXMubGlua2VkUGFyZW50LFxuXHRcdFx0b3JkaW5hbENvcnJlY3Rpb24sXG5cdFx0XHRoYXNDYXRlZ29yaWVzID0gISFheGlzLmNhdGVnb3JpZXMsXG5cdFx0XHR0cmFuc0EgPSBheGlzLnRyYW5zQTtcblxuXHRcdC8vIEFkanVzdCB0cmFuc2xhdGlvbiBmb3IgcGFkZGluZy4gWSBheGlzIHdpdGggY2F0ZWdvcmllcyBuZWVkIHRvIGdvIHRocm91Z2ggdGhlIHNhbWUgKCMxNzg0KS5cblx0XHRpZiAoYXhpcy5pc1hBeGlzIHx8IGhhc0NhdGVnb3JpZXMgfHwgcG9pbnRSYW5nZSkge1xuXHRcdFx0aWYgKGxpbmtlZFBhcmVudCkge1xuXHRcdFx0XHRtaW5Qb2ludE9mZnNldCA9IGxpbmtlZFBhcmVudC5taW5Qb2ludE9mZnNldDtcblx0XHRcdFx0cG9pbnRSYW5nZVBhZGRpbmcgPSBsaW5rZWRQYXJlbnQucG9pbnRSYW5nZVBhZGRpbmc7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVhY2goYXhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdFx0XHR2YXIgc2VyaWVzUG9pbnRSYW5nZSA9IGhhc0NhdGVnb3JpZXMgPyAxIDogKGF4aXMuaXNYQXhpcyA/IHNlcmllcy5wb2ludFJhbmdlIDogKGF4aXMuYXhpc1BvaW50UmFuZ2UgfHwgMCkpLCAvLyAjMjgwNlxuXHRcdFx0XHRcdFx0cG9pbnRQbGFjZW1lbnQgPSBzZXJpZXMub3B0aW9ucy5wb2ludFBsYWNlbWVudCxcblx0XHRcdFx0XHRcdHNlcmllc0Nsb3Nlc3RQb2ludFJhbmdlID0gc2VyaWVzLmNsb3Nlc3RQb2ludFJhbmdlO1xuXG5cdFx0XHRcdFx0aWYgKHNlcmllc1BvaW50UmFuZ2UgPiByYW5nZSkgeyAvLyAjMTQ0NlxuXHRcdFx0XHRcdFx0c2VyaWVzUG9pbnRSYW5nZSA9IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvaW50UmFuZ2UgPSBtYXRoTWF4KHBvaW50UmFuZ2UsIHNlcmllc1BvaW50UmFuZ2UpO1xuXG5cdFx0XHRcdFx0Ly8gbWluUG9pbnRPZmZzZXQgaXMgdGhlIHZhbHVlIHBhZGRpbmcgdG8gdGhlIGxlZnQgb2YgdGhlIGF4aXMgaW4gb3JkZXIgdG8gbWFrZVxuXHRcdFx0XHRcdC8vIHJvb20gZm9yIHBvaW50cyB3aXRoIGEgcG9pbnRSYW5nZSwgdHlwaWNhbGx5IGNvbHVtbnMuIFdoZW4gdGhlIHBvaW50UGxhY2VtZW50IG9wdGlvblxuXHRcdFx0XHRcdC8vIGlzICdiZXR3ZWVuJyBvciAnb24nLCB0aGlzIHBhZGRpbmcgZG9lcyBub3QgYXBwbHkuXG5cdFx0XHRcdFx0bWluUG9pbnRPZmZzZXQgPSBtYXRoTWF4KFxuXHRcdFx0XHRcdFx0bWluUG9pbnRPZmZzZXQsXG5cdFx0XHRcdFx0XHRpc1N0cmluZyhwb2ludFBsYWNlbWVudCkgPyAwIDogc2VyaWVzUG9pbnRSYW5nZSAvIDJcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gRGV0ZXJtaW5lIHRoZSB0b3RhbCBwYWRkaW5nIG5lZWRlZCB0byB0aGUgbGVuZ3RoIG9mIHRoZSBheGlzIHRvIG1ha2Ugcm9vbSBmb3IgdGhlXG5cdFx0XHRcdFx0Ly8gcG9pbnRSYW5nZS4gSWYgdGhlIHNlcmllcycgcG9pbnRQbGFjZW1lbnQgaXMgJ29uJywgbm8gcGFkZGluZyBpcyBhZGRlZC5cblx0XHRcdFx0XHRwb2ludFJhbmdlUGFkZGluZyA9IG1hdGhNYXgoXG5cdFx0XHRcdFx0XHRwb2ludFJhbmdlUGFkZGluZyxcblx0XHRcdFx0XHRcdHBvaW50UGxhY2VtZW50ID09PSAnb24nID8gMCA6IHNlcmllc1BvaW50UmFuZ2Vcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gU2V0IHRoZSBjbG9zZXN0UG9pbnRSYW5nZVxuXHRcdFx0XHRcdGlmICghc2VyaWVzLm5vU2hhcmVkVG9vbHRpcCAmJiBkZWZpbmVkKHNlcmllc0Nsb3Nlc3RQb2ludFJhbmdlKSkge1xuXHRcdFx0XHRcdFx0Y2xvc2VzdFBvaW50UmFuZ2UgPSBkZWZpbmVkKGNsb3Nlc3RQb2ludFJhbmdlKSA/XG5cdFx0XHRcdFx0XHRcdG1hdGhNaW4oY2xvc2VzdFBvaW50UmFuZ2UsIHNlcmllc0Nsb3Nlc3RQb2ludFJhbmdlKSA6XG5cdFx0XHRcdFx0XHRcdHNlcmllc0Nsb3Nlc3RQb2ludFJhbmdlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlY29yZCBtaW5Qb2ludE9mZnNldCBhbmQgcG9pbnRSYW5nZVBhZGRpbmdcblx0XHRcdG9yZGluYWxDb3JyZWN0aW9uID0gYXhpcy5vcmRpbmFsU2xvcGUgJiYgY2xvc2VzdFBvaW50UmFuZ2UgPyBheGlzLm9yZGluYWxTbG9wZSAvIGNsb3Nlc3RQb2ludFJhbmdlIDogMTsgLy8gIzk4OCwgIzE4NTNcblx0XHRcdGF4aXMubWluUG9pbnRPZmZzZXQgPSBtaW5Qb2ludE9mZnNldCA9IG1pblBvaW50T2Zmc2V0ICogb3JkaW5hbENvcnJlY3Rpb247XG5cdFx0XHRheGlzLnBvaW50UmFuZ2VQYWRkaW5nID0gcG9pbnRSYW5nZVBhZGRpbmcgPSBwb2ludFJhbmdlUGFkZGluZyAqIG9yZGluYWxDb3JyZWN0aW9uO1xuXG5cdFx0XHQvLyBwb2ludFJhbmdlIG1lYW5zIHRoZSB3aWR0aCByZXNlcnZlZCBmb3IgZWFjaCBwb2ludCwgbGlrZSBpbiBhIGNvbHVtbiBjaGFydFxuXHRcdFx0YXhpcy5wb2ludFJhbmdlID0gbWF0aE1pbihwb2ludFJhbmdlLCByYW5nZSk7XG5cblx0XHRcdC8vIGNsb3Nlc3RQb2ludFJhbmdlIG1lYW5zIHRoZSBjbG9zZXN0IGRpc3RhbmNlIGJldHdlZW4gcG9pbnRzLiBJbiBjb2x1bW5zXG5cdFx0XHQvLyBpdCBpcyBtb3N0bHkgZXF1YWwgdG8gcG9pbnRSYW5nZSwgYnV0IGluIGxpbmVzIHBvaW50UmFuZ2UgaXMgMCB3aGlsZSBjbG9zZXN0UG9pbnRSYW5nZVxuXHRcdFx0Ly8gaXMgc29tZSBvdGhlciB2YWx1ZVxuXHRcdFx0YXhpcy5jbG9zZXN0UG9pbnRSYW5nZSA9IGNsb3Nlc3RQb2ludFJhbmdlO1xuXHRcdH1cblxuXHRcdC8vIFNlY29uZGFyeSB2YWx1ZXNcblx0XHRpZiAoc2F2ZU9sZCkge1xuXHRcdFx0YXhpcy5vbGRUcmFuc0EgPSB0cmFuc0E7XG5cdFx0fVxuXHRcdGF4aXMudHJhbnNsYXRpb25TbG9wZSA9IGF4aXMudHJhbnNBID0gdHJhbnNBID0gYXhpcy5sZW4gLyAoKHJhbmdlICsgcG9pbnRSYW5nZVBhZGRpbmcpIHx8IDEpO1xuXHRcdGF4aXMudHJhbnNCID0gYXhpcy5ob3JpeiA/IGF4aXMubGVmdCA6IGF4aXMuYm90dG9tOyAvLyB0cmFuc2xhdGlvbiBhZGRlbmRcblx0XHRheGlzLm1pblBpeGVsUGFkZGluZyA9IHRyYW5zQSAqIG1pblBvaW50T2Zmc2V0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHRpY2sgcG9zaXRpb25zIHRvIHJvdW5kIHZhbHVlcyBhbmQgb3B0aW9uYWxseSBleHRlbmQgdGhlIGV4dHJlbWVzXG5cdCAqIHRvIHRoZSBuZWFyZXN0IHRpY2tcblx0ICovXG5cdHNldFRpY2tQb3NpdGlvbnM6IGZ1bmN0aW9uIChzZWNvbmRQYXNzKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0b3B0aW9ucyA9IGF4aXMub3B0aW9ucyxcblx0XHRcdHN0YXJ0T25UaWNrID0gb3B0aW9ucy5zdGFydE9uVGljayxcblx0XHRcdGVuZE9uVGljayA9IG9wdGlvbnMuZW5kT25UaWNrLFxuXHRcdFx0aXNMb2cgPSBheGlzLmlzTG9nLFxuXHRcdFx0aXNEYXRldGltZUF4aXMgPSBheGlzLmlzRGF0ZXRpbWVBeGlzLFxuXHRcdFx0aXNYQXhpcyA9IGF4aXMuaXNYQXhpcyxcblx0XHRcdGlzTGlua2VkID0gYXhpcy5pc0xpbmtlZCxcblx0XHRcdHRpY2tQb3NpdGlvbmVyID0gYXhpcy5vcHRpb25zLnRpY2tQb3NpdGlvbmVyLFxuXHRcdFx0bWF4UGFkZGluZyA9IG9wdGlvbnMubWF4UGFkZGluZyxcblx0XHRcdG1pblBhZGRpbmcgPSBvcHRpb25zLm1pblBhZGRpbmcsXG5cdFx0XHRsZW5ndGgsXG5cdFx0XHRsaW5rZWRQYXJlbnRFeHRyZW1lcyxcblx0XHRcdHRpY2tJbnRlcnZhbE9wdGlvbiA9IG9wdGlvbnMudGlja0ludGVydmFsLFxuXHRcdFx0bWluVGlja0ludGVydmFsT3B0aW9uID0gb3B0aW9ucy5taW5UaWNrSW50ZXJ2YWwsXG5cdFx0XHR0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbiA9IG9wdGlvbnMudGlja1BpeGVsSW50ZXJ2YWwsXG5cdFx0XHR0aWNrUG9zaXRpb25zLFxuXHRcdFx0a2VlcFR3b1RpY2tzT25seSxcblx0XHRcdGNhdGVnb3JpZXMgPSBheGlzLmNhdGVnb3JpZXM7XG5cblx0XHQvLyBsaW5rZWQgYXhpcyBnZXRzIHRoZSBleHRyZW1lcyBmcm9tIHRoZSBwYXJlbnQgYXhpc1xuXHRcdGlmIChpc0xpbmtlZCkge1xuXHRcdFx0YXhpcy5saW5rZWRQYXJlbnQgPSBjaGFydFtheGlzLmNvbGxdW29wdGlvbnMubGlua2VkVG9dO1xuXHRcdFx0bGlua2VkUGFyZW50RXh0cmVtZXMgPSBheGlzLmxpbmtlZFBhcmVudC5nZXRFeHRyZW1lcygpO1xuXHRcdFx0YXhpcy5taW4gPSBwaWNrKGxpbmtlZFBhcmVudEV4dHJlbWVzLm1pbiwgbGlua2VkUGFyZW50RXh0cmVtZXMuZGF0YU1pbik7XG5cdFx0XHRheGlzLm1heCA9IHBpY2sobGlua2VkUGFyZW50RXh0cmVtZXMubWF4LCBsaW5rZWRQYXJlbnRFeHRyZW1lcy5kYXRhTWF4KTtcblx0XHRcdGlmIChvcHRpb25zLnR5cGUgIT09IGF4aXMubGlua2VkUGFyZW50Lm9wdGlvbnMudHlwZSkge1xuXHRcdFx0XHRlcnJvcigxMSwgMSk7IC8vIENhbid0IGxpbmsgYXhlcyBvZiBkaWZmZXJlbnQgdHlwZVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7IC8vIGluaXRpYWwgbWluIGFuZCBtYXggZnJvbSB0aGUgZXh0cmVtZSBkYXRhIHZhbHVlc1xuXHRcdFx0YXhpcy5taW4gPSBwaWNrKGF4aXMudXNlck1pbiwgb3B0aW9ucy5taW4sIGF4aXMuZGF0YU1pbik7XG5cdFx0XHRheGlzLm1heCA9IHBpY2soYXhpcy51c2VyTWF4LCBvcHRpb25zLm1heCwgYXhpcy5kYXRhTWF4KTtcblx0XHR9XG5cblx0XHRpZiAoaXNMb2cpIHtcblx0XHRcdGlmICghc2Vjb25kUGFzcyAmJiBtYXRoTWluKGF4aXMubWluLCBwaWNrKGF4aXMuZGF0YU1pbiwgYXhpcy5taW4pKSA8PSAwKSB7IC8vICM5Nzhcblx0XHRcdFx0ZXJyb3IoMTAsIDEpOyAvLyBDYW4ndCBwbG90IG5lZ2F0aXZlIHZhbHVlcyBvbiBsb2cgYXhpc1xuXHRcdFx0fVxuXHRcdFx0YXhpcy5taW4gPSBjb3JyZWN0RmxvYXQobG9nMmxpbihheGlzLm1pbikpOyAvLyBjb3JyZWN0RmxvYXQgY3VyZXMgIzkzNFxuXHRcdFx0YXhpcy5tYXggPSBjb3JyZWN0RmxvYXQobG9nMmxpbihheGlzLm1heCkpO1xuXHRcdH1cblxuXHRcdC8vIGhhbmRsZSB6b29tZWQgcmFuZ2Vcblx0XHRpZiAoYXhpcy5yYW5nZSAmJiBkZWZpbmVkKGF4aXMubWF4KSkge1xuXHRcdFx0YXhpcy51c2VyTWluID0gYXhpcy5taW4gPSBtYXRoTWF4KGF4aXMubWluLCBheGlzLm1heCAtIGF4aXMucmFuZ2UpOyAvLyAjNjE4XG5cdFx0XHRheGlzLnVzZXJNYXggPSBheGlzLm1heDtcblxuXHRcdFx0YXhpcy5yYW5nZSA9IG51bGw7ICAvLyBkb24ndCB1c2UgaXQgd2hlbiBydW5uaW5nIHNldEV4dHJlbWVzXG5cdFx0fVxuXG5cdFx0Ly8gSG9vayBmb3IgYWRqdXN0aW5nIHRoaXMubWluIGFuZCB0aGlzLm1heC4gVXNlZCBieSBidWJibGUgc2VyaWVzLlxuXHRcdGlmIChheGlzLmJlZm9yZVBhZGRpbmcpIHtcblx0XHRcdGF4aXMuYmVmb3JlUGFkZGluZygpO1xuXHRcdH1cblxuXHRcdC8vIGFkanVzdCBtaW4gYW5kIG1heCBmb3IgdGhlIG1pbmltdW0gcmFuZ2Vcblx0XHRheGlzLmFkanVzdEZvck1pblJhbmdlKCk7XG5cblx0XHQvLyBQYWQgdGhlIHZhbHVlcyB0byBnZXQgY2xlYXIgb2YgdGhlIGNoYXJ0J3MgZWRnZXMuIFRvIGF2b2lkIHRpY2tJbnRlcnZhbCB0YWtpbmcgdGhlIHBhZGRpbmdcblx0XHQvLyBpbnRvIGFjY291bnQsIHdlIGRvIHRoaXMgYWZ0ZXIgY29tcHV0aW5nIHRpY2sgaW50ZXJ2YWwgKCMxMzM3KS5cblx0XHRpZiAoIWNhdGVnb3JpZXMgJiYgIWF4aXMuYXhpc1BvaW50UmFuZ2UgJiYgIWF4aXMudXNlUGVyY2VudGFnZSAmJiAhaXNMaW5rZWQgJiYgZGVmaW5lZChheGlzLm1pbikgJiYgZGVmaW5lZChheGlzLm1heCkpIHtcblx0XHRcdGxlbmd0aCA9IGF4aXMubWF4IC0gYXhpcy5taW47XG5cdFx0XHRpZiAobGVuZ3RoKSB7XG5cdFx0XHRcdGlmICghZGVmaW5lZChvcHRpb25zLm1pbikgJiYgIWRlZmluZWQoYXhpcy51c2VyTWluKSAmJiBtaW5QYWRkaW5nICYmIChheGlzLmRhdGFNaW4gPCAwIHx8ICFheGlzLmlnbm9yZU1pblBhZGRpbmcpKSB7XG5cdFx0XHRcdFx0YXhpcy5taW4gLT0gbGVuZ3RoICogbWluUGFkZGluZztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIWRlZmluZWQob3B0aW9ucy5tYXgpICYmICFkZWZpbmVkKGF4aXMudXNlck1heCkgICYmIG1heFBhZGRpbmcgJiYgKGF4aXMuZGF0YU1heCA+IDAgfHwgIWF4aXMuaWdub3JlTWF4UGFkZGluZykpIHtcblx0XHRcdFx0XHRheGlzLm1heCArPSBsZW5ndGggKiBtYXhQYWRkaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU3RheSB3aXRoaW4gZmxvb3IgYW5kIGNlaWxpbmdcblx0XHRpZiAoaXNOdW1iZXIob3B0aW9ucy5mbG9vcikpIHtcblx0XHRcdGF4aXMubWluID0gbWF0aE1heChheGlzLm1pbiwgb3B0aW9ucy5mbG9vcik7XG5cdFx0fVxuXHRcdGlmIChpc051bWJlcihvcHRpb25zLmNlaWxpbmcpKSB7XG5cdFx0XHRheGlzLm1heCA9IG1hdGhNaW4oYXhpcy5tYXgsIG9wdGlvbnMuY2VpbGluZyk7XG5cdFx0fVxuXG5cdFx0Ly8gZ2V0IHRpY2tJbnRlcnZhbFxuXHRcdGlmIChheGlzLm1pbiA9PT0gYXhpcy5tYXggfHwgYXhpcy5taW4gPT09IHVuZGVmaW5lZCB8fCBheGlzLm1heCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRheGlzLnRpY2tJbnRlcnZhbCA9IDE7XG5cdFx0fSBlbHNlIGlmIChpc0xpbmtlZCAmJiAhdGlja0ludGVydmFsT3B0aW9uICYmXG5cdFx0XHRcdHRpY2tQaXhlbEludGVydmFsT3B0aW9uID09PSBheGlzLmxpbmtlZFBhcmVudC5vcHRpb25zLnRpY2tQaXhlbEludGVydmFsKSB7XG5cdFx0XHRheGlzLnRpY2tJbnRlcnZhbCA9IGF4aXMubGlua2VkUGFyZW50LnRpY2tJbnRlcnZhbDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBwaWNrKFxuXHRcdFx0XHR0aWNrSW50ZXJ2YWxPcHRpb24sXG5cdFx0XHRcdGNhdGVnb3JpZXMgPyAvLyBmb3IgY2F0ZWdvcmllZCBheGlzLCAxIGlzIGRlZmF1bHQsIGZvciBsaW5lYXIgYXhpcyB1c2UgdGlja1BpeFxuXHRcdFx0XHRcdDEgOlxuXHRcdFx0XHRcdC8vIGRvbid0IGxldCBpdCBiZSBtb3JlIHRoYW4gdGhlIGRhdGEgcmFuZ2Vcblx0XHRcdFx0XHQoYXhpcy5tYXggLSBheGlzLm1pbikgKiB0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbiAvIG1hdGhNYXgoYXhpcy5sZW4sIHRpY2tQaXhlbEludGVydmFsT3B0aW9uKVxuXHRcdFx0KTtcblx0XHRcdC8vIEZvciBzcXVpc2hlZCBheGVzLCBzZXQgb25seSB0d28gdGlja3Ncblx0XHRcdGlmICghZGVmaW5lZCh0aWNrSW50ZXJ2YWxPcHRpb24pICYmIGF4aXMubGVuIDwgdGlja1BpeGVsSW50ZXJ2YWxPcHRpb24gJiYgIXRoaXMuaXNSYWRpYWwgJiZcblx0XHRcdFx0XHQhdGhpcy5pc0xvZyAmJiAhY2F0ZWdvcmllcyAmJiBzdGFydE9uVGljayAmJiBlbmRPblRpY2spIHtcblx0XHRcdFx0a2VlcFR3b1RpY2tzT25seSA9IHRydWU7XG5cdFx0XHRcdGF4aXMudGlja0ludGVydmFsIC89IDQ7IC8vIHRpY2sgZXh0cmVtZXMgY2xvc2VyIHRvIHRoZSByZWFsIHZhbHVlc1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE5vdyB3ZSdyZSBmaW5pc2hlZCBkZXRlY3RpbmcgbWluIGFuZCBtYXgsIGNyb3AgYW5kIGdyb3VwIHNlcmllcyBkYXRhLiBUaGlzXG5cdFx0Ly8gaXMgaW4gdHVybiBuZWVkZWQgaW4gb3JkZXIgdG8gZmluZCB0aWNrIHBvc2l0aW9ucyBpbiBvcmRpbmFsIGF4ZXMuXG5cdFx0aWYgKGlzWEF4aXMgJiYgIXNlY29uZFBhc3MpIHtcblx0XHRcdGVhY2goYXhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdFx0c2VyaWVzLnByb2Nlc3NEYXRhKGF4aXMubWluICE9PSBheGlzLm9sZE1pbiB8fCBheGlzLm1heCAhPT0gYXhpcy5vbGRNYXgpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gc2V0IHRoZSB0cmFuc2xhdGlvbiBmYWN0b3IgdXNlZCBpbiB0cmFuc2xhdGUgZnVuY3Rpb25cblx0XHRheGlzLnNldEF4aXNUcmFuc2xhdGlvbih0cnVlKTtcblxuXHRcdC8vIGhvb2sgZm9yIG9yZGluYWwgYXhlcyBhbmQgcmFkaWFsIGF4ZXNcblx0XHRpZiAoYXhpcy5iZWZvcmVTZXRUaWNrUG9zaXRpb25zKSB7XG5cdFx0XHRheGlzLmJlZm9yZVNldFRpY2tQb3NpdGlvbnMoKTtcblx0XHR9XG5cblx0XHQvLyBob29rIGZvciBleHRlbnNpb25zLCB1c2VkIGluIEhpZ2hzdG9jayBvcmRpbmFsIGF4ZXNcblx0XHRpZiAoYXhpcy5wb3N0UHJvY2Vzc1RpY2tJbnRlcnZhbCkge1xuXHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBheGlzLnBvc3RQcm9jZXNzVGlja0ludGVydmFsKGF4aXMudGlja0ludGVydmFsKTtcblx0XHR9XG5cblx0XHQvLyBJbiBjb2x1bW4tbGlrZSBjaGFydHMsIGRvbid0IGNyYW1wIGluIG1vcmUgdGlja3MgdGhhbiB0aGVyZSBhcmUgcG9pbnRzICgjMTk0Mylcblx0XHRpZiAoYXhpcy5wb2ludFJhbmdlKSB7XG5cdFx0XHRheGlzLnRpY2tJbnRlcnZhbCA9IG1hdGhNYXgoYXhpcy5wb2ludFJhbmdlLCBheGlzLnRpY2tJbnRlcnZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gQmVmb3JlIG5vcm1hbGl6aW5nIHRoZSB0aWNrIGludGVydmFsLCBoYW5kbGUgbWluaW11bSB0aWNrIGludGVydmFsLiBUaGlzIGFwcGxpZXMgb25seSBpZiB0aWNrSW50ZXJ2YWwgaXMgbm90IGRlZmluZWQuXG5cdFx0aWYgKCF0aWNrSW50ZXJ2YWxPcHRpb24gJiYgYXhpcy50aWNrSW50ZXJ2YWwgPCBtaW5UaWNrSW50ZXJ2YWxPcHRpb24pIHtcblx0XHRcdGF4aXMudGlja0ludGVydmFsID0gbWluVGlja0ludGVydmFsT3B0aW9uO1xuXHRcdH1cblxuXHRcdC8vIGZvciBsaW5lYXIgYXhlcywgZ2V0IG1hZ25pdHVkZSBhbmQgbm9ybWFsaXplIHRoZSBpbnRlcnZhbFxuXHRcdGlmICghaXNEYXRldGltZUF4aXMgJiYgIWlzTG9nKSB7IC8vIGxpbmVhclxuXHRcdFx0aWYgKCF0aWNrSW50ZXJ2YWxPcHRpb24pIHtcblx0XHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwgPSBub3JtYWxpemVUaWNrSW50ZXJ2YWwoXG5cdFx0XHRcdFx0YXhpcy50aWNrSW50ZXJ2YWwsIFxuXHRcdFx0XHRcdG51bGwsIFxuXHRcdFx0XHRcdGdldE1hZ25pdHVkZShheGlzLnRpY2tJbnRlcnZhbCksIFxuXHRcdFx0XHRcdC8vIElmIHRoZSB0aWNrIGludGVydmFsIGlzIGJldHdlZW4gMSBhbmQgNSBhbmQgdGhlIGF4aXMgbWF4IGlzIGluIHRoZSBvcmRlciBvZlxuXHRcdFx0XHRcdC8vIHRob3VzYW5kcywgY2hhbmNlcyBhcmUgd2UgYXJlIGRlYWxpbmcgd2l0aCB5ZWFycy4gRG9uJ3QgYWxsb3cgZGVjaW1hbHMuICMzMzYzLlxuXHRcdFx0XHRcdHBpY2sob3B0aW9ucy5hbGxvd0RlY2ltYWxzLCAhKGF4aXMudGlja0ludGVydmFsID4gMSAmJiBheGlzLnRpY2tJbnRlcnZhbCA8IDUgJiYgYXhpcy5tYXggPiAxMDAwICYmIGF4aXMubWF4IDwgOTk5OSkpXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gZ2V0IG1pbm9yVGlja0ludGVydmFsXG5cdFx0YXhpcy5taW5vclRpY2tJbnRlcnZhbCA9IG9wdGlvbnMubWlub3JUaWNrSW50ZXJ2YWwgPT09ICdhdXRvJyAmJiBheGlzLnRpY2tJbnRlcnZhbCA/XG5cdFx0XHRcdGF4aXMudGlja0ludGVydmFsIC8gNSA6IG9wdGlvbnMubWlub3JUaWNrSW50ZXJ2YWw7XG5cblx0XHQvLyBmaW5kIHRoZSB0aWNrIHBvc2l0aW9uc1xuXHRcdGF4aXMudGlja1Bvc2l0aW9ucyA9IHRpY2tQb3NpdGlvbnMgPSBvcHRpb25zLnRpY2tQb3NpdGlvbnMgP1xuXHRcdFx0W10uY29uY2F0KG9wdGlvbnMudGlja1Bvc2l0aW9ucykgOiAvLyBXb3JrIG9uIGEgY29weSAoIzE1NjUpXG5cdFx0XHQodGlja1Bvc2l0aW9uZXIgJiYgdGlja1Bvc2l0aW9uZXIuYXBwbHkoYXhpcywgW2F4aXMubWluLCBheGlzLm1heF0pKTtcblx0XHRpZiAoIXRpY2tQb3NpdGlvbnMpIHtcblxuXHRcdFx0Ly8gVG9vIG1hbnkgdGlja3Ncblx0XHRcdGlmICghYXhpcy5vcmRpbmFsUG9zaXRpb25zICYmIChheGlzLm1heCAtIGF4aXMubWluKSAvIGF4aXMudGlja0ludGVydmFsID4gbWF0aE1heCgyICogYXhpcy5sZW4sIDIwMCkpIHtcblx0XHRcdFx0ZXJyb3IoMTksIHRydWUpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaXNEYXRldGltZUF4aXMpIHtcblx0XHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMuZ2V0VGltZVRpY2tzKFxuXHRcdFx0XHRcdGF4aXMubm9ybWFsaXplVGltZVRpY2tJbnRlcnZhbChheGlzLnRpY2tJbnRlcnZhbCwgb3B0aW9ucy51bml0cyksXG5cdFx0XHRcdFx0YXhpcy5taW4sXG5cdFx0XHRcdFx0YXhpcy5tYXgsXG5cdFx0XHRcdFx0b3B0aW9ucy5zdGFydE9mV2Vlayxcblx0XHRcdFx0XHRheGlzLm9yZGluYWxQb3NpdGlvbnMsXG5cdFx0XHRcdFx0YXhpcy5jbG9zZXN0UG9pbnRSYW5nZSxcblx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2UgaWYgKGlzTG9nKSB7XG5cdFx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLmdldExvZ1RpY2tQb3NpdGlvbnMoYXhpcy50aWNrSW50ZXJ2YWwsIGF4aXMubWluLCBheGlzLm1heCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy5nZXRMaW5lYXJUaWNrUG9zaXRpb25zKGF4aXMudGlja0ludGVydmFsLCBheGlzLm1pbiwgYXhpcy5tYXgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoa2VlcFR3b1RpY2tzT25seSkge1xuXHRcdFx0XHR0aWNrUG9zaXRpb25zLnNwbGljZSgxLCB0aWNrUG9zaXRpb25zLmxlbmd0aCAtIDIpO1xuXHRcdFx0fVxuXG5cdFx0XHRheGlzLnRpY2tQb3NpdGlvbnMgPSB0aWNrUG9zaXRpb25zO1xuXHRcdH1cblxuXHRcdGlmICghaXNMaW5rZWQpIHtcblxuXHRcdFx0Ly8gcmVzZXQgbWluL21heCBvciByZW1vdmUgZXh0cmVtZXMgYmFzZWQgb24gc3RhcnQvZW5kIG9uIHRpY2tcblx0XHRcdHZhciByb3VuZGVkTWluID0gdGlja1Bvc2l0aW9uc1swXSxcblx0XHRcdFx0cm91bmRlZE1heCA9IHRpY2tQb3NpdGlvbnNbdGlja1Bvc2l0aW9ucy5sZW5ndGggLSAxXSxcblx0XHRcdFx0bWluUG9pbnRPZmZzZXQgPSBheGlzLm1pblBvaW50T2Zmc2V0IHx8IDAsXG5cdFx0XHRcdHNpbmdsZVBhZDtcblxuXHRcdFx0aWYgKHN0YXJ0T25UaWNrKSB7XG5cdFx0XHRcdGF4aXMubWluID0gcm91bmRlZE1pbjtcblx0XHRcdH0gZWxzZSBpZiAoYXhpcy5taW4gLSBtaW5Qb2ludE9mZnNldCA+IHJvdW5kZWRNaW4pIHtcblx0XHRcdFx0dGlja1Bvc2l0aW9ucy5zaGlmdCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoZW5kT25UaWNrKSB7XG5cdFx0XHRcdGF4aXMubWF4ID0gcm91bmRlZE1heDtcblx0XHRcdH0gZWxzZSBpZiAoYXhpcy5tYXggKyBtaW5Qb2ludE9mZnNldCA8IHJvdW5kZWRNYXgpIHtcblx0XHRcdFx0dGlja1Bvc2l0aW9ucy5wb3AoKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgbm8gdGljayBhcmUgbGVmdCwgc2V0IG9uZSB0aWNrIGluIHRoZSBtaWRkbGUgKCMzMTk1KSBcblx0XHRcdGlmICh0aWNrUG9zaXRpb25zLmxlbmd0aCA9PT0gMCAmJiBkZWZpbmVkKHJvdW5kZWRNaW4pKSB7XG5cdFx0XHRcdHRpY2tQb3NpdGlvbnMucHVzaCgocm91bmRlZE1heCArIHJvdW5kZWRNaW4pIC8gMik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFdoZW4gdGhlcmUgaXMgb25seSBvbmUgcG9pbnQsIG9yIGFsbCBwb2ludHMgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBvbiB0aGlzIGF4aXMsIHRoZW4gbWluXG5cdFx0XHQvLyBhbmQgbWF4IGFyZSBlcXVhbCBhbmQgdGlja1Bvc2l0aW9ucy5sZW5ndGggaXMgMCBvciAxLiBJbiB0aGlzIGNhc2UsIGFkZCBzb21lIHBhZGRpbmdcblx0XHRcdC8vIGluIG9yZGVyIHRvIGNlbnRlciB0aGUgcG9pbnQsIGJ1dCBsZWF2ZSBpdCB3aXRoIG9uZSB0aWNrLiAjMTMzNy5cblx0XHRcdGlmICh0aWNrUG9zaXRpb25zLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRzaW5nbGVQYWQgPSBtYXRoQWJzKGF4aXMubWF4KSA+IDEwZTEyID8gMSA6IDAuMDAxOyAvLyBUaGUgbG93ZXN0IHBvc3NpYmxlIG51bWJlciB0byBhdm9pZCBleHRyYSBwYWRkaW5nIG9uIGNvbHVtbnMgKCMyNjE5LCAjMjg0Nilcblx0XHRcdFx0YXhpcy5taW4gLT0gc2luZ2xlUGFkO1xuXHRcdFx0XHRheGlzLm1heCArPSBzaW5nbGVQYWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIG1heCB0aWNrcyBvZiBlaXRoZXIgdGhlIHggYW5kIHkgYXhpcyBjb2xsZWN0aW9uXG5cdCAqL1xuXHRzZXRNYXhUaWNrczogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdG1heFRpY2tzID0gY2hhcnQubWF4VGlja3MgfHwge30sXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gdGhpcy50aWNrUG9zaXRpb25zLFxuXHRcdFx0a2V5ID0gdGhpcy5fbWF4VGlja3NLZXkgPSBbdGhpcy5jb2xsLCB0aGlzLnBvcywgdGhpcy5sZW5dLmpvaW4oJy0nKTtcblxuXHRcdGlmICghdGhpcy5pc0xpbmtlZCAmJiAhdGhpcy5pc0RhdGV0aW1lQXhpcyAmJiB0aWNrUG9zaXRpb25zICYmIHRpY2tQb3NpdGlvbnMubGVuZ3RoID4gKG1heFRpY2tzW2tleV0gfHwgMCkgJiYgdGhpcy5vcHRpb25zLmFsaWduVGlja3MgIT09IGZhbHNlKSB7XG5cdFx0XHRtYXhUaWNrc1trZXldID0gdGlja1Bvc2l0aW9ucy5sZW5ndGg7XG5cdFx0fVxuXHRcdGNoYXJ0Lm1heFRpY2tzID0gbWF4VGlja3M7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFdoZW4gdXNpbmcgbXVsdGlwbGUgYXhlcywgYWRqdXN0IHRoZSBudW1iZXIgb2YgdGlja3MgdG8gbWF0Y2ggdGhlIGhpZ2hlc3Rcblx0ICogbnVtYmVyIG9mIHRpY2tzIGluIHRoYXQgZ3JvdXBcblx0ICovXG5cdGFkanVzdFRpY2tBbW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0XHRrZXkgPSBheGlzLl9tYXhUaWNrc0tleSxcblx0XHRcdHRpY2tQb3NpdGlvbnMgPSBheGlzLnRpY2tQb3NpdGlvbnMsXG5cdFx0XHRtYXhUaWNrcyA9IGNoYXJ0Lm1heFRpY2tzO1xuXG5cdFx0aWYgKG1heFRpY2tzICYmIG1heFRpY2tzW2tleV0gJiYgIWF4aXMuaXNEYXRldGltZUF4aXMgJiYgIWF4aXMuY2F0ZWdvcmllcyAmJiAhYXhpcy5pc0xpbmtlZCAmJlxuXHRcdFx0XHRheGlzLm9wdGlvbnMuYWxpZ25UaWNrcyAhPT0gZmFsc2UgJiYgdGhpcy5taW4gIT09IFVOREVGSU5FRCkge1xuXHRcdFx0dmFyIG9sZFRpY2tBbW91bnQgPSBheGlzLnRpY2tBbW91bnQsXG5cdFx0XHRcdGNhbGN1bGF0ZWRUaWNrQW1vdW50ID0gdGlja1Bvc2l0aW9ucy5sZW5ndGgsXG5cdFx0XHRcdHRpY2tBbW91bnQ7XG5cblx0XHRcdC8vIHNldCB0aGUgYXhpcy1sZXZlbCB0aWNrQW1vdW50IHRvIHVzZSBiZWxvd1xuXHRcdFx0YXhpcy50aWNrQW1vdW50ID0gdGlja0Ftb3VudCA9IG1heFRpY2tzW2tleV07XG5cblx0XHRcdGlmIChjYWxjdWxhdGVkVGlja0Ftb3VudCA8IHRpY2tBbW91bnQpIHtcblx0XHRcdFx0d2hpbGUgKHRpY2tQb3NpdGlvbnMubGVuZ3RoIDwgdGlja0Ftb3VudCkge1xuXHRcdFx0XHRcdHRpY2tQb3NpdGlvbnMucHVzaChjb3JyZWN0RmxvYXQoXG5cdFx0XHRcdFx0XHR0aWNrUG9zaXRpb25zW3RpY2tQb3NpdGlvbnMubGVuZ3RoIC0gMV0gKyBheGlzLnRpY2tJbnRlcnZhbFxuXHRcdFx0XHRcdCkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGF4aXMudHJhbnNBICo9IChjYWxjdWxhdGVkVGlja0Ftb3VudCAtIDEpIC8gKHRpY2tBbW91bnQgLSAxKTtcblx0XHRcdFx0YXhpcy5tYXggPSB0aWNrUG9zaXRpb25zW3RpY2tQb3NpdGlvbnMubGVuZ3RoIC0gMV07XG5cblx0XHRcdH1cblx0XHRcdGlmIChkZWZpbmVkKG9sZFRpY2tBbW91bnQpICYmIHRpY2tBbW91bnQgIT09IG9sZFRpY2tBbW91bnQpIHtcblx0XHRcdFx0YXhpcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgc2NhbGUgYmFzZWQgb24gZGF0YSBtaW4gYW5kIG1heCwgdXNlciBzZXQgbWluIGFuZCBtYXggb3Igb3B0aW9uc1xuXHQgKlxuXHQgKi9cblx0c2V0U2NhbGU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRzdGFja3MgPSBheGlzLnN0YWNrcyxcblx0XHRcdHR5cGUsXG5cdFx0XHRpLFxuXHRcdFx0aXNEaXJ0eURhdGEsXG5cdFx0XHRpc0RpcnR5QXhpc0xlbmd0aDtcblxuXHRcdGF4aXMub2xkTWluID0gYXhpcy5taW47XG5cdFx0YXhpcy5vbGRNYXggPSBheGlzLm1heDtcblx0XHRheGlzLm9sZEF4aXNMZW5ndGggPSBheGlzLmxlbjtcblxuXHRcdC8vIHNldCB0aGUgbmV3IGF4aXNMZW5ndGhcblx0XHRheGlzLnNldEF4aXNTaXplKCk7XG5cdFx0Ly9heGlzTGVuZ3RoID0gaG9yaXogPyBheGlzV2lkdGggOiBheGlzSGVpZ2h0O1xuXHRcdGlzRGlydHlBeGlzTGVuZ3RoID0gYXhpcy5sZW4gIT09IGF4aXMub2xkQXhpc0xlbmd0aDtcblxuXHRcdC8vIGlzIHRoZXJlIG5ldyBkYXRhP1xuXHRcdGVhY2goYXhpcy5zZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMpIHtcblx0XHRcdGlmIChzZXJpZXMuaXNEaXJ0eURhdGEgfHwgc2VyaWVzLmlzRGlydHkgfHxcblx0XHRcdFx0XHRzZXJpZXMueEF4aXMuaXNEaXJ0eSkgeyAvLyB3aGVuIHggYXhpcyBpcyBkaXJ0eSwgd2UgbmVlZCBuZXcgZGF0YSBleHRyZW1lcyBmb3IgeSBhcyB3ZWxsXG5cdFx0XHRcdGlzRGlydHlEYXRhID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGRvIHdlIHJlYWxseSBuZWVkIHRvIGdvIHRocm91Z2ggYWxsIHRoaXM/XG5cdFx0aWYgKGlzRGlydHlBeGlzTGVuZ3RoIHx8IGlzRGlydHlEYXRhIHx8IGF4aXMuaXNMaW5rZWQgfHwgYXhpcy5mb3JjZVJlZHJhdyB8fFxuXHRcdFx0YXhpcy51c2VyTWluICE9PSBheGlzLm9sZFVzZXJNaW4gfHwgYXhpcy51c2VyTWF4ICE9PSBheGlzLm9sZFVzZXJNYXgpIHtcblxuXHRcdFx0Ly8gcmVzZXQgc3RhY2tzXG5cdFx0XHRpZiAoIWF4aXMuaXNYQXhpcykge1xuXHRcdFx0XHRmb3IgKHR5cGUgaW4gc3RhY2tzKSB7XG5cdFx0XHRcdFx0Zm9yIChpIGluIHN0YWNrc1t0eXBlXSkge1xuXHRcdFx0XHRcdFx0c3RhY2tzW3R5cGVdW2ldLnRvdGFsID0gbnVsbDtcblx0XHRcdFx0XHRcdHN0YWNrc1t0eXBlXVtpXS5jdW0gPSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRheGlzLmZvcmNlUmVkcmF3ID0gZmFsc2U7XG5cblx0XHRcdC8vIGdldCBkYXRhIGV4dHJlbWVzIGlmIG5lZWRlZFxuXHRcdFx0YXhpcy5nZXRTZXJpZXNFeHRyZW1lcygpO1xuXG5cdFx0XHQvLyBnZXQgZml4ZWQgcG9zaXRpb25zIGJhc2VkIG9uIHRpY2tJbnRlcnZhbFxuXHRcdFx0YXhpcy5zZXRUaWNrUG9zaXRpb25zKCk7XG5cblx0XHRcdC8vIHJlY29yZCBvbGQgdmFsdWVzIHRvIGRlY2lkZSB3aGV0aGVyIGEgcmVzY2FsZSBpcyBuZWNlc3NhcnkgbGF0ZXIgb24gKCM1NDApXG5cdFx0XHRheGlzLm9sZFVzZXJNaW4gPSBheGlzLnVzZXJNaW47XG5cdFx0XHRheGlzLm9sZFVzZXJNYXggPSBheGlzLnVzZXJNYXg7XG5cblx0XHRcdC8vIE1hcmsgYXMgZGlydHkgaWYgaXQgaXMgbm90IGFscmVhZHkgc2V0IHRvIGRpcnR5IGFuZCBleHRyZW1lcyBoYXZlIGNoYW5nZWQuICM1OTUuXG5cdFx0XHRpZiAoIWF4aXMuaXNEaXJ0eSkge1xuXHRcdFx0XHRheGlzLmlzRGlydHkgPSBpc0RpcnR5QXhpc0xlbmd0aCB8fCBheGlzLm1pbiAhPT0gYXhpcy5vbGRNaW4gfHwgYXhpcy5tYXggIT09IGF4aXMub2xkTWF4O1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAoIWF4aXMuaXNYQXhpcykge1xuXHRcdFx0aWYgKGF4aXMub2xkU3RhY2tzKSB7XG5cdFx0XHRcdHN0YWNrcyA9IGF4aXMuc3RhY2tzID0gYXhpcy5vbGRTdGFja3M7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlc2V0IHN0YWNrc1xuXHRcdFx0Zm9yICh0eXBlIGluIHN0YWNrcykge1xuXHRcdFx0XHRmb3IgKGkgaW4gc3RhY2tzW3R5cGVdKSB7XG5cdFx0XHRcdFx0c3RhY2tzW3R5cGVdW2ldLmN1bSA9IHN0YWNrc1t0eXBlXVtpXS50b3RhbDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgbWF4aW11bSB0aWNrIGFtb3VudFxuXHRcdGF4aXMuc2V0TWF4VGlja3MoKTtcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBleHRyZW1lcyBhbmQgb3B0aW9uYWxseSByZWRyYXdcblx0ICogQHBhcmFtIHtOdW1iZXJ9IG5ld01pblxuXHQgKiBAcGFyYW0ge051bWJlcn0gbmV3TWF4XG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVkcmF3XG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IGFuaW1hdGlvbiBXaGV0aGVyIHRvIGFwcGx5IGFuaW1hdGlvbiwgYW5kIG9wdGlvbmFsbHkgYW5pbWF0aW9uXG5cdCAqICAgIGNvbmZpZ3VyYXRpb25cblx0ICogQHBhcmFtIHtPYmplY3R9IGV2ZW50QXJndW1lbnRzXG5cdCAqXG5cdCAqL1xuXHRzZXRFeHRyZW1lczogZnVuY3Rpb24gKG5ld01pbiwgbmV3TWF4LCByZWRyYXcsIGFuaW1hdGlvbiwgZXZlbnRBcmd1bWVudHMpIHtcblx0XHR2YXIgYXhpcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGF4aXMuY2hhcnQ7XG5cblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7IC8vIGRlZmF1bHRzIHRvIHRydWVcblxuXHRcdC8vIEV4dGVuZCB0aGUgYXJndW1lbnRzIHdpdGggbWluIGFuZCBtYXhcblx0XHRldmVudEFyZ3VtZW50cyA9IGV4dGVuZChldmVudEFyZ3VtZW50cywge1xuXHRcdFx0bWluOiBuZXdNaW4sXG5cdFx0XHRtYXg6IG5ld01heFxuXHRcdH0pO1xuXG5cdFx0Ly8gRmlyZSB0aGUgZXZlbnRcblx0XHRmaXJlRXZlbnQoYXhpcywgJ3NldEV4dHJlbWVzJywgZXZlbnRBcmd1bWVudHMsIGZ1bmN0aW9uICgpIHsgLy8gdGhlIGRlZmF1bHQgZXZlbnQgaGFuZGxlclxuXG5cdFx0XHRheGlzLnVzZXJNaW4gPSBuZXdNaW47XG5cdFx0XHRheGlzLnVzZXJNYXggPSBuZXdNYXg7XG5cdFx0XHRheGlzLmV2ZW50QXJncyA9IGV2ZW50QXJndW1lbnRzO1xuXG5cdFx0XHQvLyBNYXJrIGZvciBydW5uaW5nIGFmdGVyU2V0RXh0cmVtZXNcblx0XHRcdGF4aXMuaXNEaXJ0eUV4dHJlbWVzID0gdHJ1ZTtcblxuXHRcdFx0Ly8gcmVkcmF3XG5cdFx0XHRpZiAocmVkcmF3KSB7XG5cdFx0XHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBPdmVycmlkYWJsZSBtZXRob2QgZm9yIHpvb21pbmcgY2hhcnQuIFB1bGxlZCBvdXQgaW4gYSBzZXBhcmF0ZSBtZXRob2QgdG8gYWxsb3cgb3ZlcnJpZGluZ1xuXHQgKiBpbiBzdG9jayBjaGFydHMuXG5cdCAqL1xuXHR6b29tOiBmdW5jdGlvbiAobmV3TWluLCBuZXdNYXgpIHtcblx0XHR2YXIgZGF0YU1pbiA9IHRoaXMuZGF0YU1pbixcblx0XHRcdGRhdGFNYXggPSB0aGlzLmRhdGFNYXgsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG5cdFx0Ly8gUHJldmVudCBwaW5jaCB6b29taW5nIG91dCBvZiByYW5nZS4gQ2hlY2sgZm9yIGRlZmluZWQgaXMgZm9yICMxOTQ2LiAjMTczNC5cblx0XHRpZiAoIXRoaXMuYWxsb3dab29tT3V0c2lkZSkge1xuXHRcdFx0aWYgKGRlZmluZWQoZGF0YU1pbikgJiYgbmV3TWluIDw9IG1hdGhNaW4oZGF0YU1pbiwgcGljayhvcHRpb25zLm1pbiwgZGF0YU1pbikpKSB7XG5cdFx0XHRcdG5ld01pbiA9IFVOREVGSU5FRDtcblx0XHRcdH1cblx0XHRcdGlmIChkZWZpbmVkKGRhdGFNYXgpICYmIG5ld01heCA+PSBtYXRoTWF4KGRhdGFNYXgsIHBpY2sob3B0aW9ucy5tYXgsIGRhdGFNYXgpKSkge1xuXHRcdFx0XHRuZXdNYXggPSBVTkRFRklORUQ7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSW4gZnVsbCB2aWV3LCBkaXNwbGF5aW5nIHRoZSByZXNldCB6b29tIGJ1dHRvbiBpcyBub3QgcmVxdWlyZWRcblx0XHR0aGlzLmRpc3BsYXlCdG4gPSBuZXdNaW4gIT09IFVOREVGSU5FRCB8fCBuZXdNYXggIT09IFVOREVGSU5FRDtcblxuXHRcdC8vIERvIGl0XG5cdFx0dGhpcy5zZXRFeHRyZW1lcyhcblx0XHRcdG5ld01pbixcblx0XHRcdG5ld01heCxcblx0XHRcdGZhbHNlLFxuXHRcdFx0VU5ERUZJTkVELFxuXHRcdFx0eyB0cmlnZ2VyOiAnem9vbScgfVxuXHRcdCk7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFVwZGF0ZSB0aGUgYXhpcyBtZXRyaWNzXG5cdCAqL1xuXHRzZXRBeGlzU2l6ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0b2Zmc2V0TGVmdCA9IG9wdGlvbnMub2Zmc2V0TGVmdCB8fCAwLFxuXHRcdFx0b2Zmc2V0UmlnaHQgPSBvcHRpb25zLm9mZnNldFJpZ2h0IHx8IDAsXG5cdFx0XHRob3JpeiA9IHRoaXMuaG9yaXosXG5cdFx0XHR3aWR0aCA9IHBpY2sob3B0aW9ucy53aWR0aCwgY2hhcnQucGxvdFdpZHRoIC0gb2Zmc2V0TGVmdCArIG9mZnNldFJpZ2h0KSxcblx0XHRcdGhlaWdodCA9IHBpY2sob3B0aW9ucy5oZWlnaHQsIGNoYXJ0LnBsb3RIZWlnaHQpLFxuXHRcdFx0dG9wID0gcGljayhvcHRpb25zLnRvcCwgY2hhcnQucGxvdFRvcCksXG5cdFx0XHRsZWZ0ID0gcGljayhvcHRpb25zLmxlZnQsIGNoYXJ0LnBsb3RMZWZ0ICsgb2Zmc2V0TGVmdCksXG5cdFx0XHRwZXJjZW50UmVnZXggPSAvJSQvO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIHBlcmNlbnRhZ2UgYmFzZWQgaW5wdXQgdmFsdWVzXG5cdFx0aWYgKHBlcmNlbnRSZWdleC50ZXN0KGhlaWdodCkpIHtcblx0XHRcdGhlaWdodCA9IHBhcnNlSW50KGhlaWdodCwgMTApIC8gMTAwICogY2hhcnQucGxvdEhlaWdodDtcblx0XHR9XG5cdFx0aWYgKHBlcmNlbnRSZWdleC50ZXN0KHRvcCkpIHtcblx0XHRcdHRvcCA9IHBhcnNlSW50KHRvcCwgMTApIC8gMTAwICogY2hhcnQucGxvdEhlaWdodCArIGNoYXJ0LnBsb3RUb3A7XG5cdFx0fVxuXG5cdFx0Ly8gRXhwb3NlIGJhc2ljIHZhbHVlcyB0byB1c2UgaW4gU2VyaWVzIG9iamVjdCBhbmQgbmF2aWdhdG9yXG5cdFx0dGhpcy5sZWZ0ID0gbGVmdDtcblx0XHR0aGlzLnRvcCA9IHRvcDtcblx0XHR0aGlzLndpZHRoID0gd2lkdGg7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5ib3R0b20gPSBjaGFydC5jaGFydEhlaWdodCAtIGhlaWdodCAtIHRvcDtcblx0XHR0aGlzLnJpZ2h0ID0gY2hhcnQuY2hhcnRXaWR0aCAtIHdpZHRoIC0gbGVmdDtcblxuXHRcdC8vIERpcmVjdGlvbiBhZ25vc3RpYyBwcm9wZXJ0aWVzXG5cdFx0dGhpcy5sZW4gPSBtYXRoTWF4KGhvcml6ID8gd2lkdGggOiBoZWlnaHQsIDApOyAvLyBtYXRoTWF4IGZpeGVzICM5MDVcblx0XHR0aGlzLnBvcyA9IGhvcml6ID8gbGVmdCA6IHRvcDsgLy8gZGlzdGFuY2UgZnJvbSBTVkcgb3JpZ2luXG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgYWN0dWFsIGF4aXMgZXh0cmVtZXNcblx0ICovXG5cdGdldEV4dHJlbWVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0aXNMb2cgPSBheGlzLmlzTG9nO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdG1pbjogaXNMb2cgPyBjb3JyZWN0RmxvYXQobGluMmxvZyhheGlzLm1pbikpIDogYXhpcy5taW4sXG5cdFx0XHRtYXg6IGlzTG9nID8gY29ycmVjdEZsb2F0KGxpbjJsb2coYXhpcy5tYXgpKSA6IGF4aXMubWF4LFxuXHRcdFx0ZGF0YU1pbjogYXhpcy5kYXRhTWluLFxuXHRcdFx0ZGF0YU1heDogYXhpcy5kYXRhTWF4LFxuXHRcdFx0dXNlck1pbjogYXhpcy51c2VyTWluLFxuXHRcdFx0dXNlck1heDogYXhpcy51c2VyTWF4XG5cdFx0fTtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IHRoZSB6ZXJvIHBsYW5lIGVpdGhlciBiYXNlZCBvbiB6ZXJvIG9yIG9uIHRoZSBtaW4gb3IgbWF4IHZhbHVlLlxuXHQgKiBVc2VkIGluIGJhciBhbmQgYXJlYSBwbG90c1xuXHQgKi9cblx0Z2V0VGhyZXNob2xkOiBmdW5jdGlvbiAodGhyZXNob2xkKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0aXNMb2cgPSBheGlzLmlzTG9nO1xuXG5cdFx0dmFyIHJlYWxNaW4gPSBpc0xvZyA/IGxpbjJsb2coYXhpcy5taW4pIDogYXhpcy5taW4sXG5cdFx0XHRyZWFsTWF4ID0gaXNMb2cgPyBsaW4ybG9nKGF4aXMubWF4KSA6IGF4aXMubWF4O1xuXG5cdFx0aWYgKHJlYWxNaW4gPiB0aHJlc2hvbGQgfHwgdGhyZXNob2xkID09PSBudWxsKSB7XG5cdFx0XHR0aHJlc2hvbGQgPSByZWFsTWluO1xuXHRcdH0gZWxzZSBpZiAocmVhbE1heCA8IHRocmVzaG9sZCkge1xuXHRcdFx0dGhyZXNob2xkID0gcmVhbE1heDtcblx0XHR9XG5cblx0XHRyZXR1cm4gYXhpcy50cmFuc2xhdGUodGhyZXNob2xkLCAwLCAxLCAwLCAxKTtcblx0fSxcblxuXHQvKipcblx0ICogQ29tcHV0ZSBhdXRvIGFsaWdubWVudCBmb3IgdGhlIGF4aXMgbGFiZWwgYmFzZWQgb24gd2hpY2ggc2lkZSB0aGUgYXhpcyBpcyBvblxuXHQgKiBhbmQgdGhlIGdpdmVuIHJvdGF0aW9uIGZvciB0aGUgbGFiZWxcblx0ICovXG5cdGF1dG9MYWJlbEFsaWduOiBmdW5jdGlvbiAocm90YXRpb24pIHtcblx0XHR2YXIgcmV0LFxuXHRcdFx0YW5nbGUgPSAocGljayhyb3RhdGlvbiwgMCkgLSAodGhpcy5zaWRlICogOTApICsgNzIwKSAlIDM2MDtcblxuXHRcdGlmIChhbmdsZSA+IDE1ICYmIGFuZ2xlIDwgMTY1KSB7XG5cdFx0XHRyZXQgPSAncmlnaHQnO1xuXHRcdH0gZWxzZSBpZiAoYW5nbGUgPiAxOTUgJiYgYW5nbGUgPCAzNDUpIHtcblx0XHRcdHJldCA9ICdsZWZ0Jztcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0ID0gJ2NlbnRlcic7XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgdGljayBsYWJlbHMgdG8gYSBwcmVsaW1pbmFyeSBwb3NpdGlvbiB0byBnZXQgdGhlaXIgc2l6ZXNcblx0ICovXG5cdGdldE9mZnNldDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gYXhpcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRvcHRpb25zID0gYXhpcy5vcHRpb25zLFxuXHRcdFx0dGlja1Bvc2l0aW9ucyA9IGF4aXMudGlja1Bvc2l0aW9ucyxcblx0XHRcdHRpY2tzID0gYXhpcy50aWNrcyxcblx0XHRcdGhvcml6ID0gYXhpcy5ob3Jpeixcblx0XHRcdHNpZGUgPSBheGlzLnNpZGUsXG5cdFx0XHRpbnZlcnRlZFNpZGUgPSBjaGFydC5pbnZlcnRlZCA/IFsxLCAwLCAzLCAyXVtzaWRlXSA6IHNpZGUsXG5cdFx0XHRoYXNEYXRhLFxuXHRcdFx0c2hvd0F4aXMsXG5cdFx0XHR0aXRsZU9mZnNldCA9IDAsXG5cdFx0XHR0aXRsZU9mZnNldE9wdGlvbixcblx0XHRcdHRpdGxlTWFyZ2luID0gMCxcblx0XHRcdGF4aXNUaXRsZU9wdGlvbnMgPSBvcHRpb25zLnRpdGxlLFxuXHRcdFx0bGFiZWxPcHRpb25zID0gb3B0aW9ucy5sYWJlbHMsXG5cdFx0XHRsYWJlbE9mZnNldCA9IDAsIC8vIHJlc2V0XG5cdFx0XHRsYWJlbE9mZnNldFBhZGRlZCxcblx0XHRcdGF4aXNPZmZzZXQgPSBjaGFydC5heGlzT2Zmc2V0LFxuXHRcdFx0Y2xpcE9mZnNldCA9IGNoYXJ0LmNsaXBPZmZzZXQsXG5cdFx0XHRkaXJlY3Rpb25GYWN0b3IgPSBbLTEsIDEsIDEsIC0xXVtzaWRlXSxcblx0XHRcdG4sXG5cdFx0XHRpLFxuXHRcdFx0YXV0b1N0YWdnZXJMaW5lcyA9IDEsXG5cdFx0XHRtYXhTdGFnZ2VyTGluZXMgPSBwaWNrKGxhYmVsT3B0aW9ucy5tYXhTdGFnZ2VyTGluZXMsIDUpLFxuXHRcdFx0c29ydGVkUG9zaXRpb25zLFxuXHRcdFx0bGFzdFJpZ2h0LFxuXHRcdFx0b3ZlcmxhcCxcblx0XHRcdHBvcyxcblx0XHRcdGJCb3gsXG5cdFx0XHR4LFxuXHRcdFx0dyxcblx0XHRcdGxpbmVObyxcblx0XHRcdGxpbmVIZWlnaHRDb3JyZWN0aW9uO1xuXG5cdFx0Ly8gRm9yIHJldXNlIGluIEF4aXMucmVuZGVyXG5cdFx0YXhpcy5oYXNEYXRhID0gaGFzRGF0YSA9IChheGlzLmhhc1Zpc2libGVTZXJpZXMgfHwgKGRlZmluZWQoYXhpcy5taW4pICYmIGRlZmluZWQoYXhpcy5tYXgpICYmICEhdGlja1Bvc2l0aW9ucykpO1xuXHRcdGF4aXMuc2hvd0F4aXMgPSBzaG93QXhpcyA9IGhhc0RhdGEgfHwgcGljayhvcHRpb25zLnNob3dFbXB0eSwgdHJ1ZSk7XG5cblx0XHQvLyBTZXQvcmVzZXQgc3RhZ2dlckxpbmVzXG5cdFx0YXhpcy5zdGFnZ2VyTGluZXMgPSBheGlzLmhvcml6ICYmIGxhYmVsT3B0aW9ucy5zdGFnZ2VyTGluZXM7XG5cblx0XHQvLyBDcmVhdGUgdGhlIGF4aXNHcm91cCBhbmQgZ3JpZEdyb3VwIGVsZW1lbnRzIG9uIGZpcnN0IGl0ZXJhdGlvblxuXHRcdGlmICghYXhpcy5heGlzR3JvdXApIHtcblx0XHRcdGF4aXMuZ3JpZEdyb3VwID0gcmVuZGVyZXIuZygnZ3JpZCcpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiBvcHRpb25zLmdyaWRaSW5kZXggfHwgMSB9KVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0XHRheGlzLmF4aXNHcm91cCA9IHJlbmRlcmVyLmcoJ2F4aXMnKVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogb3B0aW9ucy56SW5kZXggfHwgMiB9KVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0XHRheGlzLmxhYmVsR3JvdXAgPSByZW5kZXJlci5nKCdheGlzLWxhYmVscycpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiBsYWJlbE9wdGlvbnMuekluZGV4IHx8IDcgfSlcblx0XHRcdFx0LmFkZENsYXNzKFBSRUZJWCArIGF4aXMuY29sbC50b0xvd2VyQ2FzZSgpICsgJy1sYWJlbHMnKVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0fVxuXG5cdFx0aWYgKGhhc0RhdGEgfHwgYXhpcy5pc0xpbmtlZCkge1xuXG5cdFx0XHQvLyBTZXQgdGhlIGV4cGxpY2l0IG9yIGF1dG9tYXRpYyBsYWJlbCBhbGlnbm1lbnRcblx0XHRcdGF4aXMubGFiZWxBbGlnbiA9IHBpY2sobGFiZWxPcHRpb25zLmFsaWduIHx8IGF4aXMuYXV0b0xhYmVsQWxpZ24obGFiZWxPcHRpb25zLnJvdGF0aW9uKSk7XG5cblx0XHRcdC8vIEdlbmVyYXRlIHRpY2tzXG5cdFx0XHRlYWNoKHRpY2tQb3NpdGlvbnMsIGZ1bmN0aW9uIChwb3MpIHtcblx0XHRcdFx0aWYgKCF0aWNrc1twb3NdKSB7XG5cdFx0XHRcdFx0dGlja3NbcG9zXSA9IG5ldyBUaWNrKGF4aXMsIHBvcyk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGlja3NbcG9zXS5hZGRMYWJlbCgpOyAvLyB1cGRhdGUgbGFiZWxzIGRlcGVuZGluZyBvbiB0aWNrIGludGVydmFsXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBIYW5kbGUgYXV0b21hdGljIHN0YWdnZXIgbGluZXNcblx0XHRcdGlmIChheGlzLmhvcml6ICYmICFheGlzLnN0YWdnZXJMaW5lcyAmJiBtYXhTdGFnZ2VyTGluZXMgJiYgIWxhYmVsT3B0aW9ucy5yb3RhdGlvbikge1xuXHRcdFx0XHRzb3J0ZWRQb3NpdGlvbnMgPSBheGlzLnJldmVyc2VkID8gW10uY29uY2F0KHRpY2tQb3NpdGlvbnMpLnJldmVyc2UoKSA6IHRpY2tQb3NpdGlvbnM7XG5cdFx0XHRcdHdoaWxlIChhdXRvU3RhZ2dlckxpbmVzIDwgbWF4U3RhZ2dlckxpbmVzKSB7XG5cdFx0XHRcdFx0bGFzdFJpZ2h0ID0gW107XG5cdFx0XHRcdFx0b3ZlcmxhcCA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IHNvcnRlZFBvc2l0aW9ucy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0cG9zID0gc29ydGVkUG9zaXRpb25zW2ldO1xuXHRcdFx0XHRcdFx0YkJveCA9IHRpY2tzW3Bvc10ubGFiZWwgJiYgdGlja3NbcG9zXS5sYWJlbC5nZXRCQm94KCk7XG5cdFx0XHRcdFx0XHR3ID0gYkJveCA/IGJCb3gud2lkdGggOiAwO1xuXHRcdFx0XHRcdFx0bGluZU5vID0gaSAlIGF1dG9TdGFnZ2VyTGluZXM7XG5cblx0XHRcdFx0XHRcdGlmICh3KSB7XG5cdFx0XHRcdFx0XHRcdHggPSBheGlzLnRyYW5zbGF0ZShwb3MpOyAvLyBkb24ndCBoYW5kbGUgbG9nXG5cdFx0XHRcdFx0XHRcdGlmIChsYXN0UmlnaHRbbGluZU5vXSAhPT0gVU5ERUZJTkVEICYmIHggPCBsYXN0UmlnaHRbbGluZU5vXSkge1xuXHRcdFx0XHRcdFx0XHRcdG92ZXJsYXAgPSB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdGxhc3RSaWdodFtsaW5lTm9dID0geCArIHc7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChvdmVybGFwKSB7XG5cdFx0XHRcdFx0XHRhdXRvU3RhZ2dlckxpbmVzKys7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChhdXRvU3RhZ2dlckxpbmVzID4gMSkge1xuXHRcdFx0XHRcdGF4aXMuc3RhZ2dlckxpbmVzID0gYXV0b1N0YWdnZXJMaW5lcztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cblx0XHRcdGVhY2godGlja1Bvc2l0aW9ucywgZnVuY3Rpb24gKHBvcykge1xuXHRcdFx0XHQvLyBsZWZ0IHNpZGUgbXVzdCBiZSBhbGlnbjogcmlnaHQgYW5kIHJpZ2h0IHNpZGUgbXVzdCBoYXZlIGFsaWduOiBsZWZ0IGZvciBsYWJlbHNcblx0XHRcdFx0aWYgKHNpZGUgPT09IDAgfHwgc2lkZSA9PT0gMiB8fCB7IDE6ICdsZWZ0JywgMzogJ3JpZ2h0JyB9W3NpZGVdID09PSBheGlzLmxhYmVsQWxpZ24pIHtcblxuXHRcdFx0XHRcdC8vIGdldCB0aGUgaGlnaGVzdCBvZmZzZXRcblx0XHRcdFx0XHRsYWJlbE9mZnNldCA9IG1hdGhNYXgoXG5cdFx0XHRcdFx0XHR0aWNrc1twb3NdLmdldExhYmVsU2l6ZSgpLFxuXHRcdFx0XHRcdFx0bGFiZWxPZmZzZXRcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0aWYgKGF4aXMuc3RhZ2dlckxpbmVzKSB7XG5cdFx0XHRcdGxhYmVsT2Zmc2V0ICo9IGF4aXMuc3RhZ2dlckxpbmVzO1xuXHRcdFx0XHRheGlzLmxhYmVsT2Zmc2V0ID0gbGFiZWxPZmZzZXQ7XG5cdFx0XHR9XG5cblxuXHRcdH0gZWxzZSB7IC8vIGRvZXNuJ3QgaGF2ZSBkYXRhXG5cdFx0XHRmb3IgKG4gaW4gdGlja3MpIHtcblx0XHRcdFx0dGlja3Nbbl0uZGVzdHJveSgpO1xuXHRcdFx0XHRkZWxldGUgdGlja3Nbbl07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKGF4aXNUaXRsZU9wdGlvbnMgJiYgYXhpc1RpdGxlT3B0aW9ucy50ZXh0ICYmIGF4aXNUaXRsZU9wdGlvbnMuZW5hYmxlZCAhPT0gZmFsc2UpIHtcblx0XHRcdGlmICghYXhpcy5heGlzVGl0bGUpIHtcblx0XHRcdFx0YXhpcy5heGlzVGl0bGUgPSByZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRcdGF4aXNUaXRsZU9wdGlvbnMudGV4dCxcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0YXhpc1RpdGxlT3B0aW9ucy51c2VIVE1MXG5cdFx0XHRcdClcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHpJbmRleDogNyxcblx0XHRcdFx0XHRyb3RhdGlvbjogYXhpc1RpdGxlT3B0aW9ucy5yb3RhdGlvbiB8fCAwLFxuXHRcdFx0XHRcdGFsaWduOlxuXHRcdFx0XHRcdFx0YXhpc1RpdGxlT3B0aW9ucy50ZXh0QWxpZ24gfHxcblx0XHRcdFx0XHRcdHsgbG93OiAnbGVmdCcsIG1pZGRsZTogJ2NlbnRlcicsIGhpZ2g6ICdyaWdodCcgfVtheGlzVGl0bGVPcHRpb25zLmFsaWduXVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkQ2xhc3MoUFJFRklYICsgdGhpcy5jb2xsLnRvTG93ZXJDYXNlKCkgKyAnLXRpdGxlJylcblx0XHRcdFx0LmNzcyhheGlzVGl0bGVPcHRpb25zLnN0eWxlKVxuXHRcdFx0XHQuYWRkKGF4aXMuYXhpc0dyb3VwKTtcblx0XHRcdFx0YXhpcy5heGlzVGl0bGUuaXNOZXcgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoc2hvd0F4aXMpIHtcblx0XHRcdFx0dGl0bGVPZmZzZXQgPSBheGlzLmF4aXNUaXRsZS5nZXRCQm94KClbaG9yaXogPyAnaGVpZ2h0JyA6ICd3aWR0aCddO1xuXHRcdFx0XHR0aXRsZU9mZnNldE9wdGlvbiA9IGF4aXNUaXRsZU9wdGlvbnMub2Zmc2V0O1xuXHRcdFx0XHR0aXRsZU1hcmdpbiA9IGRlZmluZWQodGl0bGVPZmZzZXRPcHRpb24pID8gMCA6IHBpY2soYXhpc1RpdGxlT3B0aW9ucy5tYXJnaW4sIGhvcml6ID8gNSA6IDEwKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gaGlkZSBvciBzaG93IHRoZSB0aXRsZSBkZXBlbmRpbmcgb24gd2hldGhlciBzaG93RW1wdHkgaXMgc2V0XG5cdFx0XHRheGlzLmF4aXNUaXRsZVtzaG93QXhpcyA/ICdzaG93JyA6ICdoaWRlJ10oKTtcblx0XHR9XG5cblx0XHQvLyBoYW5kbGUgYXV0b21hdGljIG9yIHVzZXIgc2V0IG9mZnNldFxuXHRcdGF4aXMub2Zmc2V0ID0gZGlyZWN0aW9uRmFjdG9yICogcGljayhvcHRpb25zLm9mZnNldCwgYXhpc09mZnNldFtzaWRlXSk7XG5cblx0XHRsaW5lSGVpZ2h0Q29ycmVjdGlvbiA9IHNpZGUgPT09IDIgPyBheGlzLnRpY2tCYXNlbGluZSA6IDA7XG5cdFx0bGFiZWxPZmZzZXRQYWRkZWQgPSBsYWJlbE9mZnNldCArIHRpdGxlTWFyZ2luICtcblx0XHRcdChsYWJlbE9mZnNldCAmJiAoZGlyZWN0aW9uRmFjdG9yICogKGhvcml6ID8gcGljayhsYWJlbE9wdGlvbnMueSwgYXhpcy50aWNrQmFzZWxpbmUgKyA4KSA6IGxhYmVsT3B0aW9ucy54KSAtIGxpbmVIZWlnaHRDb3JyZWN0aW9uKSk7XG5cdFx0YXhpcy5heGlzVGl0bGVNYXJnaW4gPSBwaWNrKHRpdGxlT2Zmc2V0T3B0aW9uLCBsYWJlbE9mZnNldFBhZGRlZCk7XG5cblx0XHRheGlzT2Zmc2V0W3NpZGVdID0gbWF0aE1heChcblx0XHRcdGF4aXNPZmZzZXRbc2lkZV0sXG5cdFx0XHRheGlzLmF4aXNUaXRsZU1hcmdpbiArIHRpdGxlT2Zmc2V0ICsgZGlyZWN0aW9uRmFjdG9yICogYXhpcy5vZmZzZXQsXG5cdFx0XHRsYWJlbE9mZnNldFBhZGRlZCAvLyAjMzAyN1xuXHRcdCk7XG5cdFx0Y2xpcE9mZnNldFtpbnZlcnRlZFNpZGVdID0gbWF0aE1heChjbGlwT2Zmc2V0W2ludmVydGVkU2lkZV0sIG1hdGhGbG9vcihvcHRpb25zLmxpbmVXaWR0aCAvIDIpICogMik7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgcGF0aCBmb3IgdGhlIGF4aXMgbGluZVxuXHQgKi9cblx0Z2V0TGluZVBhdGg6IGZ1bmN0aW9uIChsaW5lV2lkdGgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0b3Bwb3NpdGUgPSB0aGlzLm9wcG9zaXRlLFxuXHRcdFx0b2Zmc2V0ID0gdGhpcy5vZmZzZXQsXG5cdFx0XHRob3JpeiA9IHRoaXMuaG9yaXosXG5cdFx0XHRsaW5lTGVmdCA9IHRoaXMubGVmdCArIChvcHBvc2l0ZSA/IHRoaXMud2lkdGggOiAwKSArIG9mZnNldCxcblx0XHRcdGxpbmVUb3AgPSBjaGFydC5jaGFydEhlaWdodCAtIHRoaXMuYm90dG9tIC0gKG9wcG9zaXRlID8gdGhpcy5oZWlnaHQgOiAwKSArIG9mZnNldDtcblxuXHRcdGlmIChvcHBvc2l0ZSkge1xuXHRcdFx0bGluZVdpZHRoICo9IC0xOyAvLyBjcmlzcGlmeSB0aGUgb3RoZXIgd2F5IC0gIzE0ODAsICMxNjg3XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNoYXJ0LnJlbmRlcmVyLmNyaXNwTGluZShbXG5cdFx0XHRcdE0sXG5cdFx0XHRcdGhvcml6ID9cblx0XHRcdFx0XHR0aGlzLmxlZnQgOlxuXHRcdFx0XHRcdGxpbmVMZWZ0LFxuXHRcdFx0XHRob3JpeiA/XG5cdFx0XHRcdFx0bGluZVRvcCA6XG5cdFx0XHRcdFx0dGhpcy50b3AsXG5cdFx0XHRcdEwsXG5cdFx0XHRcdGhvcml6ID9cblx0XHRcdFx0XHRjaGFydC5jaGFydFdpZHRoIC0gdGhpcy5yaWdodCA6XG5cdFx0XHRcdFx0bGluZUxlZnQsXG5cdFx0XHRcdGhvcml6ID9cblx0XHRcdFx0XHRsaW5lVG9wIDpcblx0XHRcdFx0XHRjaGFydC5jaGFydEhlaWdodCAtIHRoaXMuYm90dG9tXG5cdFx0XHRdLCBsaW5lV2lkdGgpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBQb3NpdGlvbiB0aGUgdGl0bGVcblx0ICovXG5cdGdldFRpdGxlUG9zaXRpb246IGZ1bmN0aW9uICgpIHtcblx0XHQvLyBjb21wdXRlIGFuY2hvciBwb2ludHMgZm9yIGVhY2ggb2YgdGhlIHRpdGxlIGFsaWduIG9wdGlvbnNcblx0XHR2YXIgaG9yaXogPSB0aGlzLmhvcml6LFxuXHRcdFx0YXhpc0xlZnQgPSB0aGlzLmxlZnQsXG5cdFx0XHRheGlzVG9wID0gdGhpcy50b3AsXG5cdFx0XHRheGlzTGVuZ3RoID0gdGhpcy5sZW4sXG5cdFx0XHRheGlzVGl0bGVPcHRpb25zID0gdGhpcy5vcHRpb25zLnRpdGxlLFxuXHRcdFx0bWFyZ2luID0gaG9yaXogPyBheGlzTGVmdCA6IGF4aXNUb3AsXG5cdFx0XHRvcHBvc2l0ZSA9IHRoaXMub3Bwb3NpdGUsXG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCxcblx0XHRcdGZvbnRTaXplID0gcEludChheGlzVGl0bGVPcHRpb25zLnN0eWxlLmZvbnRTaXplIHx8IDEyKSxcblxuXHRcdFx0Ly8gdGhlIHBvc2l0aW9uIGluIHRoZSBsZW5ndGggZGlyZWN0aW9uIG9mIHRoZSBheGlzXG5cdFx0XHRhbG9uZ0F4aXMgPSB7XG5cdFx0XHRcdGxvdzogbWFyZ2luICsgKGhvcml6ID8gMCA6IGF4aXNMZW5ndGgpLFxuXHRcdFx0XHRtaWRkbGU6IG1hcmdpbiArIGF4aXNMZW5ndGggLyAyLFxuXHRcdFx0XHRoaWdoOiBtYXJnaW4gKyAoaG9yaXogPyBheGlzTGVuZ3RoIDogMClcblx0XHRcdH1bYXhpc1RpdGxlT3B0aW9ucy5hbGlnbl0sXG5cblx0XHRcdC8vIHRoZSBwb3NpdGlvbiBpbiB0aGUgcGVycGVuZGljdWxhciBkaXJlY3Rpb24gb2YgdGhlIGF4aXNcblx0XHRcdG9mZkF4aXMgPSAoaG9yaXogPyBheGlzVG9wICsgdGhpcy5oZWlnaHQgOiBheGlzTGVmdCkgK1xuXHRcdFx0XHQoaG9yaXogPyAxIDogLTEpICogLy8gaG9yaXpvbnRhbCBheGlzIHJldmVyc2VzIHRoZSBtYXJnaW5cblx0XHRcdFx0KG9wcG9zaXRlID8gLTEgOiAxKSAqIC8vIHNvIGRvZXMgb3Bwb3NpdGUgYXhlc1xuXHRcdFx0XHR0aGlzLmF4aXNUaXRsZU1hcmdpbiArXG5cdFx0XHRcdCh0aGlzLnNpZGUgPT09IDIgPyBmb250U2l6ZSA6IDApO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IGhvcml6ID9cblx0XHRcdFx0YWxvbmdBeGlzIDpcblx0XHRcdFx0b2ZmQXhpcyArIChvcHBvc2l0ZSA/IHRoaXMud2lkdGggOiAwKSArIG9mZnNldCArXG5cdFx0XHRcdFx0KGF4aXNUaXRsZU9wdGlvbnMueCB8fCAwKSwgLy8geFxuXHRcdFx0eTogaG9yaXogP1xuXHRcdFx0XHRvZmZBeGlzIC0gKG9wcG9zaXRlID8gdGhpcy5oZWlnaHQgOiAwKSArIG9mZnNldCA6XG5cdFx0XHRcdGFsb25nQXhpcyArIChheGlzVGl0bGVPcHRpb25zLnkgfHwgMCkgLy8geVxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgYXhpc1xuXHQgKi9cblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGF4aXMgPSB0aGlzLFxuXHRcdFx0aG9yaXogPSBheGlzLmhvcml6LFxuXHRcdFx0cmV2ZXJzZWQgPSBheGlzLnJldmVyc2VkLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdG9wdGlvbnMgPSBheGlzLm9wdGlvbnMsXG5cdFx0XHRpc0xvZyA9IGF4aXMuaXNMb2csXG5cdFx0XHRpc0xpbmtlZCA9IGF4aXMuaXNMaW5rZWQsXG5cdFx0XHR0aWNrUG9zaXRpb25zID0gYXhpcy50aWNrUG9zaXRpb25zLFxuXHRcdFx0c29ydGVkUG9zaXRpb25zLFxuXHRcdFx0YXhpc1RpdGxlID0gYXhpcy5heGlzVGl0bGUsXHRcdFx0XG5cdFx0XHR0aWNrcyA9IGF4aXMudGlja3MsXG5cdFx0XHRtaW5vclRpY2tzID0gYXhpcy5taW5vclRpY2tzLFxuXHRcdFx0YWx0ZXJuYXRlQmFuZHMgPSBheGlzLmFsdGVybmF0ZUJhbmRzLFxuXHRcdFx0c3RhY2tMYWJlbE9wdGlvbnMgPSBvcHRpb25zLnN0YWNrTGFiZWxzLFxuXHRcdFx0YWx0ZXJuYXRlR3JpZENvbG9yID0gb3B0aW9ucy5hbHRlcm5hdGVHcmlkQ29sb3IsXG5cdFx0XHR0aWNrbWFya09mZnNldCA9IGF4aXMudGlja21hcmtPZmZzZXQsXG5cdFx0XHRsaW5lV2lkdGggPSBvcHRpb25zLmxpbmVXaWR0aCxcblx0XHRcdGxpbmVQYXRoLFxuXHRcdFx0aGFzUmVuZGVyZWQgPSBjaGFydC5oYXNSZW5kZXJlZCxcblx0XHRcdHNsaWRlSW5UaWNrcyA9IGhhc1JlbmRlcmVkICYmIGRlZmluZWQoYXhpcy5vbGRNaW4pICYmICFpc05hTihheGlzLm9sZE1pbiksXG5cdFx0XHRoYXNEYXRhID0gYXhpcy5oYXNEYXRhLFxuXHRcdFx0c2hvd0F4aXMgPSBheGlzLnNob3dBeGlzLFxuXHRcdFx0ZnJvbSxcblx0XHRcdG92ZXJmbG93ID0gb3B0aW9ucy5sYWJlbHMub3ZlcmZsb3csXG5cdFx0XHRqdXN0aWZ5TGFiZWxzID0gYXhpcy5qdXN0aWZ5TGFiZWxzID0gaG9yaXogJiYgb3ZlcmZsb3cgIT09IGZhbHNlLFxuXHRcdFx0dG87XG5cblx0XHQvLyBSZXNldFxuXHRcdGF4aXMubGFiZWxFZGdlLmxlbmd0aCA9IDA7XG5cdFx0YXhpcy5qdXN0aWZ5VG9QbG90ID0gb3ZlcmZsb3cgPT09ICdqdXN0aWZ5JztcblxuXHRcdC8vIE1hcmsgYWxsIGVsZW1lbnRzIGluQWN0aXZlIGJlZm9yZSB3ZSBnbyBvdmVyIGFuZCBtYXJrIHRoZSBhY3RpdmUgb25lc1xuXHRcdGVhY2goW3RpY2tzLCBtaW5vclRpY2tzLCBhbHRlcm5hdGVCYW5kc10sIGZ1bmN0aW9uIChjb2xsKSB7XG5cdFx0XHR2YXIgcG9zO1xuXHRcdFx0Zm9yIChwb3MgaW4gY29sbCkge1xuXHRcdFx0XHRjb2xsW3Bvc10uaXNBY3RpdmUgPSBmYWxzZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIElmIHRoZSBzZXJpZXMgaGFzIGRhdGEgZHJhdyB0aGUgdGlja3MuIEVsc2Ugb25seSB0aGUgbGluZSBhbmQgdGl0bGVcblx0XHRpZiAoaGFzRGF0YSB8fCBpc0xpbmtlZCkge1xuXG5cdFx0XHQvLyBtaW5vciB0aWNrc1xuXHRcdFx0aWYgKGF4aXMubWlub3JUaWNrSW50ZXJ2YWwgJiYgIWF4aXMuY2F0ZWdvcmllcykge1xuXHRcdFx0XHRlYWNoKGF4aXMuZ2V0TWlub3JUaWNrUG9zaXRpb25zKCksIGZ1bmN0aW9uIChwb3MpIHtcblx0XHRcdFx0XHRpZiAoIW1pbm9yVGlja3NbcG9zXSkge1xuXHRcdFx0XHRcdFx0bWlub3JUaWNrc1twb3NdID0gbmV3IFRpY2soYXhpcywgcG9zLCAnbWlub3InKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyByZW5kZXIgbmV3IHRpY2tzIGluIG9sZCBwb3NpdGlvblxuXHRcdFx0XHRcdGlmIChzbGlkZUluVGlja3MgJiYgbWlub3JUaWNrc1twb3NdLmlzTmV3KSB7XG5cdFx0XHRcdFx0XHRtaW5vclRpY2tzW3Bvc10ucmVuZGVyKG51bGwsIHRydWUpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdG1pbm9yVGlja3NbcG9zXS5yZW5kZXIobnVsbCwgZmFsc2UsIDEpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFqb3IgdGlja3MuIFB1bGwgb3V0IHRoZSBmaXJzdCBpdGVtIGFuZCByZW5kZXIgaXQgbGFzdCBzbyB0aGF0XG5cdFx0XHQvLyB3ZSBjYW4gZ2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgbmVpZ2hib3VyIGxhYmVsLiAjODA4LlxuXHRcdFx0aWYgKHRpY2tQb3NpdGlvbnMubGVuZ3RoKSB7IC8vICMxMzAwXG5cdFx0XHRcdHNvcnRlZFBvc2l0aW9ucyA9IHRpY2tQb3NpdGlvbnMuc2xpY2UoKTtcblx0XHRcdFx0aWYgKChob3JpeiAmJiByZXZlcnNlZCkgfHwgKCFob3JpeiAmJiAhcmV2ZXJzZWQpKSB7XG5cdFx0XHRcdFx0c29ydGVkUG9zaXRpb25zLnJldmVyc2UoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoanVzdGlmeUxhYmVscykge1xuXHRcdFx0XHRcdHNvcnRlZFBvc2l0aW9ucyA9IHNvcnRlZFBvc2l0aW9ucy5zbGljZSgxKS5jb25jYXQoW3NvcnRlZFBvc2l0aW9uc1swXV0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVhY2goc29ydGVkUG9zaXRpb25zLCBmdW5jdGlvbiAocG9zLCBpKSB7XG5cblx0XHRcdFx0XHQvLyBSZW9yZ2FuaXplIHRoZSBpbmRpY2VzXG5cdFx0XHRcdFx0aWYgKGp1c3RpZnlMYWJlbHMpIHtcblx0XHRcdFx0XHRcdGkgPSAoaSA9PT0gc29ydGVkUG9zaXRpb25zLmxlbmd0aCAtIDEpID8gMCA6IGkgKyAxO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIGxpbmtlZCBheGVzIG5lZWQgYW4gZXh0cmEgY2hlY2sgdG8gZmluZCBvdXQgaWZcblx0XHRcdFx0XHRpZiAoIWlzTGlua2VkIHx8IChwb3MgPj0gYXhpcy5taW4gJiYgcG9zIDw9IGF4aXMubWF4KSkge1xuXG5cdFx0XHRcdFx0XHRpZiAoIXRpY2tzW3Bvc10pIHtcblx0XHRcdFx0XHRcdFx0dGlja3NbcG9zXSA9IG5ldyBUaWNrKGF4aXMsIHBvcyk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIHJlbmRlciBuZXcgdGlja3MgaW4gb2xkIHBvc2l0aW9uXG5cdFx0XHRcdFx0XHRpZiAoc2xpZGVJblRpY2tzICYmIHRpY2tzW3Bvc10uaXNOZXcpIHtcblx0XHRcdFx0XHRcdFx0dGlja3NbcG9zXS5yZW5kZXIoaSwgdHJ1ZSwgMC4xKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0dGlja3NbcG9zXS5yZW5kZXIoaSk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHQvLyBJbiBhIGNhdGVnb3JpemVkIGF4aXMsIHRoZSB0aWNrIG1hcmtzIGFyZSBkaXNwbGF5ZWQgYmV0d2VlbiBsYWJlbHMuIFNvXG5cdFx0XHRcdC8vIHdlIG5lZWQgdG8gYWRkIGEgdGljayBtYXJrIGFuZCBncmlkIGxpbmUgYXQgdGhlIGxlZnQgZWRnZSBvZiB0aGUgWCBheGlzLlxuXHRcdFx0XHRpZiAodGlja21hcmtPZmZzZXQgJiYgYXhpcy5taW4gPT09IDApIHtcblx0XHRcdFx0XHRpZiAoIXRpY2tzWy0xXSkge1xuXHRcdFx0XHRcdFx0dGlja3NbLTFdID0gbmV3IFRpY2soYXhpcywgLTEsIG51bGwsIHRydWUpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aWNrc1stMV0ucmVuZGVyKC0xKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cblx0XHRcdC8vIGFsdGVybmF0ZSBncmlkIGNvbG9yXG5cdFx0XHRpZiAoYWx0ZXJuYXRlR3JpZENvbG9yKSB7XG5cdFx0XHRcdGVhY2godGlja1Bvc2l0aW9ucywgZnVuY3Rpb24gKHBvcywgaSkge1xuXHRcdFx0XHRcdGlmIChpICUgMiA9PT0gMCAmJiBwb3MgPCBheGlzLm1heCkge1xuXHRcdFx0XHRcdFx0aWYgKCFhbHRlcm5hdGVCYW5kc1twb3NdKSB7XG5cdFx0XHRcdFx0XHRcdGFsdGVybmF0ZUJhbmRzW3Bvc10gPSBuZXcgSGlnaGNoYXJ0cy5QbG90TGluZU9yQmFuZChheGlzKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGZyb20gPSBwb3MgKyB0aWNrbWFya09mZnNldDsgLy8gIzk0OVxuXHRcdFx0XHRcdFx0dG8gPSB0aWNrUG9zaXRpb25zW2kgKyAxXSAhPT0gVU5ERUZJTkVEID8gdGlja1Bvc2l0aW9uc1tpICsgMV0gKyB0aWNrbWFya09mZnNldCA6IGF4aXMubWF4O1xuXHRcdFx0XHRcdFx0YWx0ZXJuYXRlQmFuZHNbcG9zXS5vcHRpb25zID0ge1xuXHRcdFx0XHRcdFx0XHRmcm9tOiBpc0xvZyA/IGxpbjJsb2coZnJvbSkgOiBmcm9tLFxuXHRcdFx0XHRcdFx0XHR0bzogaXNMb2cgPyBsaW4ybG9nKHRvKSA6IHRvLFxuXHRcdFx0XHRcdFx0XHRjb2xvcjogYWx0ZXJuYXRlR3JpZENvbG9yXG5cdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0YWx0ZXJuYXRlQmFuZHNbcG9zXS5yZW5kZXIoKTtcblx0XHRcdFx0XHRcdGFsdGVybmF0ZUJhbmRzW3Bvc10uaXNBY3RpdmUgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGN1c3RvbSBwbG90IGxpbmVzIGFuZCBiYW5kc1xuXHRcdFx0aWYgKCFheGlzLl9hZGRlZFBsb3RMQikgeyAvLyBvbmx5IGZpcnN0IHRpbWVcblx0XHRcdFx0ZWFjaCgob3B0aW9ucy5wbG90TGluZXMgfHwgW10pLmNvbmNhdChvcHRpb25zLnBsb3RCYW5kcyB8fCBbXSksIGZ1bmN0aW9uIChwbG90TGluZU9wdGlvbnMpIHtcblx0XHRcdFx0XHRheGlzLmFkZFBsb3RCYW5kT3JMaW5lKHBsb3RMaW5lT3B0aW9ucyk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRheGlzLl9hZGRlZFBsb3RMQiA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHR9IC8vIGVuZCBpZiBoYXNEYXRhXG5cblx0XHQvLyBSZW1vdmUgaW5hY3RpdmUgdGlja3Ncblx0XHRlYWNoKFt0aWNrcywgbWlub3JUaWNrcywgYWx0ZXJuYXRlQmFuZHNdLCBmdW5jdGlvbiAoY29sbCkge1xuXHRcdFx0dmFyIHBvcyxcblx0XHRcdFx0aSxcblx0XHRcdFx0Zm9yRGVzdHJ1Y3Rpb24gPSBbXSxcblx0XHRcdFx0ZGVsYXkgPSBnbG9iYWxBbmltYXRpb24gPyBnbG9iYWxBbmltYXRpb24uZHVyYXRpb24gfHwgNTAwIDogMCxcblx0XHRcdFx0ZGVzdHJveUluYWN0aXZlSXRlbXMgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0aSA9IGZvckRlc3RydWN0aW9uLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdFx0XHQvLyBXaGVuIHJlc2l6aW5nIHJhcGlkbHksIHRoZSBzYW1lIGl0ZW1zIG1heSBiZSBkZXN0cm95ZWQgaW4gZGlmZmVyZW50IHRpbWVvdXRzLFxuXHRcdFx0XHRcdFx0Ly8gb3IgdGhlIG1heSBiZSByZWFjdGl2YXRlZFxuXHRcdFx0XHRcdFx0aWYgKGNvbGxbZm9yRGVzdHJ1Y3Rpb25baV1dICYmICFjb2xsW2ZvckRlc3RydWN0aW9uW2ldXS5pc0FjdGl2ZSkge1xuXHRcdFx0XHRcdFx0XHRjb2xsW2ZvckRlc3RydWN0aW9uW2ldXS5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBjb2xsW2ZvckRlc3RydWN0aW9uW2ldXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fTtcblxuXHRcdFx0Zm9yIChwb3MgaW4gY29sbCkge1xuXG5cdFx0XHRcdGlmICghY29sbFtwb3NdLmlzQWN0aXZlKSB7XG5cdFx0XHRcdFx0Ly8gUmVuZGVyIHRvIHplcm8gb3BhY2l0eVxuXHRcdFx0XHRcdGNvbGxbcG9zXS5yZW5kZXIocG9zLCBmYWxzZSwgMCk7XG5cdFx0XHRcdFx0Y29sbFtwb3NdLmlzQWN0aXZlID0gZmFsc2U7XG5cdFx0XHRcdFx0Zm9yRGVzdHJ1Y3Rpb24ucHVzaChwb3MpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFdoZW4gdGhlIG9iamVjdHMgYXJlIGZpbmlzaGVkIGZhZGluZyBvdXQsIGRlc3Ryb3kgdGhlbVxuXHRcdFx0aWYgKGNvbGwgPT09IGFsdGVybmF0ZUJhbmRzIHx8ICFjaGFydC5oYXNSZW5kZXJlZCB8fCAhZGVsYXkpIHtcblx0XHRcdFx0ZGVzdHJveUluYWN0aXZlSXRlbXMoKTtcblx0XHRcdH0gZWxzZSBpZiAoZGVsYXkpIHtcblx0XHRcdFx0c2V0VGltZW91dChkZXN0cm95SW5hY3RpdmVJdGVtcywgZGVsYXkpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gU3RhdGljIGl0ZW1zLiBBcyB0aGUgYXhpcyBncm91cCBpcyBjbGVhcmVkIG9uIHN1YnNlcXVlbnQgY2FsbHNcblx0XHQvLyB0byByZW5kZXIsIHRoZXNlIGl0ZW1zIGFyZSBhZGRlZCBvdXRzaWRlIHRoZSBncm91cC5cblx0XHQvLyBheGlzIGxpbmVcblx0XHRpZiAobGluZVdpZHRoKSB7XG5cdFx0XHRsaW5lUGF0aCA9IGF4aXMuZ2V0TGluZVBhdGgobGluZVdpZHRoKTtcblx0XHRcdGlmICghYXhpcy5heGlzTGluZSkge1xuXHRcdFx0XHRheGlzLmF4aXNMaW5lID0gcmVuZGVyZXIucGF0aChsaW5lUGF0aClcblx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRzdHJva2U6IG9wdGlvbnMubGluZUNvbG9yLFxuXHRcdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IGxpbmVXaWR0aCxcblx0XHRcdFx0XHRcdHpJbmRleDogN1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmFkZChheGlzLmF4aXNHcm91cCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRheGlzLmF4aXNMaW5lLmFuaW1hdGUoeyBkOiBsaW5lUGF0aCB9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gc2hvdyBvciBoaWRlIHRoZSBsaW5lIGRlcGVuZGluZyBvbiBvcHRpb25zLnNob3dFbXB0eVxuXHRcdFx0YXhpcy5heGlzTGluZVtzaG93QXhpcyA/ICdzaG93JyA6ICdoaWRlJ10oKTtcblx0XHR9XG5cblx0XHRpZiAoYXhpc1RpdGxlICYmIHNob3dBeGlzKSB7XG5cblx0XHRcdGF4aXNUaXRsZVtheGlzVGl0bGUuaXNOZXcgPyAnYXR0cicgOiAnYW5pbWF0ZSddKFxuXHRcdFx0XHRheGlzLmdldFRpdGxlUG9zaXRpb24oKVxuXHRcdFx0KTtcblx0XHRcdGF4aXNUaXRsZS5pc05ldyA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIFN0YWNrZWQgdG90YWxzOlxuXHRcdGlmIChzdGFja0xhYmVsT3B0aW9ucyAmJiBzdGFja0xhYmVsT3B0aW9ucy5lbmFibGVkKSB7XG5cdFx0XHRheGlzLnJlbmRlclN0YWNrVG90YWxzKCk7XG5cdFx0fVxuXHRcdC8vIEVuZCBzdGFja2VkIHRvdGFsc1xuXG5cdFx0YXhpcy5pc0RpcnR5ID0gZmFsc2U7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlZHJhdyB0aGUgYXhpcyB0byByZWZsZWN0IGNoYW5nZXMgaW4gdGhlIGRhdGEgb3IgYXhpcyBleHRyZW1lc1xuXHQgKi9cblx0cmVkcmF3OiBmdW5jdGlvbiAoKSB7XG5cdFx0XG5cdFx0Ly8gcmVuZGVyIHRoZSBheGlzXG5cdFx0dGhpcy5yZW5kZXIoKTtcblxuXHRcdC8vIG1vdmUgcGxvdCBsaW5lcyBhbmQgYmFuZHNcblx0XHRlYWNoKHRoaXMucGxvdExpbmVzQW5kQmFuZHMsIGZ1bmN0aW9uIChwbG90TGluZSkge1xuXHRcdFx0cGxvdExpbmUucmVuZGVyKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBtYXJrIGFzc29jaWF0ZWQgc2VyaWVzIGFzIGRpcnR5IGFuZCByZWFkeSBmb3IgcmVkcmF3XG5cdFx0ZWFjaCh0aGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0c2VyaWVzLmlzRGlydHkgPSB0cnVlO1xuXHRcdH0pO1xuXG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3Ryb3lzIGFuIEF4aXMgaW5zdGFuY2UuXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoa2VlcEV2ZW50cykge1xuXHRcdHZhciBheGlzID0gdGhpcyxcblx0XHRcdHN0YWNrcyA9IGF4aXMuc3RhY2tzLFxuXHRcdFx0c3RhY2tLZXksXG5cdFx0XHRwbG90TGluZXNBbmRCYW5kcyA9IGF4aXMucGxvdExpbmVzQW5kQmFuZHMsXG5cdFx0XHRpO1xuXG5cdFx0Ly8gUmVtb3ZlIHRoZSBldmVudHNcblx0XHRpZiAoIWtlZXBFdmVudHMpIHtcblx0XHRcdHJlbW92ZUV2ZW50KGF4aXMpO1xuXHRcdH1cblxuXHRcdC8vIERlc3Ryb3kgZWFjaCBzdGFjayB0b3RhbFxuXHRcdGZvciAoc3RhY2tLZXkgaW4gc3RhY2tzKSB7XG5cdFx0XHRkZXN0cm95T2JqZWN0UHJvcGVydGllcyhzdGFja3Nbc3RhY2tLZXldKTtcblxuXHRcdFx0c3RhY2tzW3N0YWNrS2V5XSA9IG51bGw7XG5cdFx0fVxuXG5cdFx0Ly8gRGVzdHJveSBjb2xsZWN0aW9uc1xuXHRcdGVhY2goW2F4aXMudGlja3MsIGF4aXMubWlub3JUaWNrcywgYXhpcy5hbHRlcm5hdGVCYW5kc10sIGZ1bmN0aW9uIChjb2xsKSB7XG5cdFx0XHRkZXN0cm95T2JqZWN0UHJvcGVydGllcyhjb2xsKTtcblx0XHR9KTtcblx0XHRpID0gcGxvdExpbmVzQW5kQmFuZHMubGVuZ3RoO1xuXHRcdHdoaWxlIChpLS0pIHsgLy8gIzE5NzVcblx0XHRcdHBsb3RMaW5lc0FuZEJhbmRzW2ldLmRlc3Ryb3koKTtcblx0XHR9XG5cblx0XHQvLyBEZXN0cm95IGxvY2FsIHZhcmlhYmxlc1xuXHRcdGVhY2goWydzdGFja1RvdGFsR3JvdXAnLCAnYXhpc0xpbmUnLCAnYXhpc1RpdGxlJywgJ2F4aXNHcm91cCcsICdjcm9zcycsICdncmlkR3JvdXAnLCAnbGFiZWxHcm91cCddLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0aWYgKGF4aXNbcHJvcF0pIHtcblx0XHRcdFx0YXhpc1twcm9wXSA9IGF4aXNbcHJvcF0uZGVzdHJveSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gRGVzdHJveSBjcm9zc2hhaXJcblx0XHRpZiAodGhpcy5jcm9zcykge1xuXHRcdFx0dGhpcy5jcm9zcy5kZXN0cm95KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBjcm9zc2hhaXJcblx0ICovXG5cdGRyYXdDcm9zc2hhaXI6IGZ1bmN0aW9uIChlLCBwb2ludCkge1xuXHRcdGlmICghdGhpcy5jcm9zc2hhaXIpIHsgcmV0dXJuOyB9Ly8gRG8gbm90IGRyYXcgY3Jvc3NoYWlycyBpZiB5b3UgZG9uJ3QgaGF2ZSB0b28uXG5cblx0XHRpZiAoKGRlZmluZWQocG9pbnQpIHx8ICFwaWNrKHRoaXMuY3Jvc3NoYWlyLnNuYXAsIHRydWUpKSA9PT0gZmFsc2UpIHtcblx0XHRcdHRoaXMuaGlkZUNyb3NzaGFpcigpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBwYXRoLFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMuY3Jvc3NoYWlyLFxuXHRcdFx0YW5pbWF0aW9uID0gb3B0aW9ucy5hbmltYXRpb24sXG5cdFx0XHRwb3M7XG5cblx0XHQvLyBHZXQgdGhlIHBhdGhcblx0XHRpZiAoIXBpY2sob3B0aW9ucy5zbmFwLCB0cnVlKSkge1xuXHRcdFx0cG9zID0gKHRoaXMuaG9yaXogPyBlLmNoYXJ0WCAtIHRoaXMucG9zIDogdGhpcy5sZW4gLSBlLmNoYXJ0WSArIHRoaXMucG9zKTtcblx0XHR9IGVsc2UgaWYgKGRlZmluZWQocG9pbnQpKSB7XG5cdFx0XHQvKmpzbGludCBlcWVxOiB0cnVlKi9cblx0XHRcdHBvcyA9ICh0aGlzLmNoYXJ0LmludmVydGVkICE9IHRoaXMuaG9yaXopID8gcG9pbnQucGxvdFggOiB0aGlzLmxlbiAtIHBvaW50LnBsb3RZO1xuXHRcdFx0Lypqc2xpbnQgZXFlcTogZmFsc2UqL1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLmlzUmFkaWFsKSB7XG5cdFx0XHRwYXRoID0gdGhpcy5nZXRQbG90TGluZVBhdGgodGhpcy5pc1hBeGlzID8gcG9pbnQueCA6IHBpY2socG9pbnQuc3RhY2tZLCBwb2ludC55KSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBhdGggPSB0aGlzLmdldFBsb3RMaW5lUGF0aChudWxsLCBudWxsLCBudWxsLCBudWxsLCBwb3MpO1xuXHRcdH1cblxuXHRcdGlmIChwYXRoID09PSBudWxsKSB7XG5cdFx0XHR0aGlzLmhpZGVDcm9zc2hhaXIoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEcmF3IHRoZSBjcm9zc1xuXHRcdGlmICh0aGlzLmNyb3NzKSB7XG5cdFx0XHR0aGlzLmNyb3NzXG5cdFx0XHRcdC5hdHRyKHsgdmlzaWJpbGl0eTogVklTSUJMRSB9KVthbmltYXRpb24gPyAnYW5pbWF0ZScgOiAnYXR0ciddKHsgZDogcGF0aCB9LCBhbmltYXRpb24pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR2YXIgYXR0cmlicyA9IHtcblx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IG9wdGlvbnMud2lkdGggfHwgMSxcblx0XHRcdFx0c3Ryb2tlOiBvcHRpb25zLmNvbG9yIHx8ICcjQzBDMEMwJyxcblx0XHRcdFx0ekluZGV4OiBvcHRpb25zLnpJbmRleCB8fCAyXG5cdFx0XHR9O1xuXHRcdFx0aWYgKG9wdGlvbnMuZGFzaFN0eWxlKSB7XG5cdFx0XHRcdGF0dHJpYnMuZGFzaHN0eWxlID0gb3B0aW9ucy5kYXNoU3R5bGU7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmNyb3NzID0gdGhpcy5jaGFydC5yZW5kZXJlci5wYXRoKHBhdGgpLmF0dHIoYXR0cmlicykuYWRkKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKlx0SGlkZSB0aGUgY3Jvc3NoYWlyLlxuXHQgKi9cblx0aGlkZUNyb3NzaGFpcjogZnVuY3Rpb24gKCkge1xuXHRcdGlmICh0aGlzLmNyb3NzKSB7XG5cdFx0XHR0aGlzLmNyb3NzLmhpZGUoKTtcblx0XHR9XG5cdH1cbn07IC8vIGVuZCBBeGlzXG5cbmV4dGVuZChBeGlzLnByb3RvdHlwZSwgQXhpc1Bsb3RMaW5lT3JCYW5kRXh0ZW5zaW9uKTtcblxuLyoqXG4gKiBTZXQgdGhlIHRpY2sgcG9zaXRpb25zIHRvIGEgdGltZSB1bml0IHRoYXQgbWFrZXMgc2Vuc2UsIGZvciBleGFtcGxlXG4gKiBvbiB0aGUgZmlyc3Qgb2YgZWFjaCBtb250aCBvciBvbiBldmVyeSBNb25kYXkuIFJldHVybiBhbiBhcnJheVxuICogd2l0aCB0aGUgdGltZSBwb3NpdGlvbnMuIFVzZWQgaW4gZGF0ZXRpbWUgYXhlcyBhcyB3ZWxsIGFzIGZvciBncm91cGluZ1xuICogZGF0YSBvbiBhIGRhdGV0aW1lIGF4aXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG5vcm1hbGl6ZWRJbnRlcnZhbCBUaGUgaW50ZXJ2YWwgaW4gYXhpcyB2YWx1ZXMgKG1zKSBhbmQgdGhlIGNvdW50XG4gKiBAcGFyYW0ge051bWJlcn0gbWluIFRoZSBtaW5pbXVtIGluIGF4aXMgdmFsdWVzXG4gKiBAcGFyYW0ge051bWJlcn0gbWF4IFRoZSBtYXhpbXVtIGluIGF4aXMgdmFsdWVzXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhcnRPZldlZWtcbiAqL1xuQXhpcy5wcm90b3R5cGUuZ2V0VGltZVRpY2tzID0gZnVuY3Rpb24gKG5vcm1hbGl6ZWRJbnRlcnZhbCwgbWluLCBtYXgsIHN0YXJ0T2ZXZWVrKSB7XG5cdHZhciB0aWNrUG9zaXRpb25zID0gW10sXG5cdFx0aSxcblx0XHRoaWdoZXJSYW5rcyA9IHt9LFxuXHRcdHVzZVVUQyA9IGRlZmF1bHRPcHRpb25zLmdsb2JhbC51c2VVVEMsXG5cdFx0bWluWWVhciwgLy8gdXNlZCBpbiBtb250aHMgYW5kIHllYXJzIGFzIGEgYmFzaXMgZm9yIERhdGUuVVRDKClcblx0XHRtaW5EYXRlID0gbmV3IERhdGUobWluIC0gdGltZXpvbmVPZmZzZXQpLFxuXHRcdGludGVydmFsID0gbm9ybWFsaXplZEludGVydmFsLnVuaXRSYW5nZSxcblx0XHRjb3VudCA9IG5vcm1hbGl6ZWRJbnRlcnZhbC5jb3VudDtcblxuXHRpZiAoZGVmaW5lZChtaW4pKSB7IC8vICMxMzAwXG5cdFx0aWYgKGludGVydmFsID49IHRpbWVVbml0cy5zZWNvbmQpIHsgLy8gc2Vjb25kXG5cdFx0XHRtaW5EYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcblx0XHRcdG1pbkRhdGUuc2V0U2Vjb25kcyhpbnRlcnZhbCA+PSB0aW1lVW5pdHMubWludXRlID8gMCA6XG5cdFx0XHRcdGNvdW50ICogbWF0aEZsb29yKG1pbkRhdGUuZ2V0U2Vjb25kcygpIC8gY291bnQpKTtcblx0XHR9XG5cdFxuXHRcdGlmIChpbnRlcnZhbCA+PSB0aW1lVW5pdHMubWludXRlKSB7IC8vIG1pbnV0ZVxuXHRcdFx0bWluRGF0ZVtzZXRNaW51dGVzXShpbnRlcnZhbCA+PSB0aW1lVW5pdHMuaG91ciA/IDAgOlxuXHRcdFx0XHRjb3VudCAqIG1hdGhGbG9vcihtaW5EYXRlW2dldE1pbnV0ZXNdKCkgLyBjb3VudCkpO1xuXHRcdH1cblx0XG5cdFx0aWYgKGludGVydmFsID49IHRpbWVVbml0cy5ob3VyKSB7IC8vIGhvdXJcblx0XHRcdG1pbkRhdGVbc2V0SG91cnNdKGludGVydmFsID49IHRpbWVVbml0cy5kYXkgPyAwIDpcblx0XHRcdFx0Y291bnQgKiBtYXRoRmxvb3IobWluRGF0ZVtnZXRIb3Vyc10oKSAvIGNvdW50KSk7XG5cdFx0fVxuXHRcblx0XHRpZiAoaW50ZXJ2YWwgPj0gdGltZVVuaXRzLmRheSkgeyAvLyBkYXlcblx0XHRcdG1pbkRhdGVbc2V0RGF0ZV0oaW50ZXJ2YWwgPj0gdGltZVVuaXRzLm1vbnRoID8gMSA6XG5cdFx0XHRcdGNvdW50ICogbWF0aEZsb29yKG1pbkRhdGVbZ2V0RGF0ZV0oKSAvIGNvdW50KSk7XG5cdFx0fVxuXHRcblx0XHRpZiAoaW50ZXJ2YWwgPj0gdGltZVVuaXRzLm1vbnRoKSB7IC8vIG1vbnRoXG5cdFx0XHRtaW5EYXRlW3NldE1vbnRoXShpbnRlcnZhbCA+PSB0aW1lVW5pdHMueWVhciA/IDAgOlxuXHRcdFx0XHRjb3VudCAqIG1hdGhGbG9vcihtaW5EYXRlW2dldE1vbnRoXSgpIC8gY291bnQpKTtcblx0XHRcdG1pblllYXIgPSBtaW5EYXRlW2dldEZ1bGxZZWFyXSgpO1xuXHRcdH1cblx0XG5cdFx0aWYgKGludGVydmFsID49IHRpbWVVbml0cy55ZWFyKSB7IC8vIHllYXJcblx0XHRcdG1pblllYXIgLT0gbWluWWVhciAlIGNvdW50O1xuXHRcdFx0bWluRGF0ZVtzZXRGdWxsWWVhcl0obWluWWVhcik7XG5cdFx0fVxuXHRcblx0XHQvLyB3ZWVrIGlzIGEgc3BlY2lhbCBjYXNlIHRoYXQgcnVucyBvdXRzaWRlIHRoZSBoaWVyYXJjaHlcblx0XHRpZiAoaW50ZXJ2YWwgPT09IHRpbWVVbml0cy53ZWVrKSB7XG5cdFx0XHQvLyBnZXQgc3RhcnQgb2YgY3VycmVudCB3ZWVrLCBpbmRlcGVuZGVudCBvZiBjb3VudFxuXHRcdFx0bWluRGF0ZVtzZXREYXRlXShtaW5EYXRlW2dldERhdGVdKCkgLSBtaW5EYXRlW2dldERheV0oKSArXG5cdFx0XHRcdHBpY2soc3RhcnRPZldlZWssIDEpKTtcblx0XHR9XG5cdFxuXHRcblx0XHQvLyBnZXQgdGljayBwb3NpdGlvbnNcblx0XHRpID0gMTtcblx0XHRpZiAodGltZXpvbmVPZmZzZXQpIHtcblx0XHRcdG1pbkRhdGUgPSBuZXcgRGF0ZShtaW5EYXRlLmdldFRpbWUoKSArIHRpbWV6b25lT2Zmc2V0KTtcblx0XHR9XG5cdFx0bWluWWVhciA9IG1pbkRhdGVbZ2V0RnVsbFllYXJdKCk7XG5cdFx0dmFyIHRpbWUgPSBtaW5EYXRlLmdldFRpbWUoKSxcblx0XHRcdG1pbk1vbnRoID0gbWluRGF0ZVtnZXRNb250aF0oKSxcblx0XHRcdG1pbkRhdGVEYXRlID0gbWluRGF0ZVtnZXREYXRlXSgpLFxuXHRcdFx0bG9jYWxUaW1lem9uZU9mZnNldCA9ICh0aW1lVW5pdHMuZGF5ICsgXG5cdFx0XHRcdFx0KHVzZVVUQyA/IHRpbWV6b25lT2Zmc2V0IDogbWluRGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpICogNjAgKiAxMDAwKVxuXHRcdFx0XHQpICUgdGltZVVuaXRzLmRheTsgLy8gIzk1MCwgIzMzNTlcblx0XG5cdFx0Ly8gaXRlcmF0ZSBhbmQgYWRkIHRpY2sgcG9zaXRpb25zIGF0IGFwcHJvcHJpYXRlIHZhbHVlc1xuXHRcdHdoaWxlICh0aW1lIDwgbWF4KSB7XG5cdFx0XHR0aWNrUG9zaXRpb25zLnB1c2godGltZSk7XG5cdFxuXHRcdFx0Ly8gaWYgdGhlIGludGVydmFsIGlzIHllYXJzLCB1c2UgRGF0ZS5VVEMgdG8gaW5jcmVhc2UgeWVhcnNcblx0XHRcdGlmIChpbnRlcnZhbCA9PT0gdGltZVVuaXRzLnllYXIpIHtcblx0XHRcdFx0dGltZSA9IG1ha2VUaW1lKG1pblllYXIgKyBpICogY291bnQsIDApO1xuXHRcblx0XHRcdC8vIGlmIHRoZSBpbnRlcnZhbCBpcyBtb250aHMsIHVzZSBEYXRlLlVUQyB0byBpbmNyZWFzZSBtb250aHNcblx0XHRcdH0gZWxzZSBpZiAoaW50ZXJ2YWwgPT09IHRpbWVVbml0cy5tb250aCkge1xuXHRcdFx0XHR0aW1lID0gbWFrZVRpbWUobWluWWVhciwgbWluTW9udGggKyBpICogY291bnQpO1xuXHRcblx0XHRcdC8vIGlmIHdlJ3JlIHVzaW5nIGdsb2JhbCB0aW1lLCB0aGUgaW50ZXJ2YWwgaXMgbm90IGZpeGVkIGFzIGl0IGp1bXBzXG5cdFx0XHQvLyBvbmUgaG91ciBhdCB0aGUgRFNUIGNyb3Nzb3ZlclxuXHRcdFx0fSBlbHNlIGlmICghdXNlVVRDICYmIChpbnRlcnZhbCA9PT0gdGltZVVuaXRzLmRheSB8fCBpbnRlcnZhbCA9PT0gdGltZVVuaXRzLndlZWspKSB7XG5cdFx0XHRcdHRpbWUgPSBtYWtlVGltZShtaW5ZZWFyLCBtaW5Nb250aCwgbWluRGF0ZURhdGUgK1xuXHRcdFx0XHRcdGkgKiBjb3VudCAqIChpbnRlcnZhbCA9PT0gdGltZVVuaXRzLmRheSA/IDEgOiA3KSk7XG5cdFxuXHRcdFx0Ly8gZWxzZSwgdGhlIGludGVydmFsIGlzIGZpeGVkIGFuZCB3ZSB1c2Ugc2ltcGxlIGFkZGl0aW9uXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aW1lICs9IGludGVydmFsICogY291bnQ7XG5cdFx0XHR9XG5cdFxuXHRcdFx0aSsrO1xuXHRcdH1cblx0XG5cdFx0Ly8gcHVzaCB0aGUgbGFzdCB0aW1lXG5cdFx0dGlja1Bvc2l0aW9ucy5wdXNoKHRpbWUpO1xuXG5cblx0XHQvLyBtYXJrIG5ldyBkYXlzIGlmIHRoZSB0aW1lIGlzIGRpdmlkaWJsZSBieSBkYXkgKCMxNjQ5LCAjMTc2MClcblx0XHRlYWNoKGdyZXAodGlja1Bvc2l0aW9ucywgZnVuY3Rpb24gKHRpbWUpIHtcblx0XHRcdHJldHVybiBpbnRlcnZhbCA8PSB0aW1lVW5pdHMuaG91ciAmJiB0aW1lICUgdGltZVVuaXRzLmRheSA9PT0gbG9jYWxUaW1lem9uZU9mZnNldDtcblx0XHR9KSwgZnVuY3Rpb24gKHRpbWUpIHtcblx0XHRcdGhpZ2hlclJhbmtzW3RpbWVdID0gJ2RheSc7XG5cdFx0fSk7XG5cdH1cblxuXG5cdC8vIHJlY29yZCBpbmZvcm1hdGlvbiBvbiB0aGUgY2hvc2VuIHVuaXQgLSBmb3IgZHluYW1pYyBsYWJlbCBmb3JtYXR0ZXJcblx0dGlja1Bvc2l0aW9ucy5pbmZvID0gZXh0ZW5kKG5vcm1hbGl6ZWRJbnRlcnZhbCwge1xuXHRcdGhpZ2hlclJhbmtzOiBoaWdoZXJSYW5rcyxcblx0XHR0b3RhbFJhbmdlOiBpbnRlcnZhbCAqIGNvdW50XG5cdH0pO1xuXG5cdHJldHVybiB0aWNrUG9zaXRpb25zO1xufTtcblxuLyoqXG4gKiBHZXQgYSBub3JtYWxpemVkIHRpY2sgaW50ZXJ2YWwgZm9yIGRhdGVzLiBSZXR1cm5zIGEgY29uZmlndXJhdGlvbiBvYmplY3Qgd2l0aFxuICogdW5pdCByYW5nZSAoaW50ZXJ2YWwpLCBjb3VudCBhbmQgbmFtZS4gVXNlZCB0byBwcmVwYXJlIGRhdGEgZm9yIGdldFRpbWVUaWNrcy4gXG4gKiBQcmV2aW91c2x5IHRoaXMgbG9naWMgd2FzIHBhcnQgb2YgZ2V0VGltZVRpY2tzLCBidXQgYXMgZ2V0VGltZVRpY2tzIG5vdyBydW5zXG4gKiBvZiBzZWdtZW50cyBpbiBzdG9jayBjaGFydHMsIHRoZSBub3JtYWxpemluZyBsb2dpYyB3YXMgZXh0cmFjdGVkIGluIG9yZGVyIHRvIFxuICogcHJldmVudCBpdCBmb3IgcnVubmluZyBvdmVyIGFnYWluIGZvciBlYWNoIHNlZ21lbnQgaGF2aW5nIHRoZSBzYW1lIGludGVydmFsLiBcbiAqICM2NjIsICM2OTcuXG4gKi9cbkF4aXMucHJvdG90eXBlLm5vcm1hbGl6ZVRpbWVUaWNrSW50ZXJ2YWwgPSBmdW5jdGlvbiAodGlja0ludGVydmFsLCB1bml0c09wdGlvbikge1xuXHR2YXIgdW5pdHMgPSB1bml0c09wdGlvbiB8fCBbW1xuXHRcdFx0XHQnbWlsbGlzZWNvbmQnLCAvLyB1bml0IG5hbWVcblx0XHRcdFx0WzEsIDIsIDUsIDEwLCAyMCwgMjUsIDUwLCAxMDAsIDIwMCwgNTAwXSAvLyBhbGxvd2VkIG11bHRpcGxlc1xuXHRcdFx0XSwgW1xuXHRcdFx0XHQnc2Vjb25kJyxcblx0XHRcdFx0WzEsIDIsIDUsIDEwLCAxNSwgMzBdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCdtaW51dGUnLFxuXHRcdFx0XHRbMSwgMiwgNSwgMTAsIDE1LCAzMF1cblx0XHRcdF0sIFtcblx0XHRcdFx0J2hvdXInLFxuXHRcdFx0XHRbMSwgMiwgMywgNCwgNiwgOCwgMTJdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCdkYXknLFxuXHRcdFx0XHRbMSwgMl1cblx0XHRcdF0sIFtcblx0XHRcdFx0J3dlZWsnLFxuXHRcdFx0XHRbMSwgMl1cblx0XHRcdF0sIFtcblx0XHRcdFx0J21vbnRoJyxcblx0XHRcdFx0WzEsIDIsIDMsIDQsIDZdXG5cdFx0XHRdLCBbXG5cdFx0XHRcdCd5ZWFyJyxcblx0XHRcdFx0bnVsbFxuXHRcdFx0XV0sXG5cdFx0dW5pdCA9IHVuaXRzW3VuaXRzLmxlbmd0aCAtIDFdLCAvLyBkZWZhdWx0IHVuaXQgaXMgeWVhcnNcblx0XHRpbnRlcnZhbCA9IHRpbWVVbml0c1t1bml0WzBdXSxcblx0XHRtdWx0aXBsZXMgPSB1bml0WzFdLFxuXHRcdGNvdW50LFxuXHRcdGk7XG5cdFx0XG5cdC8vIGxvb3AgdGhyb3VnaCB0aGUgdW5pdHMgdG8gZmluZCB0aGUgb25lIHRoYXQgYmVzdCBmaXRzIHRoZSB0aWNrSW50ZXJ2YWxcblx0Zm9yIChpID0gMDsgaSA8IHVuaXRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0dW5pdCA9IHVuaXRzW2ldO1xuXHRcdGludGVydmFsID0gdGltZVVuaXRzW3VuaXRbMF1dO1xuXHRcdG11bHRpcGxlcyA9IHVuaXRbMV07XG5cblxuXHRcdGlmICh1bml0c1tpICsgMV0pIHtcblx0XHRcdC8vIGxlc3NUaGFuIGlzIGluIHRoZSBtaWRkbGUgYmV0d2VlbiB0aGUgaGlnaGVzdCBtdWx0aXBsZSBhbmQgdGhlIG5leHQgdW5pdC5cblx0XHRcdHZhciBsZXNzVGhhbiA9IChpbnRlcnZhbCAqIG11bHRpcGxlc1ttdWx0aXBsZXMubGVuZ3RoIC0gMV0gK1xuXHRcdFx0XHRcdFx0dGltZVVuaXRzW3VuaXRzW2kgKyAxXVswXV0pIC8gMjtcblxuXHRcdFx0Ly8gYnJlYWsgYW5kIGtlZXAgdGhlIGN1cnJlbnQgdW5pdFxuXHRcdFx0aWYgKHRpY2tJbnRlcnZhbCA8PSBsZXNzVGhhbikge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBwcmV2ZW50IDIuNSB5ZWFycyBpbnRlcnZhbHMsIHRob3VnaCAyNSwgMjUwIGV0Yy4gYXJlIGFsbG93ZWRcblx0aWYgKGludGVydmFsID09PSB0aW1lVW5pdHMueWVhciAmJiB0aWNrSW50ZXJ2YWwgPCA1ICogaW50ZXJ2YWwpIHtcblx0XHRtdWx0aXBsZXMgPSBbMSwgMiwgNV07XG5cdH1cblxuXHQvLyBnZXQgdGhlIGNvdW50XG5cdGNvdW50ID0gbm9ybWFsaXplVGlja0ludGVydmFsKFxuXHRcdHRpY2tJbnRlcnZhbCAvIGludGVydmFsLCBcblx0XHRtdWx0aXBsZXMsXG5cdFx0dW5pdFswXSA9PT0gJ3llYXInID8gbWF0aE1heChnZXRNYWduaXR1ZGUodGlja0ludGVydmFsIC8gaW50ZXJ2YWwpLCAxKSA6IDEgLy8gIzE5MTMsICMyMzYwXG5cdCk7XG5cdFxuXHRyZXR1cm4ge1xuXHRcdHVuaXRSYW5nZTogaW50ZXJ2YWwsXG5cdFx0Y291bnQ6IGNvdW50LFxuXHRcdHVuaXROYW1lOiB1bml0WzBdXG5cdH07XG59Oy8qKlxuICogTWV0aG9kcyBkZWZpbmVkIG9uIHRoZSBBeGlzIHByb3RvdHlwZVxuICovXG5cbi8qKlxuICogU2V0IHRoZSB0aWNrIHBvc2l0aW9ucyBvZiBhIGxvZ2FyaXRobWljIGF4aXNcbiAqL1xuQXhpcy5wcm90b3R5cGUuZ2V0TG9nVGlja1Bvc2l0aW9ucyA9IGZ1bmN0aW9uIChpbnRlcnZhbCwgbWluLCBtYXgsIG1pbm9yKSB7XG5cdHZhciBheGlzID0gdGhpcyxcblx0XHRvcHRpb25zID0gYXhpcy5vcHRpb25zLFxuXHRcdGF4aXNMZW5ndGggPSBheGlzLmxlbixcblx0XHQvLyBTaW5jZSB3ZSB1c2UgdGhpcyBtZXRob2QgZm9yIGJvdGggbWFqb3IgYW5kIG1pbm9yIHRpY2tzLFxuXHRcdC8vIHVzZSBhIGxvY2FsIHZhcmlhYmxlIGFuZCByZXR1cm4gdGhlIHJlc3VsdFxuXHRcdHBvc2l0aW9ucyA9IFtdOyBcblx0XG5cdC8vIFJlc2V0XG5cdGlmICghbWlub3IpIHtcblx0XHRheGlzLl9taW5vckF1dG9JbnRlcnZhbCA9IG51bGw7XG5cdH1cblx0XG5cdC8vIEZpcnN0IGNhc2U6IEFsbCB0aWNrcyBmYWxsIG9uIHdob2xlIGxvZ2FyaXRobXM6IDEsIDEwLCAxMDAgZXRjLlxuXHRpZiAoaW50ZXJ2YWwgPj0gMC41KSB7XG5cdFx0aW50ZXJ2YWwgPSBtYXRoUm91bmQoaW50ZXJ2YWwpO1xuXHRcdHBvc2l0aW9ucyA9IGF4aXMuZ2V0TGluZWFyVGlja1Bvc2l0aW9ucyhpbnRlcnZhbCwgbWluLCBtYXgpO1xuXHRcdFxuXHQvLyBTZWNvbmQgY2FzZTogV2UgbmVlZCBpbnRlcm1lZGlhcnkgdGlja3MuIEZvciBleGFtcGxlIFxuXHQvLyAxLCAyLCA0LCA2LCA4LCAxMCwgMjAsIDQwIGV0Yy4gXG5cdH0gZWxzZSBpZiAoaW50ZXJ2YWwgPj0gMC4wOCkge1xuXHRcdHZhciByb3VuZGVkTWluID0gbWF0aEZsb29yKG1pbiksXG5cdFx0XHRpbnRlcm1lZGlhdGUsXG5cdFx0XHRpLFxuXHRcdFx0aixcblx0XHRcdGxlbixcblx0XHRcdHBvcyxcblx0XHRcdGxhc3RQb3MsXG5cdFx0XHRicmVhazI7XG5cdFx0XHRcblx0XHRpZiAoaW50ZXJ2YWwgPiAwLjMpIHtcblx0XHRcdGludGVybWVkaWF0ZSA9IFsxLCAyLCA0XTtcblx0XHR9IGVsc2UgaWYgKGludGVydmFsID4gMC4xNSkgeyAvLyAwLjIgZXF1YWxzIGZpdmUgbWlub3IgdGlja3MgcGVyIDEsIDEwLCAxMDAgZXRjXG5cdFx0XHRpbnRlcm1lZGlhdGUgPSBbMSwgMiwgNCwgNiwgOF07XG5cdFx0fSBlbHNlIHsgLy8gMC4xIGVxdWFscyB0ZW4gbWlub3IgdGlja3MgcGVyIDEsIDEwLCAxMDAgZXRjXG5cdFx0XHRpbnRlcm1lZGlhdGUgPSBbMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOV07XG5cdFx0fVxuXHRcdFxuXHRcdGZvciAoaSA9IHJvdW5kZWRNaW47IGkgPCBtYXggKyAxICYmICFicmVhazI7IGkrKykge1xuXHRcdFx0bGVuID0gaW50ZXJtZWRpYXRlLmxlbmd0aDtcblx0XHRcdGZvciAoaiA9IDA7IGogPCBsZW4gJiYgIWJyZWFrMjsgaisrKSB7XG5cdFx0XHRcdHBvcyA9IGxvZzJsaW4obGluMmxvZyhpKSAqIGludGVybWVkaWF0ZVtqXSk7XG5cdFx0XHRcdGlmIChwb3MgPiBtaW4gJiYgKCFtaW5vciB8fCBsYXN0UG9zIDw9IG1heCkgJiYgbGFzdFBvcyAhPT0gVU5ERUZJTkVEKSB7IC8vICMxNjcwLCBsYXN0UG9zIGlzICMzMTEzXG5cdFx0XHRcdFx0cG9zaXRpb25zLnB1c2gobGFzdFBvcyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdGlmIChsYXN0UG9zID4gbWF4KSB7XG5cdFx0XHRcdFx0YnJlYWsyID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRsYXN0UG9zID0gcG9zO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0Ly8gVGhpcmQgY2FzZTogV2UgYXJlIHNvIGRlZXAgaW4gYmV0d2VlbiB3aG9sZSBsb2dhcml0aG1pYyB2YWx1ZXMgdGhhdFxuXHQvLyB3ZSBtaWdodCBhcyB3ZWxsIGhhbmRsZSB0aGUgdGljayBwb3NpdGlvbnMgbGlrZSBhIGxpbmVhciBheGlzLiBGb3Jcblx0Ly8gZXhhbXBsZSAxLjAxLCAxLjAyLCAxLjAzLCAxLjA0LlxuXHR9IGVsc2Uge1xuXHRcdHZhciByZWFsTWluID0gbGluMmxvZyhtaW4pLFxuXHRcdFx0cmVhbE1heCA9IGxpbjJsb2cobWF4KSxcblx0XHRcdHRpY2tJbnRlcnZhbE9wdGlvbiA9IG9wdGlvbnNbbWlub3IgPyAnbWlub3JUaWNrSW50ZXJ2YWwnIDogJ3RpY2tJbnRlcnZhbCddLFxuXHRcdFx0ZmlsdGVyZWRUaWNrSW50ZXJ2YWxPcHRpb24gPSB0aWNrSW50ZXJ2YWxPcHRpb24gPT09ICdhdXRvJyA/IG51bGwgOiB0aWNrSW50ZXJ2YWxPcHRpb24sXG5cdFx0XHR0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbiA9IG9wdGlvbnMudGlja1BpeGVsSW50ZXJ2YWwgLyAobWlub3IgPyA1IDogMSksXG5cdFx0XHR0b3RhbFBpeGVsTGVuZ3RoID0gbWlub3IgPyBheGlzTGVuZ3RoIC8gYXhpcy50aWNrUG9zaXRpb25zLmxlbmd0aCA6IGF4aXNMZW5ndGg7XG5cdFx0XG5cdFx0aW50ZXJ2YWwgPSBwaWNrKFxuXHRcdFx0ZmlsdGVyZWRUaWNrSW50ZXJ2YWxPcHRpb24sXG5cdFx0XHRheGlzLl9taW5vckF1dG9JbnRlcnZhbCxcblx0XHRcdChyZWFsTWF4IC0gcmVhbE1pbikgKiB0aWNrUGl4ZWxJbnRlcnZhbE9wdGlvbiAvICh0b3RhbFBpeGVsTGVuZ3RoIHx8IDEpXG5cdFx0KTtcblx0XHRcblx0XHRpbnRlcnZhbCA9IG5vcm1hbGl6ZVRpY2tJbnRlcnZhbChcblx0XHRcdGludGVydmFsLCBcblx0XHRcdG51bGwsIFxuXHRcdFx0Z2V0TWFnbml0dWRlKGludGVydmFsKVxuXHRcdCk7XG5cdFx0XG5cdFx0cG9zaXRpb25zID0gbWFwKGF4aXMuZ2V0TGluZWFyVGlja1Bvc2l0aW9ucyhcblx0XHRcdGludGVydmFsLCBcblx0XHRcdHJlYWxNaW4sXG5cdFx0XHRyZWFsTWF4XHRcblx0XHQpLCBsb2cybGluKTtcblx0XHRcblx0XHRpZiAoIW1pbm9yKSB7XG5cdFx0XHRheGlzLl9taW5vckF1dG9JbnRlcnZhbCA9IGludGVydmFsIC8gNTtcblx0XHR9XG5cdH1cblx0XG5cdC8vIFNldCB0aGUgYXhpcy1sZXZlbCB0aWNrSW50ZXJ2YWwgdmFyaWFibGUgXG5cdGlmICghbWlub3IpIHtcblx0XHRheGlzLnRpY2tJbnRlcnZhbCA9IGludGVydmFsO1xuXHR9XG5cdHJldHVybiBwb3NpdGlvbnM7XG59Oy8qKlxuICogVGhlIHRvb2x0aXAgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gY2hhcnQgVGhlIGNoYXJ0IGluc3RhbmNlXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUb29sdGlwIG9wdGlvbnNcbiAqL1xudmFyIFRvb2x0aXAgPSBIaWdoY2hhcnRzLlRvb2x0aXAgPSBmdW5jdGlvbiAoKSB7XG5cdHRoaXMuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xufTtcblxuVG9vbHRpcC5wcm90b3R5cGUgPSB7XG5cblx0aW5pdDogZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cblx0XHR2YXIgYm9yZGVyV2lkdGggPSBvcHRpb25zLmJvcmRlcldpZHRoLFxuXHRcdFx0c3R5bGUgPSBvcHRpb25zLnN0eWxlLFxuXHRcdFx0cGFkZGluZyA9IHBJbnQoc3R5bGUucGFkZGluZyk7XG5cblx0XHQvLyBTYXZlIHRoZSBjaGFydCBhbmQgb3B0aW9uc1xuXHRcdHRoaXMuY2hhcnQgPSBjaGFydDtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXG5cdFx0Ly8gS2VlcCB0cmFjayBvZiB0aGUgY3VycmVudCBzZXJpZXNcblx0XHQvL3RoaXMuY3VycmVudFNlcmllcyA9IFVOREVGSU5FRDtcblxuXHRcdC8vIExpc3Qgb2YgY3Jvc3NoYWlyc1xuXHRcdHRoaXMuY3Jvc3NoYWlycyA9IFtdO1xuXG5cdFx0Ly8gQ3VycmVudCB2YWx1ZXMgb2YgeCBhbmQgeSB3aGVuIGFuaW1hdGluZ1xuXHRcdHRoaXMubm93ID0geyB4OiAwLCB5OiAwIH07XG5cblx0XHQvLyBUaGUgdG9vbHRpcCBpcyBpbml0aWFsbHkgaGlkZGVuXG5cdFx0dGhpcy5pc0hpZGRlbiA9IHRydWU7XG5cblxuXHRcdC8vIGNyZWF0ZSB0aGUgbGFiZWxcblx0XHR0aGlzLmxhYmVsID0gY2hhcnQucmVuZGVyZXIubGFiZWwoJycsIDAsIDAsIG9wdGlvbnMuc2hhcGUgfHwgJ2NhbGxvdXQnLCBudWxsLCBudWxsLCBvcHRpb25zLnVzZUhUTUwsIG51bGwsICd0b29sdGlwJylcblx0XHRcdC5hdHRyKHtcblx0XHRcdFx0cGFkZGluZzogcGFkZGluZyxcblx0XHRcdFx0ZmlsbDogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXG5cdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBib3JkZXJXaWR0aCxcblx0XHRcdFx0cjogb3B0aW9ucy5ib3JkZXJSYWRpdXMsXG5cdFx0XHRcdHpJbmRleDogOFxuXHRcdFx0fSlcblx0XHRcdC5jc3Moc3R5bGUpXG5cdFx0XHQuY3NzKHsgcGFkZGluZzogMCB9KSAvLyBSZW1vdmUgaXQgZnJvbSBWTUwsIHRoZSBwYWRkaW5nIGlzIGFwcGxpZWQgYXMgYW4gYXR0cmlidXRlIGluc3RlYWQgKCMxMTE3KVxuXHRcdFx0LmFkZCgpXG5cdFx0XHQuYXR0cih7IHk6IC05OTk5IH0pOyAvLyAjMjMwMSwgIzI2NTdcblxuXHRcdC8vIFdoZW4gdXNpbmcgY2FuVkcgdGhlIHNoYWRvdyBzaG93cyB1cCBhcyBhIGdyYXkgY2lyY2xlXG5cdFx0Ly8gZXZlbiBpZiB0aGUgdG9vbHRpcCBpcyBoaWRkZW4uXG5cdFx0aWYgKCF1c2VDYW5WRykge1xuXHRcdFx0dGhpcy5sYWJlbC5zaGFkb3cob3B0aW9ucy5zaGFkb3cpO1xuXHRcdH1cblxuXHRcdC8vIFB1YmxpYyBwcm9wZXJ0eSBmb3IgZ2V0dGluZyB0aGUgc2hhcmVkIHN0YXRlLlxuXHRcdHRoaXMuc2hhcmVkID0gb3B0aW9ucy5zaGFyZWQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3Ryb3kgdGhlIHRvb2x0aXAgYW5kIGl0cyBlbGVtZW50cy5cblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHQvLyBEZXN0cm95IGFuZCBjbGVhciBsb2NhbCB2YXJpYWJsZXNcblx0XHRpZiAodGhpcy5sYWJlbCkge1xuXHRcdFx0dGhpcy5sYWJlbCA9IHRoaXMubGFiZWwuZGVzdHJveSgpO1xuXHRcdH1cblx0XHRjbGVhclRpbWVvdXQodGhpcy5oaWRlVGltZXIpO1xuXHRcdGNsZWFyVGltZW91dCh0aGlzLnRvb2x0aXBUaW1lb3V0KTtcblx0fSxcblxuXHQvKipcblx0ICogUHJvdmlkZSBhIHNvZnQgbW92ZW1lbnQgZm9yIHRoZSB0b29sdGlwXG5cdCAqXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB5XG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRtb3ZlOiBmdW5jdGlvbiAoeCwgeSwgYW5jaG9yWCwgYW5jaG9yWSkge1xuXHRcdHZhciB0b29sdGlwID0gdGhpcyxcblx0XHRcdG5vdyA9IHRvb2x0aXAubm93LFxuXHRcdFx0YW5pbWF0ZSA9IHRvb2x0aXAub3B0aW9ucy5hbmltYXRpb24gIT09IGZhbHNlICYmICF0b29sdGlwLmlzSGlkZGVuICYmIFxuXHRcdFx0XHQvLyBXaGVuIHdlIGdldCBjbG9zZSB0byB0aGUgdGFyZ2V0IHBvc2l0aW9uLCBhYm9ydCBhbmltYXRpb24gYW5kIGxhbmQgb24gdGhlIHJpZ2h0IHBsYWNlICgjMzA1Nilcblx0XHRcdFx0KG1hdGhBYnMoeCAtIG5vdy54KSA+IDEgfHwgbWF0aEFicyh5IC0gbm93LnkpID4gMSksXG5cdFx0XHRza2lwQW5jaG9yID0gdG9vbHRpcC5mb2xsb3dQb2ludGVyIHx8IHRvb2x0aXAubGVuID4gMTtcblxuXHRcdC8vIEdldCBpbnRlcm1lZGlhdGUgdmFsdWVzIGZvciBhbmltYXRpb25cblx0XHRleHRlbmQobm93LCB7XG5cdFx0XHR4OiBhbmltYXRlID8gKDIgKiBub3cueCArIHgpIC8gMyA6IHgsXG5cdFx0XHR5OiBhbmltYXRlID8gKG5vdy55ICsgeSkgLyAyIDogeSxcblx0XHRcdGFuY2hvclg6IHNraXBBbmNob3IgPyBVTkRFRklORUQgOiBhbmltYXRlID8gKDIgKiBub3cuYW5jaG9yWCArIGFuY2hvclgpIC8gMyA6IGFuY2hvclgsXG5cdFx0XHRhbmNob3JZOiBza2lwQW5jaG9yID8gVU5ERUZJTkVEIDogYW5pbWF0ZSA/IChub3cuYW5jaG9yWSArIGFuY2hvclkpIC8gMiA6IGFuY2hvcllcblx0XHR9KTtcblxuXHRcdC8vIE1vdmUgdG8gdGhlIGludGVybWVkaWF0ZSB2YWx1ZVxuXHRcdHRvb2x0aXAubGFiZWwuYXR0cihub3cpO1xuXG5cdFx0XG5cdFx0Ly8gUnVuIG9uIG5leHQgdGljayBvZiB0aGUgbW91c2UgdHJhY2tlclxuXHRcdGlmIChhbmltYXRlKSB7XG5cdFx0XG5cdFx0XHQvLyBOZXZlciBhbGxvdyB0d28gdGltZW91dHNcblx0XHRcdGNsZWFyVGltZW91dCh0aGlzLnRvb2x0aXBUaW1lb3V0KTtcblx0XHRcdFxuXHRcdFx0Ly8gU2V0IHRoZSBmaXhlZCBpbnRlcnZhbCB0aWNraW5nIGZvciB0aGUgc21vb3RoIHRvb2x0aXBcblx0XHRcdHRoaXMudG9vbHRpcFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0Ly8gVGhlIGludGVydmFsIGZ1bmN0aW9uIG1heSBzdGlsbCBiZSBydW5uaW5nIGR1cmluZyBkZXN0cm95LCBzbyBjaGVjayB0aGF0IHRoZSBjaGFydCBpcyByZWFsbHkgdGhlcmUgYmVmb3JlIGNhbGxpbmcuXG5cdFx0XHRcdGlmICh0b29sdGlwKSB7XG5cdFx0XHRcdFx0dG9vbHRpcC5tb3ZlKHgsIHksIGFuY2hvclgsIGFuY2hvclkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCAzMik7XG5cdFx0XHRcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEhpZGUgdGhlIHRvb2x0aXBcblx0ICovXG5cdGhpZGU6IGZ1bmN0aW9uIChkZWxheSkge1xuXHRcdHZhciB0b29sdGlwID0gdGhpcyxcblx0XHRcdGhvdmVyUG9pbnRzO1xuXHRcdFxuXHRcdGNsZWFyVGltZW91dCh0aGlzLmhpZGVUaW1lcik7IC8vIGRpc2FsbG93IGR1cGxpY2F0ZSB0aW1lcnMgKCMxNzI4LCAjMTc2Nilcblx0XHRpZiAoIXRoaXMuaXNIaWRkZW4pIHtcblx0XHRcdGhvdmVyUG9pbnRzID0gdGhpcy5jaGFydC5ob3ZlclBvaW50cztcblxuXHRcdFx0dGhpcy5oaWRlVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0dG9vbHRpcC5sYWJlbC5mYWRlT3V0KCk7XG5cdFx0XHRcdHRvb2x0aXAuaXNIaWRkZW4gPSB0cnVlO1xuXHRcdFx0fSwgcGljayhkZWxheSwgdGhpcy5vcHRpb25zLmhpZGVEZWxheSwgNTAwKSk7XG5cblx0XHRcdC8vIGhpZGUgcHJldmlvdXMgaG92ZXJQb2ludHMgYW5kIHNldCBuZXdcblx0XHRcdGlmIChob3ZlclBvaW50cykge1xuXHRcdFx0XHRlYWNoKGhvdmVyUG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0XHRwb2ludC5zZXRTdGF0ZSgpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5jaGFydC5ob3ZlclBvaW50cyA9IG51bGw7XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqIFxuXHQgKiBFeHRlbmRhYmxlIG1ldGhvZCB0byBnZXQgdGhlIGFuY2hvciBwb3NpdGlvbiBvZiB0aGUgdG9vbHRpcFxuXHQgKiBmcm9tIGEgcG9pbnQgb3Igc2V0IG9mIHBvaW50c1xuXHQgKi9cblx0Z2V0QW5jaG9yOiBmdW5jdGlvbiAocG9pbnRzLCBtb3VzZUV2ZW50KSB7XG5cdFx0dmFyIHJldCxcblx0XHRcdGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQsXG5cdFx0XHRwbG90VG9wID0gY2hhcnQucGxvdFRvcCxcblx0XHRcdHBsb3RYID0gMCxcblx0XHRcdHBsb3RZID0gMCxcblx0XHRcdHlBeGlzO1xuXHRcdFxuXHRcdHBvaW50cyA9IHNwbGF0KHBvaW50cyk7XG5cdFx0XG5cdFx0Ly8gUGllIHVzZXMgYSBzcGVjaWFsIHRvb2x0aXBQb3Ncblx0XHRyZXQgPSBwb2ludHNbMF0udG9vbHRpcFBvcztcblx0XHRcblx0XHQvLyBXaGVuIHRvb2x0aXAgZm9sbG93cyBtb3VzZSwgcmVsYXRlIHRoZSBwb3NpdGlvbiB0byB0aGUgbW91c2Vcblx0XHRpZiAodGhpcy5mb2xsb3dQb2ludGVyICYmIG1vdXNlRXZlbnQpIHtcblx0XHRcdGlmIChtb3VzZUV2ZW50LmNoYXJ0WCA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdG1vdXNlRXZlbnQgPSBjaGFydC5wb2ludGVyLm5vcm1hbGl6ZShtb3VzZUV2ZW50KTtcblx0XHRcdH1cblx0XHRcdHJldCA9IFtcblx0XHRcdFx0bW91c2VFdmVudC5jaGFydFggLSBjaGFydC5wbG90TGVmdCxcblx0XHRcdFx0bW91c2VFdmVudC5jaGFydFkgLSBwbG90VG9wXG5cdFx0XHRdO1xuXHRcdH1cblx0XHQvLyBXaGVuIHNoYXJlZCwgdXNlIHRoZSBhdmVyYWdlIHBvc2l0aW9uXG5cdFx0aWYgKCFyZXQpIHtcblx0XHRcdGVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0eUF4aXMgPSBwb2ludC5zZXJpZXMueUF4aXM7XG5cdFx0XHRcdHBsb3RYICs9IHBvaW50LnBsb3RYO1xuXHRcdFx0XHRwbG90WSArPSAocG9pbnQucGxvdExvdyA/IChwb2ludC5wbG90TG93ICsgcG9pbnQucGxvdEhpZ2gpIC8gMiA6IHBvaW50LnBsb3RZKSArXG5cdFx0XHRcdFx0KCFpbnZlcnRlZCAmJiB5QXhpcyA/IHlBeGlzLnRvcCAtIHBsb3RUb3AgOiAwKTsgLy8gIzExNTFcblx0XHRcdH0pO1xuXHRcdFx0XG5cdFx0XHRwbG90WCAvPSBwb2ludHMubGVuZ3RoO1xuXHRcdFx0cGxvdFkgLz0gcG9pbnRzLmxlbmd0aDtcblx0XHRcdFxuXHRcdFx0cmV0ID0gW1xuXHRcdFx0XHRpbnZlcnRlZCA/IGNoYXJ0LnBsb3RXaWR0aCAtIHBsb3RZIDogcGxvdFgsXG5cdFx0XHRcdHRoaXMuc2hhcmVkICYmICFpbnZlcnRlZCAmJiBwb2ludHMubGVuZ3RoID4gMSAmJiBtb3VzZUV2ZW50ID8gXG5cdFx0XHRcdFx0bW91c2VFdmVudC5jaGFydFkgLSBwbG90VG9wIDogLy8gcGxhY2Ugc2hhcmVkIHRvb2x0aXAgbmV4dCB0byB0aGUgbW91c2UgKCM0MjQpXG5cdFx0XHRcdFx0aW52ZXJ0ZWQgPyBjaGFydC5wbG90SGVpZ2h0IC0gcGxvdFggOiBwbG90WVxuXHRcdFx0XTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbWFwKHJldCwgbWF0aFJvdW5kKTtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBQbGFjZSB0aGUgdG9vbHRpcCBpbiBhIGNoYXJ0IHdpdGhvdXQgc3BpbGxpbmcgb3ZlclxuXHQgKiBhbmQgbm90IGNvdmVyaW5nIHRoZSBwb2ludCBpdCBzZWxmLlxuXHQgKi9cblx0Z2V0UG9zaXRpb246IGZ1bmN0aW9uIChib3hXaWR0aCwgYm94SGVpZ2h0LCBwb2ludCkge1xuXHRcdFxuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRkaXN0YW5jZSA9IHRoaXMuZGlzdGFuY2UsXG5cdFx0XHRyZXQgPSB7fSxcblx0XHRcdHN3YXBwZWQsXG5cdFx0XHRmaXJzdCA9IFsneScsIGNoYXJ0LmNoYXJ0SGVpZ2h0LCBib3hIZWlnaHQsIHBvaW50LnBsb3RZICsgY2hhcnQucGxvdFRvcF0sXG5cdFx0XHRzZWNvbmQgPSBbJ3gnLCBjaGFydC5jaGFydFdpZHRoLCBib3hXaWR0aCwgcG9pbnQucGxvdFggKyBjaGFydC5wbG90TGVmdF0sXG5cdFx0XHQvLyBUaGUgZmFyIHNpZGUgaXMgcmlnaHQgb3IgYm90dG9tXG5cdFx0XHRwcmVmZXJGYXJTaWRlID0gcG9pbnQudHRCZWxvdyB8fCAoY2hhcnQuaW52ZXJ0ZWQgJiYgIXBvaW50Lm5lZ2F0aXZlKSB8fCAoIWNoYXJ0LmludmVydGVkICYmIHBvaW50Lm5lZ2F0aXZlKSxcblx0XHRcdC8qKlxuXHRcdFx0ICogSGFuZGxlIHRoZSBwcmVmZXJyZWQgZGltZW5zaW9uLiBXaGVuIHRoZSBwcmVmZXJyZWQgZGltZW5zaW9uIGlzIHRvb2x0aXBcblx0XHRcdCAqIG9uIHRvcCBvciBib3R0b20gb2YgdGhlIHBvaW50LCBpdCB3aWxsIGxvb2sgZm9yIHNwYWNlIHRoZXJlLlxuXHRcdFx0ICovXG5cdFx0XHRmaXJzdERpbWVuc2lvbiA9IGZ1bmN0aW9uIChkaW0sIG91dGVyU2l6ZSwgaW5uZXJTaXplLCBwb2ludCkge1xuXHRcdFx0XHR2YXIgcm9vbUxlZnQgPSBpbm5lclNpemUgPCBwb2ludCAtIGRpc3RhbmNlLFxuXHRcdFx0XHRcdHJvb21SaWdodCA9IHBvaW50ICsgZGlzdGFuY2UgKyBpbm5lclNpemUgPCBvdXRlclNpemUsXG5cdFx0XHRcdFx0YWxpZ25lZExlZnQgPSBwb2ludCAtIGRpc3RhbmNlIC0gaW5uZXJTaXplLFxuXHRcdFx0XHRcdGFsaWduZWRSaWdodCA9IHBvaW50ICsgZGlzdGFuY2U7XG5cblx0XHRcdFx0aWYgKHByZWZlckZhclNpZGUgJiYgcm9vbVJpZ2h0KSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSBhbGlnbmVkUmlnaHQ7XG5cdFx0XHRcdH0gZWxzZSBpZiAoIXByZWZlckZhclNpZGUgJiYgcm9vbUxlZnQpIHtcblx0XHRcdFx0XHRyZXRbZGltXSA9IGFsaWduZWRMZWZ0O1xuXHRcdFx0XHR9IGVsc2UgaWYgKHJvb21MZWZ0KSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSBhbGlnbmVkTGVmdDtcblx0XHRcdFx0fSBlbHNlIGlmIChyb29tUmlnaHQpIHtcblx0XHRcdFx0XHRyZXRbZGltXSA9IGFsaWduZWRSaWdodDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHQvKipcblx0XHRcdCAqIEhhbmRsZSB0aGUgc2Vjb25kYXJ5IGRpbWVuc2lvbi4gSWYgdGhlIHByZWZlcnJlZCBkaW1lbnNpb24gaXMgdG9vbHRpcFxuXHRcdFx0ICogb24gdG9wIG9yIGJvdHRvbSBvZiB0aGUgcG9pbnQsIHRoZSBzZWNvbmQgZGltZW5zaW9uIGlzIHRvIGFsaWduIHRoZSB0b29sdGlwXG5cdFx0XHQgKiBhYm92ZSB0aGUgcG9pbnQsIHRyeWluZyB0byBhbGlnbiBjZW50ZXIgYnV0IGFsbG93aW5nIGxlZnQgb3IgcmlnaHRcblx0XHRcdCAqIGFsaWduIHdpdGhpbiB0aGUgY2hhcnQgYm94LlxuXHRcdFx0ICovXG5cdFx0XHRzZWNvbmREaW1lbnNpb24gPSBmdW5jdGlvbiAoZGltLCBvdXRlclNpemUsIGlubmVyU2l6ZSwgcG9pbnQpIHtcblx0XHRcdFx0Ly8gVG9vIGNsb3NlIHRvIHRoZSBlZGdlLCByZXR1cm4gZmFsc2UgYW5kIHN3YXAgZGltZW5zaW9uc1xuXHRcdFx0XHRpZiAocG9pbnQgPCBkaXN0YW5jZSB8fCBwb2ludCA+IG91dGVyU2l6ZSAtIGRpc3RhbmNlKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcblx0XHRcdFx0Ly8gQWxpZ24gbGVmdC90b3Bcblx0XHRcdFx0fSBlbHNlIGlmIChwb2ludCA8IGlubmVyU2l6ZSAvIDIpIHtcblx0XHRcdFx0XHRyZXRbZGltXSA9IDE7XG5cdFx0XHRcdC8vIEFsaWduIHJpZ2h0L2JvdHRvbVxuXHRcdFx0XHR9IGVsc2UgaWYgKHBvaW50ID4gb3V0ZXJTaXplIC0gaW5uZXJTaXplIC8gMikge1xuXHRcdFx0XHRcdHJldFtkaW1dID0gb3V0ZXJTaXplIC0gaW5uZXJTaXplIC0gMjtcblx0XHRcdFx0Ly8gQWxpZ24gY2VudGVyXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0W2RpbV0gPSBwb2ludCAtIGlubmVyU2l6ZSAvIDI7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHQvKipcblx0XHRcdCAqIFN3YXAgdGhlIGRpbWVuc2lvbnMgXG5cdFx0XHQgKi9cblx0XHRcdHN3YXAgPSBmdW5jdGlvbiAoY291bnQpIHtcblx0XHRcdFx0dmFyIHRlbXAgPSBmaXJzdDtcblx0XHRcdFx0Zmlyc3QgPSBzZWNvbmQ7XG5cdFx0XHRcdHNlY29uZCA9IHRlbXA7XG5cdFx0XHRcdHN3YXBwZWQgPSBjb3VudDtcblx0XHRcdH0sXG5cdFx0XHRydW4gPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChmaXJzdERpbWVuc2lvbi5hcHBseSgwLCBmaXJzdCkgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0aWYgKHNlY29uZERpbWVuc2lvbi5hcHBseSgwLCBzZWNvbmQpID09PSBmYWxzZSAmJiAhc3dhcHBlZCkge1xuXHRcdFx0XHRcdFx0c3dhcCh0cnVlKTtcblx0XHRcdFx0XHRcdHJ1bigpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmICghc3dhcHBlZCkge1xuXHRcdFx0XHRcdHN3YXAodHJ1ZSk7XG5cdFx0XHRcdFx0cnVuKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0LnggPSByZXQueSA9IDA7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBVbmRlciB0aGVzZSBjb25kaXRpb25zLCBwcmVmZXIgdGhlIHRvb2x0aXAgb24gdGhlIHNpZGUgb2YgdGhlIHBvaW50XG5cdFx0aWYgKGNoYXJ0LmludmVydGVkIHx8IHRoaXMubGVuID4gMSkge1xuXHRcdFx0c3dhcCgpO1xuXHRcdH1cblx0XHRydW4oKTtcblxuXHRcdHJldHVybiByZXQ7XG5cdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbiBjYXNlIG5vIHVzZXIgZGVmaW5lZCBmb3JtYXR0ZXIgaXMgZ2l2ZW4sIHRoaXMgd2lsbCBiZSB1c2VkLiBOb3RlIHRoYXQgdGhlIGNvbnRleHRcblx0ICogaGVyZSBpcyBhbiBvYmplY3QgaG9sZGluZyBwb2ludCwgc2VyaWVzLCB4LCB5IGV0Yy5cblx0ICovXG5cdGRlZmF1bHRGb3JtYXR0ZXI6IGZ1bmN0aW9uICh0b29sdGlwKSB7XG5cdFx0dmFyIGl0ZW1zID0gdGhpcy5wb2ludHMgfHwgc3BsYXQodGhpcyksXG5cdFx0XHRzZXJpZXMgPSBpdGVtc1swXS5zZXJpZXMsXG5cdFx0XHRzO1xuXG5cdFx0Ly8gYnVpbGQgdGhlIGhlYWRlclxuXHRcdHMgPSBbdG9vbHRpcC50b29sdGlwSGVhZGVyRm9ybWF0dGVyKGl0ZW1zWzBdKV07XG5cblx0XHQvLyBidWlsZCB0aGUgdmFsdWVzXG5cdFx0ZWFjaChpdGVtcywgZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHRcdHNlcmllcyA9IGl0ZW0uc2VyaWVzO1xuXHRcdFx0cy5wdXNoKChzZXJpZXMudG9vbHRpcEZvcm1hdHRlciAmJiBzZXJpZXMudG9vbHRpcEZvcm1hdHRlcihpdGVtKSkgfHxcblx0XHRcdFx0aXRlbS5wb2ludC50b29sdGlwRm9ybWF0dGVyKHNlcmllcy50b29sdGlwT3B0aW9ucy5wb2ludEZvcm1hdCkpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gZm9vdGVyXG5cdFx0cy5wdXNoKHRvb2x0aXAub3B0aW9ucy5mb290ZXJGb3JtYXQgfHwgJycpO1xuXG5cdFx0cmV0dXJuIHMuam9pbignJyk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlZnJlc2ggdGhlIHRvb2x0aXAncyB0ZXh0IGFuZCBwb3NpdGlvbi5cblx0ICogQHBhcmFtIHtPYmplY3R9IHBvaW50XG5cdCAqL1xuXHRyZWZyZXNoOiBmdW5jdGlvbiAocG9pbnQsIG1vdXNlRXZlbnQpIHtcblx0XHR2YXIgdG9vbHRpcCA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHRvb2x0aXAuY2hhcnQsXG5cdFx0XHRsYWJlbCA9IHRvb2x0aXAubGFiZWwsXG5cdFx0XHRvcHRpb25zID0gdG9vbHRpcC5vcHRpb25zLFxuXHRcdFx0eCxcblx0XHRcdHksXG5cdFx0XHRhbmNob3IsXG5cdFx0XHR0ZXh0Q29uZmlnID0ge30sXG5cdFx0XHR0ZXh0LFxuXHRcdFx0cG9pbnRDb25maWcgPSBbXSxcblx0XHRcdGZvcm1hdHRlciA9IG9wdGlvbnMuZm9ybWF0dGVyIHx8IHRvb2x0aXAuZGVmYXVsdEZvcm1hdHRlcixcblx0XHRcdGhvdmVyUG9pbnRzID0gY2hhcnQuaG92ZXJQb2ludHMsXG5cdFx0XHRib3JkZXJDb2xvcixcblx0XHRcdHNoYXJlZCA9IHRvb2x0aXAuc2hhcmVkLFxuXHRcdFx0Y3VycmVudFNlcmllcztcblx0XHRcdFxuXHRcdGNsZWFyVGltZW91dCh0aGlzLmhpZGVUaW1lcik7XG5cdFx0XG5cdFx0Ly8gZ2V0IHRoZSByZWZlcmVuY2UgcG9pbnQgY29vcmRpbmF0ZXMgKHBpZSBjaGFydHMgdXNlIHRvb2x0aXBQb3MpXG5cdFx0dG9vbHRpcC5mb2xsb3dQb2ludGVyID0gc3BsYXQocG9pbnQpWzBdLnNlcmllcy50b29sdGlwT3B0aW9ucy5mb2xsb3dQb2ludGVyO1xuXHRcdGFuY2hvciA9IHRvb2x0aXAuZ2V0QW5jaG9yKHBvaW50LCBtb3VzZUV2ZW50KTtcblx0XHR4ID0gYW5jaG9yWzBdO1xuXHRcdHkgPSBhbmNob3JbMV07XG5cblx0XHQvLyBzaGFyZWQgdG9vbHRpcCwgYXJyYXkgaXMgc2VudCBvdmVyXG5cdFx0aWYgKHNoYXJlZCAmJiAhKHBvaW50LnNlcmllcyAmJiBwb2ludC5zZXJpZXMubm9TaGFyZWRUb29sdGlwKSkge1xuXHRcdFx0XG5cdFx0XHQvLyBoaWRlIHByZXZpb3VzIGhvdmVyUG9pbnRzIGFuZCBzZXQgbmV3XG5cdFx0XHRcblx0XHRcdGNoYXJ0LmhvdmVyUG9pbnRzID0gcG9pbnQ7XG5cdFx0XHRpZiAoaG92ZXJQb2ludHMpIHtcblx0XHRcdFx0ZWFjaChob3ZlclBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdFx0cG9pbnQuc2V0U3RhdGUoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGVhY2gocG9pbnQsIGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0XHRcdGl0ZW0uc2V0U3RhdGUoSE9WRVJfU1RBVEUpO1xuXG5cdFx0XHRcdHBvaW50Q29uZmlnLnB1c2goaXRlbS5nZXRMYWJlbENvbmZpZygpKTtcblx0XHRcdH0pO1xuXG5cdFx0XHR0ZXh0Q29uZmlnID0ge1xuXHRcdFx0XHR4OiBwb2ludFswXS5jYXRlZ29yeSxcblx0XHRcdFx0eTogcG9pbnRbMF0ueVxuXHRcdFx0fTtcblx0XHRcdHRleHRDb25maWcucG9pbnRzID0gcG9pbnRDb25maWc7XG5cdFx0XHR0aGlzLmxlbiA9IHBvaW50Q29uZmlnLmxlbmd0aDtcblx0XHRcdHBvaW50ID0gcG9pbnRbMF07XG5cblx0XHQvLyBzaW5nbGUgcG9pbnQgdG9vbHRpcFxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0ZXh0Q29uZmlnID0gcG9pbnQuZ2V0TGFiZWxDb25maWcoKTtcblx0XHR9XG5cdFx0dGV4dCA9IGZvcm1hdHRlci5jYWxsKHRleHRDb25maWcsIHRvb2x0aXApO1xuXG5cdFx0Ly8gcmVnaXN0ZXIgdGhlIGN1cnJlbnQgc2VyaWVzXG5cdFx0Y3VycmVudFNlcmllcyA9IHBvaW50LnNlcmllcztcblx0XHR0aGlzLmRpc3RhbmNlID0gcGljayhjdXJyZW50U2VyaWVzLnRvb2x0aXBPcHRpb25zLmRpc3RhbmNlLCAxNik7XG5cblx0XHQvLyB1cGRhdGUgdGhlIGlubmVyIEhUTUxcblx0XHRpZiAodGV4dCA9PT0gZmFsc2UpIHtcblx0XHRcdHRoaXMuaGlkZSgpO1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIHNob3cgaXRcblx0XHRcdGlmICh0b29sdGlwLmlzSGlkZGVuKSB7XG5cdFx0XHRcdHN0b3AobGFiZWwpO1xuXHRcdFx0XHRsYWJlbC5hdHRyKCdvcGFjaXR5JywgMSkuc2hvdygpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyB1cGRhdGUgdGV4dFxuXHRcdFx0bGFiZWwuYXR0cih7XG5cdFx0XHRcdHRleHQ6IHRleHRcblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBzZXQgdGhlIHN0cm9rZSBjb2xvciBvZiB0aGUgYm94XG5cdFx0XHRib3JkZXJDb2xvciA9IG9wdGlvbnMuYm9yZGVyQ29sb3IgfHwgcG9pbnQuY29sb3IgfHwgY3VycmVudFNlcmllcy5jb2xvciB8fCAnIzYwNjA2MCc7XG5cdFx0XHRsYWJlbC5hdHRyKHtcblx0XHRcdFx0c3Ryb2tlOiBib3JkZXJDb2xvclxuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdHRvb2x0aXAudXBkYXRlUG9zaXRpb24oeyBwbG90WDogeCwgcGxvdFk6IHksIG5lZ2F0aXZlOiBwb2ludC5uZWdhdGl2ZSwgdHRCZWxvdzogcG9pbnQudHRCZWxvdyB9KTtcblx0XHRcblx0XHRcdHRoaXMuaXNIaWRkZW4gPSBmYWxzZTtcblx0XHR9XG5cdFx0ZmlyZUV2ZW50KGNoYXJ0LCAndG9vbHRpcFJlZnJlc2gnLCB7XG5cdFx0XHRcdHRleHQ6IHRleHQsXG5cdFx0XHRcdHg6IHggKyBjaGFydC5wbG90TGVmdCxcblx0XHRcdFx0eTogeSArIGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRcdGJvcmRlckNvbG9yOiBib3JkZXJDb2xvclxuXHRcdFx0fSk7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRmluZCB0aGUgbmV3IHBvc2l0aW9uIGFuZCBwZXJmb3JtIHRoZSBtb3ZlXG5cdCAqL1xuXHR1cGRhdGVQb3NpdGlvbjogZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGxhYmVsID0gdGhpcy5sYWJlbCwgXG5cdFx0XHRwb3MgPSAodGhpcy5vcHRpb25zLnBvc2l0aW9uZXIgfHwgdGhpcy5nZXRQb3NpdGlvbikuY2FsbChcblx0XHRcdFx0dGhpcyxcblx0XHRcdFx0bGFiZWwud2lkdGgsXG5cdFx0XHRcdGxhYmVsLmhlaWdodCxcblx0XHRcdFx0cG9pbnRcblx0XHRcdCk7XG5cblx0XHQvLyBkbyB0aGUgbW92ZVxuXHRcdHRoaXMubW92ZShcblx0XHRcdG1hdGhSb3VuZChwb3MueCksIFxuXHRcdFx0bWF0aFJvdW5kKHBvcy55KSwgXG5cdFx0XHRwb2ludC5wbG90WCArIGNoYXJ0LnBsb3RMZWZ0LCBcblx0XHRcdHBvaW50LnBsb3RZICsgY2hhcnQucGxvdFRvcFxuXHRcdCk7XG5cdH0sXG5cblxuXHQvKipcblx0ICogRm9ybWF0IHRoZSBoZWFkZXIgb2YgdGhlIHRvb2x0aXBcblx0ICovXG5cdHRvb2x0aXBIZWFkZXJGb3JtYXR0ZXI6IGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdHZhciBzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHR0b29sdGlwT3B0aW9ucyA9IHNlcmllcy50b29sdGlwT3B0aW9ucyxcblx0XHRcdGRhdGVUaW1lTGFiZWxGb3JtYXRzID0gdG9vbHRpcE9wdGlvbnMuZGF0ZVRpbWVMYWJlbEZvcm1hdHMsXG5cdFx0XHR4RGF0ZUZvcm1hdCA9IHRvb2x0aXBPcHRpb25zLnhEYXRlRm9ybWF0LFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHRpc0RhdGVUaW1lID0geEF4aXMgJiYgeEF4aXMub3B0aW9ucy50eXBlID09PSAnZGF0ZXRpbWUnICYmIGlzTnVtYmVyKHBvaW50LmtleSksXG5cdFx0XHRoZWFkZXJGb3JtYXQgPSB0b29sdGlwT3B0aW9ucy5oZWFkZXJGb3JtYXQsXG5cdFx0XHRjbG9zZXN0UG9pbnRSYW5nZSA9IHhBeGlzICYmIHhBeGlzLmNsb3Nlc3RQb2ludFJhbmdlLFxuXHRcdFx0bjtcblxuXHRcdC8vIEd1ZXNzIHRoZSBiZXN0IGRhdGUgZm9ybWF0IGJhc2VkIG9uIHRoZSBjbG9zZXN0IHBvaW50IGRpc3RhbmNlICgjNTY4KVxuXHRcdGlmIChpc0RhdGVUaW1lICYmICF4RGF0ZUZvcm1hdCkge1xuXHRcdFx0aWYgKGNsb3Nlc3RQb2ludFJhbmdlKSB7XG5cdFx0XHRcdGZvciAobiBpbiB0aW1lVW5pdHMpIHtcblx0XHRcdFx0XHRpZiAodGltZVVuaXRzW25dID49IGNsb3Nlc3RQb2ludFJhbmdlIHx8IFxuXHRcdFx0XHRcdFx0XHQvLyBJZiB0aGUgcG9pbnQgaXMgcGxhY2VkIGV2ZXJ5IGRheSBhdCAyMzo1OSwgd2UgbmVlZCB0byBzaG93XG5cdFx0XHRcdFx0XHRcdC8vIHRoZSBtaW51dGVzIGFzIHdlbGwuIFRoaXMgbG9naWMgb25seSB3b3JrcyBmb3IgdGltZSB1bml0cyBsZXNzIHRoYW4gXG5cdFx0XHRcdFx0XHRcdC8vIGEgZGF5LCBzaW5jZSBhbGwgaGlnaGVyIHRpbWUgdW5pdHMgYXJlIGRpdmlkYWJsZSBieSB0aG9zZS4gIzI2MzcuXG5cdFx0XHRcdFx0XHRcdCh0aW1lVW5pdHNbbl0gPD0gdGltZVVuaXRzLmRheSAmJiBwb2ludC5rZXkgJSB0aW1lVW5pdHNbbl0gPiAwKSkge1xuXHRcdFx0XHRcdFx0eERhdGVGb3JtYXQgPSBkYXRlVGltZUxhYmVsRm9ybWF0c1tuXTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0eERhdGVGb3JtYXQgPSBkYXRlVGltZUxhYmVsRm9ybWF0cy5kYXk7XG5cdFx0XHR9XG5cblx0XHRcdHhEYXRlRm9ybWF0ID0geERhdGVGb3JtYXQgfHwgZGF0ZVRpbWVMYWJlbEZvcm1hdHMueWVhcjsgLy8gIzI1NDYsIDI1ODFcblxuXHRcdH1cblxuXHRcdC8vIEluc2VydCB0aGUgaGVhZGVyIGRhdGUgZm9ybWF0IGlmIGFueVxuXHRcdGlmIChpc0RhdGVUaW1lICYmIHhEYXRlRm9ybWF0KSB7XG5cdFx0XHRoZWFkZXJGb3JtYXQgPSBoZWFkZXJGb3JtYXQucmVwbGFjZSgne3BvaW50LmtleX0nLCAne3BvaW50LmtleTonICsgeERhdGVGb3JtYXQgKyAnfScpO1xuXHRcdH1cblxuXHRcdHJldHVybiBmb3JtYXQoaGVhZGVyRm9ybWF0LCB7XG5cdFx0XHRwb2ludDogcG9pbnQsXG5cdFx0XHRzZXJpZXM6IHNlcmllc1xuXHRcdH0pO1xuXHR9XG59O1xuXG52YXIgaG92ZXJDaGFydEluZGV4O1xuXG4vLyBHbG9iYWwgZmxhZyBmb3IgdG91Y2ggc3VwcG9ydFxuaGFzVG91Y2ggPSBkb2MuZG9jdW1lbnRFbGVtZW50Lm9udG91Y2hzdGFydCAhPT0gVU5ERUZJTkVEO1xuXG4vKipcbiAqIFRoZSBtb3VzZSB0cmFja2VyIG9iamVjdC4gQWxsIG1ldGhvZHMgc3RhcnRpbmcgd2l0aCBcIm9uXCIgYXJlIHByaW1hcnkgRE9NIGV2ZW50IGhhbmRsZXJzLiBcbiAqIFN1YnNlcXVlbnQgbWV0aG9kcyBzaG91bGQgYmUgbmFtZWQgZGlmZmVyZW50bHkgZnJvbSB3aGF0IHRoZXkgYXJlIGRvaW5nLlxuICogQHBhcmFtIHtPYmplY3R9IGNoYXJ0IFRoZSBDaGFydCBpbnN0YW5jZVxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIHJvb3Qgb3B0aW9ucyBvYmplY3RcbiAqL1xudmFyIFBvaW50ZXIgPSBIaWdoY2hhcnRzLlBvaW50ZXIgPSBmdW5jdGlvbiAoY2hhcnQsIG9wdGlvbnMpIHtcblx0dGhpcy5pbml0KGNoYXJ0LCBvcHRpb25zKTtcbn07XG5cblBvaW50ZXIucHJvdG90eXBlID0ge1xuXHQvKipcblx0ICogSW5pdGlhbGl6ZSBQb2ludGVyXG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAoY2hhcnQsIG9wdGlvbnMpIHtcblx0XHRcblx0XHR2YXIgY2hhcnRPcHRpb25zID0gb3B0aW9ucy5jaGFydCxcblx0XHRcdGNoYXJ0RXZlbnRzID0gY2hhcnRPcHRpb25zLmV2ZW50cyxcblx0XHRcdHpvb21UeXBlID0gdXNlQ2FuVkcgPyAnJyA6IGNoYXJ0T3B0aW9ucy56b29tVHlwZSxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQsXG5cdFx0XHR6b29tWCxcblx0XHRcdHpvb21ZO1xuXG5cdFx0Ly8gU3RvcmUgcmVmZXJlbmNlc1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5jaGFydCA9IGNoYXJ0O1xuXHRcdFxuXHRcdC8vIFpvb20gc3RhdHVzXG5cdFx0dGhpcy56b29tWCA9IHpvb21YID0gL3gvLnRlc3Qoem9vbVR5cGUpO1xuXHRcdHRoaXMuem9vbVkgPSB6b29tWSA9IC95Ly50ZXN0KHpvb21UeXBlKTtcblx0XHR0aGlzLnpvb21Ib3IgPSAoem9vbVggJiYgIWludmVydGVkKSB8fCAoem9vbVkgJiYgaW52ZXJ0ZWQpO1xuXHRcdHRoaXMuem9vbVZlcnQgPSAoem9vbVkgJiYgIWludmVydGVkKSB8fCAoem9vbVggJiYgaW52ZXJ0ZWQpO1xuXHRcdHRoaXMuaGFzWm9vbSA9IHpvb21YIHx8IHpvb21ZO1xuXG5cdFx0Ly8gRG8gd2UgbmVlZCB0byBoYW5kbGUgY2xpY2sgb24gYSB0b3VjaCBkZXZpY2U/XG5cdFx0dGhpcy5ydW5DaGFydENsaWNrID0gY2hhcnRFdmVudHMgJiYgISFjaGFydEV2ZW50cy5jbGljaztcblxuXHRcdHRoaXMucGluY2hEb3duID0gW107XG5cdFx0dGhpcy5sYXN0VmFsaWRUb3VjaCA9IHt9O1xuXG5cdFx0aWYgKEhpZ2hjaGFydHMuVG9vbHRpcCAmJiBvcHRpb25zLnRvb2x0aXAuZW5hYmxlZCkge1xuXHRcdFx0Y2hhcnQudG9vbHRpcCA9IG5ldyBUb29sdGlwKGNoYXJ0LCBvcHRpb25zLnRvb2x0aXApO1xuXHRcdFx0dGhpcy5mb2xsb3dUb3VjaE1vdmUgPSBvcHRpb25zLnRvb2x0aXAuZm9sbG93VG91Y2hNb3ZlO1xuXHRcdH1cblxuXHRcdHRoaXMuc2V0RE9NRXZlbnRzKCk7XG5cdH0sIFxuXG5cdC8qKlxuXHQgKiBBZGQgY3Jvc3Nicm93c2VyIHN1cHBvcnQgZm9yIGNoYXJ0WCBhbmQgY2hhcnRZXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBlIFRoZSBldmVudCBvYmplY3QgaW4gc3RhbmRhcmQgYnJvd3NlcnNcblx0ICovXG5cdG5vcm1hbGl6ZTogZnVuY3Rpb24gKGUsIGNoYXJ0UG9zaXRpb24pIHtcblx0XHR2YXIgY2hhcnRYLFxuXHRcdFx0Y2hhcnRZLFxuXHRcdFx0ZVBvcztcblxuXHRcdC8vIGNvbW1vbiBJRSBub3JtYWxpemluZ1xuXHRcdGUgPSBlIHx8IHdpbmRvdy5ldmVudDtcblxuXHRcdC8vIEZyYW1ld29yayBzcGVjaWZpYyBub3JtYWxpemluZyAoIzExNjUpXG5cdFx0ZSA9IHdhc2hNb3VzZUV2ZW50KGUpO1xuXG5cdFx0Ly8gTW9yZSBJRSBub3JtYWxpemluZywgbmVlZHMgdG8gZ28gYWZ0ZXIgd2FzaE1vdXNlRXZlbnRcblx0XHRpZiAoIWUudGFyZ2V0KSB7XG5cdFx0XHRlLnRhcmdldCA9IGUuc3JjRWxlbWVudDtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gaU9TICgjMjc1Nylcblx0XHRlUG9zID0gZS50b3VjaGVzID8gIChlLnRvdWNoZXMubGVuZ3RoID8gZS50b3VjaGVzLml0ZW0oMCkgOiBlLmNoYW5nZWRUb3VjaGVzWzBdKSA6IGU7XG5cblx0XHQvLyBHZXQgbW91c2UgcG9zaXRpb25cblx0XHRpZiAoIWNoYXJ0UG9zaXRpb24pIHtcblx0XHRcdHRoaXMuY2hhcnRQb3NpdGlvbiA9IGNoYXJ0UG9zaXRpb24gPSBvZmZzZXQodGhpcy5jaGFydC5jb250YWluZXIpO1xuXHRcdH1cblxuXHRcdC8vIGNoYXJ0WCBhbmQgY2hhcnRZXG5cdFx0aWYgKGVQb3MucGFnZVggPT09IFVOREVGSU5FRCkgeyAvLyBJRSA8IDkuICM4ODYuXG5cdFx0XHRjaGFydFggPSBtYXRoTWF4KGUueCwgZS5jbGllbnRYIC0gY2hhcnRQb3NpdGlvbi5sZWZ0KTsgLy8gIzIwMDUsICMyMTI5OiB0aGUgc2Vjb25kIGNhc2UgaXMgXG5cdFx0XHRcdC8vIGZvciBJRTEwIHF1aXJrcyBtb2RlIHdpdGhpbiBmcmFtZXNldHNcblx0XHRcdGNoYXJ0WSA9IGUueTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2hhcnRYID0gZVBvcy5wYWdlWCAtIGNoYXJ0UG9zaXRpb24ubGVmdDtcblx0XHRcdGNoYXJ0WSA9IGVQb3MucGFnZVkgLSBjaGFydFBvc2l0aW9uLnRvcDtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXh0ZW5kKGUsIHtcblx0XHRcdGNoYXJ0WDogbWF0aFJvdW5kKGNoYXJ0WCksXG5cdFx0XHRjaGFydFk6IG1hdGhSb3VuZChjaGFydFkpXG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgY2xpY2sgcG9zaXRpb24gaW4gdGVybXMgb2YgYXhpcyB2YWx1ZXMuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBlIEEgcG9pbnRlciBldmVudFxuXHQgKi9cblx0Z2V0Q29vcmRpbmF0ZXM6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNvb3JkaW5hdGVzID0ge1xuXHRcdFx0XHR4QXhpczogW10sXG5cdFx0XHRcdHlBeGlzOiBbXVxuXHRcdFx0fTtcblxuXHRcdGVhY2godGhpcy5jaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0Y29vcmRpbmF0ZXNbYXhpcy5pc1hBeGlzID8gJ3hBeGlzJyA6ICd5QXhpcyddLnB1c2goe1xuXHRcdFx0XHRheGlzOiBheGlzLFxuXHRcdFx0XHR2YWx1ZTogYXhpcy50b1ZhbHVlKGVbYXhpcy5ob3JpeiA/ICdjaGFydFgnIDogJ2NoYXJ0WSddKVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGNvb3JkaW5hdGVzO1xuXHR9LFxuXHRcblx0LyoqXG5cdCAqIFJldHVybiB0aGUgaW5kZXggaW4gdGhlIHRvb2x0aXBQb2ludHMgYXJyYXksIGNvcnJlc3BvbmRpbmcgdG8gcGl4ZWwgcG9zaXRpb24gaW4gXG5cdCAqIHRoZSBwbG90IGFyZWEuXG5cdCAqL1xuXHRnZXRJbmRleDogZnVuY3Rpb24gKGUpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0O1xuXHRcdHJldHVybiBjaGFydC5pbnZlcnRlZCA/IFxuXHRcdFx0Y2hhcnQucGxvdEhlaWdodCArIGNoYXJ0LnBsb3RUb3AgLSBlLmNoYXJ0WSA6IFxuXHRcdFx0ZS5jaGFydFggLSBjaGFydC5wbG90TGVmdDtcblx0fSxcblxuXHQvKipcblx0ICogV2l0aCBsaW5lIHR5cGUgY2hhcnRzIHdpdGggYSBzaW5nbGUgdHJhY2tlciwgZ2V0IHRoZSBwb2ludCBjbG9zZXN0IHRvIHRoZSBtb3VzZS5cblx0ICogUnVuIFBvaW50Lm9uTW91c2VPdmVyIGFuZCBkaXNwbGF5IHRvb2x0aXAgZm9yIHRoZSBwb2ludCBvciBwb2ludHMuXG5cdCAqL1xuXHRydW5Qb2ludEFjdGlvbnM6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIHBvaW50ZXIgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBwb2ludGVyLmNoYXJ0LFxuXHRcdFx0c2VyaWVzID0gY2hhcnQuc2VyaWVzLFxuXHRcdFx0dG9vbHRpcCA9IGNoYXJ0LnRvb2x0aXAsXG5cdFx0XHRmb2xsb3dQb2ludGVyLFxuXHRcdFx0cG9pbnQsXG5cdFx0XHRwb2ludHMsXG5cdFx0XHRob3ZlclBvaW50ID0gY2hhcnQuaG92ZXJQb2ludCxcblx0XHRcdGhvdmVyU2VyaWVzID0gY2hhcnQuaG92ZXJTZXJpZXMsXG5cdFx0XHRpLFxuXHRcdFx0aixcblx0XHRcdGRpc3RhbmNlID0gY2hhcnQuY2hhcnRXaWR0aCxcblx0XHRcdGluZGV4ID0gcG9pbnRlci5nZXRJbmRleChlKSxcblx0XHRcdGFuY2hvcjtcblxuXHRcdC8vIHNoYXJlZCB0b29sdGlwXG5cdFx0aWYgKHRvb2x0aXAgJiYgcG9pbnRlci5vcHRpb25zLnRvb2x0aXAuc2hhcmVkICYmICEoaG92ZXJTZXJpZXMgJiYgaG92ZXJTZXJpZXMubm9TaGFyZWRUb29sdGlwKSkge1xuXHRcdFx0cG9pbnRzID0gW107XG5cblx0XHRcdC8vIGxvb3Agb3ZlciBhbGwgc2VyaWVzIGFuZCBmaW5kIHRoZSBvbmVzIHdpdGggcG9pbnRzIGNsb3Nlc3QgdG8gdGhlIG1vdXNlXG5cdFx0XHRpID0gc2VyaWVzLmxlbmd0aDtcblx0XHRcdGZvciAoaiA9IDA7IGogPCBpOyBqKyspIHtcblx0XHRcdFx0aWYgKHNlcmllc1tqXS52aXNpYmxlICYmXG5cdFx0XHRcdFx0XHRzZXJpZXNbal0ub3B0aW9ucy5lbmFibGVNb3VzZVRyYWNraW5nICE9PSBmYWxzZSAmJlxuXHRcdFx0XHRcdFx0IXNlcmllc1tqXS5ub1NoYXJlZFRvb2x0aXAgJiYgc2VyaWVzW2pdLnNpbmd1bGFyVG9vbHRpcHMgIT09IHRydWUgJiYgc2VyaWVzW2pdLnRvb2x0aXBQb2ludHMubGVuZ3RoKSB7XG5cdFx0XHRcdFx0cG9pbnQgPSBzZXJpZXNbal0udG9vbHRpcFBvaW50c1tpbmRleF07XG5cdFx0XHRcdFx0aWYgKHBvaW50ICYmIHBvaW50LnNlcmllcykgeyAvLyBub3QgYSBkdW1teSBwb2ludCwgIzE1NDRcblx0XHRcdFx0XHRcdHBvaW50Ll9kaXN0ID0gbWF0aEFicyhpbmRleCAtIHBvaW50LmNsaWVudFgpO1xuXHRcdFx0XHRcdFx0ZGlzdGFuY2UgPSBtYXRoTWluKGRpc3RhbmNlLCBwb2ludC5fZGlzdCk7XG5cdFx0XHRcdFx0XHRwb2ludHMucHVzaChwb2ludCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyByZW1vdmUgZnVydGhlc3QgcG9pbnRzXG5cdFx0XHRpID0gcG9pbnRzLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0aWYgKHBvaW50c1tpXS5fZGlzdCA+IGRpc3RhbmNlKSB7XG5cdFx0XHRcdFx0cG9pbnRzLnNwbGljZShpLCAxKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gcmVmcmVzaCB0aGUgdG9vbHRpcCBpZiBuZWNlc3Nhcnlcblx0XHRcdGlmIChwb2ludHMubGVuZ3RoICYmIChwb2ludHNbMF0uY2xpZW50WCAhPT0gcG9pbnRlci5ob3ZlclgpKSB7XG5cdFx0XHRcdHRvb2x0aXAucmVmcmVzaChwb2ludHMsIGUpO1xuXHRcdFx0XHRwb2ludGVyLmhvdmVyWCA9IHBvaW50c1swXS5jbGllbnRYO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNlcGFyYXRlIHRvb2x0aXAgYW5kIGdlbmVyYWwgbW91c2UgZXZlbnRzXG5cdFx0Zm9sbG93UG9pbnRlciA9IGhvdmVyU2VyaWVzICYmIGhvdmVyU2VyaWVzLnRvb2x0aXBPcHRpb25zLmZvbGxvd1BvaW50ZXI7XG5cdFx0aWYgKGhvdmVyU2VyaWVzICYmIGhvdmVyU2VyaWVzLnRyYWNrZXIgJiYgIWZvbGxvd1BvaW50ZXIpIHsgLy8gIzI1ODQsICMyODMwXG5cblx0XHRcdC8vIGdldCB0aGUgcG9pbnRcblx0XHRcdHBvaW50ID0gaG92ZXJTZXJpZXMudG9vbHRpcFBvaW50c1tpbmRleF07XG5cblx0XHRcdC8vIGEgbmV3IHBvaW50IGlzIGhvdmVyZWQsIHJlZnJlc2ggdGhlIHRvb2x0aXBcblx0XHRcdGlmIChwb2ludCAmJiBwb2ludCAhPT0gaG92ZXJQb2ludCkge1xuXG5cdFx0XHRcdC8vIHRyaWdnZXIgdGhlIGV2ZW50c1xuXHRcdFx0XHRwb2ludC5vbk1vdXNlT3ZlcihlKTtcblxuXHRcdFx0fVxuXHRcdFx0XG5cdFx0fSBlbHNlIGlmICh0b29sdGlwICYmIGZvbGxvd1BvaW50ZXIgJiYgIXRvb2x0aXAuaXNIaWRkZW4pIHtcblx0XHRcdGFuY2hvciA9IHRvb2x0aXAuZ2V0QW5jaG9yKFt7fV0sIGUpO1xuXHRcdFx0dG9vbHRpcC51cGRhdGVQb3NpdGlvbih7IHBsb3RYOiBhbmNob3JbMF0sIHBsb3RZOiBhbmNob3JbMV0gfSk7XG5cdFx0fVxuXG5cdFx0Ly8gU3RhcnQgdGhlIGV2ZW50IGxpc3RlbmVyIHRvIHBpY2sgdXAgdGhlIHRvb2x0aXAgXG5cdFx0aWYgKHRvb2x0aXAgJiYgIXBvaW50ZXIuX29uRG9jdW1lbnRNb3VzZU1vdmUpIHtcblx0XHRcdHBvaW50ZXIuX29uRG9jdW1lbnRNb3VzZU1vdmUgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0XHRpZiAoY2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0pIHtcblx0XHRcdFx0XHRjaGFydHNbaG92ZXJDaGFydEluZGV4XS5wb2ludGVyLm9uRG9jdW1lbnRNb3VzZU1vdmUoZSk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRhZGRFdmVudChkb2MsICdtb3VzZW1vdmUnLCBwb2ludGVyLl9vbkRvY3VtZW50TW91c2VNb3ZlKTtcblx0XHR9XG5cblx0XHQvLyBEcmF3IGluZGVwZW5kZW50IGNyb3NzaGFpcnNcblx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRheGlzLmRyYXdDcm9zc2hhaXIoZSwgcGljayhwb2ludCwgaG92ZXJQb2ludCkpO1xuXHRcdH0pO1xuXHR9LFxuXG5cblxuXHQvKipcblx0ICogUmVzZXQgdGhlIHRyYWNraW5nIGJ5IGhpZGluZyB0aGUgdG9vbHRpcCwgdGhlIGhvdmVyIHNlcmllcyBzdGF0ZSBhbmQgdGhlIGhvdmVyIHBvaW50XG5cdCAqIFxuXHQgKiBAcGFyYW0gYWxsb3dNb3ZlIHtCb29sZWFufSBJbnN0ZWFkIG9mIGRlc3Ryb3lpbmcgdGhlIHRvb2x0aXAgYWx0b2dldGhlciwgYWxsb3cgbW92aW5nIGl0IGlmIHBvc3NpYmxlXG5cdCAqL1xuXHRyZXNldDogZnVuY3Rpb24gKGFsbG93TW92ZSwgZGVsYXkpIHtcblx0XHR2YXIgcG9pbnRlciA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHBvaW50ZXIuY2hhcnQsXG5cdFx0XHRob3ZlclNlcmllcyA9IGNoYXJ0LmhvdmVyU2VyaWVzLFxuXHRcdFx0aG92ZXJQb2ludCA9IGNoYXJ0LmhvdmVyUG9pbnQsXG5cdFx0XHR0b29sdGlwID0gY2hhcnQudG9vbHRpcCxcblx0XHRcdHRvb2x0aXBQb2ludHMgPSB0b29sdGlwICYmIHRvb2x0aXAuc2hhcmVkID8gY2hhcnQuaG92ZXJQb2ludHMgOiBob3ZlclBvaW50O1xuXHRcdFx0XG5cdFx0Ly8gTmFycm93IGluIGFsbG93TW92ZVxuXHRcdGFsbG93TW92ZSA9IGFsbG93TW92ZSAmJiB0b29sdGlwICYmIHRvb2x0aXBQb2ludHM7XG5cdFx0XHRcblx0XHQvLyBDaGVjayBpZiB0aGUgcG9pbnRzIGhhdmUgbW92ZWQgb3V0c2lkZSB0aGUgcGxvdCBhcmVhLCAjMTAwM1xuXHRcdGlmIChhbGxvd01vdmUgJiYgc3BsYXQodG9vbHRpcFBvaW50cylbMF0ucGxvdFggPT09IFVOREVGSU5FRCkge1xuXHRcdFx0YWxsb3dNb3ZlID0gZmFsc2U7XG5cdFx0fVx0XG5cblx0XHQvLyBKdXN0IG1vdmUgdGhlIHRvb2x0aXAsICMzNDlcblx0XHRpZiAoYWxsb3dNb3ZlKSB7XG5cdFx0XHR0b29sdGlwLnJlZnJlc2godG9vbHRpcFBvaW50cyk7XG5cdFx0XHRpZiAoaG92ZXJQb2ludCkgeyAvLyAjMjUwMFxuXHRcdFx0XHRob3ZlclBvaW50LnNldFN0YXRlKGhvdmVyUG9pbnQuc3RhdGUsIHRydWUpO1xuXHRcdFx0fVxuXG5cdFx0Ly8gRnVsbCByZXNldFxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdGlmIChob3ZlclBvaW50KSB7XG5cdFx0XHRcdGhvdmVyUG9pbnQub25Nb3VzZU91dCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaG92ZXJTZXJpZXMpIHtcblx0XHRcdFx0aG92ZXJTZXJpZXMub25Nb3VzZU91dCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodG9vbHRpcCkge1xuXHRcdFx0XHR0b29sdGlwLmhpZGUoZGVsYXkpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAocG9pbnRlci5fb25Eb2N1bWVudE1vdXNlTW92ZSkge1xuXHRcdFx0XHRyZW1vdmVFdmVudChkb2MsICdtb3VzZW1vdmUnLCBwb2ludGVyLl9vbkRvY3VtZW50TW91c2VNb3ZlKTtcblx0XHRcdFx0cG9pbnRlci5fb25Eb2N1bWVudE1vdXNlTW92ZSA9IG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBjcm9zc2hhaXJzXG5cdFx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdGF4aXMuaGlkZUNyb3NzaGFpcigpO1xuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdHBvaW50ZXIuaG92ZXJYID0gbnVsbDtcblxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2NhbGUgc2VyaWVzIGdyb3VwcyB0byBhIGNlcnRhaW4gc2NhbGUgYW5kIHRyYW5zbGF0aW9uXG5cdCAqL1xuXHRzY2FsZUdyb3VwczogZnVuY3Rpb24gKGF0dHJpYnMsIGNsaXApIHtcblxuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRzZXJpZXNBdHRyaWJzO1xuXG5cdFx0Ly8gU2NhbGUgZWFjaCBzZXJpZXNcblx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0c2VyaWVzQXR0cmlicyA9IGF0dHJpYnMgfHwgc2VyaWVzLmdldFBsb3RCb3goKTsgLy8gIzE3MDFcblx0XHRcdGlmIChzZXJpZXMueEF4aXMgJiYgc2VyaWVzLnhBeGlzLnpvb21FbmFibGVkKSB7XG5cdFx0XHRcdHNlcmllcy5ncm91cC5hdHRyKHNlcmllc0F0dHJpYnMpO1xuXHRcdFx0XHRpZiAoc2VyaWVzLm1hcmtlckdyb3VwKSB7XG5cdFx0XHRcdFx0c2VyaWVzLm1hcmtlckdyb3VwLmF0dHIoc2VyaWVzQXR0cmlicyk7XG5cdFx0XHRcdFx0c2VyaWVzLm1hcmtlckdyb3VwLmNsaXAoY2xpcCA/IGNoYXJ0LmNsaXBSZWN0IDogbnVsbCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHNlcmllcy5kYXRhTGFiZWxzR3JvdXApIHtcblx0XHRcdFx0XHRzZXJpZXMuZGF0YUxhYmVsc0dyb3VwLmF0dHIoc2VyaWVzQXR0cmlicyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0XHRcblx0XHQvLyBDbGlwXG5cdFx0Y2hhcnQuY2xpcFJlY3QuYXR0cihjbGlwIHx8IGNoYXJ0LmNsaXBCb3gpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTdGFydCBhIGRyYWcgb3BlcmF0aW9uXG5cdCAqL1xuXHRkcmFnU3RhcnQ6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydDtcblxuXHRcdC8vIFJlY29yZCB0aGUgc3RhcnQgcG9zaXRpb25cblx0XHRjaGFydC5tb3VzZUlzRG93biA9IGUudHlwZTtcblx0XHRjaGFydC5jYW5jZWxDbGljayA9IGZhbHNlO1xuXHRcdGNoYXJ0Lm1vdXNlRG93blggPSB0aGlzLm1vdXNlRG93blggPSBlLmNoYXJ0WDtcblx0XHRjaGFydC5tb3VzZURvd25ZID0gdGhpcy5tb3VzZURvd25ZID0gZS5jaGFydFk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFBlcmZvcm0gYSBkcmFnIG9wZXJhdGlvbiBpbiByZXNwb25zZSB0byBhIG1vdXNlbW92ZSBldmVudCB3aGlsZSB0aGUgbW91c2UgaXMgZG93blxuXHQgKi9cblx0ZHJhZzogZnVuY3Rpb24gKGUpIHtcblxuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRjaGFydE9wdGlvbnMgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0Y2hhcnRYID0gZS5jaGFydFgsXG5cdFx0XHRjaGFydFkgPSBlLmNoYXJ0WSxcblx0XHRcdHpvb21Ib3IgPSB0aGlzLnpvb21Ib3IsXG5cdFx0XHR6b29tVmVydCA9IHRoaXMuem9vbVZlcnQsXG5cdFx0XHRwbG90TGVmdCA9IGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0cGxvdFRvcCA9IGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRwbG90V2lkdGggPSBjaGFydC5wbG90V2lkdGgsXG5cdFx0XHRwbG90SGVpZ2h0ID0gY2hhcnQucGxvdEhlaWdodCxcblx0XHRcdGNsaWNrZWRJbnNpZGUsXG5cdFx0XHRzaXplLFxuXHRcdFx0bW91c2VEb3duWCA9IHRoaXMubW91c2VEb3duWCxcblx0XHRcdG1vdXNlRG93blkgPSB0aGlzLm1vdXNlRG93blksXG5cdFx0XHRwYW5LZXkgPSBjaGFydE9wdGlvbnMucGFuS2V5ICYmIGVbY2hhcnRPcHRpb25zLnBhbktleSArICdLZXknXTtcblxuXHRcdC8vIElmIHRoZSBtb3VzZSBpcyBvdXRzaWRlIHRoZSBwbG90IGFyZWEsIGFkanVzdCB0byBjb29vcmRpbmF0ZXNcblx0XHQvLyBpbnNpZGUgdG8gcHJldmVudCB0aGUgc2VsZWN0aW9uIG1hcmtlciBmcm9tIGdvaW5nIG91dHNpZGVcblx0XHRpZiAoY2hhcnRYIDwgcGxvdExlZnQpIHtcblx0XHRcdGNoYXJ0WCA9IHBsb3RMZWZ0O1xuXHRcdH0gZWxzZSBpZiAoY2hhcnRYID4gcGxvdExlZnQgKyBwbG90V2lkdGgpIHtcblx0XHRcdGNoYXJ0WCA9IHBsb3RMZWZ0ICsgcGxvdFdpZHRoO1xuXHRcdH1cblxuXHRcdGlmIChjaGFydFkgPCBwbG90VG9wKSB7XG5cdFx0XHRjaGFydFkgPSBwbG90VG9wO1xuXHRcdH0gZWxzZSBpZiAoY2hhcnRZID4gcGxvdFRvcCArIHBsb3RIZWlnaHQpIHtcblx0XHRcdGNoYXJ0WSA9IHBsb3RUb3AgKyBwbG90SGVpZ2h0O1xuXHRcdH1cblx0XHRcblx0XHQvLyBkZXRlcm1pbmUgaWYgdGhlIG1vdXNlIGhhcyBtb3ZlZCBtb3JlIHRoYW4gMTBweFxuXHRcdHRoaXMuaGFzRHJhZ2dlZCA9IE1hdGguc3FydChcblx0XHRcdE1hdGgucG93KG1vdXNlRG93blggLSBjaGFydFgsIDIpICtcblx0XHRcdE1hdGgucG93KG1vdXNlRG93blkgLSBjaGFydFksIDIpXG5cdFx0KTtcblx0XHRcblx0XHRpZiAodGhpcy5oYXNEcmFnZ2VkID4gMTApIHtcblx0XHRcdGNsaWNrZWRJbnNpZGUgPSBjaGFydC5pc0luc2lkZVBsb3QobW91c2VEb3duWCAtIHBsb3RMZWZ0LCBtb3VzZURvd25ZIC0gcGxvdFRvcCk7XG5cblx0XHRcdC8vIG1ha2UgYSBzZWxlY3Rpb25cblx0XHRcdGlmIChjaGFydC5oYXNDYXJ0ZXNpYW5TZXJpZXMgJiYgKHRoaXMuem9vbVggfHwgdGhpcy56b29tWSkgJiYgY2xpY2tlZEluc2lkZSAmJiAhcGFuS2V5KSB7XG5cdFx0XHRcdGlmICghdGhpcy5zZWxlY3Rpb25NYXJrZXIpIHtcblx0XHRcdFx0XHR0aGlzLnNlbGVjdGlvbk1hcmtlciA9IGNoYXJ0LnJlbmRlcmVyLnJlY3QoXG5cdFx0XHRcdFx0XHRwbG90TGVmdCxcblx0XHRcdFx0XHRcdHBsb3RUb3AsXG5cdFx0XHRcdFx0XHR6b29tSG9yID8gMSA6IHBsb3RXaWR0aCxcblx0XHRcdFx0XHRcdHpvb21WZXJ0ID8gMSA6IHBsb3RIZWlnaHQsXG5cdFx0XHRcdFx0XHQwXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRcdGZpbGw6IGNoYXJ0T3B0aW9ucy5zZWxlY3Rpb25NYXJrZXJGaWxsIHx8ICdyZ2JhKDY5LDExNCwxNjcsMC4yNSknLFxuXHRcdFx0XHRcdFx0ekluZGV4OiA3XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuYWRkKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gYWRqdXN0IHRoZSB3aWR0aCBvZiB0aGUgc2VsZWN0aW9uIG1hcmtlclxuXHRcdFx0aWYgKHRoaXMuc2VsZWN0aW9uTWFya2VyICYmIHpvb21Ib3IpIHtcblx0XHRcdFx0c2l6ZSA9IGNoYXJ0WCAtIG1vdXNlRG93blg7XG5cdFx0XHRcdHRoaXMuc2VsZWN0aW9uTWFya2VyLmF0dHIoe1xuXHRcdFx0XHRcdHdpZHRoOiBtYXRoQWJzKHNpemUpLFxuXHRcdFx0XHRcdHg6IChzaXplID4gMCA/IDAgOiBzaXplKSArIG1vdXNlRG93blhcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHQvLyBhZGp1c3QgdGhlIGhlaWdodCBvZiB0aGUgc2VsZWN0aW9uIG1hcmtlclxuXHRcdFx0aWYgKHRoaXMuc2VsZWN0aW9uTWFya2VyICYmIHpvb21WZXJ0KSB7XG5cdFx0XHRcdHNpemUgPSBjaGFydFkgLSBtb3VzZURvd25ZO1xuXHRcdFx0XHR0aGlzLnNlbGVjdGlvbk1hcmtlci5hdHRyKHtcblx0XHRcdFx0XHRoZWlnaHQ6IG1hdGhBYnMoc2l6ZSksXG5cdFx0XHRcdFx0eTogKHNpemUgPiAwID8gMCA6IHNpemUpICsgbW91c2VEb3duWVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcGFubmluZ1xuXHRcdFx0aWYgKGNsaWNrZWRJbnNpZGUgJiYgIXRoaXMuc2VsZWN0aW9uTWFya2VyICYmIGNoYXJ0T3B0aW9ucy5wYW5uaW5nKSB7XG5cdFx0XHRcdGNoYXJ0LnBhbihlLCBjaGFydE9wdGlvbnMucGFubmluZyk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBPbiBtb3VzZSB1cCBvciB0b3VjaCBlbmQgYWNyb3NzIHRoZSBlbnRpcmUgZG9jdW1lbnQsIGRyb3AgdGhlIHNlbGVjdGlvbi5cblx0ICovXG5cdGRyb3A6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGhhc1BpbmNoZWQgPSB0aGlzLmhhc1BpbmNoZWQ7XG5cblx0XHRpZiAodGhpcy5zZWxlY3Rpb25NYXJrZXIpIHtcblx0XHRcdHZhciBzZWxlY3Rpb25EYXRhID0ge1xuXHRcdFx0XHRcdHhBeGlzOiBbXSxcblx0XHRcdFx0XHR5QXhpczogW10sXG5cdFx0XHRcdFx0b3JpZ2luYWxFdmVudDogZS5vcmlnaW5hbEV2ZW50IHx8IGVcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0aW9uQm94ID0gdGhpcy5zZWxlY3Rpb25NYXJrZXIsXG5cdFx0XHRcdHNlbGVjdGlvbkxlZnQgPSBzZWxlY3Rpb25Cb3guYXR0ciA/IHNlbGVjdGlvbkJveC5hdHRyKCd4JykgOiBzZWxlY3Rpb25Cb3gueCxcblx0XHRcdFx0c2VsZWN0aW9uVG9wID0gc2VsZWN0aW9uQm94LmF0dHIgPyBzZWxlY3Rpb25Cb3guYXR0cigneScpIDogc2VsZWN0aW9uQm94LnksXG5cdFx0XHRcdHNlbGVjdGlvbldpZHRoID0gc2VsZWN0aW9uQm94LmF0dHIgPyBzZWxlY3Rpb25Cb3guYXR0cignd2lkdGgnKSA6IHNlbGVjdGlvbkJveC53aWR0aCxcblx0XHRcdFx0c2VsZWN0aW9uSGVpZ2h0ID0gc2VsZWN0aW9uQm94LmF0dHIgPyBzZWxlY3Rpb25Cb3guYXR0cignaGVpZ2h0JykgOiBzZWxlY3Rpb25Cb3guaGVpZ2h0LFxuXHRcdFx0XHRydW5ab29tO1xuXG5cdFx0XHQvLyBhIHNlbGVjdGlvbiBoYXMgYmVlbiBtYWRlXG5cdFx0XHRpZiAodGhpcy5oYXNEcmFnZ2VkIHx8IGhhc1BpbmNoZWQpIHtcblxuXHRcdFx0XHQvLyByZWNvcmQgZWFjaCBheGlzJyBtaW4gYW5kIG1heFxuXHRcdFx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdFx0aWYgKGF4aXMuem9vbUVuYWJsZWQpIHtcblx0XHRcdFx0XHRcdHZhciBob3JpeiA9IGF4aXMuaG9yaXosXG5cdFx0XHRcdFx0XHRcdG1pblBpeGVsUGFkZGluZyA9IGUudHlwZSA9PT0gJ3RvdWNoZW5kJyA/IGF4aXMubWluUGl4ZWxQYWRkaW5nOiAwLCAvLyAjMTIwNywgIzMwNzVcblx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uTWluID0gYXhpcy50b1ZhbHVlKChob3JpeiA/IHNlbGVjdGlvbkxlZnQgOiBzZWxlY3Rpb25Ub3ApICsgbWluUGl4ZWxQYWRkaW5nKSxcblx0XHRcdFx0XHRcdFx0c2VsZWN0aW9uTWF4ID0gYXhpcy50b1ZhbHVlKChob3JpeiA/IHNlbGVjdGlvbkxlZnQgKyBzZWxlY3Rpb25XaWR0aCA6IHNlbGVjdGlvblRvcCArIHNlbGVjdGlvbkhlaWdodCkgLSBtaW5QaXhlbFBhZGRpbmcpO1xuXG5cdFx0XHRcdFx0XHRpZiAoIWlzTmFOKHNlbGVjdGlvbk1pbikgJiYgIWlzTmFOKHNlbGVjdGlvbk1heCkpIHsgLy8gIzg1OVxuXHRcdFx0XHRcdFx0XHRzZWxlY3Rpb25EYXRhW2F4aXMuY29sbF0ucHVzaCh7XG5cdFx0XHRcdFx0XHRcdFx0YXhpczogYXhpcyxcblx0XHRcdFx0XHRcdFx0XHRtaW46IG1hdGhNaW4oc2VsZWN0aW9uTWluLCBzZWxlY3Rpb25NYXgpLCAvLyBmb3IgcmV2ZXJzZWQgYXhlcyxcblx0XHRcdFx0XHRcdFx0XHRtYXg6IG1hdGhNYXgoc2VsZWN0aW9uTWluLCBzZWxlY3Rpb25NYXgpXG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0XHRydW5ab29tID0gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRpZiAocnVuWm9vbSkge1xuXHRcdFx0XHRcdGZpcmVFdmVudChjaGFydCwgJ3NlbGVjdGlvbicsIHNlbGVjdGlvbkRhdGEsIGZ1bmN0aW9uIChhcmdzKSB7IFxuXHRcdFx0XHRcdFx0Y2hhcnQuem9vbShleHRlbmQoYXJncywgaGFzUGluY2hlZCA/IHsgYW5pbWF0aW9uOiBmYWxzZSB9IDogbnVsbCkpOyBcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0XHR0aGlzLnNlbGVjdGlvbk1hcmtlciA9IHRoaXMuc2VsZWN0aW9uTWFya2VyLmRlc3Ryb3koKTtcblxuXHRcdFx0Ly8gUmVzZXQgc2NhbGluZyBwcmV2aWV3XG5cdFx0XHRpZiAoaGFzUGluY2hlZCkge1xuXHRcdFx0XHR0aGlzLnNjYWxlR3JvdXBzKCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVzZXQgYWxsXG5cdFx0aWYgKGNoYXJ0KSB7IC8vIGl0IG1heSBiZSBkZXN0cm95ZWQgb24gbW91c2UgdXAgLSAjODc3XG5cdFx0XHRjc3MoY2hhcnQuY29udGFpbmVyLCB7IGN1cnNvcjogY2hhcnQuX2N1cnNvciB9KTtcblx0XHRcdGNoYXJ0LmNhbmNlbENsaWNrID0gdGhpcy5oYXNEcmFnZ2VkID4gMTA7IC8vICMzNzBcblx0XHRcdGNoYXJ0Lm1vdXNlSXNEb3duID0gdGhpcy5oYXNEcmFnZ2VkID0gdGhpcy5oYXNQaW5jaGVkID0gZmFsc2U7XG5cdFx0XHR0aGlzLnBpbmNoRG93biA9IFtdO1xuXHRcdH1cblx0fSxcblxuXHRvbkNvbnRhaW5lck1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcblxuXHRcdGUgPSB0aGlzLm5vcm1hbGl6ZShlKTtcblxuXHRcdC8vIGlzc3VlICMyOTUsIGRyYWdnaW5nIG5vdCBhbHdheXMgd29ya2luZyBpbiBGaXJlZm94XG5cdFx0aWYgKGUucHJldmVudERlZmF1bHQpIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdFx0XG5cdFx0dGhpcy5kcmFnU3RhcnQoZSk7XG5cdH0sXG5cblx0XG5cblx0b25Eb2N1bWVudE1vdXNlVXA6IGZ1bmN0aW9uIChlKSB7XG5cdFx0aWYgKGNoYXJ0c1tob3ZlckNoYXJ0SW5kZXhdKSB7XG5cdFx0XHRjaGFydHNbaG92ZXJDaGFydEluZGV4XS5wb2ludGVyLmRyb3AoZSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTcGVjaWFsIGhhbmRsZXIgZm9yIG1vdXNlIG1vdmUgdGhhdCB3aWxsIGhpZGUgdGhlIHRvb2x0aXAgd2hlbiB0aGUgbW91c2UgbGVhdmVzIHRoZSBwbG90YXJlYS5cblx0ICogSXNzdWUgIzE0OSB3b3JrYXJvdW5kLiBUaGUgbW91c2VsZWF2ZSBldmVudCBkb2VzIG5vdCBhbHdheXMgZmlyZS4gXG5cdCAqL1xuXHRvbkRvY3VtZW50TW91c2VNb3ZlOiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRjaGFydFBvc2l0aW9uID0gdGhpcy5jaGFydFBvc2l0aW9uLFxuXHRcdFx0aG92ZXJTZXJpZXMgPSBjaGFydC5ob3ZlclNlcmllcztcblxuXHRcdGUgPSB0aGlzLm5vcm1hbGl6ZShlLCBjaGFydFBvc2l0aW9uKTtcblxuXHRcdC8vIElmIHdlJ3JlIG91dHNpZGUsIGhpZGUgdGhlIHRvb2x0aXBcblx0XHRpZiAoY2hhcnRQb3NpdGlvbiAmJiBob3ZlclNlcmllcyAmJiAhdGhpcy5pbkNsYXNzKGUudGFyZ2V0LCAnaGlnaGNoYXJ0cy10cmFja2VyJykgJiZcblx0XHRcdFx0IWNoYXJ0LmlzSW5zaWRlUGxvdChlLmNoYXJ0WCAtIGNoYXJ0LnBsb3RMZWZ0LCBlLmNoYXJ0WSAtIGNoYXJ0LnBsb3RUb3ApKSB7XG5cdFx0XHR0aGlzLnJlc2V0KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBXaGVuIG1vdXNlIGxlYXZlcyB0aGUgY29udGFpbmVyLCBoaWRlIHRoZSB0b29sdGlwLlxuXHQgKi9cblx0b25Db250YWluZXJNb3VzZUxlYXZlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gY2hhcnRzW2hvdmVyQ2hhcnRJbmRleF07XG5cdFx0aWYgKGNoYXJ0KSB7XG5cdFx0XHRjaGFydC5wb2ludGVyLnJlc2V0KCk7XG5cdFx0XHRjaGFydC5wb2ludGVyLmNoYXJ0UG9zaXRpb24gPSBudWxsOyAvLyBhbHNvIHJlc2V0IHRoZSBjaGFydCBwb3NpdGlvbiwgdXNlZCBpbiAjMTQ5IGZpeFxuXHRcdH1cblx0fSxcblxuXHQvLyBUaGUgbW91c2Vtb3ZlLCB0b3VjaG1vdmUgYW5kIHRvdWNoc3RhcnQgZXZlbnQgaGFuZGxlclxuXHRvbkNvbnRhaW5lck1vdXNlTW92ZTogZnVuY3Rpb24gKGUpIHtcblxuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cblx0XHRob3ZlckNoYXJ0SW5kZXggPSBjaGFydC5pbmRleDtcblxuXHRcdGUgPSB0aGlzLm5vcm1hbGl6ZShlKTtcdFx0XG5cdFx0ZS5yZXR1cm5WYWx1ZSA9IGZhbHNlOyAvLyAjMjI1MSwgIzMyMjRcblx0XHRcblx0XHRpZiAoY2hhcnQubW91c2VJc0Rvd24gPT09ICdtb3VzZWRvd24nKSB7XG5cdFx0XHR0aGlzLmRyYWcoZSk7XG5cdFx0fSBcblx0XHRcblx0XHQvLyBTaG93IHRoZSB0b29sdGlwIGFuZCBydW4gbW91c2Ugb3ZlciBldmVudHMgKCM5NzcpXG5cdFx0aWYgKCh0aGlzLmluQ2xhc3MoZS50YXJnZXQsICdoaWdoY2hhcnRzLXRyYWNrZXInKSB8fCBcblx0XHRcdFx0Y2hhcnQuaXNJbnNpZGVQbG90KGUuY2hhcnRYIC0gY2hhcnQucGxvdExlZnQsIGUuY2hhcnRZIC0gY2hhcnQucGxvdFRvcCkpICYmICFjaGFydC5vcGVuTWVudSkge1xuXHRcdFx0dGhpcy5ydW5Qb2ludEFjdGlvbnMoZSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBVdGlsaXR5IHRvIGRldGVjdCB3aGV0aGVyIGFuIGVsZW1lbnQgaGFzLCBvciBoYXMgYSBwYXJlbnQgd2l0aCwgYSBzcGVjaWZpY1xuXHQgKiBjbGFzcyBuYW1lLiBVc2VkIG9uIGRldGVjdGlvbiBvZiB0cmFja2VyIG9iamVjdHMgYW5kIG9uIGRlY2lkaW5nIHdoZXRoZXJcblx0ICogaG92ZXJpbmcgdGhlIHRvb2x0aXAgc2hvdWxkIGNhdXNlIHRoZSBhY3RpdmUgc2VyaWVzIHRvIG1vdXNlIG91dC5cblx0ICovXG5cdGluQ2xhc3M6IGZ1bmN0aW9uIChlbGVtZW50LCBjbGFzc05hbWUpIHtcblx0XHR2YXIgZWxlbUNsYXNzTmFtZTtcblx0XHR3aGlsZSAoZWxlbWVudCkge1xuXHRcdFx0ZWxlbUNsYXNzTmFtZSA9IGF0dHIoZWxlbWVudCwgJ2NsYXNzJyk7XG5cdFx0XHRpZiAoZWxlbUNsYXNzTmFtZSkge1xuXHRcdFx0XHRpZiAoZWxlbUNsYXNzTmFtZS5pbmRleE9mKGNsYXNzTmFtZSkgIT09IC0xKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH0gZWxzZSBpZiAoZWxlbUNsYXNzTmFtZS5pbmRleE9mKFBSRUZJWCArICdjb250YWluZXInKSAhPT0gLTEpIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG5cdFx0fVx0XHRcblx0fSxcblxuXHRvblRyYWNrZXJNb3VzZU91dDogZnVuY3Rpb24gKGUpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcy5jaGFydC5ob3ZlclNlcmllcyxcblx0XHRcdHJlbGF0ZWRUYXJnZXQgPSBlLnJlbGF0ZWRUYXJnZXQgfHwgZS50b0VsZW1lbnQsXG5cdFx0XHRyZWxhdGVkU2VyaWVzID0gcmVsYXRlZFRhcmdldCAmJiByZWxhdGVkVGFyZ2V0LnBvaW50ICYmIHJlbGF0ZWRUYXJnZXQucG9pbnQuc2VyaWVzOyAvLyAjMjQ5OVxuXHRcdFxuXHRcdGlmIChzZXJpZXMgJiYgIXNlcmllcy5vcHRpb25zLnN0aWNreVRyYWNraW5nICYmICF0aGlzLmluQ2xhc3MocmVsYXRlZFRhcmdldCwgUFJFRklYICsgJ3Rvb2x0aXAnKSAmJlxuXHRcdFx0XHRyZWxhdGVkU2VyaWVzICE9PSBzZXJpZXMpIHtcblx0XHRcdHNlcmllcy5vbk1vdXNlT3V0KCk7XG5cdFx0fVxuXHR9LFxuXG5cdG9uQ29udGFpbmVyQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdGhvdmVyUG9pbnQgPSBjaGFydC5ob3ZlclBvaW50LCBcblx0XHRcdHBsb3RMZWZ0ID0gY2hhcnQucGxvdExlZnQsXG5cdFx0XHRwbG90VG9wID0gY2hhcnQucGxvdFRvcDtcblx0XHRcblx0XHRlID0gdGhpcy5ub3JtYWxpemUoZSk7XG5cdFx0ZS5jYW5jZWxCdWJibGUgPSB0cnVlOyAvLyBJRSBzcGVjaWZpY1xuXG5cdFx0aWYgKCFjaGFydC5jYW5jZWxDbGljaykge1xuXHRcdFx0XG5cdFx0XHQvLyBPbiB0cmFja2VyIGNsaWNrLCBmaXJlIHRoZSBzZXJpZXMgYW5kIHBvaW50IGV2ZW50cy4gIzc4MywgIzE1ODNcblx0XHRcdGlmIChob3ZlclBvaW50ICYmIHRoaXMuaW5DbGFzcyhlLnRhcmdldCwgUFJFRklYICsgJ3RyYWNrZXInKSkge1xuXG5cdFx0XHRcdC8vIHRoZSBzZXJpZXMgY2xpY2sgZXZlbnRcblx0XHRcdFx0ZmlyZUV2ZW50KGhvdmVyUG9pbnQuc2VyaWVzLCAnY2xpY2snLCBleHRlbmQoZSwge1xuXHRcdFx0XHRcdHBvaW50OiBob3ZlclBvaW50XG5cdFx0XHRcdH0pKTtcblxuXHRcdFx0XHQvLyB0aGUgcG9pbnQgY2xpY2sgZXZlbnRcblx0XHRcdFx0aWYgKGNoYXJ0LmhvdmVyUG9pbnQpIHsgLy8gaXQgbWF5IGJlIGRlc3Ryb3llZCAoIzE4NDQpXG5cdFx0XHRcdFx0aG92ZXJQb2ludC5maXJlUG9pbnRFdmVudCgnY2xpY2snLCBlKTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBXaGVuIGNsaWNraW5nIG91dHNpZGUgYSB0cmFja2VyLCBmaXJlIGEgY2hhcnQgZXZlbnRcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGV4dGVuZChlLCB0aGlzLmdldENvb3JkaW5hdGVzKGUpKTtcblxuXHRcdFx0XHQvLyBmaXJlIGEgY2xpY2sgZXZlbnQgaW4gdGhlIGNoYXJ0XG5cdFx0XHRcdGlmIChjaGFydC5pc0luc2lkZVBsb3QoZS5jaGFydFggLSBwbG90TGVmdCwgZS5jaGFydFkgLSBwbG90VG9wKSkge1xuXHRcdFx0XHRcdGZpcmVFdmVudChjaGFydCwgJ2NsaWNrJywgZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIEpTIERPTSBldmVudHMgb24gdGhlIGNvbnRhaW5lciBhbmQgZG9jdW1lbnQuIFRoaXMgbWV0aG9kIHNob3VsZCBjb250YWluXG5cdCAqIGEgb25lLXRvLW9uZSBhc3NpZ25tZW50IGJldHdlZW4gbWV0aG9kcyBhbmQgdGhlaXIgaGFuZGxlcnMuIEFueSBhZHZhbmNlZCBsb2dpYyBzaG91bGRcblx0ICogYmUgbW92ZWQgdG8gdGhlIGhhbmRsZXIgcmVmbGVjdGluZyB0aGUgZXZlbnQncyBuYW1lLlxuXHQgKi9cblx0c2V0RE9NRXZlbnRzOiBmdW5jdGlvbiAoKSB7XG5cblx0XHR2YXIgcG9pbnRlciA9IHRoaXMsXG5cdFx0XHRjb250YWluZXIgPSBwb2ludGVyLmNoYXJ0LmNvbnRhaW5lcjtcblxuXHRcdGNvbnRhaW5lci5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRwb2ludGVyLm9uQ29udGFpbmVyTW91c2VEb3duKGUpO1xuXHRcdH07XG5cdFx0Y29udGFpbmVyLm9ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKGUpIHtcblx0XHRcdHBvaW50ZXIub25Db250YWluZXJNb3VzZU1vdmUoZSk7XG5cdFx0fTtcblx0XHRjb250YWluZXIub25jbGljayA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRwb2ludGVyLm9uQ29udGFpbmVyQ2xpY2soZSk7XG5cdFx0fTtcblx0XHRhZGRFdmVudChjb250YWluZXIsICdtb3VzZWxlYXZlJywgcG9pbnRlci5vbkNvbnRhaW5lck1vdXNlTGVhdmUpO1xuXHRcdGlmIChjaGFydENvdW50ID09PSAxKSB7XG5cdFx0XHRhZGRFdmVudChkb2MsICdtb3VzZXVwJywgcG9pbnRlci5vbkRvY3VtZW50TW91c2VVcCk7XG5cdFx0fVxuXHRcdGlmIChoYXNUb3VjaCkge1xuXHRcdFx0Y29udGFpbmVyLm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdHBvaW50ZXIub25Db250YWluZXJUb3VjaFN0YXJ0KGUpO1xuXHRcdFx0fTtcblx0XHRcdGNvbnRhaW5lci5vbnRvdWNobW92ZSA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdHBvaW50ZXIub25Db250YWluZXJUb3VjaE1vdmUoZSk7XG5cdFx0XHR9O1xuXHRcdFx0aWYgKGNoYXJ0Q291bnQgPT09IDEpIHtcblx0XHRcdFx0YWRkRXZlbnQoZG9jLCAndG91Y2hlbmQnLCBwb2ludGVyLm9uRG9jdW1lbnRUb3VjaEVuZCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95cyB0aGUgUG9pbnRlciBvYmplY3QgYW5kIGRpc2Nvbm5lY3RzIERPTSBldmVudHMuXG5cdCAqL1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHByb3A7XG5cblx0XHRyZW1vdmVFdmVudCh0aGlzLmNoYXJ0LmNvbnRhaW5lciwgJ21vdXNlbGVhdmUnLCB0aGlzLm9uQ29udGFpbmVyTW91c2VMZWF2ZSk7XG5cdFx0aWYgKCFjaGFydENvdW50KSB7XG5cdFx0XHRyZW1vdmVFdmVudChkb2MsICdtb3VzZXVwJywgdGhpcy5vbkRvY3VtZW50TW91c2VVcCk7XG5cdFx0XHRyZW1vdmVFdmVudChkb2MsICd0b3VjaGVuZCcsIHRoaXMub25Eb2N1bWVudFRvdWNoRW5kKTtcblx0XHR9XG5cblx0XHQvLyBtZW1vcnkgYW5kIENQVSBsZWFrXG5cdFx0Y2xlYXJJbnRlcnZhbCh0aGlzLnRvb2x0aXBUaW1lb3V0KTtcblxuXHRcdGZvciAocHJvcCBpbiB0aGlzKSB7XG5cdFx0XHR0aGlzW3Byb3BdID0gbnVsbDtcblx0XHR9XG5cdH1cbn07XG5cblxuLyogU3VwcG9ydCBmb3IgdG91Y2ggZGV2aWNlcyAqL1xuZXh0ZW5kKEhpZ2hjaGFydHMuUG9pbnRlci5wcm90b3R5cGUsIHtcblxuXHQvKipcblx0ICogUnVuIHRyYW5zbGF0aW9uIG9wZXJhdGlvbnNcblx0ICovXG5cdHBpbmNoVHJhbnNsYXRlOiBmdW5jdGlvbiAocGluY2hEb3duLCB0b3VjaGVzLCB0cmFuc2Zvcm0sIHNlbGVjdGlvbk1hcmtlciwgY2xpcCwgbGFzdFZhbGlkVG91Y2gpIHtcblx0XHRpZiAodGhpcy56b29tSG9yIHx8IHRoaXMucGluY2hIb3IpIHtcblx0XHRcdHRoaXMucGluY2hUcmFuc2xhdGVEaXJlY3Rpb24odHJ1ZSwgcGluY2hEb3duLCB0b3VjaGVzLCB0cmFuc2Zvcm0sIHNlbGVjdGlvbk1hcmtlciwgY2xpcCwgbGFzdFZhbGlkVG91Y2gpO1xuXHRcdH1cblx0XHRpZiAodGhpcy56b29tVmVydCB8fCB0aGlzLnBpbmNoVmVydCkge1xuXHRcdFx0dGhpcy5waW5jaFRyYW5zbGF0ZURpcmVjdGlvbihmYWxzZSwgcGluY2hEb3duLCB0b3VjaGVzLCB0cmFuc2Zvcm0sIHNlbGVjdGlvbk1hcmtlciwgY2xpcCwgbGFzdFZhbGlkVG91Y2gpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUnVuIHRyYW5zbGF0aW9uIG9wZXJhdGlvbnMgZm9yIGVhY2ggZGlyZWN0aW9uIChob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCkgaW5kZXBlbmRlbnRseVxuXHQgKi9cblx0cGluY2hUcmFuc2xhdGVEaXJlY3Rpb246IGZ1bmN0aW9uIChob3JpeiwgcGluY2hEb3duLCB0b3VjaGVzLCB0cmFuc2Zvcm0sIHNlbGVjdGlvbk1hcmtlciwgY2xpcCwgbGFzdFZhbGlkVG91Y2gsIGZvcmNlZFNjYWxlKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdHh5ID0gaG9yaXogPyAneCcgOiAneScsXG5cdFx0XHRYWSA9IGhvcml6ID8gJ1gnIDogJ1knLFxuXHRcdFx0c0NoYXJ0WFkgPSAnY2hhcnQnICsgWFksXG5cdFx0XHR3aCA9IGhvcml6ID8gJ3dpZHRoJyA6ICdoZWlnaHQnLFxuXHRcdFx0cGxvdExlZnRUb3AgPSBjaGFydFsncGxvdCcgKyAoaG9yaXogPyAnTGVmdCcgOiAnVG9wJyldLFxuXHRcdFx0c2VsZWN0aW9uV0gsXG5cdFx0XHRzZWxlY3Rpb25YWSxcblx0XHRcdGNsaXBYWSxcblx0XHRcdHNjYWxlID0gZm9yY2VkU2NhbGUgfHwgMSxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQsXG5cdFx0XHRib3VuZHMgPSBjaGFydC5ib3VuZHNbaG9yaXogPyAnaCcgOiAndiddLFxuXHRcdFx0c2luZ2xlVG91Y2ggPSBwaW5jaERvd24ubGVuZ3RoID09PSAxLFxuXHRcdFx0dG91Y2gwU3RhcnQgPSBwaW5jaERvd25bMF1bc0NoYXJ0WFldLFxuXHRcdFx0dG91Y2gwTm93ID0gdG91Y2hlc1swXVtzQ2hhcnRYWV0sXG5cdFx0XHR0b3VjaDFTdGFydCA9ICFzaW5nbGVUb3VjaCAmJiBwaW5jaERvd25bMV1bc0NoYXJ0WFldLFxuXHRcdFx0dG91Y2gxTm93ID0gIXNpbmdsZVRvdWNoICYmIHRvdWNoZXNbMV1bc0NoYXJ0WFldLFxuXHRcdFx0b3V0T2ZCb3VuZHMsXG5cdFx0XHR0cmFuc2Zvcm1TY2FsZSxcblx0XHRcdHNjYWxlS2V5LFxuXHRcdFx0c2V0U2NhbGUgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmICghc2luZ2xlVG91Y2ggJiYgbWF0aEFicyh0b3VjaDBTdGFydCAtIHRvdWNoMVN0YXJ0KSA+IDIwKSB7IC8vIERvbid0IHpvb20gaWYgZmluZ2VycyBhcmUgdG9vIGNsb3NlIG9uIHRoaXMgYXhpc1xuXHRcdFx0XHRcdHNjYWxlID0gZm9yY2VkU2NhbGUgfHwgbWF0aEFicyh0b3VjaDBOb3cgLSB0b3VjaDFOb3cpIC8gbWF0aEFicyh0b3VjaDBTdGFydCAtIHRvdWNoMVN0YXJ0KTsgXG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdGNsaXBYWSA9ICgocGxvdExlZnRUb3AgLSB0b3VjaDBOb3cpIC8gc2NhbGUpICsgdG91Y2gwU3RhcnQ7XG5cdFx0XHRcdHNlbGVjdGlvbldIID0gY2hhcnRbJ3Bsb3QnICsgKGhvcml6ID8gJ1dpZHRoJyA6ICdIZWlnaHQnKV0gLyBzY2FsZTtcblx0XHRcdH07XG5cblx0XHQvLyBTZXQgdGhlIHNjYWxlLCBmaXJzdCBwYXNzXG5cdFx0c2V0U2NhbGUoKTtcblxuXHRcdHNlbGVjdGlvblhZID0gY2xpcFhZOyAvLyB0aGUgY2xpcCBwb3NpdGlvbiAoeCBvciB5KSBpcyBhbHRlcmVkIGlmIG91dCBvZiBib3VuZHMsIHRoZSBzZWxlY3Rpb24gcG9zaXRpb24gaXMgbm90XG5cblx0XHQvLyBPdXQgb2YgYm91bmRzXG5cdFx0aWYgKHNlbGVjdGlvblhZIDwgYm91bmRzLm1pbikge1xuXHRcdFx0c2VsZWN0aW9uWFkgPSBib3VuZHMubWluO1xuXHRcdFx0b3V0T2ZCb3VuZHMgPSB0cnVlO1xuXHRcdH0gZWxzZSBpZiAoc2VsZWN0aW9uWFkgKyBzZWxlY3Rpb25XSCA+IGJvdW5kcy5tYXgpIHtcblx0XHRcdHNlbGVjdGlvblhZID0gYm91bmRzLm1heCAtIHNlbGVjdGlvbldIO1xuXHRcdFx0b3V0T2ZCb3VuZHMgPSB0cnVlO1xuXHRcdH1cblx0XHRcblx0XHQvLyBJcyB0aGUgY2hhcnQgZHJhZ2dlZCBvZmYgaXRzIGJvdW5kcywgZGV0ZXJtaW5lZCBieSBkYXRhTWluIGFuZCBkYXRhTWF4P1xuXHRcdGlmIChvdXRPZkJvdW5kcykge1xuXG5cdFx0XHQvLyBNb2RpZnkgdGhlIHRvdWNoTm93IHBvc2l0aW9uIGluIG9yZGVyIHRvIGNyZWF0ZSBhbiBlbGFzdGljIGRyYWcgbW92ZW1lbnQuIFRoaXMgaW5kaWNhdGVzXG5cdFx0XHQvLyB0byB0aGUgdXNlciB0aGF0IHRoZSBjaGFydCBpcyByZXNwb25zaXZlIGJ1dCBjYW4ndCBiZSBkcmFnZ2VkIGZ1cnRoZXIuXG5cdFx0XHR0b3VjaDBOb3cgLT0gMC44ICogKHRvdWNoME5vdyAtIGxhc3RWYWxpZFRvdWNoW3h5XVswXSk7XG5cdFx0XHRpZiAoIXNpbmdsZVRvdWNoKSB7XG5cdFx0XHRcdHRvdWNoMU5vdyAtPSAwLjggKiAodG91Y2gxTm93IC0gbGFzdFZhbGlkVG91Y2hbeHldWzFdKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IHRoZSBzY2FsZSwgc2Vjb25kIHBhc3MgdG8gYWRhcHQgdG8gdGhlIG1vZGlmaWVkIHRvdWNoTm93IHBvc2l0aW9uc1xuXHRcdFx0c2V0U2NhbGUoKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRsYXN0VmFsaWRUb3VjaFt4eV0gPSBbdG91Y2gwTm93LCB0b3VjaDFOb3ddO1xuXHRcdH1cblxuXHRcdC8vIFNldCBnZW9tZXRyeSBmb3IgY2xpcHBpbmcsIHNlbGVjdGlvbiBhbmQgdHJhbnNmb3JtYXRpb25cblx0XHRpZiAoIWludmVydGVkKSB7IC8vIFRPRE86IGltcGxlbWVudCBjbGlwcGluZyBmb3IgaW52ZXJ0ZWQgY2hhcnRzXG5cdFx0XHRjbGlwW3h5XSA9IGNsaXBYWSAtIHBsb3RMZWZ0VG9wO1xuXHRcdFx0Y2xpcFt3aF0gPSBzZWxlY3Rpb25XSDtcblx0XHR9XG5cdFx0c2NhbGVLZXkgPSBpbnZlcnRlZCA/IChob3JpeiA/ICdzY2FsZVknIDogJ3NjYWxlWCcpIDogJ3NjYWxlJyArIFhZO1xuXHRcdHRyYW5zZm9ybVNjYWxlID0gaW52ZXJ0ZWQgPyAxIC8gc2NhbGUgOiBzY2FsZTtcblxuXHRcdHNlbGVjdGlvbk1hcmtlclt3aF0gPSBzZWxlY3Rpb25XSDtcblx0XHRzZWxlY3Rpb25NYXJrZXJbeHldID0gc2VsZWN0aW9uWFk7XG5cdFx0dHJhbnNmb3JtW3NjYWxlS2V5XSA9IHNjYWxlO1xuXHRcdHRyYW5zZm9ybVsndHJhbnNsYXRlJyArIFhZXSA9ICh0cmFuc2Zvcm1TY2FsZSAqIHBsb3RMZWZ0VG9wKSArICh0b3VjaDBOb3cgLSAodHJhbnNmb3JtU2NhbGUgKiB0b3VjaDBTdGFydCkpO1xuXHR9LFxuXHRcblx0LyoqXG5cdCAqIEhhbmRsZSB0b3VjaCBldmVudHMgd2l0aCB0d28gdG91Y2hlc1xuXHQgKi9cblx0cGluY2g6IGZ1bmN0aW9uIChlKSB7XG5cblx0XHR2YXIgc2VsZiA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlbGYuY2hhcnQsXG5cdFx0XHRwaW5jaERvd24gPSBzZWxmLnBpbmNoRG93bixcblx0XHRcdGZvbGxvd1RvdWNoTW92ZSA9IHNlbGYuZm9sbG93VG91Y2hNb3ZlLFxuXHRcdFx0dG91Y2hlcyA9IGUudG91Y2hlcyxcblx0XHRcdHRvdWNoZXNMZW5ndGggPSB0b3VjaGVzLmxlbmd0aCxcblx0XHRcdGxhc3RWYWxpZFRvdWNoID0gc2VsZi5sYXN0VmFsaWRUb3VjaCxcblx0XHRcdGhhc1pvb20gPSBzZWxmLmhhc1pvb20sXG5cdFx0XHRzZWxlY3Rpb25NYXJrZXIgPSBzZWxmLnNlbGVjdGlvbk1hcmtlcixcblx0XHRcdHRyYW5zZm9ybSA9IHt9LFxuXHRcdFx0ZmlyZUNsaWNrRXZlbnQgPSB0b3VjaGVzTGVuZ3RoID09PSAxICYmICgoc2VsZi5pbkNsYXNzKGUudGFyZ2V0LCBQUkVGSVggKyAndHJhY2tlcicpICYmIFxuXHRcdFx0XHRjaGFydC5ydW5UcmFja2VyQ2xpY2spIHx8IHNlbGYucnVuQ2hhcnRDbGljayksXG5cdFx0XHRjbGlwID0ge307XG5cblx0XHQvLyBPbiB0b3VjaCBkZXZpY2VzLCBvbmx5IHByb2NlZWQgdG8gdHJpZ2dlciBjbGljayBpZiBhIGhhbmRsZXIgaXMgZGVmaW5lZFxuXHRcdGlmICgoaGFzWm9vbSB8fCBmb2xsb3dUb3VjaE1vdmUpICYmICFmaXJlQ2xpY2tFdmVudCkge1xuXHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH1cblx0XHRcblx0XHQvLyBOb3JtYWxpemUgZWFjaCB0b3VjaFxuXHRcdG1hcCh0b3VjaGVzLCBmdW5jdGlvbiAoZSkge1xuXHRcdFx0cmV0dXJuIHNlbGYubm9ybWFsaXplKGUpO1xuXHRcdH0pO1xuXHRcdFxuXHRcdC8vIFJlZ2lzdGVyIHRoZSB0b3VjaCBzdGFydCBwb3NpdGlvblxuXHRcdGlmIChlLnR5cGUgPT09ICd0b3VjaHN0YXJ0Jykge1xuXHRcdFx0ZWFjaCh0b3VjaGVzLCBmdW5jdGlvbiAoZSwgaSkge1xuXHRcdFx0XHRwaW5jaERvd25baV0gPSB7IGNoYXJ0WDogZS5jaGFydFgsIGNoYXJ0WTogZS5jaGFydFkgfTtcblx0XHRcdH0pO1xuXHRcdFx0bGFzdFZhbGlkVG91Y2gueCA9IFtwaW5jaERvd25bMF0uY2hhcnRYLCBwaW5jaERvd25bMV0gJiYgcGluY2hEb3duWzFdLmNoYXJ0WF07XG5cdFx0XHRsYXN0VmFsaWRUb3VjaC55ID0gW3BpbmNoRG93blswXS5jaGFydFksIHBpbmNoRG93blsxXSAmJiBwaW5jaERvd25bMV0uY2hhcnRZXTtcblxuXHRcdFx0Ly8gSWRlbnRpZnkgdGhlIGRhdGEgYm91bmRzIGluIHBpeGVsc1xuXHRcdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRpZiAoYXhpcy56b29tRW5hYmxlZCkge1xuXHRcdFx0XHRcdHZhciBib3VuZHMgPSBjaGFydC5ib3VuZHNbYXhpcy5ob3JpeiA/ICdoJyA6ICd2J10sXG5cdFx0XHRcdFx0XHRtaW5QaXhlbFBhZGRpbmcgPSBheGlzLm1pblBpeGVsUGFkZGluZyxcblx0XHRcdFx0XHRcdG1pbiA9IGF4aXMudG9QaXhlbHMocGljayhheGlzLm9wdGlvbnMubWluLCBheGlzLmRhdGFNaW4pKSxcblx0XHRcdFx0XHRcdG1heCA9IGF4aXMudG9QaXhlbHMocGljayhheGlzLm9wdGlvbnMubWF4LCBheGlzLmRhdGFNYXgpKSxcblx0XHRcdFx0XHRcdGFic01pbiA9IG1hdGhNaW4obWluLCBtYXgpLFxuXHRcdFx0XHRcdFx0YWJzTWF4ID0gbWF0aE1heChtaW4sIG1heCk7XG5cblx0XHRcdFx0XHQvLyBTdG9yZSB0aGUgYm91bmRzIGZvciB1c2UgaW4gdGhlIHRvdWNobW92ZSBoYW5kbGVyXG5cdFx0XHRcdFx0Ym91bmRzLm1pbiA9IG1hdGhNaW4oYXhpcy5wb3MsIGFic01pbiAtIG1pblBpeGVsUGFkZGluZyk7XG5cdFx0XHRcdFx0Ym91bmRzLm1heCA9IG1hdGhNYXgoYXhpcy5wb3MgKyBheGlzLmxlbiwgYWJzTWF4ICsgbWluUGl4ZWxQYWRkaW5nKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnJlcyA9IHRydWU7IC8vIHJlc2V0IG9uIG5leHQgbW92ZVxuXHRcdFxuXHRcdC8vIEV2ZW50IHR5cGUgaXMgdG91Y2htb3ZlLCBoYW5kbGUgcGFubmluZyBhbmQgcGluY2hpbmdcblx0XHR9IGVsc2UgaWYgKHBpbmNoRG93bi5sZW5ndGgpIHsgLy8gY2FuIGJlIDAgd2hlbiByZWxlYXNpbmcsIGlmIHRvdWNoZW5kIGZpcmVzIGZpcnN0XG5cdFx0XHRcblxuXHRcdFx0Ly8gU2V0IHRoZSBtYXJrZXJcblx0XHRcdGlmICghc2VsZWN0aW9uTWFya2VyKSB7XG5cdFx0XHRcdHNlbGYuc2VsZWN0aW9uTWFya2VyID0gc2VsZWN0aW9uTWFya2VyID0gZXh0ZW5kKHtcblx0XHRcdFx0XHRkZXN0cm95OiBub29wXG5cdFx0XHRcdH0sIGNoYXJ0LnBsb3RCb3gpO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHRzZWxmLnBpbmNoVHJhbnNsYXRlKHBpbmNoRG93biwgdG91Y2hlcywgdHJhbnNmb3JtLCBzZWxlY3Rpb25NYXJrZXIsIGNsaXAsIGxhc3RWYWxpZFRvdWNoKTtcblxuXHRcdFx0c2VsZi5oYXNQaW5jaGVkID0gaGFzWm9vbTtcblxuXHRcdFx0Ly8gU2NhbGUgYW5kIHRyYW5zbGF0ZSB0aGUgZ3JvdXBzIHRvIHByb3ZpZGUgdmlzdWFsIGZlZWRiYWNrIGR1cmluZyBwaW5jaGluZ1xuXHRcdFx0c2VsZi5zY2FsZUdyb3Vwcyh0cmFuc2Zvcm0sIGNsaXApO1xuXHRcdFx0XG5cdFx0XHQvLyBPcHRpb25hbGx5IG1vdmUgdGhlIHRvb2x0aXAgb24gdG91Y2htb3ZlXG5cdFx0XHRpZiAoIWhhc1pvb20gJiYgZm9sbG93VG91Y2hNb3ZlICYmIHRvdWNoZXNMZW5ndGggPT09IDEpIHtcblx0XHRcdFx0dGhpcy5ydW5Qb2ludEFjdGlvbnMoc2VsZi5ub3JtYWxpemUoZSkpO1xuXHRcdFx0fSBlbHNlIGlmIChzZWxmLnJlcykge1xuXHRcdFx0XHRzZWxmLnJlcyA9IGZhbHNlO1xuXHRcdFx0XHR0aGlzLnJlc2V0KGZhbHNlLCAwKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0b25Db250YWluZXJUb3VjaFN0YXJ0OiBmdW5jdGlvbiAoZSkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XG5cblx0XHRob3ZlckNoYXJ0SW5kZXggPSBjaGFydC5pbmRleDtcblxuXHRcdGlmIChlLnRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG5cblx0XHRcdGUgPSB0aGlzLm5vcm1hbGl6ZShlKTtcblxuXHRcdFx0aWYgKGNoYXJ0LmlzSW5zaWRlUGxvdChlLmNoYXJ0WCAtIGNoYXJ0LnBsb3RMZWZ0LCBlLmNoYXJ0WSAtIGNoYXJ0LnBsb3RUb3ApKSB7XG5cblx0XHRcdFx0Ly8gUnVuIG1vdXNlIGV2ZW50cyBhbmQgZGlzcGxheSB0b29sdGlwIGV0Y1xuXHRcdFx0XHR0aGlzLnJ1blBvaW50QWN0aW9ucyhlKTtcblxuXHRcdFx0XHR0aGlzLnBpbmNoKGUpO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBIaWRlIHRoZSB0b29sdGlwIG9uIHRvdWNoaW5nIG91dHNpZGUgdGhlIHBsb3QgYXJlYSAoIzEyMDMpXG5cdFx0XHRcdHRoaXMucmVzZXQoKTtcblx0XHRcdH1cblxuXHRcdH0gZWxzZSBpZiAoZS50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuXHRcdFx0dGhpcy5waW5jaChlKTtcblx0XHR9ICAgXG5cdH0sXG5cblx0b25Db250YWluZXJUb3VjaE1vdmU6IGZ1bmN0aW9uIChlKSB7XG5cdFx0aWYgKGUudG91Y2hlcy5sZW5ndGggPT09IDEgfHwgZS50b3VjaGVzLmxlbmd0aCA9PT0gMikge1xuXHRcdFx0dGhpcy5waW5jaChlKTtcblx0XHR9XG5cdH0sXG5cblx0b25Eb2N1bWVudFRvdWNoRW5kOiBmdW5jdGlvbiAoZSkge1xuXHRcdGlmIChjaGFydHNbaG92ZXJDaGFydEluZGV4XSkge1xuXHRcdFx0Y2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0ucG9pbnRlci5kcm9wKGUpO1xuXHRcdH1cblx0fVxuXG59KTtcbmlmICh3aW4uUG9pbnRlckV2ZW50IHx8IHdpbi5NU1BvaW50ZXJFdmVudCkge1xuXHRcblx0Ly8gVGhlIHRvdWNoZXMgb2JqZWN0IGtlZXBzIHRyYWNrIG9mIHRoZSBwb2ludHMgYmVpbmcgdG91Y2hlZCBhdCBhbGwgdGltZXNcblx0dmFyIHRvdWNoZXMgPSB7fSxcblx0XHRoYXNQb2ludGVyRXZlbnQgPSAhIXdpbi5Qb2ludGVyRXZlbnQsXG5cdFx0Z2V0V2Via2l0VG91Y2hlcyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciBrZXksIGZha2UgPSBbXTtcblx0XHRcdGZha2UuaXRlbSA9IGZ1bmN0aW9uIChpKSB7IHJldHVybiB0aGlzW2ldOyB9O1xuXHRcdFx0Zm9yIChrZXkgaW4gdG91Y2hlcykge1xuXHRcdFx0XHRpZiAodG91Y2hlcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdFx0ZmFrZS5wdXNoKHtcblx0XHRcdFx0XHRcdHBhZ2VYOiB0b3VjaGVzW2tleV0ucGFnZVgsXG5cdFx0XHRcdFx0XHRwYWdlWTogdG91Y2hlc1trZXldLnBhZ2VZLFxuXHRcdFx0XHRcdFx0dGFyZ2V0OiB0b3VjaGVzW2tleV0udGFyZ2V0XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWtlO1xuXHRcdH0sXG5cdFx0dHJhbnNsYXRlTVNQb2ludGVyID0gZnVuY3Rpb24gKGUsIG1ldGhvZCwgd2t0eXBlLCBjYWxsYmFjaykge1xuXHRcdFx0dmFyIHA7XG5cdFx0XHRlID0gZS5vcmlnaW5hbEV2ZW50IHx8IGU7XG5cdFx0XHRpZiAoKGUucG9pbnRlclR5cGUgPT09ICd0b3VjaCcgfHwgZS5wb2ludGVyVHlwZSA9PT0gZS5NU1BPSU5URVJfVFlQRV9UT1VDSCkgJiYgY2hhcnRzW2hvdmVyQ2hhcnRJbmRleF0pIHtcblx0XHRcdFx0Y2FsbGJhY2soZSk7XG5cdFx0XHRcdHAgPSBjaGFydHNbaG92ZXJDaGFydEluZGV4XS5wb2ludGVyO1xuXHRcdFx0XHRwW21ldGhvZF0oe1xuXHRcdFx0XHRcdHR5cGU6IHdrdHlwZSxcblx0XHRcdFx0XHR0YXJnZXQ6IGUuY3VycmVudFRhcmdldCxcblx0XHRcdFx0XHRwcmV2ZW50RGVmYXVsdDogbm9vcCxcblx0XHRcdFx0XHR0b3VjaGVzOiBnZXRXZWJraXRUb3VjaGVzKClcblx0XHRcdFx0fSk7XHRcdFx0XHRcblx0XHRcdH1cblx0XHR9O1xuXG5cdC8qKlxuXHQgKiBFeHRlbmQgdGhlIFBvaW50ZXIgcHJvdG90eXBlIHdpdGggbWV0aG9kcyBmb3IgZWFjaCBldmVudCBoYW5kbGVyIGFuZCBtb3JlXG5cdCAqL1xuXHRleHRlbmQoUG9pbnRlci5wcm90b3R5cGUsIHtcblx0XHRvbkNvbnRhaW5lclBvaW50ZXJEb3duOiBmdW5jdGlvbiAoZSkge1xuXHRcdFx0dHJhbnNsYXRlTVNQb2ludGVyKGUsICdvbkNvbnRhaW5lclRvdWNoU3RhcnQnLCAndG91Y2hzdGFydCcsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdHRvdWNoZXNbZS5wb2ludGVySWRdID0geyBwYWdlWDogZS5wYWdlWCwgcGFnZVk6IGUucGFnZVksIHRhcmdldDogZS5jdXJyZW50VGFyZ2V0IH07XG5cdFx0XHR9KTtcblx0XHR9LFxuXHRcdG9uQ29udGFpbmVyUG9pbnRlck1vdmU6IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHR0cmFuc2xhdGVNU1BvaW50ZXIoZSwgJ29uQ29udGFpbmVyVG91Y2hNb3ZlJywgJ3RvdWNobW92ZScsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdHRvdWNoZXNbZS5wb2ludGVySWRdID0geyBwYWdlWDogZS5wYWdlWCwgcGFnZVk6IGUucGFnZVkgfTtcblx0XHRcdFx0aWYgKCF0b3VjaGVzW2UucG9pbnRlcklkXS50YXJnZXQpIHtcblx0XHRcdFx0XHR0b3VjaGVzW2UucG9pbnRlcklkXS50YXJnZXQgPSBlLmN1cnJlbnRUYXJnZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0sXG5cdFx0b25Eb2N1bWVudFBvaW50ZXJVcDogZnVuY3Rpb24gKGUpIHtcblx0XHRcdHRyYW5zbGF0ZU1TUG9pbnRlcihlLCAnb25Db250YWluZXJUb3VjaEVuZCcsICd0b3VjaGVuZCcsIGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdGRlbGV0ZSB0b3VjaGVzW2UucG9pbnRlcklkXTtcblx0XHRcdH0pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBBZGQgb3IgcmVtb3ZlIHRoZSBNUyBQb2ludGVyIHNwZWNpZmljIGV2ZW50c1xuXHRcdCAqL1xuXHRcdGJhdGNoTVNFdmVudHM6IGZ1bmN0aW9uIChmbikge1xuXHRcdFx0Zm4odGhpcy5jaGFydC5jb250YWluZXIsIGhhc1BvaW50ZXJFdmVudCA/ICdwb2ludGVyZG93bicgOiAnTVNQb2ludGVyRG93bicsIHRoaXMub25Db250YWluZXJQb2ludGVyRG93bik7XG5cdFx0XHRmbih0aGlzLmNoYXJ0LmNvbnRhaW5lciwgaGFzUG9pbnRlckV2ZW50ID8gJ3BvaW50ZXJtb3ZlJyA6ICdNU1BvaW50ZXJNb3ZlJywgdGhpcy5vbkNvbnRhaW5lclBvaW50ZXJNb3ZlKTtcblx0XHRcdGZuKGRvYywgaGFzUG9pbnRlckV2ZW50ID8gJ3BvaW50ZXJ1cCcgOiAnTVNQb2ludGVyVXAnLCB0aGlzLm9uRG9jdW1lbnRQb2ludGVyVXApO1xuXHRcdH1cblx0fSk7XG5cblx0Ly8gRGlzYWJsZSBkZWZhdWx0IElFIGFjdGlvbnMgZm9yIHBpbmNoIGFuZCBzdWNoIG9uIGNoYXJ0IGVsZW1lbnRcblx0d3JhcChQb2ludGVyLnByb3RvdHlwZSwgJ2luaXQnLCBmdW5jdGlvbiAocHJvY2VlZCwgY2hhcnQsIG9wdGlvbnMpIHtcblx0XHRwcm9jZWVkLmNhbGwodGhpcywgY2hhcnQsIG9wdGlvbnMpO1xuXHRcdGlmICh0aGlzLmhhc1pvb20gfHwgdGhpcy5mb2xsb3dUb3VjaE1vdmUpIHtcblx0XHRcdGNzcyhjaGFydC5jb250YWluZXIsIHtcblx0XHRcdFx0Jy1tcy10b3VjaC1hY3Rpb24nOiBOT05FLFxuXHRcdFx0XHQndG91Y2gtYWN0aW9uJzogTk9ORVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9KTtcblxuXHQvLyBBZGQgSUUgc3BlY2lmaWMgdG91Y2ggZXZlbnRzIHRvIGNoYXJ0XG5cdHdyYXAoUG9pbnRlci5wcm90b3R5cGUsICdzZXRET01FdmVudHMnLCBmdW5jdGlvbiAocHJvY2VlZCkge1xuXHRcdHByb2NlZWQuYXBwbHkodGhpcyk7XG5cdFx0aWYgKHRoaXMuaGFzWm9vbSB8fCB0aGlzLmZvbGxvd1RvdWNoTW92ZSkge1xuXHRcdFx0dGhpcy5iYXRjaE1TRXZlbnRzKGFkZEV2ZW50KTtcblx0XHR9XG5cdH0pO1xuXHQvLyBEZXN0cm95IE1TIGV2ZW50cyBhbHNvXG5cdHdyYXAoUG9pbnRlci5wcm90b3R5cGUsICdkZXN0cm95JywgZnVuY3Rpb24gKHByb2NlZWQpIHtcblx0XHR0aGlzLmJhdGNoTVNFdmVudHMocmVtb3ZlRXZlbnQpO1xuXHRcdHByb2NlZWQuY2FsbCh0aGlzKTtcblx0fSk7XG59XG4vKipcbiAqIFRoZSBvdmVydmlldyBvZiB0aGUgY2hhcnQncyBzZXJpZXNcbiAqL1xudmFyIExlZ2VuZCA9IEhpZ2hjaGFydHMuTGVnZW5kID0gZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cdHRoaXMuaW5pdChjaGFydCwgb3B0aW9ucyk7XG59O1xuXG5MZWdlbmQucHJvdG90eXBlID0ge1xuXHRcblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdGhlIGxlZ2VuZFxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKGNoYXJ0LCBvcHRpb25zKSB7XG5cdFx0XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRpdGVtU3R5bGUgPSBvcHRpb25zLml0ZW1TdHlsZSxcblx0XHRcdHBhZGRpbmcgPSBwaWNrKG9wdGlvbnMucGFkZGluZywgOCksXG5cdFx0XHRpdGVtTWFyZ2luVG9wID0gb3B0aW9ucy5pdGVtTWFyZ2luVG9wIHx8IDA7XG5cdFxuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cblx0XHRpZiAoIW9wdGlvbnMuZW5hYmxlZCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XG5cdFx0bGVnZW5kLml0ZW1TdHlsZSA9IGl0ZW1TdHlsZTtcblx0XHRsZWdlbmQuaXRlbUhpZGRlblN0eWxlID0gbWVyZ2UoaXRlbVN0eWxlLCBvcHRpb25zLml0ZW1IaWRkZW5TdHlsZSk7XG5cdFx0bGVnZW5kLml0ZW1NYXJnaW5Ub3AgPSBpdGVtTWFyZ2luVG9wO1xuXHRcdGxlZ2VuZC5wYWRkaW5nID0gcGFkZGluZztcblx0XHRsZWdlbmQuaW5pdGlhbEl0ZW1YID0gcGFkZGluZztcblx0XHRsZWdlbmQuaW5pdGlhbEl0ZW1ZID0gcGFkZGluZyAtIDU7IC8vIDUgaXMgdGhlIG51bWJlciBvZiBwaXhlbHMgYWJvdmUgdGhlIHRleHRcblx0XHRsZWdlbmQubWF4SXRlbVdpZHRoID0gMDtcblx0XHRsZWdlbmQuY2hhcnQgPSBjaGFydDtcblx0XHRsZWdlbmQuaXRlbUhlaWdodCA9IDA7XG5cdFx0bGVnZW5kLmxhc3RMaW5lSGVpZ2h0ID0gMDtcblx0XHRsZWdlbmQuc3ltYm9sV2lkdGggPSBwaWNrKG9wdGlvbnMuc3ltYm9sV2lkdGgsIDE2KTtcblx0XHRsZWdlbmQucGFnZXMgPSBbXTtcblxuXG5cdFx0Ly8gUmVuZGVyIGl0XG5cdFx0bGVnZW5kLnJlbmRlcigpO1xuXG5cdFx0Ly8gbW92ZSBjaGVja2JveGVzXG5cdFx0YWRkRXZlbnQobGVnZW5kLmNoYXJ0LCAnZW5kUmVzaXplJywgZnVuY3Rpb24gKCkgeyBcblx0XHRcdGxlZ2VuZC5wb3NpdGlvbkNoZWNrYm94ZXMoKTtcblx0XHR9KTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIGNvbG9ycyBmb3IgdGhlIGxlZ2VuZCBpdGVtXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIEEgU2VyaWVzIG9yIFBvaW50IGluc3RhbmNlXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSB2aXNpYmxlIERpbW1lZCBvciBjb2xvcmVkXG5cdCAqL1xuXHRjb2xvcml6ZUl0ZW06IGZ1bmN0aW9uIChpdGVtLCB2aXNpYmxlKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gbGVnZW5kLm9wdGlvbnMsXG5cdFx0XHRsZWdlbmRJdGVtID0gaXRlbS5sZWdlbmRJdGVtLFxuXHRcdFx0bGVnZW5kTGluZSA9IGl0ZW0ubGVnZW5kTGluZSxcblx0XHRcdGxlZ2VuZFN5bWJvbCA9IGl0ZW0ubGVnZW5kU3ltYm9sLFxuXHRcdFx0aGlkZGVuQ29sb3IgPSBsZWdlbmQuaXRlbUhpZGRlblN0eWxlLmNvbG9yLFxuXHRcdFx0dGV4dENvbG9yID0gdmlzaWJsZSA/IG9wdGlvbnMuaXRlbVN0eWxlLmNvbG9yIDogaGlkZGVuQ29sb3IsXG5cdFx0XHRzeW1ib2xDb2xvciA9IHZpc2libGUgPyAoaXRlbS5sZWdlbmRDb2xvciB8fCBpdGVtLmNvbG9yIHx8ICcjQ0NDJykgOiBoaWRkZW5Db2xvcixcblx0XHRcdG1hcmtlck9wdGlvbnMgPSBpdGVtLm9wdGlvbnMgJiYgaXRlbS5vcHRpb25zLm1hcmtlcixcblx0XHRcdHN5bWJvbEF0dHIgPSB7IGZpbGw6IHN5bWJvbENvbG9yIH0sXG5cdFx0XHRrZXksXG5cdFx0XHR2YWw7XG5cdFx0XG5cdFx0aWYgKGxlZ2VuZEl0ZW0pIHtcblx0XHRcdGxlZ2VuZEl0ZW0uY3NzKHsgZmlsbDogdGV4dENvbG9yLCBjb2xvcjogdGV4dENvbG9yIH0pOyAvLyBjb2xvciBmb3IgIzE1NTMsIG9sZElFXG5cdFx0fVxuXHRcdGlmIChsZWdlbmRMaW5lKSB7XG5cdFx0XHRsZWdlbmRMaW5lLmF0dHIoeyBzdHJva2U6IHN5bWJvbENvbG9yIH0pO1xuXHRcdH1cblx0XHRcblx0XHRpZiAobGVnZW5kU3ltYm9sKSB7XG5cdFx0XHRcblx0XHRcdC8vIEFwcGx5IG1hcmtlciBvcHRpb25zXG5cdFx0XHRpZiAobWFya2VyT3B0aW9ucyAmJiBsZWdlbmRTeW1ib2wuaXNNYXJrZXIpIHsgLy8gIzU4NVxuXHRcdFx0XHRzeW1ib2xBdHRyLnN0cm9rZSA9IHN5bWJvbENvbG9yO1xuXHRcdFx0XHRtYXJrZXJPcHRpb25zID0gaXRlbS5jb252ZXJ0QXR0cmlicyhtYXJrZXJPcHRpb25zKTtcblx0XHRcdFx0Zm9yIChrZXkgaW4gbWFya2VyT3B0aW9ucykge1xuXHRcdFx0XHRcdHZhbCA9IG1hcmtlck9wdGlvbnNba2V5XTtcblx0XHRcdFx0XHRpZiAodmFsICE9PSBVTkRFRklORUQpIHtcblx0XHRcdFx0XHRcdHN5bWJvbEF0dHJba2V5XSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0bGVnZW5kU3ltYm9sLmF0dHIoc3ltYm9sQXR0cik7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBQb3NpdGlvbiB0aGUgbGVnZW5kIGl0ZW1cblx0ICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gQSBTZXJpZXMgb3IgUG9pbnQgaW5zdGFuY2Vcblx0ICovXG5cdHBvc2l0aW9uSXRlbTogZnVuY3Rpb24gKGl0ZW0pIHtcblx0XHR2YXIgbGVnZW5kID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBsZWdlbmQub3B0aW9ucyxcblx0XHRcdHN5bWJvbFBhZGRpbmcgPSBvcHRpb25zLnN5bWJvbFBhZGRpbmcsXG5cdFx0XHRsdHIgPSAhb3B0aW9ucy5ydGwsXG5cdFx0XHRsZWdlbmRJdGVtUG9zID0gaXRlbS5fbGVnZW5kSXRlbVBvcyxcblx0XHRcdGl0ZW1YID0gbGVnZW5kSXRlbVBvc1swXSxcblx0XHRcdGl0ZW1ZID0gbGVnZW5kSXRlbVBvc1sxXSxcblx0XHRcdGNoZWNrYm94ID0gaXRlbS5jaGVja2JveDtcblxuXHRcdGlmIChpdGVtLmxlZ2VuZEdyb3VwKSB7XG5cdFx0XHRpdGVtLmxlZ2VuZEdyb3VwLnRyYW5zbGF0ZShcblx0XHRcdFx0bHRyID8gaXRlbVggOiBsZWdlbmQubGVnZW5kV2lkdGggLSBpdGVtWCAtIDIgKiBzeW1ib2xQYWRkaW5nIC0gNCxcblx0XHRcdFx0aXRlbVlcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0aWYgKGNoZWNrYm94KSB7XG5cdFx0XHRjaGVja2JveC54ID0gaXRlbVg7XG5cdFx0XHRjaGVja2JveC55ID0gaXRlbVk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95IGEgc2luZ2xlIGxlZ2VuZCBpdGVtXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBpdGVtIFRoZSBzZXJpZXMgb3IgcG9pbnRcblx0ICovXG5cdGRlc3Ryb3lJdGVtOiBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdHZhciBjaGVja2JveCA9IGl0ZW0uY2hlY2tib3g7XG5cblx0XHQvLyBkZXN0cm95IFNWRyBlbGVtZW50c1xuXHRcdGVhY2goWydsZWdlbmRJdGVtJywgJ2xlZ2VuZExpbmUnLCAnbGVnZW5kU3ltYm9sJywgJ2xlZ2VuZEdyb3VwJ10sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmIChpdGVtW2tleV0pIHtcblx0XHRcdFx0aXRlbVtrZXldID0gaXRlbVtrZXldLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGlmIChjaGVja2JveCkge1xuXHRcdFx0ZGlzY2FyZEVsZW1lbnQoaXRlbS5jaGVja2JveCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBEZXN0cm95cyB0aGUgbGVnZW5kLlxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBsZWdlbmQgPSB0aGlzLFxuXHRcdFx0bGVnZW5kR3JvdXAgPSBsZWdlbmQuZ3JvdXAsXG5cdFx0XHRib3ggPSBsZWdlbmQuYm94O1xuXG5cdFx0aWYgKGJveCkge1xuXHRcdFx0bGVnZW5kLmJveCA9IGJveC5kZXN0cm95KCk7XG5cdFx0fVxuXG5cdFx0aWYgKGxlZ2VuZEdyb3VwKSB7XG5cdFx0XHRsZWdlbmQuZ3JvdXAgPSBsZWdlbmRHcm91cC5kZXN0cm95KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBQb3NpdGlvbiB0aGUgY2hlY2tib3hlcyBhZnRlciB0aGUgd2lkdGggaXMgZGV0ZXJtaW5lZFxuXHQgKi9cblx0cG9zaXRpb25DaGVja2JveGVzOiBmdW5jdGlvbiAoc2Nyb2xsT2Zmc2V0KSB7XG5cdFx0dmFyIGFsaWduQXR0ciA9IHRoaXMuZ3JvdXAuYWxpZ25BdHRyLFxuXHRcdFx0dHJhbnNsYXRlWSxcblx0XHRcdGNsaXBIZWlnaHQgPSB0aGlzLmNsaXBIZWlnaHQgfHwgdGhpcy5sZWdlbmRIZWlnaHQ7XG5cblx0XHRpZiAoYWxpZ25BdHRyKSB7XG5cdFx0XHR0cmFuc2xhdGVZID0gYWxpZ25BdHRyLnRyYW5zbGF0ZVk7XG5cdFx0XHRlYWNoKHRoaXMuYWxsSXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0XHRcdHZhciBjaGVja2JveCA9IGl0ZW0uY2hlY2tib3gsXG5cdFx0XHRcdFx0dG9wO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKGNoZWNrYm94KSB7XG5cdFx0XHRcdFx0dG9wID0gKHRyYW5zbGF0ZVkgKyBjaGVja2JveC55ICsgKHNjcm9sbE9mZnNldCB8fCAwKSArIDMpO1xuXHRcdFx0XHRcdGNzcyhjaGVja2JveCwge1xuXHRcdFx0XHRcdFx0bGVmdDogKGFsaWduQXR0ci50cmFuc2xhdGVYICsgaXRlbS5jaGVja2JveE9mZnNldCArIGNoZWNrYm94LnggLSAyMCkgKyBQWCxcblx0XHRcdFx0XHRcdHRvcDogdG9wICsgUFgsXG5cdFx0XHRcdFx0XHRkaXNwbGF5OiB0b3AgPiB0cmFuc2xhdGVZIC0gNiAmJiB0b3AgPCB0cmFuc2xhdGVZICsgY2xpcEhlaWdodCAtIDYgPyAnJyA6IE5PTkVcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgbGVnZW5kIHRpdGxlIG9uIHRvcCBvZiB0aGUgbGVnZW5kXG5cdCAqL1xuXHRyZW5kZXJUaXRsZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0cGFkZGluZyA9IHRoaXMucGFkZGluZyxcblx0XHRcdHRpdGxlT3B0aW9ucyA9IG9wdGlvbnMudGl0bGUsXG5cdFx0XHR0aXRsZUhlaWdodCA9IDAsXG5cdFx0XHRiQm94O1xuXHRcdFxuXHRcdGlmICh0aXRsZU9wdGlvbnMudGV4dCkge1xuXHRcdFx0aWYgKCF0aGlzLnRpdGxlKSB7XG5cdFx0XHRcdHRoaXMudGl0bGUgPSB0aGlzLmNoYXJ0LnJlbmRlcmVyLmxhYmVsKHRpdGxlT3B0aW9ucy50ZXh0LCBwYWRkaW5nIC0gMywgcGFkZGluZyAtIDQsIG51bGwsIG51bGwsIG51bGwsIG51bGwsIG51bGwsICdsZWdlbmQtdGl0bGUnKVxuXHRcdFx0XHRcdC5hdHRyKHsgekluZGV4OiAxIH0pXG5cdFx0XHRcdFx0LmNzcyh0aXRsZU9wdGlvbnMuc3R5bGUpXG5cdFx0XHRcdFx0LmFkZCh0aGlzLmdyb3VwKTtcblx0XHRcdH1cblx0XHRcdGJCb3ggPSB0aGlzLnRpdGxlLmdldEJCb3goKTtcblx0XHRcdHRpdGxlSGVpZ2h0ID0gYkJveC5oZWlnaHQ7XG5cdFx0XHR0aGlzLm9mZnNldFdpZHRoID0gYkJveC53aWR0aDsgLy8gIzE3MTdcblx0XHRcdHRoaXMuY29udGVudEdyb3VwLmF0dHIoeyB0cmFuc2xhdGVZOiB0aXRsZUhlaWdodCB9KTtcblx0XHR9XG5cdFx0dGhpcy50aXRsZUhlaWdodCA9IHRpdGxlSGVpZ2h0O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW5kZXIgYSBzaW5nbGUgc3BlY2lmaWMgbGVnZW5kIGl0ZW1cblx0ICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gQSBzZXJpZXMgb3IgcG9pbnRcblx0ICovXG5cdHJlbmRlckl0ZW06IGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGxlZ2VuZC5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRvcHRpb25zID0gbGVnZW5kLm9wdGlvbnMsXG5cdFx0XHRob3Jpem9udGFsID0gb3B0aW9ucy5sYXlvdXQgPT09ICdob3Jpem9udGFsJyxcblx0XHRcdHN5bWJvbFdpZHRoID0gbGVnZW5kLnN5bWJvbFdpZHRoLFxuXHRcdFx0c3ltYm9sUGFkZGluZyA9IG9wdGlvbnMuc3ltYm9sUGFkZGluZyxcblx0XHRcdGl0ZW1TdHlsZSA9IGxlZ2VuZC5pdGVtU3R5bGUsXG5cdFx0XHRpdGVtSGlkZGVuU3R5bGUgPSBsZWdlbmQuaXRlbUhpZGRlblN0eWxlLFxuXHRcdFx0cGFkZGluZyA9IGxlZ2VuZC5wYWRkaW5nLFxuXHRcdFx0aXRlbURpc3RhbmNlID0gaG9yaXpvbnRhbCA/IHBpY2sob3B0aW9ucy5pdGVtRGlzdGFuY2UsIDIwKSA6IDAsXG5cdFx0XHRsdHIgPSAhb3B0aW9ucy5ydGwsXG5cdFx0XHRpdGVtSGVpZ2h0LFxuXHRcdFx0d2lkdGhPcHRpb24gPSBvcHRpb25zLndpZHRoLFxuXHRcdFx0aXRlbU1hcmdpbkJvdHRvbSA9IG9wdGlvbnMuaXRlbU1hcmdpbkJvdHRvbSB8fCAwLFxuXHRcdFx0aXRlbU1hcmdpblRvcCA9IGxlZ2VuZC5pdGVtTWFyZ2luVG9wLFxuXHRcdFx0aW5pdGlhbEl0ZW1YID0gbGVnZW5kLmluaXRpYWxJdGVtWCxcblx0XHRcdGJCb3gsXG5cdFx0XHRpdGVtV2lkdGgsXG5cdFx0XHRsaSA9IGl0ZW0ubGVnZW5kSXRlbSxcblx0XHRcdHNlcmllcyA9IGl0ZW0uc2VyaWVzICYmIGl0ZW0uc2VyaWVzLmRyYXdMZWdlbmRTeW1ib2wgPyBpdGVtLnNlcmllcyA6IGl0ZW0sXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRzaG93Q2hlY2tib3ggPSBsZWdlbmQuY3JlYXRlQ2hlY2tib3hGb3JJdGVtICYmIHNlcmllc09wdGlvbnMgJiYgc2VyaWVzT3B0aW9ucy5zaG93Q2hlY2tib3gsXG5cdFx0XHR1c2VIVE1MID0gb3B0aW9ucy51c2VIVE1MO1xuXG5cdFx0aWYgKCFsaSkgeyAvLyBnZW5lcmF0ZSBpdCBvbmNlLCBsYXRlciBtb3ZlIGl0XG5cblx0XHRcdC8vIEdlbmVyYXRlIHRoZSBncm91cCBib3hcblx0XHRcdC8vIEEgZ3JvdXAgdG8gaG9sZCB0aGUgc3ltYm9sIGFuZCB0ZXh0LiBUZXh0IGlzIHRvIGJlIGFwcGVuZGVkIGluIExlZ2VuZCBjbGFzcy5cblx0XHRcdGl0ZW0ubGVnZW5kR3JvdXAgPSByZW5kZXJlci5nKCdsZWdlbmQtaXRlbScpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiAxIH0pXG5cdFx0XHRcdC5hZGQobGVnZW5kLnNjcm9sbEdyb3VwKTtcblxuXHRcdFx0Ly8gR2VuZXJhdGUgdGhlIGxpc3QgaXRlbSB0ZXh0IGFuZCBhZGQgaXQgdG8gdGhlIGdyb3VwXG5cdFx0XHRpdGVtLmxlZ2VuZEl0ZW0gPSBsaSA9IHJlbmRlcmVyLnRleHQoXG5cdFx0XHRcdFx0b3B0aW9ucy5sYWJlbEZvcm1hdCA/IGZvcm1hdChvcHRpb25zLmxhYmVsRm9ybWF0LCBpdGVtKSA6IG9wdGlvbnMubGFiZWxGb3JtYXR0ZXIuY2FsbChpdGVtKSxcblx0XHRcdFx0XHRsdHIgPyBzeW1ib2xXaWR0aCArIHN5bWJvbFBhZGRpbmcgOiAtc3ltYm9sUGFkZGluZyxcblx0XHRcdFx0XHRsZWdlbmQuYmFzZWxpbmUgfHwgMCxcblx0XHRcdFx0XHR1c2VIVE1MXG5cdFx0XHRcdClcblx0XHRcdFx0LmNzcyhtZXJnZShpdGVtLnZpc2libGUgPyBpdGVtU3R5bGUgOiBpdGVtSGlkZGVuU3R5bGUpKSAvLyBtZXJnZSB0byBwcmV2ZW50IG1vZGlmeWluZyBvcmlnaW5hbCAoIzEwMjEpXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRhbGlnbjogbHRyID8gJ2xlZnQnIDogJ3JpZ2h0Jyxcblx0XHRcdFx0XHR6SW5kZXg6IDJcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZChpdGVtLmxlZ2VuZEdyb3VwKTtcblxuXHRcdFx0Ly8gR2V0IHRoZSBiYXNlbGluZSBmb3IgdGhlIGZpcnN0IGl0ZW0gLSB0aGUgZm9udCBzaXplIGlzIGVxdWFsIGZvciBhbGxcblx0XHRcdGlmICghbGVnZW5kLmJhc2VsaW5lKSB7XG5cdFx0XHRcdGxlZ2VuZC5iYXNlbGluZSA9IHJlbmRlcmVyLmZvbnRNZXRyaWNzKGl0ZW1TdHlsZS5mb250U2l6ZSwgbGkpLmYgKyAzICsgaXRlbU1hcmdpblRvcDtcblx0XHRcdFx0bGkuYXR0cigneScsIGxlZ2VuZC5iYXNlbGluZSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERyYXcgdGhlIGxlZ2VuZCBzeW1ib2wgaW5zaWRlIHRoZSBncm91cCBib3hcblx0XHRcdHNlcmllcy5kcmF3TGVnZW5kU3ltYm9sKGxlZ2VuZCwgaXRlbSk7XG5cblx0XHRcdGlmIChsZWdlbmQuc2V0SXRlbUV2ZW50cykge1xuXHRcdFx0XHRsZWdlbmQuc2V0SXRlbUV2ZW50cyhpdGVtLCBsaSwgdXNlSFRNTCwgaXRlbVN0eWxlLCBpdGVtSGlkZGVuU3R5bGUpO1xuXHRcdFx0fVx0XHRcdFxuXG5cdFx0XHQvLyBDb2xvcml6ZSB0aGUgaXRlbXNcblx0XHRcdGxlZ2VuZC5jb2xvcml6ZUl0ZW0oaXRlbSwgaXRlbS52aXNpYmxlKTtcblxuXHRcdFx0Ly8gYWRkIHRoZSBIVE1MIGNoZWNrYm94IG9uIHRvcFxuXHRcdFx0aWYgKHNob3dDaGVja2JveCkge1xuXHRcdFx0XHRsZWdlbmQuY3JlYXRlQ2hlY2tib3hGb3JJdGVtKGl0ZW0pO1x0XHRcdFx0XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY2FsY3VsYXRlIHRoZSBwb3NpdGlvbnMgZm9yIHRoZSBuZXh0IGxpbmVcblx0XHRiQm94ID0gbGkuZ2V0QkJveCgpO1xuXG5cdFx0aXRlbVdpZHRoID0gaXRlbS5jaGVja2JveE9mZnNldCA9IFxuXHRcdFx0b3B0aW9ucy5pdGVtV2lkdGggfHwgXG5cdFx0XHRpdGVtLmxlZ2VuZEl0ZW1XaWR0aCB8fCBcblx0XHRcdHN5bWJvbFdpZHRoICsgc3ltYm9sUGFkZGluZyArIGJCb3gud2lkdGggKyBpdGVtRGlzdGFuY2UgKyAoc2hvd0NoZWNrYm94ID8gMjAgOiAwKTtcblx0XHRsZWdlbmQuaXRlbUhlaWdodCA9IGl0ZW1IZWlnaHQgPSBtYXRoUm91bmQoaXRlbS5sZWdlbmRJdGVtSGVpZ2h0IHx8IGJCb3guaGVpZ2h0KTtcblxuXHRcdC8vIGlmIHRoZSBpdGVtIGV4Y2VlZHMgdGhlIHdpZHRoLCBzdGFydCBhIG5ldyBsaW5lXG5cdFx0aWYgKGhvcml6b250YWwgJiYgbGVnZW5kLml0ZW1YIC0gaW5pdGlhbEl0ZW1YICsgaXRlbVdpZHRoID5cblx0XHRcdFx0KHdpZHRoT3B0aW9uIHx8IChjaGFydC5jaGFydFdpZHRoIC0gMiAqIHBhZGRpbmcgLSBpbml0aWFsSXRlbVggLSBvcHRpb25zLngpKSkge1xuXHRcdFx0bGVnZW5kLml0ZW1YID0gaW5pdGlhbEl0ZW1YO1xuXHRcdFx0bGVnZW5kLml0ZW1ZICs9IGl0ZW1NYXJnaW5Ub3AgKyBsZWdlbmQubGFzdExpbmVIZWlnaHQgKyBpdGVtTWFyZ2luQm90dG9tO1xuXHRcdFx0bGVnZW5kLmxhc3RMaW5lSGVpZ2h0ID0gMDsgLy8gcmVzZXQgZm9yIG5leHQgbGluZVxuXHRcdH1cblxuXHRcdC8vIElmIHRoZSBpdGVtIGV4Y2VlZHMgdGhlIGhlaWdodCwgc3RhcnQgYSBuZXcgY29sdW1uXG5cdFx0LyppZiAoIWhvcml6b250YWwgJiYgbGVnZW5kLml0ZW1ZICsgb3B0aW9ucy55ICsgaXRlbUhlaWdodCA+IGNoYXJ0LmNoYXJ0SGVpZ2h0IC0gc3BhY2luZ1RvcCAtIHNwYWNpbmdCb3R0b20pIHtcblx0XHRcdGxlZ2VuZC5pdGVtWSA9IGxlZ2VuZC5pbml0aWFsSXRlbVk7XG5cdFx0XHRsZWdlbmQuaXRlbVggKz0gbGVnZW5kLm1heEl0ZW1XaWR0aDtcblx0XHRcdGxlZ2VuZC5tYXhJdGVtV2lkdGggPSAwO1xuXHRcdH0qL1xuXG5cdFx0Ly8gU2V0IHRoZSBlZGdlIHBvc2l0aW9uc1xuXHRcdGxlZ2VuZC5tYXhJdGVtV2lkdGggPSBtYXRoTWF4KGxlZ2VuZC5tYXhJdGVtV2lkdGgsIGl0ZW1XaWR0aCk7XG5cdFx0bGVnZW5kLmxhc3RJdGVtWSA9IGl0ZW1NYXJnaW5Ub3AgKyBsZWdlbmQuaXRlbVkgKyBpdGVtTWFyZ2luQm90dG9tO1xuXHRcdGxlZ2VuZC5sYXN0TGluZUhlaWdodCA9IG1hdGhNYXgoaXRlbUhlaWdodCwgbGVnZW5kLmxhc3RMaW5lSGVpZ2h0KTsgLy8gIzkxNVxuXG5cdFx0Ly8gY2FjaGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBuZXdseSBnZW5lcmF0ZWQgb3IgcmVvcmRlcmVkIGl0ZW1zXG5cdFx0aXRlbS5fbGVnZW5kSXRlbVBvcyA9IFtsZWdlbmQuaXRlbVgsIGxlZ2VuZC5pdGVtWV07XG5cblx0XHQvLyBhZHZhbmNlXG5cdFx0aWYgKGhvcml6b250YWwpIHtcblx0XHRcdGxlZ2VuZC5pdGVtWCArPSBpdGVtV2lkdGg7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0bGVnZW5kLml0ZW1ZICs9IGl0ZW1NYXJnaW5Ub3AgKyBpdGVtSGVpZ2h0ICsgaXRlbU1hcmdpbkJvdHRvbTtcblx0XHRcdGxlZ2VuZC5sYXN0TGluZUhlaWdodCA9IGl0ZW1IZWlnaHQ7XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIHdpZHRoIG9mIHRoZSB3aWRlc3QgaXRlbVxuXHRcdGxlZ2VuZC5vZmZzZXRXaWR0aCA9IHdpZHRoT3B0aW9uIHx8IG1hdGhNYXgoXG5cdFx0XHQoaG9yaXpvbnRhbCA/IGxlZ2VuZC5pdGVtWCAtIGluaXRpYWxJdGVtWCAtIGl0ZW1EaXN0YW5jZSA6IGl0ZW1XaWR0aCkgKyBwYWRkaW5nLFxuXHRcdFx0bGVnZW5kLm9mZnNldFdpZHRoXG5cdFx0KTtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IGFsbCBpdGVtcywgd2hpY2ggaXMgb25lIGl0ZW0gcGVyIHNlcmllcyBmb3Igbm9ybWFsIHNlcmllcyBhbmQgb25lIGl0ZW0gcGVyIHBvaW50XG5cdCAqIGZvciBwaWUgc2VyaWVzLlxuXHQgKi9cblx0Z2V0QWxsSXRlbXM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgYWxsSXRlbXMgPSBbXTtcblx0XHRlYWNoKHRoaXMuY2hhcnQuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cdFx0XHR2YXIgc2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zO1xuXG5cdFx0XHQvLyBIYW5kbGUgc2hvd0luTGVnZW5kLiBJZiB0aGUgc2VyaWVzIGlzIGxpbmtlZCB0byBhbm90aGVyIHNlcmllcywgZGVmYXVsdHMgdG8gZmFsc2UuXG5cdFx0XHRpZiAoIXBpY2soc2VyaWVzT3B0aW9ucy5zaG93SW5MZWdlbmQsICFkZWZpbmVkKHNlcmllc09wdGlvbnMubGlua2VkVG8pID8gVU5ERUZJTkVEIDogZmFsc2UsIHRydWUpKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gdXNlIHBvaW50cyBvciBzZXJpZXMgZm9yIHRoZSBsZWdlbmQgaXRlbSBkZXBlbmRpbmcgb24gbGVnZW5kVHlwZVxuXHRcdFx0YWxsSXRlbXMgPSBhbGxJdGVtcy5jb25jYXQoXG5cdFx0XHRcdFx0c2VyaWVzLmxlZ2VuZEl0ZW1zIHx8XG5cdFx0XHRcdFx0KHNlcmllc09wdGlvbnMubGVnZW5kVHlwZSA9PT0gJ3BvaW50JyA/XG5cdFx0XHRcdFx0XHRcdHNlcmllcy5kYXRhIDpcblx0XHRcdFx0XHRcdFx0c2VyaWVzKVxuXHRcdFx0KTtcblx0XHR9KTtcblx0XHRyZXR1cm4gYWxsSXRlbXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgbGVnZW5kLiBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIGJvdGggYmVmb3JlIGFuZCBhZnRlclxuXHQgKiBjaGFydC5yZW5kZXIuIElmIGNhbGxlZCBhZnRlciwgaXQgd2lsbCBvbmx5IHJlYXJyYW5nZSBpdGVtcyBpbnN0ZWFkXG5cdCAqIG9mIGNyZWF0aW5nIG5ldyBvbmVzLlxuXHQgKi9cblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IGxlZ2VuZC5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRsZWdlbmRHcm91cCA9IGxlZ2VuZC5ncm91cCxcblx0XHRcdGFsbEl0ZW1zLFxuXHRcdFx0ZGlzcGxheSxcblx0XHRcdGxlZ2VuZFdpZHRoLFxuXHRcdFx0bGVnZW5kSGVpZ2h0LFxuXHRcdFx0Ym94ID0gbGVnZW5kLmJveCxcblx0XHRcdG9wdGlvbnMgPSBsZWdlbmQub3B0aW9ucyxcblx0XHRcdHBhZGRpbmcgPSBsZWdlbmQucGFkZGluZyxcblx0XHRcdGxlZ2VuZEJvcmRlcldpZHRoID0gb3B0aW9ucy5ib3JkZXJXaWR0aCxcblx0XHRcdGxlZ2VuZEJhY2tncm91bmRDb2xvciA9IG9wdGlvbnMuYmFja2dyb3VuZENvbG9yO1xuXG5cdFx0bGVnZW5kLml0ZW1YID0gbGVnZW5kLmluaXRpYWxJdGVtWDtcblx0XHRsZWdlbmQuaXRlbVkgPSBsZWdlbmQuaW5pdGlhbEl0ZW1ZO1xuXHRcdGxlZ2VuZC5vZmZzZXRXaWR0aCA9IDA7XG5cdFx0bGVnZW5kLmxhc3RJdGVtWSA9IDA7XG5cblx0XHRpZiAoIWxlZ2VuZEdyb3VwKSB7XG5cdFx0XHRsZWdlbmQuZ3JvdXAgPSBsZWdlbmRHcm91cCA9IHJlbmRlcmVyLmcoJ2xlZ2VuZCcpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiA3IH0pIFxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0XHRsZWdlbmQuY29udGVudEdyb3VwID0gcmVuZGVyZXIuZygpXG5cdFx0XHRcdC5hdHRyKHsgekluZGV4OiAxIH0pIC8vIGFib3ZlIGJhY2tncm91bmRcblx0XHRcdFx0LmFkZChsZWdlbmRHcm91cCk7XG5cdFx0XHRsZWdlbmQuc2Nyb2xsR3JvdXAgPSByZW5kZXJlci5nKClcblx0XHRcdFx0LmFkZChsZWdlbmQuY29udGVudEdyb3VwKTtcblx0XHR9XG5cdFx0XG5cdFx0bGVnZW5kLnJlbmRlclRpdGxlKCk7XG5cblx0XHQvLyBhZGQgZWFjaCBzZXJpZXMgb3IgcG9pbnRcblx0XHRhbGxJdGVtcyA9IGxlZ2VuZC5nZXRBbGxJdGVtcygpO1xuXG5cdFx0Ly8gc29ydCBieSBsZWdlbmRJbmRleFxuXHRcdHN0YWJsZVNvcnQoYWxsSXRlbXMsIGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0XHRyZXR1cm4gKChhLm9wdGlvbnMgJiYgYS5vcHRpb25zLmxlZ2VuZEluZGV4KSB8fCAwKSAtICgoYi5vcHRpb25zICYmIGIub3B0aW9ucy5sZWdlbmRJbmRleCkgfHwgMCk7XG5cdFx0fSk7XG5cblx0XHQvLyByZXZlcnNlZCBsZWdlbmRcblx0XHRpZiAob3B0aW9ucy5yZXZlcnNlZCkge1xuXHRcdFx0YWxsSXRlbXMucmV2ZXJzZSgpO1xuXHRcdH1cblxuXHRcdGxlZ2VuZC5hbGxJdGVtcyA9IGFsbEl0ZW1zO1xuXHRcdGxlZ2VuZC5kaXNwbGF5ID0gZGlzcGxheSA9ICEhYWxsSXRlbXMubGVuZ3RoO1xuXG5cdFx0Ly8gcmVuZGVyIHRoZSBpdGVtc1xuXHRcdGVhY2goYWxsSXRlbXMsIGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0XHRsZWdlbmQucmVuZGVySXRlbShpdGVtKTsgXG5cdFx0fSk7XG5cblx0XHQvLyBEcmF3IHRoZSBib3JkZXJcblx0XHRsZWdlbmRXaWR0aCA9IG9wdGlvbnMud2lkdGggfHwgbGVnZW5kLm9mZnNldFdpZHRoO1xuXHRcdGxlZ2VuZEhlaWdodCA9IGxlZ2VuZC5sYXN0SXRlbVkgKyBsZWdlbmQubGFzdExpbmVIZWlnaHQgKyBsZWdlbmQudGl0bGVIZWlnaHQ7XG5cdFx0XG5cdFx0XG5cdFx0bGVnZW5kSGVpZ2h0ID0gbGVnZW5kLmhhbmRsZU92ZXJmbG93KGxlZ2VuZEhlaWdodCk7XG5cblx0XHRpZiAobGVnZW5kQm9yZGVyV2lkdGggfHwgbGVnZW5kQmFja2dyb3VuZENvbG9yKSB7XG5cdFx0XHRsZWdlbmRXaWR0aCArPSBwYWRkaW5nO1xuXHRcdFx0bGVnZW5kSGVpZ2h0ICs9IHBhZGRpbmc7XG5cblx0XHRcdGlmICghYm94KSB7XG5cdFx0XHRcdGxlZ2VuZC5ib3ggPSBib3ggPSByZW5kZXJlci5yZWN0KFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRsZWdlbmRXaWR0aCxcblx0XHRcdFx0XHRsZWdlbmRIZWlnaHQsXG5cdFx0XHRcdFx0b3B0aW9ucy5ib3JkZXJSYWRpdXMsXG5cdFx0XHRcdFx0bGVnZW5kQm9yZGVyV2lkdGggfHwgMFxuXHRcdFx0XHQpLmF0dHIoe1xuXHRcdFx0XHRcdHN0cm9rZTogb3B0aW9ucy5ib3JkZXJDb2xvcixcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogbGVnZW5kQm9yZGVyV2lkdGggfHwgMCxcblx0XHRcdFx0XHRmaWxsOiBsZWdlbmRCYWNrZ3JvdW5kQ29sb3IgfHwgTk9ORVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkKGxlZ2VuZEdyb3VwKVxuXHRcdFx0XHQuc2hhZG93KG9wdGlvbnMuc2hhZG93KTtcblx0XHRcdFx0Ym94LmlzTmV3ID0gdHJ1ZTtcblxuXHRcdFx0fSBlbHNlIGlmIChsZWdlbmRXaWR0aCA+IDAgJiYgbGVnZW5kSGVpZ2h0ID4gMCkge1xuXHRcdFx0XHRib3hbYm94LmlzTmV3ID8gJ2F0dHInIDogJ2FuaW1hdGUnXShcblx0XHRcdFx0XHRib3guY3Jpc3AoeyB3aWR0aDogbGVnZW5kV2lkdGgsIGhlaWdodDogbGVnZW5kSGVpZ2h0IH0pXG5cdFx0XHRcdCk7XG5cdFx0XHRcdGJveC5pc05ldyA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBoaWRlIHRoZSBib3JkZXIgaWYgbm8gaXRlbXNcblx0XHRcdGJveFtkaXNwbGF5ID8gJ3Nob3cnIDogJ2hpZGUnXSgpO1xuXHRcdH1cblx0XHRcblx0XHRsZWdlbmQubGVnZW5kV2lkdGggPSBsZWdlbmRXaWR0aDtcblx0XHRsZWdlbmQubGVnZW5kSGVpZ2h0ID0gbGVnZW5kSGVpZ2h0O1xuXG5cdFx0Ly8gTm93IHRoYXQgdGhlIGxlZ2VuZCB3aWR0aCBhbmQgaGVpZ2h0IGFyZSBlc3RhYmxpc2hlZCwgcHV0IHRoZSBpdGVtcyBpbiB0aGUgXG5cdFx0Ly8gZmluYWwgcG9zaXRpb25cblx0XHRlYWNoKGFsbEl0ZW1zLCBmdW5jdGlvbiAoaXRlbSkge1xuXHRcdFx0bGVnZW5kLnBvc2l0aW9uSXRlbShpdGVtKTtcblx0XHR9KTtcblxuXHRcdC8vIDEueCBjb21wYXRpYmlsaXR5OiBwb3NpdGlvbmluZyBiYXNlZCBvbiBzdHlsZVxuXHRcdC8qdmFyIHByb3BzID0gWydsZWZ0JywgJ3JpZ2h0JywgJ3RvcCcsICdib3R0b20nXSxcblx0XHRcdHByb3AsXG5cdFx0XHRpID0gNDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRwcm9wID0gcHJvcHNbaV07XG5cdFx0XHRpZiAob3B0aW9ucy5zdHlsZVtwcm9wXSAmJiBvcHRpb25zLnN0eWxlW3Byb3BdICE9PSAnYXV0bycpIHtcblx0XHRcdFx0b3B0aW9uc1tpIDwgMiA/ICdhbGlnbicgOiAndmVydGljYWxBbGlnbiddID0gcHJvcDtcblx0XHRcdFx0b3B0aW9uc1tpIDwgMiA/ICd4JyA6ICd5J10gPSBwSW50KG9wdGlvbnMuc3R5bGVbcHJvcF0pICogKGkgJSAyID8gLTEgOiAxKTtcblx0XHRcdH1cblx0XHR9Ki9cblxuXHRcdGlmIChkaXNwbGF5KSB7XG5cdFx0XHRsZWdlbmRHcm91cC5hbGlnbihleHRlbmQoe1xuXHRcdFx0XHR3aWR0aDogbGVnZW5kV2lkdGgsXG5cdFx0XHRcdGhlaWdodDogbGVnZW5kSGVpZ2h0XG5cdFx0XHR9LCBvcHRpb25zKSwgdHJ1ZSwgJ3NwYWNpbmdCb3gnKTtcblx0XHR9XG5cblx0XHRpZiAoIWNoYXJ0LmlzUmVzaXppbmcpIHtcblx0XHRcdHRoaXMucG9zaXRpb25DaGVja2JveGVzKCk7XG5cdFx0fVxuXHR9LFxuXHRcblx0LyoqXG5cdCAqIFNldCB1cCB0aGUgb3ZlcmZsb3cgaGFuZGxpbmcgYnkgYWRkaW5nIG5hdmlnYXRpb24gd2l0aCB1cCBhbmQgZG93biBhcnJvd3MgYmVsb3cgdGhlXG5cdCAqIGxlZ2VuZC5cblx0ICovXG5cdGhhbmRsZU92ZXJmbG93OiBmdW5jdGlvbiAobGVnZW5kSGVpZ2h0KSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdG9wdGlvbnNZID0gb3B0aW9ucy55LFxuXHRcdFx0YWxpZ25Ub3AgPSBvcHRpb25zLnZlcnRpY2FsQWxpZ24gPT09ICd0b3AnLFxuXHRcdFx0c3BhY2VIZWlnaHQgPSBjaGFydC5zcGFjaW5nQm94LmhlaWdodCArIChhbGlnblRvcCA/IC1vcHRpb25zWSA6IG9wdGlvbnNZKSAtIHRoaXMucGFkZGluZyxcblx0XHRcdG1heEhlaWdodCA9IG9wdGlvbnMubWF4SGVpZ2h0LFxuXHRcdFx0Y2xpcEhlaWdodCxcblx0XHRcdGNsaXBSZWN0ID0gdGhpcy5jbGlwUmVjdCxcblx0XHRcdG5hdk9wdGlvbnMgPSBvcHRpb25zLm5hdmlnYXRpb24sXG5cdFx0XHRhbmltYXRpb24gPSBwaWNrKG5hdk9wdGlvbnMuYW5pbWF0aW9uLCB0cnVlKSxcblx0XHRcdGFycm93U2l6ZSA9IG5hdk9wdGlvbnMuYXJyb3dTaXplIHx8IDEyLFxuXHRcdFx0bmF2ID0gdGhpcy5uYXYsXG5cdFx0XHRwYWdlcyA9IHRoaXMucGFnZXMsXG5cdFx0XHRsYXN0WSxcblx0XHRcdGFsbEl0ZW1zID0gdGhpcy5hbGxJdGVtcztcblx0XHRcdFxuXHRcdC8vIEFkanVzdCB0aGUgaGVpZ2h0XG5cdFx0aWYgKG9wdGlvbnMubGF5b3V0ID09PSAnaG9yaXpvbnRhbCcpIHtcblx0XHRcdHNwYWNlSGVpZ2h0IC89IDI7XG5cdFx0fVxuXHRcdGlmIChtYXhIZWlnaHQpIHtcblx0XHRcdHNwYWNlSGVpZ2h0ID0gbWF0aE1pbihzcGFjZUhlaWdodCwgbWF4SGVpZ2h0KTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gUmVzZXQgdGhlIGxlZ2VuZCBoZWlnaHQgYW5kIGFkanVzdCB0aGUgY2xpcHBpbmcgcmVjdGFuZ2xlXG5cdFx0cGFnZXMubGVuZ3RoID0gMDtcblx0XHRpZiAobGVnZW5kSGVpZ2h0ID4gc3BhY2VIZWlnaHQgJiYgIW9wdGlvbnMudXNlSFRNTCkge1xuXG5cdFx0XHR0aGlzLmNsaXBIZWlnaHQgPSBjbGlwSGVpZ2h0ID0gbWF0aE1heChzcGFjZUhlaWdodCAtIDIwIC0gdGhpcy50aXRsZUhlaWdodCAtIHRoaXMucGFkZGluZywgMCk7XG5cdFx0XHR0aGlzLmN1cnJlbnRQYWdlID0gcGljayh0aGlzLmN1cnJlbnRQYWdlLCAxKTtcblx0XHRcdHRoaXMuZnVsbEhlaWdodCA9IGxlZ2VuZEhlaWdodDtcblx0XHRcdFxuXHRcdFx0Ly8gRmlsbCBwYWdlcyB3aXRoIFkgcG9zaXRpb25zIHNvIHRoYXQgdGhlIHRvcCBvZiBlYWNoIGEgbGVnZW5kIGl0ZW0gZGVmaW5lc1xuXHRcdFx0Ly8gdGhlIHNjcm9sbCB0b3AgZm9yIGVhY2ggcGFnZSAoIzIwOTgpXG5cdFx0XHRlYWNoKGFsbEl0ZW1zLCBmdW5jdGlvbiAoaXRlbSwgaSkge1xuXHRcdFx0XHR2YXIgeSA9IGl0ZW0uX2xlZ2VuZEl0ZW1Qb3NbMV0sXG5cdFx0XHRcdFx0aCA9IG1hdGhSb3VuZChpdGVtLmxlZ2VuZEl0ZW0uZ2V0QkJveCgpLmhlaWdodCksXG5cdFx0XHRcdFx0bGVuID0gcGFnZXMubGVuZ3RoO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKCFsZW4gfHwgKHkgLSBwYWdlc1tsZW4gLSAxXSA+IGNsaXBIZWlnaHQgJiYgKGxhc3RZIHx8IHkpICE9PSBwYWdlc1tsZW4gLSAxXSkpIHtcblx0XHRcdFx0XHRwYWdlcy5wdXNoKGxhc3RZIHx8IHkpO1xuXHRcdFx0XHRcdGxlbisrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRpZiAoaSA9PT0gYWxsSXRlbXMubGVuZ3RoIC0gMSAmJiB5ICsgaCAtIHBhZ2VzW2xlbiAtIDFdID4gY2xpcEhlaWdodCkge1xuXHRcdFx0XHRcdHBhZ2VzLnB1c2goeSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHkgIT09IGxhc3RZKSB7XG5cdFx0XHRcdFx0bGFzdFkgPSB5O1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gT25seSBhcHBseSBjbGlwcGluZyBpZiBuZWVkZWQuIENsaXBwaW5nIGNhdXNlcyBibHVycmVkIGxlZ2VuZCBpbiBQREYgZXhwb3J0ICgjMTc4Nylcblx0XHRcdGlmICghY2xpcFJlY3QpIHtcblx0XHRcdFx0Y2xpcFJlY3QgPSBsZWdlbmQuY2xpcFJlY3QgPSByZW5kZXJlci5jbGlwUmVjdCgwLCB0aGlzLnBhZGRpbmcsIDk5OTksIDApO1xuXHRcdFx0XHRsZWdlbmQuY29udGVudEdyb3VwLmNsaXAoY2xpcFJlY3QpO1xuXHRcdFx0fVxuXHRcdFx0Y2xpcFJlY3QuYXR0cih7XG5cdFx0XHRcdGhlaWdodDogY2xpcEhlaWdodFxuXHRcdFx0fSk7XG5cdFx0XHRcblx0XHRcdC8vIEFkZCBuYXZpZ2F0aW9uIGVsZW1lbnRzXG5cdFx0XHRpZiAoIW5hdikge1xuXHRcdFx0XHR0aGlzLm5hdiA9IG5hdiA9IHJlbmRlcmVyLmcoKS5hdHRyKHsgekluZGV4OiAxIH0pLmFkZCh0aGlzLmdyb3VwKTtcblx0XHRcdFx0dGhpcy51cCA9IHJlbmRlcmVyLnN5bWJvbCgndHJpYW5nbGUnLCAwLCAwLCBhcnJvd1NpemUsIGFycm93U2l6ZSlcblx0XHRcdFx0XHQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0bGVnZW5kLnNjcm9sbCgtMSwgYW5pbWF0aW9uKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdC5hZGQobmF2KTtcblx0XHRcdFx0dGhpcy5wYWdlciA9IHJlbmRlcmVyLnRleHQoJycsIDE1LCAxMClcblx0XHRcdFx0XHQuY3NzKG5hdk9wdGlvbnMuc3R5bGUpXG5cdFx0XHRcdFx0LmFkZChuYXYpO1xuXHRcdFx0XHR0aGlzLmRvd24gPSByZW5kZXJlci5zeW1ib2woJ3RyaWFuZ2xlLWRvd24nLCAwLCAwLCBhcnJvd1NpemUsIGFycm93U2l6ZSlcblx0XHRcdFx0XHQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0bGVnZW5kLnNjcm9sbCgxLCBhbmltYXRpb24pO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmFkZChuYXYpO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHQvLyBTZXQgaW5pdGlhbCBwb3NpdGlvblxuXHRcdFx0bGVnZW5kLnNjcm9sbCgwKTtcblx0XHRcdFxuXHRcdFx0bGVnZW5kSGVpZ2h0ID0gc3BhY2VIZWlnaHQ7XG5cdFx0XHRcblx0XHR9IGVsc2UgaWYgKG5hdikge1xuXHRcdFx0Y2xpcFJlY3QuYXR0cih7XG5cdFx0XHRcdGhlaWdodDogY2hhcnQuY2hhcnRIZWlnaHRcblx0XHRcdH0pO1xuXHRcdFx0bmF2LmhpZGUoKTtcblx0XHRcdHRoaXMuc2Nyb2xsR3JvdXAuYXR0cih7XG5cdFx0XHRcdHRyYW5zbGF0ZVk6IDFcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5jbGlwSGVpZ2h0ID0gMDsgLy8gIzEzNzlcblx0XHR9XG5cdFx0XG5cdFx0cmV0dXJuIGxlZ2VuZEhlaWdodDtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBTY3JvbGwgdGhlIGxlZ2VuZCBieSBhIG51bWJlciBvZiBwYWdlc1xuXHQgKiBAcGFyYW0ge09iamVjdH0gc2Nyb2xsQnlcblx0ICogQHBhcmFtIHtPYmplY3R9IGFuaW1hdGlvblxuXHQgKi9cblx0c2Nyb2xsOiBmdW5jdGlvbiAoc2Nyb2xsQnksIGFuaW1hdGlvbikge1xuXHRcdHZhciBwYWdlcyA9IHRoaXMucGFnZXMsXG5cdFx0XHRwYWdlQ291bnQgPSBwYWdlcy5sZW5ndGgsXG5cdFx0XHRjdXJyZW50UGFnZSA9IHRoaXMuY3VycmVudFBhZ2UgKyBzY3JvbGxCeSxcblx0XHRcdGNsaXBIZWlnaHQgPSB0aGlzLmNsaXBIZWlnaHQsXG5cdFx0XHRuYXZPcHRpb25zID0gdGhpcy5vcHRpb25zLm5hdmlnYXRpb24sXG5cdFx0XHRhY3RpdmVDb2xvciA9IG5hdk9wdGlvbnMuYWN0aXZlQ29sb3IsXG5cdFx0XHRpbmFjdGl2ZUNvbG9yID0gbmF2T3B0aW9ucy5pbmFjdGl2ZUNvbG9yLFxuXHRcdFx0cGFnZXIgPSB0aGlzLnBhZ2VyLFxuXHRcdFx0cGFkZGluZyA9IHRoaXMucGFkZGluZyxcblx0XHRcdHNjcm9sbE9mZnNldDtcblx0XHRcblx0XHQvLyBXaGVuIHJlc2l6aW5nIHdoaWxlIGxvb2tpbmcgYXQgdGhlIGxhc3QgcGFnZVxuXHRcdGlmIChjdXJyZW50UGFnZSA+IHBhZ2VDb3VudCkge1xuXHRcdFx0Y3VycmVudFBhZ2UgPSBwYWdlQ291bnQ7XG5cdFx0fVxuXHRcdFxuXHRcdGlmIChjdXJyZW50UGFnZSA+IDApIHtcblx0XHRcdFxuXHRcdFx0aWYgKGFuaW1hdGlvbiAhPT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdHNldEFuaW1hdGlvbihhbmltYXRpb24sIHRoaXMuY2hhcnQpO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHR0aGlzLm5hdi5hdHRyKHtcblx0XHRcdFx0dHJhbnNsYXRlWDogcGFkZGluZyxcblx0XHRcdFx0dHJhbnNsYXRlWTogY2xpcEhlaWdodCArIHRoaXMucGFkZGluZyArIDcgKyB0aGlzLnRpdGxlSGVpZ2h0LFxuXHRcdFx0XHR2aXNpYmlsaXR5OiBWSVNJQkxFXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMudXAuYXR0cih7XG5cdFx0XHRcdFx0ZmlsbDogY3VycmVudFBhZ2UgPT09IDEgPyBpbmFjdGl2ZUNvbG9yIDogYWN0aXZlQ29sb3Jcblx0XHRcdFx0fSlcblx0XHRcdFx0LmNzcyh7XG5cdFx0XHRcdFx0Y3Vyc29yOiBjdXJyZW50UGFnZSA9PT0gMSA/ICdkZWZhdWx0JyA6ICdwb2ludGVyJ1xuXHRcdFx0XHR9KTtcblx0XHRcdHBhZ2VyLmF0dHIoe1xuXHRcdFx0XHR0ZXh0OiBjdXJyZW50UGFnZSArICcvJyArIHBhZ2VDb3VudFxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLmRvd24uYXR0cih7XG5cdFx0XHRcdFx0eDogMTggKyB0aGlzLnBhZ2VyLmdldEJCb3goKS53aWR0aCwgLy8gYWRqdXN0IHRvIHRleHQgd2lkdGhcblx0XHRcdFx0XHRmaWxsOiBjdXJyZW50UGFnZSA9PT0gcGFnZUNvdW50ID8gaW5hY3RpdmVDb2xvciA6IGFjdGl2ZUNvbG9yXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jc3Moe1xuXHRcdFx0XHRcdGN1cnNvcjogY3VycmVudFBhZ2UgPT09IHBhZ2VDb3VudCA/ICdkZWZhdWx0JyA6ICdwb2ludGVyJ1xuXHRcdFx0XHR9KTtcblx0XHRcdFxuXHRcdFx0c2Nyb2xsT2Zmc2V0ID0gLXBhZ2VzW2N1cnJlbnRQYWdlIC0gMV0gKyB0aGlzLmluaXRpYWxJdGVtWTtcblxuXHRcdFx0dGhpcy5zY3JvbGxHcm91cC5hbmltYXRlKHtcblx0XHRcdFx0dHJhbnNsYXRlWTogc2Nyb2xsT2Zmc2V0XG5cdFx0XHR9KTtcdFx0XHRcblx0XHRcdFxuXHRcdFx0dGhpcy5jdXJyZW50UGFnZSA9IGN1cnJlbnRQYWdlO1xuXHRcdFx0dGhpcy5wb3NpdGlvbkNoZWNrYm94ZXMoc2Nyb2xsT2Zmc2V0KTtcblx0XHR9XG5cdFx0XHRcblx0fVxuXHRcbn07XG5cbi8qXG4gKiBMZWdlbmRTeW1ib2xNaXhpblxuICovIFxuXG52YXIgTGVnZW5kU3ltYm9sTWl4aW4gPSBIaWdoY2hhcnRzLkxlZ2VuZFN5bWJvbE1peGluID0ge1xuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHNlcmllcycgc3ltYm9sIGluIHRoZSBsZWdlbmRcblx0ICogXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBsZWdlbmQgVGhlIGxlZ2VuZCBvYmplY3Rcblx0ICogQHBhcmFtIHtPYmplY3R9IGl0ZW0gVGhlIHNlcmllcyAodGhpcykgb3IgcG9pbnRcblx0ICovXG5cdGRyYXdSZWN0YW5nbGU6IGZ1bmN0aW9uIChsZWdlbmQsIGl0ZW0pIHtcblx0XHR2YXIgc3ltYm9sSGVpZ2h0ID0gbGVnZW5kLm9wdGlvbnMuc3ltYm9sSGVpZ2h0IHx8IDEyO1xuXHRcdFxuXHRcdGl0ZW0ubGVnZW5kU3ltYm9sID0gdGhpcy5jaGFydC5yZW5kZXJlci5yZWN0KFxuXHRcdFx0MCxcblx0XHRcdGxlZ2VuZC5iYXNlbGluZSAtIDUgLSAoc3ltYm9sSGVpZ2h0IC8gMiksXG5cdFx0XHRsZWdlbmQuc3ltYm9sV2lkdGgsXG5cdFx0XHRzeW1ib2xIZWlnaHQsXG5cdFx0XHRsZWdlbmQub3B0aW9ucy5zeW1ib2xSYWRpdXMgfHwgMFxuXHRcdCkuYXR0cih7XG5cdFx0XHR6SW5kZXg6IDNcblx0XHR9KS5hZGQoaXRlbS5sZWdlbmRHcm91cCk7XHRcdFxuXHRcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHNlcmllcycgc3ltYm9sIGluIHRoZSBsZWdlbmQuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkYWJsZSB0byBjcmVhdGUgY3VzdG9tIFxuXHQgKiBzeW1ib2xzIHRocm91Z2ggSGlnaGNoYXJ0cy5zZXJpZXNUeXBlc1t0eXBlXS5wcm90b3R5cGUuZHJhd0xlZ2VuZFN5bWJvbHMuXG5cdCAqIFxuXHQgKiBAcGFyYW0ge09iamVjdH0gbGVnZW5kIFRoZSBsZWdlbmQgb2JqZWN0XG5cdCAqL1xuXHRkcmF3TGluZU1hcmtlcjogZnVuY3Rpb24gKGxlZ2VuZCkge1xuXG5cdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRtYXJrZXJPcHRpb25zID0gb3B0aW9ucy5tYXJrZXIsXG5cdFx0XHRyYWRpdXMsXG5cdFx0XHRsZWdlbmRPcHRpb25zID0gbGVnZW5kLm9wdGlvbnMsXG5cdFx0XHRsZWdlbmRTeW1ib2wsXG5cdFx0XHRzeW1ib2xXaWR0aCA9IGxlZ2VuZC5zeW1ib2xXaWR0aCxcblx0XHRcdHJlbmRlcmVyID0gdGhpcy5jaGFydC5yZW5kZXJlcixcblx0XHRcdGxlZ2VuZEl0ZW1Hcm91cCA9IHRoaXMubGVnZW5kR3JvdXAsXG5cdFx0XHR2ZXJ0aWNhbENlbnRlciA9IGxlZ2VuZC5iYXNlbGluZSAtIG1hdGhSb3VuZChyZW5kZXJlci5mb250TWV0cmljcyhsZWdlbmRPcHRpb25zLml0ZW1TdHlsZS5mb250U2l6ZSwgdGhpcy5sZWdlbmRJdGVtKS5iICogMC4zKSxcblx0XHRcdGF0dHI7XG5cblx0XHQvLyBEcmF3IHRoZSBsaW5lXG5cdFx0aWYgKG9wdGlvbnMubGluZVdpZHRoKSB7XG5cdFx0XHRhdHRyID0ge1xuXHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogb3B0aW9ucy5saW5lV2lkdGhcblx0XHRcdH07XG5cdFx0XHRpZiAob3B0aW9ucy5kYXNoU3R5bGUpIHtcblx0XHRcdFx0YXR0ci5kYXNoc3R5bGUgPSBvcHRpb25zLmRhc2hTdHlsZTtcblx0XHRcdH1cblx0XHRcdHRoaXMubGVnZW5kTGluZSA9IHJlbmRlcmVyLnBhdGgoW1xuXHRcdFx0XHRNLFxuXHRcdFx0XHQwLFxuXHRcdFx0XHR2ZXJ0aWNhbENlbnRlcixcblx0XHRcdFx0TCxcblx0XHRcdFx0c3ltYm9sV2lkdGgsXG5cdFx0XHRcdHZlcnRpY2FsQ2VudGVyXG5cdFx0XHRdKVxuXHRcdFx0LmF0dHIoYXR0cilcblx0XHRcdC5hZGQobGVnZW5kSXRlbUdyb3VwKTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gRHJhdyB0aGUgbWFya2VyXG5cdFx0aWYgKG1hcmtlck9wdGlvbnMgJiYgbWFya2VyT3B0aW9ucy5lbmFibGVkICE9PSBmYWxzZSkge1xuXHRcdFx0cmFkaXVzID0gbWFya2VyT3B0aW9ucy5yYWRpdXM7XG5cdFx0XHR0aGlzLmxlZ2VuZFN5bWJvbCA9IGxlZ2VuZFN5bWJvbCA9IHJlbmRlcmVyLnN5bWJvbChcblx0XHRcdFx0dGhpcy5zeW1ib2wsXG5cdFx0XHRcdChzeW1ib2xXaWR0aCAvIDIpIC0gcmFkaXVzLFxuXHRcdFx0XHR2ZXJ0aWNhbENlbnRlciAtIHJhZGl1cyxcblx0XHRcdFx0MiAqIHJhZGl1cyxcblx0XHRcdFx0MiAqIHJhZGl1c1xuXHRcdFx0KVxuXHRcdFx0LmFkZChsZWdlbmRJdGVtR3JvdXApO1xuXHRcdFx0bGVnZW5kU3ltYm9sLmlzTWFya2VyID0gdHJ1ZTtcblx0XHR9XG5cdH1cbn07XG5cbi8vIFdvcmthcm91bmQgZm9yICMyMDMwLCBob3Jpem9udGFsIGxlZ2VuZCBpdGVtcyBub3QgZGlzcGxheWluZyBpbiBJRTExIFByZXZpZXcsXG4vLyBhbmQgZm9yICMyNTgwLCBhIHNpbWlsYXIgZHJhd2luZyBmbGF3IGluIEZpcmVmb3ggMjYuXG4vLyBUT0RPOiBFeHBsb3JlIGlmIHRoZXJlJ3MgYSBnZW5lcmFsIGNhdXNlIGZvciB0aGlzLiBUaGUgcHJvYmxlbSBtYXkgYmUgcmVsYXRlZCBcbi8vIHRvIG5lc3RlZCBncm91cCBlbGVtZW50cywgYXMgdGhlIGxlZ2VuZCBpdGVtIHRleHRzIGFyZSB3aXRoaW4gNCBncm91cCBlbGVtZW50cy5cbmlmICgvVHJpZGVudFxcLzdcXC4wLy50ZXN0KHVzZXJBZ2VudCkgfHwgaXNGaXJlZm94KSB7XG5cdHdyYXAoTGVnZW5kLnByb3RvdHlwZSwgJ3Bvc2l0aW9uSXRlbScsIGZ1bmN0aW9uIChwcm9jZWVkLCBpdGVtKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXMsXG5cdFx0XHRydW5Qb3NpdGlvbkl0ZW0gPSBmdW5jdGlvbiAoKSB7IC8vIElmIGNoYXJ0IGRlc3Ryb3llZCBpbiBzeW5jLCB0aGlzIGlzIHVuZGVmaW5lZCAoIzIwMzApXG5cdFx0XHRcdGlmIChpdGVtLl9sZWdlbmRJdGVtUG9zKSB7XG5cdFx0XHRcdFx0cHJvY2VlZC5jYWxsKGxlZ2VuZCwgaXRlbSk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBEbyBpdCBub3csIGZvciBleHBvcnQgYW5kIHRvIGdldCBjaGVja2JveCBwbGFjZW1lbnRcblx0XHRydW5Qb3NpdGlvbkl0ZW0oKTtcblx0XHRcblx0XHQvLyBEbyBpdCBhZnRlciB0byB3b3JrIGFyb3VuZCB0aGUgY29yZSBpc3N1ZVxuXHRcdHNldFRpbWVvdXQocnVuUG9zaXRpb25JdGVtKTtcblx0fSk7XG59XG4vKipcbiAqIFRoZSBjaGFydCBjbGFzc1xuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIEZ1bmN0aW9uIHRvIHJ1biB3aGVuIHRoZSBjaGFydCBoYXMgbG9hZGVkXG4gKi9cbmZ1bmN0aW9uIENoYXJ0KCkge1xuXHR0aGlzLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuQ2hhcnQucHJvdG90eXBlID0ge1xuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBjaGFydFxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKHVzZXJPcHRpb25zLCBjYWxsYmFjaykge1xuXG5cdFx0Ly8gSGFuZGxlIHJlZ3VsYXIgb3B0aW9uc1xuXHRcdHZhciBvcHRpb25zLFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHVzZXJPcHRpb25zLnNlcmllczsgLy8gc2tpcCBtZXJnaW5nIGRhdGEgcG9pbnRzIHRvIGluY3JlYXNlIHBlcmZvcm1hbmNlXG5cblx0XHR1c2VyT3B0aW9ucy5zZXJpZXMgPSBudWxsO1xuXHRcdG9wdGlvbnMgPSBtZXJnZShkZWZhdWx0T3B0aW9ucywgdXNlck9wdGlvbnMpOyAvLyBkbyB0aGUgbWVyZ2Vcblx0XHRvcHRpb25zLnNlcmllcyA9IHVzZXJPcHRpb25zLnNlcmllcyA9IHNlcmllc09wdGlvbnM7IC8vIHNldCBiYWNrIHRoZSBzZXJpZXMgZGF0YVxuXHRcdHRoaXMudXNlck9wdGlvbnMgPSB1c2VyT3B0aW9ucztcblxuXHRcdHZhciBvcHRpb25zQ2hhcnQgPSBvcHRpb25zLmNoYXJ0O1xuXHRcdFxuXHRcdC8vIENyZWF0ZSBtYXJnaW4gJiBzcGFjaW5nIGFycmF5XG5cdFx0dGhpcy5tYXJnaW4gPSB0aGlzLnNwbGFzaEFycmF5KCdtYXJnaW4nLCBvcHRpb25zQ2hhcnQpO1xuXHRcdHRoaXMuc3BhY2luZyA9IHRoaXMuc3BsYXNoQXJyYXkoJ3NwYWNpbmcnLCBvcHRpb25zQ2hhcnQpO1xuXG5cdFx0dmFyIGNoYXJ0RXZlbnRzID0gb3B0aW9uc0NoYXJ0LmV2ZW50cztcblxuXHRcdC8vdGhpcy5ydW5DaGFydENsaWNrID0gY2hhcnRFdmVudHMgJiYgISFjaGFydEV2ZW50cy5jbGljaztcblx0XHR0aGlzLmJvdW5kcyA9IHsgaDoge30sIHY6IHt9IH07IC8vIFBpeGVsIGRhdGEgYm91bmRzIGZvciB0b3VjaCB6b29tXG5cblx0XHR0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cdFx0dGhpcy5pc1Jlc2l6aW5nID0gMDtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdC8vY2hhcnRUaXRsZU9wdGlvbnMgPSBVTkRFRklORUQ7XG5cdFx0Ly9jaGFydFN1YnRpdGxlT3B0aW9ucyA9IFVOREVGSU5FRDtcblxuXHRcdHRoaXMuYXhlcyA9IFtdO1xuXHRcdHRoaXMuc2VyaWVzID0gW107XG5cdFx0dGhpcy5oYXNDYXJ0ZXNpYW5TZXJpZXMgPSBvcHRpb25zQ2hhcnQuc2hvd0F4ZXM7XG5cdFx0Ly90aGlzLmF4aXNPZmZzZXQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLm1heFRpY2tzID0gVU5ERUZJTkVEOyAvLyBoYW5kbGUgdGhlIGdyZWF0ZXN0IGFtb3VudCBvZiB0aWNrcyBvbiBncm91cGVkIGF4ZXNcblx0XHQvL3RoaXMuaW52ZXJ0ZWQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLmxvYWRpbmdTaG93biA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMuY29udGFpbmVyID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5jaGFydFdpZHRoID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5jaGFydEhlaWdodCA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMubWFyZ2luUmlnaHQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLm1hcmdpbkJvdHRvbSA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMuY29udGFpbmVyV2lkdGggPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLmNvbnRhaW5lckhlaWdodCA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMub2xkQ2hhcnRXaWR0aCA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMub2xkQ2hhcnRIZWlnaHQgPSBVTkRFRklORUQ7XG5cblx0XHQvL3RoaXMucmVuZGVyVG8gPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLnJlbmRlclRvQ2xvbmUgPSBVTkRFRklORUQ7XG5cblx0XHQvL3RoaXMuc3BhY2luZ0JveCA9IFVOREVGSU5FRFxuXG5cdFx0Ly90aGlzLmxlZ2VuZCA9IFVOREVGSU5FRDtcblxuXHRcdC8vIEVsZW1lbnRzXG5cdFx0Ly90aGlzLmNoYXJ0QmFja2dyb3VuZCA9IFVOREVGSU5FRDtcblx0XHQvL3RoaXMucGxvdEJhY2tncm91bmQgPSBVTkRFRklORUQ7XG5cdFx0Ly90aGlzLnBsb3RCR0ltYWdlID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5wbG90Qm9yZGVyID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5sb2FkaW5nRGl2ID0gVU5ERUZJTkVEO1xuXHRcdC8vdGhpcy5sb2FkaW5nU3BhbiA9IFVOREVGSU5FRDtcblxuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRldmVudFR5cGU7XG5cblx0XHQvLyBBZGQgdGhlIGNoYXJ0IHRvIHRoZSBnbG9iYWwgbG9va3VwXG5cdFx0Y2hhcnQuaW5kZXggPSBjaGFydHMubGVuZ3RoO1xuXHRcdGNoYXJ0cy5wdXNoKGNoYXJ0KTtcblx0XHRjaGFydENvdW50Kys7XG5cblx0XHQvLyBTZXQgdXAgYXV0byByZXNpemVcblx0XHRpZiAob3B0aW9uc0NoYXJ0LnJlZmxvdyAhPT0gZmFsc2UpIHtcblx0XHRcdGFkZEV2ZW50KGNoYXJ0LCAnbG9hZCcsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0Y2hhcnQuaW5pdFJlZmxvdygpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gQ2hhcnQgZXZlbnQgaGFuZGxlcnNcblx0XHRpZiAoY2hhcnRFdmVudHMpIHtcblx0XHRcdGZvciAoZXZlbnRUeXBlIGluIGNoYXJ0RXZlbnRzKSB7XG5cdFx0XHRcdGFkZEV2ZW50KGNoYXJ0LCBldmVudFR5cGUsIGNoYXJ0RXZlbnRzW2V2ZW50VHlwZV0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGNoYXJ0LnhBeGlzID0gW107XG5cdFx0Y2hhcnQueUF4aXMgPSBbXTtcblxuXHRcdC8vIEV4cG9zZSBtZXRob2RzIGFuZCB2YXJpYWJsZXNcblx0XHRjaGFydC5hbmltYXRpb24gPSB1c2VDYW5WRyA/IGZhbHNlIDogcGljayhvcHRpb25zQ2hhcnQuYW5pbWF0aW9uLCB0cnVlKTtcblx0XHRjaGFydC5wb2ludENvdW50ID0gY2hhcnQuY29sb3JDb3VudGVyID0gY2hhcnQuc3ltYm9sQ291bnRlciA9IDA7XG5cblx0XHRjaGFydC5maXJzdFJlbmRlcigpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIGFuIGluZGl2aWR1YWwgc2VyaWVzLCBjYWxsZWQgaW50ZXJuYWxseSBiZWZvcmUgcmVuZGVyIHRpbWVcblx0ICovXG5cdGluaXRTZXJpZXM6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnNDaGFydCA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQsXG5cdFx0XHR0eXBlID0gb3B0aW9ucy50eXBlIHx8IG9wdGlvbnNDaGFydC50eXBlIHx8IG9wdGlvbnNDaGFydC5kZWZhdWx0U2VyaWVzVHlwZSxcblx0XHRcdHNlcmllcyxcblx0XHRcdGNvbnN0ciA9IHNlcmllc1R5cGVzW3R5cGVdO1xuXG5cdFx0Ly8gTm8gc3VjaCBzZXJpZXMgdHlwZVxuXHRcdGlmICghY29uc3RyKSB7XG5cdFx0XHRlcnJvcigxNywgdHJ1ZSk7XG5cdFx0fVxuXG5cdFx0c2VyaWVzID0gbmV3IGNvbnN0cigpO1xuXHRcdHNlcmllcy5pbml0KHRoaXMsIG9wdGlvbnMpO1xuXHRcdHJldHVybiBzZXJpZXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENoZWNrIHdoZXRoZXIgYSBnaXZlbiBwb2ludCBpcyB3aXRoaW4gdGhlIHBsb3QgYXJlYVxuXHQgKlxuXHQgKiBAcGFyYW0ge051bWJlcn0gcGxvdFggUGl4ZWwgeCByZWxhdGl2ZSB0byB0aGUgcGxvdCBhcmVhXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBwbG90WSBQaXhlbCB5IHJlbGF0aXZlIHRvIHRoZSBwbG90IGFyZWFcblx0ICogQHBhcmFtIHtCb29sZWFufSBpbnZlcnRlZCBXaGV0aGVyIHRoZSBjaGFydCBpcyBpbnZlcnRlZFxuXHQgKi9cblx0aXNJbnNpZGVQbG90OiBmdW5jdGlvbiAocGxvdFgsIHBsb3RZLCBpbnZlcnRlZCkge1xuXHRcdHZhciB4ID0gaW52ZXJ0ZWQgPyBwbG90WSA6IHBsb3RYLFxuXHRcdFx0eSA9IGludmVydGVkID8gcGxvdFggOiBwbG90WTtcblx0XHRcdFxuXHRcdHJldHVybiB4ID49IDAgJiZcblx0XHRcdHggPD0gdGhpcy5wbG90V2lkdGggJiZcblx0XHRcdHkgPj0gMCAmJlxuXHRcdFx0eSA8PSB0aGlzLnBsb3RIZWlnaHQ7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkanVzdCBhbGwgYXhlcyB0aWNrIGFtb3VudHNcblx0ICovXG5cdGFkanVzdFRpY2tBbW91bnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMub3B0aW9ucy5jaGFydC5hbGlnblRpY2tzICE9PSBmYWxzZSkge1xuXHRcdFx0ZWFjaCh0aGlzLmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdGF4aXMuYWRqdXN0VGlja0Ftb3VudCgpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRoaXMubWF4VGlja3MgPSBudWxsO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZWRyYXcgbGVnZW5kLCBheGVzIG9yIHNlcmllcyBiYXNlZCBvbiB1cGRhdGVkIGRhdGFcblx0ICpcblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gYW5pbWF0aW9uIFdoZXRoZXIgdG8gYXBwbHkgYW5pbWF0aW9uLCBhbmQgb3B0aW9uYWxseSBhbmltYXRpb25cblx0ICogICAgY29uZmlndXJhdGlvblxuXHQgKi9cblx0cmVkcmF3OiBmdW5jdGlvbiAoYW5pbWF0aW9uKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGF4ZXMgPSBjaGFydC5heGVzLFxuXHRcdFx0c2VyaWVzID0gY2hhcnQuc2VyaWVzLFxuXHRcdFx0cG9pbnRlciA9IGNoYXJ0LnBvaW50ZXIsXG5cdFx0XHRsZWdlbmQgPSBjaGFydC5sZWdlbmQsXG5cdFx0XHRyZWRyYXdMZWdlbmQgPSBjaGFydC5pc0RpcnR5TGVnZW5kLFxuXHRcdFx0aGFzU3RhY2tlZFNlcmllcyxcblx0XHRcdGhhc0RpcnR5U3RhY2tzLFxuXHRcdFx0aGFzQ2FydGVzaWFuU2VyaWVzID0gY2hhcnQuaGFzQ2FydGVzaWFuU2VyaWVzLFxuXHRcdFx0aXNEaXJ0eUJveCA9IGNoYXJ0LmlzRGlydHlCb3gsIC8vIHRvZG86IGNoZWNrIGlmIGl0IGhhcyBhY3R1YWxseSBjaGFuZ2VkP1xuXHRcdFx0c2VyaWVzTGVuZ3RoID0gc2VyaWVzLmxlbmd0aCxcblx0XHRcdGkgPSBzZXJpZXNMZW5ndGgsXG5cdFx0XHRzZXJpZSxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRpc0hpZGRlbkNoYXJ0ID0gcmVuZGVyZXIuaXNIaWRkZW4oKSxcblx0XHRcdGFmdGVyUmVkcmF3ID0gW107XG5cdFx0XHRcblx0XHRzZXRBbmltYXRpb24oYW5pbWF0aW9uLCBjaGFydCk7XG5cdFx0XG5cdFx0aWYgKGlzSGlkZGVuQ2hhcnQpIHtcblx0XHRcdGNoYXJ0LmNsb25lUmVuZGVyVG8oKTtcblx0XHR9XG5cblx0XHQvLyBBZGp1c3QgdGl0bGUgbGF5b3V0IChyZWZsb3cgbXVsdGlsaW5lIHRleHQpXG5cdFx0Y2hhcnQubGF5T3V0VGl0bGVzKCk7XG5cblx0XHQvLyBsaW5rIHN0YWNrZWQgc2VyaWVzXG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0c2VyaWUgPSBzZXJpZXNbaV07XG5cblx0XHRcdGlmIChzZXJpZS5vcHRpb25zLnN0YWNraW5nKSB7XG5cdFx0XHRcdGhhc1N0YWNrZWRTZXJpZXMgPSB0cnVlO1xuXHRcdFx0XHRcblx0XHRcdFx0aWYgKHNlcmllLmlzRGlydHkpIHtcblx0XHRcdFx0XHRoYXNEaXJ0eVN0YWNrcyA9IHRydWU7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKGhhc0RpcnR5U3RhY2tzKSB7IC8vIG1hcmsgb3RoZXJzIGFzIGRpcnR5XG5cdFx0XHRpID0gc2VyaWVzTGVuZ3RoO1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRzZXJpZSA9IHNlcmllc1tpXTtcblx0XHRcdFx0aWYgKHNlcmllLm9wdGlvbnMuc3RhY2tpbmcpIHtcblx0XHRcdFx0XHRzZXJpZS5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGhhbmRsZSB1cGRhdGVkIGRhdGEgaW4gdGhlIHNlcmllc1xuXHRcdGVhY2goc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWUpIHtcblx0XHRcdGlmIChzZXJpZS5pc0RpcnR5KSB7IC8vIHByZXBhcmUgdGhlIGRhdGEgc28gYXhpcyBjYW4gcmVhZCBpdFxuXHRcdFx0XHRpZiAoc2VyaWUub3B0aW9ucy5sZWdlbmRUeXBlID09PSAncG9pbnQnKSB7XG5cdFx0XHRcdFx0cmVkcmF3TGVnZW5kID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gaGFuZGxlIGFkZGVkIG9yIHJlbW92ZWQgc2VyaWVzXG5cdFx0aWYgKHJlZHJhd0xlZ2VuZCAmJiBsZWdlbmQub3B0aW9ucy5lbmFibGVkKSB7IC8vIHNlcmllcyBvciBwaWUgcG9pbnRzIGFyZSBhZGRlZCBvciByZW1vdmVkXG5cdFx0XHQvLyBkcmF3IGxlZ2VuZCBncmFwaGljc1xuXHRcdFx0bGVnZW5kLnJlbmRlcigpO1xuXG5cdFx0XHRjaGFydC5pc0RpcnR5TGVnZW5kID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcmVzZXQgc3RhY2tzXG5cdFx0aWYgKGhhc1N0YWNrZWRTZXJpZXMpIHtcblx0XHRcdGNoYXJ0LmdldFN0YWNrcygpO1xuXHRcdH1cblxuXG5cdFx0aWYgKGhhc0NhcnRlc2lhblNlcmllcykge1xuXHRcdFx0aWYgKCFjaGFydC5pc1Jlc2l6aW5nKSB7XG5cblx0XHRcdFx0Ly8gcmVzZXQgbWF4VGlja3Ncblx0XHRcdFx0Y2hhcnQubWF4VGlja3MgPSBudWxsO1xuXG5cdFx0XHRcdC8vIHNldCBheGVzIHNjYWxlc1xuXHRcdFx0XHRlYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdFx0YXhpcy5zZXRTY2FsZSgpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Y2hhcnQuYWRqdXN0VGlja0Ftb3VudHMoKTtcblx0XHR9XG5cblx0XHRjaGFydC5nZXRNYXJnaW5zKCk7IC8vICMzMDk4XG5cblx0XHRpZiAoaGFzQ2FydGVzaWFuU2VyaWVzKSB7XG5cdFx0XHQvLyBJZiBvbmUgYXhpcyBpcyBkaXJ0eSwgYWxsIGF4ZXMgbXVzdCBiZSByZWRyYXduICgjNzkyLCAjMjE2OSlcblx0XHRcdGVhY2goYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0aWYgKGF4aXMuaXNEaXJ0eSkge1xuXHRcdFx0XHRcdGlzRGlydHlCb3ggPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gcmVkcmF3IGF4ZXNcblx0XHRcdGVhY2goYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0XG5cdFx0XHRcdC8vIEZpcmUgJ2FmdGVyU2V0RXh0cmVtZXMnIG9ubHkgaWYgZXh0cmVtZXMgYXJlIHNldFxuXHRcdFx0XHRpZiAoYXhpcy5pc0RpcnR5RXh0cmVtZXMpIHsgLy8gIzgyMVxuXHRcdFx0XHRcdGF4aXMuaXNEaXJ0eUV4dHJlbWVzID0gZmFsc2U7XG5cdFx0XHRcdFx0YWZ0ZXJSZWRyYXcucHVzaChmdW5jdGlvbiAoKSB7IC8vIHByZXZlbnQgYSByZWN1cnNpdmUgY2FsbCB0byBjaGFydC5yZWRyYXcoKSAoIzExMTkpXG5cdFx0XHRcdFx0XHRmaXJlRXZlbnQoYXhpcywgJ2FmdGVyU2V0RXh0cmVtZXMnLCBleHRlbmQoYXhpcy5ldmVudEFyZ3MsIGF4aXMuZ2V0RXh0cmVtZXMoKSkpOyAvLyAjNzQ3LCAjNzUxXG5cdFx0XHRcdFx0XHRkZWxldGUgYXhpcy5ldmVudEFyZ3M7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdGlmIChpc0RpcnR5Qm94IHx8IGhhc1N0YWNrZWRTZXJpZXMpIHtcblx0XHRcdFx0XHRheGlzLnJlZHJhdygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gdGhlIHBsb3QgYXJlYXMgc2l6ZSBoYXMgY2hhbmdlZFxuXHRcdGlmIChpc0RpcnR5Qm94KSB7XG5cdFx0XHRjaGFydC5kcmF3Q2hhcnRCb3goKTtcblx0XHR9XG5cblxuXHRcdC8vIHJlZHJhdyBhZmZlY3RlZCBzZXJpZXNcblx0XHRlYWNoKHNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRpZiAoc2VyaWUuaXNEaXJ0eSAmJiBzZXJpZS52aXNpYmxlICYmXG5cdFx0XHRcdFx0KCFzZXJpZS5pc0NhcnRlc2lhbiB8fCBzZXJpZS54QXhpcykpIHsgLy8gaXNzdWUgIzE1M1xuXHRcdFx0XHRzZXJpZS5yZWRyYXcoKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIG1vdmUgdG9vbHRpcCBvciByZXNldFxuXHRcdGlmIChwb2ludGVyKSB7XG5cdFx0XHRwb2ludGVyLnJlc2V0KHRydWUpO1xuXHRcdH1cblxuXHRcdC8vIHJlZHJhdyBpZiBjYW52YXNcblx0XHRyZW5kZXJlci5kcmF3KCk7XG5cblx0XHQvLyBmaXJlIHRoZSBldmVudFxuXHRcdGZpcmVFdmVudChjaGFydCwgJ3JlZHJhdycpOyAvLyBqUXVlcnkgYnJlYWtzIHRoaXMgd2hlbiBjYWxsaW5nIGl0IGZyb20gYWRkRXZlbnQuIE92ZXJ3cml0ZXMgY2hhcnQucmVkcmF3XG5cdFx0XG5cdFx0aWYgKGlzSGlkZGVuQ2hhcnQpIHtcblx0XHRcdGNoYXJ0LmNsb25lUmVuZGVyVG8odHJ1ZSk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIEZpcmUgY2FsbGJhY2tzIHRoYXQgYXJlIHB1dCBvbiBob2xkIHVudGlsIGFmdGVyIHRoZSByZWRyYXdcblx0XHRlYWNoKGFmdGVyUmVkcmF3LCBmdW5jdGlvbiAoY2FsbGJhY2spIHtcblx0XHRcdGNhbGxiYWNrLmNhbGwoKTtcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogR2V0IGFuIGF4aXMsIHNlcmllcyBvciBwb2ludCBvYmplY3QgYnkgaWQuXG5cdCAqIEBwYXJhbSBpZCB7U3RyaW5nfSBUaGUgaWQgYXMgZ2l2ZW4gaW4gdGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9uc1xuXHQgKi9cblx0Z2V0OiBmdW5jdGlvbiAoaWQpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0YXhlcyA9IGNoYXJ0LmF4ZXMsXG5cdFx0XHRzZXJpZXMgPSBjaGFydC5zZXJpZXM7XG5cblx0XHR2YXIgaSxcblx0XHRcdGosXG5cdFx0XHRwb2ludHM7XG5cblx0XHQvLyBzZWFyY2ggYXhlc1xuXHRcdGZvciAoaSA9IDA7IGkgPCBheGVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXhlc1tpXS5vcHRpb25zLmlkID09PSBpZCkge1xuXHRcdFx0XHRyZXR1cm4gYXhlc1tpXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBzZWFyY2ggc2VyaWVzXG5cdFx0Zm9yIChpID0gMDsgaSA8IHNlcmllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHNlcmllc1tpXS5vcHRpb25zLmlkID09PSBpZCkge1xuXHRcdFx0XHRyZXR1cm4gc2VyaWVzW2ldO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHNlYXJjaCBwb2ludHNcblx0XHRmb3IgKGkgPSAwOyBpIDwgc2VyaWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRwb2ludHMgPSBzZXJpZXNbaV0ucG9pbnRzIHx8IFtdO1xuXHRcdFx0Zm9yIChqID0gMDsgaiA8IHBvaW50cy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHRpZiAocG9pbnRzW2pdLmlkID09PSBpZCkge1xuXHRcdFx0XHRcdHJldHVybiBwb2ludHNbal07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG51bGw7XG5cdH0sXG5cblx0LyoqXG5cdCAqIENyZWF0ZSB0aGUgQXhpcyBpbnN0YW5jZXMgYmFzZWQgb24gdGhlIGNvbmZpZyBvcHRpb25zXG5cdCAqL1xuXHRnZXRBeGVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHR4QXhpc09wdGlvbnMgPSBvcHRpb25zLnhBeGlzID0gc3BsYXQob3B0aW9ucy54QXhpcyB8fCB7fSksXG5cdFx0XHR5QXhpc09wdGlvbnMgPSBvcHRpb25zLnlBeGlzID0gc3BsYXQob3B0aW9ucy55QXhpcyB8fCB7fSksXG5cdFx0XHRvcHRpb25zQXJyYXksXG5cdFx0XHRheGlzO1xuXG5cdFx0Ly8gbWFrZSBzdXJlIHRoZSBvcHRpb25zIGFyZSBhcnJheXMgYW5kIGFkZCBzb21lIG1lbWJlcnNcblx0XHRlYWNoKHhBeGlzT3B0aW9ucywgZnVuY3Rpb24gKGF4aXMsIGkpIHtcblx0XHRcdGF4aXMuaW5kZXggPSBpO1xuXHRcdFx0YXhpcy5pc1ggPSB0cnVlO1xuXHRcdH0pO1xuXG5cdFx0ZWFjaCh5QXhpc09wdGlvbnMsIGZ1bmN0aW9uIChheGlzLCBpKSB7XG5cdFx0XHRheGlzLmluZGV4ID0gaTtcblx0XHR9KTtcblxuXHRcdC8vIGNvbmNhdGVuYXRlIGFsbCBheGlzIG9wdGlvbnMgaW50byBvbmUgYXJyYXlcblx0XHRvcHRpb25zQXJyYXkgPSB4QXhpc09wdGlvbnMuY29uY2F0KHlBeGlzT3B0aW9ucyk7XG5cblx0XHRlYWNoKG9wdGlvbnNBcnJheSwgZnVuY3Rpb24gKGF4aXNPcHRpb25zKSB7XG5cdFx0XHRheGlzID0gbmV3IEF4aXMoY2hhcnQsIGF4aXNPcHRpb25zKTtcblx0XHR9KTtcblxuXHRcdGNoYXJ0LmFkanVzdFRpY2tBbW91bnRzKCk7XG5cdH0sXG5cblxuXHQvKipcblx0ICogR2V0IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcG9pbnRzIGZyb20gYWxsIHNlcmllc1xuXHQgKi9cblx0Z2V0U2VsZWN0ZWRQb2ludHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcG9pbnRzID0gW107XG5cdFx0ZWFjaCh0aGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRwb2ludHMgPSBwb2ludHMuY29uY2F0KGdyZXAoc2VyaWUucG9pbnRzIHx8IFtdLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0cmV0dXJuIHBvaW50LnNlbGVjdGVkO1xuXHRcdFx0fSkpO1xuXHRcdH0pO1xuXHRcdHJldHVybiBwb2ludHM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHNlcmllc1xuXHQgKi9cblx0Z2V0U2VsZWN0ZWRTZXJpZXM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gZ3JlcCh0aGlzLnNlcmllcywgZnVuY3Rpb24gKHNlcmllKSB7XG5cdFx0XHRyZXR1cm4gc2VyaWUuc2VsZWN0ZWQ7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdlbmVyYXRlIHN0YWNrcyBmb3IgZWFjaCBzZXJpZXMgYW5kIGNhbGN1bGF0ZSBzdGFja3MgdG90YWwgdmFsdWVzXG5cdCAqL1xuXHRnZXRTdGFja3M6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzO1xuXG5cdFx0Ly8gcmVzZXQgc3RhY2tzIGZvciBlYWNoIHlBeGlzXG5cdFx0ZWFjaChjaGFydC55QXhpcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdGlmIChheGlzLnN0YWNrcyAmJiBheGlzLmhhc1Zpc2libGVTZXJpZXMpIHtcblx0XHRcdFx0YXhpcy5vbGRTdGFja3MgPSBheGlzLnN0YWNrcztcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdGVhY2goY2hhcnQuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWVzKSB7XG5cdFx0XHRpZiAoc2VyaWVzLm9wdGlvbnMuc3RhY2tpbmcgJiYgKHNlcmllcy52aXNpYmxlID09PSB0cnVlIHx8IGNoYXJ0Lm9wdGlvbnMuY2hhcnQuaWdub3JlSGlkZGVuU2VyaWVzID09PSBmYWxzZSkpIHtcblx0XHRcdFx0c2VyaWVzLnN0YWNrS2V5ID0gc2VyaWVzLnR5cGUgKyBwaWNrKHNlcmllcy5vcHRpb25zLnN0YWNrLCAnJyk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXHRcblxuXHQvKipcblx0ICogU2hvdyB0aGUgdGl0bGUgYW5kIHN1YnRpdGxlIG9mIHRoZSBjaGFydFxuXHQgKlxuXHQgKiBAcGFyYW0gdGl0bGVPcHRpb25zIHtPYmplY3R9IE5ldyB0aXRsZSBvcHRpb25zXG5cdCAqIEBwYXJhbSBzdWJ0aXRsZU9wdGlvbnMge09iamVjdH0gTmV3IHN1YnRpdGxlIG9wdGlvbnNcblx0ICpcblx0ICovXG5cdHNldFRpdGxlOiBmdW5jdGlvbiAodGl0bGVPcHRpb25zLCBzdWJ0aXRsZU9wdGlvbnMsIHJlZHJhdykge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gY2hhcnQub3B0aW9ucyxcblx0XHRcdGNoYXJ0VGl0bGVPcHRpb25zLFxuXHRcdFx0Y2hhcnRTdWJ0aXRsZU9wdGlvbnM7XG5cblx0XHRjaGFydFRpdGxlT3B0aW9ucyA9IG9wdGlvbnMudGl0bGUgPSBtZXJnZShvcHRpb25zLnRpdGxlLCB0aXRsZU9wdGlvbnMpO1xuXHRcdGNoYXJ0U3VidGl0bGVPcHRpb25zID0gb3B0aW9ucy5zdWJ0aXRsZSA9IG1lcmdlKG9wdGlvbnMuc3VidGl0bGUsIHN1YnRpdGxlT3B0aW9ucyk7XG5cblx0XHQvLyBhZGQgdGl0bGUgYW5kIHN1YnRpdGxlXG5cdFx0ZWFjaChbXG5cdFx0XHRbJ3RpdGxlJywgdGl0bGVPcHRpb25zLCBjaGFydFRpdGxlT3B0aW9uc10sXG5cdFx0XHRbJ3N1YnRpdGxlJywgc3VidGl0bGVPcHRpb25zLCBjaGFydFN1YnRpdGxlT3B0aW9uc11cblx0XHRdLCBmdW5jdGlvbiAoYXJyKSB7XG5cdFx0XHR2YXIgbmFtZSA9IGFyclswXSxcblx0XHRcdFx0dGl0bGUgPSBjaGFydFtuYW1lXSxcblx0XHRcdFx0dGl0bGVPcHRpb25zID0gYXJyWzFdLFxuXHRcdFx0XHRjaGFydFRpdGxlT3B0aW9ucyA9IGFyclsyXTtcblxuXHRcdFx0aWYgKHRpdGxlICYmIHRpdGxlT3B0aW9ucykge1xuXHRcdFx0XHRjaGFydFtuYW1lXSA9IHRpdGxlID0gdGl0bGUuZGVzdHJveSgpOyAvLyByZW1vdmUgb2xkXG5cdFx0XHR9XG5cdFx0XHRcblx0XHRcdGlmIChjaGFydFRpdGxlT3B0aW9ucyAmJiBjaGFydFRpdGxlT3B0aW9ucy50ZXh0ICYmICF0aXRsZSkge1xuXHRcdFx0XHRjaGFydFtuYW1lXSA9IGNoYXJ0LnJlbmRlcmVyLnRleHQoXG5cdFx0XHRcdFx0Y2hhcnRUaXRsZU9wdGlvbnMudGV4dCxcblx0XHRcdFx0XHQwLFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0Y2hhcnRUaXRsZU9wdGlvbnMudXNlSFRNTFxuXHRcdFx0XHQpXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRhbGlnbjogY2hhcnRUaXRsZU9wdGlvbnMuYWxpZ24sXG5cdFx0XHRcdFx0J2NsYXNzJzogUFJFRklYICsgbmFtZSxcblx0XHRcdFx0XHR6SW5kZXg6IGNoYXJ0VGl0bGVPcHRpb25zLnpJbmRleCB8fCA0XG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5jc3MoY2hhcnRUaXRsZU9wdGlvbnMuc3R5bGUpXG5cdFx0XHRcdC5hZGQoKTtcblx0XHRcdH1cdFxuXHRcdH0pO1xuXHRcdGNoYXJ0LmxheU91dFRpdGxlcyhyZWRyYXcpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBMYXkgb3V0IHRoZSBjaGFydCB0aXRsZXMgYW5kIGNhY2hlIHRoZSBmdWxsIG9mZnNldCBoZWlnaHQgZm9yIHVzZSBpbiBnZXRNYXJnaW5zXG5cdCAqL1xuXHRsYXlPdXRUaXRsZXM6IGZ1bmN0aW9uIChyZWRyYXcpIHtcblx0XHR2YXIgdGl0bGVPZmZzZXQgPSAwLFxuXHRcdFx0dGl0bGUgPSB0aGlzLnRpdGxlLFxuXHRcdFx0c3VidGl0bGUgPSB0aGlzLnN1YnRpdGxlLFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdHRpdGxlT3B0aW9ucyA9IG9wdGlvbnMudGl0bGUsXG5cdFx0XHRzdWJ0aXRsZU9wdGlvbnMgPSBvcHRpb25zLnN1YnRpdGxlLFxuXHRcdFx0cmVxdWlyZXNEaXJ0eUJveCxcblx0XHRcdHJlbmRlcmVyID0gdGhpcy5yZW5kZXJlcixcblx0XHRcdGF1dG9XaWR0aCA9IHRoaXMuc3BhY2luZ0JveC53aWR0aCAtIDQ0OyAvLyA0NCBtYWtlcyByb29tIGZvciBkZWZhdWx0IGNvbnRleHQgYnV0dG9uXG5cblx0XHRpZiAodGl0bGUpIHtcblx0XHRcdHRpdGxlXG5cdFx0XHRcdC5jc3MoeyB3aWR0aDogKHRpdGxlT3B0aW9ucy53aWR0aCB8fCBhdXRvV2lkdGgpICsgUFggfSlcblx0XHRcdFx0LmFsaWduKGV4dGVuZCh7IFxuXHRcdFx0XHRcdHk6IHJlbmRlcmVyLmZvbnRNZXRyaWNzKHRpdGxlT3B0aW9ucy5zdHlsZS5mb250U2l6ZSwgdGl0bGUpLmIgLSAzXG5cdFx0XHRcdH0sIHRpdGxlT3B0aW9ucyksIGZhbHNlLCAnc3BhY2luZ0JveCcpO1xuXHRcdFx0XG5cdFx0XHRpZiAoIXRpdGxlT3B0aW9ucy5mbG9hdGluZyAmJiAhdGl0bGVPcHRpb25zLnZlcnRpY2FsQWxpZ24pIHtcblx0XHRcdFx0dGl0bGVPZmZzZXQgPSB0aXRsZS5nZXRCQm94KCkuaGVpZ2h0O1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoc3VidGl0bGUpIHtcblx0XHRcdHN1YnRpdGxlXG5cdFx0XHRcdC5jc3MoeyB3aWR0aDogKHN1YnRpdGxlT3B0aW9ucy53aWR0aCB8fCBhdXRvV2lkdGgpICsgUFggfSlcblx0XHRcdFx0LmFsaWduKGV4dGVuZCh7IFxuXHRcdFx0XHRcdHk6IHRpdGxlT2Zmc2V0ICsgKHRpdGxlT3B0aW9ucy5tYXJnaW4gLSAxMykgKyByZW5kZXJlci5mb250TWV0cmljcyh0aXRsZU9wdGlvbnMuc3R5bGUuZm9udFNpemUsIHN1YnRpdGxlKS5iIFxuXHRcdFx0XHR9LCBzdWJ0aXRsZU9wdGlvbnMpLCBmYWxzZSwgJ3NwYWNpbmdCb3gnKTtcblx0XHRcdFxuXHRcdFx0aWYgKCFzdWJ0aXRsZU9wdGlvbnMuZmxvYXRpbmcgJiYgIXN1YnRpdGxlT3B0aW9ucy52ZXJ0aWNhbEFsaWduKSB7XG5cdFx0XHRcdHRpdGxlT2Zmc2V0ID0gbWF0aENlaWwodGl0bGVPZmZzZXQgKyBzdWJ0aXRsZS5nZXRCQm94KCkuaGVpZ2h0KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXF1aXJlc0RpcnR5Qm94ID0gdGhpcy50aXRsZU9mZnNldCAhPT0gdGl0bGVPZmZzZXQ7XHRcdFx0XHRcblx0XHR0aGlzLnRpdGxlT2Zmc2V0ID0gdGl0bGVPZmZzZXQ7IC8vIHVzZWQgaW4gZ2V0TWFyZ2luc1xuXG5cdFx0aWYgKCF0aGlzLmlzRGlydHlCb3ggJiYgcmVxdWlyZXNEaXJ0eUJveCkge1xuXHRcdFx0dGhpcy5pc0RpcnR5Qm94ID0gcmVxdWlyZXNEaXJ0eUJveDtcblx0XHRcdC8vIFJlZHJhdyBpZiBuZWNlc3NhcnkgKCMyNzE5LCAjMjc0NClcdFx0XG5cdFx0XHRpZiAodGhpcy5oYXNSZW5kZXJlZCAmJiBwaWNrKHJlZHJhdywgdHJ1ZSkgJiYgdGhpcy5pc0RpcnR5Qm94KSB7XG5cdFx0XHRcdHRoaXMucmVkcmF3KCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgY2hhcnQgd2lkdGggYW5kIGhlaWdodCBhY2NvcmRpbmcgdG8gb3B0aW9ucyBhbmQgY29udGFpbmVyIHNpemVcblx0ICovXG5cdGdldENoYXJ0U2l6ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0d2lkdGhPcHRpb24gPSBvcHRpb25zQ2hhcnQud2lkdGgsXG5cdFx0XHRoZWlnaHRPcHRpb24gPSBvcHRpb25zQ2hhcnQuaGVpZ2h0LFxuXHRcdFx0cmVuZGVyVG8gPSBjaGFydC5yZW5kZXJUb0Nsb25lIHx8IGNoYXJ0LnJlbmRlclRvO1xuXG5cdFx0Ly8gZ2V0IGlubmVyIHdpZHRoIGFuZCBoZWlnaHQgZnJvbSBqUXVlcnkgKCM4MjQpXG5cdFx0aWYgKCFkZWZpbmVkKHdpZHRoT3B0aW9uKSkge1xuXHRcdFx0Y2hhcnQuY29udGFpbmVyV2lkdGggPSBhZGFwdGVyUnVuKHJlbmRlclRvLCAnd2lkdGgnKTtcblx0XHR9XG5cdFx0aWYgKCFkZWZpbmVkKGhlaWdodE9wdGlvbikpIHtcblx0XHRcdGNoYXJ0LmNvbnRhaW5lckhlaWdodCA9IGFkYXB0ZXJSdW4ocmVuZGVyVG8sICdoZWlnaHQnKTtcblx0XHR9XG5cdFx0XG5cdFx0Y2hhcnQuY2hhcnRXaWR0aCA9IG1hdGhNYXgoMCwgd2lkdGhPcHRpb24gfHwgY2hhcnQuY29udGFpbmVyV2lkdGggfHwgNjAwKTsgLy8gIzEzOTMsIDE0NjBcblx0XHRjaGFydC5jaGFydEhlaWdodCA9IG1hdGhNYXgoMCwgcGljayhoZWlnaHRPcHRpb24sXG5cdFx0XHQvLyB0aGUgb2Zmc2V0SGVpZ2h0IG9mIGFuIGVtcHR5IGNvbnRhaW5lciBpcyAwIGluIHN0YW5kYXJkIGJyb3dzZXJzLCBidXQgMTkgaW4gSUU3OlxuXHRcdFx0Y2hhcnQuY29udGFpbmVySGVpZ2h0ID4gMTkgPyBjaGFydC5jb250YWluZXJIZWlnaHQgOiA0MDApKTtcblx0fSxcblxuXHQvKipcblx0ICogQ3JlYXRlIGEgY2xvbmUgb2YgdGhlIGNoYXJ0J3MgcmVuZGVyVG8gZGl2IGFuZCBwbGFjZSBpdCBvdXRzaWRlIHRoZSB2aWV3cG9ydCB0byBhbGxvd1xuXHQgKiBzaXplIGNvbXB1dGF0aW9uIG9uIGNoYXJ0LnJlbmRlciBhbmQgY2hhcnQucmVkcmF3XG5cdCAqL1xuXHRjbG9uZVJlbmRlclRvOiBmdW5jdGlvbiAocmV2ZXJ0KSB7XG5cdFx0dmFyIGNsb25lID0gdGhpcy5yZW5kZXJUb0Nsb25lLFxuXHRcdFx0Y29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG5cdFx0XG5cdFx0Ly8gRGVzdHJveSB0aGUgY2xvbmUgYW5kIGJyaW5nIHRoZSBjb250YWluZXIgYmFjayB0byB0aGUgcmVhbCByZW5kZXJUbyBkaXZcblx0XHRpZiAocmV2ZXJ0KSB7XG5cdFx0XHRpZiAoY2xvbmUpIHtcblx0XHRcdFx0dGhpcy5yZW5kZXJUby5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuXHRcdFx0XHRkaXNjYXJkRWxlbWVudChjbG9uZSk7XG5cdFx0XHRcdGRlbGV0ZSB0aGlzLnJlbmRlclRvQ2xvbmU7XG5cdFx0XHR9XG5cdFx0XG5cdFx0Ly8gU2V0IHVwIHRoZSBjbG9uZVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoY29udGFpbmVyICYmIGNvbnRhaW5lci5wYXJlbnROb2RlID09PSB0aGlzLnJlbmRlclRvKSB7XG5cdFx0XHRcdHRoaXMucmVuZGVyVG8ucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTsgLy8gZG8gbm90IGNsb25lIHRoaXNcblx0XHRcdH1cblx0XHRcdHRoaXMucmVuZGVyVG9DbG9uZSA9IGNsb25lID0gdGhpcy5yZW5kZXJUby5jbG9uZU5vZGUoMCk7XG5cdFx0XHRjc3MoY2xvbmUsIHtcblx0XHRcdFx0cG9zaXRpb246IEFCU09MVVRFLFxuXHRcdFx0XHR0b3A6ICctOTk5OXB4Jyxcblx0XHRcdFx0ZGlzcGxheTogJ2Jsb2NrJyAvLyAjODMzXG5cdFx0XHR9KTtcblx0XHRcdGlmIChjbG9uZS5zdHlsZS5zZXRQcm9wZXJ0eSkgeyAvLyAjMjYzMVxuXHRcdFx0XHRjbG9uZS5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlzcGxheScsICdibG9jaycsICdpbXBvcnRhbnQnKTtcblx0XHRcdH1cblx0XHRcdGRvYy5ib2R5LmFwcGVuZENoaWxkKGNsb25lKTtcblx0XHRcdGlmIChjb250YWluZXIpIHtcblx0XHRcdFx0Y2xvbmUuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgY29udGFpbmluZyBlbGVtZW50LCBkZXRlcm1pbmUgdGhlIHNpemUgYW5kIGNyZWF0ZSB0aGUgaW5uZXIgY29udGFpbmVyXG5cdCAqIGRpdiB0byBob2xkIHRoZSBjaGFydFxuXHQgKi9cblx0Z2V0Q29udGFpbmVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGNvbnRhaW5lcixcblx0XHRcdG9wdGlvbnNDaGFydCA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQsXG5cdFx0XHRjaGFydFdpZHRoLFxuXHRcdFx0Y2hhcnRIZWlnaHQsXG5cdFx0XHRyZW5kZXJUbyxcblx0XHRcdGluZGV4QXR0ck5hbWUgPSAnZGF0YS1oaWdoY2hhcnRzLWNoYXJ0Jyxcblx0XHRcdG9sZENoYXJ0SW5kZXgsXG5cdFx0XHRjb250YWluZXJJZDtcblxuXHRcdGNoYXJ0LnJlbmRlclRvID0gcmVuZGVyVG8gPSBvcHRpb25zQ2hhcnQucmVuZGVyVG87XG5cdFx0Y29udGFpbmVySWQgPSBQUkVGSVggKyBpZENvdW50ZXIrKztcblxuXHRcdGlmIChpc1N0cmluZyhyZW5kZXJUbykpIHtcblx0XHRcdGNoYXJ0LnJlbmRlclRvID0gcmVuZGVyVG8gPSBkb2MuZ2V0RWxlbWVudEJ5SWQocmVuZGVyVG8pO1xuXHRcdH1cblx0XHRcblx0XHQvLyBEaXNwbGF5IGFuIGVycm9yIGlmIHRoZSByZW5kZXJUbyBpcyB3cm9uZ1xuXHRcdGlmICghcmVuZGVyVG8pIHtcblx0XHRcdGVycm9yKDEzLCB0cnVlKTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gSWYgdGhlIGNvbnRhaW5lciBhbHJlYWR5IGhvbGRzIGEgY2hhcnQsIGRlc3Ryb3kgaXQuIFRoZSBjaGVjayBmb3IgaGFzUmVuZGVyZWQgaXMgdGhlcmVcblx0XHQvLyBiZWNhdXNlIHdlYiBwYWdlcyB0aGF0IGFyZSBzYXZlZCB0byBkaXNrIGZyb20gdGhlIGJyb3dzZXIsIHdpbGwgcHJlc2VydmUgdGhlIGRhdGEtaGlnaGNoYXJ0cy1jaGFydFxuXHRcdC8vIGF0dHJpYnV0ZSBhbmQgdGhlIFNWRyBjb250ZW50cywgYnV0IG5vdCBhbiBpbnRlcmFjdGl2ZSBjaGFydC4gU28gaW4gdGhpcyBjYXNlLFxuXHRcdC8vIGNoYXJ0c1tvbGRDaGFydEluZGV4XSB3aWxsIHBvaW50IHRvIHRoZSB3cm9uZyBjaGFydCBpZiBhbnkgKCMyNjA5KS5cblx0XHRvbGRDaGFydEluZGV4ID0gcEludChhdHRyKHJlbmRlclRvLCBpbmRleEF0dHJOYW1lKSk7XG5cdFx0aWYgKCFpc05hTihvbGRDaGFydEluZGV4KSAmJiBjaGFydHNbb2xkQ2hhcnRJbmRleF0gJiYgY2hhcnRzW29sZENoYXJ0SW5kZXhdLmhhc1JlbmRlcmVkKSB7XG5cdFx0XHRjaGFydHNbb2xkQ2hhcnRJbmRleF0uZGVzdHJveSgpO1xuXHRcdH1cdFx0XG5cdFx0XG5cdFx0Ly8gTWFrZSBhIHJlZmVyZW5jZSB0byB0aGUgY2hhcnQgZnJvbSB0aGUgZGl2XG5cdFx0YXR0cihyZW5kZXJUbywgaW5kZXhBdHRyTmFtZSwgY2hhcnQuaW5kZXgpO1xuXG5cdFx0Ly8gcmVtb3ZlIHByZXZpb3VzIGNoYXJ0XG5cdFx0cmVuZGVyVG8uaW5uZXJIVE1MID0gJyc7XG5cblx0XHQvLyBJZiB0aGUgY29udGFpbmVyIGRvZXNuJ3QgaGF2ZSBhbiBvZmZzZXRXaWR0aCwgaXQgaGFzIG9yIGlzIGEgY2hpbGQgb2YgYSBub2RlXG5cdFx0Ly8gdGhhdCBoYXMgZGlzcGxheTpub25lLiBXZSBuZWVkIHRvIHRlbXBvcmFyaWx5IG1vdmUgaXQgb3V0IHRvIGEgdmlzaWJsZVxuXHRcdC8vIHN0YXRlIHRvIGRldGVybWluZSB0aGUgc2l6ZSwgZWxzZSB0aGUgbGVnZW5kIGFuZCB0b29sdGlwcyB3b24ndCByZW5kZXJcblx0XHQvLyBwcm9wZXJseS4gVGhlIGFsbG93Q2xvbmUgb3B0aW9uIGlzIHVzZWQgaW4gc3BhcmtsaW5lcyBhcyBhIG1pY3JvIG9wdGltaXphdGlvbixcblx0XHQvLyBzYXZpbmcgYWJvdXQgMS0yIG1zIGVhY2ggY2hhcnQuXG5cdFx0aWYgKCFvcHRpb25zQ2hhcnQuc2tpcENsb25lICYmICFyZW5kZXJUby5vZmZzZXRXaWR0aCkge1xuXHRcdFx0Y2hhcnQuY2xvbmVSZW5kZXJUbygpO1xuXHRcdH1cblxuXHRcdC8vIGdldCB0aGUgd2lkdGggYW5kIGhlaWdodFxuXHRcdGNoYXJ0LmdldENoYXJ0U2l6ZSgpO1xuXHRcdGNoYXJ0V2lkdGggPSBjaGFydC5jaGFydFdpZHRoO1xuXHRcdGNoYXJ0SGVpZ2h0ID0gY2hhcnQuY2hhcnRIZWlnaHQ7XG5cblx0XHQvLyBjcmVhdGUgdGhlIGlubmVyIGNvbnRhaW5lclxuXHRcdGNoYXJ0LmNvbnRhaW5lciA9IGNvbnRhaW5lciA9IGNyZWF0ZUVsZW1lbnQoRElWLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogUFJFRklYICsgJ2NvbnRhaW5lcicgK1xuXHRcdFx0XHRcdChvcHRpb25zQ2hhcnQuY2xhc3NOYW1lID8gJyAnICsgb3B0aW9uc0NoYXJ0LmNsYXNzTmFtZSA6ICcnKSxcblx0XHRcdFx0aWQ6IGNvbnRhaW5lcklkXG5cdFx0XHR9LCBleHRlbmQoe1xuXHRcdFx0XHRwb3NpdGlvbjogUkVMQVRJVkUsXG5cdFx0XHRcdG92ZXJmbG93OiBISURERU4sIC8vIG5lZWRlZCBmb3IgY29udGV4dCBtZW51IChhdm9pZCBzY3JvbGxiYXJzKSBhbmRcblx0XHRcdFx0XHQvLyBjb250ZW50IG92ZXJmbG93IGluIElFXG5cdFx0XHRcdHdpZHRoOiBjaGFydFdpZHRoICsgUFgsXG5cdFx0XHRcdGhlaWdodDogY2hhcnRIZWlnaHQgKyBQWCxcblx0XHRcdFx0dGV4dEFsaWduOiAnbGVmdCcsXG5cdFx0XHRcdGxpbmVIZWlnaHQ6ICdub3JtYWwnLCAvLyAjNDI3XG5cdFx0XHRcdHpJbmRleDogMCwgLy8gIzEwNzJcblx0XHRcdFx0Jy13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcic6ICdyZ2JhKDAsMCwwLDApJ1xuXHRcdFx0fSwgb3B0aW9uc0NoYXJ0LnN0eWxlKSxcblx0XHRcdGNoYXJ0LnJlbmRlclRvQ2xvbmUgfHwgcmVuZGVyVG9cblx0XHQpO1xuXG5cdFx0Ly8gY2FjaGUgdGhlIGN1cnNvciAoIzE2NTApXG5cdFx0Y2hhcnQuX2N1cnNvciA9IGNvbnRhaW5lci5zdHlsZS5jdXJzb3I7XG5cblx0XHQvLyBJbml0aWFsaXplIHRoZSByZW5kZXJlclxuXHRcdGNoYXJ0LnJlbmRlcmVyID1cblx0XHRcdG9wdGlvbnNDaGFydC5mb3JFeHBvcnQgPyAvLyBmb3JjZSBTVkcsIHVzZWQgZm9yIFNWRyBleHBvcnRcblx0XHRcdFx0bmV3IFNWR1JlbmRlcmVyKGNvbnRhaW5lciwgY2hhcnRXaWR0aCwgY2hhcnRIZWlnaHQsIG9wdGlvbnNDaGFydC5zdHlsZSwgdHJ1ZSkgOlxuXHRcdFx0XHRuZXcgUmVuZGVyZXIoY29udGFpbmVyLCBjaGFydFdpZHRoLCBjaGFydEhlaWdodCwgb3B0aW9uc0NoYXJ0LnN0eWxlKTtcblxuXHRcdGlmICh1c2VDYW5WRykge1xuXHRcdFx0Ly8gSWYgd2UgbmVlZCBjYW52ZyBsaWJyYXJ5LCBleHRlbmQgYW5kIGNvbmZpZ3VyZSB0aGUgcmVuZGVyZXJcblx0XHRcdC8vIHRvIGdldCB0aGUgdHJhY2tlciBmb3IgdHJhbnNsYXRpbmcgbW91c2UgZXZlbnRzXG5cdFx0XHRjaGFydC5yZW5kZXJlci5jcmVhdGUoY2hhcnQsIGNvbnRhaW5lciwgY2hhcnRXaWR0aCwgY2hhcnRIZWlnaHQpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogQ2FsY3VsYXRlIG1hcmdpbnMgYnkgcmVuZGVyaW5nIGF4aXMgbGFiZWxzIGluIGEgcHJlbGltaW5hcnkgcG9zaXRpb24uIFRpdGxlLFxuXHQgKiBzdWJ0aXRsZSBhbmQgbGVnZW5kIGhhdmUgYWxyZWFkeSBiZWVuIHJlbmRlcmVkIGF0IHRoaXMgc3RhZ2UsIGJ1dCB3aWxsIGJlXG5cdCAqIG1vdmVkIGludG8gdGhlaXIgZmluYWwgcG9zaXRpb25zXG5cdCAqL1xuXHRnZXRNYXJnaW5zOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdHNwYWNpbmcgPSBjaGFydC5zcGFjaW5nLFxuXHRcdFx0YXhpc09mZnNldCxcblx0XHRcdGxlZ2VuZCA9IGNoYXJ0LmxlZ2VuZCxcblx0XHRcdG1hcmdpbiA9IGNoYXJ0Lm1hcmdpbixcblx0XHRcdGxlZ2VuZE9wdGlvbnMgPSBjaGFydC5vcHRpb25zLmxlZ2VuZCxcblx0XHRcdGxlZ2VuZE1hcmdpbiA9IHBpY2sobGVnZW5kT3B0aW9ucy5tYXJnaW4sIDIwKSxcblx0XHRcdGxlZ2VuZFggPSBsZWdlbmRPcHRpb25zLngsXG5cdFx0XHRsZWdlbmRZID0gbGVnZW5kT3B0aW9ucy55LFxuXHRcdFx0YWxpZ24gPSBsZWdlbmRPcHRpb25zLmFsaWduLFxuXHRcdFx0dmVydGljYWxBbGlnbiA9IGxlZ2VuZE9wdGlvbnMudmVydGljYWxBbGlnbixcblx0XHRcdHRpdGxlT2Zmc2V0ID0gY2hhcnQudGl0bGVPZmZzZXQ7XG5cblx0XHRjaGFydC5yZXNldE1hcmdpbnMoKTtcblx0XHRheGlzT2Zmc2V0ID0gY2hhcnQuYXhpc09mZnNldDtcblxuXHRcdC8vIEFkanVzdCBmb3IgdGl0bGUgYW5kIHN1YnRpdGxlXG5cdFx0aWYgKHRpdGxlT2Zmc2V0ICYmICFkZWZpbmVkKG1hcmdpblswXSkpIHtcblx0XHRcdGNoYXJ0LnBsb3RUb3AgPSBtYXRoTWF4KGNoYXJ0LnBsb3RUb3AsIHRpdGxlT2Zmc2V0ICsgY2hhcnQub3B0aW9ucy50aXRsZS5tYXJnaW4gKyBzcGFjaW5nWzBdKTtcblx0XHR9XG5cdFx0XG5cdFx0Ly8gQWRqdXN0IGZvciBsZWdlbmRcblx0XHRpZiAobGVnZW5kLmRpc3BsYXkgJiYgIWxlZ2VuZE9wdGlvbnMuZmxvYXRpbmcpIHtcblx0XHRcdGlmIChhbGlnbiA9PT0gJ3JpZ2h0JykgeyAvLyBob3Jpem9udGFsIGFsaWdubWVudCBoYW5kbGVkIGZpcnN0XG5cdFx0XHRcdGlmICghZGVmaW5lZChtYXJnaW5bMV0pKSB7XG5cdFx0XHRcdFx0Y2hhcnQubWFyZ2luUmlnaHQgPSBtYXRoTWF4KFxuXHRcdFx0XHRcdFx0Y2hhcnQubWFyZ2luUmlnaHQsXG5cdFx0XHRcdFx0XHRsZWdlbmQubGVnZW5kV2lkdGggLSBsZWdlbmRYICsgbGVnZW5kTWFyZ2luICsgc3BhY2luZ1sxXVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAoYWxpZ24gPT09ICdsZWZ0Jykge1xuXHRcdFx0XHRpZiAoIWRlZmluZWQobWFyZ2luWzNdKSkge1xuXHRcdFx0XHRcdGNoYXJ0LnBsb3RMZWZ0ID0gbWF0aE1heChcblx0XHRcdFx0XHRcdGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0XHRcdFx0bGVnZW5kLmxlZ2VuZFdpZHRoICsgbGVnZW5kWCArIGxlZ2VuZE1hcmdpbiArIHNwYWNpbmdbM11cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAodmVydGljYWxBbGlnbiA9PT0gJ3RvcCcpIHtcblx0XHRcdFx0aWYgKCFkZWZpbmVkKG1hcmdpblswXSkpIHtcblx0XHRcdFx0XHRjaGFydC5wbG90VG9wID0gbWF0aE1heChcblx0XHRcdFx0XHRcdGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRcdFx0XHRsZWdlbmQubGVnZW5kSGVpZ2h0ICsgbGVnZW5kWSArIGxlZ2VuZE1hcmdpbiArIHNwYWNpbmdbMF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gZWxzZSBpZiAodmVydGljYWxBbGlnbiA9PT0gJ2JvdHRvbScpIHtcblx0XHRcdFx0aWYgKCFkZWZpbmVkKG1hcmdpblsyXSkpIHtcblx0XHRcdFx0XHRjaGFydC5tYXJnaW5Cb3R0b20gPSBtYXRoTWF4KFxuXHRcdFx0XHRcdFx0Y2hhcnQubWFyZ2luQm90dG9tLFxuXHRcdFx0XHRcdFx0bGVnZW5kLmxlZ2VuZEhlaWdodCAtIGxlZ2VuZFkgKyBsZWdlbmRNYXJnaW4gKyBzcGFjaW5nWzJdXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGFkanVzdCBmb3Igc2Nyb2xsZXJcblx0XHRpZiAoY2hhcnQuZXh0cmFCb3R0b21NYXJnaW4pIHtcblx0XHRcdGNoYXJ0Lm1hcmdpbkJvdHRvbSArPSBjaGFydC5leHRyYUJvdHRvbU1hcmdpbjtcblx0XHR9XG5cdFx0aWYgKGNoYXJ0LmV4dHJhVG9wTWFyZ2luKSB7XG5cdFx0XHRjaGFydC5wbG90VG9wICs9IGNoYXJ0LmV4dHJhVG9wTWFyZ2luO1xuXHRcdH1cblxuXHRcdC8vIHByZS1yZW5kZXIgYXhlcyB0byBnZXQgbGFiZWxzIG9mZnNldCB3aWR0aFxuXHRcdGlmIChjaGFydC5oYXNDYXJ0ZXNpYW5TZXJpZXMpIHtcblx0XHRcdGVhY2goY2hhcnQuYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdFx0YXhpcy5nZXRPZmZzZXQoKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRcblx0XHRpZiAoIWRlZmluZWQobWFyZ2luWzNdKSkge1xuXHRcdFx0Y2hhcnQucGxvdExlZnQgKz0gYXhpc09mZnNldFszXTtcblx0XHR9XG5cdFx0aWYgKCFkZWZpbmVkKG1hcmdpblswXSkpIHtcblx0XHRcdGNoYXJ0LnBsb3RUb3AgKz0gYXhpc09mZnNldFswXTtcblx0XHR9XG5cdFx0aWYgKCFkZWZpbmVkKG1hcmdpblsyXSkpIHtcblx0XHRcdGNoYXJ0Lm1hcmdpbkJvdHRvbSArPSBheGlzT2Zmc2V0WzJdO1xuXHRcdH1cblx0XHRpZiAoIWRlZmluZWQobWFyZ2luWzFdKSkge1xuXHRcdFx0Y2hhcnQubWFyZ2luUmlnaHQgKz0gYXhpc09mZnNldFsxXTtcblx0XHR9XG5cblx0XHRjaGFydC5zZXRDaGFydFNpemUoKTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXNpemUgdGhlIGNoYXJ0IHRvIGl0cyBjb250YWluZXIgaWYgc2l6ZSBpcyBub3QgZXhwbGljaXRseSBzZXRcblx0ICovXG5cdHJlZmxvdzogZnVuY3Rpb24gKGUpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0b3B0aW9uc0NoYXJ0ID0gY2hhcnQub3B0aW9ucy5jaGFydCxcblx0XHRcdHJlbmRlclRvID0gY2hhcnQucmVuZGVyVG8sXG5cdFx0XHR3aWR0aCA9IG9wdGlvbnNDaGFydC53aWR0aCB8fCBhZGFwdGVyUnVuKHJlbmRlclRvLCAnd2lkdGgnKSxcblx0XHRcdGhlaWdodCA9IG9wdGlvbnNDaGFydC5oZWlnaHQgfHwgYWRhcHRlclJ1bihyZW5kZXJUbywgJ2hlaWdodCcpLFxuXHRcdFx0dGFyZ2V0ID0gZSA/IGUudGFyZ2V0IDogd2luLCAvLyAjODA1IC0gTW9vVG9vbHMgZG9lc24ndCBzdXBwbHkgZVxuXHRcdFx0ZG9SZWZsb3cgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChjaGFydC5jb250YWluZXIpIHsgLy8gSXQgbWF5IGhhdmUgYmVlbiBkZXN0cm95ZWQgaW4gdGhlIG1lYW50aW1lICgjMTI1Nylcblx0XHRcdFx0XHRjaGFydC5zZXRTaXplKHdpZHRoLCBoZWlnaHQsIGZhbHNlKTtcblx0XHRcdFx0XHRjaGFydC5oYXNVc2VyU2l6ZSA9IG51bGw7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRcblx0XHQvLyBXaWR0aCBhbmQgaGVpZ2h0IGNoZWNrcyBmb3IgZGlzcGxheTpub25lLiBUYXJnZXQgaXMgZG9jIGluIElFOCBhbmQgT3BlcmEsXG5cdFx0Ly8gd2luIGluIEZpcmVmb3gsIENocm9tZSBhbmQgSUU5LlxuXHRcdGlmICghY2hhcnQuaGFzVXNlclNpemUgJiYgd2lkdGggJiYgaGVpZ2h0ICYmICh0YXJnZXQgPT09IHdpbiB8fCB0YXJnZXQgPT09IGRvYykpIHtcblx0XHRcdGlmICh3aWR0aCAhPT0gY2hhcnQuY29udGFpbmVyV2lkdGggfHwgaGVpZ2h0ICE9PSBjaGFydC5jb250YWluZXJIZWlnaHQpIHtcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KGNoYXJ0LnJlZmxvd1RpbWVvdXQpO1xuXHRcdFx0XHRpZiAoZSkgeyAvLyBDYWxsZWQgZnJvbSB3aW5kb3cucmVzaXplXG5cdFx0XHRcdFx0Y2hhcnQucmVmbG93VGltZW91dCA9IHNldFRpbWVvdXQoZG9SZWZsb3csIDEwMCk7XG5cdFx0XHRcdH0gZWxzZSB7IC8vIENhbGxlZCBkaXJlY3RseSAoIzIyMjQpXG5cdFx0XHRcdFx0ZG9SZWZsb3coKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Y2hhcnQuY29udGFpbmVyV2lkdGggPSB3aWR0aDtcblx0XHRcdGNoYXJ0LmNvbnRhaW5lckhlaWdodCA9IGhlaWdodDtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEFkZCB0aGUgZXZlbnQgaGFuZGxlcnMgbmVjZXNzYXJ5IGZvciBhdXRvIHJlc2l6aW5nXG5cdCAqL1xuXHRpbml0UmVmbG93OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdHJlZmxvdyA9IGZ1bmN0aW9uIChlKSB7XG5cdFx0XHRcdGNoYXJ0LnJlZmxvdyhlKTtcblx0XHRcdH07XG5cdFx0XHRcblx0XHRcblx0XHRhZGRFdmVudCh3aW4sICdyZXNpemUnLCByZWZsb3cpO1xuXHRcdGFkZEV2ZW50KGNoYXJ0LCAnZGVzdHJveScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdHJlbW92ZUV2ZW50KHdpbiwgJ3Jlc2l6ZScsIHJlZmxvdyk7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlc2l6ZSB0aGUgY2hhcnQgdG8gYSBnaXZlbiB3aWR0aCBhbmQgaGVpZ2h0XG5cdCAqIEBwYXJhbSB7TnVtYmVyfSB3aWR0aFxuXHQgKiBAcGFyYW0ge051bWJlcn0gaGVpZ2h0XG5cdCAqIEBwYXJhbSB7T2JqZWN0fEJvb2xlYW59IGFuaW1hdGlvblxuXHQgKi9cblx0c2V0U2l6ZTogZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQsIGFuaW1hdGlvbikge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRjaGFydFdpZHRoLFxuXHRcdFx0Y2hhcnRIZWlnaHQsXG5cdFx0XHRmaXJlRW5kUmVzaXplO1xuXG5cdFx0Ly8gSGFuZGxlIHRoZSBpc1Jlc2l6aW5nIGNvdW50ZXJcblx0XHRjaGFydC5pc1Jlc2l6aW5nICs9IDE7XG5cdFx0ZmlyZUVuZFJlc2l6ZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmIChjaGFydCkge1xuXHRcdFx0XHRmaXJlRXZlbnQoY2hhcnQsICdlbmRSZXNpemUnLCBudWxsLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0Y2hhcnQuaXNSZXNpemluZyAtPSAxO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0Ly8gc2V0IHRoZSBhbmltYXRpb24gZm9yIHRoZSBjdXJyZW50IHByb2Nlc3Ncblx0XHRzZXRBbmltYXRpb24oYW5pbWF0aW9uLCBjaGFydCk7XG5cblx0XHRjaGFydC5vbGRDaGFydEhlaWdodCA9IGNoYXJ0LmNoYXJ0SGVpZ2h0O1xuXHRcdGNoYXJ0Lm9sZENoYXJ0V2lkdGggPSBjaGFydC5jaGFydFdpZHRoO1xuXHRcdGlmIChkZWZpbmVkKHdpZHRoKSkge1xuXHRcdFx0Y2hhcnQuY2hhcnRXaWR0aCA9IGNoYXJ0V2lkdGggPSBtYXRoTWF4KDAsIG1hdGhSb3VuZCh3aWR0aCkpO1xuXHRcdFx0Y2hhcnQuaGFzVXNlclNpemUgPSAhIWNoYXJ0V2lkdGg7XG5cdFx0fVxuXHRcdGlmIChkZWZpbmVkKGhlaWdodCkpIHtcblx0XHRcdGNoYXJ0LmNoYXJ0SGVpZ2h0ID0gY2hhcnRIZWlnaHQgPSBtYXRoTWF4KDAsIG1hdGhSb3VuZChoZWlnaHQpKTtcblx0XHR9XG5cblx0XHQvLyBSZXNpemUgdGhlIGNvbnRhaW5lciB3aXRoIHRoZSBnbG9iYWwgYW5pbWF0aW9uIGFwcGxpZWQgaWYgZW5hYmxlZCAoIzI1MDMpXG5cdFx0KGdsb2JhbEFuaW1hdGlvbiA/IGFuaW1hdGUgOiBjc3MpKGNoYXJ0LmNvbnRhaW5lciwge1xuXHRcdFx0d2lkdGg6IGNoYXJ0V2lkdGggKyBQWCxcblx0XHRcdGhlaWdodDogY2hhcnRIZWlnaHQgKyBQWFxuXHRcdH0sIGdsb2JhbEFuaW1hdGlvbik7XG5cblx0XHRjaGFydC5zZXRDaGFydFNpemUodHJ1ZSk7XG5cdFx0Y2hhcnQucmVuZGVyZXIuc2V0U2l6ZShjaGFydFdpZHRoLCBjaGFydEhlaWdodCwgYW5pbWF0aW9uKTtcblxuXHRcdC8vIGhhbmRsZSBheGVzXG5cdFx0Y2hhcnQubWF4VGlja3MgPSBudWxsO1xuXHRcdGVhY2goY2hhcnQuYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdGF4aXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRheGlzLnNldFNjYWxlKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBtYWtlIHN1cmUgbm9uLWNhcnRlc2lhbiBzZXJpZXMgYXJlIGFsc28gaGFuZGxlZFxuXHRcdGVhY2goY2hhcnQuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWUpIHtcblx0XHRcdHNlcmllLmlzRGlydHkgPSB0cnVlO1xuXHRcdH0pO1xuXG5cdFx0Y2hhcnQuaXNEaXJ0eUxlZ2VuZCA9IHRydWU7IC8vIGZvcmNlIGxlZ2VuZCByZWRyYXdcblx0XHRjaGFydC5pc0RpcnR5Qm94ID0gdHJ1ZTsgLy8gZm9yY2UgcmVkcmF3IG9mIHBsb3QgYW5kIGNoYXJ0IGJvcmRlclxuXG5cdFx0Y2hhcnQubGF5T3V0VGl0bGVzKCk7IC8vICMyODU3XG5cdFx0Y2hhcnQuZ2V0TWFyZ2lucygpO1xuXG5cdFx0Y2hhcnQucmVkcmF3KGFuaW1hdGlvbik7XG5cblxuXHRcdGNoYXJ0Lm9sZENoYXJ0SGVpZ2h0ID0gbnVsbDtcblx0XHRmaXJlRXZlbnQoY2hhcnQsICdyZXNpemUnKTtcblxuXHRcdC8vIGZpcmUgZW5kUmVzaXplIGFuZCBzZXQgaXNSZXNpemluZyBiYWNrXG5cdFx0Ly8gSWYgYW5pbWF0aW9uIGlzIGRpc2FibGVkLCBmaXJlIHdpdGhvdXQgZGVsYXlcblx0XHRpZiAoZ2xvYmFsQW5pbWF0aW9uID09PSBmYWxzZSkge1xuXHRcdFx0ZmlyZUVuZFJlc2l6ZSgpO1xuXHRcdH0gZWxzZSB7IC8vIGVsc2Ugc2V0IGEgdGltZW91dCB3aXRoIHRoZSBhbmltYXRpb24gZHVyYXRpb25cblx0XHRcdHNldFRpbWVvdXQoZmlyZUVuZFJlc2l6ZSwgKGdsb2JhbEFuaW1hdGlvbiAmJiBnbG9iYWxBbmltYXRpb24uZHVyYXRpb24pIHx8IDUwMCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgdGhlIHB1YmxpYyBjaGFydCBwcm9wZXJ0aWVzLiBUaGlzIGlzIGRvbmUgYmVmb3JlIGFuZCBhZnRlciB0aGUgcHJlLXJlbmRlclxuXHQgKiB0byBkZXRlcm1pbmUgbWFyZ2luIHNpemVzXG5cdCAqL1xuXHRzZXRDaGFydFNpemU6IGZ1bmN0aW9uIChza2lwQXhlcykge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdGNoYXJ0V2lkdGggPSBjaGFydC5jaGFydFdpZHRoLFxuXHRcdFx0Y2hhcnRIZWlnaHQgPSBjaGFydC5jaGFydEhlaWdodCxcblx0XHRcdG9wdGlvbnNDaGFydCA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQsXG5cdFx0XHRzcGFjaW5nID0gY2hhcnQuc3BhY2luZyxcblx0XHRcdGNsaXBPZmZzZXQgPSBjaGFydC5jbGlwT2Zmc2V0LFxuXHRcdFx0Y2xpcFgsXG5cdFx0XHRjbGlwWSxcblx0XHRcdHBsb3RMZWZ0LFxuXHRcdFx0cGxvdFRvcCxcblx0XHRcdHBsb3RXaWR0aCxcblx0XHRcdHBsb3RIZWlnaHQsXG5cdFx0XHRwbG90Qm9yZGVyV2lkdGg7XG5cblx0XHRjaGFydC5wbG90TGVmdCA9IHBsb3RMZWZ0ID0gbWF0aFJvdW5kKGNoYXJ0LnBsb3RMZWZ0KTtcblx0XHRjaGFydC5wbG90VG9wID0gcGxvdFRvcCA9IG1hdGhSb3VuZChjaGFydC5wbG90VG9wKTtcblx0XHRjaGFydC5wbG90V2lkdGggPSBwbG90V2lkdGggPSBtYXRoTWF4KDAsIG1hdGhSb3VuZChjaGFydFdpZHRoIC0gcGxvdExlZnQgLSBjaGFydC5tYXJnaW5SaWdodCkpO1xuXHRcdGNoYXJ0LnBsb3RIZWlnaHQgPSBwbG90SGVpZ2h0ID0gbWF0aE1heCgwLCBtYXRoUm91bmQoY2hhcnRIZWlnaHQgLSBwbG90VG9wIC0gY2hhcnQubWFyZ2luQm90dG9tKSk7XG5cblx0XHRjaGFydC5wbG90U2l6ZVggPSBpbnZlcnRlZCA/IHBsb3RIZWlnaHQgOiBwbG90V2lkdGg7XG5cdFx0Y2hhcnQucGxvdFNpemVZID0gaW52ZXJ0ZWQgPyBwbG90V2lkdGggOiBwbG90SGVpZ2h0O1xuXHRcdFxuXHRcdGNoYXJ0LnBsb3RCb3JkZXJXaWR0aCA9IG9wdGlvbnNDaGFydC5wbG90Qm9yZGVyV2lkdGggfHwgMDtcblxuXHRcdC8vIFNldCBib3hlcyB1c2VkIGZvciBhbGlnbm1lbnRcblx0XHRjaGFydC5zcGFjaW5nQm94ID0gcmVuZGVyZXIuc3BhY2luZ0JveCA9IHtcblx0XHRcdHg6IHNwYWNpbmdbM10sXG5cdFx0XHR5OiBzcGFjaW5nWzBdLFxuXHRcdFx0d2lkdGg6IGNoYXJ0V2lkdGggLSBzcGFjaW5nWzNdIC0gc3BhY2luZ1sxXSxcblx0XHRcdGhlaWdodDogY2hhcnRIZWlnaHQgLSBzcGFjaW5nWzBdIC0gc3BhY2luZ1syXVxuXHRcdH07XG5cdFx0Y2hhcnQucGxvdEJveCA9IHJlbmRlcmVyLnBsb3RCb3ggPSB7XG5cdFx0XHR4OiBwbG90TGVmdCxcblx0XHRcdHk6IHBsb3RUb3AsXG5cdFx0XHR3aWR0aDogcGxvdFdpZHRoLFxuXHRcdFx0aGVpZ2h0OiBwbG90SGVpZ2h0XG5cdFx0fTtcblxuXHRcdHBsb3RCb3JkZXJXaWR0aCA9IDIgKiBtYXRoRmxvb3IoY2hhcnQucGxvdEJvcmRlcldpZHRoIC8gMik7XG5cdFx0Y2xpcFggPSBtYXRoQ2VpbChtYXRoTWF4KHBsb3RCb3JkZXJXaWR0aCwgY2xpcE9mZnNldFszXSkgLyAyKTtcblx0XHRjbGlwWSA9IG1hdGhDZWlsKG1hdGhNYXgocGxvdEJvcmRlcldpZHRoLCBjbGlwT2Zmc2V0WzBdKSAvIDIpO1xuXHRcdGNoYXJ0LmNsaXBCb3ggPSB7XG5cdFx0XHR4OiBjbGlwWCwgXG5cdFx0XHR5OiBjbGlwWSwgXG5cdFx0XHR3aWR0aDogbWF0aEZsb29yKGNoYXJ0LnBsb3RTaXplWCAtIG1hdGhNYXgocGxvdEJvcmRlcldpZHRoLCBjbGlwT2Zmc2V0WzFdKSAvIDIgLSBjbGlwWCksIFxuXHRcdFx0aGVpZ2h0OiBtYXRoTWF4KDAsIG1hdGhGbG9vcihjaGFydC5wbG90U2l6ZVkgLSBtYXRoTWF4KHBsb3RCb3JkZXJXaWR0aCwgY2xpcE9mZnNldFsyXSkgLyAyIC0gY2xpcFkpKVxuXHRcdH07XG5cblx0XHRpZiAoIXNraXBBeGVzKSB7XG5cdFx0XHRlYWNoKGNoYXJ0LmF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRcdGF4aXMuc2V0QXhpc1NpemUoKTtcblx0XHRcdFx0YXhpcy5zZXRBeGlzVHJhbnNsYXRpb24oKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogSW5pdGlhbCBtYXJnaW5zIGJlZm9yZSBhdXRvIHNpemUgbWFyZ2lucyBhcmUgYXBwbGllZFxuXHQgKi9cblx0cmVzZXRNYXJnaW5zOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdHNwYWNpbmcgPSBjaGFydC5zcGFjaW5nLFxuXHRcdFx0bWFyZ2luID0gY2hhcnQubWFyZ2luO1xuXG5cdFx0Y2hhcnQucGxvdFRvcCA9IHBpY2sobWFyZ2luWzBdLCBzcGFjaW5nWzBdKTtcblx0XHRjaGFydC5tYXJnaW5SaWdodCA9IHBpY2sobWFyZ2luWzFdLCBzcGFjaW5nWzFdKTtcblx0XHRjaGFydC5tYXJnaW5Cb3R0b20gPSBwaWNrKG1hcmdpblsyXSwgc3BhY2luZ1syXSk7XG5cdFx0Y2hhcnQucGxvdExlZnQgPSBwaWNrKG1hcmdpblszXSwgc3BhY2luZ1szXSk7XG5cdFx0Y2hhcnQuYXhpc09mZnNldCA9IFswLCAwLCAwLCAwXTsgLy8gdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0XG5cdFx0Y2hhcnQuY2xpcE9mZnNldCA9IFswLCAwLCAwLCAwXTtcblx0fSxcblxuXHQvKipcblx0ICogRHJhdyB0aGUgYm9yZGVycyBhbmQgYmFja2dyb3VuZHMgZm9yIGNoYXJ0IGFuZCBwbG90IGFyZWFcblx0ICovXG5cdGRyYXdDaGFydEJveDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRvcHRpb25zQ2hhcnQgPSBjaGFydC5vcHRpb25zLmNoYXJ0LFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdGNoYXJ0V2lkdGggPSBjaGFydC5jaGFydFdpZHRoLFxuXHRcdFx0Y2hhcnRIZWlnaHQgPSBjaGFydC5jaGFydEhlaWdodCxcblx0XHRcdGNoYXJ0QmFja2dyb3VuZCA9IGNoYXJ0LmNoYXJ0QmFja2dyb3VuZCxcblx0XHRcdHBsb3RCYWNrZ3JvdW5kID0gY2hhcnQucGxvdEJhY2tncm91bmQsXG5cdFx0XHRwbG90Qm9yZGVyID0gY2hhcnQucGxvdEJvcmRlcixcblx0XHRcdHBsb3RCR0ltYWdlID0gY2hhcnQucGxvdEJHSW1hZ2UsXG5cdFx0XHRjaGFydEJvcmRlcldpZHRoID0gb3B0aW9uc0NoYXJ0LmJvcmRlcldpZHRoIHx8IDAsXG5cdFx0XHRjaGFydEJhY2tncm91bmRDb2xvciA9IG9wdGlvbnNDaGFydC5iYWNrZ3JvdW5kQ29sb3IsXG5cdFx0XHRwbG90QmFja2dyb3VuZENvbG9yID0gb3B0aW9uc0NoYXJ0LnBsb3RCYWNrZ3JvdW5kQ29sb3IsXG5cdFx0XHRwbG90QmFja2dyb3VuZEltYWdlID0gb3B0aW9uc0NoYXJ0LnBsb3RCYWNrZ3JvdW5kSW1hZ2UsXG5cdFx0XHRwbG90Qm9yZGVyV2lkdGggPSBvcHRpb25zQ2hhcnQucGxvdEJvcmRlcldpZHRoIHx8IDAsXG5cdFx0XHRtZ24sXG5cdFx0XHRiZ0F0dHIsXG5cdFx0XHRwbG90TGVmdCA9IGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0cGxvdFRvcCA9IGNoYXJ0LnBsb3RUb3AsXG5cdFx0XHRwbG90V2lkdGggPSBjaGFydC5wbG90V2lkdGgsXG5cdFx0XHRwbG90SGVpZ2h0ID0gY2hhcnQucGxvdEhlaWdodCxcblx0XHRcdHBsb3RCb3ggPSBjaGFydC5wbG90Qm94LFxuXHRcdFx0Y2xpcFJlY3QgPSBjaGFydC5jbGlwUmVjdCxcblx0XHRcdGNsaXBCb3ggPSBjaGFydC5jbGlwQm94O1xuXG5cdFx0Ly8gQ2hhcnQgYXJlYVxuXHRcdG1nbiA9IGNoYXJ0Qm9yZGVyV2lkdGggKyAob3B0aW9uc0NoYXJ0LnNoYWRvdyA/IDggOiAwKTtcblxuXHRcdGlmIChjaGFydEJvcmRlcldpZHRoIHx8IGNoYXJ0QmFja2dyb3VuZENvbG9yKSB7XG5cdFx0XHRpZiAoIWNoYXJ0QmFja2dyb3VuZCkge1xuXHRcdFx0XHRcblx0XHRcdFx0YmdBdHRyID0ge1xuXHRcdFx0XHRcdGZpbGw6IGNoYXJ0QmFja2dyb3VuZENvbG9yIHx8IE5PTkVcblx0XHRcdFx0fTtcblx0XHRcdFx0aWYgKGNoYXJ0Qm9yZGVyV2lkdGgpIHsgLy8gIzk4MFxuXHRcdFx0XHRcdGJnQXR0ci5zdHJva2UgPSBvcHRpb25zQ2hhcnQuYm9yZGVyQ29sb3I7XG5cdFx0XHRcdFx0YmdBdHRyWydzdHJva2Utd2lkdGgnXSA9IGNoYXJ0Qm9yZGVyV2lkdGg7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2hhcnQuY2hhcnRCYWNrZ3JvdW5kID0gcmVuZGVyZXIucmVjdChtZ24gLyAyLCBtZ24gLyAyLCBjaGFydFdpZHRoIC0gbWduLCBjaGFydEhlaWdodCAtIG1nbixcblx0XHRcdFx0XHRcdG9wdGlvbnNDaGFydC5ib3JkZXJSYWRpdXMsIGNoYXJ0Qm9yZGVyV2lkdGgpXG5cdFx0XHRcdFx0LmF0dHIoYmdBdHRyKVxuXHRcdFx0XHRcdC5hZGRDbGFzcyhQUkVGSVggKyAnYmFja2dyb3VuZCcpXG5cdFx0XHRcdFx0LmFkZCgpXG5cdFx0XHRcdFx0LnNoYWRvdyhvcHRpb25zQ2hhcnQuc2hhZG93KTtcblxuXHRcdFx0fSBlbHNlIHsgLy8gcmVzaXplXG5cdFx0XHRcdGNoYXJ0QmFja2dyb3VuZC5hbmltYXRlKFxuXHRcdFx0XHRcdGNoYXJ0QmFja2dyb3VuZC5jcmlzcCh7IHdpZHRoOiBjaGFydFdpZHRoIC0gbWduLCBoZWlnaHQ6IGNoYXJ0SGVpZ2h0IC0gbWduIH0pXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cblx0XHQvLyBQbG90IGJhY2tncm91bmRcblx0XHRpZiAocGxvdEJhY2tncm91bmRDb2xvcikge1xuXHRcdFx0aWYgKCFwbG90QmFja2dyb3VuZCkge1xuXHRcdFx0XHRjaGFydC5wbG90QmFja2dyb3VuZCA9IHJlbmRlcmVyLnJlY3QocGxvdExlZnQsIHBsb3RUb3AsIHBsb3RXaWR0aCwgcGxvdEhlaWdodCwgMClcblx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRmaWxsOiBwbG90QmFja2dyb3VuZENvbG9yXG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuYWRkKClcblx0XHRcdFx0XHQuc2hhZG93KG9wdGlvbnNDaGFydC5wbG90U2hhZG93KTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHBsb3RCYWNrZ3JvdW5kLmFuaW1hdGUocGxvdEJveCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmIChwbG90QmFja2dyb3VuZEltYWdlKSB7XG5cdFx0XHRpZiAoIXBsb3RCR0ltYWdlKSB7XG5cdFx0XHRcdGNoYXJ0LnBsb3RCR0ltYWdlID0gcmVuZGVyZXIuaW1hZ2UocGxvdEJhY2tncm91bmRJbWFnZSwgcGxvdExlZnQsIHBsb3RUb3AsIHBsb3RXaWR0aCwgcGxvdEhlaWdodClcblx0XHRcdFx0XHQuYWRkKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwbG90QkdJbWFnZS5hbmltYXRlKHBsb3RCb3gpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0XHQvLyBQbG90IGNsaXBcblx0XHRpZiAoIWNsaXBSZWN0KSB7XG5cdFx0XHRjaGFydC5jbGlwUmVjdCA9IHJlbmRlcmVyLmNsaXBSZWN0KGNsaXBCb3gpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjbGlwUmVjdC5hbmltYXRlKHtcblx0XHRcdFx0d2lkdGg6IGNsaXBCb3gud2lkdGgsXG5cdFx0XHRcdGhlaWdodDogY2xpcEJveC5oZWlnaHRcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdC8vIFBsb3QgYXJlYSBib3JkZXJcblx0XHRpZiAocGxvdEJvcmRlcldpZHRoKSB7XG5cdFx0XHRpZiAoIXBsb3RCb3JkZXIpIHtcblx0XHRcdFx0Y2hhcnQucGxvdEJvcmRlciA9IHJlbmRlcmVyLnJlY3QocGxvdExlZnQsIHBsb3RUb3AsIHBsb3RXaWR0aCwgcGxvdEhlaWdodCwgMCwgLXBsb3RCb3JkZXJXaWR0aClcblx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRzdHJva2U6IG9wdGlvbnNDaGFydC5wbG90Qm9yZGVyQ29sb3IsXG5cdFx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogcGxvdEJvcmRlcldpZHRoLFxuXHRcdFx0XHRcdFx0ZmlsbDogTk9ORSxcblx0XHRcdFx0XHRcdHpJbmRleDogMVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cGxvdEJvcmRlci5hbmltYXRlKFxuXHRcdFx0XHRcdHBsb3RCb3JkZXIuY3Jpc3AoeyB4OiBwbG90TGVmdCwgeTogcGxvdFRvcCwgd2lkdGg6IHBsb3RXaWR0aCwgaGVpZ2h0OiBwbG90SGVpZ2h0LCBzdHJva2VXaWR0aDogLXBsb3RCb3JkZXJXaWR0aCB9KSAvLyMzMjgyIHBsb3RCb3JkZXIgc2hvdWxkIGJlIG5lZ2F0aXZlXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gcmVzZXRcblx0XHRjaGFydC5pc0RpcnR5Qm94ID0gZmFsc2U7XG5cdH0sXG5cblx0LyoqXG5cdCAqIERldGVjdCB3aGV0aGVyIGEgY2VydGFpbiBjaGFydCBwcm9wZXJ0eSBpcyBuZWVkZWQgYmFzZWQgb24gaW5zcGVjdGluZyBpdHMgb3B0aW9uc1xuXHQgKiBhbmQgc2VyaWVzLiBUaGlzIG1haW5seSBhcHBsaWVzIHRvIHRoZSBjaGFydC5pbnZlcnQgcHJvcGVydHksIGFuZCBpbiBleHRlbnNpb25zIHRvIFxuXHQgKiB0aGUgY2hhcnQuYW5ndWxhciBhbmQgY2hhcnQucG9sYXIgcHJvcGVydGllcy5cblx0ICovXG5cdHByb3BGcm9tU2VyaWVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnNDaGFydCA9IGNoYXJ0Lm9wdGlvbnMuY2hhcnQsXG5cdFx0XHRrbGFzcyxcblx0XHRcdHNlcmllc09wdGlvbnMgPSBjaGFydC5vcHRpb25zLnNlcmllcyxcblx0XHRcdGksXG5cdFx0XHR2YWx1ZTtcblx0XHRcdFxuXHRcdFx0XG5cdFx0ZWFjaChbJ2ludmVydGVkJywgJ2FuZ3VsYXInLCAncG9sYXInXSwgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XG5cdFx0XHQvLyBUaGUgZGVmYXVsdCBzZXJpZXMgdHlwZSdzIGNsYXNzXG5cdFx0XHRrbGFzcyA9IHNlcmllc1R5cGVzW29wdGlvbnNDaGFydC50eXBlIHx8IG9wdGlvbnNDaGFydC5kZWZhdWx0U2VyaWVzVHlwZV07XG5cdFx0XHRcblx0XHRcdC8vIEdldCB0aGUgdmFsdWUgZnJvbSBhdmFpbGFibGUgY2hhcnQtd2lkZSBwcm9wZXJ0aWVzXG5cdFx0XHR2YWx1ZSA9IChcblx0XHRcdFx0Y2hhcnRba2V5XSB8fCAvLyAxLiBpdCBpcyBzZXQgYmVmb3JlXG5cdFx0XHRcdG9wdGlvbnNDaGFydFtrZXldIHx8IC8vIDIuIGl0IGlzIHNldCBpbiB0aGUgb3B0aW9uc1xuXHRcdFx0XHQoa2xhc3MgJiYga2xhc3MucHJvdG90eXBlW2tleV0pIC8vIDMuIGl0J3MgZGVmYXVsdCBzZXJpZXMgY2xhc3MgcmVxdWlyZXMgaXRcblx0XHRcdCk7XG5cdFxuXHRcdFx0Ly8gNC4gQ2hlY2sgaWYgYW55IHRoZSBjaGFydCdzIHNlcmllcyByZXF1aXJlIGl0XG5cdFx0XHRpID0gc2VyaWVzT3B0aW9ucyAmJiBzZXJpZXNPcHRpb25zLmxlbmd0aDtcblx0XHRcdHdoaWxlICghdmFsdWUgJiYgaS0tKSB7XG5cdFx0XHRcdGtsYXNzID0gc2VyaWVzVHlwZXNbc2VyaWVzT3B0aW9uc1tpXS50eXBlXTtcblx0XHRcdFx0aWYgKGtsYXNzICYmIGtsYXNzLnByb3RvdHlwZVtrZXldKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFxuXHRcdFx0Ly8gU2V0IHRoZSBjaGFydCBwcm9wZXJ0eVxuXHRcdFx0Y2hhcnRba2V5XSA9IHZhbHVlO1x0XG5cdFx0fSk7XG5cdFx0XG5cdH0sXG5cblx0LyoqXG5cdCAqIExpbmsgdHdvIG9yIG1vcmUgc2VyaWVzIHRvZ2V0aGVyLiBUaGlzIGlzIGRvbmUgaW5pdGlhbGx5IGZyb20gQ2hhcnQucmVuZGVyLFxuXHQgKiBhbmQgYWZ0ZXIgQ2hhcnQuYWRkU2VyaWVzIGFuZCBTZXJpZXMucmVtb3ZlLlxuXHQgKi9cblx0bGlua1NlcmllczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRjaGFydFNlcmllcyA9IGNoYXJ0LnNlcmllcztcblxuXHRcdC8vIFJlc2V0IGxpbmtzXG5cdFx0ZWFjaChjaGFydFNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0c2VyaWVzLmxpbmtlZFNlcmllcy5sZW5ndGggPSAwO1xuXHRcdH0pO1xuXG5cdFx0Ly8gQXBwbHkgbmV3IGxpbmtzXG5cdFx0ZWFjaChjaGFydFNlcmllcywgZnVuY3Rpb24gKHNlcmllcykge1xuXHRcdFx0dmFyIGxpbmtlZFRvID0gc2VyaWVzLm9wdGlvbnMubGlua2VkVG87XG5cdFx0XHRpZiAoaXNTdHJpbmcobGlua2VkVG8pKSB7XG5cdFx0XHRcdGlmIChsaW5rZWRUbyA9PT0gJzpwcmV2aW91cycpIHtcblx0XHRcdFx0XHRsaW5rZWRUbyA9IGNoYXJ0LnNlcmllc1tzZXJpZXMuaW5kZXggLSAxXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaW5rZWRUbyA9IGNoYXJ0LmdldChsaW5rZWRUbyk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGxpbmtlZFRvKSB7XG5cdFx0XHRcdFx0bGlua2VkVG8ubGlua2VkU2VyaWVzLnB1c2goc2VyaWVzKTtcblx0XHRcdFx0XHRzZXJpZXMubGlua2VkUGFyZW50ID0gbGlua2VkVG87XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogUmVuZGVyIHNlcmllcyBmb3IgdGhlIGNoYXJ0XG5cdCAqL1xuXHRyZW5kZXJTZXJpZXM6IGZ1bmN0aW9uICgpIHtcblx0XHRlYWNoKHRoaXMuc2VyaWVzLCBmdW5jdGlvbiAoc2VyaWUpIHtcblx0XHRcdHNlcmllLnRyYW5zbGF0ZSgpO1xuXHRcdFx0aWYgKHNlcmllLnNldFRvb2x0aXBQb2ludHMpIHtcblx0XHRcdFx0c2VyaWUuc2V0VG9vbHRpcFBvaW50cygpO1xuXHRcdFx0fVxuXHRcdFx0c2VyaWUucmVuZGVyKCk7XG5cdFx0fSk7XG5cdH0sXG5cdFx0XG5cdC8qKlxuXHQgKiBSZW5kZXIgbGFiZWxzIGZvciB0aGUgY2hhcnRcblx0ICovXG5cdHJlbmRlckxhYmVsczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRsYWJlbHMgPSBjaGFydC5vcHRpb25zLmxhYmVscztcblx0XHRpZiAobGFiZWxzLml0ZW1zKSB7XG5cdFx0XHRlYWNoKGxhYmVscy5pdGVtcywgZnVuY3Rpb24gKGxhYmVsKSB7XG5cdFx0XHRcdHZhciBzdHlsZSA9IGV4dGVuZChsYWJlbHMuc3R5bGUsIGxhYmVsLnN0eWxlKSxcblx0XHRcdFx0XHR4ID0gcEludChzdHlsZS5sZWZ0KSArIGNoYXJ0LnBsb3RMZWZ0LFxuXHRcdFx0XHRcdHkgPSBwSW50KHN0eWxlLnRvcCkgKyBjaGFydC5wbG90VG9wICsgMTI7XG5cblx0XHRcdFx0Ly8gZGVsZXRlIHRvIHByZXZlbnQgcmV3cml0aW5nIGluIElFXG5cdFx0XHRcdGRlbGV0ZSBzdHlsZS5sZWZ0O1xuXHRcdFx0XHRkZWxldGUgc3R5bGUudG9wO1xuXG5cdFx0XHRcdGNoYXJ0LnJlbmRlcmVyLnRleHQoXG5cdFx0XHRcdFx0bGFiZWwuaHRtbCxcblx0XHRcdFx0XHR4LFxuXHRcdFx0XHRcdHlcblx0XHRcdFx0KVxuXHRcdFx0XHQuYXR0cih7IHpJbmRleDogMiB9KVxuXHRcdFx0XHQuY3NzKHN0eWxlKVxuXHRcdFx0XHQuYWRkKCk7XG5cblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmVuZGVyIGFsbCBncmFwaGljcyBmb3IgdGhlIGNoYXJ0XG5cdCAqL1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0YXhlcyA9IGNoYXJ0LmF4ZXMsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0b3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnM7XG5cblx0XHQvLyBUaXRsZVxuXHRcdGNoYXJ0LnNldFRpdGxlKCk7XG5cblxuXHRcdC8vIExlZ2VuZFxuXHRcdGNoYXJ0LmxlZ2VuZCA9IG5ldyBMZWdlbmQoY2hhcnQsIG9wdGlvbnMubGVnZW5kKTtcblxuXHRcdGNoYXJ0LmdldFN0YWNrcygpOyAvLyByZW5kZXIgc3RhY2tzXG5cblx0XHQvLyBHZXQgbWFyZ2lucyBieSBwcmUtcmVuZGVyaW5nIGF4ZXNcblx0XHQvLyBzZXQgYXhlcyBzY2FsZXNcblx0XHRlYWNoKGF4ZXMsIGZ1bmN0aW9uIChheGlzKSB7XG5cdFx0XHRheGlzLnNldFNjYWxlKCk7XG5cdFx0fSk7XG5cblx0XHRjaGFydC5nZXRNYXJnaW5zKCk7XG5cblx0XHRjaGFydC5tYXhUaWNrcyA9IG51bGw7IC8vIHJlc2V0IGZvciBzZWNvbmQgcGFzc1xuXHRcdGVhY2goYXhlcywgZnVuY3Rpb24gKGF4aXMpIHtcblx0XHRcdGF4aXMuc2V0VGlja1Bvc2l0aW9ucyh0cnVlKTsgLy8gdXBkYXRlIHRvIHJlZmxlY3QgdGhlIG5ldyBtYXJnaW5zXG5cdFx0XHRheGlzLnNldE1heFRpY2tzKCk7XG5cdFx0fSk7XG5cdFx0Y2hhcnQuYWRqdXN0VGlja0Ftb3VudHMoKTtcblx0XHRjaGFydC5nZXRNYXJnaW5zKCk7IC8vIHNlY29uZCBwYXNzIHRvIGNoZWNrIGZvciBuZXcgbGFiZWxzXG5cblxuXHRcdC8vIERyYXcgdGhlIGJvcmRlcnMgYW5kIGJhY2tncm91bmRzXG5cdFx0Y2hhcnQuZHJhd0NoYXJ0Qm94KCk7XHRcdFxuXG5cblx0XHQvLyBBeGVzXG5cdFx0aWYgKGNoYXJ0Lmhhc0NhcnRlc2lhblNlcmllcykge1xuXHRcdFx0ZWFjaChheGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRheGlzLnJlbmRlcigpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIHNlcmllc1xuXHRcdGlmICghY2hhcnQuc2VyaWVzR3JvdXApIHtcblx0XHRcdGNoYXJ0LnNlcmllc0dyb3VwID0gcmVuZGVyZXIuZygnc2VyaWVzLWdyb3VwJylcblx0XHRcdFx0LmF0dHIoeyB6SW5kZXg6IDMgfSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdH1cblx0XHRjaGFydC5yZW5kZXJTZXJpZXMoKTtcblxuXHRcdC8vIExhYmVsc1xuXHRcdGNoYXJ0LnJlbmRlckxhYmVscygpO1xuXG5cdFx0Ly8gQ3JlZGl0c1xuXHRcdGNoYXJ0LnNob3dDcmVkaXRzKG9wdGlvbnMuY3JlZGl0cyk7XG5cblx0XHQvLyBTZXQgZmxhZ1xuXHRcdGNoYXJ0Lmhhc1JlbmRlcmVkID0gdHJ1ZTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTaG93IGNoYXJ0IGNyZWRpdHMgYmFzZWQgb24gY29uZmlnIG9wdGlvbnNcblx0ICovXG5cdHNob3dDcmVkaXRzOiBmdW5jdGlvbiAoY3JlZGl0cykge1xuXHRcdGlmIChjcmVkaXRzLmVuYWJsZWQgJiYgIXRoaXMuY3JlZGl0cykge1xuXHRcdFx0dGhpcy5jcmVkaXRzID0gdGhpcy5yZW5kZXJlci50ZXh0KFxuXHRcdFx0XHRjcmVkaXRzLnRleHQsXG5cdFx0XHRcdDAsXG5cdFx0XHRcdDBcblx0XHRcdClcblx0XHRcdC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdGlmIChjcmVkaXRzLmhyZWYpIHtcblx0XHRcdFx0XHRsb2NhdGlvbi5ocmVmID0gY3JlZGl0cy5ocmVmO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRhbGlnbjogY3JlZGl0cy5wb3NpdGlvbi5hbGlnbixcblx0XHRcdFx0ekluZGV4OiA4XG5cdFx0XHR9KVxuXHRcdFx0LmNzcyhjcmVkaXRzLnN0eWxlKVxuXHRcdFx0LmFkZCgpXG5cdFx0XHQuYWxpZ24oY3JlZGl0cy5wb3NpdGlvbik7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBDbGVhbiB1cCBtZW1vcnkgdXNhZ2Vcblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0YXhlcyA9IGNoYXJ0LmF4ZXMsXG5cdFx0XHRzZXJpZXMgPSBjaGFydC5zZXJpZXMsXG5cdFx0XHRjb250YWluZXIgPSBjaGFydC5jb250YWluZXIsXG5cdFx0XHRpLFxuXHRcdFx0cGFyZW50Tm9kZSA9IGNvbnRhaW5lciAmJiBjb250YWluZXIucGFyZW50Tm9kZTtcblx0XHRcdFxuXHRcdC8vIGZpcmUgdGhlIGNoYXJ0LmRlc3RveSBldmVudFxuXHRcdGZpcmVFdmVudChjaGFydCwgJ2Rlc3Ryb3knKTtcblx0XHRcblx0XHQvLyBEZWxldGUgdGhlIGNoYXJ0IGZyb20gY2hhcnRzIGxvb2t1cCBhcnJheVxuXHRcdGNoYXJ0c1tjaGFydC5pbmRleF0gPSBVTkRFRklORUQ7XG5cdFx0Y2hhcnRDb3VudC0tO1xuXHRcdGNoYXJ0LnJlbmRlclRvLnJlbW92ZUF0dHJpYnV0ZSgnZGF0YS1oaWdoY2hhcnRzLWNoYXJ0Jyk7XG5cblx0XHQvLyByZW1vdmUgZXZlbnRzXG5cdFx0cmVtb3ZlRXZlbnQoY2hhcnQpO1xuXG5cdFx0Ly8gPT09PSBEZXN0cm95IGNvbGxlY3Rpb25zOlxuXHRcdC8vIERlc3Ryb3kgYXhlc1xuXHRcdGkgPSBheGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRheGVzW2ldID0gYXhlc1tpXS5kZXN0cm95KCk7XG5cdFx0fVxuXG5cdFx0Ly8gRGVzdHJveSBlYWNoIHNlcmllc1xuXHRcdGkgPSBzZXJpZXMubGVuZ3RoO1xuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHNlcmllc1tpXSA9IHNlcmllc1tpXS5kZXN0cm95KCk7XG5cdFx0fVxuXG5cdFx0Ly8gPT09PSBEZXN0cm95IGNoYXJ0IHByb3BlcnRpZXM6XG5cdFx0ZWFjaChbJ3RpdGxlJywgJ3N1YnRpdGxlJywgJ2NoYXJ0QmFja2dyb3VuZCcsICdwbG90QmFja2dyb3VuZCcsICdwbG90QkdJbWFnZScsIFxuXHRcdFx0XHQncGxvdEJvcmRlcicsICdzZXJpZXNHcm91cCcsICdjbGlwUmVjdCcsICdjcmVkaXRzJywgJ3BvaW50ZXInLCAnc2Nyb2xsZXInLCBcblx0XHRcdFx0J3JhbmdlU2VsZWN0b3InLCAnbGVnZW5kJywgJ3Jlc2V0Wm9vbUJ1dHRvbicsICd0b29sdGlwJywgJ3JlbmRlcmVyJ10sIGZ1bmN0aW9uIChuYW1lKSB7XG5cdFx0XHR2YXIgcHJvcCA9IGNoYXJ0W25hbWVdO1xuXG5cdFx0XHRpZiAocHJvcCAmJiBwcm9wLmRlc3Ryb3kpIHtcblx0XHRcdFx0Y2hhcnRbbmFtZV0gPSBwcm9wLmRlc3Ryb3koKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIHJlbW92ZSBjb250YWluZXIgYW5kIGFsbCBTVkdcblx0XHRpZiAoY29udGFpbmVyKSB7IC8vIGNhbiBicmVhayBpbiBJRSB3aGVuIGRlc3Ryb3llZCBiZWZvcmUgZmluaXNoZWQgbG9hZGluZ1xuXHRcdFx0Y29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xuXHRcdFx0cmVtb3ZlRXZlbnQoY29udGFpbmVyKTtcblx0XHRcdGlmIChwYXJlbnROb2RlKSB7XG5cdFx0XHRcdGRpc2NhcmRFbGVtZW50KGNvbnRhaW5lcik7XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHQvLyBjbGVhbiBpdCBhbGwgdXBcblx0XHRmb3IgKGkgaW4gY2hhcnQpIHtcblx0XHRcdGRlbGV0ZSBjaGFydFtpXTtcblx0XHR9XG5cblx0fSxcblxuXG5cdC8qKlxuXHQgKiBWTUwgbmFtZXNwYWNlcyBjYW4ndCBiZSBhZGRlZCB1bnRpbCBhZnRlciBjb21wbGV0ZS4gTGlzdGVuaW5nXG5cdCAqIGZvciBQZXJpbmkncyBkb1Njcm9sbCBoYWNrIGlzIG5vdCBlbm91Z2guXG5cdCAqL1xuXHRpc1JlYWR5VG9SZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzO1xuXG5cdFx0Ly8gTm90ZTogaW4gc3BpdGUgb2YgSlNMaW50J3MgY29tcGxhaW50cywgd2luID09IHdpbi50b3AgaXMgcmVxdWlyZWRcblx0XHQvKmpzbGludCBlcWVxOiB0cnVlKi9cblx0XHRpZiAoKCFoYXNTVkcgJiYgKHdpbiA9PSB3aW4udG9wICYmIGRvYy5yZWFkeVN0YXRlICE9PSAnY29tcGxldGUnKSkgfHwgKHVzZUNhblZHICYmICF3aW4uY2FudmcpKSB7XG5cdFx0Lypqc2xpbnQgZXFlcTogZmFsc2UqL1xuXHRcdFx0aWYgKHVzZUNhblZHKSB7XG5cdFx0XHRcdC8vIERlbGF5IHJlbmRlcmluZyB1bnRpbCBjYW52ZyBsaWJyYXJ5IGlzIGRvd25sb2FkZWQgYW5kIHJlYWR5XG5cdFx0XHRcdENhblZHQ29udHJvbGxlci5wdXNoKGZ1bmN0aW9uICgpIHsgY2hhcnQuZmlyc3RSZW5kZXIoKTsgfSwgY2hhcnQub3B0aW9ucy5nbG9iYWwuY2FudmFzVG9vbHNVUkwpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZG9jLmF0dGFjaEV2ZW50KCdvbnJlYWR5c3RhdGVjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0ZG9jLmRldGFjaEV2ZW50KCdvbnJlYWR5c3RhdGVjaGFuZ2UnLCBjaGFydC5maXJzdFJlbmRlcik7XG5cdFx0XHRcdFx0aWYgKGRvYy5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG5cdFx0XHRcdFx0XHRjaGFydC5maXJzdFJlbmRlcigpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiB0cnVlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBQcmVwYXJlIGZvciBmaXJzdCByZW5kZXJpbmcgYWZ0ZXIgYWxsIGRhdGEgYXJlIGxvYWRlZFxuXHQgKi9cblx0Zmlyc3RSZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMsXG5cdFx0XHRjYWxsYmFjayA9IGNoYXJ0LmNhbGxiYWNrO1xuXG5cdFx0Ly8gQ2hlY2sgd2hldGhlciB0aGUgY2hhcnQgaXMgcmVhZHkgdG8gcmVuZGVyXG5cdFx0aWYgKCFjaGFydC5pc1JlYWR5VG9SZW5kZXIoKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENyZWF0ZSB0aGUgY29udGFpbmVyXG5cdFx0Y2hhcnQuZ2V0Q29udGFpbmVyKCk7XG5cblx0XHQvLyBSdW4gYW4gZWFybHkgZXZlbnQgYWZ0ZXIgdGhlIGNvbnRhaW5lciBhbmQgcmVuZGVyZXIgYXJlIGVzdGFibGlzaGVkXG5cdFx0ZmlyZUV2ZW50KGNoYXJ0LCAnaW5pdCcpO1xuXG5cdFx0XG5cdFx0Y2hhcnQucmVzZXRNYXJnaW5zKCk7XG5cdFx0Y2hhcnQuc2V0Q2hhcnRTaXplKCk7XG5cblx0XHQvLyBTZXQgdGhlIGNvbW1vbiBjaGFydCBwcm9wZXJ0aWVzIChtYWlubHkgaW52ZXJ0KSBmcm9tIHRoZSBnaXZlbiBzZXJpZXNcblx0XHRjaGFydC5wcm9wRnJvbVNlcmllcygpO1xuXG5cdFx0Ly8gZ2V0IGF4ZXNcblx0XHRjaGFydC5nZXRBeGVzKCk7XG5cblx0XHQvLyBJbml0aWFsaXplIHRoZSBzZXJpZXNcblx0XHRlYWNoKG9wdGlvbnMuc2VyaWVzIHx8IFtdLCBmdW5jdGlvbiAoc2VyaWVPcHRpb25zKSB7XG5cdFx0XHRjaGFydC5pbml0U2VyaWVzKHNlcmllT3B0aW9ucyk7XG5cdFx0fSk7XG5cblx0XHRjaGFydC5saW5rU2VyaWVzKCk7XG5cblx0XHQvLyBSdW4gYW4gZXZlbnQgYWZ0ZXIgYXhlcyBhbmQgc2VyaWVzIGFyZSBpbml0aWFsaXplZCwgYnV0IGJlZm9yZSByZW5kZXIuIEF0IHRoaXMgc3RhZ2UsXG5cdFx0Ly8gdGhlIHNlcmllcyBkYXRhIGlzIGluZGV4ZWQgYW5kIGNhY2hlZCBpbiB0aGUgeERhdGEgYW5kIHlEYXRhIGFycmF5cywgc28gd2UgY2FuIGFjY2Vzc1xuXHRcdC8vIHRob3NlIGJlZm9yZSByZW5kZXJpbmcuIFVzZWQgaW4gSGlnaHN0b2NrLiBcblx0XHRmaXJlRXZlbnQoY2hhcnQsICdiZWZvcmVSZW5kZXInKTsgXG5cblx0XHQvLyBkZXBlbmRzIG9uIGludmVydGVkIGFuZCBvbiBtYXJnaW5zIGJlaW5nIHNldFxuXHRcdGlmIChIaWdoY2hhcnRzLlBvaW50ZXIpIHtcblx0XHRcdGNoYXJ0LnBvaW50ZXIgPSBuZXcgUG9pbnRlcihjaGFydCwgb3B0aW9ucyk7XG5cdFx0fVxuXG5cdFx0Y2hhcnQucmVuZGVyKCk7XG5cblx0XHQvLyBhZGQgY2FudmFzXG5cdFx0Y2hhcnQucmVuZGVyZXIuZHJhdygpO1xuXHRcdC8vIHJ1biBjYWxsYmFja3Ncblx0XHRpZiAoY2FsbGJhY2spIHtcblx0XHRcdGNhbGxiYWNrLmFwcGx5KGNoYXJ0LCBbY2hhcnRdKTtcblx0XHR9XG5cdFx0ZWFjaChjaGFydC5jYWxsYmFja3MsIGZ1bmN0aW9uIChmbikge1xuXHRcdFx0Zm4uYXBwbHkoY2hhcnQsIFtjaGFydF0pO1xuXHRcdH0pO1xuXHRcdFxuXHRcdFxuXHRcdC8vIElmIHRoZSBjaGFydCB3YXMgcmVuZGVyZWQgb3V0c2lkZSB0aGUgdG9wIGNvbnRhaW5lciwgcHV0IGl0IGJhY2sgaW5cblx0XHRjaGFydC5jbG9uZVJlbmRlclRvKHRydWUpO1xuXHRcdFxuXHRcdGZpcmVFdmVudChjaGFydCwgJ2xvYWQnKTtcblxuXHR9LFxuXG5cdC8qKlxuXHQqIENyZWF0ZXMgYXJyYXlzIGZvciBzcGFjaW5nIGFuZCBtYXJnaW4gZnJvbSBnaXZlbiBvcHRpb25zLlxuXHQqL1xuXHRzcGxhc2hBcnJheTogZnVuY3Rpb24gKHRhcmdldCwgb3B0aW9ucykge1xuXHRcdHZhciBvVmFyID0gb3B0aW9uc1t0YXJnZXRdLFxuXHRcdFx0dEFycmF5ID0gaXNPYmplY3Qob1ZhcikgPyBvVmFyIDogW29WYXIsIG9WYXIsIG9WYXIsIG9WYXJdO1xuXG5cdFx0cmV0dXJuIFtwaWNrKG9wdGlvbnNbdGFyZ2V0ICsgJ1RvcCddLCB0QXJyYXlbMF0pLFxuXHRcdFx0XHRwaWNrKG9wdGlvbnNbdGFyZ2V0ICsgJ1JpZ2h0J10sIHRBcnJheVsxXSksXG5cdFx0XHRcdHBpY2sob3B0aW9uc1t0YXJnZXQgKyAnQm90dG9tJ10sIHRBcnJheVsyXSksXG5cdFx0XHRcdHBpY2sob3B0aW9uc1t0YXJnZXQgKyAnTGVmdCddLCB0QXJyYXlbM10pXTtcblx0fVxufTsgLy8gZW5kIENoYXJ0XG5cbi8vIEhvb2sgZm9yIGV4cG9ydGluZyBtb2R1bGVcbkNoYXJ0LnByb3RvdHlwZS5jYWxsYmFja3MgPSBbXTtcblxudmFyIENlbnRlcmVkU2VyaWVzTWl4aW4gPSBIaWdoY2hhcnRzLkNlbnRlcmVkU2VyaWVzTWl4aW4gPSB7XG5cdC8qKlxuXHQgKiBHZXQgdGhlIGNlbnRlciBvZiB0aGUgcGllIGJhc2VkIG9uIHRoZSBzaXplIGFuZCBjZW50ZXIgb3B0aW9ucyByZWxhdGl2ZSB0byB0aGUgIFxuXHQgKiBwbG90IGFyZWEuIEJvcnJvd2VkIGJ5IHRoZSBwb2xhciBhbmQgZ2F1Z2Ugc2VyaWVzIHR5cGVzLlxuXHQgKi9cblx0Z2V0Q2VudGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0XG5cdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRzbGljaW5nUm9vbSA9IDIgKiAob3B0aW9ucy5zbGljZWRPZmZzZXQgfHwgMCksXG5cdFx0XHRoYW5kbGVTbGljaW5nUm9vbSxcblx0XHRcdHBsb3RXaWR0aCA9IGNoYXJ0LnBsb3RXaWR0aCAtIDIgKiBzbGljaW5nUm9vbSxcblx0XHRcdHBsb3RIZWlnaHQgPSBjaGFydC5wbG90SGVpZ2h0IC0gMiAqIHNsaWNpbmdSb29tLFxuXHRcdFx0Y2VudGVyT3B0aW9uID0gb3B0aW9ucy5jZW50ZXIsXG5cdFx0XHRwb3NpdGlvbnMgPSBbcGljayhjZW50ZXJPcHRpb25bMF0sICc1MCUnKSwgcGljayhjZW50ZXJPcHRpb25bMV0sICc1MCUnKSwgb3B0aW9ucy5zaXplIHx8ICcxMDAlJywgb3B0aW9ucy5pbm5lclNpemUgfHwgMF0sXG5cdFx0XHRzbWFsbGVzdFNpemUgPSBtYXRoTWluKHBsb3RXaWR0aCwgcGxvdEhlaWdodCksXG5cdFx0XHRpc1BlcmNlbnQ7XG5cdFx0XG5cdFx0cmV0dXJuIG1hcChwb3NpdGlvbnMsIGZ1bmN0aW9uIChsZW5ndGgsIGkpIHtcblx0XHRcdGlzUGVyY2VudCA9IC8lJC8udGVzdChsZW5ndGgpO1xuXHRcdFx0aGFuZGxlU2xpY2luZ1Jvb20gPSBpIDwgMiB8fCAoaSA9PT0gMiAmJiBpc1BlcmNlbnQpO1xuXHRcdFx0cmV0dXJuIChpc1BlcmNlbnQgP1xuXHRcdFx0XHQvLyBpID09IDA6IGNlbnRlclgsIHJlbGF0aXZlIHRvIHdpZHRoXG5cdFx0XHRcdC8vIGkgPT0gMTogY2VudGVyWSwgcmVsYXRpdmUgdG8gaGVpZ2h0XG5cdFx0XHRcdC8vIGkgPT0gMjogc2l6ZSwgcmVsYXRpdmUgdG8gc21hbGxlc3RTaXplXG5cdFx0XHRcdC8vIGkgPT0gNDogaW5uZXJTaXplLCByZWxhdGl2ZSB0byBzbWFsbGVzdFNpemVcblx0XHRcdFx0W3Bsb3RXaWR0aCwgcGxvdEhlaWdodCwgc21hbGxlc3RTaXplLCBzbWFsbGVzdFNpemVdW2ldICpcblx0XHRcdFx0XHRwSW50KGxlbmd0aCkgLyAxMDAgOlxuXHRcdFx0XHRsZW5ndGgpICsgKGhhbmRsZVNsaWNpbmdSb29tID8gc2xpY2luZ1Jvb20gOiAwKTtcblx0XHR9KTtcblx0fVxufTtcblxuLyoqXG4gKiBUaGUgUG9pbnQgb2JqZWN0IGFuZCBwcm90b3R5cGUuIEluaGVyaXRhYmxlIGFuZCB1c2VkIGFzIGJhc2UgZm9yIFBpZVBvaW50XG4gKi9cbnZhciBQb2ludCA9IGZ1bmN0aW9uICgpIHt9O1xuUG9pbnQucHJvdG90eXBlID0ge1xuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIHRoZSBwb2ludFxuXHQgKiBAcGFyYW0ge09iamVjdH0gc2VyaWVzIFRoZSBzZXJpZXMgb2JqZWN0IGNvbnRhaW5pbmcgdGhpcyBwb2ludFxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgZGF0YSBpbiBlaXRoZXIgbnVtYmVyLCBhcnJheSBvciBvYmplY3QgZm9ybWF0XG5cdCAqL1xuXHRpbml0OiBmdW5jdGlvbiAoc2VyaWVzLCBvcHRpb25zLCB4KSB7XG5cblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0Y29sb3JzO1xuXHRcdHBvaW50LnNlcmllcyA9IHNlcmllcztcblx0XHRwb2ludC5hcHBseU9wdGlvbnMob3B0aW9ucywgeCk7XG5cdFx0cG9pbnQucG9pbnRBdHRyID0ge307XG5cblx0XHRpZiAoc2VyaWVzLm9wdGlvbnMuY29sb3JCeVBvaW50KSB7XG5cdFx0XHRjb2xvcnMgPSBzZXJpZXMub3B0aW9ucy5jb2xvcnMgfHwgc2VyaWVzLmNoYXJ0Lm9wdGlvbnMuY29sb3JzO1xuXHRcdFx0cG9pbnQuY29sb3IgPSBwb2ludC5jb2xvciB8fCBjb2xvcnNbc2VyaWVzLmNvbG9yQ291bnRlcisrXTtcblx0XHRcdC8vIGxvb3AgYmFjayB0byB6ZXJvXG5cdFx0XHRpZiAoc2VyaWVzLmNvbG9yQ291bnRlciA9PT0gY29sb3JzLmxlbmd0aCkge1xuXHRcdFx0XHRzZXJpZXMuY29sb3JDb3VudGVyID0gMDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRzZXJpZXMuY2hhcnQucG9pbnRDb3VudCsrO1xuXHRcdHJldHVybiBwb2ludDtcblx0fSxcblx0LyoqXG5cdCAqIEFwcGx5IHRoZSBvcHRpb25zIGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgZGF0YSBhbmQgcG9zc2libGUgc29tZSBleHRyYSBwcm9wZXJ0aWVzLlxuXHQgKiBUaGlzIGlzIGNhbGxlZCBvbiBwb2ludCBpbml0IG9yIGZyb20gcG9pbnQudXBkYXRlLlxuXHQgKlxuXHQgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuXHQgKi9cblx0YXBwbHlPcHRpb25zOiBmdW5jdGlvbiAob3B0aW9ucywgeCkge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRwb2ludFZhbEtleSA9IHNlcmllcy5vcHRpb25zLnBvaW50VmFsS2V5IHx8IHNlcmllcy5wb2ludFZhbEtleTtcblxuXHRcdG9wdGlvbnMgPSBQb2ludC5wcm90b3R5cGUub3B0aW9uc1RvT2JqZWN0LmNhbGwodGhpcywgb3B0aW9ucyk7XG5cblx0XHQvLyBjb3B5IG9wdGlvbnMgZGlyZWN0bHkgdG8gcG9pbnRcblx0XHRleHRlbmQocG9pbnQsIG9wdGlvbnMpO1xuXHRcdHBvaW50Lm9wdGlvbnMgPSBwb2ludC5vcHRpb25zID8gZXh0ZW5kKHBvaW50Lm9wdGlvbnMsIG9wdGlvbnMpIDogb3B0aW9ucztcblxuXHRcdC8vIEZvciBoaWdoZXIgZGltZW5zaW9uIHNlcmllcyB0eXBlcy4gRm9yIGluc3RhbmNlLCBmb3IgcmFuZ2VzLCBwb2ludC55IGlzIG1hcHBlZCB0byBwb2ludC5sb3cuXG5cdFx0aWYgKHBvaW50VmFsS2V5KSB7XG5cdFx0XHRwb2ludC55ID0gcG9pbnRbcG9pbnRWYWxLZXldO1xuXHRcdH1cblxuXHRcdC8vIElmIG5vIHggaXMgc2V0IGJ5IG5vdywgZ2V0IGF1dG8gaW5jcmVtZW50ZWQgdmFsdWUuIEFsbCBwb2ludHMgbXVzdCBoYXZlIGFuXG5cdFx0Ly8geCB2YWx1ZSwgaG93ZXZlciB0aGUgeSB2YWx1ZSBjYW4gYmUgbnVsbCB0byBjcmVhdGUgYSBnYXAgaW4gdGhlIHNlcmllc1xuXHRcdGlmIChwb2ludC54ID09PSBVTkRFRklORUQgJiYgc2VyaWVzKSB7XG5cdFx0XHRwb2ludC54ID0geCA9PT0gVU5ERUZJTkVEID8gc2VyaWVzLmF1dG9JbmNyZW1lbnQoKSA6IHg7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHBvaW50O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBUcmFuc2Zvcm0gbnVtYmVyIG9yIGFycmF5IGNvbmZpZ3MgaW50byBvYmplY3RzXG5cdCAqL1xuXHRvcHRpb25zVG9PYmplY3Q6IGZ1bmN0aW9uIChvcHRpb25zKSB7XG5cdFx0dmFyIHJldCA9IHt9LFxuXHRcdFx0c2VyaWVzID0gdGhpcy5zZXJpZXMsXG5cdFx0XHRwb2ludEFycmF5TWFwID0gc2VyaWVzLnBvaW50QXJyYXlNYXAgfHwgWyd5J10sXG5cdFx0XHR2YWx1ZUNvdW50ID0gcG9pbnRBcnJheU1hcC5sZW5ndGgsXG5cdFx0XHRmaXJzdEl0ZW1UeXBlLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRqID0gMDtcblxuXHRcdGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ251bWJlcicgfHwgb3B0aW9ucyA9PT0gbnVsbCkge1xuXHRcdFx0cmV0W3BvaW50QXJyYXlNYXBbMF1dID0gb3B0aW9ucztcblxuXHRcdH0gZWxzZSBpZiAoaXNBcnJheShvcHRpb25zKSkge1xuXHRcdFx0Ly8gd2l0aCBsZWFkaW5nIHggdmFsdWVcblx0XHRcdGlmIChvcHRpb25zLmxlbmd0aCA+IHZhbHVlQ291bnQpIHtcblx0XHRcdFx0Zmlyc3RJdGVtVHlwZSA9IHR5cGVvZiBvcHRpb25zWzBdO1xuXHRcdFx0XHRpZiAoZmlyc3RJdGVtVHlwZSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0XHRyZXQubmFtZSA9IG9wdGlvbnNbMF07XG5cdFx0XHRcdH0gZWxzZSBpZiAoZmlyc3RJdGVtVHlwZSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0XHRyZXQueCA9IG9wdGlvbnNbMF07XG5cdFx0XHRcdH1cblx0XHRcdFx0aSsrO1xuXHRcdFx0fVxuXHRcdFx0d2hpbGUgKGogPCB2YWx1ZUNvdW50KSB7XG5cdFx0XHRcdHJldFtwb2ludEFycmF5TWFwW2orK11dID0gb3B0aW9uc1tpKytdO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdvYmplY3QnKSB7XG5cdFx0XHRyZXQgPSBvcHRpb25zO1xuXG5cdFx0XHQvLyBUaGlzIGlzIHRoZSBmYXN0ZXN0IHdheSB0byBkZXRlY3QgaWYgdGhlcmUgYXJlIGluZGl2aWR1YWwgcG9pbnQgZGF0YUxhYmVscyB0aGF0IG5lZWRcblx0XHRcdC8vIHRvIGJlIGNvbnNpZGVyZWQgaW4gZHJhd0RhdGFMYWJlbHMuIFRoZXNlIGNhbiBvbmx5IG9jY3VyIGluIG9iamVjdCBjb25maWdzLlxuXHRcdFx0aWYgKG9wdGlvbnMuZGF0YUxhYmVscykge1xuXHRcdFx0XHRzZXJpZXMuX2hhc1BvaW50TGFiZWxzID0gdHJ1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2FtZSBhcHByb2FjaCBhcyBhYm92ZSBmb3IgbWFya2Vyc1xuXHRcdFx0aWYgKG9wdGlvbnMubWFya2VyKSB7XG5cdFx0XHRcdHNlcmllcy5faGFzUG9pbnRNYXJrZXJzID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvKipcblx0ICogRGVzdHJveSBhIHBvaW50IHRvIGNsZWFyIG1lbW9yeS4gSXRzIHJlZmVyZW5jZSBzdGlsbCBzdGF5cyBpbiBzZXJpZXMuZGF0YS5cblx0ICovXG5cdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRob3ZlclBvaW50cyA9IGNoYXJ0LmhvdmVyUG9pbnRzLFxuXHRcdFx0cHJvcDtcblxuXHRcdGNoYXJ0LnBvaW50Q291bnQtLTtcblxuXHRcdGlmIChob3ZlclBvaW50cykge1xuXHRcdFx0cG9pbnQuc2V0U3RhdGUoKTtcblx0XHRcdGVyYXNlKGhvdmVyUG9pbnRzLCBwb2ludCk7XG5cdFx0XHRpZiAoIWhvdmVyUG9pbnRzLmxlbmd0aCkge1xuXHRcdFx0XHRjaGFydC5ob3ZlclBvaW50cyA9IG51bGw7XG5cdFx0XHR9XG5cblx0XHR9XG5cdFx0aWYgKHBvaW50ID09PSBjaGFydC5ob3ZlclBvaW50KSB7XG5cdFx0XHRwb2ludC5vbk1vdXNlT3V0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gcmVtb3ZlIGFsbCBldmVudHNcblx0XHRpZiAocG9pbnQuZ3JhcGhpYyB8fCBwb2ludC5kYXRhTGFiZWwpIHsgLy8gcmVtb3ZlRXZlbnQgYW5kIGRlc3Ryb3lFbGVtZW50cyBhcmUgcGVyZm9ybWFuY2UgZXhwZW5zaXZlXG5cdFx0XHRyZW1vdmVFdmVudChwb2ludCk7XG5cdFx0XHRwb2ludC5kZXN0cm95RWxlbWVudHMoKTtcblx0XHR9XG5cblx0XHRpZiAocG9pbnQubGVnZW5kSXRlbSkgeyAvLyBwaWVzIGhhdmUgbGVnZW5kIGl0ZW1zXG5cdFx0XHRjaGFydC5sZWdlbmQuZGVzdHJveUl0ZW0ocG9pbnQpO1xuXHRcdH1cblxuXHRcdGZvciAocHJvcCBpbiBwb2ludCkge1xuXHRcdFx0cG9pbnRbcHJvcF0gPSBudWxsO1xuXHRcdH1cblxuXG5cdH0sXG5cblx0LyoqXG5cdCAqIERlc3Ryb3kgU1ZHIGVsZW1lbnRzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcG9pbnRcblx0ICovXG5cdGRlc3Ryb3lFbGVtZW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRwcm9wcyA9IFsnZ3JhcGhpYycsICdkYXRhTGFiZWwnLCAnZGF0YUxhYmVsVXBwZXInLCAnZ3JvdXAnLCAnY29ubmVjdG9yJywgJ3NoYWRvd0dyb3VwJ10sXG5cdFx0XHRwcm9wLFxuXHRcdFx0aSA9IDY7XG5cdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0cHJvcCA9IHByb3BzW2ldO1xuXHRcdFx0aWYgKHBvaW50W3Byb3BdKSB7XG5cdFx0XHRcdHBvaW50W3Byb3BdID0gcG9pbnRbcHJvcF0uZGVzdHJveSgpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJuIHRoZSBjb25maWd1cmF0aW9uIGhhc2ggbmVlZGVkIGZvciB0aGUgZGF0YSBsYWJlbCBhbmQgdG9vbHRpcCBmb3JtYXR0ZXJzXG5cdCAqL1xuXHRnZXRMYWJlbENvbmZpZzogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBwb2ludCA9IHRoaXM7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IHBvaW50LmNhdGVnb3J5LFxuXHRcdFx0eTogcG9pbnQueSxcblx0XHRcdGtleTogcG9pbnQubmFtZSB8fCBwb2ludC5jYXRlZ29yeSxcblx0XHRcdHNlcmllczogcG9pbnQuc2VyaWVzLFxuXHRcdFx0cG9pbnQ6IHBvaW50LFxuXHRcdFx0cGVyY2VudGFnZTogcG9pbnQucGVyY2VudGFnZSxcblx0XHRcdHRvdGFsOiBwb2ludC50b3RhbCB8fCBwb2ludC5zdGFja1RvdGFsXG5cdFx0fTtcblx0fSxcdFxuXG5cdC8qKlxuXHQgKiBFeHRlbmRhYmxlIG1ldGhvZCBmb3IgZm9ybWF0dGluZyBlYWNoIHBvaW50J3MgdG9vbHRpcCBsaW5lXG5cdCAqXG5cdCAqIEByZXR1cm4ge1N0cmluZ30gQSBzdHJpbmcgdG8gYmUgY29uY2F0ZW5hdGVkIGluIHRvIHRoZSBjb21tb24gdG9vbHRpcCB0ZXh0XG5cdCAqL1xuXHR0b29sdGlwRm9ybWF0dGVyOiBmdW5jdGlvbiAocG9pbnRGb3JtYXQpIHtcblxuXHRcdC8vIEluc2VydCBvcHRpb25zIGZvciB2YWx1ZURlY2ltYWxzLCB2YWx1ZVByZWZpeCwgYW5kIHZhbHVlU3VmZml4XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMuc2VyaWVzLFxuXHRcdFx0c2VyaWVzVG9vbHRpcE9wdGlvbnMgPSBzZXJpZXMudG9vbHRpcE9wdGlvbnMsXG5cdFx0XHR2YWx1ZURlY2ltYWxzID0gcGljayhzZXJpZXNUb29sdGlwT3B0aW9ucy52YWx1ZURlY2ltYWxzLCAnJyksXG5cdFx0XHR2YWx1ZVByZWZpeCA9IHNlcmllc1Rvb2x0aXBPcHRpb25zLnZhbHVlUHJlZml4IHx8ICcnLFxuXHRcdFx0dmFsdWVTdWZmaXggPSBzZXJpZXNUb29sdGlwT3B0aW9ucy52YWx1ZVN1ZmZpeCB8fCAnJztcblxuXHRcdC8vIExvb3Agb3ZlciB0aGUgcG9pbnQgYXJyYXkgbWFwIGFuZCByZXBsYWNlIHVuZm9ybWF0dGVkIHZhbHVlcyB3aXRoIHNwcmludGYgZm9ybWF0dGluZyBtYXJrdXBcblx0XHRlYWNoKHNlcmllcy5wb2ludEFycmF5TWFwIHx8IFsneSddLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRrZXkgPSAne3BvaW50LicgKyBrZXk7IC8vIHdpdGhvdXQgdGhlIGNsb3NpbmcgYnJhY2tldFxuXHRcdFx0aWYgKHZhbHVlUHJlZml4IHx8IHZhbHVlU3VmZml4KSB7XG5cdFx0XHRcdHBvaW50Rm9ybWF0ID0gcG9pbnRGb3JtYXQucmVwbGFjZShrZXkgKyAnfScsIHZhbHVlUHJlZml4ICsga2V5ICsgJ30nICsgdmFsdWVTdWZmaXgpO1xuXHRcdFx0fVxuXHRcdFx0cG9pbnRGb3JtYXQgPSBwb2ludEZvcm1hdC5yZXBsYWNlKGtleSArICd9Jywga2V5ICsgJzosLicgKyB2YWx1ZURlY2ltYWxzICsgJ2Z9Jyk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gZm9ybWF0KHBvaW50Rm9ybWF0LCB7XG5cdFx0XHRwb2ludDogdGhpcyxcblx0XHRcdHNlcmllczogdGhpcy5zZXJpZXNcblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogRmlyZSBhbiBldmVudCBvbiB0aGUgUG9pbnQgb2JqZWN0LiBNdXN0IG5vdCBiZSByZW5hbWVkIHRvIGZpcmVFdmVudCwgYXMgdGhpc1xuXHQgKiBjYXVzZXMgYSBuYW1lIGNsYXNoIGluIE1vb1Rvb2xzXG5cdCAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFR5cGVcblx0ICogQHBhcmFtIHtPYmplY3R9IGV2ZW50QXJncyBBZGRpdGlvbmFsIGV2ZW50IGFyZ3VtZW50c1xuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkZWZhdWx0RnVuY3Rpb24gRGVmYXVsdCBldmVudCBoYW5kbGVyXG5cdCAqL1xuXHRmaXJlUG9pbnRFdmVudDogZnVuY3Rpb24gKGV2ZW50VHlwZSwgZXZlbnRBcmdzLCBkZWZhdWx0RnVuY3Rpb24pIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gdGhpcy5zZXJpZXMsXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnM7XG5cblx0XHQvLyBsb2FkIGV2ZW50IGhhbmRsZXJzIG9uIGRlbWFuZCB0byBzYXZlIHRpbWUgb24gbW91c2VvdmVyL291dFxuXHRcdGlmIChzZXJpZXNPcHRpb25zLnBvaW50LmV2ZW50c1tldmVudFR5cGVdIHx8IChwb2ludC5vcHRpb25zICYmIHBvaW50Lm9wdGlvbnMuZXZlbnRzICYmIHBvaW50Lm9wdGlvbnMuZXZlbnRzW2V2ZW50VHlwZV0pKSB7XG5cdFx0XHR0aGlzLmltcG9ydEV2ZW50cygpO1xuXHRcdH1cblxuXHRcdC8vIGFkZCBkZWZhdWx0IGhhbmRsZXIgaWYgaW4gc2VsZWN0aW9uIG1vZGVcblx0XHRpZiAoZXZlbnRUeXBlID09PSAnY2xpY2snICYmIHNlcmllc09wdGlvbnMuYWxsb3dQb2ludFNlbGVjdCkge1xuXHRcdFx0ZGVmYXVsdEZ1bmN0aW9uID0gZnVuY3Rpb24gKGV2ZW50KSB7XG5cdFx0XHRcdC8vIENvbnRyb2wga2V5IGlzIGZvciBXaW5kb3dzLCBtZXRhICg9IENtZCBrZXkpIGZvciBNYWMsIFNoaWZ0IGZvciBPcGVyYVxuXHRcdFx0XHRwb2ludC5zZWxlY3QobnVsbCwgZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGV2ZW50LnNoaWZ0S2V5KTtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0ZmlyZUV2ZW50KHRoaXMsIGV2ZW50VHlwZSwgZXZlbnRBcmdzLCBkZWZhdWx0RnVuY3Rpb24pO1xuXHR9XG59Oy8qKlxuICogQGNsYXNzRGVzY3JpcHRpb24gVGhlIGJhc2UgZnVuY3Rpb24gd2hpY2ggYWxsIG90aGVyIHNlcmllcyB0eXBlcyBpbmhlcml0IGZyb20uIFRoZSBkYXRhIGluIHRoZSBzZXJpZXMgaXMgc3RvcmVkXG4gKiBpbiB2YXJpb3VzIGFycmF5cy5cbiAqXG4gKiAtIEZpcnN0LCBzZXJpZXMub3B0aW9ucy5kYXRhIGNvbnRhaW5zIGFsbCB0aGUgb3JpZ2luYWwgY29uZmlnIG9wdGlvbnMgZm9yXG4gKiBlYWNoIHBvaW50IHdoZXRoZXIgYWRkZWQgYnkgb3B0aW9ucyBvciBtZXRob2RzIGxpa2Ugc2VyaWVzLmFkZFBvaW50LlxuICogLSBOZXh0LCBzZXJpZXMuZGF0YSBjb250YWlucyB0aG9zZSB2YWx1ZXMgY29udmVydGVkIHRvIHBvaW50cywgYnV0IGluIGNhc2UgdGhlIHNlcmllcyBkYXRhIGxlbmd0aFxuICogZXhjZWVkcyB0aGUgY3JvcFRocmVzaG9sZCwgb3IgaWYgdGhlIGRhdGEgaXMgZ3JvdXBlZCwgc2VyaWVzLmRhdGEgZG9lc24ndCBjb250YWluIGFsbCB0aGUgcG9pbnRzLiBJdFxuICogb25seSBjb250YWlucyB0aGUgcG9pbnRzIHRoYXQgaGF2ZSBiZWVuIGNyZWF0ZWQgb24gZGVtYW5kLlxuICogLSBUaGVuIHRoZXJlJ3Mgc2VyaWVzLnBvaW50cyB0aGF0IGNvbnRhaW5zIGFsbCBjdXJyZW50bHkgdmlzaWJsZSBwb2ludCBvYmplY3RzLiBJbiBjYXNlIG9mIGNyb3BwaW5nLFxuICogdGhlIGNyb3BwZWQtYXdheSBwb2ludHMgYXJlIG5vdCBwYXJ0IG9mIHRoaXMgYXJyYXkuIFRoZSBzZXJpZXMucG9pbnRzIGFycmF5IHN0YXJ0cyBhdCBzZXJpZXMuY3JvcFN0YXJ0XG4gKiBjb21wYXJlZCB0byBzZXJpZXMuZGF0YSBhbmQgc2VyaWVzLm9wdGlvbnMuZGF0YS4gSWYgaG93ZXZlciB0aGUgc2VyaWVzIGRhdGEgaXMgZ3JvdXBlZCwgdGhlc2UgY2FuJ3RcbiAqIGJlIGNvcnJlbGF0ZWQgb25lIHRvIG9uZS5cbiAqIC0gc2VyaWVzLnhEYXRhIGFuZCBzZXJpZXMucHJvY2Vzc2VkWERhdGEgY29udGFpbiBjbGVhbiB4IHZhbHVlcywgZXF1aXZhbGVudCB0byBzZXJpZXMuZGF0YSBhbmQgc2VyaWVzLnBvaW50cy5cbiAqIC0gc2VyaWVzLnlEYXRhIGFuZCBzZXJpZXMucHJvY2Vzc2VkWURhdGEgY29udGFpbiBjbGVhbiB4IHZhbHVlcywgZXF1aXZhbGVudCB0byBzZXJpZXMuZGF0YSBhbmQgc2VyaWVzLnBvaW50cy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY2hhcnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbnZhciBTZXJpZXMgPSBmdW5jdGlvbiAoKSB7fTtcblxuU2VyaWVzLnByb3RvdHlwZSA9IHtcblxuXHRpc0NhcnRlc2lhbjogdHJ1ZSxcblx0dHlwZTogJ2xpbmUnLFxuXHRwb2ludENsYXNzOiBQb2ludCxcblx0c29ydGVkOiB0cnVlLCAvLyByZXF1aXJlcyB0aGUgZGF0YSB0byBiZSBzb3J0ZWRcblx0cmVxdWlyZVNvcnRpbmc6IHRydWUsXG5cdHBvaW50QXR0clRvT3B0aW9uczogeyAvLyBtYXBwaW5nIGJldHdlZW4gU1ZHIGF0dHJpYnV0ZXMgYW5kIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbnNcblx0XHRzdHJva2U6ICdsaW5lQ29sb3InLFxuXHRcdCdzdHJva2Utd2lkdGgnOiAnbGluZVdpZHRoJyxcblx0XHRmaWxsOiAnZmlsbENvbG9yJyxcblx0XHRyOiAncmFkaXVzJ1xuXHR9LFxuXHRheGlzVHlwZXM6IFsneEF4aXMnLCAneUF4aXMnXSxcblx0Y29sb3JDb3VudGVyOiAwLFxuXHRwYXJhbGxlbEFycmF5czogWyd4JywgJ3knXSwgLy8gZWFjaCBwb2ludCdzIHggYW5kIHkgdmFsdWVzIGFyZSBzdG9yZWQgaW4gdGhpcy54RGF0YSBhbmQgdGhpcy55RGF0YVxuXHRpbml0OiBmdW5jdGlvbiAoY2hhcnQsIG9wdGlvbnMpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGV2ZW50VHlwZSxcblx0XHRcdGV2ZW50cyxcblx0XHRcdGNoYXJ0U2VyaWVzID0gY2hhcnQuc2VyaWVzLFxuXHRcdFx0c29ydEJ5SW5kZXggPSBmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gcGljayhhLm9wdGlvbnMuaW5kZXgsIGEuX2kpIC0gcGljayhiLm9wdGlvbnMuaW5kZXgsIGIuX2kpO1xuXHRcdFx0fTtcblxuXHRcdHNlcmllcy5jaGFydCA9IGNoYXJ0O1xuXHRcdHNlcmllcy5vcHRpb25zID0gb3B0aW9ucyA9IHNlcmllcy5zZXRPcHRpb25zKG9wdGlvbnMpOyAvLyBtZXJnZSB3aXRoIHBsb3RPcHRpb25zXG5cdFx0c2VyaWVzLmxpbmtlZFNlcmllcyA9IFtdO1xuXG5cdFx0Ly8gYmluZCB0aGUgYXhlc1xuXHRcdHNlcmllcy5iaW5kQXhlcygpO1xuXG5cdFx0Ly8gc2V0IHNvbWUgdmFyaWFibGVzXG5cdFx0ZXh0ZW5kKHNlcmllcywge1xuXHRcdFx0bmFtZTogb3B0aW9ucy5uYW1lLFxuXHRcdFx0c3RhdGU6IE5PUk1BTF9TVEFURSxcblx0XHRcdHBvaW50QXR0cjoge30sXG5cdFx0XHR2aXNpYmxlOiBvcHRpb25zLnZpc2libGUgIT09IGZhbHNlLCAvLyB0cnVlIGJ5IGRlZmF1bHRcblx0XHRcdHNlbGVjdGVkOiBvcHRpb25zLnNlbGVjdGVkID09PSB0cnVlIC8vIGZhbHNlIGJ5IGRlZmF1bHRcblx0XHR9KTtcblxuXHRcdC8vIHNwZWNpYWxcblx0XHRpZiAodXNlQ2FuVkcpIHtcblx0XHRcdG9wdGlvbnMuYW5pbWF0aW9uID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gcmVnaXN0ZXIgZXZlbnQgbGlzdGVuZXJzXG5cdFx0ZXZlbnRzID0gb3B0aW9ucy5ldmVudHM7XG5cdFx0Zm9yIChldmVudFR5cGUgaW4gZXZlbnRzKSB7XG5cdFx0XHRhZGRFdmVudChzZXJpZXMsIGV2ZW50VHlwZSwgZXZlbnRzW2V2ZW50VHlwZV0pO1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHQoZXZlbnRzICYmIGV2ZW50cy5jbGljaykgfHxcblx0XHRcdChvcHRpb25zLnBvaW50ICYmIG9wdGlvbnMucG9pbnQuZXZlbnRzICYmIG9wdGlvbnMucG9pbnQuZXZlbnRzLmNsaWNrKSB8fFxuXHRcdFx0b3B0aW9ucy5hbGxvd1BvaW50U2VsZWN0XG5cdFx0KSB7XG5cdFx0XHRjaGFydC5ydW5UcmFja2VyQ2xpY2sgPSB0cnVlO1xuXHRcdH1cblxuXHRcdHNlcmllcy5nZXRDb2xvcigpO1xuXHRcdHNlcmllcy5nZXRTeW1ib2woKTtcblxuXHRcdC8vIFNldCB0aGUgZGF0YVxuXHRcdGVhY2goc2VyaWVzLnBhcmFsbGVsQXJyYXlzLCBmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRzZXJpZXNba2V5ICsgJ0RhdGEnXSA9IFtdO1xuXHRcdH0pO1xuXHRcdHNlcmllcy5zZXREYXRhKG9wdGlvbnMuZGF0YSwgZmFsc2UpO1xuXG5cdFx0Ly8gTWFyayBjYXJ0ZXNpYW5cblx0XHRpZiAoc2VyaWVzLmlzQ2FydGVzaWFuKSB7XG5cdFx0XHRjaGFydC5oYXNDYXJ0ZXNpYW5TZXJpZXMgPSB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIFJlZ2lzdGVyIGl0IGluIHRoZSBjaGFydFxuXHRcdGNoYXJ0U2VyaWVzLnB1c2goc2VyaWVzKTtcblx0XHRzZXJpZXMuX2kgPSBjaGFydFNlcmllcy5sZW5ndGggLSAxO1xuXG5cdFx0Ly8gU29ydCBzZXJpZXMgYWNjb3JkaW5nIHRvIGluZGV4IG9wdGlvbiAoIzI0OCwgIzExMjMsICMyNDU2KVxuXHRcdHN0YWJsZVNvcnQoY2hhcnRTZXJpZXMsIHNvcnRCeUluZGV4KTtcblx0XHRpZiAodGhpcy55QXhpcykge1xuXHRcdFx0c3RhYmxlU29ydCh0aGlzLnlBeGlzLnNlcmllcywgc29ydEJ5SW5kZXgpO1xuXHRcdH1cblxuXHRcdGVhY2goY2hhcnRTZXJpZXMsIGZ1bmN0aW9uIChzZXJpZXMsIGkpIHtcblx0XHRcdHNlcmllcy5pbmRleCA9IGk7XG5cdFx0XHRzZXJpZXMubmFtZSA9IHNlcmllcy5uYW1lIHx8ICdTZXJpZXMgJyArIChpICsgMSk7XG5cdFx0fSk7XG5cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSB4QXhpcyBhbmQgeUF4aXMgcHJvcGVydGllcyBvZiBjYXJ0ZXNpYW4gc2VyaWVzLCBhbmQgcmVnaXN0ZXIgdGhlIHNlcmllc1xuXHQgKiBpbiB0aGUgYXhpcy5zZXJpZXMgYXJyYXlcblx0ICovXG5cdGJpbmRBeGVzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdGF4aXNPcHRpb25zO1xuXG5cdFx0ZWFjaChzZXJpZXMuYXhpc1R5cGVzIHx8IFtdLCBmdW5jdGlvbiAoQVhJUykgeyAvLyByZXBlYXQgZm9yIHhBeGlzIGFuZCB5QXhpc1xuXG5cdFx0XHRlYWNoKGNoYXJ0W0FYSVNdLCBmdW5jdGlvbiAoYXhpcykgeyAvLyBsb29wIHRocm91Z2ggdGhlIGNoYXJ0J3MgYXhpcyBvYmplY3RzXG5cdFx0XHRcdGF4aXNPcHRpb25zID0gYXhpcy5vcHRpb25zO1xuXG5cdFx0XHRcdC8vIGFwcGx5IGlmIHRoZSBzZXJpZXMgeEF4aXMgb3IgeUF4aXMgb3B0aW9uIG1hdGhjaGVzIHRoZSBudW1iZXIgb2YgdGhlXG5cdFx0XHRcdC8vIGF4aXMsIG9yIGlmIHVuZGVmaW5lZCwgdXNlIHRoZSBmaXJzdCBheGlzXG5cdFx0XHRcdGlmICgoc2VyaWVzT3B0aW9uc1tBWElTXSA9PT0gYXhpc09wdGlvbnMuaW5kZXgpIHx8XG5cdFx0XHRcdFx0XHQoc2VyaWVzT3B0aW9uc1tBWElTXSAhPT0gVU5ERUZJTkVEICYmIHNlcmllc09wdGlvbnNbQVhJU10gPT09IGF4aXNPcHRpb25zLmlkKSB8fFxuXHRcdFx0XHRcdFx0KHNlcmllc09wdGlvbnNbQVhJU10gPT09IFVOREVGSU5FRCAmJiBheGlzT3B0aW9ucy5pbmRleCA9PT0gMCkpIHtcblxuXHRcdFx0XHRcdC8vIHJlZ2lzdGVyIHRoaXMgc2VyaWVzIGluIHRoZSBheGlzLnNlcmllcyBsb29rdXBcblx0XHRcdFx0XHRheGlzLnNlcmllcy5wdXNoKHNlcmllcyk7XG5cblx0XHRcdFx0XHQvLyBzZXQgdGhpcyBzZXJpZXMueEF4aXMgb3Igc2VyaWVzLnlBeGlzIHJlZmVyZW5jZVxuXHRcdFx0XHRcdHNlcmllc1tBWElTXSA9IGF4aXM7XG5cblx0XHRcdFx0XHQvLyBtYXJrIGRpcnR5IGZvciByZWRyYXdcblx0XHRcdFx0XHRheGlzLmlzRGlydHkgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0Ly8gVGhlIHNlcmllcyBuZWVkcyBhbiBYIGFuZCBhbiBZIGF4aXNcblx0XHRcdGlmICghc2VyaWVzW0FYSVNdICYmIHNlcmllcy5vcHRpb25hbEF4aXMgIT09IEFYSVMpIHtcblx0XHRcdFx0ZXJyb3IoMTgsIHRydWUpO1xuXHRcdFx0fVxuXG5cdFx0fSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEZvciBzaW1wbGUgc2VyaWVzIHR5cGVzIGxpa2UgbGluZSBhbmQgY29sdW1uLCB0aGUgZGF0YSB2YWx1ZXMgYXJlIGhlbGQgaW4gYXJyYXlzIGxpa2Vcblx0ICogeERhdGEgYW5kIHlEYXRhIGZvciBxdWljayBsb29rdXAgdG8gZmluZCBleHRyZW1lcyBhbmQgbW9yZS4gRm9yIG11bHRpZGltZW5zaW9uYWwgc2VyaWVzXG5cdCAqIGxpa2UgYnViYmxlIGFuZCBtYXAsIHRoaXMgY2FuIGJlIGV4dGVuZGVkIHdpdGggYXJyYXlzIGxpa2UgekRhdGEgYW5kIHZhbHVlRGF0YSBieVxuXHQgKiBhZGRpbmcgdG8gdGhlIHNlcmllcy5wYXJhbGxlbEFycmF5cyBhcnJheS5cblx0ICovXG5cdHVwZGF0ZVBhcmFsbGVsQXJyYXlzOiBmdW5jdGlvbiAocG9pbnQsIGkpIHtcblx0XHR2YXIgc2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0YXJncyA9IGFyZ3VtZW50cyxcblx0XHRcdGZuID0gdHlwZW9mIGkgPT09ICdudW1iZXInID9cblx0XHRcdFx0IC8vIEluc2VydCB0aGUgdmFsdWUgaW4gdGhlIGdpdmVuIHBvc2l0aW9uXG5cdFx0XHRcdGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0XHR2YXIgdmFsID0ga2V5ID09PSAneScgJiYgc2VyaWVzLnRvWURhdGEgPyBzZXJpZXMudG9ZRGF0YShwb2ludCkgOiBwb2ludFtrZXldO1xuXHRcdFx0XHRcdHNlcmllc1trZXkgKyAnRGF0YSddW2ldID0gdmFsO1xuXHRcdFx0XHR9IDpcblx0XHRcdFx0Ly8gQXBwbHkgdGhlIG1ldGhvZCBzcGVjaWZpZWQgaW4gaSB3aXRoIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzIGFzIGFyZ3VtZW50c1xuXHRcdFx0XHRmdW5jdGlvbiAoa2V5KSB7XG5cdFx0XHRcdFx0QXJyYXkucHJvdG90eXBlW2ldLmFwcGx5KHNlcmllc1trZXkgKyAnRGF0YSddLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAyKSk7XG5cdFx0XHRcdH07XG5cblx0XHRlYWNoKHNlcmllcy5wYXJhbGxlbEFycmF5cywgZm4pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gYW4gYXV0byBpbmNyZW1lbnRlZCB4IHZhbHVlIGJhc2VkIG9uIHRoZSBwb2ludFN0YXJ0IGFuZCBwb2ludEludGVydmFsIG9wdGlvbnMuXG5cdCAqIFRoaXMgaXMgb25seSB1c2VkIGlmIGFuIHggdmFsdWUgaXMgbm90IGdpdmVuIGZvciB0aGUgcG9pbnQgdGhhdCBjYWxscyBhdXRvSW5jcmVtZW50LlxuXHQgKi9cblx0YXV0b0luY3JlbWVudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0eEluY3JlbWVudCA9IHNlcmllcy54SW5jcmVtZW50O1xuXG5cdFx0eEluY3JlbWVudCA9IHBpY2soeEluY3JlbWVudCwgb3B0aW9ucy5wb2ludFN0YXJ0LCAwKTtcblxuXHRcdHNlcmllcy5wb2ludEludGVydmFsID0gcGljayhzZXJpZXMucG9pbnRJbnRlcnZhbCwgb3B0aW9ucy5wb2ludEludGVydmFsLCAxKTtcblxuXHRcdHNlcmllcy54SW5jcmVtZW50ID0geEluY3JlbWVudCArIHNlcmllcy5wb2ludEludGVydmFsO1xuXHRcdHJldHVybiB4SW5jcmVtZW50O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEaXZpZGUgdGhlIHNlcmllcyBkYXRhIGludG8gc2VnbWVudHMgZGl2aWRlZCBieSBudWxsIHZhbHVlcy5cblx0ICovXG5cdGdldFNlZ21lbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRsYXN0TnVsbCA9IC0xLFxuXHRcdFx0c2VnbWVudHMgPSBbXSxcblx0XHRcdGksXG5cdFx0XHRwb2ludHMgPSBzZXJpZXMucG9pbnRzLFxuXHRcdFx0cG9pbnRzTGVuZ3RoID0gcG9pbnRzLmxlbmd0aDtcblxuXHRcdGlmIChwb2ludHNMZW5ndGgpIHsgLy8gbm8gYWN0aW9uIHJlcXVpcmVkIGZvciBbXVxuXG5cdFx0XHQvLyBpZiBjb25uZWN0IG51bGxzLCBqdXN0IHJlbW92ZSBudWxsIHBvaW50c1xuXHRcdFx0aWYgKHNlcmllcy5vcHRpb25zLmNvbm5lY3ROdWxscykge1xuXHRcdFx0XHRpID0gcG9pbnRzTGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdFx0aWYgKHBvaW50c1tpXS55ID09PSBudWxsKSB7XG5cdFx0XHRcdFx0XHRwb2ludHMuc3BsaWNlKGksIDEpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAocG9pbnRzLmxlbmd0aCkge1xuXHRcdFx0XHRcdHNlZ21lbnRzID0gW3BvaW50c107XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gZWxzZSwgc3BsaXQgb24gbnVsbCBwb2ludHNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVhY2gocG9pbnRzLCBmdW5jdGlvbiAocG9pbnQsIGkpIHtcblx0XHRcdFx0XHRpZiAocG9pbnQueSA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdFx0aWYgKGkgPiBsYXN0TnVsbCArIDEpIHtcblx0XHRcdFx0XHRcdFx0c2VnbWVudHMucHVzaChwb2ludHMuc2xpY2UobGFzdE51bGwgKyAxLCBpKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRsYXN0TnVsbCA9IGk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChpID09PSBwb2ludHNMZW5ndGggLSAxKSB7IC8vIGxhc3QgdmFsdWVcblx0XHRcdFx0XHRcdHNlZ21lbnRzLnB1c2gocG9pbnRzLnNsaWNlKGxhc3ROdWxsICsgMSwgaSArIDEpKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIHJlZ2lzdGVyIGl0XG5cdFx0c2VyaWVzLnNlZ21lbnRzID0gc2VnbWVudHM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgc2VyaWVzIG9wdGlvbnMgYnkgbWVyZ2luZyBmcm9tIHRoZSBvcHRpb25zIHRyZWVcblx0ICogQHBhcmFtIHtPYmplY3R9IGl0ZW1PcHRpb25zXG5cdCAqL1xuXHRzZXRPcHRpb25zOiBmdW5jdGlvbiAoaXRlbU9wdGlvbnMpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0Y2hhcnRPcHRpb25zID0gY2hhcnQub3B0aW9ucyxcblx0XHRcdHBsb3RPcHRpb25zID0gY2hhcnRPcHRpb25zLnBsb3RPcHRpb25zLFxuXHRcdFx0dXNlck9wdGlvbnMgPSBjaGFydC51c2VyT3B0aW9ucyB8fCB7fSxcblx0XHRcdHVzZXJQbG90T3B0aW9ucyA9IHVzZXJPcHRpb25zLnBsb3RPcHRpb25zIHx8IHt9LFxuXHRcdFx0dHlwZU9wdGlvbnMgPSBwbG90T3B0aW9uc1t0aGlzLnR5cGVdLFxuXHRcdFx0b3B0aW9ucztcblxuXHRcdHRoaXMudXNlck9wdGlvbnMgPSBpdGVtT3B0aW9ucztcblxuXHRcdG9wdGlvbnMgPSBtZXJnZShcblx0XHRcdHR5cGVPcHRpb25zLFxuXHRcdFx0cGxvdE9wdGlvbnMuc2VyaWVzLFxuXHRcdFx0aXRlbU9wdGlvbnNcblx0XHQpO1xuXG5cdFx0Ly8gVGhlIHRvb2x0aXAgb3B0aW9ucyBhcmUgbWVyZ2VkIGJldHdlZW4gZ2xvYmFsIGFuZCBzZXJpZXMgc3BlY2lmaWMgb3B0aW9uc1xuXHRcdHRoaXMudG9vbHRpcE9wdGlvbnMgPSBtZXJnZShcblx0XHRcdGRlZmF1bHRPcHRpb25zLnRvb2x0aXAsXG5cdFx0XHRkZWZhdWx0T3B0aW9ucy5wbG90T3B0aW9uc1t0aGlzLnR5cGVdLnRvb2x0aXAsXG5cdFx0XHR1c2VyT3B0aW9ucy50b29sdGlwLFxuXHRcdFx0dXNlclBsb3RPcHRpb25zLnNlcmllcyAmJiB1c2VyUGxvdE9wdGlvbnMuc2VyaWVzLnRvb2x0aXAsXG5cdFx0XHR1c2VyUGxvdE9wdGlvbnNbdGhpcy50eXBlXSAmJiB1c2VyUGxvdE9wdGlvbnNbdGhpcy50eXBlXS50b29sdGlwLFxuXHRcdFx0aXRlbU9wdGlvbnMudG9vbHRpcFxuXHRcdCk7XG5cblx0XHQvLyBEZWxldGUgbWFya2VyIG9iamVjdCBpZiBub3QgYWxsb3dlZCAoIzExMjUpXG5cdFx0aWYgKHR5cGVPcHRpb25zLm1hcmtlciA9PT0gbnVsbCkge1xuXHRcdFx0ZGVsZXRlIG9wdGlvbnMubWFya2VyO1xuXHRcdH1cblxuXHRcdHJldHVybiBvcHRpb25zO1xuXG5cdH0sXG5cblx0Z2V0Q3ljbGljOiBmdW5jdGlvbiAocHJvcCwgdmFsdWUsIGRlZmF1bHRzKSB7XG5cdFx0dmFyIGksXG5cdFx0XHR1c2VyT3B0aW9ucyA9IHRoaXMudXNlck9wdGlvbnMsXG5cdFx0XHRpbmRleE5hbWUgPSAnXycgKyBwcm9wICsgJ0luZGV4Jyxcblx0XHRcdGNvdW50ZXJOYW1lID0gcHJvcCArICdDb3VudGVyJztcblxuXHRcdGlmICghdmFsdWUpIHtcblx0XHRcdGlmIChkZWZpbmVkKHVzZXJPcHRpb25zW2luZGV4TmFtZV0pKSB7IC8vIGFmdGVyIFNlcmllcy51cGRhdGUoKVxuXHRcdFx0XHRpID0gdXNlck9wdGlvbnNbaW5kZXhOYW1lXTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHVzZXJPcHRpb25zW2luZGV4TmFtZV0gPSBpID0gdGhpcy5jaGFydFtjb3VudGVyTmFtZV0gJSBkZWZhdWx0cy5sZW5ndGg7XG5cdFx0XHRcdHRoaXMuY2hhcnRbY291bnRlck5hbWVdICs9IDE7XG5cdFx0XHR9XG5cdFx0XHR2YWx1ZSA9IGRlZmF1bHRzW2ldO1xuXHRcdH1cblx0XHR0aGlzW3Byb3BdID0gdmFsdWU7XG5cdH0sXG5cblx0LyoqXG5cdCAqIEdldCB0aGUgc2VyaWVzJyBjb2xvclxuXHQgKi9cblx0Z2V0Q29sb3I6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAoIXRoaXMub3B0aW9ucy5jb2xvckJ5UG9pbnQpIHtcblx0XHRcdHRoaXMuZ2V0Q3ljbGljKCdjb2xvcicsIHRoaXMub3B0aW9ucy5jb2xvciB8fCBkZWZhdWx0UGxvdE9wdGlvbnNbdGhpcy50eXBlXS5jb2xvciwgdGhpcy5jaGFydC5vcHRpb25zLmNvbG9ycyk7XG5cdFx0fVxuXHR9LFxuXHQvKipcblx0ICogR2V0IHRoZSBzZXJpZXMnIHN5bWJvbFxuXHQgKi9cblx0Z2V0U3ltYm9sOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllc01hcmtlck9wdGlvbiA9IHRoaXMub3B0aW9ucy5tYXJrZXI7XG5cblx0XHR0aGlzLmdldEN5Y2xpYygnc3ltYm9sJywgc2VyaWVzTWFya2VyT3B0aW9uLnN5bWJvbCwgdGhpcy5jaGFydC5vcHRpb25zLnN5bWJvbHMpO1xuXG5cdFx0Ly8gZG9uJ3Qgc3Vic3RyYWN0IHJhZGl1cyBpbiBpbWFnZSBzeW1ib2xzICgjNjA0KVxuXHRcdGlmICgvXnVybC8udGVzdCh0aGlzLnN5bWJvbCkpIHtcblx0XHRcdHNlcmllc01hcmtlck9wdGlvbi5yYWRpdXMgPSAwO1xuXHRcdH1cblx0fSxcblxuXHRkcmF3TGVnZW5kU3ltYm9sOiBMZWdlbmRTeW1ib2xNaXhpbi5kcmF3TGluZU1hcmtlcixcblxuXHQvKipcblx0ICogUmVwbGFjZSB0aGUgc2VyaWVzIGRhdGEgd2l0aCBhIG5ldyBzZXQgb2YgZGF0YVxuXHQgKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuXHQgKiBAcGFyYW0ge09iamVjdH0gcmVkcmF3XG5cdCAqL1xuXHRzZXREYXRhOiBmdW5jdGlvbiAoZGF0YSwgcmVkcmF3LCBhbmltYXRpb24sIHVwZGF0ZVBvaW50cykge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b2xkRGF0YSA9IHNlcmllcy5wb2ludHMsXG5cdFx0XHRvbGREYXRhTGVuZ3RoID0gKG9sZERhdGEgJiYgb2xkRGF0YS5sZW5ndGgpIHx8IDAsXG5cdFx0XHRkYXRhTGVuZ3RoLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRmaXJzdFBvaW50ID0gbnVsbCxcblx0XHRcdHhBeGlzID0gc2VyaWVzLnhBeGlzLFxuXHRcdFx0aGFzQ2F0ZWdvcmllcyA9IHhBeGlzICYmICEheEF4aXMuY2F0ZWdvcmllcyxcblx0XHRcdHRvb2x0aXBQb2ludHMgPSBzZXJpZXMudG9vbHRpcFBvaW50cyxcblx0XHRcdGksXG5cdFx0XHR0dXJib1RocmVzaG9sZCA9IG9wdGlvbnMudHVyYm9UaHJlc2hvbGQsXG5cdFx0XHRwdCxcblx0XHRcdHhEYXRhID0gdGhpcy54RGF0YSxcblx0XHRcdHlEYXRhID0gdGhpcy55RGF0YSxcblx0XHRcdHBvaW50QXJyYXlNYXAgPSBzZXJpZXMucG9pbnRBcnJheU1hcCxcblx0XHRcdHZhbHVlQ291bnQgPSBwb2ludEFycmF5TWFwICYmIHBvaW50QXJyYXlNYXAubGVuZ3RoO1xuXG5cdFx0ZGF0YSA9IGRhdGEgfHwgW107XG5cdFx0ZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoO1xuXHRcdHJlZHJhdyA9IHBpY2socmVkcmF3LCB0cnVlKTtcblxuXHRcdC8vIElmIHRoZSBwb2ludCBjb3VudCBpcyB0aGUgc2FtZSBhcyBpcyB3YXMsIGp1c3QgcnVuIFBvaW50LnVwZGF0ZSB3aGljaCBpc1xuXHRcdC8vIGNoZWFwZXIsIGFsbG93cyBhbmltYXRpb24sIGFuZCBrZWVwcyByZWZlcmVuY2VzIHRvIHBvaW50cy5cblx0XHRpZiAodXBkYXRlUG9pbnRzICE9PSBmYWxzZSAmJiBkYXRhTGVuZ3RoICYmIG9sZERhdGFMZW5ndGggPT09IGRhdGFMZW5ndGggJiYgIXNlcmllcy5jcm9wcGVkICYmICFzZXJpZXMuaGFzR3JvdXBlZERhdGEpIHtcblx0XHRcdGVhY2goZGF0YSwgZnVuY3Rpb24gKHBvaW50LCBpKSB7XG5cdFx0XHRcdG9sZERhdGFbaV0udXBkYXRlKHBvaW50LCBmYWxzZSwgbnVsbCwgZmFsc2UpO1xuXHRcdFx0fSk7XG5cblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBSZXNldCBwcm9wZXJ0aWVzXG5cdFx0XHRzZXJpZXMueEluY3JlbWVudCA9IG51bGw7XG5cdFx0XHRzZXJpZXMucG9pbnRSYW5nZSA9IGhhc0NhdGVnb3JpZXMgPyAxIDogb3B0aW9ucy5wb2ludFJhbmdlO1xuXG5cdFx0XHRzZXJpZXMuY29sb3JDb3VudGVyID0gMDsgLy8gZm9yIHNlcmllcyB3aXRoIGNvbG9yQnlQb2ludCAoIzE1NDcpXG5cdFx0XHRcblx0XHRcdC8vIFVwZGF0ZSBwYXJhbGxlbCBhcnJheXNcblx0XHRcdGVhY2godGhpcy5wYXJhbGxlbEFycmF5cywgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0XHRzZXJpZXNba2V5ICsgJ0RhdGEnXS5sZW5ndGggPSAwO1xuXHRcdFx0fSk7XG5cblx0XHRcdC8vIEluIHR1cmJvIG1vZGUsIG9ubHkgb25lLSBvciB0d29kaW1lbnNpb25hbCBhcnJheXMgb2YgbnVtYmVycyBhcmUgYWxsb3dlZC4gVGhlXG5cdFx0XHQvLyBmaXJzdCB2YWx1ZSBpcyB0ZXN0ZWQsIGFuZCB3ZSBhc3N1bWUgdGhhdCBhbGwgdGhlIHJlc3QgYXJlIGRlZmluZWQgdGhlIHNhbWVcblx0XHRcdC8vIHdheS4gQWx0aG91Z2ggdGhlICdmb3InIGxvb3BzIGFyZSBzaW1pbGFyLCB0aGV5IGFyZSByZXBlYXRlZCBpbnNpZGUgZWFjaFxuXHRcdFx0Ly8gaWYtZWxzZSBjb25kaXRpb25hbCBmb3IgbWF4IHBlcmZvcm1hbmNlLlxuXHRcdFx0aWYgKHR1cmJvVGhyZXNob2xkICYmIGRhdGFMZW5ndGggPiB0dXJib1RocmVzaG9sZCkge1xuXG5cdFx0XHRcdC8vIGZpbmQgdGhlIGZpcnN0IG5vbi1udWxsIHBvaW50XG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHR3aGlsZSAoZmlyc3RQb2ludCA9PT0gbnVsbCAmJiBpIDwgZGF0YUxlbmd0aCkge1xuXHRcdFx0XHRcdGZpcnN0UG9pbnQgPSBkYXRhW2ldO1xuXHRcdFx0XHRcdGkrKztcblx0XHRcdFx0fVxuXG5cblx0XHRcdFx0aWYgKGlzTnVtYmVyKGZpcnN0UG9pbnQpKSB7IC8vIGFzc3VtZSBhbGwgcG9pbnRzIGFyZSBudW1iZXJzXG5cdFx0XHRcdFx0dmFyIHggPSBwaWNrKG9wdGlvbnMucG9pbnRTdGFydCwgMCksXG5cdFx0XHRcdFx0XHRwb2ludEludGVydmFsID0gcGljayhvcHRpb25zLnBvaW50SW50ZXJ2YWwsIDEpO1xuXG5cdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGRhdGFMZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0eERhdGFbaV0gPSB4O1xuXHRcdFx0XHRcdFx0eURhdGFbaV0gPSBkYXRhW2ldO1xuXHRcdFx0XHRcdFx0eCArPSBwb2ludEludGVydmFsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRzZXJpZXMueEluY3JlbWVudCA9IHg7XG5cdFx0XHRcdH0gZWxzZSBpZiAoaXNBcnJheShmaXJzdFBvaW50KSkgeyAvLyBhc3N1bWUgYWxsIHBvaW50cyBhcmUgYXJyYXlzXG5cdFx0XHRcdFx0aWYgKHZhbHVlQ291bnQpIHsgLy8gW3gsIGxvdywgaGlnaF0gb3IgW3gsIG8sIGgsIGwsIGNdXG5cdFx0XHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdHB0ID0gZGF0YVtpXTtcblx0XHRcdFx0XHRcdFx0eERhdGFbaV0gPSBwdFswXTtcblx0XHRcdFx0XHRcdFx0eURhdGFbaV0gPSBwdC5zbGljZSgxLCB2YWx1ZUNvdW50ICsgMSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHsgLy8gW3gsIHldXG5cdFx0XHRcdFx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRcdHB0ID0gZGF0YVtpXTtcblx0XHRcdFx0XHRcdFx0eERhdGFbaV0gPSBwdFswXTtcblx0XHRcdFx0XHRcdFx0eURhdGFbaV0gPSBwdFsxXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXJyb3IoMTIpOyAvLyBIaWdoY2hhcnRzIGV4cGVjdHMgY29uZmlncyB0byBiZSBudW1iZXJzIG9yIGFycmF5cyBpbiB0dXJibyBtb2RlXG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRpZiAoZGF0YVtpXSAhPT0gVU5ERUZJTkVEKSB7IC8vIHN0cmF5IGNvbW1hcyBpbiBvbGRJRVxuXHRcdFx0XHRcdFx0cHQgPSB7IHNlcmllczogc2VyaWVzIH07XG5cdFx0XHRcdFx0XHRzZXJpZXMucG9pbnRDbGFzcy5wcm90b3R5cGUuYXBwbHlPcHRpb25zLmFwcGx5KHB0LCBbZGF0YVtpXV0pO1xuXHRcdFx0XHRcdFx0c2VyaWVzLnVwZGF0ZVBhcmFsbGVsQXJyYXlzKHB0LCBpKTtcblx0XHRcdFx0XHRcdGlmIChoYXNDYXRlZ29yaWVzICYmIHB0Lm5hbWUpIHtcblx0XHRcdFx0XHRcdFx0eEF4aXMubmFtZXNbcHQueF0gPSBwdC5uYW1lOyAvLyAjMjA0NlxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBGb3JnZXR0aW5nIHRvIGNhc3Qgc3RyaW5ncyB0byBudW1iZXJzIGlzIGEgY29tbW9uIGNhdmVhdCB3aGVuIGhhbmRsaW5nIENTViBvciBKU09OXG5cdFx0XHRpZiAoaXNTdHJpbmcoeURhdGFbMF0pKSB7XG5cdFx0XHRcdGVycm9yKDE0LCB0cnVlKTtcblx0XHRcdH1cblxuXHRcdFx0c2VyaWVzLmRhdGEgPSBbXTtcblx0XHRcdHNlcmllcy5vcHRpb25zLmRhdGEgPSBkYXRhO1xuXHRcdFx0Ly9zZXJpZXMuekRhdGEgPSB6RGF0YTtcblxuXHRcdFx0Ly8gZGVzdHJveSBvbGQgcG9pbnRzXG5cdFx0XHRpID0gb2xkRGF0YUxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0aWYgKG9sZERhdGFbaV0gJiYgb2xkRGF0YVtpXS5kZXN0cm95KSB7XG5cdFx0XHRcdFx0b2xkRGF0YVtpXS5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICh0b29sdGlwUG9pbnRzKSB7IC8vICMyNTk0XG5cdFx0XHRcdHRvb2x0aXBQb2ludHMubGVuZ3RoID0gMDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcmVzZXQgbWluUmFuZ2UgKCM4NzgpXG5cdFx0XHRpZiAoeEF4aXMpIHtcblx0XHRcdFx0eEF4aXMubWluUmFuZ2UgPSB4QXhpcy51c2VyTWluUmFuZ2U7XG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlZHJhd1xuXHRcdFx0c2VyaWVzLmlzRGlydHkgPSBzZXJpZXMuaXNEaXJ0eURhdGEgPSBjaGFydC5pc0RpcnR5Qm94ID0gdHJ1ZTtcblx0XHRcdGFuaW1hdGlvbiA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChyZWRyYXcpIHtcblx0XHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUHJvY2VzcyB0aGUgZGF0YSBieSBjcm9wcGluZyBhd2F5IHVudXNlZCBkYXRhIHBvaW50cyBpZiB0aGUgc2VyaWVzIGlzIGxvbmdlclxuXHQgKiB0aGFuIHRoZSBjcm9wIHRocmVzaG9sZC4gVGhpcyBzYXZlcyBjb21wdXRpbmcgdGltZSBmb3IgbGFnZSBzZXJpZXMuXG5cdCAqL1xuXHRwcm9jZXNzRGF0YTogZnVuY3Rpb24gKGZvcmNlKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRwcm9jZXNzZWRYRGF0YSA9IHNlcmllcy54RGF0YSwgLy8gY29waWVkIGR1cmluZyBzbGljZSBvcGVyYXRpb24gYmVsb3dcblx0XHRcdHByb2Nlc3NlZFlEYXRhID0gc2VyaWVzLnlEYXRhLFxuXHRcdFx0ZGF0YUxlbmd0aCA9IHByb2Nlc3NlZFhEYXRhLmxlbmd0aCxcblx0XHRcdGNyb3BwZWREYXRhLFxuXHRcdFx0Y3JvcFN0YXJ0ID0gMCxcblx0XHRcdGNyb3BwZWQsXG5cdFx0XHRkaXN0YW5jZSxcblx0XHRcdGNsb3Nlc3RQb2ludFJhbmdlLFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHRpLCAvLyBsb29wIHZhcmlhYmxlXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRjcm9wVGhyZXNob2xkID0gb3B0aW9ucy5jcm9wVGhyZXNob2xkLFxuXHRcdFx0YWN0aXZlUG9pbnRDb3VudCA9IDAsXG5cdFx0XHRpc0NhcnRlc2lhbiA9IHNlcmllcy5pc0NhcnRlc2lhbixcblx0XHRcdHhFeHRyZW1lcyxcblx0XHRcdG1pbixcblx0XHRcdG1heDtcblxuXHRcdC8vIElmIHRoZSBzZXJpZXMgZGF0YSBvciBheGVzIGhhdmVuJ3QgY2hhbmdlZCwgZG9uJ3QgZ28gdGhyb3VnaCB0aGlzLiBSZXR1cm4gZmFsc2UgdG8gcGFzc1xuXHRcdC8vIHRoZSBtZXNzYWdlIG9uIHRvIG92ZXJyaWRlIG1ldGhvZHMgbGlrZSBpbiBkYXRhIGdyb3VwaW5nLlxuXHRcdGlmIChpc0NhcnRlc2lhbiAmJiAhc2VyaWVzLmlzRGlydHkgJiYgIXhBeGlzLmlzRGlydHkgJiYgIXNlcmllcy55QXhpcy5pc0RpcnR5ICYmICFmb3JjZSkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmICh4QXhpcykge1xuXHRcdFx0eEV4dHJlbWVzID0geEF4aXMuZ2V0RXh0cmVtZXMoKTsgLy8gY29ycmVjdGVkIGZvciBsb2cgYXhpcyAoIzMwNTMpXG5cdFx0XHRtaW4gPSB4RXh0cmVtZXMubWluO1xuXHRcdFx0bWF4ID0geEV4dHJlbWVzLm1heDtcblx0XHR9XG5cblx0XHQvLyBvcHRpb25hbGx5IGZpbHRlciBvdXQgcG9pbnRzIG91dHNpZGUgdGhlIHBsb3QgYXJlYVxuXHRcdGlmIChpc0NhcnRlc2lhbiAmJiBzZXJpZXMuc29ydGVkICYmICghY3JvcFRocmVzaG9sZCB8fCBkYXRhTGVuZ3RoID4gY3JvcFRocmVzaG9sZCB8fCBzZXJpZXMuZm9yY2VDcm9wKSkge1xuXHRcdFx0XG5cdFx0XHQvLyBpdCdzIG91dHNpZGUgY3VycmVudCBleHRyZW1lc1xuXHRcdFx0aWYgKHByb2Nlc3NlZFhEYXRhW2RhdGFMZW5ndGggLSAxXSA8IG1pbiB8fCBwcm9jZXNzZWRYRGF0YVswXSA+IG1heCkge1xuXHRcdFx0XHRwcm9jZXNzZWRYRGF0YSA9IFtdO1xuXHRcdFx0XHRwcm9jZXNzZWRZRGF0YSA9IFtdO1xuXG5cdFx0XHQvLyBvbmx5IGNyb3AgaWYgaXQncyBhY3R1YWxseSBzcGlsbGluZyBvdXRcblx0XHRcdH0gZWxzZSBpZiAocHJvY2Vzc2VkWERhdGFbMF0gPCBtaW4gfHwgcHJvY2Vzc2VkWERhdGFbZGF0YUxlbmd0aCAtIDFdID4gbWF4KSB7XG5cdFx0XHRcdGNyb3BwZWREYXRhID0gdGhpcy5jcm9wRGF0YShzZXJpZXMueERhdGEsIHNlcmllcy55RGF0YSwgbWluLCBtYXgpO1xuXHRcdFx0XHRwcm9jZXNzZWRYRGF0YSA9IGNyb3BwZWREYXRhLnhEYXRhO1xuXHRcdFx0XHRwcm9jZXNzZWRZRGF0YSA9IGNyb3BwZWREYXRhLnlEYXRhO1xuXHRcdFx0XHRjcm9wU3RhcnQgPSBjcm9wcGVkRGF0YS5zdGFydDtcblx0XHRcdFx0Y3JvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGFjdGl2ZVBvaW50Q291bnQgPSBwcm9jZXNzZWRYRGF0YS5sZW5ndGg7XG5cdFx0XHR9XG5cdFx0fVxuXG5cblx0XHQvLyBGaW5kIHRoZSBjbG9zZXN0IGRpc3RhbmNlIGJldHdlZW4gcHJvY2Vzc2VkIHBvaW50c1xuXHRcdGZvciAoaSA9IHByb2Nlc3NlZFhEYXRhLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0XHRkaXN0YW5jZSA9IHByb2Nlc3NlZFhEYXRhW2ldIC0gcHJvY2Vzc2VkWERhdGFbaSAtIDFdO1xuXHRcdFx0XG5cdFx0XHRpZiAoIWNyb3BwZWQgJiYgcHJvY2Vzc2VkWERhdGFbaV0gPiBtaW4gJiYgcHJvY2Vzc2VkWERhdGFbaV0gPCBtYXgpIHtcblx0XHRcdFx0YWN0aXZlUG9pbnRDb3VudCsrO1xuXHRcdFx0fVxuXHRcdFx0XG5cdFx0XHRpZiAoZGlzdGFuY2UgPiAwICYmIChjbG9zZXN0UG9pbnRSYW5nZSA9PT0gVU5ERUZJTkVEIHx8IGRpc3RhbmNlIDwgY2xvc2VzdFBvaW50UmFuZ2UpKSB7XG5cdFx0XHRcdGNsb3Nlc3RQb2ludFJhbmdlID0gZGlzdGFuY2U7XG5cblx0XHRcdC8vIFVuc29ydGVkIGRhdGEgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbGluZSB0b29sdGlwLCBhcyB3ZWxsIGFzIGRhdGEgZ3JvdXBpbmcgYW5kXG5cdFx0XHQvLyBuYXZpZ2F0aW9uIGluIFN0b2NrIGNoYXJ0cyAoIzcyNSkgYW5kIHdpZHRoIGNhbGN1bGF0aW9uIG9mIGNvbHVtbnMgKCMxOTAwKVxuXHRcdFx0fSBlbHNlIGlmIChkaXN0YW5jZSA8IDAgJiYgc2VyaWVzLnJlcXVpcmVTb3J0aW5nKSB7XG5cdFx0XHRcdGVycm9yKDE1KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZWNvcmQgdGhlIHByb3BlcnRpZXNcblx0XHRzZXJpZXMuY3JvcHBlZCA9IGNyb3BwZWQ7IC8vIHVuZGVmaW5lZCBvciB0cnVlXG5cdFx0c2VyaWVzLmNyb3BTdGFydCA9IGNyb3BTdGFydDtcblx0XHRzZXJpZXMucHJvY2Vzc2VkWERhdGEgPSBwcm9jZXNzZWRYRGF0YTtcblx0XHRzZXJpZXMucHJvY2Vzc2VkWURhdGEgPSBwcm9jZXNzZWRZRGF0YTtcblx0XHRzZXJpZXMuYWN0aXZlUG9pbnRDb3VudCA9IGFjdGl2ZVBvaW50Q291bnQ7XG5cblx0XHRpZiAob3B0aW9ucy5wb2ludFJhbmdlID09PSBudWxsKSB7IC8vIG51bGwgbWVhbnMgYXV0bywgYXMgZm9yIGNvbHVtbnMsIGNhbmRsZXN0aWNrcyBhbmQgT0hMQ1xuXHRcdFx0c2VyaWVzLnBvaW50UmFuZ2UgPSBjbG9zZXN0UG9pbnRSYW5nZSB8fCAxO1xuXHRcdH1cblx0XHRzZXJpZXMuY2xvc2VzdFBvaW50UmFuZ2UgPSBjbG9zZXN0UG9pbnRSYW5nZTtcblxuXHR9LFxuXG5cdC8qKlxuXHQgKiBJdGVyYXRlIG92ZXIgeERhdGEgYW5kIGNyb3AgdmFsdWVzIGJldHdlZW4gbWluIGFuZCBtYXguIFJldHVybnMgb2JqZWN0IGNvbnRhaW5pbmcgY3JvcCBzdGFydC9lbmRcblx0ICogY3JvcHBlZCB4RGF0YSB3aXRoIGNvcnJlc3BvbmRpbmcgcGFydCBvZiB5RGF0YSwgZGF0YU1pbiBhbmQgZGF0YU1heCB3aXRoaW4gdGhlIGNyb3BwZWQgcmFuZ2Vcblx0ICovXG5cdGNyb3BEYXRhOiBmdW5jdGlvbiAoeERhdGEsIHlEYXRhLCBtaW4sIG1heCkge1xuXHRcdHZhciBkYXRhTGVuZ3RoID0geERhdGEubGVuZ3RoLFxuXHRcdFx0Y3JvcFN0YXJ0ID0gMCxcblx0XHRcdGNyb3BFbmQgPSBkYXRhTGVuZ3RoLFxuXHRcdFx0Y3JvcFNob3VsZGVyID0gcGljayh0aGlzLmNyb3BTaG91bGRlciwgMSksIC8vIGxpbmUtdHlwZSBzZXJpZXMgbmVlZCBvbmUgcG9pbnQgb3V0c2lkZVxuXHRcdFx0aTtcblxuXHRcdC8vIGl0ZXJhdGUgdXAgdG8gZmluZCBzbGljZSBzdGFydFxuXHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh4RGF0YVtpXSA+PSBtaW4pIHtcblx0XHRcdFx0Y3JvcFN0YXJ0ID0gbWF0aE1heCgwLCBpIC0gY3JvcFNob3VsZGVyKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gcHJvY2VlZCB0byBmaW5kIHNsaWNlIGVuZFxuXHRcdGZvciAoOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoeERhdGFbaV0gPiBtYXgpIHtcblx0XHRcdFx0Y3JvcEVuZCA9IGkgKyBjcm9wU2hvdWxkZXI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHR4RGF0YTogeERhdGEuc2xpY2UoY3JvcFN0YXJ0LCBjcm9wRW5kKSxcblx0XHRcdHlEYXRhOiB5RGF0YS5zbGljZShjcm9wU3RhcnQsIGNyb3BFbmQpLFxuXHRcdFx0c3RhcnQ6IGNyb3BTdGFydCxcblx0XHRcdGVuZDogY3JvcEVuZFxuXHRcdH07XG5cdH0sXG5cblxuXHQvKipcblx0ICogR2VuZXJhdGUgdGhlIGRhdGEgcG9pbnQgYWZ0ZXIgdGhlIGRhdGEgaGFzIGJlZW4gcHJvY2Vzc2VkIGJ5IGNyb3BwaW5nIGF3YXlcblx0ICogdW51c2VkIHBvaW50cyBhbmQgb3B0aW9uYWxseSBncm91cGVkIGluIEhpZ2hjaGFydHMgU3RvY2suXG5cdCAqL1xuXHRnZW5lcmF0ZVBvaW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0ZGF0YU9wdGlvbnMgPSBvcHRpb25zLmRhdGEsXG5cdFx0XHRkYXRhID0gc2VyaWVzLmRhdGEsXG5cdFx0XHRkYXRhTGVuZ3RoLFxuXHRcdFx0cHJvY2Vzc2VkWERhdGEgPSBzZXJpZXMucHJvY2Vzc2VkWERhdGEsXG5cdFx0XHRwcm9jZXNzZWRZRGF0YSA9IHNlcmllcy5wcm9jZXNzZWRZRGF0YSxcblx0XHRcdHBvaW50Q2xhc3MgPSBzZXJpZXMucG9pbnRDbGFzcyxcblx0XHRcdHByb2Nlc3NlZERhdGFMZW5ndGggPSBwcm9jZXNzZWRYRGF0YS5sZW5ndGgsXG5cdFx0XHRjcm9wU3RhcnQgPSBzZXJpZXMuY3JvcFN0YXJ0IHx8IDAsXG5cdFx0XHRjdXJzb3IsXG5cdFx0XHRoYXNHcm91cGVkRGF0YSA9IHNlcmllcy5oYXNHcm91cGVkRGF0YSxcblx0XHRcdHBvaW50LFxuXHRcdFx0cG9pbnRzID0gW10sXG5cdFx0XHRpO1xuXG5cdFx0aWYgKCFkYXRhICYmICFoYXNHcm91cGVkRGF0YSkge1xuXHRcdFx0dmFyIGFyciA9IFtdO1xuXHRcdFx0YXJyLmxlbmd0aCA9IGRhdGFPcHRpb25zLmxlbmd0aDtcblx0XHRcdGRhdGEgPSBzZXJpZXMuZGF0YSA9IGFycjtcblx0XHR9XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgcHJvY2Vzc2VkRGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjdXJzb3IgPSBjcm9wU3RhcnQgKyBpO1xuXHRcdFx0aWYgKCFoYXNHcm91cGVkRGF0YSkge1xuXHRcdFx0XHRpZiAoZGF0YVtjdXJzb3JdKSB7XG5cdFx0XHRcdFx0cG9pbnQgPSBkYXRhW2N1cnNvcl07XG5cdFx0XHRcdH0gZWxzZSBpZiAoZGF0YU9wdGlvbnNbY3Vyc29yXSAhPT0gVU5ERUZJTkVEKSB7IC8vICM5NzBcblx0XHRcdFx0XHRkYXRhW2N1cnNvcl0gPSBwb2ludCA9IChuZXcgcG9pbnRDbGFzcygpKS5pbml0KHNlcmllcywgZGF0YU9wdGlvbnNbY3Vyc29yXSwgcHJvY2Vzc2VkWERhdGFbaV0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHBvaW50c1tpXSA9IHBvaW50O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gc3BsYXQgdGhlIHkgZGF0YSBpbiBjYXNlIG9mIG9obGMgZGF0YSBhcnJheVxuXHRcdFx0XHRwb2ludHNbaV0gPSAobmV3IHBvaW50Q2xhc3MoKSkuaW5pdChzZXJpZXMsIFtwcm9jZXNzZWRYRGF0YVtpXV0uY29uY2F0KHNwbGF0KHByb2Nlc3NlZFlEYXRhW2ldKSkpO1xuXHRcdFx0fVxuXHRcdFx0cG9pbnRzW2ldLmluZGV4ID0gY3Vyc29yOyAvLyBGb3IgZmFzdGVyIGFjY2VzcyBpbiBQb2ludC51cGRhdGVcblx0XHR9XG5cblx0XHQvLyBIaWRlIGNyb3BwZWQtYXdheSBwb2ludHMgLSB0aGlzIG9ubHkgcnVucyB3aGVuIHRoZSBudW1iZXIgb2YgcG9pbnRzIGlzIGFib3ZlIGNyb3BUaHJlc2hvbGQsIG9yIHdoZW5cblx0XHQvLyBzd2l0aGNoaW5nIHZpZXcgZnJvbSBub24tZ3JvdXBlZCBkYXRhIHRvIGdyb3VwZWQgZGF0YSAoIzYzNylcblx0XHRpZiAoZGF0YSAmJiAocHJvY2Vzc2VkRGF0YUxlbmd0aCAhPT0gKGRhdGFMZW5ndGggPSBkYXRhLmxlbmd0aCkgfHwgaGFzR3JvdXBlZERhdGEpKSB7XG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChpID09PSBjcm9wU3RhcnQgJiYgIWhhc0dyb3VwZWREYXRhKSB7IC8vIHdoZW4gaGFzIGdyb3VwZWQgZGF0YSwgY2xlYXIgYWxsIHBvaW50c1xuXHRcdFx0XHRcdGkgKz0gcHJvY2Vzc2VkRGF0YUxlbmd0aDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoZGF0YVtpXSkge1xuXHRcdFx0XHRcdGRhdGFbaV0uZGVzdHJveUVsZW1lbnRzKCk7XG5cdFx0XHRcdFx0ZGF0YVtpXS5wbG90WCA9IFVOREVGSU5FRDsgLy8gIzEwMDNcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHNlcmllcy5kYXRhID0gZGF0YTtcblx0XHRzZXJpZXMucG9pbnRzID0gcG9pbnRzO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDYWxjdWxhdGUgWSBleHRyZW1lcyBmb3IgdmlzaWJsZSBkYXRhXG5cdCAqL1xuXHRnZXRFeHRyZW1lczogZnVuY3Rpb24gKHlEYXRhKSB7XG5cdFx0dmFyIHhBeGlzID0gdGhpcy54QXhpcyxcblx0XHRcdHlBeGlzID0gdGhpcy55QXhpcyxcblx0XHRcdHhEYXRhID0gdGhpcy5wcm9jZXNzZWRYRGF0YSxcblx0XHRcdHlEYXRhTGVuZ3RoLFxuXHRcdFx0YWN0aXZlWURhdGEgPSBbXSxcblx0XHRcdGFjdGl2ZUNvdW50ZXIgPSAwLFxuXHRcdFx0eEV4dHJlbWVzID0geEF4aXMuZ2V0RXh0cmVtZXMoKSwgLy8gIzIxMTcsIG5lZWQgdG8gY29tcGVuc2F0ZSBmb3IgbG9nIFggYXhpc1xuXHRcdFx0eE1pbiA9IHhFeHRyZW1lcy5taW4sXG5cdFx0XHR4TWF4ID0geEV4dHJlbWVzLm1heCxcblx0XHRcdHZhbGlkVmFsdWUsXG5cdFx0XHR3aXRoaW5SYW5nZSxcblx0XHRcdGRhdGFNaW4sXG5cdFx0XHRkYXRhTWF4LFxuXHRcdFx0eCxcblx0XHRcdHksXG5cdFx0XHRpLFxuXHRcdFx0ajtcblxuXHRcdHlEYXRhID0geURhdGEgfHwgdGhpcy5zdGFja2VkWURhdGEgfHwgdGhpcy5wcm9jZXNzZWRZRGF0YTtcblx0XHR5RGF0YUxlbmd0aCA9IHlEYXRhLmxlbmd0aDtcblxuXHRcdGZvciAoaSA9IDA7IGkgPCB5RGF0YUxlbmd0aDsgaSsrKSB7XG5cblx0XHRcdHggPSB4RGF0YVtpXTtcblx0XHRcdHkgPSB5RGF0YVtpXTtcblxuXHRcdFx0Ly8gRm9yIHBvaW50cyB3aXRoaW4gdGhlIHZpc2libGUgcmFuZ2UsIGluY2x1ZGluZyB0aGUgZmlyc3QgcG9pbnQgb3V0c2lkZSB0aGVcblx0XHRcdC8vIHZpc2libGUgcmFuZ2UsIGNvbnNpZGVyIHkgZXh0cmVtZXNcblx0XHRcdHZhbGlkVmFsdWUgPSB5ICE9PSBudWxsICYmIHkgIT09IFVOREVGSU5FRCAmJiAoIXlBeGlzLmlzTG9nIHx8ICh5Lmxlbmd0aCB8fCB5ID4gMCkpO1xuXHRcdFx0d2l0aGluUmFuZ2UgPSB0aGlzLmdldEV4dHJlbWVzRnJvbUFsbCB8fCB0aGlzLmNyb3BwZWQgfHwgKCh4RGF0YVtpICsgMV0gfHwgeCkgPj0geE1pbiAmJlxuXHRcdFx0XHQoeERhdGFbaSAtIDFdIHx8IHgpIDw9IHhNYXgpO1xuXG5cdFx0XHRpZiAodmFsaWRWYWx1ZSAmJiB3aXRoaW5SYW5nZSkge1xuXG5cdFx0XHRcdGogPSB5Lmxlbmd0aDtcblx0XHRcdFx0aWYgKGopIHsgLy8gYXJyYXksIGxpa2Ugb2hsYyBvciByYW5nZSBkYXRhXG5cdFx0XHRcdFx0d2hpbGUgKGotLSkge1xuXHRcdFx0XHRcdFx0aWYgKHlbal0gIT09IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0YWN0aXZlWURhdGFbYWN0aXZlQ291bnRlcisrXSA9IHlbal07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGFjdGl2ZVlEYXRhW2FjdGl2ZUNvdW50ZXIrK10gPSB5O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMuZGF0YU1pbiA9IHBpY2soZGF0YU1pbiwgYXJyYXlNaW4oYWN0aXZlWURhdGEpKTtcblx0XHR0aGlzLmRhdGFNYXggPSBwaWNrKGRhdGFNYXgsIGFycmF5TWF4KGFjdGl2ZVlEYXRhKSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFRyYW5zbGF0ZSBkYXRhIHBvaW50cyBmcm9tIHJhdyBkYXRhIHZhbHVlcyB0byBjaGFydCBzcGVjaWZpYyBwb3NpdGlvbmluZyBkYXRhXG5cdCAqIG5lZWRlZCBsYXRlciBpbiBkcmF3UG9pbnRzLCBkcmF3R3JhcGggYW5kIGRyYXdUcmFja2VyLlxuXHQgKi9cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKCF0aGlzLnByb2Nlc3NlZFhEYXRhKSB7IC8vIGhpZGRlbiBzZXJpZXNcblx0XHRcdHRoaXMucHJvY2Vzc0RhdGEoKTtcblx0XHR9XG5cdFx0dGhpcy5nZW5lcmF0ZVBvaW50cygpO1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0c3RhY2tpbmcgPSBvcHRpb25zLnN0YWNraW5nLFxuXHRcdFx0eEF4aXMgPSBzZXJpZXMueEF4aXMsXG5cdFx0XHRjYXRlZ29yaWVzID0geEF4aXMuY2F0ZWdvcmllcyxcblx0XHRcdHlBeGlzID0gc2VyaWVzLnlBeGlzLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdGRhdGFMZW5ndGggPSBwb2ludHMubGVuZ3RoLFxuXHRcdFx0aGFzTW9kaWZ5VmFsdWUgPSAhIXNlcmllcy5tb2RpZnlWYWx1ZSxcblx0XHRcdGksXG5cdFx0XHRwb2ludFBsYWNlbWVudCA9IG9wdGlvbnMucG9pbnRQbGFjZW1lbnQsXG5cdFx0XHRkeW5hbWljYWxseVBsYWNlZCA9IHBvaW50UGxhY2VtZW50ID09PSAnYmV0d2VlbicgfHwgaXNOdW1iZXIocG9pbnRQbGFjZW1lbnQpLFxuXHRcdFx0dGhyZXNob2xkID0gb3B0aW9ucy50aHJlc2hvbGQ7XG5cblx0XHQvLyBUcmFuc2xhdGUgZWFjaCBwb2ludFxuXHRcdGZvciAoaSA9IDA7IGkgPCBkYXRhTGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhciBwb2ludCA9IHBvaW50c1tpXSxcblx0XHRcdFx0eFZhbHVlID0gcG9pbnQueCxcblx0XHRcdFx0eVZhbHVlID0gcG9pbnQueSxcblx0XHRcdFx0eUJvdHRvbSA9IHBvaW50Lmxvdyxcblx0XHRcdFx0c3RhY2sgPSBzdGFja2luZyAmJiB5QXhpcy5zdGFja3NbKHNlcmllcy5uZWdTdGFja3MgJiYgeVZhbHVlIDwgdGhyZXNob2xkID8gJy0nIDogJycpICsgc2VyaWVzLnN0YWNrS2V5XSxcblx0XHRcdFx0cG9pbnRTdGFjayxcblx0XHRcdFx0c3RhY2tWYWx1ZXM7XG5cblx0XHRcdC8vIERpc2NhcmQgZGlzYWxsb3dlZCB5IHZhbHVlcyBmb3IgbG9nIGF4ZXNcblx0XHRcdGlmICh5QXhpcy5pc0xvZyAmJiB5VmFsdWUgPD0gMCkge1xuXHRcdFx0XHRwb2ludC55ID0geVZhbHVlID0gbnVsbDtcblx0XHRcdFx0ZXJyb3IoMTApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBHZXQgdGhlIHBsb3RYIHRyYW5zbGF0aW9uXG5cdFx0XHRwb2ludC5wbG90WCA9IHhBeGlzLnRyYW5zbGF0ZSh4VmFsdWUsIDAsIDAsIDAsIDEsIHBvaW50UGxhY2VtZW50LCB0aGlzLnR5cGUgPT09ICdmbGFncycpOyAvLyBNYXRoLnJvdW5kIGZpeGVzICM1OTFcblxuXG5cdFx0XHQvLyBDYWxjdWxhdGUgdGhlIGJvdHRvbSB5IHZhbHVlIGZvciBzdGFja2VkIHNlcmllc1xuXHRcdFx0aWYgKHN0YWNraW5nICYmIHNlcmllcy52aXNpYmxlICYmIHN0YWNrICYmIHN0YWNrW3hWYWx1ZV0pIHtcblxuXHRcdFx0XHRwb2ludFN0YWNrID0gc3RhY2tbeFZhbHVlXTtcblx0XHRcdFx0c3RhY2tWYWx1ZXMgPSBwb2ludFN0YWNrLnBvaW50c1tzZXJpZXMuaW5kZXggKyAnLCcgKyBpXTtcblx0XHRcdFx0eUJvdHRvbSA9IHN0YWNrVmFsdWVzWzBdO1xuXHRcdFx0XHR5VmFsdWUgPSBzdGFja1ZhbHVlc1sxXTtcblxuXHRcdFx0XHRpZiAoeUJvdHRvbSA9PT0gMCkge1xuXHRcdFx0XHRcdHlCb3R0b20gPSBwaWNrKHRocmVzaG9sZCwgeUF4aXMubWluKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoeUF4aXMuaXNMb2cgJiYgeUJvdHRvbSA8PSAwKSB7IC8vICMxMjAwLCAjMTIzMlxuXHRcdFx0XHRcdHlCb3R0b20gPSBudWxsO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cG9pbnQudG90YWwgPSBwb2ludC5zdGFja1RvdGFsID0gcG9pbnRTdGFjay50b3RhbDtcblx0XHRcdFx0cG9pbnQucGVyY2VudGFnZSA9IHBvaW50U3RhY2sudG90YWwgJiYgKHBvaW50LnkgLyBwb2ludFN0YWNrLnRvdGFsICogMTAwKTtcblx0XHRcdFx0cG9pbnQuc3RhY2tZID0geVZhbHVlO1xuXG5cdFx0XHRcdC8vIFBsYWNlIHRoZSBzdGFjayBsYWJlbFxuXHRcdFx0XHRwb2ludFN0YWNrLnNldE9mZnNldChzZXJpZXMucG9pbnRYT2Zmc2V0IHx8IDAsIHNlcmllcy5iYXJXIHx8IDApO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0cmFuc2xhdGVkIHlCb3R0b20gb3IgcmVtb3ZlIGl0XG5cdFx0XHRwb2ludC55Qm90dG9tID0gZGVmaW5lZCh5Qm90dG9tKSA/XG5cdFx0XHRcdHlBeGlzLnRyYW5zbGF0ZSh5Qm90dG9tLCAwLCAxLCAwLCAxKSA6XG5cdFx0XHRcdG51bGw7XG5cblx0XHRcdC8vIGdlbmVyYWwgaG9vaywgdXNlZCBmb3IgSGlnaHN0b2NrIGNvbXBhcmUgbW9kZVxuXHRcdFx0aWYgKGhhc01vZGlmeVZhbHVlKSB7XG5cdFx0XHRcdHlWYWx1ZSA9IHNlcmllcy5tb2RpZnlWYWx1ZSh5VmFsdWUsIHBvaW50KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IHRoZSB0aGUgcGxvdFkgdmFsdWUsIHJlc2V0IGl0IGZvciByZWRyYXdzXG5cdFx0XHRwb2ludC5wbG90WSA9ICh0eXBlb2YgeVZhbHVlID09PSAnbnVtYmVyJyAmJiB5VmFsdWUgIT09IEluZmluaXR5KSA/XG5cdFx0XHRcdC8vbWF0aFJvdW5kKHlBeGlzLnRyYW5zbGF0ZSh5VmFsdWUsIDAsIDEsIDAsIDEpICogMTApIC8gMTAgOiAvLyBNYXRoLnJvdW5kIGZpeGVzICM1OTFcblx0XHRcdFx0eUF4aXMudHJhbnNsYXRlKHlWYWx1ZSwgMCwgMSwgMCwgMSkgOlxuXHRcdFx0XHRVTkRFRklORUQ7XG5cblx0XHRcdC8vIFNldCBjbGllbnQgcmVsYXRlZCBwb3NpdGlvbnMgZm9yIG1vdXNlIHRyYWNraW5nXG5cdFx0XHRwb2ludC5jbGllbnRYID0gZHluYW1pY2FsbHlQbGFjZWQgPyB4QXhpcy50cmFuc2xhdGUoeFZhbHVlLCAwLCAwLCAwLCAxKSA6IHBvaW50LnBsb3RYOyAvLyAjMTUxNFxuXG5cdFx0XHRwb2ludC5uZWdhdGl2ZSA9IHBvaW50LnkgPCAodGhyZXNob2xkIHx8IDApO1xuXG5cdFx0XHQvLyBzb21lIEFQSSBkYXRhXG5cdFx0XHRwb2ludC5jYXRlZ29yeSA9IGNhdGVnb3JpZXMgJiYgY2F0ZWdvcmllc1twb2ludC54XSAhPT0gVU5ERUZJTkVEID9cblx0XHRcdFx0Y2F0ZWdvcmllc1twb2ludC54XSA6IHBvaW50Lng7XG5cblx0XHR9XG5cblx0XHQvLyBub3cgdGhhdCB3ZSBoYXZlIHRoZSBjcm9wcGVkIGRhdGEsIGJ1aWxkIHRoZSBzZWdtZW50c1xuXHRcdHNlcmllcy5nZXRTZWdtZW50cygpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBbmltYXRlIGluIHRoZSBzZXJpZXNcblx0ICovXG5cdGFuaW1hdGU6IGZ1bmN0aW9uIChpbml0KSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRjbGlwUmVjdCxcblx0XHRcdG1hcmtlckNsaXBSZWN0LFxuXHRcdFx0YW5pbWF0aW9uID0gc2VyaWVzLm9wdGlvbnMuYW5pbWF0aW9uLFxuXHRcdFx0Y2xpcEJveCA9IHNlcmllcy5jbGlwQm94IHx8IGNoYXJ0LmNsaXBCb3gsXG5cdFx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdFx0c2hhcmVkQ2xpcEtleTtcblxuXHRcdC8vIEFuaW1hdGlvbiBvcHRpb24gaXMgc2V0IHRvIHRydWVcblx0XHRpZiAoYW5pbWF0aW9uICYmICFpc09iamVjdChhbmltYXRpb24pKSB7XG5cdFx0XHRhbmltYXRpb24gPSBkZWZhdWx0UGxvdE9wdGlvbnNbc2VyaWVzLnR5cGVdLmFuaW1hdGlvbjtcblx0XHR9XG5cdFx0c2hhcmVkQ2xpcEtleSA9IFsnX3NoYXJlZENsaXAnLCBhbmltYXRpb24uZHVyYXRpb24sIGFuaW1hdGlvbi5lYXNpbmcsIGNsaXBCb3guaGVpZ2h0XS5qb2luKCcsJyk7XG5cblx0XHQvLyBJbml0aWFsaXplIHRoZSBhbmltYXRpb24uIFNldCB1cCB0aGUgY2xpcHBpbmcgcmVjdGFuZ2xlLlxuXHRcdGlmIChpbml0KSB7XG5cblx0XHRcdC8vIElmIGEgY2xpcHBpbmcgcmVjdGFuZ2xlIHdpdGggdGhlIHNhbWUgcHJvcGVydGllcyBpcyBjdXJyZW50bHkgcHJlc2VudCBpbiB0aGUgY2hhcnQsIHVzZSB0aGF0LlxuXHRcdFx0Y2xpcFJlY3QgPSBjaGFydFtzaGFyZWRDbGlwS2V5XTtcblx0XHRcdG1hcmtlckNsaXBSZWN0ID0gY2hhcnRbc2hhcmVkQ2xpcEtleSArICdtJ107XG5cdFx0XHRpZiAoIWNsaXBSZWN0KSB7XG5cdFx0XHRcdGNoYXJ0W3NoYXJlZENsaXBLZXldID0gY2xpcFJlY3QgPSByZW5kZXJlci5jbGlwUmVjdChcblx0XHRcdFx0XHRleHRlbmQoY2xpcEJveCwgeyB3aWR0aDogMCB9KVxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGNoYXJ0W3NoYXJlZENsaXBLZXkgKyAnbSddID0gbWFya2VyQ2xpcFJlY3QgPSByZW5kZXJlci5jbGlwUmVjdChcblx0XHRcdFx0XHQtOTksIC8vIGluY2x1ZGUgdGhlIHdpZHRoIG9mIHRoZSBmaXJzdCBtYXJrZXJcblx0XHRcdFx0XHRpbnZlcnRlZCA/IC1jaGFydC5wbG90TGVmdCA6IC1jaGFydC5wbG90VG9wLFxuXHRcdFx0XHRcdDk5LFxuXHRcdFx0XHRcdGludmVydGVkID8gY2hhcnQuY2hhcnRXaWR0aCA6IGNoYXJ0LmNoYXJ0SGVpZ2h0XG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRzZXJpZXMuZ3JvdXAuY2xpcChjbGlwUmVjdCk7XG5cdFx0XHRzZXJpZXMubWFya2VyR3JvdXAuY2xpcChtYXJrZXJDbGlwUmVjdCk7XG5cdFx0XHRzZXJpZXMuc2hhcmVkQ2xpcEtleSA9IHNoYXJlZENsaXBLZXk7XG5cblx0XHQvLyBSdW4gdGhlIGFuaW1hdGlvblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjbGlwUmVjdCA9IGNoYXJ0W3NoYXJlZENsaXBLZXldO1xuXHRcdFx0aWYgKGNsaXBSZWN0KSB7XG5cdFx0XHRcdGNsaXBSZWN0LmFuaW1hdGUoe1xuXHRcdFx0XHRcdHdpZHRoOiBjaGFydC5wbG90U2l6ZVhcblx0XHRcdFx0fSwgYW5pbWF0aW9uKTtcblx0XHRcdH1cblx0XHRcdGlmIChjaGFydFtzaGFyZWRDbGlwS2V5ICsgJ20nXSkge1xuXHRcdFx0XHRjaGFydFtzaGFyZWRDbGlwS2V5ICsgJ20nXS5hbmltYXRlKHtcblx0XHRcdFx0XHR3aWR0aDogY2hhcnQucGxvdFNpemVYICsgOTlcblx0XHRcdFx0fSwgYW5pbWF0aW9uKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRGVsZXRlIHRoaXMgZnVuY3Rpb24gdG8gYWxsb3cgaXQgb25seSBvbmNlXG5cdFx0XHRzZXJpZXMuYW5pbWF0ZSA9IG51bGw7XG4gXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUaGlzIHJ1bnMgYWZ0ZXIgYW5pbWF0aW9uIHRvIGxhbmQgb24gdGhlIGZpbmFsIHBsb3QgY2xpcHBpbmdcblx0ICovXG5cdGFmdGVyQW5pbWF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRzaGFyZWRDbGlwS2V5ID0gdGhpcy5zaGFyZWRDbGlwS2V5LFxuXHRcdFx0Z3JvdXAgPSB0aGlzLmdyb3VwLFxuXHRcdFx0Y2xpcEJveCA9IHRoaXMuY2xpcEJveDtcblxuXHRcdGlmIChncm91cCAmJiB0aGlzLm9wdGlvbnMuY2xpcCAhPT0gZmFsc2UpIHtcblx0XHRcdGlmICghc2hhcmVkQ2xpcEtleSB8fCAhY2xpcEJveCkge1xuXHRcdFx0XHRncm91cC5jbGlwKGNsaXBCb3ggPyBjaGFydC5yZW5kZXJlci5jbGlwUmVjdChjbGlwQm94KSA6IGNoYXJ0LmNsaXBSZWN0KTtcblx0XHRcdH1cblx0XHRcdHRoaXMubWFya2VyR3JvdXAuY2xpcCgpOyAvLyBubyBjbGlwXG5cdFx0fVxuXG5cdFx0ZmlyZUV2ZW50KHRoaXMsICdhZnRlckFuaW1hdGUnKTtcblxuXHRcdC8vIFJlbW92ZSB0aGUgc2hhcmVkIGNsaXBwaW5nIHJlY3RhbmNnbGUgd2hlbiBhbGwgc2VyaWVzIGFyZSBzaG93blxuXHRcdHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHNoYXJlZENsaXBLZXkgJiYgY2hhcnRbc2hhcmVkQ2xpcEtleV0pIHtcblx0XHRcdFx0aWYgKCFjbGlwQm94KSB7XG5cdFx0XHRcdFx0Y2hhcnRbc2hhcmVkQ2xpcEtleV0gPSBjaGFydFtzaGFyZWRDbGlwS2V5XS5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGNoYXJ0W3NoYXJlZENsaXBLZXkgKyAnbSddKSB7XG5cdFx0XHRcdFx0Y2hhcnRbc2hhcmVkQ2xpcEtleSArICdtJ10gPSBjaGFydFtzaGFyZWRDbGlwS2V5ICsgJ20nXS5kZXN0cm95KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LCAxMDApO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBtYXJrZXJzXG5cdCAqL1xuXHRkcmF3UG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRwb2ludEF0dHIsXG5cdFx0XHRwb2ludHMgPSBzZXJpZXMucG9pbnRzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRwbG90WCxcblx0XHRcdHBsb3RZLFxuXHRcdFx0aSxcblx0XHRcdHBvaW50LFxuXHRcdFx0cmFkaXVzLFxuXHRcdFx0c3ltYm9sLFxuXHRcdFx0aXNJbWFnZSxcblx0XHRcdGdyYXBoaWMsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRzZXJpZXNNYXJrZXJPcHRpb25zID0gb3B0aW9ucy5tYXJrZXIsXG5cdFx0XHRzZXJpZXNQb2ludEF0dHIgPSBzZXJpZXMucG9pbnRBdHRyWycnXSxcblx0XHRcdHBvaW50TWFya2VyT3B0aW9ucyxcblx0XHRcdGhhc1BvaW50TWFya2VyLFxuXHRcdFx0ZW5hYmxlZCxcblx0XHRcdGlzSW5zaWRlLFxuXHRcdFx0bWFya2VyR3JvdXAgPSBzZXJpZXMubWFya2VyR3JvdXAsXG5cdFx0XHRnbG9iYWxseUVuYWJsZWQgPSBwaWNrKFxuXHRcdFx0XHRzZXJpZXNNYXJrZXJPcHRpb25zLmVuYWJsZWQsIFxuXHRcdFx0XHQhc2VyaWVzLnJlcXVpcmVTb3J0aW5nIHx8IHNlcmllcy5hY3RpdmVQb2ludENvdW50IDwgKDAuNSAqIHNlcmllcy54QXhpcy5sZW4gLyBzZXJpZXNNYXJrZXJPcHRpb25zLnJhZGl1cylcblx0XHRcdCk7XG5cblx0XHRpZiAoc2VyaWVzTWFya2VyT3B0aW9ucy5lbmFibGVkICE9PSBmYWxzZSB8fCBzZXJpZXMuX2hhc1BvaW50TWFya2Vycykge1xuXG5cdFx0XHRpID0gcG9pbnRzLmxlbmd0aDtcblx0XHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHRcdHBsb3RYID0gbWF0aEZsb29yKHBvaW50LnBsb3RYKTsgLy8gIzE4NDNcblx0XHRcdFx0cGxvdFkgPSBwb2ludC5wbG90WTtcblx0XHRcdFx0Z3JhcGhpYyA9IHBvaW50LmdyYXBoaWM7XG5cdFx0XHRcdHBvaW50TWFya2VyT3B0aW9ucyA9IHBvaW50Lm1hcmtlciB8fCB7fTtcblx0XHRcdFx0aGFzUG9pbnRNYXJrZXIgPSAhIXBvaW50Lm1hcmtlcjtcblx0XHRcdFx0ZW5hYmxlZCA9IChnbG9iYWxseUVuYWJsZWQgJiYgcG9pbnRNYXJrZXJPcHRpb25zLmVuYWJsZWQgPT09IFVOREVGSU5FRCkgfHwgcG9pbnRNYXJrZXJPcHRpb25zLmVuYWJsZWQ7XG5cdFx0XHRcdGlzSW5zaWRlID0gY2hhcnQuaXNJbnNpZGVQbG90KG1hdGhSb3VuZChwbG90WCksIHBsb3RZLCBjaGFydC5pbnZlcnRlZCk7IC8vICMxODU4XG5cblx0XHRcdFx0Ly8gb25seSBkcmF3IHRoZSBwb2ludCBpZiB5IGlzIGRlZmluZWRcblx0XHRcdFx0aWYgKGVuYWJsZWQgJiYgcGxvdFkgIT09IFVOREVGSU5FRCAmJiAhaXNOYU4ocGxvdFkpICYmIHBvaW50LnkgIT09IG51bGwpIHtcblxuXHRcdFx0XHRcdC8vIHNob3J0Y3V0c1xuXHRcdFx0XHRcdHBvaW50QXR0ciA9IHBvaW50LnBvaW50QXR0cltwb2ludC5zZWxlY3RlZCA/IFNFTEVDVF9TVEFURSA6IE5PUk1BTF9TVEFURV0gfHwgc2VyaWVzUG9pbnRBdHRyO1xuXHRcdFx0XHRcdHJhZGl1cyA9IHBvaW50QXR0ci5yO1xuXHRcdFx0XHRcdHN5bWJvbCA9IHBpY2socG9pbnRNYXJrZXJPcHRpb25zLnN5bWJvbCwgc2VyaWVzLnN5bWJvbCk7XG5cdFx0XHRcdFx0aXNJbWFnZSA9IHN5bWJvbC5pbmRleE9mKCd1cmwnKSA9PT0gMDtcblxuXHRcdFx0XHRcdGlmIChncmFwaGljKSB7IC8vIHVwZGF0ZVxuXHRcdFx0XHRcdFx0Z3JhcGhpY1tpc0luc2lkZSA/ICdzaG93JyA6ICdoaWRlJ10odHJ1ZSkgLy8gU2luY2UgdGhlIG1hcmtlciBncm91cCBpc24ndCBjbGlwcGVkLCBlYWNoIGluZGl2aWR1YWwgbWFya2VyIG11c3QgYmUgdG9nZ2xlZFxuXHRcdFx0XHRcdFx0XHQuYW5pbWF0ZShleHRlbmQoe1xuXHRcdFx0XHRcdFx0XHRcdHg6IHBsb3RYIC0gcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRcdHk6IHBsb3RZIC0gcmFkaXVzXG5cdFx0XHRcdFx0XHRcdH0sIGdyYXBoaWMuc3ltYm9sTmFtZSA/IHsgLy8gZG9uJ3QgYXBwbHkgdG8gaW1hZ2Ugc3ltYm9scyAjNTA3XG5cdFx0XHRcdFx0XHRcdFx0d2lkdGg6IDIgKiByYWRpdXMsXG5cdFx0XHRcdFx0XHRcdFx0aGVpZ2h0OiAyICogcmFkaXVzXG5cdFx0XHRcdFx0XHRcdH0gOiB7fSkpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoaXNJbnNpZGUgJiYgKHJhZGl1cyA+IDAgfHwgaXNJbWFnZSkpIHtcblx0XHRcdFx0XHRcdHBvaW50LmdyYXBoaWMgPSBncmFwaGljID0gY2hhcnQucmVuZGVyZXIuc3ltYm9sKFxuXHRcdFx0XHRcdFx0XHRzeW1ib2wsXG5cdFx0XHRcdFx0XHRcdHBsb3RYIC0gcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHRwbG90WSAtIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0MiAqIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0MiAqIHJhZGl1cyxcblx0XHRcdFx0XHRcdFx0aGFzUG9pbnRNYXJrZXIgPyBwb2ludE1hcmtlck9wdGlvbnMgOiBzZXJpZXNNYXJrZXJPcHRpb25zXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQuYXR0cihwb2ludEF0dHIpXG5cdFx0XHRcdFx0XHQuYWRkKG1hcmtlckdyb3VwKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0fSBlbHNlIGlmIChncmFwaGljKSB7XG5cdFx0XHRcdFx0cG9pbnQuZ3JhcGhpYyA9IGdyYXBoaWMuZGVzdHJveSgpOyAvLyAjMTI2OVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdH0sXG5cblx0LyoqXG5cdCAqIENvbnZlcnQgc3RhdGUgcHJvcGVydGllcyBmcm9tIEFQSSBuYW1pbmcgY29udmVudGlvbnMgdG8gU1ZHIGF0dHJpYnV0ZXNcblx0ICpcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgQVBJIG9wdGlvbnMgb2JqZWN0XG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBiYXNlMSBTVkcgYXR0cmlidXRlIG9iamVjdCB0byBpbmhlcml0IGZyb21cblx0ICogQHBhcmFtIHtPYmplY3R9IGJhc2UyIFNlY29uZCBsZXZlbCBTVkcgYXR0cmlidXRlIG9iamVjdCB0byBpbmhlcml0IGZyb21cblx0ICovXG5cdGNvbnZlcnRBdHRyaWJzOiBmdW5jdGlvbiAob3B0aW9ucywgYmFzZTEsIGJhc2UyLCBiYXNlMykge1xuXHRcdHZhciBjb252ZXJzaW9uID0gdGhpcy5wb2ludEF0dHJUb09wdGlvbnMsXG5cdFx0XHRhdHRyLFxuXHRcdFx0b3B0aW9uLFxuXHRcdFx0b2JqID0ge307XG5cblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblx0XHRiYXNlMSA9IGJhc2UxIHx8IHt9O1xuXHRcdGJhc2UyID0gYmFzZTIgfHwge307XG5cdFx0YmFzZTMgPSBiYXNlMyB8fCB7fTtcblxuXHRcdGZvciAoYXR0ciBpbiBjb252ZXJzaW9uKSB7XG5cdFx0XHRvcHRpb24gPSBjb252ZXJzaW9uW2F0dHJdO1xuXHRcdFx0b2JqW2F0dHJdID0gcGljayhvcHRpb25zW29wdGlvbl0sIGJhc2UxW2F0dHJdLCBiYXNlMlthdHRyXSwgYmFzZTNbYXR0cl0pO1xuXHRcdH1cblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHN0YXRlIGF0dHJpYnV0ZXMuIEVhY2ggc2VyaWVzIHR5cGUgaGFzIGl0cyBvd24gc2V0IG9mIGF0dHJpYnV0ZXNcblx0ICogdGhhdCBhcmUgYWxsb3dlZCB0byBjaGFuZ2Ugb24gYSBwb2ludCdzIHN0YXRlIGNoYW5nZS4gU2VyaWVzIHdpZGUgYXR0cmlidXRlcyBhcmUgc3RvcmVkIGZvclxuXHQgKiBhbGwgc2VyaWVzLCBhbmQgYWRkaXRpb25hbGx5IHBvaW50IHNwZWNpZmljIGF0dHJpYnV0ZXMgYXJlIHN0b3JlZCBmb3IgYWxsXG5cdCAqIHBvaW50cyB3aXRoIGluZGl2aWR1YWwgbWFya2VyIG9wdGlvbnMuIElmIHN1Y2ggb3B0aW9ucyBhcmUgbm90IGRlZmluZWQgZm9yIHRoZSBwb2ludCxcblx0ICogYSByZWZlcmVuY2UgdG8gdGhlIHNlcmllcyB3aWRlIGF0dHJpYnV0ZXMgaXMgc3RvcmVkIGluIHBvaW50LnBvaW50QXR0ci5cblx0ICovXG5cdGdldEF0dHJpYnM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdHNlcmllc09wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdG5vcm1hbE9wdGlvbnMgPSBkZWZhdWx0UGxvdE9wdGlvbnNbc2VyaWVzLnR5cGVdLm1hcmtlciA/IHNlcmllc09wdGlvbnMubWFya2VyIDogc2VyaWVzT3B0aW9ucyxcblx0XHRcdHN0YXRlT3B0aW9ucyA9IG5vcm1hbE9wdGlvbnMuc3RhdGVzLFxuXHRcdFx0c3RhdGVPcHRpb25zSG92ZXIgPSBzdGF0ZU9wdGlvbnNbSE9WRVJfU1RBVEVdLFxuXHRcdFx0cG9pbnRTdGF0ZU9wdGlvbnNIb3Zlcixcblx0XHRcdHNlcmllc0NvbG9yID0gc2VyaWVzLmNvbG9yLFxuXHRcdFx0bm9ybWFsRGVmYXVsdHMgPSB7XG5cdFx0XHRcdHN0cm9rZTogc2VyaWVzQ29sb3IsXG5cdFx0XHRcdGZpbGw6IHNlcmllc0NvbG9yXG5cdFx0XHR9LFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyB8fCBbXSwgLy8gIzkyN1xuXHRcdFx0aSxcblx0XHRcdHBvaW50LFxuXHRcdFx0c2VyaWVzUG9pbnRBdHRyID0gW10sXG5cdFx0XHRwb2ludEF0dHIsXG5cdFx0XHRwb2ludEF0dHJUb09wdGlvbnMgPSBzZXJpZXMucG9pbnRBdHRyVG9PcHRpb25zLFxuXHRcdFx0aGFzUG9pbnRTcGVjaWZpY09wdGlvbnMgPSBzZXJpZXMuaGFzUG9pbnRTcGVjaWZpY09wdGlvbnMsXG5cdFx0XHRuZWdhdGl2ZUNvbG9yID0gc2VyaWVzT3B0aW9ucy5uZWdhdGl2ZUNvbG9yLFxuXHRcdFx0ZGVmYXVsdExpbmVDb2xvciA9IG5vcm1hbE9wdGlvbnMubGluZUNvbG9yLFxuXHRcdFx0ZGVmYXVsdEZpbGxDb2xvciA9IG5vcm1hbE9wdGlvbnMuZmlsbENvbG9yLFxuXHRcdFx0dHVyYm9UaHJlc2hvbGQgPSBzZXJpZXNPcHRpb25zLnR1cmJvVGhyZXNob2xkLFxuXHRcdFx0YXR0cixcblx0XHRcdGtleTtcblxuXHRcdC8vIHNlcmllcyB0eXBlIHNwZWNpZmljIG1vZGlmaWNhdGlvbnNcblx0XHRpZiAoc2VyaWVzT3B0aW9ucy5tYXJrZXIpIHsgLy8gbGluZSwgc3BsaW5lLCBhcmVhLCBhcmVhc3BsaW5lLCBzY2F0dGVyXG5cblx0XHRcdC8vIGlmIG5vIGhvdmVyIHJhZGl1cyBpcyBnaXZlbiwgZGVmYXVsdCB0byBub3JtYWwgcmFkaXVzICsgMlxuXHRcdFx0c3RhdGVPcHRpb25zSG92ZXIucmFkaXVzID0gc3RhdGVPcHRpb25zSG92ZXIucmFkaXVzIHx8IG5vcm1hbE9wdGlvbnMucmFkaXVzICsgc3RhdGVPcHRpb25zSG92ZXIucmFkaXVzUGx1cztcblx0XHRcdHN0YXRlT3B0aW9uc0hvdmVyLmxpbmVXaWR0aCA9IHN0YXRlT3B0aW9uc0hvdmVyLmxpbmVXaWR0aCB8fCBub3JtYWxPcHRpb25zLmxpbmVXaWR0aCArIHN0YXRlT3B0aW9uc0hvdmVyLmxpbmVXaWR0aFBsdXM7XG5cblx0XHR9IGVsc2UgeyAvLyBjb2x1bW4sIGJhciwgcGllXG5cblx0XHRcdC8vIGlmIG5vIGhvdmVyIGNvbG9yIGlzIGdpdmVuLCBicmlnaHRlbiB0aGUgbm9ybWFsIGNvbG9yXG5cdFx0XHRzdGF0ZU9wdGlvbnNIb3Zlci5jb2xvciA9IHN0YXRlT3B0aW9uc0hvdmVyLmNvbG9yIHx8XG5cdFx0XHRcdENvbG9yKHN0YXRlT3B0aW9uc0hvdmVyLmNvbG9yIHx8IHNlcmllc0NvbG9yKVxuXHRcdFx0XHRcdC5icmlnaHRlbihzdGF0ZU9wdGlvbnNIb3Zlci5icmlnaHRuZXNzKS5nZXQoKTtcblx0XHR9XG5cblx0XHQvLyBnZW5lcmFsIHBvaW50IGF0dHJpYnV0ZXMgZm9yIHRoZSBzZXJpZXMgbm9ybWFsIHN0YXRlXG5cdFx0c2VyaWVzUG9pbnRBdHRyW05PUk1BTF9TVEFURV0gPSBzZXJpZXMuY29udmVydEF0dHJpYnMobm9ybWFsT3B0aW9ucywgbm9ybWFsRGVmYXVsdHMpO1xuXG5cdFx0Ly8gSE9WRVJfU1RBVEUgYW5kIFNFTEVDVF9TVEFURSBzdGF0ZXMgaW5oZXJpdCBmcm9tIG5vcm1hbCBzdGF0ZSBleGNlcHQgdGhlIGRlZmF1bHQgcmFkaXVzXG5cdFx0ZWFjaChbSE9WRVJfU1RBVEUsIFNFTEVDVF9TVEFURV0sIGZ1bmN0aW9uIChzdGF0ZSkge1xuXHRcdFx0c2VyaWVzUG9pbnRBdHRyW3N0YXRlXSA9XG5cdFx0XHRcdFx0c2VyaWVzLmNvbnZlcnRBdHRyaWJzKHN0YXRlT3B0aW9uc1tzdGF0ZV0sIHNlcmllc1BvaW50QXR0cltOT1JNQUxfU1RBVEVdKTtcblx0XHR9KTtcblxuXHRcdC8vIHNldCBpdFxuXHRcdHNlcmllcy5wb2ludEF0dHIgPSBzZXJpZXNQb2ludEF0dHI7XG5cblxuXHRcdC8vIEdlbmVyYXRlIHRoZSBwb2ludC1zcGVjaWZpYyBhdHRyaWJ1dGUgY29sbGVjdGlvbnMgaWYgc3BlY2lmaWMgcG9pbnRcblx0XHQvLyBvcHRpb25zIGFyZSBnaXZlbi4gSWYgbm90LCBjcmVhdGUgYSByZWZlcmFuY2UgdG8gdGhlIHNlcmllcyB3aWRlIHBvaW50XG5cdFx0Ly8gYXR0cmlidXRlc1xuXHRcdGkgPSBwb2ludHMubGVuZ3RoO1xuXHRcdGlmICghdHVyYm9UaHJlc2hvbGQgfHwgaSA8IHR1cmJvVGhyZXNob2xkIHx8IGhhc1BvaW50U3BlY2lmaWNPcHRpb25zKSB7XG5cdFx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRcdHBvaW50ID0gcG9pbnRzW2ldO1xuXHRcdFx0XHRub3JtYWxPcHRpb25zID0gKHBvaW50Lm9wdGlvbnMgJiYgcG9pbnQub3B0aW9ucy5tYXJrZXIpIHx8IHBvaW50Lm9wdGlvbnM7XG5cdFx0XHRcdGlmIChub3JtYWxPcHRpb25zICYmIG5vcm1hbE9wdGlvbnMuZW5hYmxlZCA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRub3JtYWxPcHRpb25zLnJhZGl1cyA9IDA7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAocG9pbnQubmVnYXRpdmUgJiYgbmVnYXRpdmVDb2xvcikge1xuXHRcdFx0XHRcdHBvaW50LmNvbG9yID0gcG9pbnQuZmlsbENvbG9yID0gbmVnYXRpdmVDb2xvcjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGhhc1BvaW50U3BlY2lmaWNPcHRpb25zID0gc2VyaWVzT3B0aW9ucy5jb2xvckJ5UG9pbnQgfHwgcG9pbnQuY29sb3I7IC8vICM4NjhcblxuXHRcdFx0XHQvLyBjaGVjayBpZiB0aGUgcG9pbnQgaGFzIHNwZWNpZmljIHZpc3VhbCBvcHRpb25zXG5cdFx0XHRcdGlmIChwb2ludC5vcHRpb25zKSB7XG5cdFx0XHRcdFx0Zm9yIChrZXkgaW4gcG9pbnRBdHRyVG9PcHRpb25zKSB7XG5cdFx0XHRcdFx0XHRpZiAoZGVmaW5lZChub3JtYWxPcHRpb25zW3BvaW50QXR0clRvT3B0aW9uc1trZXldXSkpIHtcblx0XHRcdFx0XHRcdFx0aGFzUG9pbnRTcGVjaWZpY09wdGlvbnMgPSB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGEgc3BlY2lmaWMgbWFya2VyIGNvbmZpZyBvYmplY3QgaXMgZGVmaW5lZCBmb3IgdGhlIGluZGl2aWR1YWwgcG9pbnQ6XG5cdFx0XHRcdC8vIGNyZWF0ZSBpdCdzIG93biBhdHRyaWJ1dGUgY29sbGVjdGlvblxuXHRcdFx0XHRpZiAoaGFzUG9pbnRTcGVjaWZpY09wdGlvbnMpIHtcblx0XHRcdFx0XHRub3JtYWxPcHRpb25zID0gbm9ybWFsT3B0aW9ucyB8fCB7fTtcblx0XHRcdFx0XHRwb2ludEF0dHIgPSBbXTtcblx0XHRcdFx0XHRzdGF0ZU9wdGlvbnMgPSBub3JtYWxPcHRpb25zLnN0YXRlcyB8fCB7fTsgLy8gcmVhc3NpZ24gZm9yIGluZGl2aWR1YWwgcG9pbnRcblx0XHRcdFx0XHRwb2ludFN0YXRlT3B0aW9uc0hvdmVyID0gc3RhdGVPcHRpb25zW0hPVkVSX1NUQVRFXSA9IHN0YXRlT3B0aW9uc1tIT1ZFUl9TVEFURV0gfHwge307XG5cblx0XHRcdFx0XHQvLyBIYW5kbGUgY29sb3JzIGZvciBjb2x1bW4gYW5kIHBpZXNcblx0XHRcdFx0XHRpZiAoIXNlcmllc09wdGlvbnMubWFya2VyKSB7IC8vIGNvbHVtbiwgYmFyLCBwb2ludFxuXHRcdFx0XHRcdFx0Ly8gSWYgbm8gaG92ZXIgY29sb3IgaXMgZ2l2ZW4sIGJyaWdodGVuIHRoZSBub3JtYWwgY29sb3IuICMxNjE5LCAjMjU3OVxuXHRcdFx0XHRcdFx0cG9pbnRTdGF0ZU9wdGlvbnNIb3Zlci5jb2xvciA9IHBvaW50U3RhdGVPcHRpb25zSG92ZXIuY29sb3IgfHwgKCFwb2ludC5vcHRpb25zLmNvbG9yICYmIHN0YXRlT3B0aW9uc0hvdmVyLmNvbG9yKSB8fFxuXHRcdFx0XHRcdFx0XHRDb2xvcihwb2ludC5jb2xvcilcblx0XHRcdFx0XHRcdFx0XHQuYnJpZ2h0ZW4ocG9pbnRTdGF0ZU9wdGlvbnNIb3Zlci5icmlnaHRuZXNzIHx8IHN0YXRlT3B0aW9uc0hvdmVyLmJyaWdodG5lc3MpXG5cdFx0XHRcdFx0XHRcdFx0LmdldCgpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIG5vcm1hbCBwb2ludCBzdGF0ZSBpbmhlcml0cyBzZXJpZXMgd2lkZSBub3JtYWwgc3RhdGVcblx0XHRcdFx0XHRhdHRyID0geyBjb2xvcjogcG9pbnQuY29sb3IgfTsgLy8gIzg2OFxuXHRcdFx0XHRcdGlmICghZGVmYXVsdEZpbGxDb2xvcikgeyAvLyBJbmRpdmlkdWFsIHBvaW50IGNvbG9yIG9yIG5lZ2F0aXZlIGNvbG9yIG1hcmtlcnMgKCMyMjE5KVxuXHRcdFx0XHRcdFx0YXR0ci5maWxsQ29sb3IgPSBwb2ludC5jb2xvcjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCFkZWZhdWx0TGluZUNvbG9yKSB7XG5cdFx0XHRcdFx0XHRhdHRyLmxpbmVDb2xvciA9IHBvaW50LmNvbG9yOyAvLyBCdWJibGVzIHRha2UgcG9pbnQgY29sb3IsIGxpbmUgbWFya2VycyB1c2Ugd2hpdGVcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9pbnRBdHRyW05PUk1BTF9TVEFURV0gPSBzZXJpZXMuY29udmVydEF0dHJpYnMoZXh0ZW5kKGF0dHIsIG5vcm1hbE9wdGlvbnMpLCBzZXJpZXNQb2ludEF0dHJbTk9STUFMX1NUQVRFXSk7XG5cblx0XHRcdFx0XHQvLyBpbmhlcml0IGZyb20gcG9pbnQgbm9ybWFsIGFuZCBzZXJpZXMgaG92ZXJcblx0XHRcdFx0XHRwb2ludEF0dHJbSE9WRVJfU1RBVEVdID0gc2VyaWVzLmNvbnZlcnRBdHRyaWJzKFxuXHRcdFx0XHRcdFx0c3RhdGVPcHRpb25zW0hPVkVSX1NUQVRFXSxcblx0XHRcdFx0XHRcdHNlcmllc1BvaW50QXR0cltIT1ZFUl9TVEFURV0sXG5cdFx0XHRcdFx0XHRwb2ludEF0dHJbTk9STUFMX1NUQVRFXVxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHQvLyBpbmhlcml0IGZyb20gcG9pbnQgbm9ybWFsIGFuZCBzZXJpZXMgaG92ZXJcblx0XHRcdFx0XHRwb2ludEF0dHJbU0VMRUNUX1NUQVRFXSA9IHNlcmllcy5jb252ZXJ0QXR0cmlicyhcblx0XHRcdFx0XHRcdHN0YXRlT3B0aW9uc1tTRUxFQ1RfU1RBVEVdLFxuXHRcdFx0XHRcdFx0c2VyaWVzUG9pbnRBdHRyW1NFTEVDVF9TVEFURV0sXG5cdFx0XHRcdFx0XHRwb2ludEF0dHJbTk9STUFMX1NUQVRFXVxuXHRcdFx0XHRcdCk7XG5cblxuXHRcdFx0XHQvLyBubyBtYXJrZXIgY29uZmlnIG9iamVjdCBpcyBjcmVhdGVkOiBjb3B5IGEgcmVmZXJlbmNlIHRvIHRoZSBzZXJpZXMtd2lkZVxuXHRcdFx0XHQvLyBhdHRyaWJ1dGUgY29sbGVjdGlvblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHBvaW50QXR0ciA9IHNlcmllc1BvaW50QXR0cjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHBvaW50LnBvaW50QXR0ciA9IHBvaW50QXR0cjtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIENsZWFyIERPTSBvYmplY3RzIGFuZCBmcmVlIHVwIG1lbW9yeVxuXHQgKi9cblx0ZGVzdHJveTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRpc3N1ZTEzNCA9IC9BcHBsZVdlYktpdFxcLzUzMy8udGVzdCh1c2VyQWdlbnQpLFxuXHRcdFx0ZGVzdHJveSxcblx0XHRcdGksXG5cdFx0XHRkYXRhID0gc2VyaWVzLmRhdGEgfHwgW10sXG5cdFx0XHRwb2ludCxcblx0XHRcdHByb3AsXG5cdFx0XHRheGlzO1xuXG5cdFx0Ly8gYWRkIGV2ZW50IGhvb2tcblx0XHRmaXJlRXZlbnQoc2VyaWVzLCAnZGVzdHJveScpO1xuXG5cdFx0Ly8gcmVtb3ZlIGFsbCBldmVudHNcblx0XHRyZW1vdmVFdmVudChzZXJpZXMpO1xuXG5cdFx0Ly8gZXJhc2UgZnJvbSBheGVzXG5cdFx0ZWFjaChzZXJpZXMuYXhpc1R5cGVzIHx8IFtdLCBmdW5jdGlvbiAoQVhJUykge1xuXHRcdFx0YXhpcyA9IHNlcmllc1tBWElTXTtcblx0XHRcdGlmIChheGlzKSB7XG5cdFx0XHRcdGVyYXNlKGF4aXMuc2VyaWVzLCBzZXJpZXMpO1xuXHRcdFx0XHRheGlzLmlzRGlydHkgPSBheGlzLmZvcmNlUmVkcmF3ID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIHJlbW92ZSBsZWdlbmQgaXRlbXNcblx0XHRpZiAoc2VyaWVzLmxlZ2VuZEl0ZW0pIHtcblx0XHRcdHNlcmllcy5jaGFydC5sZWdlbmQuZGVzdHJveUl0ZW0oc2VyaWVzKTtcblx0XHR9XG5cblx0XHQvLyBkZXN0cm95IGFsbCBwb2ludHMgd2l0aCB0aGVpciBlbGVtZW50c1xuXHRcdGkgPSBkYXRhLmxlbmd0aDtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRwb2ludCA9IGRhdGFbaV07XG5cdFx0XHRpZiAocG9pbnQgJiYgcG9pbnQuZGVzdHJveSkge1xuXHRcdFx0XHRwb2ludC5kZXN0cm95KCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHNlcmllcy5wb2ludHMgPSBudWxsO1xuXG5cdFx0Ly8gQ2xlYXIgdGhlIGFuaW1hdGlvbiB0aW1lb3V0IGlmIHdlIGFyZSBkZXN0cm95aW5nIHRoZSBzZXJpZXMgZHVyaW5nIGluaXRpYWwgYW5pbWF0aW9uXG5cdFx0Y2xlYXJUaW1lb3V0KHNlcmllcy5hbmltYXRpb25UaW1lb3V0KTtcblxuXHRcdC8vIGRlc3Ryb3kgYWxsIFNWR0VsZW1lbnRzIGFzc29jaWF0ZWQgdG8gdGhlIHNlcmllc1xuXHRcdGVhY2goWydhcmVhJywgJ2dyYXBoJywgJ2RhdGFMYWJlbHNHcm91cCcsICdncm91cCcsICdtYXJrZXJHcm91cCcsICd0cmFja2VyJyxcblx0XHRcdFx0J2dyYXBoTmVnJywgJ2FyZWFOZWcnLCAncG9zQ2xpcCcsICduZWdDbGlwJ10sIGZ1bmN0aW9uIChwcm9wKSB7XG5cdFx0XHRpZiAoc2VyaWVzW3Byb3BdKSB7XG5cblx0XHRcdFx0Ly8gaXNzdWUgMTM0IHdvcmthcm91bmRcblx0XHRcdFx0ZGVzdHJveSA9IGlzc3VlMTM0ICYmIHByb3AgPT09ICdncm91cCcgP1xuXHRcdFx0XHRcdCdoaWRlJyA6XG5cdFx0XHRcdFx0J2Rlc3Ryb3knO1xuXG5cdFx0XHRcdHNlcmllc1twcm9wXVtkZXN0cm95XSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gcmVtb3ZlIGZyb20gaG92ZXJTZXJpZXNcblx0XHRpZiAoY2hhcnQuaG92ZXJTZXJpZXMgPT09IHNlcmllcykge1xuXHRcdFx0Y2hhcnQuaG92ZXJTZXJpZXMgPSBudWxsO1xuXHRcdH1cblx0XHRlcmFzZShjaGFydC5zZXJpZXMsIHNlcmllcyk7XG5cblx0XHQvLyBjbGVhciBhbGwgbWVtYmVyc1xuXHRcdGZvciAocHJvcCBpbiBzZXJpZXMpIHtcblx0XHRcdGRlbGV0ZSBzZXJpZXNbcHJvcF07XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZXR1cm4gdGhlIGdyYXBoIHBhdGggb2YgYSBzZWdtZW50XG5cdCAqL1xuXHRnZXRTZWdtZW50UGF0aDogZnVuY3Rpb24gKHNlZ21lbnQpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdHNlZ21lbnRQYXRoID0gW10sXG5cdFx0XHRzdGVwID0gc2VyaWVzLm9wdGlvbnMuc3RlcDtcblxuXHRcdC8vIGJ1aWxkIHRoZSBzZWdtZW50IGxpbmVcblx0XHRlYWNoKHNlZ21lbnQsIGZ1bmN0aW9uIChwb2ludCwgaSkge1xuXG5cdFx0XHR2YXIgcGxvdFggPSBwb2ludC5wbG90WCxcblx0XHRcdFx0cGxvdFkgPSBwb2ludC5wbG90WSxcblx0XHRcdFx0bGFzdFBvaW50O1xuXG5cdFx0XHRpZiAoc2VyaWVzLmdldFBvaW50U3BsaW5lKSB7IC8vIGdlbmVyYXRlIHRoZSBzcGxpbmUgYXMgZGVmaW5lZCBpbiB0aGUgU3BsaW5lU2VyaWVzIG9iamVjdFxuXHRcdFx0XHRzZWdtZW50UGF0aC5wdXNoLmFwcGx5KHNlZ21lbnRQYXRoLCBzZXJpZXMuZ2V0UG9pbnRTcGxpbmUoc2VnbWVudCwgcG9pbnQsIGkpKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBtb3ZlVG8gb3IgbGluZVRvXG5cdFx0XHRcdHNlZ21lbnRQYXRoLnB1c2goaSA/IEwgOiBNKTtcblxuXHRcdFx0XHQvLyBzdGVwIGxpbmU/XG5cdFx0XHRcdGlmIChzdGVwICYmIGkpIHtcblx0XHRcdFx0XHRsYXN0UG9pbnQgPSBzZWdtZW50W2kgLSAxXTtcblx0XHRcdFx0XHRpZiAoc3RlcCA9PT0gJ3JpZ2h0Jykge1xuXHRcdFx0XHRcdFx0c2VnbWVudFBhdGgucHVzaChcblx0XHRcdFx0XHRcdFx0bGFzdFBvaW50LnBsb3RYLFxuXHRcdFx0XHRcdFx0XHRwbG90WVxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoc3RlcCA9PT0gJ2NlbnRlcicpIHtcblx0XHRcdFx0XHRcdHNlZ21lbnRQYXRoLnB1c2goXG5cdFx0XHRcdFx0XHRcdChsYXN0UG9pbnQucGxvdFggKyBwbG90WCkgLyAyLFxuXHRcdFx0XHRcdFx0XHRsYXN0UG9pbnQucGxvdFksXG5cdFx0XHRcdFx0XHRcdChsYXN0UG9pbnQucGxvdFggKyBwbG90WCkgLyAyLFxuXHRcdFx0XHRcdFx0XHRwbG90WVxuXHRcdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzZWdtZW50UGF0aC5wdXNoKFxuXHRcdFx0XHRcdFx0XHRwbG90WCxcblx0XHRcdFx0XHRcdFx0bGFzdFBvaW50LnBsb3RZXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG5vcm1hbCBsaW5lIHRvIG5leHQgcG9pbnRcblx0XHRcdFx0c2VnbWVudFBhdGgucHVzaChcblx0XHRcdFx0XHRwb2ludC5wbG90WCxcblx0XHRcdFx0XHRwb2ludC5wbG90WVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0cmV0dXJuIHNlZ21lbnRQYXRoO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIGdyYXBoIHBhdGhcblx0ICovXG5cdGdldEdyYXBoUGF0aDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Z3JhcGhQYXRoID0gW10sXG5cdFx0XHRzZWdtZW50UGF0aCxcblx0XHRcdHNpbmdsZVBvaW50cyA9IFtdOyAvLyB1c2VkIGluIGRyYXdUcmFja2VyXG5cblx0XHQvLyBEaXZpZGUgaW50byBzZWdtZW50cyBhbmQgYnVpbGQgZ3JhcGggYW5kIGFyZWEgcGF0aHNcblx0XHRlYWNoKHNlcmllcy5zZWdtZW50cywgZnVuY3Rpb24gKHNlZ21lbnQpIHtcblxuXHRcdFx0c2VnbWVudFBhdGggPSBzZXJpZXMuZ2V0U2VnbWVudFBhdGgoc2VnbWVudCk7XG5cblx0XHRcdC8vIGFkZCB0aGUgc2VnbWVudCB0byB0aGUgZ3JhcGgsIG9yIGEgc2luZ2xlIHBvaW50IGZvciB0cmFja2luZ1xuXHRcdFx0aWYgKHNlZ21lbnQubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRncmFwaFBhdGggPSBncmFwaFBhdGguY29uY2F0KHNlZ21lbnRQYXRoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNpbmdsZVBvaW50cy5wdXNoKHNlZ21lbnRbMF0pO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gUmVjb3JkIGl0IGZvciB1c2UgaW4gZHJhd0dyYXBoIGFuZCBkcmF3VHJhY2tlciwgYW5kIHJldHVybiBncmFwaFBhdGhcblx0XHRzZXJpZXMuc2luZ2xlUG9pbnRzID0gc2luZ2xlUG9pbnRzO1xuXHRcdHNlcmllcy5ncmFwaFBhdGggPSBncmFwaFBhdGg7XG5cblx0XHRyZXR1cm4gZ3JhcGhQYXRoO1xuXG5cdH0sXG5cblx0LyoqXG5cdCAqIERyYXcgdGhlIGFjdHVhbCBncmFwaFxuXHQgKi9cblx0ZHJhd0dyYXBoOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0cHJvcHMgPSBbWydncmFwaCcsIG9wdGlvbnMubGluZUNvbG9yIHx8IHRoaXMuY29sb3JdXSxcblx0XHRcdGxpbmVXaWR0aCA9IG9wdGlvbnMubGluZVdpZHRoLFxuXHRcdFx0ZGFzaFN0eWxlID0gIG9wdGlvbnMuZGFzaFN0eWxlLFxuXHRcdFx0cm91bmRDYXAgPSBvcHRpb25zLmxpbmVjYXAgIT09ICdzcXVhcmUnLFxuXHRcdFx0Z3JhcGhQYXRoID0gdGhpcy5nZXRHcmFwaFBhdGgoKSxcblx0XHRcdG5lZ2F0aXZlQ29sb3IgPSBvcHRpb25zLm5lZ2F0aXZlQ29sb3I7XG5cblx0XHRpZiAobmVnYXRpdmVDb2xvcikge1xuXHRcdFx0cHJvcHMucHVzaChbJ2dyYXBoTmVnJywgbmVnYXRpdmVDb2xvcl0pO1xuXHRcdH1cblxuXHRcdC8vIGRyYXcgdGhlIGdyYXBoXG5cdFx0ZWFjaChwcm9wcywgZnVuY3Rpb24gKHByb3AsIGkpIHtcblx0XHRcdHZhciBncmFwaEtleSA9IHByb3BbMF0sXG5cdFx0XHRcdGdyYXBoID0gc2VyaWVzW2dyYXBoS2V5XSxcblx0XHRcdFx0YXR0cmlicztcblxuXHRcdFx0aWYgKGdyYXBoKSB7XG5cdFx0XHRcdHN0b3AoZ3JhcGgpOyAvLyBjYW5jZWwgcnVubmluZyBhbmltYXRpb25zLCAjNDU5XG5cdFx0XHRcdGdyYXBoLmFuaW1hdGUoeyBkOiBncmFwaFBhdGggfSk7XG5cblx0XHRcdH0gZWxzZSBpZiAobGluZVdpZHRoICYmIGdyYXBoUGF0aC5sZW5ndGgpIHsgLy8gIzE0ODdcblx0XHRcdFx0YXR0cmlicyA9IHtcblx0XHRcdFx0XHRzdHJva2U6IHByb3BbMV0sXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IGxpbmVXaWR0aCxcblx0XHRcdFx0XHRmaWxsOiBOT05FLFxuXHRcdFx0XHRcdHpJbmRleDogMSAvLyAjMTA2OVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAoZGFzaFN0eWxlKSB7XG5cdFx0XHRcdFx0YXR0cmlicy5kYXNoc3R5bGUgPSBkYXNoU3R5bGU7XG5cdFx0XHRcdH0gZWxzZSBpZiAocm91bmRDYXApIHtcblx0XHRcdFx0XHRhdHRyaWJzWydzdHJva2UtbGluZWNhcCddID0gYXR0cmlic1snc3Ryb2tlLWxpbmVqb2luJ10gPSAncm91bmQnO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2VyaWVzW2dyYXBoS2V5XSA9IHNlcmllcy5jaGFydC5yZW5kZXJlci5wYXRoKGdyYXBoUGF0aClcblx0XHRcdFx0XHQuYXR0cihhdHRyaWJzKVxuXHRcdFx0XHRcdC5hZGQoc2VyaWVzLmdyb3VwKVxuXHRcdFx0XHRcdC5zaGFkb3coIWkgJiYgb3B0aW9ucy5zaGFkb3cpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBDbGlwIHRoZSBncmFwaHMgaW50byB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGNvbG91cmVkIGdyYXBoc1xuXHQgKi9cblx0Y2xpcE5lZzogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0Y2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRcdG5lZ2F0aXZlQ29sb3IgPSBvcHRpb25zLm5lZ2F0aXZlQ29sb3IgfHwgb3B0aW9ucy5uZWdhdGl2ZUZpbGxDb2xvcixcblx0XHRcdHRyYW5zbGF0ZWRUaHJlc2hvbGQsXG5cdFx0XHRwb3NBdHRyLFxuXHRcdFx0bmVnQXR0cixcblx0XHRcdGdyYXBoID0gdGhpcy5ncmFwaCxcblx0XHRcdGFyZWEgPSB0aGlzLmFyZWEsXG5cdFx0XHRwb3NDbGlwID0gdGhpcy5wb3NDbGlwLFxuXHRcdFx0bmVnQ2xpcCA9IHRoaXMubmVnQ2xpcCxcblx0XHRcdGNoYXJ0V2lkdGggPSBjaGFydC5jaGFydFdpZHRoLFxuXHRcdFx0Y2hhcnRIZWlnaHQgPSBjaGFydC5jaGFydEhlaWdodCxcblx0XHRcdGNoYXJ0U2l6ZU1heCA9IG1hdGhNYXgoY2hhcnRXaWR0aCwgY2hhcnRIZWlnaHQpLFxuXHRcdFx0eUF4aXMgPSB0aGlzLnlBeGlzLFxuXHRcdFx0YWJvdmUsXG5cdFx0XHRiZWxvdztcblxuXHRcdGlmIChuZWdhdGl2ZUNvbG9yICYmIChncmFwaCB8fCBhcmVhKSkge1xuXHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZCA9IG1hdGhSb3VuZCh5QXhpcy50b1BpeGVscyhvcHRpb25zLnRocmVzaG9sZCB8fCAwLCB0cnVlKSk7XG5cdFx0XHRpZiAodHJhbnNsYXRlZFRocmVzaG9sZCA8IDApIHtcblx0XHRcdFx0Y2hhcnRTaXplTWF4IC09IHRyYW5zbGF0ZWRUaHJlc2hvbGQ7IC8vICMyNTM0XG5cdFx0XHR9XG5cdFx0XHRhYm92ZSA9IHtcblx0XHRcdFx0eDogMCxcblx0XHRcdFx0eTogMCxcblx0XHRcdFx0d2lkdGg6IGNoYXJ0U2l6ZU1heCxcblx0XHRcdFx0aGVpZ2h0OiB0cmFuc2xhdGVkVGhyZXNob2xkXG5cdFx0XHR9O1xuXHRcdFx0YmVsb3cgPSB7XG5cdFx0XHRcdHg6IDAsXG5cdFx0XHRcdHk6IHRyYW5zbGF0ZWRUaHJlc2hvbGQsXG5cdFx0XHRcdHdpZHRoOiBjaGFydFNpemVNYXgsXG5cdFx0XHRcdGhlaWdodDogY2hhcnRTaXplTWF4XG5cdFx0XHR9O1xuXG5cdFx0XHRpZiAoY2hhcnQuaW52ZXJ0ZWQpIHtcblxuXHRcdFx0XHRhYm92ZS5oZWlnaHQgPSBiZWxvdy55ID0gY2hhcnQucGxvdFdpZHRoIC0gdHJhbnNsYXRlZFRocmVzaG9sZDtcblx0XHRcdFx0aWYgKHJlbmRlcmVyLmlzVk1MKSB7XG5cdFx0XHRcdFx0YWJvdmUgPSB7XG5cdFx0XHRcdFx0XHR4OiBjaGFydC5wbG90V2lkdGggLSB0cmFuc2xhdGVkVGhyZXNob2xkIC0gY2hhcnQucGxvdExlZnQsXG5cdFx0XHRcdFx0XHR5OiAwLFxuXHRcdFx0XHRcdFx0d2lkdGg6IGNoYXJ0V2lkdGgsXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IGNoYXJ0SGVpZ2h0XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRiZWxvdyA9IHtcblx0XHRcdFx0XHRcdHg6IHRyYW5zbGF0ZWRUaHJlc2hvbGQgKyBjaGFydC5wbG90TGVmdCAtIGNoYXJ0V2lkdGgsXG5cdFx0XHRcdFx0XHR5OiAwLFxuXHRcdFx0XHRcdFx0d2lkdGg6IGNoYXJ0LnBsb3RMZWZ0ICsgdHJhbnNsYXRlZFRocmVzaG9sZCxcblx0XHRcdFx0XHRcdGhlaWdodDogY2hhcnRXaWR0aFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKHlBeGlzLnJldmVyc2VkKSB7XG5cdFx0XHRcdHBvc0F0dHIgPSBiZWxvdztcblx0XHRcdFx0bmVnQXR0ciA9IGFib3ZlO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cG9zQXR0ciA9IGFib3ZlO1xuXHRcdFx0XHRuZWdBdHRyID0gYmVsb3c7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChwb3NDbGlwKSB7IC8vIHVwZGF0ZVxuXHRcdFx0XHRwb3NDbGlwLmFuaW1hdGUocG9zQXR0cik7XG5cdFx0XHRcdG5lZ0NsaXAuYW5pbWF0ZShuZWdBdHRyKTtcblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0dGhpcy5wb3NDbGlwID0gcG9zQ2xpcCA9IHJlbmRlcmVyLmNsaXBSZWN0KHBvc0F0dHIpO1xuXHRcdFx0XHR0aGlzLm5lZ0NsaXAgPSBuZWdDbGlwID0gcmVuZGVyZXIuY2xpcFJlY3QobmVnQXR0cik7XG5cblx0XHRcdFx0aWYgKGdyYXBoICYmIHRoaXMuZ3JhcGhOZWcpIHtcblx0XHRcdFx0XHRncmFwaC5jbGlwKHBvc0NsaXApO1xuXHRcdFx0XHRcdHRoaXMuZ3JhcGhOZWcuY2xpcChuZWdDbGlwKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChhcmVhKSB7XG5cdFx0XHRcdFx0YXJlYS5jbGlwKHBvc0NsaXApO1xuXHRcdFx0XHRcdHRoaXMuYXJlYU5lZy5jbGlwKG5lZ0NsaXApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBJbml0aWFsaXplIGFuZCBwZXJmb3JtIGdyb3VwIGludmVyc2lvbiBvbiBzZXJpZXMuZ3JvdXAgYW5kIHNlcmllcy5tYXJrZXJHcm91cFxuXHQgKi9cblx0aW52ZXJ0R3JvdXBzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydDtcblxuXHRcdC8vIFBpZSwgZ28gYXdheSAoIzE3MzYpXG5cdFx0aWYgKCFzZXJpZXMueEF4aXMpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBBIGZpeGVkIHNpemUgaXMgbmVlZGVkIGZvciBpbnZlcnNpb24gdG8gd29ya1xuXHRcdGZ1bmN0aW9uIHNldEludmVydCgpIHtcblx0XHRcdHZhciBzaXplID0ge1xuXHRcdFx0XHR3aWR0aDogc2VyaWVzLnlBeGlzLmxlbixcblx0XHRcdFx0aGVpZ2h0OiBzZXJpZXMueEF4aXMubGVuXG5cdFx0XHR9O1xuXG5cdFx0XHRlYWNoKFsnZ3JvdXAnLCAnbWFya2VyR3JvdXAnXSwgZnVuY3Rpb24gKGdyb3VwTmFtZSkge1xuXHRcdFx0XHRpZiAoc2VyaWVzW2dyb3VwTmFtZV0pIHtcblx0XHRcdFx0XHRzZXJpZXNbZ3JvdXBOYW1lXS5hdHRyKHNpemUpLmludmVydCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRhZGRFdmVudChjaGFydCwgJ3Jlc2l6ZScsIHNldEludmVydCk7IC8vIGRvIGl0IG9uIHJlc2l6ZVxuXHRcdGFkZEV2ZW50KHNlcmllcywgJ2Rlc3Ryb3knLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZW1vdmVFdmVudChjaGFydCwgJ3Jlc2l6ZScsIHNldEludmVydCk7XG5cdFx0fSk7XG5cblx0XHQvLyBEbyBpdCBub3dcblx0XHRzZXRJbnZlcnQoKTsgLy8gZG8gaXQgbm93XG5cblx0XHQvLyBPbiBzdWJzZXF1ZW50IHJlbmRlciBhbmQgcmVkcmF3LCBqdXN0IGRvIHNldEludmVydCB3aXRob3V0IHNldHRpbmcgdXAgZXZlbnRzIGFnYWluXG5cdFx0c2VyaWVzLmludmVydEdyb3VwcyA9IHNldEludmVydDtcblx0fSxcblxuXHQvKipcblx0ICogR2VuZXJhbCBhYnN0cmFjdGlvbiBmb3IgY3JlYXRpbmcgcGxvdCBncm91cHMgbGlrZSBzZXJpZXMuZ3JvdXAsIHNlcmllcy5kYXRhTGFiZWxzR3JvdXAgYW5kXG5cdCAqIHNlcmllcy5tYXJrZXJHcm91cC4gT24gc3Vic2VxdWVudCBjYWxscywgdGhlIGdyb3VwIHdpbGwgb25seSBiZSBhZGp1c3RlZCB0byB0aGUgdXBkYXRlZCBwbG90IHNpemUuXG5cdCAqL1xuXHRwbG90R3JvdXA6IGZ1bmN0aW9uIChwcm9wLCBuYW1lLCB2aXNpYmlsaXR5LCB6SW5kZXgsIHBhcmVudCkge1xuXHRcdHZhciBncm91cCA9IHRoaXNbcHJvcF0sXG5cdFx0XHRpc05ldyA9ICFncm91cDtcblxuXHRcdC8vIEdlbmVyYXRlIGl0IG9uIGZpcnN0IGNhbGxcblx0XHRpZiAoaXNOZXcpIHtcblx0XHRcdHRoaXNbcHJvcF0gPSBncm91cCA9IHRoaXMuY2hhcnQucmVuZGVyZXIuZyhuYW1lKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0dmlzaWJpbGl0eTogdmlzaWJpbGl0eSxcblx0XHRcdFx0XHR6SW5kZXg6IHpJbmRleCB8fCAwLjEgLy8gSUU4IG5lZWRzIHRoaXNcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZChwYXJlbnQpO1xuXHRcdH1cblx0XHQvLyBQbGFjZSBpdCBvbiBmaXJzdCBhbmQgc3Vic2VxdWVudCAocmVkcmF3KSBjYWxsc1xuXHRcdGdyb3VwW2lzTmV3ID8gJ2F0dHInIDogJ2FuaW1hdGUnXSh0aGlzLmdldFBsb3RCb3goKSk7XG5cdFx0cmV0dXJuIGdyb3VwO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBHZXQgdGhlIHRyYW5zbGF0aW9uIGFuZCBzY2FsZSBmb3IgdGhlIHBsb3QgYXJlYSBvZiB0aGlzIHNlcmllc1xuXHQgKi9cblx0Z2V0UGxvdEJveDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHR4QXhpcyA9IHRoaXMueEF4aXMsXG5cdFx0XHR5QXhpcyA9IHRoaXMueUF4aXM7XG5cblx0XHQvLyBTd2FwIGF4ZXMgZm9yIGludmVydGVkICgjMjMzOSlcblx0XHRpZiAoY2hhcnQuaW52ZXJ0ZWQpIHtcblx0XHRcdHhBeGlzID0geUF4aXM7XG5cdFx0XHR5QXhpcyA9IHRoaXMueEF4aXM7XG5cdFx0fVxuXHRcdHJldHVybiB7XG5cdFx0XHR0cmFuc2xhdGVYOiB4QXhpcyA/IHhBeGlzLmxlZnQgOiBjaGFydC5wbG90TGVmdCxcblx0XHRcdHRyYW5zbGF0ZVk6IHlBeGlzID8geUF4aXMudG9wIDogY2hhcnQucGxvdFRvcCxcblx0XHRcdHNjYWxlWDogMSwgLy8gIzE2MjNcblx0XHRcdHNjYWxlWTogMVxuXHRcdH07XG5cdH0sXG5cblx0LyoqXG5cdCAqIFJlbmRlciB0aGUgZ3JhcGggYW5kIG1hcmtlcnNcblx0ICovXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRncm91cCxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGFuaW1hdGlvbiA9IG9wdGlvbnMuYW5pbWF0aW9uLFxuXHRcdFx0Ly8gQW5pbWF0aW9uIGRvZXNuJ3Qgd29yayBpbiBJRTggcXVpcmtzIHdoZW4gdGhlIGdyb3VwIGRpdiBpcyBoaWRkZW4sXG5cdFx0XHQvLyBhbmQgbG9va3MgYmFkIGluIG90aGVyIG9sZElFXG5cdFx0XHRhbmltRHVyYXRpb24gPSAoYW5pbWF0aW9uICYmICEhc2VyaWVzLmFuaW1hdGUgJiYgY2hhcnQucmVuZGVyZXIuaXNTVkcgJiYgcGljayhhbmltYXRpb24uZHVyYXRpb24sIDUwMCkpIHx8IDAsXG5cdFx0XHR2aXNpYmlsaXR5ID0gc2VyaWVzLnZpc2libGUgPyBWSVNJQkxFIDogSElEREVOLFxuXHRcdFx0ekluZGV4ID0gb3B0aW9ucy56SW5kZXgsXG5cdFx0XHRoYXNSZW5kZXJlZCA9IHNlcmllcy5oYXNSZW5kZXJlZCxcblx0XHRcdGNoYXJ0U2VyaWVzR3JvdXAgPSBjaGFydC5zZXJpZXNHcm91cDtcblxuXHRcdC8vIHRoZSBncm91cFxuXHRcdGdyb3VwID0gc2VyaWVzLnBsb3RHcm91cChcblx0XHRcdCdncm91cCcsXG5cdFx0XHQnc2VyaWVzJyxcblx0XHRcdHZpc2liaWxpdHksXG5cdFx0XHR6SW5kZXgsXG5cdFx0XHRjaGFydFNlcmllc0dyb3VwXG5cdFx0KTtcblxuXHRcdHNlcmllcy5tYXJrZXJHcm91cCA9IHNlcmllcy5wbG90R3JvdXAoXG5cdFx0XHQnbWFya2VyR3JvdXAnLFxuXHRcdFx0J21hcmtlcnMnLFxuXHRcdFx0dmlzaWJpbGl0eSxcblx0XHRcdHpJbmRleCxcblx0XHRcdGNoYXJ0U2VyaWVzR3JvdXBcblx0XHQpO1xuXG5cdFx0Ly8gaW5pdGlhdGUgdGhlIGFuaW1hdGlvblxuXHRcdGlmIChhbmltRHVyYXRpb24pIHtcblx0XHRcdHNlcmllcy5hbmltYXRlKHRydWUpO1xuXHRcdH1cblxuXHRcdC8vIGNhY2hlIGF0dHJpYnV0ZXMgZm9yIHNoYXBlc1xuXHRcdHNlcmllcy5nZXRBdHRyaWJzKCk7XG5cblx0XHQvLyBTVkdSZW5kZXJlciBuZWVkcyB0byBrbm93IHRoaXMgYmVmb3JlIGRyYXdpbmcgZWxlbWVudHMgKCMxMDg5LCAjMTc5NSlcblx0XHRncm91cC5pbnZlcnRlZCA9IHNlcmllcy5pc0NhcnRlc2lhbiA/IGNoYXJ0LmludmVydGVkIDogZmFsc2U7XG5cblx0XHQvLyBkcmF3IHRoZSBncmFwaCBpZiBhbnlcblx0XHRpZiAoc2VyaWVzLmRyYXdHcmFwaCkge1xuXHRcdFx0c2VyaWVzLmRyYXdHcmFwaCgpO1xuXHRcdFx0c2VyaWVzLmNsaXBOZWcoKTtcblx0XHR9XG5cblx0XHRlYWNoKHNlcmllcy5wb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0aWYgKHBvaW50LnJlZHJhdykge1xuXHRcdFx0XHRwb2ludC5yZWRyYXcoKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGRyYXcgdGhlIGRhdGEgbGFiZWxzIChpbm4gcGllcyB0aGV5IGdvIGJlZm9yZSB0aGUgcG9pbnRzKVxuXHRcdGlmIChzZXJpZXMuZHJhd0RhdGFMYWJlbHMpIHtcblx0XHRcdHNlcmllcy5kcmF3RGF0YUxhYmVscygpO1xuXHRcdH1cblxuXHRcdC8vIGRyYXcgdGhlIHBvaW50c1xuXHRcdGlmIChzZXJpZXMudmlzaWJsZSkge1xuXHRcdFx0c2VyaWVzLmRyYXdQb2ludHMoKTtcblx0XHR9XG5cblxuXHRcdC8vIGRyYXcgdGhlIG1vdXNlIHRyYWNraW5nIGFyZWFcblx0XHRpZiAoc2VyaWVzLmRyYXdUcmFja2VyICYmIHNlcmllcy5vcHRpb25zLmVuYWJsZU1vdXNlVHJhY2tpbmcgIT09IGZhbHNlKSB7XG5cdFx0XHRzZXJpZXMuZHJhd1RyYWNrZXIoKTtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgaW52ZXJ0ZWQgc2VyaWVzIGFuZCB0cmFja2VyIGdyb3Vwc1xuXHRcdGlmIChjaGFydC5pbnZlcnRlZCkge1xuXHRcdFx0c2VyaWVzLmludmVydEdyb3VwcygpO1xuXHRcdH1cblxuXHRcdC8vIEluaXRpYWwgY2xpcHBpbmcsIG11c3QgYmUgZGVmaW5lZCBhZnRlciBpbnZlcnRpbmcgZ3JvdXBzIGZvciBWTUxcblx0XHRpZiAob3B0aW9ucy5jbGlwICE9PSBmYWxzZSAmJiAhc2VyaWVzLnNoYXJlZENsaXBLZXkgJiYgIWhhc1JlbmRlcmVkKSB7XG5cdFx0XHRncm91cC5jbGlwKGNoYXJ0LmNsaXBSZWN0KTtcblx0XHR9XG5cblx0XHQvLyBSdW4gdGhlIGFuaW1hdGlvblxuXHRcdGlmIChhbmltRHVyYXRpb24pIHtcblx0XHRcdHNlcmllcy5hbmltYXRlKCk7XG5cdFx0fSBcblxuXHRcdC8vIENhbGwgdGhlIGFmdGVyQW5pbWF0ZSBmdW5jdGlvbiBvbiBhbmltYXRpb24gY29tcGxldGUgKGJ1dCBkb24ndCBvdmVyd3JpdGUgdGhlIGFuaW1hdGlvbi5jb21wbGV0ZSBvcHRpb25cblx0XHQvLyB3aGljaCBzaG91bGQgYmUgYXZhaWxhYmxlIHRvIHRoZSB1c2VyKS5cblx0XHRpZiAoIWhhc1JlbmRlcmVkKSB7XG5cdFx0XHRpZiAoYW5pbUR1cmF0aW9uKSB7XG5cdFx0XHRcdHNlcmllcy5hbmltYXRpb25UaW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0c2VyaWVzLmFmdGVyQW5pbWF0ZSgpO1xuXHRcdFx0XHR9LCBhbmltRHVyYXRpb24pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c2VyaWVzLmFmdGVyQW5pbWF0ZSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHNlcmllcy5pc0RpcnR5ID0gc2VyaWVzLmlzRGlydHlEYXRhID0gZmFsc2U7IC8vIG1lYW5zIGRhdGEgaXMgaW4gYWNjb3JkYW5jZSB3aXRoIHdoYXQgeW91IHNlZVxuXHRcdC8vIChTZWUgIzMyMikgc2VyaWVzLmlzRGlydHkgPSBzZXJpZXMuaXNEaXJ0eURhdGEgPSBmYWxzZTsgLy8gbWVhbnMgZGF0YSBpcyBpbiBhY2NvcmRhbmNlIHdpdGggd2hhdCB5b3Ugc2VlXG5cdFx0c2VyaWVzLmhhc1JlbmRlcmVkID0gdHJ1ZTtcblx0fSxcblxuXHQvKipcblx0ICogUmVkcmF3IHRoZSBzZXJpZXMgYWZ0ZXIgYW4gdXBkYXRlIGluIHRoZSBheGVzLlxuXHQgKi9cblx0cmVkcmF3OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHdhc0RpcnR5RGF0YSA9IHNlcmllcy5pc0RpcnR5RGF0YSwgLy8gY2FjaGUgaXQgaGVyZSBhcyBpdCBpcyBzZXQgdG8gZmFsc2UgaW4gcmVuZGVyLCBidXQgdXNlZCBhZnRlclxuXHRcdFx0Z3JvdXAgPSBzZXJpZXMuZ3JvdXAsXG5cdFx0XHR4QXhpcyA9IHNlcmllcy54QXhpcyxcblx0XHRcdHlBeGlzID0gc2VyaWVzLnlBeGlzO1xuXG5cdFx0Ly8gcmVwb3NpdGlvbiBvbiByZXNpemVcblx0XHRpZiAoZ3JvdXApIHtcblx0XHRcdGlmIChjaGFydC5pbnZlcnRlZCkge1xuXHRcdFx0XHRncm91cC5hdHRyKHtcblx0XHRcdFx0XHR3aWR0aDogY2hhcnQucGxvdFdpZHRoLFxuXHRcdFx0XHRcdGhlaWdodDogY2hhcnQucGxvdEhlaWdodFxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Z3JvdXAuYW5pbWF0ZSh7XG5cdFx0XHRcdHRyYW5zbGF0ZVg6IHBpY2soeEF4aXMgJiYgeEF4aXMubGVmdCwgY2hhcnQucGxvdExlZnQpLFxuXHRcdFx0XHR0cmFuc2xhdGVZOiBwaWNrKHlBeGlzICYmIHlBeGlzLnRvcCwgY2hhcnQucGxvdFRvcClcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHNlcmllcy50cmFuc2xhdGUoKTtcblx0XHRpZiAoc2VyaWVzLnNldFRvb2x0aXBQb2ludHMpIHtcblx0XHRcdHNlcmllcy5zZXRUb29sdGlwUG9pbnRzKHRydWUpO1xuXHRcdH1cblx0XHRzZXJpZXMucmVuZGVyKCk7XG5cblx0XHRpZiAod2FzRGlydHlEYXRhKSB7XG5cdFx0XHRmaXJlRXZlbnQoc2VyaWVzLCAndXBkYXRlZERhdGEnKTtcblx0XHR9XG5cdH1cbn07IC8vIGVuZCBTZXJpZXMgcHJvdG90eXBlXG5cbi8qKlxuICogVGhlIGNsYXNzIGZvciBzdGFjayBpdGVtc1xuICovXG5mdW5jdGlvbiBTdGFja0l0ZW0oYXhpcywgb3B0aW9ucywgaXNOZWdhdGl2ZSwgeCwgc3RhY2tPcHRpb24pIHtcblx0XG5cdHZhciBpbnZlcnRlZCA9IGF4aXMuY2hhcnQuaW52ZXJ0ZWQ7XG5cblx0dGhpcy5heGlzID0gYXhpcztcblxuXHQvLyBUZWxscyBpZiB0aGUgc3RhY2sgaXMgbmVnYXRpdmVcblx0dGhpcy5pc05lZ2F0aXZlID0gaXNOZWdhdGl2ZTtcblxuXHQvLyBTYXZlIHRoZSBvcHRpb25zIHRvIGJlIGFibGUgdG8gc3R5bGUgdGhlIGxhYmVsXG5cdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cblx0Ly8gU2F2ZSB0aGUgeCB2YWx1ZSB0byBiZSBhYmxlIHRvIHBvc2l0aW9uIHRoZSBsYWJlbCBsYXRlclxuXHR0aGlzLnggPSB4O1xuXG5cdC8vIEluaXRpYWxpemUgdG90YWwgdmFsdWVcblx0dGhpcy50b3RhbCA9IG51bGw7XG5cblx0Ly8gVGhpcyB3aWxsIGtlZXAgZWFjaCBwb2ludHMnIGV4dHJlbWVzIHN0b3JlZCBieSBzZXJpZXMuaW5kZXggYW5kIHBvaW50IGluZGV4XG5cdHRoaXMucG9pbnRzID0ge307XG5cblx0Ly8gU2F2ZSB0aGUgc3RhY2sgb3B0aW9uIG9uIHRoZSBzZXJpZXMgY29uZmlndXJhdGlvbiBvYmplY3QsIGFuZCB3aGV0aGVyIHRvIHRyZWF0IGl0IGFzIHBlcmNlbnRcblx0dGhpcy5zdGFjayA9IHN0YWNrT3B0aW9uO1xuXG5cdC8vIFRoZSBhbGlnbiBvcHRpb25zIGFuZCB0ZXh0IGFsaWduIHZhcmllcyBvbiB3aGV0aGVyIHRoZSBzdGFjayBpcyBuZWdhdGl2ZSBhbmRcblx0Ly8gaWYgdGhlIGNoYXJ0IGlzIGludmVydGVkIG9yIG5vdC5cblx0Ly8gRmlyc3QgdGVzdCB0aGUgdXNlciBzdXBwbGllZCB2YWx1ZSwgdGhlbiB1c2UgdGhlIGR5bmFtaWMuXG5cdHRoaXMuYWxpZ25PcHRpb25zID0ge1xuXHRcdGFsaWduOiBvcHRpb25zLmFsaWduIHx8IChpbnZlcnRlZCA/IChpc05lZ2F0aXZlID8gJ2xlZnQnIDogJ3JpZ2h0JykgOiAnY2VudGVyJyksXG5cdFx0dmVydGljYWxBbGlnbjogb3B0aW9ucy52ZXJ0aWNhbEFsaWduIHx8IChpbnZlcnRlZCA/ICdtaWRkbGUnIDogKGlzTmVnYXRpdmUgPyAnYm90dG9tJyA6ICd0b3AnKSksXG5cdFx0eTogcGljayhvcHRpb25zLnksIGludmVydGVkID8gNCA6IChpc05lZ2F0aXZlID8gMTQgOiAtNikpLFxuXHRcdHg6IHBpY2sob3B0aW9ucy54LCBpbnZlcnRlZCA/IChpc05lZ2F0aXZlID8gLTYgOiA2KSA6IDApXG5cdH07XG5cblx0dGhpcy50ZXh0QWxpZ24gPSBvcHRpb25zLnRleHRBbGlnbiB8fCAoaW52ZXJ0ZWQgPyAoaXNOZWdhdGl2ZSA/ICdyaWdodCcgOiAnbGVmdCcpIDogJ2NlbnRlcicpO1xufVxuXG5TdGFja0l0ZW0ucHJvdG90eXBlID0ge1xuXHRkZXN0cm95OiBmdW5jdGlvbiAoKSB7XG5cdFx0ZGVzdHJveU9iamVjdFByb3BlcnRpZXModGhpcywgdGhpcy5heGlzKTtcblx0fSxcblxuXHQvKipcblx0ICogUmVuZGVycyB0aGUgc3RhY2sgdG90YWwgbGFiZWwgYW5kIGFkZHMgaXQgdG8gdGhlIHN0YWNrIGxhYmVsIGdyb3VwLlxuXHQgKi9cblx0cmVuZGVyOiBmdW5jdGlvbiAoZ3JvdXApIHtcblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdGZvcm1hdE9wdGlvbiA9IG9wdGlvbnMuZm9ybWF0LFxuXHRcdFx0c3RyID0gZm9ybWF0T3B0aW9uID9cblx0XHRcdFx0Zm9ybWF0KGZvcm1hdE9wdGlvbiwgdGhpcykgOiBcblx0XHRcdFx0b3B0aW9ucy5mb3JtYXR0ZXIuY2FsbCh0aGlzKTsgIC8vIGZvcm1hdCB0aGUgdGV4dCBpbiB0aGUgbGFiZWxcblxuXHRcdC8vIENoYW5nZSB0aGUgdGV4dCB0byByZWZsZWN0IHRoZSBuZXcgdG90YWwgYW5kIHNldCB2aXNpYmlsaXR5IHRvIGhpZGRlbiBpbiBjYXNlIHRoZSBzZXJpZSBpcyBoaWRkZW5cblx0XHRpZiAodGhpcy5sYWJlbCkge1xuXHRcdFx0dGhpcy5sYWJlbC5hdHRyKHt0ZXh0OiBzdHIsIHZpc2liaWxpdHk6IEhJRERFTn0pO1xuXHRcdC8vIENyZWF0ZSBuZXcgbGFiZWxcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5sYWJlbCA9XG5cdFx0XHRcdHRoaXMuYXhpcy5jaGFydC5yZW5kZXJlci50ZXh0KHN0ciwgbnVsbCwgbnVsbCwgb3B0aW9ucy51c2VIVE1MKVx0XHQvLyBkdW1teSBwb3NpdGlvbnMsIGFjdHVhbCBwb3NpdGlvbiB1cGRhdGVkIHdpdGggc2V0T2Zmc2V0IG1ldGhvZCBpbiBjb2x1bW5zZXJpZXNcblx0XHRcdFx0XHQuY3NzKG9wdGlvbnMuc3R5bGUpXHRcdFx0XHQvLyBhcHBseSBzdHlsZVxuXHRcdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRcdGFsaWduOiB0aGlzLnRleHRBbGlnbixcdFx0XHRcdC8vIGZpeCB0aGUgdGV4dC1hbmNob3Jcblx0XHRcdFx0XHRcdHJvdGF0aW9uOiBvcHRpb25zLnJvdGF0aW9uLFx0Ly8gcm90YXRpb25cblx0XHRcdFx0XHRcdHZpc2liaWxpdHk6IEhJRERFTlx0XHRcdFx0XHQvLyBoaWRkZW4gdW50aWwgc2V0T2Zmc2V0IGlzIGNhbGxlZFxuXHRcdFx0XHRcdH0pXHRcdFx0XHRcblx0XHRcdFx0XHQuYWRkKGdyb3VwKTtcdFx0XHRcdFx0XHRcdC8vIGFkZCB0byB0aGUgbGFiZWxzLWdyb3VwXG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXRzIHRoZSBvZmZzZXQgdGhhdCB0aGUgc3RhY2sgaGFzIGZyb20gdGhlIHggdmFsdWUgYW5kIHJlcG9zaXRpb25zIHRoZSBsYWJlbC5cblx0ICovXG5cdHNldE9mZnNldDogZnVuY3Rpb24gKHhPZmZzZXQsIHhXaWR0aCkge1xuXHRcdHZhciBzdGFja0l0ZW0gPSB0aGlzLFxuXHRcdFx0YXhpcyA9IHN0YWNrSXRlbS5heGlzLFxuXHRcdFx0Y2hhcnQgPSBheGlzLmNoYXJ0LFxuXHRcdFx0aW52ZXJ0ZWQgPSBjaGFydC5pbnZlcnRlZCxcblx0XHRcdG5lZyA9IHRoaXMuaXNOZWdhdGl2ZSxcdFx0XHRcdFx0XHRcdC8vIHNwZWNpYWwgdHJlYXRtZW50IGlzIG5lZWRlZCBmb3IgbmVnYXRpdmUgc3RhY2tzXG5cdFx0XHR5ID0gYXhpcy50cmFuc2xhdGUoYXhpcy51c2VQZXJjZW50YWdlID8gMTAwIDogdGhpcy50b3RhbCwgMCwgMCwgMCwgMSksIC8vIHN0YWNrIHZhbHVlIHRyYW5zbGF0ZWQgbWFwcGVkIHRvIGNoYXJ0IGNvb3JkaW5hdGVzXG5cdFx0XHR5WmVybyA9IGF4aXMudHJhbnNsYXRlKDApLFx0XHRcdFx0XHRcdC8vIHN0YWNrIG9yaWdpblxuXHRcdFx0aCA9IG1hdGhBYnMoeSAtIHlaZXJvKSxcdFx0XHRcdFx0XHRcdC8vIHN0YWNrIGhlaWdodFxuXHRcdFx0eCA9IGNoYXJ0LnhBeGlzWzBdLnRyYW5zbGF0ZSh0aGlzLngpICsgeE9mZnNldCxcdC8vIHN0YWNrIHggcG9zaXRpb25cblx0XHRcdHBsb3RIZWlnaHQgPSBjaGFydC5wbG90SGVpZ2h0LFxuXHRcdFx0c3RhY2tCb3ggPSB7XHQvLyB0aGlzIGlzIHRoZSBib3ggZm9yIHRoZSBjb21wbGV0ZSBzdGFja1xuXHRcdFx0XHR4OiBpbnZlcnRlZCA/IChuZWcgPyB5IDogeSAtIGgpIDogeCxcblx0XHRcdFx0eTogaW52ZXJ0ZWQgPyBwbG90SGVpZ2h0IC0geCAtIHhXaWR0aCA6IChuZWcgPyAocGxvdEhlaWdodCAtIHkgLSBoKSA6IHBsb3RIZWlnaHQgLSB5KSxcblx0XHRcdFx0d2lkdGg6IGludmVydGVkID8gaCA6IHhXaWR0aCxcblx0XHRcdFx0aGVpZ2h0OiBpbnZlcnRlZCA/IHhXaWR0aCA6IGhcblx0XHRcdH0sXG5cdFx0XHRsYWJlbCA9IHRoaXMubGFiZWwsXG5cdFx0XHRhbGlnbkF0dHI7XG5cdFx0XG5cdFx0aWYgKGxhYmVsKSB7XG5cdFx0XHRsYWJlbC5hbGlnbih0aGlzLmFsaWduT3B0aW9ucywgbnVsbCwgc3RhY2tCb3gpO1x0Ly8gYWxpZ24gdGhlIGxhYmVsIHRvIHRoZSBib3hcblx0XHRcdFx0XG5cdFx0XHQvLyBTZXQgdmlzaWJpbGl0eSAoIzY3OClcblx0XHRcdGFsaWduQXR0ciA9IGxhYmVsLmFsaWduQXR0cjtcblx0XHRcdGxhYmVsW3RoaXMub3B0aW9ucy5jcm9wID09PSBmYWxzZSB8fCBjaGFydC5pc0luc2lkZVBsb3QoYWxpZ25BdHRyLngsIGFsaWduQXR0ci55KSA/ICdzaG93JyA6ICdoaWRlJ10odHJ1ZSk7XG5cdFx0fVxuXHR9XG59O1xuXG5cbi8vIFN0YWNraW5nIG1ldGhvZHMgZGVmaW5lZCBvbiB0aGUgQXhpcyBwcm90b3R5cGVcblxuLyoqXG4gKiBCdWlsZCB0aGUgc3RhY2tzIGZyb20gdG9wIGRvd25cbiAqL1xuQXhpcy5wcm90b3R5cGUuYnVpbGRTdGFja3MgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBzZXJpZXMgPSB0aGlzLnNlcmllcyxcblx0XHRyZXZlcnNlZFN0YWNrcyA9IHBpY2sodGhpcy5vcHRpb25zLnJldmVyc2VkU3RhY2tzLCB0cnVlKSxcblx0XHRpID0gc2VyaWVzLmxlbmd0aDtcblx0aWYgKCF0aGlzLmlzWEF4aXMpIHtcblx0XHR0aGlzLnVzZVBlcmNlbnRhZ2UgPSBmYWxzZTtcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRzZXJpZXNbcmV2ZXJzZWRTdGFja3MgPyBpIDogc2VyaWVzLmxlbmd0aCAtIGkgLSAxXS5zZXRTdGFja2VkUG9pbnRzKCk7XG5cdFx0fVxuXHRcdC8vIExvb3AgdXAgYWdhaW4gdG8gY29tcHV0ZSBwZXJjZW50IHN0YWNrXG5cdFx0aWYgKHRoaXMudXNlUGVyY2VudGFnZSkge1xuXHRcdFx0Zm9yIChpID0gMDsgaSA8IHNlcmllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRzZXJpZXNbaV0uc2V0UGVyY2VudFN0YWNrcygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuQXhpcy5wcm90b3R5cGUucmVuZGVyU3RhY2tUb3RhbHMgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBheGlzID0gdGhpcyxcblx0XHRjaGFydCA9IGF4aXMuY2hhcnQsXG5cdFx0cmVuZGVyZXIgPSBjaGFydC5yZW5kZXJlcixcblx0XHRzdGFja3MgPSBheGlzLnN0YWNrcyxcblx0XHRzdGFja0tleSwgXG5cdFx0b25lU3RhY2ssIFxuXHRcdHN0YWNrQ2F0ZWdvcnksXG5cdFx0c3RhY2tUb3RhbEdyb3VwID0gYXhpcy5zdGFja1RvdGFsR3JvdXA7XG5cblx0Ly8gQ3JlYXRlIGEgc2VwYXJhdGUgZ3JvdXAgZm9yIHRoZSBzdGFjayB0b3RhbCBsYWJlbHNcblx0aWYgKCFzdGFja1RvdGFsR3JvdXApIHtcblx0XHRheGlzLnN0YWNrVG90YWxHcm91cCA9IHN0YWNrVG90YWxHcm91cCA9XG5cdFx0XHRyZW5kZXJlci5nKCdzdGFjay1sYWJlbHMnKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0dmlzaWJpbGl0eTogVklTSUJMRSxcblx0XHRcdFx0XHR6SW5kZXg6IDZcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZCgpO1xuXHR9XG5cblx0Ly8gcGxvdExlZnQvVG9wIHdpbGwgY2hhbmdlIHdoZW4geSBheGlzIGdldHMgd2lkZXIgc28gd2UgbmVlZCB0byB0cmFuc2xhdGUgdGhlXG5cdC8vIHN0YWNrVG90YWxHcm91cCBhdCBldmVyeSByZW5kZXIgY2FsbC4gU2VlIGJ1ZyAjNTA2IGFuZCAjNTE2XG5cdHN0YWNrVG90YWxHcm91cC50cmFuc2xhdGUoY2hhcnQucGxvdExlZnQsIGNoYXJ0LnBsb3RUb3ApO1xuXG5cdC8vIFJlbmRlciBlYWNoIHN0YWNrIHRvdGFsXG5cdGZvciAoc3RhY2tLZXkgaW4gc3RhY2tzKSB7XG5cdFx0b25lU3RhY2sgPSBzdGFja3Nbc3RhY2tLZXldO1xuXHRcdGZvciAoc3RhY2tDYXRlZ29yeSBpbiBvbmVTdGFjaykge1xuXHRcdFx0b25lU3RhY2tbc3RhY2tDYXRlZ29yeV0ucmVuZGVyKHN0YWNrVG90YWxHcm91cCk7XG5cdFx0fVxuXHR9XG59O1xuXG5cbi8vIFN0YWNraW5nIG1ldGhvZHMgZGVmbmllZCBmb3IgU2VyaWVzIHByb3RvdHlwZVxuXG4vKipcbiAqIEFkZHMgc2VyaWVzJyBwb2ludHMgdmFsdWUgdG8gY29ycmVzcG9uZGluZyBzdGFja1xuICovXG5TZXJpZXMucHJvdG90eXBlLnNldFN0YWNrZWRQb2ludHMgPSBmdW5jdGlvbiAoKSB7XG5cdGlmICghdGhpcy5vcHRpb25zLnN0YWNraW5nIHx8ICh0aGlzLnZpc2libGUgIT09IHRydWUgJiYgdGhpcy5jaGFydC5vcHRpb25zLmNoYXJ0Lmlnbm9yZUhpZGRlblNlcmllcyAhPT0gZmFsc2UpKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0eERhdGEgPSBzZXJpZXMucHJvY2Vzc2VkWERhdGEsXG5cdFx0eURhdGEgPSBzZXJpZXMucHJvY2Vzc2VkWURhdGEsXG5cdFx0c3RhY2tlZFlEYXRhID0gW10sXG5cdFx0eURhdGFMZW5ndGggPSB5RGF0YS5sZW5ndGgsXG5cdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdHRocmVzaG9sZCA9IHNlcmllc09wdGlvbnMudGhyZXNob2xkLFxuXHRcdHN0YWNrT3B0aW9uID0gc2VyaWVzT3B0aW9ucy5zdGFjayxcblx0XHRzdGFja2luZyA9IHNlcmllc09wdGlvbnMuc3RhY2tpbmcsXG5cdFx0c3RhY2tLZXkgPSBzZXJpZXMuc3RhY2tLZXksXG5cdFx0bmVnS2V5ID0gJy0nICsgc3RhY2tLZXksXG5cdFx0bmVnU3RhY2tzID0gc2VyaWVzLm5lZ1N0YWNrcyxcblx0XHR5QXhpcyA9IHNlcmllcy55QXhpcyxcblx0XHRzdGFja3MgPSB5QXhpcy5zdGFja3MsXG5cdFx0b2xkU3RhY2tzID0geUF4aXMub2xkU3RhY2tzLFxuXHRcdGlzTmVnYXRpdmUsXG5cdFx0c3RhY2ssXG5cdFx0b3RoZXIsXG5cdFx0a2V5LFxuXHRcdHBvaW50S2V5LFxuXHRcdGksXG5cdFx0eCxcblx0XHR5O1xuXG5cdC8vIGxvb3Agb3ZlciB0aGUgbm9uLW51bGwgeSB2YWx1ZXMgYW5kIHJlYWQgdGhlbSBpbnRvIGEgbG9jYWwgYXJyYXlcblx0Zm9yIChpID0gMDsgaSA8IHlEYXRhTGVuZ3RoOyBpKyspIHtcblx0XHR4ID0geERhdGFbaV07XG5cdFx0eSA9IHlEYXRhW2ldO1xuXHRcdHBvaW50S2V5ID0gc2VyaWVzLmluZGV4ICsgJywnICsgaTtcblxuXHRcdC8vIFJlYWQgc3RhY2tlZCB2YWx1ZXMgaW50byBhIHN0YWNrIGJhc2VkIG9uIHRoZSB4IHZhbHVlLFxuXHRcdC8vIHRoZSBzaWduIG9mIHkgYW5kIHRoZSBzdGFjayBrZXkuIFN0YWNraW5nIGlzIGFsc28gaGFuZGxlZCBmb3IgbnVsbCB2YWx1ZXMgKCM3MzkpXG5cdFx0aXNOZWdhdGl2ZSA9IG5lZ1N0YWNrcyAmJiB5IDwgdGhyZXNob2xkO1xuXHRcdGtleSA9IGlzTmVnYXRpdmUgPyBuZWdLZXkgOiBzdGFja0tleTtcblxuXHRcdC8vIENyZWF0ZSBlbXB0eSBvYmplY3QgZm9yIHRoaXMgc3RhY2sgaWYgaXQgZG9lc24ndCBleGlzdCB5ZXRcblx0XHRpZiAoIXN0YWNrc1trZXldKSB7XG5cdFx0XHRzdGFja3Nba2V5XSA9IHt9O1xuXHRcdH1cblxuXHRcdC8vIEluaXRpYWxpemUgU3RhY2tJdGVtIGZvciB0aGlzIHhcblx0XHRpZiAoIXN0YWNrc1trZXldW3hdKSB7XG5cdFx0XHRpZiAob2xkU3RhY2tzW2tleV0gJiYgb2xkU3RhY2tzW2tleV1beF0pIHtcblx0XHRcdFx0c3RhY2tzW2tleV1beF0gPSBvbGRTdGFja3Nba2V5XVt4XTtcblx0XHRcdFx0c3RhY2tzW2tleV1beF0udG90YWwgPSBudWxsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0c3RhY2tzW2tleV1beF0gPSBuZXcgU3RhY2tJdGVtKHlBeGlzLCB5QXhpcy5vcHRpb25zLnN0YWNrTGFiZWxzLCBpc05lZ2F0aXZlLCB4LCBzdGFja09wdGlvbik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIFN0YWNrSXRlbSBkb2Vzbid0IGV4aXN0LCBjcmVhdGUgaXQgZmlyc3Rcblx0XHRzdGFjayA9IHN0YWNrc1trZXldW3hdO1xuXHRcdHN0YWNrLnBvaW50c1twb2ludEtleV0gPSBbc3RhY2suY3VtIHx8IDBdO1xuXG5cdFx0Ly8gQWRkIHZhbHVlIHRvIHRoZSBzdGFjayB0b3RhbFxuXHRcdGlmIChzdGFja2luZyA9PT0gJ3BlcmNlbnQnKSB7XG5cblx0XHRcdC8vIFBlcmNlbnQgc3RhY2tlZCBjb2x1bW4sIHRvdGFscyBhcmUgdGhlIHNhbWUgZm9yIHRoZSBwb3NpdGl2ZSBhbmQgbmVnYXRpdmUgc3RhY2tzXG5cdFx0XHRvdGhlciA9IGlzTmVnYXRpdmUgPyBzdGFja0tleSA6IG5lZ0tleTtcblx0XHRcdGlmIChuZWdTdGFja3MgJiYgc3RhY2tzW290aGVyXSAmJiBzdGFja3Nbb3RoZXJdW3hdKSB7XG5cdFx0XHRcdG90aGVyID0gc3RhY2tzW290aGVyXVt4XTtcblx0XHRcdFx0c3RhY2sudG90YWwgPSBvdGhlci50b3RhbCA9IG1hdGhNYXgob3RoZXIudG90YWwsIHN0YWNrLnRvdGFsKSArIG1hdGhBYnMoeSkgfHwgMDtcblxuXHRcdFx0Ly8gUGVyY2VudCBzdGFja2VkIGFyZWFzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzdGFjay50b3RhbCA9IGNvcnJlY3RGbG9hdChzdGFjay50b3RhbCArIChtYXRoQWJzKHkpIHx8IDApKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0c3RhY2sudG90YWwgPSBjb3JyZWN0RmxvYXQoc3RhY2sudG90YWwgKyAoeSB8fCAwKSk7XG5cdFx0fVxuXG5cdFx0c3RhY2suY3VtID0gKHN0YWNrLmN1bSB8fCAwKSArICh5IHx8IDApO1xuXG5cdFx0c3RhY2sucG9pbnRzW3BvaW50S2V5XS5wdXNoKHN0YWNrLmN1bSk7XG5cdFx0c3RhY2tlZFlEYXRhW2ldID0gc3RhY2suY3VtO1xuXG5cdH1cblxuXHRpZiAoc3RhY2tpbmcgPT09ICdwZXJjZW50Jykge1xuXHRcdHlBeGlzLnVzZVBlcmNlbnRhZ2UgPSB0cnVlO1xuXHR9XG5cblx0dGhpcy5zdGFja2VkWURhdGEgPSBzdGFja2VkWURhdGE7IC8vIFRvIGJlIHVzZWQgaW4gZ2V0RXh0cmVtZXNcblxuXHQvLyBSZXNldCBvbGQgc3RhY2tzXG5cdHlBeGlzLm9sZFN0YWNrcyA9IHt9O1xufTtcblxuLyoqXG4gKiBJdGVyYXRlIG92ZXIgYWxsIHN0YWNrcyBhbmQgY29tcHV0ZSB0aGUgYWJzb2x1dGUgdmFsdWVzIHRvIHBlcmNlbnRcbiAqL1xuU2VyaWVzLnByb3RvdHlwZS5zZXRQZXJjZW50U3RhY2tzID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRzdGFja0tleSA9IHNlcmllcy5zdGFja0tleSxcblx0XHRzdGFja3MgPSBzZXJpZXMueUF4aXMuc3RhY2tzLFxuXHRcdHByb2Nlc3NlZFhEYXRhID0gc2VyaWVzLnByb2Nlc3NlZFhEYXRhO1xuXG5cdGVhY2goW3N0YWNrS2V5LCAnLScgKyBzdGFja0tleV0sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHR2YXIgaSA9IHByb2Nlc3NlZFhEYXRhLmxlbmd0aCxcblx0XHRcdHgsXG5cdFx0XHRzdGFjayxcblx0XHRcdHBvaW50RXh0cmVtZXMsXG5cdFx0XHR0b3RhbEZhY3RvcjtcblxuXHRcdHdoaWxlIChpLS0pIHtcblx0XHRcdHggPSBwcm9jZXNzZWRYRGF0YVtpXTtcblx0XHRcdHN0YWNrID0gc3RhY2tzW2tleV0gJiYgc3RhY2tzW2tleV1beF07XG5cdFx0XHRwb2ludEV4dHJlbWVzID0gc3RhY2sgJiYgc3RhY2sucG9pbnRzW3Nlcmllcy5pbmRleCArICcsJyArIGldO1xuXHRcdFx0aWYgKHBvaW50RXh0cmVtZXMpIHtcblx0XHRcdFx0dG90YWxGYWN0b3IgPSBzdGFjay50b3RhbCA/IDEwMCAvIHN0YWNrLnRvdGFsIDogMDtcblx0XHRcdFx0cG9pbnRFeHRyZW1lc1swXSA9IGNvcnJlY3RGbG9hdChwb2ludEV4dHJlbWVzWzBdICogdG90YWxGYWN0b3IpOyAvLyBZIGJvdHRvbSB2YWx1ZVxuXHRcdFx0XHRwb2ludEV4dHJlbWVzWzFdID0gY29ycmVjdEZsb2F0KHBvaW50RXh0cmVtZXNbMV0gKiB0b3RhbEZhY3Rvcik7IC8vIFkgdmFsdWVcblx0XHRcdFx0c2VyaWVzLnN0YWNrZWRZRGF0YVtpXSA9IHBvaW50RXh0cmVtZXNbMV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn07XG5cbi8vIEV4dGVuZCB0aGUgQ2hhcnQgcHJvdG90eXBlIGZvciBkeW5hbWljIG1ldGhvZHNcbmV4dGVuZChDaGFydC5wcm90b3R5cGUsIHtcblxuXHQvKipcblx0ICogQWRkIGEgc2VyaWVzIGR5bmFtaWNhbGx5IGFmdGVyICB0aW1lXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBjb25maWcgb3B0aW9uc1xuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhdyBXaGV0aGVyIHRvIHJlZHJhdyB0aGUgY2hhcnQgYWZ0ZXIgYWRkaW5nLiBEZWZhdWx0cyB0byB0cnVlLlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBhbmltYXRpb24gV2hldGhlciB0byBhcHBseSBhbmltYXRpb24sIGFuZCBvcHRpb25hbGx5IGFuaW1hdGlvblxuXHQgKiAgICBjb25maWd1cmF0aW9uXG5cdCAqXG5cdCAqIEByZXR1cm4ge09iamVjdH0gc2VyaWVzIFRoZSBuZXdseSBjcmVhdGVkIHNlcmllcyBvYmplY3Rcblx0ICovXG5cdGFkZFNlcmllczogZnVuY3Rpb24gKG9wdGlvbnMsIHJlZHJhdywgYW5pbWF0aW9uKSB7XG5cdFx0dmFyIHNlcmllcyxcblx0XHRcdGNoYXJ0ID0gdGhpcztcblxuXHRcdGlmIChvcHRpb25zKSB7XG5cdFx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7IC8vIGRlZmF1bHRzIHRvIHRydWVcblxuXHRcdFx0ZmlyZUV2ZW50KGNoYXJ0LCAnYWRkU2VyaWVzJywgeyBvcHRpb25zOiBvcHRpb25zIH0sIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0c2VyaWVzID0gY2hhcnQuaW5pdFNlcmllcyhvcHRpb25zKTtcblxuXHRcdFx0XHRjaGFydC5pc0RpcnR5TGVnZW5kID0gdHJ1ZTsgLy8gdGhlIHNlcmllcyBhcnJheSBpcyBvdXQgb2Ygc3luYyB3aXRoIHRoZSBkaXNwbGF5XG5cdFx0XHRcdGNoYXJ0LmxpbmtTZXJpZXMoKTtcblx0XHRcdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0XHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gc2VyaWVzO1xuXHR9LFxuXG5cdC8qKlxuICAgICAqIEFkZCBhbiBheGlzIHRvIHRoZSBjaGFydFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBheGlzIG9wdGlvblxuICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNYIFdoZXRoZXIgaXQgaXMgYW4gWCBheGlzIG9yIGEgdmFsdWUgYXhpc1xuICAgICAqL1xuXHRhZGRBeGlzOiBmdW5jdGlvbiAob3B0aW9ucywgaXNYLCByZWRyYXcsIGFuaW1hdGlvbikge1xuXHRcdHZhciBrZXkgPSBpc1ggPyAneEF4aXMnIDogJ3lBeGlzJyxcblx0XHRcdGNoYXJ0T3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdGF4aXM7XG5cblx0XHQvKmpzbGludCB1bnVzZWQ6IGZhbHNlKi9cblx0XHRheGlzID0gbmV3IEF4aXModGhpcywgbWVyZ2Uob3B0aW9ucywge1xuXHRcdFx0aW5kZXg6IHRoaXNba2V5XS5sZW5ndGgsXG5cdFx0XHRpc1g6IGlzWFxuXHRcdH0pKTtcblx0XHQvKmpzbGludCB1bnVzZWQ6IHRydWUqL1xuXG5cdFx0Ly8gUHVzaCB0aGUgbmV3IGF4aXMgb3B0aW9ucyB0byB0aGUgY2hhcnQgb3B0aW9uc1xuXHRcdGNoYXJ0T3B0aW9uc1trZXldID0gc3BsYXQoY2hhcnRPcHRpb25zW2tleV0gfHwge30pO1xuXHRcdGNoYXJ0T3B0aW9uc1trZXldLnB1c2gob3B0aW9ucyk7XG5cblx0XHRpZiAocGljayhyZWRyYXcsIHRydWUpKSB7XG5cdFx0XHR0aGlzLnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRGltIHRoZSBjaGFydCBhbmQgc2hvdyBhIGxvYWRpbmcgdGV4dCBvciBzeW1ib2xcblx0ICogQHBhcmFtIHtTdHJpbmd9IHN0ciBBbiBvcHRpb25hbCB0ZXh0IHRvIHNob3cgaW4gdGhlIGxvYWRpbmcgbGFiZWwgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBvbmVcblx0ICovXG5cdHNob3dMb2FkaW5nOiBmdW5jdGlvbiAoc3RyKSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBjaGFydC5vcHRpb25zLFxuXHRcdFx0bG9hZGluZ0RpdiA9IGNoYXJ0LmxvYWRpbmdEaXYsXG5cdFx0XHRsb2FkaW5nT3B0aW9ucyA9IG9wdGlvbnMubG9hZGluZyxcblx0XHRcdHNldExvYWRpbmdTaXplID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAobG9hZGluZ0Rpdikge1xuXHRcdFx0XHRcdGNzcyhsb2FkaW5nRGl2LCB7XG5cdFx0XHRcdFx0XHRsZWZ0OiBjaGFydC5wbG90TGVmdCArIFBYLFxuXHRcdFx0XHRcdFx0dG9wOiBjaGFydC5wbG90VG9wICsgUFgsXG5cdFx0XHRcdFx0XHR3aWR0aDogY2hhcnQucGxvdFdpZHRoICsgUFgsXG5cdFx0XHRcdFx0XHRoZWlnaHQ6IGNoYXJ0LnBsb3RIZWlnaHQgKyBQWFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gY3JlYXRlIHRoZSBsYXllciBhdCB0aGUgZmlyc3QgY2FsbFxuXHRcdGlmICghbG9hZGluZ0Rpdikge1xuXHRcdFx0Y2hhcnQubG9hZGluZ0RpdiA9IGxvYWRpbmdEaXYgPSBjcmVhdGVFbGVtZW50KERJViwge1xuXHRcdFx0XHRjbGFzc05hbWU6IFBSRUZJWCArICdsb2FkaW5nJ1xuXHRcdFx0fSwgZXh0ZW5kKGxvYWRpbmdPcHRpb25zLnN0eWxlLCB7XG5cdFx0XHRcdHpJbmRleDogMTAsXG5cdFx0XHRcdGRpc3BsYXk6IE5PTkVcblx0XHRcdH0pLCBjaGFydC5jb250YWluZXIpO1xuXG5cdFx0XHRjaGFydC5sb2FkaW5nU3BhbiA9IGNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdCdzcGFuJyxcblx0XHRcdFx0bnVsbCxcblx0XHRcdFx0bG9hZGluZ09wdGlvbnMubGFiZWxTdHlsZSxcblx0XHRcdFx0bG9hZGluZ0RpdlxuXHRcdFx0KTtcblx0XHRcdGFkZEV2ZW50KGNoYXJ0LCAncmVkcmF3Jywgc2V0TG9hZGluZ1NpemUpOyAvLyAjMTA4MFxuXHRcdH1cblxuXHRcdC8vIHVwZGF0ZSB0ZXh0XG5cdFx0Y2hhcnQubG9hZGluZ1NwYW4uaW5uZXJIVE1MID0gc3RyIHx8IG9wdGlvbnMubGFuZy5sb2FkaW5nO1xuXG5cdFx0Ly8gc2hvdyBpdFxuXHRcdGlmICghY2hhcnQubG9hZGluZ1Nob3duKSB7XG5cdFx0XHRjc3MobG9hZGluZ0Rpdiwge1xuXHRcdFx0XHRvcGFjaXR5OiAwLFxuXHRcdFx0XHRkaXNwbGF5OiAnJ1x0XHRcdFx0XG5cdFx0XHR9KTtcblx0XHRcdGFuaW1hdGUobG9hZGluZ0Rpdiwge1xuXHRcdFx0XHRvcGFjaXR5OiBsb2FkaW5nT3B0aW9ucy5zdHlsZS5vcGFjaXR5XG5cdFx0XHR9LCB7XG5cdFx0XHRcdGR1cmF0aW9uOiBsb2FkaW5nT3B0aW9ucy5zaG93RHVyYXRpb24gfHwgMFxuXHRcdFx0fSk7XG5cdFx0XHRjaGFydC5sb2FkaW5nU2hvd24gPSB0cnVlO1xuXHRcdH1cblx0XHRzZXRMb2FkaW5nU2l6ZSgpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBIaWRlIHRoZSBsb2FkaW5nIGxheWVyXG5cdCAqL1xuXHRoaWRlTG9hZGluZzogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuXHRcdFx0bG9hZGluZ0RpdiA9IHRoaXMubG9hZGluZ0RpdjtcblxuXHRcdGlmIChsb2FkaW5nRGl2KSB7XG5cdFx0XHRhbmltYXRlKGxvYWRpbmdEaXYsIHtcblx0XHRcdFx0b3BhY2l0eTogMFxuXHRcdFx0fSwge1xuXHRcdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5sb2FkaW5nLmhpZGVEdXJhdGlvbiB8fCAxMDAsXG5cdFx0XHRcdGNvbXBsZXRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0Y3NzKGxvYWRpbmdEaXYsIHsgZGlzcGxheTogTk9ORSB9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRoaXMubG9hZGluZ1Nob3duID0gZmFsc2U7XG5cdH1cbn0pO1xuXG4vLyBleHRlbmQgdGhlIFBvaW50IHByb3RvdHlwZSBmb3IgZHluYW1pYyBtZXRob2RzXG5leHRlbmQoUG9pbnQucHJvdG90eXBlLCB7XG5cdC8qKlxuXHQgKiBVcGRhdGUgdGhlIHBvaW50IHdpdGggbmV3IG9wdGlvbnMgKHR5cGljYWxseSB4L3kgZGF0YSkgYW5kIG9wdGlvbmFsbHkgcmVkcmF3IHRoZSBzZXJpZXMuXG5cdCAqXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFBvaW50IG9wdGlvbnMgYXMgZGVmaW5lZCBpbiB0aGUgc2VyaWVzLmRhdGEgYXJyYXlcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0IG9yIHdhaXQgZm9yIGFuIGV4cGxpY2l0IGNhbGxcblx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gYW5pbWF0aW9uIFdoZXRoZXIgdG8gYXBwbHkgYW5pbWF0aW9uLCBhbmQgb3B0aW9uYWxseSBhbmltYXRpb25cblx0ICogICAgY29uZmlndXJhdGlvblxuXHQgKlxuXHQgKi9cblx0dXBkYXRlOiBmdW5jdGlvbiAob3B0aW9ucywgcmVkcmF3LCBhbmltYXRpb24sIHJ1bkV2ZW50KSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGdyYXBoaWMgPSBwb2ludC5ncmFwaGljLFxuXHRcdFx0aSxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0c2VyaWVzT3B0aW9ucyA9IHNlcmllcy5vcHRpb25zO1xuXG5cdFx0cmVkcmF3ID0gcGljayhyZWRyYXcsIHRydWUpO1xuXG5cdFx0ZnVuY3Rpb24gdXBkYXRlKCkge1xuXG5cdFx0XHRwb2ludC5hcHBseU9wdGlvbnMob3B0aW9ucyk7XG5cblx0XHRcdC8vIFVwZGF0ZSB2aXN1YWxzXG5cdFx0XHRpZiAoaXNPYmplY3Qob3B0aW9ucykgJiYgIWlzQXJyYXkob3B0aW9ucykpIHtcblx0XHRcdFx0Ly8gRGVmZXIgdGhlIGFjdHVhbCByZWRyYXcgdW50aWwgZ2V0QXR0cmlicyBoYXMgYmVlbiBjYWxsZWQgKCMzMjYwKVxuXHRcdFx0XHRwb2ludC5yZWRyYXcgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0aWYgKGdyYXBoaWMpIHtcblx0XHRcdFx0XHRcdGlmIChvcHRpb25zICYmIG9wdGlvbnMubWFya2VyICYmIG9wdGlvbnMubWFya2VyLnN5bWJvbCkge1xuXHRcdFx0XHRcdFx0XHRwb2ludC5ncmFwaGljID0gZ3JhcGhpYy5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRncmFwaGljLmF0dHIocG9pbnQucG9pbnRBdHRyW3BvaW50LnN0YXRlIHx8ICcnXSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChvcHRpb25zICYmIG9wdGlvbnMuZGF0YUxhYmVscyAmJiBwb2ludC5kYXRhTGFiZWwpIHsgLy8gIzI0Njhcblx0XHRcdFx0XHRcdHBvaW50LmRhdGFMYWJlbCA9IHBvaW50LmRhdGFMYWJlbC5kZXN0cm95KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvaW50LnJlZHJhdyA9IG51bGw7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdC8vIHJlY29yZCBjaGFuZ2VzIGluIHRoZSBwYXJhbGxlbCBhcnJheXNcblx0XHRcdGkgPSBwb2ludC5pbmRleDtcblx0XHRcdHNlcmllcy51cGRhdGVQYXJhbGxlbEFycmF5cyhwb2ludCwgaSk7XG5cblx0XHRcdHNlcmllc09wdGlvbnMuZGF0YVtpXSA9IHBvaW50Lm9wdGlvbnM7XG5cblx0XHRcdC8vIHJlZHJhd1xuXHRcdFx0c2VyaWVzLmlzRGlydHkgPSBzZXJpZXMuaXNEaXJ0eURhdGEgPSB0cnVlO1xuXHRcdFx0aWYgKCFzZXJpZXMuZml4ZWRCb3ggJiYgc2VyaWVzLmhhc0NhcnRlc2lhblNlcmllcykgeyAvLyAjMTkwNiwgIzIzMjBcblx0XHRcdFx0Y2hhcnQuaXNEaXJ0eUJveCA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChzZXJpZXNPcHRpb25zLmxlZ2VuZFR5cGUgPT09ICdwb2ludCcpIHsgLy8gIzE4MzEsICMxODg1XG5cdFx0XHRcdGNoYXJ0LmxlZ2VuZC5kZXN0cm95SXRlbShwb2ludCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAocmVkcmF3KSB7XG5cdFx0XHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgdGhlIGV2ZW50IHdpdGggYSBkZWZhdWx0IGhhbmRsZXIgb2YgZG9pbmcgdGhlIHVwZGF0ZVxuXHRcdGlmIChydW5FdmVudCA9PT0gZmFsc2UpIHsgLy8gV2hlbiBjYWxsZWQgZnJvbSBzZXREYXRhXG5cdFx0XHR1cGRhdGUoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cG9pbnQuZmlyZVBvaW50RXZlbnQoJ3VwZGF0ZScsIHsgb3B0aW9uczogb3B0aW9ucyB9LCB1cGRhdGUpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmVtb3ZlIGEgcG9pbnQgYW5kIG9wdGlvbmFsbHkgcmVkcmF3IHRoZSBzZXJpZXMgYW5kIGlmIG5lY2Vzc2FyeSB0aGUgYXhlc1xuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhdyBXaGV0aGVyIHRvIHJlZHJhdyB0aGUgY2hhcnQgb3Igd2FpdCBmb3IgYW4gZXhwbGljaXQgY2FsbFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBhbmltYXRpb24gV2hldGhlciB0byBhcHBseSBhbmltYXRpb24sIGFuZCBvcHRpb25hbGx5IGFuaW1hdGlvblxuXHQgKiAgICBjb25maWd1cmF0aW9uXG5cdCAqL1xuXHRyZW1vdmU6IGZ1bmN0aW9uIChyZWRyYXcsIGFuaW1hdGlvbikge1xuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRwb2ludHMgPSBzZXJpZXMucG9pbnRzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRpLFxuXHRcdFx0ZGF0YSA9IHNlcmllcy5kYXRhO1xuXG5cdFx0c2V0QW5pbWF0aW9uKGFuaW1hdGlvbiwgY2hhcnQpO1xuXHRcdHJlZHJhdyA9IHBpY2socmVkcmF3LCB0cnVlKTtcblxuXHRcdC8vIGZpcmUgdGhlIGV2ZW50IHdpdGggYSBkZWZhdWx0IGhhbmRsZXIgb2YgcmVtb3ZpbmcgdGhlIHBvaW50XG5cdFx0cG9pbnQuZmlyZVBvaW50RXZlbnQoJ3JlbW92ZScsIG51bGwsIGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0Ly8gc3BsaWNlIGFsbCB0aGUgcGFyYWxsZWwgYXJyYXlzXG5cdFx0XHRpID0gaW5BcnJheShwb2ludCwgZGF0YSk7XG5cdFx0XHRpZiAoZGF0YS5sZW5ndGggPT09IHBvaW50cy5sZW5ndGgpIHtcblx0XHRcdFx0cG9pbnRzLnNwbGljZShpLCAxKTtcblx0XHRcdH1cblx0XHRcdGRhdGEuc3BsaWNlKGksIDEpO1xuXHRcdFx0c2VyaWVzLm9wdGlvbnMuZGF0YS5zcGxpY2UoaSwgMSk7XG5cdFx0XHRzZXJpZXMudXBkYXRlUGFyYWxsZWxBcnJheXMocG9pbnQsICdzcGxpY2UnLCBpLCAxKTtcblxuXHRcdFx0cG9pbnQuZGVzdHJveSgpO1xuXG5cdFx0XHQvLyByZWRyYXdcblx0XHRcdHNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdHNlcmllcy5pc0RpcnR5RGF0YSA9IHRydWU7XG5cdFx0XHRpZiAocmVkcmF3KSB7XG5cdFx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KTtcblxuLy8gRXh0ZW5kIHRoZSBzZXJpZXMgcHJvdG90eXBlIGZvciBkeW5hbWljIG1ldGhvZHNcbmV4dGVuZChTZXJpZXMucHJvdG90eXBlLCB7XG5cdC8qKlxuXHQgKiBBZGQgYSBwb2ludCBkeW5hbWljYWxseSBhZnRlciBjaGFydCBsb2FkIHRpbWVcblx0ICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgUG9pbnQgb3B0aW9ucyBhcyBnaXZlbiBpbiBzZXJpZXMuZGF0YVxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhdyBXaGV0aGVyIHRvIHJlZHJhdyB0aGUgY2hhcnQgb3Igd2FpdCBmb3IgYW4gZXhwbGljaXQgY2FsbFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHNoaWZ0IElmIHNoaWZ0IGlzIHRydWUsIGEgcG9pbnQgaXMgc2hpZnRlZCBvZmYgdGhlIHN0YXJ0XG5cdCAqICAgIG9mIHRoZSBzZXJpZXMgYXMgb25lIGlzIGFwcGVuZGVkIHRvIHRoZSBlbmQuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IGFuaW1hdGlvbiBXaGV0aGVyIHRvIGFwcGx5IGFuaW1hdGlvbiwgYW5kIG9wdGlvbmFsbHkgYW5pbWF0aW9uXG5cdCAqICAgIGNvbmZpZ3VyYXRpb25cblx0ICovXG5cdGFkZFBvaW50OiBmdW5jdGlvbiAob3B0aW9ucywgcmVkcmF3LCBzaGlmdCwgYW5pbWF0aW9uKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRkYXRhID0gc2VyaWVzLmRhdGEsXG5cdFx0XHRncmFwaCA9IHNlcmllcy5ncmFwaCxcblx0XHRcdGFyZWEgPSBzZXJpZXMuYXJlYSxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0bmFtZXMgPSBzZXJpZXMueEF4aXMgJiYgc2VyaWVzLnhBeGlzLm5hbWVzLFxuXHRcdFx0Y3VycmVudFNoaWZ0ID0gKGdyYXBoICYmIGdyYXBoLnNoaWZ0KSB8fCAwLFxuXHRcdFx0ZGF0YU9wdGlvbnMgPSBzZXJpZXNPcHRpb25zLmRhdGEsXG5cdFx0XHRwb2ludCxcblx0XHRcdGlzSW5UaGVNaWRkbGUsXG5cdFx0XHR4RGF0YSA9IHNlcmllcy54RGF0YSxcblx0XHRcdHgsXG5cdFx0XHRpO1xuXG5cdFx0c2V0QW5pbWF0aW9uKGFuaW1hdGlvbiwgY2hhcnQpO1xuXG5cdFx0Ly8gTWFrZSBncmFwaCBhbmltYXRlIHNpZGV3YXlzXG5cdFx0aWYgKHNoaWZ0KSB7XG5cdFx0XHRlYWNoKFtncmFwaCwgYXJlYSwgc2VyaWVzLmdyYXBoTmVnLCBzZXJpZXMuYXJlYU5lZ10sIGZ1bmN0aW9uIChzaGFwZSkge1xuXHRcdFx0XHRpZiAoc2hhcGUpIHtcblx0XHRcdFx0XHRzaGFwZS5zaGlmdCA9IGN1cnJlbnRTaGlmdCArIDE7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoYXJlYSkge1xuXHRcdFx0YXJlYS5pc0FyZWEgPSB0cnVlOyAvLyBuZWVkZWQgaW4gYW5pbWF0aW9uLCBib3RoIHdpdGggYW5kIHdpdGhvdXQgc2hpZnRcblx0XHR9XG5cblx0XHQvLyBPcHRpb25hbCByZWRyYXcsIGRlZmF1bHRzIHRvIHRydWVcblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7XG5cblx0XHQvLyBHZXQgb3B0aW9ucyBhbmQgcHVzaCB0aGUgcG9pbnQgdG8geERhdGEsIHlEYXRhIGFuZCBzZXJpZXMub3B0aW9ucy4gSW4gc2VyaWVzLmdlbmVyYXRlUG9pbnRzXG5cdFx0Ly8gdGhlIFBvaW50IGluc3RhbmNlIHdpbGwgYmUgY3JlYXRlZCBvbiBkZW1hbmQgYW5kIHB1c2hlZCB0byB0aGUgc2VyaWVzLmRhdGEgYXJyYXkuXG5cdFx0cG9pbnQgPSB7IHNlcmllczogc2VyaWVzIH07XG5cdFx0c2VyaWVzLnBvaW50Q2xhc3MucHJvdG90eXBlLmFwcGx5T3B0aW9ucy5hcHBseShwb2ludCwgW29wdGlvbnNdKTtcblx0XHR4ID0gcG9pbnQueDtcblxuXHRcdC8vIEdldCB0aGUgaW5zZXJ0aW9uIHBvaW50XG5cdFx0aSA9IHhEYXRhLmxlbmd0aDtcblx0XHRpZiAoc2VyaWVzLnJlcXVpcmVTb3J0aW5nICYmIHggPCB4RGF0YVtpIC0gMV0pIHtcblx0XHRcdGlzSW5UaGVNaWRkbGUgPSB0cnVlO1xuXHRcdFx0d2hpbGUgKGkgJiYgeERhdGFbaSAtIDFdID4geCkge1xuXHRcdFx0XHRpLS07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0c2VyaWVzLnVwZGF0ZVBhcmFsbGVsQXJyYXlzKHBvaW50LCAnc3BsaWNlJywgaSwgMCwgMCk7IC8vIGluc2VydCB1bmRlZmluZWQgaXRlbVxuXHRcdHNlcmllcy51cGRhdGVQYXJhbGxlbEFycmF5cyhwb2ludCwgaSk7IC8vIHVwZGF0ZSBpdFxuXG5cdFx0aWYgKG5hbWVzICYmIHBvaW50Lm5hbWUpIHtcblx0XHRcdG5hbWVzW3hdID0gcG9pbnQubmFtZTtcblx0XHR9XG5cdFx0ZGF0YU9wdGlvbnMuc3BsaWNlKGksIDAsIG9wdGlvbnMpO1xuXG5cdFx0aWYgKGlzSW5UaGVNaWRkbGUpIHtcblx0XHRcdHNlcmllcy5kYXRhLnNwbGljZShpLCAwLCBudWxsKTtcblx0XHRcdHNlcmllcy5wcm9jZXNzRGF0YSgpO1xuXHRcdH1cblxuXHRcdC8vIEdlbmVyYXRlIHBvaW50cyB0byBiZSBhZGRlZCB0byB0aGUgbGVnZW5kICgjMTMyOSlcblx0XHRpZiAoc2VyaWVzT3B0aW9ucy5sZWdlbmRUeXBlID09PSAncG9pbnQnKSB7XG5cdFx0XHRzZXJpZXMuZ2VuZXJhdGVQb2ludHMoKTtcblx0XHR9XG5cblx0XHQvLyBTaGlmdCB0aGUgZmlyc3QgcG9pbnQgb2ZmIHRoZSBwYXJhbGxlbCBhcnJheXNcblx0XHQvLyB0b2RvOiBjb25zaWRlciBzZXJpZXMucmVtb3ZlUG9pbnQoaSkgbWV0aG9kXG5cdFx0aWYgKHNoaWZ0KSB7XG5cdFx0XHRpZiAoZGF0YVswXSAmJiBkYXRhWzBdLnJlbW92ZSkge1xuXHRcdFx0XHRkYXRhWzBdLnJlbW92ZShmYWxzZSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkYXRhLnNoaWZ0KCk7XG5cdFx0XHRcdHNlcmllcy51cGRhdGVQYXJhbGxlbEFycmF5cyhwb2ludCwgJ3NoaWZ0Jyk7XG5cblx0XHRcdFx0ZGF0YU9wdGlvbnMuc2hpZnQoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyByZWRyYXdcblx0XHRzZXJpZXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0c2VyaWVzLmlzRGlydHlEYXRhID0gdHJ1ZTtcblx0XHRpZiAocmVkcmF3KSB7XG5cdFx0XHRzZXJpZXMuZ2V0QXR0cmlicygpOyAvLyAjMTkzN1xuXHRcdFx0Y2hhcnQucmVkcmF3KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBSZW1vdmUgYSBzZXJpZXMgYW5kIG9wdGlvbmFsbHkgcmVkcmF3IHRoZSBjaGFydFxuXHQgKlxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhdyBXaGV0aGVyIHRvIHJlZHJhdyB0aGUgY2hhcnQgb3Igd2FpdCBmb3IgYW4gZXhwbGljaXQgY2FsbFxuXHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBhbmltYXRpb24gV2hldGhlciB0byBhcHBseSBhbmltYXRpb24sIGFuZCBvcHRpb25hbGx5IGFuaW1hdGlvblxuXHQgKiAgICBjb25maWd1cmF0aW9uXG5cdCAqL1xuXG5cdHJlbW92ZTogZnVuY3Rpb24gKHJlZHJhdywgYW5pbWF0aW9uKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydDtcblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7XG5cblx0XHRpZiAoIXNlcmllcy5pc1JlbW92aW5nKSB7ICAvKiBwcmV2ZW50IHRyaWdnZXJpbmcgbmF0aXZlIGV2ZW50IGluIGpRdWVyeVxuXHRcdFx0XHQoY2FsbGluZyB0aGUgcmVtb3ZlIGZ1bmN0aW9uIGZyb20gdGhlIHJlbW92ZSBldmVudCkgKi9cblx0XHRcdHNlcmllcy5pc1JlbW92aW5nID0gdHJ1ZTtcblxuXHRcdFx0Ly8gZmlyZSB0aGUgZXZlbnQgd2l0aCBhIGRlZmF1bHQgaGFuZGxlciBvZiByZW1vdmluZyB0aGUgcG9pbnRcblx0XHRcdGZpcmVFdmVudChzZXJpZXMsICdyZW1vdmUnLCBudWxsLCBmdW5jdGlvbiAoKSB7XG5cblxuXHRcdFx0XHQvLyBkZXN0cm95IGVsZW1lbnRzXG5cdFx0XHRcdHNlcmllcy5kZXN0cm95KCk7XG5cblxuXHRcdFx0XHQvLyByZWRyYXdcblx0XHRcdFx0Y2hhcnQuaXNEaXJ0eUxlZ2VuZCA9IGNoYXJ0LmlzRGlydHlCb3ggPSB0cnVlO1xuXHRcdFx0XHRjaGFydC5saW5rU2VyaWVzKCk7XG5cblx0XHRcdFx0aWYgKHJlZHJhdykge1xuXHRcdFx0XHRcdGNoYXJ0LnJlZHJhdyhhbmltYXRpb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdH1cblx0XHRzZXJpZXMuaXNSZW1vdmluZyA9IGZhbHNlO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgdGhlIHNlcmllcyB3aXRoIGEgbmV3IHNldCBvZiBvcHRpb25zXG5cdCAqL1xuXHR1cGRhdGU6IGZ1bmN0aW9uIChuZXdPcHRpb25zLCByZWRyYXcpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRcdC8vIG11c3QgdXNlIHVzZXIgb3B0aW9ucyB3aGVuIGNoYW5naW5nIHR5cGUgYmVjYXVzZSB0aGlzLm9wdGlvbnMgaXMgbWVyZ2VkXG5cdFx0XHQvLyBpbiB3aXRoIHR5cGUgc3BlY2lmaWMgcGxvdE9wdGlvbnNcblx0XHRcdG9sZE9wdGlvbnMgPSB0aGlzLnVzZXJPcHRpb25zLFxuXHRcdFx0b2xkVHlwZSA9IHRoaXMudHlwZSxcblx0XHRcdHByb3RvID0gc2VyaWVzVHlwZXNbb2xkVHlwZV0ucHJvdG90eXBlLFxuXHRcdFx0cHJlc2VydmUgPSBbJ2dyb3VwJywgJ21hcmtlckdyb3VwJywgJ2RhdGFMYWJlbHNHcm91cCddLFxuXHRcdFx0bjtcblxuXHRcdC8vIE1ha2Ugc3VyZSBncm91cHMgYXJlIG5vdCBkZXN0cm95ZWQgKCMzMDk0KVxuXHRcdGVhY2gocHJlc2VydmUsIGZ1bmN0aW9uIChwcm9wKSB7XG5cdFx0XHRwcmVzZXJ2ZVtwcm9wXSA9IHNlcmllc1twcm9wXTtcblx0XHRcdGRlbGV0ZSBzZXJpZXNbcHJvcF07XG5cdFx0fSk7XG5cblx0XHQvLyBEbyB0aGUgbWVyZ2UsIHdpdGggc29tZSBmb3JjZWQgb3B0aW9uc1xuXHRcdG5ld09wdGlvbnMgPSBtZXJnZShvbGRPcHRpb25zLCB7XG5cdFx0XHRhbmltYXRpb246IGZhbHNlLFxuXHRcdFx0aW5kZXg6IHRoaXMuaW5kZXgsXG5cdFx0XHRwb2ludFN0YXJ0OiB0aGlzLnhEYXRhWzBdIC8vIHdoZW4gdXBkYXRpbmcgYWZ0ZXIgYWRkUG9pbnRcblx0XHR9LCB7IGRhdGE6IHRoaXMub3B0aW9ucy5kYXRhIH0sIG5ld09wdGlvbnMpO1xuXG5cdFx0Ly8gRGVzdHJveSB0aGUgc2VyaWVzIGFuZCByZWluc2VydCBtZXRob2RzIGZyb20gdGhlIHR5cGUgcHJvdG90eXBlXG5cdFx0dGhpcy5yZW1vdmUoZmFsc2UpO1xuXHRcdGZvciAobiBpbiBwcm90bykgeyAvLyBPdmVyd3JpdGUgc2VyaWVzLXR5cGUgc3BlY2lmaWMgbWV0aG9kcyAoIzIyNzApXG5cdFx0XHRpZiAocHJvdG8uaGFzT3duUHJvcGVydHkobikpIHtcblx0XHRcdFx0dGhpc1tuXSA9IFVOREVGSU5FRDtcblx0XHRcdH1cblx0XHR9XG5cdFx0ZXh0ZW5kKHRoaXMsIHNlcmllc1R5cGVzW25ld09wdGlvbnMudHlwZSB8fCBvbGRUeXBlXS5wcm90b3R5cGUpO1xuXG5cdFx0Ly8gUmUtcmVnaXN0ZXIgZ3JvdXBzICgjMzA5NClcblx0XHRlYWNoKHByZXNlcnZlLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0c2VyaWVzW3Byb3BdID0gcHJlc2VydmVbcHJvcF07XG5cdFx0fSk7XG5cblxuXHRcdHRoaXMuaW5pdChjaGFydCwgbmV3T3B0aW9ucyk7XG5cdFx0Y2hhcnQubGlua1NlcmllcygpOyAvLyBMaW5rcyBhcmUgbG9zdCBpbiB0aGlzLnJlbW92ZSAoIzMwMjgpXG5cdFx0aWYgKHBpY2socmVkcmF3LCB0cnVlKSkge1xuXHRcdFx0Y2hhcnQucmVkcmF3KGZhbHNlKTtcblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBFeHRlbmQgdGhlIEF4aXMucHJvdG90eXBlIGZvciBkeW5hbWljIG1ldGhvZHNcbmV4dGVuZChBeGlzLnByb3RvdHlwZSwge1xuXG5cdC8qKlxuXHQgKiBVcGRhdGUgdGhlIGF4aXMgd2l0aCBhIG5ldyBvcHRpb25zIHN0cnVjdHVyZVxuXHQgKi9cblx0dXBkYXRlOiBmdW5jdGlvbiAobmV3T3B0aW9ucywgcmVkcmF3KSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydDtcblxuXHRcdG5ld09wdGlvbnMgPSBjaGFydC5vcHRpb25zW3RoaXMuY29sbF1bdGhpcy5vcHRpb25zLmluZGV4XSA9IG1lcmdlKHRoaXMudXNlck9wdGlvbnMsIG5ld09wdGlvbnMpO1xuXG5cdFx0dGhpcy5kZXN0cm95KHRydWUpO1xuXHRcdHRoaXMuX2FkZGVkUGxvdExCID0gVU5ERUZJTkVEOyAvLyAjMTYxMSwgIzI4ODdcblxuXHRcdHRoaXMuaW5pdChjaGFydCwgZXh0ZW5kKG5ld09wdGlvbnMsIHsgZXZlbnRzOiBVTkRFRklORUQgfSkpO1xuXG5cdFx0Y2hhcnQuaXNEaXJ0eUJveCA9IHRydWU7XG5cdFx0aWYgKHBpY2socmVkcmF3LCB0cnVlKSkge1xuXHRcdFx0Y2hhcnQucmVkcmF3KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuICAgICAqIFJlbW92ZSB0aGUgYXhpcyBmcm9tIHRoZSBjaGFydFxuICAgICAqL1xuXHRyZW1vdmU6IGZ1bmN0aW9uIChyZWRyYXcpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0a2V5ID0gdGhpcy5jb2xsLCAvLyB4QXhpcyBvciB5QXhpc1xuXHRcdFx0YXhpc1NlcmllcyA9IHRoaXMuc2VyaWVzLFxuXHRcdFx0aSA9IGF4aXNTZXJpZXMubGVuZ3RoO1xuXG5cdFx0Ly8gUmVtb3ZlIGFzc29jaWF0ZWQgc2VyaWVzICgjMjY4Nylcblx0XHR3aGlsZSAoaS0tKSB7XG5cdFx0XHRpZiAoYXhpc1Nlcmllc1tpXSkge1xuXHRcdFx0XHRheGlzU2VyaWVzW2ldLnJlbW92ZShmYWxzZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHRoZSBheGlzXG5cdFx0ZXJhc2UoY2hhcnQuYXhlcywgdGhpcyk7XG5cdFx0ZXJhc2UoY2hhcnRba2V5XSwgdGhpcyk7XG5cdFx0Y2hhcnQub3B0aW9uc1trZXldLnNwbGljZSh0aGlzLm9wdGlvbnMuaW5kZXgsIDEpO1xuXHRcdGVhY2goY2hhcnRba2V5XSwgZnVuY3Rpb24gKGF4aXMsIGkpIHsgLy8gUmUtaW5kZXgsICMxNzA2XG5cdFx0XHRheGlzLm9wdGlvbnMuaW5kZXggPSBpO1xuXHRcdH0pO1xuXHRcdHRoaXMuZGVzdHJveSgpO1xuXHRcdGNoYXJ0LmlzRGlydHlCb3ggPSB0cnVlO1xuXG5cdFx0aWYgKHBpY2socmVkcmF3LCB0cnVlKSkge1xuXHRcdFx0Y2hhcnQucmVkcmF3KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgdGhlIGF4aXMgdGl0bGUgYnkgb3B0aW9uc1xuXHQgKi9cblx0c2V0VGl0bGU6IGZ1bmN0aW9uIChuZXdUaXRsZU9wdGlvbnMsIHJlZHJhdykge1xuXHRcdHRoaXMudXBkYXRlKHsgdGl0bGU6IG5ld1RpdGxlT3B0aW9ucyB9LCByZWRyYXcpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBTZXQgbmV3IGF4aXMgY2F0ZWdvcmllcyBhbmQgb3B0aW9uYWxseSByZWRyYXdcblx0ICogQHBhcmFtIHtBcnJheX0gY2F0ZWdvcmllc1xuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHJlZHJhd1xuXHQgKi9cblx0c2V0Q2F0ZWdvcmllczogZnVuY3Rpb24gKGNhdGVnb3JpZXMsIHJlZHJhdykge1xuXHRcdHRoaXMudXBkYXRlKHsgY2F0ZWdvcmllczogY2F0ZWdvcmllcyB9LCByZWRyYXcpO1xuXHR9XG5cbn0pO1xuXG5cbi8qKlxuICogTGluZVNlcmllcyBvYmplY3RcbiAqL1xudmFyIExpbmVTZXJpZXMgPSBleHRlbmRDbGFzcyhTZXJpZXMpO1xuc2VyaWVzVHlwZXMubGluZSA9IExpbmVTZXJpZXM7XG5cbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIGFyZWFcbiAqL1xuZGVmYXVsdFBsb3RPcHRpb25zLmFyZWEgPSBtZXJnZShkZWZhdWx0U2VyaWVzT3B0aW9ucywge1xuXHR0aHJlc2hvbGQ6IDBcblx0Ly8gdHJhY2tCeUFyZWE6IGZhbHNlLFxuXHQvLyBsaW5lQ29sb3I6IG51bGwsIC8vIG92ZXJyaWRlcyBjb2xvciwgYnV0IGxldHMgZmlsbENvbG9yIGJlIHVuYWx0ZXJlZFxuXHQvLyBmaWxsT3BhY2l0eTogMC43NSxcblx0Ly8gZmlsbENvbG9yOiBudWxsXG59KTtcblxuLyoqXG4gKiBBcmVhU2VyaWVzIG9iamVjdFxuICovXG52YXIgQXJlYVNlcmllcyA9IGV4dGVuZENsYXNzKFNlcmllcywge1xuXHR0eXBlOiAnYXJlYScsXG5cdC8qKlxuXHQgKiBGb3Igc3RhY2tzLCBkb24ndCBzcGxpdCBzZWdtZW50cyBvbiBudWxsIHZhbHVlcy4gSW5zdGVhZCwgZHJhdyBudWxsIHZhbHVlcyB3aXRoIFxuXHQgKiBubyBtYXJrZXIuIEFsc28gaW5zZXJ0IGR1bW15IHBvaW50cyBmb3IgYW55IFggcG9zaXRpb24gdGhhdCBleGlzdHMgaW4gb3RoZXIgc2VyaWVzXG5cdCAqIGluIHRoZSBzdGFjay5cblx0ICovIFxuXHRnZXRTZWdtZW50czogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0c2VnbWVudHMgPSBbXSxcblx0XHRcdHNlZ21lbnQgPSBbXSxcblx0XHRcdGtleXMgPSBbXSxcblx0XHRcdHhBeGlzID0gdGhpcy54QXhpcyxcblx0XHRcdHlBeGlzID0gdGhpcy55QXhpcyxcblx0XHRcdHN0YWNrID0geUF4aXMuc3RhY2tzW3RoaXMuc3RhY2tLZXldLFxuXHRcdFx0cG9pbnRNYXAgPSB7fSxcblx0XHRcdHBsb3RYLFxuXHRcdFx0cGxvdFksXG5cdFx0XHRwb2ludHMgPSB0aGlzLnBvaW50cyxcblx0XHRcdGNvbm5lY3ROdWxscyA9IHRoaXMub3B0aW9ucy5jb25uZWN0TnVsbHMsXG5cdFx0XHRpLFxuXHRcdFx0eDtcblxuXHRcdGlmICh0aGlzLm9wdGlvbnMuc3RhY2tpbmcgJiYgIXRoaXMuY3JvcHBlZCkgeyAvLyBjcm9wcGVkIGNhdXNlcyBhcnRlZmFjdHMgaW4gU3RvY2ssIGFuZCBwZXJmIGlzc3VlXG5cdFx0XHQvLyBDcmVhdGUgYSBtYXAgd2hlcmUgd2UgY2FuIHF1aWNrbHkgbG9vayB1cCB0aGUgcG9pbnRzIGJ5IHRoZWlyIFggdmFsdWUuXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdHBvaW50TWFwW3BvaW50c1tpXS54XSA9IHBvaW50c1tpXTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU29ydCB0aGUga2V5cyAoIzE2NTEpXG5cdFx0XHRmb3IgKHggaW4gc3RhY2spIHtcblx0XHRcdFx0aWYgKHN0YWNrW3hdLnRvdGFsICE9PSBudWxsKSB7IC8vIG51bGxlZCBhZnRlciBzd2l0Y2hpbmcgYmV0d2VlbiBncm91cGluZyBhbmQgbm90ICgjMTY1MSwgIzIzMzYpXG5cdFx0XHRcdFx0a2V5cy5wdXNoKCt4KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0a2V5cy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0XHRcdHJldHVybiBhIC0gYjtcblx0XHRcdH0pO1xuXG5cdFx0XHRlYWNoKGtleXMsIGZ1bmN0aW9uICh4KSB7XG5cdFx0XHRcdHZhciB5ID0gMCxcblx0XHRcdFx0XHRzdGFja1BvaW50O1xuXG5cdFx0XHRcdGlmIChjb25uZWN0TnVsbHMgJiYgKCFwb2ludE1hcFt4XSB8fCBwb2ludE1hcFt4XS55ID09PSBudWxsKSkgeyAvLyAjMTgzNlxuXHRcdFx0XHRcdHJldHVybjtcblxuXHRcdFx0XHQvLyBUaGUgcG9pbnQgZXhpc3RzLCBwdXNoIGl0IHRvIHRoZSBzZWdtZW50XG5cdFx0XHRcdH0gZWxzZSBpZiAocG9pbnRNYXBbeF0pIHtcblx0XHRcdFx0XHRzZWdtZW50LnB1c2gocG9pbnRNYXBbeF0pO1xuXG5cdFx0XHRcdC8vIFRoZXJlIGlzIG5vIHBvaW50IGZvciB0aGlzIFggdmFsdWUgaW4gdGhpcyBzZXJpZXMsIHNvIHdlIFxuXHRcdFx0XHQvLyBpbnNlcnQgYSBkdW1teSBwb2ludCBpbiBvcmRlciBmb3IgdGhlIGFyZWFzIHRvIGJlIGRyYXduXG5cdFx0XHRcdC8vIGNvcnJlY3RseS5cblx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdC8vIExvb3AgZG93biB0aGUgc3RhY2sgdG8gZmluZCB0aGUgc2VyaWVzIGJlbG93IHRoaXMgb25lIHRoYXQgaGFzXG5cdFx0XHRcdFx0Ly8gYSB2YWx1ZSAoIzE5OTEpXG5cdFx0XHRcdFx0Zm9yIChpID0gc2VyaWVzLmluZGV4OyBpIDw9IHlBeGlzLnNlcmllcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdFx0c3RhY2tQb2ludCA9IHN0YWNrW3hdLnBvaW50c1tpICsgJywnICsgeF07XG5cdFx0XHRcdFx0XHRpZiAoc3RhY2tQb2ludCkge1xuXHRcdFx0XHRcdFx0XHR5ID0gc3RhY2tQb2ludFsxXTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cGxvdFggPSB4QXhpcy50cmFuc2xhdGUoeCk7XG5cdFx0XHRcdFx0cGxvdFkgPSB5QXhpcy50b1BpeGVscyh5LCB0cnVlKTtcblx0XHRcdFx0XHRzZWdtZW50LnB1c2goeyBcblx0XHRcdFx0XHRcdHk6IG51bGwsIFxuXHRcdFx0XHRcdFx0cGxvdFg6IHBsb3RYLFxuXHRcdFx0XHRcdFx0Y2xpZW50WDogcGxvdFgsIFxuXHRcdFx0XHRcdFx0cGxvdFk6IHBsb3RZLCBcblx0XHRcdFx0XHRcdHlCb3R0b206IHBsb3RZLFxuXHRcdFx0XHRcdFx0b25Nb3VzZU92ZXI6IG5vb3Bcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGlmIChzZWdtZW50Lmxlbmd0aCkge1xuXHRcdFx0XHRzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblx0XHRcdFNlcmllcy5wcm90b3R5cGUuZ2V0U2VnbWVudHMuY2FsbCh0aGlzKTtcblx0XHRcdHNlZ21lbnRzID0gdGhpcy5zZWdtZW50cztcblx0XHR9XG5cblx0XHR0aGlzLnNlZ21lbnRzID0gc2VnbWVudHM7XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRXh0ZW5kIHRoZSBiYXNlIFNlcmllcyBnZXRTZWdtZW50UGF0aCBtZXRob2QgYnkgYWRkaW5nIHRoZSBwYXRoIGZvciB0aGUgYXJlYS5cblx0ICogVGhpcyBwYXRoIGlzIHB1c2hlZCB0byB0aGUgc2VyaWVzLmFyZWFQYXRoIHByb3BlcnR5LlxuXHQgKi9cblx0Z2V0U2VnbWVudFBhdGg6IGZ1bmN0aW9uIChzZWdtZW50KSB7XG5cdFx0XG5cdFx0dmFyIHNlZ21lbnRQYXRoID0gU2VyaWVzLnByb3RvdHlwZS5nZXRTZWdtZW50UGF0aC5jYWxsKHRoaXMsIHNlZ21lbnQpLCAvLyBjYWxsIGJhc2UgbWV0aG9kXG5cdFx0XHRhcmVhU2VnbWVudFBhdGggPSBbXS5jb25jYXQoc2VnbWVudFBhdGgpLCAvLyB3b3JrIG9uIGEgY29weSBmb3IgdGhlIGFyZWEgcGF0aFxuXHRcdFx0aSxcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRzZWdMZW5ndGggPSBzZWdtZW50UGF0aC5sZW5ndGgsXG5cdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkID0gdGhpcy55QXhpcy5nZXRUaHJlc2hvbGQob3B0aW9ucy50aHJlc2hvbGQpLCAvLyAjMjE4MVxuXHRcdFx0eUJvdHRvbTtcblx0XHRcblx0XHRpZiAoc2VnTGVuZ3RoID09PSAzKSB7IC8vIGZvciBhbmltYXRpb24gZnJvbSAxIHRvIHR3byBwb2ludHNcblx0XHRcdGFyZWFTZWdtZW50UGF0aC5wdXNoKEwsIHNlZ21lbnRQYXRoWzFdLCBzZWdtZW50UGF0aFsyXSk7XG5cdFx0fVxuXHRcdGlmIChvcHRpb25zLnN0YWNraW5nICYmICF0aGlzLmNsb3NlZFN0YWNrcykge1xuXHRcdFx0XG5cdFx0XHQvLyBGb2xsb3cgc3RhY2sgYmFjay4gVG9kbzogaW1wbGVtZW50IGFyZWFzcGxpbmUuIEEgZ2VuZXJhbCBzb2x1dGlvbiBjb3VsZCBiZSB0byBcblx0XHRcdC8vIHJldmVyc2UgdGhlIGVudGlyZSBncmFwaFBhdGggb2YgdGhlIHByZXZpb3VzIHNlcmllcywgdGhvdWdoIG1heSBiZSBoYXJkIHdpdGhcblx0XHRcdC8vIHNwbGluZXMgYW5kIHdpdGggc2VyaWVzIHdpdGggZGlmZmVyZW50IGV4dHJlbWVzXG5cdFx0XHRmb3IgKGkgPSBzZWdtZW50Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cblx0XHRcdFx0eUJvdHRvbSA9IHBpY2soc2VnbWVudFtpXS55Qm90dG9tLCB0cmFuc2xhdGVkVGhyZXNob2xkKTtcblx0XHRcdFxuXHRcdFx0XHQvLyBzdGVwIGxpbmU/XG5cdFx0XHRcdGlmIChpIDwgc2VnbWVudC5sZW5ndGggLSAxICYmIG9wdGlvbnMuc3RlcCkge1xuXHRcdFx0XHRcdGFyZWFTZWdtZW50UGF0aC5wdXNoKHNlZ21lbnRbaSArIDFdLnBsb3RYLCB5Qm90dG9tKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRcblx0XHRcdFx0YXJlYVNlZ21lbnRQYXRoLnB1c2goc2VnbWVudFtpXS5wbG90WCwgeUJvdHRvbSk7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2UgeyAvLyBmb2xsb3cgemVybyBsaW5lIGJhY2tcblx0XHRcdHRoaXMuY2xvc2VTZWdtZW50KGFyZWFTZWdtZW50UGF0aCwgc2VnbWVudCwgdHJhbnNsYXRlZFRocmVzaG9sZCk7XG5cdFx0fVxuXHRcdHRoaXMuYXJlYVBhdGggPSB0aGlzLmFyZWFQYXRoLmNvbmNhdChhcmVhU2VnbWVudFBhdGgpO1xuXHRcdHJldHVybiBzZWdtZW50UGF0aDtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBFeHRlbmRhYmxlIG1ldGhvZCB0byBjbG9zZSB0aGUgc2VnbWVudCBwYXRoIG9mIGFuIGFyZWEuIFRoaXMgaXMgb3ZlcnJpZGRlbiBpbiBwb2xhciBcblx0ICogY2hhcnRzLlxuXHQgKi9cblx0Y2xvc2VTZWdtZW50OiBmdW5jdGlvbiAocGF0aCwgc2VnbWVudCwgdHJhbnNsYXRlZFRocmVzaG9sZCkge1xuXHRcdHBhdGgucHVzaChcblx0XHRcdEwsXG5cdFx0XHRzZWdtZW50W3NlZ21lbnQubGVuZ3RoIC0gMV0ucGxvdFgsXG5cdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkLFxuXHRcdFx0TCxcblx0XHRcdHNlZ21lbnRbMF0ucGxvdFgsXG5cdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkXG5cdFx0KTtcblx0fSxcblx0XG5cdC8qKlxuXHQgKiBEcmF3IHRoZSBncmFwaCBhbmQgdGhlIHVuZGVybHlpbmcgYXJlYS4gVGhpcyBtZXRob2QgY2FsbHMgdGhlIFNlcmllcyBiYXNlXG5cdCAqIGZ1bmN0aW9uIGFuZCBhZGRzIHRoZSBhcmVhLiBUaGUgYXJlYVBhdGggaXMgY2FsY3VsYXRlZCBpbiB0aGUgZ2V0U2VnbWVudFBhdGhcblx0ICogbWV0aG9kIGNhbGxlZCBmcm9tIFNlcmllcy5wcm90b3R5cGUuZHJhd0dyYXBoLlxuXHQgKi9cblx0ZHJhd0dyYXBoOiBmdW5jdGlvbiAoKSB7XG5cdFx0XG5cdFx0Ly8gRGVmaW5lIG9yIHJlc2V0IGFyZWFQYXRoXG5cdFx0dGhpcy5hcmVhUGF0aCA9IFtdO1xuXHRcdFxuXHRcdC8vIENhbGwgdGhlIGJhc2UgbWV0aG9kXG5cdFx0U2VyaWVzLnByb3RvdHlwZS5kcmF3R3JhcGguYXBwbHkodGhpcyk7XG5cdFx0XG5cdFx0Ly8gRGVmaW5lIGxvY2FsIHZhcmlhYmxlc1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0YXJlYVBhdGggPSB0aGlzLmFyZWFQYXRoLFxuXHRcdFx0b3B0aW9ucyA9IHRoaXMub3B0aW9ucyxcblx0XHRcdG5lZ2F0aXZlQ29sb3IgPSBvcHRpb25zLm5lZ2F0aXZlQ29sb3IsXG5cdFx0XHRuZWdhdGl2ZUZpbGxDb2xvciA9IG9wdGlvbnMubmVnYXRpdmVGaWxsQ29sb3IsXG5cdFx0XHRwcm9wcyA9IFtbJ2FyZWEnLCB0aGlzLmNvbG9yLCBvcHRpb25zLmZpbGxDb2xvcl1dOyAvLyBhcmVhIG5hbWUsIG1haW4gY29sb3IsIGZpbGwgY29sb3Jcblx0XHRcblx0XHRpZiAobmVnYXRpdmVDb2xvciB8fCBuZWdhdGl2ZUZpbGxDb2xvcikge1xuXHRcdFx0cHJvcHMucHVzaChbJ2FyZWFOZWcnLCBuZWdhdGl2ZUNvbG9yLCBuZWdhdGl2ZUZpbGxDb2xvcl0pO1xuXHRcdH1cblx0XHRcblx0XHRlYWNoKHByb3BzLCBmdW5jdGlvbiAocHJvcCkge1xuXHRcdFx0dmFyIGFyZWFLZXkgPSBwcm9wWzBdLFxuXHRcdFx0XHRhcmVhID0gc2VyaWVzW2FyZWFLZXldO1xuXHRcdFx0XHRcblx0XHRcdC8vIENyZWF0ZSBvciB1cGRhdGUgdGhlIGFyZWFcblx0XHRcdGlmIChhcmVhKSB7IC8vIHVwZGF0ZVxuXHRcdFx0XHRhcmVhLmFuaW1hdGUoeyBkOiBhcmVhUGF0aCB9KTtcblx0XG5cdFx0XHR9IGVsc2UgeyAvLyBjcmVhdGVcblx0XHRcdFx0c2VyaWVzW2FyZWFLZXldID0gc2VyaWVzLmNoYXJ0LnJlbmRlcmVyLnBhdGgoYXJlYVBhdGgpXG5cdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0ZmlsbDogcGljayhcblx0XHRcdFx0XHRcdFx0cHJvcFsyXSxcblx0XHRcdFx0XHRcdFx0Q29sb3IocHJvcFsxXSkuc2V0T3BhY2l0eShwaWNrKG9wdGlvbnMuZmlsbE9wYWNpdHksIDAuNzUpKS5nZXQoKVxuXHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHRcdHpJbmRleDogMCAvLyAjMTA2OVxuXHRcdFx0XHRcdH0pLmFkZChzZXJpZXMuZ3JvdXApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGRyYXdMZWdlbmRTeW1ib2w6IExlZ2VuZFN5bWJvbE1peGluLmRyYXdSZWN0YW5nbGVcbn0pO1xuXG5zZXJpZXNUeXBlcy5hcmVhID0gQXJlYVNlcmllcztcbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIHNwbGluZVxuICovXG5kZWZhdWx0UGxvdE9wdGlvbnMuc3BsaW5lID0gbWVyZ2UoZGVmYXVsdFNlcmllc09wdGlvbnMpO1xuXG4vKipcbiAqIFNwbGluZVNlcmllcyBvYmplY3RcbiAqL1xudmFyIFNwbGluZVNlcmllcyA9IGV4dGVuZENsYXNzKFNlcmllcywge1xuXHR0eXBlOiAnc3BsaW5lJyxcblxuXHQvKipcblx0ICogR2V0IHRoZSBzcGxpbmUgc2VnbWVudCBmcm9tIGEgZ2l2ZW4gcG9pbnQncyBwcmV2aW91cyBuZWlnaGJvdXIgdG8gdGhlIGdpdmVuIHBvaW50XG5cdCAqL1xuXHRnZXRQb2ludFNwbGluZTogZnVuY3Rpb24gKHNlZ21lbnQsIHBvaW50LCBpKSB7XG5cdFx0dmFyIHNtb290aGluZyA9IDEuNSwgLy8gMSBtZWFucyBjb250cm9sIHBvaW50cyBtaWR3YXkgYmV0d2VlbiBwb2ludHMsIDIgbWVhbnMgMS8zIGZyb20gdGhlIHBvaW50LCAzIGlzIDEvNCBldGNcblx0XHRcdGRlbm9tID0gc21vb3RoaW5nICsgMSxcblx0XHRcdHBsb3RYID0gcG9pbnQucGxvdFgsXG5cdFx0XHRwbG90WSA9IHBvaW50LnBsb3RZLFxuXHRcdFx0bGFzdFBvaW50ID0gc2VnbWVudFtpIC0gMV0sXG5cdFx0XHRuZXh0UG9pbnQgPSBzZWdtZW50W2kgKyAxXSxcblx0XHRcdGxlZnRDb250WCxcblx0XHRcdGxlZnRDb250WSxcblx0XHRcdHJpZ2h0Q29udFgsXG5cdFx0XHRyaWdodENvbnRZLFxuXHRcdFx0cmV0O1xuXG5cdFx0Ly8gZmluZCBjb250cm9sIHBvaW50c1xuXHRcdGlmIChsYXN0UG9pbnQgJiYgbmV4dFBvaW50KSB7XG5cdFx0XG5cdFx0XHR2YXIgbGFzdFggPSBsYXN0UG9pbnQucGxvdFgsXG5cdFx0XHRcdGxhc3RZID0gbGFzdFBvaW50LnBsb3RZLFxuXHRcdFx0XHRuZXh0WCA9IG5leHRQb2ludC5wbG90WCxcblx0XHRcdFx0bmV4dFkgPSBuZXh0UG9pbnQucGxvdFksXG5cdFx0XHRcdGNvcnJlY3Rpb247XG5cblx0XHRcdGxlZnRDb250WCA9IChzbW9vdGhpbmcgKiBwbG90WCArIGxhc3RYKSAvIGRlbm9tO1xuXHRcdFx0bGVmdENvbnRZID0gKHNtb290aGluZyAqIHBsb3RZICsgbGFzdFkpIC8gZGVub207XG5cdFx0XHRyaWdodENvbnRYID0gKHNtb290aGluZyAqIHBsb3RYICsgbmV4dFgpIC8gZGVub207XG5cdFx0XHRyaWdodENvbnRZID0gKHNtb290aGluZyAqIHBsb3RZICsgbmV4dFkpIC8gZGVub207XG5cblx0XHRcdC8vIGhhdmUgdGhlIHR3byBjb250cm9sIHBvaW50cyBtYWtlIGEgc3RyYWlnaHQgbGluZSB0aHJvdWdoIG1haW4gcG9pbnRcblx0XHRcdGNvcnJlY3Rpb24gPSAoKHJpZ2h0Q29udFkgLSBsZWZ0Q29udFkpICogKHJpZ2h0Q29udFggLSBwbG90WCkpIC9cblx0XHRcdFx0KHJpZ2h0Q29udFggLSBsZWZ0Q29udFgpICsgcGxvdFkgLSByaWdodENvbnRZO1xuXG5cdFx0XHRsZWZ0Q29udFkgKz0gY29ycmVjdGlvbjtcblx0XHRcdHJpZ2h0Q29udFkgKz0gY29ycmVjdGlvbjtcblxuXHRcdFx0Ly8gdG8gcHJldmVudCBmYWxzZSBleHRyZW1lcywgY2hlY2sgdGhhdCBjb250cm9sIHBvaW50cyBhcmUgYmV0d2VlblxuXHRcdFx0Ly8gbmVpZ2hib3VyaW5nIHBvaW50cycgeSB2YWx1ZXNcblx0XHRcdGlmIChsZWZ0Q29udFkgPiBsYXN0WSAmJiBsZWZ0Q29udFkgPiBwbG90WSkge1xuXHRcdFx0XHRsZWZ0Q29udFkgPSBtYXRoTWF4KGxhc3RZLCBwbG90WSk7XG5cdFx0XHRcdHJpZ2h0Q29udFkgPSAyICogcGxvdFkgLSBsZWZ0Q29udFk7IC8vIG1pcnJvciBvZiBsZWZ0IGNvbnRyb2wgcG9pbnRcblx0XHRcdH0gZWxzZSBpZiAobGVmdENvbnRZIDwgbGFzdFkgJiYgbGVmdENvbnRZIDwgcGxvdFkpIHtcblx0XHRcdFx0bGVmdENvbnRZID0gbWF0aE1pbihsYXN0WSwgcGxvdFkpO1xuXHRcdFx0XHRyaWdodENvbnRZID0gMiAqIHBsb3RZIC0gbGVmdENvbnRZO1xuXHRcdFx0fVxuXHRcdFx0aWYgKHJpZ2h0Q29udFkgPiBuZXh0WSAmJiByaWdodENvbnRZID4gcGxvdFkpIHtcblx0XHRcdFx0cmlnaHRDb250WSA9IG1hdGhNYXgobmV4dFksIHBsb3RZKTtcblx0XHRcdFx0bGVmdENvbnRZID0gMiAqIHBsb3RZIC0gcmlnaHRDb250WTtcblx0XHRcdH0gZWxzZSBpZiAocmlnaHRDb250WSA8IG5leHRZICYmIHJpZ2h0Q29udFkgPCBwbG90WSkge1xuXHRcdFx0XHRyaWdodENvbnRZID0gbWF0aE1pbihuZXh0WSwgcGxvdFkpO1xuXHRcdFx0XHRsZWZ0Q29udFkgPSAyICogcGxvdFkgLSByaWdodENvbnRZO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyByZWNvcmQgZm9yIGRyYXdpbmcgaW4gbmV4dCBwb2ludFxuXHRcdFx0cG9pbnQucmlnaHRDb250WCA9IHJpZ2h0Q29udFg7XG5cdFx0XHRwb2ludC5yaWdodENvbnRZID0gcmlnaHRDb250WTtcblxuXHRcdH1cblx0XHRcblx0XHQvLyBWaXN1YWxpemUgY29udHJvbCBwb2ludHMgZm9yIGRlYnVnZ2luZ1xuXHRcdC8qXG5cdFx0aWYgKGxlZnRDb250WCkge1xuXHRcdFx0dGhpcy5jaGFydC5yZW5kZXJlci5jaXJjbGUobGVmdENvbnRYICsgdGhpcy5jaGFydC5wbG90TGVmdCwgbGVmdENvbnRZICsgdGhpcy5jaGFydC5wbG90VG9wLCAyKVxuXHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0c3Ryb2tlOiAncmVkJyxcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogMSxcblx0XHRcdFx0XHRmaWxsOiAnbm9uZSdcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0dGhpcy5jaGFydC5yZW5kZXJlci5wYXRoKFsnTScsIGxlZnRDb250WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIGxlZnRDb250WSArIHRoaXMuY2hhcnQucGxvdFRvcCxcblx0XHRcdFx0J0wnLCBwbG90WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIHBsb3RZICsgdGhpcy5jaGFydC5wbG90VG9wXSlcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHN0cm9rZTogJ3JlZCcsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IDFcblx0XHRcdFx0fSlcblx0XHRcdFx0LmFkZCgpO1xuXHRcdFx0dGhpcy5jaGFydC5yZW5kZXJlci5jaXJjbGUocmlnaHRDb250WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIHJpZ2h0Q29udFkgKyB0aGlzLmNoYXJ0LnBsb3RUb3AsIDIpXG5cdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRzdHJva2U6ICdncmVlbicsXG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IDEsXG5cdFx0XHRcdFx0ZmlsbDogJ25vbmUnXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hZGQoKTtcblx0XHRcdHRoaXMuY2hhcnQucmVuZGVyZXIucGF0aChbJ00nLCByaWdodENvbnRYICsgdGhpcy5jaGFydC5wbG90TGVmdCwgcmlnaHRDb250WSArIHRoaXMuY2hhcnQucGxvdFRvcCxcblx0XHRcdFx0J0wnLCBwbG90WCArIHRoaXMuY2hhcnQucGxvdExlZnQsIHBsb3RZICsgdGhpcy5jaGFydC5wbG90VG9wXSlcblx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdHN0cm9rZTogJ2dyZWVuJyxcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogMVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuYWRkKCk7XG5cdFx0fVxuXHRcdCovXG5cblx0XHQvLyBtb3ZlVG8gb3IgbGluZVRvXG5cdFx0aWYgKCFpKSB7XG5cdFx0XHRyZXQgPSBbTSwgcGxvdFgsIHBsb3RZXTtcblx0XHR9IGVsc2UgeyAvLyBjdXJ2ZSBmcm9tIGxhc3QgcG9pbnQgdG8gdGhpc1xuXHRcdFx0cmV0ID0gW1xuXHRcdFx0XHQnQycsXG5cdFx0XHRcdGxhc3RQb2ludC5yaWdodENvbnRYIHx8IGxhc3RQb2ludC5wbG90WCxcblx0XHRcdFx0bGFzdFBvaW50LnJpZ2h0Q29udFkgfHwgbGFzdFBvaW50LnBsb3RZLFxuXHRcdFx0XHRsZWZ0Q29udFggfHwgcGxvdFgsXG5cdFx0XHRcdGxlZnRDb250WSB8fCBwbG90WSxcblx0XHRcdFx0cGxvdFgsXG5cdFx0XHRcdHBsb3RZXG5cdFx0XHRdO1xuXHRcdFx0bGFzdFBvaW50LnJpZ2h0Q29udFggPSBsYXN0UG9pbnQucmlnaHRDb250WSA9IG51bGw7IC8vIHJlc2V0IGZvciB1cGRhdGluZyBzZXJpZXMgbGF0ZXJcblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fVxufSk7XG5zZXJpZXNUeXBlcy5zcGxpbmUgPSBTcGxpbmVTZXJpZXM7XG5cbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIGFyZWFzcGxpbmVcbiAqL1xuZGVmYXVsdFBsb3RPcHRpb25zLmFyZWFzcGxpbmUgPSBtZXJnZShkZWZhdWx0UGxvdE9wdGlvbnMuYXJlYSk7XG5cbi8qKlxuICogQXJlYVNwbGluZVNlcmllcyBvYmplY3RcbiAqL1xudmFyIGFyZWFQcm90byA9IEFyZWFTZXJpZXMucHJvdG90eXBlLFxuXHRBcmVhU3BsaW5lU2VyaWVzID0gZXh0ZW5kQ2xhc3MoU3BsaW5lU2VyaWVzLCB7XG5cdFx0dHlwZTogJ2FyZWFzcGxpbmUnLFxuXHRcdGNsb3NlZFN0YWNrczogdHJ1ZSwgLy8gaW5zdGVhZCBvZiBmb2xsb3dpbmcgdGhlIHByZXZpb3VzIGdyYXBoIGJhY2ssIGZvbGxvdyB0aGUgdGhyZXNob2xkIGJhY2tcblx0XHRcblx0XHQvLyBNaXggaW4gbWV0aG9kcyBmcm9tIHRoZSBhcmVhIHNlcmllc1xuXHRcdGdldFNlZ21lbnRQYXRoOiBhcmVhUHJvdG8uZ2V0U2VnbWVudFBhdGgsXG5cdFx0Y2xvc2VTZWdtZW50OiBhcmVhUHJvdG8uY2xvc2VTZWdtZW50LFxuXHRcdGRyYXdHcmFwaDogYXJlYVByb3RvLmRyYXdHcmFwaCxcblx0XHRkcmF3TGVnZW5kU3ltYm9sOiBMZWdlbmRTeW1ib2xNaXhpbi5kcmF3UmVjdGFuZ2xlXG5cdH0pO1xuXG5zZXJpZXNUeXBlcy5hcmVhc3BsaW5lID0gQXJlYVNwbGluZVNlcmllcztcblxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBmb3IgY29sdW1uXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5jb2x1bW4gPSBtZXJnZShkZWZhdWx0U2VyaWVzT3B0aW9ucywge1xuXHRib3JkZXJDb2xvcjogJyNGRkZGRkYnLFxuXHQvL2JvcmRlcldpZHRoOiAxLFxuXHRib3JkZXJSYWRpdXM6IDAsXG5cdC8vY29sb3JCeVBvaW50OiB1bmRlZmluZWQsXG5cdGdyb3VwUGFkZGluZzogMC4yLFxuXHQvL2dyb3VwaW5nOiB0cnVlLFxuXHRtYXJrZXI6IG51bGwsIC8vIHBvaW50IG9wdGlvbnMgYXJlIHNwZWNpZmllZCBpbiB0aGUgYmFzZSBvcHRpb25zXG5cdHBvaW50UGFkZGluZzogMC4xLFxuXHQvL3BvaW50V2lkdGg6IG51bGwsXG5cdG1pblBvaW50TGVuZ3RoOiAwLFxuXHRjcm9wVGhyZXNob2xkOiA1MCwgLy8gd2hlbiB0aGVyZSBhcmUgbW9yZSBwb2ludHMsIHRoZXkgd2lsbCBub3QgYW5pbWF0ZSBvdXQgb2YgdGhlIGNoYXJ0IG9uIHhBeGlzLnNldEV4dHJlbWVzXG5cdHBvaW50UmFuZ2U6IG51bGwsIC8vIG51bGwgbWVhbnMgYXV0bywgbWVhbmluZyAxIGluIGEgY2F0ZWdvcml6ZWQgYXhpcyBhbmQgbGVhc3QgZGlzdGFuY2UgYmV0d2VlbiBwb2ludHMgaWYgbm90IGNhdGVnb3JpZXNcblx0c3RhdGVzOiB7XG5cdFx0aG92ZXI6IHtcblx0XHRcdGJyaWdodG5lc3M6IDAuMSxcblx0XHRcdHNoYWRvdzogZmFsc2UsXG5cdFx0XHRoYWxvOiBmYWxzZVxuXHRcdH0sXG5cdFx0c2VsZWN0OiB7XG5cdFx0XHRjb2xvcjogJyNDMEMwQzAnLFxuXHRcdFx0Ym9yZGVyQ29sb3I6ICcjMDAwMDAwJyxcblx0XHRcdHNoYWRvdzogZmFsc2Vcblx0XHR9XG5cdH0sXG5cdGRhdGFMYWJlbHM6IHtcblx0XHRhbGlnbjogbnVsbCwgLy8gYXV0b1xuXHRcdHZlcnRpY2FsQWxpZ246IG51bGwsIC8vIGF1dG9cblx0XHR5OiBudWxsXG5cdH0sXG5cdHN0aWNreVRyYWNraW5nOiBmYWxzZSxcblx0dG9vbHRpcDoge1xuXHRcdGRpc3RhbmNlOiA2XG5cdH0sXG5cdHRocmVzaG9sZDogMFxufSk7XG5cbi8qKlxuICogQ29sdW1uU2VyaWVzIG9iamVjdFxuICovXG52YXIgQ29sdW1uU2VyaWVzID0gZXh0ZW5kQ2xhc3MoU2VyaWVzLCB7XG5cdHR5cGU6ICdjb2x1bW4nLFxuXHRwb2ludEF0dHJUb09wdGlvbnM6IHsgLy8gbWFwcGluZyBiZXR3ZWVuIFNWRyBhdHRyaWJ1dGVzIGFuZCB0aGUgY29ycmVzcG9uZGluZyBvcHRpb25zXG5cdFx0c3Ryb2tlOiAnYm9yZGVyQ29sb3InLFxuXHRcdGZpbGw6ICdjb2xvcicsXG5cdFx0cjogJ2JvcmRlclJhZGl1cydcblx0fSxcblx0Y3JvcFNob3VsZGVyOiAwLFxuXHR0cmFja2VyR3JvdXBzOiBbJ2dyb3VwJywgJ2RhdGFMYWJlbHNHcm91cCddLFxuXHRuZWdTdGFja3M6IHRydWUsIC8vIHVzZSBzZXBhcmF0ZSBuZWdhdGl2ZSBzdGFja3MsIHVubGlrZSBhcmVhIHN0YWNrcyB3aGVyZSBhIG5lZ2F0aXZlIFxuXHRcdC8vIHBvaW50IGlzIHN1YnN0cmFjdGVkIGZyb20gcHJldmlvdXMgKCMxOTEwKVxuXHRcblx0LyoqXG5cdCAqIEluaXRpYWxpemUgdGhlIHNlcmllc1xuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKCkge1xuXHRcdFNlcmllcy5wcm90b3R5cGUuaW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydDtcblxuXHRcdC8vIGlmIHRoZSBzZXJpZXMgaXMgYWRkZWQgZHluYW1pY2FsbHksIGZvcmNlIHJlZHJhdyBvZiBvdGhlclxuXHRcdC8vIHNlcmllcyBhZmZlY3RlZCBieSBhIG5ldyBjb2x1bW5cblx0XHRpZiAoY2hhcnQuaGFzUmVuZGVyZWQpIHtcblx0XHRcdGVhY2goY2hhcnQuc2VyaWVzLCBmdW5jdGlvbiAob3RoZXJTZXJpZXMpIHtcblx0XHRcdFx0aWYgKG90aGVyU2VyaWVzLnR5cGUgPT09IHNlcmllcy50eXBlKSB7XG5cdFx0XHRcdFx0b3RoZXJTZXJpZXMuaXNEaXJ0eSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUmV0dXJuIHRoZSB3aWR0aCBhbmQgeCBvZmZzZXQgb2YgdGhlIGNvbHVtbnMgYWRqdXN0ZWQgZm9yIGdyb3VwaW5nLCBncm91cFBhZGRpbmcsIHBvaW50UGFkZGluZyxcblx0ICogcG9pbnRXaWR0aCBldGMuIFxuXHQgKi9cblx0Z2V0Q29sdW1uTWV0cmljczogZnVuY3Rpb24gKCkge1xuXG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHR4QXhpcyA9IHNlcmllcy54QXhpcyxcblx0XHRcdHlBeGlzID0gc2VyaWVzLnlBeGlzLFxuXHRcdFx0cmV2ZXJzZWRYQXhpcyA9IHhBeGlzLnJldmVyc2VkLFxuXHRcdFx0c3RhY2tLZXksXG5cdFx0XHRzdGFja0dyb3VwcyA9IHt9LFxuXHRcdFx0Y29sdW1uSW5kZXgsXG5cdFx0XHRjb2x1bW5Db3VudCA9IDA7XG5cblx0XHQvLyBHZXQgdGhlIHRvdGFsIG51bWJlciBvZiBjb2x1bW4gdHlwZSBzZXJpZXMuXG5cdFx0Ly8gVGhpcyBpcyBjYWxsZWQgb24gZXZlcnkgc2VyaWVzLiBDb25zaWRlciBtb3ZpbmcgdGhpcyBsb2dpYyB0byBhXG5cdFx0Ly8gY2hhcnQub3JkZXJTdGFja3MoKSBmdW5jdGlvbiBhbmQgY2FsbCBpdCBvbiBpbml0LCBhZGRTZXJpZXMgYW5kIHJlbW92ZVNlcmllc1xuXHRcdGlmIChvcHRpb25zLmdyb3VwaW5nID09PSBmYWxzZSkge1xuXHRcdFx0Y29sdW1uQ291bnQgPSAxO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRlYWNoKHNlcmllcy5jaGFydC5zZXJpZXMsIGZ1bmN0aW9uIChvdGhlclNlcmllcykge1xuXHRcdFx0XHR2YXIgb3RoZXJPcHRpb25zID0gb3RoZXJTZXJpZXMub3B0aW9ucyxcblx0XHRcdFx0XHRvdGhlcllBeGlzID0gb3RoZXJTZXJpZXMueUF4aXM7XG5cdFx0XHRcdGlmIChvdGhlclNlcmllcy50eXBlID09PSBzZXJpZXMudHlwZSAmJiBvdGhlclNlcmllcy52aXNpYmxlICYmXG5cdFx0XHRcdFx0XHR5QXhpcy5sZW4gPT09IG90aGVyWUF4aXMubGVuICYmIHlBeGlzLnBvcyA9PT0gb3RoZXJZQXhpcy5wb3MpIHsgIC8vICM2NDIsICMyMDg2XG5cdFx0XHRcdFx0aWYgKG90aGVyT3B0aW9ucy5zdGFja2luZykge1xuXHRcdFx0XHRcdFx0c3RhY2tLZXkgPSBvdGhlclNlcmllcy5zdGFja0tleTtcblx0XHRcdFx0XHRcdGlmIChzdGFja0dyb3Vwc1tzdGFja0tleV0gPT09IFVOREVGSU5FRCkge1xuXHRcdFx0XHRcdFx0XHRzdGFja0dyb3Vwc1tzdGFja0tleV0gPSBjb2x1bW5Db3VudCsrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Y29sdW1uSW5kZXggPSBzdGFja0dyb3Vwc1tzdGFja0tleV07XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChvdGhlck9wdGlvbnMuZ3JvdXBpbmcgIT09IGZhbHNlKSB7IC8vICMxMTYyXG5cdFx0XHRcdFx0XHRjb2x1bW5JbmRleCA9IGNvbHVtbkNvdW50Kys7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG90aGVyU2VyaWVzLmNvbHVtbkluZGV4ID0gY29sdW1uSW5kZXg7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHZhciBjYXRlZ29yeVdpZHRoID0gbWF0aE1pbihcblx0XHRcdFx0bWF0aEFicyh4QXhpcy50cmFuc0EpICogKHhBeGlzLm9yZGluYWxTbG9wZSB8fCBvcHRpb25zLnBvaW50UmFuZ2UgfHwgeEF4aXMuY2xvc2VzdFBvaW50UmFuZ2UgfHwgeEF4aXMudGlja0ludGVydmFsIHx8IDEpLCAvLyAjMjYxMFxuXHRcdFx0XHR4QXhpcy5sZW4gLy8gIzE1MzVcblx0XHRcdCksXG5cdFx0XHRncm91cFBhZGRpbmcgPSBjYXRlZ29yeVdpZHRoICogb3B0aW9ucy5ncm91cFBhZGRpbmcsXG5cdFx0XHRncm91cFdpZHRoID0gY2F0ZWdvcnlXaWR0aCAtIDIgKiBncm91cFBhZGRpbmcsXG5cdFx0XHRwb2ludE9mZnNldFdpZHRoID0gZ3JvdXBXaWR0aCAvIGNvbHVtbkNvdW50LFxuXHRcdFx0b3B0aW9uUG9pbnRXaWR0aCA9IG9wdGlvbnMucG9pbnRXaWR0aCxcblx0XHRcdHBvaW50UGFkZGluZyA9IGRlZmluZWQob3B0aW9uUG9pbnRXaWR0aCkgPyAocG9pbnRPZmZzZXRXaWR0aCAtIG9wdGlvblBvaW50V2lkdGgpIC8gMiA6XG5cdFx0XHRcdHBvaW50T2Zmc2V0V2lkdGggKiBvcHRpb25zLnBvaW50UGFkZGluZyxcblx0XHRcdHBvaW50V2lkdGggPSBwaWNrKG9wdGlvblBvaW50V2lkdGgsIHBvaW50T2Zmc2V0V2lkdGggLSAyICogcG9pbnRQYWRkaW5nKSwgLy8gZXhhY3QgcG9pbnQgd2lkdGgsIHVzZWQgaW4gcG9sYXIgY2hhcnRzXG5cdFx0XHRjb2xJbmRleCA9IChyZXZlcnNlZFhBeGlzID8gXG5cdFx0XHRcdGNvbHVtbkNvdW50IC0gKHNlcmllcy5jb2x1bW5JbmRleCB8fCAwKSA6IC8vICMxMjUxXG5cdFx0XHRcdHNlcmllcy5jb2x1bW5JbmRleCkgfHwgMCxcblx0XHRcdHBvaW50WE9mZnNldCA9IHBvaW50UGFkZGluZyArIChncm91cFBhZGRpbmcgKyBjb2xJbmRleCAqXG5cdFx0XHRcdHBvaW50T2Zmc2V0V2lkdGggLSAoY2F0ZWdvcnlXaWR0aCAvIDIpKSAqXG5cdFx0XHRcdChyZXZlcnNlZFhBeGlzID8gLTEgOiAxKTtcblxuXHRcdC8vIFNhdmUgaXQgZm9yIHJlYWRpbmcgaW4gbGlua2VkIHNlcmllcyAoRXJyb3IgYmFycyBwYXJ0aWN1bGFybHkpXG5cdFx0cmV0dXJuIChzZXJpZXMuY29sdW1uTWV0cmljcyA9IHsgXG5cdFx0XHR3aWR0aDogcG9pbnRXaWR0aCwgXG5cdFx0XHRvZmZzZXQ6IHBvaW50WE9mZnNldCBcblx0XHR9KTtcblx0XHRcdFxuXHR9LFxuXG5cdC8qKlxuXHQgKiBUcmFuc2xhdGUgZWFjaCBwb2ludCB0byB0aGUgcGxvdCBhcmVhIGNvb3JkaW5hdGUgc3lzdGVtIGFuZCBmaW5kIHNoYXBlIHBvc2l0aW9uc1xuXHQgKi9cblx0dHJhbnNsYXRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGJvcmRlcldpZHRoID0gc2VyaWVzLmJvcmRlcldpZHRoID0gcGljayhcblx0XHRcdFx0b3B0aW9ucy5ib3JkZXJXaWR0aCwgXG5cdFx0XHRcdHNlcmllcy5hY3RpdmVQb2ludENvdW50ID4gMC41ICogc2VyaWVzLnhBeGlzLmxlbiA/IDAgOiAxXG5cdFx0XHQpLFxuXHRcdFx0eUF4aXMgPSBzZXJpZXMueUF4aXMsXG5cdFx0XHR0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCxcblx0XHRcdHRyYW5zbGF0ZWRUaHJlc2hvbGQgPSBzZXJpZXMudHJhbnNsYXRlZFRocmVzaG9sZCA9IHlBeGlzLmdldFRocmVzaG9sZCh0aHJlc2hvbGQpLFxuXHRcdFx0bWluUG9pbnRMZW5ndGggPSBwaWNrKG9wdGlvbnMubWluUG9pbnRMZW5ndGgsIDUpLFxuXHRcdFx0bWV0cmljcyA9IHNlcmllcy5nZXRDb2x1bW5NZXRyaWNzKCksXG5cdFx0XHRwb2ludFdpZHRoID0gbWV0cmljcy53aWR0aCxcblx0XHRcdHNlcmllc0JhclcgPSBzZXJpZXMuYmFyVyA9IG1hdGhNYXgocG9pbnRXaWR0aCwgMSArIDIgKiBib3JkZXJXaWR0aCksIC8vIHBvc3Rwcm9jZXNzZWQgZm9yIGJvcmRlciB3aWR0aFxuXHRcdFx0cG9pbnRYT2Zmc2V0ID0gc2VyaWVzLnBvaW50WE9mZnNldCA9IG1ldHJpY3Mub2Zmc2V0LFxuXHRcdFx0eENyaXNwID0gLShib3JkZXJXaWR0aCAlIDIgPyAwLjUgOiAwKSxcblx0XHRcdHlDcmlzcCA9IGJvcmRlcldpZHRoICUgMiA/IDAuNSA6IDE7XG5cblx0XHRpZiAoY2hhcnQucmVuZGVyZXIuaXNWTUwgJiYgY2hhcnQuaW52ZXJ0ZWQpIHtcblx0XHRcdHlDcmlzcCArPSAxO1xuXHRcdH1cblxuXHRcdC8vIFdoZW4gdGhlIHBvaW50UGFkZGluZyBpcyAwLCB3ZSB3YW50IHRoZSBjb2x1bW5zIHRvIGJlIHBhY2tlZCB0aWdodGx5LCBzbyB3ZSBhbGxvdyBpbmRpdmlkdWFsXG5cdFx0Ly8gY29sdW1ucyB0byBoYXZlIGluZGl2aWR1YWwgc2l6ZXMuIFdoZW4gcG9pbnRQYWRkaW5nIGlzIGdyZWF0ZXIsIHdlIHN0cml2ZSBmb3IgZXF1YWwtd2lkdGhcblx0XHQvLyBjb2x1bW5zICgjMjY5NCkuXG5cdFx0aWYgKG9wdGlvbnMucG9pbnRQYWRkaW5nKSB7XG5cdFx0XHRzZXJpZXNCYXJXID0gbWF0aENlaWwoc2VyaWVzQmFyVyk7XG5cdFx0fVxuXG5cdFx0U2VyaWVzLnByb3RvdHlwZS50cmFuc2xhdGUuYXBwbHkoc2VyaWVzKTtcblxuXHRcdC8vIFJlY29yZCB0aGUgbmV3IHZhbHVlc1xuXHRcdGVhY2goc2VyaWVzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHR2YXIgeUJvdHRvbSA9IHBpY2socG9pbnQueUJvdHRvbSwgdHJhbnNsYXRlZFRocmVzaG9sZCksXG5cdFx0XHRcdHBsb3RZID0gbWF0aE1pbihtYXRoTWF4KC05OTkgLSB5Qm90dG9tLCBwb2ludC5wbG90WSksIHlBeGlzLmxlbiArIDk5OSArIHlCb3R0b20pLCAvLyBEb24ndCBkcmF3IHRvbyBmYXIgb3V0c2lkZSBwbG90IGFyZWEgKCMxMzAzLCAjMjI0MSlcblx0XHRcdFx0YmFyWCA9IHBvaW50LnBsb3RYICsgcG9pbnRYT2Zmc2V0LFxuXHRcdFx0XHRiYXJXID0gc2VyaWVzQmFyVyxcblx0XHRcdFx0YmFyWSA9IG1hdGhNaW4ocGxvdFksIHlCb3R0b20pLFxuXHRcdFx0XHRyaWdodCxcblx0XHRcdFx0Ym90dG9tLFxuXHRcdFx0XHRmcm9tVG9wLFxuXHRcdFx0XHRiYXJIID0gbWF0aE1heChwbG90WSwgeUJvdHRvbSkgLSBiYXJZO1xuXG5cdFx0XHQvLyBIYW5kbGUgb3B0aW9ucy5taW5Qb2ludExlbmd0aFxuXHRcdFx0aWYgKG1hdGhBYnMoYmFySCkgPCBtaW5Qb2ludExlbmd0aCkge1xuXHRcdFx0XHRpZiAobWluUG9pbnRMZW5ndGgpIHtcblx0XHRcdFx0XHRiYXJIID0gbWluUG9pbnRMZW5ndGg7XG5cdFx0XHRcdFx0YmFyWSA9XG5cdFx0XHRcdFx0XHRtYXRoUm91bmQobWF0aEFicyhiYXJZIC0gdHJhbnNsYXRlZFRocmVzaG9sZCkgPiBtaW5Qb2ludExlbmd0aCA/IC8vIHN0YWNrZWRcblx0XHRcdFx0XHRcdFx0eUJvdHRvbSAtIG1pblBvaW50TGVuZ3RoIDogLy8ga2VlcCBwb3NpdGlvblxuXHRcdFx0XHRcdFx0XHR0cmFuc2xhdGVkVGhyZXNob2xkIC0gKHlBeGlzLnRyYW5zbGF0ZShwb2ludC55LCAwLCAxLCAwLCAxKSA8PSB0cmFuc2xhdGVkVGhyZXNob2xkID8gbWluUG9pbnRMZW5ndGggOiAwKSk7IC8vIHVzZSBleGFjdCB5QXhpcy50cmFuc2xhdGlvbiAoIzE0ODUpXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FjaGUgZm9yIGFjY2VzcyBpbiBwb2xhclxuXHRcdFx0cG9pbnQuYmFyWCA9IGJhclg7XG5cdFx0XHRwb2ludC5wb2ludFdpZHRoID0gcG9pbnRXaWR0aDtcblxuXHRcdFx0Ly8gRml4IHRoZSB0b29sdGlwIG9uIGNlbnRlciBvZiBncm91cGVkIGNvbHVtbnMgKCMxMjE2LCAjNDI0KVxuXHRcdFx0cG9pbnQudG9vbHRpcFBvcyA9IGNoYXJ0LmludmVydGVkID8gXG5cdFx0XHRcdFt5QXhpcy5sZW4gLSBwbG90WSwgc2VyaWVzLnhBeGlzLmxlbiAtIGJhclggLSBiYXJXIC8gMl0gOiBcblx0XHRcdFx0W2JhclggKyBiYXJXIC8gMiwgcGxvdFkgKyB5QXhpcy5wb3MgLSBjaGFydC5wbG90VG9wXTtcblxuXHRcdFx0Ly8gUm91bmQgb2ZmIHRvIG9idGFpbiBjcmlzcCBlZGdlcyBhbmQgYXZvaWQgb3ZlcmxhcHBpbmcgd2l0aCBuZWlnaGJvdXJzICgjMjY5NClcblx0XHRcdHJpZ2h0ID0gbWF0aFJvdW5kKGJhclggKyBiYXJXKSArIHhDcmlzcDtcblx0XHRcdGJhclggPSBtYXRoUm91bmQoYmFyWCkgKyB4Q3Jpc3A7XG5cdFx0XHRiYXJXID0gcmlnaHQgLSBiYXJYO1xuXG5cdFx0XHRmcm9tVG9wID0gbWF0aEFicyhiYXJZKSA8IDAuNTtcblx0XHRcdGJvdHRvbSA9IG1hdGhSb3VuZChiYXJZICsgYmFySCkgKyB5Q3Jpc3A7XG5cdFx0XHRiYXJZID0gbWF0aFJvdW5kKGJhclkpICsgeUNyaXNwO1xuXHRcdFx0YmFySCA9IGJvdHRvbSAtIGJhclk7XG5cblx0XHRcdC8vIFRvcCBlZGdlcyBhcmUgZXhjZXB0aW9uc1xuXHRcdFx0aWYgKGZyb21Ub3ApIHtcblx0XHRcdFx0YmFyWSAtPSAxO1xuXHRcdFx0XHRiYXJIICs9IDE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlZ2lzdGVyIHNoYXBlIHR5cGUgYW5kIGFyZ3VtZW50cyB0byBiZSB1c2VkIGluIGRyYXdQb2ludHNcblx0XHRcdHBvaW50LnNoYXBlVHlwZSA9ICdyZWN0Jztcblx0XHRcdHBvaW50LnNoYXBlQXJncyA9IHtcblx0XHRcdFx0eDogYmFyWCxcblx0XHRcdFx0eTogYmFyWSxcblx0XHRcdFx0d2lkdGg6IGJhclcsXG5cdFx0XHRcdGhlaWdodDogYmFySFxuXHRcdFx0fTtcblxuXHRcdH0pO1xuXG5cdH0sXG5cblx0Z2V0U3ltYm9sOiBub29wLFxuXHRcblx0LyoqXG5cdCAqIFVzZSBhIHNvbGlkIHJlY3RhbmdsZSBsaWtlIHRoZSBhcmVhIHNlcmllcyB0eXBlc1xuXHQgKi9cblx0ZHJhd0xlZ2VuZFN5bWJvbDogTGVnZW5kU3ltYm9sTWl4aW4uZHJhd1JlY3RhbmdsZSxcblx0XG5cdFxuXHQvKipcblx0ICogQ29sdW1ucyBoYXZlIG5vIGdyYXBoXG5cdCAqL1xuXHRkcmF3R3JhcGg6IG5vb3AsXG5cblx0LyoqXG5cdCAqIERyYXcgdGhlIGNvbHVtbnMuIEZvciBiYXJzLCB0aGUgc2VyaWVzLmdyb3VwIGlzIHJvdGF0ZWQsIHNvIHRoZSBzYW1lIGNvb3JkaW5hdGVzXG5cdCAqIGFwcGx5IGZvciBjb2x1bW5zIGFuZCBiYXJzLiBUaGlzIG1ldGhvZCBpcyBpbmhlcml0ZWQgYnkgc2NhdHRlciBzZXJpZXMuXG5cdCAqXG5cdCAqL1xuXHRkcmF3UG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHRoaXMuY2hhcnQsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0YW5pbWF0aW9uTGltaXQgPSBvcHRpb25zLmFuaW1hdGlvbkxpbWl0IHx8IDI1MCxcblx0XHRcdHNoYXBlQXJncyxcblx0XHRcdHBvaW50QXR0cjtcblxuXHRcdC8vIGRyYXcgdGhlIGNvbHVtbnNcblx0XHRlYWNoKHNlcmllcy5wb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0dmFyIHBsb3RZID0gcG9pbnQucGxvdFksXG5cdFx0XHRcdGdyYXBoaWMgPSBwb2ludC5ncmFwaGljLFxuXHRcdFx0XHRib3JkZXJBdHRyO1xuXG5cdFx0XHRpZiAocGxvdFkgIT09IFVOREVGSU5FRCAmJiAhaXNOYU4ocGxvdFkpICYmIHBvaW50LnkgIT09IG51bGwpIHtcblx0XHRcdFx0c2hhcGVBcmdzID0gcG9pbnQuc2hhcGVBcmdzO1xuXG5cdFx0XHRcdGJvcmRlckF0dHIgPSBkZWZpbmVkKHNlcmllcy5ib3JkZXJXaWR0aCkgPyB7XG5cdFx0XHRcdFx0J3N0cm9rZS13aWR0aCc6IHNlcmllcy5ib3JkZXJXaWR0aFxuXHRcdFx0XHR9IDoge307XG5cblx0XHRcdFx0cG9pbnRBdHRyID0gcG9pbnQucG9pbnRBdHRyW3BvaW50LnNlbGVjdGVkID8gU0VMRUNUX1NUQVRFIDogTk9STUFMX1NUQVRFXSB8fCBzZXJpZXMucG9pbnRBdHRyW05PUk1BTF9TVEFURV07XG5cdFx0XHRcdFxuXHRcdFx0XHRpZiAoZ3JhcGhpYykgeyAvLyB1cGRhdGVcblx0XHRcdFx0XHRzdG9wKGdyYXBoaWMpO1xuXHRcdFx0XHRcdGdyYXBoaWMuYXR0cihib3JkZXJBdHRyKVtjaGFydC5wb2ludENvdW50IDwgYW5pbWF0aW9uTGltaXQgPyAnYW5pbWF0ZScgOiAnYXR0ciddKG1lcmdlKHNoYXBlQXJncykpO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cG9pbnQuZ3JhcGhpYyA9IGdyYXBoaWMgPSByZW5kZXJlcltwb2ludC5zaGFwZVR5cGVdKHNoYXBlQXJncylcblx0XHRcdFx0XHRcdC5hdHRyKHBvaW50QXR0cilcblx0XHRcdFx0XHRcdC5hdHRyKGJvcmRlckF0dHIpXG5cdFx0XHRcdFx0XHQuYWRkKHNlcmllcy5ncm91cClcblx0XHRcdFx0XHRcdC5zaGFkb3cob3B0aW9ucy5zaGFkb3csIG51bGwsIG9wdGlvbnMuc3RhY2tpbmcgJiYgIW9wdGlvbnMuYm9yZGVyUmFkaXVzKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKGdyYXBoaWMpIHtcblx0XHRcdFx0cG9pbnQuZ3JhcGhpYyA9IGdyYXBoaWMuZGVzdHJveSgpOyAvLyAjMTI2OVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBBbmltYXRlIHRoZSBjb2x1bW4gaGVpZ2h0cyBvbmUgYnkgb25lIGZyb20gemVyb1xuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IGluaXQgV2hldGhlciB0byBpbml0aWFsaXplIHRoZSBhbmltYXRpb24gb3IgcnVuIGl0XG5cdCAqL1xuXHRhbmltYXRlOiBmdW5jdGlvbiAoaW5pdCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0eUF4aXMgPSB0aGlzLnlBeGlzLFxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0aW52ZXJ0ZWQgPSB0aGlzLmNoYXJ0LmludmVydGVkLFxuXHRcdFx0YXR0ciA9IHt9LFxuXHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZDtcblxuXHRcdGlmIChoYXNTVkcpIHsgLy8gVk1MIGlzIHRvbyBzbG93IGFueXdheVxuXHRcdFx0aWYgKGluaXQpIHtcblx0XHRcdFx0YXR0ci5zY2FsZVkgPSAwLjAwMTtcblx0XHRcdFx0dHJhbnNsYXRlZFRocmVzaG9sZCA9IG1hdGhNaW4oeUF4aXMucG9zICsgeUF4aXMubGVuLCBtYXRoTWF4KHlBeGlzLnBvcywgeUF4aXMudG9QaXhlbHMob3B0aW9ucy50aHJlc2hvbGQpKSk7XG5cdFx0XHRcdGlmIChpbnZlcnRlZCkge1xuXHRcdFx0XHRcdGF0dHIudHJhbnNsYXRlWCA9IHRyYW5zbGF0ZWRUaHJlc2hvbGQgLSB5QXhpcy5sZW47XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0YXR0ci50cmFuc2xhdGVZID0gdHJhbnNsYXRlZFRocmVzaG9sZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRzZXJpZXMuZ3JvdXAuYXR0cihhdHRyKTtcblxuXHRcdFx0fSBlbHNlIHsgLy8gcnVuIHRoZSBhbmltYXRpb25cblx0XHRcdFx0XG5cdFx0XHRcdGF0dHIuc2NhbGVZID0gMTtcblx0XHRcdFx0YXR0cltpbnZlcnRlZCA/ICd0cmFuc2xhdGVYJyA6ICd0cmFuc2xhdGVZJ10gPSB5QXhpcy5wb3M7XG5cdFx0XHRcdHNlcmllcy5ncm91cC5hbmltYXRlKGF0dHIsIHNlcmllcy5vcHRpb25zLmFuaW1hdGlvbik7XG5cblx0XHRcdFx0Ly8gZGVsZXRlIHRoaXMgZnVuY3Rpb24gdG8gYWxsb3cgaXQgb25seSBvbmNlXG5cdFx0XHRcdHNlcmllcy5hbmltYXRlID0gbnVsbDtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdFxuXHQvKipcblx0ICogUmVtb3ZlIHRoaXMgc2VyaWVzIGZyb20gdGhlIGNoYXJ0XG5cdCAqL1xuXHRyZW1vdmU6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0O1xuXG5cdFx0Ly8gY29sdW1uIGFuZCBiYXIgc2VyaWVzIGFmZmVjdHMgb3RoZXIgc2VyaWVzIG9mIHRoZSBzYW1lIHR5cGVcblx0XHQvLyBhcyB0aGV5IGFyZSBlaXRoZXIgc3RhY2tlZCBvciBncm91cGVkXG5cdFx0aWYgKGNoYXJ0Lmhhc1JlbmRlcmVkKSB7XG5cdFx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKG90aGVyU2VyaWVzKSB7XG5cdFx0XHRcdGlmIChvdGhlclNlcmllcy50eXBlID09PSBzZXJpZXMudHlwZSkge1xuXHRcdFx0XHRcdG90aGVyU2VyaWVzLmlzRGlydHkgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRTZXJpZXMucHJvdG90eXBlLnJlbW92ZS5hcHBseShzZXJpZXMsIGFyZ3VtZW50cyk7XG5cdH1cbn0pO1xuc2VyaWVzVHlwZXMuY29sdW1uID0gQ29sdW1uU2VyaWVzO1xuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgb3B0aW9ucyBmb3IgYmFyXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5iYXIgPSBtZXJnZShkZWZhdWx0UGxvdE9wdGlvbnMuY29sdW1uKTtcbi8qKlxuICogVGhlIEJhciBzZXJpZXMgY2xhc3NcbiAqL1xudmFyIEJhclNlcmllcyA9IGV4dGVuZENsYXNzKENvbHVtblNlcmllcywge1xuXHR0eXBlOiAnYmFyJyxcblx0aW52ZXJ0ZWQ6IHRydWVcbn0pO1xuc2VyaWVzVHlwZXMuYmFyID0gQmFyU2VyaWVzO1xuXG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBzY2F0dGVyXG4gKi9cbmRlZmF1bHRQbG90T3B0aW9ucy5zY2F0dGVyID0gbWVyZ2UoZGVmYXVsdFNlcmllc09wdGlvbnMsIHtcblx0bGluZVdpZHRoOiAwLFxuXHR0b29sdGlwOiB7XG5cdFx0aGVhZGVyRm9ybWF0OiAnPHNwYW4gc3R5bGU9XCJjb2xvcjp7c2VyaWVzLmNvbG9yfVwiPlxcdTI1Q0Y8L3NwYW4+IDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOiAxMHB4O1wiPiB7c2VyaWVzLm5hbWV9PC9zcGFuPjxici8+Jyxcblx0XHRwb2ludEZvcm1hdDogJ3g6IDxiPntwb2ludC54fTwvYj48YnIvPnk6IDxiPntwb2ludC55fTwvYj48YnIvPidcblx0fSxcblx0c3RpY2t5VHJhY2tpbmc6IGZhbHNlXG59KTtcblxuLyoqXG4gKiBUaGUgc2NhdHRlciBzZXJpZXMgY2xhc3NcbiAqL1xudmFyIFNjYXR0ZXJTZXJpZXMgPSBleHRlbmRDbGFzcyhTZXJpZXMsIHtcblx0dHlwZTogJ3NjYXR0ZXInLFxuXHRzb3J0ZWQ6IGZhbHNlLFxuXHRyZXF1aXJlU29ydGluZzogZmFsc2UsXG5cdG5vU2hhcmVkVG9vbHRpcDogdHJ1ZSxcblx0dHJhY2tlckdyb3VwczogWydtYXJrZXJHcm91cCcsICdkYXRhTGFiZWxzR3JvdXAnXSxcblx0dGFrZU9yZGluYWxQb3NpdGlvbjogZmFsc2UsIC8vICMyMzQyXG5cdHNpbmd1bGFyVG9vbHRpcHM6IHRydWUsXG5cdGRyYXdHcmFwaDogZnVuY3Rpb24gKCkge1xuXHRcdGlmICh0aGlzLm9wdGlvbnMubGluZVdpZHRoKSB7XG5cdFx0XHRTZXJpZXMucHJvdG90eXBlLmRyYXdHcmFwaC5jYWxsKHRoaXMpO1xuXHRcdH1cblx0fVxufSk7XG5cbnNlcmllc1R5cGVzLnNjYXR0ZXIgPSBTY2F0dGVyU2VyaWVzO1xuXG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBvcHRpb25zIGZvciBwaWVcbiAqL1xuZGVmYXVsdFBsb3RPcHRpb25zLnBpZSA9IG1lcmdlKGRlZmF1bHRTZXJpZXNPcHRpb25zLCB7XG5cdGJvcmRlckNvbG9yOiAnI0ZGRkZGRicsXG5cdGJvcmRlcldpZHRoOiAxLFxuXHRjZW50ZXI6IFtudWxsLCBudWxsXSxcblx0Y2xpcDogZmFsc2UsXG5cdGNvbG9yQnlQb2ludDogdHJ1ZSwgLy8gYWx3YXlzIHRydWUgZm9yIHBpZXNcblx0ZGF0YUxhYmVsczoge1xuXHRcdC8vIGFsaWduOiBudWxsLFxuXHRcdC8vIGNvbm5lY3RvcldpZHRoOiAxLFxuXHRcdC8vIGNvbm5lY3RvckNvbG9yOiBwb2ludC5jb2xvcixcblx0XHQvLyBjb25uZWN0b3JQYWRkaW5nOiA1LFxuXHRcdGRpc3RhbmNlOiAzMCxcblx0XHRlbmFibGVkOiB0cnVlLFxuXHRcdGZvcm1hdHRlcjogZnVuY3Rpb24gKCkgeyAvLyAjMjk0NVxuXHRcdFx0cmV0dXJuIHRoaXMucG9pbnQubmFtZTtcblx0XHR9XG5cdFx0Ly8gc29mdENvbm5lY3RvcjogdHJ1ZSxcblx0XHQvL3k6IDBcblx0fSxcblx0aWdub3JlSGlkZGVuUG9pbnQ6IHRydWUsXG5cdC8vaW5uZXJTaXplOiAwLFxuXHRsZWdlbmRUeXBlOiAncG9pbnQnLFxuXHRtYXJrZXI6IG51bGwsIC8vIHBvaW50IG9wdGlvbnMgYXJlIHNwZWNpZmllZCBpbiB0aGUgYmFzZSBvcHRpb25zXG5cdHNpemU6IG51bGwsXG5cdHNob3dJbkxlZ2VuZDogZmFsc2UsXG5cdHNsaWNlZE9mZnNldDogMTAsXG5cdHN0YXRlczoge1xuXHRcdGhvdmVyOiB7XG5cdFx0XHRicmlnaHRuZXNzOiAwLjEsXG5cdFx0XHRzaGFkb3c6IGZhbHNlXG5cdFx0fVxuXHR9LFxuXHRzdGlja3lUcmFja2luZzogZmFsc2UsXG5cdHRvb2x0aXA6IHtcblx0XHRmb2xsb3dQb2ludGVyOiB0cnVlXG5cdH1cbn0pO1xuXG4vKipcbiAqIEV4dGVuZGVkIHBvaW50IG9iamVjdCBmb3IgcGllc1xuICovXG52YXIgUGllUG9pbnQgPSBleHRlbmRDbGFzcyhQb2ludCwge1xuXHQvKipcblx0ICogSW5pdGlhdGUgdGhlIHBpZSBzbGljZVxuXHQgKi9cblx0aW5pdDogZnVuY3Rpb24gKCkge1xuXG5cdFx0UG9pbnQucHJvdG90eXBlLmluaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuXHRcdHZhciBwb2ludCA9IHRoaXMsXG5cdFx0XHR0b2dnbGVTbGljZTtcblxuXHRcdC8vIERpc2FsbG93IG5lZ2F0aXZlIHZhbHVlcyAoIzE1MzApXG5cdFx0aWYgKHBvaW50LnkgPCAwKSB7XG5cdFx0XHRwb2ludC55ID0gbnVsbDtcblx0XHR9XG5cblx0XHQvL3Zpc2libGU6IG9wdGlvbnMudmlzaWJsZSAhPT0gZmFsc2UsXG5cdFx0ZXh0ZW5kKHBvaW50LCB7XG5cdFx0XHR2aXNpYmxlOiBwb2ludC52aXNpYmxlICE9PSBmYWxzZSxcblx0XHRcdG5hbWU6IHBpY2socG9pbnQubmFtZSwgJ1NsaWNlJylcblx0XHR9KTtcblxuXHRcdC8vIGFkZCBldmVudCBsaXN0ZW5lciBmb3Igc2VsZWN0XG5cdFx0dG9nZ2xlU2xpY2UgPSBmdW5jdGlvbiAoZSkge1xuXHRcdFx0cG9pbnQuc2xpY2UoZS50eXBlID09PSAnc2VsZWN0Jyk7XG5cdFx0fTtcblx0XHRhZGRFdmVudChwb2ludCwgJ3NlbGVjdCcsIHRvZ2dsZVNsaWNlKTtcblx0XHRhZGRFdmVudChwb2ludCwgJ3Vuc2VsZWN0JywgdG9nZ2xlU2xpY2UpO1xuXG5cdFx0cmV0dXJuIHBvaW50O1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIHBpZSBzbGljZVxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHZpcyBXaGV0aGVyIHRvIHNob3cgdGhlIHNsaWNlIG9yIG5vdC4gSWYgdW5kZWZpbmVkLCB0aGVcblx0ICogICAgdmlzaWJpbGl0eSBpcyB0b2dnbGVkXG5cdCAqL1xuXHRzZXRWaXNpYmxlOiBmdW5jdGlvbiAodmlzKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0O1xuXG5cdFx0Ly8gaWYgY2FsbGVkIHdpdGhvdXQgYW4gYXJndW1lbnQsIHRvZ2dsZSB2aXNpYmlsaXR5XG5cdFx0cG9pbnQudmlzaWJsZSA9IHBvaW50Lm9wdGlvbnMudmlzaWJsZSA9IHZpcyA9IHZpcyA9PT0gVU5ERUZJTkVEID8gIXBvaW50LnZpc2libGUgOiB2aXM7XG5cdFx0c2VyaWVzLm9wdGlvbnMuZGF0YVtpbkFycmF5KHBvaW50LCBzZXJpZXMuZGF0YSldID0gcG9pbnQub3B0aW9uczsgLy8gdXBkYXRlIHVzZXJPcHRpb25zLmRhdGFcblxuXHRcdC8vIFNob3cgYW5kIGhpZGUgYXNzb2NpYXRlZCBlbGVtZW50c1xuXHRcdGVhY2goWydncmFwaGljJywgJ2RhdGFMYWJlbCcsICdjb25uZWN0b3InLCAnc2hhZG93R3JvdXAnXSwgZnVuY3Rpb24gKGtleSkge1xuXHRcdFx0aWYgKHBvaW50W2tleV0pIHtcblx0XHRcdFx0cG9pbnRba2V5XVt2aXMgPyAnc2hvdycgOiAnaGlkZSddKHRydWUpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0aWYgKHBvaW50LmxlZ2VuZEl0ZW0pIHtcblx0XHRcdGNoYXJ0LmxlZ2VuZC5jb2xvcml6ZUl0ZW0ocG9pbnQsIHZpcyk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIEhhbmRsZSBpZ25vcmUgaGlkZGVuIHNsaWNlc1xuXHRcdGlmICghc2VyaWVzLmlzRGlydHkgJiYgc2VyaWVzLm9wdGlvbnMuaWdub3JlSGlkZGVuUG9pbnQpIHtcblx0XHRcdHNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdGNoYXJ0LnJlZHJhdygpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IG9yIHRvZ2dsZSB3aGV0aGVyIHRoZSBzbGljZSBpcyBjdXQgb3V0IGZyb20gdGhlIHBpZVxuXHQgKiBAcGFyYW0ge0Jvb2xlYW59IHNsaWNlZCBXaGVuIHVuZGVmaW5lZCwgdGhlIHNsaWNlIHN0YXRlIGlzIHRvZ2dsZWRcblx0ICogQHBhcmFtIHtCb29sZWFufSByZWRyYXcgV2hldGhlciB0byByZWRyYXcgdGhlIGNoYXJ0LiBUcnVlIGJ5IGRlZmF1bHQuXG5cdCAqL1xuXHRzbGljZTogZnVuY3Rpb24gKHNsaWNlZCwgcmVkcmF3LCBhbmltYXRpb24pIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHR0cmFuc2xhdGlvbjtcblxuXHRcdHNldEFuaW1hdGlvbihhbmltYXRpb24sIGNoYXJ0KTtcblxuXHRcdC8vIHJlZHJhdyBpcyB0cnVlIGJ5IGRlZmF1bHRcblx0XHRyZWRyYXcgPSBwaWNrKHJlZHJhdywgdHJ1ZSk7XG5cblx0XHQvLyBpZiBjYWxsZWQgd2l0aG91dCBhbiBhcmd1bWVudCwgdG9nZ2xlXG5cdFx0cG9pbnQuc2xpY2VkID0gcG9pbnQub3B0aW9ucy5zbGljZWQgPSBzbGljZWQgPSBkZWZpbmVkKHNsaWNlZCkgPyBzbGljZWQgOiAhcG9pbnQuc2xpY2VkO1xuXHRcdHNlcmllcy5vcHRpb25zLmRhdGFbaW5BcnJheShwb2ludCwgc2VyaWVzLmRhdGEpXSA9IHBvaW50Lm9wdGlvbnM7IC8vIHVwZGF0ZSB1c2VyT3B0aW9ucy5kYXRhXG5cblx0XHR0cmFuc2xhdGlvbiA9IHNsaWNlZCA/IHBvaW50LnNsaWNlZFRyYW5zbGF0aW9uIDoge1xuXHRcdFx0dHJhbnNsYXRlWDogMCxcblx0XHRcdHRyYW5zbGF0ZVk6IDBcblx0XHR9O1xuXG5cdFx0cG9pbnQuZ3JhcGhpYy5hbmltYXRlKHRyYW5zbGF0aW9uKTtcblx0XHRcblx0XHRpZiAocG9pbnQuc2hhZG93R3JvdXApIHtcblx0XHRcdHBvaW50LnNoYWRvd0dyb3VwLmFuaW1hdGUodHJhbnNsYXRpb24pO1xuXHRcdH1cblxuXHR9LFxuXG5cdGhhbG9QYXRoOiBmdW5jdGlvbiAoc2l6ZSkge1xuXHRcdHZhciBzaGFwZUFyZ3MgPSB0aGlzLnNoYXBlQXJncyxcblx0XHRcdGNoYXJ0ID0gdGhpcy5zZXJpZXMuY2hhcnQ7XG5cblx0XHRyZXR1cm4gdGhpcy5zbGljZWQgfHwgIXRoaXMudmlzaWJsZSA/IFtdIDogdGhpcy5zZXJpZXMuY2hhcnQucmVuZGVyZXIuc3ltYm9scy5hcmMoY2hhcnQucGxvdExlZnQgKyBzaGFwZUFyZ3MueCwgY2hhcnQucGxvdFRvcCArIHNoYXBlQXJncy55LCBzaGFwZUFyZ3MuciArIHNpemUsIHNoYXBlQXJncy5yICsgc2l6ZSwge1xuXHRcdFx0aW5uZXJSOiB0aGlzLnNoYXBlQXJncy5yLFxuXHRcdFx0c3RhcnQ6IHNoYXBlQXJncy5zdGFydCxcblx0XHRcdGVuZDogc2hhcGVBcmdzLmVuZFxuXHRcdH0pO1xuXHR9XG59KTtcblxuLyoqXG4gKiBUaGUgUGllIHNlcmllcyBjbGFzc1xuICovXG52YXIgUGllU2VyaWVzID0ge1xuXHR0eXBlOiAncGllJyxcblx0aXNDYXJ0ZXNpYW46IGZhbHNlLFxuXHRwb2ludENsYXNzOiBQaWVQb2ludCxcblx0cmVxdWlyZVNvcnRpbmc6IGZhbHNlLFxuXHRub1NoYXJlZFRvb2x0aXA6IHRydWUsXG5cdHRyYWNrZXJHcm91cHM6IFsnZ3JvdXAnLCAnZGF0YUxhYmVsc0dyb3VwJ10sXG5cdGF4aXNUeXBlczogW10sXG5cdHBvaW50QXR0clRvT3B0aW9uczogeyAvLyBtYXBwaW5nIGJldHdlZW4gU1ZHIGF0dHJpYnV0ZXMgYW5kIHRoZSBjb3JyZXNwb25kaW5nIG9wdGlvbnNcblx0XHRzdHJva2U6ICdib3JkZXJDb2xvcicsXG5cdFx0J3N0cm9rZS13aWR0aCc6ICdib3JkZXJXaWR0aCcsXG5cdFx0ZmlsbDogJ2NvbG9yJ1xuXHR9LFxuXHRzaW5ndWxhclRvb2x0aXBzOiB0cnVlLFxuXG5cdC8qKlxuXHQgKiBQaWVzIGhhdmUgb25lIGNvbG9yIGVhY2ggcG9pbnRcblx0ICovXG5cdGdldENvbG9yOiBub29wLFxuXG5cdC8qKlxuXHQgKiBBbmltYXRlIHRoZSBwaWVzIGluXG5cdCAqL1xuXHRhbmltYXRlOiBmdW5jdGlvbiAoaW5pdCkge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdHN0YXJ0QW5nbGVSYWQgPSBzZXJpZXMuc3RhcnRBbmdsZVJhZDtcblxuXHRcdGlmICghaW5pdCkge1xuXHRcdFx0ZWFjaChwb2ludHMsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0XHR2YXIgZ3JhcGhpYyA9IHBvaW50LmdyYXBoaWMsXG5cdFx0XHRcdFx0YXJncyA9IHBvaW50LnNoYXBlQXJncztcblxuXHRcdFx0XHRpZiAoZ3JhcGhpYykge1xuXHRcdFx0XHRcdC8vIHN0YXJ0IHZhbHVlc1xuXHRcdFx0XHRcdGdyYXBoaWMuYXR0cih7XG5cdFx0XHRcdFx0XHRyOiBzZXJpZXMuY2VudGVyWzNdIC8gMiwgLy8gYW5pbWF0ZSBmcm9tIGlubmVyIHJhZGl1cyAoIzc3OSlcblx0XHRcdFx0XHRcdHN0YXJ0OiBzdGFydEFuZ2xlUmFkLFxuXHRcdFx0XHRcdFx0ZW5kOiBzdGFydEFuZ2xlUmFkXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHQvLyBhbmltYXRlXG5cdFx0XHRcdFx0Z3JhcGhpYy5hbmltYXRlKHtcblx0XHRcdFx0XHRcdHI6IGFyZ3Mucixcblx0XHRcdFx0XHRcdHN0YXJ0OiBhcmdzLnN0YXJ0LFxuXHRcdFx0XHRcdFx0ZW5kOiBhcmdzLmVuZFxuXHRcdFx0XHRcdH0sIHNlcmllcy5vcHRpb25zLmFuaW1hdGlvbik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBkZWxldGUgdGhpcyBmdW5jdGlvbiB0byBhbGxvdyBpdCBvbmx5IG9uY2Vcblx0XHRcdHNlcmllcy5hbmltYXRlID0gbnVsbDtcblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIEV4dGVuZCB0aGUgYmFzaWMgc2V0RGF0YSBtZXRob2QgYnkgcnVubmluZyBwcm9jZXNzRGF0YSBhbmQgZ2VuZXJhdGVQb2ludHMgaW1tZWRpYXRlbHksXG5cdCAqIGluIG9yZGVyIHRvIGFjY2VzcyB0aGUgcG9pbnRzIGZyb20gdGhlIGxlZ2VuZC5cblx0ICovXG5cdHNldERhdGE6IGZ1bmN0aW9uIChkYXRhLCByZWRyYXcsIGFuaW1hdGlvbiwgdXBkYXRlUG9pbnRzKSB7XG5cdFx0U2VyaWVzLnByb3RvdHlwZS5zZXREYXRhLmNhbGwodGhpcywgZGF0YSwgZmFsc2UsIGFuaW1hdGlvbiwgdXBkYXRlUG9pbnRzKTtcblx0XHR0aGlzLnByb2Nlc3NEYXRhKCk7XG5cdFx0dGhpcy5nZW5lcmF0ZVBvaW50cygpO1xuXHRcdGlmIChwaWNrKHJlZHJhdywgdHJ1ZSkpIHtcblx0XHRcdHRoaXMuY2hhcnQucmVkcmF3KGFuaW1hdGlvbik7XG5cdFx0fSBcblx0fSxcblxuXHQvKipcblx0ICogRXh0ZW5kIHRoZSBnZW5lcmF0ZVBvaW50cyBtZXRob2QgYnkgYWRkaW5nIHRvdGFsIGFuZCBwZXJjZW50YWdlIHByb3BlcnRpZXMgdG8gZWFjaCBwb2ludFxuXHQgKi9cblx0Z2VuZXJhdGVQb2ludHM6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgaSxcblx0XHRcdHRvdGFsID0gMCxcblx0XHRcdHBvaW50cyxcblx0XHRcdGxlbixcblx0XHRcdHBvaW50LFxuXHRcdFx0aWdub3JlSGlkZGVuUG9pbnQgPSB0aGlzLm9wdGlvbnMuaWdub3JlSGlkZGVuUG9pbnQ7XG5cblx0XHRTZXJpZXMucHJvdG90eXBlLmdlbmVyYXRlUG9pbnRzLmNhbGwodGhpcyk7XG5cblx0XHQvLyBQb3B1bGF0ZSBsb2NhbCB2YXJzXG5cdFx0cG9pbnRzID0gdGhpcy5wb2ludHM7XG5cdFx0bGVuID0gcG9pbnRzLmxlbmd0aDtcblx0XHRcblx0XHQvLyBHZXQgdGhlIHRvdGFsIHN1bVxuXHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHR0b3RhbCArPSAoaWdub3JlSGlkZGVuUG9pbnQgJiYgIXBvaW50LnZpc2libGUpID8gMCA6IHBvaW50Lnk7XG5cdFx0fVxuXHRcdHRoaXMudG90YWwgPSB0b3RhbDtcblxuXHRcdC8vIFNldCBlYWNoIHBvaW50J3MgcHJvcGVydGllc1xuXHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuXHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHRwb2ludC5wZXJjZW50YWdlID0gdG90YWwgPiAwID8gKHBvaW50LnkgLyB0b3RhbCkgKiAxMDAgOiAwO1xuXHRcdFx0cG9pbnQudG90YWwgPSB0b3RhbDtcblx0XHR9XG5cdFx0XG5cdH0sXG5cdFxuXHQvKipcblx0ICogRG8gdHJhbnNsYXRpb24gZm9yIHBpZSBzbGljZXNcblx0ICovXG5cdHRyYW5zbGF0ZTogZnVuY3Rpb24gKHBvc2l0aW9ucykge1xuXHRcdHRoaXMuZ2VuZXJhdGVQb2ludHMoKTtcblx0XHRcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGN1bXVsYXRpdmUgPSAwLFxuXHRcdFx0cHJlY2lzaW9uID0gMTAwMCwgLy8gaXNzdWUgIzE3MlxuXHRcdFx0b3B0aW9ucyA9IHNlcmllcy5vcHRpb25zLFxuXHRcdFx0c2xpY2VkT2Zmc2V0ID0gb3B0aW9ucy5zbGljZWRPZmZzZXQsXG5cdFx0XHRjb25uZWN0b3JPZmZzZXQgPSBzbGljZWRPZmZzZXQgKyBvcHRpb25zLmJvcmRlcldpZHRoLFxuXHRcdFx0c3RhcnQsXG5cdFx0XHRlbmQsXG5cdFx0XHRhbmdsZSxcblx0XHRcdHN0YXJ0QW5nbGUgPSBvcHRpb25zLnN0YXJ0QW5nbGUgfHwgMCxcblx0XHRcdHN0YXJ0QW5nbGVSYWQgPSBzZXJpZXMuc3RhcnRBbmdsZVJhZCA9IG1hdGhQSSAvIDE4MCAqIChzdGFydEFuZ2xlIC0gOTApLFxuXHRcdFx0ZW5kQW5nbGVSYWQgPSBzZXJpZXMuZW5kQW5nbGVSYWQgPSBtYXRoUEkgLyAxODAgKiAoKHBpY2sob3B0aW9ucy5lbmRBbmdsZSwgc3RhcnRBbmdsZSArIDM2MCkpIC0gOTApLFxuXHRcdFx0Y2lyYyA9IGVuZEFuZ2xlUmFkIC0gc3RhcnRBbmdsZVJhZCwgLy8yICogbWF0aFBJLFxuXHRcdFx0cG9pbnRzID0gc2VyaWVzLnBvaW50cyxcblx0XHRcdHJhZGl1c1gsIC8vIHRoZSB4IGNvbXBvbmVudCBvZiB0aGUgcmFkaXVzIHZlY3RvciBmb3IgYSBnaXZlbiBwb2ludFxuXHRcdFx0cmFkaXVzWSxcblx0XHRcdGxhYmVsRGlzdGFuY2UgPSBvcHRpb25zLmRhdGFMYWJlbHMuZGlzdGFuY2UsXG5cdFx0XHRpZ25vcmVIaWRkZW5Qb2ludCA9IG9wdGlvbnMuaWdub3JlSGlkZGVuUG9pbnQsXG5cdFx0XHRpLFxuXHRcdFx0bGVuID0gcG9pbnRzLmxlbmd0aCxcblx0XHRcdHBvaW50O1xuXG5cdFx0Ly8gR2V0IHBvc2l0aW9ucyAtIGVpdGhlciBhbiBpbnRlZ2VyIG9yIGEgcGVyY2VudGFnZSBzdHJpbmcgbXVzdCBiZSBnaXZlbi5cblx0XHQvLyBJZiBwb3NpdGlvbnMgYXJlIHBhc3NlZCBhcyBhIHBhcmFtZXRlciwgd2UncmUgaW4gYSByZWN1cnNpdmUgbG9vcCBmb3IgYWRqdXN0aW5nXG5cdFx0Ly8gc3BhY2UgZm9yIGRhdGEgbGFiZWxzLlxuXHRcdGlmICghcG9zaXRpb25zKSB7XG5cdFx0XHRzZXJpZXMuY2VudGVyID0gcG9zaXRpb25zID0gc2VyaWVzLmdldENlbnRlcigpO1xuXHRcdH1cblxuXHRcdC8vIHV0aWxpdHkgZm9yIGdldHRpbmcgdGhlIHggdmFsdWUgZnJvbSBhIGdpdmVuIHksIHVzZWQgZm9yIGFudGljb2xsaXNpb24gbG9naWMgaW4gZGF0YSBsYWJlbHNcblx0XHRzZXJpZXMuZ2V0WCA9IGZ1bmN0aW9uICh5LCBsZWZ0KSB7XG5cblx0XHRcdGFuZ2xlID0gbWF0aC5hc2luKG1hdGhNaW4oKHkgLSBwb3NpdGlvbnNbMV0pIC8gKHBvc2l0aW9uc1syXSAvIDIgKyBsYWJlbERpc3RhbmNlKSwgMSkpO1xuXG5cdFx0XHRyZXR1cm4gcG9zaXRpb25zWzBdICtcblx0XHRcdFx0KGxlZnQgPyAtMSA6IDEpICpcblx0XHRcdFx0KG1hdGhDb3MoYW5nbGUpICogKHBvc2l0aW9uc1syXSAvIDIgKyBsYWJlbERpc3RhbmNlKSk7XG5cdFx0fTtcblxuXHRcdC8vIENhbGN1bGF0ZSB0aGUgZ2VvbWV0cnkgZm9yIGVhY2ggcG9pbnRcblx0XHRmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdFxuXHRcdFx0cG9pbnQgPSBwb2ludHNbaV07XG5cdFx0XHRcblx0XHRcdC8vIHNldCBzdGFydCBhbmQgZW5kIGFuZ2xlXG5cdFx0XHRzdGFydCA9IHN0YXJ0QW5nbGVSYWQgKyAoY3VtdWxhdGl2ZSAqIGNpcmMpO1xuXHRcdFx0aWYgKCFpZ25vcmVIaWRkZW5Qb2ludCB8fCBwb2ludC52aXNpYmxlKSB7XG5cdFx0XHRcdGN1bXVsYXRpdmUgKz0gcG9pbnQucGVyY2VudGFnZSAvIDEwMDtcblx0XHRcdH1cblx0XHRcdGVuZCA9IHN0YXJ0QW5nbGVSYWQgKyAoY3VtdWxhdGl2ZSAqIGNpcmMpO1xuXG5cdFx0XHQvLyBzZXQgdGhlIHNoYXBlXG5cdFx0XHRwb2ludC5zaGFwZVR5cGUgPSAnYXJjJztcblx0XHRcdHBvaW50LnNoYXBlQXJncyA9IHtcblx0XHRcdFx0eDogcG9zaXRpb25zWzBdLFxuXHRcdFx0XHR5OiBwb3NpdGlvbnNbMV0sXG5cdFx0XHRcdHI6IHBvc2l0aW9uc1syXSAvIDIsXG5cdFx0XHRcdGlubmVyUjogcG9zaXRpb25zWzNdIC8gMixcblx0XHRcdFx0c3RhcnQ6IG1hdGhSb3VuZChzdGFydCAqIHByZWNpc2lvbikgLyBwcmVjaXNpb24sXG5cdFx0XHRcdGVuZDogbWF0aFJvdW5kKGVuZCAqIHByZWNpc2lvbikgLyBwcmVjaXNpb25cblx0XHRcdH07XG5cblx0XHRcdC8vIFRoZSBhbmdsZSBtdXN0IHN0YXkgd2l0aGluIC05MCBhbmQgMjcwICgjMjY0NSlcblx0XHRcdGFuZ2xlID0gKGVuZCArIHN0YXJ0KSAvIDI7XG5cdFx0XHRpZiAoYW5nbGUgPiAxLjUgKiBtYXRoUEkpIHtcblx0XHRcdFx0YW5nbGUgLT0gMiAqIG1hdGhQSTtcblx0XHRcdH0gZWxzZSBpZiAoYW5nbGUgPCAtbWF0aFBJIC8gMikge1xuXHRcdFx0XHRhbmdsZSArPSAyICogbWF0aFBJO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDZW50ZXIgZm9yIHRoZSBzbGljZWQgb3V0IHNsaWNlXG5cdFx0XHRwb2ludC5zbGljZWRUcmFuc2xhdGlvbiA9IHtcblx0XHRcdFx0dHJhbnNsYXRlWDogbWF0aFJvdW5kKG1hdGhDb3MoYW5nbGUpICogc2xpY2VkT2Zmc2V0KSxcblx0XHRcdFx0dHJhbnNsYXRlWTogbWF0aFJvdW5kKG1hdGhTaW4oYW5nbGUpICogc2xpY2VkT2Zmc2V0KVxuXHRcdFx0fTtcblxuXHRcdFx0Ly8gc2V0IHRoZSBhbmNob3IgcG9pbnQgZm9yIHRvb2x0aXBzXG5cdFx0XHRyYWRpdXNYID0gbWF0aENvcyhhbmdsZSkgKiBwb3NpdGlvbnNbMl0gLyAyO1xuXHRcdFx0cmFkaXVzWSA9IG1hdGhTaW4oYW5nbGUpICogcG9zaXRpb25zWzJdIC8gMjtcblx0XHRcdHBvaW50LnRvb2x0aXBQb3MgPSBbXG5cdFx0XHRcdHBvc2l0aW9uc1swXSArIHJhZGl1c1ggKiAwLjcsXG5cdFx0XHRcdHBvc2l0aW9uc1sxXSArIHJhZGl1c1kgKiAwLjdcblx0XHRcdF07XG5cdFx0XHRcblx0XHRcdHBvaW50LmhhbGYgPSBhbmdsZSA8IC1tYXRoUEkgLyAyIHx8IGFuZ2xlID4gbWF0aFBJIC8gMiA/IDEgOiAwO1xuXHRcdFx0cG9pbnQuYW5nbGUgPSBhbmdsZTtcblxuXHRcdFx0Ly8gc2V0IHRoZSBhbmNob3IgcG9pbnQgZm9yIGRhdGEgbGFiZWxzXG5cdFx0XHRjb25uZWN0b3JPZmZzZXQgPSBtYXRoTWluKGNvbm5lY3Rvck9mZnNldCwgbGFiZWxEaXN0YW5jZSAvIDIpOyAvLyAjMTY3OFxuXHRcdFx0cG9pbnQubGFiZWxQb3MgPSBbXG5cdFx0XHRcdHBvc2l0aW9uc1swXSArIHJhZGl1c1ggKyBtYXRoQ29zKGFuZ2xlKSAqIGxhYmVsRGlzdGFuY2UsIC8vIGZpcnN0IGJyZWFrIG9mIGNvbm5lY3RvclxuXHRcdFx0XHRwb3NpdGlvbnNbMV0gKyByYWRpdXNZICsgbWF0aFNpbihhbmdsZSkgKiBsYWJlbERpc3RhbmNlLCAvLyBhL2Fcblx0XHRcdFx0cG9zaXRpb25zWzBdICsgcmFkaXVzWCArIG1hdGhDb3MoYW5nbGUpICogY29ubmVjdG9yT2Zmc2V0LCAvLyBzZWNvbmQgYnJlYWssIHJpZ2h0IG91dHNpZGUgcGllXG5cdFx0XHRcdHBvc2l0aW9uc1sxXSArIHJhZGl1c1kgKyBtYXRoU2luKGFuZ2xlKSAqIGNvbm5lY3Rvck9mZnNldCwgLy8gYS9hXG5cdFx0XHRcdHBvc2l0aW9uc1swXSArIHJhZGl1c1gsIC8vIGxhbmRpbmcgcG9pbnQgZm9yIGNvbm5lY3RvclxuXHRcdFx0XHRwb3NpdGlvbnNbMV0gKyByYWRpdXNZLCAvLyBhL2Fcblx0XHRcdFx0bGFiZWxEaXN0YW5jZSA8IDAgPyAvLyBhbGlnbm1lbnRcblx0XHRcdFx0XHQnY2VudGVyJyA6XG5cdFx0XHRcdFx0cG9pbnQuaGFsZiA/ICdyaWdodCcgOiAnbGVmdCcsIC8vIGFsaWdubWVudFxuXHRcdFx0XHRhbmdsZSAvLyBjZW50ZXIgYW5nbGVcblx0XHRcdF07XG5cblx0XHR9XG5cdH0sXG5cdFxuXHRkcmF3R3JhcGg6IG51bGwsXG5cblx0LyoqXG5cdCAqIERyYXcgdGhlIGRhdGEgcG9pbnRzXG5cdCAqL1xuXHRkcmF3UG9pbnRzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHJlbmRlcmVyID0gY2hhcnQucmVuZGVyZXIsXG5cdFx0XHRncm91cFRyYW5zbGF0aW9uLFxuXHRcdFx0Ly9jZW50ZXIsXG5cdFx0XHRncmFwaGljLFxuXHRcdFx0Ly9ncm91cCxcblx0XHRcdHNoYWRvdyA9IHNlcmllcy5vcHRpb25zLnNoYWRvdyxcblx0XHRcdHNoYWRvd0dyb3VwLFxuXHRcdFx0c2hhcGVBcmdzO1xuXG5cdFx0aWYgKHNoYWRvdyAmJiAhc2VyaWVzLnNoYWRvd0dyb3VwKSB7XG5cdFx0XHRzZXJpZXMuc2hhZG93R3JvdXAgPSByZW5kZXJlci5nKCdzaGFkb3cnKVxuXHRcdFx0XHQuYWRkKHNlcmllcy5ncm91cCk7XG5cdFx0fVxuXG5cdFx0Ly8gZHJhdyB0aGUgc2xpY2VzXG5cdFx0ZWFjaChzZXJpZXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdGdyYXBoaWMgPSBwb2ludC5ncmFwaGljO1xuXHRcdFx0c2hhcGVBcmdzID0gcG9pbnQuc2hhcGVBcmdzO1xuXHRcdFx0c2hhZG93R3JvdXAgPSBwb2ludC5zaGFkb3dHcm91cDtcblxuXHRcdFx0Ly8gcHV0IHRoZSBzaGFkb3cgYmVoaW5kIGFsbCBwb2ludHNcblx0XHRcdGlmIChzaGFkb3cgJiYgIXNoYWRvd0dyb3VwKSB7XG5cdFx0XHRcdHNoYWRvd0dyb3VwID0gcG9pbnQuc2hhZG93R3JvdXAgPSByZW5kZXJlci5nKCdzaGFkb3cnKVxuXHRcdFx0XHRcdC5hZGQoc2VyaWVzLnNoYWRvd0dyb3VwKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gaWYgdGhlIHBvaW50IGlzIHNsaWNlZCwgdXNlIHNwZWNpYWwgdHJhbnNsYXRpb24sIGVsc2UgdXNlIHBsb3QgYXJlYSB0cmFzbGF0aW9uXG5cdFx0XHRncm91cFRyYW5zbGF0aW9uID0gcG9pbnQuc2xpY2VkID8gcG9pbnQuc2xpY2VkVHJhbnNsYXRpb24gOiB7XG5cdFx0XHRcdHRyYW5zbGF0ZVg6IDAsXG5cdFx0XHRcdHRyYW5zbGF0ZVk6IDBcblx0XHRcdH07XG5cblx0XHRcdC8vZ3JvdXAudHJhbnNsYXRlKGdyb3VwVHJhbnNsYXRpb25bMF0sIGdyb3VwVHJhbnNsYXRpb25bMV0pO1xuXHRcdFx0aWYgKHNoYWRvd0dyb3VwKSB7XG5cdFx0XHRcdHNoYWRvd0dyb3VwLmF0dHIoZ3JvdXBUcmFuc2xhdGlvbik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGRyYXcgdGhlIHNsaWNlXG5cdFx0XHRpZiAoZ3JhcGhpYykge1xuXHRcdFx0XHRncmFwaGljLmFuaW1hdGUoZXh0ZW5kKHNoYXBlQXJncywgZ3JvdXBUcmFuc2xhdGlvbikpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cG9pbnQuZ3JhcGhpYyA9IGdyYXBoaWMgPSByZW5kZXJlcltwb2ludC5zaGFwZVR5cGVdKHNoYXBlQXJncylcblx0XHRcdFx0XHQuc2V0UmFkaWFsUmVmZXJlbmNlKHNlcmllcy5jZW50ZXIpXG5cdFx0XHRcdFx0LmF0dHIoXG5cdFx0XHRcdFx0XHRwb2ludC5wb2ludEF0dHJbcG9pbnQuc2VsZWN0ZWQgPyBTRUxFQ1RfU1RBVEUgOiBOT1JNQUxfU1RBVEVdXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdC5hdHRyKHsgXG5cdFx0XHRcdFx0XHQnc3Ryb2tlLWxpbmVqb2luJzogJ3JvdW5kJ1xuXHRcdFx0XHRcdFx0Ly96SW5kZXg6IDEgLy8gIzI3MjIgKHJldmVyc2VkKVxuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmF0dHIoZ3JvdXBUcmFuc2xhdGlvbilcblx0XHRcdFx0XHQuYWRkKHNlcmllcy5ncm91cClcblx0XHRcdFx0XHQuc2hhZG93KHNoYWRvdywgc2hhZG93R3JvdXApO1x0XG5cdFx0XHR9XG5cblx0XHRcdC8vIGRldGVjdCBwb2ludCBzcGVjaWZpYyB2aXNpYmlsaXR5ICgjMjQzMClcblx0XHRcdGlmIChwb2ludC52aXNpYmxlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cG9pbnQuc2V0VmlzaWJsZShwb2ludC52aXNpYmxlKTtcblx0XHRcdH1cblxuXHRcdH0pO1xuXG5cdH0sXG5cblx0LyoqXG5cdCAqIFV0aWxpdHkgZm9yIHNvcnRpbmcgZGF0YSBsYWJlbHNcblx0ICovXG5cdHNvcnRCeUFuZ2xlOiBmdW5jdGlvbiAocG9pbnRzLCBzaWduKSB7XG5cdFx0cG9pbnRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcblx0XHRcdHJldHVybiBhLmFuZ2xlICE9PSB1bmRlZmluZWQgJiYgKGIuYW5nbGUgLSBhLmFuZ2xlKSAqIHNpZ247XG5cdFx0fSk7XG5cdH0sXHRcdFxuXG5cdC8qKlxuXHQgKiBVc2UgYSBzaW1wbGUgc3ltYm9sIGZyb20gTGVnZW5kU3ltYm9sTWl4aW5cblx0ICovXG5cdGRyYXdMZWdlbmRTeW1ib2w6IExlZ2VuZFN5bWJvbE1peGluLmRyYXdSZWN0YW5nbGUsXG5cblx0LyoqXG5cdCAqIFVzZSB0aGUgZ2V0Q2VudGVyIG1ldGhvZCBmcm9tIGRyYXdMZWdlbmRTeW1ib2xcblx0ICovXG5cdGdldENlbnRlcjogQ2VudGVyZWRTZXJpZXNNaXhpbi5nZXRDZW50ZXIsXG5cblx0LyoqXG5cdCAqIFBpZXMgZG9uJ3QgaGF2ZSBwb2ludCBtYXJrZXIgc3ltYm9sc1xuXHQgKi9cblx0Z2V0U3ltYm9sOiBub29wXG5cbn07XG5QaWVTZXJpZXMgPSBleHRlbmRDbGFzcyhTZXJpZXMsIFBpZVNlcmllcyk7XG5zZXJpZXNUeXBlcy5waWUgPSBQaWVTZXJpZXM7XG5cbi8qKlxuICogRHJhdyB0aGUgZGF0YSBsYWJlbHNcbiAqL1xuU2VyaWVzLnByb3RvdHlwZS5kcmF3RGF0YUxhYmVscyA9IGZ1bmN0aW9uICgpIHtcblxuXHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRzZXJpZXNPcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0Y3Vyc29yID0gc2VyaWVzT3B0aW9ucy5jdXJzb3IsXG5cdFx0b3B0aW9ucyA9IHNlcmllc09wdGlvbnMuZGF0YUxhYmVscyxcblx0XHRwb2ludHMgPSBzZXJpZXMucG9pbnRzLFxuXHRcdHBvaW50T3B0aW9ucyxcblx0XHRnZW5lcmFsT3B0aW9ucyxcblx0XHRoYXNSZW5kZXJlZCA9IHNlcmllcy5oYXNSZW5kZXJlZCB8fCAwLFxuXHRcdHN0cixcblx0XHRkYXRhTGFiZWxzR3JvdXA7XG5cblx0aWYgKG9wdGlvbnMuZW5hYmxlZCB8fCBzZXJpZXMuX2hhc1BvaW50TGFiZWxzKSB7XG5cblx0XHQvLyBQcm9jZXNzIGRlZmF1bHQgYWxpZ25tZW50IG9mIGRhdGEgbGFiZWxzIGZvciBjb2x1bW5zXG5cdFx0aWYgKHNlcmllcy5kbFByb2Nlc3NPcHRpb25zKSB7XG5cdFx0XHRzZXJpZXMuZGxQcm9jZXNzT3B0aW9ucyhvcHRpb25zKTtcblx0XHR9XG5cblx0XHQvLyBDcmVhdGUgYSBzZXBhcmF0ZSBncm91cCBmb3IgdGhlIGRhdGEgbGFiZWxzIHRvIGF2b2lkIHJvdGF0aW9uXG5cdFx0ZGF0YUxhYmVsc0dyb3VwID0gc2VyaWVzLnBsb3RHcm91cChcblx0XHRcdCdkYXRhTGFiZWxzR3JvdXAnLFxuXHRcdFx0J2RhdGEtbGFiZWxzJyxcblx0XHRcdG9wdGlvbnMuZGVmZXIgPyBISURERU4gOiBWSVNJQkxFLFxuXHRcdFx0b3B0aW9ucy56SW5kZXggfHwgNlxuXHRcdCk7XG5cblx0XHRpZiAocGljayhvcHRpb25zLmRlZmVyLCB0cnVlKSkge1xuXHRcdFx0ZGF0YUxhYmVsc0dyb3VwLmF0dHIoeyBvcGFjaXR5OiAraGFzUmVuZGVyZWQgfSk7IC8vICMzMzAwXG5cdFx0XHRpZiAoIWhhc1JlbmRlcmVkKSB7XG5cdFx0XHRcdGFkZEV2ZW50KHNlcmllcywgJ2FmdGVyQW5pbWF0ZScsIGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRpZiAoc2VyaWVzLnZpc2libGUpIHsgLy8gIzMwMjMsICMzMDI0XG5cdFx0XHRcdFx0XHRkYXRhTGFiZWxzR3JvdXAuc2hvdygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhTGFiZWxzR3JvdXBbc2VyaWVzT3B0aW9ucy5hbmltYXRpb24gPyAnYW5pbWF0ZScgOiAnYXR0ciddKHsgb3BhY2l0eTogMSB9LCB7IGR1cmF0aW9uOiAyMDAgfSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE1ha2UgdGhlIGxhYmVscyBmb3IgZWFjaCBwb2ludFxuXHRcdGdlbmVyYWxPcHRpb25zID0gb3B0aW9ucztcblx0XHRlYWNoKHBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cblx0XHRcdHZhciBlbmFibGVkLFxuXHRcdFx0XHRkYXRhTGFiZWwgPSBwb2ludC5kYXRhTGFiZWwsXG5cdFx0XHRcdGxhYmVsQ29uZmlnLFxuXHRcdFx0XHRhdHRyLFxuXHRcdFx0XHRuYW1lLFxuXHRcdFx0XHRyb3RhdGlvbixcblx0XHRcdFx0Y29ubmVjdG9yID0gcG9pbnQuY29ubmVjdG9yLFxuXHRcdFx0XHRpc05ldyA9IHRydWU7XG5cblx0XHRcdC8vIERldGVybWluZSBpZiBlYWNoIGRhdGEgbGFiZWwgaXMgZW5hYmxlZFxuXHRcdFx0cG9pbnRPcHRpb25zID0gcG9pbnQub3B0aW9ucyAmJiBwb2ludC5vcHRpb25zLmRhdGFMYWJlbHM7XG5cdFx0XHRlbmFibGVkID0gcGljayhwb2ludE9wdGlvbnMgJiYgcG9pbnRPcHRpb25zLmVuYWJsZWQsIGdlbmVyYWxPcHRpb25zLmVuYWJsZWQpOyAvLyAjMjI4MlxuXG5cblx0XHRcdC8vIElmIHRoZSBwb2ludCBpcyBvdXRzaWRlIHRoZSBwbG90IGFyZWEsIGRlc3Ryb3kgaXQuICM2NzgsICM4MjBcblx0XHRcdGlmIChkYXRhTGFiZWwgJiYgIWVuYWJsZWQpIHtcblx0XHRcdFx0cG9pbnQuZGF0YUxhYmVsID0gZGF0YUxhYmVsLmRlc3Ryb3koKTtcblxuXHRcdFx0Ly8gSW5kaXZpZHVhbCBsYWJlbHMgYXJlIGRpc2FibGVkIGlmIHRoZSBhcmUgZXhwbGljaXRseSBkaXNhYmxlZFxuXHRcdFx0Ly8gaW4gdGhlIHBvaW50IG9wdGlvbnMsIG9yIGlmIHRoZXkgZmFsbCBvdXRzaWRlIHRoZSBwbG90IGFyZWEuXG5cdFx0XHR9IGVsc2UgaWYgKGVuYWJsZWQpIHtcblxuXHRcdFx0XHQvLyBDcmVhdGUgaW5kaXZpZHVhbCBvcHRpb25zIHN0cnVjdHVyZSB0aGF0IGNhbiBiZSBleHRlbmRlZCB3aXRob3V0XG5cdFx0XHRcdC8vIGFmZmVjdGluZyBvdGhlcnNcblx0XHRcdFx0b3B0aW9ucyA9IG1lcmdlKGdlbmVyYWxPcHRpb25zLCBwb2ludE9wdGlvbnMpO1xuXG5cdFx0XHRcdHJvdGF0aW9uID0gb3B0aW9ucy5yb3RhdGlvbjtcblxuXHRcdFx0XHQvLyBHZXQgdGhlIHN0cmluZ1xuXHRcdFx0XHRsYWJlbENvbmZpZyA9IHBvaW50LmdldExhYmVsQ29uZmlnKCk7XG5cdFx0XHRcdHN0ciA9IG9wdGlvbnMuZm9ybWF0ID9cblx0XHRcdFx0XHRmb3JtYXQob3B0aW9ucy5mb3JtYXQsIGxhYmVsQ29uZmlnKSA6XG5cdFx0XHRcdFx0b3B0aW9ucy5mb3JtYXR0ZXIuY2FsbChsYWJlbENvbmZpZywgb3B0aW9ucyk7XG5cblx0XHRcdFx0Ly8gRGV0ZXJtaW5lIHRoZSBjb2xvclxuXHRcdFx0XHRvcHRpb25zLnN0eWxlLmNvbG9yID0gcGljayhvcHRpb25zLmNvbG9yLCBvcHRpb25zLnN0eWxlLmNvbG9yLCBzZXJpZXMuY29sb3IsICdibGFjaycpO1xuXG5cblx0XHRcdFx0Ly8gdXBkYXRlIGV4aXN0aW5nIGxhYmVsXG5cdFx0XHRcdGlmIChkYXRhTGFiZWwpIHtcblxuXHRcdFx0XHRcdGlmIChkZWZpbmVkKHN0cikpIHtcblx0XHRcdFx0XHRcdGRhdGFMYWJlbFxuXHRcdFx0XHRcdFx0XHQuYXR0cih7XG5cdFx0XHRcdFx0XHRcdFx0dGV4dDogc3RyXG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0aXNOZXcgPSBmYWxzZTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7IC8vICMxNDM3IC0gdGhlIGxhYmVsIGlzIHNob3duIGNvbmRpdGlvbmFsbHlcblx0XHRcdFx0XHRcdHBvaW50LmRhdGFMYWJlbCA9IGRhdGFMYWJlbCA9IGRhdGFMYWJlbC5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHRpZiAoY29ubmVjdG9yKSB7XG5cdFx0XHRcdFx0XHRcdHBvaW50LmNvbm5lY3RvciA9IGNvbm5lY3Rvci5kZXN0cm95KCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIGNyZWF0ZSBuZXcgbGFiZWxcblx0XHRcdFx0fSBlbHNlIGlmIChkZWZpbmVkKHN0cikpIHtcblx0XHRcdFx0XHRhdHRyID0ge1xuXHRcdFx0XHRcdFx0Ly9hbGlnbjogYWxpZ24sXG5cdFx0XHRcdFx0XHRmaWxsOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcblx0XHRcdFx0XHRcdHN0cm9rZTogb3B0aW9ucy5ib3JkZXJDb2xvcixcblx0XHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBvcHRpb25zLmJvcmRlcldpZHRoLFxuXHRcdFx0XHRcdFx0cjogb3B0aW9ucy5ib3JkZXJSYWRpdXMgfHwgMCxcblx0XHRcdFx0XHRcdHJvdGF0aW9uOiByb3RhdGlvbixcblx0XHRcdFx0XHRcdHBhZGRpbmc6IG9wdGlvbnMucGFkZGluZyxcblx0XHRcdFx0XHRcdHpJbmRleDogMVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0Ly8gUmVtb3ZlIHVudXNlZCBhdHRyaWJ1dGVzICgjOTQ3KVxuXHRcdFx0XHRcdGZvciAobmFtZSBpbiBhdHRyKSB7XG5cdFx0XHRcdFx0XHRpZiAoYXR0cltuYW1lXSA9PT0gVU5ERUZJTkVEKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBhdHRyW25hbWVdO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGRhdGFMYWJlbCA9IHBvaW50LmRhdGFMYWJlbCA9IHNlcmllcy5jaGFydC5yZW5kZXJlcltyb3RhdGlvbiA/ICd0ZXh0JyA6ICdsYWJlbCddKCAvLyBsYWJlbHMgZG9uJ3Qgc3VwcG9ydCByb3RhdGlvblxuXHRcdFx0XHRcdFx0c3RyLFxuXHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdC05OTksXG5cdFx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHRcdG51bGwsXG5cdFx0XHRcdFx0XHRvcHRpb25zLnVzZUhUTUxcblx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0LmF0dHIoYXR0cilcblx0XHRcdFx0XHQuY3NzKGV4dGVuZChvcHRpb25zLnN0eWxlLCBjdXJzb3IgJiYgeyBjdXJzb3I6IGN1cnNvciB9KSlcblx0XHRcdFx0XHQuYWRkKGRhdGFMYWJlbHNHcm91cClcblx0XHRcdFx0XHQuc2hhZG93KG9wdGlvbnMuc2hhZG93KTtcblxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGRhdGFMYWJlbCkge1xuXHRcdFx0XHRcdC8vIE5vdyB0aGUgZGF0YSBsYWJlbCBpcyBjcmVhdGVkIGFuZCBwbGFjZWQgYXQgMCwwLCBzbyB3ZSBuZWVkIHRvIGFsaWduIGl0XG5cdFx0XHRcdFx0c2VyaWVzLmFsaWduRGF0YUxhYmVsKHBvaW50LCBkYXRhTGFiZWwsIG9wdGlvbnMsIG51bGwsIGlzTmV3KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59O1xuXG4vKipcbiAqIEFsaWduIGVhY2ggaW5kaXZpZHVhbCBkYXRhIGxhYmVsXG4gKi9cblNlcmllcy5wcm90b3R5cGUuYWxpZ25EYXRhTGFiZWwgPSBmdW5jdGlvbiAocG9pbnQsIGRhdGFMYWJlbCwgb3B0aW9ucywgYWxpZ25UbywgaXNOZXcpIHtcblx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydCxcblx0XHRpbnZlcnRlZCA9IGNoYXJ0LmludmVydGVkLFxuXHRcdHBsb3RYID0gcGljayhwb2ludC5wbG90WCwgLTk5OSksXG5cdFx0cGxvdFkgPSBwaWNrKHBvaW50LnBsb3RZLCAtOTk5KSxcblx0XHRiQm94ID0gZGF0YUxhYmVsLmdldEJCb3goKSxcblx0XHQvLyBNYXRoLnJvdW5kIGZvciByb3VuZGluZyBlcnJvcnMgKCMyNjgzKSwgYWxpZ25UbyB0byBhbGxvdyBjb2x1bW4gbGFiZWxzICgjMjcwMClcblx0XHR2aXNpYmxlID0gdGhpcy52aXNpYmxlICYmIChwb2ludC5zZXJpZXMuZm9yY2VETCB8fCBjaGFydC5pc0luc2lkZVBsb3QocGxvdFgsIG1hdGhSb3VuZChwbG90WSksIGludmVydGVkKSB8fFxuXHRcdFx0KGFsaWduVG8gJiYgY2hhcnQuaXNJbnNpZGVQbG90KHBsb3RYLCBpbnZlcnRlZCA/IGFsaWduVG8ueCArIDEgOiBhbGlnblRvLnkgKyBhbGlnblRvLmhlaWdodCAtIDEsIGludmVydGVkKSkpLFxuXHRcdGFsaWduQXR0cjsgLy8gdGhlIGZpbmFsIHBvc2l0aW9uO1xuXG5cdGlmICh2aXNpYmxlKSB7XG5cblx0XHQvLyBUaGUgYWxpZ25tZW50IGJveCBpcyBhIHNpbmd1bGFyIHBvaW50XG5cdFx0YWxpZ25UbyA9IGV4dGVuZCh7XG5cdFx0XHR4OiBpbnZlcnRlZCA/IGNoYXJ0LnBsb3RXaWR0aCAtIHBsb3RZIDogcGxvdFgsXG5cdFx0XHR5OiBtYXRoUm91bmQoaW52ZXJ0ZWQgPyBjaGFydC5wbG90SGVpZ2h0IC0gcGxvdFggOiBwbG90WSksXG5cdFx0XHR3aWR0aDogMCxcblx0XHRcdGhlaWdodDogMFxuXHRcdH0sIGFsaWduVG8pO1xuXG5cdFx0Ly8gQWRkIHRoZSB0ZXh0IHNpemUgZm9yIGFsaWdubWVudCBjYWxjdWxhdGlvblxuXHRcdGV4dGVuZChvcHRpb25zLCB7XG5cdFx0XHR3aWR0aDogYkJveC53aWR0aCxcblx0XHRcdGhlaWdodDogYkJveC5oZWlnaHRcblx0XHR9KTtcblxuXHRcdC8vIEFsbG93IGEgaG9vayBmb3IgY2hhbmdpbmcgYWxpZ25tZW50IGluIHRoZSBsYXN0IG1vbWVudCwgdGhlbiBkbyB0aGUgYWxpZ25tZW50XG5cdFx0aWYgKG9wdGlvbnMucm90YXRpb24pIHsgLy8gRmFuY3kgYm94IGFsaWdubWVudCBpc24ndCBzdXBwb3J0ZWQgZm9yIHJvdGF0ZWQgdGV4dFxuXHRcdFx0ZGF0YUxhYmVsW2lzTmV3ID8gJ2F0dHInIDogJ2FuaW1hdGUnXSh7XG5cdFx0XHRcdFx0eDogYWxpZ25Uby54ICsgb3B0aW9ucy54ICsgYWxpZ25Uby53aWR0aCAvIDIsXG5cdFx0XHRcdFx0eTogYWxpZ25Uby55ICsgb3B0aW9ucy55ICsgYWxpZ25Uby5oZWlnaHQgLyAyXG5cdFx0XHRcdH0pXG5cdFx0XHRcdC5hdHRyKHsgLy8gIzMwMDNcblx0XHRcdFx0XHRhbGlnbjogb3B0aW9ucy5hbGlnblxuXHRcdFx0XHR9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YUxhYmVsLmFsaWduKG9wdGlvbnMsIG51bGwsIGFsaWduVG8pO1xuXHRcdFx0YWxpZ25BdHRyID0gZGF0YUxhYmVsLmFsaWduQXR0cjtcblxuXHRcdFx0Ly8gSGFuZGxlIGp1c3RpZnkgb3IgY3JvcFxuXHRcdFx0aWYgKHBpY2sob3B0aW9ucy5vdmVyZmxvdywgJ2p1c3RpZnknKSA9PT0gJ2p1c3RpZnknKSB7XG5cdFx0XHRcdHRoaXMuanVzdGlmeURhdGFMYWJlbChkYXRhTGFiZWwsIG9wdGlvbnMsIGFsaWduQXR0ciwgYkJveCwgYWxpZ25UbywgaXNOZXcpO1xuXG5cdFx0XHR9IGVsc2UgaWYgKHBpY2sob3B0aW9ucy5jcm9wLCB0cnVlKSkge1xuXHRcdFx0XHQvLyBOb3cgY2hlY2sgdGhhdCB0aGUgZGF0YSBsYWJlbCBpcyB3aXRoaW4gdGhlIHBsb3QgYXJlYVxuXHRcdFx0XHR2aXNpYmxlID0gY2hhcnQuaXNJbnNpZGVQbG90KGFsaWduQXR0ci54LCBhbGlnbkF0dHIueSkgJiYgY2hhcnQuaXNJbnNpZGVQbG90KGFsaWduQXR0ci54ICsgYkJveC53aWR0aCwgYWxpZ25BdHRyLnkgKyBiQm94LmhlaWdodCk7XG5cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTaG93IG9yIGhpZGUgYmFzZWQgb24gdGhlIGZpbmFsIGFsaWduZWQgcG9zaXRpb25cblx0aWYgKCF2aXNpYmxlKSB7XG5cdFx0ZGF0YUxhYmVsLmF0dHIoeyB5OiAtOTk5IH0pO1xuXHRcdGRhdGFMYWJlbC5wbGFjZWQgPSBmYWxzZTsgLy8gZG9uJ3QgYW5pbWF0ZSBiYWNrIGluXG5cdH1cblxufTtcblxuLyoqXG4gKiBJZiBkYXRhIGxhYmVscyBmYWxsIHBhcnRseSBvdXRzaWRlIHRoZSBwbG90IGFyZWEsIGFsaWduIHRoZW0gYmFjayBpbiwgaW4gYSB3YXkgdGhhdFxuICogZG9lc24ndCBoaWRlIHRoZSBwb2ludC5cbiAqL1xuU2VyaWVzLnByb3RvdHlwZS5qdXN0aWZ5RGF0YUxhYmVsID0gZnVuY3Rpb24gKGRhdGFMYWJlbCwgb3B0aW9ucywgYWxpZ25BdHRyLCBiQm94LCBhbGlnblRvLCBpc05ldykge1xuXHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdGFsaWduID0gb3B0aW9ucy5hbGlnbixcblx0XHR2ZXJ0aWNhbEFsaWduID0gb3B0aW9ucy52ZXJ0aWNhbEFsaWduLFxuXHRcdG9mZixcblx0XHRqdXN0aWZpZWQ7XG5cblx0Ly8gT2ZmIGxlZnRcblx0b2ZmID0gYWxpZ25BdHRyLng7XG5cdGlmIChvZmYgPCAwKSB7XG5cdFx0aWYgKGFsaWduID09PSAncmlnaHQnKSB7XG5cdFx0XHRvcHRpb25zLmFsaWduID0gJ2xlZnQnO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvcHRpb25zLnggPSAtb2ZmO1xuXHRcdH1cblx0XHRqdXN0aWZpZWQgPSB0cnVlO1xuXHR9XG5cblx0Ly8gT2ZmIHJpZ2h0XG5cdG9mZiA9IGFsaWduQXR0ci54ICsgYkJveC53aWR0aDtcblx0aWYgKG9mZiA+IGNoYXJ0LnBsb3RXaWR0aCkge1xuXHRcdGlmIChhbGlnbiA9PT0gJ2xlZnQnKSB7XG5cdFx0XHRvcHRpb25zLmFsaWduID0gJ3JpZ2h0Jztcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3B0aW9ucy54ID0gY2hhcnQucGxvdFdpZHRoIC0gb2ZmO1xuXHRcdH1cblx0XHRqdXN0aWZpZWQgPSB0cnVlO1xuXHR9XG5cblx0Ly8gT2ZmIHRvcFxuXHRvZmYgPSBhbGlnbkF0dHIueTtcblx0aWYgKG9mZiA8IDApIHtcblx0XHRpZiAodmVydGljYWxBbGlnbiA9PT0gJ2JvdHRvbScpIHtcblx0XHRcdG9wdGlvbnMudmVydGljYWxBbGlnbiA9ICd0b3AnO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvcHRpb25zLnkgPSAtb2ZmO1xuXHRcdH1cblx0XHRqdXN0aWZpZWQgPSB0cnVlO1xuXHR9XG5cblx0Ly8gT2ZmIGJvdHRvbVxuXHRvZmYgPSBhbGlnbkF0dHIueSArIGJCb3guaGVpZ2h0O1xuXHRpZiAob2ZmID4gY2hhcnQucGxvdEhlaWdodCkge1xuXHRcdGlmICh2ZXJ0aWNhbEFsaWduID09PSAndG9wJykge1xuXHRcdFx0b3B0aW9ucy52ZXJ0aWNhbEFsaWduID0gJ2JvdHRvbSc7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG9wdGlvbnMueSA9IGNoYXJ0LnBsb3RIZWlnaHQgLSBvZmY7XG5cdFx0fVxuXHRcdGp1c3RpZmllZCA9IHRydWU7XG5cdH1cblxuXHRpZiAoanVzdGlmaWVkKSB7XG5cdFx0ZGF0YUxhYmVsLnBsYWNlZCA9ICFpc05ldztcblx0XHRkYXRhTGFiZWwuYWxpZ24ob3B0aW9ucywgbnVsbCwgYWxpZ25Ubyk7XG5cdH1cbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgdGhlIGJhc2UgZHJhd0RhdGFMYWJlbHMgbWV0aG9kIGJ5IHBpZSBzcGVjaWZpYyBmdW5jdGlvbmFsaXR5XG4gKi9cbmlmIChzZXJpZXNUeXBlcy5waWUpIHtcblx0c2VyaWVzVHlwZXMucGllLnByb3RvdHlwZS5kcmF3RGF0YUxhYmVscyA9IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGRhdGEgPSBzZXJpZXMuZGF0YSxcblx0XHRcdHBvaW50LFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMuZGF0YUxhYmVscyxcblx0XHRcdGNvbm5lY3RvclBhZGRpbmcgPSBwaWNrKG9wdGlvbnMuY29ubmVjdG9yUGFkZGluZywgMTApLFxuXHRcdFx0Y29ubmVjdG9yV2lkdGggPSBwaWNrKG9wdGlvbnMuY29ubmVjdG9yV2lkdGgsIDEpLFxuXHRcdFx0cGxvdFdpZHRoID0gY2hhcnQucGxvdFdpZHRoLFxuXHRcdFx0cGxvdEhlaWdodCA9IGNoYXJ0LnBsb3RIZWlnaHQsXG5cdFx0XHRjb25uZWN0b3IsXG5cdFx0XHRjb25uZWN0b3JQYXRoLFxuXHRcdFx0c29mdENvbm5lY3RvciA9IHBpY2sob3B0aW9ucy5zb2Z0Q29ubmVjdG9yLCB0cnVlKSxcblx0XHRcdGRpc3RhbmNlT3B0aW9uID0gb3B0aW9ucy5kaXN0YW5jZSxcblx0XHRcdHNlcmllc0NlbnRlciA9IHNlcmllcy5jZW50ZXIsXG5cdFx0XHRyYWRpdXMgPSBzZXJpZXNDZW50ZXJbMl0gLyAyLFxuXHRcdFx0Y2VudGVyWSA9IHNlcmllc0NlbnRlclsxXSxcblx0XHRcdG91dHNpZGUgPSBkaXN0YW5jZU9wdGlvbiA+IDAsXG5cdFx0XHRkYXRhTGFiZWwsXG5cdFx0XHRkYXRhTGFiZWxXaWR0aCxcblx0XHRcdGxhYmVsUG9zLFxuXHRcdFx0bGFiZWxIZWlnaHQsXG5cdFx0XHRoYWx2ZXMgPSBbLy8gZGl2aWRlIHRoZSBwb2ludHMgaW50byByaWdodCBhbmQgbGVmdCBoYWx2ZXMgZm9yIGFudGkgY29sbGlzaW9uXG5cdFx0XHRcdFtdLCAvLyByaWdodFxuXHRcdFx0XHRbXSAgLy8gbGVmdFxuXHRcdFx0XSxcblx0XHRcdHgsXG5cdFx0XHR5LFxuXHRcdFx0dmlzaWJpbGl0eSxcblx0XHRcdHJhbmtBcnIsXG5cdFx0XHRpLFxuXHRcdFx0aixcblx0XHRcdG92ZXJmbG93ID0gWzAsIDAsIDAsIDBdLCAvLyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcblx0XHRcdHNvcnQgPSBmdW5jdGlvbiAoYSwgYikge1xuXHRcdFx0XHRyZXR1cm4gYi55IC0gYS55O1xuXHRcdFx0fTtcblxuXHRcdC8vIGdldCBvdXQgaWYgbm90IGVuYWJsZWRcblx0XHRpZiAoIXNlcmllcy52aXNpYmxlIHx8ICghb3B0aW9ucy5lbmFibGVkICYmICFzZXJpZXMuX2hhc1BvaW50TGFiZWxzKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIHJ1biBwYXJlbnQgbWV0aG9kXG5cdFx0U2VyaWVzLnByb3RvdHlwZS5kcmF3RGF0YUxhYmVscy5hcHBseShzZXJpZXMpO1xuXG5cdFx0Ly8gYXJyYW5nZSBwb2ludHMgZm9yIGRldGVjdGlvbiBjb2xsaXNpb25cblx0XHRlYWNoKGRhdGEsIGZ1bmN0aW9uIChwb2ludCkge1xuXHRcdFx0aWYgKHBvaW50LmRhdGFMYWJlbCAmJiBwb2ludC52aXNpYmxlKSB7IC8vICM0MDcsICMyNTEwXG5cdFx0XHRcdGhhbHZlc1twb2ludC5oYWxmXS5wdXNoKHBvaW50KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8qIExvb3Agb3ZlciB0aGUgcG9pbnRzIGluIGVhY2ggaGFsZiwgc3RhcnRpbmcgZnJvbSB0aGUgdG9wIGFuZCBib3R0b21cblx0XHQgKiBvZiB0aGUgcGllIHRvIGRldGVjdCBvdmVybGFwcGluZyBsYWJlbHMuXG5cdFx0ICovXG5cdFx0aSA9IDI7XG5cdFx0d2hpbGUgKGktLSkge1xuXG5cdFx0XHR2YXIgc2xvdHMgPSBbXSxcblx0XHRcdFx0c2xvdHNMZW5ndGgsXG5cdFx0XHRcdHVzZWRTbG90cyA9IFtdLFxuXHRcdFx0XHRwb2ludHMgPSBoYWx2ZXNbaV0sXG5cdFx0XHRcdHBvcyxcblx0XHRcdFx0Ym90dG9tLFxuXHRcdFx0XHRsZW5ndGggPSBwb2ludHMubGVuZ3RoLFxuXHRcdFx0XHRzbG90SW5kZXg7XG5cblx0XHRcdGlmICghbGVuZ3RoKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTb3J0IGJ5IGFuZ2xlXG5cdFx0XHRzZXJpZXMuc29ydEJ5QW5nbGUocG9pbnRzLCBpIC0gMC41KTtcblxuXHRcdFx0Ly8gQXNzdW1lIGVxdWFsIGxhYmVsIGhlaWdodHMgb24gZWl0aGVyIGhlbWlzcGhlcmUgKCMyNjMwKVxuXHRcdFx0aiA9IGxhYmVsSGVpZ2h0ID0gMDtcblx0XHRcdHdoaWxlICghbGFiZWxIZWlnaHQgJiYgcG9pbnRzW2pdKSB7IC8vICMxNTY5XG5cdFx0XHRcdGxhYmVsSGVpZ2h0ID0gcG9pbnRzW2pdICYmIHBvaW50c1tqXS5kYXRhTGFiZWwgJiYgKHBvaW50c1tqXS5kYXRhTGFiZWwuZ2V0QkJveCgpLmhlaWdodCB8fCAyMSk7IC8vIDIxIGlzIGZvciAjOTY4XG5cdFx0XHRcdGorKztcblx0XHRcdH1cblxuXHRcdFx0Ly8gT25seSBkbyBhbnRpLWNvbGxpc2lvbiB3aGVuIHdlIGFyZSBvdXRzaWRlIHRoZSBwaWUgYW5kIGhhdmUgY29ubmVjdG9ycyAoIzg1Nilcblx0XHRcdGlmIChkaXN0YW5jZU9wdGlvbiA+IDApIHtcblxuXHRcdFx0XHQvLyBCdWlsZCB0aGUgc2xvdHNcblx0XHRcdFx0Ym90dG9tID0gbWF0aE1pbihjZW50ZXJZICsgcmFkaXVzICsgZGlzdGFuY2VPcHRpb24sIGNoYXJ0LnBsb3RIZWlnaHQpO1xuXHRcdFx0XHRmb3IgKHBvcyA9IG1hdGhNYXgoMCwgY2VudGVyWSAtIHJhZGl1cyAtIGRpc3RhbmNlT3B0aW9uKTsgcG9zIDw9IGJvdHRvbTsgcG9zICs9IGxhYmVsSGVpZ2h0KSB7XG5cdFx0XHRcdFx0c2xvdHMucHVzaChwb3MpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHNsb3RzTGVuZ3RoID0gc2xvdHMubGVuZ3RoO1xuXG5cblx0XHRcdFx0LyogVmlzdWFsaXplIHRoZSBzbG90c1xuXHRcdFx0XHRpZiAoIXNlcmllcy5zbG90RWxlbWVudHMpIHtcblx0XHRcdFx0XHRzZXJpZXMuc2xvdEVsZW1lbnRzID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKGkgPT09IDEpIHtcblx0XHRcdFx0XHRzZXJpZXMuc2xvdEVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW0pIHtcblx0XHRcdFx0XHRcdGVsZW0uZGVzdHJveSgpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdHNlcmllcy5zbG90RWxlbWVudHMubGVuZ3RoID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0XHRcdFxuXHRcdFx0XHRzbG90cy5mb3JFYWNoKGZ1bmN0aW9uIChwb3MsIG5vKSB7XG5cdFx0XHRcdFx0dmFyIHNsb3RYID0gc2VyaWVzLmdldFgocG9zLCBpKSArIGNoYXJ0LnBsb3RMZWZ0IC0gKGkgPyAxMDAgOiAwKSxcblx0XHRcdFx0XHRcdHNsb3RZID0gcG9zICsgY2hhcnQucGxvdFRvcDtcblx0XHRcdFx0XHRcblx0XHRcdFx0XHRpZiAoIWlzTmFOKHNsb3RYKSkge1xuXHRcdFx0XHRcdFx0c2VyaWVzLnNsb3RFbGVtZW50cy5wdXNoKGNoYXJ0LnJlbmRlcmVyLnJlY3Qoc2xvdFgsIHNsb3RZIC0gNywgMTAwLCBsYWJlbEhlaWdodCwgMSlcblx0XHRcdFx0XHRcdFx0LmF0dHIoe1xuXHRcdFx0XHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiAxLFxuXHRcdFx0XHRcdFx0XHRcdHN0cm9rZTogJ3NpbHZlcicsXG5cdFx0XHRcdFx0XHRcdFx0ZmlsbDogJ3JnYmEoMCwwLDI1NSwwLjEpJ1xuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0XHQuYWRkKCkpO1xuXHRcdFx0XHRcdFx0c2VyaWVzLnNsb3RFbGVtZW50cy5wdXNoKGNoYXJ0LnJlbmRlcmVyLnRleHQoJ1Nsb3QgJysgbm8sIHNsb3RYLCBzbG90WSArIDQpXG5cdFx0XHRcdFx0XHRcdC5hdHRyKHtcblx0XHRcdFx0XHRcdFx0XHRmaWxsOiAnc2lsdmVyJ1xuXHRcdFx0XHRcdFx0XHR9KS5hZGQoKSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0Ly8gKi9cblxuXHRcdFx0XHQvLyBpZiB0aGVyZSBhcmUgbW9yZSB2YWx1ZXMgdGhhbiBhdmFpbGFibGUgc2xvdHMsIHJlbW92ZSBsb3dlc3QgdmFsdWVzXG5cdFx0XHRcdGlmIChsZW5ndGggPiBzbG90c0xlbmd0aCkge1xuXHRcdFx0XHRcdC8vIGNyZWF0ZSBhbiBhcnJheSBmb3Igc29ydGluZyBhbmQgcmFua2luZyB0aGUgcG9pbnRzIHdpdGhpbiBlYWNoIHF1YXJ0ZXJcblx0XHRcdFx0XHRyYW5rQXJyID0gW10uY29uY2F0KHBvaW50cyk7XG5cdFx0XHRcdFx0cmFua0Fyci5zb3J0KHNvcnQpO1xuXHRcdFx0XHRcdGogPSBsZW5ndGg7XG5cdFx0XHRcdFx0d2hpbGUgKGotLSkge1xuXHRcdFx0XHRcdFx0cmFua0FycltqXS5yYW5rID0gajtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aiA9IGxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoai0tKSB7XG5cdFx0XHRcdFx0XHRpZiAocG9pbnRzW2pdLnJhbmsgPj0gc2xvdHNMZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0cG9pbnRzLnNwbGljZShqLCAxKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bGVuZ3RoID0gcG9pbnRzLmxlbmd0aDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRoZSBsYWJlbCBnb2VzIHRvIHRoZSBuZWFyZXN0IG9wZW4gc2xvdCwgYnV0IG5vdCBjbG9zZXIgdG8gdGhlIGVkZ2UgdGhhblxuXHRcdFx0XHQvLyB0aGUgbGFiZWwncyBpbmRleC5cblx0XHRcdFx0Zm9yIChqID0gMDsgaiA8IGxlbmd0aDsgaisrKSB7XG5cblx0XHRcdFx0XHRwb2ludCA9IHBvaW50c1tqXTtcblx0XHRcdFx0XHRsYWJlbFBvcyA9IHBvaW50LmxhYmVsUG9zO1xuXG5cdFx0XHRcdFx0dmFyIGNsb3Nlc3QgPSA5OTk5LFxuXHRcdFx0XHRcdFx0ZGlzdGFuY2UsXG5cdFx0XHRcdFx0XHRzbG90STtcblxuXHRcdFx0XHRcdC8vIGZpbmQgdGhlIGNsb3Nlc3Qgc2xvdCBpbmRleFxuXHRcdFx0XHRcdGZvciAoc2xvdEkgPSAwOyBzbG90SSA8IHNsb3RzTGVuZ3RoOyBzbG90SSsrKSB7XG5cdFx0XHRcdFx0XHRkaXN0YW5jZSA9IG1hdGhBYnMoc2xvdHNbc2xvdEldIC0gbGFiZWxQb3NbMV0pO1xuXHRcdFx0XHRcdFx0aWYgKGRpc3RhbmNlIDwgY2xvc2VzdCkge1xuXHRcdFx0XHRcdFx0XHRjbG9zZXN0ID0gZGlzdGFuY2U7XG5cdFx0XHRcdFx0XHRcdHNsb3RJbmRleCA9IHNsb3RJO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIGlmIHRoYXQgc2xvdCBpbmRleCBpcyBjbG9zZXIgdG8gdGhlIGVkZ2VzIG9mIHRoZSBzbG90cywgbW92ZSBpdFxuXHRcdFx0XHRcdC8vIHRvIHRoZSBjbG9zZXN0IGFwcHJvcHJpYXRlIHNsb3Rcblx0XHRcdFx0XHRpZiAoc2xvdEluZGV4IDwgaiAmJiBzbG90c1tqXSAhPT0gbnVsbCkgeyAvLyBjbHVzdGVyIGF0IHRoZSB0b3Bcblx0XHRcdFx0XHRcdHNsb3RJbmRleCA9IGo7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChzbG90c0xlbmd0aCAgPCBsZW5ndGggLSBqICsgc2xvdEluZGV4ICYmIHNsb3RzW2pdICE9PSBudWxsKSB7IC8vIGNsdXN0ZXIgYXQgdGhlIGJvdHRvbVxuXHRcdFx0XHRcdFx0c2xvdEluZGV4ID0gc2xvdHNMZW5ndGggLSBsZW5ndGggKyBqO1xuXHRcdFx0XHRcdFx0d2hpbGUgKHNsb3RzW3Nsb3RJbmRleF0gPT09IG51bGwpIHsgLy8gbWFrZSBzdXJlIGl0IGlzIG5vdCB0YWtlblxuXHRcdFx0XHRcdFx0XHRzbG90SW5kZXgrKztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gU2xvdCBpcyB0YWtlbiwgZmluZCBuZXh0IGZyZWUgc2xvdCBiZWxvdy4gSW4gdGhlIG5leHQgcnVuLCB0aGUgbmV4dCBzbGljZSB3aWxsIGZpbmQgdGhlXG5cdFx0XHRcdFx0XHQvLyBzbG90IGFib3ZlIHRoZXNlLCBiZWNhdXNlIGl0IGlzIHRoZSBjbG9zZXN0IG9uZVxuXHRcdFx0XHRcdFx0d2hpbGUgKHNsb3RzW3Nsb3RJbmRleF0gPT09IG51bGwpIHsgLy8gbWFrZSBzdXJlIGl0IGlzIG5vdCB0YWtlblxuXHRcdFx0XHRcdFx0XHRzbG90SW5kZXgrKztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR1c2VkU2xvdHMucHVzaCh7IGk6IHNsb3RJbmRleCwgeTogc2xvdHNbc2xvdEluZGV4XSB9KTtcblx0XHRcdFx0XHRzbG90c1tzbG90SW5kZXhdID0gbnVsbDsgLy8gbWFyayBhcyB0YWtlblxuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIHNvcnQgdGhlbSBpbiBvcmRlciB0byBmaWxsIGluIGZyb20gdGhlIHRvcFxuXHRcdFx0XHR1c2VkU2xvdHMuc29ydChzb3J0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gbm93IHRoZSB1c2VkIHNsb3RzIGFyZSBzb3J0ZWQsIGZpbGwgdGhlbSB1cCBzZXF1ZW50aWFsbHlcblx0XHRcdGZvciAoaiA9IDA7IGogPCBsZW5ndGg7IGorKykge1xuXG5cdFx0XHRcdHZhciBzbG90LCBuYXR1cmFsWTtcblxuXHRcdFx0XHRwb2ludCA9IHBvaW50c1tqXTtcblx0XHRcdFx0bGFiZWxQb3MgPSBwb2ludC5sYWJlbFBvcztcblx0XHRcdFx0ZGF0YUxhYmVsID0gcG9pbnQuZGF0YUxhYmVsO1xuXHRcdFx0XHR2aXNpYmlsaXR5ID0gcG9pbnQudmlzaWJsZSA9PT0gZmFsc2UgPyBISURERU4gOiBWSVNJQkxFO1xuXHRcdFx0XHRuYXR1cmFsWSA9IGxhYmVsUG9zWzFdO1xuXG5cdFx0XHRcdGlmIChkaXN0YW5jZU9wdGlvbiA+IDApIHtcblx0XHRcdFx0XHRzbG90ID0gdXNlZFNsb3RzLnBvcCgpO1xuXHRcdFx0XHRcdHNsb3RJbmRleCA9IHNsb3QuaTtcblxuXHRcdFx0XHRcdC8vIGlmIHRoZSBzbG90IG5leHQgdG8gY3VycnJlbnQgc2xvdCBpcyBmcmVlLCB0aGUgeSB2YWx1ZSBpcyBhbGxvd2VkXG5cdFx0XHRcdFx0Ly8gdG8gZmFsbCBiYWNrIHRvIHRoZSBuYXR1cmFsIHBvc2l0aW9uXG5cdFx0XHRcdFx0eSA9IHNsb3QueTtcblx0XHRcdFx0XHRpZiAoKG5hdHVyYWxZID4geSAmJiBzbG90c1tzbG90SW5kZXggKyAxXSAhPT0gbnVsbCkgfHxcblx0XHRcdFx0XHRcdFx0KG5hdHVyYWxZIDwgeSAmJiAgc2xvdHNbc2xvdEluZGV4IC0gMV0gIT09IG51bGwpKSB7XG5cdFx0XHRcdFx0XHR5ID0gbWF0aE1pbihtYXRoTWF4KDAsIG5hdHVyYWxZKSwgY2hhcnQucGxvdEhlaWdodCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0eSA9IG5hdHVyYWxZO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gZ2V0IHRoZSB4IC0gdXNlIHRoZSBuYXR1cmFsIHggcG9zaXRpb24gZm9yIGZpcnN0IGFuZCBsYXN0IHNsb3QsIHRvIHByZXZlbnQgdGhlIHRvcFxuXHRcdFx0XHQvLyBhbmQgYm90dG9uIHNsaWNlIGNvbm5lY3RvcnMgZnJvbSB0b3VjaGluZyBlYWNoIG90aGVyIG9uIGVpdGhlciBzaWRlXG5cdFx0XHRcdHggPSBvcHRpb25zLmp1c3RpZnkgP1xuXHRcdFx0XHRcdHNlcmllc0NlbnRlclswXSArIChpID8gLTEgOiAxKSAqIChyYWRpdXMgKyBkaXN0YW5jZU9wdGlvbikgOlxuXHRcdFx0XHRcdHNlcmllcy5nZXRYKHkgPT09IGNlbnRlclkgLSByYWRpdXMgLSBkaXN0YW5jZU9wdGlvbiB8fCB5ID09PSBjZW50ZXJZICsgcmFkaXVzICsgZGlzdGFuY2VPcHRpb24gPyBuYXR1cmFsWSA6IHksIGkpO1xuXG5cblx0XHRcdFx0Ly8gUmVjb3JkIHRoZSBwbGFjZW1lbnQgYW5kIHZpc2liaWxpdHlcblx0XHRcdFx0ZGF0YUxhYmVsLl9hdHRyID0ge1xuXHRcdFx0XHRcdHZpc2liaWxpdHk6IHZpc2liaWxpdHksXG5cdFx0XHRcdFx0YWxpZ246IGxhYmVsUG9zWzZdXG5cdFx0XHRcdH07XG5cdFx0XHRcdGRhdGFMYWJlbC5fcG9zID0ge1xuXHRcdFx0XHRcdHg6IHggKyBvcHRpb25zLnggK1xuXHRcdFx0XHRcdFx0KHsgbGVmdDogY29ubmVjdG9yUGFkZGluZywgcmlnaHQ6IC1jb25uZWN0b3JQYWRkaW5nIH1bbGFiZWxQb3NbNl1dIHx8IDApLFxuXHRcdFx0XHRcdHk6IHkgKyBvcHRpb25zLnkgLSAxMCAvLyAxMCBpcyBmb3IgdGhlIGJhc2VsaW5lIChsYWJlbCB2cyB0ZXh0KVxuXHRcdFx0XHR9O1xuXHRcdFx0XHRkYXRhTGFiZWwuY29ublggPSB4O1xuXHRcdFx0XHRkYXRhTGFiZWwuY29ublkgPSB5O1xuXG5cblx0XHRcdFx0Ly8gRGV0ZWN0IG92ZXJmbG93aW5nIGRhdGEgbGFiZWxzXG5cdFx0XHRcdGlmICh0aGlzLm9wdGlvbnMuc2l6ZSA9PT0gbnVsbCkge1xuXHRcdFx0XHRcdGRhdGFMYWJlbFdpZHRoID0gZGF0YUxhYmVsLndpZHRoO1xuXHRcdFx0XHRcdC8vIE92ZXJmbG93IGxlZnRcblx0XHRcdFx0XHRpZiAoeCAtIGRhdGFMYWJlbFdpZHRoIDwgY29ubmVjdG9yUGFkZGluZykge1xuXHRcdFx0XHRcdFx0b3ZlcmZsb3dbM10gPSBtYXRoTWF4KG1hdGhSb3VuZChkYXRhTGFiZWxXaWR0aCAtIHggKyBjb25uZWN0b3JQYWRkaW5nKSwgb3ZlcmZsb3dbM10pO1xuXG5cdFx0XHRcdFx0Ly8gT3ZlcmZsb3cgcmlnaHRcblx0XHRcdFx0XHR9IGVsc2UgaWYgKHggKyBkYXRhTGFiZWxXaWR0aCA+IHBsb3RXaWR0aCAtIGNvbm5lY3RvclBhZGRpbmcpIHtcblx0XHRcdFx0XHRcdG92ZXJmbG93WzFdID0gbWF0aE1heChtYXRoUm91bmQoeCArIGRhdGFMYWJlbFdpZHRoIC0gcGxvdFdpZHRoICsgY29ubmVjdG9yUGFkZGluZyksIG92ZXJmbG93WzFdKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBPdmVyZmxvdyB0b3Bcblx0XHRcdFx0XHRpZiAoeSAtIGxhYmVsSGVpZ2h0IC8gMiA8IDApIHtcblx0XHRcdFx0XHRcdG92ZXJmbG93WzBdID0gbWF0aE1heChtYXRoUm91bmQoLXkgKyBsYWJlbEhlaWdodCAvIDIpLCBvdmVyZmxvd1swXSk7XG5cblx0XHRcdFx0XHQvLyBPdmVyZmxvdyBsZWZ0XG5cdFx0XHRcdFx0fSBlbHNlIGlmICh5ICsgbGFiZWxIZWlnaHQgLyAyID4gcGxvdEhlaWdodCkge1xuXHRcdFx0XHRcdFx0b3ZlcmZsb3dbMl0gPSBtYXRoTWF4KG1hdGhSb3VuZCh5ICsgbGFiZWxIZWlnaHQgLyAyIC0gcGxvdEhlaWdodCksIG92ZXJmbG93WzJdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gLy8gZm9yIGVhY2ggcG9pbnRcblx0XHR9IC8vIGZvciBlYWNoIGhhbGZcblxuXHRcdC8vIERvIG5vdCBhcHBseSB0aGUgZmluYWwgcGxhY2VtZW50IGFuZCBkcmF3IHRoZSBjb25uZWN0b3JzIHVudGlsIHdlIGhhdmUgdmVyaWZpZWRcblx0XHQvLyB0aGF0IGxhYmVscyBhcmUgbm90IHNwaWxsaW5nIG92ZXIuXG5cdFx0aWYgKGFycmF5TWF4KG92ZXJmbG93KSA9PT0gMCB8fCB0aGlzLnZlcmlmeURhdGFMYWJlbE92ZXJmbG93KG92ZXJmbG93KSkge1xuXG5cdFx0XHQvLyBQbGFjZSB0aGUgbGFiZWxzIGluIHRoZSBmaW5hbCBwb3NpdGlvblxuXHRcdFx0dGhpcy5wbGFjZURhdGFMYWJlbHMoKTtcblxuXHRcdFx0Ly8gRHJhdyB0aGUgY29ubmVjdG9yc1xuXHRcdFx0aWYgKG91dHNpZGUgJiYgY29ubmVjdG9yV2lkdGgpIHtcblx0XHRcdFx0ZWFjaCh0aGlzLnBvaW50cywgZnVuY3Rpb24gKHBvaW50KSB7XG5cdFx0XHRcdFx0Y29ubmVjdG9yID0gcG9pbnQuY29ubmVjdG9yO1xuXHRcdFx0XHRcdGxhYmVsUG9zID0gcG9pbnQubGFiZWxQb3M7XG5cdFx0XHRcdFx0ZGF0YUxhYmVsID0gcG9pbnQuZGF0YUxhYmVsO1xuXG5cdFx0XHRcdFx0aWYgKGRhdGFMYWJlbCAmJiBkYXRhTGFiZWwuX3Bvcykge1xuXHRcdFx0XHRcdFx0dmlzaWJpbGl0eSA9IGRhdGFMYWJlbC5fYXR0ci52aXNpYmlsaXR5O1xuXHRcdFx0XHRcdFx0eCA9IGRhdGFMYWJlbC5jb25uWDtcblx0XHRcdFx0XHRcdHkgPSBkYXRhTGFiZWwuY29ublk7XG5cdFx0XHRcdFx0XHRjb25uZWN0b3JQYXRoID0gc29mdENvbm5lY3RvciA/IFtcblx0XHRcdFx0XHRcdFx0TSxcblx0XHRcdFx0XHRcdFx0eCArIChsYWJlbFBvc1s2XSA9PT0gJ2xlZnQnID8gNSA6IC01KSwgeSwgLy8gZW5kIG9mIHRoZSBzdHJpbmcgYXQgdGhlIGxhYmVsXG5cdFx0XHRcdFx0XHRcdCdDJyxcblx0XHRcdFx0XHRcdFx0eCwgeSwgLy8gZmlyc3QgYnJlYWssIG5leHQgdG8gdGhlIGxhYmVsXG5cdFx0XHRcdFx0XHRcdDIgKiBsYWJlbFBvc1syXSAtIGxhYmVsUG9zWzRdLCAyICogbGFiZWxQb3NbM10gLSBsYWJlbFBvc1s1XSxcblx0XHRcdFx0XHRcdFx0bGFiZWxQb3NbMl0sIGxhYmVsUG9zWzNdLCAvLyBzZWNvbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0TCxcblx0XHRcdFx0XHRcdFx0bGFiZWxQb3NbNF0sIGxhYmVsUG9zWzVdIC8vIGJhc2Vcblx0XHRcdFx0XHRcdF0gOiBbXG5cdFx0XHRcdFx0XHRcdE0sXG5cdFx0XHRcdFx0XHRcdHggKyAobGFiZWxQb3NbNl0gPT09ICdsZWZ0JyA/IDUgOiAtNSksIHksIC8vIGVuZCBvZiB0aGUgc3RyaW5nIGF0IHRoZSBsYWJlbFxuXHRcdFx0XHRcdFx0XHRMLFxuXHRcdFx0XHRcdFx0XHRsYWJlbFBvc1syXSwgbGFiZWxQb3NbM10sIC8vIHNlY29uZCBicmVha1xuXHRcdFx0XHRcdFx0XHRMLFxuXHRcdFx0XHRcdFx0XHRsYWJlbFBvc1s0XSwgbGFiZWxQb3NbNV0gLy8gYmFzZVxuXHRcdFx0XHRcdFx0XTtcblxuXHRcdFx0XHRcdFx0aWYgKGNvbm5lY3Rvcikge1xuXHRcdFx0XHRcdFx0XHRjb25uZWN0b3IuYW5pbWF0ZSh7IGQ6IGNvbm5lY3RvclBhdGggfSk7XG5cdFx0XHRcdFx0XHRcdGNvbm5lY3Rvci5hdHRyKCd2aXNpYmlsaXR5JywgdmlzaWJpbGl0eSk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHBvaW50LmNvbm5lY3RvciA9IGNvbm5lY3RvciA9IHNlcmllcy5jaGFydC5yZW5kZXJlci5wYXRoKGNvbm5lY3RvclBhdGgpLmF0dHIoe1xuXHRcdFx0XHRcdFx0XHRcdCdzdHJva2Utd2lkdGgnOiBjb25uZWN0b3JXaWR0aCxcblx0XHRcdFx0XHRcdFx0XHRzdHJva2U6IG9wdGlvbnMuY29ubmVjdG9yQ29sb3IgfHwgcG9pbnQuY29sb3IgfHwgJyM2MDYwNjAnLFxuXHRcdFx0XHRcdFx0XHRcdHZpc2liaWxpdHk6IHZpc2liaWxpdHlcblx0XHRcdFx0XHRcdFx0XHQvL3pJbmRleDogMCAvLyAjMjcyMiAocmV2ZXJzZWQpXG5cdFx0XHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0XHRcdC5hZGQoc2VyaWVzLmRhdGFMYWJlbHNHcm91cCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChjb25uZWN0b3IpIHtcblx0XHRcdFx0XHRcdHBvaW50LmNvbm5lY3RvciA9IGNvbm5lY3Rvci5kZXN0cm95KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdC8qKlxuXHQgKiBQZXJmb3JtIHRoZSBmaW5hbCBwbGFjZW1lbnQgb2YgdGhlIGRhdGEgbGFiZWxzIGFmdGVyIHdlIGhhdmUgdmVyaWZpZWQgdGhhdCB0aGV5XG5cdCAqIGZhbGwgd2l0aGluIHRoZSBwbG90IGFyZWEuXG5cdCAqL1xuXHRzZXJpZXNUeXBlcy5waWUucHJvdG90eXBlLnBsYWNlRGF0YUxhYmVscyA9IGZ1bmN0aW9uICgpIHtcblx0XHRlYWNoKHRoaXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdHZhciBkYXRhTGFiZWwgPSBwb2ludC5kYXRhTGFiZWwsXG5cdFx0XHRcdF9wb3M7XG5cblx0XHRcdGlmIChkYXRhTGFiZWwpIHtcblx0XHRcdFx0X3BvcyA9IGRhdGFMYWJlbC5fcG9zO1xuXHRcdFx0XHRpZiAoX3Bvcykge1xuXHRcdFx0XHRcdGRhdGFMYWJlbC5hdHRyKGRhdGFMYWJlbC5fYXR0cik7XG5cdFx0XHRcdFx0ZGF0YUxhYmVsW2RhdGFMYWJlbC5tb3ZlZCA/ICdhbmltYXRlJyA6ICdhdHRyJ10oX3Bvcyk7XG5cdFx0XHRcdFx0ZGF0YUxhYmVsLm1vdmVkID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIGlmIChkYXRhTGFiZWwpIHtcblx0XHRcdFx0XHRkYXRhTGFiZWwuYXR0cih7IHk6IC05OTkgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fTtcblxuXHRzZXJpZXNUeXBlcy5waWUucHJvdG90eXBlLmFsaWduRGF0YUxhYmVsID0gIG5vb3A7XG5cblx0LyoqXG5cdCAqIFZlcmlmeSB3aGV0aGVyIHRoZSBkYXRhIGxhYmVscyBhcmUgYWxsb3dlZCB0byBkcmF3LCBvciB3ZSBzaG91bGQgcnVuIG1vcmUgdHJhbnNsYXRpb24gYW5kIGRhdGFcblx0ICogbGFiZWwgcG9zaXRpb25pbmcgdG8ga2VlcCB0aGVtIGluc2lkZSB0aGUgcGxvdCBhcmVhLiBSZXR1cm5zIHRydWUgd2hlbiBkYXRhIGxhYmVscyBhcmUgcmVhZHlcblx0ICogdG8gZHJhdy5cblx0ICovXG5cdHNlcmllc1R5cGVzLnBpZS5wcm90b3R5cGUudmVyaWZ5RGF0YUxhYmVsT3ZlcmZsb3cgPSBmdW5jdGlvbiAob3ZlcmZsb3cpIHtcblxuXHRcdHZhciBjZW50ZXIgPSB0aGlzLmNlbnRlcixcblx0XHRcdG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG5cdFx0XHRjZW50ZXJPcHRpb24gPSBvcHRpb25zLmNlbnRlcixcblx0XHRcdG1pblNpemUgPSBvcHRpb25zLm1pblNpemUgfHwgODAsXG5cdFx0XHRuZXdTaXplID0gbWluU2l6ZSxcblx0XHRcdHJldDtcblxuXHRcdC8vIEhhbmRsZSBob3Jpem9udGFsIHNpemUgYW5kIGNlbnRlclxuXHRcdGlmIChjZW50ZXJPcHRpb25bMF0gIT09IG51bGwpIHsgLy8gRml4ZWQgY2VudGVyXG5cdFx0XHRuZXdTaXplID0gbWF0aE1heChjZW50ZXJbMl0gLSBtYXRoTWF4KG92ZXJmbG93WzFdLCBvdmVyZmxvd1szXSksIG1pblNpemUpO1xuXG5cdFx0fSBlbHNlIHsgLy8gQXV0byBjZW50ZXJcblx0XHRcdG5ld1NpemUgPSBtYXRoTWF4KFxuXHRcdFx0XHRjZW50ZXJbMl0gLSBvdmVyZmxvd1sxXSAtIG92ZXJmbG93WzNdLCAvLyBob3Jpem9udGFsIG92ZXJmbG93XG5cdFx0XHRcdG1pblNpemVcblx0XHRcdCk7XG5cdFx0XHRjZW50ZXJbMF0gKz0gKG92ZXJmbG93WzNdIC0gb3ZlcmZsb3dbMV0pIC8gMjsgLy8gaG9yaXpvbnRhbCBjZW50ZXJcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgdmVydGljYWwgc2l6ZSBhbmQgY2VudGVyXG5cdFx0aWYgKGNlbnRlck9wdGlvblsxXSAhPT0gbnVsbCkgeyAvLyBGaXhlZCBjZW50ZXJcblx0XHRcdG5ld1NpemUgPSBtYXRoTWF4KG1hdGhNaW4obmV3U2l6ZSwgY2VudGVyWzJdIC0gbWF0aE1heChvdmVyZmxvd1swXSwgb3ZlcmZsb3dbMl0pKSwgbWluU2l6ZSk7XG5cblx0XHR9IGVsc2UgeyAvLyBBdXRvIGNlbnRlclxuXHRcdFx0bmV3U2l6ZSA9IG1hdGhNYXgoXG5cdFx0XHRcdG1hdGhNaW4oXG5cdFx0XHRcdFx0bmV3U2l6ZSxcblx0XHRcdFx0XHRjZW50ZXJbMl0gLSBvdmVyZmxvd1swXSAtIG92ZXJmbG93WzJdIC8vIHZlcnRpY2FsIG92ZXJmbG93XG5cdFx0XHRcdCksXG5cdFx0XHRcdG1pblNpemVcblx0XHRcdCk7XG5cdFx0XHRjZW50ZXJbMV0gKz0gKG92ZXJmbG93WzBdIC0gb3ZlcmZsb3dbMl0pIC8gMjsgLy8gdmVydGljYWwgY2VudGVyXG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIHNpemUgbXVzdCBiZSBkZWNyZWFzZWQsIHdlIG5lZWQgdG8gcnVuIHRyYW5zbGF0ZSBhbmQgZHJhd0RhdGFMYWJlbHMgYWdhaW5cblx0XHRpZiAobmV3U2l6ZSA8IGNlbnRlclsyXSkge1xuXHRcdFx0Y2VudGVyWzJdID0gbmV3U2l6ZTtcblx0XHRcdHRoaXMudHJhbnNsYXRlKGNlbnRlcik7XG5cdFx0XHRlYWNoKHRoaXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0aWYgKHBvaW50LmRhdGFMYWJlbCkge1xuXHRcdFx0XHRcdHBvaW50LmRhdGFMYWJlbC5fcG9zID0gbnVsbDsgLy8gcmVzZXRcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdGlmICh0aGlzLmRyYXdEYXRhTGFiZWxzKSB7XG5cdFx0XHRcdHRoaXMuZHJhd0RhdGFMYWJlbHMoKTtcblx0XHRcdH1cblx0XHQvLyBFbHNlLCByZXR1cm4gdHJ1ZSB0byBpbmRpY2F0ZSB0aGF0IHRoZSBwaWUgYW5kIGl0cyBsYWJlbHMgaXMgd2l0aGluIHRoZSBwbG90IGFyZWFcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0ID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIHJldDtcblx0fTtcbn1cblxuaWYgKHNlcmllc1R5cGVzLmNvbHVtbikge1xuXG5cdC8qKlxuXHQgKiBPdmVycmlkZSB0aGUgYmFzaWMgZGF0YSBsYWJlbCBhbGlnbm1lbnQgYnkgYWRqdXN0aW5nIGZvciB0aGUgcG9zaXRpb24gb2YgdGhlIGNvbHVtblxuXHQgKi9cblx0c2VyaWVzVHlwZXMuY29sdW1uLnByb3RvdHlwZS5hbGlnbkRhdGFMYWJlbCA9IGZ1bmN0aW9uIChwb2ludCwgZGF0YUxhYmVsLCBvcHRpb25zLCAgYWxpZ25UbywgaXNOZXcpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLmNoYXJ0LFxuXHRcdFx0aW52ZXJ0ZWQgPSBjaGFydC5pbnZlcnRlZCxcblx0XHRcdGRsQm94ID0gcG9pbnQuZGxCb3ggfHwgcG9pbnQuc2hhcGVBcmdzLCAvLyBkYXRhIGxhYmVsIGJveCBmb3IgYWxpZ25tZW50XG5cdFx0XHRiZWxvdyA9IHBvaW50LmJlbG93IHx8IChwb2ludC5wbG90WSA+IHBpY2sodGhpcy50cmFuc2xhdGVkVGhyZXNob2xkLCBjaGFydC5wbG90U2l6ZVkpKSxcblx0XHRcdGluc2lkZSA9IHBpY2sob3B0aW9ucy5pbnNpZGUsICEhdGhpcy5vcHRpb25zLnN0YWNraW5nKTsgLy8gZHJhdyBpdCBpbnNpZGUgdGhlIGJveD9cblxuXHRcdC8vIEFsaWduIHRvIHRoZSBjb2x1bW4gaXRzZWxmLCBvciB0aGUgdG9wIG9mIGl0XG5cdFx0aWYgKGRsQm94KSB7IC8vIEFyZWEgcmFuZ2UgdXNlcyB0aGlzIG1ldGhvZCBidXQgbm90IGFsaWduVG9cblx0XHRcdGFsaWduVG8gPSBtZXJnZShkbEJveCk7XG5cblx0XHRcdGlmIChpbnZlcnRlZCkge1xuXHRcdFx0XHRhbGlnblRvID0ge1xuXHRcdFx0XHRcdHg6IGNoYXJ0LnBsb3RXaWR0aCAtIGFsaWduVG8ueSAtIGFsaWduVG8uaGVpZ2h0LFxuXHRcdFx0XHRcdHk6IGNoYXJ0LnBsb3RIZWlnaHQgLSBhbGlnblRvLnggLSBhbGlnblRvLndpZHRoLFxuXHRcdFx0XHRcdHdpZHRoOiBhbGlnblRvLmhlaWdodCxcblx0XHRcdFx0XHRoZWlnaHQ6IGFsaWduVG8ud2lkdGhcblx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29tcHV0ZSB0aGUgYWxpZ25tZW50IGJveFxuXHRcdFx0aWYgKCFpbnNpZGUpIHtcblx0XHRcdFx0aWYgKGludmVydGVkKSB7XG5cdFx0XHRcdFx0YWxpZ25Uby54ICs9IGJlbG93ID8gMCA6IGFsaWduVG8ud2lkdGg7XG5cdFx0XHRcdFx0YWxpZ25Uby53aWR0aCA9IDA7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0YWxpZ25Uby55ICs9IGJlbG93ID8gYWxpZ25Uby5oZWlnaHQgOiAwO1xuXHRcdFx0XHRcdGFsaWduVG8uaGVpZ2h0ID0gMDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXG5cdFx0Ly8gV2hlbiBhbGlnbm1lbnQgaXMgdW5kZWZpbmVkICh0eXBpY2FsbHkgY29sdW1ucyBhbmQgYmFycyksIGRpc3BsYXkgdGhlIGluZGl2aWR1YWxcblx0XHQvLyBwb2ludCBiZWxvdyBvciBhYm92ZSB0aGUgcG9pbnQgZGVwZW5kaW5nIG9uIHRoZSB0aHJlc2hvbGRcblx0XHRvcHRpb25zLmFsaWduID0gcGljayhcblx0XHRcdG9wdGlvbnMuYWxpZ24sXG5cdFx0XHQhaW52ZXJ0ZWQgfHwgaW5zaWRlID8gJ2NlbnRlcicgOiBiZWxvdyA/ICdyaWdodCcgOiAnbGVmdCdcblx0XHQpO1xuXHRcdG9wdGlvbnMudmVydGljYWxBbGlnbiA9IHBpY2soXG5cdFx0XHRvcHRpb25zLnZlcnRpY2FsQWxpZ24sXG5cdFx0XHRpbnZlcnRlZCB8fCBpbnNpZGUgPyAnbWlkZGxlJyA6IGJlbG93ID8gJ3RvcCcgOiAnYm90dG9tJ1xuXHRcdCk7XG5cblx0XHQvLyBDYWxsIHRoZSBwYXJlbnQgbWV0aG9kXG5cdFx0U2VyaWVzLnByb3RvdHlwZS5hbGlnbkRhdGFMYWJlbC5jYWxsKHRoaXMsIHBvaW50LCBkYXRhTGFiZWwsIG9wdGlvbnMsIGFsaWduVG8sIGlzTmV3KTtcblx0fTtcbn1cblxuXG5cbi8qKlxuICogVHJhY2tlck1peGluIGZvciBwb2ludHMgYW5kIGdyYXBoc1xuICovXG5cbnZhciBUcmFja2VyTWl4aW4gPSBIaWdoY2hhcnRzLlRyYWNrZXJNaXhpbiA9IHtcblxuXHRkcmF3VHJhY2tlclBvaW50OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHBvaW50ZXIgPSBjaGFydC5wb2ludGVyLFxuXHRcdFx0Y3Vyc29yID0gc2VyaWVzLm9wdGlvbnMuY3Vyc29yLFxuXHRcdFx0Y3NzID0gY3Vyc29yICYmIHsgY3Vyc29yOiBjdXJzb3IgfSxcblx0XHRcdG9uTW91c2VPdmVyID0gZnVuY3Rpb24gKGUpIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IGUudGFyZ2V0LFxuXHRcdFx0XHRwb2ludDtcblxuXHRcdFx0XHRpZiAoY2hhcnQuaG92ZXJTZXJpZXMgIT09IHNlcmllcykge1xuXHRcdFx0XHRcdHNlcmllcy5vbk1vdXNlT3ZlcigpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0d2hpbGUgKHRhcmdldCAmJiAhcG9pbnQpIHtcblx0XHRcdFx0XHRwb2ludCA9IHRhcmdldC5wb2ludDtcblx0XHRcdFx0XHR0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChwb2ludCAhPT0gVU5ERUZJTkVEICYmIHBvaW50ICE9PSBjaGFydC5ob3ZlclBvaW50KSB7IC8vIHVuZGVmaW5lZCBvbiBncmFwaCBpbiBzY2F0dGVyY2hhcnRcblx0XHRcdFx0XHRwb2ludC5vbk1vdXNlT3ZlcihlKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdC8vIEFkZCByZWZlcmVuY2UgdG8gdGhlIHBvaW50XG5cdFx0ZWFjaChzZXJpZXMucG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdGlmIChwb2ludC5ncmFwaGljKSB7XG5cdFx0XHRcdHBvaW50LmdyYXBoaWMuZWxlbWVudC5wb2ludCA9IHBvaW50O1xuXHRcdFx0fVxuXHRcdFx0aWYgKHBvaW50LmRhdGFMYWJlbCkge1xuXHRcdFx0XHRwb2ludC5kYXRhTGFiZWwuZWxlbWVudC5wb2ludCA9IHBvaW50O1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0Ly8gQWRkIHRoZSBldmVudCBsaXN0ZW5lcnMsIHdlIG5lZWQgdG8gZG8gdGhpcyBvbmx5IG9uY2Vcblx0XHRpZiAoIXNlcmllcy5faGFzVHJhY2tpbmcpIHtcblx0XHRcdGVhY2goc2VyaWVzLnRyYWNrZXJHcm91cHMsIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdFx0aWYgKHNlcmllc1trZXldKSB7IC8vIHdlIGRvbid0IGFsd2F5cyBoYXZlIGRhdGFMYWJlbHNHcm91cFxuXHRcdFx0XHRcdHNlcmllc1trZXldXG5cdFx0XHRcdFx0XHQuYWRkQ2xhc3MoUFJFRklYICsgJ3RyYWNrZXInKVxuXHRcdFx0XHRcdFx0Lm9uKCdtb3VzZW92ZXInLCBvbk1vdXNlT3Zlcilcblx0XHRcdFx0XHRcdC5vbignbW91c2VvdXQnLCBmdW5jdGlvbiAoZSkgeyBwb2ludGVyLm9uVHJhY2tlck1vdXNlT3V0KGUpOyB9KVxuXHRcdFx0XHRcdFx0LmNzcyhjc3MpO1xuXHRcdFx0XHRcdGlmIChoYXNUb3VjaCkge1xuXHRcdFx0XHRcdFx0c2VyaWVzW2tleV0ub24oJ3RvdWNoc3RhcnQnLCBvbk1vdXNlT3Zlcik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdHNlcmllcy5faGFzVHJhY2tpbmcgPSB0cnVlO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogRHJhdyB0aGUgdHJhY2tlciBvYmplY3QgdGhhdCBzaXRzIGFib3ZlIGFsbCBkYXRhIGxhYmVscyBhbmQgbWFya2VycyB0b1xuXHQgKiB0cmFjayBtb3VzZSBldmVudHMgb24gdGhlIGdyYXBoIG9yIHBvaW50cy4gRm9yIHRoZSBsaW5lIHR5cGUgY2hhcnRzXG5cdCAqIHRoZSB0cmFja2VyIHVzZXMgdGhlIHNhbWUgZ3JhcGhQYXRoLCBidXQgd2l0aCBhIGdyZWF0ZXIgc3Ryb2tlIHdpZHRoXG5cdCAqIGZvciBiZXR0ZXIgY29udHJvbC5cblx0ICovXG5cdGRyYXdUcmFja2VyR3JhcGg6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdHRyYWNrQnlBcmVhID0gb3B0aW9ucy50cmFja0J5QXJlYSxcblx0XHRcdHRyYWNrZXJQYXRoID0gW10uY29uY2F0KHRyYWNrQnlBcmVhID8gc2VyaWVzLmFyZWFQYXRoIDogc2VyaWVzLmdyYXBoUGF0aCksXG5cdFx0XHR0cmFja2VyUGF0aExlbmd0aCA9IHRyYWNrZXJQYXRoLmxlbmd0aCxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0cG9pbnRlciA9IGNoYXJ0LnBvaW50ZXIsXG5cdFx0XHRyZW5kZXJlciA9IGNoYXJ0LnJlbmRlcmVyLFxuXHRcdFx0c25hcCA9IGNoYXJ0Lm9wdGlvbnMudG9vbHRpcC5zbmFwLFxuXHRcdFx0dHJhY2tlciA9IHNlcmllcy50cmFja2VyLFxuXHRcdFx0Y3Vyc29yID0gb3B0aW9ucy5jdXJzb3IsXG5cdFx0XHRjc3MgPSBjdXJzb3IgJiYgeyBjdXJzb3I6IGN1cnNvciB9LFxuXHRcdFx0c2luZ2xlUG9pbnRzID0gc2VyaWVzLnNpbmdsZVBvaW50cyxcblx0XHRcdHNpbmdsZVBvaW50LFxuXHRcdFx0aSxcblx0XHRcdG9uTW91c2VPdmVyID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRpZiAoY2hhcnQuaG92ZXJTZXJpZXMgIT09IHNlcmllcykge1xuXHRcdFx0XHRcdHNlcmllcy5vbk1vdXNlT3ZlcigpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0Lypcblx0XHRcdCAqIEVtcGlyaWNhbCBsb3dlc3QgcG9zc2libGUgb3BhY2l0aWVzIGZvciBUUkFDS0VSX0ZJTEwgZm9yIGFuIGVsZW1lbnQgdG8gc3RheSBpbnZpc2libGUgYnV0IGNsaWNrYWJsZVxuXHRcdFx0ICogSUU2OiAwLjAwMlxuXHRcdFx0ICogSUU3OiAwLjAwMlxuXHRcdFx0ICogSUU4OiAwLjAwMlxuXHRcdFx0ICogSUU5OiAwLjAwMDAwMDAwMDAxICh1bmxpbWl0ZWQpXG5cdFx0XHQgKiBJRTEwOiAwLjAwMDEgKGV4cG9ydGluZyBvbmx5KVxuXHRcdFx0ICogRkY6IDAuMDAwMDAwMDAwMDEgKHVubGltaXRlZClcblx0XHRcdCAqIENocm9tZTogMC4wMDAwMDFcblx0XHRcdCAqIFNhZmFyaTogMC4wMDAwMDFcblx0XHRcdCAqIE9wZXJhOiAwLjAwMDAwMDAwMDAxICh1bmxpbWl0ZWQpXG5cdFx0XHQgKi9cblx0XHRcdFRSQUNLRVJfRklMTCA9ICdyZ2JhKDE5MiwxOTIsMTkyLCcgKyAoaGFzU1ZHID8gMC4wMDAxIDogMC4wMDIpICsgJyknO1xuXG5cdFx0Ly8gRXh0ZW5kIGVuZCBwb2ludHMuIEEgYmV0dGVyIHdheSB3b3VsZCBiZSB0byB1c2Ugcm91bmQgbGluZWNhcHMsXG5cdFx0Ly8gYnV0IHRob3NlIGFyZSBub3QgY2xpY2thYmxlIGluIFZNTC5cblx0XHRpZiAodHJhY2tlclBhdGhMZW5ndGggJiYgIXRyYWNrQnlBcmVhKSB7XG5cdFx0XHRpID0gdHJhY2tlclBhdGhMZW5ndGggKyAxO1xuXHRcdFx0d2hpbGUgKGktLSkge1xuXHRcdFx0XHRpZiAodHJhY2tlclBhdGhbaV0gPT09IE0pIHsgLy8gZXh0ZW5kIGxlZnQgc2lkZVxuXHRcdFx0XHRcdHRyYWNrZXJQYXRoLnNwbGljZShpICsgMSwgMCwgdHJhY2tlclBhdGhbaSArIDFdIC0gc25hcCwgdHJhY2tlclBhdGhbaSArIDJdLCBMKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoKGkgJiYgdHJhY2tlclBhdGhbaV0gPT09IE0pIHx8IGkgPT09IHRyYWNrZXJQYXRoTGVuZ3RoKSB7IC8vIGV4dGVuZCByaWdodCBzaWRlXG5cdFx0XHRcdFx0dHJhY2tlclBhdGguc3BsaWNlKGksIDAsIEwsIHRyYWNrZXJQYXRoW2kgLSAyXSArIHNuYXAsIHRyYWNrZXJQYXRoW2kgLSAxXSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBoYW5kbGUgc2luZ2xlIHBvaW50c1xuXHRcdGZvciAoaSA9IDA7IGkgPCBzaW5nbGVQb2ludHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHNpbmdsZVBvaW50ID0gc2luZ2xlUG9pbnRzW2ldO1xuXHRcdFx0dHJhY2tlclBhdGgucHVzaChNLCBzaW5nbGVQb2ludC5wbG90WCAtIHNuYXAsIHNpbmdsZVBvaW50LnBsb3RZLFxuXHRcdFx0TCwgc2luZ2xlUG9pbnQucGxvdFggKyBzbmFwLCBzaW5nbGVQb2ludC5wbG90WSk7XG5cdFx0fVxuXG5cdFx0Ly8gZHJhdyB0aGUgdHJhY2tlclxuXHRcdGlmICh0cmFja2VyKSB7XG5cdFx0XHR0cmFja2VyLmF0dHIoeyBkOiB0cmFja2VyUGF0aCB9KTtcblx0XHR9IGVsc2UgeyAvLyBjcmVhdGVcblxuXHRcdFx0c2VyaWVzLnRyYWNrZXIgPSByZW5kZXJlci5wYXRoKHRyYWNrZXJQYXRoKVxuXHRcdFx0LmF0dHIoe1xuXHRcdFx0XHQnc3Ryb2tlLWxpbmVqb2luJzogJ3JvdW5kJywgLy8gIzEyMjVcblx0XHRcdFx0dmlzaWJpbGl0eTogc2VyaWVzLnZpc2libGUgPyBWSVNJQkxFIDogSElEREVOLFxuXHRcdFx0XHRzdHJva2U6IFRSQUNLRVJfRklMTCxcblx0XHRcdFx0ZmlsbDogdHJhY2tCeUFyZWEgPyBUUkFDS0VSX0ZJTEwgOiBOT05FLFxuXHRcdFx0XHQnc3Ryb2tlLXdpZHRoJyA6IG9wdGlvbnMubGluZVdpZHRoICsgKHRyYWNrQnlBcmVhID8gMCA6IDIgKiBzbmFwKSxcblx0XHRcdFx0ekluZGV4OiAyXG5cdFx0XHR9KVxuXHRcdFx0LmFkZChzZXJpZXMuZ3JvdXApO1xuXG5cdFx0XHQvLyBUaGUgdHJhY2tlciBpcyBhZGRlZCB0byB0aGUgc2VyaWVzIGdyb3VwLCB3aGljaCBpcyBjbGlwcGVkLCBidXQgaXMgY292ZXJlZFxuXHRcdFx0Ly8gYnkgdGhlIG1hcmtlciBncm91cC4gU28gdGhlIG1hcmtlciBncm91cCBhbHNvIG5lZWRzIHRvIGNhcHR1cmUgZXZlbnRzLlxuXHRcdFx0ZWFjaChbc2VyaWVzLnRyYWNrZXIsIHNlcmllcy5tYXJrZXJHcm91cF0sIGZ1bmN0aW9uICh0cmFja2VyKSB7XG5cdFx0XHRcdHRyYWNrZXIuYWRkQ2xhc3MoUFJFRklYICsgJ3RyYWNrZXInKVxuXHRcdFx0XHRcdC5vbignbW91c2VvdmVyJywgb25Nb3VzZU92ZXIpXG5cdFx0XHRcdFx0Lm9uKCdtb3VzZW91dCcsIGZ1bmN0aW9uIChlKSB7IHBvaW50ZXIub25UcmFja2VyTW91c2VPdXQoZSk7IH0pXG5cdFx0XHRcdFx0LmNzcyhjc3MpO1xuXG5cdFx0XHRcdGlmIChoYXNUb3VjaCkge1xuXHRcdFx0XHRcdHRyYWNrZXIub24oJ3RvdWNoc3RhcnQnLCBvbk1vdXNlT3Zlcik7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufTtcbi8qIEVuZCBUcmFja2VyTWl4aW4gKi9cblxuXG4vKipcbiAqIEFkZCB0cmFja2luZyBldmVudCBsaXN0ZW5lciB0byB0aGUgc2VyaWVzIGdyb3VwLCBzbyB0aGUgcG9pbnQgZ3JhcGhpY3NcbiAqIHRoZW1zZWx2ZXMgYWN0IGFzIHRyYWNrZXJzXG4gKi8gXG5cbmlmIChzZXJpZXNUeXBlcy5jb2x1bW4pIHtcblx0Q29sdW1uU2VyaWVzLnByb3RvdHlwZS5kcmF3VHJhY2tlciA9IFRyYWNrZXJNaXhpbi5kcmF3VHJhY2tlclBvaW50O1x0XG59XG5cbmlmIChzZXJpZXNUeXBlcy5waWUpIHtcblx0c2VyaWVzVHlwZXMucGllLnByb3RvdHlwZS5kcmF3VHJhY2tlciA9IFRyYWNrZXJNaXhpbi5kcmF3VHJhY2tlclBvaW50O1xufVxuXG5pZiAoc2VyaWVzVHlwZXMuc2NhdHRlcikge1xuXHRTY2F0dGVyU2VyaWVzLnByb3RvdHlwZS5kcmF3VHJhY2tlciA9IFRyYWNrZXJNaXhpbi5kcmF3VHJhY2tlclBvaW50O1xufVxuXG4vKiBcbiAqIEV4dGVuZCBMZWdlbmQgZm9yIGl0ZW0gZXZlbnRzIFxuICovIFxuZXh0ZW5kKExlZ2VuZC5wcm90b3R5cGUsIHtcblxuXHRzZXRJdGVtRXZlbnRzOiBmdW5jdGlvbiAoaXRlbSwgbGVnZW5kSXRlbSwgdXNlSFRNTCwgaXRlbVN0eWxlLCBpdGVtSGlkZGVuU3R5bGUpIHtcblx0dmFyIGxlZ2VuZCA9IHRoaXM7XG5cdC8vIFNldCB0aGUgZXZlbnRzIG9uIHRoZSBpdGVtIGdyb3VwLCBvciBpbiBjYXNlIG9mIHVzZUhUTUwsIHRoZSBpdGVtIGl0c2VsZiAoIzEyNDkpXG5cdCh1c2VIVE1MID8gbGVnZW5kSXRlbSA6IGl0ZW0ubGVnZW5kR3JvdXApLm9uKCdtb3VzZW92ZXInLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRpdGVtLnNldFN0YXRlKEhPVkVSX1NUQVRFKTtcblx0XHRcdGxlZ2VuZEl0ZW0uY3NzKGxlZ2VuZC5vcHRpb25zLml0ZW1Ib3ZlclN0eWxlKTtcblx0XHR9KVxuXHRcdC5vbignbW91c2VvdXQnLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRsZWdlbmRJdGVtLmNzcyhpdGVtLnZpc2libGUgPyBpdGVtU3R5bGUgOiBpdGVtSGlkZGVuU3R5bGUpO1xuXHRcdFx0aXRlbS5zZXRTdGF0ZSgpO1xuXHRcdH0pXG5cdFx0Lm9uKCdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0dmFyIHN0ckxlZ2VuZEl0ZW1DbGljayA9ICdsZWdlbmRJdGVtQ2xpY2snLFxuXHRcdFx0XHRmbkxlZ2VuZEl0ZW1DbGljayA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRpdGVtLnNldFZpc2libGUoKTtcblx0XHRcdFx0fTtcblx0XHRcdFx0XG5cdFx0XHQvLyBQYXNzIG92ZXIgdGhlIGNsaWNrL3RvdWNoIGV2ZW50LiAjNC5cblx0XHRcdGV2ZW50ID0ge1xuXHRcdFx0XHRicm93c2VyRXZlbnQ6IGV2ZW50XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBjbGljayB0aGUgbmFtZSBvciBzeW1ib2xcblx0XHRcdGlmIChpdGVtLmZpcmVQb2ludEV2ZW50KSB7IC8vIHBvaW50XG5cdFx0XHRcdGl0ZW0uZmlyZVBvaW50RXZlbnQoc3RyTGVnZW5kSXRlbUNsaWNrLCBldmVudCwgZm5MZWdlbmRJdGVtQ2xpY2spO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZmlyZUV2ZW50KGl0ZW0sIHN0ckxlZ2VuZEl0ZW1DbGljaywgZXZlbnQsIGZuTGVnZW5kSXRlbUNsaWNrKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRjcmVhdGVDaGVja2JveEZvckl0ZW06IGZ1bmN0aW9uIChpdGVtKSB7XG5cdFx0dmFyIGxlZ2VuZCA9IHRoaXM7XG5cblx0XHRpdGVtLmNoZWNrYm94ID0gY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7XG5cdFx0XHR0eXBlOiAnY2hlY2tib3gnLFxuXHRcdFx0Y2hlY2tlZDogaXRlbS5zZWxlY3RlZCxcblx0XHRcdGRlZmF1bHRDaGVja2VkOiBpdGVtLnNlbGVjdGVkIC8vIHJlcXVpcmVkIGJ5IElFN1xuXHRcdH0sIGxlZ2VuZC5vcHRpb25zLml0ZW1DaGVja2JveFN0eWxlLCBsZWdlbmQuY2hhcnQuY29udGFpbmVyKTtcblxuXHRcdGFkZEV2ZW50KGl0ZW0uY2hlY2tib3gsICdjbGljaycsIGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0dmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcblx0XHRcdGZpcmVFdmVudChpdGVtLCAnY2hlY2tib3hDbGljaycsIHtcblx0XHRcdFx0XHRjaGVja2VkOiB0YXJnZXQuY2hlY2tlZFxuXHRcdFx0XHR9LFxuXHRcdFx0XHRmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0aXRlbS5zZWxlY3QoKTtcblx0XHRcdFx0fVxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVx0XG59KTtcblxuLyogXG4gKiBBZGQgcG9pbnRlciBjdXJzb3IgdG8gbGVnZW5kIGl0ZW1zdHlsZSBpbiBkZWZhdWx0T3B0aW9uc1xuICovXG5kZWZhdWx0T3B0aW9ucy5sZWdlbmQuaXRlbVN0eWxlLmN1cnNvciA9ICdwb2ludGVyJztcblxuXG4vKiBcbiAqIEV4dGVuZCB0aGUgQ2hhcnQgb2JqZWN0IHdpdGggaW50ZXJhY3Rpb25cbiAqL1xuXG5leHRlbmQoQ2hhcnQucHJvdG90eXBlLCB7XG5cdC8qKlxuXHQgKiBEaXNwbGF5IHRoZSB6b29tIGJ1dHRvblxuXHQgKi9cblx0c2hvd1Jlc2V0Wm9vbTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXMsXG5cdFx0XHRsYW5nID0gZGVmYXVsdE9wdGlvbnMubGFuZyxcblx0XHRcdGJ0bk9wdGlvbnMgPSBjaGFydC5vcHRpb25zLmNoYXJ0LnJlc2V0Wm9vbUJ1dHRvbixcblx0XHRcdHRoZW1lID0gYnRuT3B0aW9ucy50aGVtZSxcblx0XHRcdHN0YXRlcyA9IHRoZW1lLnN0YXRlcyxcblx0XHRcdGFsaWduVG8gPSBidG5PcHRpb25zLnJlbGF0aXZlVG8gPT09ICdjaGFydCcgPyBudWxsIDogJ3Bsb3RCb3gnO1xuXHRcdFx0XG5cdFx0dGhpcy5yZXNldFpvb21CdXR0b24gPSBjaGFydC5yZW5kZXJlci5idXR0b24obGFuZy5yZXNldFpvb20sIG51bGwsIG51bGwsIGZ1bmN0aW9uICgpIHsgY2hhcnQuem9vbU91dCgpOyB9LCB0aGVtZSwgc3RhdGVzICYmIHN0YXRlcy5ob3Zlcilcblx0XHRcdC5hdHRyKHtcblx0XHRcdFx0YWxpZ246IGJ0bk9wdGlvbnMucG9zaXRpb24uYWxpZ24sXG5cdFx0XHRcdHRpdGxlOiBsYW5nLnJlc2V0Wm9vbVRpdGxlXG5cdFx0XHR9KVxuXHRcdFx0LmFkZCgpXG5cdFx0XHQuYWxpZ24oYnRuT3B0aW9ucy5wb3NpdGlvbiwgZmFsc2UsIGFsaWduVG8pO1xuXHRcdFx0XG5cdH0sXG5cblx0LyoqXG5cdCAqIFpvb20gb3V0IHRvIDE6MVxuXHQgKi9cblx0em9vbU91dDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjaGFydCA9IHRoaXM7XG5cdFx0ZmlyZUV2ZW50KGNoYXJ0LCAnc2VsZWN0aW9uJywgeyByZXNldFNlbGVjdGlvbjogdHJ1ZSB9LCBmdW5jdGlvbiAoKSB7IFxuXHRcdFx0Y2hhcnQuem9vbSgpO1xuXHRcdH0pO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBab29tIGludG8gYSBnaXZlbiBwb3J0aW9uIG9mIHRoZSBjaGFydCBnaXZlbiBieSBheGlzIGNvb3JkaW5hdGVzXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuXHQgKi9cblx0em9vbTogZnVuY3Rpb24gKGV2ZW50KSB7XG5cdFx0dmFyIGNoYXJ0ID0gdGhpcyxcblx0XHRcdGhhc1pvb21lZCxcblx0XHRcdHBvaW50ZXIgPSBjaGFydC5wb2ludGVyLFxuXHRcdFx0ZGlzcGxheUJ1dHRvbiA9IGZhbHNlLFxuXHRcdFx0cmVzZXRab29tQnV0dG9uO1xuXG5cdFx0Ly8gSWYgem9vbSBpcyBjYWxsZWQgd2l0aCBubyBhcmd1bWVudHMsIHJlc2V0IHRoZSBheGVzXG5cdFx0aWYgKCFldmVudCB8fCBldmVudC5yZXNldFNlbGVjdGlvbikge1xuXHRcdFx0ZWFjaChjaGFydC5heGVzLCBmdW5jdGlvbiAoYXhpcykge1xuXHRcdFx0XHRoYXNab29tZWQgPSBheGlzLnpvb20oKTtcblx0XHRcdH0pO1xuXHRcdH0gZWxzZSB7IC8vIGVsc2UsIHpvb20gaW4gb24gYWxsIGF4ZXNcblx0XHRcdGVhY2goZXZlbnQueEF4aXMuY29uY2F0KGV2ZW50LnlBeGlzKSwgZnVuY3Rpb24gKGF4aXNEYXRhKSB7XG5cdFx0XHRcdHZhciBheGlzID0gYXhpc0RhdGEuYXhpcyxcblx0XHRcdFx0XHRpc1hBeGlzID0gYXhpcy5pc1hBeGlzO1xuXG5cdFx0XHRcdC8vIGRvbid0IHpvb20gbW9yZSB0aGFuIG1pblJhbmdlXG5cdFx0XHRcdGlmIChwb2ludGVyW2lzWEF4aXMgPyAnem9vbVgnIDogJ3pvb21ZJ10gfHwgcG9pbnRlcltpc1hBeGlzID8gJ3BpbmNoWCcgOiAncGluY2hZJ10pIHtcblx0XHRcdFx0XHRoYXNab29tZWQgPSBheGlzLnpvb20oYXhpc0RhdGEubWluLCBheGlzRGF0YS5tYXgpO1xuXHRcdFx0XHRcdGlmIChheGlzLmRpc3BsYXlCdG4pIHtcblx0XHRcdFx0XHRcdGRpc3BsYXlCdXR0b24gPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdFxuXHRcdC8vIFNob3cgb3IgaGlkZSB0aGUgUmVzZXQgem9vbSBidXR0b25cblx0XHRyZXNldFpvb21CdXR0b24gPSBjaGFydC5yZXNldFpvb21CdXR0b247XG5cdFx0aWYgKGRpc3BsYXlCdXR0b24gJiYgIXJlc2V0Wm9vbUJ1dHRvbikge1xuXHRcdFx0Y2hhcnQuc2hvd1Jlc2V0Wm9vbSgpO1xuXHRcdH0gZWxzZSBpZiAoIWRpc3BsYXlCdXR0b24gJiYgaXNPYmplY3QocmVzZXRab29tQnV0dG9uKSkge1xuXHRcdFx0Y2hhcnQucmVzZXRab29tQnV0dG9uID0gcmVzZXRab29tQnV0dG9uLmRlc3Ryb3koKTtcblx0XHR9XG5cdFx0XG5cblx0XHQvLyBSZWRyYXdcblx0XHRpZiAoaGFzWm9vbWVkKSB7XG5cdFx0XHRjaGFydC5yZWRyYXcoXG5cdFx0XHRcdHBpY2soY2hhcnQub3B0aW9ucy5jaGFydC5hbmltYXRpb24sIGV2ZW50ICYmIGV2ZW50LmFuaW1hdGlvbiwgY2hhcnQucG9pbnRDb3VudCA8IDEwMCkgLy8gYW5pbWF0aW9uXG5cdFx0XHQpO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogUGFuIHRoZSBjaGFydCBieSBkcmFnZ2luZyB0aGUgbW91c2UgYWNyb3NzIHRoZSBwYW5lLiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZFxuXHQgKiBvbiBtb3VzZSBtb3ZlLCBhbmQgdGhlIGRpc3RhbmNlIHRvIHBhbiBpcyBjb21wdXRlZCBmcm9tIGNoYXJ0WCBjb21wYXJlZCB0b1xuXHQgKiB0aGUgZmlyc3QgY2hhcnRYIHBvc2l0aW9uIGluIHRoZSBkcmFnZ2luZyBvcGVyYXRpb24uXG5cdCAqL1xuXHRwYW46IGZ1bmN0aW9uIChlLCBwYW5uaW5nKSB7XG5cblx0XHR2YXIgY2hhcnQgPSB0aGlzLFxuXHRcdFx0aG92ZXJQb2ludHMgPSBjaGFydC5ob3ZlclBvaW50cyxcblx0XHRcdGRvUmVkcmF3O1xuXG5cdFx0Ly8gcmVtb3ZlIGFjdGl2ZSBwb2ludHMgZm9yIHNoYXJlZCB0b29sdGlwXG5cdFx0aWYgKGhvdmVyUG9pbnRzKSB7XG5cdFx0XHRlYWNoKGhvdmVyUG9pbnRzLCBmdW5jdGlvbiAocG9pbnQpIHtcblx0XHRcdFx0cG9pbnQuc2V0U3RhdGUoKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGVhY2gocGFubmluZyA9PT0gJ3h5JyA/IFsxLCAwXSA6IFsxXSwgZnVuY3Rpb24gKGlzWCkgeyAvLyB4eSBpcyB1c2VkIGluIG1hcHNcblx0XHRcdHZhciBtb3VzZVBvcyA9IGVbaXNYID8gJ2NoYXJ0WCcgOiAnY2hhcnRZJ10sXG5cdFx0XHRcdGF4aXMgPSBjaGFydFtpc1ggPyAneEF4aXMnIDogJ3lBeGlzJ11bMF0sXG5cdFx0XHRcdHN0YXJ0UG9zID0gY2hhcnRbaXNYID8gJ21vdXNlRG93blgnIDogJ21vdXNlRG93blknXSxcblx0XHRcdFx0aGFsZlBvaW50UmFuZ2UgPSAoYXhpcy5wb2ludFJhbmdlIHx8IDApIC8gMixcblx0XHRcdFx0ZXh0cmVtZXMgPSBheGlzLmdldEV4dHJlbWVzKCksXG5cdFx0XHRcdG5ld01pbiA9IGF4aXMudG9WYWx1ZShzdGFydFBvcyAtIG1vdXNlUG9zLCB0cnVlKSArIGhhbGZQb2ludFJhbmdlLFxuXHRcdFx0XHRuZXdNYXggPSBheGlzLnRvVmFsdWUoc3RhcnRQb3MgKyBjaGFydFtpc1ggPyAncGxvdFdpZHRoJyA6ICdwbG90SGVpZ2h0J10gLSBtb3VzZVBvcywgdHJ1ZSkgLSBoYWxmUG9pbnRSYW5nZTtcblxuXHRcdFx0aWYgKGF4aXMuc2VyaWVzLmxlbmd0aCAmJiBuZXdNaW4gPiBtYXRoTWluKGV4dHJlbWVzLmRhdGFNaW4sIGV4dHJlbWVzLm1pbikgJiYgbmV3TWF4IDwgbWF0aE1heChleHRyZW1lcy5kYXRhTWF4LCBleHRyZW1lcy5tYXgpKSB7XG5cdFx0XHRcdGF4aXMuc2V0RXh0cmVtZXMobmV3TWluLCBuZXdNYXgsIGZhbHNlLCBmYWxzZSwgeyB0cmlnZ2VyOiAncGFuJyB9KTtcblx0XHRcdFx0ZG9SZWRyYXcgPSB0cnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRjaGFydFtpc1ggPyAnbW91c2VEb3duWCcgOiAnbW91c2VEb3duWSddID0gbW91c2VQb3M7IC8vIHNldCBuZXcgcmVmZXJlbmNlIGZvciBuZXh0IHJ1blxuXHRcdH0pO1xuXG5cdFx0aWYgKGRvUmVkcmF3KSB7XG5cdFx0XHRjaGFydC5yZWRyYXcoZmFsc2UpO1xuXHRcdH1cblx0XHRjc3MoY2hhcnQuY29udGFpbmVyLCB7IGN1cnNvcjogJ21vdmUnIH0pO1xuXHR9XG59KTtcblxuLypcbiAqIEV4dGVuZCB0aGUgUG9pbnQgb2JqZWN0IHdpdGggaW50ZXJhY3Rpb25cbiAqL1xuZXh0ZW5kKFBvaW50LnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogVG9nZ2xlIHRoZSBzZWxlY3Rpb24gc3RhdHVzIG9mIGEgcG9pbnRcblx0ICogQHBhcmFtIHtCb29sZWFufSBzZWxlY3RlZCBXaGV0aGVyIHRvIHNlbGVjdCBvciB1bnNlbGVjdCB0aGUgcG9pbnQuXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbn0gYWNjdW11bGF0ZSBXaGV0aGVyIHRvIGFkZCB0byB0aGUgcHJldmlvdXMgc2VsZWN0aW9uLiBCeSBkZWZhdWx0LFxuXHQgKlx0XHQgdGhpcyBoYXBwZW5zIGlmIHRoZSBjb250cm9sIGtleSAoQ21kIG9uIE1hYykgd2FzIHByZXNzZWQgZHVyaW5nIGNsaWNraW5nLlxuXHQgKi9cblx0c2VsZWN0OiBmdW5jdGlvbiAoc2VsZWN0ZWQsIGFjY3VtdWxhdGUpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0c2VyaWVzID0gcG9pbnQuc2VyaWVzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQ7XG5cblx0XHRzZWxlY3RlZCA9IHBpY2soc2VsZWN0ZWQsICFwb2ludC5zZWxlY3RlZCk7XG5cblx0XHQvLyBmaXJlIHRoZSBldmVudCB3aXRoIHRoZSBkZWZhbHV0IGhhbmRsZXJcblx0XHRwb2ludC5maXJlUG9pbnRFdmVudChzZWxlY3RlZCA/ICdzZWxlY3QnIDogJ3Vuc2VsZWN0JywgeyBhY2N1bXVsYXRlOiBhY2N1bXVsYXRlIH0sIGZ1bmN0aW9uICgpIHtcblx0XHRcdHBvaW50LnNlbGVjdGVkID0gcG9pbnQub3B0aW9ucy5zZWxlY3RlZCA9IHNlbGVjdGVkO1xuXHRcdFx0c2VyaWVzLm9wdGlvbnMuZGF0YVtpbkFycmF5KHBvaW50LCBzZXJpZXMuZGF0YSldID0gcG9pbnQub3B0aW9ucztcblxuXHRcdFx0cG9pbnQuc2V0U3RhdGUoc2VsZWN0ZWQgJiYgU0VMRUNUX1NUQVRFKTtcblxuXHRcdFx0Ly8gdW5zZWxlY3QgYWxsIG90aGVyIHBvaW50cyB1bmxlc3MgQ3RybCBvciBDbWQgKyBjbGlja1xuXHRcdFx0aWYgKCFhY2N1bXVsYXRlKSB7XG5cdFx0XHRcdGVhY2goY2hhcnQuZ2V0U2VsZWN0ZWRQb2ludHMoKSwgZnVuY3Rpb24gKGxvb3BQb2ludCkge1xuXHRcdFx0XHRcdGlmIChsb29wUG9pbnQuc2VsZWN0ZWQgJiYgbG9vcFBvaW50ICE9PSBwb2ludCkge1xuXHRcdFx0XHRcdFx0bG9vcFBvaW50LnNlbGVjdGVkID0gbG9vcFBvaW50Lm9wdGlvbnMuc2VsZWN0ZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdHNlcmllcy5vcHRpb25zLmRhdGFbaW5BcnJheShsb29wUG9pbnQsIHNlcmllcy5kYXRhKV0gPSBsb29wUG9pbnQub3B0aW9ucztcblx0XHRcdFx0XHRcdGxvb3BQb2ludC5zZXRTdGF0ZShOT1JNQUxfU1RBVEUpO1xuXHRcdFx0XHRcdFx0XHRsb29wUG9pbnQuZmlyZVBvaW50RXZlbnQoJ3Vuc2VsZWN0Jyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHQvKipcblx0ICogUnVucyBvbiBtb3VzZSBvdmVyIHRoZSBwb2ludFxuXHQgKi9cblx0b25Nb3VzZU92ZXI6IGZ1bmN0aW9uIChlKSB7XG5cdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdHNlcmllcyA9IHBvaW50LnNlcmllcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0dG9vbHRpcCA9IGNoYXJ0LnRvb2x0aXAsXG5cdFx0XHRob3ZlclBvaW50ID0gY2hhcnQuaG92ZXJQb2ludDtcblxuXHRcdC8vIHNldCBub3JtYWwgc3RhdGUgdG8gcHJldmlvdXMgc2VyaWVzXG5cdFx0aWYgKGhvdmVyUG9pbnQgJiYgaG92ZXJQb2ludCAhPT0gcG9pbnQpIHtcblx0XHRcdGhvdmVyUG9pbnQub25Nb3VzZU91dCgpO1xuXHRcdH1cblxuXHRcdC8vIHRyaWdnZXIgdGhlIGV2ZW50XG5cdFx0cG9pbnQuZmlyZVBvaW50RXZlbnQoJ21vdXNlT3ZlcicpO1xuXG5cdFx0Ly8gdXBkYXRlIHRoZSB0b29sdGlwXG5cdFx0aWYgKHRvb2x0aXAgJiYgKCF0b29sdGlwLnNoYXJlZCB8fCBzZXJpZXMubm9TaGFyZWRUb29sdGlwKSkge1xuXHRcdFx0dG9vbHRpcC5yZWZyZXNoKHBvaW50LCBlKTtcblx0XHR9XG5cblx0XHQvLyBob3ZlciB0aGlzXG5cdFx0cG9pbnQuc2V0U3RhdGUoSE9WRVJfU1RBVEUpO1xuXHRcdGNoYXJ0LmhvdmVyUG9pbnQgPSBwb2ludDtcblx0fSxcblxuXHQvKipcblx0ICogUnVucyBvbiBtb3VzZSBvdXQgZnJvbSB0aGUgcG9pbnRcblx0ICovXG5cdG9uTW91c2VPdXQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgY2hhcnQgPSB0aGlzLnNlcmllcy5jaGFydCxcblx0XHRcdGhvdmVyUG9pbnRzID0gY2hhcnQuaG92ZXJQb2ludHM7XG5cblx0XHR0aGlzLmZpcmVQb2ludEV2ZW50KCdtb3VzZU91dCcpO1xuXG5cdFx0aWYgKCFob3ZlclBvaW50cyB8fCBpbkFycmF5KHRoaXMsIGhvdmVyUG9pbnRzKSA9PT0gLTEpIHsgLy8gIzg4NywgIzIyNDBcblx0XHRcdHRoaXMuc2V0U3RhdGUoKTtcblx0XHRcdGNoYXJ0LmhvdmVyUG9pbnQgPSBudWxsO1xuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogSW1wb3J0IGV2ZW50cyBmcm9tIHRoZSBzZXJpZXMnIGFuZCBwb2ludCdzIG9wdGlvbnMuIE9ubHkgZG8gaXQgb25cblx0ICogZGVtYW5kLCB0byBzYXZlIHByb2Nlc3NpbmcgdGltZSBvbiBob3ZlcmluZy5cblx0ICovXG5cdGltcG9ydEV2ZW50czogZnVuY3Rpb24gKCkge1xuXHRcdGlmICghdGhpcy5oYXNJbXBvcnRlZEV2ZW50cykge1xuXHRcdFx0dmFyIHBvaW50ID0gdGhpcyxcblx0XHRcdFx0b3B0aW9ucyA9IG1lcmdlKHBvaW50LnNlcmllcy5vcHRpb25zLnBvaW50LCBwb2ludC5vcHRpb25zKSxcblx0XHRcdFx0ZXZlbnRzID0gb3B0aW9ucy5ldmVudHMsXG5cdFx0XHRcdGV2ZW50VHlwZTtcblxuXHRcdFx0cG9pbnQuZXZlbnRzID0gZXZlbnRzO1xuXG5cdFx0XHRmb3IgKGV2ZW50VHlwZSBpbiBldmVudHMpIHtcblx0XHRcdFx0YWRkRXZlbnQocG9pbnQsIGV2ZW50VHlwZSwgZXZlbnRzW2V2ZW50VHlwZV0pO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5oYXNJbXBvcnRlZEV2ZW50cyA9IHRydWU7XG5cblx0XHR9XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNldCB0aGUgcG9pbnQncyBzdGF0ZVxuXHQgKiBAcGFyYW0ge1N0cmluZ30gc3RhdGVcblx0ICovXG5cdHNldFN0YXRlOiBmdW5jdGlvbiAoc3RhdGUsIG1vdmUpIHtcblx0XHR2YXIgcG9pbnQgPSB0aGlzLFxuXHRcdFx0cGxvdFggPSBwb2ludC5wbG90WCxcblx0XHRcdHBsb3RZID0gcG9pbnQucGxvdFksXG5cdFx0XHRzZXJpZXMgPSBwb2ludC5zZXJpZXMsXG5cdFx0XHRzdGF0ZU9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucy5zdGF0ZXMsXG5cdFx0XHRtYXJrZXJPcHRpb25zID0gZGVmYXVsdFBsb3RPcHRpb25zW3Nlcmllcy50eXBlXS5tYXJrZXIgJiYgc2VyaWVzLm9wdGlvbnMubWFya2VyLFxuXHRcdFx0bm9ybWFsRGlzYWJsZWQgPSBtYXJrZXJPcHRpb25zICYmICFtYXJrZXJPcHRpb25zLmVuYWJsZWQsXG5cdFx0XHRtYXJrZXJTdGF0ZU9wdGlvbnMgPSBtYXJrZXJPcHRpb25zICYmIG1hcmtlck9wdGlvbnMuc3RhdGVzW3N0YXRlXSxcblx0XHRcdHN0YXRlRGlzYWJsZWQgPSBtYXJrZXJTdGF0ZU9wdGlvbnMgJiYgbWFya2VyU3RhdGVPcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlLFxuXHRcdFx0c3RhdGVNYXJrZXJHcmFwaGljID0gc2VyaWVzLnN0YXRlTWFya2VyR3JhcGhpYyxcblx0XHRcdHBvaW50TWFya2VyID0gcG9pbnQubWFya2VyIHx8IHt9LFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRyYWRpdXMsXG5cdFx0XHRoYWxvID0gc2VyaWVzLmhhbG8sXG5cdFx0XHRoYWxvT3B0aW9ucyxcblx0XHRcdG5ld1N5bWJvbCxcblx0XHRcdHBvaW50QXR0cjtcblxuXHRcdHN0YXRlID0gc3RhdGUgfHwgTk9STUFMX1NUQVRFOyAvLyBlbXB0eSBzdHJpbmdcblx0XHRwb2ludEF0dHIgPSBwb2ludC5wb2ludEF0dHJbc3RhdGVdIHx8IHNlcmllcy5wb2ludEF0dHJbc3RhdGVdO1xuXG5cdFx0aWYgKFxuXHRcdFx0XHQvLyBhbHJlYWR5IGhhcyB0aGlzIHN0YXRlXG5cdFx0XHRcdChzdGF0ZSA9PT0gcG9pbnQuc3RhdGUgJiYgIW1vdmUpIHx8XG5cdFx0XHRcdC8vIHNlbGVjdGVkIHBvaW50cyBkb24ndCByZXNwb25kIHRvIGhvdmVyXG5cdFx0XHRcdChwb2ludC5zZWxlY3RlZCAmJiBzdGF0ZSAhPT0gU0VMRUNUX1NUQVRFKSB8fFxuXHRcdFx0XHQvLyBzZXJpZXMnIHN0YXRlIG9wdGlvbnMgaXMgZGlzYWJsZWRcblx0XHRcdFx0KHN0YXRlT3B0aW9uc1tzdGF0ZV0gJiYgc3RhdGVPcHRpb25zW3N0YXRlXS5lbmFibGVkID09PSBmYWxzZSkgfHxcblx0XHRcdFx0Ly8gZ2VuZXJhbCBwb2ludCBtYXJrZXIncyBzdGF0ZSBvcHRpb25zIGlzIGRpc2FibGVkXG5cdFx0XHRcdChzdGF0ZSAmJiAoc3RhdGVEaXNhYmxlZCB8fCAobm9ybWFsRGlzYWJsZWQgJiYgbWFya2VyU3RhdGVPcHRpb25zLmVuYWJsZWQgPT09IGZhbHNlKSkpIHx8XG5cdFx0XHRcdC8vIGluZGl2aWR1YWwgcG9pbnQgbWFya2VyJ3Mgc3RhdGUgb3B0aW9ucyBpcyBkaXNhYmxlZFxuXHRcdFx0XHQoc3RhdGUgJiYgcG9pbnRNYXJrZXIuc3RhdGVzICYmIHBvaW50TWFya2VyLnN0YXRlc1tzdGF0ZV0gJiYgcG9pbnRNYXJrZXIuc3RhdGVzW3N0YXRlXS5lbmFibGVkID09PSBmYWxzZSkgLy8gIzE2MTBcblxuXHRcdFx0KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gYXBwbHkgaG92ZXIgc3R5bGVzIHRvIHRoZSBleGlzdGluZyBwb2ludFxuXHRcdGlmIChwb2ludC5ncmFwaGljKSB7XG5cdFx0XHRyYWRpdXMgPSBtYXJrZXJPcHRpb25zICYmIHBvaW50LmdyYXBoaWMuc3ltYm9sTmFtZSAmJiBwb2ludEF0dHIucjtcblx0XHRcdHBvaW50LmdyYXBoaWMuYXR0cihtZXJnZShcblx0XHRcdFx0cG9pbnRBdHRyLFxuXHRcdFx0XHRyYWRpdXMgPyB7IC8vIG5ldyBzeW1ib2wgYXR0cmlidXRlcyAoIzUwNywgIzYxMilcblx0XHRcdFx0XHR4OiBwbG90WCAtIHJhZGl1cyxcblx0XHRcdFx0XHR5OiBwbG90WSAtIHJhZGl1cyxcblx0XHRcdFx0XHR3aWR0aDogMiAqIHJhZGl1cyxcblx0XHRcdFx0XHRoZWlnaHQ6IDIgKiByYWRpdXNcblx0XHRcdFx0fSA6IHt9XG5cdFx0XHQpKTtcblxuXHRcdFx0Ly8gWm9vbWluZyBpbiBmcm9tIGEgcmFuZ2Ugd2l0aCBubyBtYXJrZXJzIHRvIGEgcmFuZ2Ugd2l0aCBtYXJrZXJzXG5cdFx0XHRpZiAoc3RhdGVNYXJrZXJHcmFwaGljKSB7XG5cdFx0XHRcdHN0YXRlTWFya2VyR3JhcGhpYy5oaWRlKCk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGlmIGEgZ3JhcGhpYyBpcyBub3QgYXBwbGllZCB0byBlYWNoIHBvaW50IGluIHRoZSBub3JtYWwgc3RhdGUsIGNyZWF0ZSBhIHNoYXJlZFxuXHRcdFx0Ly8gZ3JhcGhpYyBmb3IgdGhlIGhvdmVyIHN0YXRlXG5cdFx0XHRpZiAoc3RhdGUgJiYgbWFya2VyU3RhdGVPcHRpb25zKSB7XG5cdFx0XHRcdHJhZGl1cyA9IG1hcmtlclN0YXRlT3B0aW9ucy5yYWRpdXM7XG5cdFx0XHRcdG5ld1N5bWJvbCA9IHBvaW50TWFya2VyLnN5bWJvbCB8fCBzZXJpZXMuc3ltYm9sO1xuXG5cdFx0XHRcdC8vIElmIHRoZSBwb2ludCBoYXMgYW5vdGhlciBzeW1ib2wgdGhhbiB0aGUgcHJldmlvdXMgb25lLCB0aHJvdyBhd2F5IHRoZVxuXHRcdFx0XHQvLyBzdGF0ZSBtYXJrZXIgZ3JhcGhpYyBhbmQgZm9yY2UgYSBuZXcgb25lICgjMTQ1OSlcblx0XHRcdFx0aWYgKHN0YXRlTWFya2VyR3JhcGhpYyAmJiBzdGF0ZU1hcmtlckdyYXBoaWMuY3VycmVudFN5bWJvbCAhPT0gbmV3U3ltYm9sKSB7XG5cdFx0XHRcdFx0c3RhdGVNYXJrZXJHcmFwaGljID0gc3RhdGVNYXJrZXJHcmFwaGljLmRlc3Ryb3koKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFkZCBhIG5ldyBzdGF0ZSBtYXJrZXIgZ3JhcGhpY1xuXHRcdFx0XHRpZiAoIXN0YXRlTWFya2VyR3JhcGhpYykge1xuXHRcdFx0XHRcdGlmIChuZXdTeW1ib2wpIHtcblx0XHRcdFx0XHRcdHNlcmllcy5zdGF0ZU1hcmtlckdyYXBoaWMgPSBzdGF0ZU1hcmtlckdyYXBoaWMgPSBjaGFydC5yZW5kZXJlci5zeW1ib2woXG5cdFx0XHRcdFx0XHRcdG5ld1N5bWJvbCxcblx0XHRcdFx0XHRcdFx0cGxvdFggLSByYWRpdXMsXG5cdFx0XHRcdFx0XHRcdHBsb3RZIC0gcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHQyICogcmFkaXVzLFxuXHRcdFx0XHRcdFx0XHQyICogcmFkaXVzXG5cdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQuYXR0cihwb2ludEF0dHIpXG5cdFx0XHRcdFx0XHQuYWRkKHNlcmllcy5tYXJrZXJHcm91cCk7XG5cdFx0XHRcdFx0XHRzdGF0ZU1hcmtlckdyYXBoaWMuY3VycmVudFN5bWJvbCA9IG5ld1N5bWJvbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTW92ZSB0aGUgZXhpc3RpbmcgZ3JhcGhpY1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0YXRlTWFya2VyR3JhcGhpY1ttb3ZlID8gJ2FuaW1hdGUnIDogJ2F0dHInXSh7IC8vICMxMDU0XG5cdFx0XHRcdFx0XHR4OiBwbG90WCAtIHJhZGl1cyxcblx0XHRcdFx0XHRcdHk6IHBsb3RZIC0gcmFkaXVzXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKHN0YXRlTWFya2VyR3JhcGhpYykge1xuXHRcdFx0XHRzdGF0ZU1hcmtlckdyYXBoaWNbc3RhdGUgJiYgY2hhcnQuaXNJbnNpZGVQbG90KHBsb3RYLCBwbG90WSwgY2hhcnQuaW52ZXJ0ZWQpID8gJ3Nob3cnIDogJ2hpZGUnXSgpOyAvLyAjMjQ1MFxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNob3cgbWUgeW91ciBoYWxvXG5cdFx0aGFsb09wdGlvbnMgPSBzdGF0ZU9wdGlvbnNbc3RhdGVdICYmIHN0YXRlT3B0aW9uc1tzdGF0ZV0uaGFsbztcblx0XHRpZiAoaGFsb09wdGlvbnMgJiYgaGFsb09wdGlvbnMuc2l6ZSkge1xuXHRcdFx0aWYgKCFoYWxvKSB7XG5cdFx0XHRcdHNlcmllcy5oYWxvID0gaGFsbyA9IGNoYXJ0LnJlbmRlcmVyLnBhdGgoKVxuXHRcdFx0XHRcdC5hZGQoc2VyaWVzLnNlcmllc0dyb3VwKTtcblx0XHRcdH1cblx0XHRcdGhhbG8uYXR0cihleHRlbmQoe1xuXHRcdFx0XHRmaWxsOiBDb2xvcihwb2ludC5jb2xvciB8fCBzZXJpZXMuY29sb3IpLnNldE9wYWNpdHkoaGFsb09wdGlvbnMub3BhY2l0eSkuZ2V0KClcblx0XHRcdH0sIGhhbG9PcHRpb25zLmF0dHJpYnV0ZXMpKVttb3ZlID8gJ2FuaW1hdGUnIDogJ2F0dHInXSh7XG5cdFx0XHRcdGQ6IHBvaW50LmhhbG9QYXRoKGhhbG9PcHRpb25zLnNpemUpXG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgaWYgKGhhbG8pIHtcblx0XHRcdGhhbG8uYXR0cih7IGQ6IFtdIH0pO1xuXHRcdH1cblxuXHRcdHBvaW50LnN0YXRlID0gc3RhdGU7XG5cdH0sXG5cblx0aGFsb1BhdGg6IGZ1bmN0aW9uIChzaXplKSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMuc2VyaWVzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRwbG90Qm94ID0gc2VyaWVzLmdldFBsb3RCb3goKSxcblx0XHRcdGludmVydGVkID0gY2hhcnQuaW52ZXJ0ZWQ7XG5cblx0XHRyZXR1cm4gY2hhcnQucmVuZGVyZXIuc3ltYm9scy5jaXJjbGUoXG5cdFx0XHRwbG90Qm94LnRyYW5zbGF0ZVggKyAoaW52ZXJ0ZWQgPyBzZXJpZXMueUF4aXMubGVuIC0gdGhpcy5wbG90WSA6IHRoaXMucGxvdFgpIC0gc2l6ZSwgXG5cdFx0XHRwbG90Qm94LnRyYW5zbGF0ZVkgKyAoaW52ZXJ0ZWQgPyBzZXJpZXMueEF4aXMubGVuIC0gdGhpcy5wbG90WCA6IHRoaXMucGxvdFkpIC0gc2l6ZSwgXG5cdFx0XHRzaXplICogMiwgXG5cdFx0XHRzaXplICogMlxuXHRcdCk7XG5cdH1cbn0pO1xuXG4vKlxuICogRXh0ZW5kIHRoZSBTZXJpZXMgb2JqZWN0IHdpdGggaW50ZXJhY3Rpb25cbiAqL1xuXG5leHRlbmQoU2VyaWVzLnByb3RvdHlwZSwge1xuXHQvKipcblx0ICogU2VyaWVzIG1vdXNlIG92ZXIgaGFuZGxlclxuXHQgKi9cblx0b25Nb3VzZU92ZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdGNoYXJ0ID0gc2VyaWVzLmNoYXJ0LFxuXHRcdFx0aG92ZXJTZXJpZXMgPSBjaGFydC5ob3ZlclNlcmllcztcblxuXHRcdC8vIHNldCBub3JtYWwgc3RhdGUgdG8gcHJldmlvdXMgc2VyaWVzXG5cdFx0aWYgKGhvdmVyU2VyaWVzICYmIGhvdmVyU2VyaWVzICE9PSBzZXJpZXMpIHtcblx0XHRcdGhvdmVyU2VyaWVzLm9uTW91c2VPdXQoKTtcblx0XHR9XG5cblx0XHQvLyB0cmlnZ2VyIHRoZSBldmVudCwgYnV0IHRvIHNhdmUgcHJvY2Vzc2luZyB0aW1lLFxuXHRcdC8vIG9ubHkgaWYgZGVmaW5lZFxuXHRcdGlmIChzZXJpZXMub3B0aW9ucy5ldmVudHMubW91c2VPdmVyKSB7XG5cdFx0XHRmaXJlRXZlbnQoc2VyaWVzLCAnbW91c2VPdmVyJyk7XG5cdFx0fVxuXG5cdFx0Ly8gaG92ZXIgdGhpc1xuXHRcdHNlcmllcy5zZXRTdGF0ZShIT1ZFUl9TVEFURSk7XG5cdFx0Y2hhcnQuaG92ZXJTZXJpZXMgPSBzZXJpZXM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNlcmllcyBtb3VzZSBvdXQgaGFuZGxlclxuXHQgKi9cblx0b25Nb3VzZU91dDogZnVuY3Rpb24gKCkge1xuXHRcdC8vIHRyaWdnZXIgdGhlIGV2ZW50IG9ubHkgaWYgbGlzdGVuZXJzIGV4aXN0XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRvcHRpb25zID0gc2VyaWVzLm9wdGlvbnMsXG5cdFx0XHRjaGFydCA9IHNlcmllcy5jaGFydCxcblx0XHRcdHRvb2x0aXAgPSBjaGFydC50b29sdGlwLFxuXHRcdFx0aG92ZXJQb2ludCA9IGNoYXJ0LmhvdmVyUG9pbnQ7XG5cblx0XHQvLyB0cmlnZ2VyIG1vdXNlIG91dCBvbiB0aGUgcG9pbnQsIHdoaWNoIG11c3QgYmUgaW4gdGhpcyBzZXJpZXNcblx0XHRpZiAoaG92ZXJQb2ludCkge1xuXHRcdFx0aG92ZXJQb2ludC5vbk1vdXNlT3V0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gZmlyZSB0aGUgbW91c2Ugb3V0IGV2ZW50XG5cdFx0aWYgKHNlcmllcyAmJiBvcHRpb25zLmV2ZW50cy5tb3VzZU91dCkge1xuXHRcdFx0ZmlyZUV2ZW50KHNlcmllcywgJ21vdXNlT3V0Jyk7XG5cdFx0fVxuXG5cblx0XHQvLyBoaWRlIHRoZSB0b29sdGlwXG5cdFx0aWYgKHRvb2x0aXAgJiYgIW9wdGlvbnMuc3RpY2t5VHJhY2tpbmcgJiYgKCF0b29sdGlwLnNoYXJlZCB8fCBzZXJpZXMubm9TaGFyZWRUb29sdGlwKSkge1xuXHRcdFx0dG9vbHRpcC5oaWRlKCk7XG5cdFx0fVxuXG5cdFx0Ly8gc2V0IG5vcm1hbCBzdGF0ZVxuXHRcdHNlcmllcy5zZXRTdGF0ZSgpO1xuXHRcdGNoYXJ0LmhvdmVyU2VyaWVzID0gbnVsbDtcblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSBzdGF0ZSBvZiB0aGUgZ3JhcGhcblx0ICovXG5cdHNldFN0YXRlOiBmdW5jdGlvbiAoc3RhdGUpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcyxcblx0XHRcdG9wdGlvbnMgPSBzZXJpZXMub3B0aW9ucyxcblx0XHRcdGdyYXBoID0gc2VyaWVzLmdyYXBoLFxuXHRcdFx0Z3JhcGhOZWcgPSBzZXJpZXMuZ3JhcGhOZWcsXG5cdFx0XHRzdGF0ZU9wdGlvbnMgPSBvcHRpb25zLnN0YXRlcyxcblx0XHRcdGxpbmVXaWR0aCA9IG9wdGlvbnMubGluZVdpZHRoLFxuXHRcdFx0YXR0cmlicztcblxuXHRcdHN0YXRlID0gc3RhdGUgfHwgTk9STUFMX1NUQVRFO1xuXG5cdFx0aWYgKHNlcmllcy5zdGF0ZSAhPT0gc3RhdGUpIHtcblx0XHRcdHNlcmllcy5zdGF0ZSA9IHN0YXRlO1xuXG5cdFx0XHRpZiAoc3RhdGVPcHRpb25zW3N0YXRlXSAmJiBzdGF0ZU9wdGlvbnNbc3RhdGVdLmVuYWJsZWQgPT09IGZhbHNlKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHN0YXRlKSB7XG5cdFx0XHRcdGxpbmVXaWR0aCA9IHN0YXRlT3B0aW9uc1tzdGF0ZV0ubGluZVdpZHRoIHx8IGxpbmVXaWR0aCArIChzdGF0ZU9wdGlvbnNbc3RhdGVdLmxpbmVXaWR0aFBsdXMgfHwgMCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChncmFwaCAmJiAhZ3JhcGguZGFzaHN0eWxlKSB7IC8vIGhvdmVyIGlzIHR1cm5lZCBvZmYgZm9yIGRhc2hlZCBsaW5lcyBpbiBWTUxcblx0XHRcdFx0YXR0cmlicyA9IHtcblx0XHRcdFx0XHQnc3Ryb2tlLXdpZHRoJzogbGluZVdpZHRoXG5cdFx0XHRcdH07XG5cdFx0XHRcdC8vIHVzZSBhdHRyIGJlY2F1c2UgYW5pbWF0ZSB3aWxsIGNhdXNlIGFueSBvdGhlciBhbmltYXRpb24gb24gdGhlIGdyYXBoIHRvIHN0b3Bcblx0XHRcdFx0Z3JhcGguYXR0cihhdHRyaWJzKTtcblx0XHRcdFx0aWYgKGdyYXBoTmVnKSB7XG5cdFx0XHRcdFx0Z3JhcGhOZWcuYXR0cihhdHRyaWJzKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvKipcblx0ICogU2V0IHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBncmFwaFxuXHQgKlxuXHQgKiBAcGFyYW0gdmlzIHtCb29sZWFufSBUcnVlIHRvIHNob3cgdGhlIHNlcmllcywgZmFsc2UgdG8gaGlkZS4gSWYgVU5ERUZJTkVELFxuXHQgKlx0XHRcdFx0dGhlIHZpc2liaWxpdHkgaXMgdG9nZ2xlZC5cblx0ICovXG5cdHNldFZpc2libGU6IGZ1bmN0aW9uICh2aXMsIHJlZHJhdykge1xuXHRcdHZhciBzZXJpZXMgPSB0aGlzLFxuXHRcdFx0Y2hhcnQgPSBzZXJpZXMuY2hhcnQsXG5cdFx0XHRsZWdlbmRJdGVtID0gc2VyaWVzLmxlZ2VuZEl0ZW0sXG5cdFx0XHRzaG93T3JIaWRlLFxuXHRcdFx0aWdub3JlSGlkZGVuU2VyaWVzID0gY2hhcnQub3B0aW9ucy5jaGFydC5pZ25vcmVIaWRkZW5TZXJpZXMsXG5cdFx0XHRvbGRWaXNpYmlsaXR5ID0gc2VyaWVzLnZpc2libGU7XG5cblx0XHQvLyBpZiBjYWxsZWQgd2l0aG91dCBhbiBhcmd1bWVudCwgdG9nZ2xlIHZpc2liaWxpdHlcblx0XHRzZXJpZXMudmlzaWJsZSA9IHZpcyA9IHNlcmllcy51c2VyT3B0aW9ucy52aXNpYmxlID0gdmlzID09PSBVTkRFRklORUQgPyAhb2xkVmlzaWJpbGl0eSA6IHZpcztcblx0XHRzaG93T3JIaWRlID0gdmlzID8gJ3Nob3cnIDogJ2hpZGUnO1xuXG5cdFx0Ly8gc2hvdyBvciBoaWRlIGVsZW1lbnRzXG5cdFx0ZWFjaChbJ2dyb3VwJywgJ2RhdGFMYWJlbHNHcm91cCcsICdtYXJrZXJHcm91cCcsICd0cmFja2VyJ10sIGZ1bmN0aW9uIChrZXkpIHtcblx0XHRcdGlmIChzZXJpZXNba2V5XSkge1xuXHRcdFx0XHRzZXJpZXNba2V5XVtzaG93T3JIaWRlXSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cblx0XHQvLyBoaWRlIHRvb2x0aXAgKCMxMzYxKVxuXHRcdGlmIChjaGFydC5ob3ZlclNlcmllcyA9PT0gc2VyaWVzKSB7XG5cdFx0XHRzZXJpZXMub25Nb3VzZU91dCgpO1xuXHRcdH1cblxuXG5cdFx0aWYgKGxlZ2VuZEl0ZW0pIHtcblx0XHRcdGNoYXJ0LmxlZ2VuZC5jb2xvcml6ZUl0ZW0oc2VyaWVzLCB2aXMpO1xuXHRcdH1cblxuXG5cdFx0Ly8gcmVzY2FsZSBvciBhZGFwdCB0byByZXNpemVkIGNoYXJ0XG5cdFx0c2VyaWVzLmlzRGlydHkgPSB0cnVlO1xuXHRcdC8vIGluIGEgc3RhY2ssIGFsbCBvdGhlciBzZXJpZXMgYXJlIGFmZmVjdGVkXG5cdFx0aWYgKHNlcmllcy5vcHRpb25zLnN0YWNraW5nKSB7XG5cdFx0XHRlYWNoKGNoYXJ0LnNlcmllcywgZnVuY3Rpb24gKG90aGVyU2VyaWVzKSB7XG5cdFx0XHRcdGlmIChvdGhlclNlcmllcy5vcHRpb25zLnN0YWNraW5nICYmIG90aGVyU2VyaWVzLnZpc2libGUpIHtcblx0XHRcdFx0XHRvdGhlclNlcmllcy5pc0RpcnR5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0Ly8gc2hvdyBvciBoaWRlIGxpbmtlZCBzZXJpZXNcblx0XHRlYWNoKHNlcmllcy5saW5rZWRTZXJpZXMsIGZ1bmN0aW9uIChvdGhlclNlcmllcykge1xuXHRcdFx0b3RoZXJTZXJpZXMuc2V0VmlzaWJsZSh2aXMsIGZhbHNlKTtcblx0XHR9KTtcblxuXHRcdGlmIChpZ25vcmVIaWRkZW5TZXJpZXMpIHtcblx0XHRcdGNoYXJ0LmlzRGlydHlCb3ggPSB0cnVlO1xuXHRcdH1cblx0XHRpZiAocmVkcmF3ICE9PSBmYWxzZSkge1xuXHRcdFx0Y2hhcnQucmVkcmF3KCk7XG5cdFx0fVxuXG5cdFx0ZmlyZUV2ZW50KHNlcmllcywgc2hvd09ySGlkZSk7XG5cdH0sXG5cblx0LyoqXG5cdCAqIE1lbW9yaXplIHRvb2x0aXAgdGV4dHMgYW5kIHBvc2l0aW9uc1xuXHQgKi9cblx0c2V0VG9vbHRpcFBvaW50czogZnVuY3Rpb24gKHJlbmV3KSB7XG5cdFx0dmFyIHNlcmllcyA9IHRoaXMsXG5cdFx0XHRwb2ludHMgPSBbXSxcblx0XHRcdHBvaW50c0xlbmd0aCxcblx0XHRcdGxvdyxcblx0XHRcdGhpZ2gsXG5cdFx0XHR4QXhpcyA9IHNlcmllcy54QXhpcyxcblx0XHRcdHhFeHRyZW1lcyA9IHhBeGlzICYmIHhBeGlzLmdldEV4dHJlbWVzKCksXG5cdFx0XHRheGlzTGVuZ3RoID0geEF4aXMgPyAoeEF4aXMudG9vbHRpcExlbiB8fCB4QXhpcy5sZW4pIDogc2VyaWVzLmNoYXJ0LnBsb3RTaXplWCwgLy8gdG9vbHRpcExlbiBhbmQgdG9vbHRpcFBvc05hbWUgdXNlZCBpbiBwb2xhclxuXHRcdFx0cG9pbnQsXG5cdFx0XHRwb2ludFgsXG5cdFx0XHRuZXh0UG9pbnQsXG5cdFx0XHRpLFxuXHRcdFx0dG9vbHRpcFBvaW50cyA9IFtdOyAvLyBhIGxvb2t1cCBhcnJheSBmb3IgZWFjaCBwaXhlbCBpbiB0aGUgeCBkaW1lbnNpb25cblxuXHRcdC8vIGRvbid0IHdhc3RlIHJlc291cmNlcyBpZiB0cmFja2VyIGlzIGRpc2FibGVkXG5cdFx0aWYgKHNlcmllcy5vcHRpb25zLmVuYWJsZU1vdXNlVHJhY2tpbmcgPT09IGZhbHNlIHx8IHNlcmllcy5zaW5ndWxhclRvb2x0aXBzKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gcmVuZXdcblx0XHRpZiAocmVuZXcpIHtcblx0XHRcdHNlcmllcy50b29sdGlwUG9pbnRzID0gbnVsbDtcblx0XHR9XG5cblx0XHQvLyBjb25jYXQgc2VnbWVudHMgdG8gb3ZlcmNvbWUgbnVsbCB2YWx1ZXNcblx0XHRlYWNoKHNlcmllcy5zZWdtZW50cyB8fCBzZXJpZXMucG9pbnRzLCBmdW5jdGlvbiAoc2VnbWVudCkge1xuXHRcdFx0cG9pbnRzID0gcG9pbnRzLmNvbmNhdChzZWdtZW50KTtcblx0XHR9KTtcblxuXHRcdC8vIFJldmVyc2UgdGhlIHBvaW50cyBpbiBjYXNlIHRoZSBYIGF4aXMgaXMgcmV2ZXJzZWRcblx0XHRpZiAoeEF4aXMgJiYgeEF4aXMucmV2ZXJzZWQpIHtcblx0XHRcdHBvaW50cyA9IHBvaW50cy5yZXZlcnNlKCk7XG5cdFx0fVxuXG5cdFx0Ly8gUG9sYXIgbmVlZHMgYWRkaXRpb25hbCBzaGFwaW5nXG5cdFx0aWYgKHNlcmllcy5vcmRlclRvb2x0aXBQb2ludHMpIHtcblx0XHRcdHNlcmllcy5vcmRlclRvb2x0aXBQb2ludHMocG9pbnRzKTtcblx0XHR9XG5cblx0XHQvLyBBc3NpZ24gZWFjaCBwaXhlbCBwb3NpdGlvbiB0byB0aGUgbmVhcmVzdCBwb2ludFxuXHRcdHBvaW50c0xlbmd0aCA9IHBvaW50cy5sZW5ndGg7XG5cdFx0Zm9yIChpID0gMDsgaSA8IHBvaW50c0xlbmd0aDsgaSsrKSB7XG5cdFx0XHRwb2ludCA9IHBvaW50c1tpXTtcblx0XHRcdHBvaW50WCA9IHBvaW50Lng7XG5cdFx0XHRpZiAocG9pbnRYID49IHhFeHRyZW1lcy5taW4gJiYgcG9pbnRYIDw9IHhFeHRyZW1lcy5tYXgpIHsgLy8gIzExNDlcblx0XHRcdFx0bmV4dFBvaW50ID0gcG9pbnRzW2kgKyAxXTtcblxuXHRcdFx0XHQvLyBTZXQgdGhpcyByYW5nZSdzIGxvdyB0byB0aGUgbGFzdCByYW5nZSdzIGhpZ2ggcGx1cyBvbmVcblx0XHRcdFx0bG93ID0gaGlnaCA9PT0gVU5ERUZJTkVEID8gMCA6IGhpZ2ggKyAxO1xuXHRcdFx0XHQvLyBOb3cgZmluZCB0aGUgbmV3IGhpZ2hcblx0XHRcdFx0aGlnaCA9IHBvaW50c1tpICsgMV0gP1xuXHRcdFx0XHRcdG1hdGhNaW4obWF0aE1heCgwLCBtYXRoRmxvb3IoIC8vICMyMDcwXG5cdFx0XHRcdFx0XHQocG9pbnQuY2xpZW50WCArIChuZXh0UG9pbnQgPyAobmV4dFBvaW50LndyYXBwZWRDbGllbnRYIHx8IG5leHRQb2ludC5jbGllbnRYKSA6IGF4aXNMZW5ndGgpKSAvIDJcblx0XHRcdFx0XHQpKSwgYXhpc0xlbmd0aCkgOlxuXHRcdFx0XHRcdGF4aXNMZW5ndGg7XG5cblx0XHRcdFx0d2hpbGUgKGxvdyA+PSAwICYmIGxvdyA8PSBoaWdoKSB7XG5cdFx0XHRcdFx0dG9vbHRpcFBvaW50c1tsb3crK10gPSBwb2ludDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRzZXJpZXMudG9vbHRpcFBvaW50cyA9IHRvb2x0aXBQb2ludHM7XG5cdH0sXG5cblx0LyoqXG5cdCAqIFNob3cgdGhlIGdyYXBoXG5cdCAqL1xuXHRzaG93OiBmdW5jdGlvbiAoKSB7XG5cdFx0dGhpcy5zZXRWaXNpYmxlKHRydWUpO1xuXHR9LFxuXG5cdC8qKlxuXHQgKiBIaWRlIHRoZSBncmFwaFxuXHQgKi9cblx0aGlkZTogZnVuY3Rpb24gKCkge1xuXHRcdHRoaXMuc2V0VmlzaWJsZShmYWxzZSk7XG5cdH0sXG5cblxuXHQvKipcblx0ICogU2V0IHRoZSBzZWxlY3RlZCBzdGF0ZSBvZiB0aGUgZ3JhcGhcblx0ICpcblx0ICogQHBhcmFtIHNlbGVjdGVkIHtCb29sZWFufSBUcnVlIHRvIHNlbGVjdCB0aGUgc2VyaWVzLCBmYWxzZSB0byB1bnNlbGVjdC4gSWZcblx0ICpcdFx0XHRcdFVOREVGSU5FRCwgdGhlIHNlbGVjdGlvbiBzdGF0ZSBpcyB0b2dnbGVkLlxuXHQgKi9cblx0c2VsZWN0OiBmdW5jdGlvbiAoc2VsZWN0ZWQpIHtcblx0XHR2YXIgc2VyaWVzID0gdGhpcztcblx0XHQvLyBpZiBjYWxsZWQgd2l0aG91dCBhbiBhcmd1bWVudCwgdG9nZ2xlXG5cdFx0c2VyaWVzLnNlbGVjdGVkID0gc2VsZWN0ZWQgPSAoc2VsZWN0ZWQgPT09IFVOREVGSU5FRCkgPyAhc2VyaWVzLnNlbGVjdGVkIDogc2VsZWN0ZWQ7XG5cblx0XHRpZiAoc2VyaWVzLmNoZWNrYm94KSB7XG5cdFx0XHRzZXJpZXMuY2hlY2tib3guY2hlY2tlZCA9IHNlbGVjdGVkO1xuXHRcdH1cblxuXHRcdGZpcmVFdmVudChzZXJpZXMsIHNlbGVjdGVkID8gJ3NlbGVjdCcgOiAndW5zZWxlY3QnKTtcblx0fSxcblxuXHRkcmF3VHJhY2tlcjogVHJhY2tlck1peGluLmRyYXdUcmFja2VyR3JhcGhcbn0pO1xuLy8gZ2xvYmFsIHZhcmlhYmxlc1xuZXh0ZW5kKEhpZ2hjaGFydHMsIHtcblx0XG5cdC8vIENvbnN0cnVjdG9yc1xuXHRBeGlzOiBBeGlzLFxuXHRDaGFydDogQ2hhcnQsXG5cdENvbG9yOiBDb2xvcixcblx0UG9pbnQ6IFBvaW50LFxuXHRUaWNrOiBUaWNrLFx0XG5cdFJlbmRlcmVyOiBSZW5kZXJlcixcblx0U2VyaWVzOiBTZXJpZXMsXG5cdFNWR0VsZW1lbnQ6IFNWR0VsZW1lbnQsXG5cdFNWR1JlbmRlcmVyOiBTVkdSZW5kZXJlcixcblx0XG5cdC8vIFZhcmlvdXNcblx0YXJyYXlNaW46IGFycmF5TWluLFxuXHRhcnJheU1heDogYXJyYXlNYXgsXG5cdGNoYXJ0czogY2hhcnRzLFxuXHRkYXRlRm9ybWF0OiBkYXRlRm9ybWF0LFxuXHRmb3JtYXQ6IGZvcm1hdCxcblx0cGF0aEFuaW06IHBhdGhBbmltLFxuXHRnZXRPcHRpb25zOiBnZXRPcHRpb25zLFxuXHRoYXNCaWRpQnVnOiBoYXNCaWRpQnVnLFxuXHRpc1RvdWNoRGV2aWNlOiBpc1RvdWNoRGV2aWNlLFxuXHRudW1iZXJGb3JtYXQ6IG51bWJlckZvcm1hdCxcblx0c2VyaWVzVHlwZXM6IHNlcmllc1R5cGVzLFxuXHRzZXRPcHRpb25zOiBzZXRPcHRpb25zLFxuXHRhZGRFdmVudDogYWRkRXZlbnQsXG5cdHJlbW92ZUV2ZW50OiByZW1vdmVFdmVudCxcblx0Y3JlYXRlRWxlbWVudDogY3JlYXRlRWxlbWVudCxcblx0ZGlzY2FyZEVsZW1lbnQ6IGRpc2NhcmRFbGVtZW50LFxuXHRjc3M6IGNzcyxcblx0ZWFjaDogZWFjaCxcblx0ZXh0ZW5kOiBleHRlbmQsXG5cdG1hcDogbWFwLFxuXHRtZXJnZTogbWVyZ2UsXG5cdHBpY2s6IHBpY2ssXG5cdHNwbGF0OiBzcGxhdCxcblx0ZXh0ZW5kQ2xhc3M6IGV4dGVuZENsYXNzLFxuXHRwSW50OiBwSW50LFxuXHR3cmFwOiB3cmFwLFxuXHRzdmc6IGhhc1NWRyxcblx0Y2FudmFzOiB1c2VDYW5WRyxcblx0dm1sOiAhaGFzU1ZHICYmICF1c2VDYW5WRyxcblx0cHJvZHVjdDogUFJPRFVDVCxcblx0dmVyc2lvbjogVkVSU0lPTlxufSk7XG5cbn0oKSk7XG5cbi8qKlxuICogQGxpY2Vuc2UgSGlnaGNoYXJ0cyBKUyB2NC4wLjQgKDIwMTQtMDktMDIpXG4gKlxuICogU3RhbmRhbG9uZSBIaWdoY2hhcnRzIEZyYW1ld29ya1xuICpcbiAqIExpY2Vuc2U6IE1JVCBMaWNlbnNlXG4gKi9cblxuXG4vKmdsb2JhbCBIaWdoY2hhcnRzICovXG52YXIgSGlnaGNoYXJ0c0FkYXB0ZXIgPSAoZnVuY3Rpb24gKCkge1xuXG4gIHZhciBVTkRFRklORUQsXG4gICAgZG9jID0gZG9jdW1lbnQsXG4gICAgZW1wdHlBcnJheSA9IFtdLFxuICAgIHRpbWVycyA9IFtdLFxuICAgIHRpbWVySWQsXG4gICAgYW5pbVNldHRlcnMgPSB7fSxcbiAgICBGeDtcblxuICBNYXRoLmVhc2VJbk91dFNpbmUgPSBmdW5jdGlvbiAodCwgYiwgYywgZCkge1xuICAgIHJldHVybiAtYyAvIDIgKiAoTWF0aC5jb3MoTWF0aC5QSSAqIHQgLyBkKSAtIDEpICsgYjtcbiAgfTtcblxuXG5cbiAgLyoqXG4gICAqIEV4dGVuZCBnaXZlbiBvYmplY3Qgd2l0aCBjdXN0b20gZXZlbnRzXG4gICAqL1xuICBmdW5jdGlvbiBhdWdtZW50KG9iaikge1xuICAgIGZ1bmN0aW9uIHJlbW92ZU9uZUV2ZW50KGVsLCB0eXBlLCBmbikge1xuICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmbiwgZmFsc2UpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIElFUmVtb3ZlT25lRXZlbnQoZWwsIHR5cGUsIGZuKSB7XG4gICAgICBmbiA9IGVsLkhDUHJveGllZE1ldGhvZHNbZm4udG9TdHJpbmcoKV07XG4gICAgICBlbC5kZXRhY2hFdmVudCgnb24nICsgdHlwZSwgZm4pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbEV2ZW50cyhlbCwgdHlwZSkge1xuICAgICAgdmFyIGV2ZW50cyA9IGVsLkhDRXZlbnRzLFxuICAgICAgICByZW1vdmUsXG4gICAgICAgIHR5cGVzLFxuICAgICAgICBsZW4sXG4gICAgICAgIG47XG5cbiAgICAgIGlmIChlbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgIHJlbW92ZSA9IHJlbW92ZU9uZUV2ZW50O1xuICAgICAgfSBlbHNlIGlmIChlbC5hdHRhY2hFdmVudCkge1xuICAgICAgICByZW1vdmUgPSBJRVJlbW92ZU9uZUV2ZW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuOyAvLyBicmVhayBvbiBub24tRE9NIGV2ZW50c1xuICAgICAgfVxuXG5cbiAgICAgIGlmICh0eXBlKSB7XG4gICAgICAgIHR5cGVzID0ge307XG4gICAgICAgIHR5cGVzW3R5cGVdID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHR5cGVzID0gZXZlbnRzO1xuICAgICAgfVxuXG4gICAgICBmb3IgKG4gaW4gdHlwZXMpIHtcbiAgICAgICAgaWYgKGV2ZW50c1tuXSkge1xuICAgICAgICAgIGxlbiA9IGV2ZW50c1tuXS5sZW5ndGg7XG4gICAgICAgICAgd2hpbGUgKGxlbi0tKSB7XG4gICAgICAgICAgICByZW1vdmUoZWwsIG4sIGV2ZW50c1tuXVtsZW5dKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIW9iai5IQ0V4dGVuZGVkKSB7XG4gICAgICBIaWdoY2hhcnRzLmV4dGVuZChvYmosIHtcbiAgICAgICAgSENFeHRlbmRlZDogdHJ1ZSxcblxuICAgICAgICBIQ0V2ZW50czoge30sXG5cbiAgICAgICAgYmluZDogZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgICAgICAgdmFyIGVsID0gdGhpcyxcbiAgICAgICAgICAgIGV2ZW50cyA9IHRoaXMuSENFdmVudHMsXG4gICAgICAgICAgICB3cmFwcGVkRm47XG5cbiAgICAgICAgICAvLyBoYW5kbGUgRE9NIGV2ZW50cyBpbiBtb2Rlcm4gYnJvd3NlcnNcbiAgICAgICAgICBpZiAoZWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihuYW1lLCBmbiwgZmFsc2UpO1xuXG4gICAgICAgICAgICAvLyBoYW5kbGUgb2xkIElFIGltcGxlbWVudGF0aW9uXG4gICAgICAgICAgfSBlbHNlIGlmIChlbC5hdHRhY2hFdmVudCkge1xuXG4gICAgICAgICAgICB3cmFwcGVkRm4gPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICBlLnRhcmdldCA9IGUuc3JjRWxlbWVudCB8fCB3aW5kb3c7IC8vICMyODIwXG4gICAgICAgICAgICAgIGZuLmNhbGwoZWwsIGUpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKCFlbC5IQ1Byb3hpZWRNZXRob2RzKSB7XG4gICAgICAgICAgICAgIGVsLkhDUHJveGllZE1ldGhvZHMgPSB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbGluayB3cmFwcGVkIGZuIHdpdGggb3JpZ2luYWwgZm4sIHNvIHdlIGNhbiBnZXQgdGhpcyBpbiByZW1vdmVFdmVudFxuICAgICAgICAgICAgZWwuSENQcm94aWVkTWV0aG9kc1tmbi50b1N0cmluZygpXSA9IHdyYXBwZWRGbjtcblxuICAgICAgICAgICAgZWwuYXR0YWNoRXZlbnQoJ29uJyArIG5hbWUsIHdyYXBwZWRGbik7XG4gICAgICAgICAgfVxuXG5cbiAgICAgICAgICBpZiAoZXZlbnRzW25hbWVdID09PSBVTkRFRklORUQpIHtcbiAgICAgICAgICAgIGV2ZW50c1tuYW1lXSA9IFtdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGV2ZW50c1tuYW1lXS5wdXNoKGZuKTtcbiAgICAgICAgfSxcblxuICAgICAgICB1bmJpbmQ6IGZ1bmN0aW9uIChuYW1lLCBmbikge1xuICAgICAgICAgIHZhciBldmVudHMsXG4gICAgICAgICAgICBpbmRleDtcblxuICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICBldmVudHMgPSB0aGlzLkhDRXZlbnRzW25hbWVdIHx8IFtdO1xuICAgICAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICAgIGluZGV4ID0gSGlnaGNoYXJ0c0FkYXB0ZXIuaW5BcnJheShmbiwgZXZlbnRzKTtcbiAgICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgICBldmVudHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB0aGlzLkhDRXZlbnRzW25hbWVdID0gZXZlbnRzO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICh0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICByZW1vdmVPbmVFdmVudCh0aGlzLCBuYW1lLCBmbik7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5hdHRhY2hFdmVudCkge1xuICAgICAgICAgICAgICAgIElFUmVtb3ZlT25lRXZlbnQodGhpcywgbmFtZSwgZm4pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZW1vdmVBbGxFdmVudHModGhpcywgbmFtZSk7XG4gICAgICAgICAgICAgIHRoaXMuSENFdmVudHNbbmFtZV0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVtb3ZlQWxsRXZlbnRzKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5IQ0V2ZW50cyA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICB0cmlnZ2VyOiBmdW5jdGlvbiAobmFtZSwgYXJncykge1xuICAgICAgICAgIHZhciBldmVudHMgPSB0aGlzLkhDRXZlbnRzW25hbWVdIHx8IFtdLFxuICAgICAgICAgICAgdGFyZ2V0ID0gdGhpcyxcbiAgICAgICAgICAgIGxlbiA9IGV2ZW50cy5sZW5ndGgsXG4gICAgICAgICAgICBpLFxuICAgICAgICAgICAgcHJldmVudERlZmF1bHQsXG4gICAgICAgICAgICBmbjtcblxuICAgICAgICAgIC8vIEF0dGFjaCBhIHNpbXBsZSBwcmV2ZW50RGVmYXVsdCBmdW5jdGlvbiB0byBza2lwIGRlZmF1bHQgaGFuZGxlciBpZiBjYWxsZWRcbiAgICAgICAgICBwcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGFyZ3MuZGVmYXVsdFByZXZlbnRlZCA9IHRydWU7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgZm4gPSBldmVudHNbaV07XG5cbiAgICAgICAgICAgIC8vIGFyZ3MgaXMgbmV2ZXIgbnVsbCBoZXJlXG4gICAgICAgICAgICBpZiAoYXJncy5zdG9wcGVkKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXJncy5wcmV2ZW50RGVmYXVsdCA9IHByZXZlbnREZWZhdWx0O1xuICAgICAgICAgICAgYXJncy50YXJnZXQgPSB0YXJnZXQ7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZSB0eXBlIGlzIG5vdCBzZXQsIHdlJ3JlIHJ1bm5pbmcgYSBjdXN0b20gZXZlbnQgKCMyMjk3KS4gSWYgaXQgaXMgc2V0LFxuICAgICAgICAgICAgLy8gd2UncmUgcnVubmluZyBhIGJyb3dzZXIgZXZlbnQsIGFuZCBzZXR0aW5nIGl0IHdpbGwgY2F1c2UgZW4gZXJyb3IgaW5cbiAgICAgICAgICAgIC8vIElFOCAoIzI0NjUpLlxuICAgICAgICAgICAgaWYgKCFhcmdzLnR5cGUpIHtcbiAgICAgICAgICAgICAgYXJncy50eXBlID0gbmFtZTtcbiAgICAgICAgICAgIH1cblxuXG5cbiAgICAgICAgICAgIC8vIElmIHRoZSBldmVudCBoYW5kbGVyIHJldHVybiBmYWxzZSwgcHJldmVudCB0aGUgZGVmYXVsdCBoYW5kbGVyIGZyb20gZXhlY3V0aW5nXG4gICAgICAgICAgICBpZiAoZm4uY2FsbCh0aGlzLCBhcmdzKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgYXJncy5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG5cbiAgcmV0dXJuIHtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgdGhlIGFkYXB0ZXIuIFRoaXMgaXMgcnVuIG9uY2UgYXMgSGlnaGNoYXJ0cyBpcyBmaXJzdCBydW4uXG4gICAgICovXG4gICAgaW5pdDogZnVuY3Rpb24gKHBhdGhBbmltKSB7XG5cbiAgICAgIC8qKlxuICAgICAgICogQ29tcGF0aWJpbGl0eSBzZWN0aW9uIHRvIGFkZCBzdXBwb3J0IGZvciBsZWdhY3kgSUUuIFRoaXMgY2FuIGJlIHJlbW92ZWQgaWYgb2xkIElFXG4gICAgICAgKiBzdXBwb3J0IGlzIG5vdCBuZWVkZWQuXG4gICAgICAgKi9cbiAgICAgIGlmICghZG9jLmRlZmF1bHRWaWV3KSB7XG4gICAgICAgIHRoaXMuX2dldFN0eWxlID0gZnVuY3Rpb24gKGVsLCBwcm9wKSB7XG4gICAgICAgICAgdmFyIHZhbDtcbiAgICAgICAgICBpZiAoZWwuc3R5bGVbcHJvcF0pIHtcbiAgICAgICAgICAgIHJldHVybiBlbC5zdHlsZVtwcm9wXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHByb3AgPT09ICdvcGFjaXR5Jykge1xuICAgICAgICAgICAgICBwcm9wID0gJ2ZpbHRlcic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKmpzbGludCB1bnBhcmFtOiB0cnVlKi9cbiAgICAgICAgICAgIHZhbCA9IGVsLmN1cnJlbnRTdHlsZVtwcm9wLnJlcGxhY2UoL1xcLShcXHcpL2csIGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBiLnRvVXBwZXJDYXNlKCk7IH0pXTtcbiAgICAgICAgICAgIGlmIChwcm9wID09PSAnZmlsdGVyJykge1xuICAgICAgICAgICAgICB2YWwgPSB2YWwucmVwbGFjZShcbiAgICAgICAgICAgICAgICAvYWxwaGFcXChvcGFjaXR5PShbMC05XSspXFwpLyxcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGIgLyAxMDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypqc2xpbnQgdW5wYXJhbTogZmFsc2UqL1xuICAgICAgICAgICAgcmV0dXJuIHZhbCA9PT0gJycgPyAxIDogdmFsO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5hZGFwdGVyUnVuID0gZnVuY3Rpb24gKGVsZW0sIG1ldGhvZCkge1xuICAgICAgICAgIHZhciBhbGlhcyA9IHsgd2lkdGg6ICdjbGllbnRXaWR0aCcsIGhlaWdodDogJ2NsaWVudEhlaWdodCcgfVttZXRob2RdO1xuXG4gICAgICAgICAgaWYgKGFsaWFzKSB7XG4gICAgICAgICAgICBlbGVtLnN0eWxlLnpvb20gPSAxO1xuICAgICAgICAgICAgcmV0dXJuIGVsZW1bYWxpYXNdIC0gMiAqIHBhcnNlSW50KEhpZ2hjaGFydHNBZGFwdGVyLl9nZXRTdHlsZShlbGVtLCAncGFkZGluZycpLCAxMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBpZiAoIUFycmF5LnByb3RvdHlwZS5mb3JFYWNoKSB7XG4gICAgICAgIHRoaXMuZWFjaCA9IGZ1bmN0aW9uIChhcnIsIGZuKSB7IC8vIGxlZ2FjeVxuICAgICAgICAgIHZhciBpID0gMCxcbiAgICAgICAgICAgIGxlbiA9IGFyci5sZW5ndGg7XG4gICAgICAgICAgZm9yICg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgaWYgKGZuLmNhbGwoYXJyW2ldLCBhcnJbaV0sIGksIGFycikgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFBcnJheS5wcm90b3R5cGUuaW5kZXhPZikge1xuICAgICAgICB0aGlzLmluQXJyYXkgPSBmdW5jdGlvbiAoaXRlbSwgYXJyKSB7XG4gICAgICAgICAgdmFyIGxlbixcbiAgICAgICAgICAgIGkgPSAwO1xuXG4gICAgICAgICAgaWYgKGFycikge1xuICAgICAgICAgICAgbGVuID0gYXJyLmxlbmd0aDtcblxuICAgICAgICAgICAgZm9yICg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICBpZiAoYXJyW2ldID09PSBpdGVtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGlmICghQXJyYXkucHJvdG90eXBlLmZpbHRlcikge1xuICAgICAgICB0aGlzLmdyZXAgPSBmdW5jdGlvbiAoZWxlbWVudHMsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgdmFyIHJldCA9IFtdLFxuICAgICAgICAgICAgaSA9IDAsXG4gICAgICAgICAgICBsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cbiAgICAgICAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoISFjYWxsYmFjayhlbGVtZW50c1tpXSwgaSkpIHtcbiAgICAgICAgICAgICAgcmV0LnB1c2goZWxlbWVudHNbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIC8vLS0tIEVuZCBjb21wYXRpYmlsaXR5IHNlY3Rpb24gLS0tXG5cblxuICAgICAgLyoqXG4gICAgICAgKiBTdGFydCBvZiBhbmltYXRpb24gc3BlY2lmaWMgY29kZVxuICAgICAgICovXG4gICAgICBGeCA9IGZ1bmN0aW9uIChlbGVtLCBvcHRpb25zLCBwcm9wKSB7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuZWxlbSA9IGVsZW07XG4gICAgICAgIHRoaXMucHJvcCA9IHByb3A7XG4gICAgICB9O1xuICAgICAgRngucHJvdG90eXBlID0ge1xuXG4gICAgICAgIHVwZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzdHlsZXMsXG4gICAgICAgICAgICBwYXRocyA9IHRoaXMucGF0aHMsXG4gICAgICAgICAgICBlbGVtID0gdGhpcy5lbGVtLFxuICAgICAgICAgICAgZWxlbWVsZW0gPSBlbGVtLmVsZW1lbnQ7IC8vIGlmIGRlc3Ryb3llZCwgaXQgaXMgbnVsbFxuXG4gICAgICAgICAgLy8gQW5pbWF0aW9uIHNldHRlciBkZWZpbmVkIGZyb20gb3V0c2lkZVxuICAgICAgICAgIGlmIChhbmltU2V0dGVyc1t0aGlzLnByb3BdKSB7XG4gICAgICAgICAgICBhbmltU2V0dGVyc1t0aGlzLnByb3BdKHRoaXMpO1xuXG4gICAgICAgICAgICAvLyBBbmltYXRpbmcgYSBwYXRoIGRlZmluaXRpb24gb24gU1ZHRWxlbWVudFxuICAgICAgICAgIH0gZWxzZSBpZiAocGF0aHMgJiYgZWxlbWVsZW0pIHtcbiAgICAgICAgICAgIGVsZW0uYXR0cignZCcsIHBhdGhBbmltLnN0ZXAocGF0aHNbMF0sIHBhdGhzWzFdLCB0aGlzLm5vdywgdGhpcy50b0QpKTtcblxuICAgICAgICAgICAgLy8gT3RoZXIgYW5pbWF0aW9ucyBvbiBTVkdFbGVtZW50XG4gICAgICAgICAgfSBlbHNlIGlmIChlbGVtLmF0dHIpIHtcbiAgICAgICAgICAgIGlmIChlbGVtZWxlbSkge1xuICAgICAgICAgICAgICBlbGVtLmF0dHIodGhpcy5wcm9wLCB0aGlzLm5vdyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEhUTUwgc3R5bGVzXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0eWxlcyA9IHt9O1xuICAgICAgICAgICAgc3R5bGVzW3RoaXMucHJvcF0gPSB0aGlzLm5vdyArIHRoaXMudW5pdDtcbiAgICAgICAgICAgIEhpZ2hjaGFydHMuY3NzKGVsZW0sIHN0eWxlcyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zdGVwKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKHRoaXMuZWxlbSwgdGhpcy5ub3csIHRoaXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICB9LFxuICAgICAgICBjdXN0b206IGZ1bmN0aW9uIChmcm9tLCB0bywgdW5pdCkge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgICAgIHQgPSBmdW5jdGlvbiAoZ290b0VuZCkge1xuICAgICAgICAgICAgICByZXR1cm4gc2VsZi5zdGVwKGdvdG9FbmQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGk7XG5cbiAgICAgICAgICB0aGlzLnN0YXJ0VGltZSA9ICtuZXcgRGF0ZSgpO1xuICAgICAgICAgIHRoaXMuc3RhcnQgPSBmcm9tO1xuICAgICAgICAgIHRoaXMuZW5kID0gdG87XG4gICAgICAgICAgdGhpcy51bml0ID0gdW5pdDtcbiAgICAgICAgICB0aGlzLm5vdyA9IHRoaXMuc3RhcnQ7XG4gICAgICAgICAgdGhpcy5wb3MgPSB0aGlzLnN0YXRlID0gMDtcblxuICAgICAgICAgIHQuZWxlbSA9IHRoaXMuZWxlbTtcblxuICAgICAgICAgIGlmICh0KCkgJiYgdGltZXJzLnB1c2godCkgPT09IDEpIHtcbiAgICAgICAgICAgIHRpbWVySWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG5cbiAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdGltZXJzW2ldKCkpIHtcbiAgICAgICAgICAgICAgICAgIHRpbWVycy5zcGxpY2UoaS0tLCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoIXRpbWVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKHRpbWVySWQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAxMyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIHN0ZXA6IGZ1bmN0aW9uIChnb3RvRW5kKSB7XG4gICAgICAgICAgdmFyIHQgPSArbmV3IERhdGUoKSxcbiAgICAgICAgICAgIHJldCxcbiAgICAgICAgICAgIGRvbmUsXG4gICAgICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zLFxuICAgICAgICAgICAgZWxlbSA9IHRoaXMuZWxlbSxcbiAgICAgICAgICAgIGk7XG5cbiAgICAgICAgICBpZiAoZWxlbS5zdG9wQW5pbWF0aW9uIHx8IChlbGVtLmF0dHIgJiYgIWVsZW0uZWxlbWVudCkpIHsgLy8gIzI2MTYsIGVsZW1lbnQgaW5jbHVkaW5nIGZsYWcgaXMgZGVzdHJveWVkXG4gICAgICAgICAgICByZXQgPSBmYWxzZTtcblxuICAgICAgICAgIH0gZWxzZSBpZiAoZ290b0VuZCB8fCB0ID49IG9wdGlvbnMuZHVyYXRpb24gKyB0aGlzLnN0YXJ0VGltZSkge1xuICAgICAgICAgICAgdGhpcy5ub3cgPSB0aGlzLmVuZDtcbiAgICAgICAgICAgIHRoaXMucG9zID0gdGhpcy5zdGF0ZSA9IDE7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuY3VyQW5pbVt0aGlzLnByb3BdID0gdHJ1ZTtcblxuICAgICAgICAgICAgZG9uZSA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGkgaW4gb3B0aW9ucy5jdXJBbmltKSB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLmN1ckFuaW1baV0gIT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBkb25lID0gZmFsc2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRvbmUpIHtcbiAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuY29tcGxldGUpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLmNvbXBsZXRlLmNhbGwoZWxlbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldCA9IGZhbHNlO1xuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBuID0gdCAtIHRoaXMuc3RhcnRUaW1lO1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IG4gLyBvcHRpb25zLmR1cmF0aW9uO1xuICAgICAgICAgICAgdGhpcy5wb3MgPSBvcHRpb25zLmVhc2luZyhuLCAwLCAxLCBvcHRpb25zLmR1cmF0aW9uKTtcbiAgICAgICAgICAgIHRoaXMubm93ID0gdGhpcy5zdGFydCArICgodGhpcy5lbmQgLSB0aGlzLnN0YXJ0KSAqIHRoaXMucG9zKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlKCk7XG4gICAgICAgICAgICByZXQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvKipcbiAgICAgICAqIFRoZSBhZGFwdGVyIGFuaW1hdGUgbWV0aG9kXG4gICAgICAgKi9cbiAgICAgIHRoaXMuYW5pbWF0ZSA9IGZ1bmN0aW9uIChlbCwgcHJvcCwgb3B0KSB7XG4gICAgICAgIHZhciBzdGFydCxcbiAgICAgICAgICB1bml0ID0gJycsXG4gICAgICAgICAgZW5kLFxuICAgICAgICAgIGZ4LFxuICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgbmFtZTtcblxuICAgICAgICBlbC5zdG9wQW5pbWF0aW9uID0gZmFsc2U7IC8vIHJlYWR5IGZvciBuZXdcblxuICAgICAgICBpZiAodHlwZW9mIG9wdCAhPT0gJ29iamVjdCcgfHwgb3B0ID09PSBudWxsKSB7XG4gICAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgICAgICBvcHQgPSB7XG4gICAgICAgICAgICBkdXJhdGlvbjogYXJnc1syXSxcbiAgICAgICAgICAgIGVhc2luZzogYXJnc1szXSxcbiAgICAgICAgICAgIGNvbXBsZXRlOiBhcmdzWzRdXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdC5kdXJhdGlvbiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICBvcHQuZHVyYXRpb24gPSA0MDA7XG4gICAgICAgIH1cbiAgICAgICAgb3B0LmVhc2luZyA9IE1hdGhbb3B0LmVhc2luZ10gfHwgTWF0aC5lYXNlSW5PdXRTaW5lO1xuICAgICAgICBvcHQuY3VyQW5pbSA9IEhpZ2hjaGFydHMuZXh0ZW5kKHt9LCBwcm9wKTtcblxuICAgICAgICBmb3IgKG5hbWUgaW4gcHJvcCkge1xuICAgICAgICAgIGZ4ID0gbmV3IEZ4KGVsLCBvcHQsIG5hbWUpO1xuICAgICAgICAgIGVuZCA9IG51bGw7XG5cbiAgICAgICAgICBpZiAobmFtZSA9PT0gJ2QnKSB7XG4gICAgICAgICAgICBmeC5wYXRocyA9IHBhdGhBbmltLmluaXQoXG4gICAgICAgICAgICAgIGVsLFxuICAgICAgICAgICAgICBlbC5kLFxuICAgICAgICAgICAgICBwcm9wLmRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBmeC50b0QgPSBwcm9wLmQ7XG4gICAgICAgICAgICBzdGFydCA9IDA7XG4gICAgICAgICAgICBlbmQgPSAxO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZWwuYXR0cikge1xuICAgICAgICAgICAgc3RhcnQgPSBlbC5hdHRyKG5hbWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGFydCA9IHBhcnNlRmxvYXQoSGlnaGNoYXJ0c0FkYXB0ZXIuX2dldFN0eWxlKGVsLCBuYW1lKSkgfHwgMDtcbiAgICAgICAgICAgIGlmIChuYW1lICE9PSAnb3BhY2l0eScpIHtcbiAgICAgICAgICAgICAgdW5pdCA9ICdweCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFlbmQpIHtcbiAgICAgICAgICAgIGVuZCA9IHByb3BbbmFtZV07XG4gICAgICAgICAgfVxuICAgICAgICAgIGZ4LmN1c3RvbShzdGFydCwgZW5kLCB1bml0KTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgbWV0aG9kIHRvIHJldHVybiBDU1MgdmFsdWUgZm9yIGdpdmVuIGVsZW1lbnQgYW5kIHByb3BlcnR5XG4gICAgICovXG4gICAgX2dldFN0eWxlOiBmdW5jdGlvbiAoZWwsIHByb3ApIHtcbiAgICAgIHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgdW5kZWZpbmVkKS5nZXRQcm9wZXJ0eVZhbHVlKHByb3ApO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gYW5pbWF0aW9uIHNldHRlciBmb3IgYSBzcGVjaWZpYyBwcm9wZXJ0eVxuICAgICAqL1xuICAgIGFkZEFuaW1TZXR0ZXI6IGZ1bmN0aW9uIChwcm9wLCBmbikge1xuICAgICAgYW5pbVNldHRlcnNbcHJvcF0gPSBmbjtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRG93bmxvYWRzIGEgc2NyaXB0IGFuZCBleGVjdXRlcyBhIGNhbGxiYWNrIHdoZW4gZG9uZS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc2NyaXB0TG9jYXRpb25cbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFja1xuICAgICAqL1xuICAgIGdldFNjcmlwdDogZnVuY3Rpb24gKHNjcmlwdExvY2F0aW9uLCBjYWxsYmFjaykge1xuICAgICAgLy8gV2UgY2Fubm90IGFzc3VtZSB0aGF0IEFzc2V0cyBjbGFzcyBmcm9tIG1vb3Rvb2xzLW1vcmUgaXMgYXZhaWxhYmxlIHNvIGluc3RlYWQgaW5zZXJ0IGEgc2NyaXB0IHRhZyB0byBkb3dubG9hZCBzY3JpcHQuXG4gICAgICB2YXIgaGVhZCA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaGVhZCcpWzBdLFxuICAgICAgICBzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cbiAgICAgIHNjcmlwdC50eXBlID0gJ3RleHQvamF2YXNjcmlwdCc7XG4gICAgICBzY3JpcHQuc3JjID0gc2NyaXB0TG9jYXRpb247XG4gICAgICBzY3JpcHQub25sb2FkID0gY2FsbGJhY2s7XG5cbiAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBpbmRleCBvZiBhbiBpdGVtIGluIGFuIGFycmF5LCBvciAtMSBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBpbkFycmF5OiBmdW5jdGlvbiAoaXRlbSwgYXJyKSB7XG4gICAgICByZXR1cm4gYXJyLmluZGV4T2YgPyBhcnIuaW5kZXhPZihpdGVtKSA6IGVtcHR5QXJyYXkuaW5kZXhPZi5jYWxsKGFyciwgaXRlbSk7XG4gICAgfSxcblxuXG4gICAgLyoqXG4gICAgICogQSBkaXJlY3QgbGluayB0byBhZGFwdGVyIG1ldGhvZHNcbiAgICAgKi9cbiAgICBhZGFwdGVyUnVuOiBmdW5jdGlvbiAoZWxlbSwgbWV0aG9kKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQoSGlnaGNoYXJ0c0FkYXB0ZXIuX2dldFN0eWxlKGVsZW0sIG1ldGhvZCksIDEwKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRmlsdGVyIGFuIGFycmF5XG4gICAgICovXG4gICAgZ3JlcDogZnVuY3Rpb24gKGVsZW1lbnRzLCBjYWxsYmFjaykge1xuICAgICAgcmV0dXJuIGVtcHR5QXJyYXkuZmlsdGVyLmNhbGwoZWxlbWVudHMsIGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogTWFwIGFuIGFycmF5XG4gICAgICovXG4gICAgbWFwOiBmdW5jdGlvbiAoYXJyLCBmbikge1xuICAgICAgdmFyIHJlc3VsdHMgPSBbXSwgaSA9IDAsIGxlbiA9IGFyci5sZW5ndGg7XG5cbiAgICAgIGZvciAoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgcmVzdWx0c1tpXSA9IGZuLmNhbGwoYXJyW2ldLCBhcnJbaV0sIGksIGFycik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVsZW1lbnQncyBvZmZzZXQgcG9zaXRpb24sIGNvcnJlY3RlZCBieSBvdmVyZmxvdzphdXRvLiBMb29zZWx5IGJhc2VkIG9uIGpRdWVyeSdzIG9mZnNldCBtZXRob2QuXG4gICAgICovXG4gICAgb2Zmc2V0OiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgIHZhciBkb2NFbGVtID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFxuICAgICAgICBib3ggPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdG9wOiBib3gudG9wICArICh3aW5kb3cucGFnZVlPZmZzZXQgfHwgZG9jRWxlbS5zY3JvbGxUb3ApICAtIChkb2NFbGVtLmNsaWVudFRvcCAgfHwgMCksXG4gICAgICAgIGxlZnQ6IGJveC5sZWZ0ICsgKHdpbmRvdy5wYWdlWE9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbExlZnQpIC0gKGRvY0VsZW0uY2xpZW50TGVmdCB8fCAwKVxuICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWRkIGFuIGV2ZW50IGxpc3RlbmVyXG4gICAgICovXG4gICAgYWRkRXZlbnQ6IGZ1bmN0aW9uIChlbCwgdHlwZSwgZm4pIHtcbiAgICAgIGF1Z21lbnQoZWwpLmJpbmQodHlwZSwgZm4pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgZXZlbnQgYWRkZWQgd2l0aCBhZGRFdmVudFxuICAgICAqL1xuICAgIHJlbW92ZUV2ZW50OiBmdW5jdGlvbiAoZWwsIHR5cGUsIGZuKSB7XG4gICAgICBhdWdtZW50KGVsKS51bmJpbmQodHlwZSwgZm4pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBGaXJlIGFuIGV2ZW50IG9uIGEgY3VzdG9tIG9iamVjdFxuICAgICAqL1xuICAgIGZpcmVFdmVudDogZnVuY3Rpb24gKGVsLCB0eXBlLCBldmVudEFyZ3VtZW50cywgZGVmYXVsdEZ1bmN0aW9uKSB7XG4gICAgICB2YXIgZTtcblxuICAgICAgaWYgKGRvYy5jcmVhdGVFdmVudCAmJiAoZWwuZGlzcGF0Y2hFdmVudCB8fCBlbC5maXJlRXZlbnQpKSB7XG4gICAgICAgIGUgPSBkb2MuY3JlYXRlRXZlbnQoJ0V2ZW50cycpO1xuICAgICAgICBlLmluaXRFdmVudCh0eXBlLCB0cnVlLCB0cnVlKTtcbiAgICAgICAgZS50YXJnZXQgPSBlbDtcblxuICAgICAgICBIaWdoY2hhcnRzLmV4dGVuZChlLCBldmVudEFyZ3VtZW50cyk7XG5cbiAgICAgICAgaWYgKGVsLmRpc3BhdGNoRXZlbnQpIHtcbiAgICAgICAgICBlbC5kaXNwYXRjaEV2ZW50KGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsLmZpcmVFdmVudCh0eXBlLCBlKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2UgaWYgKGVsLkhDRXh0ZW5kZWQgPT09IHRydWUpIHtcbiAgICAgICAgZXZlbnRBcmd1bWVudHMgPSBldmVudEFyZ3VtZW50cyB8fCB7fTtcbiAgICAgICAgZWwudHJpZ2dlcih0eXBlLCBldmVudEFyZ3VtZW50cyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudEFyZ3VtZW50cyAmJiBldmVudEFyZ3VtZW50cy5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIGRlZmF1bHRGdW5jdGlvbiA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWZhdWx0RnVuY3Rpb24pIHtcbiAgICAgICAgZGVmYXVsdEZ1bmN0aW9uKGV2ZW50QXJndW1lbnRzKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgd2FzaE1vdXNlRXZlbnQ6IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gZTtcbiAgICB9LFxuXG5cbiAgICAvKipcbiAgICAgKiBTdG9wIHJ1bm5pbmcgYW5pbWF0aW9uXG4gICAgICovXG4gICAgc3RvcDogZnVuY3Rpb24gKGVsKSB7XG4gICAgICBlbC5zdG9wQW5pbWF0aW9uID0gdHJ1ZTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogVXRpbGl0eSBmb3IgaXRlcmF0aW5nIG92ZXIgYW4gYXJyYXkuIFBhcmFtZXRlcnMgYXJlIHJldmVyc2VkIGNvbXBhcmVkIHRvIGpRdWVyeS5cbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgICAqL1xuICAgIGVhY2g6IGZ1bmN0aW9uIChhcnIsIGZuKSB7IC8vIG1vZGVybiBicm93c2Vyc1xuICAgICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwoYXJyLCBmbik7XG4gICAgfVxuICB9O1xufSgpKTsiLCJ2YXIgcHJvY2Vzcz1yZXF1aXJlKFwiX19icm93c2VyaWZ5X3Byb2Nlc3NcIik7LypnbG9iYWwgc2V0SW1tZWRpYXRlOiBmYWxzZSwgc2V0VGltZW91dDogZmFsc2UsIGNvbnNvbGU6IGZhbHNlICovXG4oZnVuY3Rpb24gKCkge1xuXG4gICAgdmFyIGFzeW5jID0ge307XG5cbiAgICAvLyBnbG9iYWwgb24gdGhlIHNlcnZlciwgd2luZG93IGluIHRoZSBicm93c2VyXG4gICAgdmFyIHJvb3QsIHByZXZpb3VzX2FzeW5jO1xuXG4gICAgcm9vdCA9IHRoaXM7XG4gICAgaWYgKHJvb3QgIT0gbnVsbCkge1xuICAgICAgcHJldmlvdXNfYXN5bmMgPSByb290LmFzeW5jO1xuICAgIH1cblxuICAgIGFzeW5jLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJvb3QuYXN5bmMgPSBwcmV2aW91c19hc3luYztcbiAgICAgICAgcmV0dXJuIGFzeW5jO1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBvbmx5X29uY2UoZm4pIHtcbiAgICAgICAgdmFyIGNhbGxlZCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBpZiAoY2FsbGVkKSB0aHJvdyBuZXcgRXJyb3IoXCJDYWxsYmFjayB3YXMgYWxyZWFkeSBjYWxsZWQuXCIpO1xuICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGZuLmFwcGx5KHJvb3QsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLy8vIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJsaXR5IGZ1bmN0aW9ucyAvLy8vXG5cbiAgICB2YXIgX2VhY2ggPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvcikge1xuICAgICAgICBpZiAoYXJyLmZvckVhY2gpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnIuZm9yRWFjaChpdGVyYXRvcik7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKGFycltpXSwgaSwgYXJyKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICB2YXIgX21hcCA9IGZ1bmN0aW9uIChhcnIsIGl0ZXJhdG9yKSB7XG4gICAgICAgIGlmIChhcnIubWFwKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyLm1hcChpdGVyYXRvcik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgX2VhY2goYXJyLCBmdW5jdGlvbiAoeCwgaSwgYSkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGl0ZXJhdG9yKHgsIGksIGEpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH07XG5cbiAgICB2YXIgX3JlZHVjZSA9IGZ1bmN0aW9uIChhcnIsIGl0ZXJhdG9yLCBtZW1vKSB7XG4gICAgICAgIGlmIChhcnIucmVkdWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyLnJlZHVjZShpdGVyYXRvciwgbWVtbyk7XG4gICAgICAgIH1cbiAgICAgICAgX2VhY2goYXJyLCBmdW5jdGlvbiAoeCwgaSwgYSkge1xuICAgICAgICAgICAgbWVtbyA9IGl0ZXJhdG9yKG1lbW8sIHgsIGksIGEpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgfTtcblxuICAgIHZhciBfa2V5cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKSB7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBrIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrKSkge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ga2V5cztcbiAgICB9O1xuXG4gICAgLy8vLyBleHBvcnRlZCBhc3luYyBtb2R1bGUgZnVuY3Rpb25zIC8vLy9cblxuICAgIC8vLy8gbmV4dFRpY2sgaW1wbGVtZW50YXRpb24gd2l0aCBicm93c2VyLWNvbXBhdGlibGUgZmFsbGJhY2sgLy8vL1xuICAgIGlmICh0eXBlb2YgcHJvY2VzcyA9PT0gJ3VuZGVmaW5lZCcgfHwgIShwcm9jZXNzLm5leHRUaWNrKSkge1xuICAgICAgICBpZiAodHlwZW9mIHNldEltbWVkaWF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgYXN5bmMubmV4dFRpY2sgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgICAgICAvLyBub3QgYSBkaXJlY3QgYWxpYXMgZm9yIElFMTAgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgYXN5bmMuc2V0SW1tZWRpYXRlID0gYXN5bmMubmV4dFRpY2s7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhc3luYy5uZXh0VGljayA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZSA9IGFzeW5jLm5leHRUaWNrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBhc3luYy5uZXh0VGljayA9IHByb2Nlc3MubmV4dFRpY2s7XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgYXN5bmMuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgIC8vIG5vdCBhIGRpcmVjdCBhbGlhcyBmb3IgSUUxMCBjb21wYXRpYmlsaXR5XG4gICAgICAgICAgICAgIHNldEltbWVkaWF0ZShmbik7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXN5bmMuc2V0SW1tZWRpYXRlID0gYXN5bmMubmV4dFRpY2s7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYy5lYWNoID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIGlmICghYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbXBsZXRlZCA9IDA7XG4gICAgICAgIF9lYWNoKGFyciwgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKHgsIG9ubHlfb25jZShmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGVkICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb21wbGV0ZWQgPj0gYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgYXN5bmMuZm9yRWFjaCA9IGFzeW5jLmVhY2g7XG5cbiAgICBhc3luYy5lYWNoU2VyaWVzID0gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIGlmICghYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbXBsZXRlZCA9IDA7XG4gICAgICAgIHZhciBpdGVyYXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaXRlcmF0b3IoYXJyW2NvbXBsZXRlZF0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWQgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBsZXRlZCA+PSBhcnIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZXJhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICBpdGVyYXRlKCk7XG4gICAgfTtcbiAgICBhc3luYy5mb3JFYWNoU2VyaWVzID0gYXN5bmMuZWFjaFNlcmllcztcblxuICAgIGFzeW5jLmVhY2hMaW1pdCA9IGZ1bmN0aW9uIChhcnIsIGxpbWl0LCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIGZuID0gX2VhY2hMaW1pdChsaW1pdCk7XG4gICAgICAgIGZuLmFwcGx5KG51bGwsIFthcnIsIGl0ZXJhdG9yLCBjYWxsYmFja10pO1xuICAgIH07XG4gICAgYXN5bmMuZm9yRWFjaExpbWl0ID0gYXN5bmMuZWFjaExpbWl0O1xuXG4gICAgdmFyIF9lYWNoTGltaXQgPSBmdW5jdGlvbiAobGltaXQpIHtcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgaWYgKCFhcnIubGVuZ3RoIHx8IGxpbWl0IDw9IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBjb21wbGV0ZWQgPSAwO1xuICAgICAgICAgICAgdmFyIHN0YXJ0ZWQgPSAwO1xuICAgICAgICAgICAgdmFyIHJ1bm5pbmcgPSAwO1xuXG4gICAgICAgICAgICAoZnVuY3Rpb24gcmVwbGVuaXNoICgpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29tcGxldGVkID49IGFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgd2hpbGUgKHJ1bm5pbmcgPCBsaW1pdCAmJiBzdGFydGVkIDwgYXJyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBzdGFydGVkICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgaXRlcmF0b3IoYXJyW3N0YXJ0ZWQgLSAxXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZCArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29tcGxldGVkID49IGFyci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxlbmlzaCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfTtcbiAgICB9O1xuXG5cbiAgICB2YXIgZG9QYXJhbGxlbCA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KG51bGwsIFthc3luYy5lYWNoXS5jb25jYXQoYXJncykpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgdmFyIGRvUGFyYWxsZWxMaW1pdCA9IGZ1bmN0aW9uKGxpbWl0LCBmbikge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KG51bGwsIFtfZWFjaExpbWl0KGxpbWl0KV0uY29uY2F0KGFyZ3MpKTtcbiAgICAgICAgfTtcbiAgICB9O1xuICAgIHZhciBkb1NlcmllcyA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KG51bGwsIFthc3luYy5lYWNoU2VyaWVzXS5jb25jYXQoYXJncykpO1xuICAgICAgICB9O1xuICAgIH07XG5cblxuICAgIHZhciBfYXN5bmNNYXAgPSBmdW5jdGlvbiAoZWFjaGZuLCBhcnIsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgICAgICBhcnIgPSBfbWFwKGFyciwgZnVuY3Rpb24gKHgsIGkpIHtcbiAgICAgICAgICAgIHJldHVybiB7aW5kZXg6IGksIHZhbHVlOiB4fTtcbiAgICAgICAgfSk7XG4gICAgICAgIGVhY2hmbihhcnIsIGZ1bmN0aW9uICh4LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaXRlcmF0b3IoeC52YWx1ZSwgZnVuY3Rpb24gKGVyciwgdikge1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbeC5pbmRleF0gPSB2O1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY2FsbGJhY2soZXJyLCByZXN1bHRzKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBhc3luYy5tYXAgPSBkb1BhcmFsbGVsKF9hc3luY01hcCk7XG4gICAgYXN5bmMubWFwU2VyaWVzID0gZG9TZXJpZXMoX2FzeW5jTWFwKTtcbiAgICBhc3luYy5tYXBMaW1pdCA9IGZ1bmN0aW9uIChhcnIsIGxpbWl0LCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuIF9tYXBMaW1pdChsaW1pdCkoYXJyLCBpdGVyYXRvciwgY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICB2YXIgX21hcExpbWl0ID0gZnVuY3Rpb24obGltaXQpIHtcbiAgICAgICAgcmV0dXJuIGRvUGFyYWxsZWxMaW1pdChsaW1pdCwgX2FzeW5jTWFwKTtcbiAgICB9O1xuXG4gICAgLy8gcmVkdWNlIG9ubHkgaGFzIGEgc2VyaWVzIHZlcnNpb24sIGFzIGRvaW5nIHJlZHVjZSBpbiBwYXJhbGxlbCB3b24ndFxuICAgIC8vIHdvcmsgaW4gbWFueSBzaXR1YXRpb25zLlxuICAgIGFzeW5jLnJlZHVjZSA9IGZ1bmN0aW9uIChhcnIsIG1lbW8sIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICBhc3luYy5lYWNoU2VyaWVzKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcihtZW1vLCB4LCBmdW5jdGlvbiAoZXJyLCB2KSB7XG4gICAgICAgICAgICAgICAgbWVtbyA9IHY7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhlcnIsIG1lbW8pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIC8vIGluamVjdCBhbGlhc1xuICAgIGFzeW5jLmluamVjdCA9IGFzeW5jLnJlZHVjZTtcbiAgICAvLyBmb2xkbCBhbGlhc1xuICAgIGFzeW5jLmZvbGRsID0gYXN5bmMucmVkdWNlO1xuXG4gICAgYXN5bmMucmVkdWNlUmlnaHQgPSBmdW5jdGlvbiAoYXJyLCBtZW1vLCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJldmVyc2VkID0gX21hcChhcnIsIGZ1bmN0aW9uICh4KSB7XG4gICAgICAgICAgICByZXR1cm4geDtcbiAgICAgICAgfSkucmV2ZXJzZSgpO1xuICAgICAgICBhc3luYy5yZWR1Y2UocmV2ZXJzZWQsIG1lbW8sIGl0ZXJhdG9yLCBjYWxsYmFjayk7XG4gICAgfTtcbiAgICAvLyBmb2xkciBhbGlhc1xuICAgIGFzeW5jLmZvbGRyID0gYXN5bmMucmVkdWNlUmlnaHQ7XG5cbiAgICB2YXIgX2ZpbHRlciA9IGZ1bmN0aW9uIChlYWNoZm4sIGFyciwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXN1bHRzID0gW107XG4gICAgICAgIGFyciA9IF9tYXAoYXJyLCBmdW5jdGlvbiAoeCwgaSkge1xuICAgICAgICAgICAgcmV0dXJuIHtpbmRleDogaSwgdmFsdWU6IHh9O1xuICAgICAgICB9KTtcbiAgICAgICAgZWFjaGZuKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LnZhbHVlLCBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhfbWFwKHJlc3VsdHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICAgICAgICAgIH0pLCBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB4LnZhbHVlO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGFzeW5jLmZpbHRlciA9IGRvUGFyYWxsZWwoX2ZpbHRlcik7XG4gICAgYXN5bmMuZmlsdGVyU2VyaWVzID0gZG9TZXJpZXMoX2ZpbHRlcik7XG4gICAgLy8gc2VsZWN0IGFsaWFzXG4gICAgYXN5bmMuc2VsZWN0ID0gYXN5bmMuZmlsdGVyO1xuICAgIGFzeW5jLnNlbGVjdFNlcmllcyA9IGFzeW5jLmZpbHRlclNlcmllcztcblxuICAgIHZhciBfcmVqZWN0ID0gZnVuY3Rpb24gKGVhY2hmbiwgYXJyLCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgYXJyID0gX21hcChhcnIsIGZ1bmN0aW9uICh4LCBpKSB7XG4gICAgICAgICAgICByZXR1cm4ge2luZGV4OiBpLCB2YWx1ZTogeH07XG4gICAgICAgIH0pO1xuICAgICAgICBlYWNoZm4oYXJyLCBmdW5jdGlvbiAoeCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKHgudmFsdWUsIGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF2KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhfbWFwKHJlc3VsdHMuc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICAgICAgICAgIH0pLCBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB4LnZhbHVlO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIGFzeW5jLnJlamVjdCA9IGRvUGFyYWxsZWwoX3JlamVjdCk7XG4gICAgYXN5bmMucmVqZWN0U2VyaWVzID0gZG9TZXJpZXMoX3JlamVjdCk7XG5cbiAgICB2YXIgX2RldGVjdCA9IGZ1bmN0aW9uIChlYWNoZm4sIGFyciwgaXRlcmF0b3IsIG1haW5fY2FsbGJhY2spIHtcbiAgICAgICAgZWFjaGZuKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LCBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBtYWluX2NhbGxiYWNrKHgpO1xuICAgICAgICAgICAgICAgICAgICBtYWluX2NhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBtYWluX2NhbGxiYWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgYXN5bmMuZGV0ZWN0ID0gZG9QYXJhbGxlbChfZGV0ZWN0KTtcbiAgICBhc3luYy5kZXRlY3RTZXJpZXMgPSBkb1NlcmllcyhfZGV0ZWN0KTtcblxuICAgIGFzeW5jLnNvbWUgPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvciwgbWFpbl9jYWxsYmFjaykge1xuICAgICAgICBhc3luYy5lYWNoKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LCBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIGlmICh2KSB7XG4gICAgICAgICAgICAgICAgICAgIG1haW5fY2FsbGJhY2sodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIG1haW5fY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBtYWluX2NhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvLyBhbnkgYWxpYXNcbiAgICBhc3luYy5hbnkgPSBhc3luYy5zb21lO1xuXG4gICAgYXN5bmMuZXZlcnkgPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvciwgbWFpbl9jYWxsYmFjaykge1xuICAgICAgICBhc3luYy5lYWNoKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LCBmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICAgIGlmICghdikge1xuICAgICAgICAgICAgICAgICAgICBtYWluX2NhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgbWFpbl9jYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIG1haW5fY2FsbGJhY2sodHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLy8gYWxsIGFsaWFzXG4gICAgYXN5bmMuYWxsID0gYXN5bmMuZXZlcnk7XG5cbiAgICBhc3luYy5zb3J0QnkgPSBmdW5jdGlvbiAoYXJyLCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgYXN5bmMubWFwKGFyciwgZnVuY3Rpb24gKHgsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih4LCBmdW5jdGlvbiAoZXJyLCBjcml0ZXJpYSkge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHt2YWx1ZTogeCwgY3JpdGVyaWE6IGNyaXRlcmlhfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnIsIHJlc3VsdHMpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBmbiA9IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWEsIGIgPSByaWdodC5jcml0ZXJpYTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgX21hcChyZXN1bHRzLnNvcnQoZm4pLCBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geC52YWx1ZTtcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBhc3luYy5hdXRvID0gZnVuY3Rpb24gKHRhc2tzLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICB2YXIga2V5cyA9IF9rZXlzKHRhc2tzKTtcbiAgICAgICAgaWYgKCFrZXlzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlc3VsdHMgPSB7fTtcblxuICAgICAgICB2YXIgbGlzdGVuZXJzID0gW107XG4gICAgICAgIHZhciBhZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgICAgbGlzdGVuZXJzLnVuc2hpZnQoZm4pO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgcmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdGVuZXJzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgaWYgKGxpc3RlbmVyc1tpXSA9PT0gZm4pIHtcbiAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHRhc2tDb21wbGV0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIF9lYWNoKGxpc3RlbmVycy5zbGljZSgwKSwgZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIGFkZExpc3RlbmVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChfa2V5cyhyZXN1bHRzKS5sZW5ndGggPT09IGtleXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0cyk7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgX2VhY2goa2V5cywgZnVuY3Rpb24gKGspIHtcbiAgICAgICAgICAgIHZhciB0YXNrID0gKHRhc2tzW2tdIGluc3RhbmNlb2YgRnVuY3Rpb24pID8gW3Rhc2tzW2tdXTogdGFza3Nba107XG4gICAgICAgICAgICB2YXIgdGFza0NhbGxiYWNrID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1swXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc2FmZVJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgX2VhY2goX2tleXMocmVzdWx0cyksIGZ1bmN0aW9uKHJrZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNhZmVSZXN1bHRzW3JrZXldID0gcmVzdWx0c1tya2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHNhZmVSZXN1bHRzW2tdID0gYXJncztcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCBzYWZlUmVzdWx0cyk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHN0b3Agc3Vic2VxdWVudCBlcnJvcnMgaGl0dGluZyBjYWxsYmFjayBtdWx0aXBsZSB0aW1lc1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1trXSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZSh0YXNrQ29tcGxldGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB2YXIgcmVxdWlyZXMgPSB0YXNrLnNsaWNlKDAsIE1hdGguYWJzKHRhc2subGVuZ3RoIC0gMSkpIHx8IFtdO1xuICAgICAgICAgICAgdmFyIHJlYWR5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfcmVkdWNlKHJlcXVpcmVzLCBmdW5jdGlvbiAoYSwgeCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGEgJiYgcmVzdWx0cy5oYXNPd25Qcm9wZXJ0eSh4KSk7XG4gICAgICAgICAgICAgICAgfSwgdHJ1ZSkgJiYgIXJlc3VsdHMuaGFzT3duUHJvcGVydHkoayk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHJlYWR5KCkpIHtcbiAgICAgICAgICAgICAgICB0YXNrW3Rhc2subGVuZ3RoIC0gMV0odGFza0NhbGxiYWNrLCByZXN1bHRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlYWR5KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tbdGFzay5sZW5ndGggLSAxXSh0YXNrQ2FsbGJhY2ssIHJlc3VsdHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBhZGRMaXN0ZW5lcihsaXN0ZW5lcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBhc3luYy53YXRlcmZhbGwgPSBmdW5jdGlvbiAodGFza3MsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIGlmICh0YXNrcy5jb25zdHJ1Y3RvciAhPT0gQXJyYXkpIHtcbiAgICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCB0byB3YXRlcmZhbGwgbXVzdCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMnKTtcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRhc2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHdyYXBJdGVyYXRvciA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXh0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKHdyYXBJdGVyYXRvcihuZXh0KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFzeW5jLnNldEltbWVkaWF0ZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVyYXRvci5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgd3JhcEl0ZXJhdG9yKGFzeW5jLml0ZXJhdG9yKHRhc2tzKSkoKTtcbiAgICB9O1xuXG4gICAgdmFyIF9wYXJhbGxlbCA9IGZ1bmN0aW9uKGVhY2hmbiwgdGFza3MsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIGlmICh0YXNrcy5jb25zdHJ1Y3RvciA9PT0gQXJyYXkpIHtcbiAgICAgICAgICAgIGVhY2hmbi5tYXAodGFza3MsIGZ1bmN0aW9uIChmbiwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBpZiAoZm4pIHtcbiAgICAgICAgICAgICAgICAgICAgZm4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1swXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwobnVsbCwgZXJyLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgIGVhY2hmbi5lYWNoKF9rZXlzKHRhc2tzKSwgZnVuY3Rpb24gKGssIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdGFza3Nba10oZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhcmdzLmxlbmd0aCA8PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1swXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXN1bHRzW2tdID0gYXJncztcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgYXN5bmMucGFyYWxsZWwgPSBmdW5jdGlvbiAodGFza3MsIGNhbGxiYWNrKSB7XG4gICAgICAgIF9wYXJhbGxlbCh7IG1hcDogYXN5bmMubWFwLCBlYWNoOiBhc3luYy5lYWNoIH0sIHRhc2tzLCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIGFzeW5jLnBhcmFsbGVsTGltaXQgPSBmdW5jdGlvbih0YXNrcywgbGltaXQsIGNhbGxiYWNrKSB7XG4gICAgICAgIF9wYXJhbGxlbCh7IG1hcDogX21hcExpbWl0KGxpbWl0KSwgZWFjaDogX2VhY2hMaW1pdChsaW1pdCkgfSwgdGFza3MsIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgYXN5bmMuc2VyaWVzID0gZnVuY3Rpb24gKHRhc2tzLCBjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAodGFza3MuY29uc3RydWN0b3IgPT09IEFycmF5KSB7XG4gICAgICAgICAgICBhc3luYy5tYXBTZXJpZXModGFza3MsIGZ1bmN0aW9uIChmbiwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICBpZiAoZm4pIHtcbiAgICAgICAgICAgICAgICAgICAgZm4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzID0gYXJnc1swXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwobnVsbCwgZXJyLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgIGFzeW5jLmVhY2hTZXJpZXMoX2tleXModGFza3MpLCBmdW5jdGlvbiAoaywgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICB0YXNrc1trXShmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3MubGVuZ3RoIDw9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3MgPSBhcmdzWzBdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHNba10gPSBhcmdzO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgcmVzdWx0cyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBhc3luYy5pdGVyYXRvciA9IGZ1bmN0aW9uICh0YXNrcykge1xuICAgICAgICB2YXIgbWFrZUNhbGxiYWNrID0gZnVuY3Rpb24gKGluZGV4KSB7XG4gICAgICAgICAgICB2YXIgZm4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRhc2tzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0YXNrc1tpbmRleF0uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZuLm5leHQoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmbi5uZXh0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAoaW5kZXggPCB0YXNrcy5sZW5ndGggLSAxKSA/IG1ha2VDYWxsYmFjayhpbmRleCArIDEpOiBudWxsO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBmbjtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1ha2VDYWxsYmFjaygwKTtcbiAgICB9O1xuXG4gICAgYXN5bmMuYXBwbHkgPSBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KFxuICAgICAgICAgICAgICAgIG51bGwsIGFyZ3MuY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpXG4gICAgICAgICAgICApO1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICB2YXIgX2NvbmNhdCA9IGZ1bmN0aW9uIChlYWNoZm4sIGFyciwgZm4sIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByID0gW107XG4gICAgICAgIGVhY2hmbihhcnIsIGZ1bmN0aW9uICh4LCBjYikge1xuICAgICAgICAgICAgZm4oeCwgZnVuY3Rpb24gKGVyciwgeSkge1xuICAgICAgICAgICAgICAgIHIgPSByLmNvbmNhdCh5IHx8IFtdKTtcbiAgICAgICAgICAgICAgICBjYihlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgcik7XG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgYXN5bmMuY29uY2F0ID0gZG9QYXJhbGxlbChfY29uY2F0KTtcbiAgICBhc3luYy5jb25jYXRTZXJpZXMgPSBkb1NlcmllcyhfY29uY2F0KTtcblxuICAgIGFzeW5jLndoaWxzdCA9IGZ1bmN0aW9uICh0ZXN0LCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRlc3QoKSkge1xuICAgICAgICAgICAgaXRlcmF0b3IoZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFzeW5jLndoaWxzdCh0ZXN0LCBpdGVyYXRvciwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGFzeW5jLmRvV2hpbHN0ID0gZnVuY3Rpb24gKGl0ZXJhdG9yLCB0ZXN0LCBjYWxsYmFjaykge1xuICAgICAgICBpdGVyYXRvcihmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGVzdCgpKSB7XG4gICAgICAgICAgICAgICAgYXN5bmMuZG9XaGlsc3QoaXRlcmF0b3IsIHRlc3QsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBhc3luYy51bnRpbCA9IGZ1bmN0aW9uICh0ZXN0LCBpdGVyYXRvciwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKCF0ZXN0KCkpIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhc3luYy51bnRpbCh0ZXN0LCBpdGVyYXRvciwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGFzeW5jLmRvVW50aWwgPSBmdW5jdGlvbiAoaXRlcmF0b3IsIHRlc3QsIGNhbGxiYWNrKSB7XG4gICAgICAgIGl0ZXJhdG9yKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGVzdCgpKSB7XG4gICAgICAgICAgICAgICAgYXN5bmMuZG9VbnRpbChpdGVyYXRvciwgdGVzdCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIGFzeW5jLnF1ZXVlID0gZnVuY3Rpb24gKHdvcmtlciwgY29uY3VycmVuY3kpIHtcbiAgICAgICAgaWYgKGNvbmN1cnJlbmN5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbmN1cnJlbmN5ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBfaW5zZXJ0KHEsIGRhdGEsIHBvcywgY2FsbGJhY2spIHtcbiAgICAgICAgICBpZihkYXRhLmNvbnN0cnVjdG9yICE9PSBBcnJheSkge1xuICAgICAgICAgICAgICBkYXRhID0gW2RhdGFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBfZWFjaChkYXRhLCBmdW5jdGlvbih0YXNrKSB7XG4gICAgICAgICAgICAgIHZhciBpdGVtID0ge1xuICAgICAgICAgICAgICAgICAgZGF0YTogdGFzayxcbiAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyBjYWxsYmFjayA6IG51bGxcbiAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICBpZiAocG9zKSB7XG4gICAgICAgICAgICAgICAgcS50YXNrcy51bnNoaWZ0KGl0ZW0pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHEudGFza3MucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChxLnNhdHVyYXRlZCAmJiBxLnRhc2tzLmxlbmd0aCA9PT0gY29uY3VycmVuY3kpIHtcbiAgICAgICAgICAgICAgICAgIHEuc2F0dXJhdGVkKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYXN5bmMuc2V0SW1tZWRpYXRlKHEucHJvY2Vzcyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgd29ya2VycyA9IDA7XG4gICAgICAgIHZhciBxID0ge1xuICAgICAgICAgICAgdGFza3M6IFtdLFxuICAgICAgICAgICAgY29uY3VycmVuY3k6IGNvbmN1cnJlbmN5LFxuICAgICAgICAgICAgc2F0dXJhdGVkOiBudWxsLFxuICAgICAgICAgICAgZW1wdHk6IG51bGwsXG4gICAgICAgICAgICBkcmFpbjogbnVsbCxcbiAgICAgICAgICAgIHB1c2g6IGZ1bmN0aW9uIChkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICBfaW5zZXJ0KHEsIGRhdGEsIGZhbHNlLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdW5zaGlmdDogZnVuY3Rpb24gKGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIF9pbnNlcnQocSwgZGF0YSwgdHJ1ZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb2Nlc3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAod29ya2VycyA8IHEuY29uY3VycmVuY3kgJiYgcS50YXNrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhc2sgPSBxLnRhc2tzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChxLmVtcHR5ICYmIHEudGFza3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBxLmVtcHR5KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgd29ya2VycyArPSAxO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtlcnMgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXNrLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFzay5jYWxsYmFjay5hcHBseSh0YXNrLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHEuZHJhaW4gJiYgcS50YXNrcy5sZW5ndGggKyB3b3JrZXJzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcS5kcmFpbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcS5wcm9jZXNzKCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHZhciBjYiA9IG9ubHlfb25jZShuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgd29ya2VyKHRhc2suZGF0YSwgY2IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsZW5ndGg6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcS50YXNrcy5sZW5ndGg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnVubmluZzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB3b3JrZXJzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcTtcbiAgICB9O1xuXG4gICAgYXN5bmMuY2FyZ28gPSBmdW5jdGlvbiAod29ya2VyLCBwYXlsb2FkKSB7XG4gICAgICAgIHZhciB3b3JraW5nICAgICA9IGZhbHNlLFxuICAgICAgICAgICAgdGFza3MgICAgICAgPSBbXTtcblxuICAgICAgICB2YXIgY2FyZ28gPSB7XG4gICAgICAgICAgICB0YXNrczogdGFza3MsXG4gICAgICAgICAgICBwYXlsb2FkOiBwYXlsb2FkLFxuICAgICAgICAgICAgc2F0dXJhdGVkOiBudWxsLFxuICAgICAgICAgICAgZW1wdHk6IG51bGwsXG4gICAgICAgICAgICBkcmFpbjogbnVsbCxcbiAgICAgICAgICAgIHB1c2g6IGZ1bmN0aW9uIChkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgIGlmKGRhdGEuY29uc3RydWN0b3IgIT09IEFycmF5KSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEgPSBbZGF0YV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIF9lYWNoKGRhdGEsIGZ1bmN0aW9uKHRhc2spIHtcbiAgICAgICAgICAgICAgICAgICAgdGFza3MucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB0YXNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJyA/IGNhbGxiYWNrIDogbnVsbFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNhcmdvLnNhdHVyYXRlZCAmJiB0YXNrcy5sZW5ndGggPT09IHBheWxvYWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcmdvLnNhdHVyYXRlZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYXN5bmMuc2V0SW1tZWRpYXRlKGNhcmdvLnByb2Nlc3MpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb2Nlc3M6IGZ1bmN0aW9uIHByb2Nlc3MoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHdvcmtpbmcpIHJldHVybjtcbiAgICAgICAgICAgICAgICBpZiAodGFza3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKGNhcmdvLmRyYWluKSBjYXJnby5kcmFpbigpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIHRzID0gdHlwZW9mIHBheWxvYWQgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB0YXNrcy5zcGxpY2UoMCwgcGF5bG9hZClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHRhc2tzLnNwbGljZSgwKTtcblxuICAgICAgICAgICAgICAgIHZhciBkcyA9IF9tYXAodHMsIGZ1bmN0aW9uICh0YXNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXNrLmRhdGE7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBpZihjYXJnby5lbXB0eSkgY2FyZ28uZW1wdHkoKTtcbiAgICAgICAgICAgICAgICB3b3JraW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB3b3JrZXIoZHMsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgd29ya2luZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICAgICAgICAgICAgICBfZWFjaCh0cywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5jYWxsYmFjay5hcHBseShudWxsLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgcHJvY2VzcygpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxlbmd0aDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0YXNrcy5sZW5ndGg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcnVubmluZzogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB3b3JraW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gY2FyZ287XG4gICAgfTtcblxuICAgIHZhciBfY29uc29sZV9mbiA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgIGZuLmFwcGx5KG51bGwsIGFyZ3MuY29uY2F0KFtmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uc29sZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnNvbGUuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY29uc29sZVtuYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX2VhY2goYXJncywgZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlW25hbWVdKHgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XSkpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgYXN5bmMubG9nID0gX2NvbnNvbGVfZm4oJ2xvZycpO1xuICAgIGFzeW5jLmRpciA9IF9jb25zb2xlX2ZuKCdkaXInKTtcbiAgICAvKmFzeW5jLmluZm8gPSBfY29uc29sZV9mbignaW5mbycpO1xuICAgIGFzeW5jLndhcm4gPSBfY29uc29sZV9mbignd2FybicpO1xuICAgIGFzeW5jLmVycm9yID0gX2NvbnNvbGVfZm4oJ2Vycm9yJyk7Ki9cblxuICAgIGFzeW5jLm1lbW9pemUgPSBmdW5jdGlvbiAoZm4sIGhhc2hlcikge1xuICAgICAgICB2YXIgbWVtbyA9IHt9O1xuICAgICAgICB2YXIgcXVldWVzID0ge307XG4gICAgICAgIGhhc2hlciA9IGhhc2hlciB8fCBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgcmV0dXJuIHg7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBtZW1vaXplZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IGFyZ3MucG9wKCk7XG4gICAgICAgICAgICB2YXIga2V5ID0gaGFzaGVyLmFwcGx5KG51bGwsIGFyZ3MpO1xuICAgICAgICAgICAgaWYgKGtleSBpbiBtZW1vKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgbWVtb1trZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGtleSBpbiBxdWV1ZXMpIHtcbiAgICAgICAgICAgICAgICBxdWV1ZXNba2V5XS5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHF1ZXVlc1trZXldID0gW2NhbGxiYWNrXTtcbiAgICAgICAgICAgICAgICBmbi5hcHBseShudWxsLCBhcmdzLmNvbmNhdChbZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBtZW1vW2tleV0gPSBhcmd1bWVudHM7XG4gICAgICAgICAgICAgICAgICAgIHZhciBxID0gcXVldWVzW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBxdWV1ZXNba2V5XTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBxLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgIHFbaV0uYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1dKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIG1lbW9pemVkLm1lbW8gPSBtZW1vO1xuICAgICAgICBtZW1vaXplZC51bm1lbW9pemVkID0gZm47XG4gICAgICAgIHJldHVybiBtZW1vaXplZDtcbiAgICB9O1xuXG4gICAgYXN5bmMudW5tZW1vaXplID0gZnVuY3Rpb24gKGZuKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gKGZuLnVubWVtb2l6ZWQgfHwgZm4pLmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH07XG5cbiAgICBhc3luYy50aW1lcyA9IGZ1bmN0aW9uIChjb3VudCwgaXRlcmF0b3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBjb3VudGVyID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgY291bnRlci5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhc3luYy5tYXAoY291bnRlciwgaXRlcmF0b3IsIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgYXN5bmMudGltZXNTZXJpZXMgPSBmdW5jdGlvbiAoY291bnQsIGl0ZXJhdG9yLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgY291bnRlciA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGNvdW50ZXIucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXN5bmMubWFwU2VyaWVzKGNvdW50ZXIsIGl0ZXJhdG9yLCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIGFzeW5jLmNvbXBvc2UgPSBmdW5jdGlvbiAoLyogZnVuY3Rpb25zLi4uICovKSB7XG4gICAgICAgIHZhciBmbnMgPSBBcnJheS5wcm90b3R5cGUucmV2ZXJzZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgYXN5bmMucmVkdWNlKGZucywgYXJncywgZnVuY3Rpb24gKG5ld2FyZ3MsIGZuLCBjYikge1xuICAgICAgICAgICAgICAgIGZuLmFwcGx5KHRoYXQsIG5ld2FyZ3MuY29uY2F0KFtmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBlcnIgPSBhcmd1bWVudHNbMF07XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXh0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgICAgICAgICAgICAgIGNiKGVyciwgbmV4dGFyZ3MpO1xuICAgICAgICAgICAgICAgIH1dKSlcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmdW5jdGlvbiAoZXJyLCByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkodGhhdCwgW2Vycl0uY29uY2F0KHJlc3VsdHMpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICB2YXIgX2FwcGx5RWFjaCA9IGZ1bmN0aW9uIChlYWNoZm4sIGZucyAvKmFyZ3MuLi4qLykge1xuICAgICAgICB2YXIgZ28gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIGVhY2hmbihmbnMsIGZ1bmN0aW9uIChmbiwgY2IpIHtcbiAgICAgICAgICAgICAgICBmbi5hcHBseSh0aGF0LCBhcmdzLmNvbmNhdChbY2JdKSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FsbGJhY2spO1xuICAgICAgICB9O1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICAgICAgICAgIHJldHVybiBnby5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnbztcbiAgICAgICAgfVxuICAgIH07XG4gICAgYXN5bmMuYXBwbHlFYWNoID0gZG9QYXJhbGxlbChfYXBwbHlFYWNoKTtcbiAgICBhc3luYy5hcHBseUVhY2hTZXJpZXMgPSBkb1NlcmllcyhfYXBwbHlFYWNoKTtcblxuICAgIGFzeW5jLmZvcmV2ZXIgPSBmdW5jdGlvbiAoZm4sIGNhbGxiYWNrKSB7XG4gICAgICAgIGZ1bmN0aW9uIG5leHQoZXJyKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmbihuZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0KCk7XG4gICAgfTtcblxuICAgIC8vIEFNRCAvIFJlcXVpcmVKU1xuICAgIGlmICh0eXBlb2YgZGVmaW5lICE9PSAndW5kZWZpbmVkJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICAgIGRlZmluZShbXSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGFzeW5jO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8gTm9kZS5qc1xuICAgIGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gYXN5bmM7XG4gICAgfVxuICAgIC8vIGluY2x1ZGVkIGRpcmVjdGx5IHZpYSA8c2NyaXB0PiB0YWdcbiAgICBlbHNlIHtcbiAgICAgICAgcm9vdC5hc3luYyA9IGFzeW5jO1xuICAgIH1cblxufSgpKTtcbiIsImZ1bmN0aW9uIHJlcGxhY2UoYSwgYilcclxue1xyXG4gaWYgKCFiKVxyXG4ge1xyXG4gIHJldHVybiBhO1xyXG4gfVxyXG4gdmFyIGtleTtcclxuIGZvciAoa2V5IGluIGIpXHJcbiB7XHJcbiAgaWYoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKVxyXG4gIHsgXHJcbiAgIGFba2V5XSA9IGJba2V5XTtcclxuICB9XHJcbiB9XHJcbiAgIFxyXG4gcmV0dXJuIGE7XHJcbn0gZXhwb3J0cy5yZXBsYWNlPXJlcGxhY2U7XHJcblxyXG5mdW5jdGlvbiBhZGQoYSwgYilcclxue1xyXG4gaWYgKCFiKVxyXG4ge1xyXG4gIHJldHVybiBhO1xyXG4gfVxyXG4gdmFyIGtleTtcclxuIGZvciAoa2V5IGluIGIpXHJcbiB7XHJcbiAgaWYoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKVxyXG4gIHsgXHJcbiAgIGlmKHR5cGVvZiBhW2tleV0gPT09ICd1bmRlZmluZWQnIHx8ICBhW2tleV09PT1udWxsKVxyXG4gICB7XHJcbiAgICBhW2tleV0gPSBiW2tleV07XHJcbiAgIH1cclxuICB9XHJcbiB9XHJcbiByZXR1cm4gYTtcclxufSBleHBvcnRzLmFkZD1hZGQ7XHJcblxyXG5cclxuZnVuY3Rpb24gZXh0ZW5kKGEsIGIsIGNvbnRleHQsIG5ld29ianMsIGFwYXJlbnQsIGFuYW1lLCBoYXZlYXBhcmVudCkgLy8gY29udGV4dCBpcyBhbnRpIGNpcmN1bGFyIHJlZmVyZW5jZXMgbWVjaGFuaXNtXHJcbntcclxuIGlmIChhPT1iKXsgcmV0dXJuIGE7fVxyXG4gaWYgKCFiKSAgeyByZXR1cm4gYTt9XHJcbiBcclxuIHZhciBrZXksIGNsZWFuX2NvbnRleHQ9ZmFsc2UsIHJldHVybl9zdWJsZXZlbD1mYWxzZSxiX3BvcztcclxuIGlmKCFoYXZlYXBhcmVudCl7IGFwYXJlbnQ9eydhJzphfTsgYW5hbWU9J2EnOyB9XHJcbiBpZighY29udGV4dCl7Y2xlYW5fY29udGV4dD10cnVlO2NvbnRleHQ9W107bmV3b2Jqcz1bXTt9XHJcbiBiX3Bvcz1jb250ZXh0LmluZGV4T2YoYik7XHJcbiBpZiggYl9wb3M9PS0xICkge2NvbnRleHQucHVzaChiKTtuZXdvYmpzLnB1c2goW2FwYXJlbnQsIGFuYW1lXSk7fSBlbHNlIHsgcmV0dXJuIG5ld29ianNbYl9wb3NdWzBdWyBuZXdvYmpzW2JfcG9zXVsxXSBdOyB9XHJcblxyXG4gZm9yIChrZXkgaW4gYilcclxuIHtcclxuICAgaWYoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKVxyXG4gICB7IFxyXG4gICBpZih0eXBlb2YgYVtrZXldID09PSAndW5kZWZpbmVkJylcclxuICAgeyAgIFxyXG4gICAgaWYodHlwZW9mIGJba2V5XSA9PT0gJ29iamVjdCcpXHJcbiAgICB7XHJcbiAgICAgaWYoIGJba2V5XSBpbnN0YW5jZW9mIEFycmF5ICkgLy8gaHR0cDovL2phdmFzY3JpcHQuY3JvY2tmb3JkLmNvbS9yZW1lZGlhbC5odG1sXHJcbiAgICAgIHthW2tleV0gPSBleHRlbmQoW10sIGJba2V5XSxjb250ZXh0LG5ld29ianMsYSxrZXksdHJ1ZSk7fVxyXG4gICAgIGVsc2UgaWYoYltrZXldPT09bnVsbClcclxuICAgICAge2Fba2V5XSA9IG51bGw7fVxyXG4gICAgIGVsc2UgaWYoIGJba2V5XSBpbnN0YW5jZW9mIERhdGUgKVxyXG4gICAgICB7IGFba2V5XT0gbmV3IGJba2V5XS5jb25zdHJ1Y3RvcigpO2Fba2V5XS5zZXRUaW1lKGJba2V5XS5nZXRUaW1lKCkpOyAgfVxyXG4gICAgIGVsc2VcclxuICAgICAgeyBhW2tleV0gPSBleHRlbmQoe30sIGJba2V5XSxjb250ZXh0LG5ld29ianMsYSxrZXksdHJ1ZSk7IC8qYVtrZXldLmNvbnN0cnVjdG9yID0gYltrZXldLmNvbnN0cnVjdG9yOyAgYVtrZXldLnByb3RvdHlwZSA9IGJba2V5XS5wcm90b3R5cGU7Ki8gfVxyXG4gICAgfVxyXG4gICAgZWxzZVxyXG4gICAgeyAgYVtrZXldID0gYltrZXldOyB9XHJcbiAgIH1cclxuICAgZWxzZSBpZih0eXBlb2YgYVtrZXldID09PSAnb2JqZWN0JyAmJiBhW2tleV0gIT09IG51bGwpXHJcbiAgIHsgIGFba2V5XSA9IGV4dGVuZChhW2tleV0sIGJba2V5XSxjb250ZXh0LG5ld29ianMsYSxrZXksdHJ1ZSk7IC8qYVtrZXldLmNvbnN0cnVjdG9yID0gYltrZXldLmNvbnN0cnVjdG9yOyAgYVtrZXldLnByb3RvdHlwZSA9IGJba2V5XS5wcm90b3R5cGU7Ki8gfVxyXG4gICBlbHNlICBcclxuICAgeyAgYVtrZXldID0gYltrZXldOyB9XHJcbiAgfVxyXG4gfVxyXG4gaWYoY2xlYW5fY29udGV4dCkge2NvbnRleHQ9bnVsbDtuZXdvYmpzPW51bGw7fVxyXG4gaWYoIWhhdmVhcGFyZW50KVxyXG4ge1xyXG4gIGFwYXJlbnQ9bnVsbDtcclxuICByZXR1cm4gYTtcclxuIH1cclxuIGlmKHR5cGVvZiBhID09PSAnb2JqZWN0JyAmJiAhKGEgaW5zdGFuY2VvZiBBcnJheSkgKVxyXG4ge1xyXG4gIC8qYS5jb25zdHJ1Y3RvciA9IGIuY29uc3RydWN0b3I7XHJcbiAgYS5wcm90b3R5cGUgICA9IGIucHJvdG90eXBlKi87XHJcbiB9IFxyXG4gcmV0dXJuIGE7XHJcbn0gZXhwb3J0cy5leHRlbmQ9ZXh0ZW5kO1xyXG5cclxuZnVuY3Rpb24gZXh0ZW5kdXB0b2xldmVsKGEsIGIsIGxldmVscywgY29udGV4dCwgbmV3b2JqcywgYXBhcmVudCwgYW5hbWUsIGhhdmVhcGFyZW50KVxyXG57XHJcbiBpZiAoYT09Yil7IHJldHVybiBhO31cclxuIGlmICghYil7IHJldHVybiBhO31cclxuXHJcbiB2YXIga2V5LCBjbGVhbl9jb250ZXh0PWZhbHNlLCByZXR1cm5fc3VibGV2ZWw9ZmFsc2U7XHJcbiBpZighaGF2ZWFwYXJlbnQpeyBhcGFyZW50PXsnYSc6YX07IGFuYW1lPSdhJzsgfVxyXG4gaWYoIWNvbnRleHQpe2NsZWFuX2NvbnRleHQ9dHJ1ZTtjb250ZXh0PVtdO25ld29ianM9W107fVxyXG4gYl9wb3M9Y29udGV4dC5pbmRleE9mKGIpO1xyXG4gaWYoIGJfcG9zPT0tMSApIHtjb250ZXh0LnB1c2goYik7bmV3b2Jqcy5wdXNoKFthcGFyZW50LCBhbmFtZV0pO30gZWxzZSB7IHJldHVybiBuZXdvYmpzW2JfcG9zXVswXVsgbmV3b2Jqc1tiX3Bvc11bMV0gXTsgfVxyXG4gXHJcbiBmb3IgKGtleSBpbiBiKVxyXG4ge1xyXG4gIGlmKGIuaGFzT3duUHJvcGVydHkoa2V5KSlcclxuICB7IFxyXG4gICBpZih0eXBlb2YgYVtrZXldID09PSAndW5kZWZpbmVkJylcclxuICAge1xyXG4gICAgaWYodHlwZW9mIGJba2V5XSA9PT0gJ29iamVjdCcgJiYgbGV2ZWxzPjApXHJcbiAgICB7XHJcbiAgICAgaWYoIGJba2V5XSBpbnN0YW5jZW9mIEFycmF5ICkgLy8gaHR0cDovL2phdmFzY3JpcHQuY3JvY2tmb3JkLmNvbS9yZW1lZGlhbC5odG1sXHJcbiAgICAgeyBhW2tleV0gPSBleHRlbmR1cHRvbGV2ZWwoW10sIGJba2V5XSxsZXZlbHMtMSxjb250ZXh0LG5ld29ianMsYSxrZXksdHJ1ZSk7IH1cclxuICAgICBlbHNlIGlmKGJba2V5XT09PW51bGwpXHJcbiAgICAgeyBhW2tleV0gPSBudWxsOyB9XHJcbiAgICAgZWxzZSBpZiggYltrZXldIGluc3RhbmNlb2YgRGF0ZSApXHJcbiAgICAgeyBhW2tleV09IG5ldyBiW2tleV0uY29uc3RydWN0b3IoKTthW2tleV0uc2V0VGltZShiW2tleV0uZ2V0VGltZSgpKTsgIH1cclxuICAgICBlbHNlXHJcbiAgICAgeyBhW2tleV0gPSBleHRlbmR1cHRvbGV2ZWwoe30sIGJba2V5XSxsZXZlbHMtMSxjb250ZXh0LG5ld29ianMsYSxrZXksdHJ1ZSk7IH1cclxuICAgIH1cclxuICAgIGVsc2VcclxuICAgIHsgIGFba2V5XSA9IGJba2V5XTsgfVxyXG4gICB9XHJcbiAgIGVsc2UgaWYodHlwZW9mIGFba2V5XSA9PT0gJ29iamVjdCcgJiYgYVtrZXldICE9PSBudWxsICYmIGxldmVscz4wKVxyXG4gICB7ICBhW2tleV0gPSBleHRlbmR1cHRvbGV2ZWwoYVtrZXldLCBiW2tleV0sbGV2ZWxzLTEsY29udGV4dCxuZXdvYmpzLGEsa2V5LHRydWUpOyB9XHJcbiAgIGVsc2UgIFxyXG4gICB7ICBhW2tleV0gPSBiW2tleV07IH1cclxuICB9XHJcbiB9XHJcbiBpZihjbGVhbl9jb250ZXh0KSB7Y29udGV4dD1udWxsO25ld29ianM9bnVsbDt9XHJcblxyXG4gaWYoIWhhdmVhcGFyZW50KVxyXG4ge1xyXG4gIGFwYXJlbnQ9bnVsbDtcclxuICByZXR1cm4gYTtcclxuIH1cclxuIGlmKHR5cGVvZiBhID09PSAnb2JqZWN0JyAmJiAhKGEgaW5zdGFuY2VvZiBBcnJheSkgKVxyXG4ge1xyXG4gIC8qYS5jb25zdHJ1Y3RvciA9IGIuY29uc3RydWN0b3I7XHJcbiAgYS5wcm90b3R5cGUgICA9IGIucHJvdG90eXBlOyovXHJcbiB9IFxyXG4gcmV0dXJuIGE7XHJcbn0gZXhwb3J0cy5leHRlbmR1cHRvbGV2ZWw9ZXh0ZW5kdXB0b2xldmVsO1xyXG5cclxuZnVuY3Rpb24gY2xvbmUob2JqKVxyXG57XHJcbiBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpXHJcbiB7XHJcbiAgaWYgKG9iaiA9PT1udWxsICkgeyByZXR1cm4gbnVsbDsgfVxyXG4gIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSApXHJcbiAgeyByZXR1cm4gZXh0ZW5kKFtdLCBvYmopOyB9XHJcbiAgZWxzZSBpZiggb2JqIGluc3RhbmNlb2YgRGF0ZSApXHJcbiAge1xyXG4gICB2YXIgdD0gbmV3IG9iai5jb25zdHJ1Y3RvcigpO1xyXG4gICB0LnNldFRpbWUob2JqLmdldFRpbWUoKSk7XHJcbiAgIHJldHVybiB0O1xyXG4gIH1cclxuICBlbHNlXHJcbiAgeyByZXR1cm4gZXh0ZW5kKHt9LCBvYmopOyB9XHJcbiB9XHJcbiByZXR1cm4gb2JqO1xyXG59IGV4cG9ydHMuY2xvbmU9Y2xvbmU7XHJcblxyXG5mdW5jdGlvbiBjbG9uZWV4dGVuZChvYmosZXh0ZWRkYXRhKVxyXG57XHJcbiBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpXHJcbiB7XHJcbiAgaWYgKG9iaiA9PT1udWxsICkgeyByZXR1cm4gbnVsbDsgfVxyXG4gIHJldHVybiBleHRlbmQoY2xvbmUob2JqKSxleHRlZGRhdGEpO1xyXG4gfVxyXG4gcmV0dXJuIG9iajtcclxufSBleHBvcnRzLmNsb25lZXh0ZW5kPWNsb25lZXh0ZW5kO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGNsb25ldXB0b2xldmVsKG9iaixsZXZlbCkgLy8gY2xvbmUgb25seSBudW1sZXZlbHMgbGV2ZWxzIG90aGVyIGxldmVscyBsZWF2ZSByZWZlcmVuY2VzXHJcbntcclxuIGlmICh0eXBlb2Ygb2JqID09PSAnb2JqZWN0JylcclxuIHtcclxuICBpZiAob2JqID09PW51bGwgKSB7IHJldHVybiBudWxsOyB9XHJcbiAgaWYgKG9iaiBpbnN0YW5jZW9mIEFycmF5ICkgeyByZXR1cm4gZXh0ZW5kdXB0b2xldmVsKFtdLCBvYmosbGV2ZWwpOyB9XHJcbiAgcmV0dXJuIGV4dGVuZHVwdG9sZXZlbCh7fSwgb2JqLGxldmVsKTtcclxuIH1cclxuIHJldHVybiBvYmo7XHJcbn0gZXhwb3J0cy5jbG9uZXVwdG9sZXZlbD1jbG9uZXVwdG9sZXZlbDtcclxuXHJcbmZ1bmN0aW9uIGZvcmVhY2gob2JqZWN0LCBibG9jaywgY29udGV4dClcclxue1xyXG4gaWYgKG9iamVjdClcclxuIHtcclxuICBpZiAodHlwZW9mIG9iamVjdCA9PT0gXCJvYmplY3RcIiAmJiBvYmplY3QgaW5zdGFuY2VvZiBBcnJheSlcclxuICAgcmV0dXJuIG9iamVjdC5mb3JFYWNoKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpXHJcbiAgZWxzZSAvL2lmICh0eXBlb2Ygb2JqZWN0ID09PSBcIm9iamVjdFwiKSAvLyBvciAob2JqZWN0IGluc3RhbmNlb2YgRnVuY3Rpb24pLi4uXHJcbiAge1xyXG4gICBpZihvYmplY3QpXHJcbiAgIGZvciAodmFyIGtleSBpbiBvYmplY3QpXHJcbiAgIHtcclxuICAgIGlmKG9iamVjdC5oYXNPd25Qcm9wZXJ0eShrZXkpKVxyXG4gICAge1xyXG4gICAgIGlmKGJsb2NrLmNhbGwoY29udGV4dCwgb2JqZWN0W2tleV0sIGtleSwgb2JqZWN0KT09PWZhbHNlKWJyZWFrO1xyXG4gICAgfVxyXG4gICB9XHJcbiAgfSAgXHJcbiB9XHJcbn0gZXhwb3J0cy5mb3JlYWNoPWZvcmVhY2g7XHJcblxyXG4vKlxyXG4gaGFzYnVncyBhbmQgdXNlbGVzcywgeWV0IGludGVyZXN0aW5nIG1heWJlIGRldmVsb3BlZCBsYXRlciBmb3IgZG90IHBhdGhlZCBvYmplY3QgdHJhbnNmb3JtYXRpb246XHJcbiBcclxuIHtcclxuICAnZm9vLmJhcic6J2JsdWViYXInLFxyXG4gICdmb28uY29sb3InOidibHVlJ1xyXG4gfVxyXG4gXHJcbiB0cmFuc2ZvcmVtZWQgdG9cclxuIFxyXG4ge1xyXG4gIGZvbzpcclxuICB7XHJcbiAgIGJhcjonYmx1ZWJhcicsXHJcbiAgIGNvbG9yOidibHVlJ1xyXG4gIH1cclxuIH1cclxuIFxyXG4gbGlrZTpcclxuIFxyXG4gdmFyIGNvbmZpZz17fTtcclxuIGNsb25lZXh0ZW5kLmRvdHBhdGgoY29uZmlnLHtcclxuICAnZm9vLmJhcic6J2JsdWViYXInLFxyXG4gICdmb28uY29sb3InOidibHVlJ1xyXG4gfSlcclxuIFxyXG4gLy9cclxuIGZ1bmN0aW9uIGRvdHBhdGgoZGF0YSxkb3RrZXlzLHByZXNlcnZlKVxyXG4ge1xyXG4gICAgICBpZighcHJlc2VydmUpcHJlc2VydmU9ZmFsc2U7XHJcbiAgICAgIHZhciBjcmVhdGU9IXByZXNlcnZlO1xyXG4gICAgICBpZihjcmVhdGUpIGlmKCFkYXRhKSBkYXRhPXt9O1xyXG4gICAgICB2YXIga2V5cz0gZG90a2V5cy5zcGxpdChcIi5cIiksdmFsdWU9ZGF0YTtcclxuICAgICAgZm9yICh2YXIgaT0wO2k8a2V5cy5sZW5ndGg7aSsrKVxyXG4gICAgICB7XHJcbiAgICAgICAgICBpZighdmFsdWVba2V5c1tpXV0pIC8vc2hvdWxkIHlvdSBjcmVhdGUgb25lP1xyXG4gICAgICAgICAge1xyXG4gICAgICAgICAgICAgIGlmKGNyZWF0ZSlcclxuICAgICAgICAgICAgICAgICAgdmFsdWVba2V5c1tpXV09e307XHJcbiAgICAgICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtrZXlzW2ldXTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdmFsdWU7XHJcbiB9XHJcbiAqLyIsInZhciBCdWZmZXI9cmVxdWlyZShcIl9fYnJvd3NlcmlmeV9CdWZmZXJcIikuQnVmZmVyOy8qIVxuICogTm9kZS5KUyBtb2R1bGUgXCJEZWVwIEV4dGVuZFwiXG4gKiBAZGVzY3JpcHRpb24gUmVjdXJzaXZlIG9iamVjdCBleHRlbmRpbmcuXG4gKiBAYXV0aG9yIFZpYWNoZXNsYXYgTG90c21hbm92ICh1bmNsZWNodSkgPGxvdHNtYW5vdjg5QGdtYWlsLmNvbT5cbiAqIEBsaWNlbnNlIE1JVFxuICpcbiAqIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxuICpcbiAqIENvcHlyaWdodCAoYykgMjAxMyBWaWFjaGVzbGF2IExvdHNtYW5vdlxuICpcbiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkgb2ZcbiAqIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW5cbiAqIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG9cbiAqIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mXG4gKiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sXG4gKiBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiAqXG4gKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiAqIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4gKlxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1NcbiAqIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUlxuICogQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSXG4gKiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTlxuICogQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cbiAqL1xuXG4vKipcbiAqIEV4dGVuaW5nIG9iamVjdCB0aGF0IGVudGVyZWQgaW4gZmlyc3QgYXJndW1lbnQuXG4gKiBSZXR1cm5zIGV4dGVuZGVkIG9iamVjdCBvciBmYWxzZSBpZiBoYXZlIG5vIHRhcmdldCBvYmplY3Qgb3IgaW5jb3JyZWN0IHR5cGUuXG4gKiBJZiB5b3Ugd2lzaCB0byBjbG9uZSBvYmplY3QsIHNpbXBseSB1c2UgdGhhdDpcbiAqICBkZWVwRXh0ZW5kKHt9LCB5b3VyT2JqXzEsIFt5b3VyT2JqX05dKSAtIGZpcnN0IGFyZyBpcyBuZXcgZW1wdHkgb2JqZWN0XG4gKi9cbnZhciBkZWVwRXh0ZW5kID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoLypvYmpfMSwgW29ial8yXSwgW29ial9OXSovKSB7XG5cdGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMSB8fCB0eXBlb2YgYXJndW1lbnRzWzBdICE9PSAnb2JqZWN0Jykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgcmV0dXJuIGFyZ3VtZW50c1swXTtcblxuXHR2YXIgdGFyZ2V0ID0gYXJndW1lbnRzWzBdO1xuXG5cdC8vIGNvbnZlcnQgYXJndW1lbnRzIHRvIGFycmF5IGFuZCBjdXQgb2ZmIHRhcmdldCBvYmplY3Rcblx0dmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG5cdHZhciBrZXksIHZhbCwgc3JjLCBjbG9uZSwgdG1wQnVmO1xuXG5cdGFyZ3MuZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG5cdFx0aWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSByZXR1cm47XG5cblx0XHRmb3IgKGtleSBpbiBvYmopIHtcblx0XHRcdGlmICggISAoa2V5IGluIG9iaikpIGNvbnRpbnVlO1xuXG5cdFx0XHRzcmMgPSB0YXJnZXRba2V5XTtcblx0XHRcdHZhbCA9IG9ialtrZXldO1xuXG5cdFx0XHRpZiAodmFsID09PSB0YXJnZXQpIGNvbnRpbnVlO1xuXG5cdFx0XHRpZiAodHlwZW9mIHZhbCAhPT0gJ29iamVjdCcgfHwgdmFsID09PSBudWxsKSB7XG5cdFx0XHRcdHRhcmdldFtrZXldID0gdmFsO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgQnVmZmVyKSB7XG5cdFx0XHRcdHRtcEJ1ZiA9IG5ldyBCdWZmZXIodmFsLmxlbmd0aCk7XG5cdFx0XHRcdHZhbC5jb3B5KHRtcEJ1Zik7XG5cdFx0XHRcdHRhcmdldFtrZXldID0gdG1wQnVmO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgRGF0ZSkge1xuXHRcdFx0XHR0YXJnZXRba2V5XSA9IG5ldyBEYXRlKHZhbC5nZXRUaW1lKCkpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKHR5cGVvZiBzcmMgIT09ICdvYmplY3QnIHx8IHNyYyA9PT0gbnVsbCkge1xuXHRcdFx0XHRjbG9uZSA9IChBcnJheS5pc0FycmF5KHZhbCkpID8gW10gOiB7fTtcblx0XHRcdFx0dGFyZ2V0W2tleV0gPSBkZWVwRXh0ZW5kKGNsb25lLCB2YWwpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuXHRcdFx0XHRjbG9uZSA9IChBcnJheS5pc0FycmF5KHNyYykpID8gc3JjIDogW107XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjbG9uZSA9ICghQXJyYXkuaXNBcnJheShzcmMpKSA/IHNyYyA6IHt9O1xuXHRcdFx0fVxuXG5cdFx0XHR0YXJnZXRba2V5XSA9IGRlZXBFeHRlbmQoY2xvbmUsIHZhbCk7XG5cdFx0fVxuXHR9KTtcblxuXHRyZXR1cm4gdGFyZ2V0O1xufVxuIiwiLyohXG4gKiBFdmVudEVtaXR0ZXIyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vaGlqMW54L0V2ZW50RW1pdHRlcjJcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTMgaGlqMW54XG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuXG4gKi9cbjshZnVuY3Rpb24odW5kZWZpbmVkKSB7XG5cbiAgdmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5ID8gQXJyYXkuaXNBcnJheSA6IGZ1bmN0aW9uIF9pc0FycmF5KG9iaikge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gXCJbb2JqZWN0IEFycmF5XVwiO1xuICB9O1xuICB2YXIgZGVmYXVsdE1heExpc3RlbmVycyA9IDEwO1xuXG4gIGZ1bmN0aW9uIGluaXQoKSB7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgaWYgKHRoaXMuX2NvbmYpIHtcbiAgICAgIGNvbmZpZ3VyZS5jYWxsKHRoaXMsIHRoaXMuX2NvbmYpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbmZpZ3VyZShjb25mKSB7XG4gICAgaWYgKGNvbmYpIHtcblxuICAgICAgdGhpcy5fY29uZiA9IGNvbmY7XG5cbiAgICAgIGNvbmYuZGVsaW1pdGVyICYmICh0aGlzLmRlbGltaXRlciA9IGNvbmYuZGVsaW1pdGVyKTtcbiAgICAgIGNvbmYubWF4TGlzdGVuZXJzICYmICh0aGlzLl9ldmVudHMubWF4TGlzdGVuZXJzID0gY29uZi5tYXhMaXN0ZW5lcnMpO1xuICAgICAgY29uZi53aWxkY2FyZCAmJiAodGhpcy53aWxkY2FyZCA9IGNvbmYud2lsZGNhcmQpO1xuICAgICAgY29uZi5uZXdMaXN0ZW5lciAmJiAodGhpcy5uZXdMaXN0ZW5lciA9IGNvbmYubmV3TGlzdGVuZXIpO1xuXG4gICAgICBpZiAodGhpcy53aWxkY2FyZCkge1xuICAgICAgICB0aGlzLmxpc3RlbmVyVHJlZSA9IHt9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIEV2ZW50RW1pdHRlcihjb25mKSB7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgdGhpcy5uZXdMaXN0ZW5lciA9IGZhbHNlO1xuICAgIGNvbmZpZ3VyZS5jYWxsKHRoaXMsIGNvbmYpO1xuICB9XG5cbiAgLy9cbiAgLy8gQXR0ZW50aW9uLCBmdW5jdGlvbiByZXR1cm4gdHlwZSBub3cgaXMgYXJyYXksIGFsd2F5cyAhXG4gIC8vIEl0IGhhcyB6ZXJvIGVsZW1lbnRzIGlmIG5vIGFueSBtYXRjaGVzIGZvdW5kIGFuZCBvbmUgb3IgbW9yZVxuICAvLyBlbGVtZW50cyAobGVhZnMpIGlmIHRoZXJlIGFyZSBtYXRjaGVzXG4gIC8vXG4gIGZ1bmN0aW9uIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgdHJlZSwgaSkge1xuICAgIGlmICghdHJlZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICB2YXIgbGlzdGVuZXJzPVtdLCBsZWFmLCBsZW4sIGJyYW5jaCwgeFRyZWUsIHh4VHJlZSwgaXNvbGF0ZWRCcmFuY2gsIGVuZFJlYWNoZWQsXG4gICAgICAgIHR5cGVMZW5ndGggPSB0eXBlLmxlbmd0aCwgY3VycmVudFR5cGUgPSB0eXBlW2ldLCBuZXh0VHlwZSA9IHR5cGVbaSsxXTtcbiAgICBpZiAoaSA9PT0gdHlwZUxlbmd0aCAmJiB0cmVlLl9saXN0ZW5lcnMpIHtcbiAgICAgIC8vXG4gICAgICAvLyBJZiBhdCB0aGUgZW5kIG9mIHRoZSBldmVudChzKSBsaXN0IGFuZCB0aGUgdHJlZSBoYXMgbGlzdGVuZXJzXG4gICAgICAvLyBpbnZva2UgdGhvc2UgbGlzdGVuZXJzLlxuICAgICAgLy9cbiAgICAgIGlmICh0eXBlb2YgdHJlZS5fbGlzdGVuZXJzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGhhbmRsZXJzICYmIGhhbmRsZXJzLnB1c2godHJlZS5fbGlzdGVuZXJzKTtcbiAgICAgICAgcmV0dXJuIFt0cmVlXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGVhZiA9IDAsIGxlbiA9IHRyZWUuX2xpc3RlbmVycy5sZW5ndGg7IGxlYWYgPCBsZW47IGxlYWYrKykge1xuICAgICAgICAgIGhhbmRsZXJzICYmIGhhbmRsZXJzLnB1c2godHJlZS5fbGlzdGVuZXJzW2xlYWZdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3RyZWVdO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICgoY3VycmVudFR5cGUgPT09ICcqJyB8fCBjdXJyZW50VHlwZSA9PT0gJyoqJykgfHwgdHJlZVtjdXJyZW50VHlwZV0pIHtcbiAgICAgIC8vXG4gICAgICAvLyBJZiB0aGUgZXZlbnQgZW1pdHRlZCBpcyAnKicgYXQgdGhpcyBwYXJ0XG4gICAgICAvLyBvciB0aGVyZSBpcyBhIGNvbmNyZXRlIG1hdGNoIGF0IHRoaXMgcGF0Y2hcbiAgICAgIC8vXG4gICAgICBpZiAoY3VycmVudFR5cGUgPT09ICcqJykge1xuICAgICAgICBmb3IgKGJyYW5jaCBpbiB0cmVlKSB7XG4gICAgICAgICAgaWYgKGJyYW5jaCAhPT0gJ19saXN0ZW5lcnMnICYmIHRyZWUuaGFzT3duUHJvcGVydHkoYnJhbmNoKSkge1xuICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmNvbmNhdChzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHRyZWVbYnJhbmNoXSwgaSsxKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsaXN0ZW5lcnM7XG4gICAgICB9IGVsc2UgaWYoY3VycmVudFR5cGUgPT09ICcqKicpIHtcbiAgICAgICAgZW5kUmVhY2hlZCA9IChpKzEgPT09IHR5cGVMZW5ndGggfHwgKGkrMiA9PT0gdHlwZUxlbmd0aCAmJiBuZXh0VHlwZSA9PT0gJyonKSk7XG4gICAgICAgIGlmKGVuZFJlYWNoZWQgJiYgdHJlZS5fbGlzdGVuZXJzKSB7XG4gICAgICAgICAgLy8gVGhlIG5leHQgZWxlbWVudCBoYXMgYSBfbGlzdGVuZXJzLCBhZGQgaXQgdG8gdGhlIGhhbmRsZXJzLlxuICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlLCB0eXBlTGVuZ3RoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGJyYW5jaCBpbiB0cmVlKSB7XG4gICAgICAgICAgaWYgKGJyYW5jaCAhPT0gJ19saXN0ZW5lcnMnICYmIHRyZWUuaGFzT3duUHJvcGVydHkoYnJhbmNoKSkge1xuICAgICAgICAgICAgaWYoYnJhbmNoID09PSAnKicgfHwgYnJhbmNoID09PSAnKionKSB7XG4gICAgICAgICAgICAgIGlmKHRyZWVbYnJhbmNoXS5fbGlzdGVuZXJzICYmICFlbmRSZWFjaGVkKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmNvbmNhdChzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHRyZWVbYnJhbmNoXSwgdHlwZUxlbmd0aCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlW2JyYW5jaF0sIGkpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZihicmFuY2ggPT09IG5leHRUeXBlKSB7XG4gICAgICAgICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5jb25jYXQoc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB0cmVlW2JyYW5jaF0sIGkrMikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gTm8gbWF0Y2ggb24gdGhpcyBvbmUsIHNoaWZ0IGludG8gdGhlIHRyZWUgYnV0IG5vdCBpbiB0aGUgdHlwZSBhcnJheS5cbiAgICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmNvbmNhdChzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHRyZWVbYnJhbmNoXSwgaSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbGlzdGVuZXJzO1xuICAgICAgfVxuXG4gICAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuY29uY2F0KHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgdHJlZVtjdXJyZW50VHlwZV0sIGkrMSkpO1xuICAgIH1cblxuICAgIHhUcmVlID0gdHJlZVsnKiddO1xuICAgIGlmICh4VHJlZSkge1xuICAgICAgLy9cbiAgICAgIC8vIElmIHRoZSBsaXN0ZW5lciB0cmVlIHdpbGwgYWxsb3cgYW55IG1hdGNoIGZvciB0aGlzIHBhcnQsXG4gICAgICAvLyB0aGVuIHJlY3Vyc2l2ZWx5IGV4cGxvcmUgYWxsIGJyYW5jaGVzIG9mIHRoZSB0cmVlXG4gICAgICAvL1xuICAgICAgc2VhcmNoTGlzdGVuZXJUcmVlKGhhbmRsZXJzLCB0eXBlLCB4VHJlZSwgaSsxKTtcbiAgICB9XG5cbiAgICB4eFRyZWUgPSB0cmVlWycqKiddO1xuICAgIGlmKHh4VHJlZSkge1xuICAgICAgaWYoaSA8IHR5cGVMZW5ndGgpIHtcbiAgICAgICAgaWYoeHhUcmVlLl9saXN0ZW5lcnMpIHtcbiAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGEgbGlzdGVuZXIgb24gYSAnKionLCBpdCB3aWxsIGNhdGNoIGFsbCwgc28gYWRkIGl0cyBoYW5kbGVyLlxuICAgICAgICAgIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgeHhUcmVlLCB0eXBlTGVuZ3RoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJ1aWxkIGFycmF5cyBvZiBtYXRjaGluZyBuZXh0IGJyYW5jaGVzIGFuZCBvdGhlcnMuXG4gICAgICAgIGZvcihicmFuY2ggaW4geHhUcmVlKSB7XG4gICAgICAgICAgaWYoYnJhbmNoICE9PSAnX2xpc3RlbmVycycgJiYgeHhUcmVlLmhhc093blByb3BlcnR5KGJyYW5jaCkpIHtcbiAgICAgICAgICAgIGlmKGJyYW5jaCA9PT0gbmV4dFR5cGUpIHtcbiAgICAgICAgICAgICAgLy8gV2Uga25vdyB0aGUgbmV4dCBlbGVtZW50IHdpbGwgbWF0Y2gsIHNvIGp1bXAgdHdpY2UuXG4gICAgICAgICAgICAgIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgeHhUcmVlW2JyYW5jaF0sIGkrMik7XG4gICAgICAgICAgICB9IGVsc2UgaWYoYnJhbmNoID09PSBjdXJyZW50VHlwZSkge1xuICAgICAgICAgICAgICAvLyBDdXJyZW50IG5vZGUgbWF0Y2hlcywgbW92ZSBpbnRvIHRoZSB0cmVlLlxuICAgICAgICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHh4VHJlZVticmFuY2hdLCBpKzEpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaXNvbGF0ZWRCcmFuY2ggPSB7fTtcbiAgICAgICAgICAgICAgaXNvbGF0ZWRCcmFuY2hbYnJhbmNoXSA9IHh4VHJlZVticmFuY2hdO1xuICAgICAgICAgICAgICBzZWFyY2hMaXN0ZW5lclRyZWUoaGFuZGxlcnMsIHR5cGUsIHsgJyoqJzogaXNvbGF0ZWRCcmFuY2ggfSwgaSsxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZih4eFRyZWUuX2xpc3RlbmVycykge1xuICAgICAgICAvLyBXZSBoYXZlIHJlYWNoZWQgdGhlIGVuZCBhbmQgc3RpbGwgb24gYSAnKionXG4gICAgICAgIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgeHhUcmVlLCB0eXBlTGVuZ3RoKTtcbiAgICAgIH0gZWxzZSBpZih4eFRyZWVbJyonXSAmJiB4eFRyZWVbJyonXS5fbGlzdGVuZXJzKSB7XG4gICAgICAgIHNlYXJjaExpc3RlbmVyVHJlZShoYW5kbGVycywgdHlwZSwgeHhUcmVlWycqJ10sIHR5cGVMZW5ndGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsaXN0ZW5lcnM7XG4gIH1cblxuICBmdW5jdGlvbiBncm93TGlzdGVuZXJUcmVlKHR5cGUsIGxpc3RlbmVyKSB7XG5cbiAgICB0eXBlID0gdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnID8gdHlwZS5zcGxpdCh0aGlzLmRlbGltaXRlcikgOiB0eXBlLnNsaWNlKCk7XG5cbiAgICAvL1xuICAgIC8vIExvb2tzIGZvciB0d28gY29uc2VjdXRpdmUgJyoqJywgaWYgc28sIGRvbid0IGFkZCB0aGUgZXZlbnQgYXQgYWxsLlxuICAgIC8vXG4gICAgZm9yKHZhciBpID0gMCwgbGVuID0gdHlwZS5sZW5ndGg7IGkrMSA8IGxlbjsgaSsrKSB7XG4gICAgICBpZih0eXBlW2ldID09PSAnKionICYmIHR5cGVbaSsxXSA9PT0gJyoqJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRyZWUgPSB0aGlzLmxpc3RlbmVyVHJlZTtcbiAgICB2YXIgbmFtZSA9IHR5cGUuc2hpZnQoKTtcblxuICAgIHdoaWxlIChuYW1lKSB7XG5cbiAgICAgIGlmICghdHJlZVtuYW1lXSkge1xuICAgICAgICB0cmVlW25hbWVdID0ge307XG4gICAgICB9XG5cbiAgICAgIHRyZWUgPSB0cmVlW25hbWVdO1xuXG4gICAgICBpZiAodHlwZS5sZW5ndGggPT09IDApIHtcblxuICAgICAgICBpZiAoIXRyZWUuX2xpc3RlbmVycykge1xuICAgICAgICAgIHRyZWUuX2xpc3RlbmVycyA9IGxpc3RlbmVyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodHlwZW9mIHRyZWUuX2xpc3RlbmVycyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRyZWUuX2xpc3RlbmVycyA9IFt0cmVlLl9saXN0ZW5lcnMsIGxpc3RlbmVyXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0FycmF5KHRyZWUuX2xpc3RlbmVycykpIHtcblxuICAgICAgICAgIHRyZWUuX2xpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblxuICAgICAgICAgIGlmICghdHJlZS5fbGlzdGVuZXJzLndhcm5lZCkge1xuXG4gICAgICAgICAgICB2YXIgbSA9IGRlZmF1bHRNYXhMaXN0ZW5lcnM7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5fZXZlbnRzLm1heExpc3RlbmVycyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgbSA9IHRoaXMuX2V2ZW50cy5tYXhMaXN0ZW5lcnM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtID4gMCAmJiB0cmVlLl9saXN0ZW5lcnMubGVuZ3RoID4gbSkge1xuXG4gICAgICAgICAgICAgIHRyZWUuX2xpc3RlbmVycy53YXJuZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCcobm9kZSkgd2FybmluZzogcG9zc2libGUgRXZlbnRFbWl0dGVyIG1lbW9yeSAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlLl9saXN0ZW5lcnMubGVuZ3RoKTtcbiAgICAgICAgICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIG5hbWUgPSB0eXBlLnNoaWZ0KCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhblxuICAvLyAxMCBsaXN0ZW5lcnMgYXJlIGFkZGVkIHRvIGl0LiBUaGlzIGlzIGEgdXNlZnVsIGRlZmF1bHQgd2hpY2hcbiAgLy8gaGVscHMgZmluZGluZyBtZW1vcnkgbGVha3MuXG4gIC8vXG4gIC8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuICAvLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmRlbGltaXRlciA9ICcuJztcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgICB0aGlzLl9ldmVudHMgfHwgaW5pdC5jYWxsKHRoaXMpO1xuICAgIHRoaXMuX2V2ZW50cy5tYXhMaXN0ZW5lcnMgPSBuO1xuICAgIGlmICghdGhpcy5fY29uZikgdGhpcy5fY29uZiA9IHt9O1xuICAgIHRoaXMuX2NvbmYubWF4TGlzdGVuZXJzID0gbjtcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50ID0gJyc7XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgdGhpcy5tYW55KGV2ZW50LCAxLCBmbik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5tYW55ID0gZnVuY3Rpb24oZXZlbnQsIHR0bCwgZm4pIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21hbnkgb25seSBhY2NlcHRzIGluc3RhbmNlcyBvZiBGdW5jdGlvbicpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpc3RlbmVyKCkge1xuICAgICAgaWYgKC0tdHRsID09PSAwKSB7XG4gICAgICAgIHNlbGYub2ZmKGV2ZW50LCBsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgICBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIGxpc3RlbmVyLl9vcmlnaW4gPSBmbjtcblxuICAgIHRoaXMub24oZXZlbnQsIGxpc3RlbmVyKTtcblxuICAgIHJldHVybiBzZWxmO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKCkge1xuXG4gICAgdGhpcy5fZXZlbnRzIHx8IGluaXQuY2FsbCh0aGlzKTtcblxuICAgIHZhciB0eXBlID0gYXJndW1lbnRzWzBdO1xuXG4gICAgaWYgKHR5cGUgPT09ICduZXdMaXN0ZW5lcicgJiYgIXRoaXMubmV3TGlzdGVuZXIpIHtcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIH1cblxuICAgIC8vIExvb3AgdGhyb3VnaCB0aGUgKl9hbGwqIGZ1bmN0aW9ucyBhbmQgaW52b2tlIHRoZW0uXG4gICAgaWYgKHRoaXMuX2FsbCkge1xuICAgICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobCAtIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsOyBpKyspIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yIChpID0gMCwgbCA9IHRoaXMuX2FsbC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgdGhpcy5ldmVudCA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2FsbFtpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gICAgaWYgKHR5cGUgPT09ICdlcnJvcicpIHtcblxuICAgICAgaWYgKCF0aGlzLl9hbGwgJiZcbiAgICAgICAgIXRoaXMuX2V2ZW50cy5lcnJvciAmJlxuICAgICAgICAhKHRoaXMud2lsZGNhcmQgJiYgdGhpcy5saXN0ZW5lclRyZWUuZXJyb3IpKSB7XG5cbiAgICAgICAgaWYgKGFyZ3VtZW50c1sxXSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgYXJndW1lbnRzWzFdOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuY2F1Z2h0LCB1bnNwZWNpZmllZCAnZXJyb3InIGV2ZW50LlwiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGhhbmRsZXI7XG5cbiAgICBpZih0aGlzLndpbGRjYXJkKSB7XG4gICAgICBoYW5kbGVyID0gW107XG4gICAgICB2YXIgbnMgPSB0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycgPyB0eXBlLnNwbGl0KHRoaXMuZGVsaW1pdGVyKSA6IHR5cGUuc2xpY2UoKTtcbiAgICAgIHNlYXJjaExpc3RlbmVyVHJlZS5jYWxsKHRoaXMsIGhhbmRsZXIsIG5zLCB0aGlzLmxpc3RlbmVyVHJlZSwgMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgaGFuZGxlciA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuZXZlbnQgPSB0eXBlO1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIHNsb3dlclxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB2YXIgbCA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgICAgICAgICB2YXIgYXJncyA9IG5ldyBBcnJheShsIC0gMSk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGw7IGkrKykgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaGFuZGxlcikge1xuICAgICAgdmFyIGwgPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgdmFyIGFyZ3MgPSBuZXcgQXJyYXkobCAtIDEpO1xuICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsOyBpKyspIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICB2YXIgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHRoaXMuZXZlbnQgPSB0eXBlO1xuICAgICAgICBsaXN0ZW5lcnNbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gKGxpc3RlbmVycy5sZW5ndGggPiAwKSB8fCAhIXRoaXMuX2FsbDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICByZXR1cm4gISF0aGlzLl9hbGw7XG4gICAgfVxuXG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG5cbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMub25BbnkodHlwZSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29uIG9ubHkgYWNjZXB0cyBpbnN0YW5jZXMgb2YgRnVuY3Rpb24nKTtcbiAgICB9XG4gICAgdGhpcy5fZXZlbnRzIHx8IGluaXQuY2FsbCh0aGlzKTtcblxuICAgIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT0gXCJuZXdMaXN0ZW5lcnNcIiEgQmVmb3JlXG4gICAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lcnNcIi5cbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgZ3Jvd0xpc3RlbmVyVHJlZS5jYWxsKHRoaXMsIHR5cGUsIGxpc3RlbmVyKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKSB7XG4gICAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IGxpc3RlbmVyO1xuICAgIH1cbiAgICBlbHNlIGlmKHR5cGVvZiB0aGlzLl9ldmVudHNbdHlwZV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIEFkZGluZyB0aGUgc2Vjb25kIGVsZW1lbnQsIG5lZWQgdG8gY2hhbmdlIHRvIGFycmF5LlxuICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc0FycmF5KHRoaXMuX2V2ZW50c1t0eXBlXSkpIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5wdXNoKGxpc3RlbmVyKTtcblxuICAgICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdLndhcm5lZCkge1xuXG4gICAgICAgIHZhciBtID0gZGVmYXVsdE1heExpc3RlbmVycztcblxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2V2ZW50cy5tYXhMaXN0ZW5lcnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgbSA9IHRoaXMuX2V2ZW50cy5tYXhMaXN0ZW5lcnM7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcblxuICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2xlYWsgZGV0ZWN0ZWQuICVkIGxpc3RlbmVycyBhZGRlZC4gJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgICAgIGNvbnNvbGUudHJhY2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uQW55ID0gZnVuY3Rpb24oZm4pIHtcblxuICAgIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb25Bbnkgb25seSBhY2NlcHRzIGluc3RhbmNlcyBvZiBGdW5jdGlvbicpO1xuICAgIH1cblxuICAgIGlmKCF0aGlzLl9hbGwpIHtcbiAgICAgIHRoaXMuX2FsbCA9IFtdO1xuICAgIH1cblxuICAgIC8vIEFkZCB0aGUgZnVuY3Rpb24gdG8gdGhlIGV2ZW50IGxpc3RlbmVyIGNvbGxlY3Rpb24uXG4gICAgdGhpcy5fYWxsLnB1c2goZm4pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uO1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3JlbW92ZUxpc3RlbmVyIG9ubHkgdGFrZXMgaW5zdGFuY2VzIG9mIEZ1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgdmFyIGhhbmRsZXJzLGxlYWZzPVtdO1xuXG4gICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgdmFyIG5zID0gdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnID8gdHlwZS5zcGxpdCh0aGlzLmRlbGltaXRlcikgOiB0eXBlLnNsaWNlKCk7XG4gICAgICBsZWFmcyA9IHNlYXJjaExpc3RlbmVyVHJlZS5jYWxsKHRoaXMsIG51bGwsIG5zLCB0aGlzLmxpc3RlbmVyVHJlZSwgMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgLy8gZG9lcyBub3QgdXNlIGxpc3RlbmVycygpLCBzbyBubyBzaWRlIGVmZmVjdCBvZiBjcmVhdGluZyBfZXZlbnRzW3R5cGVdXG4gICAgICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSkgcmV0dXJuIHRoaXM7XG4gICAgICBoYW5kbGVycyA9IHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICAgIGxlYWZzLnB1c2goe19saXN0ZW5lcnM6aGFuZGxlcnN9KTtcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpTGVhZj0wOyBpTGVhZjxsZWFmcy5sZW5ndGg7IGlMZWFmKyspIHtcbiAgICAgIHZhciBsZWFmID0gbGVhZnNbaUxlYWZdO1xuICAgICAgaGFuZGxlcnMgPSBsZWFmLl9saXN0ZW5lcnM7XG4gICAgICBpZiAoaXNBcnJheShoYW5kbGVycykpIHtcblxuICAgICAgICB2YXIgcG9zaXRpb24gPSAtMTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gaGFuZGxlcnMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAoaGFuZGxlcnNbaV0gPT09IGxpc3RlbmVyIHx8XG4gICAgICAgICAgICAoaGFuZGxlcnNbaV0ubGlzdGVuZXIgJiYgaGFuZGxlcnNbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB8fFxuICAgICAgICAgICAgKGhhbmRsZXJzW2ldLl9vcmlnaW4gJiYgaGFuZGxlcnNbaV0uX29yaWdpbiA9PT0gbGlzdGVuZXIpKSB7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocG9zaXRpb24gPCAwKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZih0aGlzLndpbGRjYXJkKSB7XG4gICAgICAgICAgbGVhZi5fbGlzdGVuZXJzLnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLnNwbGljZShwb3NpdGlvbiwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFuZGxlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgICAgICAgZGVsZXRlIGxlYWYuX2xpc3RlbmVycztcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGhhbmRsZXJzID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAoaGFuZGxlcnMubGlzdGVuZXIgJiYgaGFuZGxlcnMubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB8fFxuICAgICAgICAoaGFuZGxlcnMuX29yaWdpbiAmJiBoYW5kbGVycy5fb3JpZ2luID09PSBsaXN0ZW5lcikpIHtcbiAgICAgICAgaWYodGhpcy53aWxkY2FyZCkge1xuICAgICAgICAgIGRlbGV0ZSBsZWFmLl9saXN0ZW5lcnM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmQW55ID0gZnVuY3Rpb24oZm4pIHtcbiAgICB2YXIgaSA9IDAsIGwgPSAwLCBmbnM7XG4gICAgaWYgKGZuICYmIHRoaXMuX2FsbCAmJiB0aGlzLl9hbGwubGVuZ3RoID4gMCkge1xuICAgICAgZm5zID0gdGhpcy5fYWxsO1xuICAgICAgZm9yKGkgPSAwLCBsID0gZm5zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICBpZihmbiA9PT0gZm5zW2ldKSB7XG4gICAgICAgICAgZm5zLnNwbGljZShpLCAxKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hbGwgPSBbXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmO1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlQWxsTGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAhdGhpcy5fZXZlbnRzIHx8IGluaXQuY2FsbCh0aGlzKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgIHZhciBucyA9IHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJyA/IHR5cGUuc3BsaXQodGhpcy5kZWxpbWl0ZXIpIDogdHlwZS5zbGljZSgpO1xuICAgICAgdmFyIGxlYWZzID0gc2VhcmNoTGlzdGVuZXJUcmVlLmNhbGwodGhpcywgbnVsbCwgbnMsIHRoaXMubGlzdGVuZXJUcmVlLCAwKTtcblxuICAgICAgZm9yICh2YXIgaUxlYWY9MDsgaUxlYWY8bGVhZnMubGVuZ3RoOyBpTGVhZisrKSB7XG4gICAgICAgIHZhciBsZWFmID0gbGVhZnNbaUxlYWZdO1xuICAgICAgICBsZWFmLl9saXN0ZW5lcnMgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5fZXZlbnRzW3R5cGVdKSByZXR1cm4gdGhpcztcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXSA9IG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIEV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICAgIGlmKHRoaXMud2lsZGNhcmQpIHtcbiAgICAgIHZhciBoYW5kbGVycyA9IFtdO1xuICAgICAgdmFyIG5zID0gdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnID8gdHlwZS5zcGxpdCh0aGlzLmRlbGltaXRlcikgOiB0eXBlLnNsaWNlKCk7XG4gICAgICBzZWFyY2hMaXN0ZW5lclRyZWUuY2FsbCh0aGlzLCBoYW5kbGVycywgbnMsIHRoaXMubGlzdGVuZXJUcmVlLCAwKTtcbiAgICAgIHJldHVybiBoYW5kbGVycztcbiAgICB9XG5cbiAgICB0aGlzLl9ldmVudHMgfHwgaW5pdC5jYWxsKHRoaXMpO1xuXG4gICAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pIHRoaXMuX2V2ZW50c1t0eXBlXSA9IFtdO1xuICAgIGlmICghaXNBcnJheSh0aGlzLl9ldmVudHNbdHlwZV0pKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgfTtcblxuICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVyc0FueSA9IGZ1bmN0aW9uKCkge1xuXG4gICAgaWYodGhpcy5fYWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYWxsO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgfTtcblxuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgIC8vIEFNRC4gUmVnaXN0ZXIgYXMgYW4gYW5vbnltb3VzIG1vZHVsZS5cbiAgICBkZWZpbmUoZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgIC8vIENvbW1vbkpTXG4gICAgZXhwb3J0cy5FdmVudEVtaXR0ZXIyID0gRXZlbnRFbWl0dGVyO1xuICB9XG4gIGVsc2Uge1xuICAgIC8vIEJyb3dzZXIgZ2xvYmFsLlxuICAgIHdpbmRvdy5FdmVudEVtaXR0ZXIyID0gRXZlbnRFbWl0dGVyO1xuICB9XG59KCk7XG4iLCJcblxuLy9cbi8vIFRoZSBzaGltcyBpbiB0aGlzIGZpbGUgYXJlIG5vdCBmdWxseSBpbXBsZW1lbnRlZCBzaGltcyBmb3IgdGhlIEVTNVxuLy8gZmVhdHVyZXMsIGJ1dCBkbyB3b3JrIGZvciB0aGUgcGFydGljdWxhciB1c2VjYXNlcyB0aGVyZSBpcyBpblxuLy8gdGhlIG90aGVyIG1vZHVsZXMuXG4vL1xuXG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLy8gQXJyYXkuaXNBcnJheSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5mdW5jdGlvbiBpc0FycmF5KHhzKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKHhzKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cbmV4cG9ydHMuaXNBcnJheSA9IHR5cGVvZiBBcnJheS5pc0FycmF5ID09PSAnZnVuY3Rpb24nID8gQXJyYXkuaXNBcnJheSA6IGlzQXJyYXk7XG5cbi8vIEFycmF5LnByb3RvdHlwZS5pbmRleE9mIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuaW5kZXhPZiA9IGZ1bmN0aW9uIGluZGV4T2YoeHMsIHgpIHtcbiAgaWYgKHhzLmluZGV4T2YpIHJldHVybiB4cy5pbmRleE9mKHgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHggPT09IHhzW2ldKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59O1xuXG4vLyBBcnJheS5wcm90b3R5cGUuZmlsdGVyIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMuZmlsdGVyID0gZnVuY3Rpb24gZmlsdGVyKHhzLCBmbikge1xuICBpZiAoeHMuZmlsdGVyKSByZXR1cm4geHMuZmlsdGVyKGZuKTtcbiAgdmFyIHJlcyA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGZuKHhzW2ldLCBpLCB4cykpIHJlcy5wdXNoKHhzW2ldKTtcbiAgfVxuICByZXR1cm4gcmVzO1xufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLmZvckVhY2ggaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaCh4cywgZm4sIHNlbGYpIHtcbiAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuLCBzZWxmKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIGZuLmNhbGwoc2VsZiwgeHNbaV0sIGksIHhzKTtcbiAgfVxufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLm1hcCBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLm1hcCA9IGZ1bmN0aW9uIG1hcCh4cywgZm4pIHtcbiAgaWYgKHhzLm1hcCkgcmV0dXJuIHhzLm1hcChmbik7XG4gIHZhciBvdXQgPSBuZXcgQXJyYXkoeHMubGVuZ3RoKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgIG91dFtpXSA9IGZuKHhzW2ldLCBpLCB4cyk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cbi8vIEFycmF5LnByb3RvdHlwZS5yZWR1Y2UgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5yZWR1Y2UgPSBmdW5jdGlvbiByZWR1Y2UoYXJyYXksIGNhbGxiYWNrLCBvcHRfaW5pdGlhbFZhbHVlKSB7XG4gIGlmIChhcnJheS5yZWR1Y2UpIHJldHVybiBhcnJheS5yZWR1Y2UoY2FsbGJhY2ssIG9wdF9pbml0aWFsVmFsdWUpO1xuICB2YXIgdmFsdWUsIGlzVmFsdWVTZXQgPSBmYWxzZTtcblxuICBpZiAoMiA8IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICB2YWx1ZSA9IG9wdF9pbml0aWFsVmFsdWU7XG4gICAgaXNWYWx1ZVNldCA9IHRydWU7XG4gIH1cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcnJheS5sZW5ndGg7IGwgPiBpOyArK2kpIHtcbiAgICBpZiAoYXJyYXkuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIGlmIChpc1ZhbHVlU2V0KSB7XG4gICAgICAgIHZhbHVlID0gY2FsbGJhY2sodmFsdWUsIGFycmF5W2ldLCBpLCBhcnJheSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSBhcnJheVtpXTtcbiAgICAgICAgaXNWYWx1ZVNldCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuLy8gU3RyaW5nLnByb3RvdHlwZS5zdWJzdHIgLSBuZWdhdGl2ZSBpbmRleCBkb24ndCB3b3JrIGluIElFOFxuaWYgKCdhYicuc3Vic3RyKC0xKSAhPT0gJ2InKSB7XG4gIGV4cG9ydHMuc3Vic3RyID0gZnVuY3Rpb24gKHN0ciwgc3RhcnQsIGxlbmd0aCkge1xuICAgIC8vIGRpZCB3ZSBnZXQgYSBuZWdhdGl2ZSBzdGFydCwgY2FsY3VsYXRlIGhvdyBtdWNoIGl0IGlzIGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nXG4gICAgaWYgKHN0YXJ0IDwgMCkgc3RhcnQgPSBzdHIubGVuZ3RoICsgc3RhcnQ7XG5cbiAgICAvLyBjYWxsIHRoZSBvcmlnaW5hbCBmdW5jdGlvblxuICAgIHJldHVybiBzdHIuc3Vic3RyKHN0YXJ0LCBsZW5ndGgpO1xuICB9O1xufSBlbHNlIHtcbiAgZXhwb3J0cy5zdWJzdHIgPSBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHN0ci5zdWJzdHIoc3RhcnQsIGxlbmd0aCk7XG4gIH07XG59XG5cbi8vIFN0cmluZy5wcm90b3R5cGUudHJpbSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLnRyaW0gPSBmdW5jdGlvbiAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKCk7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xufTtcblxuLy8gRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5iaW5kID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG4gIHZhciBmbiA9IGFyZ3Muc2hpZnQoKTtcbiAgaWYgKGZuLmJpbmQpIHJldHVybiBmbi5iaW5kLmFwcGx5KGZuLCBhcmdzKTtcbiAgdmFyIHNlbGYgPSBhcmdzLnNoaWZ0KCk7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgZm4uYXBwbHkoc2VsZiwgYXJncy5jb25jYXQoW0FycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyldKSk7XG4gIH07XG59O1xuXG4vLyBPYmplY3QuY3JlYXRlIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmZ1bmN0aW9uIGNyZWF0ZShwcm90b3R5cGUsIHByb3BlcnRpZXMpIHtcbiAgdmFyIG9iamVjdDtcbiAgaWYgKHByb3RvdHlwZSA9PT0gbnVsbCkge1xuICAgIG9iamVjdCA9IHsgJ19fcHJvdG9fXycgOiBudWxsIH07XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBwcm90b3R5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICAndHlwZW9mIHByb3RvdHlwZVsnICsgKHR5cGVvZiBwcm90b3R5cGUpICsgJ10gIT0gXFwnb2JqZWN0XFwnJ1xuICAgICAgKTtcbiAgICB9XG4gICAgdmFyIFR5cGUgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICBUeXBlLnByb3RvdHlwZSA9IHByb3RvdHlwZTtcbiAgICBvYmplY3QgPSBuZXcgVHlwZSgpO1xuICAgIG9iamVjdC5fX3Byb3RvX18gPSBwcm90b3R5cGU7XG4gIH1cbiAgaWYgKHR5cGVvZiBwcm9wZXJ0aWVzICE9PSAndW5kZWZpbmVkJyAmJiBPYmplY3QuZGVmaW5lUHJvcGVydGllcykge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG9iamVjdCwgcHJvcGVydGllcyk7XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cbmV4cG9ydHMuY3JlYXRlID0gdHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicgPyBPYmplY3QuY3JlYXRlIDogY3JlYXRlO1xuXG4vLyBPYmplY3Qua2V5cyBhbmQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgaXMgc3VwcG9ydGVkIGluIElFOSBob3dldmVyXG4vLyB0aGV5IGRvIHNob3cgYSBkZXNjcmlwdGlvbiBhbmQgbnVtYmVyIHByb3BlcnR5IG9uIEVycm9yIG9iamVjdHNcbmZ1bmN0aW9uIG5vdE9iamVjdChvYmplY3QpIHtcbiAgcmV0dXJuICgodHlwZW9mIG9iamVjdCAhPSBcIm9iamVjdFwiICYmIHR5cGVvZiBvYmplY3QgIT0gXCJmdW5jdGlvblwiKSB8fCBvYmplY3QgPT09IG51bGwpO1xufVxuXG5mdW5jdGlvbiBrZXlzU2hpbShvYmplY3QpIHtcbiAgaWYgKG5vdE9iamVjdChvYmplY3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdC5rZXlzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvciAodmFyIG5hbWUgaW4gb2JqZWN0KSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBuYW1lKSkge1xuICAgICAgcmVzdWx0LnB1c2gobmFtZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIGdldE93blByb3BlcnR5TmFtZXMgaXMgYWxtb3N0IHRoZSBzYW1lIGFzIE9iamVjdC5rZXlzIG9uZSBrZXkgZmVhdHVyZVxuLy8gIGlzIHRoYXQgaXQgcmV0dXJucyBoaWRkZW4gcHJvcGVydGllcywgc2luY2UgdGhhdCBjYW4ndCBiZSBpbXBsZW1lbnRlZCxcbi8vICB0aGlzIGZlYXR1cmUgZ2V0cyByZWR1Y2VkIHNvIGl0IGp1c3Qgc2hvd3MgdGhlIGxlbmd0aCBwcm9wZXJ0eSBvbiBhcnJheXNcbmZ1bmN0aW9uIHByb3BlcnR5U2hpbShvYmplY3QpIHtcbiAgaWYgKG5vdE9iamVjdChvYmplY3QpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG4gIH1cblxuICB2YXIgcmVzdWx0ID0ga2V5c1NoaW0ob2JqZWN0KTtcbiAgaWYgKGV4cG9ydHMuaXNBcnJheShvYmplY3QpICYmIGV4cG9ydHMuaW5kZXhPZihvYmplY3QsICdsZW5ndGgnKSA9PT0gLTEpIHtcbiAgICByZXN1bHQucHVzaCgnbGVuZ3RoJyk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxudmFyIGtleXMgPSB0eXBlb2YgT2JqZWN0LmtleXMgPT09ICdmdW5jdGlvbicgPyBPYmplY3Qua2V5cyA6IGtleXNTaGltO1xudmFyIGdldE93blByb3BlcnR5TmFtZXMgPSB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgPT09ICdmdW5jdGlvbicgP1xuICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA6IHByb3BlcnR5U2hpbTtcblxuaWYgKG5ldyBFcnJvcigpLmhhc093blByb3BlcnR5KCdkZXNjcmlwdGlvbicpKSB7XG4gIHZhciBFUlJPUl9QUk9QRVJUWV9GSUxURVIgPSBmdW5jdGlvbiAob2JqLCBhcnJheSkge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEVycm9yXScpIHtcbiAgICAgIGFycmF5ID0gZXhwb3J0cy5maWx0ZXIoYXJyYXksIGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiBuYW1lICE9PSAnZGVzY3JpcHRpb24nICYmIG5hbWUgIT09ICdudW1iZXInICYmIG5hbWUgIT09ICdtZXNzYWdlJztcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXk7XG4gIH07XG5cbiAgZXhwb3J0cy5rZXlzID0gZnVuY3Rpb24gKG9iamVjdCkge1xuICAgIHJldHVybiBFUlJPUl9QUk9QRVJUWV9GSUxURVIob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xuICB9O1xuICBleHBvcnRzLmdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIEVSUk9SX1BST1BFUlRZX0ZJTFRFUihvYmplY3QsIGdldE93blByb3BlcnR5TmFtZXMob2JqZWN0KSk7XG4gIH07XG59IGVsc2Uge1xuICBleHBvcnRzLmtleXMgPSBrZXlzO1xuICBleHBvcnRzLmdldE93blByb3BlcnR5TmFtZXMgPSBnZXRPd25Qcm9wZXJ0eU5hbWVzO1xufVxuXG4vLyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIC0gc3VwcG9ydGVkIGluIElFOCBidXQgb25seSBvbiBkb20gZWxlbWVudHNcbmZ1bmN0aW9uIHZhbHVlT2JqZWN0KHZhbHVlLCBrZXkpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbn1cblxuaWYgKHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gIHRyeSB7XG4gICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih7J2EnOiAxfSwgJ2EnKTtcbiAgICBleHBvcnRzLmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBJRTggZG9tIGVsZW1lbnQgaXNzdWUgLSB1c2UgYSB0cnkgY2F0Y2ggYW5kIGRlZmF1bHQgdG8gdmFsdWVPYmplY3RcbiAgICBleHBvcnRzLmdldE93blByb3BlcnR5RGVzY3JpcHRvciA9IGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlT2JqZWN0KHZhbHVlLCBrZXkpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn0gZWxzZSB7XG4gIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gdmFsdWVPYmplY3Q7XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gYSBkdXBsZXggc3RyZWFtIGlzIGp1c3QgYSBzdHJlYW0gdGhhdCBpcyBib3RoIHJlYWRhYmxlIGFuZCB3cml0YWJsZS5cbi8vIFNpbmNlIEpTIGRvZXNuJ3QgaGF2ZSBtdWx0aXBsZSBwcm90b3R5cGFsIGluaGVyaXRhbmNlLCB0aGlzIGNsYXNzXG4vLyBwcm90b3R5cGFsbHkgaW5oZXJpdHMgZnJvbSBSZWFkYWJsZSwgYW5kIHRoZW4gcGFyYXNpdGljYWxseSBmcm9tXG4vLyBXcml0YWJsZS5cblxubW9kdWxlLmV4cG9ydHMgPSBEdXBsZXg7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBzaGltcyA9IHJlcXVpcmUoJ19zaGltcycpO1xudmFyIHRpbWVycyA9IHJlcXVpcmUoJ3RpbWVycycpO1xudmFyIFJlYWRhYmxlID0gcmVxdWlyZSgnX3N0cmVhbV9yZWFkYWJsZScpO1xudmFyIFdyaXRhYmxlID0gcmVxdWlyZSgnX3N0cmVhbV93cml0YWJsZScpO1xuXG51dGlsLmluaGVyaXRzKER1cGxleCwgUmVhZGFibGUpO1xuXG5zaGltcy5mb3JFYWNoKHNoaW1zLmtleXMoV3JpdGFibGUucHJvdG90eXBlKSwgZnVuY3Rpb24obWV0aG9kKSB7XG4gIGlmICghRHVwbGV4LnByb3RvdHlwZVttZXRob2RdKVxuICAgIER1cGxleC5wcm90b3R5cGVbbWV0aG9kXSA9IFdyaXRhYmxlLnByb3RvdHlwZVttZXRob2RdO1xufSk7XG5cbmZ1bmN0aW9uIER1cGxleChvcHRpb25zKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEdXBsZXgpKVxuICAgIHJldHVybiBuZXcgRHVwbGV4KG9wdGlvbnMpO1xuXG4gIFJlYWRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG4gIFdyaXRhYmxlLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5yZWFkYWJsZSA9PT0gZmFsc2UpXG4gICAgdGhpcy5yZWFkYWJsZSA9IGZhbHNlO1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMud3JpdGFibGUgPT09IGZhbHNlKVxuICAgIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcblxuICB0aGlzLmFsbG93SGFsZk9wZW4gPSB0cnVlO1xuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmFsbG93SGFsZk9wZW4gPT09IGZhbHNlKVxuICAgIHRoaXMuYWxsb3dIYWxmT3BlbiA9IGZhbHNlO1xuXG4gIHRoaXMub25jZSgnZW5kJywgb25lbmQpO1xufVxuXG4vLyB0aGUgbm8taGFsZi1vcGVuIGVuZm9yY2VyXG5mdW5jdGlvbiBvbmVuZCgpIHtcbiAgLy8gaWYgd2UgYWxsb3cgaGFsZi1vcGVuIHN0YXRlLCBvciBpZiB0aGUgd3JpdGFibGUgc2lkZSBlbmRlZCxcbiAgLy8gdGhlbiB3ZSdyZSBvay5cbiAgaWYgKHRoaXMuYWxsb3dIYWxmT3BlbiB8fCB0aGlzLl93cml0YWJsZVN0YXRlLmVuZGVkKVxuICAgIHJldHVybjtcblxuICAvLyBubyBtb3JlIGRhdGEgY2FuIGJlIHdyaXR0ZW4uXG4gIC8vIEJ1dCBhbGxvdyBtb3JlIHdyaXRlcyB0byBoYXBwZW4gaW4gdGhpcyB0aWNrLlxuICB0aW1lcnMuc2V0SW1tZWRpYXRlKHNoaW1zLmJpbmQodGhpcy5lbmQsIHRoaXMpKTtcbn1cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHBhc3N0aHJvdWdoIHN0cmVhbS5cbi8vIGJhc2ljYWxseSBqdXN0IHRoZSBtb3N0IG1pbmltYWwgc29ydCBvZiBUcmFuc2Zvcm0gc3RyZWFtLlxuLy8gRXZlcnkgd3JpdHRlbiBjaHVuayBnZXRzIG91dHB1dCBhcy1pcy5cblxubW9kdWxlLmV4cG9ydHMgPSBQYXNzVGhyb3VnaDtcblxudmFyIFRyYW5zZm9ybSA9IHJlcXVpcmUoJ19zdHJlYW1fdHJhbnNmb3JtJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnV0aWwuaW5oZXJpdHMoUGFzc1Rocm91Z2gsIFRyYW5zZm9ybSk7XG5cbmZ1bmN0aW9uIFBhc3NUaHJvdWdoKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBhc3NUaHJvdWdoKSlcbiAgICByZXR1cm4gbmV3IFBhc3NUaHJvdWdoKG9wdGlvbnMpO1xuXG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5QYXNzVGhyb3VnaC5wcm90b3R5cGUuX3RyYW5zZm9ybSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobnVsbCwgY2h1bmspO1xufTtcbiIsInZhciBwcm9jZXNzPXJlcXVpcmUoXCJfX2Jyb3dzZXJpZnlfcHJvY2Vzc1wiKTsvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxubW9kdWxlLmV4cG9ydHMgPSBSZWFkYWJsZTtcblJlYWRhYmxlLlJlYWRhYmxlU3RhdGUgPSBSZWFkYWJsZVN0YXRlO1xuXG52YXIgRUUgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG52YXIgdGltZXJzID0gcmVxdWlyZSgndGltZXJzJyk7XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBTdHJpbmdEZWNvZGVyO1xuXG51dGlsLmluaGVyaXRzKFJlYWRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHN0cmVhbSkge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAvLyB0aGUgcG9pbnQgYXQgd2hpY2ggaXQgc3RvcHMgY2FsbGluZyBfcmVhZCgpIHRvIGZpbGwgdGhlIGJ1ZmZlclxuICAvLyBOb3RlOiAwIGlzIGEgdmFsaWQgdmFsdWUsIG1lYW5zIFwiZG9uJ3QgY2FsbCBfcmVhZCBwcmVlbXB0aXZlbHkgZXZlclwiXG4gIHZhciBod20gPSBvcHRpb25zLmhpZ2hXYXRlck1hcms7XG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IChod20gfHwgaHdtID09PSAwKSA/IGh3bSA6IDE2ICogMTAyNDtcblxuICAvLyBjYXN0IHRvIGludHMuXG4gIHRoaXMuaGlnaFdhdGVyTWFyayA9IH5+dGhpcy5oaWdoV2F0ZXJNYXJrO1xuXG4gIHRoaXMuYnVmZmVyID0gW107XG4gIHRoaXMubGVuZ3RoID0gMDtcbiAgdGhpcy5waXBlcyA9IG51bGw7XG4gIHRoaXMucGlwZXNDb3VudCA9IDA7XG4gIHRoaXMuZmxvd2luZyA9IGZhbHNlO1xuICB0aGlzLmVuZGVkID0gZmFsc2U7XG4gIHRoaXMuZW5kRW1pdHRlZCA9IGZhbHNlO1xuICB0aGlzLnJlYWRpbmcgPSBmYWxzZTtcblxuICAvLyBJbiBzdHJlYW1zIHRoYXQgbmV2ZXIgaGF2ZSBhbnkgZGF0YSwgYW5kIGRvIHB1c2gobnVsbCkgcmlnaHQgYXdheSxcbiAgLy8gdGhlIGNvbnN1bWVyIGNhbiBtaXNzIHRoZSAnZW5kJyBldmVudCBpZiB0aGV5IGRvIHNvbWUgSS9PIGJlZm9yZVxuICAvLyBjb25zdW1pbmcgdGhlIHN0cmVhbS4gIFNvLCB3ZSBkb24ndCBlbWl0KCdlbmQnKSB1bnRpbCBzb21lIHJlYWRpbmdcbiAgLy8gaGFwcGVucy5cbiAgdGhpcy5jYWxsZWRSZWFkID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY3Vhc2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gd2hlbmV2ZXIgd2UgcmV0dXJuIG51bGwsIHRoZW4gd2Ugc2V0IGEgZmxhZyB0byBzYXlcbiAgLy8gdGhhdCB3ZSdyZSBhd2FpdGluZyBhICdyZWFkYWJsZScgZXZlbnQgZW1pc3Npb24uXG4gIHRoaXMubmVlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG4gIHRoaXMucmVhZGFibGVMaXN0ZW5pbmcgPSBmYWxzZTtcblxuXG4gIC8vIG9iamVjdCBzdHJlYW0gZmxhZy4gVXNlZCB0byBtYWtlIHJlYWQobikgaWdub3JlIG4gYW5kIHRvXG4gIC8vIG1ha2UgYWxsIHRoZSBidWZmZXIgbWVyZ2luZyBhbmQgbGVuZ3RoIGNoZWNrcyBnbyBhd2F5XG4gIHRoaXMub2JqZWN0TW9kZSA9ICEhb3B0aW9ucy5vYmplY3RNb2RlO1xuXG4gIC8vIENyeXB0byBpcyBraW5kIG9mIG9sZCBhbmQgY3J1c3R5LiAgSGlzdG9yaWNhbGx5LCBpdHMgZGVmYXVsdCBzdHJpbmdcbiAgLy8gZW5jb2RpbmcgaXMgJ2JpbmFyeScgc28gd2UgaGF2ZSB0byBtYWtlIHRoaXMgY29uZmlndXJhYmxlLlxuICAvLyBFdmVyeXRoaW5nIGVsc2UgaW4gdGhlIHVuaXZlcnNlIHVzZXMgJ3V0ZjgnLCB0aG91Z2guXG4gIHRoaXMuZGVmYXVsdEVuY29kaW5nID0gb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcgfHwgJ3V0ZjgnO1xuXG4gIC8vIHdoZW4gcGlwaW5nLCB3ZSBvbmx5IGNhcmUgYWJvdXQgJ3JlYWRhYmxlJyBldmVudHMgdGhhdCBoYXBwZW5cbiAgLy8gYWZ0ZXIgcmVhZCgpaW5nIGFsbCB0aGUgYnl0ZXMgYW5kIG5vdCBnZXR0aW5nIGFueSBwdXNoYmFjay5cbiAgdGhpcy5yYW5PdXQgPSBmYWxzZTtcblxuICAvLyB0aGUgbnVtYmVyIG9mIHdyaXRlcnMgdGhhdCBhcmUgYXdhaXRpbmcgYSBkcmFpbiBldmVudCBpbiAucGlwZSgpc1xuICB0aGlzLmF3YWl0RHJhaW4gPSAwO1xuXG4gIC8vIGlmIHRydWUsIGEgbWF5YmVSZWFkTW9yZSBoYXMgYmVlbiBzY2hlZHVsZWRcbiAgdGhpcy5yZWFkaW5nTW9yZSA9IGZhbHNlO1xuXG4gIHRoaXMuZGVjb2RlciA9IG51bGw7XG4gIHRoaXMuZW5jb2RpbmcgPSBudWxsO1xuICBpZiAob3B0aW9ucy5lbmNvZGluZykge1xuICAgIGlmICghU3RyaW5nRGVjb2RlcilcbiAgICAgIFN0cmluZ0RlY29kZXIgPSByZXF1aXJlKCdzdHJpbmdfZGVjb2RlcicpLlN0cmluZ0RlY29kZXI7XG4gICAgdGhpcy5kZWNvZGVyID0gbmV3IFN0cmluZ0RlY29kZXIob3B0aW9ucy5lbmNvZGluZyk7XG4gICAgdGhpcy5lbmNvZGluZyA9IG9wdGlvbnMuZW5jb2Rpbmc7XG4gIH1cbn1cblxuZnVuY3Rpb24gUmVhZGFibGUob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgUmVhZGFibGUpKVxuICAgIHJldHVybiBuZXcgUmVhZGFibGUob3B0aW9ucyk7XG5cbiAgdGhpcy5fcmVhZGFibGVTdGF0ZSA9IG5ldyBSZWFkYWJsZVN0YXRlKG9wdGlvbnMsIHRoaXMpO1xuXG4gIC8vIGxlZ2FjeVxuICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcblxuICBTdHJlYW0uY2FsbCh0aGlzKTtcbn1cblxuLy8gTWFudWFsbHkgc2hvdmUgc29tZXRoaW5nIGludG8gdGhlIHJlYWQoKSBidWZmZXIuXG4vLyBUaGlzIHJldHVybnMgdHJ1ZSBpZiB0aGUgaGlnaFdhdGVyTWFyayBoYXMgbm90IGJlZW4gaGl0IHlldCxcbi8vIHNpbWlsYXIgdG8gaG93IFdyaXRhYmxlLndyaXRlKCkgcmV0dXJucyB0cnVlIGlmIHlvdSBzaG91bGRcbi8vIHdyaXRlKCkgc29tZSBtb3JlLlxuUmVhZGFibGUucHJvdG90eXBlLnB1c2ggPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcpIHtcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAodHlwZW9mIGNodW5rID09PSAnc3RyaW5nJyAmJiAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuICAgIGlmIChlbmNvZGluZyAhPT0gc3RhdGUuZW5jb2RpbmcpIHtcbiAgICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICAgICAgZW5jb2RpbmcgPSAnJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBmYWxzZSk7XG59O1xuXG4vLyBVbnNoaWZ0IHNob3VsZCAqYWx3YXlzKiBiZSBzb21ldGhpbmcgZGlyZWN0bHkgb3V0IG9mIHJlYWQoKVxuUmVhZGFibGUucHJvdG90eXBlLnVuc2hpZnQgPSBmdW5jdGlvbihjaHVuaykge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuICByZXR1cm4gcmVhZGFibGVBZGRDaHVuayh0aGlzLCBzdGF0ZSwgY2h1bmssICcnLCB0cnVlKTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRhYmxlQWRkQ2h1bmsoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBhZGRUb0Zyb250KSB7XG4gIHZhciBlciA9IGNodW5rSW52YWxpZChzdGF0ZSwgY2h1bmspO1xuICBpZiAoZXIpIHtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIH0gZWxzZSBpZiAoY2h1bmsgPT09IG51bGwgfHwgY2h1bmsgPT09IHVuZGVmaW5lZCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICBpZiAoIXN0YXRlLmVuZGVkKVxuICAgICAgb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKTtcbiAgfSBlbHNlIGlmIChzdGF0ZS5vYmplY3RNb2RlIHx8IGNodW5rICYmIGNodW5rLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoc3RhdGUuZW5kZWQgJiYgIWFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0ucHVzaCgpIGFmdGVyIEVPRicpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIGlmIChzdGF0ZS5lbmRFbWl0dGVkICYmIGFkZFRvRnJvbnQpIHtcbiAgICAgIHZhciBlID0gbmV3IEVycm9yKCdzdHJlYW0udW5zaGlmdCgpIGFmdGVyIGVuZCBldmVudCcpO1xuICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChzdGF0ZS5kZWNvZGVyICYmICFhZGRUb0Zyb250ICYmICFlbmNvZGluZylcbiAgICAgICAgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLndyaXRlKGNodW5rKTtcblxuICAgICAgLy8gdXBkYXRlIHRoZSBidWZmZXIgaW5mby5cbiAgICAgIHN0YXRlLmxlbmd0aCArPSBzdGF0ZS5vYmplY3RNb2RlID8gMSA6IGNodW5rLmxlbmd0aDtcbiAgICAgIGlmIChhZGRUb0Zyb250KSB7XG4gICAgICAgIHN0YXRlLmJ1ZmZlci51bnNoaWZ0KGNodW5rKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXRlLnJlYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3RhdGUubmVlZFJlYWRhYmxlKVxuICAgICAgICBlbWl0UmVhZGFibGUoc3RyZWFtKTtcblxuICAgICAgbWF5YmVSZWFkTW9yZShzdHJlYW0sIHN0YXRlKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoIWFkZFRvRnJvbnQpIHtcbiAgICBzdGF0ZS5yZWFkaW5nID0gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gbmVlZE1vcmVEYXRhKHN0YXRlKTtcbn1cblxuXG5cbi8vIGlmIGl0J3MgcGFzdCB0aGUgaGlnaCB3YXRlciBtYXJrLCB3ZSBjYW4gcHVzaCBpbiBzb21lIG1vcmUuXG4vLyBBbHNvLCBpZiB3ZSBoYXZlIG5vIGRhdGEgeWV0LCB3ZSBjYW4gc3RhbmQgc29tZVxuLy8gbW9yZSBieXRlcy4gIFRoaXMgaXMgdG8gd29yayBhcm91bmQgY2FzZXMgd2hlcmUgaHdtPTAsXG4vLyBzdWNoIGFzIHRoZSByZXBsLiAgQWxzbywgaWYgdGhlIHB1c2goKSB0cmlnZ2VyZWQgYVxuLy8gcmVhZGFibGUgZXZlbnQsIGFuZCB0aGUgdXNlciBjYWxsZWQgcmVhZChsYXJnZU51bWJlcikgc3VjaCB0aGF0XG4vLyBuZWVkUmVhZGFibGUgd2FzIHNldCwgdGhlbiB3ZSBvdWdodCB0byBwdXNoIG1vcmUsIHNvIHRoYXQgYW5vdGhlclxuLy8gJ3JlYWRhYmxlJyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZC5cbmZ1bmN0aW9uIG5lZWRNb3JlRGF0YShzdGF0ZSkge1xuICByZXR1cm4gIXN0YXRlLmVuZGVkICYmXG4gICAgICAgICAoc3RhdGUubmVlZFJlYWRhYmxlIHx8XG4gICAgICAgICAgc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyayB8fFxuICAgICAgICAgIHN0YXRlLmxlbmd0aCA9PT0gMCk7XG59XG5cbi8vIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LlxuUmVhZGFibGUucHJvdG90eXBlLnNldEVuY29kaW5nID0gZnVuY3Rpb24oZW5jKSB7XG4gIGlmICghU3RyaW5nRGVjb2RlcilcbiAgICBTdHJpbmdEZWNvZGVyID0gcmVxdWlyZSgnc3RyaW5nX2RlY29kZXInKS5TdHJpbmdEZWNvZGVyO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmRlY29kZXIgPSBuZXcgU3RyaW5nRGVjb2RlcihlbmMpO1xuICB0aGlzLl9yZWFkYWJsZVN0YXRlLmVuY29kaW5nID0gZW5jO1xufTtcblxuLy8gRG9uJ3QgcmFpc2UgdGhlIGh3bSA+IDEyOE1CXG52YXIgTUFYX0hXTSA9IDB4ODAwMDAwO1xuZnVuY3Rpb24gcm91bmRVcFRvTmV4dFBvd2VyT2YyKG4pIHtcbiAgaWYgKG4gPj0gTUFYX0hXTSkge1xuICAgIG4gPSBNQVhfSFdNO1xuICB9IGVsc2Uge1xuICAgIC8vIEdldCB0aGUgbmV4dCBoaWdoZXN0IHBvd2VyIG9mIDJcbiAgICBuLS07XG4gICAgZm9yICh2YXIgcCA9IDE7IHAgPCAzMjsgcCA8PD0gMSkgbiB8PSBuID4+IHA7XG4gICAgbisrO1xuICB9XG4gIHJldHVybiBuO1xufVxuXG5mdW5jdGlvbiBob3dNdWNoVG9SZWFkKG4sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUuZW5kZWQpXG4gICAgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXRlLm9iamVjdE1vZGUpXG4gICAgcmV0dXJuIG4gPT09IDAgPyAwIDogMTtcblxuICBpZiAoaXNOYU4obikgfHwgbiA9PT0gbnVsbCkge1xuICAgIC8vIG9ubHkgZmxvdyBvbmUgYnVmZmVyIGF0IGEgdGltZVxuICAgIGlmIChzdGF0ZS5mbG93aW5nICYmIHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgICByZXR1cm4gc3RhdGUuYnVmZmVyWzBdLmxlbmd0aDtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gc3RhdGUubGVuZ3RoO1xuICB9XG5cbiAgaWYgKG4gPD0gMClcbiAgICByZXR1cm4gMDtcblxuICAvLyBJZiB3ZSdyZSBhc2tpbmcgZm9yIG1vcmUgdGhhbiB0aGUgdGFyZ2V0IGJ1ZmZlciBsZXZlbCxcbiAgLy8gdGhlbiByYWlzZSB0aGUgd2F0ZXIgbWFyay4gIEJ1bXAgdXAgdG8gdGhlIG5leHQgaGlnaGVzdFxuICAvLyBwb3dlciBvZiAyLCB0byBwcmV2ZW50IGluY3JlYXNpbmcgaXQgZXhjZXNzaXZlbHkgaW4gdGlueVxuICAvLyBhbW91bnRzLlxuICBpZiAobiA+IHN0YXRlLmhpZ2hXYXRlck1hcmspXG4gICAgc3RhdGUuaGlnaFdhdGVyTWFyayA9IHJvdW5kVXBUb05leHRQb3dlck9mMihuKTtcblxuICAvLyBkb24ndCBoYXZlIHRoYXQgbXVjaC4gIHJldHVybiBudWxsLCB1bmxlc3Mgd2UndmUgZW5kZWQuXG4gIGlmIChuID4gc3RhdGUubGVuZ3RoKSB7XG4gICAgaWYgKCFzdGF0ZS5lbmRlZCkge1xuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZWxzZVxuICAgICAgcmV0dXJuIHN0YXRlLmxlbmd0aDtcbiAgfVxuXG4gIHJldHVybiBuO1xufVxuXG4vLyB5b3UgY2FuIG92ZXJyaWRlIGVpdGhlciB0aGlzIG1ldGhvZCwgb3IgdGhlIGFzeW5jIF9yZWFkKG4pIGJlbG93LlxuUmVhZGFibGUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbihuKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHN0YXRlLmNhbGxlZFJlYWQgPSB0cnVlO1xuICB2YXIgbk9yaWcgPSBuO1xuXG4gIGlmICh0eXBlb2YgbiAhPT0gJ251bWJlcicgfHwgbiA+IDApXG4gICAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gZmFsc2U7XG5cbiAgLy8gaWYgd2UncmUgZG9pbmcgcmVhZCgwKSB0byB0cmlnZ2VyIGEgcmVhZGFibGUgZXZlbnQsIGJ1dCB3ZVxuICAvLyBhbHJlYWR5IGhhdmUgYSBidW5jaCBvZiBkYXRhIGluIHRoZSBidWZmZXIsIHRoZW4ganVzdCB0cmlnZ2VyXG4gIC8vIHRoZSAncmVhZGFibGUnIGV2ZW50IGFuZCBtb3ZlIG9uLlxuICBpZiAobiA9PT0gMCAmJlxuICAgICAgc3RhdGUubmVlZFJlYWRhYmxlICYmXG4gICAgICAoc3RhdGUubGVuZ3RoID49IHN0YXRlLmhpZ2hXYXRlck1hcmsgfHwgc3RhdGUuZW5kZWQpKSB7XG4gICAgZW1pdFJlYWRhYmxlKHRoaXMpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbiA9IGhvd011Y2hUb1JlYWQobiwgc3RhdGUpO1xuXG4gIC8vIGlmIHdlJ3ZlIGVuZGVkLCBhbmQgd2UncmUgbm93IGNsZWFyLCB0aGVuIGZpbmlzaCBpdCB1cC5cbiAgaWYgKG4gPT09IDAgJiYgc3RhdGUuZW5kZWQpIHtcbiAgICBpZiAoc3RhdGUubGVuZ3RoID09PSAwKVxuICAgICAgZW5kUmVhZGFibGUodGhpcyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBbGwgdGhlIGFjdHVhbCBjaHVuayBnZW5lcmF0aW9uIGxvZ2ljIG5lZWRzIHRvIGJlXG4gIC8vICpiZWxvdyogdGhlIGNhbGwgdG8gX3JlYWQuICBUaGUgcmVhc29uIGlzIHRoYXQgaW4gY2VydGFpblxuICAvLyBzeW50aGV0aWMgc3RyZWFtIGNhc2VzLCBzdWNoIGFzIHBhc3N0aHJvdWdoIHN0cmVhbXMsIF9yZWFkXG4gIC8vIG1heSBiZSBhIGNvbXBsZXRlbHkgc3luY2hyb25vdXMgb3BlcmF0aW9uIHdoaWNoIG1heSBjaGFuZ2VcbiAgLy8gdGhlIHN0YXRlIG9mIHRoZSByZWFkIGJ1ZmZlciwgcHJvdmlkaW5nIGVub3VnaCBkYXRhIHdoZW5cbiAgLy8gYmVmb3JlIHRoZXJlIHdhcyAqbm90KiBlbm91Z2guXG4gIC8vXG4gIC8vIFNvLCB0aGUgc3RlcHMgYXJlOlxuICAvLyAxLiBGaWd1cmUgb3V0IHdoYXQgdGhlIHN0YXRlIG9mIHRoaW5ncyB3aWxsIGJlIGFmdGVyIHdlIGRvXG4gIC8vIGEgcmVhZCBmcm9tIHRoZSBidWZmZXIuXG4gIC8vXG4gIC8vIDIuIElmIHRoYXQgcmVzdWx0aW5nIHN0YXRlIHdpbGwgdHJpZ2dlciBhIF9yZWFkLCB0aGVuIGNhbGwgX3JlYWQuXG4gIC8vIE5vdGUgdGhhdCB0aGlzIG1heSBiZSBhc3luY2hyb25vdXMsIG9yIHN5bmNocm9ub3VzLiAgWWVzLCBpdCBpc1xuICAvLyBkZWVwbHkgdWdseSB0byB3cml0ZSBBUElzIHRoaXMgd2F5LCBidXQgdGhhdCBzdGlsbCBkb2Vzbid0IG1lYW5cbiAgLy8gdGhhdCB0aGUgUmVhZGFibGUgY2xhc3Mgc2hvdWxkIGJlaGF2ZSBpbXByb3Blcmx5LCBhcyBzdHJlYW1zIGFyZVxuICAvLyBkZXNpZ25lZCB0byBiZSBzeW5jL2FzeW5jIGFnbm9zdGljLlxuICAvLyBUYWtlIG5vdGUgaWYgdGhlIF9yZWFkIGNhbGwgaXMgc3luYyBvciBhc3luYyAoaWUsIGlmIHRoZSByZWFkIGNhbGxcbiAgLy8gaGFzIHJldHVybmVkIHlldCksIHNvIHRoYXQgd2Uga25vdyB3aGV0aGVyIG9yIG5vdCBpdCdzIHNhZmUgdG8gZW1pdFxuICAvLyAncmVhZGFibGUnIGV0Yy5cbiAgLy9cbiAgLy8gMy4gQWN0dWFsbHkgcHVsbCB0aGUgcmVxdWVzdGVkIGNodW5rcyBvdXQgb2YgdGhlIGJ1ZmZlciBhbmQgcmV0dXJuLlxuXG4gIC8vIGlmIHdlIG5lZWQgYSByZWFkYWJsZSBldmVudCwgdGhlbiB3ZSBuZWVkIHRvIGRvIHNvbWUgcmVhZGluZy5cbiAgdmFyIGRvUmVhZCA9IHN0YXRlLm5lZWRSZWFkYWJsZTtcblxuICAvLyBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBsZXNzIHRoYW4gdGhlIGhpZ2hXYXRlck1hcmssIHRoZW4gYWxzbyByZWFkIHNvbWVcbiAgaWYgKHN0YXRlLmxlbmd0aCAtIG4gPD0gc3RhdGUuaGlnaFdhdGVyTWFyaylcbiAgICBkb1JlYWQgPSB0cnVlO1xuXG4gIC8vIGhvd2V2ZXIsIGlmIHdlJ3ZlIGVuZGVkLCB0aGVuIHRoZXJlJ3Mgbm8gcG9pbnQsIGFuZCBpZiB3ZSdyZSBhbHJlYWR5XG4gIC8vIHJlYWRpbmcsIHRoZW4gaXQncyB1bm5lY2Vzc2FyeS5cbiAgaWYgKHN0YXRlLmVuZGVkIHx8IHN0YXRlLnJlYWRpbmcpXG4gICAgZG9SZWFkID0gZmFsc2U7XG5cbiAgaWYgKGRvUmVhZCkge1xuICAgIHN0YXRlLnJlYWRpbmcgPSB0cnVlO1xuICAgIHN0YXRlLnN5bmMgPSB0cnVlO1xuICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgY3VycmVudGx5IHplcm8sIHRoZW4gd2UgKm5lZWQqIGEgcmVhZGFibGUgZXZlbnQuXG4gICAgaWYgKHN0YXRlLmxlbmd0aCA9PT0gMClcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgLy8gY2FsbCBpbnRlcm5hbCByZWFkIG1ldGhvZFxuICAgIHRoaXMuX3JlYWQoc3RhdGUuaGlnaFdhdGVyTWFyayk7XG4gICAgc3RhdGUuc3luYyA9IGZhbHNlO1xuICB9XG5cbiAgLy8gSWYgX3JlYWQgY2FsbGVkIGl0cyBjYWxsYmFjayBzeW5jaHJvbm91c2x5LCB0aGVuIGByZWFkaW5nYFxuICAvLyB3aWxsIGJlIGZhbHNlLCBhbmQgd2UgbmVlZCB0byByZS1ldmFsdWF0ZSBob3cgbXVjaCBkYXRhIHdlXG4gIC8vIGNhbiByZXR1cm4gdG8gdGhlIHVzZXIuXG4gIGlmIChkb1JlYWQgJiYgIXN0YXRlLnJlYWRpbmcpXG4gICAgbiA9IGhvd011Y2hUb1JlYWQobk9yaWcsIHN0YXRlKTtcblxuICB2YXIgcmV0O1xuICBpZiAobiA+IDApXG4gICAgcmV0ID0gZnJvbUxpc3Qobiwgc3RhdGUpO1xuICBlbHNlXG4gICAgcmV0ID0gbnVsbDtcblxuICBpZiAocmV0ID09PSBudWxsKSB7XG4gICAgc3RhdGUubmVlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgICBuID0gMDtcbiAgfVxuXG4gIHN0YXRlLmxlbmd0aCAtPSBuO1xuXG4gIC8vIElmIHdlIGhhdmUgbm90aGluZyBpbiB0aGUgYnVmZmVyLCB0aGVuIHdlIHdhbnQgdG8ga25vd1xuICAvLyBhcyBzb29uIGFzIHdlICpkbyogZ2V0IHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIuXG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgIXN0YXRlLmVuZGVkKVxuICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gSWYgd2UgaGFwcGVuZWQgdG8gcmVhZCgpIGV4YWN0bHkgdGhlIHJlbWFpbmluZyBhbW91bnQgaW4gdGhlXG4gIC8vIGJ1ZmZlciwgYW5kIHRoZSBFT0YgaGFzIGJlZW4gc2VlbiBhdCB0aGlzIHBvaW50LCB0aGVuIG1ha2Ugc3VyZVxuICAvLyB0aGF0IHdlIGVtaXQgJ2VuZCcgb24gdGhlIHZlcnkgbmV4dCB0aWNrLlxuICBpZiAoc3RhdGUuZW5kZWQgJiYgIXN0YXRlLmVuZEVtaXR0ZWQgJiYgc3RhdGUubGVuZ3RoID09PSAwKVxuICAgIGVuZFJlYWRhYmxlKHRoaXMpO1xuXG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBjaHVua0ludmFsaWQoc3RhdGUsIGNodW5rKSB7XG4gIHZhciBlciA9IG51bGw7XG4gIGlmICghQnVmZmVyLmlzQnVmZmVyKGNodW5rKSAmJlxuICAgICAgJ3N0cmluZycgIT09IHR5cGVvZiBjaHVuayAmJlxuICAgICAgY2h1bmsgIT09IG51bGwgJiZcbiAgICAgIGNodW5rICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICFzdGF0ZS5vYmplY3RNb2RlICYmXG4gICAgICAhZXIpIHtcbiAgICBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgfVxuICByZXR1cm4gZXI7XG59XG5cblxuZnVuY3Rpb24gb25Fb2ZDaHVuayhzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5kZWNvZGVyICYmICFzdGF0ZS5lbmRlZCkge1xuICAgIHZhciBjaHVuayA9IHN0YXRlLmRlY29kZXIuZW5kKCk7XG4gICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aCkge1xuICAgICAgc3RhdGUuYnVmZmVyLnB1c2goY2h1bmspO1xuICAgICAgc3RhdGUubGVuZ3RoICs9IHN0YXRlLm9iamVjdE1vZGUgPyAxIDogY2h1bmsubGVuZ3RoO1xuICAgIH1cbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG5cbiAgLy8gaWYgd2UndmUgZW5kZWQgYW5kIHdlIGhhdmUgc29tZSBkYXRhIGxlZnQsIHRoZW4gZW1pdFxuICAvLyAncmVhZGFibGUnIG5vdyB0byBtYWtlIHN1cmUgaXQgZ2V0cyBwaWNrZWQgdXAuXG4gIGlmIChzdGF0ZS5sZW5ndGggPiAwKVxuICAgIGVtaXRSZWFkYWJsZShzdHJlYW0pO1xuICBlbHNlXG4gICAgZW5kUmVhZGFibGUoc3RyZWFtKTtcbn1cblxuLy8gRG9uJ3QgZW1pdCByZWFkYWJsZSByaWdodCBhd2F5IGluIHN5bmMgbW9kZSwgYmVjYXVzZSB0aGlzIGNhbiB0cmlnZ2VyXG4vLyBhbm90aGVyIHJlYWQoKSBjYWxsID0+IHN0YWNrIG92ZXJmbG93LiAgVGhpcyB3YXksIGl0IG1pZ2h0IHRyaWdnZXJcbi8vIGEgbmV4dFRpY2sgcmVjdXJzaW9uIHdhcm5pbmcsIGJ1dCB0aGF0J3Mgbm90IHNvIGJhZC5cbmZ1bmN0aW9uIGVtaXRSZWFkYWJsZShzdHJlYW0pIHtcbiAgdmFyIHN0YXRlID0gc3RyZWFtLl9yZWFkYWJsZVN0YXRlO1xuICBzdGF0ZS5uZWVkUmVhZGFibGUgPSBmYWxzZTtcbiAgaWYgKHN0YXRlLmVtaXR0ZWRSZWFkYWJsZSlcbiAgICByZXR1cm47XG5cbiAgc3RhdGUuZW1pdHRlZFJlYWRhYmxlID0gdHJ1ZTtcbiAgaWYgKHN0YXRlLnN5bmMpXG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbiAgICB9KTtcbiAgZWxzZVxuICAgIGVtaXRSZWFkYWJsZV8oc3RyZWFtKTtcbn1cblxuZnVuY3Rpb24gZW1pdFJlYWRhYmxlXyhzdHJlYW0pIHtcbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG59XG5cblxuLy8gYXQgdGhpcyBwb2ludCwgdGhlIHVzZXIgaGFzIHByZXN1bWFibHkgc2VlbiB0aGUgJ3JlYWRhYmxlJyBldmVudCxcbi8vIGFuZCBjYWxsZWQgcmVhZCgpIHRvIGNvbnN1bWUgc29tZSBkYXRhLiAgdGhhdCBtYXkgaGF2ZSB0cmlnZ2VyZWRcbi8vIGluIHR1cm4gYW5vdGhlciBfcmVhZChuKSBjYWxsLCBpbiB3aGljaCBjYXNlIHJlYWRpbmcgPSB0cnVlIGlmXG4vLyBpdCdzIGluIHByb2dyZXNzLlxuLy8gSG93ZXZlciwgaWYgd2UncmUgbm90IGVuZGVkLCBvciByZWFkaW5nLCBhbmQgdGhlIGxlbmd0aCA8IGh3bSxcbi8vIHRoZW4gZ28gYWhlYWQgYW5kIHRyeSB0byByZWFkIHNvbWUgbW9yZSBwcmVlbXB0aXZlbHkuXG5mdW5jdGlvbiBtYXliZVJlYWRNb3JlKHN0cmVhbSwgc3RhdGUpIHtcbiAgaWYgKCFzdGF0ZS5yZWFkaW5nTW9yZSkge1xuICAgIHN0YXRlLnJlYWRpbmdNb3JlID0gdHJ1ZTtcbiAgICB0aW1lcnMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbWF5YmVSZWFkTW9yZV8oc3RyZWFtLCBzdGF0ZSkge1xuICB2YXIgbGVuID0gc3RhdGUubGVuZ3RoO1xuICB3aGlsZSAoIXN0YXRlLnJlYWRpbmcgJiYgIXN0YXRlLmZsb3dpbmcgJiYgIXN0YXRlLmVuZGVkICYmXG4gICAgICAgICBzdGF0ZS5sZW5ndGggPCBzdGF0ZS5oaWdoV2F0ZXJNYXJrKSB7XG4gICAgc3RyZWFtLnJlYWQoMCk7XG4gICAgaWYgKGxlbiA9PT0gc3RhdGUubGVuZ3RoKVxuICAgICAgLy8gZGlkbid0IGdldCBhbnkgZGF0YSwgc3RvcCBzcGlubmluZy5cbiAgICAgIGJyZWFrO1xuICAgIGVsc2VcbiAgICAgIGxlbiA9IHN0YXRlLmxlbmd0aDtcbiAgfVxuICBzdGF0ZS5yZWFkaW5nTW9yZSA9IGZhbHNlO1xufVxuXG4vLyBhYnN0cmFjdCBtZXRob2QuICB0byBiZSBvdmVycmlkZGVuIGluIHNwZWNpZmljIGltcGxlbWVudGF0aW9uIGNsYXNzZXMuXG4vLyBjYWxsIGNiKGVyLCBkYXRhKSB3aGVyZSBkYXRhIGlzIDw9IG4gaW4gbGVuZ3RoLlxuLy8gZm9yIHZpcnR1YWwgKG5vbi1zdHJpbmcsIG5vbi1idWZmZXIpIHN0cmVhbXMsIFwibGVuZ3RoXCIgaXMgc29tZXdoYXRcbi8vIGFyYml0cmFyeSwgYW5kIHBlcmhhcHMgbm90IHZlcnkgbWVhbmluZ2Z1bC5cblJlYWRhYmxlLnByb3RvdHlwZS5fcmVhZCA9IGZ1bmN0aW9uKG4pIHtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm90IGltcGxlbWVudGVkJykpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBpcGUgPSBmdW5jdGlvbihkZXN0LCBwaXBlT3B0cykge1xuICB2YXIgc3JjID0gdGhpcztcbiAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcblxuICBzd2l0Y2ggKHN0YXRlLnBpcGVzQ291bnQpIHtcbiAgICBjYXNlIDA6XG4gICAgICBzdGF0ZS5waXBlcyA9IGRlc3Q7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDE6XG4gICAgICBzdGF0ZS5waXBlcyA9IFtzdGF0ZS5waXBlcywgZGVzdF07XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgc3RhdGUucGlwZXMucHVzaChkZXN0KTtcbiAgICAgIGJyZWFrO1xuICB9XG4gIHN0YXRlLnBpcGVzQ291bnQgKz0gMTtcblxuICB2YXIgZG9FbmQgPSAoIXBpcGVPcHRzIHx8IHBpcGVPcHRzLmVuZCAhPT0gZmFsc2UpICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3Rkb3V0ICYmXG4gICAgICAgICAgICAgIGRlc3QgIT09IHByb2Nlc3Muc3RkZXJyO1xuXG4gIHZhciBlbmRGbiA9IGRvRW5kID8gb25lbmQgOiBjbGVhbnVwO1xuICBpZiAoc3RhdGUuZW5kRW1pdHRlZClcbiAgICB0aW1lcnMuc2V0SW1tZWRpYXRlKGVuZEZuKTtcbiAgZWxzZVxuICAgIHNyYy5vbmNlKCdlbmQnLCBlbmRGbik7XG5cbiAgZGVzdC5vbigndW5waXBlJywgb251bnBpcGUpO1xuICBmdW5jdGlvbiBvbnVucGlwZShyZWFkYWJsZSkge1xuICAgIGlmIChyZWFkYWJsZSAhPT0gc3JjKSByZXR1cm47XG4gICAgY2xlYW51cCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25lbmQoKSB7XG4gICAgZGVzdC5lbmQoKTtcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIGRlc3QgZHJhaW5zLCBpdCByZWR1Y2VzIHRoZSBhd2FpdERyYWluIGNvdW50ZXJcbiAgLy8gb24gdGhlIHNvdXJjZS4gIFRoaXMgd291bGQgYmUgbW9yZSBlbGVnYW50IHdpdGggYSAub25jZSgpXG4gIC8vIGhhbmRsZXIgaW4gZmxvdygpLCBidXQgYWRkaW5nIGFuZCByZW1vdmluZyByZXBlYXRlZGx5IGlzXG4gIC8vIHRvbyBzbG93LlxuICB2YXIgb25kcmFpbiA9IHBpcGVPbkRyYWluKHNyYyk7XG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgZnVuY3Rpb24gY2xlYW51cCgpIHtcbiAgICAvLyBjbGVhbnVwIGV2ZW50IGhhbmRsZXJzIG9uY2UgdGhlIHBpcGUgaXMgYnJva2VuXG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdmaW5pc2gnLCBvbmZpbmlzaCk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIGRlc3QucmVtb3ZlTGlzdGVuZXIoJ3VucGlwZScsIG9udW5waXBlKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTtcbiAgICBzcmMucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIGNsZWFudXApO1xuXG4gICAgLy8gaWYgdGhlIHJlYWRlciBpcyB3YWl0aW5nIGZvciBhIGRyYWluIGV2ZW50IGZyb20gdGhpc1xuICAgIC8vIHNwZWNpZmljIHdyaXRlciwgdGhlbiBpdCB3b3VsZCBjYXVzZSBpdCB0byBuZXZlciBzdGFydFxuICAgIC8vIGZsb3dpbmcgYWdhaW4uXG4gICAgLy8gU28sIGlmIHRoaXMgaXMgYXdhaXRpbmcgYSBkcmFpbiwgdGhlbiB3ZSBqdXN0IGNhbGwgaXQgbm93LlxuICAgIC8vIElmIHdlIGRvbid0IGtub3csIHRoZW4gYXNzdW1lIHRoYXQgd2UgYXJlIHdhaXRpbmcgZm9yIG9uZS5cbiAgICBpZiAoIWRlc3QuX3dyaXRhYmxlU3RhdGUgfHwgZGVzdC5fd3JpdGFibGVTdGF0ZS5uZWVkRHJhaW4pXG4gICAgICBvbmRyYWluKCk7XG4gIH1cblxuICAvLyBpZiB0aGUgZGVzdCBoYXMgYW4gZXJyb3IsIHRoZW4gc3RvcCBwaXBpbmcgaW50byBpdC5cbiAgLy8gaG93ZXZlciwgZG9uJ3Qgc3VwcHJlc3MgdGhlIHRocm93aW5nIGJlaGF2aW9yIGZvciB0aGlzLlxuICAvLyBjaGVjayBmb3IgbGlzdGVuZXJzIGJlZm9yZSBlbWl0IHJlbW92ZXMgb25lLXRpbWUgbGlzdGVuZXJzLlxuICB2YXIgZXJyTGlzdGVuZXJzID0gRUUubGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKTtcbiAgZnVuY3Rpb24gb25lcnJvcihlcikge1xuICAgIHVucGlwZSgpO1xuICAgIGlmIChlcnJMaXN0ZW5lcnMgPT09IDAgJiYgRUUubGlzdGVuZXJDb3VudChkZXN0LCAnZXJyb3InKSA9PT0gMClcbiAgICAgIGRlc3QuZW1pdCgnZXJyb3InLCBlcik7XG4gIH1cbiAgZGVzdC5vbmNlKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gIC8vIEJvdGggY2xvc2UgYW5kIGZpbmlzaCBzaG91bGQgdHJpZ2dlciB1bnBpcGUsIGJ1dCBvbmx5IG9uY2UuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZmluaXNoJywgb25maW5pc2gpO1xuICAgIHVucGlwZSgpO1xuICB9XG4gIGRlc3Qub25jZSgnY2xvc2UnLCBvbmNsb3NlKTtcbiAgZnVuY3Rpb24gb25maW5pc2goKSB7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICB1bnBpcGUoKTtcbiAgfVxuICBkZXN0Lm9uY2UoJ2ZpbmlzaCcsIG9uZmluaXNoKTtcblxuICBmdW5jdGlvbiB1bnBpcGUoKSB7XG4gICAgc3JjLnVucGlwZShkZXN0KTtcbiAgfVxuXG4gIC8vIHRlbGwgdGhlIGRlc3QgdGhhdCBpdCdzIGJlaW5nIHBpcGVkIHRvXG4gIGRlc3QuZW1pdCgncGlwZScsIHNyYyk7XG5cbiAgLy8gc3RhcnQgdGhlIGZsb3cgaWYgaXQgaGFzbid0IGJlZW4gc3RhcnRlZCBhbHJlYWR5LlxuICBpZiAoIXN0YXRlLmZsb3dpbmcpIHtcbiAgICAvLyB0aGUgaGFuZGxlciB0aGF0IHdhaXRzIGZvciByZWFkYWJsZSBldmVudHMgYWZ0ZXIgYWxsXG4gICAgLy8gdGhlIGRhdGEgZ2V0cyBzdWNrZWQgb3V0IGluIGZsb3cuXG4gICAgLy8gVGhpcyB3b3VsZCBiZSBlYXNpZXIgdG8gZm9sbG93IHdpdGggYSAub25jZSgpIGhhbmRsZXJcbiAgICAvLyBpbiBmbG93KCksIGJ1dCB0aGF0IGlzIHRvbyBzbG93LlxuICAgIHRoaXMub24oJ3JlYWRhYmxlJywgcGlwZU9uUmVhZGFibGUpO1xuXG4gICAgc3RhdGUuZmxvd2luZyA9IHRydWU7XG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGZsb3coc3JjKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBkZXN0O1xufTtcblxuZnVuY3Rpb24gcGlwZU9uRHJhaW4oc3JjKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZGVzdCA9IHRoaXM7XG4gICAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICAgIHN0YXRlLmF3YWl0RHJhaW4tLTtcbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA9PT0gMClcbiAgICAgIGZsb3coc3JjKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZmxvdyhzcmMpIHtcbiAgdmFyIHN0YXRlID0gc3JjLl9yZWFkYWJsZVN0YXRlO1xuICB2YXIgY2h1bms7XG4gIHN0YXRlLmF3YWl0RHJhaW4gPSAwO1xuXG4gIGZ1bmN0aW9uIHdyaXRlKGRlc3QsIGksIGxpc3QpIHtcbiAgICB2YXIgd3JpdHRlbiA9IGRlc3Qud3JpdGUoY2h1bmspO1xuICAgIGlmIChmYWxzZSA9PT0gd3JpdHRlbikge1xuICAgICAgc3RhdGUuYXdhaXREcmFpbisrO1xuICAgIH1cbiAgfVxuXG4gIHdoaWxlIChzdGF0ZS5waXBlc0NvdW50ICYmIG51bGwgIT09IChjaHVuayA9IHNyYy5yZWFkKCkpKSB7XG5cbiAgICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSlcbiAgICAgIHdyaXRlKHN0YXRlLnBpcGVzLCAwLCBudWxsKTtcbiAgICBlbHNlXG4gICAgICBzaGltcy5mb3JFYWNoKHN0YXRlLnBpcGVzLCB3cml0ZSk7XG5cbiAgICBzcmMuZW1pdCgnZGF0YScsIGNodW5rKTtcblxuICAgIC8vIGlmIGFueW9uZSBuZWVkcyBhIGRyYWluLCB0aGVuIHdlIGhhdmUgdG8gd2FpdCBmb3IgdGhhdC5cbiAgICBpZiAoc3RhdGUuYXdhaXREcmFpbiA+IDApXG4gICAgICByZXR1cm47XG4gIH1cblxuICAvLyBpZiBldmVyeSBkZXN0aW5hdGlvbiB3YXMgdW5waXBlZCwgZWl0aGVyIGJlZm9yZSBlbnRlcmluZyB0aGlzXG4gIC8vIGZ1bmN0aW9uLCBvciBpbiB0aGUgd2hpbGUgbG9vcCwgdGhlbiBzdG9wIGZsb3dpbmcuXG4gIC8vXG4gIC8vIE5COiBUaGlzIGlzIGEgcHJldHR5IHJhcmUgZWRnZSBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMCkge1xuICAgIHN0YXRlLmZsb3dpbmcgPSBmYWxzZTtcblxuICAgIC8vIGlmIHRoZXJlIHdlcmUgZGF0YSBldmVudCBsaXN0ZW5lcnMgYWRkZWQsIHRoZW4gc3dpdGNoIHRvIG9sZCBtb2RlLlxuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHNyYywgJ2RhdGEnKSA+IDApXG4gICAgICBlbWl0RGF0YUV2ZW50cyhzcmMpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGF0IHRoaXMgcG9pbnQsIG5vIG9uZSBuZWVkZWQgYSBkcmFpbiwgc28gd2UganVzdCByYW4gb3V0IG9mIGRhdGFcbiAgLy8gb24gdGhlIG5leHQgcmVhZGFibGUgZXZlbnQsIHN0YXJ0IGl0IG92ZXIgYWdhaW4uXG4gIHN0YXRlLnJhbk91dCA9IHRydWU7XG59XG5cbmZ1bmN0aW9uIHBpcGVPblJlYWRhYmxlKCkge1xuICBpZiAodGhpcy5fcmVhZGFibGVTdGF0ZS5yYW5PdXQpIHtcbiAgICB0aGlzLl9yZWFkYWJsZVN0YXRlLnJhbk91dCA9IGZhbHNlO1xuICAgIGZsb3codGhpcyk7XG4gIH1cbn1cblxuXG5SZWFkYWJsZS5wcm90b3R5cGUudW5waXBlID0gZnVuY3Rpb24oZGVzdCkge1xuICB2YXIgc3RhdGUgPSB0aGlzLl9yZWFkYWJsZVN0YXRlO1xuXG4gIC8vIGlmIHdlJ3JlIG5vdCBwaXBpbmcgYW55d2hlcmUsIHRoZW4gZG8gbm90aGluZy5cbiAgaWYgKHN0YXRlLnBpcGVzQ291bnQgPT09IDApXG4gICAgcmV0dXJuIHRoaXM7XG5cbiAgLy8ganVzdCBvbmUgZGVzdGluYXRpb24uICBtb3N0IGNvbW1vbiBjYXNlLlxuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSkge1xuICAgIC8vIHBhc3NlZCBpbiBvbmUsIGJ1dCBpdCdzIG5vdCB0aGUgcmlnaHQgb25lLlxuICAgIGlmIChkZXN0ICYmIGRlc3QgIT09IHN0YXRlLnBpcGVzKVxuICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoIWRlc3QpXG4gICAgICBkZXN0ID0gc3RhdGUucGlwZXM7XG5cbiAgICAvLyBnb3QgYSBtYXRjaC5cbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBwaXBlT25SZWFkYWJsZSk7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuICAgIGlmIChkZXN0KVxuICAgICAgZGVzdC5lbWl0KCd1bnBpcGUnLCB0aGlzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIHNsb3cgY2FzZS4gbXVsdGlwbGUgcGlwZSBkZXN0aW5hdGlvbnMuXG5cbiAgaWYgKCFkZXN0KSB7XG4gICAgLy8gcmVtb3ZlIGFsbC5cbiAgICB2YXIgZGVzdHMgPSBzdGF0ZS5waXBlcztcbiAgICB2YXIgbGVuID0gc3RhdGUucGlwZXNDb3VudDtcbiAgICBzdGF0ZS5waXBlcyA9IG51bGw7XG4gICAgc3RhdGUucGlwZXNDb3VudCA9IDA7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcigncmVhZGFibGUnLCBwaXBlT25SZWFkYWJsZSk7XG4gICAgc3RhdGUuZmxvd2luZyA9IGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKylcbiAgICAgIGRlc3RzW2ldLmVtaXQoJ3VucGlwZScsIHRoaXMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGZpbmQgdGhlIHJpZ2h0IG9uZS5cbiAgdmFyIGkgPSBzaGltcy5pbmRleE9mKHN0YXRlLnBpcGVzLCBkZXN0KTtcbiAgaWYgKGkgPT09IC0xKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIHN0YXRlLnBpcGVzLnNwbGljZShpLCAxKTtcbiAgc3RhdGUucGlwZXNDb3VudCAtPSAxO1xuICBpZiAoc3RhdGUucGlwZXNDb3VudCA9PT0gMSlcbiAgICBzdGF0ZS5waXBlcyA9IHN0YXRlLnBpcGVzWzBdO1xuXG4gIGRlc3QuZW1pdCgndW5waXBlJywgdGhpcyk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBzZXQgdXAgZGF0YSBldmVudHMgaWYgdGhleSBhcmUgYXNrZWQgZm9yXG4vLyBFbnN1cmUgcmVhZGFibGUgbGlzdGVuZXJzIGV2ZW50dWFsbHkgZ2V0IHNvbWV0aGluZ1xuUmVhZGFibGUucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXYsIGZuKSB7XG4gIHZhciByZXMgPSBTdHJlYW0ucHJvdG90eXBlLm9uLmNhbGwodGhpcywgZXYsIGZuKTtcblxuICBpZiAoZXYgPT09ICdkYXRhJyAmJiAhdGhpcy5fcmVhZGFibGVTdGF0ZS5mbG93aW5nKVxuICAgIGVtaXREYXRhRXZlbnRzKHRoaXMpO1xuXG4gIGlmIChldiA9PT0gJ3JlYWRhYmxlJyAmJiB0aGlzLnJlYWRhYmxlKSB7XG4gICAgdmFyIHN0YXRlID0gdGhpcy5fcmVhZGFibGVTdGF0ZTtcbiAgICBpZiAoIXN0YXRlLnJlYWRhYmxlTGlzdGVuaW5nKSB7XG4gICAgICBzdGF0ZS5yZWFkYWJsZUxpc3RlbmluZyA9IHRydWU7XG4gICAgICBzdGF0ZS5lbWl0dGVkUmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG4gICAgICBpZiAoIXN0YXRlLnJlYWRpbmcpIHtcbiAgICAgICAgdGhpcy5yZWFkKDApO1xuICAgICAgfSBlbHNlIGlmIChzdGF0ZS5sZW5ndGgpIHtcbiAgICAgICAgZW1pdFJlYWRhYmxlKHRoaXMsIHN0YXRlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufTtcblJlYWRhYmxlLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IFJlYWRhYmxlLnByb3RvdHlwZS5vbjtcblxuLy8gcGF1c2UoKSBhbmQgcmVzdW1lKCkgYXJlIHJlbW5hbnRzIG9mIHRoZSBsZWdhY3kgcmVhZGFibGUgc3RyZWFtIEFQSVxuLy8gSWYgdGhlIHVzZXIgdXNlcyB0aGVtLCB0aGVuIHN3aXRjaCBpbnRvIG9sZCBtb2RlLlxuUmVhZGFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICBlbWl0RGF0YUV2ZW50cyh0aGlzKTtcbiAgdGhpcy5yZWFkKDApO1xuICB0aGlzLmVtaXQoJ3Jlc3VtZScpO1xufTtcblxuUmVhZGFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGVtaXREYXRhRXZlbnRzKHRoaXMsIHRydWUpO1xuICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG59O1xuXG5mdW5jdGlvbiBlbWl0RGF0YUV2ZW50cyhzdHJlYW0sIHN0YXJ0UGF1c2VkKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICBpZiAoc3RhdGUuZmxvd2luZykge1xuICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3MvcmVhZGFibGUtc3RyZWFtL2lzc3Vlcy8xNlxuICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHN3aXRjaCB0byBvbGQgbW9kZSBub3cuJyk7XG4gIH1cblxuICB2YXIgcGF1c2VkID0gc3RhcnRQYXVzZWQgfHwgZmFsc2U7XG4gIHZhciByZWFkYWJsZSA9IGZhbHNlO1xuXG4gIC8vIGNvbnZlcnQgdG8gYW4gb2xkLXN0eWxlIHN0cmVhbS5cbiAgc3RyZWFtLnJlYWRhYmxlID0gdHJ1ZTtcbiAgc3RyZWFtLnBpcGUgPSBTdHJlYW0ucHJvdG90eXBlLnBpcGU7XG4gIHN0cmVhbS5vbiA9IHN0cmVhbS5hZGRMaXN0ZW5lciA9IFN0cmVhbS5wcm90b3R5cGUub247XG5cbiAgc3RyZWFtLm9uKCdyZWFkYWJsZScsIGZ1bmN0aW9uKCkge1xuICAgIHJlYWRhYmxlID0gdHJ1ZTtcblxuICAgIHZhciBjO1xuICAgIHdoaWxlICghcGF1c2VkICYmIChudWxsICE9PSAoYyA9IHN0cmVhbS5yZWFkKCkpKSlcbiAgICAgIHN0cmVhbS5lbWl0KCdkYXRhJywgYyk7XG5cbiAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAgcmVhZGFibGUgPSBmYWxzZTtcbiAgICAgIHN0cmVhbS5fcmVhZGFibGVTdGF0ZS5uZWVkUmVhZGFibGUgPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgc3RyZWFtLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gICAgcGF1c2VkID0gdHJ1ZTtcbiAgICB0aGlzLmVtaXQoJ3BhdXNlJyk7XG4gIH07XG5cbiAgc3RyZWFtLnJlc3VtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHBhdXNlZCA9IGZhbHNlO1xuICAgIGlmIChyZWFkYWJsZSlcbiAgICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICAgIHN0cmVhbS5lbWl0KCdyZWFkYWJsZScpO1xuICAgICAgfSk7XG4gICAgZWxzZVxuICAgICAgdGhpcy5yZWFkKDApO1xuICAgIHRoaXMuZW1pdCgncmVzdW1lJyk7XG4gIH07XG5cbiAgLy8gbm93IG1ha2UgaXQgc3RhcnQsIGp1c3QgaW4gY2FzZSBpdCBoYWRuJ3QgYWxyZWFkeS5cbiAgc3RyZWFtLmVtaXQoJ3JlYWRhYmxlJyk7XG59XG5cbi8vIHdyYXAgYW4gb2xkLXN0eWxlIHN0cmVhbSBhcyB0aGUgYXN5bmMgZGF0YSBzb3VyY2UuXG4vLyBUaGlzIGlzICpub3QqIHBhcnQgb2YgdGhlIHJlYWRhYmxlIHN0cmVhbSBpbnRlcmZhY2UuXG4vLyBJdCBpcyBhbiB1Z2x5IHVuZm9ydHVuYXRlIG1lc3Mgb2YgaGlzdG9yeS5cblJlYWRhYmxlLnByb3RvdHlwZS53cmFwID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gIHZhciBwYXVzZWQgPSBmYWxzZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHN0cmVhbS5vbignZW5kJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIgJiYgIXN0YXRlLmVuZGVkKSB7XG4gICAgICB2YXIgY2h1bmsgPSBzdGF0ZS5kZWNvZGVyLmVuZCgpO1xuICAgICAgaWYgKGNodW5rICYmIGNodW5rLmxlbmd0aClcbiAgICAgICAgc2VsZi5wdXNoKGNodW5rKTtcbiAgICB9XG5cbiAgICBzZWxmLnB1c2gobnVsbCk7XG4gIH0pO1xuXG4gIHN0cmVhbS5vbignZGF0YScsIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgaWYgKHN0YXRlLmRlY29kZXIpXG4gICAgICBjaHVuayA9IHN0YXRlLmRlY29kZXIud3JpdGUoY2h1bmspO1xuICAgIGlmICghY2h1bmsgfHwgIXN0YXRlLm9iamVjdE1vZGUgJiYgIWNodW5rLmxlbmd0aClcbiAgICAgIHJldHVybjtcblxuICAgIHZhciByZXQgPSBzZWxmLnB1c2goY2h1bmspO1xuICAgIGlmICghcmV0KSB7XG4gICAgICBwYXVzZWQgPSB0cnVlO1xuICAgICAgc3RyZWFtLnBhdXNlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBwcm94eSBhbGwgdGhlIG90aGVyIG1ldGhvZHMuXG4gIC8vIGltcG9ydGFudCB3aGVuIHdyYXBwaW5nIGZpbHRlcnMgYW5kIGR1cGxleGVzLlxuICBmb3IgKHZhciBpIGluIHN0cmVhbSkge1xuICAgIGlmICh0eXBlb2Ygc3RyZWFtW2ldID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIHR5cGVvZiB0aGlzW2ldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpc1tpXSA9IGZ1bmN0aW9uKG1ldGhvZCkgeyByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBzdHJlYW1bbWV0aG9kXS5hcHBseShzdHJlYW0sIGFyZ3VtZW50cyk7XG4gICAgICB9fShpKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm94eSBjZXJ0YWluIGltcG9ydGFudCBldmVudHMuXG4gIHZhciBldmVudHMgPSBbJ2Vycm9yJywgJ2Nsb3NlJywgJ2Rlc3Ryb3knLCAncGF1c2UnLCAncmVzdW1lJ107XG4gIHNoaW1zLmZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldikge1xuICAgIHN0cmVhbS5vbihldiwgc2hpbXMuYmluZChzZWxmLmVtaXQsIHNlbGYsIGV2KSk7XG4gIH0pO1xuXG4gIC8vIHdoZW4gd2UgdHJ5IHRvIGNvbnN1bWUgc29tZSBtb3JlIGJ5dGVzLCBzaW1wbHkgdW5wYXVzZSB0aGVcbiAgLy8gdW5kZXJseWluZyBzdHJlYW0uXG4gIHNlbGYuX3JlYWQgPSBmdW5jdGlvbihuKSB7XG4gICAgaWYgKHBhdXNlZCkge1xuICAgICAgcGF1c2VkID0gZmFsc2U7XG4gICAgICBzdHJlYW0ucmVzdW1lKCk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuXG5cbi8vIGV4cG9zZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgb25seS5cblJlYWRhYmxlLl9mcm9tTGlzdCA9IGZyb21MaXN0O1xuXG4vLyBQbHVjayBvZmYgbiBieXRlcyBmcm9tIGFuIGFycmF5IG9mIGJ1ZmZlcnMuXG4vLyBMZW5ndGggaXMgdGhlIGNvbWJpbmVkIGxlbmd0aHMgb2YgYWxsIHRoZSBidWZmZXJzIGluIHRoZSBsaXN0LlxuZnVuY3Rpb24gZnJvbUxpc3Qobiwgc3RhdGUpIHtcbiAgdmFyIGxpc3QgPSBzdGF0ZS5idWZmZXI7XG4gIHZhciBsZW5ndGggPSBzdGF0ZS5sZW5ndGg7XG4gIHZhciBzdHJpbmdNb2RlID0gISFzdGF0ZS5kZWNvZGVyO1xuICB2YXIgb2JqZWN0TW9kZSA9ICEhc3RhdGUub2JqZWN0TW9kZTtcbiAgdmFyIHJldDtcblxuICAvLyBub3RoaW5nIGluIHRoZSBsaXN0LCBkZWZpbml0ZWx5IGVtcHR5LlxuICBpZiAobGlzdC5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG51bGw7XG5cbiAgaWYgKGxlbmd0aCA9PT0gMClcbiAgICByZXQgPSBudWxsO1xuICBlbHNlIGlmIChvYmplY3RNb2RlKVxuICAgIHJldCA9IGxpc3Quc2hpZnQoKTtcbiAgZWxzZSBpZiAoIW4gfHwgbiA+PSBsZW5ndGgpIHtcbiAgICAvLyByZWFkIGl0IGFsbCwgdHJ1bmNhdGUgdGhlIGFycmF5LlxuICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgcmV0ID0gbGlzdC5qb2luKCcnKTtcbiAgICBlbHNlXG4gICAgICByZXQgPSBCdWZmZXIuY29uY2F0KGxpc3QsIGxlbmd0aCk7XG4gICAgbGlzdC5sZW5ndGggPSAwO1xuICB9IGVsc2Uge1xuICAgIC8vIHJlYWQganVzdCBzb21lIG9mIGl0LlxuICAgIGlmIChuIDwgbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGp1c3QgdGFrZSBhIHBhcnQgb2YgdGhlIGZpcnN0IGxpc3QgaXRlbS5cbiAgICAgIC8vIHNsaWNlIGlzIHRoZSBzYW1lIGZvciBidWZmZXJzIGFuZCBzdHJpbmdzLlxuICAgICAgdmFyIGJ1ZiA9IGxpc3RbMF07XG4gICAgICByZXQgPSBidWYuc2xpY2UoMCwgbik7XG4gICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKG4pO1xuICAgIH0gZWxzZSBpZiAobiA9PT0gbGlzdFswXS5sZW5ndGgpIHtcbiAgICAgIC8vIGZpcnN0IGxpc3QgaXMgYSBwZXJmZWN0IG1hdGNoXG4gICAgICByZXQgPSBsaXN0LnNoaWZ0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGNvbXBsZXggY2FzZS5cbiAgICAgIC8vIHdlIGhhdmUgZW5vdWdoIHRvIGNvdmVyIGl0LCBidXQgaXQgc3BhbnMgcGFzdCB0aGUgZmlyc3QgYnVmZmVyLlxuICAgICAgaWYgKHN0cmluZ01vZGUpXG4gICAgICAgIHJldCA9ICcnO1xuICAgICAgZWxzZVxuICAgICAgICByZXQgPSBuZXcgQnVmZmVyKG4pO1xuXG4gICAgICB2YXIgYyA9IDA7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGxpc3QubGVuZ3RoOyBpIDwgbCAmJiBjIDwgbjsgaSsrKSB7XG4gICAgICAgIHZhciBidWYgPSBsaXN0WzBdO1xuICAgICAgICB2YXIgY3B5ID0gTWF0aC5taW4obiAtIGMsIGJ1Zi5sZW5ndGgpO1xuXG4gICAgICAgIGlmIChzdHJpbmdNb2RlKVxuICAgICAgICAgIHJldCArPSBidWYuc2xpY2UoMCwgY3B5KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJ1Zi5jb3B5KHJldCwgYywgMCwgY3B5KTtcblxuICAgICAgICBpZiAoY3B5IDwgYnVmLmxlbmd0aClcbiAgICAgICAgICBsaXN0WzBdID0gYnVmLnNsaWNlKGNweSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBsaXN0LnNoaWZ0KCk7XG5cbiAgICAgICAgYyArPSBjcHk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gZW5kUmVhZGFibGUoc3RyZWFtKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSBiZWZvcmUgY29uc3VtaW5nIGFsbCB0aGUgYnl0ZXMsIHRoZW4gdGhhdCBpcyBhXG4gIC8vIGJ1ZyBpbiBub2RlLiAgU2hvdWxkIG5ldmVyIGhhcHBlbi5cbiAgaWYgKHN0YXRlLmxlbmd0aCA+IDApXG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbmRSZWFkYWJsZSBjYWxsZWQgb24gbm9uLWVtcHR5IHN0cmVhbScpO1xuXG4gIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5jYWxsZWRSZWFkKSB7XG4gICAgc3RhdGUuZW5kZWQgPSB0cnVlO1xuICAgIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgICAvLyBDaGVjayB0aGF0IHdlIGRpZG4ndCBnZXQgb25lIGxhc3QgdW5zaGlmdC5cbiAgICAgIGlmICghc3RhdGUuZW5kRW1pdHRlZCAmJiBzdGF0ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgc3RhdGUuZW5kRW1pdHRlZCA9IHRydWU7XG4gICAgICAgIHN0cmVhbS5yZWFkYWJsZSA9IGZhbHNlO1xuICAgICAgICBzdHJlYW0uZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyBhIHRyYW5zZm9ybSBzdHJlYW0gaXMgYSByZWFkYWJsZS93cml0YWJsZSBzdHJlYW0gd2hlcmUgeW91IGRvXG4vLyBzb21ldGhpbmcgd2l0aCB0aGUgZGF0YS4gIFNvbWV0aW1lcyBpdCdzIGNhbGxlZCBhIFwiZmlsdGVyXCIsXG4vLyBidXQgdGhhdCdzIG5vdCBhIGdyZWF0IG5hbWUgZm9yIGl0LCBzaW5jZSB0aGF0IGltcGxpZXMgYSB0aGluZyB3aGVyZVxuLy8gc29tZSBiaXRzIHBhc3MgdGhyb3VnaCwgYW5kIG90aGVycyBhcmUgc2ltcGx5IGlnbm9yZWQuICAoVGhhdCB3b3VsZFxuLy8gYmUgYSB2YWxpZCBleGFtcGxlIG9mIGEgdHJhbnNmb3JtLCBvZiBjb3Vyc2UuKVxuLy9cbi8vIFdoaWxlIHRoZSBvdXRwdXQgaXMgY2F1c2FsbHkgcmVsYXRlZCB0byB0aGUgaW5wdXQsIGl0J3Mgbm90IGFcbi8vIG5lY2Vzc2FyaWx5IHN5bW1ldHJpYyBvciBzeW5jaHJvbm91cyB0cmFuc2Zvcm1hdGlvbi4gIEZvciBleGFtcGxlLFxuLy8gYSB6bGliIHN0cmVhbSBtaWdodCB0YWtlIG11bHRpcGxlIHBsYWluLXRleHQgd3JpdGVzKCksIGFuZCB0aGVuXG4vLyBlbWl0IGEgc2luZ2xlIGNvbXByZXNzZWQgY2h1bmsgc29tZSB0aW1lIGluIHRoZSBmdXR1cmUuXG4vL1xuLy8gSGVyZSdzIGhvdyB0aGlzIHdvcmtzOlxuLy9cbi8vIFRoZSBUcmFuc2Zvcm0gc3RyZWFtIGhhcyBhbGwgdGhlIGFzcGVjdHMgb2YgdGhlIHJlYWRhYmxlIGFuZCB3cml0YWJsZVxuLy8gc3RyZWFtIGNsYXNzZXMuICBXaGVuIHlvdSB3cml0ZShjaHVuayksIHRoYXQgY2FsbHMgX3dyaXRlKGNodW5rLGNiKVxuLy8gaW50ZXJuYWxseSwgYW5kIHJldHVybnMgZmFsc2UgaWYgdGhlcmUncyBhIGxvdCBvZiBwZW5kaW5nIHdyaXRlc1xuLy8gYnVmZmVyZWQgdXAuICBXaGVuIHlvdSBjYWxsIHJlYWQoKSwgdGhhdCBjYWxscyBfcmVhZChuKSB1bnRpbFxuLy8gdGhlcmUncyBlbm91Z2ggcGVuZGluZyByZWFkYWJsZSBkYXRhIGJ1ZmZlcmVkIHVwLlxuLy9cbi8vIEluIGEgdHJhbnNmb3JtIHN0cmVhbSwgdGhlIHdyaXR0ZW4gZGF0YSBpcyBwbGFjZWQgaW4gYSBidWZmZXIuICBXaGVuXG4vLyBfcmVhZChuKSBpcyBjYWxsZWQsIGl0IHRyYW5zZm9ybXMgdGhlIHF1ZXVlZCB1cCBkYXRhLCBjYWxsaW5nIHRoZVxuLy8gYnVmZmVyZWQgX3dyaXRlIGNiJ3MgYXMgaXQgY29uc3VtZXMgY2h1bmtzLiAgSWYgY29uc3VtaW5nIGEgc2luZ2xlXG4vLyB3cml0dGVuIGNodW5rIHdvdWxkIHJlc3VsdCBpbiBtdWx0aXBsZSBvdXRwdXQgY2h1bmtzLCB0aGVuIHRoZSBmaXJzdFxuLy8gb3V0cHV0dGVkIGJpdCBjYWxscyB0aGUgcmVhZGNiLCBhbmQgc3Vic2VxdWVudCBjaHVua3MganVzdCBnbyBpbnRvXG4vLyB0aGUgcmVhZCBidWZmZXIsIGFuZCB3aWxsIGNhdXNlIGl0IHRvIGVtaXQgJ3JlYWRhYmxlJyBpZiBuZWNlc3NhcnkuXG4vL1xuLy8gVGhpcyB3YXksIGJhY2stcHJlc3N1cmUgaXMgYWN0dWFsbHkgZGV0ZXJtaW5lZCBieSB0aGUgcmVhZGluZyBzaWRlLFxuLy8gc2luY2UgX3JlYWQgaGFzIHRvIGJlIGNhbGxlZCB0byBzdGFydCBwcm9jZXNzaW5nIGEgbmV3IGNodW5rLiAgSG93ZXZlcixcbi8vIGEgcGF0aG9sb2dpY2FsIGluZmxhdGUgdHlwZSBvZiB0cmFuc2Zvcm0gY2FuIGNhdXNlIGV4Y2Vzc2l2ZSBidWZmZXJpbmdcbi8vIGhlcmUuICBGb3IgZXhhbXBsZSwgaW1hZ2luZSBhIHN0cmVhbSB3aGVyZSBldmVyeSBieXRlIG9mIGlucHV0IGlzXG4vLyBpbnRlcnByZXRlZCBhcyBhbiBpbnRlZ2VyIGZyb20gMC0yNTUsIGFuZCB0aGVuIHJlc3VsdHMgaW4gdGhhdCBtYW55XG4vLyBieXRlcyBvZiBvdXRwdXQuICBXcml0aW5nIHRoZSA0IGJ5dGVzIHtmZixmZixmZixmZn0gd291bGQgcmVzdWx0IGluXG4vLyAxa2Igb2YgZGF0YSBiZWluZyBvdXRwdXQuICBJbiB0aGlzIGNhc2UsIHlvdSBjb3VsZCB3cml0ZSBhIHZlcnkgc21hbGxcbi8vIGFtb3VudCBvZiBpbnB1dCwgYW5kIGVuZCB1cCB3aXRoIGEgdmVyeSBsYXJnZSBhbW91bnQgb2Ygb3V0cHV0LiAgSW5cbi8vIHN1Y2ggYSBwYXRob2xvZ2ljYWwgaW5mbGF0aW5nIG1lY2hhbmlzbSwgdGhlcmUnZCBiZSBubyB3YXkgdG8gdGVsbFxuLy8gdGhlIHN5c3RlbSB0byBzdG9wIGRvaW5nIHRoZSB0cmFuc2Zvcm0uICBBIHNpbmdsZSA0TUIgd3JpdGUgY291bGRcbi8vIGNhdXNlIHRoZSBzeXN0ZW0gdG8gcnVuIG91dCBvZiBtZW1vcnkuXG4vL1xuLy8gSG93ZXZlciwgZXZlbiBpbiBzdWNoIGEgcGF0aG9sb2dpY2FsIGNhc2UsIG9ubHkgYSBzaW5nbGUgd3JpdHRlbiBjaHVua1xuLy8gd291bGQgYmUgY29uc3VtZWQsIGFuZCB0aGVuIHRoZSByZXN0IHdvdWxkIHdhaXQgKHVuLXRyYW5zZm9ybWVkKSB1bnRpbFxuLy8gdGhlIHJlc3VsdHMgb2YgdGhlIHByZXZpb3VzIHRyYW5zZm9ybWVkIGNodW5rIHdlcmUgY29uc3VtZWQuXG5cbm1vZHVsZS5leHBvcnRzID0gVHJhbnNmb3JtO1xuXG52YXIgRHVwbGV4ID0gcmVxdWlyZSgnX3N0cmVhbV9kdXBsZXgnKTtcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xudXRpbC5pbmhlcml0cyhUcmFuc2Zvcm0sIER1cGxleCk7XG5cblxuZnVuY3Rpb24gVHJhbnNmb3JtU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIHRoaXMuYWZ0ZXJUcmFuc2Zvcm0gPSBmdW5jdGlvbihlciwgZGF0YSkge1xuICAgIHJldHVybiBhZnRlclRyYW5zZm9ybShzdHJlYW0sIGVyLCBkYXRhKTtcbiAgfTtcblxuICB0aGlzLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgdGhpcy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcbiAgdGhpcy53cml0ZWNiID0gbnVsbDtcbiAgdGhpcy53cml0ZWNodW5rID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYWZ0ZXJUcmFuc2Zvcm0oc3RyZWFtLCBlciwgZGF0YSkge1xuICB2YXIgdHMgPSBzdHJlYW0uX3RyYW5zZm9ybVN0YXRlO1xuICB0cy50cmFuc2Zvcm1pbmcgPSBmYWxzZTtcblxuICB2YXIgY2IgPSB0cy53cml0ZWNiO1xuXG4gIGlmICghY2IpXG4gICAgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcignbm8gd3JpdGVjYiBpbiBUcmFuc2Zvcm0gY2xhc3MnKSk7XG5cbiAgdHMud3JpdGVjaHVuayA9IG51bGw7XG4gIHRzLndyaXRlY2IgPSBudWxsO1xuXG4gIGlmIChkYXRhICE9PSBudWxsICYmIGRhdGEgIT09IHVuZGVmaW5lZClcbiAgICBzdHJlYW0ucHVzaChkYXRhKTtcblxuICBpZiAoY2IpXG4gICAgY2IoZXIpO1xuXG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgcnMucmVhZGluZyA9IGZhbHNlO1xuICBpZiAocnMubmVlZFJlYWRhYmxlIHx8IHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspIHtcbiAgICBzdHJlYW0uX3JlYWQocnMuaGlnaFdhdGVyTWFyayk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBUcmFuc2Zvcm0ob3B0aW9ucykge1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgVHJhbnNmb3JtKSlcbiAgICByZXR1cm4gbmV3IFRyYW5zZm9ybShvcHRpb25zKTtcblxuICBEdXBsZXguY2FsbCh0aGlzLCBvcHRpb25zKTtcblxuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZSA9IG5ldyBUcmFuc2Zvcm1TdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyB3aGVuIHRoZSB3cml0YWJsZSBzaWRlIGZpbmlzaGVzLCB0aGVuIGZsdXNoIG91dCBhbnl0aGluZyByZW1haW5pbmcuXG4gIHZhciBzdHJlYW0gPSB0aGlzO1xuXG4gIC8vIHN0YXJ0IG91dCBhc2tpbmcgZm9yIGEgcmVhZGFibGUgZXZlbnQgb25jZSBkYXRhIGlzIHRyYW5zZm9ybWVkLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLm5lZWRSZWFkYWJsZSA9IHRydWU7XG5cbiAgLy8gd2UgaGF2ZSBpbXBsZW1lbnRlZCB0aGUgX3JlYWQgbWV0aG9kLCBhbmQgZG9uZSB0aGUgb3RoZXIgdGhpbmdzXG4gIC8vIHRoYXQgUmVhZGFibGUgd2FudHMgYmVmb3JlIHRoZSBmaXJzdCBfcmVhZCBjYWxsLCBzbyB1bnNldCB0aGVcbiAgLy8gc3luYyBndWFyZCBmbGFnLlxuICB0aGlzLl9yZWFkYWJsZVN0YXRlLnN5bmMgPSBmYWxzZTtcblxuICB0aGlzLm9uY2UoJ2ZpbmlzaCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgdGhpcy5fZmx1c2gpXG4gICAgICB0aGlzLl9mbHVzaChmdW5jdGlvbihlcikge1xuICAgICAgICBkb25lKHN0cmVhbSwgZXIpO1xuICAgICAgfSk7XG4gICAgZWxzZVxuICAgICAgZG9uZShzdHJlYW0pO1xuICB9KTtcbn1cblxuVHJhbnNmb3JtLnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nKSB7XG4gIHRoaXMuX3RyYW5zZm9ybVN0YXRlLm5lZWRUcmFuc2Zvcm0gPSBmYWxzZTtcbiAgcmV0dXJuIER1cGxleC5wcm90b3R5cGUucHVzaC5jYWxsKHRoaXMsIGNodW5rLCBlbmNvZGluZyk7XG59O1xuXG4vLyBUaGlzIGlzIHRoZSBwYXJ0IHdoZXJlIHlvdSBkbyBzdHVmZiFcbi8vIG92ZXJyaWRlIHRoaXMgZnVuY3Rpb24gaW4gaW1wbGVtZW50YXRpb24gY2xhc3Nlcy5cbi8vICdjaHVuaycgaXMgYW4gaW5wdXQgY2h1bmsuXG4vL1xuLy8gQ2FsbCBgcHVzaChuZXdDaHVuaylgIHRvIHBhc3MgYWxvbmcgdHJhbnNmb3JtZWQgb3V0cHV0XG4vLyB0byB0aGUgcmVhZGFibGUgc2lkZS4gIFlvdSBtYXkgY2FsbCAncHVzaCcgemVybyBvciBtb3JlIHRpbWVzLlxuLy9cbi8vIENhbGwgYGNiKGVycilgIHdoZW4geW91IGFyZSBkb25lIHdpdGggdGhpcyBjaHVuay4gIElmIHlvdSBwYXNzXG4vLyBhbiBlcnJvciwgdGhlbiB0aGF0J2xsIHB1dCB0aGUgaHVydCBvbiB0aGUgd2hvbGUgb3BlcmF0aW9uLiAgSWYgeW91XG4vLyBuZXZlciBjYWxsIGNiKCksIHRoZW4geW91J2xsIG5ldmVyIGdldCBhbm90aGVyIGNodW5rLlxuVHJhbnNmb3JtLnByb3RvdHlwZS5fdHJhbnNmb3JtID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB0aHJvdyBuZXcgRXJyb3IoJ25vdCBpbXBsZW1lbnRlZCcpO1xufTtcblxuVHJhbnNmb3JtLnByb3RvdHlwZS5fd3JpdGUgPSBmdW5jdGlvbihjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHZhciB0cyA9IHRoaXMuX3RyYW5zZm9ybVN0YXRlO1xuICB0cy53cml0ZWNiID0gY2I7XG4gIHRzLndyaXRlY2h1bmsgPSBjaHVuaztcbiAgdHMud3JpdGVlbmNvZGluZyA9IGVuY29kaW5nO1xuICBpZiAoIXRzLnRyYW5zZm9ybWluZykge1xuICAgIHZhciBycyA9IHRoaXMuX3JlYWRhYmxlU3RhdGU7XG4gICAgaWYgKHRzLm5lZWRUcmFuc2Zvcm0gfHxcbiAgICAgICAgcnMubmVlZFJlYWRhYmxlIHx8XG4gICAgICAgIHJzLmxlbmd0aCA8IHJzLmhpZ2hXYXRlck1hcmspXG4gICAgICB0aGlzLl9yZWFkKHJzLmhpZ2hXYXRlck1hcmspO1xuICB9XG59O1xuXG4vLyBEb2Vzbid0IG1hdHRlciB3aGF0IHRoZSBhcmdzIGFyZSBoZXJlLlxuLy8gX3RyYW5zZm9ybSBkb2VzIGFsbCB0aGUgd29yay5cbi8vIFRoYXQgd2UgZ290IGhlcmUgbWVhbnMgdGhhdCB0aGUgcmVhZGFibGUgc2lkZSB3YW50cyBtb3JlIGRhdGEuXG5UcmFuc2Zvcm0ucHJvdG90eXBlLl9yZWFkID0gZnVuY3Rpb24obikge1xuICB2YXIgdHMgPSB0aGlzLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAodHMud3JpdGVjaHVuayAmJiB0cy53cml0ZWNiICYmICF0cy50cmFuc2Zvcm1pbmcpIHtcbiAgICB0cy50cmFuc2Zvcm1pbmcgPSB0cnVlO1xuICAgIHRoaXMuX3RyYW5zZm9ybSh0cy53cml0ZWNodW5rLCB0cy53cml0ZWVuY29kaW5nLCB0cy5hZnRlclRyYW5zZm9ybSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFyayB0aGF0IHdlIG5lZWQgYSB0cmFuc2Zvcm0sIHNvIHRoYXQgYW55IGRhdGEgdGhhdCBjb21lcyBpblxuICAgIC8vIHdpbGwgZ2V0IHByb2Nlc3NlZCwgbm93IHRoYXQgd2UndmUgYXNrZWQgZm9yIGl0LlxuICAgIHRzLm5lZWRUcmFuc2Zvcm0gPSB0cnVlO1xuICB9XG59O1xuXG5cbmZ1bmN0aW9uIGRvbmUoc3RyZWFtLCBlcikge1xuICBpZiAoZXIpXG4gICAgcmV0dXJuIHN0cmVhbS5lbWl0KCdlcnJvcicsIGVyKTtcblxuICAvLyBpZiB0aGVyZSdzIG5vdGhpbmcgaW4gdGhlIHdyaXRlIGJ1ZmZlciwgdGhlbiB0aGF0IG1lYW5zXG4gIC8vIHRoYXQgbm90aGluZyBtb3JlIHdpbGwgZXZlciBiZSBwcm92aWRlZFxuICB2YXIgd3MgPSBzdHJlYW0uX3dyaXRhYmxlU3RhdGU7XG4gIHZhciBycyA9IHN0cmVhbS5fcmVhZGFibGVTdGF0ZTtcbiAgdmFyIHRzID0gc3RyZWFtLl90cmFuc2Zvcm1TdGF0ZTtcblxuICBpZiAod3MubGVuZ3RoKVxuICAgIHRocm93IG5ldyBFcnJvcignY2FsbGluZyB0cmFuc2Zvcm0gZG9uZSB3aGVuIHdzLmxlbmd0aCAhPSAwJyk7XG5cbiAgaWYgKHRzLnRyYW5zZm9ybWluZylcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbGxpbmcgdHJhbnNmb3JtIGRvbmUgd2hlbiBzdGlsbCB0cmFuc2Zvcm1pbmcnKTtcblxuICByZXR1cm4gc3RyZWFtLnB1c2gobnVsbCk7XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gQSBiaXQgc2ltcGxlciB0aGFuIHJlYWRhYmxlIHN0cmVhbXMuXG4vLyBJbXBsZW1lbnQgYW4gYXN5bmMgLl93cml0ZShjaHVuaywgY2IpLCBhbmQgaXQnbGwgaGFuZGxlIGFsbFxuLy8gdGhlIGRyYWluIGV2ZW50IGVtaXNzaW9uIGFuZCBidWZmZXJpbmcuXG5cbm1vZHVsZS5leHBvcnRzID0gV3JpdGFibGU7XG5Xcml0YWJsZS5Xcml0YWJsZVN0YXRlID0gV3JpdGFibGVTdGF0ZTtcblxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgdGltZXJzID0gcmVxdWlyZSgndGltZXJzJyk7XG52YXIgQnVmZmVyID0gcmVxdWlyZSgnYnVmZmVyJykuQnVmZmVyO1xuXG51dGlsLmluaGVyaXRzKFdyaXRhYmxlLCBTdHJlYW0pO1xuXG5mdW5jdGlvbiBXcml0ZVJlcShjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHRoaXMuY2h1bmsgPSBjaHVuaztcbiAgdGhpcy5lbmNvZGluZyA9IGVuY29kaW5nO1xuICB0aGlzLmNhbGxiYWNrID0gY2I7XG59XG5cbmZ1bmN0aW9uIFdyaXRhYmxlU3RhdGUob3B0aW9ucywgc3RyZWFtKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIC8vIHRoZSBwb2ludCBhdCB3aGljaCB3cml0ZSgpIHN0YXJ0cyByZXR1cm5pbmcgZmFsc2VcbiAgLy8gTm90ZTogMCBpcyBhIHZhbGlkIHZhbHVlLCBtZWFucyB0aGF0IHdlIGFsd2F5cyByZXR1cm4gZmFsc2UgaWZcbiAgLy8gdGhlIGVudGlyZSBidWZmZXIgaXMgbm90IGZsdXNoZWQgaW1tZWRpYXRlbHkgb24gd3JpdGUoKVxuICB2YXIgaHdtID0gb3B0aW9ucy5oaWdoV2F0ZXJNYXJrO1xuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSAoaHdtIHx8IGh3bSA9PT0gMCkgPyBod20gOiAxNiAqIDEwMjQ7XG5cbiAgLy8gb2JqZWN0IHN0cmVhbSBmbGFnIHRvIGluZGljYXRlIHdoZXRoZXIgb3Igbm90IHRoaXMgc3RyZWFtXG4gIC8vIGNvbnRhaW5zIGJ1ZmZlcnMgb3Igb2JqZWN0cy5cbiAgdGhpcy5vYmplY3RNb2RlID0gISFvcHRpb25zLm9iamVjdE1vZGU7XG5cbiAgLy8gY2FzdCB0byBpbnRzLlxuICB0aGlzLmhpZ2hXYXRlck1hcmsgPSB+fnRoaXMuaGlnaFdhdGVyTWFyaztcblxuICB0aGlzLm5lZWREcmFpbiA9IGZhbHNlO1xuICAvLyBhdCB0aGUgc3RhcnQgb2YgY2FsbGluZyBlbmQoKVxuICB0aGlzLmVuZGluZyA9IGZhbHNlO1xuICAvLyB3aGVuIGVuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIHJldHVybmVkXG4gIHRoaXMuZW5kZWQgPSBmYWxzZTtcbiAgLy8gd2hlbiAnZmluaXNoJyBpcyBlbWl0dGVkXG4gIHRoaXMuZmluaXNoZWQgPSBmYWxzZTtcblxuICAvLyBzaG91bGQgd2UgZGVjb2RlIHN0cmluZ3MgaW50byBidWZmZXJzIGJlZm9yZSBwYXNzaW5nIHRvIF93cml0ZT9cbiAgLy8gdGhpcyBpcyBoZXJlIHNvIHRoYXQgc29tZSBub2RlLWNvcmUgc3RyZWFtcyBjYW4gb3B0aW1pemUgc3RyaW5nXG4gIC8vIGhhbmRsaW5nIGF0IGEgbG93ZXIgbGV2ZWwuXG4gIHZhciBub0RlY29kZSA9IG9wdGlvbnMuZGVjb2RlU3RyaW5ncyA9PT0gZmFsc2U7XG4gIHRoaXMuZGVjb2RlU3RyaW5ncyA9ICFub0RlY29kZTtcblxuICAvLyBDcnlwdG8gaXMga2luZCBvZiBvbGQgYW5kIGNydXN0eS4gIEhpc3RvcmljYWxseSwgaXRzIGRlZmF1bHQgc3RyaW5nXG4gIC8vIGVuY29kaW5nIGlzICdiaW5hcnknIHNvIHdlIGhhdmUgdG8gbWFrZSB0aGlzIGNvbmZpZ3VyYWJsZS5cbiAgLy8gRXZlcnl0aGluZyBlbHNlIGluIHRoZSB1bml2ZXJzZSB1c2VzICd1dGY4JywgdGhvdWdoLlxuICB0aGlzLmRlZmF1bHRFbmNvZGluZyA9IG9wdGlvbnMuZGVmYXVsdEVuY29kaW5nIHx8ICd1dGY4JztcblxuICAvLyBub3QgYW4gYWN0dWFsIGJ1ZmZlciB3ZSBrZWVwIHRyYWNrIG9mLCBidXQgYSBtZWFzdXJlbWVudFxuICAvLyBvZiBob3cgbXVjaCB3ZSdyZSB3YWl0aW5nIHRvIGdldCBwdXNoZWQgdG8gc29tZSB1bmRlcmx5aW5nXG4gIC8vIHNvY2tldCBvciBmaWxlLlxuICB0aGlzLmxlbmd0aCA9IDA7XG5cbiAgLy8gYSBmbGFnIHRvIHNlZSB3aGVuIHdlJ3JlIGluIHRoZSBtaWRkbGUgb2YgYSB3cml0ZS5cbiAgdGhpcy53cml0aW5nID0gZmFsc2U7XG5cbiAgLy8gYSBmbGFnIHRvIGJlIGFibGUgdG8gdGVsbCBpZiB0aGUgb253cml0ZSBjYiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksXG4gIC8vIG9yIG9uIGEgbGF0ZXIgdGljay4gIFdlIHNldCB0aGlzIHRvIHRydWUgYXQgZmlyc3QsIGJlY3Vhc2UgYW55XG4gIC8vIGFjdGlvbnMgdGhhdCBzaG91bGRuJ3QgaGFwcGVuIHVudGlsIFwibGF0ZXJcIiBzaG91bGQgZ2VuZXJhbGx5IGFsc29cbiAgLy8gbm90IGhhcHBlbiBiZWZvcmUgdGhlIGZpcnN0IHdyaXRlIGNhbGwuXG4gIHRoaXMuc3luYyA9IHRydWU7XG5cbiAgLy8gYSBmbGFnIHRvIGtub3cgaWYgd2UncmUgcHJvY2Vzc2luZyBwcmV2aW91c2x5IGJ1ZmZlcmVkIGl0ZW1zLCB3aGljaFxuICAvLyBtYXkgY2FsbCB0aGUgX3dyaXRlKCkgY2FsbGJhY2sgaW4gdGhlIHNhbWUgdGljaywgc28gdGhhdCB3ZSBkb24ndFxuICAvLyBlbmQgdXAgaW4gYW4gb3ZlcmxhcHBlZCBvbndyaXRlIHNpdHVhdGlvbi5cbiAgdGhpcy5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQncyBwYXNzZWQgdG8gX3dyaXRlKGNodW5rLGNiKVxuICB0aGlzLm9ud3JpdGUgPSBmdW5jdGlvbihlcikge1xuICAgIG9ud3JpdGUoc3RyZWFtLCBlcik7XG4gIH07XG5cbiAgLy8gdGhlIGNhbGxiYWNrIHRoYXQgdGhlIHVzZXIgc3VwcGxpZXMgdG8gd3JpdGUoY2h1bmssZW5jb2RpbmcsY2IpXG4gIHRoaXMud3JpdGVjYiA9IG51bGw7XG5cbiAgLy8gdGhlIGFtb3VudCB0aGF0IGlzIGJlaW5nIHdyaXR0ZW4gd2hlbiBfd3JpdGUgaXMgY2FsbGVkLlxuICB0aGlzLndyaXRlbGVuID0gMDtcblxuICB0aGlzLmJ1ZmZlciA9IFtdO1xufVxuXG5mdW5jdGlvbiBXcml0YWJsZShvcHRpb25zKSB7XG4gIC8vIFdyaXRhYmxlIGN0b3IgaXMgYXBwbGllZCB0byBEdXBsZXhlcywgdGhvdWdoIHRoZXkncmUgbm90XG4gIC8vIGluc3RhbmNlb2YgV3JpdGFibGUsIHRoZXkncmUgaW5zdGFuY2VvZiBSZWFkYWJsZS5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFdyaXRhYmxlKSAmJiAhKHRoaXMgaW5zdGFuY2VvZiBTdHJlYW0uRHVwbGV4KSlcbiAgICByZXR1cm4gbmV3IFdyaXRhYmxlKG9wdGlvbnMpO1xuXG4gIHRoaXMuX3dyaXRhYmxlU3RhdGUgPSBuZXcgV3JpdGFibGVTdGF0ZShvcHRpb25zLCB0aGlzKTtcblxuICAvLyBsZWdhY3kuXG4gIHRoaXMud3JpdGFibGUgPSB0cnVlO1xuXG4gIFN0cmVhbS5jYWxsKHRoaXMpO1xufVxuXG4vLyBPdGhlcndpc2UgcGVvcGxlIGNhbiBwaXBlIFdyaXRhYmxlIHN0cmVhbXMsIHdoaWNoIGlzIGp1c3Qgd3JvbmcuXG5Xcml0YWJsZS5wcm90b3R5cGUucGlwZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKCdDYW5ub3QgcGlwZS4gTm90IHJlYWRhYmxlLicpKTtcbn07XG5cblxuZnVuY3Rpb24gd3JpdGVBZnRlckVuZChzdHJlYW0sIHN0YXRlLCBjYikge1xuICB2YXIgZXIgPSBuZXcgRXJyb3IoJ3dyaXRlIGFmdGVyIGVuZCcpO1xuICAvLyBUT0RPOiBkZWZlciBlcnJvciBldmVudHMgY29uc2lzdGVudGx5IGV2ZXJ5d2hlcmUsIG5vdCBqdXN0IHRoZSBjYlxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gIHRpbWVycy5zZXRJbW1lZGlhdGUoZnVuY3Rpb24oKSB7XG4gICAgY2IoZXIpO1xuICB9KTtcbn1cblxuLy8gSWYgd2UgZ2V0IHNvbWV0aGluZyB0aGF0IGlzIG5vdCBhIGJ1ZmZlciwgc3RyaW5nLCBudWxsLCBvciB1bmRlZmluZWQsXG4vLyBhbmQgd2UncmUgbm90IGluIG9iamVjdE1vZGUsIHRoZW4gdGhhdCdzIGFuIGVycm9yLlxuLy8gT3RoZXJ3aXNlIHN0cmVhbSBjaHVua3MgYXJlIGFsbCBjb25zaWRlcmVkIHRvIGJlIG9mIGxlbmd0aD0xLCBhbmQgdGhlXG4vLyB3YXRlcm1hcmtzIGRldGVybWluZSBob3cgbWFueSBvYmplY3RzIHRvIGtlZXAgaW4gdGhlIGJ1ZmZlciwgcmF0aGVyIHRoYW5cbi8vIGhvdyBtYW55IGJ5dGVzIG9yIGNoYXJhY3RlcnMuXG5mdW5jdGlvbiB2YWxpZENodW5rKHN0cmVhbSwgc3RhdGUsIGNodW5rLCBjYikge1xuICB2YXIgdmFsaWQgPSB0cnVlO1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihjaHVuaykgJiZcbiAgICAgICdzdHJpbmcnICE9PSB0eXBlb2YgY2h1bmsgJiZcbiAgICAgIGNodW5rICE9PSBudWxsICYmXG4gICAgICBjaHVuayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc3RhdGUub2JqZWN0TW9kZSkge1xuICAgIHZhciBlciA9IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgbm9uLXN0cmluZy9idWZmZXIgY2h1bmsnKTtcbiAgICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGNiKGVyKTtcbiAgICB9KTtcbiAgICB2YWxpZCA9IGZhbHNlO1xuICB9XG4gIHJldHVybiB2YWxpZDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuICB2YXIgcmV0ID0gZmFsc2U7XG5cbiAgaWYgKHR5cGVvZiBlbmNvZGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNiID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBudWxsO1xuICB9XG5cbiAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihjaHVuaykpXG4gICAgZW5jb2RpbmcgPSAnYnVmZmVyJztcbiAgZWxzZSBpZiAoIWVuY29kaW5nKVxuICAgIGVuY29kaW5nID0gc3RhdGUuZGVmYXVsdEVuY29kaW5nO1xuXG4gIGlmICh0eXBlb2YgY2IgIT09ICdmdW5jdGlvbicpXG4gICAgY2IgPSBmdW5jdGlvbigpIHt9O1xuXG4gIGlmIChzdGF0ZS5lbmRlZClcbiAgICB3cml0ZUFmdGVyRW5kKHRoaXMsIHN0YXRlLCBjYik7XG4gIGVsc2UgaWYgKHZhbGlkQ2h1bmsodGhpcywgc3RhdGUsIGNodW5rLCBjYikpXG4gICAgcmV0ID0gd3JpdGVPckJ1ZmZlcih0aGlzLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYik7XG5cbiAgcmV0dXJuIHJldDtcbn07XG5cbmZ1bmN0aW9uIGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpIHtcbiAgaWYgKCFzdGF0ZS5vYmplY3RNb2RlICYmXG4gICAgICBzdGF0ZS5kZWNvZGVTdHJpbmdzICE9PSBmYWxzZSAmJlxuICAgICAgdHlwZW9mIGNodW5rID09PSAnc3RyaW5nJykge1xuICAgIGNodW5rID0gbmV3IEJ1ZmZlcihjaHVuaywgZW5jb2RpbmcpO1xuICB9XG4gIHJldHVybiBjaHVuaztcbn1cblxuLy8gaWYgd2UncmUgYWxyZWFkeSB3cml0aW5nIHNvbWV0aGluZywgdGhlbiBqdXN0IHB1dCB0aGlzXG4vLyBpbiB0aGUgcXVldWUsIGFuZCB3YWl0IG91ciB0dXJuLiAgT3RoZXJ3aXNlLCBjYWxsIF93cml0ZVxuLy8gSWYgd2UgcmV0dXJuIGZhbHNlLCB0aGVuIHdlIG5lZWQgYSBkcmFpbiBldmVudCwgc28gc2V0IHRoYXQgZmxhZy5cbmZ1bmN0aW9uIHdyaXRlT3JCdWZmZXIoc3RyZWFtLCBzdGF0ZSwgY2h1bmssIGVuY29kaW5nLCBjYikge1xuICBjaHVuayA9IGRlY29kZUNodW5rKHN0YXRlLCBjaHVuaywgZW5jb2RpbmcpO1xuICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgc3RhdGUubGVuZ3RoICs9IGxlbjtcblxuICB2YXIgcmV0ID0gc3RhdGUubGVuZ3RoIDwgc3RhdGUuaGlnaFdhdGVyTWFyaztcbiAgc3RhdGUubmVlZERyYWluID0gIXJldDtcblxuICBpZiAoc3RhdGUud3JpdGluZylcbiAgICBzdGF0ZS5idWZmZXIucHVzaChuZXcgV3JpdGVSZXEoY2h1bmssIGVuY29kaW5nLCBjYikpO1xuICBlbHNlXG4gICAgZG9Xcml0ZShzdHJlYW0sIHN0YXRlLCBsZW4sIGNodW5rLCBlbmNvZGluZywgY2IpO1xuXG4gIHJldHVybiByZXQ7XG59XG5cbmZ1bmN0aW9uIGRvV3JpdGUoc3RyZWFtLCBzdGF0ZSwgbGVuLCBjaHVuaywgZW5jb2RpbmcsIGNiKSB7XG4gIHN0YXRlLndyaXRlbGVuID0gbGVuO1xuICBzdGF0ZS53cml0ZWNiID0gY2I7XG4gIHN0YXRlLndyaXRpbmcgPSB0cnVlO1xuICBzdGF0ZS5zeW5jID0gdHJ1ZTtcbiAgc3RyZWFtLl93cml0ZShjaHVuaywgZW5jb2RpbmcsIHN0YXRlLm9ud3JpdGUpO1xuICBzdGF0ZS5zeW5jID0gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpIHtcbiAgaWYgKHN5bmMpXG4gICAgdGltZXJzLnNldEltbWVkaWF0ZShmdW5jdGlvbigpIHtcbiAgICAgIGNiKGVyKTtcbiAgICB9KTtcbiAgZWxzZVxuICAgIGNiKGVyKTtcblxuICBzdHJlYW0uZW1pdCgnZXJyb3InLCBlcik7XG59XG5cbmZ1bmN0aW9uIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSkge1xuICBzdGF0ZS53cml0aW5nID0gZmFsc2U7XG4gIHN0YXRlLndyaXRlY2IgPSBudWxsO1xuICBzdGF0ZS5sZW5ndGggLT0gc3RhdGUud3JpdGVsZW47XG4gIHN0YXRlLndyaXRlbGVuID0gMDtcbn1cblxuZnVuY3Rpb24gb253cml0ZShzdHJlYW0sIGVyKSB7XG4gIHZhciBzdGF0ZSA9IHN0cmVhbS5fd3JpdGFibGVTdGF0ZTtcbiAgdmFyIHN5bmMgPSBzdGF0ZS5zeW5jO1xuICB2YXIgY2IgPSBzdGF0ZS53cml0ZWNiO1xuXG4gIG9ud3JpdGVTdGF0ZVVwZGF0ZShzdGF0ZSk7XG5cbiAgaWYgKGVyKVxuICAgIG9ud3JpdGVFcnJvcihzdHJlYW0sIHN0YXRlLCBzeW5jLCBlciwgY2IpO1xuICBlbHNlIHtcbiAgICAvLyBDaGVjayBpZiB3ZSdyZSBhY3R1YWxseSByZWFkeSB0byBmaW5pc2gsIGJ1dCBkb24ndCBlbWl0IHlldFxuICAgIHZhciBmaW5pc2hlZCA9IG5lZWRGaW5pc2goc3RyZWFtLCBzdGF0ZSk7XG5cbiAgICBpZiAoIWZpbmlzaGVkICYmICFzdGF0ZS5idWZmZXJQcm9jZXNzaW5nICYmIHN0YXRlLmJ1ZmZlci5sZW5ndGgpXG4gICAgICBjbGVhckJ1ZmZlcihzdHJlYW0sIHN0YXRlKTtcblxuICAgIGlmIChzeW5jKSB7XG4gICAgICB0aW1lcnMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkge1xuICAgICAgICBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYik7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWZ0ZXJXcml0ZShzdHJlYW0sIHN0YXRlLCBmaW5pc2hlZCwgY2IpO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhZnRlcldyaXRlKHN0cmVhbSwgc3RhdGUsIGZpbmlzaGVkLCBjYikge1xuICBpZiAoIWZpbmlzaGVkKVxuICAgIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKTtcbiAgY2IoKTtcbiAgaWYgKGZpbmlzaGVkKVxuICAgIGZpbmlzaE1heWJlKHN0cmVhbSwgc3RhdGUpO1xufVxuXG4vLyBNdXN0IGZvcmNlIGNhbGxiYWNrIHRvIGJlIGNhbGxlZCBvbiBuZXh0VGljaywgc28gdGhhdCB3ZSBkb24ndFxuLy8gZW1pdCAnZHJhaW4nIGJlZm9yZSB0aGUgd3JpdGUoKSBjb25zdW1lciBnZXRzIHRoZSAnZmFsc2UnIHJldHVyblxuLy8gdmFsdWUsIGFuZCBoYXMgYSBjaGFuY2UgdG8gYXR0YWNoIGEgJ2RyYWluJyBsaXN0ZW5lci5cbmZ1bmN0aW9uIG9ud3JpdGVEcmFpbihzdHJlYW0sIHN0YXRlKSB7XG4gIGlmIChzdGF0ZS5sZW5ndGggPT09IDAgJiYgc3RhdGUubmVlZERyYWluKSB7XG4gICAgc3RhdGUubmVlZERyYWluID0gZmFsc2U7XG4gICAgc3RyZWFtLmVtaXQoJ2RyYWluJyk7XG4gIH1cbn1cblxuXG4vLyBpZiB0aGVyZSdzIHNvbWV0aGluZyBpbiB0aGUgYnVmZmVyIHdhaXRpbmcsIHRoZW4gcHJvY2VzcyBpdFxuZnVuY3Rpb24gY2xlYXJCdWZmZXIoc3RyZWFtLCBzdGF0ZSkge1xuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gdHJ1ZTtcblxuICBmb3IgKHZhciBjID0gMDsgYyA8IHN0YXRlLmJ1ZmZlci5sZW5ndGg7IGMrKykge1xuICAgIHZhciBlbnRyeSA9IHN0YXRlLmJ1ZmZlcltjXTtcbiAgICB2YXIgY2h1bmsgPSBlbnRyeS5jaHVuaztcbiAgICB2YXIgZW5jb2RpbmcgPSBlbnRyeS5lbmNvZGluZztcbiAgICB2YXIgY2IgPSBlbnRyeS5jYWxsYmFjaztcbiAgICB2YXIgbGVuID0gc3RhdGUub2JqZWN0TW9kZSA/IDEgOiBjaHVuay5sZW5ndGg7XG5cbiAgICBkb1dyaXRlKHN0cmVhbSwgc3RhdGUsIGxlbiwgY2h1bmssIGVuY29kaW5nLCBjYik7XG5cbiAgICAvLyBpZiB3ZSBkaWRuJ3QgY2FsbCB0aGUgb253cml0ZSBpbW1lZGlhdGVseSwgdGhlblxuICAgIC8vIGl0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byB3YWl0IHVudGlsIGl0IGRvZXMuXG4gICAgLy8gYWxzbywgdGhhdCBtZWFucyB0aGF0IHRoZSBjaHVuayBhbmQgY2IgYXJlIGN1cnJlbnRseVxuICAgIC8vIGJlaW5nIHByb2Nlc3NlZCwgc28gbW92ZSB0aGUgYnVmZmVyIGNvdW50ZXIgcGFzdCB0aGVtLlxuICAgIGlmIChzdGF0ZS53cml0aW5nKSB7XG4gICAgICBjKys7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBzdGF0ZS5idWZmZXJQcm9jZXNzaW5nID0gZmFsc2U7XG4gIGlmIChjIDwgc3RhdGUuYnVmZmVyLmxlbmd0aClcbiAgICBzdGF0ZS5idWZmZXIgPSBzdGF0ZS5idWZmZXIuc2xpY2UoYyk7XG4gIGVsc2VcbiAgICBzdGF0ZS5idWZmZXIubGVuZ3RoID0gMDtcbn1cblxuV3JpdGFibGUucHJvdG90eXBlLl93cml0ZSA9IGZ1bmN0aW9uKGNodW5rLCBlbmNvZGluZywgY2IpIHtcbiAgY2IobmV3IEVycm9yKCdub3QgaW1wbGVtZW50ZWQnKSk7XG59O1xuXG5Xcml0YWJsZS5wcm90b3R5cGUuZW5kID0gZnVuY3Rpb24oY2h1bmssIGVuY29kaW5nLCBjYikge1xuICB2YXIgc3RhdGUgPSB0aGlzLl93cml0YWJsZVN0YXRlO1xuXG4gIGlmICh0eXBlb2YgY2h1bmsgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYiA9IGNodW5rO1xuICAgIGNodW5rID0gbnVsbDtcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGVuY29kaW5nID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2IgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIGNodW5rICE9PSAndW5kZWZpbmVkJyAmJiBjaHVuayAhPT0gbnVsbClcbiAgICB0aGlzLndyaXRlKGNodW5rLCBlbmNvZGluZyk7XG5cbiAgLy8gaWdub3JlIHVubmVjZXNzYXJ5IGVuZCgpIGNhbGxzLlxuICBpZiAoIXN0YXRlLmVuZGluZyAmJiAhc3RhdGUuZmluaXNoZWQpXG4gICAgZW5kV3JpdGFibGUodGhpcywgc3RhdGUsIGNiKTtcbn07XG5cblxuZnVuY3Rpb24gbmVlZEZpbmlzaChzdHJlYW0sIHN0YXRlKSB7XG4gIHJldHVybiAoc3RhdGUuZW5kaW5nICYmXG4gICAgICAgICAgc3RhdGUubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgIXN0YXRlLmZpbmlzaGVkICYmXG4gICAgICAgICAgIXN0YXRlLndyaXRpbmcpO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKSB7XG4gIHZhciBuZWVkID0gbmVlZEZpbmlzaChzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKG5lZWQpIHtcbiAgICBzdGF0ZS5maW5pc2hlZCA9IHRydWU7XG4gICAgc3RyZWFtLmVtaXQoJ2ZpbmlzaCcpO1xuICB9XG4gIHJldHVybiBuZWVkO1xufVxuXG5mdW5jdGlvbiBlbmRXcml0YWJsZShzdHJlYW0sIHN0YXRlLCBjYikge1xuICBzdGF0ZS5lbmRpbmcgPSB0cnVlO1xuICBmaW5pc2hNYXliZShzdHJlYW0sIHN0YXRlKTtcbiAgaWYgKGNiKSB7XG4gICAgaWYgKHN0YXRlLmZpbmlzaGVkKVxuICAgICAgdGltZXJzLnNldEltbWVkaWF0ZShjYik7XG4gICAgZWxzZVxuICAgICAgc3RyZWFtLm9uY2UoJ2ZpbmlzaCcsIGNiKTtcbiAgfVxuICBzdGF0ZS5lbmRlZCA9IHRydWU7XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gVVRJTElUWVxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcbnZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICB0aGlzLm1lc3NhZ2UgPSBvcHRpb25zLm1lc3NhZ2UgfHwgZ2V0TWVzc2FnZSh0aGlzKTtcbn07XG5cbi8vIGFzc2VydC5Bc3NlcnRpb25FcnJvciBpbnN0YW5jZW9mIEVycm9yXG51dGlsLmluaGVyaXRzKGFzc2VydC5Bc3NlcnRpb25FcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiByZXBsYWNlcihrZXksIHZhbHVlKSB7XG4gIGlmICh1dGlsLmlzVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiAnJyArIHZhbHVlO1xuICB9XG4gIGlmICh1dGlsLmlzTnVtYmVyKHZhbHVlKSAmJiAoaXNOYU4odmFsdWUpIHx8ICFpc0Zpbml0ZSh2YWx1ZSkpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgaWYgKHV0aWwuaXNGdW5jdGlvbih2YWx1ZSkgfHwgdXRpbC5pc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHRydW5jYXRlKHMsIG4pIHtcbiAgaWYgKHV0aWwuaXNTdHJpbmcocykpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPCBuID8gcyA6IHMuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHM7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TWVzc2FnZShzZWxmKSB7XG4gIHJldHVybiB0cnVuY2F0ZShKU09OLnN0cmluZ2lmeShzZWxmLmFjdHVhbCwgcmVwbGFjZXIpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5leHBlY3RlZCwgcmVwbGFjZXIpLCAxMjgpO1xufVxuXG4vLyBBdCBwcmVzZW50IG9ubHkgdGhlIHRocmVlIGtleXMgbWVudGlvbmVkIGFib3ZlIGFyZSB1c2VkIGFuZFxuLy8gdW5kZXJzdG9vZCBieSB0aGUgc3BlYy4gSW1wbGVtZW50YXRpb25zIG9yIHN1YiBtb2R1bGVzIGNhbiBwYXNzXG4vLyBvdGhlciBrZXlzIHRvIHRoZSBBc3NlcnRpb25FcnJvcidzIGNvbnN0cnVjdG9yIC0gdGhleSB3aWxsIGJlXG4vLyBpZ25vcmVkLlxuXG4vLyAzLiBBbGwgb2YgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgbXVzdCB0aHJvdyBhbiBBc3NlcnRpb25FcnJvclxuLy8gd2hlbiBhIGNvcnJlc3BvbmRpbmcgY29uZGl0aW9uIGlzIG5vdCBtZXQsIHdpdGggYSBtZXNzYWdlIHRoYXRcbi8vIG1heSBiZSB1bmRlZmluZWQgaWYgbm90IHByb3ZpZGVkLiAgQWxsIGFzc2VydGlvbiBtZXRob2RzIHByb3ZpZGVcbi8vIGJvdGggdGhlIGFjdHVhbCBhbmQgZXhwZWN0ZWQgdmFsdWVzIHRvIHRoZSBhc3NlcnRpb24gZXJyb3IgZm9yXG4vLyBkaXNwbGF5IHB1cnBvc2VzLlxuXG5mdW5jdGlvbiBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yLCBzdGFja1N0YXJ0RnVuY3Rpb24pIHtcbiAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgIHN0YWNrU3RhcnRGdW5jdGlvbjogc3RhY2tTdGFydEZ1bmN0aW9uXG4gIH0pO1xufVxuXG4vLyBFWFRFTlNJT04hIGFsbG93cyBmb3Igd2VsbCBiZWhhdmVkIGVycm9ycyBkZWZpbmVkIGVsc2V3aGVyZS5cbmFzc2VydC5mYWlsID0gZmFpbDtcblxuLy8gNC4gUHVyZSBhc3NlcnRpb24gdGVzdHMgd2hldGhlciBhIHZhbHVlIGlzIHRydXRoeSwgYXMgZGV0ZXJtaW5lZFxuLy8gYnkgISFndWFyZC5cbi8vIGFzc2VydC5vayhndWFyZCwgbWVzc2FnZV9vcHQpO1xuLy8gVGhpcyBzdGF0ZW1lbnQgaXMgZXF1aXZhbGVudCB0byBhc3NlcnQuZXF1YWwodHJ1ZSwgISFndWFyZCxcbi8vIG1lc3NhZ2Vfb3B0KTsuIFRvIHRlc3Qgc3RyaWN0bHkgZm9yIHRoZSB2YWx1ZSB0cnVlLCB1c2Vcbi8vIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCBndWFyZCwgbWVzc2FnZV9vcHQpOy5cblxuZnVuY3Rpb24gb2sodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09JywgYXNzZXJ0Lm9rKTtcbn1cbmFzc2VydC5vayA9IG9rO1xuXG4vLyA1LiBUaGUgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHNoYWxsb3csIGNvZXJjaXZlIGVxdWFsaXR5IHdpdGhcbi8vID09LlxuLy8gYXNzZXJ0LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkKSBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5lcXVhbCk7XG59O1xuXG4vLyA2LiBUaGUgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igd2hldGhlciB0d28gb2JqZWN0cyBhcmUgbm90IGVxdWFsXG4vLyB3aXRoICE9IGFzc2VydC5ub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIG5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9JywgYXNzZXJ0Lm5vdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gNy4gVGhlIGVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBhIGRlZXAgZXF1YWxpdHkgcmVsYXRpb24uXG4vLyBhc3NlcnQuZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmRlZXBFcXVhbCA9IGZ1bmN0aW9uIGRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBFcXVhbCcsIGFzc2VydC5kZWVwRXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgLy8gNy4xLiBBbGwgaWRlbnRpY2FsIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIGlmICh1dGlsLmlzQnVmZmVyKGFjdHVhbCkgJiYgdXRpbC5pc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICBpZiAoYWN0dWFsLmxlbmd0aCAhPSBleHBlY3RlZC5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWN0dWFsLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYWN0dWFsW2ldICE9PSBleHBlY3RlZFtpXSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIC8vIDcuMi4gSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgRGF0ZSBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgRGF0ZSBvYmplY3QgdGhhdCByZWZlcnMgdG8gdGhlIHNhbWUgdGltZS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzRGF0ZShhY3R1YWwpICYmIHV0aWwuaXNEYXRlKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKCk7XG5cbiAgLy8gNy4zIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgUmVnRXhwIG9iamVjdCB3aXRoIHRoZSBzYW1lIHNvdXJjZSBhbmRcbiAgLy8gcHJvcGVydGllcyAoYGdsb2JhbGAsIGBtdWx0aWxpbmVgLCBgbGFzdEluZGV4YCwgYGlnbm9yZUNhc2VgKS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzUmVnRXhwKGFjdHVhbCkgJiYgdXRpbC5pc1JlZ0V4cChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmXG4gICAgICAgICAgIGFjdHVhbC5nbG9iYWwgPT09IGV4cGVjdGVkLmdsb2JhbCAmJlxuICAgICAgICAgICBhY3R1YWwubXVsdGlsaW5lID09PSBleHBlY3RlZC5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgYWN0dWFsLmxhc3RJbmRleCA9PT0gZXhwZWN0ZWQubGFzdEluZGV4ICYmXG4gICAgICAgICAgIGFjdHVhbC5pZ25vcmVDYXNlID09PSBleHBlY3RlZC5pZ25vcmVDYXNlO1xuXG4gIC8vIDcuNC4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICghdXRpbC5pc09iamVjdChhY3R1YWwpICYmICF1dGlsLmlzT2JqZWN0KGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gNy41IEZvciBhbGwgb3RoZXIgT2JqZWN0IHBhaXJzLCBpbmNsdWRpbmcgQXJyYXkgb2JqZWN0cywgZXF1aXZhbGVuY2UgaXNcbiAgLy8gZGV0ZXJtaW5lZCBieSBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGFzIHZlcmlmaWVkXG4gIC8vIHdpdGggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKSwgdGhlIHNhbWUgc2V0IG9mIGtleXNcbiAgLy8gKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksIGVxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeVxuICAvLyBjb3JyZXNwb25kaW5nIGtleSwgYW5kIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS4gTm90ZTogdGhpc1xuICAvLyBhY2NvdW50cyBmb3IgYm90aCBuYW1lZCBhbmQgaW5kZXhlZCBwcm9wZXJ0aWVzIG9uIEFycmF5cy5cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYikge1xuICBpZiAodXRpbC5pc051bGxPclVuZGVmaW5lZChhKSB8fCB1dGlsLmlzTnVsbE9yVW5kZWZpbmVkKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LlxuICBpZiAoYS5wcm90b3R5cGUgIT09IGIucHJvdG90eXBlKSByZXR1cm4gZmFsc2U7XG4gIC8vfn5+SSd2ZSBtYW5hZ2VkIHRvIGJyZWFrIE9iamVjdC5rZXlzIHRocm91Z2ggc2NyZXd5IGFyZ3VtZW50cyBwYXNzaW5nLlxuICAvLyAgIENvbnZlcnRpbmcgdG8gYXJyYXkgc29sdmVzIHRoZSBwcm9ibGVtLlxuICBpZiAoaXNBcmd1bWVudHMoYSkpIHtcbiAgICBpZiAoIWlzQXJndW1lbnRzKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIF9kZWVwRXF1YWwoYSwgYik7XG4gIH1cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBzaGltcy5rZXlzKGEpLFxuICAgICAgICBrYiA9IHNoaW1zLmtleXMoYiksXG4gICAgICAgIGtleSwgaTtcbiAgfSBjYXRjaCAoZSkgey8vaGFwcGVucyB3aGVuIG9uZSBpcyBhIHN0cmluZyBsaXRlcmFsIGFuZCB0aGUgb3RoZXIgaXNuJ3RcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPSBrYi5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvL3RoZSBzYW1lIHNldCBvZiBrZXlzIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLFxuICBrYS5zb3J0KCk7XG4gIGtiLnNvcnQoKTtcbiAgLy9+fn5jaGVhcCBrZXkgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChrYVtpXSAhPSBrYltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvL2VxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeSBjb3JyZXNwb25kaW5nIGtleSwgYW5kXG4gIC8vfn5+cG9zc2libHkgZXhwZW5zaXZlIGRlZXAgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghX2RlZXBFcXVhbChhW2tleV0sIGJba2V5XSkpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcEVxdWFsJywgYXNzZXJ0Lm5vdERlZXBFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDkuIFRoZSBzdHJpY3QgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHN0cmljdCBlcXVhbGl0eSwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBzdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT09JywgYXNzZXJ0LnN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gMTAuIFRoZSBzdHJpY3Qgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igc3RyaWN0IGluZXF1YWxpdHksIGFzXG4vLyBkZXRlcm1pbmVkIGJ5ICE9PS4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIG5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPT0nLCBhc3NlcnQubm90U3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZXhwZWN0ZWQpID09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcmV0dXJuIGV4cGVjdGVkLnRlc3QoYWN0dWFsKTtcbiAgfSBlbHNlIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gX3Rocm93cyhzaG91bGRUaHJvdywgYmxvY2ssIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIHZhciBhY3R1YWw7XG5cbiAgaWYgKHV0aWwuaXNTdHJpbmcoZXhwZWN0ZWQpKSB7XG4gICAgbWVzc2FnZSA9IGV4cGVjdGVkO1xuICAgIGV4cGVjdGVkID0gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGFjdHVhbCA9IGU7XG4gIH1cblxuICBtZXNzYWdlID0gKGV4cGVjdGVkICYmIGV4cGVjdGVkLm5hbWUgPyAnICgnICsgZXhwZWN0ZWQubmFtZSArICcpLicgOiAnLicpICtcbiAgICAgICAgICAgIChtZXNzYWdlID8gJyAnICsgbWVzc2FnZSA6ICcuJyk7XG5cbiAgaWYgKHNob3VsZFRocm93ICYmICFhY3R1YWwpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdNaXNzaW5nIGV4cGVjdGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICghc2hvdWxkVGhyb3cgJiYgZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdHb3QgdW53YW50ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKChzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgZXhwZWN0ZWQgJiZcbiAgICAgICFleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHwgKCFzaG91bGRUaHJvdyAmJiBhY3R1YWwpKSB7XG4gICAgdGhyb3cgYWN0dWFsO1xuICB9XG59XG5cbi8vIDExLiBFeHBlY3RlZCB0byB0aHJvdyBhbiBlcnJvcjpcbi8vIGFzc2VydC50aHJvd3MoYmxvY2ssIEVycm9yX29wdCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQudGhyb3dzID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MuYXBwbHkodGhpcywgW3RydWVdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG4vLyBFWFRFTlNJT04hIFRoaXMgaXMgYW5ub3lpbmcgdG8gd3JpdGUgb3V0c2lkZSB0aGlzIG1vZHVsZS5cbmFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFtmYWxzZV0uY29uY2F0KHBTbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbn07XG5cbmFzc2VydC5pZkVycm9yID0gZnVuY3Rpb24oZXJyKSB7IGlmIChlcnIpIHt0aHJvdyBlcnI7fX07IiwiLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2V2ZW50cyB8fCB7fTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gdGhpcy5fbWF4TGlzdGVuZXJzIHx8IHVuZGVmaW5lZDtcbn1cbm1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjEwLnhcbkV2ZW50RW1pdHRlci5FdmVudEVtaXR0ZXIgPSBFdmVudEVtaXR0ZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuX21heExpc3RlbmVycyA9IHVuZGVmaW5lZDtcblxuLy8gQnkgZGVmYXVsdCBFdmVudEVtaXR0ZXJzIHdpbGwgcHJpbnQgYSB3YXJuaW5nIGlmIG1vcmUgdGhhbiAxMCBsaXN0ZW5lcnMgYXJlXG4vLyBhZGRlZCB0byBpdC4gVGhpcyBpcyBhIHVzZWZ1bCBkZWZhdWx0IHdoaWNoIGhlbHBzIGZpbmRpbmcgbWVtb3J5IGxlYWtzLlxuRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnMgPSAxMDtcblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24obikge1xuICBpZiAoIXV0aWwuaXNOdW1iZXIobikgfHwgbiA8IDApXG4gICAgdGhyb3cgVHlwZUVycm9yKCduIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgdGhpcy5fbWF4TGlzdGVuZXJzID0gbjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbih0eXBlKSB7XG4gIHZhciBlciwgaGFuZGxlciwgbGVuLCBhcmdzLCBpLCBsaXN0ZW5lcnM7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gSWYgdGhlcmUgaXMgbm8gJ2Vycm9yJyBldmVudCBsaXN0ZW5lciB0aGVuIHRocm93LlxuICBpZiAodHlwZSA9PT0gJ2Vycm9yJykge1xuICAgIGlmICghdGhpcy5fZXZlbnRzLmVycm9yIHx8XG4gICAgICAgICh1dGlsLmlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKHV0aWwuaXNVbmRlZmluZWQoaGFuZGxlcikpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGlmICh1dGlsLmlzRnVuY3Rpb24oaGFuZGxlcikpIHtcbiAgICBzd2l0Y2ggKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIC8vIGZhc3QgY2FzZXNcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgaGFuZGxlci5jYWxsKHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdLCBhcmd1bWVudHNbMl0pO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIHNsb3dlclxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICAgICAgYXJncyA9IG5ldyBBcnJheShsZW4gLSAxKTtcbiAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKVxuICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICBoYW5kbGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfSBlbHNlIGlmICh1dGlsLmlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuXG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCF1dGlsLmlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpXG4gICAgdGhpcy5fZXZlbnRzID0ge307XG5cbiAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgLy8gYWRkaW5nIGl0IHRvIHRoZSBsaXN0ZW5lcnMsIGZpcnN0IGVtaXQgXCJuZXdMaXN0ZW5lclwiLlxuICBpZiAodGhpcy5fZXZlbnRzLm5ld0xpc3RlbmVyKVxuICAgIHRoaXMuZW1pdCgnbmV3TGlzdGVuZXInLCB0eXBlLFxuICAgICAgICAgICAgICB1dGlsLmlzRnVuY3Rpb24obGlzdGVuZXIubGlzdGVuZXIpID9cbiAgICAgICAgICAgICAgbGlzdGVuZXIubGlzdGVuZXIgOiBsaXN0ZW5lcik7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbdHlwZV0pXG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gbGlzdGVuZXI7XG4gIGVsc2UgaWYgKHV0aWwuaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmICh1dGlsLmlzT2JqZWN0KHRoaXMuX2V2ZW50c1t0eXBlXSkgJiYgIXRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQpIHtcbiAgICB2YXIgbTtcbiAgICBpZiAoIXV0aWwuaXNVbmRlZmluZWQodGhpcy5fbWF4TGlzdGVuZXJzKSkge1xuICAgICAgbSA9IHRoaXMuX21heExpc3RlbmVycztcbiAgICB9IGVsc2Uge1xuICAgICAgbSA9IEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH1cblxuICAgIGlmIChtICYmIG0gPiAwICYmIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGggPiBtKSB7XG4gICAgICB0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJyhub2RlKSB3YXJuaW5nOiBwb3NzaWJsZSBFdmVudEVtaXR0ZXIgbWVtb3J5ICcgK1xuICAgICAgICAgICAgICAgICAgICAnbGVhayBkZXRlY3RlZC4gJWQgbGlzdGVuZXJzIGFkZGVkLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ1VzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvIGluY3JlYXNlIGxpbWl0LicsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS5sZW5ndGgpO1xuICAgICAgY29uc29sZS50cmFjZSgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXI7XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICghdXRpbC5pc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcbiAgICBsaXN0ZW5lci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIXV0aWwuaXNGdW5jdGlvbihsaXN0ZW5lcikpXG4gICAgdGhyb3cgVHlwZUVycm9yKCdsaXN0ZW5lciBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIGxpc3QgPSB0aGlzLl9ldmVudHNbdHlwZV07XG4gIGxlbmd0aCA9IGxpc3QubGVuZ3RoO1xuICBwb3NpdGlvbiA9IC0xO1xuXG4gIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fFxuICAgICAgKHV0aWwuaXNGdW5jdGlvbihsaXN0Lmxpc3RlbmVyKSAmJiBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikpIHtcbiAgICBkZWxldGUgdGhpcy5fZXZlbnRzW3R5cGVdO1xuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuXG4gIH0gZWxzZSBpZiAodXRpbC5pc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKHV0aWwuaXNGdW5jdGlvbihsaXN0ZW5lcnMpKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICB9IGVsc2Uge1xuICAgIC8vIExJRk8gb3JkZXJcbiAgICB3aGlsZSAobGlzdGVuZXJzLmxlbmd0aClcbiAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzW2xpc3RlbmVycy5sZW5ndGggLSAxXSk7XG4gIH1cbiAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJzID0gZnVuY3Rpb24odHlwZSkge1xuICB2YXIgcmV0O1xuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW3R5cGVdKVxuICAgIHJldCA9IFtdO1xuICBlbHNlIGlmICh1dGlsLmlzRnVuY3Rpb24odGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICByZXQgPSBbdGhpcy5fZXZlbnRzW3R5cGVdXTtcbiAgZWxzZVxuICAgIHJldCA9IHRoaXMuX2V2ZW50c1t0eXBlXS5zbGljZSgpO1xuICByZXR1cm4gcmV0O1xufTtcblxuRXZlbnRFbWl0dGVyLmxpc3RlbmVyQ291bnQgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlKSB7XG4gIHZhciByZXQ7XG4gIGlmICghZW1pdHRlci5fZXZlbnRzIHx8ICFlbWl0dGVyLl9ldmVudHNbdHlwZV0pXG4gICAgcmV0ID0gMDtcbiAgZWxzZSBpZiAodXRpbC5pc0Z1bmN0aW9uKGVtaXR0ZXIuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gMTtcbiAgZWxzZVxuICAgIHJldCA9IGVtaXR0ZXIuX2V2ZW50c1t0eXBlXS5sZW5ndGg7XG4gIHJldHVybiByZXQ7XG59OyIsInZhciBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuXG52YXIgaHR0cHMgPSBtb2R1bGUuZXhwb3J0cztcblxuZm9yICh2YXIga2V5IGluIGh0dHApIHtcbiAgICBpZiAoaHR0cC5oYXNPd25Qcm9wZXJ0eShrZXkpKSBodHRwc1trZXldID0gaHR0cFtrZXldO1xufTtcblxuaHR0cHMucmVxdWVzdCA9IGZ1bmN0aW9uIChwYXJhbXMsIGNiKSB7XG4gICAgaWYgKCFwYXJhbXMpIHBhcmFtcyA9IHt9O1xuICAgIHBhcmFtcy5zY2hlbWUgPSAnaHR0cHMnO1xuICAgIHJldHVybiBodHRwLnJlcXVlc3QuY2FsbCh0aGlzLCBwYXJhbXMsIGNiKTtcbn0iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gUXVlcnkgU3RyaW5nIFV0aWxpdGllc1xuXG52YXIgUXVlcnlTdHJpbmcgPSBleHBvcnRzO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcbnZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG5cbi8vIElmIG9iai5oYXNPd25Qcm9wZXJ0eSBoYXMgYmVlbiBvdmVycmlkZGVuLCB0aGVuIGNhbGxpbmdcbi8vIG9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSB3aWxsIGJyZWFrLlxuLy8gU2VlOiBodHRwczovL2dpdGh1Yi5jb20vam95ZW50L25vZGUvaXNzdWVzLzE3MDdcbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cblxuZnVuY3Rpb24gY2hhckNvZGUoYykge1xuICByZXR1cm4gYy5jaGFyQ29kZUF0KDApO1xufVxuXG5cbi8vIGEgc2FmZSBmYXN0IGFsdGVybmF0aXZlIHRvIGRlY29kZVVSSUNvbXBvbmVudFxuUXVlcnlTdHJpbmcudW5lc2NhcGVCdWZmZXIgPSBmdW5jdGlvbihzLCBkZWNvZGVTcGFjZXMpIHtcbiAgdmFyIG91dCA9IG5ldyBCdWZmZXIocy5sZW5ndGgpO1xuICB2YXIgc3RhdGUgPSAnQ0hBUic7IC8vIHN0YXRlczogQ0hBUiwgSEVYMCwgSEVYMVxuICB2YXIgbiwgbSwgaGV4Y2hhcjtcblxuICBmb3IgKHZhciBpbkluZGV4ID0gMCwgb3V0SW5kZXggPSAwOyBpbkluZGV4IDw9IHMubGVuZ3RoOyBpbkluZGV4KyspIHtcbiAgICB2YXIgYyA9IHMuY2hhckNvZGVBdChpbkluZGV4KTtcbiAgICBzd2l0Y2ggKHN0YXRlKSB7XG4gICAgICBjYXNlICdDSEFSJzpcbiAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgY2FzZSBjaGFyQ29kZSgnJScpOlxuICAgICAgICAgICAgbiA9IDA7XG4gICAgICAgICAgICBtID0gMDtcbiAgICAgICAgICAgIHN0YXRlID0gJ0hFWDAnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBjaGFyQ29kZSgnKycpOlxuICAgICAgICAgICAgaWYgKGRlY29kZVNwYWNlcykgYyA9IGNoYXJDb2RlKCcgJyk7XG4gICAgICAgICAgICAvLyBwYXNzIHRocnVcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgb3V0W291dEluZGV4KytdID0gYztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdIRVgwJzpcbiAgICAgICAgc3RhdGUgPSAnSEVYMSc7XG4gICAgICAgIGhleGNoYXIgPSBjO1xuICAgICAgICBpZiAoY2hhckNvZGUoJzAnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJzknKSkge1xuICAgICAgICAgIG4gPSBjIC0gY2hhckNvZGUoJzAnKTtcbiAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSgnYScpIDw9IGMgJiYgYyA8PSBjaGFyQ29kZSgnZicpKSB7XG4gICAgICAgICAgbiA9IGMgLSBjaGFyQ29kZSgnYScpICsgMTA7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUoJ0EnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJ0YnKSkge1xuICAgICAgICAgIG4gPSBjIC0gY2hhckNvZGUoJ0EnKSArIDEwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IGNoYXJDb2RlKCclJyk7XG4gICAgICAgICAgb3V0W291dEluZGV4KytdID0gYztcbiAgICAgICAgICBzdGF0ZSA9ICdDSEFSJztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnSEVYMSc6XG4gICAgICAgIHN0YXRlID0gJ0NIQVInO1xuICAgICAgICBpZiAoY2hhckNvZGUoJzAnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJzknKSkge1xuICAgICAgICAgIG0gPSBjIC0gY2hhckNvZGUoJzAnKTtcbiAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSgnYScpIDw9IGMgJiYgYyA8PSBjaGFyQ29kZSgnZicpKSB7XG4gICAgICAgICAgbSA9IGMgLSBjaGFyQ29kZSgnYScpICsgMTA7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhckNvZGUoJ0EnKSA8PSBjICYmIGMgPD0gY2hhckNvZGUoJ0YnKSkge1xuICAgICAgICAgIG0gPSBjIC0gY2hhckNvZGUoJ0EnKSArIDEwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dFtvdXRJbmRleCsrXSA9IGNoYXJDb2RlKCclJyk7XG4gICAgICAgICAgb3V0W291dEluZGV4KytdID0gaGV4Y2hhcjtcbiAgICAgICAgICBvdXRbb3V0SW5kZXgrK10gPSBjO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIG91dFtvdXRJbmRleCsrXSA9IDE2ICogbiArIG07XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRPRE8gc3VwcG9ydCByZXR1cm5pbmcgYXJiaXRyYXJ5IGJ1ZmZlcnMuXG5cbiAgcmV0dXJuIG91dC5zbGljZSgwLCBvdXRJbmRleCAtIDEpO1xufTtcblxuXG5RdWVyeVN0cmluZy51bmVzY2FwZSA9IGZ1bmN0aW9uKHMsIGRlY29kZVNwYWNlcykge1xuICByZXR1cm4gUXVlcnlTdHJpbmcudW5lc2NhcGVCdWZmZXIocywgZGVjb2RlU3BhY2VzKS50b1N0cmluZygpO1xufTtcblxuXG5RdWVyeVN0cmluZy5lc2NhcGUgPSBmdW5jdGlvbihzdHIpIHtcbiAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpO1xufTtcblxudmFyIHN0cmluZ2lmeVByaW1pdGl2ZSA9IGZ1bmN0aW9uKHYpIHtcbiAgaWYgKHV0aWwuaXNTdHJpbmcodikpXG4gICAgcmV0dXJuIHY7XG4gIGlmICh1dGlsLmlzQm9vbGVhbih2KSlcbiAgICByZXR1cm4gdiA/ICd0cnVlJyA6ICdmYWxzZSc7XG4gIGlmICh1dGlsLmlzTnVtYmVyKHYpKVxuICAgIHJldHVybiBpc0Zpbml0ZSh2KSA/IHYgOiAnJztcbiAgcmV0dXJuICcnO1xufTtcblxuXG5RdWVyeVN0cmluZy5zdHJpbmdpZnkgPSBRdWVyeVN0cmluZy5lbmNvZGUgPSBmdW5jdGlvbihvYmosIHNlcCwgZXEsIG5hbWUpIHtcbiAgc2VwID0gc2VwIHx8ICcmJztcbiAgZXEgPSBlcSB8fCAnPSc7XG4gIGlmICh1dGlsLmlzTnVsbChvYmopKSB7XG4gICAgb2JqID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKHV0aWwuaXNPYmplY3Qob2JqKSkge1xuICAgIHJldHVybiBzaGltcy5tYXAoc2hpbXMua2V5cyhvYmopLCBmdW5jdGlvbihrKSB7XG4gICAgICB2YXIga3MgPSBRdWVyeVN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKGspKSArIGVxO1xuICAgICAgaWYgKHV0aWwuaXNBcnJheShvYmpba10pKSB7XG4gICAgICAgIHJldHVybiBzaGltcy5tYXAob2JqW2tdLCBmdW5jdGlvbih2KSB7XG4gICAgICAgICAgcmV0dXJuIGtzICsgUXVlcnlTdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZSh2KSk7XG4gICAgICAgIH0pLmpvaW4oc2VwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBrcyArIFF1ZXJ5U3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUob2JqW2tdKSk7XG4gICAgICB9XG4gICAgfSkuam9pbihzZXApO1xuXG4gIH1cblxuICBpZiAoIW5hbWUpIHJldHVybiAnJztcbiAgcmV0dXJuIFF1ZXJ5U3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUobmFtZSkpICsgZXEgK1xuICAgICAgICAgUXVlcnlTdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShvYmopKTtcbn07XG5cbi8vIFBhcnNlIGEga2V5PXZhbCBzdHJpbmcuXG5RdWVyeVN0cmluZy5wYXJzZSA9IFF1ZXJ5U3RyaW5nLmRlY29kZSA9IGZ1bmN0aW9uKHFzLCBzZXAsIGVxLCBvcHRpb25zKSB7XG4gIHNlcCA9IHNlcCB8fCAnJic7XG4gIGVxID0gZXEgfHwgJz0nO1xuICB2YXIgb2JqID0ge307XG5cbiAgaWYgKCF1dGlsLmlzU3RyaW5nKHFzKSB8fCBxcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gb2JqO1xuICB9XG5cbiAgdmFyIHJlZ2V4cCA9IC9cXCsvZztcbiAgcXMgPSBxcy5zcGxpdChzZXApO1xuXG4gIHZhciBtYXhLZXlzID0gMTAwMDtcbiAgaWYgKG9wdGlvbnMgJiYgdXRpbC5pc051bWJlcihvcHRpb25zLm1heEtleXMpKSB7XG4gICAgbWF4S2V5cyA9IG9wdGlvbnMubWF4S2V5cztcbiAgfVxuXG4gIHZhciBsZW4gPSBxcy5sZW5ndGg7XG4gIC8vIG1heEtleXMgPD0gMCBtZWFucyB0aGF0IHdlIHNob3VsZCBub3QgbGltaXQga2V5cyBjb3VudFxuICBpZiAobWF4S2V5cyA+IDAgJiYgbGVuID4gbWF4S2V5cykge1xuICAgIGxlbiA9IG1heEtleXM7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7XG4gICAgdmFyIHggPSBxc1tpXS5yZXBsYWNlKHJlZ2V4cCwgJyUyMCcpLFxuICAgICAgICBpZHggPSB4LmluZGV4T2YoZXEpLFxuICAgICAgICBrc3RyLCB2c3RyLCBrLCB2O1xuXG4gICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICBrc3RyID0geC5zdWJzdHIoMCwgaWR4KTtcbiAgICAgIHZzdHIgPSB4LnN1YnN0cihpZHggKyAxKTtcbiAgICB9IGVsc2Uge1xuICAgICAga3N0ciA9IHg7XG4gICAgICB2c3RyID0gJyc7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGsgPSBkZWNvZGVVUklDb21wb25lbnQoa3N0cik7XG4gICAgICB2ID0gZGVjb2RlVVJJQ29tcG9uZW50KHZzdHIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGsgPSBRdWVyeVN0cmluZy51bmVzY2FwZShrc3RyLCB0cnVlKTtcbiAgICAgIHYgPSBRdWVyeVN0cmluZy51bmVzY2FwZSh2c3RyLCB0cnVlKTtcbiAgICB9XG5cbiAgICBpZiAoIWhhc093blByb3BlcnR5KG9iaiwgaykpIHtcbiAgICAgIG9ialtrXSA9IHY7XG4gICAgfSBlbHNlIGlmICh1dGlsLmlzQXJyYXkob2JqW2tdKSkge1xuICAgICAgb2JqW2tdLnB1c2godik7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ialtrXSA9IFtvYmpba10sIHZdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvYmo7XG59OyIsIi8vIENvcHlyaWdodCBKb3llbnQsIEluYy4gYW5kIG90aGVyIE5vZGUgY29udHJpYnV0b3JzLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhXG4vLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlXG4vLyBcIlNvZnR3YXJlXCIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmdcbi8vIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCxcbi8vIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXRcbi8vIHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZVxuLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWRcbi8vIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1Ncbi8vIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0Zcbi8vIE1FUkNIQU5UQUJJTElUWSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU5cbi8vIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLFxuLy8gREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SXG4vLyBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFXG4vLyBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG5tb2R1bGUuZXhwb3J0cyA9IFN0cmVhbTtcblxudmFyIEVFID0gcmVxdWlyZSgnZXZlbnRzJykuRXZlbnRFbWl0dGVyO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnV0aWwuaW5oZXJpdHMoU3RyZWFtLCBFRSk7XG5TdHJlYW0uUmVhZGFibGUgPSByZXF1aXJlKCdfc3RyZWFtX3JlYWRhYmxlJyk7XG5TdHJlYW0uV3JpdGFibGUgPSByZXF1aXJlKCdfc3RyZWFtX3dyaXRhYmxlJyk7XG5TdHJlYW0uRHVwbGV4ID0gcmVxdWlyZSgnX3N0cmVhbV9kdXBsZXgnKTtcblN0cmVhbS5UcmFuc2Zvcm0gPSByZXF1aXJlKCdfc3RyZWFtX3RyYW5zZm9ybScpO1xuU3RyZWFtLlBhc3NUaHJvdWdoID0gcmVxdWlyZSgnX3N0cmVhbV9wYXNzdGhyb3VnaCcpO1xuXG4vLyBCYWNrd2FyZHMtY29tcGF0IHdpdGggbm9kZSAwLjQueFxuU3RyZWFtLlN0cmVhbSA9IFN0cmVhbTtcblxuXG5cbi8vIG9sZC1zdHlsZSBzdHJlYW1zLiAgTm90ZSB0aGF0IHRoZSBwaXBlIG1ldGhvZCAodGhlIG9ubHkgcmVsZXZhbnRcbi8vIHBhcnQgb2YgdGhpcyBjbGFzcykgaXMgb3ZlcnJpZGRlbiBpbiB0aGUgUmVhZGFibGUgY2xhc3MuXG5cbmZ1bmN0aW9uIFN0cmVhbSgpIHtcbiAgRUUuY2FsbCh0aGlzKTtcbn1cblxuU3RyZWFtLnByb3RvdHlwZS5waXBlID0gZnVuY3Rpb24oZGVzdCwgb3B0aW9ucykge1xuICB2YXIgc291cmNlID0gdGhpcztcblxuICBmdW5jdGlvbiBvbmRhdGEoY2h1bmspIHtcbiAgICBpZiAoZGVzdC53cml0YWJsZSkge1xuICAgICAgaWYgKGZhbHNlID09PSBkZXN0LndyaXRlKGNodW5rKSAmJiBzb3VyY2UucGF1c2UpIHtcbiAgICAgICAgc291cmNlLnBhdXNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc291cmNlLm9uKCdkYXRhJywgb25kYXRhKTtcblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIGlmIChzb3VyY2UucmVhZGFibGUgJiYgc291cmNlLnJlc3VtZSkge1xuICAgICAgc291cmNlLnJlc3VtZSgpO1xuICAgIH1cbiAgfVxuXG4gIGRlc3Qub24oJ2RyYWluJywgb25kcmFpbik7XG5cbiAgLy8gSWYgdGhlICdlbmQnIG9wdGlvbiBpcyBub3Qgc3VwcGxpZWQsIGRlc3QuZW5kKCkgd2lsbCBiZSBjYWxsZWQgd2hlblxuICAvLyBzb3VyY2UgZ2V0cyB0aGUgJ2VuZCcgb3IgJ2Nsb3NlJyBldmVudHMuICBPbmx5IGRlc3QuZW5kKCkgb25jZS5cbiAgaWYgKCFkZXN0Ll9pc1N0ZGlvICYmICghb3B0aW9ucyB8fCBvcHRpb25zLmVuZCAhPT0gZmFsc2UpKSB7XG4gICAgc291cmNlLm9uKCdlbmQnLCBvbmVuZCk7XG4gICAgc291cmNlLm9uKCdjbG9zZScsIG9uY2xvc2UpO1xuICB9XG5cbiAgdmFyIGRpZE9uRW5kID0gZmFsc2U7XG4gIGZ1bmN0aW9uIG9uZW5kKCkge1xuICAgIGlmIChkaWRPbkVuZCkgcmV0dXJuO1xuICAgIGRpZE9uRW5kID0gdHJ1ZTtcblxuICAgIGRlc3QuZW5kKCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKSB7XG4gICAgaWYgKGRpZE9uRW5kKSByZXR1cm47XG4gICAgZGlkT25FbmQgPSB0cnVlO1xuXG4gICAgaWYgKHR5cGVvZiBkZXN0LmRlc3Ryb3kgPT09ICdmdW5jdGlvbicpIGRlc3QuZGVzdHJveSgpO1xuICB9XG5cbiAgLy8gZG9uJ3QgbGVhdmUgZGFuZ2xpbmcgcGlwZXMgd2hlbiB0aGVyZSBhcmUgZXJyb3JzLlxuICBmdW5jdGlvbiBvbmVycm9yKGVyKSB7XG4gICAgY2xlYW51cCgpO1xuICAgIGlmIChFRS5saXN0ZW5lckNvdW50KHRoaXMsICdlcnJvcicpID09PSAwKSB7XG4gICAgICB0aHJvdyBlcjsgLy8gVW5oYW5kbGVkIHN0cmVhbSBlcnJvciBpbiBwaXBlLlxuICAgIH1cbiAgfVxuXG4gIHNvdXJjZS5vbignZXJyb3InLCBvbmVycm9yKTtcbiAgZGVzdC5vbignZXJyb3InLCBvbmVycm9yKTtcblxuICAvLyByZW1vdmUgYWxsIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkLlxuICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZGF0YScsIG9uZGF0YSk7XG4gICAgZGVzdC5yZW1vdmVMaXN0ZW5lcignZHJhaW4nLCBvbmRyYWluKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZW5kJywgb25lbmQpO1xuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcblxuICAgIHNvdXJjZS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBvbmVycm9yKTtcbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuXG4gICAgc291cmNlLnJlbW92ZUxpc3RlbmVyKCdlbmQnLCBjbGVhbnVwKTtcbiAgICBzb3VyY2UucmVtb3ZlTGlzdGVuZXIoJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgICBkZXN0LnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIGNsZWFudXApO1xuICB9XG5cbiAgc291cmNlLm9uKCdlbmQnLCBjbGVhbnVwKTtcbiAgc291cmNlLm9uKCdjbG9zZScsIGNsZWFudXApO1xuXG4gIGRlc3Qub24oJ2Nsb3NlJywgY2xlYW51cCk7XG5cbiAgZGVzdC5lbWl0KCdwaXBlJywgc291cmNlKTtcblxuICAvLyBBbGxvdyBmb3IgdW5peC1saWtlIHVzYWdlOiBBLnBpcGUoQikucGlwZShDKVxuICByZXR1cm4gZGVzdDtcbn07XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlcjtcblxuZnVuY3Rpb24gYXNzZXJ0RW5jb2RpbmcoZW5jb2RpbmcpIHtcbiAgaWYgKGVuY29kaW5nICYmICFCdWZmZXIuaXNFbmNvZGluZyhlbmNvZGluZykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2Rpbmc6ICcgKyBlbmNvZGluZyk7XG4gIH1cbn1cblxudmFyIFN0cmluZ0RlY29kZXIgPSBleHBvcnRzLlN0cmluZ0RlY29kZXIgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICB0aGlzLmVuY29kaW5nID0gKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bLV9dLywgJycpO1xuICBhc3NlcnRFbmNvZGluZyhlbmNvZGluZyk7XG4gIHN3aXRjaCAodGhpcy5lbmNvZGluZykge1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgLy8gQ0VTVS04IHJlcHJlc2VudHMgZWFjaCBvZiBTdXJyb2dhdGUgUGFpciBieSAzLWJ5dGVzXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAvLyBVVEYtMTYgcmVwcmVzZW50cyBlYWNoIG9mIFN1cnJvZ2F0ZSBQYWlyIGJ5IDItYnl0ZXNcbiAgICAgIHRoaXMuc3Vycm9nYXRlU2l6ZSA9IDI7XG4gICAgICB0aGlzLmRldGVjdEluY29tcGxldGVDaGFyID0gdXRmMTZEZXRlY3RJbmNvbXBsZXRlQ2hhcjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAvLyBCYXNlLTY0IHN0b3JlcyAzIGJ5dGVzIGluIDQgY2hhcnMsIGFuZCBwYWRzIHRoZSByZW1haW5kZXIuXG4gICAgICB0aGlzLnN1cnJvZ2F0ZVNpemUgPSAzO1xuICAgICAgdGhpcy5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRoaXMud3JpdGUgPSBwYXNzVGhyb3VnaFdyaXRlO1xuICAgICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5jaGFyQnVmZmVyID0gbmV3IEJ1ZmZlcig2KTtcbiAgdGhpcy5jaGFyUmVjZWl2ZWQgPSAwO1xuICB0aGlzLmNoYXJMZW5ndGggPSAwO1xufTtcblxuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICB2YXIgY2hhclN0ciA9ICcnO1xuICB2YXIgb2Zmc2V0ID0gMDtcblxuICAvLyBpZiBvdXIgbGFzdCB3cml0ZSBlbmRlZCB3aXRoIGFuIGluY29tcGxldGUgbXVsdGlieXRlIGNoYXJhY3RlclxuICB3aGlsZSAodGhpcy5jaGFyTGVuZ3RoKSB7XG4gICAgLy8gZGV0ZXJtaW5lIGhvdyBtYW55IHJlbWFpbmluZyBieXRlcyB0aGlzIGJ1ZmZlciBoYXMgdG8gb2ZmZXIgZm9yIHRoaXMgY2hhclxuICAgIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gdGhpcy5jaGFyTGVuZ3RoIC0gdGhpcy5jaGFyUmVjZWl2ZWQpID9cbiAgICAgICAgICAgICAgICB0aGlzLmNoYXJMZW5ndGggLSB0aGlzLmNoYXJSZWNlaXZlZCA6XG4gICAgICAgICAgICAgICAgYnVmZmVyLmxlbmd0aDtcblxuICAgIC8vIGFkZCB0aGUgbmV3IGJ5dGVzIHRvIHRoZSBjaGFyIGJ1ZmZlclxuICAgIGJ1ZmZlci5jb3B5KHRoaXMuY2hhckJ1ZmZlciwgdGhpcy5jaGFyUmVjZWl2ZWQsIG9mZnNldCwgaSk7XG4gICAgdGhpcy5jaGFyUmVjZWl2ZWQgKz0gKGkgLSBvZmZzZXQpO1xuICAgIG9mZnNldCA9IGk7XG5cbiAgICBpZiAodGhpcy5jaGFyUmVjZWl2ZWQgPCB0aGlzLmNoYXJMZW5ndGgpIHtcbiAgICAgIC8vIHN0aWxsIG5vdCBlbm91Z2ggY2hhcnMgaW4gdGhpcyBidWZmZXI/IHdhaXQgZm9yIG1vcmUgLi4uXG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgLy8gZ2V0IHRoZSBjaGFyYWN0ZXIgdGhhdCB3YXMgc3BsaXRcbiAgICBjaGFyU3RyID0gdGhpcy5jaGFyQnVmZmVyLnNsaWNlKDAsIHRoaXMuY2hhckxlbmd0aCkudG9TdHJpbmcodGhpcy5lbmNvZGluZyk7XG5cbiAgICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICAgIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChjaGFyU3RyLmxlbmd0aCAtIDEpO1xuICAgIGlmIChjaGFyQ29kZSA+PSAweEQ4MDAgJiYgY2hhckNvZGUgPD0gMHhEQkZGKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggKz0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgICAgY2hhclN0ciA9ICcnO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHRoaXMuY2hhclJlY2VpdmVkID0gdGhpcy5jaGFyTGVuZ3RoID0gMDtcblxuICAgIC8vIGlmIHRoZXJlIGFyZSBubyBtb3JlIGJ5dGVzIGluIHRoaXMgYnVmZmVyLCBqdXN0IGVtaXQgb3VyIGNoYXJcbiAgICBpZiAoaSA9PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gY2hhclN0cjtcblxuICAgIC8vIG90aGVyd2lzZSBjdXQgb2ZmIHRoZSBjaGFyYWN0ZXJzIGVuZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBidWZmZXJcbiAgICBidWZmZXIgPSBidWZmZXIuc2xpY2UoaSwgYnVmZmVyLmxlbmd0aCk7XG4gICAgYnJlYWs7XG4gIH1cblxuICB2YXIgbGVuSW5jb21wbGV0ZSA9IHRoaXMuZGV0ZWN0SW5jb21wbGV0ZUNoYXIoYnVmZmVyKTtcblxuICB2YXIgZW5kID0gYnVmZmVyLmxlbmd0aDtcbiAgaWYgKHRoaXMuY2hhckxlbmd0aCkge1xuICAgIC8vIGJ1ZmZlciB0aGUgaW5jb21wbGV0ZSBjaGFyYWN0ZXIgYnl0ZXMgd2UgZ290XG4gICAgYnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCAwLCBidWZmZXIubGVuZ3RoIC0gbGVuSW5jb21wbGV0ZSwgZW5kKTtcbiAgICB0aGlzLmNoYXJSZWNlaXZlZCA9IGxlbkluY29tcGxldGU7XG4gICAgZW5kIC09IGxlbkluY29tcGxldGU7XG4gIH1cblxuICBjaGFyU3RyICs9IGJ1ZmZlci50b1N0cmluZyh0aGlzLmVuY29kaW5nLCAwLCBlbmQpO1xuXG4gIHZhciBlbmQgPSBjaGFyU3RyLmxlbmd0aCAtIDE7XG4gIHZhciBjaGFyQ29kZSA9IGNoYXJTdHIuY2hhckNvZGVBdChlbmQpO1xuICAvLyBsZWFkIHN1cnJvZ2F0ZSAoRDgwMC1EQkZGKSBpcyBhbHNvIHRoZSBpbmNvbXBsZXRlIGNoYXJhY3RlclxuICBpZiAoY2hhckNvZGUgPj0gMHhEODAwICYmIGNoYXJDb2RlIDw9IDB4REJGRikge1xuICAgIHZhciBzaXplID0gdGhpcy5zdXJyb2dhdGVTaXplO1xuICAgIHRoaXMuY2hhckxlbmd0aCArPSBzaXplO1xuICAgIHRoaXMuY2hhclJlY2VpdmVkICs9IHNpemU7XG4gICAgdGhpcy5jaGFyQnVmZmVyLmNvcHkodGhpcy5jaGFyQnVmZmVyLCBzaXplLCAwLCBzaXplKTtcbiAgICB0aGlzLmNoYXJCdWZmZXIud3JpdGUoY2hhclN0ci5jaGFyQXQoY2hhclN0ci5sZW5ndGggLSAxKSwgdGhpcy5lbmNvZGluZyk7XG4gICAgcmV0dXJuIGNoYXJTdHIuc3Vic3RyaW5nKDAsIGVuZCk7XG4gIH1cblxuICAvLyBvciBqdXN0IGVtaXQgdGhlIGNoYXJTdHJcbiAgcmV0dXJuIGNoYXJTdHI7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5kZXRlY3RJbmNvbXBsZXRlQ2hhciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAvLyBkZXRlcm1pbmUgaG93IG1hbnkgYnl0ZXMgd2UgaGF2ZSB0byBjaGVjayBhdCB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyXG4gIHZhciBpID0gKGJ1ZmZlci5sZW5ndGggPj0gMykgPyAzIDogYnVmZmVyLmxlbmd0aDtcblxuICAvLyBGaWd1cmUgb3V0IGlmIG9uZSBvZiB0aGUgbGFzdCBpIGJ5dGVzIG9mIG91ciBidWZmZXIgYW5ub3VuY2VzIGFuXG4gIC8vIGluY29tcGxldGUgY2hhci5cbiAgZm9yICg7IGkgPiAwOyBpLS0pIHtcbiAgICB2YXIgYyA9IGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gaV07XG5cbiAgICAvLyBTZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VVEYtOCNEZXNjcmlwdGlvblxuXG4gICAgLy8gMTEwWFhYWFhcbiAgICBpZiAoaSA9PSAxICYmIGMgPj4gNSA9PSAweDA2KSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMFhYWFhcbiAgICBpZiAoaSA8PSAyICYmIGMgPj4gNCA9PSAweDBFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSAzO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gMTExMTBYWFhcbiAgICBpZiAoaSA8PSAzICYmIGMgPj4gMyA9PSAweDFFKSB7XG4gICAgICB0aGlzLmNoYXJMZW5ndGggPSA0O1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGk7XG59O1xuXG5TdHJpbmdEZWNvZGVyLnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgdmFyIHJlcyA9ICcnO1xuICBpZiAoYnVmZmVyICYmIGJ1ZmZlci5sZW5ndGgpXG4gICAgcmVzID0gdGhpcy53cml0ZShidWZmZXIpO1xuXG4gIGlmICh0aGlzLmNoYXJSZWNlaXZlZCkge1xuICAgIHZhciBjciA9IHRoaXMuY2hhclJlY2VpdmVkO1xuICAgIHZhciBidWYgPSB0aGlzLmNoYXJCdWZmZXI7XG4gICAgdmFyIGVuYyA9IHRoaXMuZW5jb2Rpbmc7XG4gICAgcmVzICs9IGJ1Zi5zbGljZSgwLCBjcikudG9TdHJpbmcoZW5jKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiBwYXNzVGhyb3VnaFdyaXRlKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyLnRvU3RyaW5nKHRoaXMuZW5jb2RpbmcpO1xufVxuXG5mdW5jdGlvbiB1dGYxNkRldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDI7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAyIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG5cbmZ1bmN0aW9uIGJhc2U2NERldGVjdEluY29tcGxldGVDaGFyKGJ1ZmZlcikge1xuICB2YXIgaW5jb21wbGV0ZSA9IHRoaXMuY2hhclJlY2VpdmVkID0gYnVmZmVyLmxlbmd0aCAlIDM7XG4gIHRoaXMuY2hhckxlbmd0aCA9IGluY29tcGxldGUgPyAzIDogMDtcbiAgcmV0dXJuIGluY29tcGxldGU7XG59XG4iLCJ0cnkge1xuICAgIC8vIE9sZCBJRSBicm93c2VycyB0aGF0IGRvIG5vdCBjdXJyeSBhcmd1bWVudHNcbiAgICBpZiAoIXNldFRpbWVvdXQuY2FsbCkge1xuICAgICAgICB2YXIgc2xpY2VyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuICAgICAgICBleHBvcnRzLnNldFRpbWVvdXQgPSBmdW5jdGlvbihmbikge1xuICAgICAgICAgICAgdmFyIGFyZ3MgPSBzbGljZXIuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgICAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfTtcblxuICAgICAgICBleHBvcnRzLnNldEludGVydmFsID0gZnVuY3Rpb24oZm4pIHtcbiAgICAgICAgICAgIHZhciBhcmdzID0gc2xpY2VyLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICAgICAgICAgIHJldHVybiBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBleHBvcnRzLnNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgICBleHBvcnRzLnNldEludGVydmFsID0gc2V0SW50ZXJ2YWw7XG4gICAgfVxuICAgIGV4cG9ydHMuY2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgIGV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGNsZWFySW50ZXJ2YWw7XG5cbiAgICBpZiAod2luZG93LnNldEltbWVkaWF0ZSkge1xuICAgICAgZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICAgICAgZXhwb3J0cy5jbGVhckltbWVkaWF0ZSA9IHdpbmRvdy5jbGVhckltbWVkaWF0ZTtcbiAgICB9XG5cbiAgICAvLyBDaHJvbWUgYW5kIFBoYW50b21KUyBzZWVtcyB0byBkZXBlbmQgb24gYHRoaXNgIHBzZXVkbyB2YXJpYWJsZSBiZWluZyBhXG4gICAgLy8gYHdpbmRvd2AgYW5kIHRocm93cyBpbnZhbGlkIGludm9jYXRpb24gZXhjZXB0aW9uIG90aGVyd2lzZS4gSWYgdGhpcyBjb2RlXG4gICAgLy8gcnVucyBpbiBzdWNoIEpTIHJ1bnRpbWUgbmV4dCBsaW5lIHdpbGwgdGhyb3cgYW5kIGBjYXRjaGAgY2xhdXNlIHdpbGxcbiAgICAvLyBleHBvcnRlZCB0aW1lcnMgZnVuY3Rpb25zIGJvdW5kIHRvIGEgd2luZG93LlxuICAgIGV4cG9ydHMuc2V0VGltZW91dChmdW5jdGlvbigpIHt9KTtcbn0gY2F0Y2ggKF8pIHtcbiAgICBmdW5jdGlvbiBiaW5kKGYsIGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHsgcmV0dXJuIGYuYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKSB9O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgZXhwb3J0cy5zZXRUaW1lb3V0ID0gYmluZChzZXRUaW1lb3V0LCB3aW5kb3cpO1xuICAgICAgZXhwb3J0cy5zZXRJbnRlcnZhbCA9IGJpbmQoc2V0SW50ZXJ2YWwsIHdpbmRvdyk7XG4gICAgICBleHBvcnRzLmNsZWFyVGltZW91dCA9IGJpbmQoY2xlYXJUaW1lb3V0LCB3aW5kb3cpO1xuICAgICAgZXhwb3J0cy5jbGVhckludGVydmFsID0gYmluZChjbGVhckludGVydmFsLCB3aW5kb3cpO1xuICAgICAgaWYgKHdpbmRvdy5zZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgZXhwb3J0cy5zZXRJbW1lZGlhdGUgPSBiaW5kKHdpbmRvdy5zZXRJbW1lZGlhdGUsIHdpbmRvdyk7XG4gICAgICAgIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSBiaW5kKHdpbmRvdy5jbGVhckltbWVkaWF0ZSwgd2luZG93KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHR5cGVvZiBzZXRUaW1lb3V0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBleHBvcnRzLnNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBzZXRJbnRlcnZhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZXhwb3J0cy5zZXRJbnRlcnZhbCA9IHNldEludGVydmFsO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjbGVhclRpbWVvdXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGV4cG9ydHMuY2xlYXJUaW1lb3V0ID0gY2xlYXJUaW1lb3V0O1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBjbGVhckludGVydmFsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGV4cG9ydHMuY2xlYXJJbnRlcnZhbCA9IGNsZWFySW50ZXJ2YWw7XG4gICAgICB9XG4gICAgfVxufVxuXG5leHBvcnRzLnVucmVmID0gZnVuY3Rpb24gdW5yZWYoKSB7fTtcbmV4cG9ydHMucmVmID0gZnVuY3Rpb24gcmVmKCkge307XG5cbmlmICghZXhwb3J0cy5zZXRJbW1lZGlhdGUpIHtcbiAgdmFyIGN1cnJlbnRLZXkgPSAwLCBxdWV1ZSA9IHt9LCBhY3RpdmUgPSBmYWxzZTtcblxuICBleHBvcnRzLnNldEltbWVkaWF0ZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgICBmdW5jdGlvbiBkcmFpbigpIHtcbiAgICAgICAgYWN0aXZlID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiBxdWV1ZSkge1xuICAgICAgICAgIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShjdXJyZW50S2V5LCBrZXkpKSB7XG4gICAgICAgICAgICB2YXIgZm4gPSBxdWV1ZVtrZXldO1xuICAgICAgICAgICAgZGVsZXRlIHF1ZXVlW2tleV07XG4gICAgICAgICAgICBmbigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UgJiYgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbiAoZXYpIHtcbiAgICAgICAgICBpZiAoZXYuc291cmNlID09PSB3aW5kb3cgJiYgZXYuZGF0YSA9PT0gJ2Jyb3dzZXJpZnktdGljaycpIHtcbiAgICAgICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZHJhaW4oKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICAgICAgICB2YXIgaWQgPSArK2N1cnJlbnRLZXk7XG4gICAgICAgICAgcXVldWVbaWRdID0gZm47XG4gICAgICAgICAgaWYgKCFhY3RpdmUpIHtcbiAgICAgICAgICAgIGFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ2Jyb3dzZXJpZnktdGljaycsICcqJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpZDtcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICAgICAgICB2YXIgaWQgPSArK2N1cnJlbnRLZXk7XG4gICAgICAgICAgcXVldWVbaWRdID0gZm47XG4gICAgICAgICAgaWYgKCFhY3RpdmUpIHtcbiAgICAgICAgICAgIGFjdGl2ZSA9IHRydWU7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGRyYWluLCAwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgICB9O1xuICAgICAgfVxuICB9KSgpO1xuXG4gIGV4cG9ydHMuY2xlYXJJbW1lZGlhdGUgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZShpZCkge1xuICAgIGRlbGV0ZSBxdWV1ZVtpZF07XG4gIH07XG59XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHB1bnljb2RlID0geyBlbmNvZGUgOiBmdW5jdGlvbiAocykgeyByZXR1cm4gcyB9IH07XG52YXIgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKTtcbnZhciBzaGltcyA9IHJlcXVpcmUoJ19zaGltcycpO1xuXG5leHBvcnRzLnBhcnNlID0gdXJsUGFyc2U7XG5leHBvcnRzLnJlc29sdmUgPSB1cmxSZXNvbHZlO1xuZXhwb3J0cy5yZXNvbHZlT2JqZWN0ID0gdXJsUmVzb2x2ZU9iamVjdDtcbmV4cG9ydHMuZm9ybWF0ID0gdXJsRm9ybWF0O1xuXG5leHBvcnRzLlVybCA9IFVybDtcblxuZnVuY3Rpb24gVXJsKCkge1xuICB0aGlzLnByb3RvY29sID0gbnVsbDtcbiAgdGhpcy5zbGFzaGVzID0gbnVsbDtcbiAgdGhpcy5hdXRoID0gbnVsbDtcbiAgdGhpcy5ob3N0ID0gbnVsbDtcbiAgdGhpcy5wb3J0ID0gbnVsbDtcbiAgdGhpcy5ob3N0bmFtZSA9IG51bGw7XG4gIHRoaXMuaGFzaCA9IG51bGw7XG4gIHRoaXMuc2VhcmNoID0gbnVsbDtcbiAgdGhpcy5xdWVyeSA9IG51bGw7XG4gIHRoaXMucGF0aG5hbWUgPSBudWxsO1xuICB0aGlzLnBhdGggPSBudWxsO1xuICB0aGlzLmhyZWYgPSBudWxsO1xufVxuXG4vLyBSZWZlcmVuY2U6IFJGQyAzOTg2LCBSRkMgMTgwOCwgUkZDIDIzOTZcblxuLy8gZGVmaW5lIHRoZXNlIGhlcmUgc28gYXQgbGVhc3QgdGhleSBvbmx5IGhhdmUgdG8gYmVcbi8vIGNvbXBpbGVkIG9uY2Ugb24gdGhlIGZpcnN0IG1vZHVsZSBsb2FkLlxudmFyIHByb3RvY29sUGF0dGVybiA9IC9eKFthLXowLTkuKy1dKzopL2ksXG4gICAgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvLFxuXG4gICAgLy8gUkZDIDIzOTY6IGNoYXJhY3RlcnMgcmVzZXJ2ZWQgZm9yIGRlbGltaXRpbmcgVVJMcy5cbiAgICAvLyBXZSBhY3R1YWxseSBqdXN0IGF1dG8tZXNjYXBlIHRoZXNlLlxuICAgIGRlbGltcyA9IFsnPCcsICc+JywgJ1wiJywgJ2AnLCAnICcsICdcXHInLCAnXFxuJywgJ1xcdCddLFxuXG4gICAgLy8gUkZDIDIzOTY6IGNoYXJhY3RlcnMgbm90IGFsbG93ZWQgZm9yIHZhcmlvdXMgcmVhc29ucy5cbiAgICB1bndpc2UgPSBbJ3snLCAnfScsICd8JywgJ1xcXFwnLCAnXicsICdgJ10uY29uY2F0KGRlbGltcyksXG5cbiAgICAvLyBBbGxvd2VkIGJ5IFJGQ3MsIGJ1dCBjYXVzZSBvZiBYU1MgYXR0YWNrcy4gIEFsd2F5cyBlc2NhcGUgdGhlc2UuXG4gICAgYXV0b0VzY2FwZSA9IFsnXFwnJ10uY29uY2F0KHVud2lzZSksXG4gICAgLy8gQ2hhcmFjdGVycyB0aGF0IGFyZSBuZXZlciBldmVyIGFsbG93ZWQgaW4gYSBob3N0bmFtZS5cbiAgICAvLyBOb3RlIHRoYXQgYW55IGludmFsaWQgY2hhcnMgYXJlIGFsc28gaGFuZGxlZCwgYnV0IHRoZXNlXG4gICAgLy8gYXJlIHRoZSBvbmVzIHRoYXQgYXJlICpleHBlY3RlZCogdG8gYmUgc2Vlbiwgc28gd2UgZmFzdC1wYXRoXG4gICAgLy8gdGhlbS5cbiAgICBub25Ib3N0Q2hhcnMgPSBbJyUnLCAnLycsICc/JywgJzsnLCAnIyddLmNvbmNhdChhdXRvRXNjYXBlKSxcbiAgICBob3N0RW5kaW5nQ2hhcnMgPSBbJy8nLCAnPycsICcjJ10sXG4gICAgaG9zdG5hbWVNYXhMZW4gPSAyNTUsXG4gICAgaG9zdG5hbWVQYXJ0UGF0dGVybiA9IC9eW2EtejAtOUEtWl8tXXswLDYzfSQvLFxuICAgIGhvc3RuYW1lUGFydFN0YXJ0ID0gL14oW2EtejAtOUEtWl8tXXswLDYzfSkoLiopJC8sXG4gICAgLy8gcHJvdG9jb2xzIHRoYXQgY2FuIGFsbG93IFwidW5zYWZlXCIgYW5kIFwidW53aXNlXCIgY2hhcnMuXG4gICAgdW5zYWZlUHJvdG9jb2wgPSB7XG4gICAgICAnamF2YXNjcmlwdCc6IHRydWUsXG4gICAgICAnamF2YXNjcmlwdDonOiB0cnVlXG4gICAgfSxcbiAgICAvLyBwcm90b2NvbHMgdGhhdCBuZXZlciBoYXZlIGEgaG9zdG5hbWUuXG4gICAgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgICAgICdqYXZhc2NyaXB0JzogdHJ1ZSxcbiAgICAgICdqYXZhc2NyaXB0Oic6IHRydWVcbiAgICB9LFxuICAgIC8vIHByb3RvY29scyB0aGF0IGFsd2F5cyBjb250YWluIGEgLy8gYml0LlxuICAgIHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgICAgICdodHRwJzogdHJ1ZSxcbiAgICAgICdodHRwcyc6IHRydWUsXG4gICAgICAnZnRwJzogdHJ1ZSxcbiAgICAgICdnb3BoZXInOiB0cnVlLFxuICAgICAgJ2ZpbGUnOiB0cnVlLFxuICAgICAgJ2h0dHA6JzogdHJ1ZSxcbiAgICAgICdodHRwczonOiB0cnVlLFxuICAgICAgJ2Z0cDonOiB0cnVlLFxuICAgICAgJ2dvcGhlcjonOiB0cnVlLFxuICAgICAgJ2ZpbGU6JzogdHJ1ZVxuICAgIH0sXG4gICAgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG5mdW5jdGlvbiB1cmxQYXJzZSh1cmwsIHBhcnNlUXVlcnlTdHJpbmcsIHNsYXNoZXNEZW5vdGVIb3N0KSB7XG4gIGlmICh1cmwgJiYgdXRpbC5pc09iamVjdCh1cmwpICYmIHVybCBpbnN0YW5jZW9mIFVybCkgcmV0dXJuIHVybDtcblxuICB2YXIgdSA9IG5ldyBVcmw7XG4gIHUucGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCk7XG4gIHJldHVybiB1O1xufVxuXG5VcmwucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24odXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAoIXV0aWwuaXNTdHJpbmcodXJsKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQYXJhbWV0ZXIgJ3VybCcgbXVzdCBiZSBhIHN0cmluZywgbm90IFwiICsgdHlwZW9mIHVybCk7XG4gIH1cblxuICB2YXIgcmVzdCA9IHVybDtcblxuICAvLyB0cmltIGJlZm9yZSBwcm9jZWVkaW5nLlxuICAvLyBUaGlzIGlzIHRvIHN1cHBvcnQgcGFyc2Ugc3R1ZmYgbGlrZSBcIiAgaHR0cDovL2Zvby5jb20gIFxcblwiXG4gIHJlc3QgPSBzaGltcy50cmltKHJlc3QpO1xuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zdWJzdHIocHJvdG8ubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGZpZ3VyZSBvdXQgaWYgaXQncyBnb3QgYSBob3N0XG4gIC8vIHVzZXJAc2VydmVyIGlzICphbHdheXMqIGludGVycHJldGVkIGFzIGEgaG9zdG5hbWUsIGFuZCB1cmxcbiAgLy8gcmVzb2x1dGlvbiB3aWxsIHRyZWF0IC8vZm9vL2JhciBhcyBob3N0PWZvbyxwYXRoPWJhciBiZWNhdXNlIHRoYXQnc1xuICAvLyBob3cgdGhlIGJyb3dzZXIgcmVzb2x2ZXMgcmVsYXRpdmUgVVJMcy5cbiAgaWYgKHNsYXNoZXNEZW5vdGVIb3N0IHx8IHByb3RvIHx8IHJlc3QubWF0Y2goL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8pKSB7XG4gICAgdmFyIHNsYXNoZXMgPSByZXN0LnN1YnN0cigwLCAyKSA9PT0gJy8vJztcbiAgICBpZiAoc2xhc2hlcyAmJiAhKHByb3RvICYmIGhvc3RsZXNzUHJvdG9jb2xbcHJvdG9dKSkge1xuICAgICAgcmVzdCA9IHJlc3Quc3Vic3RyKDIpO1xuICAgICAgdGhpcy5zbGFzaGVzID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAoIWhvc3RsZXNzUHJvdG9jb2xbcHJvdG9dICYmXG4gICAgICAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuXG4gICAgLy8gdGhlcmUncyBhIGhvc3RuYW1lLlxuICAgIC8vIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiAvLCA/LCA7LCBvciAjIGVuZHMgdGhlIGhvc3QuXG4gICAgLy9cbiAgICAvLyBJZiB0aGVyZSBpcyBhbiBAIGluIHRoZSBob3N0bmFtZSwgdGhlbiBub24taG9zdCBjaGFycyAqYXJlKiBhbGxvd2VkXG4gICAgLy8gdG8gdGhlIGxlZnQgb2YgdGhlIGxhc3QgQCBzaWduLCB1bmxlc3Mgc29tZSBob3N0LWVuZGluZyBjaGFyYWN0ZXJcbiAgICAvLyBjb21lcyAqYmVmb3JlKiB0aGUgQC1zaWduLlxuICAgIC8vIFVSTHMgYXJlIG9ibm94aW91cy5cbiAgICAvL1xuICAgIC8vIGV4OlxuICAgIC8vIGh0dHA6Ly9hQGJAYy8gPT4gdXNlcjphQGIgaG9zdDpjXG4gICAgLy8gaHR0cDovL2FAYj9AYyA9PiB1c2VyOmEgaG9zdDpjIHBhdGg6Lz9AY1xuXG4gICAgLy8gdjAuMTIgVE9ETyhpc2FhY3MpOiBUaGlzIGlzIG5vdCBxdWl0ZSBob3cgQ2hyb21lIGRvZXMgdGhpbmdzLlxuICAgIC8vIFJldmlldyBvdXIgdGVzdCBjYXNlIGFnYWluc3QgYnJvd3NlcnMgbW9yZSBjb21wcmVoZW5zaXZlbHkuXG5cbiAgICAvLyBmaW5kIHRoZSBmaXJzdCBpbnN0YW5jZSBvZiBhbnkgaG9zdEVuZGluZ0NoYXJzXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhvc3RFbmRpbmdDaGFycy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGhlYyA9IHJlc3QuaW5kZXhPZihob3N0RW5kaW5nQ2hhcnNbaV0pO1xuICAgICAgaWYgKGhlYyAhPT0gLTEgJiYgKGhvc3RFbmQgPT09IC0xIHx8IGhlYyA8IGhvc3RFbmQpKVxuICAgICAgICBob3N0RW5kID0gaGVjO1xuICAgIH1cblxuICAgIC8vIGF0IHRoaXMgcG9pbnQsIGVpdGhlciB3ZSBoYXZlIGFuIGV4cGxpY2l0IHBvaW50IHdoZXJlIHRoZVxuICAgIC8vIGF1dGggcG9ydGlvbiBjYW5ub3QgZ28gcGFzdCwgb3IgdGhlIGxhc3QgQCBjaGFyIGlzIHRoZSBkZWNpZGVyLlxuICAgIHZhciBhdXRoLCBhdFNpZ247XG4gICAgaWYgKGhvc3RFbmQgPT09IC0xKSB7XG4gICAgICAvLyBhdFNpZ24gY2FuIGJlIGFueXdoZXJlLlxuICAgICAgYXRTaWduID0gcmVzdC5sYXN0SW5kZXhPZignQCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBhdFNpZ24gbXVzdCBiZSBpbiBhdXRoIHBvcnRpb24uXG4gICAgICAvLyBodHRwOi8vYUBiL2NAZCA9PiBob3N0OmIgYXV0aDphIHBhdGg6L2NAZFxuICAgICAgYXRTaWduID0gcmVzdC5sYXN0SW5kZXhPZignQCcsIGhvc3RFbmQpO1xuICAgIH1cblxuICAgIC8vIE5vdyB3ZSBoYXZlIGEgcG9ydGlvbiB3aGljaCBpcyBkZWZpbml0ZWx5IHRoZSBhdXRoLlxuICAgIC8vIFB1bGwgdGhhdCBvZmYuXG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIGF1dGggPSByZXN0LnNsaWNlKDAsIGF0U2lnbik7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZShhdFNpZ24gKyAxKTtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChhdXRoKTtcbiAgICB9XG5cbiAgICAvLyB0aGUgaG9zdCBpcyB0aGUgcmVtYWluaW5nIHRvIHRoZSBsZWZ0IG9mIHRoZSBmaXJzdCBub24taG9zdCBjaGFyXG4gICAgaG9zdEVuZCA9IC0xO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9uSG9zdENoYXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaGVjID0gcmVzdC5pbmRleE9mKG5vbkhvc3RDaGFyc1tpXSk7XG4gICAgICBpZiAoaGVjICE9PSAtMSAmJiAoaG9zdEVuZCA9PT0gLTEgfHwgaGVjIDwgaG9zdEVuZCkpXG4gICAgICAgIGhvc3RFbmQgPSBoZWM7XG4gICAgfVxuICAgIC8vIGlmIHdlIHN0aWxsIGhhdmUgbm90IGhpdCBpdCwgdGhlbiB0aGUgZW50aXJlIHRoaW5nIGlzIGEgaG9zdC5cbiAgICBpZiAoaG9zdEVuZCA9PT0gLTEpXG4gICAgICBob3N0RW5kID0gcmVzdC5sZW5ndGg7XG5cbiAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKDAsIGhvc3RFbmQpO1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKGhvc3RFbmQpO1xuXG4gICAgLy8gcHVsbCBvdXQgcG9ydC5cbiAgICB0aGlzLnBhcnNlSG9zdCgpO1xuXG4gICAgLy8gd2UndmUgaW5kaWNhdGVkIHRoYXQgdGhlcmUgaXMgYSBob3N0bmFtZSxcbiAgICAvLyBzbyBldmVuIGlmIGl0J3MgZW1wdHksIGl0IGhhcyB0byBiZSBwcmVzZW50LlxuICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lIHx8ICcnO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZVswXSA9PT0gJ1snICYmXG4gICAgICAgIHRoaXMuaG9zdG5hbWVbdGhpcy5ob3N0bmFtZS5sZW5ndGggLSAxXSA9PT0gJ10nO1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHZhciBob3N0cGFydHMgPSB0aGlzLmhvc3RuYW1lLnNwbGl0KC9cXC4vKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gaG9zdHBhcnRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICB2YXIgcGFydCA9IGhvc3RwYXJ0c1tpXTtcbiAgICAgICAgaWYgKCFwYXJ0KSBjb250aW51ZTtcbiAgICAgICAgaWYgKCFwYXJ0Lm1hdGNoKGhvc3RuYW1lUGFydFBhdHRlcm4pKSB7XG4gICAgICAgICAgdmFyIG5ld3BhcnQgPSAnJztcbiAgICAgICAgICBmb3IgKHZhciBqID0gMCwgayA9IHBhcnQubGVuZ3RoOyBqIDwgazsgaisrKSB7XG4gICAgICAgICAgICBpZiAocGFydC5jaGFyQ29kZUF0KGopID4gMTI3KSB7XG4gICAgICAgICAgICAgIC8vIHdlIHJlcGxhY2Ugbm9uLUFTQ0lJIGNoYXIgd2l0aCBhIHRlbXBvcmFyeSBwbGFjZWhvbGRlclxuICAgICAgICAgICAgICAvLyB3ZSBuZWVkIHRoaXMgdG8gbWFrZSBzdXJlIHNpemUgb2YgaG9zdG5hbWUgaXMgbm90XG4gICAgICAgICAgICAgIC8vIGJyb2tlbiBieSByZXBsYWNpbmcgbm9uLUFTQ0lJIGJ5IG5vdGhpbmdcbiAgICAgICAgICAgICAgbmV3cGFydCArPSAneCc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBuZXdwYXJ0ICs9IHBhcnRbal07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHdlIHRlc3QgYWdhaW4gd2l0aCBBU0NJSSBjaGFyIG9ubHlcbiAgICAgICAgICBpZiAoIW5ld3BhcnQubWF0Y2goaG9zdG5hbWVQYXJ0UGF0dGVybikpIHtcbiAgICAgICAgICAgIHZhciB2YWxpZFBhcnRzID0gaG9zdHBhcnRzLnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgdmFyIG5vdEhvc3QgPSBob3N0cGFydHMuc2xpY2UoaSArIDEpO1xuICAgICAgICAgICAgdmFyIGJpdCA9IHBhcnQubWF0Y2goaG9zdG5hbWVQYXJ0U3RhcnQpO1xuICAgICAgICAgICAgaWYgKGJpdCkge1xuICAgICAgICAgICAgICB2YWxpZFBhcnRzLnB1c2goYml0WzFdKTtcbiAgICAgICAgICAgICAgbm90SG9zdC51bnNoaWZ0KGJpdFsyXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobm90SG9zdC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmVzdCA9ICcvJyArIG5vdEhvc3Quam9pbignLicpICsgcmVzdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaG9zdG5hbWUgPSB2YWxpZFBhcnRzLmpvaW4oJy4nKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmhvc3RuYW1lLmxlbmd0aCA+IGhvc3RuYW1lTWF4TGVuKSB7XG4gICAgICB0aGlzLmhvc3RuYW1lID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gdGhpcy5ob3N0bmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55IGNvZGVkIHJlcHJlc2VudGF0aW9uIG9mIFwiZG9tYWluXCIuXG4gICAgICAvLyBJdCBvbmx5IGNvbnZlcnRzIHRoZSBwYXJ0IG9mIHRoZSBkb21haW4gbmFtZSB0aGF0XG4gICAgICAvLyBoYXMgbm9uIEFTQ0lJIGNoYXJhY3RlcnMuIEkuZS4gaXQgZG9zZW50IG1hdHRlciBpZlxuICAgICAgLy8geW91IGNhbGwgaXQgd2l0aCBhIGRvbWFpbiB0aGF0IGFscmVhZHkgaXMgaW4gQVNDSUkuXG4gICAgICB2YXIgZG9tYWluQXJyYXkgPSB0aGlzLmhvc3RuYW1lLnNwbGl0KCcuJyk7XG4gICAgICB2YXIgbmV3T3V0ID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvbWFpbkFycmF5Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBzID0gZG9tYWluQXJyYXlbaV07XG4gICAgICAgIG5ld091dC5wdXNoKHMubWF0Y2goL1teQS1aYS16MC05Xy1dLykgP1xuICAgICAgICAgICAgJ3huLS0nICsgcHVueWNvZGUuZW5jb2RlKHMpIDogcyk7XG4gICAgICB9XG4gICAgICB0aGlzLmhvc3RuYW1lID0gbmV3T3V0LmpvaW4oJy4nKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcbiAgICB0aGlzLmhyZWYgKz0gdGhpcy5ob3N0O1xuXG4gICAgLy8gc3RyaXAgWyBhbmQgXSBmcm9tIHRoZSBob3N0bmFtZVxuICAgIC8vIHRoZSBob3N0IGZpZWxkIHN0aWxsIHJldGFpbnMgdGhlbSwgdGhvdWdoXG4gICAgaWYgKGlwdjZIb3N0bmFtZSkge1xuICAgICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUuc3Vic3RyKDEsIHRoaXMuaG9zdG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBpZiAocmVzdFswXSAhPT0gJy8nKSB7XG4gICAgICAgIHJlc3QgPSAnLycgKyByZXN0O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG5vdyByZXN0IGlzIHNldCB0byB0aGUgcG9zdC1ob3N0IHN0dWZmLlxuICAvLyBjaG9wIG9mZiBhbnkgZGVsaW0gY2hhcnMuXG4gIGlmICghdW5zYWZlUHJvdG9jb2xbbG93ZXJQcm90b10pIHtcblxuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGZvciAodmFyIGkgPSAwLCBsID0gYXV0b0VzY2FwZS5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHZhciBhZSA9IGF1dG9Fc2NhcGVbaV07XG4gICAgICB2YXIgZXNjID0gZW5jb2RlVVJJQ29tcG9uZW50KGFlKTtcbiAgICAgIGlmIChlc2MgPT09IGFlKSB7XG4gICAgICAgIGVzYyA9IGVzY2FwZShhZSk7XG4gICAgICB9XG4gICAgICByZXN0ID0gcmVzdC5zcGxpdChhZSkuam9pbihlc2MpO1xuICAgIH1cbiAgfVxuXG5cbiAgLy8gY2hvcCBvZmYgZnJvbSB0aGUgdGFpbCBmaXJzdC5cbiAgdmFyIGhhc2ggPSByZXN0LmluZGV4T2YoJyMnKTtcbiAgaWYgKGhhc2ggIT09IC0xKSB7XG4gICAgLy8gZ290IGEgZnJhZ21lbnQgc3RyaW5nLlxuICAgIHRoaXMuaGFzaCA9IHJlc3Quc3Vic3RyKGhhc2gpO1xuICAgIHJlc3QgPSByZXN0LnNsaWNlKDAsIGhhc2gpO1xuICB9XG4gIHZhciBxbSA9IHJlc3QuaW5kZXhPZignPycpO1xuICBpZiAocW0gIT09IC0xKSB7XG4gICAgdGhpcy5zZWFyY2ggPSByZXN0LnN1YnN0cihxbSk7XG4gICAgdGhpcy5xdWVyeSA9IHJlc3Quc3Vic3RyKHFtICsgMSk7XG4gICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgIHRoaXMucXVlcnkgPSBxdWVyeXN0cmluZy5wYXJzZSh0aGlzLnF1ZXJ5KTtcbiAgICB9XG4gICAgcmVzdCA9IHJlc3Quc2xpY2UoMCwgcW0pO1xuICB9IGVsc2UgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAvLyBubyBxdWVyeSBzdHJpbmcsIGJ1dCBwYXJzZVF1ZXJ5U3RyaW5nIHN0aWxsIHJlcXVlc3RlZFxuICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgdGhpcy5xdWVyeSA9IHt9O1xuICB9XG4gIGlmIChyZXN0KSB0aGlzLnBhdGhuYW1lID0gcmVzdDtcbiAgaWYgKHNsYXNoZWRQcm90b2NvbFtsb3dlclByb3RvXSAmJlxuICAgICAgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvL3RvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gIGlmICh0aGlzLnBhdGhuYW1lIHx8IHRoaXMuc2VhcmNoKSB7XG4gICAgdmFyIHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIHZhciBzID0gdGhpcy5zZWFyY2ggfHwgJyc7XG4gICAgdGhpcy5wYXRoID0gcCArIHM7XG4gIH1cblxuICAvLyBmaW5hbGx5LCByZWNvbnN0cnVjdCB0aGUgaHJlZiBiYXNlZCBvbiB3aGF0IGhhcyBiZWVuIHZhbGlkYXRlZC5cbiAgdGhpcy5ocmVmID0gdGhpcy5mb3JtYXQoKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyBmb3JtYXQgYSBwYXJzZWQgb2JqZWN0IGludG8gYSB1cmwgc3RyaW5nXG5mdW5jdGlvbiB1cmxGb3JtYXQob2JqKSB7XG4gIC8vIGVuc3VyZSBpdCdzIGFuIG9iamVjdCwgYW5kIG5vdCBhIHN0cmluZyB1cmwuXG4gIC8vIElmIGl0J3MgYW4gb2JqLCB0aGlzIGlzIGEgbm8tb3AuXG4gIC8vIHRoaXMgd2F5LCB5b3UgY2FuIGNhbGwgdXJsX2Zvcm1hdCgpIG9uIHN0cmluZ3NcbiAgLy8gdG8gY2xlYW4gdXAgcG90ZW50aWFsbHkgd29ua3kgdXJscy5cbiAgaWYgKHV0aWwuaXNTdHJpbmcob2JqKSkgb2JqID0gdXJsUGFyc2Uob2JqKTtcbiAgaWYgKCEob2JqIGluc3RhbmNlb2YgVXJsKSkgcmV0dXJuIFVybC5wcm90b3R5cGUuZm9ybWF0LmNhbGwob2JqKTtcbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuVXJsLnByb3RvdHlwZS5mb3JtYXQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGF1dGggPSB0aGlzLmF1dGggfHwgJyc7XG4gIGlmIChhdXRoKSB7XG4gICAgYXV0aCA9IGVuY29kZVVSSUNvbXBvbmVudChhdXRoKTtcbiAgICBhdXRoID0gYXV0aC5yZXBsYWNlKC8lM0EvaSwgJzonKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJycsXG4gICAgICBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJycsXG4gICAgICBoYXNoID0gdGhpcy5oYXNoIHx8ICcnLFxuICAgICAgaG9zdCA9IGZhbHNlLFxuICAgICAgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/XG4gICAgICAgIHRoaXMuaG9zdG5hbWUgOlxuICAgICAgICAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAmJlxuICAgICAgdXRpbC5pc09iamVjdCh0aGlzLnF1ZXJ5KSAmJlxuICAgICAgc2hpbXMua2V5cyh0aGlzLnF1ZXJ5KS5sZW5ndGgpIHtcbiAgICBxdWVyeSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh0aGlzLnF1ZXJ5KTtcbiAgfVxuXG4gIHZhciBzZWFyY2ggPSB0aGlzLnNlYXJjaCB8fCAocXVlcnkgJiYgKCc/JyArIHF1ZXJ5KSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHNoaW1zLnN1YnN0cihwcm90b2NvbCwgLTEpICE9PSAnOicpIHByb3RvY29sICs9ICc6JztcblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fFxuICAgICAgKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkge1xuICAgIGhvc3QgPSAnLy8nICsgKGhvc3QgfHwgJycpO1xuICAgIGlmIChwYXRobmFtZSAmJiBwYXRobmFtZS5jaGFyQXQoMCkgIT09ICcvJykgcGF0aG5hbWUgPSAnLycgKyBwYXRobmFtZTtcbiAgfSBlbHNlIGlmICghaG9zdCkge1xuICAgIGhvc3QgPSAnJztcbiAgfVxuXG4gIGlmIChoYXNoICYmIGhhc2guY2hhckF0KDApICE9PSAnIycpIGhhc2ggPSAnIycgKyBoYXNoO1xuICBpZiAoc2VhcmNoICYmIHNlYXJjaC5jaGFyQXQoMCkgIT09ICc/Jykgc2VhcmNoID0gJz8nICsgc2VhcmNoO1xuXG4gIHBhdGhuYW1lID0gcGF0aG5hbWUucmVwbGFjZSgvWz8jXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQobWF0Y2gpO1xuICB9KTtcbiAgc2VhcmNoID0gc2VhcmNoLnJlcGxhY2UoJyMnLCAnJTIzJyk7XG5cbiAgcmV0dXJuIHByb3RvY29sICsgaG9zdCArIHBhdGhuYW1lICsgc2VhcmNoICsgaGFzaDtcbn07XG5cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cblVybC5wcm90b3R5cGUucmVzb2x2ZSA9IGZ1bmN0aW9uKHJlbGF0aXZlKSB7XG4gIHJldHVybiB0aGlzLnJlc29sdmVPYmplY3QodXJsUGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKSkuZm9ybWF0KCk7XG59O1xuXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG5VcmwucHJvdG90eXBlLnJlc29sdmVPYmplY3QgPSBmdW5jdGlvbihyZWxhdGl2ZSkge1xuICBpZiAodXRpbC5pc1N0cmluZyhyZWxhdGl2ZSkpIHtcbiAgICB2YXIgcmVsID0gbmV3IFVybCgpO1xuICAgIHJlbC5wYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpO1xuICAgIHJlbGF0aXZlID0gcmVsO1xuICB9XG5cbiAgdmFyIHJlc3VsdCA9IG5ldyBVcmwoKTtcbiAgc2hpbXMuZm9yRWFjaChzaGltcy5rZXlzKHRoaXMpLCBmdW5jdGlvbihrKSB7XG4gICAgcmVzdWx0W2tdID0gdGhpc1trXTtcbiAgfSwgdGhpcyk7XG5cbiAgLy8gaGFzaCBpcyBhbHdheXMgb3ZlcnJpZGRlbiwgbm8gbWF0dGVyIHdoYXQuXG4gIC8vIGV2ZW4gaHJlZj1cIlwiIHdpbGwgcmVtb3ZlIGl0LlxuICByZXN1bHQuaGFzaCA9IHJlbGF0aXZlLmhhc2g7XG5cbiAgLy8gaWYgdGhlIHJlbGF0aXZlIHVybCBpcyBlbXB0eSwgdGhlbiB0aGVyZSdzIG5vdGhpbmcgbGVmdCB0byBkbyBoZXJlLlxuICBpZiAocmVsYXRpdmUuaHJlZiA9PT0gJycpIHtcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gaHJlZnMgbGlrZSAvL2Zvby9iYXIgYWx3YXlzIGN1dCB0byB0aGUgcHJvdG9jb2wuXG4gIGlmIChyZWxhdGl2ZS5zbGFzaGVzICYmICFyZWxhdGl2ZS5wcm90b2NvbCkge1xuICAgIC8vIHRha2UgZXZlcnl0aGluZyBleGNlcHQgdGhlIHByb3RvY29sIGZyb20gcmVsYXRpdmVcbiAgICBzaGltcy5mb3JFYWNoKHNoaW1zLmtleXMocmVsYXRpdmUpLCBmdW5jdGlvbihrKSB7XG4gICAgICBpZiAoayAhPT0gJ3Byb3RvY29sJylcbiAgICAgICAgcmVzdWx0W2tdID0gcmVsYXRpdmVba107XG4gICAgfSk7XG5cbiAgICAvL3VybFBhcnNlIGFwcGVuZHMgdHJhaWxpbmcgLyB0byB1cmxzIGxpa2UgaHR0cDovL3d3dy5leGFtcGxlLmNvbVxuICAgIGlmIChzbGFzaGVkUHJvdG9jb2xbcmVzdWx0LnByb3RvY29sXSAmJlxuICAgICAgICByZXN1bHQuaG9zdG5hbWUgJiYgIXJlc3VsdC5wYXRobmFtZSkge1xuICAgICAgcmVzdWx0LnBhdGggPSByZXN1bHQucGF0aG5hbWUgPSAnLyc7XG4gICAgfVxuXG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmIChyZWxhdGl2ZS5wcm90b2NvbCAmJiByZWxhdGl2ZS5wcm90b2NvbCAhPT0gcmVzdWx0LnByb3RvY29sKSB7XG4gICAgLy8gaWYgaXQncyBhIGtub3duIHVybCBwcm90b2NvbCwgdGhlbiBjaGFuZ2luZ1xuICAgIC8vIHRoZSBwcm90b2NvbCBkb2VzIHdlaXJkIHRoaW5nc1xuICAgIC8vIGZpcnN0LCBpZiBpdCdzIG5vdCBmaWxlOiwgdGhlbiB3ZSBNVVNUIGhhdmUgYSBob3N0LFxuICAgIC8vIGFuZCBpZiB0aGVyZSB3YXMgYSBwYXRoXG4gICAgLy8gdG8gYmVnaW4gd2l0aCwgdGhlbiB3ZSBNVVNUIGhhdmUgYSBwYXRoLlxuICAgIC8vIGlmIGl0IGlzIGZpbGU6LCB0aGVuIHRoZSBob3N0IGlzIGRyb3BwZWQsXG4gICAgLy8gYmVjYXVzZSB0aGF0J3Mga25vd24gdG8gYmUgaG9zdGxlc3MuXG4gICAgLy8gYW55dGhpbmcgZWxzZSBpcyBhc3N1bWVkIHRvIGJlIGFic29sdXRlLlxuICAgIGlmICghc2xhc2hlZFByb3RvY29sW3JlbGF0aXZlLnByb3RvY29sXSkge1xuICAgICAgc2hpbXMuZm9yRWFjaChzaGltcy5rZXlzKHJlbGF0aXZlKSwgZnVuY3Rpb24oaykge1xuICAgICAgICByZXN1bHRba10gPSByZWxhdGl2ZVtrXTtcbiAgICAgIH0pO1xuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmICghcmVsYXRpdmUuaG9zdCAmJiAhaG9zdGxlc3NQcm90b2NvbFtyZWxhdGl2ZS5wcm90b2NvbF0pIHtcbiAgICAgIHZhciByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gKHJlc3VsdC5wYXRobmFtZSAmJiByZXN1bHQucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpLFxuICAgICAgaXNSZWxBYnMgPSAoXG4gICAgICAgICAgcmVsYXRpdmUuaG9zdCB8fFxuICAgICAgICAgIHJlbGF0aXZlLnBhdGhuYW1lICYmIHJlbGF0aXZlLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gJy8nXG4gICAgICApLFxuICAgICAgbXVzdEVuZEFicyA9IChpc1JlbEFicyB8fCBpc1NvdXJjZUFicyB8fFxuICAgICAgICAgICAgICAgICAgICAocmVzdWx0Lmhvc3QgJiYgcmVsYXRpdmUucGF0aG5hbWUpKSxcbiAgICAgIHJlbW92ZUFsbERvdHMgPSBtdXN0RW5kQWJzLFxuICAgICAgc3JjUGF0aCA9IHJlc3VsdC5wYXRobmFtZSAmJiByZXN1bHQucGF0aG5hbWUuc3BsaXQoJy8nKSB8fCBbXSxcbiAgICAgIHJlbFBhdGggPSByZWxhdGl2ZS5wYXRobmFtZSAmJiByZWxhdGl2ZS5wYXRobmFtZS5zcGxpdCgnLycpIHx8IFtdLFxuICAgICAgcHN5Y2hvdGljID0gcmVzdWx0LnByb3RvY29sICYmICFzbGFzaGVkUHJvdG9jb2xbcmVzdWx0LnByb3RvY29sXTtcblxuICAvLyBpZiB0aGUgdXJsIGlzIGEgbm9uLXNsYXNoZWQgdXJsLCB0aGVuIHJlbGF0aXZlXG4gIC8vIGxpbmtzIGxpa2UgLi4vLi4gc2hvdWxkIGJlIGFibGVcbiAgLy8gdG8gY3Jhd2wgdXAgdG8gdGhlIGhvc3RuYW1lLCBhcyB3ZWxsLiAgVGhpcyBpcyBzdHJhbmdlLlxuICAvLyByZXN1bHQucHJvdG9jb2wgaGFzIGFscmVhZHkgYmVlbiBzZXQgYnkgbm93LlxuICAvLyBMYXRlciBvbiwgcHV0IHRoZSBmaXJzdCBwYXRoIHBhcnQgaW50byB0aGUgaG9zdCBmaWVsZC5cbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9ICcnO1xuICAgIHJlc3VsdC5wb3J0ID0gbnVsbDtcbiAgICBpZiAocmVzdWx0Lmhvc3QpIHtcbiAgICAgIGlmIChzcmNQYXRoWzBdID09PSAnJykgc3JjUGF0aFswXSA9IHJlc3VsdC5ob3N0O1xuICAgICAgZWxzZSBzcmNQYXRoLnVuc2hpZnQocmVzdWx0Lmhvc3QpO1xuICAgIH1cbiAgICByZXN1bHQuaG9zdCA9ICcnO1xuICAgIGlmIChyZWxhdGl2ZS5wcm90b2NvbCkge1xuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgPSBudWxsO1xuICAgICAgcmVsYXRpdmUucG9ydCA9IG51bGw7XG4gICAgICBpZiAocmVsYXRpdmUuaG9zdCkge1xuICAgICAgICBpZiAocmVsUGF0aFswXSA9PT0gJycpIHJlbFBhdGhbMF0gPSByZWxhdGl2ZS5ob3N0O1xuICAgICAgICBlbHNlIHJlbFBhdGgudW5zaGlmdChyZWxhdGl2ZS5ob3N0KTtcbiAgICAgIH1cbiAgICAgIHJlbGF0aXZlLmhvc3QgPSBudWxsO1xuICAgIH1cbiAgICBtdXN0RW5kQWJzID0gbXVzdEVuZEFicyAmJiAocmVsUGF0aFswXSA9PT0gJycgfHwgc3JjUGF0aFswXSA9PT0gJycpO1xuICB9XG5cbiAgaWYgKGlzUmVsQWJzKSB7XG4gICAgLy8gaXQncyBhYnNvbHV0ZS5cbiAgICByZXN1bHQuaG9zdCA9IChyZWxhdGl2ZS5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgPT09ICcnKSA/XG4gICAgICAgICAgICAgICAgICByZWxhdGl2ZS5ob3N0IDogcmVzdWx0Lmhvc3Q7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gKHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3RuYW1lID09PSAnJykgP1xuICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aXZlLmhvc3RuYW1lIDogcmVzdWx0Lmhvc3RuYW1lO1xuICAgIHJlc3VsdC5zZWFyY2ggPSByZWxhdGl2ZS5zZWFyY2g7XG4gICAgcmVzdWx0LnF1ZXJ5ID0gcmVsYXRpdmUucXVlcnk7XG4gICAgc3JjUGF0aCA9IHJlbFBhdGg7XG4gICAgLy8gZmFsbCB0aHJvdWdoIHRvIHRoZSBkb3QtaGFuZGxpbmcgYmVsb3cuXG4gIH0gZWxzZSBpZiAocmVsUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBpdCdzIHJlbGF0aXZlXG4gICAgLy8gdGhyb3cgYXdheSB0aGUgZXhpc3RpbmcgZmlsZSwgYW5kIHRha2UgdGhlIG5ldyBwYXRoIGluc3RlYWQuXG4gICAgaWYgKCFzcmNQYXRoKSBzcmNQYXRoID0gW107XG4gICAgc3JjUGF0aC5wb3AoKTtcbiAgICBzcmNQYXRoID0gc3JjUGF0aC5jb25jYXQocmVsUGF0aCk7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgfSBlbHNlIGlmICghdXRpbC5pc051bGxPclVuZGVmaW5lZChyZWxhdGl2ZS5zZWFyY2gpKSB7XG4gICAgLy8ganVzdCBwdWxsIG91dCB0aGUgc2VhcmNoLlxuICAgIC8vIGxpa2UgaHJlZj0nP2ZvbycuXG4gICAgLy8gUHV0IHRoaXMgYWZ0ZXIgdGhlIG90aGVyIHR3byBjYXNlcyBiZWNhdXNlIGl0IHNpbXBsaWZpZXMgdGhlIGJvb2xlYW5zXG4gICAgaWYgKHBzeWNob3RpYykge1xuICAgICAgcmVzdWx0Lmhvc3RuYW1lID0gcmVzdWx0Lmhvc3QgPSBzcmNQYXRoLnNoaWZ0KCk7XG4gICAgICAvL29jY2F0aW9uYWx5IHRoZSBhdXRoIGNhbiBnZXQgc3R1Y2sgb25seSBpbiBob3N0XG4gICAgICAvL3RoaXMgZXNwZWNpYWx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIHZhciBhdXRoSW5Ib3N0ID0gcmVzdWx0Lmhvc3QgJiYgcmVzdWx0Lmhvc3QuaW5kZXhPZignQCcpID4gMCA/XG4gICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5ob3N0LnNwbGl0KCdAJykgOiBmYWxzZTtcbiAgICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICAgIHJlc3VsdC5hdXRoID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgICByZXN1bHQuaG9zdCA9IHJlc3VsdC5ob3N0bmFtZSA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICAvL3RvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKCF1dGlsLmlzTnVsbChyZXN1bHQucGF0aG5hbWUpIHx8ICF1dGlsLmlzTnVsbChyZXN1bHQuc2VhcmNoKSkge1xuICAgICAgcmVzdWx0LnBhdGggPSAocmVzdWx0LnBhdGhuYW1lID8gcmVzdWx0LnBhdGhuYW1lIDogJycpICtcbiAgICAgICAgICAgICAgICAgICAgKHJlc3VsdC5zZWFyY2ggPyByZXN1bHQuc2VhcmNoIDogJycpO1xuICAgIH1cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIC8vIG5vIHBhdGggYXQgYWxsLiAgZWFzeS5cbiAgICAvLyB3ZSd2ZSBhbHJlYWR5IGhhbmRsZWQgdGhlIG90aGVyIHN0dWZmIGFib3ZlLlxuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgLy90byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICAgIGlmIChyZXN1bHQuc2VhcmNoKSB7XG4gICAgICByZXN1bHQucGF0aCA9ICcvJyArIHJlc3VsdC5zZWFyY2g7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gbnVsbDtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGlmIGEgdXJsIEVORHMgaW4gLiBvciAuLiwgdGhlbiBpdCBtdXN0IGdldCBhIHRyYWlsaW5nIHNsYXNoLlxuICAvLyBob3dldmVyLCBpZiBpdCBlbmRzIGluIGFueXRoaW5nIGVsc2Ugbm9uLXNsYXNoeSxcbiAgLy8gdGhlbiBpdCBtdXN0IE5PVCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgdmFyIGxhc3QgPSBzcmNQYXRoLnNsaWNlKC0xKVswXTtcbiAgdmFyIGhhc1RyYWlsaW5nU2xhc2ggPSAoXG4gICAgICAocmVzdWx0Lmhvc3QgfHwgcmVsYXRpdmUuaG9zdCkgJiYgKGxhc3QgPT09ICcuJyB8fCBsYXN0ID09PSAnLi4nKSB8fFxuICAgICAgbGFzdCA9PT0gJycpO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09ICcuJykge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAnLi4nKSB7XG4gICAgICBzcmNQYXRoLnNwbGljZShpLCAxKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3JjUGF0aC5zcGxpY2UoaSwgMSk7XG4gICAgICB1cC0tO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXRoIGlzIGFsbG93ZWQgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIHJlc3RvcmUgbGVhZGluZyAuLnNcbiAgaWYgKCFtdXN0RW5kQWJzICYmICFyZW1vdmVBbGxEb3RzKSB7XG4gICAgZm9yICg7IHVwLS07IHVwKSB7XG4gICAgICBzcmNQYXRoLnVuc2hpZnQoJy4uJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgc3JjUGF0aFswXSAhPT0gJycgJiZcbiAgICAgICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiAoc2hpbXMuc3Vic3RyKHNyY1BhdGguam9pbignLycpLCAtMSkgIT09ICcvJykpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fFxuICAgICAgKHNyY1BhdGhbMF0gJiYgc3JjUGF0aFswXS5jaGFyQXQoMCkgPT09ICcvJyk7XG5cbiAgLy8gcHV0IHRoZSBob3N0IGJhY2tcbiAgaWYgKHBzeWNob3RpYykge1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gaXNBYnNvbHV0ZSA/ICcnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1BhdGgubGVuZ3RoID8gc3JjUGF0aC5zaGlmdCgpIDogJyc7XG4gICAgLy9vY2NhdGlvbmFseSB0aGUgYXV0aCBjYW4gZ2V0IHN0dWNrIG9ubHkgaW4gaG9zdFxuICAgIC8vdGhpcyBlc3BlY2lhbHkgaGFwcGVucyBpbiBjYXNlcyBsaWtlXG4gICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICB2YXIgYXV0aEluSG9zdCA9IHJlc3VsdC5ob3N0ICYmIHJlc3VsdC5ob3N0LmluZGV4T2YoJ0AnKSA+IDAgP1xuICAgICAgICAgICAgICAgICAgICAgcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAoIXV0aWwuaXNOdWxsKHJlc3VsdC5wYXRobmFtZSkgfHwgIXV0aWwuaXNOdWxsKHJlc3VsdC5zZWFyY2gpKSB7XG4gICAgcmVzdWx0LnBhdGggPSAocmVzdWx0LnBhdGhuYW1lID8gcmVzdWx0LnBhdGhuYW1lIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgfVxuICByZXN1bHQuYXV0aCA9IHJlbGF0aXZlLmF1dGggfHwgcmVzdWx0LmF1dGg7XG4gIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG5VcmwucHJvdG90eXBlLnBhcnNlSG9zdCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc3Vic3RyKDEpO1xuICAgIH1cbiAgICBob3N0ID0gaG9zdC5zdWJzdHIoMCwgaG9zdC5sZW5ndGggLSBwb3J0Lmxlbmd0aCk7XG4gIH1cbiAgaWYgKGhvc3QpIHRoaXMuaG9zdG5hbWUgPSBob3N0O1xufTsiLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIHNoaW1zID0gcmVxdWlyZSgnX3NoaW1zJyk7XG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG4vKipcbiAqIEVjaG9zIHRoZSB2YWx1ZSBvZiBhIHZhbHVlLiBUcnlzIHRvIHByaW50IHRoZSB2YWx1ZSBvdXRcbiAqIGluIHRoZSBiZXN0IHdheSBwb3NzaWJsZSBnaXZlbiB0aGUgZGlmZmVyZW50IHR5cGVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBwcmludCBvdXQuXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0cyBPcHRpb25hbCBvcHRpb25zIG9iamVjdCB0aGF0IGFsdGVycyB0aGUgb3V0cHV0LlxuICovXG4vKiBsZWdhY3k6IG9iaiwgc2hvd0hpZGRlbiwgZGVwdGgsIGNvbG9ycyovXG5mdW5jdGlvbiBpbnNwZWN0KG9iaiwgb3B0cykge1xuICAvLyBkZWZhdWx0IG9wdGlvbnNcbiAgdmFyIGN0eCA9IHtcbiAgICBzZWVuOiBbXSxcbiAgICBzdHlsaXplOiBzdHlsaXplTm9Db2xvclxuICB9O1xuICAvLyBsZWdhY3kuLi5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gMykgY3R4LmRlcHRoID0gYXJndW1lbnRzWzJdO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSA0KSBjdHguY29sb3JzID0gYXJndW1lbnRzWzNdO1xuICBpZiAoaXNCb29sZWFuKG9wdHMpKSB7XG4gICAgLy8gbGVnYWN5Li4uXG4gICAgY3R4LnNob3dIaWRkZW4gPSBvcHRzO1xuICB9IGVsc2UgaWYgKG9wdHMpIHtcbiAgICAvLyBnb3QgYW4gXCJvcHRpb25zXCIgb2JqZWN0XG4gICAgZXhwb3J0cy5fZXh0ZW5kKGN0eCwgb3B0cyk7XG4gIH1cbiAgLy8gc2V0IGRlZmF1bHQgb3B0aW9uc1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LnNob3dIaWRkZW4pKSBjdHguc2hvd0hpZGRlbiA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmRlcHRoKSkgY3R4LmRlcHRoID0gMjtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jb2xvcnMpKSBjdHguY29sb3JzID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY3VzdG9tSW5zcGVjdCkpIGN0eC5jdXN0b21JbnNwZWN0ID0gdHJ1ZTtcbiAgaWYgKGN0eC5jb2xvcnMpIGN0eC5zdHlsaXplID0gc3R5bGl6ZVdpdGhDb2xvcjtcbiAgcmV0dXJuIGZvcm1hdFZhbHVlKGN0eCwgb2JqLCBjdHguZGVwdGgpO1xufVxuZXhwb3J0cy5pbnNwZWN0ID0gaW5zcGVjdDtcblxuXG4vLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FOU0lfZXNjYXBlX2NvZGUjZ3JhcGhpY3Ncbmluc3BlY3QuY29sb3JzID0ge1xuICAnYm9sZCcgOiBbMSwgMjJdLFxuICAnaXRhbGljJyA6IFszLCAyM10sXG4gICd1bmRlcmxpbmUnIDogWzQsIDI0XSxcbiAgJ2ludmVyc2UnIDogWzcsIDI3XSxcbiAgJ3doaXRlJyA6IFszNywgMzldLFxuICAnZ3JleScgOiBbOTAsIDM5XSxcbiAgJ2JsYWNrJyA6IFszMCwgMzldLFxuICAnYmx1ZScgOiBbMzQsIDM5XSxcbiAgJ2N5YW4nIDogWzM2LCAzOV0sXG4gICdncmVlbicgOiBbMzIsIDM5XSxcbiAgJ21hZ2VudGEnIDogWzM1LCAzOV0sXG4gICdyZWQnIDogWzMxLCAzOV0sXG4gICd5ZWxsb3cnIDogWzMzLCAzOV1cbn07XG5cbi8vIERvbid0IHVzZSAnYmx1ZScgbm90IHZpc2libGUgb24gY21kLmV4ZVxuaW5zcGVjdC5zdHlsZXMgPSB7XG4gICdzcGVjaWFsJzogJ2N5YW4nLFxuICAnbnVtYmVyJzogJ3llbGxvdycsXG4gICdib29sZWFuJzogJ3llbGxvdycsXG4gICd1bmRlZmluZWQnOiAnZ3JleScsXG4gICdudWxsJzogJ2JvbGQnLFxuICAnc3RyaW5nJzogJ2dyZWVuJyxcbiAgJ2RhdGUnOiAnbWFnZW50YScsXG4gIC8vIFwibmFtZVwiOiBpbnRlbnRpb25hbGx5IG5vdCBzdHlsaW5nXG4gICdyZWdleHAnOiAncmVkJ1xufTtcblxuXG5mdW5jdGlvbiBzdHlsaXplV2l0aENvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHZhciBzdHlsZSA9IGluc3BlY3Quc3R5bGVzW3N0eWxlVHlwZV07XG5cbiAgaWYgKHN0eWxlKSB7XG4gICAgcmV0dXJuICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMF0gKyAnbScgKyBzdHIgK1xuICAgICAgICAgICAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzFdICsgJ20nO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzdHlsaXplTm9Db2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICByZXR1cm4gc3RyO1xufVxuXG5cbmZ1bmN0aW9uIGFycmF5VG9IYXNoKGFycmF5KSB7XG4gIHZhciBoYXNoID0ge307XG5cbiAgc2hpbXMuZm9yRWFjaChhcnJheSwgZnVuY3Rpb24odmFsLCBpZHgpIHtcbiAgICBoYXNoW3ZhbF0gPSB0cnVlO1xuICB9KTtcblxuICByZXR1cm4gaGFzaDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMpIHtcbiAgLy8gUHJvdmlkZSBhIGhvb2sgZm9yIHVzZXItc3BlY2lmaWVkIGluc3BlY3QgZnVuY3Rpb25zLlxuICAvLyBDaGVjayB0aGF0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFuIGluc3BlY3QgZnVuY3Rpb24gb24gaXRcbiAgaWYgKGN0eC5jdXN0b21JbnNwZWN0ICYmXG4gICAgICB2YWx1ZSAmJlxuICAgICAgaXNGdW5jdGlvbih2YWx1ZS5pbnNwZWN0KSAmJlxuICAgICAgLy8gRmlsdGVyIG91dCB0aGUgdXRpbCBtb2R1bGUsIGl0J3MgaW5zcGVjdCBmdW5jdGlvbiBpcyBzcGVjaWFsXG4gICAgICB2YWx1ZS5pbnNwZWN0ICE9PSBleHBvcnRzLmluc3BlY3QgJiZcbiAgICAgIC8vIEFsc28gZmlsdGVyIG91dCBhbnkgcHJvdG90eXBlIG9iamVjdHMgdXNpbmcgdGhlIGNpcmN1bGFyIGNoZWNrLlxuICAgICAgISh2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgPT09IHZhbHVlKSkge1xuICAgIHZhciByZXQgPSB2YWx1ZS5pbnNwZWN0KHJlY3Vyc2VUaW1lcyk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IHNoaW1zLmtleXModmFsdWUpO1xuICB2YXIgdmlzaWJsZUtleXMgPSBhcnJheVRvSGFzaChrZXlzKTtcblxuICBpZiAoY3R4LnNob3dIaWRkZW4pIHtcbiAgICBrZXlzID0gc2hpbXMuZ2V0T3duUHJvcGVydHlOYW1lcyh2YWx1ZSk7XG4gIH1cblxuICAvLyBTb21lIHR5cGUgb2Ygb2JqZWN0IHdpdGhvdXQgcHJvcGVydGllcyBjYW4gYmUgc2hvcnRjdXR0ZWQuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgICAgdmFyIG5hbWUgPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZSgnW0Z1bmN0aW9uJyArIG5hbWUgKyAnXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICAgIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBjdHguc3R5bGl6ZShSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAncmVnZXhwJyk7XG4gICAgfVxuICAgIGlmIChpc0RhdGUodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdkYXRlJyk7XG4gICAgfVxuICAgIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYmFzZSA9ICcnLCBhcnJheSA9IGZhbHNlLCBicmFjZXMgPSBbJ3snLCAnfSddO1xuXG4gIC8vIE1ha2UgQXJyYXkgc2F5IHRoYXQgdGhleSBhcmUgQXJyYXlcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgYXJyYXkgPSB0cnVlO1xuICAgIGJyYWNlcyA9IFsnWycsICddJ107XG4gIH1cblxuICAvLyBNYWtlIGZ1bmN0aW9ucyBzYXkgdGhhdCB0aGV5IGFyZSBmdW5jdGlvbnNcbiAgaWYgKGlzRnVuY3Rpb24odmFsdWUpKSB7XG4gICAgdmFyIG4gPSB2YWx1ZS5uYW1lID8gJzogJyArIHZhbHVlLm5hbWUgOiAnJztcbiAgICBiYXNlID0gJyBbRnVuY3Rpb24nICsgbiArICddJztcbiAgfVxuXG4gIC8vIE1ha2UgUmVnRXhwcyBzYXkgdGhhdCB0aGV5IGFyZSBSZWdFeHBzXG4gIGlmIChpc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZGF0ZXMgd2l0aCBwcm9wZXJ0aWVzIGZpcnN0IHNheSB0aGUgZGF0ZVxuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgfVxuXG4gIC8vIE1ha2UgZXJyb3Igd2l0aCBtZXNzYWdlIGZpcnN0IHNheSB0aGUgZXJyb3JcbiAgaWYgKGlzRXJyb3IodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIGZvcm1hdEVycm9yKHZhbHVlKTtcbiAgfVxuXG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCAmJiAoIWFycmF5IHx8IHZhbHVlLmxlbmd0aCA9PSAwKSkge1xuICAgIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgYnJhY2VzWzFdO1xuICB9XG5cbiAgaWYgKHJlY3Vyc2VUaW1lcyA8IDApIHtcbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tPYmplY3RdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBjdHguc2Vlbi5wdXNoKHZhbHVlKTtcblxuICB2YXIgb3V0cHV0O1xuICBpZiAoYXJyYXkpIHtcbiAgICBvdXRwdXQgPSBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKTtcbiAgfSBlbHNlIHtcbiAgICBvdXRwdXQgPSBrZXlzLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KTtcbiAgICB9KTtcbiAgfVxuXG4gIGN0eC5zZWVuLnBvcCgpO1xuXG4gIHJldHVybiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpIHtcbiAgaWYgKGlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ3VuZGVmaW5lZCcsICd1bmRlZmluZWQnKTtcbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhciBzaW1wbGUgPSAnXFwnJyArIEpTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC9eXCJ8XCIkL2csICcnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKSArICdcXCcnO1xuICAgIHJldHVybiBjdHguc3R5bGl6ZShzaW1wbGUsICdzdHJpbmcnKTtcbiAgfVxuICBpZiAoaXNOdW1iZXIodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnbnVtYmVyJyk7XG4gIGlmIChpc0Jvb2xlYW4odmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnJyArIHZhbHVlLCAnYm9vbGVhbicpO1xuICAvLyBGb3Igc29tZSByZWFzb24gdHlwZW9mIG51bGwgaXMgXCJvYmplY3RcIiwgc28gc3BlY2lhbCBjYXNlIGhlcmUuXG4gIGlmIChpc051bGwodmFsdWUpKVxuICAgIHJldHVybiBjdHguc3R5bGl6ZSgnbnVsbCcsICdudWxsJyk7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0RXJyb3IodmFsdWUpIHtcbiAgcmV0dXJuICdbJyArIEVycm9yLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSArICddJztcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRBcnJheShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXlzKSB7XG4gIHZhciBvdXRwdXQgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSB2YWx1ZS5sZW5ndGg7IGkgPCBsOyArK2kpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkodmFsdWUsIFN0cmluZyhpKSkpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAgU3RyaW5nKGkpLCB0cnVlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKCcnKTtcbiAgICB9XG4gIH1cblxuICBzaGltcy5mb3JFYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgIGlmICgha2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgb3V0cHV0LnB1c2goZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cyxcbiAgICAgICAgICBrZXksIHRydWUpKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsIGtleSwgYXJyYXkpIHtcbiAgdmFyIG5hbWUsIHN0ciwgZGVzYztcbiAgZGVzYyA9IHNoaW1zLmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YWx1ZSwga2V5KSB8fCB7IHZhbHVlOiB2YWx1ZVtrZXldIH07XG4gIGlmIChkZXNjLmdldCkge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXIvU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChkZXNjLnNldCkge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tTZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChzaGltcy5pbmRleE9mKGN0eC5zZWVuLCBkZXNjLnZhbHVlKSA8IDApIHtcbiAgICAgIGlmIChpc051bGwocmVjdXJzZVRpbWVzKSkge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIG51bGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCByZWN1cnNlVGltZXMgLSAxKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xuICAgICAgICBpZiAoYXJyYXkpIHtcbiAgICAgICAgICBzdHIgPSBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJykuc3Vic3RyKDIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciA9ICdcXG4nICsgc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0NpcmN1bGFyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG4gIGlmIChpc1VuZGVmaW5lZChuYW1lKSkge1xuICAgIGlmIChhcnJheSAmJiBrZXkubWF0Y2goL15cXGQrJC8pKSB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgICBuYW1lID0gSlNPTi5zdHJpbmdpZnkoJycgKyBrZXkpO1xuICAgIGlmIChuYW1lLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKSkge1xuICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyKDEsIG5hbWUubGVuZ3RoIC0gMik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ25hbWUnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmFtZSA9IG5hbWUucmVwbGFjZSgvJy9nLCBcIlxcXFwnXCIpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJylcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoLyheXCJ8XCIkKS9nLCBcIidcIik7XG4gICAgICBuYW1lID0gY3R4LnN0eWxpemUobmFtZSwgJ3N0cmluZycpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuYW1lICsgJzogJyArIHN0cjtcbn1cblxuXG5mdW5jdGlvbiByZWR1Y2VUb1NpbmdsZVN0cmluZyhvdXRwdXQsIGJhc2UsIGJyYWNlcykge1xuICB2YXIgbnVtTGluZXNFc3QgPSAwO1xuICB2YXIgbGVuZ3RoID0gc2hpbXMucmVkdWNlKG91dHB1dCwgZnVuY3Rpb24ocHJldiwgY3VyKSB7XG4gICAgbnVtTGluZXNFc3QrKztcbiAgICBpZiAoY3VyLmluZGV4T2YoJ1xcbicpID49IDApIG51bUxpbmVzRXN0Kys7XG4gICAgcmV0dXJuIHByZXYgKyBjdXIucmVwbGFjZSgvXFx1MDAxYlxcW1xcZFxcZD9tL2csICcnKS5sZW5ndGggKyAxO1xuICB9LCAwKTtcblxuICBpZiAobGVuZ3RoID4gNjApIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICtcbiAgICAgICAgICAgKGJhc2UgPT09ICcnID8gJycgOiBiYXNlICsgJ1xcbiAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIG91dHB1dC5qb2luKCcsXFxuICAnKSArXG4gICAgICAgICAgICcgJyArXG4gICAgICAgICAgIGJyYWNlc1sxXTtcbiAgfVxuXG4gIHJldHVybiBicmFjZXNbMF0gKyBiYXNlICsgJyAnICsgb3V0cHV0LmpvaW4oJywgJykgKyAnICcgKyBicmFjZXNbMV07XG59XG5cblxuLy8gTk9URTogVGhlc2UgdHlwZSBjaGVja2luZyBmdW5jdGlvbnMgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYGluc3RhbmNlb2ZgXG4vLyBiZWNhdXNlIGl0IGlzIGZyYWdpbGUgYW5kIGNhbiBiZSBlYXNpbHkgZmFrZWQgd2l0aCBgT2JqZWN0LmNyZWF0ZSgpYC5cbmZ1bmN0aW9uIGlzQXJyYXkoYXIpIHtcbiAgcmV0dXJuIHNoaW1zLmlzQXJyYXkoYXIpO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gaXNBcnJheTtcblxuZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nO1xufVxuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5cbmZ1bmN0aW9uIGlzTnVsbChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsID0gaXNOdWxsO1xuXG5mdW5jdGlvbiBpc051bGxPclVuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PSBudWxsO1xufVxuZXhwb3J0cy5pc051bGxPclVuZGVmaW5lZCA9IGlzTnVsbE9yVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdudW1iZXInO1xufVxuZXhwb3J0cy5pc051bWJlciA9IGlzTnVtYmVyO1xuXG5mdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnO1xufVxuZXhwb3J0cy5pc1N0cmluZyA9IGlzU3RyaW5nO1xuXG5mdW5jdGlvbiBpc1N5bWJvbChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnO1xufVxuZXhwb3J0cy5pc1N5bWJvbCA9IGlzU3ltYm9sO1xuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZChhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gdm9pZCAwO1xufVxuZXhwb3J0cy5pc1VuZGVmaW5lZCA9IGlzVW5kZWZpbmVkO1xuXG5mdW5jdGlvbiBpc1JlZ0V4cChyZSkge1xuICByZXR1cm4gaXNPYmplY3QocmUpICYmIG9iamVjdFRvU3RyaW5nKHJlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSc7XG59XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5cbmZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ29iamVjdCcgJiYgYXJnO1xufVxuZXhwb3J0cy5pc09iamVjdCA9IGlzT2JqZWN0O1xuXG5mdW5jdGlvbiBpc0RhdGUoZCkge1xuICByZXR1cm4gaXNPYmplY3QoZCkgJiYgb2JqZWN0VG9TdHJpbmcoZCkgPT09ICdbb2JqZWN0IERhdGVdJztcbn1cbmV4cG9ydHMuaXNEYXRlID0gaXNEYXRlO1xuXG5mdW5jdGlvbiBpc0Vycm9yKGUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGUpICYmIG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nO1xufVxuZXhwb3J0cy5pc0Vycm9yID0gaXNFcnJvcjtcblxuZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbic7XG59XG5leHBvcnRzLmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xuXG5mdW5jdGlvbiBpc1ByaW1pdGl2ZShhcmcpIHtcbiAgcmV0dXJuIGFyZyA9PT0gbnVsbCB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ2Jvb2xlYW4nIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N0cmluZycgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzeW1ib2wnIHx8ICAvLyBFUzYgc3ltYm9sXG4gICAgICAgICB0eXBlb2YgYXJnID09PSAndW5kZWZpbmVkJztcbn1cbmV4cG9ydHMuaXNQcmltaXRpdmUgPSBpc1ByaW1pdGl2ZTtcblxuZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmJpbmFyeVNsaWNlID09PSAnZnVuY3Rpb24nXG4gIDtcbn1cbmV4cG9ydHMuaXNCdWZmZXIgPSBpc0J1ZmZlcjtcblxuZnVuY3Rpb24gb2JqZWN0VG9TdHJpbmcobykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pO1xufVxuXG5cbmZ1bmN0aW9uIHBhZChuKSB7XG4gIHJldHVybiBuIDwgMTAgPyAnMCcgKyBuLnRvU3RyaW5nKDEwKSA6IG4udG9TdHJpbmcoMTApO1xufVxuXG5cbnZhciBtb250aHMgPSBbJ0phbicsICdGZWInLCAnTWFyJywgJ0FwcicsICdNYXknLCAnSnVuJywgJ0p1bCcsICdBdWcnLCAnU2VwJyxcbiAgICAgICAgICAgICAgJ09jdCcsICdOb3YnLCAnRGVjJ107XG5cbi8vIDI2IEZlYiAxNjoxOTozNFxuZnVuY3Rpb24gdGltZXN0YW1wKCkge1xuICB2YXIgZCA9IG5ldyBEYXRlKCk7XG4gIHZhciB0aW1lID0gW3BhZChkLmdldEhvdXJzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRNaW51dGVzKCkpLFxuICAgICAgICAgICAgICBwYWQoZC5nZXRTZWNvbmRzKCkpXS5qb2luKCc6Jyk7XG4gIHJldHVybiBbZC5nZXREYXRlKCksIG1vbnRoc1tkLmdldE1vbnRoKCldLCB0aW1lXS5qb2luKCcgJyk7XG59XG5cblxuLy8gbG9nIGlzIGp1c3QgYSB0aGluIHdyYXBwZXIgdG8gY29uc29sZS5sb2cgdGhhdCBwcmVwZW5kcyBhIHRpbWVzdGFtcFxuZXhwb3J0cy5sb2cgPSBmdW5jdGlvbigpIHtcbiAgY29uc29sZS5sb2coJyVzIC0gJXMnLCB0aW1lc3RhbXAoKSwgZXhwb3J0cy5mb3JtYXQuYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKSk7XG59O1xuXG5cbi8qKlxuICogSW5oZXJpdCB0aGUgcHJvdG90eXBlIG1ldGhvZHMgZnJvbSBvbmUgY29uc3RydWN0b3IgaW50byBhbm90aGVyLlxuICpcbiAqIFRoZSBGdW5jdGlvbi5wcm90b3R5cGUuaW5oZXJpdHMgZnJvbSBsYW5nLmpzIHJld3JpdHRlbiBhcyBhIHN0YW5kYWxvbmVcbiAqIGZ1bmN0aW9uIChub3Qgb24gRnVuY3Rpb24ucHJvdG90eXBlKS4gTk9URTogSWYgdGhpcyBmaWxlIGlzIHRvIGJlIGxvYWRlZFxuICogZHVyaW5nIGJvb3RzdHJhcHBpbmcgdGhpcyBmdW5jdGlvbiBuZWVkcyB0byBiZSByZXdyaXR0ZW4gdXNpbmcgc29tZSBuYXRpdmVcbiAqIGZ1bmN0aW9ucyBhcyBwcm90b3R5cGUgc2V0dXAgdXNpbmcgbm9ybWFsIEphdmFTY3JpcHQgZG9lcyBub3Qgd29yayBhc1xuICogZXhwZWN0ZWQgZHVyaW5nIGJvb3RzdHJhcHBpbmcgKHNlZSBtaXJyb3IuanMgaW4gcjExNDkwMykuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB3aGljaCBuZWVkcyB0byBpbmhlcml0IHRoZVxuICogICAgIHByb3RvdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IHN1cGVyQ3RvciBDb25zdHJ1Y3RvciBmdW5jdGlvbiB0byBpbmhlcml0IHByb3RvdHlwZSBmcm9tLlxuICovXG5leHBvcnRzLmluaGVyaXRzID0gZnVuY3Rpb24oY3Rvciwgc3VwZXJDdG9yKSB7XG4gIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yO1xuICBjdG9yLnByb3RvdHlwZSA9IHNoaW1zLmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG59O1xuXG5leHBvcnRzLl9leHRlbmQgPSBmdW5jdGlvbihvcmlnaW4sIGFkZCkge1xuICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiBhZGQgaXNuJ3QgYW4gb2JqZWN0XG4gIGlmICghYWRkIHx8ICFpc09iamVjdChhZGQpKSByZXR1cm4gb3JpZ2luO1xuXG4gIHZhciBrZXlzID0gc2hpbXMua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuIiwiZXhwb3J0cy5yZWFkSUVFRTc1NCA9IGZ1bmN0aW9uKGJ1ZmZlciwgb2Zmc2V0LCBpc0JFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgbkJpdHMgPSAtNyxcbiAgICAgIGkgPSBpc0JFID8gMCA6IChuQnl0ZXMgLSAxKSxcbiAgICAgIGQgPSBpc0JFID8gMSA6IC0xLFxuICAgICAgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXTtcblxuICBpICs9IGQ7XG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIHMgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBlTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcbiAgZSA+Pj0gKC1uQml0cyk7XG4gIG5CaXRzICs9IG1MZW47XG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpO1xuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpO1xuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbik7XG4gICAgZSA9IGUgLSBlQmlhcztcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcbn07XG5cbmV4cG9ydHMud3JpdGVJRUVFNzU0ID0gZnVuY3Rpb24oYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGMsXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxuICAgICAgaSA9IGlzQkUgPyAobkJ5dGVzIC0gMSkgOiAwLFxuICAgICAgZCA9IGlzQkUgPyAtMSA6IDEsXG4gICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrO1xuICAgICAgYyAvPSAyO1xuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcblxuICBlID0gKGUgPDwgbUxlbikgfCBtO1xuICBlTGVuICs9IG1MZW47XG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xufTtcbiIsInZhciBhc3NlcnQ7XG5leHBvcnRzLkJ1ZmZlciA9IEJ1ZmZlcjtcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IEJ1ZmZlcjtcbkJ1ZmZlci5wb29sU2l6ZSA9IDgxOTI7XG5leHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTID0gNTA7XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0oc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKCk7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xufVxuXG5mdW5jdGlvbiBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG9mZnNldCkge1xuICBpZighYXNzZXJ0KSBhc3NlcnQ9IHJlcXVpcmUoJ2Fzc2VydCcpO1xuICBpZiAoISh0aGlzIGluc3RhbmNlb2YgQnVmZmVyKSkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nLCBvZmZzZXQpO1xuICB9XG4gIHRoaXMucGFyZW50ID0gdGhpcztcbiAgdGhpcy5vZmZzZXQgPSAwO1xuXG4gIC8vIFdvcmstYXJvdW5kOiBub2RlJ3MgYmFzZTY0IGltcGxlbWVudGF0aW9uXG4gIC8vIGFsbG93cyBmb3Igbm9uLXBhZGRlZCBzdHJpbmdzIHdoaWxlIGJhc2U2NC1qc1xuICAvLyBkb2VzIG5vdC4uXG4gIGlmIChlbmNvZGluZyA9PSBcImJhc2U2NFwiICYmIHR5cGVvZiBzdWJqZWN0ID09IFwic3RyaW5nXCIpIHtcbiAgICBzdWJqZWN0ID0gc3RyaW5ndHJpbShzdWJqZWN0KTtcbiAgICB3aGlsZSAoc3ViamVjdC5sZW5ndGggJSA0ICE9IDApIHtcbiAgICAgIHN1YmplY3QgPSBzdWJqZWN0ICsgXCI9XCI7IFxuICAgIH1cbiAgfVxuXG4gIHZhciB0eXBlO1xuXG4gIC8vIEFyZSB3ZSBzbGljaW5nP1xuICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ251bWJlcicpIHtcbiAgICB0aGlzLmxlbmd0aCA9IGNvZXJjZShlbmNvZGluZyk7XG4gICAgLy8gc2xpY2luZyB3b3Jrcywgd2l0aCBsaW1pdGF0aW9ucyAobm8gcGFyZW50IHRyYWNraW5nL3VwZGF0ZSlcbiAgICAvLyBjaGVjayBodHRwczovL2dpdGh1Yi5jb20vdG9vdHMvYnVmZmVyLWJyb3dzZXJpZnkvaXNzdWVzLzE5XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbaV0gPSBzdWJqZWN0LmdldChpK29mZnNldCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIEZpbmQgdGhlIGxlbmd0aFxuICAgIHN3aXRjaCAodHlwZSA9IHR5cGVvZiBzdWJqZWN0KSB7XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICB0aGlzLmxlbmd0aCA9IGNvZXJjZShzdWJqZWN0KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3N0cmluZyc6XG4gICAgICAgIHRoaXMubGVuZ3RoID0gQnVmZmVyLmJ5dGVMZW5ndGgoc3ViamVjdCwgZW5jb2RpbmcpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnb2JqZWN0JzogLy8gQXNzdW1lIG9iamVjdCBpcyBhbiBhcnJheVxuICAgICAgICB0aGlzLmxlbmd0aCA9IGNvZXJjZShzdWJqZWN0Lmxlbmd0aCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IG5lZWRzIHRvIGJlIGEgbnVtYmVyLCAnICtcbiAgICAgICAgICAgICAgICAgICAgICAgICdhcnJheSBvciBzdHJpbmcuJyk7XG4gICAgfVxuXG4gICAgLy8gVHJlYXQgYXJyYXktaXNoIG9iamVjdHMgYXMgYSBieXRlIGFycmF5LlxuICAgIGlmIChpc0FycmF5SXNoKHN1YmplY3QpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHN1YmplY3QgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgICAgICB0aGlzW2ldID0gc3ViamVjdC5yZWFkVUludDgoaSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgdGhpc1tpXSA9IHN1YmplY3RbaV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIFdlIGFyZSBhIHN0cmluZ1xuICAgICAgdGhpcy5sZW5ndGggPSB0aGlzLndyaXRlKHN1YmplY3QsIDAsIGVuY29kaW5nKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdGhpc1tpXSA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gZ2V0KGkpIHtcbiAgaWYgKGkgPCAwIHx8IGkgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignb29iJyk7XG4gIHJldHVybiB0aGlzW2ldO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiBzZXQoaSwgdikge1xuICBpZiAoaSA8IDAgfHwgaSA+PSB0aGlzLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdvb2InKTtcbiAgcmV0dXJuIHRoaXNbaV0gPSB2O1xufTtcblxuQnVmZmVyLmJ5dGVMZW5ndGggPSBmdW5jdGlvbiAoc3RyLCBlbmNvZGluZykge1xuICBzd2l0Y2ggKGVuY29kaW5nIHx8IFwidXRmOFwiKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldHVybiBzdHIubGVuZ3RoIC8gMjtcblxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldHVybiB1dGY4VG9CeXRlcyhzdHIpLmxlbmd0aDtcblxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICBjYXNlICdiaW5hcnknOlxuICAgICAgcmV0dXJuIHN0ci5sZW5ndGg7XG5cbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0dXJuIGJhc2U2NFRvQnl0ZXMoc3RyKS5sZW5ndGg7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJyk7XG4gIH1cbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUudXRmOFdyaXRlID0gZnVuY3Rpb24gKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGJ5dGVzLCBwb3M7XG4gIHJldHVybiBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9ICBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyksIHRoaXMsIG9mZnNldCwgbGVuZ3RoKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuYXNjaWlXcml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBieXRlcywgcG9zO1xuICByZXR1cm4gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSAgYmxpdEJ1ZmZlcihhc2NpaVRvQnl0ZXMoc3RyaW5nKSwgdGhpcywgb2Zmc2V0LCBsZW5ndGgpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5iaW5hcnlXcml0ZSA9IEJ1ZmZlci5wcm90b3R5cGUuYXNjaWlXcml0ZTtcblxuQnVmZmVyLnByb3RvdHlwZS5iYXNlNjRXcml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBieXRlcywgcG9zO1xuICByZXR1cm4gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgdGhpcywgb2Zmc2V0LCBsZW5ndGgpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5iYXNlNjRTbGljZSA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpXG4gIHJldHVybiByZXF1aXJlKFwiYmFzZTY0LWpzXCIpLmZyb21CeXRlQXJyYXkoYnl0ZXMpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS51dGY4U2xpY2UgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBieXRlcyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB2YXIgcmVzID0gXCJcIjtcbiAgdmFyIHRtcCA9IFwiXCI7XG4gIHZhciBpID0gMDtcbiAgd2hpbGUgKGkgPCBieXRlcy5sZW5ndGgpIHtcbiAgICBpZiAoYnl0ZXNbaV0gPD0gMHg3Rikge1xuICAgICAgcmVzICs9IGRlY29kZVV0ZjhDaGFyKHRtcCkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKTtcbiAgICAgIHRtcCA9IFwiXCI7XG4gICAgfSBlbHNlXG4gICAgICB0bXAgKz0gXCIlXCIgKyBieXRlc1tpXS50b1N0cmluZygxNik7XG5cbiAgICBpKys7XG4gIH1cblxuICByZXR1cm4gcmVzICsgZGVjb2RlVXRmOENoYXIodG1wKTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5hc2NpaVNsaWNlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgdmFyIHJldCA9IFwiXCI7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyBpKyspXG4gICAgcmV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pO1xuICByZXR1cm4gcmV0O1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmJpbmFyeVNsaWNlID0gQnVmZmVyLnByb3RvdHlwZS5hc2NpaVNsaWNlO1xuXG5CdWZmZXIucHJvdG90eXBlLmluc3BlY3QgPSBmdW5jdGlvbigpIHtcbiAgdmFyIG91dCA9IFtdLFxuICAgICAgbGVuID0gdGhpcy5sZW5ndGg7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBvdXRbaV0gPSB0b0hleCh0aGlzW2ldKTtcbiAgICBpZiAoaSA9PSBleHBvcnRzLklOU1BFQ1RfTUFYX0JZVEVTKSB7XG4gICAgICBvdXRbaSArIDFdID0gJy4uLic7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuICc8QnVmZmVyICcgKyBvdXQuam9pbignICcpICsgJz4nO1xufTtcblxuXG5CdWZmZXIucHJvdG90eXBlLmhleFNsaWNlID0gZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGg7XG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMDtcbiAgaWYgKCFlbmQgfHwgZW5kIDwgMCB8fCBlbmQgPiBsZW4pIGVuZCA9IGxlbjtcblxuICB2YXIgb3V0ID0gJyc7XG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KHRoaXNbaV0pO1xuICB9XG4gIHJldHVybiBvdXQ7XG59O1xuXG5cbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKCk7XG4gIHN0YXJ0ID0gK3N0YXJ0IHx8IDA7XG4gIGlmICh0eXBlb2YgZW5kID09ICd1bmRlZmluZWQnKSBlbmQgPSB0aGlzLmxlbmd0aDtcblxuICAvLyBGYXN0cGF0aCBlbXB0eSBzdHJpbmdzXG4gIGlmICgrZW5kID09IHN0YXJ0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgc3dpdGNoIChlbmNvZGluZykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXR1cm4gdGhpcy5oZXhTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldHVybiB0aGlzLnV0ZjhTbGljZShzdGFydCwgZW5kKTtcblxuICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgIHJldHVybiB0aGlzLmFzY2lpU2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICdiaW5hcnknOlxuICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0dXJuIHRoaXMuYmFzZTY0U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgICByZXR1cm4gdGhpcy51Y3MyU2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nJyk7XG4gIH1cbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS5oZXhXcml0ZSA9IGZ1bmN0aW9uKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gK29mZnNldCB8fCAwO1xuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXQ7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nO1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9ICtsZW5ndGg7XG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nO1xuICAgIH1cbiAgfVxuXG4gIC8vIG11c3QgYmUgYW4gZXZlbiBudW1iZXIgb2YgZGlnaXRzXG4gIHZhciBzdHJMZW4gPSBzdHJpbmcubGVuZ3RoO1xuICBpZiAoc3RyTGVuICUgMikge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGxlbmd0aCA+IHN0ckxlbiAvIDIpIHtcbiAgICBsZW5ndGggPSBzdHJMZW4gLyAyO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnl0ZSA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNik7XG4gICAgaWYgKGlzTmFOKGJ5dGUpKSB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpO1xuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSBieXRlO1xuICB9XG4gIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gaSAqIDI7XG4gIHJldHVybiBpO1xufTtcblxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgLy8gU3VwcG9ydCBib3RoIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZylcbiAgLy8gYW5kIHRoZSBsZWdhY3kgKHN0cmluZywgZW5jb2RpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICBpZiAoaXNGaW5pdGUob2Zmc2V0KSkge1xuICAgIGlmICghaXNGaW5pdGUobGVuZ3RoKSkge1xuICAgICAgZW5jb2RpbmcgPSBsZW5ndGg7XG4gICAgICBsZW5ndGggPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9IGVsc2UgeyAgLy8gbGVnYWN5XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZztcbiAgICBlbmNvZGluZyA9IG9mZnNldDtcbiAgICBvZmZzZXQgPSBsZW5ndGg7XG4gICAgbGVuZ3RoID0gc3dhcDtcbiAgfVxuXG4gIG9mZnNldCA9ICtvZmZzZXQgfHwgMDtcbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0O1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSArbGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgICB9XG4gIH1cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpO1xuXG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0dXJuIHRoaXMuaGV4V3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXR1cm4gdGhpcy51dGY4V3JpdGUoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCk7XG5cbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXR1cm4gdGhpcy5hc2NpaVdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldHVybiB0aGlzLmJpbmFyeVdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldHVybiB0aGlzLmJhc2U2NFdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgICAgcmV0dXJuIHRoaXMudWNzMldyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpO1xuICB9XG59O1xuXG4vLyBzbGljZShzdGFydCwgZW5kKVxuZnVuY3Rpb24gY2xhbXAoaW5kZXgsIGxlbiwgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICdudW1iZXInKSByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICBpbmRleCA9IH5+aW5kZXg7ICAvLyBDb2VyY2UgdG8gaW50ZWdlci5cbiAgaWYgKGluZGV4ID49IGxlbikgcmV0dXJuIGxlbjtcbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleDtcbiAgaW5kZXggKz0gbGVuO1xuICBpZiAoaW5kZXggPj0gMCkgcmV0dXJuIGluZGV4O1xuICByZXR1cm4gMDtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoO1xuICBzdGFydCA9IGNsYW1wKHN0YXJ0LCBsZW4sIDApO1xuICBlbmQgPSBjbGFtcChlbmQsIGxlbiwgbGVuKTtcbiAgcmV0dXJuIG5ldyBCdWZmZXIodGhpcywgZW5kIC0gc3RhcnQsICtzdGFydCk7XG59O1xuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbih0YXJnZXQsIHRhcmdldF9zdGFydCwgc3RhcnQsIGVuZCkge1xuICB2YXIgc291cmNlID0gdGhpcztcbiAgc3RhcnQgfHwgKHN0YXJ0ID0gMCk7XG4gIGlmIChlbmQgPT09IHVuZGVmaW5lZCB8fCBpc05hTihlbmQpKSB7XG4gICAgZW5kID0gdGhpcy5sZW5ndGg7XG4gIH1cbiAgdGFyZ2V0X3N0YXJ0IHx8ICh0YXJnZXRfc3RhcnQgPSAwKTtcblxuICBpZiAoZW5kIDwgc3RhcnQpIHRocm93IG5ldyBFcnJvcignc291cmNlRW5kIDwgc291cmNlU3RhcnQnKTtcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwO1xuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PSAwIHx8IHNvdXJjZS5sZW5ndGggPT0gMCkgcmV0dXJuIDA7XG5cbiAgaWYgKHRhcmdldF9zdGFydCA8IDAgfHwgdGFyZ2V0X3N0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlU3RhcnQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gc291cmNlLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc291cmNlRW5kIG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoO1xuICB9XG5cbiAgaWYgKHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgPCBlbmQgLSBzdGFydCkge1xuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgKyBzdGFydDtcbiAgfVxuXG4gIHZhciB0ZW1wID0gW107XG4gIGZvciAodmFyIGk9c3RhcnQ7IGk8ZW5kOyBpKyspIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIHRoaXNbaV0gIT09ICd1bmRlZmluZWQnLCBcImNvcHlpbmcgdW5kZWZpbmVkIGJ1ZmZlciBieXRlcyFcIik7XG4gICAgdGVtcC5wdXNoKHRoaXNbaV0pO1xuICB9XG5cbiAgZm9yICh2YXIgaT10YXJnZXRfc3RhcnQ7IGk8dGFyZ2V0X3N0YXJ0K3RlbXAubGVuZ3RoOyBpKyspIHtcbiAgICB0YXJnZXRbaV0gPSB0ZW1wW2ktdGFyZ2V0X3N0YXJ0XTtcbiAgfVxufTtcblxuLy8gZmlsbCh2YWx1ZSwgc3RhcnQ9MCwgZW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmZpbGwgPSBmdW5jdGlvbiBmaWxsKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gIHZhbHVlIHx8ICh2YWx1ZSA9IDApO1xuICBzdGFydCB8fCAoc3RhcnQgPSAwKTtcbiAgZW5kIHx8IChlbmQgPSB0aGlzLmxlbmd0aCk7XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICB2YWx1ZSA9IHZhbHVlLmNoYXJDb2RlQXQoMCk7XG4gIH1cbiAgaWYgKCEodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykgfHwgaXNOYU4odmFsdWUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd2YWx1ZSBpcyBub3QgYSBudW1iZXInKTtcbiAgfVxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IEVycm9yKCdlbmQgPCBzdGFydCcpO1xuXG4gIC8vIEZpbGwgMCBieXRlczsgd2UncmUgZG9uZVxuICBpZiAoZW5kID09PSBzdGFydCkgcmV0dXJuIDA7XG4gIGlmICh0aGlzLmxlbmd0aCA9PSAwKSByZXR1cm4gMDtcblxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHRoaXMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBpZiAoZW5kIDwgMCB8fCBlbmQgPiB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignZW5kIG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgdGhpc1tpXSA9IHZhbHVlO1xuICB9XG59XG5cbi8vIFN0YXRpYyBtZXRob2RzXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiBpc0J1ZmZlcihiKSB7XG4gIHJldHVybiBiIGluc3RhbmNlb2YgQnVmZmVyIHx8IGIgaW5zdGFuY2VvZiBCdWZmZXI7XG59O1xuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gKGxpc3QsIHRvdGFsTGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlVzYWdlOiBCdWZmZXIuY29uY2F0KGxpc3QsIFt0b3RhbExlbmd0aF0pXFxuIFxcXG4gICAgICBsaXN0IHNob3VsZCBiZSBhbiBBcnJheS5cIik7XG4gIH1cblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKTtcbiAgfSBlbHNlIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBsaXN0WzBdO1xuICB9XG5cbiAgaWYgKHR5cGVvZiB0b3RhbExlbmd0aCAhPT0gJ251bWJlcicpIHtcbiAgICB0b3RhbExlbmd0aCA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgYnVmID0gbGlzdFtpXTtcbiAgICAgIHRvdGFsTGVuZ3RoICs9IGJ1Zi5sZW5ndGg7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZmZlciA9IG5ldyBCdWZmZXIodG90YWxMZW5ndGgpO1xuICB2YXIgcG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGJ1ZiA9IGxpc3RbaV07XG4gICAgYnVmLmNvcHkoYnVmZmVyLCBwb3MpO1xuICAgIHBvcyArPSBidWYubGVuZ3RoO1xuICB9XG4gIHJldHVybiBidWZmZXI7XG59O1xuXG5CdWZmZXIuaXNFbmNvZGluZyA9IGZ1bmN0aW9uKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKCkpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgY2FzZSAncmF3JzpcbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuLy8gaGVscGVyc1xuXG5mdW5jdGlvbiBjb2VyY2UobGVuZ3RoKSB7XG4gIC8vIENvZXJjZSBsZW5ndGggdG8gYSBudW1iZXIgKHBvc3NpYmx5IE5hTiksIHJvdW5kIHVwXG4gIC8vIGluIGNhc2UgaXQncyBmcmFjdGlvbmFsIChlLmcuIDEyMy40NTYpIHRoZW4gZG8gYVxuICAvLyBkb3VibGUgbmVnYXRlIHRvIGNvZXJjZSBhIE5hTiB0byAwLiBFYXN5LCByaWdodD9cbiAgbGVuZ3RoID0gfn5NYXRoLmNlaWwoK2xlbmd0aCk7XG4gIHJldHVybiBsZW5ndGggPCAwID8gMCA6IGxlbmd0aDtcbn1cblxuZnVuY3Rpb24gaXNBcnJheShzdWJqZWN0KSB7XG4gIHJldHVybiAoQXJyYXkuaXNBcnJheSB8fFxuICAgIGZ1bmN0aW9uKHN1YmplY3Qpe1xuICAgICAgcmV0dXJuIHt9LnRvU3RyaW5nLmFwcGx5KHN1YmplY3QpID09ICdbb2JqZWN0IEFycmF5XSdcbiAgICB9KVxuICAgIChzdWJqZWN0KVxufVxuXG5mdW5jdGlvbiBpc0FycmF5SXNoKHN1YmplY3QpIHtcbiAgcmV0dXJuIGlzQXJyYXkoc3ViamVjdCkgfHwgQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpIHx8XG4gICAgICAgICBzdWJqZWN0ICYmIHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAgdHlwZW9mIHN1YmplY3QubGVuZ3RoID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gdG9IZXgobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNik7XG4gIHJldHVybiBuLnRvU3RyaW5nKDE2KTtcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspXG4gICAgaWYgKHN0ci5jaGFyQ29kZUF0KGkpIDw9IDB4N0YpXG4gICAgICBieXRlQXJyYXkucHVzaChzdHIuY2hhckNvZGVBdChpKSk7XG4gICAgZWxzZSB7XG4gICAgICB2YXIgaCA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIuY2hhckF0KGkpKS5zdWJzdHIoMSkuc3BsaXQoJyUnKTtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaC5sZW5ndGg7IGorKylcbiAgICAgICAgYnl0ZUFycmF5LnB1c2gocGFyc2VJbnQoaFtqXSwgMTYpKTtcbiAgICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheTtcbn1cblxuZnVuY3Rpb24gYXNjaWlUb0J5dGVzKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKysgKVxuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKCBzdHIuY2hhckNvZGVBdChpKSAmIDB4RkYgKTtcblxuICByZXR1cm4gYnl0ZUFycmF5O1xufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzKHN0cikge1xuICByZXR1cm4gcmVxdWlyZShcImJhc2U2NC1qc1wiKS50b0J5dGVBcnJheShzdHIpO1xufVxuXG5mdW5jdGlvbiBibGl0QnVmZmVyKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgcG9zLCBpID0gMDtcbiAgd2hpbGUgKGkgPCBsZW5ndGgpIHtcbiAgICBpZiAoKGkrb2Zmc2V0ID49IGRzdC5sZW5ndGgpIHx8IChpID49IHNyYy5sZW5ndGgpKVxuICAgICAgYnJlYWs7XG5cbiAgICBkc3RbaSArIG9mZnNldF0gPSBzcmNbaV07XG4gICAgaSsrO1xuICB9XG4gIHJldHVybiBpO1xufVxuXG5mdW5jdGlvbiBkZWNvZGVVdGY4Q2hhcihzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cik7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkZGRCk7IC8vIFVURiA4IGludmFsaWQgY2hhclxuICB9XG59XG5cbi8vIHJlYWQvd3JpdGUgYml0LXR3aWRkbGluZ1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFyIGJ1ZmZlciA9IHRoaXM7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSByZXR1cm47XG5cbiAgcmV0dXJuIGJ1ZmZlcltvZmZzZXRdO1xufTtcblxuZnVuY3Rpb24gcmVhZFVJbnQxNihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhciB2YWwgPSAwO1xuXG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gMDtcblxuICBpZiAoaXNCaWdFbmRpYW4pIHtcbiAgICB2YWwgPSBidWZmZXJbb2Zmc2V0XSA8PCA4O1xuICAgIGlmIChvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAxXTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFsID0gYnVmZmVyW29mZnNldF07XG4gICAgaWYgKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgICB2YWwgfD0gYnVmZmVyW29mZnNldCArIDFdIDw8IDg7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHZhbDtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2TEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkVUludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRVSW50MzIoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgdmFsID0gMDtcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICBpZiAob2Zmc2V0ID49IGJ1ZmZlci5sZW5ndGgpIHJldHVybiAwO1xuXG4gIGlmIChpc0JpZ0VuZGlhbikge1xuICAgIGlmIChvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCA9IGJ1ZmZlcltvZmZzZXQgKyAxXSA8PCAxNjtcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgfD0gYnVmZmVyW29mZnNldCArIDJdIDw8IDg7XG4gICAgaWYgKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAzXTtcbiAgICB2YWwgPSB2YWwgKyAoYnVmZmVyW29mZnNldF0gPDwgMjQgPj4+IDApO1xuICB9IGVsc2Uge1xuICAgIGlmIChvZmZzZXQgKyAyIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCA9IGJ1ZmZlcltvZmZzZXQgKyAyXSA8PCAxNjtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgfD0gYnVmZmVyW29mZnNldCArIDFdIDw8IDg7XG4gICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXRdO1xuICAgIGlmIChvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCA9IHZhbCArIChidWZmZXJbb2Zmc2V0ICsgM10gPDwgMjQgPj4+IDApO1xuICB9XG5cbiAgcmV0dXJuIHZhbDtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDMyTEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkVUludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cblxuLypcbiAqIFNpZ25lZCBpbnRlZ2VyIHR5cGVzLCB5YXkgdGVhbSEgQSByZW1pbmRlciBvbiBob3cgdHdvJ3MgY29tcGxlbWVudCBhY3R1YWxseVxuICogd29ya3MuIFRoZSBmaXJzdCBiaXQgaXMgdGhlIHNpZ25lZCBiaXQsIGkuZS4gdGVsbHMgdXMgd2hldGhlciBvciBub3QgdGhlXG4gKiBudW1iZXIgc2hvdWxkIGJlIHBvc2l0aXZlIG9yIG5lZ2F0aXZlLiBJZiB0aGUgdHdvJ3MgY29tcGxlbWVudCB2YWx1ZSBpc1xuICogcG9zaXRpdmUsIHRoZW4gd2UncmUgZG9uZSwgYXMgaXQncyBlcXVpdmFsZW50IHRvIHRoZSB1bnNpZ25lZCByZXByZXNlbnRhdGlvbi5cbiAqXG4gKiBOb3cgaWYgdGhlIG51bWJlciBpcyBwb3NpdGl2ZSwgeW91J3JlIHByZXR0eSBtdWNoIGRvbmUsIHlvdSBjYW4ganVzdCBsZXZlcmFnZVxuICogdGhlIHVuc2lnbmVkIHRyYW5zbGF0aW9ucyBhbmQgcmV0dXJuIHRob3NlLiBVbmZvcnR1bmF0ZWx5LCBuZWdhdGl2ZSBudW1iZXJzXG4gKiBhcmVuJ3QgcXVpdGUgdGhhdCBzdHJhaWdodGZvcndhcmQuXG4gKlxuICogQXQgZmlyc3QgZ2xhbmNlLCBvbmUgbWlnaHQgYmUgaW5jbGluZWQgdG8gdXNlIHRoZSB0cmFkaXRpb25hbCBmb3JtdWxhIHRvXG4gKiB0cmFuc2xhdGUgYmluYXJ5IG51bWJlcnMgYmV0d2VlbiB0aGUgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIHZhbHVlcyBpbiB0d28nc1xuICogY29tcGxlbWVudC4gKFRob3VnaCBpdCBkb2Vzbid0IHF1aXRlIHdvcmsgZm9yIHRoZSBtb3N0IG5lZ2F0aXZlIHZhbHVlKVxuICogTWFpbmx5OlxuICogIC0gaW52ZXJ0IGFsbCB0aGUgYml0c1xuICogIC0gYWRkIG9uZSB0byB0aGUgcmVzdWx0XG4gKlxuICogT2YgY291cnNlLCB0aGlzIGRvZXNuJ3QgcXVpdGUgd29yayBpbiBKYXZhc2NyaXB0LiBUYWtlIGZvciBleGFtcGxlIHRoZSB2YWx1ZVxuICogb2YgLTEyOC4gVGhpcyBjb3VsZCBiZSByZXByZXNlbnRlZCBpbiAxNiBiaXRzIChiaWctZW5kaWFuKSBhcyAweGZmODAuIEJ1dCBvZlxuICogY291cnNlLCBKYXZhc2NyaXB0IHdpbGwgZG8gdGhlIGZvbGxvd2luZzpcbiAqXG4gKiA+IH4weGZmODBcbiAqIC02NTQwOVxuICpcbiAqIFdob2ggdGhlcmUsIEphdmFzY3JpcHQsIHRoYXQncyBub3QgcXVpdGUgcmlnaHQuIEJ1dCB3YWl0LCBhY2NvcmRpbmcgdG9cbiAqIEphdmFzY3JpcHQgdGhhdCdzIHBlcmZlY3RseSBjb3JyZWN0LiBXaGVuIEphdmFzY3JpcHQgZW5kcyB1cCBzZWVpbmcgdGhlXG4gKiBjb25zdGFudCAweGZmODAsIGl0IGhhcyBubyBub3Rpb24gdGhhdCBpdCBpcyBhY3R1YWxseSBhIHNpZ25lZCBudW1iZXIuIEl0XG4gKiBhc3N1bWVzIHRoYXQgd2UndmUgaW5wdXQgdGhlIHVuc2lnbmVkIHZhbHVlIDB4ZmY4MC4gVGh1cywgd2hlbiBpdCBkb2VzIHRoZVxuICogYmluYXJ5IG5lZ2F0aW9uLCBpdCBjYXN0cyBpdCBpbnRvIGEgc2lnbmVkIHZhbHVlLCAocG9zaXRpdmUgMHhmZjgwKS4gVGhlblxuICogd2hlbiB5b3UgcGVyZm9ybSBiaW5hcnkgbmVnYXRpb24gb24gdGhhdCwgaXQgdHVybnMgaXQgaW50byBhIG5lZ2F0aXZlIG51bWJlci5cbiAqXG4gKiBJbnN0ZWFkLCB3ZSdyZSBnb2luZyB0byBoYXZlIHRvIHVzZSB0aGUgZm9sbG93aW5nIGdlbmVyYWwgZm9ybXVsYSwgdGhhdCB3b3Jrc1xuICogaW4gYSByYXRoZXIgSmF2YXNjcmlwdCBmcmllbmRseSB3YXkuIEknbSBnbGFkIHdlIGRvbid0IHN1cHBvcnQgdGhpcyBraW5kIG9mXG4gKiB3ZWlyZCBudW1iZXJpbmcgc2NoZW1lIGluIHRoZSBrZXJuZWwuXG4gKlxuICogKEJJVC1NQVggLSAodW5zaWduZWQpdmFsICsgMSkgKiAtMVxuICpcbiAqIFRoZSBhc3R1dGUgb2JzZXJ2ZXIsIG1heSB0aGluayB0aGF0IHRoaXMgZG9lc24ndCBtYWtlIHNlbnNlIGZvciA4LWJpdCBudW1iZXJzXG4gKiAocmVhbGx5IGl0IGlzbid0IG5lY2Vzc2FyeSBmb3IgdGhlbSkuIEhvd2V2ZXIsIHdoZW4geW91IGdldCAxNi1iaXQgbnVtYmVycyxcbiAqIHlvdSBkby4gTGV0J3MgZ28gYmFjayB0byBvdXIgcHJpb3IgZXhhbXBsZSBhbmQgc2VlIGhvdyB0aGlzIHdpbGwgbG9vazpcbiAqXG4gKiAoMHhmZmZmIC0gMHhmZjgwICsgMSkgKiAtMVxuICogKDB4MDA3ZiArIDEpICogLTFcbiAqICgweDAwODApICogLTFcbiAqL1xuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFyIGJ1ZmZlciA9IHRoaXM7XG4gIHZhciBuZWc7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSByZXR1cm47XG5cbiAgbmVnID0gYnVmZmVyW29mZnNldF0gJiAweDgwO1xuICBpZiAoIW5lZykge1xuICAgIHJldHVybiAoYnVmZmVyW29mZnNldF0pO1xuICB9XG5cbiAgcmV0dXJuICgoMHhmZiAtIGJ1ZmZlcltvZmZzZXRdICsgMSkgKiAtMSk7XG59O1xuXG5mdW5jdGlvbiByZWFkSW50MTYoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgbmVnLCB2YWw7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgdmFsID0gcmVhZFVJbnQxNihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgbmVnID0gdmFsICYgMHg4MDAwO1xuICBpZiAoIW5lZykge1xuICAgIHJldHVybiB2YWw7XG4gIH1cblxuICByZXR1cm4gKDB4ZmZmZiAtIHZhbCArIDEpICogLTE7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRJbnQzMihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIHZhciBuZWcsIHZhbDtcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICB2YWwgPSByZWFkVUludDMyKGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICBuZWcgPSB2YWwgJiAweDgwMDAwMDAwO1xuICBpZiAoIW5lZykge1xuICAgIHJldHVybiAodmFsKTtcbiAgfVxuXG4gIHJldHVybiAoMHhmZmZmZmZmZiAtIHZhbCArIDEpICogLTE7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRGbG9hdChidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICByZXR1cm4gcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLnJlYWRJRUVFNzU0KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbixcbiAgICAgIDIzLCA0KTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRGbG9hdEJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gcmVhZERvdWJsZShidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyA3IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG4gIH1cblxuICByZXR1cm4gcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLnJlYWRJRUVFNzU0KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbixcbiAgICAgIDUyLCA4KTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkRG91YmxlKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUJFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZERvdWJsZSh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cblxuLypcbiAqIFdlIGhhdmUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIHZhbHVlIGlzIGEgdmFsaWQgaW50ZWdlci4gVGhpcyBtZWFucyB0aGF0IGl0IGlzXG4gKiBub24tbmVnYXRpdmUuIEl0IGhhcyBubyBmcmFjdGlvbmFsIGNvbXBvbmVudCBhbmQgdGhhdCBpdCBkb2VzIG5vdCBleGNlZWQgdGhlXG4gKiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUuXG4gKlxuICogICAgICB2YWx1ZSAgICAgICAgICAgVGhlIG51bWJlciB0byBjaGVjayBmb3IgdmFsaWRpdHlcbiAqXG4gKiAgICAgIG1heCAgICAgICAgICAgICBUaGUgbWF4aW11bSB2YWx1ZVxuICovXG5mdW5jdGlvbiB2ZXJpZnVpbnQodmFsdWUsIG1heCkge1xuICBhc3NlcnQub2sodHlwZW9mICh2YWx1ZSkgPT0gJ251bWJlcicsXG4gICAgICAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA+PSAwLFxuICAgICAgJ3NwZWNpZmllZCBhIG5lZ2F0aXZlIHZhbHVlIGZvciB3cml0aW5nIGFuIHVuc2lnbmVkIHZhbHVlJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGlzIGxhcmdlciB0aGFuIG1heGltdW0gdmFsdWUgZm9yIHR5cGUnKTtcblxuICBhc3NlcnQub2soTWF0aC5mbG9vcih2YWx1ZSkgPT09IHZhbHVlLCAndmFsdWUgaGFzIGEgZnJhY3Rpb25hbCBjb21wb25lbnQnKTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFyIGJ1ZmZlciA9IHRoaXM7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPCBidWZmZXIubGVuZ3RoKSB7XG4gICAgYnVmZmVyW29mZnNldF0gPSB2YWx1ZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gd3JpdGVVSW50MTYoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmYpO1xuICB9XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBNYXRoLm1pbihidWZmZXIubGVuZ3RoIC0gb2Zmc2V0LCAyKTsgaSsrKSB7XG4gICAgYnVmZmVyW29mZnNldCArIGldID1cbiAgICAgICAgKHZhbHVlICYgKDB4ZmYgPDwgKDggKiAoaXNCaWdFbmRpYW4gPyAxIC0gaSA6IGkpKSkpID4+PlxuICAgICAgICAgICAgKGlzQmlnRW5kaWFuID8gMSAtIGkgOiBpKSAqIDg7XG4gIH1cblxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVVSW50MzIoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmZmZmZmZmKTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTWF0aC5taW4oYnVmZmVyLmxlbmd0aCAtIG9mZnNldCwgNCk7IGkrKykge1xuICAgIGJ1ZmZlcltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSA+Pj4gKGlzQmlnRW5kaWFuID8gMyAtIGkgOiBpKSAqIDgpICYgMHhmZjtcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuXG4vKlxuICogV2Ugbm93IG1vdmUgb250byBvdXIgZnJpZW5kcyBpbiB0aGUgc2lnbmVkIG51bWJlciBjYXRlZ29yeS4gVW5saWtlIHVuc2lnbmVkXG4gKiBudW1iZXJzLCB3ZSdyZSBnb2luZyB0byBoYXZlIHRvIHdvcnJ5IGEgYml0IG1vcmUgYWJvdXQgaG93IHdlIHB1dCB2YWx1ZXMgaW50b1xuICogYXJyYXlzLiBTaW5jZSB3ZSBhcmUgb25seSB3b3JyeWluZyBhYm91dCBzaWduZWQgMzItYml0IHZhbHVlcywgd2UncmUgaW5cbiAqIHNsaWdodGx5IGJldHRlciBzaGFwZS4gVW5mb3J0dW5hdGVseSwgd2UgcmVhbGx5IGNhbid0IGRvIG91ciBmYXZvcml0ZSBiaW5hcnlcbiAqICYgaW4gdGhpcyBzeXN0ZW0uIEl0IHJlYWxseSBzZWVtcyB0byBkbyB0aGUgd3JvbmcgdGhpbmcuIEZvciBleGFtcGxlOlxuICpcbiAqID4gLTMyICYgMHhmZlxuICogMjI0XG4gKlxuICogV2hhdCdzIGhhcHBlbmluZyBhYm92ZSBpcyByZWFsbHk6IDB4ZTAgJiAweGZmID0gMHhlMC4gSG93ZXZlciwgdGhlIHJlc3VsdHMgb2ZcbiAqIHRoaXMgYXJlbid0IHRyZWF0ZWQgYXMgYSBzaWduZWQgbnVtYmVyLiBVbHRpbWF0ZWx5IGEgYmFkIHRoaW5nLlxuICpcbiAqIFdoYXQgd2UncmUgZ29pbmcgdG8gd2FudCB0byBkbyBpcyBiYXNpY2FsbHkgY3JlYXRlIHRoZSB1bnNpZ25lZCBlcXVpdmFsZW50IG9mXG4gKiBvdXIgcmVwcmVzZW50YXRpb24gYW5kIHBhc3MgdGhhdCBvZmYgdG8gdGhlIHd1aW50KiBmdW5jdGlvbnMuIFRvIGRvIHRoYXRcbiAqIHdlJ3JlIGdvaW5nIHRvIGRvIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogIC0gaWYgdGhlIHZhbHVlIGlzIHBvc2l0aXZlXG4gKiAgICAgIHdlIGNhbiBwYXNzIGl0IGRpcmVjdGx5IG9mZiB0byB0aGUgZXF1aXZhbGVudCB3dWludFxuICogIC0gaWYgdGhlIHZhbHVlIGlzIG5lZ2F0aXZlXG4gKiAgICAgIHdlIGRvIHRoZSBmb2xsb3dpbmcgY29tcHV0YXRpb246XG4gKiAgICAgICAgIG1iICsgdmFsICsgMSwgd2hlcmVcbiAqICAgICAgICAgbWIgICBpcyB0aGUgbWF4aW11bSB1bnNpZ25lZCB2YWx1ZSBpbiB0aGF0IGJ5dGUgc2l6ZVxuICogICAgICAgICB2YWwgIGlzIHRoZSBKYXZhc2NyaXB0IG5lZ2F0aXZlIGludGVnZXJcbiAqXG4gKlxuICogQXMgYSBjb25jcmV0ZSB2YWx1ZSwgdGFrZSAtMTI4LiBJbiBzaWduZWQgMTYgYml0cyB0aGlzIHdvdWxkIGJlIDB4ZmY4MC4gSWZcbiAqIHlvdSBkbyBvdXQgdGhlIGNvbXB1dGF0aW9uczpcbiAqXG4gKiAweGZmZmYgLSAxMjggKyAxXG4gKiAweGZmZmYgLSAxMjdcbiAqIDB4ZmY4MFxuICpcbiAqIFlvdSBjYW4gdGhlbiBlbmNvZGUgdGhpcyB2YWx1ZSBhcyB0aGUgc2lnbmVkIHZlcnNpb24uIFRoaXMgaXMgcmVhbGx5IHJhdGhlclxuICogaGFja3ksIGJ1dCBpdCBzaG91bGQgd29yayBhbmQgZ2V0IHRoZSBqb2IgZG9uZSB3aGljaCBpcyBvdXIgZ29hbCBoZXJlLlxuICovXG5cbi8qXG4gKiBBIHNlcmllcyBvZiBjaGVja3MgdG8gbWFrZSBzdXJlIHdlIGFjdHVhbGx5IGhhdmUgYSBzaWduZWQgMzItYml0IG51bWJlclxuICovXG5mdW5jdGlvbiB2ZXJpZnNpbnQodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydC5vayh0eXBlb2YgKHZhbHVlKSA9PSAnbnVtYmVyJyxcbiAgICAgICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGxhcmdlciB0aGFuIG1heGltdW0gYWxsb3dlZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA+PSBtaW4sICd2YWx1ZSBzbWFsbGVyIHRoYW4gbWluaW11bSBhbGxvd2VkIHZhbHVlJyk7XG5cbiAgYXNzZXJ0Lm9rKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSwgJ3ZhbHVlIGhhcyBhIGZyYWN0aW9uYWwgY29tcG9uZW50Jyk7XG59XG5cbmZ1bmN0aW9uIHZlcmlmSUVFRTc1NCh2YWx1ZSwgbWF4LCBtaW4pIHtcbiAgYXNzZXJ0Lm9rKHR5cGVvZiAodmFsdWUpID09ICdudW1iZXInLFxuICAgICAgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKTtcblxuICBhc3NlcnQub2sodmFsdWUgPD0gbWF4LCAndmFsdWUgbGFyZ2VyIHRoYW4gbWF4aW11bSBhbGxvd2VkIHZhbHVlJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlID49IG1pbiwgJ3ZhbHVlIHNtYWxsZXIgdGhhbiBtaW5pbXVtIGFsbG93ZWQgdmFsdWUnKTtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB2YXIgYnVmZmVyID0gdGhpcztcblxuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2YsIC0weDgwKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA+PSAwKSB7XG4gICAgYnVmZmVyLndyaXRlVUludDgodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpO1xuICB9IGVsc2Uge1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KDB4ZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgbm9Bc3NlcnQpO1xuICB9XG59O1xuXG5mdW5jdGlvbiB3cml0ZUludDE2KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmLCAtMHg4MDAwKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA+PSAwKSB7XG4gICAgd3JpdGVVSW50MTYoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICB9IGVsc2Uge1xuICAgIHdyaXRlVUludDE2KGJ1ZmZlciwgMHhmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2TEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxuZnVuY3Rpb24gd3JpdGVJbnQzMihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDMgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA+PSAwKSB7XG4gICAgd3JpdGVVSW50MzIoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICB9IGVsc2Uge1xuICAgIHdyaXRlVUludDMyKGJ1ZmZlciwgMHhmZmZmZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyQkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlRmxvYXQoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAzLjQwMjgyMzQ2NjM4NTI4ODZlKzM4LCAtMy40MDI4MjM0NjYzODUyODg2ZSszOCk7XG4gIH1cblxuICByZXF1aXJlKCcuL2J1ZmZlcl9pZWVlNzU0Jykud3JpdGVJRUVFNzU0KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICAyMywgNCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlRG91YmxlKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgNyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCk7XG4gIH1cblxuICByZXF1aXJlKCcuL2J1ZmZlcl9pZWVlNzU0Jykud3JpdGVJRUVFNzU0KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICA1MiwgOCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlRG91YmxlKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlQkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuIiwiKGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuXHR2YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG5cdGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5KGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyO1xuXHRcblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyAnSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNCc7XG5cdFx0fVxuXG5cdFx0Ly8gdGhlIG51bWJlciBvZiBlcXVhbCBzaWducyAocGxhY2UgaG9sZGVycylcblx0XHQvLyBpZiB0aGVyZSBhcmUgdHdvIHBsYWNlaG9sZGVycywgdGhhbiB0aGUgdHdvIGNoYXJhY3RlcnMgYmVmb3JlIGl0XG5cdFx0Ly8gcmVwcmVzZW50IG9uZSBieXRlXG5cdFx0Ly8gaWYgdGhlcmUgaXMgb25seSBvbmUsIHRoZW4gdGhlIHRocmVlIGNoYXJhY3RlcnMgYmVmb3JlIGl0IHJlcHJlc2VudCAyIGJ5dGVzXG5cdFx0Ly8gdGhpcyBpcyBqdXN0IGEgY2hlYXAgaGFjayB0byBub3QgZG8gaW5kZXhPZiB0d2ljZVxuXHRcdHBsYWNlSG9sZGVycyA9IGI2NC5pbmRleE9mKCc9Jyk7XG5cdFx0cGxhY2VIb2xkZXJzID0gcGxhY2VIb2xkZXJzID4gMCA/IGI2NC5sZW5ndGggLSBwbGFjZUhvbGRlcnMgOiAwO1xuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gW107Ly9uZXcgVWludDhBcnJheShiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpO1xuXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuXHRcdGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoO1xuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGxvb2t1cC5pbmRleE9mKGI2NFtpXSkgPDwgMTgpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMV0pIDw8IDEyKSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDJdKSA8PCA2KSB8IGxvb2t1cC5pbmRleE9mKGI2NFtpICsgM10pO1xuXHRcdFx0YXJyLnB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNik7XG5cdFx0XHRhcnIucHVzaCgodG1wICYgMHhGRjAwKSA+PiA4KTtcblx0XHRcdGFyci5wdXNoKHRtcCAmIDB4RkYpO1xuXHRcdH1cblxuXHRcdGlmIChwbGFjZUhvbGRlcnMgPT09IDIpIHtcblx0XHRcdHRtcCA9IChsb29rdXAuaW5kZXhPZihiNjRbaV0pIDw8IDIpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMV0pID4+IDQpO1xuXHRcdFx0YXJyLnB1c2godG1wICYgMHhGRik7XG5cdFx0fSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcblx0XHRcdHRtcCA9IChsb29rdXAuaW5kZXhPZihiNjRbaV0pIDw8IDEwKSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDFdKSA8PCA0KSB8IChsb29rdXAuaW5kZXhPZihiNjRbaSArIDJdKSA+PiAyKTtcblx0XHRcdGFyci5wdXNoKCh0bXAgPj4gOCkgJiAweEZGKTtcblx0XHRcdGFyci5wdXNoKHRtcCAmIDB4RkYpO1xuXHRcdH1cblxuXHRcdHJldHVybiBhcnI7XG5cdH1cblxuXHRmdW5jdGlvbiB1aW50OFRvQmFzZTY0KHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGg7XG5cblx0XHRmdW5jdGlvbiB0cmlwbGV0VG9CYXNlNjQgKG51bSkge1xuXHRcdFx0cmV0dXJuIGxvb2t1cFtudW0gPj4gMTggJiAweDNGXSArIGxvb2t1cFtudW0gPj4gMTIgJiAweDNGXSArIGxvb2t1cFtudW0gPj4gNiAmIDB4M0ZdICsgbG9va3VwW251bSAmIDB4M0ZdO1xuXHRcdH07XG5cblx0XHQvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG5cdFx0Zm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG5cdFx0XHR0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKTtcblx0XHRcdG91dHB1dCArPSB0cmlwbGV0VG9CYXNlNjQodGVtcCk7XG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbdGVtcCA+PiAyXTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFsodGVtcCA8PCA0KSAmIDB4M0ZdO1xuXHRcdFx0XHRvdXRwdXQgKz0gJz09Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlIDI6XG5cdFx0XHRcdHRlbXAgPSAodWludDhbdWludDgubGVuZ3RoIC0gMl0gPDwgOCkgKyAodWludDhbdWludDgubGVuZ3RoIC0gMV0pO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwW3RlbXAgPj4gMTBdO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwWyh0ZW1wID4+IDQpICYgMHgzRl07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbKHRlbXAgPDwgMikgJiAweDNGXTtcblx0XHRcdFx0b3V0cHV0ICs9ICc9Jztcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdG1vZHVsZS5leHBvcnRzLnRvQnl0ZUFycmF5ID0gYjY0VG9CeXRlQXJyYXk7XG5cdG1vZHVsZS5leHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0O1xufSgpKTtcbiIsInZhciBCdWZmZXIgPSByZXF1aXJlKCdidWZmZXInKS5CdWZmZXI7XG52YXIgaW50U2l6ZSA9IDQ7XG52YXIgemVyb0J1ZmZlciA9IG5ldyBCdWZmZXIoaW50U2l6ZSk7IHplcm9CdWZmZXIuZmlsbCgwKTtcbnZhciBjaHJzeiA9IDg7XG5cbmZ1bmN0aW9uIHRvQXJyYXkoYnVmLCBiaWdFbmRpYW4pIHtcbiAgaWYgKChidWYubGVuZ3RoICUgaW50U2l6ZSkgIT09IDApIHtcbiAgICB2YXIgbGVuID0gYnVmLmxlbmd0aCArIChpbnRTaXplIC0gKGJ1Zi5sZW5ndGggJSBpbnRTaXplKSk7XG4gICAgYnVmID0gQnVmZmVyLmNvbmNhdChbYnVmLCB6ZXJvQnVmZmVyXSwgbGVuKTtcbiAgfVxuXG4gIHZhciBhcnIgPSBbXTtcbiAgdmFyIGZuID0gYmlnRW5kaWFuID8gYnVmLnJlYWRJbnQzMkJFIDogYnVmLnJlYWRJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ1Zi5sZW5ndGg7IGkgKz0gaW50U2l6ZSkge1xuICAgIGFyci5wdXNoKGZuLmNhbGwoYnVmLCBpKSk7XG4gIH1cbiAgcmV0dXJuIGFycjtcbn1cblxuZnVuY3Rpb24gdG9CdWZmZXIoYXJyLCBzaXplLCBiaWdFbmRpYW4pIHtcbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIoc2l6ZSk7XG4gIHZhciBmbiA9IGJpZ0VuZGlhbiA/IGJ1Zi53cml0ZUludDMyQkUgOiBidWYud3JpdGVJbnQzMkxFO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGZuLmNhbGwoYnVmLCBhcnJbaV0sIGkgKiA0LCB0cnVlKTtcbiAgfVxuICByZXR1cm4gYnVmO1xufVxuXG5mdW5jdGlvbiBoYXNoKGJ1ZiwgZm4sIGhhc2hTaXplLCBiaWdFbmRpYW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgYnVmID0gbmV3IEJ1ZmZlcihidWYpO1xuICB2YXIgYXJyID0gZm4odG9BcnJheShidWYsIGJpZ0VuZGlhbiksIGJ1Zi5sZW5ndGggKiBjaHJzeik7XG4gIHJldHVybiB0b0J1ZmZlcihhcnIsIGhhc2hTaXplLCBiaWdFbmRpYW4pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgaGFzaDogaGFzaCB9O1xuIiwidmFyIEJ1ZmZlciA9IHJlcXVpcmUoJ2J1ZmZlcicpLkJ1ZmZlclxudmFyIHNoYSA9IHJlcXVpcmUoJy4vc2hhJylcbnZhciBzaGEyNTYgPSByZXF1aXJlKCcuL3NoYTI1NicpXG52YXIgcm5nID0gcmVxdWlyZSgnLi9ybmcnKVxudmFyIG1kNSA9IHJlcXVpcmUoJy4vbWQ1JylcblxudmFyIGFsZ29yaXRobXMgPSB7XG4gIHNoYTE6IHNoYSxcbiAgc2hhMjU2OiBzaGEyNTYsXG4gIG1kNTogbWQ1XG59XG5cbnZhciBibG9ja3NpemUgPSA2NFxudmFyIHplcm9CdWZmZXIgPSBuZXcgQnVmZmVyKGJsb2Nrc2l6ZSk7IHplcm9CdWZmZXIuZmlsbCgwKVxuZnVuY3Rpb24gaG1hYyhmbiwga2V5LCBkYXRhKSB7XG4gIGlmKCFCdWZmZXIuaXNCdWZmZXIoa2V5KSkga2V5ID0gbmV3IEJ1ZmZlcihrZXkpXG4gIGlmKCFCdWZmZXIuaXNCdWZmZXIoZGF0YSkpIGRhdGEgPSBuZXcgQnVmZmVyKGRhdGEpXG5cbiAgaWYoa2V5Lmxlbmd0aCA+IGJsb2Nrc2l6ZSkge1xuICAgIGtleSA9IGZuKGtleSlcbiAgfSBlbHNlIGlmKGtleS5sZW5ndGggPCBibG9ja3NpemUpIHtcbiAgICBrZXkgPSBCdWZmZXIuY29uY2F0KFtrZXksIHplcm9CdWZmZXJdLCBibG9ja3NpemUpXG4gIH1cblxuICB2YXIgaXBhZCA9IG5ldyBCdWZmZXIoYmxvY2tzaXplKSwgb3BhZCA9IG5ldyBCdWZmZXIoYmxvY2tzaXplKVxuICBmb3IodmFyIGkgPSAwOyBpIDwgYmxvY2tzaXplOyBpKyspIHtcbiAgICBpcGFkW2ldID0ga2V5W2ldIF4gMHgzNlxuICAgIG9wYWRbaV0gPSBrZXlbaV0gXiAweDVDXG4gIH1cblxuICB2YXIgaGFzaCA9IGZuKEJ1ZmZlci5jb25jYXQoW2lwYWQsIGRhdGFdKSlcbiAgcmV0dXJuIGZuKEJ1ZmZlci5jb25jYXQoW29wYWQsIGhhc2hdKSlcbn1cblxuZnVuY3Rpb24gaGFzaChhbGcsIGtleSkge1xuICBhbGcgPSBhbGcgfHwgJ3NoYTEnXG4gIHZhciBmbiA9IGFsZ29yaXRobXNbYWxnXVxuICB2YXIgYnVmcyA9IFtdXG4gIHZhciBsZW5ndGggPSAwXG4gIGlmKCFmbikgZXJyb3IoJ2FsZ29yaXRobTonLCBhbGcsICdpcyBub3QgeWV0IHN1cHBvcnRlZCcpXG4gIHJldHVybiB7XG4gICAgdXBkYXRlOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgaWYoIUJ1ZmZlci5pc0J1ZmZlcihkYXRhKSkgZGF0YSA9IG5ldyBCdWZmZXIoZGF0YSlcbiAgICAgICAgXG4gICAgICBidWZzLnB1c2goZGF0YSlcbiAgICAgIGxlbmd0aCArPSBkYXRhLmxlbmd0aFxuICAgICAgcmV0dXJuIHRoaXNcbiAgICB9LFxuICAgIGRpZ2VzdDogZnVuY3Rpb24gKGVuYykge1xuICAgICAgdmFyIGJ1ZiA9IEJ1ZmZlci5jb25jYXQoYnVmcylcbiAgICAgIHZhciByID0ga2V5ID8gaG1hYyhmbiwga2V5LCBidWYpIDogZm4oYnVmKVxuICAgICAgYnVmcyA9IG51bGxcbiAgICAgIHJldHVybiBlbmMgPyByLnRvU3RyaW5nKGVuYykgOiByXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGVycm9yICgpIHtcbiAgdmFyIG0gPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cykuam9pbignICcpXG4gIHRocm93IG5ldyBFcnJvcihbXG4gICAgbSxcbiAgICAnd2UgYWNjZXB0IHB1bGwgcmVxdWVzdHMnLFxuICAgICdodHRwOi8vZ2l0aHViLmNvbS9kb21pbmljdGFyci9jcnlwdG8tYnJvd3NlcmlmeSdcbiAgICBdLmpvaW4oJ1xcbicpKVxufVxuXG5leHBvcnRzLmNyZWF0ZUhhc2ggPSBmdW5jdGlvbiAoYWxnKSB7IHJldHVybiBoYXNoKGFsZykgfVxuZXhwb3J0cy5jcmVhdGVIbWFjID0gZnVuY3Rpb24gKGFsZywga2V5KSB7IHJldHVybiBoYXNoKGFsZywga2V5KSB9XG5leHBvcnRzLnJhbmRvbUJ5dGVzID0gZnVuY3Rpb24oc2l6ZSwgY2FsbGJhY2spIHtcbiAgaWYgKGNhbGxiYWNrICYmIGNhbGxiYWNrLmNhbGwpIHtcbiAgICB0cnkge1xuICAgICAgY2FsbGJhY2suY2FsbCh0aGlzLCB1bmRlZmluZWQsIG5ldyBCdWZmZXIocm5nKHNpemUpKSlcbiAgICB9IGNhdGNoIChlcnIpIHsgY2FsbGJhY2soZXJyKSB9XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIocm5nKHNpemUpKVxuICB9XG59XG5cbmZ1bmN0aW9uIGVhY2goYSwgZikge1xuICBmb3IodmFyIGkgaW4gYSlcbiAgICBmKGFbaV0sIGkpXG59XG5cbi8vIHRoZSBsZWFzdCBJIGNhbiBkbyBpcyBtYWtlIGVycm9yIG1lc3NhZ2VzIGZvciB0aGUgcmVzdCBvZiB0aGUgbm9kZS5qcy9jcnlwdG8gYXBpLlxuZWFjaChbJ2NyZWF0ZUNyZWRlbnRpYWxzJ1xuLCAnY3JlYXRlQ2lwaGVyJ1xuLCAnY3JlYXRlQ2lwaGVyaXYnXG4sICdjcmVhdGVEZWNpcGhlcidcbiwgJ2NyZWF0ZURlY2lwaGVyaXYnXG4sICdjcmVhdGVTaWduJ1xuLCAnY3JlYXRlVmVyaWZ5J1xuLCAnY3JlYXRlRGlmZmllSGVsbG1hbidcbiwgJ3Bia2RmMiddLCBmdW5jdGlvbiAobmFtZSkge1xuICBleHBvcnRzW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgIGVycm9yKCdzb3JyeSwnLCBuYW1lLCAnaXMgbm90IGltcGxlbWVudGVkIHlldCcpXG4gIH1cbn0pXG4iLCIvKlxyXG4gKiBBIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgdGhlIFJTQSBEYXRhIFNlY3VyaXR5LCBJbmMuIE1ENSBNZXNzYWdlXHJcbiAqIERpZ2VzdCBBbGdvcml0aG0sIGFzIGRlZmluZWQgaW4gUkZDIDEzMjEuXHJcbiAqIFZlcnNpb24gMi4xIENvcHlyaWdodCAoQykgUGF1bCBKb2huc3RvbiAxOTk5IC0gMjAwMi5cclxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxyXG4gKiBEaXN0cmlidXRlZCB1bmRlciB0aGUgQlNEIExpY2Vuc2VcclxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIG1vcmUgaW5mby5cclxuICovXHJcblxyXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xyXG5cclxuLypcclxuICogUGVyZm9ybSBhIHNpbXBsZSBzZWxmLXRlc3QgdG8gc2VlIGlmIHRoZSBWTSBpcyB3b3JraW5nXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfdm1fdGVzdCgpXHJcbntcclxuICByZXR1cm4gaGV4X21kNShcImFiY1wiKSA9PSBcIjkwMDE1MDk4M2NkMjRmYjBkNjk2M2Y3ZDI4ZTE3ZjcyXCI7XHJcbn1cclxuXHJcbi8qXHJcbiAqIENhbGN1bGF0ZSB0aGUgTUQ1IG9mIGFuIGFycmF5IG9mIGxpdHRsZS1lbmRpYW4gd29yZHMsIGFuZCBhIGJpdCBsZW5ndGhcclxuICovXHJcbmZ1bmN0aW9uIGNvcmVfbWQ1KHgsIGxlbilcclxue1xyXG4gIC8qIGFwcGVuZCBwYWRkaW5nICovXHJcbiAgeFtsZW4gPj4gNV0gfD0gMHg4MCA8PCAoKGxlbikgJSAzMik7XHJcbiAgeFsoKChsZW4gKyA2NCkgPj4+IDkpIDw8IDQpICsgMTRdID0gbGVuO1xyXG5cclxuICB2YXIgYSA9ICAxNzMyNTg0MTkzO1xyXG4gIHZhciBiID0gLTI3MTczMzg3OTtcclxuICB2YXIgYyA9IC0xNzMyNTg0MTk0O1xyXG4gIHZhciBkID0gIDI3MTczMzg3ODtcclxuXHJcbiAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyBpICs9IDE2KVxyXG4gIHtcclxuICAgIHZhciBvbGRhID0gYTtcclxuICAgIHZhciBvbGRiID0gYjtcclxuICAgIHZhciBvbGRjID0gYztcclxuICAgIHZhciBvbGRkID0gZDtcclxuXHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgMF0sIDcgLCAtNjgwODc2OTM2KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyAxXSwgMTIsIC0zODk1NjQ1ODYpO1xyXG4gICAgYyA9IG1kNV9mZihjLCBkLCBhLCBiLCB4W2krIDJdLCAxNywgIDYwNjEwNTgxOSk7XHJcbiAgICBiID0gbWQ1X2ZmKGIsIGMsIGQsIGEsIHhbaSsgM10sIDIyLCAtMTA0NDUyNTMzMCk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgNF0sIDcgLCAtMTc2NDE4ODk3KTtcclxuICAgIGQgPSBtZDVfZmYoZCwgYSwgYiwgYywgeFtpKyA1XSwgMTIsICAxMjAwMDgwNDI2KTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTcsIC0xNDczMjMxMzQxKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKyA3XSwgMjIsIC00NTcwNTk4Myk7XHJcbiAgICBhID0gbWQ1X2ZmKGEsIGIsIGMsIGQsIHhbaSsgOF0sIDcgLCAgMTc3MDAzNTQxNik7XHJcbiAgICBkID0gbWQ1X2ZmKGQsIGEsIGIsIGMsIHhbaSsgOV0sIDEyLCAtMTk1ODQxNDQxNyk7XHJcbiAgICBjID0gbWQ1X2ZmKGMsIGQsIGEsIGIsIHhbaSsxMF0sIDE3LCAtNDIwNjMpO1xyXG4gICAgYiA9IG1kNV9mZihiLCBjLCBkLCBhLCB4W2krMTFdLCAyMiwgLTE5OTA0MDQxNjIpO1xyXG4gICAgYSA9IG1kNV9mZihhLCBiLCBjLCBkLCB4W2krMTJdLCA3ICwgIDE4MDQ2MDM2ODIpO1xyXG4gICAgZCA9IG1kNV9mZihkLCBhLCBiLCBjLCB4W2krMTNdLCAxMiwgLTQwMzQxMTAxKTtcclxuICAgIGMgPSBtZDVfZmYoYywgZCwgYSwgYiwgeFtpKzE0XSwgMTcsIC0xNTAyMDAyMjkwKTtcclxuICAgIGIgPSBtZDVfZmYoYiwgYywgZCwgYSwgeFtpKzE1XSwgMjIsICAxMjM2NTM1MzI5KTtcclxuXHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgMV0sIDUgLCAtMTY1Nzk2NTEwKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyA2XSwgOSAsIC0xMDY5NTAxNjMyKTtcclxuICAgIGMgPSBtZDVfZ2coYywgZCwgYSwgYiwgeFtpKzExXSwgMTQsICA2NDM3MTc3MTMpO1xyXG4gICAgYiA9IG1kNV9nZyhiLCBjLCBkLCBhLCB4W2krIDBdLCAyMCwgLTM3Mzg5NzMwMik7XHJcbiAgICBhID0gbWQ1X2dnKGEsIGIsIGMsIGQsIHhbaSsgNV0sIDUgLCAtNzAxNTU4NjkxKTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKzEwXSwgOSAsICAzODAxNjA4Myk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsxNV0sIDE0LCAtNjYwNDc4MzM1KTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA0XSwgMjAsIC00MDU1Mzc4NDgpO1xyXG4gICAgYSA9IG1kNV9nZyhhLCBiLCBjLCBkLCB4W2krIDldLCA1ICwgIDU2ODQ0NjQzOCk7XHJcbiAgICBkID0gbWQ1X2dnKGQsIGEsIGIsIGMsIHhbaSsxNF0sIDkgLCAtMTAxOTgwMzY5MCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgM10sIDE0LCAtMTg3MzYzOTYxKTtcclxuICAgIGIgPSBtZDVfZ2coYiwgYywgZCwgYSwgeFtpKyA4XSwgMjAsICAxMTYzNTMxNTAxKTtcclxuICAgIGEgPSBtZDVfZ2coYSwgYiwgYywgZCwgeFtpKzEzXSwgNSAsIC0xNDQ0NjgxNDY3KTtcclxuICAgIGQgPSBtZDVfZ2coZCwgYSwgYiwgYywgeFtpKyAyXSwgOSAsIC01MTQwMzc4NCk7XHJcbiAgICBjID0gbWQ1X2dnKGMsIGQsIGEsIGIsIHhbaSsgN10sIDE0LCAgMTczNTMyODQ3Myk7XHJcbiAgICBiID0gbWQ1X2dnKGIsIGMsIGQsIGEsIHhbaSsxMl0sIDIwLCAtMTkyNjYwNzczNCk7XHJcblxyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDVdLCA0ICwgLTM3ODU1OCk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsgOF0sIDExLCAtMjAyMjU3NDQ2Myk7XHJcbiAgICBjID0gbWQ1X2hoKGMsIGQsIGEsIGIsIHhbaSsxMV0sIDE2LCAgMTgzOTAzMDU2Mik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxNF0sIDIzLCAtMzUzMDk1NTYpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDFdLCA0ICwgLTE1MzA5OTIwNjApO1xyXG4gICAgZCA9IG1kNV9oaChkLCBhLCBiLCBjLCB4W2krIDRdLCAxMSwgIDEyNzI4OTMzNTMpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDddLCAxNiwgLTE1NTQ5NzYzMik7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsxMF0sIDIzLCAtMTA5NDczMDY0MCk7XHJcbiAgICBhID0gbWQ1X2hoKGEsIGIsIGMsIGQsIHhbaSsxM10sIDQgLCAgNjgxMjc5MTc0KTtcclxuICAgIGQgPSBtZDVfaGgoZCwgYSwgYiwgYywgeFtpKyAwXSwgMTEsIC0zNTg1MzcyMjIpO1xyXG4gICAgYyA9IG1kNV9oaChjLCBkLCBhLCBiLCB4W2krIDNdLCAxNiwgLTcyMjUyMTk3OSk7XHJcbiAgICBiID0gbWQ1X2hoKGIsIGMsIGQsIGEsIHhbaSsgNl0sIDIzLCAgNzYwMjkxODkpO1xyXG4gICAgYSA9IG1kNV9oaChhLCBiLCBjLCBkLCB4W2krIDldLCA0ICwgLTY0MDM2NDQ4Nyk7XHJcbiAgICBkID0gbWQ1X2hoKGQsIGEsIGIsIGMsIHhbaSsxMl0sIDExLCAtNDIxODE1ODM1KTtcclxuICAgIGMgPSBtZDVfaGgoYywgZCwgYSwgYiwgeFtpKzE1XSwgMTYsICA1MzA3NDI1MjApO1xyXG4gICAgYiA9IG1kNV9oaChiLCBjLCBkLCBhLCB4W2krIDJdLCAyMywgLTk5NTMzODY1MSk7XHJcblxyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDBdLCA2ICwgLTE5ODYzMDg0NCk7XHJcbiAgICBkID0gbWQ1X2lpKGQsIGEsIGIsIGMsIHhbaSsgN10sIDEwLCAgMTEyNjg5MTQxNSk7XHJcbiAgICBjID0gbWQ1X2lpKGMsIGQsIGEsIGIsIHhbaSsxNF0sIDE1LCAtMTQxNjM1NDkwNSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgNV0sIDIxLCAtNTc0MzQwNTUpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krMTJdLCA2ICwgIDE3MDA0ODU1NzEpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krIDNdLCAxMCwgLTE4OTQ5ODY2MDYpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krMTBdLCAxNSwgLTEwNTE1MjMpO1xyXG4gICAgYiA9IG1kNV9paShiLCBjLCBkLCBhLCB4W2krIDFdLCAyMSwgLTIwNTQ5MjI3OTkpO1xyXG4gICAgYSA9IG1kNV9paShhLCBiLCBjLCBkLCB4W2krIDhdLCA2ICwgIDE4NzMzMTMzNTkpO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTVdLCAxMCwgLTMwNjExNzQ0KTtcclxuICAgIGMgPSBtZDVfaWkoYywgZCwgYSwgYiwgeFtpKyA2XSwgMTUsIC0xNTYwMTk4MzgwKTtcclxuICAgIGIgPSBtZDVfaWkoYiwgYywgZCwgYSwgeFtpKzEzXSwgMjEsICAxMzA5MTUxNjQ5KTtcclxuICAgIGEgPSBtZDVfaWkoYSwgYiwgYywgZCwgeFtpKyA0XSwgNiAsIC0xNDU1MjMwNzApO1xyXG4gICAgZCA9IG1kNV9paShkLCBhLCBiLCBjLCB4W2krMTFdLCAxMCwgLTExMjAyMTAzNzkpO1xyXG4gICAgYyA9IG1kNV9paShjLCBkLCBhLCBiLCB4W2krIDJdLCAxNSwgIDcxODc4NzI1OSk7XHJcbiAgICBiID0gbWQ1X2lpKGIsIGMsIGQsIGEsIHhbaSsgOV0sIDIxLCAtMzQzNDg1NTUxKTtcclxuXHJcbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XHJcbiAgICBiID0gc2FmZV9hZGQoYiwgb2xkYik7XHJcbiAgICBjID0gc2FmZV9hZGQoYywgb2xkYyk7XHJcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XHJcbiAgfVxyXG4gIHJldHVybiBBcnJheShhLCBiLCBjLCBkKTtcclxuXHJcbn1cclxuXHJcbi8qXHJcbiAqIFRoZXNlIGZ1bmN0aW9ucyBpbXBsZW1lbnQgdGhlIGZvdXIgYmFzaWMgb3BlcmF0aW9ucyB0aGUgYWxnb3JpdGhtIHVzZXMuXHJcbiAqL1xyXG5mdW5jdGlvbiBtZDVfY21uKHEsIGEsIGIsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gc2FmZV9hZGQoYml0X3JvbChzYWZlX2FkZChzYWZlX2FkZChhLCBxKSwgc2FmZV9hZGQoeCwgdCkpLCBzKSxiKTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZmYoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgYykgfCAoKH5iKSAmIGQpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfZ2coYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKChiICYgZCkgfCAoYyAmICh+ZCkpLCBhLCBiLCB4LCBzLCB0KTtcclxufVxyXG5mdW5jdGlvbiBtZDVfaGgoYSwgYiwgYywgZCwgeCwgcywgdClcclxue1xyXG4gIHJldHVybiBtZDVfY21uKGIgXiBjIF4gZCwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuZnVuY3Rpb24gbWQ1X2lpKGEsIGIsIGMsIGQsIHgsIHMsIHQpXHJcbntcclxuICByZXR1cm4gbWQ1X2NtbihjIF4gKGIgfCAofmQpKSwgYSwgYiwgeCwgcywgdCk7XHJcbn1cclxuXHJcbi8qXHJcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zIGludGVybmFsbHlcclxuICogdG8gd29yayBhcm91bmQgYnVncyBpbiBzb21lIEpTIGludGVycHJldGVycy5cclxuICovXHJcbmZ1bmN0aW9uIHNhZmVfYWRkKHgsIHkpXHJcbntcclxuICB2YXIgbHN3ID0gKHggJiAweEZGRkYpICsgKHkgJiAweEZGRkYpO1xyXG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcclxuICByZXR1cm4gKG1zdyA8PCAxNikgfCAobHN3ICYgMHhGRkZGKTtcclxufVxyXG5cclxuLypcclxuICogQml0d2lzZSByb3RhdGUgYSAzMi1iaXQgbnVtYmVyIHRvIHRoZSBsZWZ0LlxyXG4gKi9cclxuZnVuY3Rpb24gYml0X3JvbChudW0sIGNudClcclxue1xyXG4gIHJldHVybiAobnVtIDw8IGNudCkgfCAobnVtID4+PiAoMzIgLSBjbnQpKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBtZDUoYnVmKSB7XHJcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfbWQ1LCAxNik7XHJcbn07XHJcbiIsIi8vIE9yaWdpbmFsIGNvZGUgYWRhcHRlZCBmcm9tIFJvYmVydCBLaWVmZmVyLlxuLy8gZGV0YWlscyBhdCBodHRwczovL2dpdGh1Yi5jb20vYnJvb2ZhL25vZGUtdXVpZFxuKGZ1bmN0aW9uKCkge1xuICB2YXIgX2dsb2JhbCA9IHRoaXM7XG5cbiAgdmFyIG1hdGhSTkcsIHdoYXR3Z1JORztcblxuICAvLyBOT1RFOiBNYXRoLnJhbmRvbSgpIGRvZXMgbm90IGd1YXJhbnRlZSBcImNyeXB0b2dyYXBoaWMgcXVhbGl0eVwiXG4gIG1hdGhSTkcgPSBmdW5jdGlvbihzaXplKSB7XG4gICAgdmFyIGJ5dGVzID0gbmV3IEFycmF5KHNpemUpO1xuICAgIHZhciByO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCBzaXplOyBpKyspIHtcbiAgICAgIGlmICgoaSAmIDB4MDMpID09IDApIHIgPSBNYXRoLnJhbmRvbSgpICogMHgxMDAwMDAwMDA7XG4gICAgICBieXRlc1tpXSA9IHIgPj4+ICgoaSAmIDB4MDMpIDw8IDMpICYgMHhmZjtcbiAgICB9XG5cbiAgICByZXR1cm4gYnl0ZXM7XG4gIH1cblxuICBpZiAoX2dsb2JhbC5jcnlwdG8gJiYgY3J5cHRvLmdldFJhbmRvbVZhbHVlcykge1xuICAgIHdoYXR3Z1JORyA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KHNpemUpO1xuICAgICAgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhieXRlcyk7XG4gICAgICByZXR1cm4gYnl0ZXM7XG4gICAgfVxuICB9XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSB3aGF0d2dSTkcgfHwgbWF0aFJORztcblxufSgpKVxuIiwiLypcbiAqIEEgSmF2YVNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgU2VjdXJlIEhhc2ggQWxnb3JpdGhtLCBTSEEtMSwgYXMgZGVmaW5lZFxuICogaW4gRklQUyBQVUIgMTgwLTFcbiAqIFZlcnNpb24gMi4xYSBDb3B5cmlnaHQgUGF1bCBKb2huc3RvbiAyMDAwIC0gMjAwMi5cbiAqIE90aGVyIGNvbnRyaWJ1dG9yczogR3JlZyBIb2x0LCBBbmRyZXcgS2VwZXJ0LCBZZG5hciwgTG9zdGluZXRcbiAqIERpc3RyaWJ1dGVkIHVuZGVyIHRoZSBCU0QgTGljZW5zZVxuICogU2VlIGh0dHA6Ly9wYWpob21lLm9yZy51ay9jcnlwdC9tZDUgZm9yIGRldGFpbHMuXG4gKi9cblxudmFyIGhlbHBlcnMgPSByZXF1aXJlKCcuL2hlbHBlcnMnKTtcblxuLypcbiAqIENhbGN1bGF0ZSB0aGUgU0hBLTEgb2YgYW4gYXJyYXkgb2YgYmlnLWVuZGlhbiB3b3JkcywgYW5kIGEgYml0IGxlbmd0aFxuICovXG5mdW5jdGlvbiBjb3JlX3NoYTEoeCwgbGVuKVxue1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICB4W2xlbiA+PiA1XSB8PSAweDgwIDw8ICgyNCAtIGxlbiAlIDMyKTtcbiAgeFsoKGxlbiArIDY0ID4+IDkpIDw8IDQpICsgMTVdID0gbGVuO1xuXG4gIHZhciB3ID0gQXJyYXkoODApO1xuICB2YXIgYSA9ICAxNzMyNTg0MTkzO1xuICB2YXIgYiA9IC0yNzE3MzM4Nzk7XG4gIHZhciBjID0gLTE3MzI1ODQxOTQ7XG4gIHZhciBkID0gIDI3MTczMzg3ODtcbiAgdmFyIGUgPSAtMTAwOTU4OTc3NjtcblxuICBmb3IodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7IGkgKz0gMTYpXG4gIHtcbiAgICB2YXIgb2xkYSA9IGE7XG4gICAgdmFyIG9sZGIgPSBiO1xuICAgIHZhciBvbGRjID0gYztcbiAgICB2YXIgb2xkZCA9IGQ7XG4gICAgdmFyIG9sZGUgPSBlO1xuXG4gICAgZm9yKHZhciBqID0gMDsgaiA8IDgwOyBqKyspXG4gICAge1xuICAgICAgaWYoaiA8IDE2KSB3W2pdID0geFtpICsgal07XG4gICAgICBlbHNlIHdbal0gPSByb2wod1tqLTNdIF4gd1tqLThdIF4gd1tqLTE0XSBeIHdbai0xNl0sIDEpO1xuICAgICAgdmFyIHQgPSBzYWZlX2FkZChzYWZlX2FkZChyb2woYSwgNSksIHNoYTFfZnQoaiwgYiwgYywgZCkpLFxuICAgICAgICAgICAgICAgICAgICAgICBzYWZlX2FkZChzYWZlX2FkZChlLCB3W2pdKSwgc2hhMV9rdChqKSkpO1xuICAgICAgZSA9IGQ7XG4gICAgICBkID0gYztcbiAgICAgIGMgPSByb2woYiwgMzApO1xuICAgICAgYiA9IGE7XG4gICAgICBhID0gdDtcbiAgICB9XG5cbiAgICBhID0gc2FmZV9hZGQoYSwgb2xkYSk7XG4gICAgYiA9IHNhZmVfYWRkKGIsIG9sZGIpO1xuICAgIGMgPSBzYWZlX2FkZChjLCBvbGRjKTtcbiAgICBkID0gc2FmZV9hZGQoZCwgb2xkZCk7XG4gICAgZSA9IHNhZmVfYWRkKGUsIG9sZGUpO1xuICB9XG4gIHJldHVybiBBcnJheShhLCBiLCBjLCBkLCBlKTtcblxufVxuXG4vKlxuICogUGVyZm9ybSB0aGUgYXBwcm9wcmlhdGUgdHJpcGxldCBjb21iaW5hdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGN1cnJlbnRcbiAqIGl0ZXJhdGlvblxuICovXG5mdW5jdGlvbiBzaGExX2Z0KHQsIGIsIGMsIGQpXG57XG4gIGlmKHQgPCAyMCkgcmV0dXJuIChiICYgYykgfCAoKH5iKSAmIGQpO1xuICBpZih0IDwgNDApIHJldHVybiBiIF4gYyBeIGQ7XG4gIGlmKHQgPCA2MCkgcmV0dXJuIChiICYgYykgfCAoYiAmIGQpIHwgKGMgJiBkKTtcbiAgcmV0dXJuIGIgXiBjIF4gZDtcbn1cblxuLypcbiAqIERldGVybWluZSB0aGUgYXBwcm9wcmlhdGUgYWRkaXRpdmUgY29uc3RhbnQgZm9yIHRoZSBjdXJyZW50IGl0ZXJhdGlvblxuICovXG5mdW5jdGlvbiBzaGExX2t0KHQpXG57XG4gIHJldHVybiAodCA8IDIwKSA/ICAxNTE4NTAwMjQ5IDogKHQgPCA0MCkgPyAgMTg1OTc3NTM5MyA6XG4gICAgICAgICAodCA8IDYwKSA/IC0xODk0MDA3NTg4IDogLTg5OTQ5NzUxNDtcbn1cblxuLypcbiAqIEFkZCBpbnRlZ2Vycywgd3JhcHBpbmcgYXQgMl4zMi4gVGhpcyB1c2VzIDE2LWJpdCBvcGVyYXRpb25zIGludGVybmFsbHlcbiAqIHRvIHdvcmsgYXJvdW5kIGJ1Z3MgaW4gc29tZSBKUyBpbnRlcnByZXRlcnMuXG4gKi9cbmZ1bmN0aW9uIHNhZmVfYWRkKHgsIHkpXG57XG4gIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRik7XG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG59XG5cbi8qXG4gKiBCaXR3aXNlIHJvdGF0ZSBhIDMyLWJpdCBudW1iZXIgdG8gdGhlIGxlZnQuXG4gKi9cbmZ1bmN0aW9uIHJvbChudW0sIGNudClcbntcbiAgcmV0dXJuIChudW0gPDwgY250KSB8IChudW0gPj4+ICgzMiAtIGNudCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNoYTEoYnVmKSB7XG4gIHJldHVybiBoZWxwZXJzLmhhc2goYnVmLCBjb3JlX3NoYTEsIDIwLCB0cnVlKTtcbn07XG4iLCJcbi8qKlxuICogQSBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIHRoZSBTZWN1cmUgSGFzaCBBbGdvcml0aG0sIFNIQS0yNTYsIGFzIGRlZmluZWRcbiAqIGluIEZJUFMgMTgwLTJcbiAqIFZlcnNpb24gMi4yLWJldGEgQ29weXJpZ2h0IEFuZ2VsIE1hcmluLCBQYXVsIEpvaG5zdG9uIDIwMDAgLSAyMDA5LlxuICogT3RoZXIgY29udHJpYnV0b3JzOiBHcmVnIEhvbHQsIEFuZHJldyBLZXBlcnQsIFlkbmFyLCBMb3N0aW5ldFxuICpcbiAqL1xuXG52YXIgaGVscGVycyA9IHJlcXVpcmUoJy4vaGVscGVycycpO1xuXG52YXIgc2FmZV9hZGQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHZhciBsc3cgPSAoeCAmIDB4RkZGRikgKyAoeSAmIDB4RkZGRik7XG4gIHZhciBtc3cgPSAoeCA+PiAxNikgKyAoeSA+PiAxNikgKyAobHN3ID4+IDE2KTtcbiAgcmV0dXJuIChtc3cgPDwgMTYpIHwgKGxzdyAmIDB4RkZGRik7XG59O1xuXG52YXIgUyA9IGZ1bmN0aW9uKFgsIG4pIHtcbiAgcmV0dXJuIChYID4+PiBuKSB8IChYIDw8ICgzMiAtIG4pKTtcbn07XG5cbnZhciBSID0gZnVuY3Rpb24oWCwgbikge1xuICByZXR1cm4gKFggPj4+IG4pO1xufTtcblxudmFyIENoID0gZnVuY3Rpb24oeCwgeSwgeikge1xuICByZXR1cm4gKCh4ICYgeSkgXiAoKH54KSAmIHopKTtcbn07XG5cbnZhciBNYWogPSBmdW5jdGlvbih4LCB5LCB6KSB7XG4gIHJldHVybiAoKHggJiB5KSBeICh4ICYgeikgXiAoeSAmIHopKTtcbn07XG5cbnZhciBTaWdtYTAyNTYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiAoUyh4LCAyKSBeIFMoeCwgMTMpIF4gUyh4LCAyMikpO1xufTtcblxudmFyIFNpZ21hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDYpIF4gUyh4LCAxMSkgXiBTKHgsIDI1KSk7XG59O1xuXG52YXIgR2FtbWEwMjU2ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gKFMoeCwgNykgXiBTKHgsIDE4KSBeIFIoeCwgMykpO1xufTtcblxudmFyIEdhbW1hMTI1NiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIChTKHgsIDE3KSBeIFMoeCwgMTkpIF4gUih4LCAxMCkpO1xufTtcblxudmFyIGNvcmVfc2hhMjU2ID0gZnVuY3Rpb24obSwgbCkge1xuICB2YXIgSyA9IG5ldyBBcnJheSgweDQyOEEyRjk4LDB4NzEzNzQ0OTEsMHhCNUMwRkJDRiwweEU5QjVEQkE1LDB4Mzk1NkMyNUIsMHg1OUYxMTFGMSwweDkyM0Y4MkE0LDB4QUIxQzVFRDUsMHhEODA3QUE5OCwweDEyODM1QjAxLDB4MjQzMTg1QkUsMHg1NTBDN0RDMywweDcyQkU1RDc0LDB4ODBERUIxRkUsMHg5QkRDMDZBNywweEMxOUJGMTc0LDB4RTQ5QjY5QzEsMHhFRkJFNDc4NiwweEZDMTlEQzYsMHgyNDBDQTFDQywweDJERTkyQzZGLDB4NEE3NDg0QUEsMHg1Q0IwQTlEQywweDc2Rjk4OERBLDB4OTgzRTUxNTIsMHhBODMxQzY2RCwweEIwMDMyN0M4LDB4QkY1OTdGQzcsMHhDNkUwMEJGMywweEQ1QTc5MTQ3LDB4NkNBNjM1MSwweDE0MjkyOTY3LDB4MjdCNzBBODUsMHgyRTFCMjEzOCwweDREMkM2REZDLDB4NTMzODBEMTMsMHg2NTBBNzM1NCwweDc2NkEwQUJCLDB4ODFDMkM5MkUsMHg5MjcyMkM4NSwweEEyQkZFOEExLDB4QTgxQTY2NEIsMHhDMjRCOEI3MCwweEM3NkM1MUEzLDB4RDE5MkU4MTksMHhENjk5MDYyNCwweEY0MEUzNTg1LDB4MTA2QUEwNzAsMHgxOUE0QzExNiwweDFFMzc2QzA4LDB4Mjc0ODc3NEMsMHgzNEIwQkNCNSwweDM5MUMwQ0IzLDB4NEVEOEFBNEEsMHg1QjlDQ0E0RiwweDY4MkU2RkYzLDB4NzQ4RjgyRUUsMHg3OEE1NjM2RiwweDg0Qzg3ODE0LDB4OENDNzAyMDgsMHg5MEJFRkZGQSwweEE0NTA2Q0VCLDB4QkVGOUEzRjcsMHhDNjcxNzhGMik7XG4gIHZhciBIQVNIID0gbmV3IEFycmF5KDB4NkEwOUU2NjcsIDB4QkI2N0FFODUsIDB4M0M2RUYzNzIsIDB4QTU0RkY1M0EsIDB4NTEwRTUyN0YsIDB4OUIwNTY4OEMsIDB4MUY4M0Q5QUIsIDB4NUJFMENEMTkpO1xuICAgIHZhciBXID0gbmV3IEFycmF5KDY0KTtcbiAgICB2YXIgYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSwgajtcbiAgICB2YXIgVDEsIFQyO1xuICAvKiBhcHBlbmQgcGFkZGluZyAqL1xuICBtW2wgPj4gNV0gfD0gMHg4MCA8PCAoMjQgLSBsICUgMzIpO1xuICBtWygobCArIDY0ID4+IDkpIDw8IDQpICsgMTVdID0gbDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBtLmxlbmd0aDsgaSArPSAxNikge1xuICAgIGEgPSBIQVNIWzBdOyBiID0gSEFTSFsxXTsgYyA9IEhBU0hbMl07IGQgPSBIQVNIWzNdOyBlID0gSEFTSFs0XTsgZiA9IEhBU0hbNV07IGcgPSBIQVNIWzZdOyBoID0gSEFTSFs3XTtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IDY0OyBqKyspIHtcbiAgICAgIGlmIChqIDwgMTYpIHtcbiAgICAgICAgV1tqXSA9IG1baiArIGldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgV1tqXSA9IHNhZmVfYWRkKHNhZmVfYWRkKHNhZmVfYWRkKEdhbW1hMTI1NihXW2ogLSAyXSksIFdbaiAtIDddKSwgR2FtbWEwMjU2KFdbaiAtIDE1XSkpLCBXW2ogLSAxNl0pO1xuICAgICAgfVxuICAgICAgVDEgPSBzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChzYWZlX2FkZChoLCBTaWdtYTEyNTYoZSkpLCBDaChlLCBmLCBnKSksIEtbal0pLCBXW2pdKTtcbiAgICAgIFQyID0gc2FmZV9hZGQoU2lnbWEwMjU2KGEpLCBNYWooYSwgYiwgYykpO1xuICAgICAgaCA9IGc7IGcgPSBmOyBmID0gZTsgZSA9IHNhZmVfYWRkKGQsIFQxKTsgZCA9IGM7IGMgPSBiOyBiID0gYTsgYSA9IHNhZmVfYWRkKFQxLCBUMik7XG4gICAgfVxuICAgIEhBU0hbMF0gPSBzYWZlX2FkZChhLCBIQVNIWzBdKTsgSEFTSFsxXSA9IHNhZmVfYWRkKGIsIEhBU0hbMV0pOyBIQVNIWzJdID0gc2FmZV9hZGQoYywgSEFTSFsyXSk7IEhBU0hbM10gPSBzYWZlX2FkZChkLCBIQVNIWzNdKTtcbiAgICBIQVNIWzRdID0gc2FmZV9hZGQoZSwgSEFTSFs0XSk7IEhBU0hbNV0gPSBzYWZlX2FkZChmLCBIQVNIWzVdKTsgSEFTSFs2XSA9IHNhZmVfYWRkKGcsIEhBU0hbNl0pOyBIQVNIWzddID0gc2FmZV9hZGQoaCwgSEFTSFs3XSk7XG4gIH1cbiAgcmV0dXJuIEhBU0g7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHNoYTI1NihidWYpIHtcbiAgcmV0dXJuIGhlbHBlcnMuaGFzaChidWYsIGNvcmVfc2hhMjU2LCAzMiwgdHJ1ZSk7XG59O1xuIiwidmFyIGh0dHAgPSBtb2R1bGUuZXhwb3J0cztcbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXI7XG52YXIgUmVxdWVzdCA9IHJlcXVpcmUoJy4vbGliL3JlcXVlc3QnKTtcblxuaHR0cC5yZXF1ZXN0ID0gZnVuY3Rpb24gKHBhcmFtcywgY2IpIHtcbiAgICBpZiAoIXBhcmFtcykgcGFyYW1zID0ge307XG4gICAgaWYgKCFwYXJhbXMuaG9zdCAmJiAhcGFyYW1zLnBvcnQpIHtcbiAgICAgICAgcGFyYW1zLnBvcnQgPSBwYXJzZUludCh3aW5kb3cubG9jYXRpb24ucG9ydCwgMTApO1xuICAgIH1cbiAgICBpZiAoIXBhcmFtcy5ob3N0KSBwYXJhbXMuaG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZTtcbiAgICBpZiAoIXBhcmFtcy5wb3J0KSBwYXJhbXMucG9ydCA9IDgwO1xuICAgIGlmICghcGFyYW1zLnNjaGVtZSkgcGFyYW1zLnNjaGVtZSA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbC5zcGxpdCgnOicpWzBdO1xuICAgIFxuICAgIHZhciByZXEgPSBuZXcgUmVxdWVzdChuZXcgeGhySHR0cCwgcGFyYW1zKTtcbiAgICBpZiAoY2IpIHJlcS5vbigncmVzcG9uc2UnLCBjYik7XG4gICAgcmV0dXJuIHJlcTtcbn07XG5cbmh0dHAuZ2V0ID0gZnVuY3Rpb24gKHBhcmFtcywgY2IpIHtcbiAgICBwYXJhbXMubWV0aG9kID0gJ0dFVCc7XG4gICAgdmFyIHJlcSA9IGh0dHAucmVxdWVzdChwYXJhbXMsIGNiKTtcbiAgICByZXEuZW5kKCk7XG4gICAgcmV0dXJuIHJlcTtcbn07XG5cbmh0dHAuQWdlbnQgPSBmdW5jdGlvbiAoKSB7fTtcbmh0dHAuQWdlbnQuZGVmYXVsdE1heFNvY2tldHMgPSA0O1xuXG52YXIgeGhySHR0cCA9IChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignbm8gd2luZG93IG9iamVjdCBwcmVzZW50Jyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHdpbmRvdy5YTUxIdHRwUmVxdWVzdCkge1xuICAgICAgICByZXR1cm4gd2luZG93LlhNTEh0dHBSZXF1ZXN0O1xuICAgIH1cbiAgICBlbHNlIGlmICh3aW5kb3cuQWN0aXZlWE9iamVjdCkge1xuICAgICAgICB2YXIgYXhzID0gW1xuICAgICAgICAgICAgJ01zeG1sMi5YTUxIVFRQLjYuMCcsXG4gICAgICAgICAgICAnTXN4bWwyLlhNTEhUVFAuMy4wJyxcbiAgICAgICAgICAgICdNaWNyb3NvZnQuWE1MSFRUUCdcbiAgICAgICAgXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBheHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdmFyIGF4ID0gbmV3KHdpbmRvdy5BY3RpdmVYT2JqZWN0KShheHNbaV0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChheCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF4XyA9IGF4O1xuICAgICAgICAgICAgICAgICAgICAgICAgYXggPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF4XztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcod2luZG93LkFjdGl2ZVhPYmplY3QpKGF4c1tpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHt9XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhamF4IG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYWpheCBub3Qgc3VwcG9ydGVkIGluIHRoaXMgYnJvd3NlcicpO1xuICAgIH1cbn0pKCk7XG4iLCJ2YXIgU3RyZWFtID0gcmVxdWlyZSgnc3RyZWFtJyk7XG52YXIgUmVzcG9uc2UgPSByZXF1aXJlKCcuL3Jlc3BvbnNlJyk7XG52YXIgY29uY2F0U3RyZWFtID0gcmVxdWlyZSgnY29uY2F0LXN0cmVhbScpO1xudmFyIEJhc2U2NCA9IHJlcXVpcmUoJ0Jhc2U2NCcpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnZhciBSZXF1ZXN0ID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoeGhyLCBwYXJhbXMpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgc2VsZi54aHIgPSB4aHI7XG4gICAgc2VsZi5ib2R5ID0gY29uY2F0U3RyZWFtKClcbiAgICBcbiAgICB2YXIgdXJpID0gcGFyYW1zLmhvc3RcbiAgICAgICAgKyAocGFyYW1zLnBvcnQgPyAnOicgKyBwYXJhbXMucG9ydCA6ICcnKVxuICAgICAgICArIChwYXJhbXMucGF0aCB8fCAnLycpXG4gICAgO1xuICAgIFxuICAgIHhoci5vcGVuKFxuICAgICAgICBwYXJhbXMubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICAocGFyYW1zLnNjaGVtZSB8fCAnaHR0cCcpICsgJzovLycgKyB1cmksXG4gICAgICAgIHRydWVcbiAgICApO1xuICAgIFxuICAgIGlmIChwYXJhbXMuaGVhZGVycykge1xuICAgICAgICB2YXIga2V5cyA9IG9iamVjdEtleXMocGFyYW1zLmhlYWRlcnMpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBrZXkgPSBrZXlzW2ldO1xuICAgICAgICAgICAgaWYgKCFzZWxmLmlzU2FmZVJlcXVlc3RIZWFkZXIoa2V5KSkgY29udGludWU7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBwYXJhbXMuaGVhZGVyc1trZXldO1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWx1ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlW2pdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHhoci5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsdWUpXG4gICAgICAgIH1cbiAgICB9XG4gICAgXG4gICAgaWYgKHBhcmFtcy5hdXRoKSB7XG4gICAgICAgIC8vYmFzaWMgYXV0aFxuICAgICAgICB0aGlzLnNldEhlYWRlcignQXV0aG9yaXphdGlvbicsICdCYXNpYyAnICsgQmFzZTY0LmJ0b2EocGFyYW1zLmF1dGgpKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzID0gbmV3IFJlc3BvbnNlO1xuICAgIHJlcy5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgICB9KTtcbiAgICBcbiAgICByZXMub24oJ3JlYWR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLmVtaXQoJ3Jlc3BvbnNlJywgcmVzKTtcbiAgICB9KTtcbiAgICBcbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXMuaGFuZGxlKHhocik7XG4gICAgfTtcbn07XG5cbnV0aWwuaW5oZXJpdHMoUmVxdWVzdCwgU3RyZWFtKTtcblxuUmVxdWVzdC5wcm90b3R5cGUuc2V0SGVhZGVyID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdGhpcy54aHIuc2V0UmVxdWVzdEhlYWRlcihrZXksIHZhbHVlKTtcbiAgICB9XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChzKSB7XG4gICAgdGhpcy5ib2R5LndyaXRlKHMpO1xufTtcblxuUmVxdWVzdC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzKSB7XG4gICAgdGhpcy54aHIuYWJvcnQoKTtcbiAgICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5lbmQgPSBmdW5jdGlvbiAocykge1xuICAgIGlmIChzICE9PSB1bmRlZmluZWQpIHRoaXMuYm9keS53cml0ZShzKTtcbiAgICB0aGlzLmJvZHkuZW5kKClcbiAgICB0aGlzLnhoci5zZW5kKHRoaXMuYm9keS5nZXRCb2R5KCkpO1xufTtcblxuLy8gVGFrZW4gZnJvbSBodHRwOi8vZHhyLm1vemlsbGEub3JnL21vemlsbGEvbW96aWxsYS1jZW50cmFsL2NvbnRlbnQvYmFzZS9zcmMvbnNYTUxIdHRwUmVxdWVzdC5jcHAuaHRtbFxuUmVxdWVzdC51bnNhZmVIZWFkZXJzID0gW1xuICAgIFwiYWNjZXB0LWNoYXJzZXRcIixcbiAgICBcImFjY2VwdC1lbmNvZGluZ1wiLFxuICAgIFwiYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1oZWFkZXJzXCIsXG4gICAgXCJhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LW1ldGhvZFwiLFxuICAgIFwiY29ubmVjdGlvblwiLFxuICAgIFwiY29udGVudC1sZW5ndGhcIixcbiAgICBcImNvb2tpZVwiLFxuICAgIFwiY29va2llMlwiLFxuICAgIFwiY29udGVudC10cmFuc2Zlci1lbmNvZGluZ1wiLFxuICAgIFwiZGF0ZVwiLFxuICAgIFwiZXhwZWN0XCIsXG4gICAgXCJob3N0XCIsXG4gICAgXCJrZWVwLWFsaXZlXCIsXG4gICAgXCJvcmlnaW5cIixcbiAgICBcInJlZmVyZXJcIixcbiAgICBcInRlXCIsXG4gICAgXCJ0cmFpbGVyXCIsXG4gICAgXCJ0cmFuc2Zlci1lbmNvZGluZ1wiLFxuICAgIFwidXBncmFkZVwiLFxuICAgIFwidXNlci1hZ2VudFwiLFxuICAgIFwidmlhXCJcbl07XG5cblJlcXVlc3QucHJvdG90eXBlLmlzU2FmZVJlcXVlc3RIZWFkZXIgPSBmdW5jdGlvbiAoaGVhZGVyTmFtZSkge1xuICAgIGlmICghaGVhZGVyTmFtZSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBpbmRleE9mKFJlcXVlc3QudW5zYWZlSGVhZGVycywgaGVhZGVyTmFtZS50b0xvd2VyQ2FzZSgpKSA9PT0gLTE7XG59O1xuXG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGluZGV4T2YgPSBmdW5jdGlvbiAoeHMsIHgpIHtcbiAgICBpZiAoeHMuaW5kZXhPZikgcmV0dXJuIHhzLmluZGV4T2YoeCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoeHNbaV0gPT09IHgpIHJldHVybiBpO1xuICAgIH1cbiAgICByZXR1cm4gLTE7XG59O1xuIiwidmFyIFN0cmVhbSA9IHJlcXVpcmUoJ3N0cmVhbScpO1xudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG5cbnZhciBSZXNwb25zZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHJlcykge1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgICB0aGlzLnJlYWRhYmxlID0gdHJ1ZTtcbn07XG5cbnV0aWwuaW5oZXJpdHMoUmVzcG9uc2UsIFN0cmVhbSk7XG5cbnZhciBjYXBhYmxlID0ge1xuICAgIHN0cmVhbWluZyA6IHRydWUsXG4gICAgc3RhdHVzMiA6IHRydWVcbn07XG5cbmZ1bmN0aW9uIHBhcnNlSGVhZGVycyAocmVzKSB7XG4gICAgdmFyIGxpbmVzID0gcmVzLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLnNwbGl0KC9cXHI/XFxuLyk7XG4gICAgdmFyIGhlYWRlcnMgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZXNbaV07XG4gICAgICAgIGlmIChsaW5lID09PSAnJykgY29udGludWU7XG4gICAgICAgIFxuICAgICAgICB2YXIgbSA9IGxpbmUubWF0Y2goL14oW146XSspOlxccyooLiopLyk7XG4gICAgICAgIGlmIChtKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0gbVsxXS50b0xvd2VyQ2FzZSgpLCB2YWx1ZSA9IG1bMl07XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChoZWFkZXJzW2tleV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkoaGVhZGVyc1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0ucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0gPSBbIGhlYWRlcnNba2V5XSwgdmFsdWUgXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBoZWFkZXJzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGhlYWRlcnNbbGluZV0gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBoZWFkZXJzO1xufVxuXG5SZXNwb25zZS5wcm90b3R5cGUuZ2V0UmVzcG9uc2UgPSBmdW5jdGlvbiAoeGhyKSB7XG4gICAgdmFyIHJlc3BUeXBlID0gU3RyaW5nKHhoci5yZXNwb25zZVR5cGUpLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKHJlc3BUeXBlID09PSAnYmxvYicpIHJldHVybiB4aHIucmVzcG9uc2VCbG9iIHx8IHhoci5yZXNwb25zZTtcbiAgICBpZiAocmVzcFR5cGUgPT09ICdhcnJheWJ1ZmZlcicpIHJldHVybiB4aHIucmVzcG9uc2U7XG4gICAgcmV0dXJuIHhoci5yZXNwb25zZVRleHQ7XG59XG5cblJlc3BvbnNlLnByb3RvdHlwZS5nZXRIZWFkZXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuaGVhZGVyc1trZXkudG9Mb3dlckNhc2UoKV07XG59O1xuXG5SZXNwb25zZS5wcm90b3R5cGUuaGFuZGxlID0gZnVuY3Rpb24gKHJlcykge1xuICAgIGlmIChyZXMucmVhZHlTdGF0ZSA9PT0gMiAmJiBjYXBhYmxlLnN0YXR1czIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHJlcy5zdGF0dXM7XG4gICAgICAgICAgICB0aGlzLmhlYWRlcnMgPSBwYXJzZUhlYWRlcnMocmVzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjYXBhYmxlLnN0YXR1czIgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYgKGNhcGFibGUuc3RhdHVzMikge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGNhcGFibGUuc3RyZWFtaW5nICYmIHJlcy5yZWFkeVN0YXRlID09PSAzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhdHVzQ29kZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzQ29kZSA9IHJlcy5zdGF0dXM7XG4gICAgICAgICAgICAgICAgdGhpcy5oZWFkZXJzID0gcGFyc2VIZWFkZXJzKHJlcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHt9XG4gICAgICAgIFxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdGhpcy5fZW1pdERhdGEocmVzKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBjYXBhYmxlLnN0cmVhbWluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlcy5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgIGlmICghdGhpcy5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXR1c0NvZGUgPSByZXMuc3RhdHVzO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdyZWFkeScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2VtaXREYXRhKHJlcyk7XG4gICAgICAgIFxuICAgICAgICBpZiAocmVzLmVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgdGhpcy5nZXRSZXNwb25zZShyZXMpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIFxuICAgICAgICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG4gICAgfVxufTtcblxuUmVzcG9uc2UucHJvdG90eXBlLl9lbWl0RGF0YSA9IGZ1bmN0aW9uIChyZXMpIHtcbiAgICB2YXIgcmVzcEJvZHkgPSB0aGlzLmdldFJlc3BvbnNlKHJlcyk7XG4gICAgaWYgKHJlc3BCb2R5LnRvU3RyaW5nKCkubWF0Y2goL0FycmF5QnVmZmVyLykpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgbmV3IFVpbnQ4QXJyYXkocmVzcEJvZHksIHRoaXMub2Zmc2V0KSk7XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gcmVzcEJvZHkuYnl0ZUxlbmd0aDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAocmVzcEJvZHkubGVuZ3RoID4gdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgcmVzcEJvZHkuc2xpY2UodGhpcy5vZmZzZXQpKTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSByZXNwQm9keS5sZW5ndGg7XG4gICAgfVxufTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcbiIsIjsoZnVuY3Rpb24gKCkge1xuXG4gIHZhclxuICAgIG9iamVjdCA9IHR5cGVvZiBleHBvcnRzICE9ICd1bmRlZmluZWQnID8gZXhwb3J0cyA6IHRoaXMsIC8vICM4OiB3ZWIgd29ya2Vyc1xuICAgIGNoYXJzID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JyxcbiAgICBJTlZBTElEX0NIQVJBQ1RFUl9FUlIgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgLy8gZmFicmljYXRlIGEgc3VpdGFibGUgZXJyb3Igb2JqZWN0XG4gICAgICB0cnkgeyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCckJyk7IH1cbiAgICAgIGNhdGNoIChlcnJvcikgeyByZXR1cm4gZXJyb3I7IH19KCkpO1xuXG4gIC8vIGVuY29kZXJcbiAgLy8gW2h0dHBzOi8vZ2lzdC5naXRodWIuY29tLzk5OTE2Nl0gYnkgW2h0dHBzOi8vZ2l0aHViLmNvbS9uaWduYWddXG4gIG9iamVjdC5idG9hIHx8IChcbiAgb2JqZWN0LmJ0b2EgPSBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICBmb3IgKFxuICAgICAgLy8gaW5pdGlhbGl6ZSByZXN1bHQgYW5kIGNvdW50ZXJcbiAgICAgIHZhciBibG9jaywgY2hhckNvZGUsIGlkeCA9IDAsIG1hcCA9IGNoYXJzLCBvdXRwdXQgPSAnJztcbiAgICAgIC8vIGlmIHRoZSBuZXh0IGlucHV0IGluZGV4IGRvZXMgbm90IGV4aXN0OlxuICAgICAgLy8gICBjaGFuZ2UgdGhlIG1hcHBpbmcgdGFibGUgdG8gXCI9XCJcbiAgICAgIC8vICAgY2hlY2sgaWYgZCBoYXMgbm8gZnJhY3Rpb25hbCBkaWdpdHNcbiAgICAgIGlucHV0LmNoYXJBdChpZHggfCAwKSB8fCAobWFwID0gJz0nLCBpZHggJSAxKTtcbiAgICAgIC8vIFwiOCAtIGlkeCAlIDEgKiA4XCIgZ2VuZXJhdGVzIHRoZSBzZXF1ZW5jZSAyLCA0LCA2LCA4XG4gICAgICBvdXRwdXQgKz0gbWFwLmNoYXJBdCg2MyAmIGJsb2NrID4+IDggLSBpZHggJSAxICogOClcbiAgICApIHtcbiAgICAgIGNoYXJDb2RlID0gaW5wdXQuY2hhckNvZGVBdChpZHggKz0gMy80KTtcbiAgICAgIGlmIChjaGFyQ29kZSA+IDB4RkYpIHRocm93IElOVkFMSURfQ0hBUkFDVEVSX0VSUjtcbiAgICAgIGJsb2NrID0gYmxvY2sgPDwgOCB8IGNoYXJDb2RlO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9KTtcblxuICAvLyBkZWNvZGVyXG4gIC8vIFtodHRwczovL2dpc3QuZ2l0aHViLmNvbS8xMDIwMzk2XSBieSBbaHR0cHM6Ly9naXRodWIuY29tL2F0a11cbiAgb2JqZWN0LmF0b2IgfHwgKFxuICBvYmplY3QuYXRvYiA9IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvPSskLywgJycpXG4gICAgaWYgKGlucHV0Lmxlbmd0aCAlIDQgPT0gMSkgdGhyb3cgSU5WQUxJRF9DSEFSQUNURVJfRVJSO1xuICAgIGZvciAoXG4gICAgICAvLyBpbml0aWFsaXplIHJlc3VsdCBhbmQgY291bnRlcnNcbiAgICAgIHZhciBiYyA9IDAsIGJzLCBidWZmZXIsIGlkeCA9IDAsIG91dHB1dCA9ICcnO1xuICAgICAgLy8gZ2V0IG5leHQgY2hhcmFjdGVyXG4gICAgICBidWZmZXIgPSBpbnB1dC5jaGFyQXQoaWR4KyspO1xuICAgICAgLy8gY2hhcmFjdGVyIGZvdW5kIGluIHRhYmxlPyBpbml0aWFsaXplIGJpdCBzdG9yYWdlIGFuZCBhZGQgaXRzIGFzY2lpIHZhbHVlO1xuICAgICAgfmJ1ZmZlciAmJiAoYnMgPSBiYyAlIDQgPyBicyAqIDY0ICsgYnVmZmVyIDogYnVmZmVyLFxuICAgICAgICAvLyBhbmQgaWYgbm90IGZpcnN0IG9mIGVhY2ggNCBjaGFyYWN0ZXJzLFxuICAgICAgICAvLyBjb252ZXJ0IHRoZSBmaXJzdCA4IGJpdHMgdG8gb25lIGFzY2lpIGNoYXJhY3RlclxuICAgICAgICBiYysrICUgNCkgPyBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgyNTUgJiBicyA+PiAoLTIgKiBiYyAmIDYpKSA6IDBcbiAgICApIHtcbiAgICAgIC8vIHRyeSB0byBmaW5kIGNoYXJhY3RlciBpbiB0YWJsZSAoMC02Mywgbm90IGZvdW5kID0+IC0xKVxuICAgICAgYnVmZmVyID0gY2hhcnMuaW5kZXhPZihidWZmZXIpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9KTtcblxufSgpKTtcbiIsInZhciBzdHJlYW0gPSByZXF1aXJlKCdzdHJlYW0nKVxudmFyIGJvcHMgPSByZXF1aXJlKCdib3BzJylcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbCcpXG5cbmZ1bmN0aW9uIENvbmNhdFN0cmVhbShjYikge1xuICBzdHJlYW0uU3RyZWFtLmNhbGwodGhpcylcbiAgdGhpcy53cml0YWJsZSA9IHRydWVcbiAgaWYgKGNiKSB0aGlzLmNiID0gY2JcbiAgdGhpcy5ib2R5ID0gW11cbiAgdGhpcy5vbignZXJyb3InLCBmdW5jdGlvbihlcnIpIHtcbiAgICAvLyBuby1vcFxuICB9KVxufVxuXG51dGlsLmluaGVyaXRzKENvbmNhdFN0cmVhbSwgc3RyZWFtLlN0cmVhbSlcblxuQ29uY2F0U3RyZWFtLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGNodW5rKSB7XG4gIHRoaXMuYm9keS5wdXNoKGNodW5rKVxufVxuXG5Db25jYXRTdHJlYW0ucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHt9XG5cbkNvbmNhdFN0cmVhbS5wcm90b3R5cGUuYXJyYXlDb25jYXQgPSBmdW5jdGlvbihhcnJzKSB7XG4gIGlmIChhcnJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdXG4gIGlmIChhcnJzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGFycnNbMF1cbiAgcmV0dXJuIGFycnMucmVkdWNlKGZ1bmN0aW9uIChhLCBiKSB7IHJldHVybiBhLmNvbmNhdChiKSB9KVxufVxuXG5Db25jYXRTdHJlYW0ucHJvdG90eXBlLmlzQXJyYXkgPSBmdW5jdGlvbihhcnIpIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYXJyKVxufVxuXG5Db25jYXRTdHJlYW0ucHJvdG90eXBlLmdldEJvZHkgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmJvZHkubGVuZ3RoID09PSAwKSByZXR1cm5cbiAgaWYgKHR5cGVvZih0aGlzLmJvZHlbMF0pID09PSBcInN0cmluZ1wiKSByZXR1cm4gdGhpcy5ib2R5LmpvaW4oJycpXG4gIGlmICh0aGlzLmlzQXJyYXkodGhpcy5ib2R5WzBdKSkgcmV0dXJuIHRoaXMuYXJyYXlDb25jYXQodGhpcy5ib2R5KVxuICBpZiAoYm9wcy5pcyh0aGlzLmJvZHlbMF0pKSByZXR1cm4gYm9wcy5qb2luKHRoaXMuYm9keSlcbiAgcmV0dXJuIHRoaXMuYm9keVxufVxuXG5Db25jYXRTdHJlYW0ucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5jYikgdGhpcy5jYih0aGlzLmdldEJvZHkoKSlcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihjYikge1xuICByZXR1cm4gbmV3IENvbmNhdFN0cmVhbShjYilcbn1cblxubW9kdWxlLmV4cG9ydHMuQ29uY2F0U3RyZWFtID0gQ29uY2F0U3RyZWFtXG4iLCJ2YXIgcHJvdG8gPSB7fVxubW9kdWxlLmV4cG9ydHMgPSBwcm90b1xuXG5wcm90by5mcm9tID0gcmVxdWlyZSgnLi9mcm9tLmpzJylcbnByb3RvLnRvID0gcmVxdWlyZSgnLi90by5qcycpXG5wcm90by5pcyA9IHJlcXVpcmUoJy4vaXMuanMnKVxucHJvdG8uc3ViYXJyYXkgPSByZXF1aXJlKCcuL3N1YmFycmF5LmpzJylcbnByb3RvLmpvaW4gPSByZXF1aXJlKCcuL2pvaW4uanMnKVxucHJvdG8uY29weSA9IHJlcXVpcmUoJy4vY29weS5qcycpXG5wcm90by5jcmVhdGUgPSByZXF1aXJlKCcuL2NyZWF0ZS5qcycpXG5cbm1peChyZXF1aXJlKCcuL3JlYWQuanMnKSwgcHJvdG8pXG5taXgocmVxdWlyZSgnLi93cml0ZS5qcycpLCBwcm90bylcblxuZnVuY3Rpb24gbWl4KGZyb20sIGludG8pIHtcbiAgZm9yKHZhciBrZXkgaW4gZnJvbSkge1xuICAgIGludG9ba2V5XSA9IGZyb21ba2V5XVxuICB9XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHRvX3V0ZjhcblxudmFyIG91dCA9IFtdXG4gICwgY29sID0gW11cbiAgLCBmY2MgPSBTdHJpbmcuZnJvbUNoYXJDb2RlXG4gICwgbWFzayA9IFsweDQwLCAweDIwLCAweDEwLCAweDA4LCAweDA0LCAweDAyLCAweDAxXVxuICAsIHVubWFzayA9IFtcbiAgICAgIDB4MDBcbiAgICAsIDB4MDFcbiAgICAsIDB4MDIgfCAweDAxXG4gICAgLCAweDA0IHwgMHgwMiB8IDB4MDFcbiAgICAsIDB4MDggfCAweDA0IHwgMHgwMiB8IDB4MDFcbiAgICAsIDB4MTAgfCAweDA4IHwgMHgwNCB8IDB4MDIgfCAweDAxXG4gICAgLCAweDIwIHwgMHgxMCB8IDB4MDggfCAweDA0IHwgMHgwMiB8IDB4MDFcbiAgICAsIDB4NDAgfCAweDIwIHwgMHgxMCB8IDB4MDggfCAweDA0IHwgMHgwMiB8IDB4MDFcbiAgXVxuXG5mdW5jdGlvbiB0b191dGY4KGJ5dGVzLCBzdGFydCwgZW5kKSB7XG4gIHN0YXJ0ID0gc3RhcnQgPT09IHVuZGVmaW5lZCA/IDAgOiBzdGFydFxuICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGJ5dGVzLmxlbmd0aCA6IGVuZFxuXG4gIHZhciBpZHggPSAwXG4gICAgLCBoaSA9IDB4ODBcbiAgICAsIGNvbGxlY3RpbmcgPSAwXG4gICAgLCBwb3NcbiAgICAsIGJ5XG5cbiAgY29sLmxlbmd0aCA9XG4gIG91dC5sZW5ndGggPSAwXG5cbiAgd2hpbGUoaWR4IDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgYnkgPSBieXRlc1tpZHhdXG4gICAgaWYoIWNvbGxlY3RpbmcgJiYgYnkgJiBoaSkge1xuICAgICAgcG9zID0gZmluZF9wYWRfcG9zaXRpb24oYnkpXG4gICAgICBjb2xsZWN0aW5nICs9IHBvc1xuICAgICAgaWYocG9zIDwgOCkge1xuICAgICAgICBjb2xbY29sLmxlbmd0aF0gPSBieSAmIHVubWFza1s2IC0gcG9zXVxuICAgICAgfVxuICAgIH0gZWxzZSBpZihjb2xsZWN0aW5nKSB7XG4gICAgICBjb2xbY29sLmxlbmd0aF0gPSBieSAmIHVubWFza1s2XVxuICAgICAgLS1jb2xsZWN0aW5nXG4gICAgICBpZighY29sbGVjdGluZyAmJiBjb2wubGVuZ3RoKSB7XG4gICAgICAgIG91dFtvdXQubGVuZ3RoXSA9IGZjYyhyZWR1Y2VkKGNvbCwgcG9zKSlcbiAgICAgICAgY29sLmxlbmd0aCA9IDBcbiAgICAgIH1cbiAgICB9IGVsc2UgeyBcbiAgICAgIG91dFtvdXQubGVuZ3RoXSA9IGZjYyhieSlcbiAgICB9XG4gICAgKytpZHhcbiAgfVxuICBpZihjb2wubGVuZ3RoICYmICFjb2xsZWN0aW5nKSB7XG4gICAgb3V0W291dC5sZW5ndGhdID0gZmNjKHJlZHVjZWQoY29sLCBwb3MpKVxuICAgIGNvbC5sZW5ndGggPSAwXG4gIH1cbiAgcmV0dXJuIG91dC5qb2luKCcnKVxufVxuXG5mdW5jdGlvbiBmaW5kX3BhZF9wb3NpdGlvbihieXQpIHtcbiAgZm9yKHZhciBpID0gMDsgaSA8IDc7ICsraSkge1xuICAgIGlmKCEoYnl0ICYgbWFza1tpXSkpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIHJlZHVjZWQobGlzdCkge1xuICB2YXIgb3V0ID0gMFxuICBmb3IodmFyIGkgPSAwLCBsZW4gPSBsaXN0Lmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgb3V0IHw9IGxpc3RbaV0gPDwgKChsZW4gLSBpIC0gMSkgKiA2KVxuICB9XG4gIHJldHVybiBvdXRcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gY29weVxuXG52YXIgc2xpY2UgPSBbXS5zbGljZVxuXG5mdW5jdGlvbiBjb3B5KHNvdXJjZSwgdGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHNvdXJjZV9zdGFydCwgc291cmNlX2VuZCkge1xuICB0YXJnZXRfc3RhcnQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IDAgOiB0YXJnZXRfc3RhcnRcbiAgc291cmNlX3N0YXJ0ID0gYXJndW1lbnRzLmxlbmd0aCA8IDQgPyAwIDogc291cmNlX3N0YXJ0XG4gIHNvdXJjZV9lbmQgPSBhcmd1bWVudHMubGVuZ3RoIDwgNSA/IHNvdXJjZS5sZW5ndGggOiBzb3VyY2VfZW5kXG5cbiAgaWYoc291cmNlX2VuZCA9PT0gc291cmNlX3N0YXJ0KSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBpZih0YXJnZXQubGVuZ3RoID09PSAwIHx8IHNvdXJjZS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmKHNvdXJjZV9lbmQgPiBzb3VyY2UubGVuZ3RoKSB7XG4gICAgc291cmNlX2VuZCA9IHNvdXJjZS5sZW5ndGhcbiAgfVxuXG4gIGlmKHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgPCBzb3VyY2VfZW5kIC0gc291cmNlX3N0YXJ0KSB7XG4gICAgc291cmNlX2VuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgKyBzdGFydFxuICB9XG5cbiAgaWYoc291cmNlLmJ1ZmZlciAhPT0gdGFyZ2V0LmJ1ZmZlcikge1xuICAgIHJldHVybiBmYXN0X2NvcHkoc291cmNlLCB0YXJnZXQsIHRhcmdldF9zdGFydCwgc291cmNlX3N0YXJ0LCBzb3VyY2VfZW5kKVxuICB9XG4gIHJldHVybiBzbG93X2NvcHkoc291cmNlLCB0YXJnZXQsIHRhcmdldF9zdGFydCwgc291cmNlX3N0YXJ0LCBzb3VyY2VfZW5kKVxufVxuXG5mdW5jdGlvbiBmYXN0X2NvcHkoc291cmNlLCB0YXJnZXQsIHRhcmdldF9zdGFydCwgc291cmNlX3N0YXJ0LCBzb3VyY2VfZW5kKSB7XG4gIHZhciBsZW4gPSAoc291cmNlX2VuZCAtIHNvdXJjZV9zdGFydCkgKyB0YXJnZXRfc3RhcnRcblxuICBmb3IodmFyIGkgPSB0YXJnZXRfc3RhcnQsIGogPSBzb3VyY2Vfc3RhcnQ7XG4gICAgICBpIDwgbGVuO1xuICAgICAgKytpLFxuICAgICAgKytqKSB7XG4gICAgdGFyZ2V0W2ldID0gc291cmNlW2pdXG4gIH1cbn1cblxuZnVuY3Rpb24gc2xvd19jb3B5KGZyb20sIHRvLCBqLCBpLCBqZW5kKSB7XG4gIC8vIHRoZSBidWZmZXJzIGNvdWxkIG92ZXJsYXAuXG4gIHZhciBpZW5kID0gamVuZCArIGlcbiAgICAsIHRtcCA9IG5ldyBVaW50OEFycmF5KHNsaWNlLmNhbGwoZnJvbSwgaSwgaWVuZCkpXG4gICAgLCB4ID0gMFxuXG4gIGZvcig7IGkgPCBpZW5kOyArK2ksICsreCkge1xuICAgIHRvW2orK10gPSB0bXBbeF1cbiAgfVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihzaXplKSB7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShzaXplKVxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBmcm9tXG5cbnZhciBiYXNlNjQgPSByZXF1aXJlKCdiYXNlNjQtanMnKVxuXG52YXIgZGVjb2RlcnMgPSB7XG4gICAgaGV4OiBmcm9tX2hleFxuICAsIHV0Zjg6IGZyb21fdXRmXG4gICwgYmFzZTY0OiBmcm9tX2Jhc2U2NFxufVxuXG5mdW5jdGlvbiBmcm9tKHNvdXJjZSwgZW5jb2RpbmcpIHtcbiAgaWYoQXJyYXkuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHNvdXJjZSlcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVyc1tlbmNvZGluZyB8fCAndXRmOCddKHNvdXJjZSlcbn1cblxuZnVuY3Rpb24gZnJvbV9oZXgoc3RyKSB7XG4gIHZhciBzaXplID0gc3RyLmxlbmd0aCAvIDJcbiAgICAsIGJ1ZiA9IG5ldyBVaW50OEFycmF5KHNpemUpXG4gICAgLCBjaGFyYWN0ZXIgPSAnJ1xuXG4gIGZvcih2YXIgaSA9IDAsIGxlbiA9IHN0ci5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIGNoYXJhY3RlciArPSBzdHIuY2hhckF0KGkpXG5cbiAgICBpZihpID4gMCAmJiAoaSAlIDIpID09PSAxKSB7XG4gICAgICBidWZbaT4+PjFdID0gcGFyc2VJbnQoY2hhcmFjdGVyLCAxNilcbiAgICAgIGNoYXJhY3RlciA9ICcnIFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgXG59XG5cbmZ1bmN0aW9uIGZyb21fdXRmKHN0cikge1xuICB2YXIgYnl0ZXMgPSBbXVxuICAgICwgdG1wXG4gICAgLCBjaFxuXG4gIGZvcih2YXIgaSA9IDAsIGxlbiA9IHN0ci5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgIGNoID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBpZihjaCAmIDB4ODApIHtcbiAgICAgIHRtcCA9IGVuY29kZVVSSUNvbXBvbmVudChzdHIuY2hhckF0KGkpKS5zdWJzdHIoMSkuc3BsaXQoJyUnKVxuICAgICAgZm9yKHZhciBqID0gMCwgamxlbiA9IHRtcC5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcbiAgICAgICAgYnl0ZXNbYnl0ZXMubGVuZ3RoXSA9IHBhcnNlSW50KHRtcFtqXSwgMTYpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ5dGVzW2J5dGVzLmxlbmd0aF0gPSBjaCBcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpXG59XG5cbmZ1bmN0aW9uIGZyb21fYmFzZTY0KHN0cikge1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYmFzZTY0LnRvQnl0ZUFycmF5KHN0cikpIFxufVxuIiwiXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICByZXR1cm4gYnVmZmVyIGluc3RhbmNlb2YgVWludDhBcnJheTtcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gam9pblxuXG5mdW5jdGlvbiBqb2luKHRhcmdldHMsIGhpbnQpIHtcbiAgaWYoIXRhcmdldHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KDApXG4gIH1cblxuICB2YXIgbGVuID0gaGludCAhPT0gdW5kZWZpbmVkID8gaGludCA6IGdldF9sZW5ndGgodGFyZ2V0cylcbiAgICAsIG91dCA9IG5ldyBVaW50OEFycmF5KGxlbilcbiAgICAsIGN1ciA9IHRhcmdldHNbMF1cbiAgICAsIGN1cmxlbiA9IGN1ci5sZW5ndGhcbiAgICAsIGN1cmlkeCA9IDBcbiAgICAsIGN1cm9mZiA9IDBcbiAgICAsIGkgPSAwXG5cbiAgd2hpbGUoaSA8IGxlbikge1xuICAgIGlmKGN1cm9mZiA9PT0gY3VybGVuKSB7XG4gICAgICBjdXJvZmYgPSAwXG4gICAgICArK2N1cmlkeFxuICAgICAgY3VyID0gdGFyZ2V0c1tjdXJpZHhdXG4gICAgICBjdXJsZW4gPSBjdXIgJiYgY3VyLmxlbmd0aFxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgb3V0W2krK10gPSBjdXJbY3Vyb2ZmKytdIFxuICB9XG5cbiAgcmV0dXJuIG91dFxufVxuXG5mdW5jdGlvbiBnZXRfbGVuZ3RoKHRhcmdldHMpIHtcbiAgdmFyIHNpemUgPSAwXG4gIGZvcih2YXIgaSA9IDAsIGxlbiA9IHRhcmdldHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICBzaXplICs9IHRhcmdldHNbaV0uYnl0ZUxlbmd0aFxuICB9XG4gIHJldHVybiBzaXplXG59XG4iLCJ2YXIgcHJvdG9cbiAgLCBtYXBcblxubW9kdWxlLmV4cG9ydHMgPSBwcm90byA9IHt9XG5cbm1hcCA9IHR5cGVvZiBXZWFrTWFwID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiBuZXcgV2Vha01hcFxuXG5wcm90by5nZXQgPSAhbWFwID8gbm9fd2Vha21hcF9nZXQgOiBnZXRcblxuZnVuY3Rpb24gbm9fd2Vha21hcF9nZXQodGFyZ2V0KSB7XG4gIHJldHVybiBuZXcgRGF0YVZpZXcodGFyZ2V0LmJ1ZmZlciwgMClcbn1cblxuZnVuY3Rpb24gZ2V0KHRhcmdldCkge1xuICB2YXIgb3V0ID0gbWFwLmdldCh0YXJnZXQuYnVmZmVyKVxuICBpZighb3V0KSB7XG4gICAgbWFwLnNldCh0YXJnZXQuYnVmZmVyLCBvdXQgPSBuZXcgRGF0YVZpZXcodGFyZ2V0LmJ1ZmZlciwgMCkpXG4gIH1cbiAgcmV0dXJuIG91dFxufVxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgcmVhZFVJbnQ4OiAgICAgIHJlYWRfdWludDhcbiAgLCByZWFkSW50ODogICAgICAgcmVhZF9pbnQ4XG4gICwgcmVhZFVJbnQxNkxFOiAgIHJlYWRfdWludDE2X2xlXG4gICwgcmVhZFVJbnQzMkxFOiAgIHJlYWRfdWludDMyX2xlXG4gICwgcmVhZEludDE2TEU6ICAgIHJlYWRfaW50MTZfbGVcbiAgLCByZWFkSW50MzJMRTogICAgcmVhZF9pbnQzMl9sZVxuICAsIHJlYWRGbG9hdExFOiAgICByZWFkX2Zsb2F0X2xlXG4gICwgcmVhZERvdWJsZUxFOiAgIHJlYWRfZG91YmxlX2xlXG4gICwgcmVhZFVJbnQxNkJFOiAgIHJlYWRfdWludDE2X2JlXG4gICwgcmVhZFVJbnQzMkJFOiAgIHJlYWRfdWludDMyX2JlXG4gICwgcmVhZEludDE2QkU6ICAgIHJlYWRfaW50MTZfYmVcbiAgLCByZWFkSW50MzJCRTogICAgcmVhZF9pbnQzMl9iZVxuICAsIHJlYWRGbG9hdEJFOiAgICByZWFkX2Zsb2F0X2JlXG4gICwgcmVhZERvdWJsZUJFOiAgIHJlYWRfZG91YmxlX2JlXG59XG5cbnZhciBtYXAgPSByZXF1aXJlKCcuL21hcHBlZC5qcycpXG5cbmZ1bmN0aW9uIHJlYWRfdWludDgodGFyZ2V0LCBhdCkge1xuICByZXR1cm4gdGFyZ2V0W2F0XVxufVxuXG5mdW5jdGlvbiByZWFkX2ludDgodGFyZ2V0LCBhdCkge1xuICB2YXIgdiA9IHRhcmdldFthdF07XG4gIHJldHVybiB2IDwgMHg4MCA/IHYgOiB2IC0gMHgxMDBcbn1cblxuZnVuY3Rpb24gcmVhZF91aW50MTZfbGUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRVaW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gcmVhZF91aW50MzJfbGUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRVaW50MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gcmVhZF9pbnQxNl9sZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEludDE2KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHJlYWRfaW50MzJfbGUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRJbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB0cnVlKVxufVxuXG5mdW5jdGlvbiByZWFkX2Zsb2F0X2xlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0RmxvYXQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB0cnVlKVxufVxuXG5mdW5jdGlvbiByZWFkX2RvdWJsZV9sZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEZsb2F0NjQoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gcmVhZF91aW50MTZfYmUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRVaW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHJlYWRfdWludDMyX2JlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0VWludDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiByZWFkX2ludDE2X2JlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0SW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHJlYWRfaW50MzJfYmUodGFyZ2V0LCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5nZXRJbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gcmVhZF9mbG9hdF9iZSh0YXJnZXQsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LmdldEZsb2F0MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHJlYWRfZG91YmxlX2JlKHRhcmdldCwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuZ2V0RmxvYXQ2NChhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCBmYWxzZSlcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gc3ViYXJyYXlcblxuZnVuY3Rpb24gc3ViYXJyYXkoYnVmLCBmcm9tLCB0bykge1xuICByZXR1cm4gYnVmLnN1YmFycmF5KGZyb20gfHwgMCwgdG8gfHwgYnVmLmxlbmd0aClcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gdG9cblxudmFyIGJhc2U2NCA9IHJlcXVpcmUoJ2Jhc2U2NC1qcycpXG4gICwgdG91dGY4ID0gcmVxdWlyZSgndG8tdXRmOCcpXG5cbnZhciBlbmNvZGVycyA9IHtcbiAgICBoZXg6IHRvX2hleFxuICAsIHV0Zjg6IHRvX3V0ZlxuICAsIGJhc2U2NDogdG9fYmFzZTY0XG59XG5cbmZ1bmN0aW9uIHRvKGJ1ZiwgZW5jb2RpbmcpIHtcbiAgcmV0dXJuIGVuY29kZXJzW2VuY29kaW5nIHx8ICd1dGY4J10oYnVmKVxufVxuXG5mdW5jdGlvbiB0b19oZXgoYnVmKSB7XG4gIHZhciBzdHIgPSAnJ1xuICAgICwgYnl0XG5cbiAgZm9yKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgYnl0ID0gYnVmW2ldXG4gICAgc3RyICs9ICgoYnl0ICYgMHhGMCkgPj4+IDQpLnRvU3RyaW5nKDE2KVxuICAgIHN0ciArPSAoYnl0ICYgMHgwRikudG9TdHJpbmcoMTYpXG4gIH1cblxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHRvX3V0ZihidWYpIHtcbiAgcmV0dXJuIHRvdXRmOChidWYpXG59XG5cbmZ1bmN0aW9uIHRvX2Jhc2U2NChidWYpIHtcbiAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zilcbn1cblxuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgd3JpdGVVSW50ODogICAgICB3cml0ZV91aW50OFxuICAsIHdyaXRlSW50ODogICAgICAgd3JpdGVfaW50OFxuICAsIHdyaXRlVUludDE2TEU6ICAgd3JpdGVfdWludDE2X2xlXG4gICwgd3JpdGVVSW50MzJMRTogICB3cml0ZV91aW50MzJfbGVcbiAgLCB3cml0ZUludDE2TEU6ICAgIHdyaXRlX2ludDE2X2xlXG4gICwgd3JpdGVJbnQzMkxFOiAgICB3cml0ZV9pbnQzMl9sZVxuICAsIHdyaXRlRmxvYXRMRTogICAgd3JpdGVfZmxvYXRfbGVcbiAgLCB3cml0ZURvdWJsZUxFOiAgIHdyaXRlX2RvdWJsZV9sZVxuICAsIHdyaXRlVUludDE2QkU6ICAgd3JpdGVfdWludDE2X2JlXG4gICwgd3JpdGVVSW50MzJCRTogICB3cml0ZV91aW50MzJfYmVcbiAgLCB3cml0ZUludDE2QkU6ICAgIHdyaXRlX2ludDE2X2JlXG4gICwgd3JpdGVJbnQzMkJFOiAgICB3cml0ZV9pbnQzMl9iZVxuICAsIHdyaXRlRmxvYXRCRTogICAgd3JpdGVfZmxvYXRfYmVcbiAgLCB3cml0ZURvdWJsZUJFOiAgIHdyaXRlX2RvdWJsZV9iZVxufVxuXG52YXIgbWFwID0gcmVxdWlyZSgnLi9tYXBwZWQuanMnKVxuXG5mdW5jdGlvbiB3cml0ZV91aW50OCh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICByZXR1cm4gdGFyZ2V0W2F0XSA9IHZhbHVlXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2ludDgodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgcmV0dXJuIHRhcmdldFthdF0gPSB2YWx1ZSA8IDAgPyB2YWx1ZSArIDB4MTAwIDogdmFsdWVcbn1cblxuZnVuY3Rpb24gd3JpdGVfdWludDE2X2xlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldFVpbnQxNihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfdWludDMyX2xlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldFVpbnQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfaW50MTZfbGUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0SW50MTYoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIHRydWUpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2ludDMyX2xlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldEludDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCB0cnVlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9mbG9hdF9sZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRGbG9hdDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCB0cnVlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9kb3VibGVfbGUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0RmxvYXQ2NChhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgdHJ1ZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfdWludDE2X2JlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldFVpbnQxNihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX3VpbnQzMl9iZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRVaW50MzIoYXQgKyB0YXJnZXQuYnl0ZU9mZnNldCwgdmFsdWUsIGZhbHNlKVxufVxuXG5mdW5jdGlvbiB3cml0ZV9pbnQxNl9iZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRJbnQxNihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2ludDMyX2JlKHRhcmdldCwgdmFsdWUsIGF0KSB7XG4gIHZhciBkdiA9IG1hcC5nZXQodGFyZ2V0KTtcbiAgcmV0dXJuIGR2LnNldEludDMyKGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCBmYWxzZSlcbn1cblxuZnVuY3Rpb24gd3JpdGVfZmxvYXRfYmUodGFyZ2V0LCB2YWx1ZSwgYXQpIHtcbiAgdmFyIGR2ID0gbWFwLmdldCh0YXJnZXQpO1xuICByZXR1cm4gZHYuc2V0RmxvYXQzMihhdCArIHRhcmdldC5ieXRlT2Zmc2V0LCB2YWx1ZSwgZmFsc2UpXG59XG5cbmZ1bmN0aW9uIHdyaXRlX2RvdWJsZV9iZSh0YXJnZXQsIHZhbHVlLCBhdCkge1xuICB2YXIgZHYgPSBtYXAuZ2V0KHRhcmdldCk7XG4gIHJldHVybiBkdi5zZXRGbG9hdDY0KGF0ICsgdGFyZ2V0LmJ5dGVPZmZzZXQsIHZhbHVlLCBmYWxzZSlcbn1cbiIsInJlcXVpcmU9KGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpfXZhciBmPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChmLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGYsZi5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkoezE6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuZXhwb3J0cy5yZWFkSUVFRTc1NCA9IGZ1bmN0aW9uKGJ1ZmZlciwgb2Zmc2V0LCBpc0JFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgbkJpdHMgPSAtNyxcbiAgICAgIGkgPSBpc0JFID8gMCA6IChuQnl0ZXMgLSAxKSxcbiAgICAgIGQgPSBpc0JFID8gMSA6IC0xLFxuICAgICAgcyA9IGJ1ZmZlcltvZmZzZXQgKyBpXTtcblxuICBpICs9IGQ7XG5cbiAgZSA9IHMgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIHMgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBlTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBtID0gZSAmICgoMSA8PCAoLW5CaXRzKSkgLSAxKTtcbiAgZSA+Pj0gKC1uQml0cyk7XG4gIG5CaXRzICs9IG1MZW47XG4gIGZvciAoOyBuQml0cyA+IDA7IG0gPSBtICogMjU2ICsgYnVmZmVyW29mZnNldCArIGldLCBpICs9IGQsIG5CaXRzIC09IDgpO1xuXG4gIGlmIChlID09PSAwKSB7XG4gICAgZSA9IDEgLSBlQmlhcztcbiAgfSBlbHNlIGlmIChlID09PSBlTWF4KSB7XG4gICAgcmV0dXJuIG0gPyBOYU4gOiAoKHMgPyAtMSA6IDEpICogSW5maW5pdHkpO1xuICB9IGVsc2Uge1xuICAgIG0gPSBtICsgTWF0aC5wb3coMiwgbUxlbik7XG4gICAgZSA9IGUgLSBlQmlhcztcbiAgfVxuICByZXR1cm4gKHMgPyAtMSA6IDEpICogbSAqIE1hdGgucG93KDIsIGUgLSBtTGVuKTtcbn07XG5cbmV4cG9ydHMud3JpdGVJRUVFNzU0ID0gZnVuY3Rpb24oYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGMsXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxuICAgICAgaSA9IGlzQkUgPyAobkJ5dGVzIC0gMSkgOiAwLFxuICAgICAgZCA9IGlzQkUgPyAtMSA6IDEsXG4gICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrO1xuICAgICAgYyAvPSAyO1xuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcblxuICBlID0gKGUgPDwgbUxlbikgfCBtO1xuICBlTGVuICs9IG1MZW47XG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xufTtcblxufSx7fV0sXCJxOVR4Q0NcIjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG52YXIgYXNzZXJ0O1xuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXI7XG5leHBvcnRzLlNsb3dCdWZmZXIgPSBCdWZmZXI7XG5CdWZmZXIucG9vbFNpemUgPSA4MTkyO1xuZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUyA9IDUwO1xuXG5mdW5jdGlvbiBzdHJpbmd0cmltKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpO1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbn1cblxuZnVuY3Rpb24gQnVmZmVyKHN1YmplY3QsIGVuY29kaW5nLCBvZmZzZXQpIHtcbiAgaWYoIWFzc2VydCkgYXNzZXJ0PSByZXF1aXJlKCdhc3NlcnQnKTtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgb2Zmc2V0KTtcbiAgfVxuICB0aGlzLnBhcmVudCA9IHRoaXM7XG4gIHRoaXMub2Zmc2V0ID0gMDtcblxuICAvLyBXb3JrLWFyb3VuZDogbm9kZSdzIGJhc2U2NCBpbXBsZW1lbnRhdGlvblxuICAvLyBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgc3RyaW5ncyB3aGlsZSBiYXNlNjQtanNcbiAgLy8gZG9lcyBub3QuLlxuICBpZiAoZW5jb2RpbmcgPT0gXCJiYXNlNjRcIiAmJiB0eXBlb2Ygc3ViamVjdCA9PSBcInN0cmluZ1wiKSB7XG4gICAgc3ViamVjdCA9IHN0cmluZ3RyaW0oc3ViamVjdCk7XG4gICAgd2hpbGUgKHN1YmplY3QubGVuZ3RoICUgNCAhPSAwKSB7XG4gICAgICBzdWJqZWN0ID0gc3ViamVjdCArIFwiPVwiOyBcbiAgICB9XG4gIH1cblxuICB2YXIgdHlwZTtcblxuICAvLyBBcmUgd2Ugc2xpY2luZz9cbiAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdudW1iZXInKSB7XG4gICAgdGhpcy5sZW5ndGggPSBjb2VyY2UoZW5jb2RpbmcpO1xuICAgIC8vIHNsaWNpbmcgd29ya3MsIHdpdGggbGltaXRhdGlvbnMgKG5vIHBhcmVudCB0cmFja2luZy91cGRhdGUpXG4gICAgLy8gY2hlY2sgaHR0cHM6Ly9naXRodWIuY29tL3Rvb3RzL2J1ZmZlci1icm93c2VyaWZ5L2lzc3Vlcy8xOVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB0aGlzW2ldID0gc3ViamVjdC5nZXQoaStvZmZzZXQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBGaW5kIHRoZSBsZW5ndGhcbiAgICBzd2l0Y2ggKHR5cGUgPSB0eXBlb2Ygc3ViamVjdCkge1xuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgdGhpcy5sZW5ndGggPSBjb2VyY2Uoc3ViamVjdCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICB0aGlzLmxlbmd0aCA9IEJ1ZmZlci5ieXRlTGVuZ3RoKHN1YmplY3QsIGVuY29kaW5nKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ29iamVjdCc6IC8vIEFzc3VtZSBvYmplY3QgaXMgYW4gYXJyYXlcbiAgICAgICAgdGhpcy5sZW5ndGggPSBjb2VyY2Uoc3ViamVjdC5sZW5ndGgpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCBuZWVkcyB0byBiZSBhIG51bWJlciwgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAnYXJyYXkgb3Igc3RyaW5nLicpO1xuICAgIH1cblxuICAgIC8vIFRyZWF0IGFycmF5LWlzaCBvYmplY3RzIGFzIGEgYnl0ZSBhcnJheS5cbiAgICBpZiAoaXNBcnJheUlzaChzdWJqZWN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzdWJqZWN0IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgICAgdGhpc1tpXSA9IHN1YmplY3QucmVhZFVJbnQ4KGkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHRoaXNbaV0gPSBzdWJqZWN0W2ldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0eXBlID09ICdzdHJpbmcnKSB7XG4gICAgICAvLyBXZSBhcmUgYSBzdHJpbmdcbiAgICAgIHRoaXMubGVuZ3RoID0gdGhpcy53cml0ZShzdWJqZWN0LCAwLCBlbmNvZGluZyk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXNbaV0gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIGdldChpKSB7XG4gIGlmIChpIDwgMCB8fCBpID49IHRoaXMubGVuZ3RoKSB0aHJvdyBuZXcgRXJyb3IoJ29vYicpO1xuICByZXR1cm4gdGhpc1tpXTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gc2V0KGksIHYpIHtcbiAgaWYgKGkgPCAwIHx8IGkgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBFcnJvcignb29iJyk7XG4gIHJldHVybiB0aGlzW2ldID0gdjtcbn07XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gKHN0ciwgZW5jb2RpbmcpIHtcbiAgc3dpdGNoIChlbmNvZGluZyB8fCBcInV0ZjhcIikge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXR1cm4gc3RyLmxlbmd0aCAvIDI7XG5cbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXR1cm4gdXRmOFRvQnl0ZXMoc3RyKS5sZW5ndGg7XG5cbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldHVybiBzdHIubGVuZ3RoO1xuXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldHVybiBiYXNlNjRUb0J5dGVzKHN0cikubGVuZ3RoO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpO1xuICB9XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnV0ZjhXcml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBieXRlcywgcG9zO1xuICByZXR1cm4gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSAgYmxpdEJ1ZmZlcih1dGY4VG9CeXRlcyhzdHJpbmcpLCB0aGlzLCBvZmZzZXQsIGxlbmd0aCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLmFzY2lpV3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgYnl0ZXMsIHBvcztcbiAgcmV0dXJuIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIHRoaXMsIG9mZnNldCwgbGVuZ3RoKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmluYXJ5V3JpdGUgPSBCdWZmZXIucHJvdG90eXBlLmFzY2lpV3JpdGU7XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmFzZTY0V3JpdGUgPSBmdW5jdGlvbiAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgYnl0ZXMsIHBvcztcbiAgcmV0dXJuIEJ1ZmZlci5fY2hhcnNXcml0dGVuID0gYmxpdEJ1ZmZlcihiYXNlNjRUb0J5dGVzKHN0cmluZyksIHRoaXMsIG9mZnNldCwgbGVuZ3RoKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUuYmFzZTY0U2xpY2UgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKVxuICByZXR1cm4gcmVxdWlyZShcImJhc2U2NC1qc1wiKS5mcm9tQnl0ZUFycmF5KGJ5dGVzKTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUudXRmOFNsaWNlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYnl0ZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgdmFyIHJlcyA9IFwiXCI7XG4gIHZhciB0bXAgPSBcIlwiO1xuICB2YXIgaSA9IDA7XG4gIHdoaWxlIChpIDwgYnl0ZXMubGVuZ3RoKSB7XG4gICAgaWYgKGJ5dGVzW2ldIDw9IDB4N0YpIHtcbiAgICAgIHJlcyArPSBkZWNvZGVVdGY4Q2hhcih0bXApICsgU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7XG4gICAgICB0bXAgPSBcIlwiO1xuICAgIH0gZWxzZVxuICAgICAgdG1wICs9IFwiJVwiICsgYnl0ZXNbaV0udG9TdHJpbmcoMTYpO1xuXG4gICAgaSsrO1xuICB9XG5cbiAgcmV0dXJuIHJlcyArIGRlY29kZVV0ZjhDaGFyKHRtcCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuYXNjaWlTbGljZSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGJ5dGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIHZhciByZXQgPSBcIlwiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5dGVzLmxlbmd0aDsgaSsrKVxuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKTtcbiAgcmV0dXJuIHJldDtcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5iaW5hcnlTbGljZSA9IEJ1ZmZlci5wcm90b3R5cGUuYXNjaWlTbGljZTtcblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBvdXQgPSBbXSxcbiAgICAgIGxlbiA9IHRoaXMubGVuZ3RoO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gdG9IZXgodGhpc1tpXSk7XG4gICAgaWYgKGkgPT0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUykge1xuICAgICAgb3V0W2kgKyAxXSA9ICcuLi4nO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiAnPEJ1ZmZlciAnICsgb3V0LmpvaW4oJyAnKSArICc+Jztcbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS5oZXhTbGljZSA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IHRoaXMubGVuZ3RoO1xuXG4gIGlmICghc3RhcnQgfHwgc3RhcnQgPCAwKSBzdGFydCA9IDA7XG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW47XG5cbiAgdmFyIG91dCA9ICcnO1xuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIG91dCArPSB0b0hleCh0aGlzW2ldKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuXG5CdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpO1xuICBzdGFydCA9ICtzdGFydCB8fCAwO1xuICBpZiAodHlwZW9mIGVuZCA9PSAndW5kZWZpbmVkJykgZW5kID0gdGhpcy5sZW5ndGg7XG5cbiAgLy8gRmFzdHBhdGggZW1wdHkgc3RyaW5nc1xuICBpZiAoK2VuZCA9PSBzdGFydCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0dXJuIHRoaXMuaGV4U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXR1cm4gdGhpcy51dGY4U2xpY2Uoc3RhcnQsIGVuZCk7XG5cbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXR1cm4gdGhpcy5hc2NpaVNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldHVybiB0aGlzLmJpbmFyeVNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICAgIHJldHVybiB0aGlzLmJhc2U2NFNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgICAgcmV0dXJuIHRoaXMudWNzMlNsaWNlKHN0YXJ0LCBlbmQpO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpO1xuICB9XG59O1xuXG5cbkJ1ZmZlci5wcm90b3R5cGUuaGV4V3JpdGUgPSBmdW5jdGlvbihzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIG9mZnNldCA9ICtvZmZzZXQgfHwgMDtcbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0O1xuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSArbGVuZ3RoO1xuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZztcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aDtcbiAgaWYgKHN0ckxlbiAlIDIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaGV4IHN0cmluZycpO1xuICB9XG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMjtcbiAgfVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGJ5dGUgPSBwYXJzZUludChzdHJpbmcuc3Vic3RyKGkgKiAyLCAyKSwgMTYpO1xuICAgIGlmIChpc05hTihieXRlKSkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKTtcbiAgICB0aGlzW29mZnNldCArIGldID0gYnl0ZTtcbiAgfVxuICBCdWZmZXIuX2NoYXJzV3JpdHRlbiA9IGkgKiAyO1xuICByZXR1cm4gaTtcbn07XG5cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKSB7XG4gIC8vIFN1cHBvcnQgYm90aCAoc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpXG4gIC8vIGFuZCB0aGUgbGVnYWN5IChzdHJpbmcsIGVuY29kaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgaWYgKGlzRmluaXRlKG9mZnNldCkpIHtcbiAgICBpZiAoIWlzRmluaXRlKGxlbmd0aCkpIHtcbiAgICAgIGVuY29kaW5nID0gbGVuZ3RoO1xuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSBlbHNlIHsgIC8vIGxlZ2FjeVxuICAgIHZhciBzd2FwID0gZW5jb2Rpbmc7XG4gICAgZW5jb2RpbmcgPSBvZmZzZXQ7XG4gICAgb2Zmc2V0ID0gbGVuZ3RoO1xuICAgIGxlbmd0aCA9IHN3YXA7XG4gIH1cblxuICBvZmZzZXQgPSArb2Zmc2V0IHx8IDA7XG4gIHZhciByZW1haW5pbmcgPSB0aGlzLmxlbmd0aCAtIG9mZnNldDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gK2xlbmd0aDtcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmc7XG4gICAgfVxuICB9XG4gIGVuY29kaW5nID0gU3RyaW5nKGVuY29kaW5nIHx8ICd1dGY4JykudG9Mb3dlckNhc2UoKTtcblxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldHVybiB0aGlzLmhleFdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAndXRmOCc6XG4gICAgY2FzZSAndXRmLTgnOlxuICAgICAgcmV0dXJuIHRoaXMudXRmOFdyaXRlKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpO1xuXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0dXJuIHRoaXMuYXNjaWlXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnlXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXR1cm4gdGhpcy5iYXNlNjRXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIHJldHVybiB0aGlzLnVjczJXcml0ZShzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKTtcbiAgfVxufTtcblxuLy8gc2xpY2Uoc3RhcnQsIGVuZClcbmZ1bmN0aW9uIGNsYW1wKGluZGV4LCBsZW4sIGRlZmF1bHRWYWx1ZSkge1xuICBpZiAodHlwZW9mIGluZGV4ICE9PSAnbnVtYmVyJykgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgaW5kZXggPSB+fmluZGV4OyAgLy8gQ29lcmNlIHRvIGludGVnZXIuXG4gIGlmIChpbmRleCA+PSBsZW4pIHJldHVybiBsZW47XG4gIGlmIChpbmRleCA+PSAwKSByZXR1cm4gaW5kZXg7XG4gIGluZGV4ICs9IGxlbjtcbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleDtcbiAgcmV0dXJuIDA7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aDtcbiAgc3RhcnQgPSBjbGFtcChzdGFydCwgbGVuLCAwKTtcbiAgZW5kID0gY2xhbXAoZW5kLCBsZW4sIGxlbik7XG4gIHJldHVybiBuZXcgQnVmZmVyKHRoaXMsIGVuZCAtIHN0YXJ0LCArc3RhcnQpO1xufTtcblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24odGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXM7XG4gIHN0YXJ0IHx8IChzdGFydCA9IDApO1xuICBpZiAoZW5kID09PSB1bmRlZmluZWQgfHwgaXNOYU4oZW5kKSkge1xuICAgIGVuZCA9IHRoaXMubGVuZ3RoO1xuICB9XG4gIHRhcmdldF9zdGFydCB8fCAodGFyZ2V0X3N0YXJ0ID0gMCk7XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KSB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUVuZCA8IHNvdXJjZVN0YXJ0Jyk7XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMDtcbiAgaWYgKHRhcmdldC5sZW5ndGggPT0gMCB8fCBzb3VyY2UubGVuZ3RoID09IDApIHJldHVybiAwO1xuXG4gIGlmICh0YXJnZXRfc3RhcnQgPCAwIHx8IHRhcmdldF9zdGFydCA+PSB0YXJnZXQubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0YXJnZXRTdGFydCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZVN0YXJ0IG91dCBvZiBib3VuZHMnKTtcbiAgfVxuXG4gIGlmIChlbmQgPCAwIHx8IGVuZCA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZUVuZCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICAvLyBBcmUgd2Ugb29iP1xuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICBlbmQgPSB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0IDwgZW5kIC0gc3RhcnQpIHtcbiAgICBlbmQgPSB0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0ICsgc3RhcnQ7XG4gIH1cblxuICB2YXIgdGVtcCA9IFtdO1xuICBmb3IgKHZhciBpPXN0YXJ0OyBpPGVuZDsgaSsrKSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiB0aGlzW2ldICE9PSAndW5kZWZpbmVkJywgXCJjb3B5aW5nIHVuZGVmaW5lZCBidWZmZXIgYnl0ZXMhXCIpO1xuICAgIHRlbXAucHVzaCh0aGlzW2ldKTtcbiAgfVxuXG4gIGZvciAodmFyIGk9dGFyZ2V0X3N0YXJ0OyBpPHRhcmdldF9zdGFydCt0ZW1wLmxlbmd0aDsgaSsrKSB7XG4gICAgdGFyZ2V0W2ldID0gdGVtcFtpLXRhcmdldF9zdGFydF07XG4gIH1cbn07XG5cbi8vIGZpbGwodmFsdWUsIHN0YXJ0PTAsIGVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5maWxsID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICB2YWx1ZSB8fCAodmFsdWUgPSAwKTtcbiAgc3RhcnQgfHwgKHN0YXJ0ID0gMCk7XG4gIGVuZCB8fCAoZW5kID0gdGhpcy5sZW5ndGgpO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApO1xuICB9XG4gIGlmICghKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHx8IGlzTmFOKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcigndmFsdWUgaXMgbm90IGEgbnVtYmVyJyk7XG4gIH1cblxuICBpZiAoZW5kIDwgc3RhcnQpIHRocm93IG5ldyBFcnJvcignZW5kIDwgc3RhcnQnKTtcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVybiAwO1xuICBpZiAodGhpcy5sZW5ndGggPT0gMCkgcmV0dXJuIDA7XG5cbiAgaWYgKHN0YXJ0IDwgMCB8fCBzdGFydCA+PSB0aGlzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcignc3RhcnQgb3V0IG9mIGJvdW5kcycpO1xuICB9XG5cbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VuZCBvdXQgb2YgYm91bmRzJyk7XG4gIH1cblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHRoaXNbaV0gPSB2YWx1ZTtcbiAgfVxufVxuXG4vLyBTdGF0aWMgbWV0aG9kc1xuQnVmZmVyLmlzQnVmZmVyID0gZnVuY3Rpb24gaXNCdWZmZXIoYikge1xuICByZXR1cm4gYiBpbnN0YW5jZW9mIEJ1ZmZlciB8fCBiIGluc3RhbmNlb2YgQnVmZmVyO1xufTtcblxuQnVmZmVyLmNvbmNhdCA9IGZ1bmN0aW9uIChsaXN0LCB0b3RhbExlbmd0aCkge1xuICBpZiAoIWlzQXJyYXkobGlzdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVc2FnZTogQnVmZmVyLmNvbmNhdChsaXN0LCBbdG90YWxMZW5ndGhdKVxcbiBcXFxuICAgICAgbGlzdCBzaG91bGQgYmUgYW4gQXJyYXkuXCIpO1xuICB9XG5cbiAgaWYgKGxpc3QubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoMCk7XG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgdG90YWxMZW5ndGggIT09ICdudW1iZXInKSB7XG4gICAgdG90YWxMZW5ndGggPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGJ1ZiA9IGxpc3RbaV07XG4gICAgICB0b3RhbExlbmd0aCArPSBidWYubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHZhciBidWZmZXIgPSBuZXcgQnVmZmVyKHRvdGFsTGVuZ3RoKTtcbiAgdmFyIHBvcyA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgIHZhciBidWYgPSBsaXN0W2ldO1xuICAgIGJ1Zi5jb3B5KGJ1ZmZlciwgcG9zKTtcbiAgICBwb3MgKz0gYnVmLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gYnVmZmVyO1xufTtcblxuQnVmZmVyLmlzRW5jb2RpbmcgPSBmdW5jdGlvbihlbmNvZGluZykge1xuICBzd2l0Y2ggKChlbmNvZGluZyArICcnKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgIGNhc2UgJ3Jhdyc6XG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIGhlbHBlcnNcblxuZnVuY3Rpb24gY29lcmNlKGxlbmd0aCkge1xuICAvLyBDb2VyY2UgbGVuZ3RoIHRvIGEgbnVtYmVyIChwb3NzaWJseSBOYU4pLCByb3VuZCB1cFxuICAvLyBpbiBjYXNlIGl0J3MgZnJhY3Rpb25hbCAoZS5nLiAxMjMuNDU2KSB0aGVuIGRvIGFcbiAgLy8gZG91YmxlIG5lZ2F0ZSB0byBjb2VyY2UgYSBOYU4gdG8gMC4gRWFzeSwgcmlnaHQ/XG4gIGxlbmd0aCA9IH5+TWF0aC5jZWlsKCtsZW5ndGgpO1xuICByZXR1cm4gbGVuZ3RoIDwgMCA/IDAgOiBsZW5ndGg7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkoc3ViamVjdCkge1xuICByZXR1cm4gKEFycmF5LmlzQXJyYXkgfHxcbiAgICBmdW5jdGlvbihzdWJqZWN0KXtcbiAgICAgIHJldHVybiB7fS50b1N0cmluZy5hcHBseShzdWJqZWN0KSA9PSAnW29iamVjdCBBcnJheV0nXG4gICAgfSlcbiAgICAoc3ViamVjdClcbn1cblxuZnVuY3Rpb24gaXNBcnJheUlzaChzdWJqZWN0KSB7XG4gIHJldHVybiBpc0FycmF5KHN1YmplY3QpIHx8IEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSB8fFxuICAgICAgICAgc3ViamVjdCAmJiB0eXBlb2Ygc3ViamVjdCA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgIHR5cGVvZiBzdWJqZWN0Lmxlbmd0aCA9PT0gJ251bWJlcic7XG59XG5cbmZ1bmN0aW9uIHRvSGV4KG4pIHtcbiAgaWYgKG4gPCAxNikgcmV0dXJuICcwJyArIG4udG9TdHJpbmcoMTYpO1xuICByZXR1cm4gbi50b1N0cmluZygxNik7XG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKVxuICAgIGlmIChzdHIuY2hhckNvZGVBdChpKSA8PSAweDdGKVxuICAgICAgYnl0ZUFycmF5LnB1c2goc3RyLmNoYXJDb2RlQXQoaSkpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIGggPSBlbmNvZGVVUklDb21wb25lbnQoc3RyLmNoYXJBdChpKSkuc3Vic3RyKDEpLnNwbGl0KCclJyk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGgubGVuZ3RoOyBqKyspXG4gICAgICAgIGJ5dGVBcnJheS5wdXNoKHBhcnNlSW50KGhbal0sIDE2KSk7XG4gICAgfVxuXG4gIHJldHVybiBieXRlQXJyYXk7XG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyhzdHIpIHtcbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrIClcbiAgICAvLyBOb2RlJ3MgY29kZSBzZWVtcyB0byBiZSBkb2luZyB0aGlzIGFuZCBub3QgJiAweDdGLi5cbiAgICBieXRlQXJyYXkucHVzaCggc3RyLmNoYXJDb2RlQXQoaSkgJiAweEZGICk7XG5cbiAgcmV0dXJuIGJ5dGVBcnJheTtcbn1cblxuZnVuY3Rpb24gYmFzZTY0VG9CeXRlcyhzdHIpIHtcbiAgcmV0dXJuIHJlcXVpcmUoXCJiYXNlNjQtanNcIikudG9CeXRlQXJyYXkoc3RyKTtcbn1cblxuZnVuY3Rpb24gYmxpdEJ1ZmZlcihzcmMsIGRzdCwgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIHBvcywgaSA9IDA7XG4gIHdoaWxlIChpIDwgbGVuZ3RoKSB7XG4gICAgaWYgKChpK29mZnNldCA+PSBkc3QubGVuZ3RoKSB8fCAoaSA+PSBzcmMubGVuZ3RoKSlcbiAgICAgIGJyZWFrO1xuXG4gICAgZHN0W2kgKyBvZmZzZXRdID0gc3JjW2ldO1xuICAgIGkrKztcbiAgfVxuICByZXR1cm4gaTtcbn1cblxuZnVuY3Rpb24gZGVjb2RlVXRmOENoYXIoc3RyKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChzdHIpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgweEZGRkQpOyAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuXG4vLyByZWFkL3dyaXRlIGJpdC10d2lkZGxpbmdcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDggPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHJldHVybiBidWZmZXJbb2Zmc2V0XTtcbn07XG5cbmZ1bmN0aW9uIHJlYWRVSW50MTYoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgdmFsID0gMDtcblxuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuIDA7XG5cbiAgaWYgKGlzQmlnRW5kaWFuKSB7XG4gICAgdmFsID0gYnVmZmVyW29mZnNldF0gPDwgODtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgMV07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHZhbCA9IGJ1ZmZlcltvZmZzZXRdO1xuICAgIGlmIChvZmZzZXQgKyAxIDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAxXSA8PCA4O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB2YWw7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQxNih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MTZCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkVUludDMyKGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIHZhbCA9IDA7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgaWYgKG9mZnNldCA+PSBidWZmZXIubGVuZ3RoKSByZXR1cm4gMDtcblxuICBpZiAoaXNCaWdFbmRpYW4pIHtcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSBidWZmZXJbb2Zmc2V0ICsgMV0gPDwgMTY7XG4gICAgaWYgKG9mZnNldCArIDIgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAyXSA8PCA4O1xuICAgIGlmIChvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aClcbiAgICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0ICsgM107XG4gICAgdmFsID0gdmFsICsgKGJ1ZmZlcltvZmZzZXRdIDw8IDI0ID4+PiAwKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSBidWZmZXJbb2Zmc2V0ICsgMl0gPDwgMTY7XG4gICAgaWYgKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoKVxuICAgICAgdmFsIHw9IGJ1ZmZlcltvZmZzZXQgKyAxXSA8PCA4O1xuICAgIHZhbCB8PSBidWZmZXJbb2Zmc2V0XTtcbiAgICBpZiAob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgpXG4gICAgICB2YWwgPSB2YWwgKyAoYnVmZmVyW29mZnNldCArIDNdIDw8IDI0ID4+PiAwKTtcbiAgfVxuXG4gIHJldHVybiB2YWw7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZFVJbnQzMih0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRVSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5cbi8qXG4gKiBTaWduZWQgaW50ZWdlciB0eXBlcywgeWF5IHRlYW0hIEEgcmVtaW5kZXIgb24gaG93IHR3bydzIGNvbXBsZW1lbnQgYWN0dWFsbHlcbiAqIHdvcmtzLiBUaGUgZmlyc3QgYml0IGlzIHRoZSBzaWduZWQgYml0LCBpLmUuIHRlbGxzIHVzIHdoZXRoZXIgb3Igbm90IHRoZVxuICogbnVtYmVyIHNob3VsZCBiZSBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gSWYgdGhlIHR3bydzIGNvbXBsZW1lbnQgdmFsdWUgaXNcbiAqIHBvc2l0aXZlLCB0aGVuIHdlJ3JlIGRvbmUsIGFzIGl0J3MgZXF1aXZhbGVudCB0byB0aGUgdW5zaWduZWQgcmVwcmVzZW50YXRpb24uXG4gKlxuICogTm93IGlmIHRoZSBudW1iZXIgaXMgcG9zaXRpdmUsIHlvdSdyZSBwcmV0dHkgbXVjaCBkb25lLCB5b3UgY2FuIGp1c3QgbGV2ZXJhZ2VcbiAqIHRoZSB1bnNpZ25lZCB0cmFuc2xhdGlvbnMgYW5kIHJldHVybiB0aG9zZS4gVW5mb3J0dW5hdGVseSwgbmVnYXRpdmUgbnVtYmVyc1xuICogYXJlbid0IHF1aXRlIHRoYXQgc3RyYWlnaHRmb3J3YXJkLlxuICpcbiAqIEF0IGZpcnN0IGdsYW5jZSwgb25lIG1pZ2h0IGJlIGluY2xpbmVkIHRvIHVzZSB0aGUgdHJhZGl0aW9uYWwgZm9ybXVsYSB0b1xuICogdHJhbnNsYXRlIGJpbmFyeSBudW1iZXJzIGJldHdlZW4gdGhlIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSB2YWx1ZXMgaW4gdHdvJ3NcbiAqIGNvbXBsZW1lbnQuIChUaG91Z2ggaXQgZG9lc24ndCBxdWl0ZSB3b3JrIGZvciB0aGUgbW9zdCBuZWdhdGl2ZSB2YWx1ZSlcbiAqIE1haW5seTpcbiAqICAtIGludmVydCBhbGwgdGhlIGJpdHNcbiAqICAtIGFkZCBvbmUgdG8gdGhlIHJlc3VsdFxuICpcbiAqIE9mIGNvdXJzZSwgdGhpcyBkb2Vzbid0IHF1aXRlIHdvcmsgaW4gSmF2YXNjcmlwdC4gVGFrZSBmb3IgZXhhbXBsZSB0aGUgdmFsdWVcbiAqIG9mIC0xMjguIFRoaXMgY291bGQgYmUgcmVwcmVzZW50ZWQgaW4gMTYgYml0cyAoYmlnLWVuZGlhbikgYXMgMHhmZjgwLiBCdXQgb2ZcbiAqIGNvdXJzZSwgSmF2YXNjcmlwdCB3aWxsIGRvIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogPiB+MHhmZjgwXG4gKiAtNjU0MDlcbiAqXG4gKiBXaG9oIHRoZXJlLCBKYXZhc2NyaXB0LCB0aGF0J3Mgbm90IHF1aXRlIHJpZ2h0LiBCdXQgd2FpdCwgYWNjb3JkaW5nIHRvXG4gKiBKYXZhc2NyaXB0IHRoYXQncyBwZXJmZWN0bHkgY29ycmVjdC4gV2hlbiBKYXZhc2NyaXB0IGVuZHMgdXAgc2VlaW5nIHRoZVxuICogY29uc3RhbnQgMHhmZjgwLCBpdCBoYXMgbm8gbm90aW9uIHRoYXQgaXQgaXMgYWN0dWFsbHkgYSBzaWduZWQgbnVtYmVyLiBJdFxuICogYXNzdW1lcyB0aGF0IHdlJ3ZlIGlucHV0IHRoZSB1bnNpZ25lZCB2YWx1ZSAweGZmODAuIFRodXMsIHdoZW4gaXQgZG9lcyB0aGVcbiAqIGJpbmFyeSBuZWdhdGlvbiwgaXQgY2FzdHMgaXQgaW50byBhIHNpZ25lZCB2YWx1ZSwgKHBvc2l0aXZlIDB4ZmY4MCkuIFRoZW5cbiAqIHdoZW4geW91IHBlcmZvcm0gYmluYXJ5IG5lZ2F0aW9uIG9uIHRoYXQsIGl0IHR1cm5zIGl0IGludG8gYSBuZWdhdGl2ZSBudW1iZXIuXG4gKlxuICogSW5zdGVhZCwgd2UncmUgZ29pbmcgdG8gaGF2ZSB0byB1c2UgdGhlIGZvbGxvd2luZyBnZW5lcmFsIGZvcm11bGEsIHRoYXQgd29ya3NcbiAqIGluIGEgcmF0aGVyIEphdmFzY3JpcHQgZnJpZW5kbHkgd2F5LiBJJ20gZ2xhZCB3ZSBkb24ndCBzdXBwb3J0IHRoaXMga2luZCBvZlxuICogd2VpcmQgbnVtYmVyaW5nIHNjaGVtZSBpbiB0aGUga2VybmVsLlxuICpcbiAqIChCSVQtTUFYIC0gKHVuc2lnbmVkKXZhbCArIDEpICogLTFcbiAqXG4gKiBUaGUgYXN0dXRlIG9ic2VydmVyLCBtYXkgdGhpbmsgdGhhdCB0aGlzIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3IgOC1iaXQgbnVtYmVyc1xuICogKHJlYWxseSBpdCBpc24ndCBuZWNlc3NhcnkgZm9yIHRoZW0pLiBIb3dldmVyLCB3aGVuIHlvdSBnZXQgMTYtYml0IG51bWJlcnMsXG4gKiB5b3UgZG8uIExldCdzIGdvIGJhY2sgdG8gb3VyIHByaW9yIGV4YW1wbGUgYW5kIHNlZSBob3cgdGhpcyB3aWxsIGxvb2s6XG4gKlxuICogKDB4ZmZmZiAtIDB4ZmY4MCArIDEpICogLTFcbiAqICgweDAwN2YgKyAxKSAqIC0xXG4gKiAoMHgwMDgwKSAqIC0xXG4gKi9cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuICB2YXIgbmVnO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIGlmIChvZmZzZXQgPj0gYnVmZmVyLmxlbmd0aCkgcmV0dXJuO1xuXG4gIG5lZyA9IGJ1ZmZlcltvZmZzZXRdICYgMHg4MDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gKGJ1ZmZlcltvZmZzZXRdKTtcbiAgfVxuXG4gIHJldHVybiAoKDB4ZmYgLSBidWZmZXJbb2Zmc2V0XSArIDEpICogLTEpO1xufTtcblxuZnVuY3Rpb24gcmVhZEludDE2KGJ1ZmZlciwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgdmFyIG5lZywgdmFsO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcbiAgfVxuXG4gIHZhbCA9IHJlYWRVSW50MTYoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCk7XG4gIG5lZyA9IHZhbCAmIDB4ODAwMDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgcmV0dXJuICgweGZmZmYgLSB2YWwgKyAxKSAqIC0xO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2QkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MTYodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkSW50MzIoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICB2YXIgbmVnLCB2YWw7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgdmFsID0gcmVhZFVJbnQzMihidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgbmVnID0gdmFsICYgMHg4MDAwMDAwMDtcbiAgaWYgKCFuZWcpIHtcbiAgICByZXR1cm4gKHZhbCk7XG4gIH1cblxuICByZXR1cm4gKDB4ZmZmZmZmZmYgLSB2YWwgKyAxKSAqIC0xO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZEludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyQkUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkSW50MzIodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiByZWFkRmxvYXQoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS5yZWFkSUVFRTc1NChidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICAyMywgNCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbihvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiByZWFkRmxvYXQodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHJlYWREb3VibGUoYnVmZmVyLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgNyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuICB9XG5cbiAgcmV0dXJuIHJlcXVpcmUoJy4vYnVmZmVyX2llZWU3NTQnKS5yZWFkSUVFRTc1NChidWZmZXIsIG9mZnNldCwgaXNCaWdFbmRpYW4sXG4gICAgICA1MiwgOCk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZERvdWJsZUxFID0gZnVuY3Rpb24ob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gcmVhZERvdWJsZSh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydCk7XG59O1xuXG5CdWZmZXIucHJvdG90eXBlLnJlYWREb3VibGVCRSA9IGZ1bmN0aW9uKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHJlYWREb3VibGUodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5cbi8qXG4gKiBXZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB2YWx1ZSBpcyBhIHZhbGlkIGludGVnZXIuIFRoaXMgbWVhbnMgdGhhdCBpdCBpc1xuICogbm9uLW5lZ2F0aXZlLiBJdCBoYXMgbm8gZnJhY3Rpb25hbCBjb21wb25lbnQgYW5kIHRoYXQgaXQgZG9lcyBub3QgZXhjZWVkIHRoZVxuICogbWF4aW11bSBhbGxvd2VkIHZhbHVlLlxuICpcbiAqICAgICAgdmFsdWUgICAgICAgICAgIFRoZSBudW1iZXIgdG8gY2hlY2sgZm9yIHZhbGlkaXR5XG4gKlxuICogICAgICBtYXggICAgICAgICAgICAgVGhlIG1heGltdW0gdmFsdWVcbiAqL1xuZnVuY3Rpb24gdmVyaWZ1aW50KHZhbHVlLCBtYXgpIHtcbiAgYXNzZXJ0Lm9rKHR5cGVvZiAodmFsdWUpID09ICdudW1iZXInLFxuICAgICAgJ2Nhbm5vdCB3cml0ZSBhIG5vbi1udW1iZXIgYXMgYSBudW1iZXInKTtcblxuICBhc3NlcnQub2sodmFsdWUgPj0gMCxcbiAgICAgICdzcGVjaWZpZWQgYSBuZWdhdGl2ZSB2YWx1ZSBmb3Igd3JpdGluZyBhbiB1bnNpZ25lZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBpcyBsYXJnZXIgdGhhbiBtYXhpbXVtIHZhbHVlIGZvciB0eXBlJyk7XG5cbiAgYXNzZXJ0Lm9rKE1hdGguZmxvb3IodmFsdWUpID09PSB2YWx1ZSwgJ3ZhbHVlIGhhcyBhIGZyYWN0aW9uYWwgY29tcG9uZW50Jyk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhciBidWZmZXIgPSB0aGlzO1xuXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZik7XG4gIH1cblxuICBpZiAob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCkge1xuICAgIGJ1ZmZlcltvZmZzZXRdID0gdmFsdWU7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIHdyaXRlVUludDE2KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMSA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmKTtcbiAgfVxuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgTWF0aC5taW4oYnVmZmVyLmxlbmd0aCAtIG9mZnNldCwgMik7IGkrKykge1xuICAgIGJ1ZmZlcltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGlzQmlnRW5kaWFuID8gMSAtIGkgOiBpKSkpKSA+Pj5cbiAgICAgICAgICAgIChpc0JpZ0VuZGlhbiA/IDEgLSBpIDogaSkgKiA4O1xuICB9XG5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MTZCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlVUludDMyKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICd0cnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmdWludCh2YWx1ZSwgMHhmZmZmZmZmZik7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IE1hdGgubWluKGJ1ZmZlci5sZW5ndGggLSBvZmZzZXQsIDQpOyBpKyspIHtcbiAgICBidWZmZXJbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgPj4+IChpc0JpZ0VuZGlhbiA/IDMgLSBpIDogaSkgKiA4KSAmIDB4ZmY7XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50MzJCRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cblxuLypcbiAqIFdlIG5vdyBtb3ZlIG9udG8gb3VyIGZyaWVuZHMgaW4gdGhlIHNpZ25lZCBudW1iZXIgY2F0ZWdvcnkuIFVubGlrZSB1bnNpZ25lZFxuICogbnVtYmVycywgd2UncmUgZ29pbmcgdG8gaGF2ZSB0byB3b3JyeSBhIGJpdCBtb3JlIGFib3V0IGhvdyB3ZSBwdXQgdmFsdWVzIGludG9cbiAqIGFycmF5cy4gU2luY2Ugd2UgYXJlIG9ubHkgd29ycnlpbmcgYWJvdXQgc2lnbmVkIDMyLWJpdCB2YWx1ZXMsIHdlJ3JlIGluXG4gKiBzbGlnaHRseSBiZXR0ZXIgc2hhcGUuIFVuZm9ydHVuYXRlbHksIHdlIHJlYWxseSBjYW4ndCBkbyBvdXIgZmF2b3JpdGUgYmluYXJ5XG4gKiAmIGluIHRoaXMgc3lzdGVtLiBJdCByZWFsbHkgc2VlbXMgdG8gZG8gdGhlIHdyb25nIHRoaW5nLiBGb3IgZXhhbXBsZTpcbiAqXG4gKiA+IC0zMiAmIDB4ZmZcbiAqIDIyNFxuICpcbiAqIFdoYXQncyBoYXBwZW5pbmcgYWJvdmUgaXMgcmVhbGx5OiAweGUwICYgMHhmZiA9IDB4ZTAuIEhvd2V2ZXIsIHRoZSByZXN1bHRzIG9mXG4gKiB0aGlzIGFyZW4ndCB0cmVhdGVkIGFzIGEgc2lnbmVkIG51bWJlci4gVWx0aW1hdGVseSBhIGJhZCB0aGluZy5cbiAqXG4gKiBXaGF0IHdlJ3JlIGdvaW5nIHRvIHdhbnQgdG8gZG8gaXMgYmFzaWNhbGx5IGNyZWF0ZSB0aGUgdW5zaWduZWQgZXF1aXZhbGVudCBvZlxuICogb3VyIHJlcHJlc2VudGF0aW9uIGFuZCBwYXNzIHRoYXQgb2ZmIHRvIHRoZSB3dWludCogZnVuY3Rpb25zLiBUbyBkbyB0aGF0XG4gKiB3ZSdyZSBnb2luZyB0byBkbyB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAtIGlmIHRoZSB2YWx1ZSBpcyBwb3NpdGl2ZVxuICogICAgICB3ZSBjYW4gcGFzcyBpdCBkaXJlY3RseSBvZmYgdG8gdGhlIGVxdWl2YWxlbnQgd3VpbnRcbiAqICAtIGlmIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZVxuICogICAgICB3ZSBkbyB0aGUgZm9sbG93aW5nIGNvbXB1dGF0aW9uOlxuICogICAgICAgICBtYiArIHZhbCArIDEsIHdoZXJlXG4gKiAgICAgICAgIG1iICAgaXMgdGhlIG1heGltdW0gdW5zaWduZWQgdmFsdWUgaW4gdGhhdCBieXRlIHNpemVcbiAqICAgICAgICAgdmFsICBpcyB0aGUgSmF2YXNjcmlwdCBuZWdhdGl2ZSBpbnRlZ2VyXG4gKlxuICpcbiAqIEFzIGEgY29uY3JldGUgdmFsdWUsIHRha2UgLTEyOC4gSW4gc2lnbmVkIDE2IGJpdHMgdGhpcyB3b3VsZCBiZSAweGZmODAuIElmXG4gKiB5b3UgZG8gb3V0IHRoZSBjb21wdXRhdGlvbnM6XG4gKlxuICogMHhmZmZmIC0gMTI4ICsgMVxuICogMHhmZmZmIC0gMTI3XG4gKiAweGZmODBcbiAqXG4gKiBZb3UgY2FuIHRoZW4gZW5jb2RlIHRoaXMgdmFsdWUgYXMgdGhlIHNpZ25lZCB2ZXJzaW9uLiBUaGlzIGlzIHJlYWxseSByYXRoZXJcbiAqIGhhY2t5LCBidXQgaXQgc2hvdWxkIHdvcmsgYW5kIGdldCB0aGUgam9iIGRvbmUgd2hpY2ggaXMgb3VyIGdvYWwgaGVyZS5cbiAqL1xuXG4vKlxuICogQSBzZXJpZXMgb2YgY2hlY2tzIHRvIG1ha2Ugc3VyZSB3ZSBhY3R1YWxseSBoYXZlIGEgc2lnbmVkIDMyLWJpdCBudW1iZXJcbiAqL1xuZnVuY3Rpb24gdmVyaWZzaW50KHZhbHVlLCBtYXgsIG1pbikge1xuICBhc3NlcnQub2sodHlwZW9mICh2YWx1ZSkgPT0gJ251bWJlcicsXG4gICAgICAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKTtcblxuICBhc3NlcnQub2sodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayhNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpO1xufVxuXG5mdW5jdGlvbiB2ZXJpZklFRUU3NTQodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydC5vayh0eXBlb2YgKHZhbHVlKSA9PSAnbnVtYmVyJyxcbiAgICAgICdjYW5ub3Qgd3JpdGUgYSBub24tbnVtYmVyIGFzIGEgbnVtYmVyJyk7XG5cbiAgYXNzZXJ0Lm9rKHZhbHVlIDw9IG1heCwgJ3ZhbHVlIGxhcmdlciB0aGFuIG1heGltdW0gYWxsb3dlZCB2YWx1ZScpO1xuXG4gIGFzc2VydC5vayh2YWx1ZSA+PSBtaW4sICd2YWx1ZSBzbWFsbGVyIHRoYW4gbWluaW11bSBhbGxvd2VkIHZhbHVlJyk7XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFyIGJ1ZmZlciA9IHRoaXM7XG5cbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0IDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmLCAtMHg4MCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIGJ1ZmZlci53cml0ZVVJbnQ4KHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICBidWZmZXIud3JpdGVVSW50OCgweGZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIG5vQXNzZXJ0KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gd3JpdGVJbnQxNihidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDEgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2ZmZiwgLTB4ODAwMCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIHdyaXRlVUludDE2KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICB3cml0ZVVJbnQxNihidWZmZXIsIDB4ZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpO1xuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KTtcbn07XG5cbmZ1bmN0aW9uIHdyaXRlSW50MzIoYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0JpZ0VuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydC5vayh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyB2YWx1ZScpO1xuXG4gICAgYXNzZXJ0Lm9rKHR5cGVvZiAoaXNCaWdFbmRpYW4pID09PSAnYm9vbGVhbicsXG4gICAgICAgICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLFxuICAgICAgICAnbWlzc2luZyBvZmZzZXQnKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgKyAzIDwgYnVmZmVyLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpO1xuXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMCk7XG4gIH1cblxuICBpZiAodmFsdWUgPj0gMCkge1xuICAgIHdyaXRlVUludDMyKGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfSBlbHNlIHtcbiAgICB3cml0ZVVJbnQzMihidWZmZXIsIDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDEsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KTtcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZUZsb2F0KGJ1ZmZlciwgdmFsdWUsIG9mZnNldCwgaXNCaWdFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQub2sodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3NpbmcgdmFsdWUnKTtcblxuICAgIGFzc2VydC5vayh0eXBlb2YgKGlzQmlnRW5kaWFuKSA9PT0gJ2Jvb2xlYW4nLFxuICAgICAgICAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCxcbiAgICAgICAgJ21pc3Npbmcgb2Zmc2V0Jyk7XG5cbiAgICBhc3NlcnQub2sob2Zmc2V0ICsgMyA8IGJ1ZmZlci5sZW5ndGgsXG4gICAgICAgICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKTtcblxuICAgIHZlcmlmSUVFRTc1NCh2YWx1ZSwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLndyaXRlSUVFRTc1NChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgMjMsIDQpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KTtcbn07XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdEJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydCk7XG59O1xuXG5mdW5jdGlvbiB3cml0ZURvdWJsZShidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0Lm9rKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIHZhbHVlJyk7XG5cbiAgICBhc3NlcnQub2sodHlwZW9mIChpc0JpZ0VuZGlhbikgPT09ICdib29sZWFuJyxcbiAgICAgICAgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKTtcblxuICAgIGFzc2VydC5vayhvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpO1xuXG4gICAgYXNzZXJ0Lm9rKG9mZnNldCArIDcgPCBidWZmZXIubGVuZ3RoLFxuICAgICAgICAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJyk7XG5cbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4LCAtMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgpO1xuICB9XG5cbiAgcmVxdWlyZSgnLi9idWZmZXJfaWVlZTc1NCcpLndyaXRlSUVFRTc1NChidWZmZXIsIHZhbHVlLCBvZmZzZXQsIGlzQmlnRW5kaWFuLFxuICAgICAgNTIsIDgpO1xufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRG91YmxlTEUgPSBmdW5jdGlvbih2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICB3cml0ZURvdWJsZSh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpO1xufTtcblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZURvdWJsZUJFID0gZnVuY3Rpb24odmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpO1xufTtcblxufSx7XCIuL2J1ZmZlcl9pZWVlNzU0XCI6MSxcImFzc2VydFwiOjYsXCJiYXNlNjQtanNcIjo0fV0sXCJidWZmZXItYnJvd3NlcmlmeVwiOltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcbm1vZHVsZS5leHBvcnRzPXJlcXVpcmUoJ3E5VHhDQycpO1xufSx7fV0sNDpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4oZnVuY3Rpb24gKGV4cG9ydHMpIHtcblx0J3VzZSBzdHJpY3QnO1xuXG5cdHZhciBsb29rdXAgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkoYjY0KSB7XG5cdFx0dmFyIGksIGosIGwsIHRtcCwgcGxhY2VIb2xkZXJzLCBhcnI7XG5cdFxuXHRcdGlmIChiNjQubGVuZ3RoICUgNCA+IDApIHtcblx0XHRcdHRocm93ICdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0Jztcblx0XHR9XG5cblx0XHQvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuXHRcdC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcblx0XHQvLyByZXByZXNlbnQgb25lIGJ5dGVcblx0XHQvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcblx0XHQvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG5cdFx0cGxhY2VIb2xkZXJzID0gYjY0LmluZGV4T2YoJz0nKTtcblx0XHRwbGFjZUhvbGRlcnMgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIHBsYWNlSG9sZGVycyA6IDA7XG5cblx0XHQvLyBiYXNlNjQgaXMgNC8zICsgdXAgdG8gdHdvIGNoYXJhY3RlcnMgb2YgdGhlIG9yaWdpbmFsIGRhdGFcblx0XHRhcnIgPSBbXTsvL25ldyBVaW50OEFycmF5KGI2NC5sZW5ndGggKiAzIC8gNCAtIHBsYWNlSG9sZGVycyk7XG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGg7XG5cblx0XHRmb3IgKGkgPSAwLCBqID0gMDsgaSA8IGw7IGkgKz0gNCwgaiArPSAzKSB7XG5cdFx0XHR0bXAgPSAobG9va3VwLmluZGV4T2YoYjY0W2ldKSA8PCAxOCkgfCAobG9va3VwLmluZGV4T2YoYjY0W2kgKyAxXSkgPDwgMTIpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMl0pIDw8IDYpIHwgbG9va3VwLmluZGV4T2YoYjY0W2kgKyAzXSk7XG5cdFx0XHRhcnIucHVzaCgodG1wICYgMHhGRjAwMDApID4+IDE2KTtcblx0XHRcdGFyci5wdXNoKCh0bXAgJiAweEZGMDApID4+IDgpO1xuXHRcdFx0YXJyLnB1c2godG1wICYgMHhGRik7XG5cdFx0fVxuXG5cdFx0aWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuXHRcdFx0dG1wID0gKGxvb2t1cC5pbmRleE9mKGI2NFtpXSkgPDwgMikgfCAobG9va3VwLmluZGV4T2YoYjY0W2kgKyAxXSkgPj4gNCk7XG5cdFx0XHRhcnIucHVzaCh0bXAgJiAweEZGKTtcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGxvb2t1cC5pbmRleE9mKGI2NFtpXSkgPDwgMTApIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMV0pIDw8IDQpIHwgKGxvb2t1cC5pbmRleE9mKGI2NFtpICsgMl0pID4+IDIpO1xuXHRcdFx0YXJyLnB1c2goKHRtcCA+PiA4KSAmIDB4RkYpO1xuXHRcdFx0YXJyLnB1c2godG1wICYgMHhGRik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFycjtcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQodWludDgpIHtcblx0XHR2YXIgaSxcblx0XHRcdGV4dHJhQnl0ZXMgPSB1aW50OC5sZW5ndGggJSAzLCAvLyBpZiB3ZSBoYXZlIDEgYnl0ZSBsZWZ0LCBwYWQgMiBieXRlc1xuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdHRlbXAsIGxlbmd0aDtcblxuXHRcdGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwW251bSA+PiAxOCAmIDB4M0ZdICsgbG9va3VwW251bSA+PiAxMiAmIDB4M0ZdICsgbG9va3VwW251bSA+PiA2ICYgMHgzRl0gKyBsb29rdXBbbnVtICYgMHgzRl07XG5cdFx0fTtcblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pO1xuXHRcdFx0b3V0cHV0ICs9IHRyaXBsZXRUb0Jhc2U2NCh0ZW1wKTtcblx0XHR9XG5cblx0XHQvLyBwYWQgdGhlIGVuZCB3aXRoIHplcm9zLCBidXQgbWFrZSBzdXJlIHRvIG5vdCBmb3JnZXQgdGhlIGV4dHJhIGJ5dGVzXG5cdFx0c3dpdGNoIChleHRyYUJ5dGVzKSB7XG5cdFx0XHRjYXNlIDE6XG5cdFx0XHRcdHRlbXAgPSB1aW50OFt1aW50OC5sZW5ndGggLSAxXTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFt0ZW1wID4+IDJdO1xuXHRcdFx0XHRvdXRwdXQgKz0gbG9va3VwWyh0ZW1wIDw8IDQpICYgMHgzRl07XG5cdFx0XHRcdG91dHB1dCArPSAnPT0nO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0dGVtcCA9ICh1aW50OFt1aW50OC5sZW5ndGggLSAyXSA8PCA4KSArICh1aW50OFt1aW50OC5sZW5ndGggLSAxXSk7XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbdGVtcCA+PiAxMF07XG5cdFx0XHRcdG91dHB1dCArPSBsb29rdXBbKHRlbXAgPj4gNCkgJiAweDNGXTtcblx0XHRcdFx0b3V0cHV0ICs9IGxvb2t1cFsodGVtcCA8PCAyKSAmIDB4M0ZdO1xuXHRcdFx0XHRvdXRwdXQgKz0gJz0nO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0bW9kdWxlLmV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheTtcblx0bW9kdWxlLmV4cG9ydHMuZnJvbUJ5dGVBcnJheSA9IHVpbnQ4VG9CYXNlNjQ7XG59KCkpO1xuXG59LHt9XSw1OltmdW5jdGlvbihyZXF1aXJlLG1vZHVsZSxleHBvcnRzKXtcblxuXG4vL1xuLy8gVGhlIHNoaW1zIGluIHRoaXMgZmlsZSBhcmUgbm90IGZ1bGx5IGltcGxlbWVudGVkIHNoaW1zIGZvciB0aGUgRVM1XG4vLyBmZWF0dXJlcywgYnV0IGRvIHdvcmsgZm9yIHRoZSBwYXJ0aWN1bGFyIHVzZWNhc2VzIHRoZXJlIGlzIGluXG4vLyB0aGUgb3RoZXIgbW9kdWxlcy5cbi8vXG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vLyBBcnJheS5pc0FycmF5IGlzIHN1cHBvcnRlZCBpbiBJRTlcbmZ1bmN0aW9uIGlzQXJyYXkoeHMpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufVxuZXhwb3J0cy5pc0FycmF5ID0gdHlwZW9mIEFycmF5LmlzQXJyYXkgPT09ICdmdW5jdGlvbicgPyBBcnJheS5pc0FycmF5IDogaXNBcnJheTtcblxuLy8gQXJyYXkucHJvdG90eXBlLmluZGV4T2YgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5pbmRleE9mID0gZnVuY3Rpb24gaW5kZXhPZih4cywgeCkge1xuICBpZiAoeHMuaW5kZXhPZikgcmV0dXJuIHhzLmluZGV4T2YoeCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoeCA9PT0geHNbaV0pIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbi8vIEFycmF5LnByb3RvdHlwZS5maWx0ZXIgaXMgc3VwcG9ydGVkIGluIElFOVxuZXhwb3J0cy5maWx0ZXIgPSBmdW5jdGlvbiBmaWx0ZXIoeHMsIGZuKSB7XG4gIGlmICh4cy5maWx0ZXIpIHJldHVybiB4cy5maWx0ZXIoZm4pO1xuICB2YXIgcmVzID0gW107XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoZm4oeHNbaV0sIGksIHhzKSkgcmVzLnB1c2goeHNbaV0pO1xuICB9XG4gIHJldHVybiByZXM7XG59O1xuXG4vLyBBcnJheS5wcm90b3R5cGUuZm9yRWFjaCBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLmZvckVhY2ggPSBmdW5jdGlvbiBmb3JFYWNoKHhzLCBmbiwgc2VsZikge1xuICBpZiAoeHMuZm9yRWFjaCkgcmV0dXJuIHhzLmZvckVhY2goZm4sIHNlbGYpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgZm4uY2FsbChzZWxmLCB4c1tpXSwgaSwgeHMpO1xuICB9XG59O1xuXG4vLyBBcnJheS5wcm90b3R5cGUubWFwIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMubWFwID0gZnVuY3Rpb24gbWFwKHhzLCBmbikge1xuICBpZiAoeHMubWFwKSByZXR1cm4geHMubWFwKGZuKTtcbiAgdmFyIG91dCA9IG5ldyBBcnJheSh4cy5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgb3V0W2ldID0gZm4oeHNbaV0sIGksIHhzKTtcbiAgfVxuICByZXR1cm4gb3V0O1xufTtcblxuLy8gQXJyYXkucHJvdG90eXBlLnJlZHVjZSBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLnJlZHVjZSA9IGZ1bmN0aW9uIHJlZHVjZShhcnJheSwgY2FsbGJhY2ssIG9wdF9pbml0aWFsVmFsdWUpIHtcbiAgaWYgKGFycmF5LnJlZHVjZSkgcmV0dXJuIGFycmF5LnJlZHVjZShjYWxsYmFjaywgb3B0X2luaXRpYWxWYWx1ZSk7XG4gIHZhciB2YWx1ZSwgaXNWYWx1ZVNldCA9IGZhbHNlO1xuXG4gIGlmICgyIDwgYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHZhbHVlID0gb3B0X2luaXRpYWxWYWx1ZTtcbiAgICBpc1ZhbHVlU2V0ID0gdHJ1ZTtcbiAgfVxuICBmb3IgKHZhciBpID0gMCwgbCA9IGFycmF5Lmxlbmd0aDsgbCA+IGk7ICsraSkge1xuICAgIGlmIChhcnJheS5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgaWYgKGlzVmFsdWVTZXQpIHtcbiAgICAgICAgdmFsdWUgPSBjYWxsYmFjayh2YWx1ZSwgYXJyYXlbaV0sIGksIGFycmF5KTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICB2YWx1ZSA9IGFycmF5W2ldO1xuICAgICAgICBpc1ZhbHVlU2V0ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsdWU7XG59O1xuXG4vLyBTdHJpbmcucHJvdG90eXBlLnN1YnN0ciAtIG5lZ2F0aXZlIGluZGV4IGRvbid0IHdvcmsgaW4gSUU4XG5pZiAoJ2FiJy5zdWJzdHIoLTEpICE9PSAnYicpIHtcbiAgZXhwb3J0cy5zdWJzdHIgPSBmdW5jdGlvbiAoc3RyLCBzdGFydCwgbGVuZ3RoKSB7XG4gICAgLy8gZGlkIHdlIGdldCBhIG5lZ2F0aXZlIHN0YXJ0LCBjYWxjdWxhdGUgaG93IG11Y2ggaXQgaXMgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmdcbiAgICBpZiAoc3RhcnQgPCAwKSBzdGFydCA9IHN0ci5sZW5ndGggKyBzdGFydDtcblxuICAgIC8vIGNhbGwgdGhlIG9yaWdpbmFsIGZ1bmN0aW9uXG4gICAgcmV0dXJuIHN0ci5zdWJzdHIoc3RhcnQsIGxlbmd0aCk7XG4gIH07XG59IGVsc2Uge1xuICBleHBvcnRzLnN1YnN0ciA9IGZ1bmN0aW9uIChzdHIsIHN0YXJ0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gc3RyLnN1YnN0cihzdGFydCwgbGVuZ3RoKTtcbiAgfTtcbn1cblxuLy8gU3RyaW5nLnByb3RvdHlwZS50cmltIGlzIHN1cHBvcnRlZCBpbiBJRTlcbmV4cG9ydHMudHJpbSA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgaWYgKHN0ci50cmltKSByZXR1cm4gc3RyLnRyaW0oKTtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7XG59O1xuXG4vLyBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCBpcyBzdXBwb3J0ZWQgaW4gSUU5XG5leHBvcnRzLmJpbmQgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgdmFyIGZuID0gYXJncy5zaGlmdCgpO1xuICBpZiAoZm4uYmluZCkgcmV0dXJuIGZuLmJpbmQuYXBwbHkoZm4sIGFyZ3MpO1xuICB2YXIgc2VsZiA9IGFyZ3Muc2hpZnQoKTtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICBmbi5hcHBseShzZWxmLCBhcmdzLmNvbmNhdChbQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKV0pKTtcbiAgfTtcbn07XG5cbi8vIE9iamVjdC5jcmVhdGUgaXMgc3VwcG9ydGVkIGluIElFOVxuZnVuY3Rpb24gY3JlYXRlKHByb3RvdHlwZSwgcHJvcGVydGllcykge1xuICB2YXIgb2JqZWN0O1xuICBpZiAocHJvdG90eXBlID09PSBudWxsKSB7XG4gICAgb2JqZWN0ID0geyAnX19wcm90b19fJyA6IG51bGwgfTtcbiAgfVxuICBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHByb3RvdHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICd0eXBlb2YgcHJvdG90eXBlWycgKyAodHlwZW9mIHByb3RvdHlwZSkgKyAnXSAhPSBcXCdvYmplY3RcXCcnXG4gICAgICApO1xuICAgIH1cbiAgICB2YXIgVHlwZSA9IGZ1bmN0aW9uICgpIHt9O1xuICAgIFR5cGUucHJvdG90eXBlID0gcHJvdG90eXBlO1xuICAgIG9iamVjdCA9IG5ldyBUeXBlKCk7XG4gICAgb2JqZWN0Ll9fcHJvdG9fXyA9IHByb3RvdHlwZTtcbiAgfVxuICBpZiAodHlwZW9mIHByb3BlcnRpZXMgIT09ICd1bmRlZmluZWQnICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMob2JqZWN0LCBwcm9wZXJ0aWVzKTtcbiAgfVxuICByZXR1cm4gb2JqZWN0O1xufVxuZXhwb3J0cy5jcmVhdGUgPSB0eXBlb2YgT2JqZWN0LmNyZWF0ZSA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC5jcmVhdGUgOiBjcmVhdGU7XG5cbi8vIE9iamVjdC5rZXlzIGFuZCBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyBpcyBzdXBwb3J0ZWQgaW4gSUU5IGhvd2V2ZXJcbi8vIHRoZXkgZG8gc2hvdyBhIGRlc2NyaXB0aW9uIGFuZCBudW1iZXIgcHJvcGVydHkgb24gRXJyb3Igb2JqZWN0c1xuZnVuY3Rpb24gbm90T2JqZWN0KG9iamVjdCkge1xuICByZXR1cm4gKCh0eXBlb2Ygb2JqZWN0ICE9IFwib2JqZWN0XCIgJiYgdHlwZW9mIG9iamVjdCAhPSBcImZ1bmN0aW9uXCIpIHx8IG9iamVjdCA9PT0gbnVsbCk7XG59XG5cbmZ1bmN0aW9uIGtleXNTaGltKG9iamVjdCkge1xuICBpZiAobm90T2JqZWN0KG9iamVjdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0LmtleXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yICh2YXIgbmFtZSBpbiBvYmplY3QpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIG5hbWUpKSB7XG4gICAgICByZXN1bHQucHVzaChuYW1lKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLy8gZ2V0T3duUHJvcGVydHlOYW1lcyBpcyBhbG1vc3QgdGhlIHNhbWUgYXMgT2JqZWN0LmtleXMgb25lIGtleSBmZWF0dXJlXG4vLyAgaXMgdGhhdCBpdCByZXR1cm5zIGhpZGRlbiBwcm9wZXJ0aWVzLCBzaW5jZSB0aGF0IGNhbid0IGJlIGltcGxlbWVudGVkLFxuLy8gIHRoaXMgZmVhdHVyZSBnZXRzIHJlZHVjZWQgc28gaXQganVzdCBzaG93cyB0aGUgbGVuZ3RoIHByb3BlcnR5IG9uIGFycmF5c1xuZnVuY3Rpb24gcHJvcGVydHlTaGltKG9iamVjdCkge1xuICBpZiAobm90T2JqZWN0KG9iamVjdCkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgY2FsbGVkIG9uIGEgbm9uLW9iamVjdFwiKTtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBrZXlzU2hpbShvYmplY3QpO1xuICBpZiAoZXhwb3J0cy5pc0FycmF5KG9iamVjdCkgJiYgZXhwb3J0cy5pbmRleE9mKG9iamVjdCwgJ2xlbmd0aCcpID09PSAtMSkge1xuICAgIHJlc3VsdC5wdXNoKCdsZW5ndGgnKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG52YXIga2V5cyA9IHR5cGVvZiBPYmplY3Qua2V5cyA9PT0gJ2Z1bmN0aW9uJyA/IE9iamVjdC5rZXlzIDoga2V5c1NoaW07XG52YXIgZ2V0T3duUHJvcGVydHlOYW1lcyA9IHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyA9PT0gJ2Z1bmN0aW9uJyA/XG4gIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIDogcHJvcGVydHlTaGltO1xuXG5pZiAobmV3IEVycm9yKCkuaGFzT3duUHJvcGVydHkoJ2Rlc2NyaXB0aW9uJykpIHtcbiAgdmFyIEVSUk9SX1BST1BFUlRZX0ZJTFRFUiA9IGZ1bmN0aW9uIChvYmosIGFycmF5KSB7XG4gICAgaWYgKHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgRXJyb3JdJykge1xuICAgICAgYXJyYXkgPSBleHBvcnRzLmZpbHRlcihhcnJheSwgZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIG5hbWUgIT09ICdkZXNjcmlwdGlvbicgJiYgbmFtZSAhPT0gJ251bWJlcicgJiYgbmFtZSAhPT0gJ21lc3NhZ2UnO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfTtcblxuICBleHBvcnRzLmtleXMgPSBmdW5jdGlvbiAob2JqZWN0KSB7XG4gICAgcmV0dXJuIEVSUk9SX1BST1BFUlRZX0ZJTFRFUihvYmplY3QsIGtleXMob2JqZWN0KSk7XG4gIH07XG4gIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlOYW1lcyA9IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICByZXR1cm4gRVJST1JfUFJPUEVSVFlfRklMVEVSKG9iamVjdCwgZ2V0T3duUHJvcGVydHlOYW1lcyhvYmplY3QpKTtcbiAgfTtcbn0gZWxzZSB7XG4gIGV4cG9ydHMua2V5cyA9IGtleXM7XG4gIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlOYW1lcyA9IGdldE93blByb3BlcnR5TmFtZXM7XG59XG5cbi8vIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgLSBzdXBwb3J0ZWQgaW4gSUU4IGJ1dCBvbmx5IG9uIGRvbSBlbGVtZW50c1xuZnVuY3Rpb24gdmFsdWVPYmplY3QodmFsdWUsIGtleSkge1xuICByZXR1cm4geyB2YWx1ZTogdmFsdWVba2V5XSB9O1xufVxuXG5pZiAodHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgdHJ5IHtcbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHsnYSc6IDF9LCAnYScpO1xuICAgIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIElFOCBkb20gZWxlbWVudCBpc3N1ZSAtIHVzZSBhIHRyeSBjYXRjaCBhbmQgZGVmYXVsdCB0byB2YWx1ZU9iamVjdFxuICAgIGV4cG9ydHMuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yID0gZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gdmFsdWVPYmplY3QodmFsdWUsIGtleSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxufSBlbHNlIHtcbiAgZXhwb3J0cy5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSB2YWx1ZU9iamVjdDtcbn1cblxufSx7fV0sNjpbZnVuY3Rpb24ocmVxdWlyZSxtb2R1bGUsZXhwb3J0cyl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuLy8gVVRJTElUWVxudmFyIHV0aWwgPSByZXF1aXJlKCd1dGlsJyk7XG52YXIgc2hpbXMgPSByZXF1aXJlKCdfc2hpbXMnKTtcbnZhciBwU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbi8vIDEuIFRoZSBhc3NlcnQgbW9kdWxlIHByb3ZpZGVzIGZ1bmN0aW9ucyB0aGF0IHRocm93XG4vLyBBc3NlcnRpb25FcnJvcidzIHdoZW4gcGFydGljdWxhciBjb25kaXRpb25zIGFyZSBub3QgbWV0LiBUaGVcbi8vIGFzc2VydCBtb2R1bGUgbXVzdCBjb25mb3JtIHRvIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlLlxuXG52YXIgYXNzZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSBvaztcblxuLy8gMi4gVGhlIEFzc2VydGlvbkVycm9yIGlzIGRlZmluZWQgaW4gYXNzZXJ0LlxuLy8gbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7IG1lc3NhZ2U6IG1lc3NhZ2UsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0dWFsOiBhY3R1YWwsXG4vLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkIH0pXG5cbmFzc2VydC5Bc3NlcnRpb25FcnJvciA9IGZ1bmN0aW9uIEFzc2VydGlvbkVycm9yKG9wdGlvbnMpIHtcbiAgdGhpcy5uYW1lID0gJ0Fzc2VydGlvbkVycm9yJztcbiAgdGhpcy5hY3R1YWwgPSBvcHRpb25zLmFjdHVhbDtcbiAgdGhpcy5leHBlY3RlZCA9IG9wdGlvbnMuZXhwZWN0ZWQ7XG4gIHRoaXMub3BlcmF0b3IgPSBvcHRpb25zLm9wZXJhdG9yO1xuICB0aGlzLm1lc3NhZ2UgPSBvcHRpb25zLm1lc3NhZ2UgfHwgZ2V0TWVzc2FnZSh0aGlzKTtcbn07XG5cbi8vIGFzc2VydC5Bc3NlcnRpb25FcnJvciBpbnN0YW5jZW9mIEVycm9yXG51dGlsLmluaGVyaXRzKGFzc2VydC5Bc3NlcnRpb25FcnJvciwgRXJyb3IpO1xuXG5mdW5jdGlvbiByZXBsYWNlcihrZXksIHZhbHVlKSB7XG4gIGlmICh1dGlsLmlzVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiAnJyArIHZhbHVlO1xuICB9XG4gIGlmICh1dGlsLmlzTnVtYmVyKHZhbHVlKSAmJiAoaXNOYU4odmFsdWUpIHx8ICFpc0Zpbml0ZSh2YWx1ZSkpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7XG4gIH1cbiAgaWYgKHV0aWwuaXNGdW5jdGlvbih2YWx1ZSkgfHwgdXRpbC5pc1JlZ0V4cCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHRydW5jYXRlKHMsIG4pIHtcbiAgaWYgKHV0aWwuaXNTdHJpbmcocykpIHtcbiAgICByZXR1cm4gcy5sZW5ndGggPCBuID8gcyA6IHMuc2xpY2UoMCwgbik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHM7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0TWVzc2FnZShzZWxmKSB7XG4gIHJldHVybiB0cnVuY2F0ZShKU09OLnN0cmluZ2lmeShzZWxmLmFjdHVhbCwgcmVwbGFjZXIpLCAxMjgpICsgJyAnICtcbiAgICAgICAgIHNlbGYub3BlcmF0b3IgKyAnICcgK1xuICAgICAgICAgdHJ1bmNhdGUoSlNPTi5zdHJpbmdpZnkoc2VsZi5leHBlY3RlZCwgcmVwbGFjZXIpLCAxMjgpO1xufVxuXG4vLyBBdCBwcmVzZW50IG9ubHkgdGhlIHRocmVlIGtleXMgbWVudGlvbmVkIGFib3ZlIGFyZSB1c2VkIGFuZFxuLy8gdW5kZXJzdG9vZCBieSB0aGUgc3BlYy4gSW1wbGVtZW50YXRpb25zIG9yIHN1YiBtb2R1bGVzIGNhbiBwYXNzXG4vLyBvdGhlciBrZXlzIHRvIHRoZSBBc3NlcnRpb25FcnJvcidzIGNvbnN0cnVjdG9yIC0gdGhleSB3aWxsIGJlXG4vLyBpZ25vcmVkLlxuXG4vLyAzLiBBbGwgb2YgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnMgbXVzdCB0aHJvdyBhbiBBc3NlcnRpb25FcnJvclxuLy8gd2hlbiBhIGNvcnJlc3BvbmRpbmcgY29uZGl0aW9uIGlzIG5vdCBtZXQsIHdpdGggYSBtZXNzYWdlIHRoYXRcbi8vIG1heSBiZSB1bmRlZmluZWQgaWYgbm90IHByb3ZpZGVkLiAgQWxsIGFzc2VydGlvbiBtZXRob2RzIHByb3ZpZGVcbi8vIGJvdGggdGhlIGFjdHVhbCBhbmQgZXhwZWN0ZWQgdmFsdWVzIHRvIHRoZSBhc3NlcnRpb24gZXJyb3IgZm9yXG4vLyBkaXNwbGF5IHB1cnBvc2VzLlxuXG5mdW5jdGlvbiBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsIG9wZXJhdG9yLCBzdGFja1N0YXJ0RnVuY3Rpb24pIHtcbiAgdGhyb3cgbmV3IGFzc2VydC5Bc3NlcnRpb25FcnJvcih7XG4gICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICBhY3R1YWw6IGFjdHVhbCxcbiAgICBleHBlY3RlZDogZXhwZWN0ZWQsXG4gICAgb3BlcmF0b3I6IG9wZXJhdG9yLFxuICAgIHN0YWNrU3RhcnRGdW5jdGlvbjogc3RhY2tTdGFydEZ1bmN0aW9uXG4gIH0pO1xufVxuXG4vLyBFWFRFTlNJT04hIGFsbG93cyBmb3Igd2VsbCBiZWhhdmVkIGVycm9ycyBkZWZpbmVkIGVsc2V3aGVyZS5cbmFzc2VydC5mYWlsID0gZmFpbDtcblxuLy8gNC4gUHVyZSBhc3NlcnRpb24gdGVzdHMgd2hldGhlciBhIHZhbHVlIGlzIHRydXRoeSwgYXMgZGV0ZXJtaW5lZFxuLy8gYnkgISFndWFyZC5cbi8vIGFzc2VydC5vayhndWFyZCwgbWVzc2FnZV9vcHQpO1xuLy8gVGhpcyBzdGF0ZW1lbnQgaXMgZXF1aXZhbGVudCB0byBhc3NlcnQuZXF1YWwodHJ1ZSwgISFndWFyZCxcbi8vIG1lc3NhZ2Vfb3B0KTsuIFRvIHRlc3Qgc3RyaWN0bHkgZm9yIHRoZSB2YWx1ZSB0cnVlLCB1c2Vcbi8vIGFzc2VydC5zdHJpY3RFcXVhbCh0cnVlLCBndWFyZCwgbWVzc2FnZV9vcHQpOy5cblxuZnVuY3Rpb24gb2sodmFsdWUsIG1lc3NhZ2UpIHtcbiAgaWYgKCF2YWx1ZSkgZmFpbCh2YWx1ZSwgdHJ1ZSwgbWVzc2FnZSwgJz09JywgYXNzZXJ0Lm9rKTtcbn1cbmFzc2VydC5vayA9IG9rO1xuXG4vLyA1LiBUaGUgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHNoYWxsb3csIGNvZXJjaXZlIGVxdWFsaXR5IHdpdGhcbi8vID09LlxuLy8gYXNzZXJ0LmVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmVxdWFsID0gZnVuY3Rpb24gZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsICE9IGV4cGVjdGVkKSBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PScsIGFzc2VydC5lcXVhbCk7XG59O1xuXG4vLyA2LiBUaGUgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igd2hldGhlciB0d28gb2JqZWN0cyBhcmUgbm90IGVxdWFsXG4vLyB3aXRoICE9IGFzc2VydC5ub3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RFcXVhbCA9IGZ1bmN0aW9uIG5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9JywgYXNzZXJ0Lm5vdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gNy4gVGhlIGVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBhIGRlZXAgZXF1YWxpdHkgcmVsYXRpb24uXG4vLyBhc3NlcnQuZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0LmRlZXBFcXVhbCA9IGZ1bmN0aW9uIGRlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmICghX2RlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJ2RlZXBFcXVhbCcsIGFzc2VydC5kZWVwRXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgLy8gNy4xLiBBbGwgaWRlbnRpY2FsIHZhbHVlcyBhcmUgZXF1aXZhbGVudCwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4gIGlmIChhY3R1YWwgPT09IGV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG5cbiAgfSBlbHNlIGlmICh1dGlsLmlzQnVmZmVyKGFjdHVhbCkgJiYgdXRpbC5pc0J1ZmZlcihleHBlY3RlZCkpIHtcbiAgICBpZiAoYWN0dWFsLmxlbmd0aCAhPSBleHBlY3RlZC5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYWN0dWFsLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoYWN0dWFsW2ldICE9PSBleHBlY3RlZFtpXSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuXG4gIC8vIDcuMi4gSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgRGF0ZSBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgRGF0ZSBvYmplY3QgdGhhdCByZWZlcnMgdG8gdGhlIHNhbWUgdGltZS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzRGF0ZShhY3R1YWwpICYmIHV0aWwuaXNEYXRlKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuZ2V0VGltZSgpID09PSBleHBlY3RlZC5nZXRUaW1lKCk7XG5cbiAgLy8gNy4zIElmIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyBhIFJlZ0V4cCBvYmplY3QsIHRoZSBhY3R1YWwgdmFsdWUgaXNcbiAgLy8gZXF1aXZhbGVudCBpZiBpdCBpcyBhbHNvIGEgUmVnRXhwIG9iamVjdCB3aXRoIHRoZSBzYW1lIHNvdXJjZSBhbmRcbiAgLy8gcHJvcGVydGllcyAoYGdsb2JhbGAsIGBtdWx0aWxpbmVgLCBgbGFzdEluZGV4YCwgYGlnbm9yZUNhc2VgKS5cbiAgfSBlbHNlIGlmICh1dGlsLmlzUmVnRXhwKGFjdHVhbCkgJiYgdXRpbC5pc1JlZ0V4cChleHBlY3RlZCkpIHtcbiAgICByZXR1cm4gYWN0dWFsLnNvdXJjZSA9PT0gZXhwZWN0ZWQuc291cmNlICYmXG4gICAgICAgICAgIGFjdHVhbC5nbG9iYWwgPT09IGV4cGVjdGVkLmdsb2JhbCAmJlxuICAgICAgICAgICBhY3R1YWwubXVsdGlsaW5lID09PSBleHBlY3RlZC5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgYWN0dWFsLmxhc3RJbmRleCA9PT0gZXhwZWN0ZWQubGFzdEluZGV4ICYmXG4gICAgICAgICAgIGFjdHVhbC5pZ25vcmVDYXNlID09PSBleHBlY3RlZC5pZ25vcmVDYXNlO1xuXG4gIC8vIDcuNC4gT3RoZXIgcGFpcnMgdGhhdCBkbyBub3QgYm90aCBwYXNzIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JyxcbiAgLy8gZXF1aXZhbGVuY2UgaXMgZGV0ZXJtaW5lZCBieSA9PS5cbiAgfSBlbHNlIGlmICghdXRpbC5pc09iamVjdChhY3R1YWwpICYmICF1dGlsLmlzT2JqZWN0KGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwgPT0gZXhwZWN0ZWQ7XG5cbiAgLy8gNy41IEZvciBhbGwgb3RoZXIgT2JqZWN0IHBhaXJzLCBpbmNsdWRpbmcgQXJyYXkgb2JqZWN0cywgZXF1aXZhbGVuY2UgaXNcbiAgLy8gZGV0ZXJtaW5lZCBieSBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGFzIHZlcmlmaWVkXG4gIC8vIHdpdGggT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKSwgdGhlIHNhbWUgc2V0IG9mIGtleXNcbiAgLy8gKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksIGVxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeVxuICAvLyBjb3JyZXNwb25kaW5nIGtleSwgYW5kIGFuIGlkZW50aWNhbCAncHJvdG90eXBlJyBwcm9wZXJ0eS4gTm90ZTogdGhpc1xuICAvLyBhY2NvdW50cyBmb3IgYm90aCBuYW1lZCBhbmQgaW5kZXhlZCBwcm9wZXJ0aWVzIG9uIEFycmF5cy5cbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gb2JqRXF1aXYoYWN0dWFsLCBleHBlY3RlZCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNBcmd1bWVudHMob2JqZWN0KSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PSAnW29iamVjdCBBcmd1bWVudHNdJztcbn1cblxuZnVuY3Rpb24gb2JqRXF1aXYoYSwgYikge1xuICBpZiAodXRpbC5pc051bGxPclVuZGVmaW5lZChhKSB8fCB1dGlsLmlzTnVsbE9yVW5kZWZpbmVkKGIpKVxuICAgIHJldHVybiBmYWxzZTtcbiAgLy8gYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LlxuICBpZiAoYS5wcm90b3R5cGUgIT09IGIucHJvdG90eXBlKSByZXR1cm4gZmFsc2U7XG4gIC8vfn5+SSd2ZSBtYW5hZ2VkIHRvIGJyZWFrIE9iamVjdC5rZXlzIHRocm91Z2ggc2NyZXd5IGFyZ3VtZW50cyBwYXNzaW5nLlxuICAvLyAgIENvbnZlcnRpbmcgdG8gYXJyYXkgc29sdmVzIHRoZSBwcm9ibGVtLlxuICBpZiAoaXNBcmd1bWVudHMoYSkpIHtcbiAgICBpZiAoIWlzQXJndW1lbnRzKGIpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGEgPSBwU2xpY2UuY2FsbChhKTtcbiAgICBiID0gcFNsaWNlLmNhbGwoYik7XG4gICAgcmV0dXJuIF9kZWVwRXF1YWwoYSwgYik7XG4gIH1cbiAgdHJ5IHtcbiAgICB2YXIga2EgPSBzaGltcy5rZXlzKGEpLFxuICAgICAgICBrYiA9IHNoaW1zLmtleXMoYiksXG4gICAgICAgIGtleSwgaTtcbiAgfSBjYXRjaCAoZSkgey8vaGFwcGVucyB3aGVuIG9uZSBpcyBhIHN0cmluZyBsaXRlcmFsIGFuZCB0aGUgb3RoZXIgaXNuJ3RcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gaGF2aW5nIHRoZSBzYW1lIG51bWJlciBvZiBvd25lZCBwcm9wZXJ0aWVzIChrZXlzIGluY29ycG9yYXRlc1xuICAvLyBoYXNPd25Qcm9wZXJ0eSlcbiAgaWYgKGthLmxlbmd0aCAhPSBrYi5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvL3RoZSBzYW1lIHNldCBvZiBrZXlzIChhbHRob3VnaCBub3QgbmVjZXNzYXJpbHkgdGhlIHNhbWUgb3JkZXIpLFxuICBrYS5zb3J0KCk7XG4gIGtiLnNvcnQoKTtcbiAgLy9+fn5jaGVhcCBrZXkgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGlmIChrYVtpXSAhPSBrYltpXSlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvL2VxdWl2YWxlbnQgdmFsdWVzIGZvciBldmVyeSBjb3JyZXNwb25kaW5nIGtleSwgYW5kXG4gIC8vfn5+cG9zc2libHkgZXhwZW5zaXZlIGRlZXAgdGVzdFxuICBmb3IgKGkgPSBrYS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGtleSA9IGthW2ldO1xuICAgIGlmICghX2RlZXBFcXVhbChhW2tleV0sIGJba2V5XSkpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gOC4gVGhlIG5vbi1lcXVpdmFsZW5jZSBhc3NlcnRpb24gdGVzdHMgZm9yIGFueSBkZWVwIGluZXF1YWxpdHkuXG4vLyBhc3NlcnQubm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdERlZXBFcXVhbCA9IGZ1bmN0aW9uIG5vdERlZXBFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnbm90RGVlcEVxdWFsJywgYXNzZXJ0Lm5vdERlZXBFcXVhbCk7XG4gIH1cbn07XG5cbi8vIDkuIFRoZSBzdHJpY3QgZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIHN0cmljdCBlcXVhbGl0eSwgYXMgZGV0ZXJtaW5lZCBieSA9PT0uXG4vLyBhc3NlcnQuc3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuc3RyaWN0RXF1YWwgPSBmdW5jdGlvbiBzdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnPT09JywgYXNzZXJ0LnN0cmljdEVxdWFsKTtcbiAgfVxufTtcblxuLy8gMTAuIFRoZSBzdHJpY3Qgbm9uLWVxdWFsaXR5IGFzc2VydGlvbiB0ZXN0cyBmb3Igc3RyaWN0IGluZXF1YWxpdHksIGFzXG4vLyBkZXRlcm1pbmVkIGJ5ICE9PS4gIGFzc2VydC5ub3RTdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5ub3RTdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIG5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICchPT0nLCBhc3NlcnQubm90U3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSB7XG4gIGlmICghYWN0dWFsIHx8ICFleHBlY3RlZCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZXhwZWN0ZWQpID09ICdbb2JqZWN0IFJlZ0V4cF0nKSB7XG4gICAgcmV0dXJuIGV4cGVjdGVkLnRlc3QoYWN0dWFsKTtcbiAgfSBlbHNlIGlmIChhY3R1YWwgaW5zdGFuY2VvZiBleHBlY3RlZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGV4cGVjdGVkLmNhbGwoe30sIGFjdHVhbCkgPT09IHRydWUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gX3Rocm93cyhzaG91bGRUaHJvdywgYmxvY2ssIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIHZhciBhY3R1YWw7XG5cbiAgaWYgKHV0aWwuaXNTdHJpbmcoZXhwZWN0ZWQpKSB7XG4gICAgbWVzc2FnZSA9IGV4cGVjdGVkO1xuICAgIGV4cGVjdGVkID0gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgYmxvY2soKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGFjdHVhbCA9IGU7XG4gIH1cblxuICBtZXNzYWdlID0gKGV4cGVjdGVkICYmIGV4cGVjdGVkLm5hbWUgPyAnICgnICsgZXhwZWN0ZWQubmFtZSArICcpLicgOiAnLicpICtcbiAgICAgICAgICAgIChtZXNzYWdlID8gJyAnICsgbWVzc2FnZSA6ICcuJyk7XG5cbiAgaWYgKHNob3VsZFRocm93ICYmICFhY3R1YWwpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdNaXNzaW5nIGV4cGVjdGVkIGV4Y2VwdGlvbicgKyBtZXNzYWdlKTtcbiAgfVxuXG4gIGlmICghc2hvdWxkVGhyb3cgJiYgZXhwZWN0ZWRFeGNlcHRpb24oYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsICdHb3QgdW53YW50ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKChzaG91bGRUaHJvdyAmJiBhY3R1YWwgJiYgZXhwZWN0ZWQgJiZcbiAgICAgICFleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkgfHwgKCFzaG91bGRUaHJvdyAmJiBhY3R1YWwpKSB7XG4gICAgdGhyb3cgYWN0dWFsO1xuICB9XG59XG5cbi8vIDExLiBFeHBlY3RlZCB0byB0aHJvdyBhbiBlcnJvcjpcbi8vIGFzc2VydC50aHJvd3MoYmxvY2ssIEVycm9yX29wdCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQudGhyb3dzID0gZnVuY3Rpb24oYmxvY2ssIC8qb3B0aW9uYWwqL2Vycm9yLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MuYXBwbHkodGhpcywgW3RydWVdLmNvbmNhdChwU2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG59O1xuXG4vLyBFWFRFTlNJT04hIFRoaXMgaXMgYW5ub3lpbmcgdG8gd3JpdGUgb3V0c2lkZSB0aGlzIG1vZHVsZS5cbmFzc2VydC5kb2VzTm90VGhyb3cgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovbWVzc2FnZSkge1xuICBfdGhyb3dzLmFwcGx5KHRoaXMsIFtmYWxzZV0uY29uY2F0KHBTbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbn07XG5cbmFzc2VydC5pZkVycm9yID0gZnVuY3Rpb24oZXJyKSB7IGlmIChlcnIpIHt0aHJvdyBlcnI7fX07XG59LHtcIl9zaGltc1wiOjUsXCJ1dGlsXCI6N31dLDc6W2Z1bmN0aW9uKHJlcXVpcmUsbW9kdWxlLGV4cG9ydHMpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBzaGltcyA9IHJlcXVpcmUoJ19zaGltcycpO1xuXG52YXIgZm9ybWF0UmVnRXhwID0gLyVbc2RqJV0vZztcbmV4cG9ydHMuZm9ybWF0ID0gZnVuY3Rpb24oZikge1xuICBpZiAoIWlzU3RyaW5nKGYpKSB7XG4gICAgdmFyIG9iamVjdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgb2JqZWN0cy5wdXNoKGluc3BlY3QoYXJndW1lbnRzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHZhciBpID0gMTtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciBsZW4gPSBhcmdzLmxlbmd0aDtcbiAgdmFyIHN0ciA9IFN0cmluZyhmKS5yZXBsYWNlKGZvcm1hdFJlZ0V4cCwgZnVuY3Rpb24oeCkge1xuICAgIGlmICh4ID09PSAnJSUnKSByZXR1cm4gJyUnO1xuICAgIGlmIChpID49IGxlbikgcmV0dXJuIHg7XG4gICAgc3dpdGNoICh4KSB7XG4gICAgICBjYXNlICclcyc6IHJldHVybiBTdHJpbmcoYXJnc1tpKytdKTtcbiAgICAgIGNhc2UgJyVkJzogcmV0dXJuIE51bWJlcihhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWonOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShhcmdzW2krK10pO1xuICAgICAgICB9IGNhdGNoIChfKSB7XG4gICAgICAgICAgcmV0dXJuICdbQ2lyY3VsYXJdJztcbiAgICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9KTtcbiAgZm9yICh2YXIgeCA9IGFyZ3NbaV07IGkgPCBsZW47IHggPSBhcmdzWysraV0pIHtcbiAgICBpZiAoaXNOdWxsKHgpIHx8ICFpc09iamVjdCh4KSkge1xuICAgICAgc3RyICs9ICcgJyArIHg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciArPSAnICcgKyBpbnNwZWN0KHgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RyO1xufTtcblxuLyoqXG4gKiBFY2hvcyB0aGUgdmFsdWUgb2YgYSB2YWx1ZS4gVHJ5cyB0byBwcmludCB0aGUgdmFsdWUgb3V0XG4gKiBpbiB0aGUgYmVzdCB3YXkgcG9zc2libGUgZ2l2ZW4gdGhlIGRpZmZlcmVudCB0eXBlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIFRoZSBvYmplY3QgdG8gcHJpbnQgb3V0LlxuICogQHBhcmFtIHtPYmplY3R9IG9wdHMgT3B0aW9uYWwgb3B0aW9ucyBvYmplY3QgdGhhdCBhbHRlcnMgdGhlIG91dHB1dC5cbiAqL1xuLyogbGVnYWN5OiBvYmosIHNob3dIaWRkZW4sIGRlcHRoLCBjb2xvcnMqL1xuZnVuY3Rpb24gaW5zcGVjdChvYmosIG9wdHMpIHtcbiAgLy8gZGVmYXVsdCBvcHRpb25zXG4gIHZhciBjdHggPSB7XG4gICAgc2VlbjogW10sXG4gICAgc3R5bGl6ZTogc3R5bGl6ZU5vQ29sb3JcbiAgfTtcbiAgLy8gbGVnYWN5Li4uXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDMpIGN0eC5kZXB0aCA9IGFyZ3VtZW50c1syXTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPj0gNCkgY3R4LmNvbG9ycyA9IGFyZ3VtZW50c1szXTtcbiAgaWYgKGlzQm9vbGVhbihvcHRzKSkge1xuICAgIC8vIGxlZ2FjeS4uLlxuICAgIGN0eC5zaG93SGlkZGVuID0gb3B0cztcbiAgfSBlbHNlIGlmIChvcHRzKSB7XG4gICAgLy8gZ290IGFuIFwib3B0aW9uc1wiIG9iamVjdFxuICAgIGV4cG9ydHMuX2V4dGVuZChjdHgsIG9wdHMpO1xuICB9XG4gIC8vIHNldCBkZWZhdWx0IG9wdGlvbnNcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5zaG93SGlkZGVuKSkgY3R4LnNob3dIaWRkZW4gPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5kZXB0aCkpIGN0eC5kZXB0aCA9IDI7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguY29sb3JzKSkgY3R4LmNvbG9ycyA9IGZhbHNlO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmN1c3RvbUluc3BlY3QpKSBjdHguY3VzdG9tSW5zcGVjdCA9IHRydWU7XG4gIGlmIChjdHguY29sb3JzKSBjdHguc3R5bGl6ZSA9IHN0eWxpemVXaXRoQ29sb3I7XG4gIHJldHVybiBmb3JtYXRWYWx1ZShjdHgsIG9iaiwgY3R4LmRlcHRoKTtcbn1cbmV4cG9ydHMuaW5zcGVjdCA9IGluc3BlY3Q7XG5cblxuLy8gaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9BTlNJX2VzY2FwZV9jb2RlI2dyYXBoaWNzXG5pbnNwZWN0LmNvbG9ycyA9IHtcbiAgJ2JvbGQnIDogWzEsIDIyXSxcbiAgJ2l0YWxpYycgOiBbMywgMjNdLFxuICAndW5kZXJsaW5lJyA6IFs0LCAyNF0sXG4gICdpbnZlcnNlJyA6IFs3LCAyN10sXG4gICd3aGl0ZScgOiBbMzcsIDM5XSxcbiAgJ2dyZXknIDogWzkwLCAzOV0sXG4gICdibGFjaycgOiBbMzAsIDM5XSxcbiAgJ2JsdWUnIDogWzM0LCAzOV0sXG4gICdjeWFuJyA6IFszNiwgMzldLFxuICAnZ3JlZW4nIDogWzMyLCAzOV0sXG4gICdtYWdlbnRhJyA6IFszNSwgMzldLFxuICAncmVkJyA6IFszMSwgMzldLFxuICAneWVsbG93JyA6IFszMywgMzldXG59O1xuXG4vLyBEb24ndCB1c2UgJ2JsdWUnIG5vdCB2aXNpYmxlIG9uIGNtZC5leGVcbmluc3BlY3Quc3R5bGVzID0ge1xuICAnc3BlY2lhbCc6ICdjeWFuJyxcbiAgJ251bWJlcic6ICd5ZWxsb3cnLFxuICAnYm9vbGVhbic6ICd5ZWxsb3cnLFxuICAndW5kZWZpbmVkJzogJ2dyZXknLFxuICAnbnVsbCc6ICdib2xkJyxcbiAgJ3N0cmluZyc6ICdncmVlbicsXG4gICdkYXRlJzogJ21hZ2VudGEnLFxuICAvLyBcIm5hbWVcIjogaW50ZW50aW9uYWxseSBub3Qgc3R5bGluZ1xuICAncmVnZXhwJzogJ3JlZCdcbn07XG5cblxuZnVuY3Rpb24gc3R5bGl6ZVdpdGhDb2xvcihzdHIsIHN0eWxlVHlwZSkge1xuICB2YXIgc3R5bGUgPSBpbnNwZWN0LnN0eWxlc1tzdHlsZVR5cGVdO1xuXG4gIGlmIChzdHlsZSkge1xuICAgIHJldHVybiAnXFx1MDAxYlsnICsgaW5zcGVjdC5jb2xvcnNbc3R5bGVdWzBdICsgJ20nICsgc3RyICtcbiAgICAgICAgICAgJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVsxXSArICdtJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG59XG5cblxuZnVuY3Rpb24gc3R5bGl6ZU5vQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgcmV0dXJuIHN0cjtcbn1cblxuXG5mdW5jdGlvbiBhcnJheVRvSGFzaChhcnJheSkge1xuICB2YXIgaGFzaCA9IHt9O1xuXG4gIHNoaW1zLmZvckVhY2goYXJyYXksIGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMpO1xuICAgIGlmICghaXNTdHJpbmcocmV0KSkge1xuICAgICAgcmV0ID0gZm9ybWF0VmFsdWUoY3R4LCByZXQsIHJlY3Vyc2VUaW1lcyk7XG4gICAgfVxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvLyBQcmltaXRpdmUgdHlwZXMgY2Fubm90IGhhdmUgcHJvcGVydGllc1xuICB2YXIgcHJpbWl0aXZlID0gZm9ybWF0UHJpbWl0aXZlKGN0eCwgdmFsdWUpO1xuICBpZiAocHJpbWl0aXZlKSB7XG4gICAgcmV0dXJuIHByaW1pdGl2ZTtcbiAgfVxuXG4gIC8vIExvb2sgdXAgdGhlIGtleXMgb2YgdGhlIG9iamVjdC5cbiAgdmFyIGtleXMgPSBzaGltcy5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IHNoaW1zLmdldE93blByb3BlcnR5TmFtZXModmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG5cbiAgc2hpbXMuZm9yRWFjaChrZXlzLCBmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBzaGltcy5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodmFsdWUsIGtleSkgfHwgeyB2YWx1ZTogdmFsdWVba2V5XSB9O1xuICBpZiAoZGVzYy5nZXQpIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbR2V0dGVyL1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZGVzYy5zZXQpIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbU2V0dGVyXScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh2aXNpYmxlS2V5cywga2V5KSkge1xuICAgIG5hbWUgPSAnWycgKyBrZXkgKyAnXSc7XG4gIH1cbiAgaWYgKCFzdHIpIHtcbiAgICBpZiAoc2hpbXMuaW5kZXhPZihjdHguc2VlbiwgZGVzYy52YWx1ZSkgPCAwKSB7XG4gICAgICBpZiAoaXNOdWxsKHJlY3Vyc2VUaW1lcykpIHtcbiAgICAgICAgc3RyID0gZm9ybWF0VmFsdWUoY3R4LCBkZXNjLnZhbHVlLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgcmVjdXJzZVRpbWVzIC0gMSk7XG4gICAgICB9XG4gICAgICBpZiAoc3RyLmluZGV4T2YoJ1xcbicpID4gLTEpIHtcbiAgICAgICAgaWYgKGFycmF5KSB7XG4gICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCdcXG4nKS5tYXAoZnVuY3Rpb24obGluZSkge1xuICAgICAgICAgICAgcmV0dXJuICcgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpLnN1YnN0cigyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzdHIgPSAnXFxuJyArIHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAgJyArIGxpbmU7XG4gICAgICAgICAgfSkuam9pbignXFxuJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tDaXJjdWxhcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNVbmRlZmluZWQobmFtZSkpIHtcbiAgICBpZiAoYXJyYXkgJiYga2V5Lm1hdGNoKC9eXFxkKyQvKSkge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gICAgbmFtZSA9IEpTT04uc3RyaW5naWZ5KCcnICsga2V5KTtcbiAgICBpZiAobmFtZS5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLykpIHtcbiAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cigxLCBuYW1lLmxlbmd0aCAtIDIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICduYW1lJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSBuYW1lLnJlcGxhY2UoLycvZywgXCJcXFxcJ1wiKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFwiL2csICdcIicpXG4gICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oXlwifFwiJCkvZywgXCInXCIpO1xuICAgICAgbmFtZSA9IGN0eC5zdHlsaXplKG5hbWUsICdzdHJpbmcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZSArICc6ICcgKyBzdHI7XG59XG5cblxuZnVuY3Rpb24gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpIHtcbiAgdmFyIG51bUxpbmVzRXN0ID0gMDtcbiAgdmFyIGxlbmd0aCA9IHNoaW1zLnJlZHVjZShvdXRwdXQsIGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBzaGltcy5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZztcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJiBvYmplY3RUb1N0cmluZyhlKSA9PT0gJ1tvYmplY3QgRXJyb3JdJztcbn1cbmV4cG9ydHMuaXNFcnJvciA9IGlzRXJyb3I7XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nO1xufVxuZXhwb3J0cy5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcblxuZnVuY3Rpb24gaXNQcmltaXRpdmUoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGwgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3ltYm9sJyB8fCAgLy8gRVM2IHN5bWJvbFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3VuZGVmaW5lZCc7XG59XG5leHBvcnRzLmlzUHJpbWl0aXZlID0gaXNQcmltaXRpdmU7XG5cbmZ1bmN0aW9uIGlzQnVmZmVyKGFyZykge1xuICByZXR1cm4gYXJnIGluc3RhbmNlb2YgQnVmZmVyO1xufVxuZXhwb3J0cy5pc0J1ZmZlciA9IGlzQnVmZmVyO1xuXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyhvKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7XG59XG5cblxuZnVuY3Rpb24gcGFkKG4pIHtcbiAgcmV0dXJuIG4gPCAxMCA/ICcwJyArIG4udG9TdHJpbmcoMTApIDogbi50b1N0cmluZygxMCk7XG59XG5cblxudmFyIG1vbnRocyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLFxuICAgICAgICAgICAgICAnT2N0JywgJ05vdicsICdEZWMnXTtcblxuLy8gMjYgRmViIDE2OjE5OjM0XG5mdW5jdGlvbiB0aW1lc3RhbXAoKSB7XG4gIHZhciBkID0gbmV3IERhdGUoKTtcbiAgdmFyIHRpbWUgPSBbcGFkKGQuZ2V0SG91cnMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldE1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgIHBhZChkLmdldFNlY29uZHMoKSldLmpvaW4oJzonKTtcbiAgcmV0dXJuIFtkLmdldERhdGUoKSwgbW9udGhzW2QuZ2V0TW9udGgoKV0sIHRpbWVdLmpvaW4oJyAnKTtcbn1cblxuXG4vLyBsb2cgaXMganVzdCBhIHRoaW4gd3JhcHBlciB0byBjb25zb2xlLmxvZyB0aGF0IHByZXBlbmRzIGEgdGltZXN0YW1wXG5leHBvcnRzLmxvZyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLmxvZygnJXMgLSAlcycsIHRpbWVzdGFtcCgpLCBleHBvcnRzLmZvcm1hdC5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpKTtcbn07XG5cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXIuXG4gKlxuICogVGhlIEZ1bmN0aW9uLnByb3RvdHlwZS5pbmhlcml0cyBmcm9tIGxhbmcuanMgcmV3cml0dGVuIGFzIGEgc3RhbmRhbG9uZVxuICogZnVuY3Rpb24gKG5vdCBvbiBGdW5jdGlvbi5wcm90b3R5cGUpLiBOT1RFOiBJZiB0aGlzIGZpbGUgaXMgdG8gYmUgbG9hZGVkXG4gKiBkdXJpbmcgYm9vdHN0cmFwcGluZyB0aGlzIGZ1bmN0aW9uIG5lZWRzIHRvIGJlIHJld3JpdHRlbiB1c2luZyBzb21lIG5hdGl2ZVxuICogZnVuY3Rpb25zIGFzIHByb3RvdHlwZSBzZXR1cCB1c2luZyBub3JtYWwgSmF2YVNjcmlwdCBkb2VzIG5vdCB3b3JrIGFzXG4gKiBleHBlY3RlZCBkdXJpbmcgYm9vdHN0cmFwcGluZyAoc2VlIG1pcnJvci5qcyBpbiByMTE0OTAzKS5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHdoaWNoIG5lZWRzIHRvIGluaGVyaXQgdGhlXG4gKiAgICAgcHJvdG90eXBlLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gc3VwZXJDdG9yIENvbnN0cnVjdG9yIGZ1bmN0aW9uIHRvIGluaGVyaXQgcHJvdG90eXBlIGZyb20uXG4gKi9cbmV4cG9ydHMuaW5oZXJpdHMgPSBmdW5jdGlvbihjdG9yLCBzdXBlckN0b3IpIHtcbiAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG4gIGN0b3IucHJvdG90eXBlID0gc2hpbXMuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IGN0b3IsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcbn07XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBzaGltcy5rZXlzKGFkZCk7XG4gIHZhciBpID0ga2V5cy5sZW5ndGg7XG4gIHdoaWxlIChpLS0pIHtcbiAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gIH1cbiAgcmV0dXJuIG9yaWdpbjtcbn07XG5cbmZ1bmN0aW9uIGhhc093blByb3BlcnR5KG9iaiwgcHJvcCkge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbn0se1wiX3NoaW1zXCI6NX1dfSx7fSxbXSlcbjs7bW9kdWxlLmV4cG9ydHM9cmVxdWlyZShcImJ1ZmZlci1icm93c2VyaWZ5XCIpXG4iLCIvLyBzaGltIGZvciB1c2luZyBwcm9jZXNzIGluIGJyb3dzZXJcblxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG5wcm9jZXNzLm5leHRUaWNrID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgY2FuU2V0SW1tZWRpYXRlID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cuc2V0SW1tZWRpYXRlO1xuICAgIHZhciBjYW5Qb3N0ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAmJiB3aW5kb3cucG9zdE1lc3NhZ2UgJiYgd2luZG93LmFkZEV2ZW50TGlzdGVuZXJcbiAgICA7XG5cbiAgICBpZiAoY2FuU2V0SW1tZWRpYXRlKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZikgeyByZXR1cm4gd2luZG93LnNldEltbWVkaWF0ZShmKSB9O1xuICAgIH1cblxuICAgIGlmIChjYW5Qb3N0KSB7XG4gICAgICAgIHZhciBxdWV1ZSA9IFtdO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgdmFyIHNvdXJjZSA9IGV2LnNvdXJjZTtcbiAgICAgICAgICAgIGlmICgoc291cmNlID09PSB3aW5kb3cgfHwgc291cmNlID09PSBudWxsKSAmJiBldi5kYXRhID09PSAncHJvY2Vzcy10aWNrJykge1xuICAgICAgICAgICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgIGlmIChxdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBmbiA9IHF1ZXVlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0cnVlKTtcblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gbmV4dFRpY2soZm4pIHtcbiAgICAgICAgICAgIHF1ZXVlLnB1c2goZm4pO1xuICAgICAgICAgICAgd2luZG93LnBvc3RNZXNzYWdlKCdwcm9jZXNzLXRpY2snLCAnKicpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICBzZXRUaW1lb3V0KGZuLCAwKTtcbiAgICB9O1xufSkoKTtcblxucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5cbnByb2Nlc3MuYmluZGluZyA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZCcpO1xufVxuXG4vLyBUT0RPKHNodHlsbWFuKVxucHJvY2Vzcy5jd2QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiAnLycgfTtcbnByb2Nlc3MuY2hkaXIgPSBmdW5jdGlvbiAoZGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG4iLCJ2YXIgalF1ZXJ5ID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbi8qIVxuICogalF1ZXJ5IFVJIENvcmUgMS4xMC40XG4gKiBodHRwOi8vanF1ZXJ5dWkuY29tXG4gKlxuICogQ29weXJpZ2h0IDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIGh0dHA6Ly9hcGkuanF1ZXJ5dWkuY29tL2NhdGVnb3J5L3VpLWNvcmUvXG4gKi9cbihmdW5jdGlvbiggJCwgdW5kZWZpbmVkICkge1xuXG52YXIgdXVpZCA9IDAsXG5cdHJ1bmlxdWVJZCA9IC9edWktaWQtXFxkKyQvO1xuXG4vLyAkLnVpIG1pZ2h0IGV4aXN0IGZyb20gY29tcG9uZW50cyB3aXRoIG5vIGRlcGVuZGVuY2llcywgZS5nLiwgJC51aS5wb3NpdGlvblxuJC51aSA9ICQudWkgfHwge307XG5cbiQuZXh0ZW5kKCAkLnVpLCB7XG5cdHZlcnNpb246IFwiMS4xMC40XCIsXG5cblx0a2V5Q29kZToge1xuXHRcdEJBQ0tTUEFDRTogOCxcblx0XHRDT01NQTogMTg4LFxuXHRcdERFTEVURTogNDYsXG5cdFx0RE9XTjogNDAsXG5cdFx0RU5EOiAzNSxcblx0XHRFTlRFUjogMTMsXG5cdFx0RVNDQVBFOiAyNyxcblx0XHRIT01FOiAzNixcblx0XHRMRUZUOiAzNyxcblx0XHROVU1QQURfQUREOiAxMDcsXG5cdFx0TlVNUEFEX0RFQ0lNQUw6IDExMCxcblx0XHROVU1QQURfRElWSURFOiAxMTEsXG5cdFx0TlVNUEFEX0VOVEVSOiAxMDgsXG5cdFx0TlVNUEFEX01VTFRJUExZOiAxMDYsXG5cdFx0TlVNUEFEX1NVQlRSQUNUOiAxMDksXG5cdFx0UEFHRV9ET1dOOiAzNCxcblx0XHRQQUdFX1VQOiAzMyxcblx0XHRQRVJJT0Q6IDE5MCxcblx0XHRSSUdIVDogMzksXG5cdFx0U1BBQ0U6IDMyLFxuXHRcdFRBQjogOSxcblx0XHRVUDogMzhcblx0fVxufSk7XG5cbi8vIHBsdWdpbnNcbiQuZm4uZXh0ZW5kKHtcblx0Zm9jdXM6IChmdW5jdGlvbiggb3JpZyApIHtcblx0XHRyZXR1cm4gZnVuY3Rpb24oIGRlbGF5LCBmbiApIHtcblx0XHRcdHJldHVybiB0eXBlb2YgZGVsYXkgPT09IFwibnVtYmVyXCIgP1xuXHRcdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXHRcdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHQkKCBlbGVtICkuZm9jdXMoKTtcblx0XHRcdFx0XHRcdGlmICggZm4gKSB7XG5cdFx0XHRcdFx0XHRcdGZuLmNhbGwoIGVsZW0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9LCBkZWxheSApO1xuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdG9yaWcuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdH07XG5cdH0pKCAkLmZuLmZvY3VzICksXG5cblx0c2Nyb2xsUGFyZW50OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgc2Nyb2xsUGFyZW50O1xuXHRcdGlmICgoJC51aS5pZSAmJiAoLyhzdGF0aWN8cmVsYXRpdmUpLykudGVzdCh0aGlzLmNzcyhcInBvc2l0aW9uXCIpKSkgfHwgKC9hYnNvbHV0ZS8pLnRlc3QodGhpcy5jc3MoXCJwb3NpdGlvblwiKSkpIHtcblx0XHRcdHNjcm9sbFBhcmVudCA9IHRoaXMucGFyZW50cygpLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICgvKHJlbGF0aXZlfGFic29sdXRlfGZpeGVkKS8pLnRlc3QoJC5jc3ModGhpcyxcInBvc2l0aW9uXCIpKSAmJiAoLyhhdXRvfHNjcm9sbCkvKS50ZXN0KCQuY3NzKHRoaXMsXCJvdmVyZmxvd1wiKSskLmNzcyh0aGlzLFwib3ZlcmZsb3cteVwiKSskLmNzcyh0aGlzLFwib3ZlcmZsb3cteFwiKSk7XG5cdFx0XHR9KS5lcSgwKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0c2Nyb2xsUGFyZW50ID0gdGhpcy5wYXJlbnRzKCkuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gKC8oYXV0b3xzY3JvbGwpLykudGVzdCgkLmNzcyh0aGlzLFwib3ZlcmZsb3dcIikrJC5jc3ModGhpcyxcIm92ZXJmbG93LXlcIikrJC5jc3ModGhpcyxcIm92ZXJmbG93LXhcIikpO1xuXHRcdFx0fSkuZXEoMCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuICgvZml4ZWQvKS50ZXN0KHRoaXMuY3NzKFwicG9zaXRpb25cIikpIHx8ICFzY3JvbGxQYXJlbnQubGVuZ3RoID8gJChkb2N1bWVudCkgOiBzY3JvbGxQYXJlbnQ7XG5cdH0sXG5cblx0ekluZGV4OiBmdW5jdGlvbiggekluZGV4ICkge1xuXHRcdGlmICggekluZGV4ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5jc3MoIFwiekluZGV4XCIsIHpJbmRleCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHR2YXIgZWxlbSA9ICQoIHRoaXNbIDAgXSApLCBwb3NpdGlvbiwgdmFsdWU7XG5cdFx0XHR3aGlsZSAoIGVsZW0ubGVuZ3RoICYmIGVsZW1bIDAgXSAhPT0gZG9jdW1lbnQgKSB7XG5cdFx0XHRcdC8vIElnbm9yZSB6LWluZGV4IGlmIHBvc2l0aW9uIGlzIHNldCB0byBhIHZhbHVlIHdoZXJlIHotaW5kZXggaXMgaWdub3JlZCBieSB0aGUgYnJvd3NlclxuXHRcdFx0XHQvLyBUaGlzIG1ha2VzIGJlaGF2aW9yIG9mIHRoaXMgZnVuY3Rpb24gY29uc2lzdGVudCBhY3Jvc3MgYnJvd3NlcnNcblx0XHRcdFx0Ly8gV2ViS2l0IGFsd2F5cyByZXR1cm5zIGF1dG8gaWYgdGhlIGVsZW1lbnQgaXMgcG9zaXRpb25lZFxuXHRcdFx0XHRwb3NpdGlvbiA9IGVsZW0uY3NzKCBcInBvc2l0aW9uXCIgKTtcblx0XHRcdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcInJlbGF0aXZlXCIgfHwgcG9zaXRpb24gPT09IFwiZml4ZWRcIiApIHtcblx0XHRcdFx0XHQvLyBJRSByZXR1cm5zIDAgd2hlbiB6SW5kZXggaXMgbm90IHNwZWNpZmllZFxuXHRcdFx0XHRcdC8vIG90aGVyIGJyb3dzZXJzIHJldHVybiBhIHN0cmluZ1xuXHRcdFx0XHRcdC8vIHdlIGlnbm9yZSB0aGUgY2FzZSBvZiBuZXN0ZWQgZWxlbWVudHMgd2l0aCBhbiBleHBsaWNpdCB2YWx1ZSBvZiAwXG5cdFx0XHRcdFx0Ly8gPGRpdiBzdHlsZT1cInotaW5kZXg6IC0xMDtcIj48ZGl2IHN0eWxlPVwiei1pbmRleDogMDtcIj48L2Rpdj48L2Rpdj5cblx0XHRcdFx0XHR2YWx1ZSA9IHBhcnNlSW50KCBlbGVtLmNzcyggXCJ6SW5kZXhcIiApLCAxMCApO1xuXHRcdFx0XHRcdGlmICggIWlzTmFOKCB2YWx1ZSApICYmIHZhbHVlICE9PSAwICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbGVtID0gZWxlbS5wYXJlbnQoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gMDtcblx0fSxcblxuXHR1bmlxdWVJZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIXRoaXMuaWQgKSB7XG5cdFx0XHRcdHRoaXMuaWQgPSBcInVpLWlkLVwiICsgKCsrdXVpZCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0cmVtb3ZlVW5pcXVlSWQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHJ1bmlxdWVJZC50ZXN0KCB0aGlzLmlkICkgKSB7XG5cdFx0XHRcdCQoIHRoaXMgKS5yZW1vdmVBdHRyKCBcImlkXCIgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSk7XG5cbi8vIHNlbGVjdG9yc1xuZnVuY3Rpb24gZm9jdXNhYmxlKCBlbGVtZW50LCBpc1RhYkluZGV4Tm90TmFOICkge1xuXHR2YXIgbWFwLCBtYXBOYW1lLCBpbWcsXG5cdFx0bm9kZU5hbWUgPSBlbGVtZW50Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdGlmICggXCJhcmVhXCIgPT09IG5vZGVOYW1lICkge1xuXHRcdG1hcCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcblx0XHRtYXBOYW1lID0gbWFwLm5hbWU7XG5cdFx0aWYgKCAhZWxlbWVudC5ocmVmIHx8ICFtYXBOYW1lIHx8IG1hcC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSBcIm1hcFwiICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRpbWcgPSAkKCBcImltZ1t1c2VtYXA9I1wiICsgbWFwTmFtZSArIFwiXVwiIClbMF07XG5cdFx0cmV0dXJuICEhaW1nICYmIHZpc2libGUoIGltZyApO1xuXHR9XG5cdHJldHVybiAoIC9pbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9ufG9iamVjdC8udGVzdCggbm9kZU5hbWUgKSA/XG5cdFx0IWVsZW1lbnQuZGlzYWJsZWQgOlxuXHRcdFwiYVwiID09PSBub2RlTmFtZSA/XG5cdFx0XHRlbGVtZW50LmhyZWYgfHwgaXNUYWJJbmRleE5vdE5hTiA6XG5cdFx0XHRpc1RhYkluZGV4Tm90TmFOKSAmJlxuXHRcdC8vIHRoZSBlbGVtZW50IGFuZCBhbGwgb2YgaXRzIGFuY2VzdG9ycyBtdXN0IGJlIHZpc2libGVcblx0XHR2aXNpYmxlKCBlbGVtZW50ICk7XG59XG5cbmZ1bmN0aW9uIHZpc2libGUoIGVsZW1lbnQgKSB7XG5cdHJldHVybiAkLmV4cHIuZmlsdGVycy52aXNpYmxlKCBlbGVtZW50ICkgJiZcblx0XHQhJCggZWxlbWVudCApLnBhcmVudHMoKS5hZGRCYWNrKCkuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuICQuY3NzKCB0aGlzLCBcInZpc2liaWxpdHlcIiApID09PSBcImhpZGRlblwiO1xuXHRcdH0pLmxlbmd0aDtcbn1cblxuJC5leHRlbmQoICQuZXhwclsgXCI6XCIgXSwge1xuXHRkYXRhOiAkLmV4cHIuY3JlYXRlUHNldWRvID9cblx0XHQkLmV4cHIuY3JlYXRlUHNldWRvKGZ1bmN0aW9uKCBkYXRhTmFtZSApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuICEhJC5kYXRhKCBlbGVtLCBkYXRhTmFtZSApO1xuXHRcdFx0fTtcblx0XHR9KSA6XG5cdFx0Ly8gc3VwcG9ydDogalF1ZXJ5IDwxLjhcblx0XHRmdW5jdGlvbiggZWxlbSwgaSwgbWF0Y2ggKSB7XG5cdFx0XHRyZXR1cm4gISEkLmRhdGEoIGVsZW0sIG1hdGNoWyAzIF0gKTtcblx0XHR9LFxuXG5cdGZvY3VzYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdFx0cmV0dXJuIGZvY3VzYWJsZSggZWxlbWVudCwgIWlzTmFOKCAkLmF0dHIoIGVsZW1lbnQsIFwidGFiaW5kZXhcIiApICkgKTtcblx0fSxcblxuXHR0YWJiYWJsZTogZnVuY3Rpb24oIGVsZW1lbnQgKSB7XG5cdFx0dmFyIHRhYkluZGV4ID0gJC5hdHRyKCBlbGVtZW50LCBcInRhYmluZGV4XCIgKSxcblx0XHRcdGlzVGFiSW5kZXhOYU4gPSBpc05hTiggdGFiSW5kZXggKTtcblx0XHRyZXR1cm4gKCBpc1RhYkluZGV4TmFOIHx8IHRhYkluZGV4ID49IDAgKSAmJiBmb2N1c2FibGUoIGVsZW1lbnQsICFpc1RhYkluZGV4TmFOICk7XG5cdH1cbn0pO1xuXG4vLyBzdXBwb3J0OiBqUXVlcnkgPDEuOFxuaWYgKCAhJCggXCI8YT5cIiApLm91dGVyV2lkdGgoIDEgKS5qcXVlcnkgKSB7XG5cdCQuZWFjaCggWyBcIldpZHRoXCIsIFwiSGVpZ2h0XCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdFx0dmFyIHNpZGUgPSBuYW1lID09PSBcIldpZHRoXCIgPyBbIFwiTGVmdFwiLCBcIlJpZ2h0XCIgXSA6IFsgXCJUb3BcIiwgXCJCb3R0b21cIiBdLFxuXHRcdFx0dHlwZSA9IG5hbWUudG9Mb3dlckNhc2UoKSxcblx0XHRcdG9yaWcgPSB7XG5cdFx0XHRcdGlubmVyV2lkdGg6ICQuZm4uaW5uZXJXaWR0aCxcblx0XHRcdFx0aW5uZXJIZWlnaHQ6ICQuZm4uaW5uZXJIZWlnaHQsXG5cdFx0XHRcdG91dGVyV2lkdGg6ICQuZm4ub3V0ZXJXaWR0aCxcblx0XHRcdFx0b3V0ZXJIZWlnaHQ6ICQuZm4ub3V0ZXJIZWlnaHRcblx0XHRcdH07XG5cblx0XHRmdW5jdGlvbiByZWR1Y2UoIGVsZW0sIHNpemUsIGJvcmRlciwgbWFyZ2luICkge1xuXHRcdFx0JC5lYWNoKCBzaWRlLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2l6ZSAtPSBwYXJzZUZsb2F0KCAkLmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyB0aGlzICkgKSB8fCAwO1xuXHRcdFx0XHRpZiAoIGJvcmRlciApIHtcblx0XHRcdFx0XHRzaXplIC09IHBhcnNlRmxvYXQoICQuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgdGhpcyArIFwiV2lkdGhcIiApICkgfHwgMDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIG1hcmdpbiApIHtcblx0XHRcdFx0XHRzaXplIC09IHBhcnNlRmxvYXQoICQuY3NzKCBlbGVtLCBcIm1hcmdpblwiICsgdGhpcyApICkgfHwgMDtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gc2l6ZTtcblx0XHR9XG5cblx0XHQkLmZuWyBcImlubmVyXCIgKyBuYW1lIF0gPSBmdW5jdGlvbiggc2l6ZSApIHtcblx0XHRcdGlmICggc2l6ZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gb3JpZ1sgXCJpbm5lclwiICsgbmFtZSBdLmNhbGwoIHRoaXMgKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0JCggdGhpcyApLmNzcyggdHlwZSwgcmVkdWNlKCB0aGlzLCBzaXplICkgKyBcInB4XCIgKTtcblx0XHRcdH0pO1xuXHRcdH07XG5cblx0XHQkLmZuWyBcIm91dGVyXCIgKyBuYW1lXSA9IGZ1bmN0aW9uKCBzaXplLCBtYXJnaW4gKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBzaXplICE9PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRyZXR1cm4gb3JpZ1sgXCJvdXRlclwiICsgbmFtZSBdLmNhbGwoIHRoaXMsIHNpemUgKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0JCggdGhpcykuY3NzKCB0eXBlLCByZWR1Y2UoIHRoaXMsIHNpemUsIHRydWUsIG1hcmdpbiApICsgXCJweFwiICk7XG5cdFx0XHR9KTtcblx0XHR9O1xuXHR9KTtcbn1cblxuLy8gc3VwcG9ydDogalF1ZXJ5IDwxLjhcbmlmICggISQuZm4uYWRkQmFjayApIHtcblx0JC5mbi5hZGRCYWNrID0gZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLmFkZCggc2VsZWN0b3IgPT0gbnVsbCA/XG5cdFx0XHR0aGlzLnByZXZPYmplY3QgOiB0aGlzLnByZXZPYmplY3QuZmlsdGVyKCBzZWxlY3RvciApXG5cdFx0KTtcblx0fTtcbn1cblxuLy8gc3VwcG9ydDogalF1ZXJ5IDEuNi4xLCAxLjYuMiAoaHR0cDovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvOTQxMylcbmlmICggJCggXCI8YT5cIiApLmRhdGEoIFwiYS1iXCIsIFwiYVwiICkucmVtb3ZlRGF0YSggXCJhLWJcIiApLmRhdGEoIFwiYS1iXCIgKSApIHtcblx0JC5mbi5yZW1vdmVEYXRhID0gKGZ1bmN0aW9uKCByZW1vdmVEYXRhICkge1xuXHRcdHJldHVybiBmdW5jdGlvbigga2V5ICkge1xuXHRcdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRyZXR1cm4gcmVtb3ZlRGF0YS5jYWxsKCB0aGlzLCAkLmNhbWVsQ2FzZSgga2V5ICkgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiByZW1vdmVEYXRhLmNhbGwoIHRoaXMgKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9KSggJC5mbi5yZW1vdmVEYXRhICk7XG59XG5cblxuXG5cblxuLy8gZGVwcmVjYXRlZFxuJC51aS5pZSA9ICEhL21zaWUgW1xcdy5dKy8uZXhlYyggbmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpICk7XG5cbiQuc3VwcG9ydC5zZWxlY3RzdGFydCA9IFwib25zZWxlY3RzdGFydFwiIGluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcbiQuZm4uZXh0ZW5kKHtcblx0ZGlzYWJsZVNlbGVjdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuYmluZCggKCAkLnN1cHBvcnQuc2VsZWN0c3RhcnQgPyBcInNlbGVjdHN0YXJ0XCIgOiBcIm1vdXNlZG93blwiICkgK1xuXHRcdFx0XCIudWktZGlzYWJsZVNlbGVjdGlvblwiLCBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHR9KTtcblx0fSxcblxuXHRlbmFibGVTZWxlY3Rpb246IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnVuYmluZCggXCIudWktZGlzYWJsZVNlbGVjdGlvblwiICk7XG5cdH1cbn0pO1xuXG4kLmV4dGVuZCggJC51aSwge1xuXHQvLyAkLnVpLnBsdWdpbiBpcyBkZXByZWNhdGVkLiBVc2UgJC53aWRnZXQoKSBleHRlbnNpb25zIGluc3RlYWQuXG5cdHBsdWdpbjoge1xuXHRcdGFkZDogZnVuY3Rpb24oIG1vZHVsZSwgb3B0aW9uLCBzZXQgKSB7XG5cdFx0XHR2YXIgaSxcblx0XHRcdFx0cHJvdG8gPSAkLnVpWyBtb2R1bGUgXS5wcm90b3R5cGU7XG5cdFx0XHRmb3IgKCBpIGluIHNldCApIHtcblx0XHRcdFx0cHJvdG8ucGx1Z2luc1sgaSBdID0gcHJvdG8ucGx1Z2luc1sgaSBdIHx8IFtdO1xuXHRcdFx0XHRwcm90by5wbHVnaW5zWyBpIF0ucHVzaCggWyBvcHRpb24sIHNldFsgaSBdIF0gKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdGNhbGw6IGZ1bmN0aW9uKCBpbnN0YW5jZSwgbmFtZSwgYXJncyApIHtcblx0XHRcdHZhciBpLFxuXHRcdFx0XHRzZXQgPSBpbnN0YW5jZS5wbHVnaW5zWyBuYW1lIF07XG5cdFx0XHRpZiAoICFzZXQgfHwgIWluc3RhbmNlLmVsZW1lbnRbIDAgXS5wYXJlbnROb2RlIHx8IGluc3RhbmNlLmVsZW1lbnRbIDAgXS5wYXJlbnROb2RlLm5vZGVUeXBlID09PSAxMSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBpbnN0YW5jZS5vcHRpb25zWyBzZXRbIGkgXVsgMCBdIF0gKSB7XG5cdFx0XHRcdFx0c2V0WyBpIF1bIDEgXS5hcHBseSggaW5zdGFuY2UuZWxlbWVudCwgYXJncyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIG9ubHkgdXNlZCBieSByZXNpemFibGVcblx0aGFzU2Nyb2xsOiBmdW5jdGlvbiggZWwsIGEgKSB7XG5cblx0XHQvL0lmIG92ZXJmbG93IGlzIGhpZGRlbiwgdGhlIGVsZW1lbnQgbWlnaHQgaGF2ZSBleHRyYSBjb250ZW50LCBidXQgdGhlIHVzZXIgd2FudHMgdG8gaGlkZSBpdFxuXHRcdGlmICggJCggZWwgKS5jc3MoIFwib3ZlcmZsb3dcIiApID09PSBcImhpZGRlblwiKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0dmFyIHNjcm9sbCA9ICggYSAmJiBhID09PSBcImxlZnRcIiApID8gXCJzY3JvbGxMZWZ0XCIgOiBcInNjcm9sbFRvcFwiLFxuXHRcdFx0aGFzID0gZmFsc2U7XG5cblx0XHRpZiAoIGVsWyBzY3JvbGwgXSA+IDAgKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHQvLyBUT0RPOiBkZXRlcm1pbmUgd2hpY2ggY2FzZXMgYWN0dWFsbHkgY2F1c2UgdGhpcyB0byBoYXBwZW5cblx0XHQvLyBpZiB0aGUgZWxlbWVudCBkb2Vzbid0IGhhdmUgdGhlIHNjcm9sbCBzZXQsIHNlZSBpZiBpdCdzIHBvc3NpYmxlIHRvXG5cdFx0Ly8gc2V0IHRoZSBzY3JvbGxcblx0XHRlbFsgc2Nyb2xsIF0gPSAxO1xuXHRcdGhhcyA9ICggZWxbIHNjcm9sbCBdID4gMCApO1xuXHRcdGVsWyBzY3JvbGwgXSA9IDA7XG5cdFx0cmV0dXJuIGhhcztcblx0fVxufSk7XG5cbn0pKCBqUXVlcnkgKTtcbiIsInZhciBqUXVlcnkgPSByZXF1aXJlKCdqcXVlcnknKTtcbnJlcXVpcmUoJy4vY29yZScpO1xuXG4vKiFcbiAqIGpRdWVyeSBVSSBEYXRlcGlja2VyIDEuMTAuNFxuICogaHR0cDovL2pxdWVyeXVpLmNvbVxuICpcbiAqIENvcHlyaWdodCAyMDE0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBodHRwOi8vYXBpLmpxdWVyeXVpLmNvbS9kYXRlcGlja2VyL1xuICpcbiAqIERlcGVuZHM6XG4gKlx0anF1ZXJ5LnVpLmNvcmUuanNcbiAqL1xuKGZ1bmN0aW9uKCAkLCB1bmRlZmluZWQgKSB7XG5cbiQuZXh0ZW5kKCQudWksIHsgZGF0ZXBpY2tlcjogeyB2ZXJzaW9uOiBcIjEuMTAuNFwiIH0gfSk7XG5cbnZhciBQUk9QX05BTUUgPSBcImRhdGVwaWNrZXJcIixcblx0aW5zdEFjdGl2ZTtcblxuLyogRGF0ZSBwaWNrZXIgbWFuYWdlci5cbiAgIFVzZSB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoaXMgY2xhc3MsICQuZGF0ZXBpY2tlciwgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgZGF0ZSBwaWNrZXIuXG4gICBTZXR0aW5ncyBmb3IgKGdyb3VwcyBvZikgZGF0ZSBwaWNrZXJzIGFyZSBtYWludGFpbmVkIGluIGFuIGluc3RhbmNlIG9iamVjdCxcbiAgIGFsbG93aW5nIG11bHRpcGxlIGRpZmZlcmVudCBzZXR0aW5ncyBvbiB0aGUgc2FtZSBwYWdlLiAqL1xuXG5mdW5jdGlvbiBEYXRlcGlja2VyKCkge1xuXHR0aGlzLl9jdXJJbnN0ID0gbnVsbDsgLy8gVGhlIGN1cnJlbnQgaW5zdGFuY2UgaW4gdXNlXG5cdHRoaXMuX2tleUV2ZW50ID0gZmFsc2U7IC8vIElmIHRoZSBsYXN0IGV2ZW50IHdhcyBhIGtleSBldmVudFxuXHR0aGlzLl9kaXNhYmxlZElucHV0cyA9IFtdOyAvLyBMaXN0IG9mIGRhdGUgcGlja2VyIGlucHV0cyB0aGF0IGhhdmUgYmVlbiBkaXNhYmxlZFxuXHR0aGlzLl9kYXRlcGlja2VyU2hvd2luZyA9IGZhbHNlOyAvLyBUcnVlIGlmIHRoZSBwb3B1cCBwaWNrZXIgaXMgc2hvd2luZyAsIGZhbHNlIGlmIG5vdFxuXHR0aGlzLl9pbkRpYWxvZyA9IGZhbHNlOyAvLyBUcnVlIGlmIHNob3dpbmcgd2l0aGluIGEgXCJkaWFsb2dcIiwgZmFsc2UgaWYgbm90XG5cdHRoaXMuX21haW5EaXZJZCA9IFwidWktZGF0ZXBpY2tlci1kaXZcIjsgLy8gVGhlIElEIG9mIHRoZSBtYWluIGRhdGVwaWNrZXIgZGl2aXNpb25cblx0dGhpcy5faW5saW5lQ2xhc3MgPSBcInVpLWRhdGVwaWNrZXItaW5saW5lXCI7IC8vIFRoZSBuYW1lIG9mIHRoZSBpbmxpbmUgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2FwcGVuZENsYXNzID0gXCJ1aS1kYXRlcGlja2VyLWFwcGVuZFwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgYXBwZW5kIG1hcmtlciBjbGFzc1xuXHR0aGlzLl90cmlnZ2VyQ2xhc3MgPSBcInVpLWRhdGVwaWNrZXItdHJpZ2dlclwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgdHJpZ2dlciBtYXJrZXIgY2xhc3Ncblx0dGhpcy5fZGlhbG9nQ2xhc3MgPSBcInVpLWRhdGVwaWNrZXItZGlhbG9nXCI7IC8vIFRoZSBuYW1lIG9mIHRoZSBkaWFsb2cgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2Rpc2FibGVDbGFzcyA9IFwidWktZGF0ZXBpY2tlci1kaXNhYmxlZFwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgZGlzYWJsZWQgY292ZXJpbmcgbWFya2VyIGNsYXNzXG5cdHRoaXMuX3Vuc2VsZWN0YWJsZUNsYXNzID0gXCJ1aS1kYXRlcGlja2VyLXVuc2VsZWN0YWJsZVwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgdW5zZWxlY3RhYmxlIGNlbGwgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2N1cnJlbnRDbGFzcyA9IFwidWktZGF0ZXBpY2tlci1jdXJyZW50LWRheVwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgY3VycmVudCBkYXkgbWFya2VyIGNsYXNzXG5cdHRoaXMuX2RheU92ZXJDbGFzcyA9IFwidWktZGF0ZXBpY2tlci1kYXlzLWNlbGwtb3ZlclwiOyAvLyBUaGUgbmFtZSBvZiB0aGUgZGF5IGhvdmVyIG1hcmtlciBjbGFzc1xuXHR0aGlzLnJlZ2lvbmFsID0gW107IC8vIEF2YWlsYWJsZSByZWdpb25hbCBzZXR0aW5ncywgaW5kZXhlZCBieSBsYW5ndWFnZSBjb2RlXG5cdHRoaXMucmVnaW9uYWxbXCJcIl0gPSB7IC8vIERlZmF1bHQgcmVnaW9uYWwgc2V0dGluZ3Ncblx0XHRjbG9zZVRleHQ6IFwiRG9uZVwiLCAvLyBEaXNwbGF5IHRleHQgZm9yIGNsb3NlIGxpbmtcblx0XHRwcmV2VGV4dDogXCJQcmV2XCIsIC8vIERpc3BsYXkgdGV4dCBmb3IgcHJldmlvdXMgbW9udGggbGlua1xuXHRcdG5leHRUZXh0OiBcIk5leHRcIiwgLy8gRGlzcGxheSB0ZXh0IGZvciBuZXh0IG1vbnRoIGxpbmtcblx0XHRjdXJyZW50VGV4dDogXCJUb2RheVwiLCAvLyBEaXNwbGF5IHRleHQgZm9yIGN1cnJlbnQgbW9udGggbGlua1xuXHRcdG1vbnRoTmFtZXM6IFtcIkphbnVhcnlcIixcIkZlYnJ1YXJ5XCIsXCJNYXJjaFwiLFwiQXByaWxcIixcIk1heVwiLFwiSnVuZVwiLFxuXHRcdFx0XCJKdWx5XCIsXCJBdWd1c3RcIixcIlNlcHRlbWJlclwiLFwiT2N0b2JlclwiLFwiTm92ZW1iZXJcIixcIkRlY2VtYmVyXCJdLCAvLyBOYW1lcyBvZiBtb250aHMgZm9yIGRyb3AtZG93biBhbmQgZm9ybWF0dGluZ1xuXHRcdG1vbnRoTmFtZXNTaG9ydDogW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdLCAvLyBGb3IgZm9ybWF0dGluZ1xuXHRcdGRheU5hbWVzOiBbXCJTdW5kYXlcIiwgXCJNb25kYXlcIiwgXCJUdWVzZGF5XCIsIFwiV2VkbmVzZGF5XCIsIFwiVGh1cnNkYXlcIiwgXCJGcmlkYXlcIiwgXCJTYXR1cmRheVwiXSwgLy8gRm9yIGZvcm1hdHRpbmdcblx0XHRkYXlOYW1lc1Nob3J0OiBbXCJTdW5cIiwgXCJNb25cIiwgXCJUdWVcIiwgXCJXZWRcIiwgXCJUaHVcIiwgXCJGcmlcIiwgXCJTYXRcIl0sIC8vIEZvciBmb3JtYXR0aW5nXG5cdFx0ZGF5TmFtZXNNaW46IFtcIlN1XCIsXCJNb1wiLFwiVHVcIixcIldlXCIsXCJUaFwiLFwiRnJcIixcIlNhXCJdLCAvLyBDb2x1bW4gaGVhZGluZ3MgZm9yIGRheXMgc3RhcnRpbmcgYXQgU3VuZGF5XG5cdFx0d2Vla0hlYWRlcjogXCJXa1wiLCAvLyBDb2x1bW4gaGVhZGVyIGZvciB3ZWVrIG9mIHRoZSB5ZWFyXG5cdFx0ZGF0ZUZvcm1hdDogXCJtbS9kZC95eVwiLCAvLyBTZWUgZm9ybWF0IG9wdGlvbnMgb24gcGFyc2VEYXRlXG5cdFx0Zmlyc3REYXk6IDAsIC8vIFRoZSBmaXJzdCBkYXkgb2YgdGhlIHdlZWssIFN1biA9IDAsIE1vbiA9IDEsIC4uLlxuXHRcdGlzUlRMOiBmYWxzZSwgLy8gVHJ1ZSBpZiByaWdodC10by1sZWZ0IGxhbmd1YWdlLCBmYWxzZSBpZiBsZWZ0LXRvLXJpZ2h0XG5cdFx0c2hvd01vbnRoQWZ0ZXJZZWFyOiBmYWxzZSwgLy8gVHJ1ZSBpZiB0aGUgeWVhciBzZWxlY3QgcHJlY2VkZXMgbW9udGgsIGZhbHNlIGZvciBtb250aCB0aGVuIHllYXJcblx0XHR5ZWFyU3VmZml4OiBcIlwiIC8vIEFkZGl0aW9uYWwgdGV4dCB0byBhcHBlbmQgdG8gdGhlIHllYXIgaW4gdGhlIG1vbnRoIGhlYWRlcnNcblx0fTtcblx0dGhpcy5fZGVmYXVsdHMgPSB7IC8vIEdsb2JhbCBkZWZhdWx0cyBmb3IgYWxsIHRoZSBkYXRlIHBpY2tlciBpbnN0YW5jZXNcblx0XHRzaG93T246IFwiZm9jdXNcIiwgLy8gXCJmb2N1c1wiIGZvciBwb3B1cCBvbiBmb2N1cyxcblx0XHRcdC8vIFwiYnV0dG9uXCIgZm9yIHRyaWdnZXIgYnV0dG9uLCBvciBcImJvdGhcIiBmb3IgZWl0aGVyXG5cdFx0c2hvd0FuaW06IFwiZmFkZUluXCIsIC8vIE5hbWUgb2YgalF1ZXJ5IGFuaW1hdGlvbiBmb3IgcG9wdXBcblx0XHRzaG93T3B0aW9uczoge30sIC8vIE9wdGlvbnMgZm9yIGVuaGFuY2VkIGFuaW1hdGlvbnNcblx0XHRkZWZhdWx0RGF0ZTogbnVsbCwgLy8gVXNlZCB3aGVuIGZpZWxkIGlzIGJsYW5rOiBhY3R1YWwgZGF0ZSxcblx0XHRcdC8vICsvLW51bWJlciBmb3Igb2Zmc2V0IGZyb20gdG9kYXksIG51bGwgZm9yIHRvZGF5XG5cdFx0YXBwZW5kVGV4dDogXCJcIiwgLy8gRGlzcGxheSB0ZXh0IGZvbGxvd2luZyB0aGUgaW5wdXQgYm94LCBlLmcuIHNob3dpbmcgdGhlIGZvcm1hdFxuXHRcdGJ1dHRvblRleHQ6IFwiLi4uXCIsIC8vIFRleHQgZm9yIHRyaWdnZXIgYnV0dG9uXG5cdFx0YnV0dG9uSW1hZ2U6IFwiXCIsIC8vIFVSTCBmb3IgdHJpZ2dlciBidXR0b24gaW1hZ2Vcblx0XHRidXR0b25JbWFnZU9ubHk6IGZhbHNlLCAvLyBUcnVlIGlmIHRoZSBpbWFnZSBhcHBlYXJzIGFsb25lLCBmYWxzZSBpZiBpdCBhcHBlYXJzIG9uIGEgYnV0dG9uXG5cdFx0aGlkZUlmTm9QcmV2TmV4dDogZmFsc2UsIC8vIFRydWUgdG8gaGlkZSBuZXh0L3ByZXZpb3VzIG1vbnRoIGxpbmtzXG5cdFx0XHQvLyBpZiBub3QgYXBwbGljYWJsZSwgZmFsc2UgdG8ganVzdCBkaXNhYmxlIHRoZW1cblx0XHRuYXZpZ2F0aW9uQXNEYXRlRm9ybWF0OiBmYWxzZSwgLy8gVHJ1ZSBpZiBkYXRlIGZvcm1hdHRpbmcgYXBwbGllZCB0byBwcmV2L3RvZGF5L25leHQgbGlua3Ncblx0XHRnb3RvQ3VycmVudDogZmFsc2UsIC8vIFRydWUgaWYgdG9kYXkgbGluayBnb2VzIGJhY2sgdG8gY3VycmVudCBzZWxlY3Rpb24gaW5zdGVhZFxuXHRcdGNoYW5nZU1vbnRoOiBmYWxzZSwgLy8gVHJ1ZSBpZiBtb250aCBjYW4gYmUgc2VsZWN0ZWQgZGlyZWN0bHksIGZhbHNlIGlmIG9ubHkgcHJldi9uZXh0XG5cdFx0Y2hhbmdlWWVhcjogZmFsc2UsIC8vIFRydWUgaWYgeWVhciBjYW4gYmUgc2VsZWN0ZWQgZGlyZWN0bHksIGZhbHNlIGlmIG9ubHkgcHJldi9uZXh0XG5cdFx0eWVhclJhbmdlOiBcImMtMTA6YysxMFwiLCAvLyBSYW5nZSBvZiB5ZWFycyB0byBkaXNwbGF5IGluIGRyb3AtZG93bixcblx0XHRcdC8vIGVpdGhlciByZWxhdGl2ZSB0byB0b2RheSdzIHllYXIgKC1ubjorbm4pLCByZWxhdGl2ZSB0byBjdXJyZW50bHkgZGlzcGxheWVkIHllYXJcblx0XHRcdC8vIChjLW5uOmMrbm4pLCBhYnNvbHV0ZSAobm5ubjpubm5uKSwgb3IgYSBjb21iaW5hdGlvbiBvZiB0aGUgYWJvdmUgKG5ubm46LW4pXG5cdFx0c2hvd090aGVyTW9udGhzOiBmYWxzZSwgLy8gVHJ1ZSB0byBzaG93IGRhdGVzIGluIG90aGVyIG1vbnRocywgZmFsc2UgdG8gbGVhdmUgYmxhbmtcblx0XHRzZWxlY3RPdGhlck1vbnRoczogZmFsc2UsIC8vIFRydWUgdG8gYWxsb3cgc2VsZWN0aW9uIG9mIGRhdGVzIGluIG90aGVyIG1vbnRocywgZmFsc2UgZm9yIHVuc2VsZWN0YWJsZVxuXHRcdHNob3dXZWVrOiBmYWxzZSwgLy8gVHJ1ZSB0byBzaG93IHdlZWsgb2YgdGhlIHllYXIsIGZhbHNlIHRvIG5vdCBzaG93IGl0XG5cdFx0Y2FsY3VsYXRlV2VlazogdGhpcy5pc284NjAxV2VlaywgLy8gSG93IHRvIGNhbGN1bGF0ZSB0aGUgd2VlayBvZiB0aGUgeWVhcixcblx0XHRcdC8vIHRha2VzIGEgRGF0ZSBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIHRoZSB3ZWVrIGZvciBpdFxuXHRcdHNob3J0WWVhckN1dG9mZjogXCIrMTBcIiwgLy8gU2hvcnQgeWVhciB2YWx1ZXMgPCB0aGlzIGFyZSBpbiB0aGUgY3VycmVudCBjZW50dXJ5LFxuXHRcdFx0Ly8gPiB0aGlzIGFyZSBpbiB0aGUgcHJldmlvdXMgY2VudHVyeSxcblx0XHRcdC8vIHN0cmluZyB2YWx1ZSBzdGFydGluZyB3aXRoIFwiK1wiIGZvciBjdXJyZW50IHllYXIgKyB2YWx1ZVxuXHRcdG1pbkRhdGU6IG51bGwsIC8vIFRoZSBlYXJsaWVzdCBzZWxlY3RhYmxlIGRhdGUsIG9yIG51bGwgZm9yIG5vIGxpbWl0XG5cdFx0bWF4RGF0ZTogbnVsbCwgLy8gVGhlIGxhdGVzdCBzZWxlY3RhYmxlIGRhdGUsIG9yIG51bGwgZm9yIG5vIGxpbWl0XG5cdFx0ZHVyYXRpb246IFwiZmFzdFwiLCAvLyBEdXJhdGlvbiBvZiBkaXNwbGF5L2Nsb3N1cmVcblx0XHRiZWZvcmVTaG93RGF5OiBudWxsLCAvLyBGdW5jdGlvbiB0aGF0IHRha2VzIGEgZGF0ZSBhbmQgcmV0dXJucyBhbiBhcnJheSB3aXRoXG5cdFx0XHQvLyBbMF0gPSB0cnVlIGlmIHNlbGVjdGFibGUsIGZhbHNlIGlmIG5vdCwgWzFdID0gY3VzdG9tIENTUyBjbGFzcyBuYW1lKHMpIG9yIFwiXCIsXG5cdFx0XHQvLyBbMl0gPSBjZWxsIHRpdGxlIChvcHRpb25hbCksIGUuZy4gJC5kYXRlcGlja2VyLm5vV2Vla2VuZHNcblx0XHRiZWZvcmVTaG93OiBudWxsLCAvLyBGdW5jdGlvbiB0aGF0IHRha2VzIGFuIGlucHV0IGZpZWxkIGFuZFxuXHRcdFx0Ly8gcmV0dXJucyBhIHNldCBvZiBjdXN0b20gc2V0dGluZ3MgZm9yIHRoZSBkYXRlIHBpY2tlclxuXHRcdG9uU2VsZWN0OiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGEgZGF0ZSBpcyBzZWxlY3RlZFxuXHRcdG9uQ2hhbmdlTW9udGhZZWFyOiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHRoZSBtb250aCBvciB5ZWFyIGlzIGNoYW5nZWRcblx0XHRvbkNsb3NlOiBudWxsLCAvLyBEZWZpbmUgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIHRoZSBkYXRlcGlja2VyIGlzIGNsb3NlZFxuXHRcdG51bWJlck9mTW9udGhzOiAxLCAvLyBOdW1iZXIgb2YgbW9udGhzIHRvIHNob3cgYXQgYSB0aW1lXG5cdFx0c2hvd0N1cnJlbnRBdFBvczogMCwgLy8gVGhlIHBvc2l0aW9uIGluIG11bHRpcGUgbW9udGhzIGF0IHdoaWNoIHRvIHNob3cgdGhlIGN1cnJlbnQgbW9udGggKHN0YXJ0aW5nIGF0IDApXG5cdFx0c3RlcE1vbnRoczogMSwgLy8gTnVtYmVyIG9mIG1vbnRocyB0byBzdGVwIGJhY2svZm9yd2FyZFxuXHRcdHN0ZXBCaWdNb250aHM6IDEyLCAvLyBOdW1iZXIgb2YgbW9udGhzIHRvIHN0ZXAgYmFjay9mb3J3YXJkIGZvciB0aGUgYmlnIGxpbmtzXG5cdFx0YWx0RmllbGQ6IFwiXCIsIC8vIFNlbGVjdG9yIGZvciBhbiBhbHRlcm5hdGUgZmllbGQgdG8gc3RvcmUgc2VsZWN0ZWQgZGF0ZXMgaW50b1xuXHRcdGFsdEZvcm1hdDogXCJcIiwgLy8gVGhlIGRhdGUgZm9ybWF0IHRvIHVzZSBmb3IgdGhlIGFsdGVybmF0ZSBmaWVsZFxuXHRcdGNvbnN0cmFpbklucHV0OiB0cnVlLCAvLyBUaGUgaW5wdXQgaXMgY29uc3RyYWluZWQgYnkgdGhlIGN1cnJlbnQgZGF0ZSBmb3JtYXRcblx0XHRzaG93QnV0dG9uUGFuZWw6IGZhbHNlLCAvLyBUcnVlIHRvIHNob3cgYnV0dG9uIHBhbmVsLCBmYWxzZSB0byBub3Qgc2hvdyBpdFxuXHRcdGF1dG9TaXplOiBmYWxzZSwgLy8gVHJ1ZSB0byBzaXplIHRoZSBpbnB1dCBmb3IgdGhlIGRhdGUgZm9ybWF0LCBmYWxzZSB0byBsZWF2ZSBhcyBpc1xuXHRcdGRpc2FibGVkOiBmYWxzZSAvLyBUaGUgaW5pdGlhbCBkaXNhYmxlZCBzdGF0ZVxuXHR9O1xuXHQkLmV4dGVuZCh0aGlzLl9kZWZhdWx0cywgdGhpcy5yZWdpb25hbFtcIlwiXSk7XG5cdHRoaXMuZHBEaXYgPSBiaW5kSG92ZXIoJChcIjxkaXYgaWQ9J1wiICsgdGhpcy5fbWFpbkRpdklkICsgXCInIGNsYXNzPSd1aS1kYXRlcGlja2VyIHVpLXdpZGdldCB1aS13aWRnZXQtY29udGVudCB1aS1oZWxwZXItY2xlYXJmaXggdWktY29ybmVyLWFsbCc+PC9kaXY+XCIpKTtcbn1cblxuJC5leHRlbmQoRGF0ZXBpY2tlci5wcm90b3R5cGUsIHtcblx0LyogQ2xhc3MgbmFtZSBhZGRlZCB0byBlbGVtZW50cyB0byBpbmRpY2F0ZSBhbHJlYWR5IGNvbmZpZ3VyZWQgd2l0aCBhIGRhdGUgcGlja2VyLiAqL1xuXHRtYXJrZXJDbGFzc05hbWU6IFwiaGFzRGF0ZXBpY2tlclwiLFxuXG5cdC8vS2VlcCB0cmFjayBvZiB0aGUgbWF4aW11bSBudW1iZXIgb2Ygcm93cyBkaXNwbGF5ZWQgKHNlZSAjNzA0Mylcblx0bWF4Um93czogNCxcblxuXHQvLyBUT0RPIHJlbmFtZSB0byBcIndpZGdldFwiIHdoZW4gc3dpdGNoaW5nIHRvIHdpZGdldCBmYWN0b3J5XG5cdF93aWRnZXREYXRlcGlja2VyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kcERpdjtcblx0fSxcblxuXHQvKiBPdmVycmlkZSB0aGUgZGVmYXVsdCBzZXR0aW5ncyBmb3IgYWxsIGluc3RhbmNlcyBvZiB0aGUgZGF0ZSBwaWNrZXIuXG5cdCAqIEBwYXJhbSAgc2V0dGluZ3MgIG9iamVjdCAtIHRoZSBuZXcgc2V0dGluZ3MgdG8gdXNlIGFzIGRlZmF1bHRzIChhbm9ueW1vdXMgb2JqZWN0KVxuXHQgKiBAcmV0dXJuIHRoZSBtYW5hZ2VyIG9iamVjdFxuXHQgKi9cblx0c2V0RGVmYXVsdHM6IGZ1bmN0aW9uKHNldHRpbmdzKSB7XG5cdFx0ZXh0ZW5kUmVtb3ZlKHRoaXMuX2RlZmF1bHRzLCBzZXR0aW5ncyB8fCB7fSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0LyogQXR0YWNoIHRoZSBkYXRlIHBpY2tlciB0byBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAqIEBwYXJhbSAgdGFyZ2V0XHRlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqIEBwYXJhbSAgc2V0dGluZ3MgIG9iamVjdCAtIHRoZSBuZXcgc2V0dGluZ3MgdG8gdXNlIGZvciB0aGlzIGRhdGUgcGlja2VyIGluc3RhbmNlIChhbm9ueW1vdXMpXG5cdCAqL1xuXHRfYXR0YWNoRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBzZXR0aW5ncykge1xuXHRcdHZhciBub2RlTmFtZSwgaW5saW5lLCBpbnN0O1xuXHRcdG5vZGVOYW1lID0gdGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0aW5saW5lID0gKG5vZGVOYW1lID09PSBcImRpdlwiIHx8IG5vZGVOYW1lID09PSBcInNwYW5cIik7XG5cdFx0aWYgKCF0YXJnZXQuaWQpIHtcblx0XHRcdHRoaXMudXVpZCArPSAxO1xuXHRcdFx0dGFyZ2V0LmlkID0gXCJkcFwiICsgdGhpcy51dWlkO1xuXHRcdH1cblx0XHRpbnN0ID0gdGhpcy5fbmV3SW5zdCgkKHRhcmdldCksIGlubGluZSk7XG5cdFx0aW5zdC5zZXR0aW5ncyA9ICQuZXh0ZW5kKHt9LCBzZXR0aW5ncyB8fCB7fSk7XG5cdFx0aWYgKG5vZGVOYW1lID09PSBcImlucHV0XCIpIHtcblx0XHRcdHRoaXMuX2Nvbm5lY3REYXRlcGlja2VyKHRhcmdldCwgaW5zdCk7XG5cdFx0fSBlbHNlIGlmIChpbmxpbmUpIHtcblx0XHRcdHRoaXMuX2lubGluZURhdGVwaWNrZXIodGFyZ2V0LCBpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0LyogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9iamVjdC4gKi9cblx0X25ld0luc3Q6IGZ1bmN0aW9uKHRhcmdldCwgaW5saW5lKSB7XG5cdFx0dmFyIGlkID0gdGFyZ2V0WzBdLmlkLnJlcGxhY2UoLyhbXkEtWmEtejAtOV9cXC1dKS9nLCBcIlxcXFxcXFxcJDFcIik7IC8vIGVzY2FwZSBqUXVlcnkgbWV0YSBjaGFyc1xuXHRcdHJldHVybiB7aWQ6IGlkLCBpbnB1dDogdGFyZ2V0LCAvLyBhc3NvY2lhdGVkIHRhcmdldFxuXHRcdFx0c2VsZWN0ZWREYXk6IDAsIHNlbGVjdGVkTW9udGg6IDAsIHNlbGVjdGVkWWVhcjogMCwgLy8gY3VycmVudCBzZWxlY3Rpb25cblx0XHRcdGRyYXdNb250aDogMCwgZHJhd1llYXI6IDAsIC8vIG1vbnRoIGJlaW5nIGRyYXduXG5cdFx0XHRpbmxpbmU6IGlubGluZSwgLy8gaXMgZGF0ZXBpY2tlciBpbmxpbmUgb3Igbm90XG5cdFx0XHRkcERpdjogKCFpbmxpbmUgPyB0aGlzLmRwRGl2IDogLy8gcHJlc2VudGF0aW9uIGRpdlxuXHRcdFx0YmluZEhvdmVyKCQoXCI8ZGl2IGNsYXNzPSdcIiArIHRoaXMuX2lubGluZUNsYXNzICsgXCIgdWktZGF0ZXBpY2tlciB1aS13aWRnZXQgdWktd2lkZ2V0LWNvbnRlbnQgdWktaGVscGVyLWNsZWFyZml4IHVpLWNvcm5lci1hbGwnPjwvZGl2PlwiKSkpfTtcblx0fSxcblxuXHQvKiBBdHRhY2ggdGhlIGRhdGUgcGlja2VyIHRvIGFuIGlucHV0IGZpZWxkLiAqL1xuXHRfY29ubmVjdERhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgaW5zdCkge1xuXHRcdHZhciBpbnB1dCA9ICQodGFyZ2V0KTtcblx0XHRpbnN0LmFwcGVuZCA9ICQoW10pO1xuXHRcdGluc3QudHJpZ2dlciA9ICQoW10pO1xuXHRcdGlmIChpbnB1dC5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy5fYXR0YWNobWVudHMoaW5wdXQsIGluc3QpO1xuXHRcdGlucHV0LmFkZENsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKS5rZXlkb3duKHRoaXMuX2RvS2V5RG93bikuXG5cdFx0XHRrZXlwcmVzcyh0aGlzLl9kb0tleVByZXNzKS5rZXl1cCh0aGlzLl9kb0tleVVwKTtcblx0XHR0aGlzLl9hdXRvU2l6ZShpbnN0KTtcblx0XHQkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUsIGluc3QpO1xuXHRcdC8vSWYgZGlzYWJsZWQgb3B0aW9uIGlzIHRydWUsIGRpc2FibGUgdGhlIGRhdGVwaWNrZXIgb25jZSBpdCBoYXMgYmVlbiBhdHRhY2hlZCB0byB0aGUgaW5wdXQgKHNlZSB0aWNrZXQgIzU2NjUpXG5cdFx0aWYoIGluc3Quc2V0dGluZ3MuZGlzYWJsZWQgKSB7XG5cdFx0XHR0aGlzLl9kaXNhYmxlRGF0ZXBpY2tlciggdGFyZ2V0ICk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIE1ha2UgYXR0YWNobWVudHMgYmFzZWQgb24gc2V0dGluZ3MuICovXG5cdF9hdHRhY2htZW50czogZnVuY3Rpb24oaW5wdXQsIGluc3QpIHtcblx0XHR2YXIgc2hvd09uLCBidXR0b25UZXh0LCBidXR0b25JbWFnZSxcblx0XHRcdGFwcGVuZFRleHQgPSB0aGlzLl9nZXQoaW5zdCwgXCJhcHBlbmRUZXh0XCIpLFxuXHRcdFx0aXNSVEwgPSB0aGlzLl9nZXQoaW5zdCwgXCJpc1JUTFwiKTtcblxuXHRcdGlmIChpbnN0LmFwcGVuZCkge1xuXHRcdFx0aW5zdC5hcHBlbmQucmVtb3ZlKCk7XG5cdFx0fVxuXHRcdGlmIChhcHBlbmRUZXh0KSB7XG5cdFx0XHRpbnN0LmFwcGVuZCA9ICQoXCI8c3BhbiBjbGFzcz0nXCIgKyB0aGlzLl9hcHBlbmRDbGFzcyArIFwiJz5cIiArIGFwcGVuZFRleHQgKyBcIjwvc3Bhbj5cIik7XG5cdFx0XHRpbnB1dFtpc1JUTCA/IFwiYmVmb3JlXCIgOiBcImFmdGVyXCJdKGluc3QuYXBwZW5kKTtcblx0XHR9XG5cblx0XHRpbnB1dC51bmJpbmQoXCJmb2N1c1wiLCB0aGlzLl9zaG93RGF0ZXBpY2tlcik7XG5cblx0XHRpZiAoaW5zdC50cmlnZ2VyKSB7XG5cdFx0XHRpbnN0LnRyaWdnZXIucmVtb3ZlKCk7XG5cdFx0fVxuXG5cdFx0c2hvd09uID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvd09uXCIpO1xuXHRcdGlmIChzaG93T24gPT09IFwiZm9jdXNcIiB8fCBzaG93T24gPT09IFwiYm90aFwiKSB7IC8vIHBvcC11cCBkYXRlIHBpY2tlciB3aGVuIGluIHRoZSBtYXJrZWQgZmllbGRcblx0XHRcdGlucHV0LmZvY3VzKHRoaXMuX3Nob3dEYXRlcGlja2VyKTtcblx0XHR9XG5cdFx0aWYgKHNob3dPbiA9PT0gXCJidXR0b25cIiB8fCBzaG93T24gPT09IFwiYm90aFwiKSB7IC8vIHBvcC11cCBkYXRlIHBpY2tlciB3aGVuIGJ1dHRvbiBjbGlja2VkXG5cdFx0XHRidXR0b25UZXh0ID0gdGhpcy5fZ2V0KGluc3QsIFwiYnV0dG9uVGV4dFwiKTtcblx0XHRcdGJ1dHRvbkltYWdlID0gdGhpcy5fZ2V0KGluc3QsIFwiYnV0dG9uSW1hZ2VcIik7XG5cdFx0XHRpbnN0LnRyaWdnZXIgPSAkKHRoaXMuX2dldChpbnN0LCBcImJ1dHRvbkltYWdlT25seVwiKSA/XG5cdFx0XHRcdCQoXCI8aW1nLz5cIikuYWRkQ2xhc3ModGhpcy5fdHJpZ2dlckNsYXNzKS5cblx0XHRcdFx0XHRhdHRyKHsgc3JjOiBidXR0b25JbWFnZSwgYWx0OiBidXR0b25UZXh0LCB0aXRsZTogYnV0dG9uVGV4dCB9KSA6XG5cdFx0XHRcdCQoXCI8YnV0dG9uIHR5cGU9J2J1dHRvbic+PC9idXR0b24+XCIpLmFkZENsYXNzKHRoaXMuX3RyaWdnZXJDbGFzcykuXG5cdFx0XHRcdFx0aHRtbCghYnV0dG9uSW1hZ2UgPyBidXR0b25UZXh0IDogJChcIjxpbWcvPlwiKS5hdHRyKFxuXHRcdFx0XHRcdHsgc3JjOmJ1dHRvbkltYWdlLCBhbHQ6YnV0dG9uVGV4dCwgdGl0bGU6YnV0dG9uVGV4dCB9KSkpO1xuXHRcdFx0aW5wdXRbaXNSVEwgPyBcImJlZm9yZVwiIDogXCJhZnRlclwiXShpbnN0LnRyaWdnZXIpO1xuXHRcdFx0aW5zdC50cmlnZ2VyLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoJC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyAmJiAkLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCA9PT0gaW5wdXRbMF0pIHtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdH0gZWxzZSBpZiAoJC5kYXRlcGlja2VyLl9kYXRlcGlja2VyU2hvd2luZyAmJiAkLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCAhPT0gaW5wdXRbMF0pIHtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcihpbnB1dFswXSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9zaG93RGF0ZXBpY2tlcihpbnB1dFswXSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEFwcGx5IHRoZSBtYXhpbXVtIGxlbmd0aCBmb3IgdGhlIGRhdGUgZm9ybWF0LiAqL1xuXHRfYXV0b1NpemU6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHRpZiAodGhpcy5fZ2V0KGluc3QsIFwiYXV0b1NpemVcIikgJiYgIWluc3QuaW5saW5lKSB7XG5cdFx0XHR2YXIgZmluZE1heCwgbWF4LCBtYXhJLCBpLFxuXHRcdFx0XHRkYXRlID0gbmV3IERhdGUoMjAwOSwgMTIgLSAxLCAyMCksIC8vIEVuc3VyZSBkb3VibGUgZGlnaXRzXG5cdFx0XHRcdGRhdGVGb3JtYXQgPSB0aGlzLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpO1xuXG5cdFx0XHRpZiAoZGF0ZUZvcm1hdC5tYXRjaCgvW0RNXS8pKSB7XG5cdFx0XHRcdGZpbmRNYXggPSBmdW5jdGlvbihuYW1lcykge1xuXHRcdFx0XHRcdG1heCA9IDA7XG5cdFx0XHRcdFx0bWF4SSA9IDA7XG5cdFx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0XHRpZiAobmFtZXNbaV0ubGVuZ3RoID4gbWF4KSB7XG5cdFx0XHRcdFx0XHRcdG1heCA9IG5hbWVzW2ldLmxlbmd0aDtcblx0XHRcdFx0XHRcdFx0bWF4SSA9IGk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXhJO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRkYXRlLnNldE1vbnRoKGZpbmRNYXgodGhpcy5fZ2V0KGluc3QsIChkYXRlRm9ybWF0Lm1hdGNoKC9NTS8pID9cblx0XHRcdFx0XHRcIm1vbnRoTmFtZXNcIiA6IFwibW9udGhOYW1lc1Nob3J0XCIpKSkpO1xuXHRcdFx0XHRkYXRlLnNldERhdGUoZmluZE1heCh0aGlzLl9nZXQoaW5zdCwgKGRhdGVGb3JtYXQubWF0Y2goL0RELykgP1xuXHRcdFx0XHRcdFwiZGF5TmFtZXNcIiA6IFwiZGF5TmFtZXNTaG9ydFwiKSkpICsgMjAgLSBkYXRlLmdldERheSgpKTtcblx0XHRcdH1cblx0XHRcdGluc3QuaW5wdXQuYXR0cihcInNpemVcIiwgdGhpcy5fZm9ybWF0RGF0ZShpbnN0LCBkYXRlKS5sZW5ndGgpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBBdHRhY2ggYW4gaW5saW5lIGRhdGUgcGlja2VyIHRvIGEgZGl2LiAqL1xuXHRfaW5saW5lRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBpbnN0KSB7XG5cdFx0dmFyIGRpdlNwYW4gPSAkKHRhcmdldCk7XG5cdFx0aWYgKGRpdlNwYW4uaGFzQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGRpdlNwYW4uYWRkQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmFwcGVuZChpbnN0LmRwRGl2KTtcblx0XHQkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUsIGluc3QpO1xuXHRcdHRoaXMuX3NldERhdGUoaW5zdCwgdGhpcy5fZ2V0RGVmYXVsdERhdGUoaW5zdCksIHRydWUpO1xuXHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0dGhpcy5fdXBkYXRlQWx0ZXJuYXRlKGluc3QpO1xuXHRcdC8vSWYgZGlzYWJsZWQgb3B0aW9uIGlzIHRydWUsIGRpc2FibGUgdGhlIGRhdGVwaWNrZXIgYmVmb3JlIHNob3dpbmcgaXQgKHNlZSB0aWNrZXQgIzU2NjUpXG5cdFx0aWYoIGluc3Quc2V0dGluZ3MuZGlzYWJsZWQgKSB7XG5cdFx0XHR0aGlzLl9kaXNhYmxlRGF0ZXBpY2tlciggdGFyZ2V0ICk7XG5cdFx0fVxuXHRcdC8vIFNldCBkaXNwbGF5OmJsb2NrIGluIHBsYWNlIG9mIGluc3QuZHBEaXYuc2hvdygpIHdoaWNoIHdvbid0IHdvcmsgb24gZGlzY29ubmVjdGVkIGVsZW1lbnRzXG5cdFx0Ly8gaHR0cDovL2J1Z3MuanF1ZXJ5dWkuY29tL3RpY2tldC83NTUyIC0gQSBEYXRlcGlja2VyIGNyZWF0ZWQgb24gYSBkZXRhY2hlZCBkaXYgaGFzIHplcm8gaGVpZ2h0XG5cdFx0aW5zdC5kcERpdi5jc3MoIFwiZGlzcGxheVwiLCBcImJsb2NrXCIgKTtcblx0fSxcblxuXHQvKiBQb3AtdXAgdGhlIGRhdGUgcGlja2VyIGluIGEgXCJkaWFsb2dcIiBib3guXG5cdCAqIEBwYXJhbSAgaW5wdXQgZWxlbWVudCAtIGlnbm9yZWRcblx0ICogQHBhcmFtICBkYXRlXHRzdHJpbmcgb3IgRGF0ZSAtIHRoZSBpbml0aWFsIGRhdGUgdG8gZGlzcGxheVxuXHQgKiBAcGFyYW0gIG9uU2VsZWN0ICBmdW5jdGlvbiAtIHRoZSBmdW5jdGlvbiB0byBjYWxsIHdoZW4gYSBkYXRlIGlzIHNlbGVjdGVkXG5cdCAqIEBwYXJhbSAgc2V0dGluZ3MgIG9iamVjdCAtIHVwZGF0ZSB0aGUgZGlhbG9nIGRhdGUgcGlja2VyIGluc3RhbmNlJ3Mgc2V0dGluZ3MgKGFub255bW91cyBvYmplY3QpXG5cdCAqIEBwYXJhbSAgcG9zIGludFsyXSAtIGNvb3JkaW5hdGVzIGZvciB0aGUgZGlhbG9nJ3MgcG9zaXRpb24gd2l0aGluIHRoZSBzY3JlZW4gb3Jcblx0ICpcdFx0XHRcdFx0ZXZlbnQgLSB3aXRoIHgveSBjb29yZGluYXRlcyBvclxuXHQgKlx0XHRcdFx0XHRsZWF2ZSBlbXB0eSBmb3IgZGVmYXVsdCAoc2NyZWVuIGNlbnRyZSlcblx0ICogQHJldHVybiB0aGUgbWFuYWdlciBvYmplY3Rcblx0ICovXG5cdF9kaWFsb2dEYXRlcGlja2VyOiBmdW5jdGlvbihpbnB1dCwgZGF0ZSwgb25TZWxlY3QsIHNldHRpbmdzLCBwb3MpIHtcblx0XHR2YXIgaWQsIGJyb3dzZXJXaWR0aCwgYnJvd3NlckhlaWdodCwgc2Nyb2xsWCwgc2Nyb2xsWSxcblx0XHRcdGluc3QgPSB0aGlzLl9kaWFsb2dJbnN0OyAvLyBpbnRlcm5hbCBpbnN0YW5jZVxuXG5cdFx0aWYgKCFpbnN0KSB7XG5cdFx0XHR0aGlzLnV1aWQgKz0gMTtcblx0XHRcdGlkID0gXCJkcFwiICsgdGhpcy51dWlkO1xuXHRcdFx0dGhpcy5fZGlhbG9nSW5wdXQgPSAkKFwiPGlucHV0IHR5cGU9J3RleHQnIGlkPSdcIiArIGlkICtcblx0XHRcdFx0XCInIHN0eWxlPSdwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogLTEwMHB4OyB3aWR0aDogMHB4OycvPlwiKTtcblx0XHRcdHRoaXMuX2RpYWxvZ0lucHV0LmtleWRvd24odGhpcy5fZG9LZXlEb3duKTtcblx0XHRcdCQoXCJib2R5XCIpLmFwcGVuZCh0aGlzLl9kaWFsb2dJbnB1dCk7XG5cdFx0XHRpbnN0ID0gdGhpcy5fZGlhbG9nSW5zdCA9IHRoaXMuX25ld0luc3QodGhpcy5fZGlhbG9nSW5wdXQsIGZhbHNlKTtcblx0XHRcdGluc3Quc2V0dGluZ3MgPSB7fTtcblx0XHRcdCQuZGF0YSh0aGlzLl9kaWFsb2dJbnB1dFswXSwgUFJPUF9OQU1FLCBpbnN0KTtcblx0XHR9XG5cdFx0ZXh0ZW5kUmVtb3ZlKGluc3Quc2V0dGluZ3MsIHNldHRpbmdzIHx8IHt9KTtcblx0XHRkYXRlID0gKGRhdGUgJiYgZGF0ZS5jb25zdHJ1Y3RvciA9PT0gRGF0ZSA/IHRoaXMuX2Zvcm1hdERhdGUoaW5zdCwgZGF0ZSkgOiBkYXRlKTtcblx0XHR0aGlzLl9kaWFsb2dJbnB1dC52YWwoZGF0ZSk7XG5cblx0XHR0aGlzLl9wb3MgPSAocG9zID8gKHBvcy5sZW5ndGggPyBwb3MgOiBbcG9zLnBhZ2VYLCBwb3MucGFnZVldKSA6IG51bGwpO1xuXHRcdGlmICghdGhpcy5fcG9zKSB7XG5cdFx0XHRicm93c2VyV2lkdGggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG5cdFx0XHRicm93c2VySGVpZ2h0ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDtcblx0XHRcdHNjcm9sbFggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbExlZnQ7XG5cdFx0XHRzY3JvbGxZID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcDtcblx0XHRcdHRoaXMuX3BvcyA9IC8vIHNob3VsZCB1c2UgYWN0dWFsIHdpZHRoL2hlaWdodCBiZWxvd1xuXHRcdFx0XHRbKGJyb3dzZXJXaWR0aCAvIDIpIC0gMTAwICsgc2Nyb2xsWCwgKGJyb3dzZXJIZWlnaHQgLyAyKSAtIDE1MCArIHNjcm9sbFldO1xuXHRcdH1cblxuXHRcdC8vIG1vdmUgaW5wdXQgb24gc2NyZWVuIGZvciBmb2N1cywgYnV0IGhpZGRlbiBiZWhpbmQgZGlhbG9nXG5cdFx0dGhpcy5fZGlhbG9nSW5wdXQuY3NzKFwibGVmdFwiLCAodGhpcy5fcG9zWzBdICsgMjApICsgXCJweFwiKS5jc3MoXCJ0b3BcIiwgdGhpcy5fcG9zWzFdICsgXCJweFwiKTtcblx0XHRpbnN0LnNldHRpbmdzLm9uU2VsZWN0ID0gb25TZWxlY3Q7XG5cdFx0dGhpcy5faW5EaWFsb2cgPSB0cnVlO1xuXHRcdHRoaXMuZHBEaXYuYWRkQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpO1xuXHRcdHRoaXMuX3Nob3dEYXRlcGlja2VyKHRoaXMuX2RpYWxvZ0lucHV0WzBdKTtcblx0XHRpZiAoJC5ibG9ja1VJKSB7XG5cdFx0XHQkLmJsb2NrVUkodGhpcy5kcERpdik7XG5cdFx0fVxuXHRcdCQuZGF0YSh0aGlzLl9kaWFsb2dJbnB1dFswXSwgUFJPUF9OQU1FLCBpbnN0KTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKiBEZXRhY2ggYSBkYXRlcGlja2VyIGZyb20gaXRzIGNvbnRyb2wuXG5cdCAqIEBwYXJhbSAgdGFyZ2V0XHRlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqL1xuXHRfZGVzdHJveURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHZhciBub2RlTmFtZSxcblx0XHRcdCR0YXJnZXQgPSAkKHRhcmdldCksXG5cdFx0XHRpbnN0ID0gJC5kYXRhKHRhcmdldCwgUFJPUF9OQU1FKTtcblxuXHRcdGlmICghJHRhcmdldC5oYXNDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRub2RlTmFtZSA9IHRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdCQucmVtb3ZlRGF0YSh0YXJnZXQsIFBST1BfTkFNRSk7XG5cdFx0aWYgKG5vZGVOYW1lID09PSBcImlucHV0XCIpIHtcblx0XHRcdGluc3QuYXBwZW5kLnJlbW92ZSgpO1xuXHRcdFx0aW5zdC50cmlnZ2VyLnJlbW92ZSgpO1xuXHRcdFx0JHRhcmdldC5yZW1vdmVDbGFzcyh0aGlzLm1hcmtlckNsYXNzTmFtZSkuXG5cdFx0XHRcdHVuYmluZChcImZvY3VzXCIsIHRoaXMuX3Nob3dEYXRlcGlja2VyKS5cblx0XHRcdFx0dW5iaW5kKFwia2V5ZG93blwiLCB0aGlzLl9kb0tleURvd24pLlxuXHRcdFx0XHR1bmJpbmQoXCJrZXlwcmVzc1wiLCB0aGlzLl9kb0tleVByZXNzKS5cblx0XHRcdFx0dW5iaW5kKFwia2V5dXBcIiwgdGhpcy5fZG9LZXlVcCk7XG5cdFx0fSBlbHNlIGlmIChub2RlTmFtZSA9PT0gXCJkaXZcIiB8fCBub2RlTmFtZSA9PT0gXCJzcGFuXCIpIHtcblx0XHRcdCR0YXJnZXQucmVtb3ZlQ2xhc3ModGhpcy5tYXJrZXJDbGFzc05hbWUpLmVtcHR5KCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEVuYWJsZSB0aGUgZGF0ZSBwaWNrZXIgdG8gYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldFx0ZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKi9cblx0X2VuYWJsZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHZhciBub2RlTmFtZSwgaW5saW5lLFxuXHRcdFx0JHRhcmdldCA9ICQodGFyZ2V0KSxcblx0XHRcdGluc3QgPSAkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUpO1xuXG5cdFx0aWYgKCEkdGFyZ2V0Lmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG5vZGVOYW1lID0gdGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0aWYgKG5vZGVOYW1lID09PSBcImlucHV0XCIpIHtcblx0XHRcdHRhcmdldC5kaXNhYmxlZCA9IGZhbHNlO1xuXHRcdFx0aW5zdC50cmlnZ2VyLmZpbHRlcihcImJ1dHRvblwiKS5cblx0XHRcdFx0ZWFjaChmdW5jdGlvbigpIHsgdGhpcy5kaXNhYmxlZCA9IGZhbHNlOyB9KS5lbmQoKS5cblx0XHRcdFx0ZmlsdGVyKFwiaW1nXCIpLmNzcyh7b3BhY2l0eTogXCIxLjBcIiwgY3Vyc29yOiBcIlwifSk7XG5cdFx0fSBlbHNlIGlmIChub2RlTmFtZSA9PT0gXCJkaXZcIiB8fCBub2RlTmFtZSA9PT0gXCJzcGFuXCIpIHtcblx0XHRcdGlubGluZSA9ICR0YXJnZXQuY2hpbGRyZW4oXCIuXCIgKyB0aGlzLl9pbmxpbmVDbGFzcyk7XG5cdFx0XHRpbmxpbmUuY2hpbGRyZW4oKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWRpc2FibGVkXCIpO1xuXHRcdFx0aW5saW5lLmZpbmQoXCJzZWxlY3QudWktZGF0ZXBpY2tlci1tb250aCwgc2VsZWN0LnVpLWRhdGVwaWNrZXIteWVhclwiKS5cblx0XHRcdFx0cHJvcChcImRpc2FibGVkXCIsIGZhbHNlKTtcblx0XHR9XG5cdFx0dGhpcy5fZGlzYWJsZWRJbnB1dHMgPSAkLm1hcCh0aGlzLl9kaXNhYmxlZElucHV0cyxcblx0XHRcdGZ1bmN0aW9uKHZhbHVlKSB7IHJldHVybiAodmFsdWUgPT09IHRhcmdldCA/IG51bGwgOiB2YWx1ZSk7IH0pOyAvLyBkZWxldGUgZW50cnlcblx0fSxcblxuXHQvKiBEaXNhYmxlIHRoZSBkYXRlIHBpY2tlciB0byBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAqIEBwYXJhbSAgdGFyZ2V0XHRlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqL1xuXHRfZGlzYWJsZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHZhciBub2RlTmFtZSwgaW5saW5lLFxuXHRcdFx0JHRhcmdldCA9ICQodGFyZ2V0KSxcblx0XHRcdGluc3QgPSAkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUpO1xuXG5cdFx0aWYgKCEkdGFyZ2V0Lmhhc0NsYXNzKHRoaXMubWFya2VyQ2xhc3NOYW1lKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdG5vZGVOYW1lID0gdGFyZ2V0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0aWYgKG5vZGVOYW1lID09PSBcImlucHV0XCIpIHtcblx0XHRcdHRhcmdldC5kaXNhYmxlZCA9IHRydWU7XG5cdFx0XHRpbnN0LnRyaWdnZXIuZmlsdGVyKFwiYnV0dG9uXCIpLlxuXHRcdFx0XHRlYWNoKGZ1bmN0aW9uKCkgeyB0aGlzLmRpc2FibGVkID0gdHJ1ZTsgfSkuZW5kKCkuXG5cdFx0XHRcdGZpbHRlcihcImltZ1wiKS5jc3Moe29wYWNpdHk6IFwiMC41XCIsIGN1cnNvcjogXCJkZWZhdWx0XCJ9KTtcblx0XHR9IGVsc2UgaWYgKG5vZGVOYW1lID09PSBcImRpdlwiIHx8IG5vZGVOYW1lID09PSBcInNwYW5cIikge1xuXHRcdFx0aW5saW5lID0gJHRhcmdldC5jaGlsZHJlbihcIi5cIiArIHRoaXMuX2lubGluZUNsYXNzKTtcblx0XHRcdGlubGluZS5jaGlsZHJlbigpLmFkZENsYXNzKFwidWktc3RhdGUtZGlzYWJsZWRcIik7XG5cdFx0XHRpbmxpbmUuZmluZChcInNlbGVjdC51aS1kYXRlcGlja2VyLW1vbnRoLCBzZWxlY3QudWktZGF0ZXBpY2tlci15ZWFyXCIpLlxuXHRcdFx0XHRwcm9wKFwiZGlzYWJsZWRcIiwgdHJ1ZSk7XG5cdFx0fVxuXHRcdHRoaXMuX2Rpc2FibGVkSW5wdXRzID0gJC5tYXAodGhpcy5fZGlzYWJsZWRJbnB1dHMsXG5cdFx0XHRmdW5jdGlvbih2YWx1ZSkgeyByZXR1cm4gKHZhbHVlID09PSB0YXJnZXQgPyBudWxsIDogdmFsdWUpOyB9KTsgLy8gZGVsZXRlIGVudHJ5XG5cdFx0dGhpcy5fZGlzYWJsZWRJbnB1dHNbdGhpcy5fZGlzYWJsZWRJbnB1dHMubGVuZ3RoXSA9IHRhcmdldDtcblx0fSxcblxuXHQvKiBJcyB0aGUgZmlyc3QgZmllbGQgaW4gYSBqUXVlcnkgY29sbGVjdGlvbiBkaXNhYmxlZCBhcyBhIGRhdGVwaWNrZXI/XG5cdCAqIEBwYXJhbSAgdGFyZ2V0XHRlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqIEByZXR1cm4gYm9vbGVhbiAtIHRydWUgaWYgZGlzYWJsZWQsIGZhbHNlIGlmIGVuYWJsZWRcblx0ICovXG5cdF9pc0Rpc2FibGVkRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0KSB7XG5cdFx0aWYgKCF0YXJnZXQpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLl9kaXNhYmxlZElucHV0cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKHRoaXMuX2Rpc2FibGVkSW5wdXRzW2ldID09PSB0YXJnZXQpIHtcblx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBmYWxzZTtcblx0fSxcblxuXHQvKiBSZXRyaWV2ZSB0aGUgaW5zdGFuY2UgZGF0YSBmb3IgdGhlIHRhcmdldCBjb250cm9sLlxuXHQgKiBAcGFyYW0gIHRhcmdldCAgZWxlbWVudCAtIHRoZSB0YXJnZXQgaW5wdXQgZmllbGQgb3IgZGl2aXNpb24gb3Igc3BhblxuXHQgKiBAcmV0dXJuICBvYmplY3QgLSB0aGUgYXNzb2NpYXRlZCBpbnN0YW5jZSBkYXRhXG5cdCAqIEB0aHJvd3MgIGVycm9yIGlmIGEgalF1ZXJ5IHByb2JsZW0gZ2V0dGluZyBkYXRhXG5cdCAqL1xuXHRfZ2V0SW5zdDogZnVuY3Rpb24odGFyZ2V0KSB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiAkLmRhdGEodGFyZ2V0LCBQUk9QX05BTUUpO1xuXHRcdH1cblx0XHRjYXRjaCAoZXJyKSB7XG5cdFx0XHR0aHJvdyBcIk1pc3NpbmcgaW5zdGFuY2UgZGF0YSBmb3IgdGhpcyBkYXRlcGlja2VyXCI7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFVwZGF0ZSBvciByZXRyaWV2ZSB0aGUgc2V0dGluZ3MgZm9yIGEgZGF0ZSBwaWNrZXIgYXR0YWNoZWQgdG8gYW4gaW5wdXQgZmllbGQgb3IgZGl2aXNpb24uXG5cdCAqIEBwYXJhbSAgdGFyZ2V0ICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqIEBwYXJhbSAgbmFtZVx0b2JqZWN0IC0gdGhlIG5ldyBzZXR0aW5ncyB0byB1cGRhdGUgb3Jcblx0ICpcdFx0XHRcdHN0cmluZyAtIHRoZSBuYW1lIG9mIHRoZSBzZXR0aW5nIHRvIGNoYW5nZSBvciByZXRyaWV2ZSxcblx0ICpcdFx0XHRcdHdoZW4gcmV0cmlldmluZyBhbHNvIFwiYWxsXCIgZm9yIGFsbCBpbnN0YW5jZSBzZXR0aW5ncyBvclxuXHQgKlx0XHRcdFx0XCJkZWZhdWx0c1wiIGZvciBhbGwgZ2xvYmFsIGRlZmF1bHRzXG5cdCAqIEBwYXJhbSAgdmFsdWUgICBhbnkgLSB0aGUgbmV3IHZhbHVlIGZvciB0aGUgc2V0dGluZ1xuXHQgKlx0XHRcdFx0KG9taXQgaWYgYWJvdmUgaXMgYW4gb2JqZWN0IG9yIHRvIHJldHJpZXZlIGEgdmFsdWUpXG5cdCAqL1xuXHRfb3B0aW9uRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBuYW1lLCB2YWx1ZSkge1xuXHRcdHZhciBzZXR0aW5ncywgZGF0ZSwgbWluRGF0ZSwgbWF4RGF0ZSxcblx0XHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldCk7XG5cblx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMiAmJiB0eXBlb2YgbmFtZSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0cmV0dXJuIChuYW1lID09PSBcImRlZmF1bHRzXCIgPyAkLmV4dGVuZCh7fSwgJC5kYXRlcGlja2VyLl9kZWZhdWx0cykgOlxuXHRcdFx0XHQoaW5zdCA/IChuYW1lID09PSBcImFsbFwiID8gJC5leHRlbmQoe30sIGluc3Quc2V0dGluZ3MpIDpcblx0XHRcdFx0dGhpcy5fZ2V0KGluc3QsIG5hbWUpKSA6IG51bGwpKTtcblx0XHR9XG5cblx0XHRzZXR0aW5ncyA9IG5hbWUgfHwge307XG5cdFx0aWYgKHR5cGVvZiBuYW1lID09PSBcInN0cmluZ1wiKSB7XG5cdFx0XHRzZXR0aW5ncyA9IHt9O1xuXHRcdFx0c2V0dGluZ3NbbmFtZV0gPSB2YWx1ZTtcblx0XHR9XG5cblx0XHRpZiAoaW5zdCkge1xuXHRcdFx0aWYgKHRoaXMuX2N1ckluc3QgPT09IGluc3QpIHtcblx0XHRcdFx0dGhpcy5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdH1cblxuXHRcdFx0ZGF0ZSA9IHRoaXMuX2dldERhdGVEYXRlcGlja2VyKHRhcmdldCwgdHJ1ZSk7XG5cdFx0XHRtaW5EYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1pblwiKTtcblx0XHRcdG1heERhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsIFwibWF4XCIpO1xuXHRcdFx0ZXh0ZW5kUmVtb3ZlKGluc3Quc2V0dGluZ3MsIHNldHRpbmdzKTtcblx0XHRcdC8vIHJlZm9ybWF0IHRoZSBvbGQgbWluRGF0ZS9tYXhEYXRlIHZhbHVlcyBpZiBkYXRlRm9ybWF0IGNoYW5nZXMgYW5kIGEgbmV3IG1pbkRhdGUvbWF4RGF0ZSBpc24ndCBwcm92aWRlZFxuXHRcdFx0aWYgKG1pbkRhdGUgIT09IG51bGwgJiYgc2V0dGluZ3MuZGF0ZUZvcm1hdCAhPT0gdW5kZWZpbmVkICYmIHNldHRpbmdzLm1pbkRhdGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRpbnN0LnNldHRpbmdzLm1pbkRhdGUgPSB0aGlzLl9mb3JtYXREYXRlKGluc3QsIG1pbkRhdGUpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKG1heERhdGUgIT09IG51bGwgJiYgc2V0dGluZ3MuZGF0ZUZvcm1hdCAhPT0gdW5kZWZpbmVkICYmIHNldHRpbmdzLm1heERhdGUgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRpbnN0LnNldHRpbmdzLm1heERhdGUgPSB0aGlzLl9mb3JtYXREYXRlKGluc3QsIG1heERhdGUpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBcImRpc2FibGVkXCIgaW4gc2V0dGluZ3MgKSB7XG5cdFx0XHRcdGlmICggc2V0dGluZ3MuZGlzYWJsZWQgKSB7XG5cdFx0XHRcdFx0dGhpcy5fZGlzYWJsZURhdGVwaWNrZXIodGFyZ2V0KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLl9lbmFibGVEYXRlcGlja2VyKHRhcmdldCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMuX2F0dGFjaG1lbnRzKCQodGFyZ2V0KSwgaW5zdCk7XG5cdFx0XHR0aGlzLl9hdXRvU2l6ZShpbnN0KTtcblx0XHRcdHRoaXMuX3NldERhdGUoaW5zdCwgZGF0ZSk7XG5cdFx0XHR0aGlzLl91cGRhdGVBbHRlcm5hdGUoaW5zdCk7XG5cdFx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBjaGFuZ2UgbWV0aG9kIGRlcHJlY2F0ZWRcblx0X2NoYW5nZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgdmFsdWUpIHtcblx0XHR0aGlzLl9vcHRpb25EYXRlcGlja2VyKHRhcmdldCwgbmFtZSwgdmFsdWUpO1xuXHR9LFxuXG5cdC8qIFJlZHJhdyB0aGUgZGF0ZSBwaWNrZXIgYXR0YWNoZWQgdG8gYW4gaW5wdXQgZmllbGQgb3IgZGl2aXNpb24uXG5cdCAqIEBwYXJhbSAgdGFyZ2V0ICBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqL1xuXHRfcmVmcmVzaERhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdHZhciBpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXQpO1xuXHRcdGlmIChpbnN0KSB7XG5cdFx0XHR0aGlzLl91cGRhdGVEYXRlcGlja2VyKGluc3QpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBTZXQgdGhlIGRhdGVzIGZvciBhIGpRdWVyeSBzZWxlY3Rpb24uXG5cdCAqIEBwYXJhbSAgdGFyZ2V0IGVsZW1lbnQgLSB0aGUgdGFyZ2V0IGlucHV0IGZpZWxkIG9yIGRpdmlzaW9uIG9yIHNwYW5cblx0ICogQHBhcmFtICBkYXRlXHREYXRlIC0gdGhlIG5ldyBkYXRlXG5cdCAqL1xuXHRfc2V0RGF0ZURhdGVwaWNrZXI6IGZ1bmN0aW9uKHRhcmdldCwgZGF0ZSkge1xuXHRcdHZhciBpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXQpO1xuXHRcdGlmIChpbnN0KSB7XG5cdFx0XHR0aGlzLl9zZXREYXRlKGluc3QsIGRhdGUpO1xuXHRcdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHRcdHRoaXMuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0LyogR2V0IHRoZSBkYXRlKHMpIGZvciB0aGUgZmlyc3QgZW50cnkgaW4gYSBqUXVlcnkgc2VsZWN0aW9uLlxuXHQgKiBAcGFyYW0gIHRhcmdldCBlbGVtZW50IC0gdGhlIHRhcmdldCBpbnB1dCBmaWVsZCBvciBkaXZpc2lvbiBvciBzcGFuXG5cdCAqIEBwYXJhbSAgbm9EZWZhdWx0IGJvb2xlYW4gLSB0cnVlIGlmIG5vIGRlZmF1bHQgZGF0ZSBpcyB0byBiZSB1c2VkXG5cdCAqIEByZXR1cm4gRGF0ZSAtIHRoZSBjdXJyZW50IGRhdGVcblx0ICovXG5cdF9nZXREYXRlRGF0ZXBpY2tlcjogZnVuY3Rpb24odGFyZ2V0LCBub0RlZmF1bHQpIHtcblx0XHR2YXIgaW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0KTtcblx0XHRpZiAoaW5zdCAmJiAhaW5zdC5pbmxpbmUpIHtcblx0XHRcdHRoaXMuX3NldERhdGVGcm9tRmllbGQoaW5zdCwgbm9EZWZhdWx0KTtcblx0XHR9XG5cdFx0cmV0dXJuIChpbnN0ID8gdGhpcy5fZ2V0RGF0ZShpbnN0KSA6IG51bGwpO1xuXHR9LFxuXG5cdC8qIEhhbmRsZSBrZXlzdHJva2VzLiAqL1xuXHRfZG9LZXlEb3duOiBmdW5jdGlvbihldmVudCkge1xuXHRcdHZhciBvblNlbGVjdCwgZGF0ZVN0ciwgc2VsLFxuXHRcdFx0aW5zdCA9ICQuZGF0ZXBpY2tlci5fZ2V0SW5zdChldmVudC50YXJnZXQpLFxuXHRcdFx0aGFuZGxlZCA9IHRydWUsXG5cdFx0XHRpc1JUTCA9IGluc3QuZHBEaXYuaXMoXCIudWktZGF0ZXBpY2tlci1ydGxcIik7XG5cblx0XHRpbnN0Ll9rZXlFdmVudCA9IHRydWU7XG5cdFx0aWYgKCQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcpIHtcblx0XHRcdHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xuXHRcdFx0XHRjYXNlIDk6ICQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoKTtcblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBoaWRlIG9uIHRhYiBvdXRcblx0XHRcdFx0Y2FzZSAxMzogc2VsID0gJChcInRkLlwiICsgJC5kYXRlcGlja2VyLl9kYXlPdmVyQ2xhc3MgKyBcIjpub3QoLlwiICtcblx0XHRcdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fY3VycmVudENsYXNzICsgXCIpXCIsIGluc3QuZHBEaXYpO1xuXHRcdFx0XHRcdFx0aWYgKHNlbFswXSkge1xuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3NlbGVjdERheShldmVudC50YXJnZXQsIGluc3Quc2VsZWN0ZWRNb250aCwgaW5zdC5zZWxlY3RlZFllYXIsIHNlbFswXSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdG9uU2VsZWN0ID0gJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJvblNlbGVjdFwiKTtcblx0XHRcdFx0XHRcdGlmIChvblNlbGVjdCkge1xuXHRcdFx0XHRcdFx0XHRkYXRlU3RyID0gJC5kYXRlcGlja2VyLl9mb3JtYXREYXRlKGluc3QpO1xuXG5cdFx0XHRcdFx0XHRcdC8vIHRyaWdnZXIgY3VzdG9tIGNhbGxiYWNrXG5cdFx0XHRcdFx0XHRcdG9uU2VsZWN0LmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLCBbZGF0ZVN0ciwgaW5zdF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7IC8vIGRvbid0IHN1Ym1pdCB0aGUgZm9ybVxuXHRcdFx0XHRjYXNlIDI3OiAkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gaGlkZSBvbiBlc2NhcGVcblx0XHRcdFx0Y2FzZSAzMzogJC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgKGV2ZW50LmN0cmxLZXkgP1xuXHRcdFx0XHRcdFx0XHQtJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwQmlnTW9udGhzXCIpIDpcblx0XHRcdFx0XHRcdFx0LSQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic3RlcE1vbnRoc1wiKSksIFwiTVwiKTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBwcmV2aW91cyBtb250aC95ZWFyIG9uIHBhZ2UgdXAvKyBjdHJsXG5cdFx0XHRcdGNhc2UgMzQ6ICQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChldmVudC5jdHJsS2V5ID9cblx0XHRcdFx0XHRcdFx0KyQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwic3RlcEJpZ01vbnRoc1wiKSA6XG5cdFx0XHRcdFx0XHRcdCskLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInN0ZXBNb250aHNcIikpLCBcIk1cIik7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gbmV4dCBtb250aC95ZWFyIG9uIHBhZ2UgZG93bi8rIGN0cmxcblx0XHRcdFx0Y2FzZSAzNTogaWYgKGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleSkge1xuXHRcdFx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2NsZWFyRGF0ZShldmVudC50YXJnZXQpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aGFuZGxlZCA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblx0XHRcdFx0XHRcdGJyZWFrOyAvLyBjbGVhciBvbiBjdHJsIG9yIGNvbW1hbmQgK2VuZFxuXHRcdFx0XHRjYXNlIDM2OiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fZ290b1RvZGF5KGV2ZW50LnRhcmdldCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vIGN1cnJlbnQgb24gY3RybCBvciBjb21tYW5kICtob21lXG5cdFx0XHRcdGNhc2UgMzc6IGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgKGlzUlRMID8gKzEgOiAtMSksIFwiRFwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHQvLyAtMSBkYXkgb24gY3RybCBvciBjb21tYW5kICtsZWZ0XG5cdFx0XHRcdFx0XHRpZiAoZXZlbnQub3JpZ2luYWxFdmVudC5hbHRLZXkpIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgKGV2ZW50LmN0cmxLZXkgP1xuXHRcdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInN0ZXBCaWdNb250aHNcIikgOlxuXHRcdFx0XHRcdFx0XHRcdC0kLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInN0ZXBNb250aHNcIikpLCBcIk1cIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHQvLyBuZXh0IG1vbnRoL3llYXIgb24gYWx0ICtsZWZ0IG9uIE1hY1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgMzg6IGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgLTcsIFwiRFwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHRicmVhazsgLy8gLTEgd2VlayBvbiBjdHJsIG9yIGNvbW1hbmQgK3VwXG5cdFx0XHRcdGNhc2UgMzk6IGlmIChldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkpIHtcblx0XHRcdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGV2ZW50LnRhcmdldCwgKGlzUlRMID8gLTEgOiArMSksIFwiRFwiKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGhhbmRsZWQgPSBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XG5cdFx0XHRcdFx0XHQvLyArMSBkYXkgb24gY3RybCBvciBjb21tYW5kICtyaWdodFxuXHRcdFx0XHRcdFx0aWYgKGV2ZW50Lm9yaWdpbmFsRXZlbnQuYWx0S2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsIChldmVudC5jdHJsS2V5ID9cblx0XHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwQmlnTW9udGhzXCIpIDpcblx0XHRcdFx0XHRcdFx0XHQrJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzdGVwTW9udGhzXCIpKSwgXCJNXCIpO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gbmV4dCBtb250aC95ZWFyIG9uIGFsdCArcmlnaHRcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRjYXNlIDQwOiBpZiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5KSB7XG5cdFx0XHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fYWRqdXN0RGF0ZShldmVudC50YXJnZXQsICs3LCBcIkRcIik7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRoYW5kbGVkID0gZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5O1xuXHRcdFx0XHRcdFx0YnJlYWs7IC8vICsxIHdlZWsgb24gY3RybCBvciBjb21tYW5kICtkb3duXG5cdFx0XHRcdGRlZmF1bHQ6IGhhbmRsZWQgPSBmYWxzZTtcblx0XHRcdH1cblx0XHR9IGVsc2UgaWYgKGV2ZW50LmtleUNvZGUgPT09IDM2ICYmIGV2ZW50LmN0cmxLZXkpIHsgLy8gZGlzcGxheSB0aGUgZGF0ZSBwaWNrZXIgb24gY3RybCtob21lXG5cdFx0XHQkLmRhdGVwaWNrZXIuX3Nob3dEYXRlcGlja2VyKHRoaXMpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRoYW5kbGVkID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0aWYgKGhhbmRsZWQpIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cdH0sXG5cblx0LyogRmlsdGVyIGVudGVyZWQgY2hhcmFjdGVycyAtIGJhc2VkIG9uIGRhdGUgZm9ybWF0LiAqL1xuXHRfZG9LZXlQcmVzczogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgY2hhcnMsIGNocixcblx0XHRcdGluc3QgPSAkLmRhdGVwaWNrZXIuX2dldEluc3QoZXZlbnQudGFyZ2V0KTtcblxuXHRcdGlmICgkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcImNvbnN0cmFpbklucHV0XCIpKSB7XG5cdFx0XHRjaGFycyA9ICQuZGF0ZXBpY2tlci5fcG9zc2libGVDaGFycygkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcImRhdGVGb3JtYXRcIikpO1xuXHRcdFx0Y2hyID0gU3RyaW5nLmZyb21DaGFyQ29kZShldmVudC5jaGFyQ29kZSA9PSBudWxsID8gZXZlbnQua2V5Q29kZSA6IGV2ZW50LmNoYXJDb2RlKTtcblx0XHRcdHJldHVybiBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgKGNociA8IFwiIFwiIHx8ICFjaGFycyB8fCBjaGFycy5pbmRleE9mKGNocikgPiAtMSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFN5bmNocm9uaXNlIG1hbnVhbCBlbnRyeSBhbmQgZmllbGQvYWx0ZXJuYXRlIGZpZWxkLiAqL1xuXHRfZG9LZXlVcDogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHR2YXIgZGF0ZSxcblx0XHRcdGluc3QgPSAkLmRhdGVwaWNrZXIuX2dldEluc3QoZXZlbnQudGFyZ2V0KTtcblxuXHRcdGlmIChpbnN0LmlucHV0LnZhbCgpICE9PSBpbnN0Lmxhc3RWYWwpIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGUgPSAkLmRhdGVwaWNrZXIucGFyc2VEYXRlKCQuZGF0ZXBpY2tlci5fZ2V0KGluc3QsIFwiZGF0ZUZvcm1hdFwiKSxcblx0XHRcdFx0XHQoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQudmFsKCkgOiBudWxsKSxcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cblx0XHRcdFx0aWYgKGRhdGUpIHsgLy8gb25seSBpZiB2YWxpZFxuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2V0RGF0ZUZyb21GaWVsZChpbnN0KTtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3VwZGF0ZUFsdGVybmF0ZShpbnN0KTtcblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGNhdGNoIChlcnIpIHtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0LyogUG9wLXVwIHRoZSBkYXRlIHBpY2tlciBmb3IgYSBnaXZlbiBpbnB1dCBmaWVsZC5cblx0ICogSWYgZmFsc2UgcmV0dXJuZWQgZnJvbSBiZWZvcmVTaG93IGV2ZW50IGhhbmRsZXIgZG8gbm90IHNob3cuXG5cdCAqIEBwYXJhbSAgaW5wdXQgIGVsZW1lbnQgLSB0aGUgaW5wdXQgZmllbGQgYXR0YWNoZWQgdG8gdGhlIGRhdGUgcGlja2VyIG9yXG5cdCAqXHRcdFx0XHRcdGV2ZW50IC0gaWYgdHJpZ2dlcmVkIGJ5IGZvY3VzXG5cdCAqL1xuXHRfc2hvd0RhdGVwaWNrZXI6IGZ1bmN0aW9uKGlucHV0KSB7XG5cdFx0aW5wdXQgPSBpbnB1dC50YXJnZXQgfHwgaW5wdXQ7XG5cdFx0aWYgKGlucHV0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwiaW5wdXRcIikgeyAvLyBmaW5kIGZyb20gYnV0dG9uL2ltYWdlIHRyaWdnZXJcblx0XHRcdGlucHV0ID0gJChcImlucHV0XCIsIGlucHV0LnBhcmVudE5vZGUpWzBdO1xuXHRcdH1cblxuXHRcdGlmICgkLmRhdGVwaWNrZXIuX2lzRGlzYWJsZWREYXRlcGlja2VyKGlucHV0KSB8fCAkLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCA9PT0gaW5wdXQpIHsgLy8gYWxyZWFkeSBoZXJlXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIGluc3QsIGJlZm9yZVNob3csIGJlZm9yZVNob3dTZXR0aW5ncywgaXNGaXhlZCxcblx0XHRcdG9mZnNldCwgc2hvd0FuaW0sIGR1cmF0aW9uO1xuXG5cdFx0aW5zdCA9ICQuZGF0ZXBpY2tlci5fZ2V0SW5zdChpbnB1dCk7XG5cdFx0aWYgKCQuZGF0ZXBpY2tlci5fY3VySW5zdCAmJiAkLmRhdGVwaWNrZXIuX2N1ckluc3QgIT09IGluc3QpIHtcblx0XHRcdCQuZGF0ZXBpY2tlci5fY3VySW5zdC5kcERpdi5zdG9wKHRydWUsIHRydWUpO1xuXHRcdFx0aWYgKCBpbnN0ICYmICQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgKSB7XG5cdFx0XHRcdCQuZGF0ZXBpY2tlci5faGlkZURhdGVwaWNrZXIoICQuZGF0ZXBpY2tlci5fY3VySW5zdC5pbnB1dFswXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGJlZm9yZVNob3cgPSAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcImJlZm9yZVNob3dcIik7XG5cdFx0YmVmb3JlU2hvd1NldHRpbmdzID0gYmVmb3JlU2hvdyA/IGJlZm9yZVNob3cuYXBwbHkoaW5wdXQsIFtpbnB1dCwgaW5zdF0pIDoge307XG5cdFx0aWYoYmVmb3JlU2hvd1NldHRpbmdzID09PSBmYWxzZSl7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdGV4dGVuZFJlbW92ZShpbnN0LnNldHRpbmdzLCBiZWZvcmVTaG93U2V0dGluZ3MpO1xuXG5cdFx0aW5zdC5sYXN0VmFsID0gbnVsbDtcblx0XHQkLmRhdGVwaWNrZXIuX2xhc3RJbnB1dCA9IGlucHV0O1xuXHRcdCQuZGF0ZXBpY2tlci5fc2V0RGF0ZUZyb21GaWVsZChpbnN0KTtcblxuXHRcdGlmICgkLmRhdGVwaWNrZXIuX2luRGlhbG9nKSB7IC8vIGhpZGUgY3Vyc29yXG5cdFx0XHRpbnB1dC52YWx1ZSA9IFwiXCI7XG5cdFx0fVxuXHRcdGlmICghJC5kYXRlcGlja2VyLl9wb3MpIHsgLy8gcG9zaXRpb24gYmVsb3cgaW5wdXRcblx0XHRcdCQuZGF0ZXBpY2tlci5fcG9zID0gJC5kYXRlcGlja2VyLl9maW5kUG9zKGlucHV0KTtcblx0XHRcdCQuZGF0ZXBpY2tlci5fcG9zWzFdICs9IGlucHV0Lm9mZnNldEhlaWdodDsgLy8gYWRkIHRoZSBoZWlnaHRcblx0XHR9XG5cblx0XHRpc0ZpeGVkID0gZmFsc2U7XG5cdFx0JChpbnB1dCkucGFyZW50cygpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpc0ZpeGVkIHw9ICQodGhpcykuY3NzKFwicG9zaXRpb25cIikgPT09IFwiZml4ZWRcIjtcblx0XHRcdHJldHVybiAhaXNGaXhlZDtcblx0XHR9KTtcblxuXHRcdG9mZnNldCA9IHtsZWZ0OiAkLmRhdGVwaWNrZXIuX3Bvc1swXSwgdG9wOiAkLmRhdGVwaWNrZXIuX3Bvc1sxXX07XG5cdFx0JC5kYXRlcGlja2VyLl9wb3MgPSBudWxsO1xuXHRcdC8vdG8gYXZvaWQgZmxhc2hlcyBvbiBGaXJlZm94XG5cdFx0aW5zdC5kcERpdi5lbXB0eSgpO1xuXHRcdC8vIGRldGVybWluZSBzaXppbmcgb2Zmc2NyZWVuXG5cdFx0aW5zdC5kcERpdi5jc3Moe3Bvc2l0aW9uOiBcImFic29sdXRlXCIsIGRpc3BsYXk6IFwiYmxvY2tcIiwgdG9wOiBcIi0xMDAwcHhcIn0pO1xuXHRcdCQuZGF0ZXBpY2tlci5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0XHQvLyBmaXggd2lkdGggZm9yIGR5bmFtaWMgbnVtYmVyIG9mIGRhdGUgcGlja2Vyc1xuXHRcdC8vIGFuZCBhZGp1c3QgcG9zaXRpb24gYmVmb3JlIHNob3dpbmdcblx0XHRvZmZzZXQgPSAkLmRhdGVwaWNrZXIuX2NoZWNrT2Zmc2V0KGluc3QsIG9mZnNldCwgaXNGaXhlZCk7XG5cdFx0aW5zdC5kcERpdi5jc3Moe3Bvc2l0aW9uOiAoJC5kYXRlcGlja2VyLl9pbkRpYWxvZyAmJiAkLmJsb2NrVUkgP1xuXHRcdFx0XCJzdGF0aWNcIiA6IChpc0ZpeGVkID8gXCJmaXhlZFwiIDogXCJhYnNvbHV0ZVwiKSksIGRpc3BsYXk6IFwibm9uZVwiLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgKyBcInB4XCIsIHRvcDogb2Zmc2V0LnRvcCArIFwicHhcIn0pO1xuXG5cdFx0aWYgKCFpbnN0LmlubGluZSkge1xuXHRcdFx0c2hvd0FuaW0gPSAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInNob3dBbmltXCIpO1xuXHRcdFx0ZHVyYXRpb24gPSAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcImR1cmF0aW9uXCIpO1xuXHRcdFx0aW5zdC5kcERpdi56SW5kZXgoJChpbnB1dCkuekluZGV4KCkrMSk7XG5cdFx0XHQkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCAkLmVmZmVjdHMgJiYgJC5lZmZlY3RzLmVmZmVjdFsgc2hvd0FuaW0gXSApIHtcblx0XHRcdFx0aW5zdC5kcERpdi5zaG93KHNob3dBbmltLCAkLmRhdGVwaWNrZXIuX2dldChpbnN0LCBcInNob3dPcHRpb25zXCIpLCBkdXJhdGlvbik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpbnN0LmRwRGl2W3Nob3dBbmltIHx8IFwic2hvd1wiXShzaG93QW5pbSA/IGR1cmF0aW9uIDogbnVsbCk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggJC5kYXRlcGlja2VyLl9zaG91bGRGb2N1c0lucHV0KCBpbnN0ICkgKSB7XG5cdFx0XHRcdGluc3QuaW5wdXQuZm9jdXMoKTtcblx0XHRcdH1cblxuXHRcdFx0JC5kYXRlcGlja2VyLl9jdXJJbnN0ID0gaW5zdDtcblx0XHR9XG5cdH0sXG5cblx0LyogR2VuZXJhdGUgdGhlIGRhdGUgcGlja2VyIGNvbnRlbnQuICovXG5cdF91cGRhdGVEYXRlcGlja2VyOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dGhpcy5tYXhSb3dzID0gNDsgLy9SZXNldCB0aGUgbWF4IG51bWJlciBvZiByb3dzIGJlaW5nIGRpc3BsYXllZCAoc2VlICM3MDQzKVxuXHRcdGluc3RBY3RpdmUgPSBpbnN0OyAvLyBmb3IgZGVsZWdhdGUgaG92ZXIgZXZlbnRzXG5cdFx0aW5zdC5kcERpdi5lbXB0eSgpLmFwcGVuZCh0aGlzLl9nZW5lcmF0ZUhUTUwoaW5zdCkpO1xuXHRcdHRoaXMuX2F0dGFjaEhhbmRsZXJzKGluc3QpO1xuXHRcdGluc3QuZHBEaXYuZmluZChcIi5cIiArIHRoaXMuX2RheU92ZXJDbGFzcyArIFwiIGFcIikubW91c2VvdmVyKCk7XG5cblx0XHR2YXIgb3JpZ3llYXJzaHRtbCxcblx0XHRcdG51bU1vbnRocyA9IHRoaXMuX2dldE51bWJlck9mTW9udGhzKGluc3QpLFxuXHRcdFx0Y29scyA9IG51bU1vbnRoc1sxXSxcblx0XHRcdHdpZHRoID0gMTc7XG5cblx0XHRpbnN0LmRwRGl2LnJlbW92ZUNsYXNzKFwidWktZGF0ZXBpY2tlci1tdWx0aS0yIHVpLWRhdGVwaWNrZXItbXVsdGktMyB1aS1kYXRlcGlja2VyLW11bHRpLTRcIikud2lkdGgoXCJcIik7XG5cdFx0aWYgKGNvbHMgPiAxKSB7XG5cdFx0XHRpbnN0LmRwRGl2LmFkZENsYXNzKFwidWktZGF0ZXBpY2tlci1tdWx0aS1cIiArIGNvbHMpLmNzcyhcIndpZHRoXCIsICh3aWR0aCAqIGNvbHMpICsgXCJlbVwiKTtcblx0XHR9XG5cdFx0aW5zdC5kcERpdlsobnVtTW9udGhzWzBdICE9PSAxIHx8IG51bU1vbnRoc1sxXSAhPT0gMSA/IFwiYWRkXCIgOiBcInJlbW92ZVwiKSArXG5cdFx0XHRcIkNsYXNzXCJdKFwidWktZGF0ZXBpY2tlci1tdWx0aVwiKTtcblx0XHRpbnN0LmRwRGl2Wyh0aGlzLl9nZXQoaW5zdCwgXCJpc1JUTFwiKSA/IFwiYWRkXCIgOiBcInJlbW92ZVwiKSArXG5cdFx0XHRcIkNsYXNzXCJdKFwidWktZGF0ZXBpY2tlci1ydGxcIik7XG5cblx0XHRpZiAoaW5zdCA9PT0gJC5kYXRlcGlja2VyLl9jdXJJbnN0ICYmICQuZGF0ZXBpY2tlci5fZGF0ZXBpY2tlclNob3dpbmcgJiYgJC5kYXRlcGlja2VyLl9zaG91bGRGb2N1c0lucHV0KCBpbnN0ICkgKSB7XG5cdFx0XHRpbnN0LmlucHV0LmZvY3VzKCk7XG5cdFx0fVxuXG5cdFx0Ly8gZGVmZmVyZWQgcmVuZGVyIG9mIHRoZSB5ZWFycyBzZWxlY3QgKHRvIGF2b2lkIGZsYXNoZXMgb24gRmlyZWZveClcblx0XHRpZiggaW5zdC55ZWFyc2h0bWwgKXtcblx0XHRcdG9yaWd5ZWFyc2h0bWwgPSBpbnN0LnllYXJzaHRtbDtcblx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcblx0XHRcdFx0Ly9hc3N1cmUgdGhhdCBpbnN0LnllYXJzaHRtbCBkaWRuJ3QgY2hhbmdlLlxuXHRcdFx0XHRpZiggb3JpZ3llYXJzaHRtbCA9PT0gaW5zdC55ZWFyc2h0bWwgJiYgaW5zdC55ZWFyc2h0bWwgKXtcblx0XHRcdFx0XHRpbnN0LmRwRGl2LmZpbmQoXCJzZWxlY3QudWktZGF0ZXBpY2tlci15ZWFyOmZpcnN0XCIpLnJlcGxhY2VXaXRoKGluc3QueWVhcnNodG1sKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRvcmlneWVhcnNodG1sID0gaW5zdC55ZWFyc2h0bWwgPSBudWxsO1xuXHRcdFx0fSwgMCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vICM2Njk0IC0gZG9uJ3QgZm9jdXMgdGhlIGlucHV0IGlmIGl0J3MgYWxyZWFkeSBmb2N1c2VkXG5cdC8vIHRoaXMgYnJlYWtzIHRoZSBjaGFuZ2UgZXZlbnQgaW4gSUVcblx0Ly8gU3VwcG9ydDogSUUgYW5kIGpRdWVyeSA8MS45XG5cdF9zaG91bGRGb2N1c0lucHV0OiBmdW5jdGlvbiggaW5zdCApIHtcblx0XHRyZXR1cm4gaW5zdC5pbnB1dCAmJiBpbnN0LmlucHV0LmlzKCBcIjp2aXNpYmxlXCIgKSAmJiAhaW5zdC5pbnB1dC5pcyggXCI6ZGlzYWJsZWRcIiApICYmICFpbnN0LmlucHV0LmlzKCBcIjpmb2N1c1wiICk7XG5cdH0sXG5cblx0LyogQ2hlY2sgcG9zaXRpb25pbmcgdG8gcmVtYWluIG9uIHNjcmVlbi4gKi9cblx0X2NoZWNrT2Zmc2V0OiBmdW5jdGlvbihpbnN0LCBvZmZzZXQsIGlzRml4ZWQpIHtcblx0XHR2YXIgZHBXaWR0aCA9IGluc3QuZHBEaXYub3V0ZXJXaWR0aCgpLFxuXHRcdFx0ZHBIZWlnaHQgPSBpbnN0LmRwRGl2Lm91dGVySGVpZ2h0KCksXG5cdFx0XHRpbnB1dFdpZHRoID0gaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQub3V0ZXJXaWR0aCgpIDogMCxcblx0XHRcdGlucHV0SGVpZ2h0ID0gaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQub3V0ZXJIZWlnaHQoKSA6IDAsXG5cdFx0XHR2aWV3V2lkdGggPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggKyAoaXNGaXhlZCA/IDAgOiAkKGRvY3VtZW50KS5zY3JvbGxMZWZ0KCkpLFxuXHRcdFx0dmlld0hlaWdodCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgKyAoaXNGaXhlZCA/IDAgOiAkKGRvY3VtZW50KS5zY3JvbGxUb3AoKSk7XG5cblx0XHRvZmZzZXQubGVmdCAtPSAodGhpcy5fZ2V0KGluc3QsIFwiaXNSVExcIikgPyAoZHBXaWR0aCAtIGlucHV0V2lkdGgpIDogMCk7XG5cdFx0b2Zmc2V0LmxlZnQgLT0gKGlzRml4ZWQgJiYgb2Zmc2V0LmxlZnQgPT09IGluc3QuaW5wdXQub2Zmc2V0KCkubGVmdCkgPyAkKGRvY3VtZW50KS5zY3JvbGxMZWZ0KCkgOiAwO1xuXHRcdG9mZnNldC50b3AgLT0gKGlzRml4ZWQgJiYgb2Zmc2V0LnRvcCA9PT0gKGluc3QuaW5wdXQub2Zmc2V0KCkudG9wICsgaW5wdXRIZWlnaHQpKSA/ICQoZG9jdW1lbnQpLnNjcm9sbFRvcCgpIDogMDtcblxuXHRcdC8vIG5vdyBjaGVjayBpZiBkYXRlcGlja2VyIGlzIHNob3dpbmcgb3V0c2lkZSB3aW5kb3cgdmlld3BvcnQgLSBtb3ZlIHRvIGEgYmV0dGVyIHBsYWNlIGlmIHNvLlxuXHRcdG9mZnNldC5sZWZ0IC09IE1hdGgubWluKG9mZnNldC5sZWZ0LCAob2Zmc2V0LmxlZnQgKyBkcFdpZHRoID4gdmlld1dpZHRoICYmIHZpZXdXaWR0aCA+IGRwV2lkdGgpID9cblx0XHRcdE1hdGguYWJzKG9mZnNldC5sZWZ0ICsgZHBXaWR0aCAtIHZpZXdXaWR0aCkgOiAwKTtcblx0XHRvZmZzZXQudG9wIC09IE1hdGgubWluKG9mZnNldC50b3AsIChvZmZzZXQudG9wICsgZHBIZWlnaHQgPiB2aWV3SGVpZ2h0ICYmIHZpZXdIZWlnaHQgPiBkcEhlaWdodCkgP1xuXHRcdFx0TWF0aC5hYnMoZHBIZWlnaHQgKyBpbnB1dEhlaWdodCkgOiAwKTtcblxuXHRcdHJldHVybiBvZmZzZXQ7XG5cdH0sXG5cblx0LyogRmluZCBhbiBvYmplY3QncyBwb3NpdGlvbiBvbiB0aGUgc2NyZWVuLiAqL1xuXHRfZmluZFBvczogZnVuY3Rpb24ob2JqKSB7XG5cdFx0dmFyIHBvc2l0aW9uLFxuXHRcdFx0aW5zdCA9IHRoaXMuX2dldEluc3Qob2JqKSxcblx0XHRcdGlzUlRMID0gdGhpcy5fZ2V0KGluc3QsIFwiaXNSVExcIik7XG5cblx0XHR3aGlsZSAob2JqICYmIChvYmoudHlwZSA9PT0gXCJoaWRkZW5cIiB8fCBvYmoubm9kZVR5cGUgIT09IDEgfHwgJC5leHByLmZpbHRlcnMuaGlkZGVuKG9iaikpKSB7XG5cdFx0XHRvYmogPSBvYmpbaXNSVEwgPyBcInByZXZpb3VzU2libGluZ1wiIDogXCJuZXh0U2libGluZ1wiXTtcblx0XHR9XG5cblx0XHRwb3NpdGlvbiA9ICQob2JqKS5vZmZzZXQoKTtcblx0XHRyZXR1cm4gW3Bvc2l0aW9uLmxlZnQsIHBvc2l0aW9uLnRvcF07XG5cdH0sXG5cblx0LyogSGlkZSB0aGUgZGF0ZSBwaWNrZXIgZnJvbSB2aWV3LlxuXHQgKiBAcGFyYW0gIGlucHV0ICBlbGVtZW50IC0gdGhlIGlucHV0IGZpZWxkIGF0dGFjaGVkIHRvIHRoZSBkYXRlIHBpY2tlclxuXHQgKi9cblx0X2hpZGVEYXRlcGlja2VyOiBmdW5jdGlvbihpbnB1dCkge1xuXHRcdHZhciBzaG93QW5pbSwgZHVyYXRpb24sIHBvc3RQcm9jZXNzLCBvbkNsb3NlLFxuXHRcdFx0aW5zdCA9IHRoaXMuX2N1ckluc3Q7XG5cblx0XHRpZiAoIWluc3QgfHwgKGlucHV0ICYmIGluc3QgIT09ICQuZGF0YShpbnB1dCwgUFJPUF9OQU1FKSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fZGF0ZXBpY2tlclNob3dpbmcpIHtcblx0XHRcdHNob3dBbmltID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvd0FuaW1cIik7XG5cdFx0XHRkdXJhdGlvbiA9IHRoaXMuX2dldChpbnN0LCBcImR1cmF0aW9uXCIpO1xuXHRcdFx0cG9zdFByb2Nlc3MgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0JC5kYXRlcGlja2VyLl90aWR5RGlhbG9nKGluc3QpO1xuXHRcdFx0fTtcblxuXHRcdFx0Ly8gREVQUkVDQVRFRDogYWZ0ZXIgQkMgZm9yIDEuOC54ICQuZWZmZWN0c1sgc2hvd0FuaW0gXSBpcyBub3QgbmVlZGVkXG5cdFx0XHRpZiAoICQuZWZmZWN0cyAmJiAoICQuZWZmZWN0cy5lZmZlY3RbIHNob3dBbmltIF0gfHwgJC5lZmZlY3RzWyBzaG93QW5pbSBdICkgKSB7XG5cdFx0XHRcdGluc3QuZHBEaXYuaGlkZShzaG93QW5pbSwgJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJzaG93T3B0aW9uc1wiKSwgZHVyYXRpb24sIHBvc3RQcm9jZXNzKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGluc3QuZHBEaXZbKHNob3dBbmltID09PSBcInNsaWRlRG93blwiID8gXCJzbGlkZVVwXCIgOlxuXHRcdFx0XHRcdChzaG93QW5pbSA9PT0gXCJmYWRlSW5cIiA/IFwiZmFkZU91dFwiIDogXCJoaWRlXCIpKV0oKHNob3dBbmltID8gZHVyYXRpb24gOiBudWxsKSwgcG9zdFByb2Nlc3MpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIXNob3dBbmltKSB7XG5cdFx0XHRcdHBvc3RQcm9jZXNzKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLl9kYXRlcGlja2VyU2hvd2luZyA9IGZhbHNlO1xuXG5cdFx0XHRvbkNsb3NlID0gdGhpcy5fZ2V0KGluc3QsIFwib25DbG9zZVwiKTtcblx0XHRcdGlmIChvbkNsb3NlKSB7XG5cdFx0XHRcdG9uQ2xvc2UuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksIFsoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXQudmFsKCkgOiBcIlwiKSwgaW5zdF0pO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9sYXN0SW5wdXQgPSBudWxsO1xuXHRcdFx0aWYgKHRoaXMuX2luRGlhbG9nKSB7XG5cdFx0XHRcdHRoaXMuX2RpYWxvZ0lucHV0LmNzcyh7IHBvc2l0aW9uOiBcImFic29sdXRlXCIsIGxlZnQ6IFwiMFwiLCB0b3A6IFwiLTEwMHB4XCIgfSk7XG5cdFx0XHRcdGlmICgkLmJsb2NrVUkpIHtcblx0XHRcdFx0XHQkLnVuYmxvY2tVSSgpO1xuXHRcdFx0XHRcdCQoXCJib2R5XCIpLmFwcGVuZCh0aGlzLmRwRGl2KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0dGhpcy5faW5EaWFsb2cgPSBmYWxzZTtcblx0XHR9XG5cdH0sXG5cblx0LyogVGlkeSB1cCBhZnRlciBhIGRpYWxvZyBkaXNwbGF5LiAqL1xuXHRfdGlkeURpYWxvZzogZnVuY3Rpb24oaW5zdCkge1xuXHRcdGluc3QuZHBEaXYucmVtb3ZlQ2xhc3ModGhpcy5fZGlhbG9nQ2xhc3MpLnVuYmluZChcIi51aS1kYXRlcGlja2VyLWNhbGVuZGFyXCIpO1xuXHR9LFxuXG5cdC8qIENsb3NlIGRhdGUgcGlja2VyIGlmIGNsaWNrZWQgZWxzZXdoZXJlLiAqL1xuXHRfY2hlY2tFeHRlcm5hbENsaWNrOiBmdW5jdGlvbihldmVudCkge1xuXHRcdGlmICghJC5kYXRlcGlja2VyLl9jdXJJbnN0KSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyICR0YXJnZXQgPSAkKGV2ZW50LnRhcmdldCksXG5cdFx0XHRpbnN0ID0gJC5kYXRlcGlja2VyLl9nZXRJbnN0KCR0YXJnZXRbMF0pO1xuXG5cdFx0aWYgKCAoICggJHRhcmdldFswXS5pZCAhPT0gJC5kYXRlcGlja2VyLl9tYWluRGl2SWQgJiZcblx0XHRcdFx0JHRhcmdldC5wYXJlbnRzKFwiI1wiICsgJC5kYXRlcGlja2VyLl9tYWluRGl2SWQpLmxlbmd0aCA9PT0gMCAmJlxuXHRcdFx0XHQhJHRhcmdldC5oYXNDbGFzcygkLmRhdGVwaWNrZXIubWFya2VyQ2xhc3NOYW1lKSAmJlxuXHRcdFx0XHQhJHRhcmdldC5jbG9zZXN0KFwiLlwiICsgJC5kYXRlcGlja2VyLl90cmlnZ2VyQ2xhc3MpLmxlbmd0aCAmJlxuXHRcdFx0XHQkLmRhdGVwaWNrZXIuX2RhdGVwaWNrZXJTaG93aW5nICYmICEoJC5kYXRlcGlja2VyLl9pbkRpYWxvZyAmJiAkLmJsb2NrVUkpICkgKSB8fFxuXHRcdFx0KCAkdGFyZ2V0Lmhhc0NsYXNzKCQuZGF0ZXBpY2tlci5tYXJrZXJDbGFzc05hbWUpICYmICQuZGF0ZXBpY2tlci5fY3VySW5zdCAhPT0gaW5zdCApICkge1xuXHRcdFx0XHQkLmRhdGVwaWNrZXIuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIEFkanVzdCBvbmUgb2YgdGhlIGRhdGUgc3ViLWZpZWxkcy4gKi9cblx0X2FkanVzdERhdGU6IGZ1bmN0aW9uKGlkLCBvZmZzZXQsIHBlcmlvZCkge1xuXHRcdHZhciB0YXJnZXQgPSAkKGlkKSxcblx0XHRcdGluc3QgPSB0aGlzLl9nZXRJbnN0KHRhcmdldFswXSk7XG5cblx0XHRpZiAodGhpcy5faXNEaXNhYmxlZERhdGVwaWNrZXIodGFyZ2V0WzBdKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLl9hZGp1c3RJbnN0RGF0ZShpbnN0LCBvZmZzZXQgK1xuXHRcdFx0KHBlcmlvZCA9PT0gXCJNXCIgPyB0aGlzLl9nZXQoaW5zdCwgXCJzaG93Q3VycmVudEF0UG9zXCIpIDogMCksIC8vIHVuZG8gcG9zaXRpb25pbmdcblx0XHRcdHBlcmlvZCk7XG5cdFx0dGhpcy5fdXBkYXRlRGF0ZXBpY2tlcihpbnN0KTtcblx0fSxcblxuXHQvKiBBY3Rpb24gZm9yIGN1cnJlbnQgbGluay4gKi9cblx0X2dvdG9Ub2RheTogZnVuY3Rpb24oaWQpIHtcblx0XHR2YXIgZGF0ZSxcblx0XHRcdHRhcmdldCA9ICQoaWQpLFxuXHRcdFx0aW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblxuXHRcdGlmICh0aGlzLl9nZXQoaW5zdCwgXCJnb3RvQ3VycmVudFwiKSAmJiBpbnN0LmN1cnJlbnREYXkpIHtcblx0XHRcdGluc3Quc2VsZWN0ZWREYXkgPSBpbnN0LmN1cnJlbnREYXk7XG5cdFx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGluc3QuY3VycmVudE1vbnRoO1xuXHRcdFx0aW5zdC5kcmF3WWVhciA9IGluc3Quc2VsZWN0ZWRZZWFyID0gaW5zdC5jdXJyZW50WWVhcjtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0ZSA9IG5ldyBEYXRlKCk7XG5cdFx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gZGF0ZS5nZXREYXRlKCk7XG5cdFx0XHRpbnN0LmRyYXdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCA9IGRhdGUuZ2V0TW9udGgoKTtcblx0XHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHR9XG5cdFx0dGhpcy5fbm90aWZ5Q2hhbmdlKGluc3QpO1xuXHRcdHRoaXMuX2FkanVzdERhdGUodGFyZ2V0KTtcblx0fSxcblxuXHQvKiBBY3Rpb24gZm9yIHNlbGVjdGluZyBhIG5ldyBtb250aC95ZWFyLiAqL1xuXHRfc2VsZWN0TW9udGhZZWFyOiBmdW5jdGlvbihpZCwgc2VsZWN0LCBwZXJpb2QpIHtcblx0XHR2YXIgdGFyZ2V0ID0gJChpZCksXG5cdFx0XHRpbnN0ID0gdGhpcy5fZ2V0SW5zdCh0YXJnZXRbMF0pO1xuXG5cdFx0aW5zdFtcInNlbGVjdGVkXCIgKyAocGVyaW9kID09PSBcIk1cIiA/IFwiTW9udGhcIiA6IFwiWWVhclwiKV0gPVxuXHRcdGluc3RbXCJkcmF3XCIgKyAocGVyaW9kID09PSBcIk1cIiA/IFwiTW9udGhcIiA6IFwiWWVhclwiKV0gPVxuXHRcdFx0cGFyc2VJbnQoc2VsZWN0Lm9wdGlvbnNbc2VsZWN0LnNlbGVjdGVkSW5kZXhdLnZhbHVlLDEwKTtcblxuXHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0XHR0aGlzLl9hZGp1c3REYXRlKHRhcmdldCk7XG5cdH0sXG5cblx0LyogQWN0aW9uIGZvciBzZWxlY3RpbmcgYSBkYXkuICovXG5cdF9zZWxlY3REYXk6IGZ1bmN0aW9uKGlkLCBtb250aCwgeWVhciwgdGQpIHtcblx0XHR2YXIgaW5zdCxcblx0XHRcdHRhcmdldCA9ICQoaWQpO1xuXG5cdFx0aWYgKCQodGQpLmhhc0NsYXNzKHRoaXMuX3Vuc2VsZWN0YWJsZUNsYXNzKSB8fCB0aGlzLl9pc0Rpc2FibGVkRGF0ZXBpY2tlcih0YXJnZXRbMF0pKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gaW5zdC5jdXJyZW50RGF5ID0gJChcImFcIiwgdGQpLmh0bWwoKTtcblx0XHRpbnN0LnNlbGVjdGVkTW9udGggPSBpbnN0LmN1cnJlbnRNb250aCA9IG1vbnRoO1xuXHRcdGluc3Quc2VsZWN0ZWRZZWFyID0gaW5zdC5jdXJyZW50WWVhciA9IHllYXI7XG5cdFx0dGhpcy5fc2VsZWN0RGF0ZShpZCwgdGhpcy5fZm9ybWF0RGF0ZShpbnN0LFxuXHRcdFx0aW5zdC5jdXJyZW50RGF5LCBpbnN0LmN1cnJlbnRNb250aCwgaW5zdC5jdXJyZW50WWVhcikpO1xuXHR9LFxuXG5cdC8qIEVyYXNlIHRoZSBpbnB1dCBmaWVsZCBhbmQgaGlkZSB0aGUgZGF0ZSBwaWNrZXIuICovXG5cdF9jbGVhckRhdGU6IGZ1bmN0aW9uKGlkKSB7XG5cdFx0dmFyIHRhcmdldCA9ICQoaWQpO1xuXHRcdHRoaXMuX3NlbGVjdERhdGUodGFyZ2V0LCBcIlwiKTtcblx0fSxcblxuXHQvKiBVcGRhdGUgdGhlIGlucHV0IGZpZWxkIHdpdGggdGhlIHNlbGVjdGVkIGRhdGUuICovXG5cdF9zZWxlY3REYXRlOiBmdW5jdGlvbihpZCwgZGF0ZVN0cikge1xuXHRcdHZhciBvblNlbGVjdCxcblx0XHRcdHRhcmdldCA9ICQoaWQpLFxuXHRcdFx0aW5zdCA9IHRoaXMuX2dldEluc3QodGFyZ2V0WzBdKTtcblxuXHRcdGRhdGVTdHIgPSAoZGF0ZVN0ciAhPSBudWxsID8gZGF0ZVN0ciA6IHRoaXMuX2Zvcm1hdERhdGUoaW5zdCkpO1xuXHRcdGlmIChpbnN0LmlucHV0KSB7XG5cdFx0XHRpbnN0LmlucHV0LnZhbChkYXRlU3RyKTtcblx0XHR9XG5cdFx0dGhpcy5fdXBkYXRlQWx0ZXJuYXRlKGluc3QpO1xuXG5cdFx0b25TZWxlY3QgPSB0aGlzLl9nZXQoaW5zdCwgXCJvblNlbGVjdFwiKTtcblx0XHRpZiAob25TZWxlY3QpIHtcblx0XHRcdG9uU2VsZWN0LmFwcGx5KChpbnN0LmlucHV0ID8gaW5zdC5pbnB1dFswXSA6IG51bGwpLCBbZGF0ZVN0ciwgaW5zdF0pOyAgLy8gdHJpZ2dlciBjdXN0b20gY2FsbGJhY2tcblx0XHR9IGVsc2UgaWYgKGluc3QuaW5wdXQpIHtcblx0XHRcdGluc3QuaW5wdXQudHJpZ2dlcihcImNoYW5nZVwiKTsgLy8gZmlyZSB0aGUgY2hhbmdlIGV2ZW50XG5cdFx0fVxuXG5cdFx0aWYgKGluc3QuaW5saW5lKXtcblx0XHRcdHRoaXMuX3VwZGF0ZURhdGVwaWNrZXIoaW5zdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuX2hpZGVEYXRlcGlja2VyKCk7XG5cdFx0XHR0aGlzLl9sYXN0SW5wdXQgPSBpbnN0LmlucHV0WzBdO1xuXHRcdFx0aWYgKHR5cGVvZihpbnN0LmlucHV0WzBdKSAhPT0gXCJvYmplY3RcIikge1xuXHRcdFx0XHRpbnN0LmlucHV0LmZvY3VzKCk7IC8vIHJlc3RvcmUgZm9jdXNcblx0XHRcdH1cblx0XHRcdHRoaXMuX2xhc3RJbnB1dCA9IG51bGw7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIFVwZGF0ZSBhbnkgYWx0ZXJuYXRlIGZpZWxkIHRvIHN5bmNocm9uaXNlIHdpdGggdGhlIG1haW4gZmllbGQuICovXG5cdF91cGRhdGVBbHRlcm5hdGU6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgYWx0Rm9ybWF0LCBkYXRlLCBkYXRlU3RyLFxuXHRcdFx0YWx0RmllbGQgPSB0aGlzLl9nZXQoaW5zdCwgXCJhbHRGaWVsZFwiKTtcblxuXHRcdGlmIChhbHRGaWVsZCkgeyAvLyB1cGRhdGUgYWx0ZXJuYXRlIGZpZWxkIHRvb1xuXHRcdFx0YWx0Rm9ybWF0ID0gdGhpcy5fZ2V0KGluc3QsIFwiYWx0Rm9ybWF0XCIpIHx8IHRoaXMuX2dldChpbnN0LCBcImRhdGVGb3JtYXRcIik7XG5cdFx0XHRkYXRlID0gdGhpcy5fZ2V0RGF0ZShpbnN0KTtcblx0XHRcdGRhdGVTdHIgPSB0aGlzLmZvcm1hdERhdGUoYWx0Rm9ybWF0LCBkYXRlLCB0aGlzLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpO1xuXHRcdFx0JChhbHRGaWVsZCkuZWFjaChmdW5jdGlvbigpIHsgJCh0aGlzKS52YWwoZGF0ZVN0cik7IH0pO1xuXHRcdH1cblx0fSxcblxuXHQvKiBTZXQgYXMgYmVmb3JlU2hvd0RheSBmdW5jdGlvbiB0byBwcmV2ZW50IHNlbGVjdGlvbiBvZiB3ZWVrZW5kcy5cblx0ICogQHBhcmFtICBkYXRlICBEYXRlIC0gdGhlIGRhdGUgdG8gY3VzdG9taXNlXG5cdCAqIEByZXR1cm4gW2Jvb2xlYW4sIHN0cmluZ10gLSBpcyB0aGlzIGRhdGUgc2VsZWN0YWJsZT8sIHdoYXQgaXMgaXRzIENTUyBjbGFzcz9cblx0ICovXG5cdG5vV2Vla2VuZHM6IGZ1bmN0aW9uKGRhdGUpIHtcblx0XHR2YXIgZGF5ID0gZGF0ZS5nZXREYXkoKTtcblx0XHRyZXR1cm4gWyhkYXkgPiAwICYmIGRheSA8IDYpLCBcIlwiXTtcblx0fSxcblxuXHQvKiBTZXQgYXMgY2FsY3VsYXRlV2VlayB0byBkZXRlcm1pbmUgdGhlIHdlZWsgb2YgdGhlIHllYXIgYmFzZWQgb24gdGhlIElTTyA4NjAxIGRlZmluaXRpb24uXG5cdCAqIEBwYXJhbSAgZGF0ZSAgRGF0ZSAtIHRoZSBkYXRlIHRvIGdldCB0aGUgd2VlayBmb3Jcblx0ICogQHJldHVybiAgbnVtYmVyIC0gdGhlIG51bWJlciBvZiB0aGUgd2VlayB3aXRoaW4gdGhlIHllYXIgdGhhdCBjb250YWlucyB0aGlzIGRhdGVcblx0ICovXG5cdGlzbzg2MDFXZWVrOiBmdW5jdGlvbihkYXRlKSB7XG5cdFx0dmFyIHRpbWUsXG5cdFx0XHRjaGVja0RhdGUgPSBuZXcgRGF0ZShkYXRlLmdldFRpbWUoKSk7XG5cblx0XHQvLyBGaW5kIFRodXJzZGF5IG9mIHRoaXMgd2VlayBzdGFydGluZyBvbiBNb25kYXlcblx0XHRjaGVja0RhdGUuc2V0RGF0ZShjaGVja0RhdGUuZ2V0RGF0ZSgpICsgNCAtIChjaGVja0RhdGUuZ2V0RGF5KCkgfHwgNykpO1xuXG5cdFx0dGltZSA9IGNoZWNrRGF0ZS5nZXRUaW1lKCk7XG5cdFx0Y2hlY2tEYXRlLnNldE1vbnRoKDApOyAvLyBDb21wYXJlIHdpdGggSmFuIDFcblx0XHRjaGVja0RhdGUuc2V0RGF0ZSgxKTtcblx0XHRyZXR1cm4gTWF0aC5mbG9vcihNYXRoLnJvdW5kKCh0aW1lIC0gY2hlY2tEYXRlKSAvIDg2NDAwMDAwKSAvIDcpICsgMTtcblx0fSxcblxuXHQvKiBQYXJzZSBhIHN0cmluZyB2YWx1ZSBpbnRvIGEgZGF0ZSBvYmplY3QuXG5cdCAqIFNlZSBmb3JtYXREYXRlIGJlbG93IGZvciB0aGUgcG9zc2libGUgZm9ybWF0cy5cblx0ICpcblx0ICogQHBhcmFtICBmb3JtYXQgc3RyaW5nIC0gdGhlIGV4cGVjdGVkIGZvcm1hdCBvZiB0aGUgZGF0ZVxuXHQgKiBAcGFyYW0gIHZhbHVlIHN0cmluZyAtIHRoZSBkYXRlIGluIHRoZSBhYm92ZSBmb3JtYXRcblx0ICogQHBhcmFtICBzZXR0aW5ncyBPYmplY3QgLSBhdHRyaWJ1dGVzIGluY2x1ZGU6XG5cdCAqXHRcdFx0XHRcdHNob3J0WWVhckN1dG9mZiAgbnVtYmVyIC0gdGhlIGN1dG9mZiB5ZWFyIGZvciBkZXRlcm1pbmluZyB0aGUgY2VudHVyeSAob3B0aW9uYWwpXG5cdCAqXHRcdFx0XHRcdGRheU5hbWVzU2hvcnRcdHN0cmluZ1s3XSAtIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0ZGF5TmFtZXNcdFx0c3RyaW5nWzddIC0gbmFtZXMgb2YgdGhlIGRheXMgZnJvbSBTdW5kYXkgKG9wdGlvbmFsKVxuXHQgKlx0XHRcdFx0XHRtb250aE5hbWVzU2hvcnQgc3RyaW5nWzEyXSAtIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBtb250aHMgKG9wdGlvbmFsKVxuXHQgKlx0XHRcdFx0XHRtb250aE5hbWVzXHRcdHN0cmluZ1sxMl0gLSBuYW1lcyBvZiB0aGUgbW9udGhzIChvcHRpb25hbClcblx0ICogQHJldHVybiAgRGF0ZSAtIHRoZSBleHRyYWN0ZWQgZGF0ZSB2YWx1ZSBvciBudWxsIGlmIHZhbHVlIGlzIGJsYW5rXG5cdCAqL1xuXHRwYXJzZURhdGU6IGZ1bmN0aW9uIChmb3JtYXQsIHZhbHVlLCBzZXR0aW5ncykge1xuXHRcdGlmIChmb3JtYXQgPT0gbnVsbCB8fCB2YWx1ZSA9PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBcIkludmFsaWQgYXJndW1lbnRzXCI7XG5cdFx0fVxuXG5cdFx0dmFsdWUgPSAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiID8gdmFsdWUudG9TdHJpbmcoKSA6IHZhbHVlICsgXCJcIik7XG5cdFx0aWYgKHZhbHVlID09PSBcIlwiKSB7XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cblx0XHR2YXIgaUZvcm1hdCwgZGltLCBleHRyYSxcblx0XHRcdGlWYWx1ZSA9IDAsXG5cdFx0XHRzaG9ydFllYXJDdXRvZmZUZW1wID0gKHNldHRpbmdzID8gc2V0dGluZ3Muc2hvcnRZZWFyQ3V0b2ZmIDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMuc2hvcnRZZWFyQ3V0b2ZmLFxuXHRcdFx0c2hvcnRZZWFyQ3V0b2ZmID0gKHR5cGVvZiBzaG9ydFllYXJDdXRvZmZUZW1wICE9PSBcInN0cmluZ1wiID8gc2hvcnRZZWFyQ3V0b2ZmVGVtcCA6XG5cdFx0XHRcdG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKSAlIDEwMCArIHBhcnNlSW50KHNob3J0WWVhckN1dG9mZlRlbXAsIDEwKSksXG5cdFx0XHRkYXlOYW1lc1Nob3J0ID0gKHNldHRpbmdzID8gc2V0dGluZ3MuZGF5TmFtZXNTaG9ydCA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzU2hvcnQsXG5cdFx0XHRkYXlOYW1lcyA9IChzZXR0aW5ncyA/IHNldHRpbmdzLmRheU5hbWVzIDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMuZGF5TmFtZXMsXG5cdFx0XHRtb250aE5hbWVzU2hvcnQgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5tb250aE5hbWVzU2hvcnQgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzU2hvcnQsXG5cdFx0XHRtb250aE5hbWVzID0gKHNldHRpbmdzID8gc2V0dGluZ3MubW9udGhOYW1lcyA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLm1vbnRoTmFtZXMsXG5cdFx0XHR5ZWFyID0gLTEsXG5cdFx0XHRtb250aCA9IC0xLFxuXHRcdFx0ZGF5ID0gLTEsXG5cdFx0XHRkb3kgPSAtMSxcblx0XHRcdGxpdGVyYWwgPSBmYWxzZSxcblx0XHRcdGRhdGUsXG5cdFx0XHQvLyBDaGVjayB3aGV0aGVyIGEgZm9ybWF0IGNoYXJhY3RlciBpcyBkb3VibGVkXG5cdFx0XHRsb29rQWhlYWQgPSBmdW5jdGlvbihtYXRjaCkge1xuXHRcdFx0XHR2YXIgbWF0Y2hlcyA9IChpRm9ybWF0ICsgMSA8IGZvcm1hdC5sZW5ndGggJiYgZm9ybWF0LmNoYXJBdChpRm9ybWF0ICsgMSkgPT09IG1hdGNoKTtcblx0XHRcdFx0aWYgKG1hdGNoZXMpIHtcblx0XHRcdFx0XHRpRm9ybWF0Kys7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG1hdGNoZXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gRXh0cmFjdCBhIG51bWJlciBmcm9tIHRoZSBzdHJpbmcgdmFsdWVcblx0XHRcdGdldE51bWJlciA9IGZ1bmN0aW9uKG1hdGNoKSB7XG5cdFx0XHRcdHZhciBpc0RvdWJsZWQgPSBsb29rQWhlYWQobWF0Y2gpLFxuXHRcdFx0XHRcdHNpemUgPSAobWF0Y2ggPT09IFwiQFwiID8gMTQgOiAobWF0Y2ggPT09IFwiIVwiID8gMjAgOlxuXHRcdFx0XHRcdChtYXRjaCA9PT0gXCJ5XCIgJiYgaXNEb3VibGVkID8gNCA6IChtYXRjaCA9PT0gXCJvXCIgPyAzIDogMikpKSksXG5cdFx0XHRcdFx0ZGlnaXRzID0gbmV3IFJlZ0V4cChcIl5cXFxcZHsxLFwiICsgc2l6ZSArIFwifVwiKSxcblx0XHRcdFx0XHRudW0gPSB2YWx1ZS5zdWJzdHJpbmcoaVZhbHVlKS5tYXRjaChkaWdpdHMpO1xuXHRcdFx0XHRpZiAoIW51bSkge1xuXHRcdFx0XHRcdHRocm93IFwiTWlzc2luZyBudW1iZXIgYXQgcG9zaXRpb24gXCIgKyBpVmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0aVZhbHVlICs9IG51bVswXS5sZW5ndGg7XG5cdFx0XHRcdHJldHVybiBwYXJzZUludChudW1bMF0sIDEwKTtcblx0XHRcdH0sXG5cdFx0XHQvLyBFeHRyYWN0IGEgbmFtZSBmcm9tIHRoZSBzdHJpbmcgdmFsdWUgYW5kIGNvbnZlcnQgdG8gYW4gaW5kZXhcblx0XHRcdGdldE5hbWUgPSBmdW5jdGlvbihtYXRjaCwgc2hvcnROYW1lcywgbG9uZ05hbWVzKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IC0xLFxuXHRcdFx0XHRcdG5hbWVzID0gJC5tYXAobG9va0FoZWFkKG1hdGNoKSA/IGxvbmdOYW1lcyA6IHNob3J0TmFtZXMsIGZ1bmN0aW9uICh2LCBrKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gWyBbaywgdl0gXTtcblx0XHRcdFx0XHR9KS5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gLShhWzFdLmxlbmd0aCAtIGJbMV0ubGVuZ3RoKTtcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHQkLmVhY2gobmFtZXMsIGZ1bmN0aW9uIChpLCBwYWlyKSB7XG5cdFx0XHRcdFx0dmFyIG5hbWUgPSBwYWlyWzFdO1xuXHRcdFx0XHRcdGlmICh2YWx1ZS5zdWJzdHIoaVZhbHVlLCBuYW1lLmxlbmd0aCkudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpKSB7XG5cdFx0XHRcdFx0XHRpbmRleCA9IHBhaXJbMF07XG5cdFx0XHRcdFx0XHRpVmFsdWUgKz0gbmFtZS5sZW5ndGg7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdFx0aWYgKGluZGV4ICE9PSAtMSkge1xuXHRcdFx0XHRcdHJldHVybiBpbmRleCArIDE7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhyb3cgXCJVbmtub3duIG5hbWUgYXQgcG9zaXRpb24gXCIgKyBpVmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHQvLyBDb25maXJtIHRoYXQgYSBsaXRlcmFsIGNoYXJhY3RlciBtYXRjaGVzIHRoZSBzdHJpbmcgdmFsdWVcblx0XHRcdGNoZWNrTGl0ZXJhbCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAodmFsdWUuY2hhckF0KGlWYWx1ZSkgIT09IGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkpIHtcblx0XHRcdFx0XHR0aHJvdyBcIlVuZXhwZWN0ZWQgbGl0ZXJhbCBhdCBwb3NpdGlvbiBcIiArIGlWYWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpVmFsdWUrKztcblx0XHRcdH07XG5cblx0XHRmb3IgKGlGb3JtYXQgPSAwOyBpRm9ybWF0IDwgZm9ybWF0Lmxlbmd0aDsgaUZvcm1hdCsrKSB7XG5cdFx0XHRpZiAobGl0ZXJhbCkge1xuXHRcdFx0XHRpZiAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSA9PT0gXCInXCIgJiYgIWxvb2tBaGVhZChcIidcIikpIHtcblx0XHRcdFx0XHRsaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y2hlY2tMaXRlcmFsKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHN3aXRjaCAoZm9ybWF0LmNoYXJBdChpRm9ybWF0KSkge1xuXHRcdFx0XHRcdGNhc2UgXCJkXCI6XG5cdFx0XHRcdFx0XHRkYXkgPSBnZXROdW1iZXIoXCJkXCIpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIkRcIjpcblx0XHRcdFx0XHRcdGdldE5hbWUoXCJEXCIsIGRheU5hbWVzU2hvcnQsIGRheU5hbWVzKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJvXCI6XG5cdFx0XHRcdFx0XHRkb3kgPSBnZXROdW1iZXIoXCJvXCIpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIm1cIjpcblx0XHRcdFx0XHRcdG1vbnRoID0gZ2V0TnVtYmVyKFwibVwiKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCJNXCI6XG5cdFx0XHRcdFx0XHRtb250aCA9IGdldE5hbWUoXCJNXCIsIG1vbnRoTmFtZXNTaG9ydCwgbW9udGhOYW1lcyk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwieVwiOlxuXHRcdFx0XHRcdFx0eWVhciA9IGdldE51bWJlcihcInlcIik7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwiQFwiOlxuXHRcdFx0XHRcdFx0ZGF0ZSA9IG5ldyBEYXRlKGdldE51bWJlcihcIkBcIikpO1xuXHRcdFx0XHRcdFx0eWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRcdFx0XHRcdG1vbnRoID0gZGF0ZS5nZXRNb250aCgpICsgMTtcblx0XHRcdFx0XHRcdGRheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSBcIiFcIjpcblx0XHRcdFx0XHRcdGRhdGUgPSBuZXcgRGF0ZSgoZ2V0TnVtYmVyKFwiIVwiKSAtIHRoaXMuX3RpY2tzVG8xOTcwKSAvIDEwMDAwKTtcblx0XHRcdFx0XHRcdHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCk7XG5cdFx0XHRcdFx0XHRtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7XG5cdFx0XHRcdFx0XHRkYXkgPSBkYXRlLmdldERhdGUoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgXCInXCI6XG5cdFx0XHRcdFx0XHRpZiAobG9va0FoZWFkKFwiJ1wiKSl7XG5cdFx0XHRcdFx0XHRcdGNoZWNrTGl0ZXJhbCgpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0bGl0ZXJhbCA9IHRydWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0Y2hlY2tMaXRlcmFsKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoaVZhbHVlIDwgdmFsdWUubGVuZ3RoKXtcblx0XHRcdGV4dHJhID0gdmFsdWUuc3Vic3RyKGlWYWx1ZSk7XG5cdFx0XHRpZiAoIS9eXFxzKy8udGVzdChleHRyYSkpIHtcblx0XHRcdFx0dGhyb3cgXCJFeHRyYS91bnBhcnNlZCBjaGFyYWN0ZXJzIGZvdW5kIGluIGRhdGU6IFwiICsgZXh0cmE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKHllYXIgPT09IC0xKSB7XG5cdFx0XHR5ZWFyID0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpO1xuXHRcdH0gZWxzZSBpZiAoeWVhciA8IDEwMCkge1xuXHRcdFx0eWVhciArPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgLSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCkgJSAxMDAgK1xuXHRcdFx0XHQoeWVhciA8PSBzaG9ydFllYXJDdXRvZmYgPyAwIDogLTEwMCk7XG5cdFx0fVxuXG5cdFx0aWYgKGRveSA+IC0xKSB7XG5cdFx0XHRtb250aCA9IDE7XG5cdFx0XHRkYXkgPSBkb3k7XG5cdFx0XHRkbyB7XG5cdFx0XHRcdGRpbSA9IHRoaXMuX2dldERheXNJbk1vbnRoKHllYXIsIG1vbnRoIC0gMSk7XG5cdFx0XHRcdGlmIChkYXkgPD0gZGltKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0bW9udGgrKztcblx0XHRcdFx0ZGF5IC09IGRpbTtcblx0XHRcdH0gd2hpbGUgKHRydWUpO1xuXHRcdH1cblxuXHRcdGRhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZSh5ZWFyLCBtb250aCAtIDEsIGRheSkpO1xuXHRcdGlmIChkYXRlLmdldEZ1bGxZZWFyKCkgIT09IHllYXIgfHwgZGF0ZS5nZXRNb250aCgpICsgMSAhPT0gbW9udGggfHwgZGF0ZS5nZXREYXRlKCkgIT09IGRheSkge1xuXHRcdFx0dGhyb3cgXCJJbnZhbGlkIGRhdGVcIjsgLy8gRS5nLiAzMS8wMi8wMFxuXHRcdH1cblx0XHRyZXR1cm4gZGF0ZTtcblx0fSxcblxuXHQvKiBTdGFuZGFyZCBkYXRlIGZvcm1hdHMuICovXG5cdEFUT006IFwieXktbW0tZGRcIiwgLy8gUkZDIDMzMzkgKElTTyA4NjAxKVxuXHRDT09LSUU6IFwiRCwgZGQgTSB5eVwiLFxuXHRJU09fODYwMTogXCJ5eS1tbS1kZFwiLFxuXHRSRkNfODIyOiBcIkQsIGQgTSB5XCIsXG5cdFJGQ184NTA6IFwiREQsIGRkLU0teVwiLFxuXHRSRkNfMTAzNjogXCJELCBkIE0geVwiLFxuXHRSRkNfMTEyMzogXCJELCBkIE0geXlcIixcblx0UkZDXzI4MjI6IFwiRCwgZCBNIHl5XCIsXG5cdFJTUzogXCJELCBkIE0geVwiLCAvLyBSRkMgODIyXG5cdFRJQ0tTOiBcIiFcIixcblx0VElNRVNUQU1QOiBcIkBcIixcblx0VzNDOiBcInl5LW1tLWRkXCIsIC8vIElTTyA4NjAxXG5cblx0X3RpY2tzVG8xOTcwOiAoKCgxOTcwIC0gMSkgKiAzNjUgKyBNYXRoLmZsb29yKDE5NzAgLyA0KSAtIE1hdGguZmxvb3IoMTk3MCAvIDEwMCkgK1xuXHRcdE1hdGguZmxvb3IoMTk3MCAvIDQwMCkpICogMjQgKiA2MCAqIDYwICogMTAwMDAwMDApLFxuXG5cdC8qIEZvcm1hdCBhIGRhdGUgb2JqZWN0IGludG8gYSBzdHJpbmcgdmFsdWUuXG5cdCAqIFRoZSBmb3JtYXQgY2FuIGJlIGNvbWJpbmF0aW9ucyBvZiB0aGUgZm9sbG93aW5nOlxuXHQgKiBkICAtIGRheSBvZiBtb250aCAobm8gbGVhZGluZyB6ZXJvKVxuXHQgKiBkZCAtIGRheSBvZiBtb250aCAodHdvIGRpZ2l0KVxuXHQgKiBvICAtIGRheSBvZiB5ZWFyIChubyBsZWFkaW5nIHplcm9zKVxuXHQgKiBvbyAtIGRheSBvZiB5ZWFyICh0aHJlZSBkaWdpdClcblx0ICogRCAgLSBkYXkgbmFtZSBzaG9ydFxuXHQgKiBERCAtIGRheSBuYW1lIGxvbmdcblx0ICogbSAgLSBtb250aCBvZiB5ZWFyIChubyBsZWFkaW5nIHplcm8pXG5cdCAqIG1tIC0gbW9udGggb2YgeWVhciAodHdvIGRpZ2l0KVxuXHQgKiBNICAtIG1vbnRoIG5hbWUgc2hvcnRcblx0ICogTU0gLSBtb250aCBuYW1lIGxvbmdcblx0ICogeSAgLSB5ZWFyICh0d28gZGlnaXQpXG5cdCAqIHl5IC0geWVhciAoZm91ciBkaWdpdClcblx0ICogQCAtIFVuaXggdGltZXN0YW1wIChtcyBzaW5jZSAwMS8wMS8xOTcwKVxuXHQgKiAhIC0gV2luZG93cyB0aWNrcyAoMTAwbnMgc2luY2UgMDEvMDEvMDAwMSlcblx0ICogXCIuLi5cIiAtIGxpdGVyYWwgdGV4dFxuXHQgKiAnJyAtIHNpbmdsZSBxdW90ZVxuXHQgKlxuXHQgKiBAcGFyYW0gIGZvcm1hdCBzdHJpbmcgLSB0aGUgZGVzaXJlZCBmb3JtYXQgb2YgdGhlIGRhdGVcblx0ICogQHBhcmFtICBkYXRlIERhdGUgLSB0aGUgZGF0ZSB2YWx1ZSB0byBmb3JtYXRcblx0ICogQHBhcmFtICBzZXR0aW5ncyBPYmplY3QgLSBhdHRyaWJ1dGVzIGluY2x1ZGU6XG5cdCAqXHRcdFx0XHRcdGRheU5hbWVzU2hvcnRcdHN0cmluZ1s3XSAtIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBkYXlzIGZyb20gU3VuZGF5IChvcHRpb25hbClcblx0ICpcdFx0XHRcdFx0ZGF5TmFtZXNcdFx0c3RyaW5nWzddIC0gbmFtZXMgb2YgdGhlIGRheXMgZnJvbSBTdW5kYXkgKG9wdGlvbmFsKVxuXHQgKlx0XHRcdFx0XHRtb250aE5hbWVzU2hvcnQgc3RyaW5nWzEyXSAtIGFiYnJldmlhdGVkIG5hbWVzIG9mIHRoZSBtb250aHMgKG9wdGlvbmFsKVxuXHQgKlx0XHRcdFx0XHRtb250aE5hbWVzXHRcdHN0cmluZ1sxMl0gLSBuYW1lcyBvZiB0aGUgbW9udGhzIChvcHRpb25hbClcblx0ICogQHJldHVybiAgc3RyaW5nIC0gdGhlIGRhdGUgaW4gdGhlIGFib3ZlIGZvcm1hdFxuXHQgKi9cblx0Zm9ybWF0RGF0ZTogZnVuY3Rpb24gKGZvcm1hdCwgZGF0ZSwgc2V0dGluZ3MpIHtcblx0XHRpZiAoIWRhdGUpIHtcblx0XHRcdHJldHVybiBcIlwiO1xuXHRcdH1cblxuXHRcdHZhciBpRm9ybWF0LFxuXHRcdFx0ZGF5TmFtZXNTaG9ydCA9IChzZXR0aW5ncyA/IHNldHRpbmdzLmRheU5hbWVzU2hvcnQgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5kYXlOYW1lc1Nob3J0LFxuXHRcdFx0ZGF5TmFtZXMgPSAoc2V0dGluZ3MgPyBzZXR0aW5ncy5kYXlOYW1lcyA6IG51bGwpIHx8IHRoaXMuX2RlZmF1bHRzLmRheU5hbWVzLFxuXHRcdFx0bW9udGhOYW1lc1Nob3J0ID0gKHNldHRpbmdzID8gc2V0dGluZ3MubW9udGhOYW1lc1Nob3J0IDogbnVsbCkgfHwgdGhpcy5fZGVmYXVsdHMubW9udGhOYW1lc1Nob3J0LFxuXHRcdFx0bW9udGhOYW1lcyA9IChzZXR0aW5ncyA/IHNldHRpbmdzLm1vbnRoTmFtZXMgOiBudWxsKSB8fCB0aGlzLl9kZWZhdWx0cy5tb250aE5hbWVzLFxuXHRcdFx0Ly8gQ2hlY2sgd2hldGhlciBhIGZvcm1hdCBjaGFyYWN0ZXIgaXMgZG91YmxlZFxuXHRcdFx0bG9va0FoZWFkID0gZnVuY3Rpb24obWF0Y2gpIHtcblx0XHRcdFx0dmFyIG1hdGNoZXMgPSAoaUZvcm1hdCArIDEgPCBmb3JtYXQubGVuZ3RoICYmIGZvcm1hdC5jaGFyQXQoaUZvcm1hdCArIDEpID09PSBtYXRjaCk7XG5cdFx0XHRcdGlmIChtYXRjaGVzKSB7XG5cdFx0XHRcdFx0aUZvcm1hdCsrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBtYXRjaGVzO1xuXHRcdFx0fSxcblx0XHRcdC8vIEZvcm1hdCBhIG51bWJlciwgd2l0aCBsZWFkaW5nIHplcm8gaWYgbmVjZXNzYXJ5XG5cdFx0XHRmb3JtYXROdW1iZXIgPSBmdW5jdGlvbihtYXRjaCwgdmFsdWUsIGxlbikge1xuXHRcdFx0XHR2YXIgbnVtID0gXCJcIiArIHZhbHVlO1xuXHRcdFx0XHRpZiAobG9va0FoZWFkKG1hdGNoKSkge1xuXHRcdFx0XHRcdHdoaWxlIChudW0ubGVuZ3RoIDwgbGVuKSB7XG5cdFx0XHRcdFx0XHRudW0gPSBcIjBcIiArIG51bTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIG51bTtcblx0XHRcdH0sXG5cdFx0XHQvLyBGb3JtYXQgYSBuYW1lLCBzaG9ydCBvciBsb25nIGFzIHJlcXVlc3RlZFxuXHRcdFx0Zm9ybWF0TmFtZSA9IGZ1bmN0aW9uKG1hdGNoLCB2YWx1ZSwgc2hvcnROYW1lcywgbG9uZ05hbWVzKSB7XG5cdFx0XHRcdHJldHVybiAobG9va0FoZWFkKG1hdGNoKSA/IGxvbmdOYW1lc1t2YWx1ZV0gOiBzaG9ydE5hbWVzW3ZhbHVlXSk7XG5cdFx0XHR9LFxuXHRcdFx0b3V0cHV0ID0gXCJcIixcblx0XHRcdGxpdGVyYWwgPSBmYWxzZTtcblxuXHRcdGlmIChkYXRlKSB7XG5cdFx0XHRmb3IgKGlGb3JtYXQgPSAwOyBpRm9ybWF0IDwgZm9ybWF0Lmxlbmd0aDsgaUZvcm1hdCsrKSB7XG5cdFx0XHRcdGlmIChsaXRlcmFsKSB7XG5cdFx0XHRcdFx0aWYgKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkgPT09IFwiJ1wiICYmICFsb29rQWhlYWQoXCInXCIpKSB7XG5cdFx0XHRcdFx0XHRsaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzd2l0Y2ggKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkpIHtcblx0XHRcdFx0XHRcdGNhc2UgXCJkXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROdW1iZXIoXCJkXCIsIGRhdGUuZ2V0RGF0ZSgpLCAyKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwiRFwiOlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0TmFtZShcIkRcIiwgZGF0ZS5nZXREYXkoKSwgZGF5TmFtZXNTaG9ydCwgZGF5TmFtZXMpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJvXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROdW1iZXIoXCJvXCIsXG5cdFx0XHRcdFx0XHRcdFx0TWF0aC5yb3VuZCgobmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKS5nZXRUaW1lKCkgLSBuZXcgRGF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIDAsIDApLmdldFRpbWUoKSkgLyA4NjQwMDAwMCksIDMpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJtXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROdW1iZXIoXCJtXCIsIGRhdGUuZ2V0TW9udGgoKSArIDEsIDIpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCJNXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBmb3JtYXROYW1lKFwiTVwiLCBkYXRlLmdldE1vbnRoKCksIG1vbnRoTmFtZXNTaG9ydCwgbW9udGhOYW1lcyk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcInlcIjpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IChsb29rQWhlYWQoXCJ5XCIpID8gZGF0ZS5nZXRGdWxsWWVhcigpIDpcblx0XHRcdFx0XHRcdFx0XHQoZGF0ZS5nZXRZZWFyKCkgJSAxMDAgPCAxMCA/IFwiMFwiIDogXCJcIikgKyBkYXRlLmdldFllYXIoKSAlIDEwMCk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIkBcIjpcblx0XHRcdFx0XHRcdFx0b3V0cHV0ICs9IGRhdGUuZ2V0VGltZSgpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdGNhc2UgXCIhXCI6XG5cdFx0XHRcdFx0XHRcdG91dHB1dCArPSBkYXRlLmdldFRpbWUoKSAqIDEwMDAwICsgdGhpcy5fdGlja3NUbzE5NzA7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIidcIjpcblx0XHRcdFx0XHRcdFx0aWYgKGxvb2tBaGVhZChcIidcIikpIHtcblx0XHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gXCInXCI7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0bGl0ZXJhbCA9IHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0XHRvdXRwdXQgKz0gZm9ybWF0LmNoYXJBdChpRm9ybWF0KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fSxcblxuXHQvKiBFeHRyYWN0IGFsbCBwb3NzaWJsZSBjaGFyYWN0ZXJzIGZyb20gdGhlIGRhdGUgZm9ybWF0LiAqL1xuXHRfcG9zc2libGVDaGFyczogZnVuY3Rpb24gKGZvcm1hdCkge1xuXHRcdHZhciBpRm9ybWF0LFxuXHRcdFx0Y2hhcnMgPSBcIlwiLFxuXHRcdFx0bGl0ZXJhbCA9IGZhbHNlLFxuXHRcdFx0Ly8gQ2hlY2sgd2hldGhlciBhIGZvcm1hdCBjaGFyYWN0ZXIgaXMgZG91YmxlZFxuXHRcdFx0bG9va0FoZWFkID0gZnVuY3Rpb24obWF0Y2gpIHtcblx0XHRcdFx0dmFyIG1hdGNoZXMgPSAoaUZvcm1hdCArIDEgPCBmb3JtYXQubGVuZ3RoICYmIGZvcm1hdC5jaGFyQXQoaUZvcm1hdCArIDEpID09PSBtYXRjaCk7XG5cdFx0XHRcdGlmIChtYXRjaGVzKSB7XG5cdFx0XHRcdFx0aUZvcm1hdCsrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBtYXRjaGVzO1xuXHRcdFx0fTtcblxuXHRcdGZvciAoaUZvcm1hdCA9IDA7IGlGb3JtYXQgPCBmb3JtYXQubGVuZ3RoOyBpRm9ybWF0KyspIHtcblx0XHRcdGlmIChsaXRlcmFsKSB7XG5cdFx0XHRcdGlmIChmb3JtYXQuY2hhckF0KGlGb3JtYXQpID09PSBcIidcIiAmJiAhbG9va0FoZWFkKFwiJ1wiKSkge1xuXHRcdFx0XHRcdGxpdGVyYWwgPSBmYWxzZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjaGFycyArPSBmb3JtYXQuY2hhckF0KGlGb3JtYXQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzd2l0Y2ggKGZvcm1hdC5jaGFyQXQoaUZvcm1hdCkpIHtcblx0XHRcdFx0XHRjYXNlIFwiZFwiOiBjYXNlIFwibVwiOiBjYXNlIFwieVwiOiBjYXNlIFwiQFwiOlxuXHRcdFx0XHRcdFx0Y2hhcnMgKz0gXCIwMTIzNDU2Nzg5XCI7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlIFwiRFwiOiBjYXNlIFwiTVwiOlxuXHRcdFx0XHRcdFx0cmV0dXJuIG51bGw7IC8vIEFjY2VwdCBhbnl0aGluZ1xuXHRcdFx0XHRcdGNhc2UgXCInXCI6XG5cdFx0XHRcdFx0XHRpZiAobG9va0FoZWFkKFwiJ1wiKSkge1xuXHRcdFx0XHRcdFx0XHRjaGFycyArPSBcIidcIjtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGxpdGVyYWwgPSB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0XHRcdGNoYXJzICs9IGZvcm1hdC5jaGFyQXQoaUZvcm1hdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNoYXJzO1xuXHR9LFxuXG5cdC8qIEdldCBhIHNldHRpbmcgdmFsdWUsIGRlZmF1bHRpbmcgaWYgbmVjZXNzYXJ5LiAqL1xuXHRfZ2V0OiBmdW5jdGlvbihpbnN0LCBuYW1lKSB7XG5cdFx0cmV0dXJuIGluc3Quc2V0dGluZ3NbbmFtZV0gIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRpbnN0LnNldHRpbmdzW25hbWVdIDogdGhpcy5fZGVmYXVsdHNbbmFtZV07XG5cdH0sXG5cblx0LyogUGFyc2UgZXhpc3RpbmcgZGF0ZSBhbmQgaW5pdGlhbGlzZSBkYXRlIHBpY2tlci4gKi9cblx0X3NldERhdGVGcm9tRmllbGQ6IGZ1bmN0aW9uKGluc3QsIG5vRGVmYXVsdCkge1xuXHRcdGlmIChpbnN0LmlucHV0LnZhbCgpID09PSBpbnN0Lmxhc3RWYWwpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YXIgZGF0ZUZvcm1hdCA9IHRoaXMuX2dldChpbnN0LCBcImRhdGVGb3JtYXRcIiksXG5cdFx0XHRkYXRlcyA9IGluc3QubGFzdFZhbCA9IGluc3QuaW5wdXQgPyBpbnN0LmlucHV0LnZhbCgpIDogbnVsbCxcblx0XHRcdGRlZmF1bHREYXRlID0gdGhpcy5fZ2V0RGVmYXVsdERhdGUoaW5zdCksXG5cdFx0XHRkYXRlID0gZGVmYXVsdERhdGUsXG5cdFx0XHRzZXR0aW5ncyA9IHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KTtcblxuXHRcdHRyeSB7XG5cdFx0XHRkYXRlID0gdGhpcy5wYXJzZURhdGUoZGF0ZUZvcm1hdCwgZGF0ZXMsIHNldHRpbmdzKSB8fCBkZWZhdWx0RGF0ZTtcblx0XHR9IGNhdGNoIChldmVudCkge1xuXHRcdFx0ZGF0ZXMgPSAobm9EZWZhdWx0ID8gXCJcIiA6IGRhdGVzKTtcblx0XHR9XG5cdFx0aW5zdC5zZWxlY3RlZERheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdGluc3QuZHJhd01vbnRoID0gaW5zdC5zZWxlY3RlZE1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuXHRcdGluc3QuZHJhd1llYXIgPSBpbnN0LnNlbGVjdGVkWWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblx0XHRpbnN0LmN1cnJlbnREYXkgPSAoZGF0ZXMgPyBkYXRlLmdldERhdGUoKSA6IDApO1xuXHRcdGluc3QuY3VycmVudE1vbnRoID0gKGRhdGVzID8gZGF0ZS5nZXRNb250aCgpIDogMCk7XG5cdFx0aW5zdC5jdXJyZW50WWVhciA9IChkYXRlcyA/IGRhdGUuZ2V0RnVsbFllYXIoKSA6IDApO1xuXHRcdHRoaXMuX2FkanVzdEluc3REYXRlKGluc3QpO1xuXHR9LFxuXG5cdC8qIFJldHJpZXZlIHRoZSBkZWZhdWx0IGRhdGUgc2hvd24gb24gb3BlbmluZy4gKi9cblx0X2dldERlZmF1bHREYXRlOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0cmV0dXJuIHRoaXMuX3Jlc3RyaWN0TWluTWF4KGluc3QsXG5cdFx0XHR0aGlzLl9kZXRlcm1pbmVEYXRlKGluc3QsIHRoaXMuX2dldChpbnN0LCBcImRlZmF1bHREYXRlXCIpLCBuZXcgRGF0ZSgpKSk7XG5cdH0sXG5cblx0LyogQSBkYXRlIG1heSBiZSBzcGVjaWZpZWQgYXMgYW4gZXhhY3QgdmFsdWUgb3IgYSByZWxhdGl2ZSBvbmUuICovXG5cdF9kZXRlcm1pbmVEYXRlOiBmdW5jdGlvbihpbnN0LCBkYXRlLCBkZWZhdWx0RGF0ZSkge1xuXHRcdHZhciBvZmZzZXROdW1lcmljID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG5cdFx0XHRcdHZhciBkYXRlID0gbmV3IERhdGUoKTtcblx0XHRcdFx0ZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgb2Zmc2V0KTtcblx0XHRcdFx0cmV0dXJuIGRhdGU7XG5cdFx0XHR9LFxuXHRcdFx0b2Zmc2V0U3RyaW5nID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0cmV0dXJuICQuZGF0ZXBpY2tlci5wYXJzZURhdGUoJC5kYXRlcGlja2VyLl9nZXQoaW5zdCwgXCJkYXRlRm9ybWF0XCIpLFxuXHRcdFx0XHRcdFx0b2Zmc2V0LCAkLmRhdGVwaWNrZXIuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0Y2F0Y2ggKGUpIHtcblx0XHRcdFx0XHQvLyBJZ25vcmVcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHZhciBkYXRlID0gKG9mZnNldC50b0xvd2VyQ2FzZSgpLm1hdGNoKC9eYy8pID9cblx0XHRcdFx0XHQkLmRhdGVwaWNrZXIuX2dldERhdGUoaW5zdCkgOiBudWxsKSB8fCBuZXcgRGF0ZSgpLFxuXHRcdFx0XHRcdHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKCksXG5cdFx0XHRcdFx0bW9udGggPSBkYXRlLmdldE1vbnRoKCksXG5cdFx0XHRcdFx0ZGF5ID0gZGF0ZS5nZXREYXRlKCksXG5cdFx0XHRcdFx0cGF0dGVybiA9IC8oWytcXC1dP1swLTldKylcXHMqKGR8RHx3fFd8bXxNfHl8WSk/L2csXG5cdFx0XHRcdFx0bWF0Y2hlcyA9IHBhdHRlcm4uZXhlYyhvZmZzZXQpO1xuXG5cdFx0XHRcdHdoaWxlIChtYXRjaGVzKSB7XG5cdFx0XHRcdFx0c3dpdGNoIChtYXRjaGVzWzJdIHx8IFwiZFwiKSB7XG5cdFx0XHRcdFx0XHRjYXNlIFwiZFwiIDogY2FzZSBcIkRcIiA6XG5cdFx0XHRcdFx0XHRcdGRheSArPSBwYXJzZUludChtYXRjaGVzWzFdLDEwKTsgYnJlYWs7XG5cdFx0XHRcdFx0XHRjYXNlIFwid1wiIDogY2FzZSBcIldcIiA6XG5cdFx0XHRcdFx0XHRcdGRheSArPSBwYXJzZUludChtYXRjaGVzWzFdLDEwKSAqIDc7IGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcIm1cIiA6IGNhc2UgXCJNXCIgOlxuXHRcdFx0XHRcdFx0XHRtb250aCArPSBwYXJzZUludChtYXRjaGVzWzFdLDEwKTtcblx0XHRcdFx0XHRcdFx0ZGF5ID0gTWF0aC5taW4oZGF5LCAkLmRhdGVwaWNrZXIuX2dldERheXNJbk1vbnRoKHllYXIsIG1vbnRoKSk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0Y2FzZSBcInlcIjogY2FzZSBcIllcIiA6XG5cdFx0XHRcdFx0XHRcdHllYXIgKz0gcGFyc2VJbnQobWF0Y2hlc1sxXSwxMCk7XG5cdFx0XHRcdFx0XHRcdGRheSA9IE1hdGgubWluKGRheSwgJC5kYXRlcGlja2VyLl9nZXREYXlzSW5Nb250aCh5ZWFyLCBtb250aCkpO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bWF0Y2hlcyA9IHBhdHRlcm4uZXhlYyhvZmZzZXQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgZGF5KTtcblx0XHRcdH0sXG5cdFx0XHRuZXdEYXRlID0gKGRhdGUgPT0gbnVsbCB8fCBkYXRlID09PSBcIlwiID8gZGVmYXVsdERhdGUgOiAodHlwZW9mIGRhdGUgPT09IFwic3RyaW5nXCIgPyBvZmZzZXRTdHJpbmcoZGF0ZSkgOlxuXHRcdFx0XHQodHlwZW9mIGRhdGUgPT09IFwibnVtYmVyXCIgPyAoaXNOYU4oZGF0ZSkgPyBkZWZhdWx0RGF0ZSA6IG9mZnNldE51bWVyaWMoZGF0ZSkpIDogbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpKSkpO1xuXG5cdFx0bmV3RGF0ZSA9IChuZXdEYXRlICYmIG5ld0RhdGUudG9TdHJpbmcoKSA9PT0gXCJJbnZhbGlkIERhdGVcIiA/IGRlZmF1bHREYXRlIDogbmV3RGF0ZSk7XG5cdFx0aWYgKG5ld0RhdGUpIHtcblx0XHRcdG5ld0RhdGUuc2V0SG91cnMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldE1pbnV0ZXMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldFNlY29uZHMoMCk7XG5cdFx0XHRuZXdEYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ld0RhdGUpO1xuXHR9LFxuXG5cdC8qIEhhbmRsZSBzd2l0Y2ggdG8vZnJvbSBkYXlsaWdodCBzYXZpbmcuXG5cdCAqIEhvdXJzIG1heSBiZSBub24temVybyBvbiBkYXlsaWdodCBzYXZpbmcgY3V0LW92ZXI6XG5cdCAqID4gMTIgd2hlbiBtaWRuaWdodCBjaGFuZ2VvdmVyLCBidXQgdGhlbiBjYW5ub3QgZ2VuZXJhdGVcblx0ICogbWlkbmlnaHQgZGF0ZXRpbWUsIHNvIGp1bXAgdG8gMUFNLCBvdGhlcndpc2UgcmVzZXQuXG5cdCAqIEBwYXJhbSAgZGF0ZSAgKERhdGUpIHRoZSBkYXRlIHRvIGNoZWNrXG5cdCAqIEByZXR1cm4gIChEYXRlKSB0aGUgY29ycmVjdGVkIGRhdGVcblx0ICovXG5cdF9kYXlsaWdodFNhdmluZ0FkanVzdDogZnVuY3Rpb24oZGF0ZSkge1xuXHRcdGlmICghZGF0ZSkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXHRcdGRhdGUuc2V0SG91cnMoZGF0ZS5nZXRIb3VycygpID4gMTIgPyBkYXRlLmdldEhvdXJzKCkgKyAyIDogMCk7XG5cdFx0cmV0dXJuIGRhdGU7XG5cdH0sXG5cblx0LyogU2V0IHRoZSBkYXRlKHMpIGRpcmVjdGx5LiAqL1xuXHRfc2V0RGF0ZTogZnVuY3Rpb24oaW5zdCwgZGF0ZSwgbm9DaGFuZ2UpIHtcblx0XHR2YXIgY2xlYXIgPSAhZGF0ZSxcblx0XHRcdG9yaWdNb250aCA9IGluc3Quc2VsZWN0ZWRNb250aCxcblx0XHRcdG9yaWdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIsXG5cdFx0XHRuZXdEYXRlID0gdGhpcy5fcmVzdHJpY3RNaW5NYXgoaW5zdCwgdGhpcy5fZGV0ZXJtaW5lRGF0ZShpbnN0LCBkYXRlLCBuZXcgRGF0ZSgpKSk7XG5cblx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gaW5zdC5jdXJyZW50RGF5ID0gbmV3RGF0ZS5nZXREYXRlKCk7XG5cdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBpbnN0LmN1cnJlbnRNb250aCA9IG5ld0RhdGUuZ2V0TW9udGgoKTtcblx0XHRpbnN0LmRyYXdZZWFyID0gaW5zdC5zZWxlY3RlZFllYXIgPSBpbnN0LmN1cnJlbnRZZWFyID0gbmV3RGF0ZS5nZXRGdWxsWWVhcigpO1xuXHRcdGlmICgob3JpZ01vbnRoICE9PSBpbnN0LnNlbGVjdGVkTW9udGggfHwgb3JpZ1llYXIgIT09IGluc3Quc2VsZWN0ZWRZZWFyKSAmJiAhbm9DaGFuZ2UpIHtcblx0XHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0XHR9XG5cdFx0dGhpcy5fYWRqdXN0SW5zdERhdGUoaW5zdCk7XG5cdFx0aWYgKGluc3QuaW5wdXQpIHtcblx0XHRcdGluc3QuaW5wdXQudmFsKGNsZWFyID8gXCJcIiA6IHRoaXMuX2Zvcm1hdERhdGUoaW5zdCkpO1xuXHRcdH1cblx0fSxcblxuXHQvKiBSZXRyaWV2ZSB0aGUgZGF0ZShzKSBkaXJlY3RseS4gKi9cblx0X2dldERhdGU6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgc3RhcnREYXRlID0gKCFpbnN0LmN1cnJlbnRZZWFyIHx8IChpbnN0LmlucHV0ICYmIGluc3QuaW5wdXQudmFsKCkgPT09IFwiXCIpID8gbnVsbCA6XG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShcblx0XHRcdGluc3QuY3VycmVudFllYXIsIGluc3QuY3VycmVudE1vbnRoLCBpbnN0LmN1cnJlbnREYXkpKSk7XG5cdFx0XHRyZXR1cm4gc3RhcnREYXRlO1xuXHR9LFxuXG5cdC8qIEF0dGFjaCB0aGUgb254eHggaGFuZGxlcnMuICBUaGVzZSBhcmUgZGVjbGFyZWQgc3RhdGljYWxseSBzb1xuXHQgKiB0aGV5IHdvcmsgd2l0aCBzdGF0aWMgY29kZSB0cmFuc2Zvcm1lcnMgbGlrZSBDYWphLlxuXHQgKi9cblx0X2F0dGFjaEhhbmRsZXJzOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIHN0ZXBNb250aHMgPSB0aGlzLl9nZXQoaW5zdCwgXCJzdGVwTW9udGhzXCIpLFxuXHRcdFx0aWQgPSBcIiNcIiArIGluc3QuaWQucmVwbGFjZSggL1xcXFxcXFxcL2csIFwiXFxcXFwiICk7XG5cdFx0aW5zdC5kcERpdi5maW5kKFwiW2RhdGEtaGFuZGxlcl1cIikubWFwKGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciBoYW5kbGVyID0ge1xuXHRcdFx0XHRwcmV2OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGlkLCAtc3RlcE1vbnRocywgXCJNXCIpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRuZXh0OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9hZGp1c3REYXRlKGlkLCArc3RlcE1vbnRocywgXCJNXCIpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRoaWRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9oaWRlRGF0ZXBpY2tlcigpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHR0b2RheTogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fZ290b1RvZGF5KGlkKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0c2VsZWN0RGF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9zZWxlY3REYXkoaWQsICt0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEtbW9udGhcIiksICt0aGlzLmdldEF0dHJpYnV0ZShcImRhdGEteWVhclwiKSwgdGhpcyk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZWxlY3RNb250aDogZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdCQuZGF0ZXBpY2tlci5fc2VsZWN0TW9udGhZZWFyKGlkLCB0aGlzLCBcIk1cIik7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRzZWxlY3RZZWFyOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdFx0JC5kYXRlcGlja2VyLl9zZWxlY3RNb250aFllYXIoaWQsIHRoaXMsIFwiWVwiKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHQkKHRoaXMpLmJpbmQodGhpcy5nZXRBdHRyaWJ1dGUoXCJkYXRhLWV2ZW50XCIpLCBoYW5kbGVyW3RoaXMuZ2V0QXR0cmlidXRlKFwiZGF0YS1oYW5kbGVyXCIpXSk7XG5cdFx0fSk7XG5cdH0sXG5cblx0LyogR2VuZXJhdGUgdGhlIEhUTUwgZm9yIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBkYXRlIHBpY2tlci4gKi9cblx0X2dlbmVyYXRlSFRNTDogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBtYXhEcmF3LCBwcmV2VGV4dCwgcHJldiwgbmV4dFRleHQsIG5leHQsIGN1cnJlbnRUZXh0LCBnb3RvRGF0ZSxcblx0XHRcdGNvbnRyb2xzLCBidXR0b25QYW5lbCwgZmlyc3REYXksIHNob3dXZWVrLCBkYXlOYW1lcywgZGF5TmFtZXNNaW4sXG5cdFx0XHRtb250aE5hbWVzLCBtb250aE5hbWVzU2hvcnQsIGJlZm9yZVNob3dEYXksIHNob3dPdGhlck1vbnRocyxcblx0XHRcdHNlbGVjdE90aGVyTW9udGhzLCBkZWZhdWx0RGF0ZSwgaHRtbCwgZG93LCByb3csIGdyb3VwLCBjb2wsIHNlbGVjdGVkRGF0ZSxcblx0XHRcdGNvcm5lckNsYXNzLCBjYWxlbmRlciwgdGhlYWQsIGRheSwgZGF5c0luTW9udGgsIGxlYWREYXlzLCBjdXJSb3dzLCBudW1Sb3dzLFxuXHRcdFx0cHJpbnREYXRlLCBkUm93LCB0Ym9keSwgZGF5U2V0dGluZ3MsIG90aGVyTW9udGgsIHVuc2VsZWN0YWJsZSxcblx0XHRcdHRlbXBEYXRlID0gbmV3IERhdGUoKSxcblx0XHRcdHRvZGF5ID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QoXG5cdFx0XHRcdG5ldyBEYXRlKHRlbXBEYXRlLmdldEZ1bGxZZWFyKCksIHRlbXBEYXRlLmdldE1vbnRoKCksIHRlbXBEYXRlLmdldERhdGUoKSkpLCAvLyBjbGVhciB0aW1lXG5cdFx0XHRpc1JUTCA9IHRoaXMuX2dldChpbnN0LCBcImlzUlRMXCIpLFxuXHRcdFx0c2hvd0J1dHRvblBhbmVsID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvd0J1dHRvblBhbmVsXCIpLFxuXHRcdFx0aGlkZUlmTm9QcmV2TmV4dCA9IHRoaXMuX2dldChpbnN0LCBcImhpZGVJZk5vUHJldk5leHRcIiksXG5cdFx0XHRuYXZpZ2F0aW9uQXNEYXRlRm9ybWF0ID0gdGhpcy5fZ2V0KGluc3QsIFwibmF2aWdhdGlvbkFzRGF0ZUZvcm1hdFwiKSxcblx0XHRcdG51bU1vbnRocyA9IHRoaXMuX2dldE51bWJlck9mTW9udGhzKGluc3QpLFxuXHRcdFx0c2hvd0N1cnJlbnRBdFBvcyA9IHRoaXMuX2dldChpbnN0LCBcInNob3dDdXJyZW50QXRQb3NcIiksXG5cdFx0XHRzdGVwTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsIFwic3RlcE1vbnRoc1wiKSxcblx0XHRcdGlzTXVsdGlNb250aCA9IChudW1Nb250aHNbMF0gIT09IDEgfHwgbnVtTW9udGhzWzFdICE9PSAxKSxcblx0XHRcdGN1cnJlbnREYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QoKCFpbnN0LmN1cnJlbnREYXkgPyBuZXcgRGF0ZSg5OTk5LCA5LCA5KSA6XG5cdFx0XHRcdG5ldyBEYXRlKGluc3QuY3VycmVudFllYXIsIGluc3QuY3VycmVudE1vbnRoLCBpbnN0LmN1cnJlbnREYXkpKSksXG5cdFx0XHRtaW5EYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1pblwiKSxcblx0XHRcdG1heERhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsIFwibWF4XCIpLFxuXHRcdFx0ZHJhd01vbnRoID0gaW5zdC5kcmF3TW9udGggLSBzaG93Q3VycmVudEF0UG9zLFxuXHRcdFx0ZHJhd1llYXIgPSBpbnN0LmRyYXdZZWFyO1xuXG5cdFx0aWYgKGRyYXdNb250aCA8IDApIHtcblx0XHRcdGRyYXdNb250aCArPSAxMjtcblx0XHRcdGRyYXdZZWFyLS07XG5cdFx0fVxuXHRcdGlmIChtYXhEYXRlKSB7XG5cdFx0XHRtYXhEcmF3ID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUobWF4RGF0ZS5nZXRGdWxsWWVhcigpLFxuXHRcdFx0XHRtYXhEYXRlLmdldE1vbnRoKCkgLSAobnVtTW9udGhzWzBdICogbnVtTW9udGhzWzFdKSArIDEsIG1heERhdGUuZ2V0RGF0ZSgpKSk7XG5cdFx0XHRtYXhEcmF3ID0gKG1pbkRhdGUgJiYgbWF4RHJhdyA8IG1pbkRhdGUgPyBtaW5EYXRlIDogbWF4RHJhdyk7XG5cdFx0XHR3aGlsZSAodGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZHJhd1llYXIsIGRyYXdNb250aCwgMSkpID4gbWF4RHJhdykge1xuXHRcdFx0XHRkcmF3TW9udGgtLTtcblx0XHRcdFx0aWYgKGRyYXdNb250aCA8IDApIHtcblx0XHRcdFx0XHRkcmF3TW9udGggPSAxMTtcblx0XHRcdFx0XHRkcmF3WWVhci0tO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGluc3QuZHJhd01vbnRoID0gZHJhd01vbnRoO1xuXHRcdGluc3QuZHJhd1llYXIgPSBkcmF3WWVhcjtcblxuXHRcdHByZXZUZXh0ID0gdGhpcy5fZ2V0KGluc3QsIFwicHJldlRleHRcIik7XG5cdFx0cHJldlRleHQgPSAoIW5hdmlnYXRpb25Bc0RhdGVGb3JtYXQgPyBwcmV2VGV4dCA6IHRoaXMuZm9ybWF0RGF0ZShwcmV2VGV4dCxcblx0XHRcdHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGRyYXdZZWFyLCBkcmF3TW9udGggLSBzdGVwTW9udGhzLCAxKSksXG5cdFx0XHR0aGlzLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpKTtcblxuXHRcdHByZXYgPSAodGhpcy5fY2FuQWRqdXN0TW9udGgoaW5zdCwgLTEsIGRyYXdZZWFyLCBkcmF3TW9udGgpID9cblx0XHRcdFwiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItcHJldiB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J3ByZXYnIGRhdGEtZXZlbnQ9J2NsaWNrJ1wiICtcblx0XHRcdFwiIHRpdGxlPSdcIiArIHByZXZUZXh0ICsgXCInPjxzcGFuIGNsYXNzPSd1aS1pY29uIHVpLWljb24tY2lyY2xlLXRyaWFuZ2xlLVwiICsgKCBpc1JUTCA/IFwiZVwiIDogXCJ3XCIpICsgXCInPlwiICsgcHJldlRleHQgKyBcIjwvc3Bhbj48L2E+XCIgOlxuXHRcdFx0KGhpZGVJZk5vUHJldk5leHQgPyBcIlwiIDogXCI8YSBjbGFzcz0ndWktZGF0ZXBpY2tlci1wcmV2IHVpLWNvcm5lci1hbGwgdWktc3RhdGUtZGlzYWJsZWQnIHRpdGxlPSdcIisgcHJldlRleHQgK1wiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIiArICggaXNSVEwgPyBcImVcIiA6IFwid1wiKSArIFwiJz5cIiArIHByZXZUZXh0ICsgXCI8L3NwYW4+PC9hPlwiKSk7XG5cblx0XHRuZXh0VGV4dCA9IHRoaXMuX2dldChpbnN0LCBcIm5leHRUZXh0XCIpO1xuXHRcdG5leHRUZXh0ID0gKCFuYXZpZ2F0aW9uQXNEYXRlRm9ybWF0ID8gbmV4dFRleHQgOiB0aGlzLmZvcm1hdERhdGUobmV4dFRleHQsXG5cdFx0XHR0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShkcmF3WWVhciwgZHJhd01vbnRoICsgc3RlcE1vbnRocywgMSkpLFxuXHRcdFx0dGhpcy5fZ2V0Rm9ybWF0Q29uZmlnKGluc3QpKSk7XG5cblx0XHRuZXh0ID0gKHRoaXMuX2NhbkFkanVzdE1vbnRoKGluc3QsICsxLCBkcmF3WWVhciwgZHJhd01vbnRoKSA/XG5cdFx0XHRcIjxhIGNsYXNzPSd1aS1kYXRlcGlja2VyLW5leHQgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSduZXh0JyBkYXRhLWV2ZW50PSdjbGljaydcIiArXG5cdFx0XHRcIiB0aXRsZT0nXCIgKyBuZXh0VGV4dCArIFwiJz48c3BhbiBjbGFzcz0ndWktaWNvbiB1aS1pY29uLWNpcmNsZS10cmlhbmdsZS1cIiArICggaXNSVEwgPyBcIndcIiA6IFwiZVwiKSArIFwiJz5cIiArIG5leHRUZXh0ICsgXCI8L3NwYW4+PC9hPlwiIDpcblx0XHRcdChoaWRlSWZOb1ByZXZOZXh0ID8gXCJcIiA6IFwiPGEgY2xhc3M9J3VpLWRhdGVwaWNrZXItbmV4dCB1aS1jb3JuZXItYWxsIHVpLXN0YXRlLWRpc2FibGVkJyB0aXRsZT0nXCIrIG5leHRUZXh0ICsgXCInPjxzcGFuIGNsYXNzPSd1aS1pY29uIHVpLWljb24tY2lyY2xlLXRyaWFuZ2xlLVwiICsgKCBpc1JUTCA/IFwid1wiIDogXCJlXCIpICsgXCInPlwiICsgbmV4dFRleHQgKyBcIjwvc3Bhbj48L2E+XCIpKTtcblxuXHRcdGN1cnJlbnRUZXh0ID0gdGhpcy5fZ2V0KGluc3QsIFwiY3VycmVudFRleHRcIik7XG5cdFx0Z290b0RhdGUgPSAodGhpcy5fZ2V0KGluc3QsIFwiZ290b0N1cnJlbnRcIikgJiYgaW5zdC5jdXJyZW50RGF5ID8gY3VycmVudERhdGUgOiB0b2RheSk7XG5cdFx0Y3VycmVudFRleHQgPSAoIW5hdmlnYXRpb25Bc0RhdGVGb3JtYXQgPyBjdXJyZW50VGV4dCA6XG5cdFx0XHR0aGlzLmZvcm1hdERhdGUoY3VycmVudFRleHQsIGdvdG9EYXRlLCB0aGlzLl9nZXRGb3JtYXRDb25maWcoaW5zdCkpKTtcblxuXHRcdGNvbnRyb2xzID0gKCFpbnN0LmlubGluZSA/IFwiPGJ1dHRvbiB0eXBlPSdidXR0b24nIGNsYXNzPSd1aS1kYXRlcGlja2VyLWNsb3NlIHVpLXN0YXRlLWRlZmF1bHQgdWktcHJpb3JpdHktcHJpbWFyeSB1aS1jb3JuZXItYWxsJyBkYXRhLWhhbmRsZXI9J2hpZGUnIGRhdGEtZXZlbnQ9J2NsaWNrJz5cIiArXG5cdFx0XHR0aGlzLl9nZXQoaW5zdCwgXCJjbG9zZVRleHRcIikgKyBcIjwvYnV0dG9uPlwiIDogXCJcIik7XG5cblx0XHRidXR0b25QYW5lbCA9IChzaG93QnV0dG9uUGFuZWwpID8gXCI8ZGl2IGNsYXNzPSd1aS1kYXRlcGlja2VyLWJ1dHRvbnBhbmUgdWktd2lkZ2V0LWNvbnRlbnQnPlwiICsgKGlzUlRMID8gY29udHJvbHMgOiBcIlwiKSArXG5cdFx0XHQodGhpcy5faXNJblJhbmdlKGluc3QsIGdvdG9EYXRlKSA/IFwiPGJ1dHRvbiB0eXBlPSdidXR0b24nIGNsYXNzPSd1aS1kYXRlcGlja2VyLWN1cnJlbnQgdWktc3RhdGUtZGVmYXVsdCB1aS1wcmlvcml0eS1zZWNvbmRhcnkgdWktY29ybmVyLWFsbCcgZGF0YS1oYW5kbGVyPSd0b2RheScgZGF0YS1ldmVudD0nY2xpY2snXCIgK1xuXHRcdFx0XCI+XCIgKyBjdXJyZW50VGV4dCArIFwiPC9idXR0b24+XCIgOiBcIlwiKSArIChpc1JUTCA/IFwiXCIgOiBjb250cm9scykgKyBcIjwvZGl2PlwiIDogXCJcIjtcblxuXHRcdGZpcnN0RGF5ID0gcGFyc2VJbnQodGhpcy5fZ2V0KGluc3QsIFwiZmlyc3REYXlcIiksMTApO1xuXHRcdGZpcnN0RGF5ID0gKGlzTmFOKGZpcnN0RGF5KSA/IDAgOiBmaXJzdERheSk7XG5cblx0XHRzaG93V2VlayA9IHRoaXMuX2dldChpbnN0LCBcInNob3dXZWVrXCIpO1xuXHRcdGRheU5hbWVzID0gdGhpcy5fZ2V0KGluc3QsIFwiZGF5TmFtZXNcIik7XG5cdFx0ZGF5TmFtZXNNaW4gPSB0aGlzLl9nZXQoaW5zdCwgXCJkYXlOYW1lc01pblwiKTtcblx0XHRtb250aE5hbWVzID0gdGhpcy5fZ2V0KGluc3QsIFwibW9udGhOYW1lc1wiKTtcblx0XHRtb250aE5hbWVzU2hvcnQgPSB0aGlzLl9nZXQoaW5zdCwgXCJtb250aE5hbWVzU2hvcnRcIik7XG5cdFx0YmVmb3JlU2hvd0RheSA9IHRoaXMuX2dldChpbnN0LCBcImJlZm9yZVNob3dEYXlcIik7XG5cdFx0c2hvd090aGVyTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvd090aGVyTW9udGhzXCIpO1xuXHRcdHNlbGVjdE90aGVyTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsIFwic2VsZWN0T3RoZXJNb250aHNcIik7XG5cdFx0ZGVmYXVsdERhdGUgPSB0aGlzLl9nZXREZWZhdWx0RGF0ZShpbnN0KTtcblx0XHRodG1sID0gXCJcIjtcblx0XHRkb3c7XG5cdFx0Zm9yIChyb3cgPSAwOyByb3cgPCBudW1Nb250aHNbMF07IHJvdysrKSB7XG5cdFx0XHRncm91cCA9IFwiXCI7XG5cdFx0XHR0aGlzLm1heFJvd3MgPSA0O1xuXHRcdFx0Zm9yIChjb2wgPSAwOyBjb2wgPCBudW1Nb250aHNbMV07IGNvbCsrKSB7XG5cdFx0XHRcdHNlbGVjdGVkRGF0ZSA9IHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKGRyYXdZZWFyLCBkcmF3TW9udGgsIGluc3Quc2VsZWN0ZWREYXkpKTtcblx0XHRcdFx0Y29ybmVyQ2xhc3MgPSBcIiB1aS1jb3JuZXItYWxsXCI7XG5cdFx0XHRcdGNhbGVuZGVyID0gXCJcIjtcblx0XHRcdFx0aWYgKGlzTXVsdGlNb250aCkge1xuXHRcdFx0XHRcdGNhbGVuZGVyICs9IFwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1ncm91cFwiO1xuXHRcdFx0XHRcdGlmIChudW1Nb250aHNbMV0gPiAxKSB7XG5cdFx0XHRcdFx0XHRzd2l0Y2ggKGNvbCkge1xuXHRcdFx0XHRcdFx0XHRjYXNlIDA6IGNhbGVuZGVyICs9IFwiIHVpLWRhdGVwaWNrZXItZ3JvdXAtZmlyc3RcIjtcblx0XHRcdFx0XHRcdFx0XHRjb3JuZXJDbGFzcyA9IFwiIHVpLWNvcm5lci1cIiArIChpc1JUTCA/IFwicmlnaHRcIiA6IFwibGVmdFwiKTsgYnJlYWs7XG5cdFx0XHRcdFx0XHRcdGNhc2UgbnVtTW9udGhzWzFdLTE6IGNhbGVuZGVyICs9IFwiIHVpLWRhdGVwaWNrZXItZ3JvdXAtbGFzdFwiO1xuXHRcdFx0XHRcdFx0XHRcdGNvcm5lckNsYXNzID0gXCIgdWktY29ybmVyLVwiICsgKGlzUlRMID8gXCJsZWZ0XCIgOiBcInJpZ2h0XCIpOyBicmVhaztcblx0XHRcdFx0XHRcdFx0ZGVmYXVsdDogY2FsZW5kZXIgKz0gXCIgdWktZGF0ZXBpY2tlci1ncm91cC1taWRkbGVcIjsgY29ybmVyQ2xhc3MgPSBcIlwiOyBicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y2FsZW5kZXIgKz0gXCInPlwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNhbGVuZGVyICs9IFwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci1oZWFkZXIgdWktd2lkZ2V0LWhlYWRlciB1aS1oZWxwZXItY2xlYXJmaXhcIiArIGNvcm5lckNsYXNzICsgXCInPlwiICtcblx0XHRcdFx0XHQoL2FsbHxsZWZ0Ly50ZXN0KGNvcm5lckNsYXNzKSAmJiByb3cgPT09IDAgPyAoaXNSVEwgPyBuZXh0IDogcHJldikgOiBcIlwiKSArXG5cdFx0XHRcdFx0KC9hbGx8cmlnaHQvLnRlc3QoY29ybmVyQ2xhc3MpICYmIHJvdyA9PT0gMCA/IChpc1JUTCA/IHByZXYgOiBuZXh0KSA6IFwiXCIpICtcblx0XHRcdFx0XHR0aGlzLl9nZW5lcmF0ZU1vbnRoWWVhckhlYWRlcihpbnN0LCBkcmF3TW9udGgsIGRyYXdZZWFyLCBtaW5EYXRlLCBtYXhEYXRlLFxuXHRcdFx0XHRcdHJvdyA+IDAgfHwgY29sID4gMCwgbW9udGhOYW1lcywgbW9udGhOYW1lc1Nob3J0KSArIC8vIGRyYXcgbW9udGggaGVhZGVyc1xuXHRcdFx0XHRcdFwiPC9kaXY+PHRhYmxlIGNsYXNzPSd1aS1kYXRlcGlja2VyLWNhbGVuZGFyJz48dGhlYWQ+XCIgK1xuXHRcdFx0XHRcdFwiPHRyPlwiO1xuXHRcdFx0XHR0aGVhZCA9IChzaG93V2VlayA/IFwiPHRoIGNsYXNzPSd1aS1kYXRlcGlja2VyLXdlZWstY29sJz5cIiArIHRoaXMuX2dldChpbnN0LCBcIndlZWtIZWFkZXJcIikgKyBcIjwvdGg+XCIgOiBcIlwiKTtcblx0XHRcdFx0Zm9yIChkb3cgPSAwOyBkb3cgPCA3OyBkb3crKykgeyAvLyBkYXlzIG9mIHRoZSB3ZWVrXG5cdFx0XHRcdFx0ZGF5ID0gKGRvdyArIGZpcnN0RGF5KSAlIDc7XG5cdFx0XHRcdFx0dGhlYWQgKz0gXCI8dGhcIiArICgoZG93ICsgZmlyc3REYXkgKyA2KSAlIDcgPj0gNSA/IFwiIGNsYXNzPSd1aS1kYXRlcGlja2VyLXdlZWstZW5kJ1wiIDogXCJcIikgKyBcIj5cIiArXG5cdFx0XHRcdFx0XHRcIjxzcGFuIHRpdGxlPSdcIiArIGRheU5hbWVzW2RheV0gKyBcIic+XCIgKyBkYXlOYW1lc01pbltkYXldICsgXCI8L3NwYW4+PC90aD5cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRjYWxlbmRlciArPSB0aGVhZCArIFwiPC90cj48L3RoZWFkPjx0Ym9keT5cIjtcblx0XHRcdFx0ZGF5c0luTW9udGggPSB0aGlzLl9nZXREYXlzSW5Nb250aChkcmF3WWVhciwgZHJhd01vbnRoKTtcblx0XHRcdFx0aWYgKGRyYXdZZWFyID09PSBpbnN0LnNlbGVjdGVkWWVhciAmJiBkcmF3TW9udGggPT09IGluc3Quc2VsZWN0ZWRNb250aCkge1xuXHRcdFx0XHRcdGluc3Quc2VsZWN0ZWREYXkgPSBNYXRoLm1pbihpbnN0LnNlbGVjdGVkRGF5LCBkYXlzSW5Nb250aCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bGVhZERheXMgPSAodGhpcy5fZ2V0Rmlyc3REYXlPZk1vbnRoKGRyYXdZZWFyLCBkcmF3TW9udGgpIC0gZmlyc3REYXkgKyA3KSAlIDc7XG5cdFx0XHRcdGN1clJvd3MgPSBNYXRoLmNlaWwoKGxlYWREYXlzICsgZGF5c0luTW9udGgpIC8gNyk7IC8vIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHJvd3MgdG8gZ2VuZXJhdGVcblx0XHRcdFx0bnVtUm93cyA9IChpc011bHRpTW9udGggPyB0aGlzLm1heFJvd3MgPiBjdXJSb3dzID8gdGhpcy5tYXhSb3dzIDogY3VyUm93cyA6IGN1clJvd3MpOyAvL0lmIG11bHRpcGxlIG1vbnRocywgdXNlIHRoZSBoaWdoZXIgbnVtYmVyIG9mIHJvd3MgKHNlZSAjNzA0Mylcblx0XHRcdFx0dGhpcy5tYXhSb3dzID0gbnVtUm93cztcblx0XHRcdFx0cHJpbnREYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoZHJhd1llYXIsIGRyYXdNb250aCwgMSAtIGxlYWREYXlzKSk7XG5cdFx0XHRcdGZvciAoZFJvdyA9IDA7IGRSb3cgPCBudW1Sb3dzOyBkUm93KyspIHsgLy8gY3JlYXRlIGRhdGUgcGlja2VyIHJvd3Ncblx0XHRcdFx0XHRjYWxlbmRlciArPSBcIjx0cj5cIjtcblx0XHRcdFx0XHR0Ym9keSA9ICghc2hvd1dlZWsgPyBcIlwiIDogXCI8dGQgY2xhc3M9J3VpLWRhdGVwaWNrZXItd2Vlay1jb2wnPlwiICtcblx0XHRcdFx0XHRcdHRoaXMuX2dldChpbnN0LCBcImNhbGN1bGF0ZVdlZWtcIikocHJpbnREYXRlKSArIFwiPC90ZD5cIik7XG5cdFx0XHRcdFx0Zm9yIChkb3cgPSAwOyBkb3cgPCA3OyBkb3crKykgeyAvLyBjcmVhdGUgZGF0ZSBwaWNrZXIgZGF5c1xuXHRcdFx0XHRcdFx0ZGF5U2V0dGluZ3MgPSAoYmVmb3JlU2hvd0RheSA/XG5cdFx0XHRcdFx0XHRcdGJlZm9yZVNob3dEYXkuYXBwbHkoKGluc3QuaW5wdXQgPyBpbnN0LmlucHV0WzBdIDogbnVsbCksIFtwcmludERhdGVdKSA6IFt0cnVlLCBcIlwiXSk7XG5cdFx0XHRcdFx0XHRvdGhlck1vbnRoID0gKHByaW50RGF0ZS5nZXRNb250aCgpICE9PSBkcmF3TW9udGgpO1xuXHRcdFx0XHRcdFx0dW5zZWxlY3RhYmxlID0gKG90aGVyTW9udGggJiYgIXNlbGVjdE90aGVyTW9udGhzKSB8fCAhZGF5U2V0dGluZ3NbMF0gfHxcblx0XHRcdFx0XHRcdFx0KG1pbkRhdGUgJiYgcHJpbnREYXRlIDwgbWluRGF0ZSkgfHwgKG1heERhdGUgJiYgcHJpbnREYXRlID4gbWF4RGF0ZSk7XG5cdFx0XHRcdFx0XHR0Ym9keSArPSBcIjx0ZCBjbGFzcz0nXCIgK1xuXHRcdFx0XHRcdFx0XHQoKGRvdyArIGZpcnN0RGF5ICsgNikgJSA3ID49IDUgPyBcIiB1aS1kYXRlcGlja2VyLXdlZWstZW5kXCIgOiBcIlwiKSArIC8vIGhpZ2hsaWdodCB3ZWVrZW5kc1xuXHRcdFx0XHRcdFx0XHQob3RoZXJNb250aCA/IFwiIHVpLWRhdGVwaWNrZXItb3RoZXItbW9udGhcIiA6IFwiXCIpICsgLy8gaGlnaGxpZ2h0IGRheXMgZnJvbSBvdGhlciBtb250aHNcblx0XHRcdFx0XHRcdFx0KChwcmludERhdGUuZ2V0VGltZSgpID09PSBzZWxlY3RlZERhdGUuZ2V0VGltZSgpICYmIGRyYXdNb250aCA9PT0gaW5zdC5zZWxlY3RlZE1vbnRoICYmIGluc3QuX2tleUV2ZW50KSB8fCAvLyB1c2VyIHByZXNzZWQga2V5XG5cdFx0XHRcdFx0XHRcdChkZWZhdWx0RGF0ZS5nZXRUaW1lKCkgPT09IHByaW50RGF0ZS5nZXRUaW1lKCkgJiYgZGVmYXVsdERhdGUuZ2V0VGltZSgpID09PSBzZWxlY3RlZERhdGUuZ2V0VGltZSgpKSA/XG5cdFx0XHRcdFx0XHRcdC8vIG9yIGRlZmF1bHREYXRlIGlzIGN1cnJlbnQgcHJpbnRlZERhdGUgYW5kIGRlZmF1bHREYXRlIGlzIHNlbGVjdGVkRGF0ZVxuXHRcdFx0XHRcdFx0XHRcIiBcIiArIHRoaXMuX2RheU92ZXJDbGFzcyA6IFwiXCIpICsgLy8gaGlnaGxpZ2h0IHNlbGVjdGVkIGRheVxuXHRcdFx0XHRcdFx0XHQodW5zZWxlY3RhYmxlID8gXCIgXCIgKyB0aGlzLl91bnNlbGVjdGFibGVDbGFzcyArIFwiIHVpLXN0YXRlLWRpc2FibGVkXCI6IFwiXCIpICsgIC8vIGhpZ2hsaWdodCB1bnNlbGVjdGFibGUgZGF5c1xuXHRcdFx0XHRcdFx0XHQob3RoZXJNb250aCAmJiAhc2hvd090aGVyTW9udGhzID8gXCJcIiA6IFwiIFwiICsgZGF5U2V0dGluZ3NbMV0gKyAvLyBoaWdobGlnaHQgY3VzdG9tIGRhdGVzXG5cdFx0XHRcdFx0XHRcdChwcmludERhdGUuZ2V0VGltZSgpID09PSBjdXJyZW50RGF0ZS5nZXRUaW1lKCkgPyBcIiBcIiArIHRoaXMuX2N1cnJlbnRDbGFzcyA6IFwiXCIpICsgLy8gaGlnaGxpZ2h0IHNlbGVjdGVkIGRheVxuXHRcdFx0XHRcdFx0XHQocHJpbnREYXRlLmdldFRpbWUoKSA9PT0gdG9kYXkuZ2V0VGltZSgpID8gXCIgdWktZGF0ZXBpY2tlci10b2RheVwiIDogXCJcIikpICsgXCInXCIgKyAvLyBoaWdobGlnaHQgdG9kYXkgKGlmIGRpZmZlcmVudClcblx0XHRcdFx0XHRcdFx0KCghb3RoZXJNb250aCB8fCBzaG93T3RoZXJNb250aHMpICYmIGRheVNldHRpbmdzWzJdID8gXCIgdGl0bGU9J1wiICsgZGF5U2V0dGluZ3NbMl0ucmVwbGFjZSgvJy9nLCBcIiYjMzk7XCIpICsgXCInXCIgOiBcIlwiKSArIC8vIGNlbGwgdGl0bGVcblx0XHRcdFx0XHRcdFx0KHVuc2VsZWN0YWJsZSA/IFwiXCIgOiBcIiBkYXRhLWhhbmRsZXI9J3NlbGVjdERheScgZGF0YS1ldmVudD0nY2xpY2snIGRhdGEtbW9udGg9J1wiICsgcHJpbnREYXRlLmdldE1vbnRoKCkgKyBcIicgZGF0YS15ZWFyPSdcIiArIHByaW50RGF0ZS5nZXRGdWxsWWVhcigpICsgXCInXCIpICsgXCI+XCIgKyAvLyBhY3Rpb25zXG5cdFx0XHRcdFx0XHRcdChvdGhlck1vbnRoICYmICFzaG93T3RoZXJNb250aHMgPyBcIiYjeGEwO1wiIDogLy8gZGlzcGxheSBmb3Igb3RoZXIgbW9udGhzXG5cdFx0XHRcdFx0XHRcdCh1bnNlbGVjdGFibGUgPyBcIjxzcGFuIGNsYXNzPSd1aS1zdGF0ZS1kZWZhdWx0Jz5cIiArIHByaW50RGF0ZS5nZXREYXRlKCkgKyBcIjwvc3Bhbj5cIiA6IFwiPGEgY2xhc3M9J3VpLXN0YXRlLWRlZmF1bHRcIiArXG5cdFx0XHRcdFx0XHRcdChwcmludERhdGUuZ2V0VGltZSgpID09PSB0b2RheS5nZXRUaW1lKCkgPyBcIiB1aS1zdGF0ZS1oaWdobGlnaHRcIiA6IFwiXCIpICtcblx0XHRcdFx0XHRcdFx0KHByaW50RGF0ZS5nZXRUaW1lKCkgPT09IGN1cnJlbnREYXRlLmdldFRpbWUoKSA/IFwiIHVpLXN0YXRlLWFjdGl2ZVwiIDogXCJcIikgKyAvLyBoaWdobGlnaHQgc2VsZWN0ZWQgZGF5XG5cdFx0XHRcdFx0XHRcdChvdGhlck1vbnRoID8gXCIgdWktcHJpb3JpdHktc2Vjb25kYXJ5XCIgOiBcIlwiKSArIC8vIGRpc3Rpbmd1aXNoIGRhdGVzIGZyb20gb3RoZXIgbW9udGhzXG5cdFx0XHRcdFx0XHRcdFwiJyBocmVmPScjJz5cIiArIHByaW50RGF0ZS5nZXREYXRlKCkgKyBcIjwvYT5cIikpICsgXCI8L3RkPlwiOyAvLyBkaXNwbGF5IHNlbGVjdGFibGUgZGF0ZVxuXHRcdFx0XHRcdFx0cHJpbnREYXRlLnNldERhdGUocHJpbnREYXRlLmdldERhdGUoKSArIDEpO1xuXHRcdFx0XHRcdFx0cHJpbnREYXRlID0gdGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QocHJpbnREYXRlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y2FsZW5kZXIgKz0gdGJvZHkgKyBcIjwvdHI+XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZHJhd01vbnRoKys7XG5cdFx0XHRcdGlmIChkcmF3TW9udGggPiAxMSkge1xuXHRcdFx0XHRcdGRyYXdNb250aCA9IDA7XG5cdFx0XHRcdFx0ZHJhd1llYXIrKztcblx0XHRcdFx0fVxuXHRcdFx0XHRjYWxlbmRlciArPSBcIjwvdGJvZHk+PC90YWJsZT5cIiArIChpc011bHRpTW9udGggPyBcIjwvZGl2PlwiICtcblx0XHRcdFx0XHRcdFx0KChudW1Nb250aHNbMF0gPiAwICYmIGNvbCA9PT0gbnVtTW9udGhzWzFdLTEpID8gXCI8ZGl2IGNsYXNzPSd1aS1kYXRlcGlja2VyLXJvdy1icmVhayc+PC9kaXY+XCIgOiBcIlwiKSA6IFwiXCIpO1xuXHRcdFx0XHRncm91cCArPSBjYWxlbmRlcjtcblx0XHRcdH1cblx0XHRcdGh0bWwgKz0gZ3JvdXA7XG5cdFx0fVxuXHRcdGh0bWwgKz0gYnV0dG9uUGFuZWw7XG5cdFx0aW5zdC5fa2V5RXZlbnQgPSBmYWxzZTtcblx0XHRyZXR1cm4gaHRtbDtcblx0fSxcblxuXHQvKiBHZW5lcmF0ZSB0aGUgbW9udGggYW5kIHllYXIgaGVhZGVyLiAqL1xuXHRfZ2VuZXJhdGVNb250aFllYXJIZWFkZXI6IGZ1bmN0aW9uKGluc3QsIGRyYXdNb250aCwgZHJhd1llYXIsIG1pbkRhdGUsIG1heERhdGUsXG5cdFx0XHRzZWNvbmRhcnksIG1vbnRoTmFtZXMsIG1vbnRoTmFtZXNTaG9ydCkge1xuXG5cdFx0dmFyIGluTWluWWVhciwgaW5NYXhZZWFyLCBtb250aCwgeWVhcnMsIHRoaXNZZWFyLCBkZXRlcm1pbmVZZWFyLCB5ZWFyLCBlbmRZZWFyLFxuXHRcdFx0Y2hhbmdlTW9udGggPSB0aGlzLl9nZXQoaW5zdCwgXCJjaGFuZ2VNb250aFwiKSxcblx0XHRcdGNoYW5nZVllYXIgPSB0aGlzLl9nZXQoaW5zdCwgXCJjaGFuZ2VZZWFyXCIpLFxuXHRcdFx0c2hvd01vbnRoQWZ0ZXJZZWFyID0gdGhpcy5fZ2V0KGluc3QsIFwic2hvd01vbnRoQWZ0ZXJZZWFyXCIpLFxuXHRcdFx0aHRtbCA9IFwiPGRpdiBjbGFzcz0ndWktZGF0ZXBpY2tlci10aXRsZSc+XCIsXG5cdFx0XHRtb250aEh0bWwgPSBcIlwiO1xuXG5cdFx0Ly8gbW9udGggc2VsZWN0aW9uXG5cdFx0aWYgKHNlY29uZGFyeSB8fCAhY2hhbmdlTW9udGgpIHtcblx0XHRcdG1vbnRoSHRtbCArPSBcIjxzcGFuIGNsYXNzPSd1aS1kYXRlcGlja2VyLW1vbnRoJz5cIiArIG1vbnRoTmFtZXNbZHJhd01vbnRoXSArIFwiPC9zcGFuPlwiO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRpbk1pblllYXIgPSAobWluRGF0ZSAmJiBtaW5EYXRlLmdldEZ1bGxZZWFyKCkgPT09IGRyYXdZZWFyKTtcblx0XHRcdGluTWF4WWVhciA9IChtYXhEYXRlICYmIG1heERhdGUuZ2V0RnVsbFllYXIoKSA9PT0gZHJhd1llYXIpO1xuXHRcdFx0bW9udGhIdG1sICs9IFwiPHNlbGVjdCBjbGFzcz0ndWktZGF0ZXBpY2tlci1tb250aCcgZGF0YS1oYW5kbGVyPSdzZWxlY3RNb250aCcgZGF0YS1ldmVudD0nY2hhbmdlJz5cIjtcblx0XHRcdGZvciAoIG1vbnRoID0gMDsgbW9udGggPCAxMjsgbW9udGgrKykge1xuXHRcdFx0XHRpZiAoKCFpbk1pblllYXIgfHwgbW9udGggPj0gbWluRGF0ZS5nZXRNb250aCgpKSAmJiAoIWluTWF4WWVhciB8fCBtb250aCA8PSBtYXhEYXRlLmdldE1vbnRoKCkpKSB7XG5cdFx0XHRcdFx0bW9udGhIdG1sICs9IFwiPG9wdGlvbiB2YWx1ZT0nXCIgKyBtb250aCArIFwiJ1wiICtcblx0XHRcdFx0XHRcdChtb250aCA9PT0gZHJhd01vbnRoID8gXCIgc2VsZWN0ZWQ9J3NlbGVjdGVkJ1wiIDogXCJcIikgK1xuXHRcdFx0XHRcdFx0XCI+XCIgKyBtb250aE5hbWVzU2hvcnRbbW9udGhdICsgXCI8L29wdGlvbj5cIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0bW9udGhIdG1sICs9IFwiPC9zZWxlY3Q+XCI7XG5cdFx0fVxuXG5cdFx0aWYgKCFzaG93TW9udGhBZnRlclllYXIpIHtcblx0XHRcdGh0bWwgKz0gbW9udGhIdG1sICsgKHNlY29uZGFyeSB8fCAhKGNoYW5nZU1vbnRoICYmIGNoYW5nZVllYXIpID8gXCImI3hhMDtcIiA6IFwiXCIpO1xuXHRcdH1cblxuXHRcdC8vIHllYXIgc2VsZWN0aW9uXG5cdFx0aWYgKCAhaW5zdC55ZWFyc2h0bWwgKSB7XG5cdFx0XHRpbnN0LnllYXJzaHRtbCA9IFwiXCI7XG5cdFx0XHRpZiAoc2Vjb25kYXJ5IHx8ICFjaGFuZ2VZZWFyKSB7XG5cdFx0XHRcdGh0bWwgKz0gXCI8c3BhbiBjbGFzcz0ndWktZGF0ZXBpY2tlci15ZWFyJz5cIiArIGRyYXdZZWFyICsgXCI8L3NwYW4+XCI7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBkZXRlcm1pbmUgcmFuZ2Ugb2YgeWVhcnMgdG8gZGlzcGxheVxuXHRcdFx0XHR5ZWFycyA9IHRoaXMuX2dldChpbnN0LCBcInllYXJSYW5nZVwiKS5zcGxpdChcIjpcIik7XG5cdFx0XHRcdHRoaXNZZWFyID0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpO1xuXHRcdFx0XHRkZXRlcm1pbmVZZWFyID0gZnVuY3Rpb24odmFsdWUpIHtcblx0XHRcdFx0XHR2YXIgeWVhciA9ICh2YWx1ZS5tYXRjaCgvY1srXFwtXS4qLykgPyBkcmF3WWVhciArIHBhcnNlSW50KHZhbHVlLnN1YnN0cmluZygxKSwgMTApIDpcblx0XHRcdFx0XHRcdCh2YWx1ZS5tYXRjaCgvWytcXC1dLiovKSA/IHRoaXNZZWFyICsgcGFyc2VJbnQodmFsdWUsIDEwKSA6XG5cdFx0XHRcdFx0XHRwYXJzZUludCh2YWx1ZSwgMTApKSk7XG5cdFx0XHRcdFx0cmV0dXJuIChpc05hTih5ZWFyKSA/IHRoaXNZZWFyIDogeWVhcik7XG5cdFx0XHRcdH07XG5cdFx0XHRcdHllYXIgPSBkZXRlcm1pbmVZZWFyKHllYXJzWzBdKTtcblx0XHRcdFx0ZW5kWWVhciA9IE1hdGgubWF4KHllYXIsIGRldGVybWluZVllYXIoeWVhcnNbMV0gfHwgXCJcIikpO1xuXHRcdFx0XHR5ZWFyID0gKG1pbkRhdGUgPyBNYXRoLm1heCh5ZWFyLCBtaW5EYXRlLmdldEZ1bGxZZWFyKCkpIDogeWVhcik7XG5cdFx0XHRcdGVuZFllYXIgPSAobWF4RGF0ZSA/IE1hdGgubWluKGVuZFllYXIsIG1heERhdGUuZ2V0RnVsbFllYXIoKSkgOiBlbmRZZWFyKTtcblx0XHRcdFx0aW5zdC55ZWFyc2h0bWwgKz0gXCI8c2VsZWN0IGNsYXNzPSd1aS1kYXRlcGlja2VyLXllYXInIGRhdGEtaGFuZGxlcj0nc2VsZWN0WWVhcicgZGF0YS1ldmVudD0nY2hhbmdlJz5cIjtcblx0XHRcdFx0Zm9yICg7IHllYXIgPD0gZW5kWWVhcjsgeWVhcisrKSB7XG5cdFx0XHRcdFx0aW5zdC55ZWFyc2h0bWwgKz0gXCI8b3B0aW9uIHZhbHVlPSdcIiArIHllYXIgKyBcIidcIiArXG5cdFx0XHRcdFx0XHQoeWVhciA9PT0gZHJhd1llYXIgPyBcIiBzZWxlY3RlZD0nc2VsZWN0ZWQnXCIgOiBcIlwiKSArXG5cdFx0XHRcdFx0XHRcIj5cIiArIHllYXIgKyBcIjwvb3B0aW9uPlwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGluc3QueWVhcnNodG1sICs9IFwiPC9zZWxlY3Q+XCI7XG5cblx0XHRcdFx0aHRtbCArPSBpbnN0LnllYXJzaHRtbDtcblx0XHRcdFx0aW5zdC55ZWFyc2h0bWwgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGh0bWwgKz0gdGhpcy5fZ2V0KGluc3QsIFwieWVhclN1ZmZpeFwiKTtcblx0XHRpZiAoc2hvd01vbnRoQWZ0ZXJZZWFyKSB7XG5cdFx0XHRodG1sICs9IChzZWNvbmRhcnkgfHwgIShjaGFuZ2VNb250aCAmJiBjaGFuZ2VZZWFyKSA/IFwiJiN4YTA7XCIgOiBcIlwiKSArIG1vbnRoSHRtbDtcblx0XHR9XG5cdFx0aHRtbCArPSBcIjwvZGl2PlwiOyAvLyBDbG9zZSBkYXRlcGlja2VyX2hlYWRlclxuXHRcdHJldHVybiBodG1sO1xuXHR9LFxuXG5cdC8qIEFkanVzdCBvbmUgb2YgdGhlIGRhdGUgc3ViLWZpZWxkcy4gKi9cblx0X2FkanVzdEluc3REYXRlOiBmdW5jdGlvbihpbnN0LCBvZmZzZXQsIHBlcmlvZCkge1xuXHRcdHZhciB5ZWFyID0gaW5zdC5kcmF3WWVhciArIChwZXJpb2QgPT09IFwiWVwiID8gb2Zmc2V0IDogMCksXG5cdFx0XHRtb250aCA9IGluc3QuZHJhd01vbnRoICsgKHBlcmlvZCA9PT0gXCJNXCIgPyBvZmZzZXQgOiAwKSxcblx0XHRcdGRheSA9IE1hdGgubWluKGluc3Quc2VsZWN0ZWREYXksIHRoaXMuX2dldERheXNJbk1vbnRoKHllYXIsIG1vbnRoKSkgKyAocGVyaW9kID09PSBcIkRcIiA/IG9mZnNldCA6IDApLFxuXHRcdFx0ZGF0ZSA9IHRoaXMuX3Jlc3RyaWN0TWluTWF4KGluc3QsIHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpKSk7XG5cblx0XHRpbnN0LnNlbGVjdGVkRGF5ID0gZGF0ZS5nZXREYXRlKCk7XG5cdFx0aW5zdC5kcmF3TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGggPSBkYXRlLmdldE1vbnRoKCk7XG5cdFx0aW5zdC5kcmF3WWVhciA9IGluc3Quc2VsZWN0ZWRZZWFyID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuXHRcdGlmIChwZXJpb2QgPT09IFwiTVwiIHx8IHBlcmlvZCA9PT0gXCJZXCIpIHtcblx0XHRcdHRoaXMuX25vdGlmeUNoYW5nZShpbnN0KTtcblx0XHR9XG5cdH0sXG5cblx0LyogRW5zdXJlIGEgZGF0ZSBpcyB3aXRoaW4gYW55IG1pbi9tYXggYm91bmRzLiAqL1xuXHRfcmVzdHJpY3RNaW5NYXg6IGZ1bmN0aW9uKGluc3QsIGRhdGUpIHtcblx0XHR2YXIgbWluRGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgXCJtaW5cIiksXG5cdFx0XHRtYXhEYXRlID0gdGhpcy5fZ2V0TWluTWF4RGF0ZShpbnN0LCBcIm1heFwiKSxcblx0XHRcdG5ld0RhdGUgPSAobWluRGF0ZSAmJiBkYXRlIDwgbWluRGF0ZSA/IG1pbkRhdGUgOiBkYXRlKTtcblx0XHRyZXR1cm4gKG1heERhdGUgJiYgbmV3RGF0ZSA+IG1heERhdGUgPyBtYXhEYXRlIDogbmV3RGF0ZSk7XG5cdH0sXG5cblx0LyogTm90aWZ5IGNoYW5nZSBvZiBtb250aC95ZWFyLiAqL1xuXHRfbm90aWZ5Q2hhbmdlOiBmdW5jdGlvbihpbnN0KSB7XG5cdFx0dmFyIG9uQ2hhbmdlID0gdGhpcy5fZ2V0KGluc3QsIFwib25DaGFuZ2VNb250aFllYXJcIik7XG5cdFx0aWYgKG9uQ2hhbmdlKSB7XG5cdFx0XHRvbkNoYW5nZS5hcHBseSgoaW5zdC5pbnB1dCA/IGluc3QuaW5wdXRbMF0gOiBudWxsKSxcblx0XHRcdFx0W2luc3Quc2VsZWN0ZWRZZWFyLCBpbnN0LnNlbGVjdGVkTW9udGggKyAxLCBpbnN0XSk7XG5cdFx0fVxuXHR9LFxuXG5cdC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIG1vbnRocyB0byBzaG93LiAqL1xuXHRfZ2V0TnVtYmVyT2ZNb250aHM6IGZ1bmN0aW9uKGluc3QpIHtcblx0XHR2YXIgbnVtTW9udGhzID0gdGhpcy5fZ2V0KGluc3QsIFwibnVtYmVyT2ZNb250aHNcIik7XG5cdFx0cmV0dXJuIChudW1Nb250aHMgPT0gbnVsbCA/IFsxLCAxXSA6ICh0eXBlb2YgbnVtTW9udGhzID09PSBcIm51bWJlclwiID8gWzEsIG51bU1vbnRoc10gOiBudW1Nb250aHMpKTtcblx0fSxcblxuXHQvKiBEZXRlcm1pbmUgdGhlIGN1cnJlbnQgbWF4aW11bSBkYXRlIC0gZW5zdXJlIG5vIHRpbWUgY29tcG9uZW50cyBhcmUgc2V0LiAqL1xuXHRfZ2V0TWluTWF4RGF0ZTogZnVuY3Rpb24oaW5zdCwgbWluTWF4KSB7XG5cdFx0cmV0dXJuIHRoaXMuX2RldGVybWluZURhdGUoaW5zdCwgdGhpcy5fZ2V0KGluc3QsIG1pbk1heCArIFwiRGF0ZVwiKSwgbnVsbCk7XG5cdH0sXG5cblx0LyogRmluZCB0aGUgbnVtYmVyIG9mIGRheXMgaW4gYSBnaXZlbiBtb250aC4gKi9cblx0X2dldERheXNJbk1vbnRoOiBmdW5jdGlvbih5ZWFyLCBtb250aCkge1xuXHRcdHJldHVybiAzMiAtIHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHllYXIsIG1vbnRoLCAzMikpLmdldERhdGUoKTtcblx0fSxcblxuXHQvKiBGaW5kIHRoZSBkYXkgb2YgdGhlIHdlZWsgb2YgdGhlIGZpcnN0IG9mIGEgbW9udGguICovXG5cdF9nZXRGaXJzdERheU9mTW9udGg6IGZ1bmN0aW9uKHllYXIsIG1vbnRoKSB7XG5cdFx0cmV0dXJuIG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKS5nZXREYXkoKTtcblx0fSxcblxuXHQvKiBEZXRlcm1pbmVzIGlmIHdlIHNob3VsZCBhbGxvdyBhIFwibmV4dC9wcmV2XCIgbW9udGggZGlzcGxheSBjaGFuZ2UuICovXG5cdF9jYW5BZGp1c3RNb250aDogZnVuY3Rpb24oaW5zdCwgb2Zmc2V0LCBjdXJZZWFyLCBjdXJNb250aCkge1xuXHRcdHZhciBudW1Nb250aHMgPSB0aGlzLl9nZXROdW1iZXJPZk1vbnRocyhpbnN0KSxcblx0XHRcdGRhdGUgPSB0aGlzLl9kYXlsaWdodFNhdmluZ0FkanVzdChuZXcgRGF0ZShjdXJZZWFyLFxuXHRcdFx0Y3VyTW9udGggKyAob2Zmc2V0IDwgMCA/IG9mZnNldCA6IG51bU1vbnRoc1swXSAqIG51bU1vbnRoc1sxXSksIDEpKTtcblxuXHRcdGlmIChvZmZzZXQgPCAwKSB7XG5cdFx0XHRkYXRlLnNldERhdGUodGhpcy5fZ2V0RGF5c0luTW9udGgoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCkpKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuX2lzSW5SYW5nZShpbnN0LCBkYXRlKTtcblx0fSxcblxuXHQvKiBJcyB0aGUgZ2l2ZW4gZGF0ZSBpbiB0aGUgYWNjZXB0ZWQgcmFuZ2U/ICovXG5cdF9pc0luUmFuZ2U6IGZ1bmN0aW9uKGluc3QsIGRhdGUpIHtcblx0XHR2YXIgeWVhclNwbGl0LCBjdXJyZW50WWVhcixcblx0XHRcdG1pbkRhdGUgPSB0aGlzLl9nZXRNaW5NYXhEYXRlKGluc3QsIFwibWluXCIpLFxuXHRcdFx0bWF4RGF0ZSA9IHRoaXMuX2dldE1pbk1heERhdGUoaW5zdCwgXCJtYXhcIiksXG5cdFx0XHRtaW5ZZWFyID0gbnVsbCxcblx0XHRcdG1heFllYXIgPSBudWxsLFxuXHRcdFx0eWVhcnMgPSB0aGlzLl9nZXQoaW5zdCwgXCJ5ZWFyUmFuZ2VcIik7XG5cdFx0XHRpZiAoeWVhcnMpe1xuXHRcdFx0XHR5ZWFyU3BsaXQgPSB5ZWFycy5zcGxpdChcIjpcIik7XG5cdFx0XHRcdGN1cnJlbnRZZWFyID0gbmV3IERhdGUoKS5nZXRGdWxsWWVhcigpO1xuXHRcdFx0XHRtaW5ZZWFyID0gcGFyc2VJbnQoeWVhclNwbGl0WzBdLCAxMCk7XG5cdFx0XHRcdG1heFllYXIgPSBwYXJzZUludCh5ZWFyU3BsaXRbMV0sIDEwKTtcblx0XHRcdFx0aWYgKCB5ZWFyU3BsaXRbMF0ubWF0Y2goL1srXFwtXS4qLykgKSB7XG5cdFx0XHRcdFx0bWluWWVhciArPSBjdXJyZW50WWVhcjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIHllYXJTcGxpdFsxXS5tYXRjaCgvWytcXC1dLiovKSApIHtcblx0XHRcdFx0XHRtYXhZZWFyICs9IGN1cnJlbnRZZWFyO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRyZXR1cm4gKCghbWluRGF0ZSB8fCBkYXRlLmdldFRpbWUoKSA+PSBtaW5EYXRlLmdldFRpbWUoKSkgJiZcblx0XHRcdCghbWF4RGF0ZSB8fCBkYXRlLmdldFRpbWUoKSA8PSBtYXhEYXRlLmdldFRpbWUoKSkgJiZcblx0XHRcdCghbWluWWVhciB8fCBkYXRlLmdldEZ1bGxZZWFyKCkgPj0gbWluWWVhcikgJiZcblx0XHRcdCghbWF4WWVhciB8fCBkYXRlLmdldEZ1bGxZZWFyKCkgPD0gbWF4WWVhcikpO1xuXHR9LFxuXG5cdC8qIFByb3ZpZGUgdGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MgZm9yIGZvcm1hdHRpbmcvcGFyc2luZy4gKi9cblx0X2dldEZvcm1hdENvbmZpZzogZnVuY3Rpb24oaW5zdCkge1xuXHRcdHZhciBzaG9ydFllYXJDdXRvZmYgPSB0aGlzLl9nZXQoaW5zdCwgXCJzaG9ydFllYXJDdXRvZmZcIik7XG5cdFx0c2hvcnRZZWFyQ3V0b2ZmID0gKHR5cGVvZiBzaG9ydFllYXJDdXRvZmYgIT09IFwic3RyaW5nXCIgPyBzaG9ydFllYXJDdXRvZmYgOlxuXHRcdFx0bmV3IERhdGUoKS5nZXRGdWxsWWVhcigpICUgMTAwICsgcGFyc2VJbnQoc2hvcnRZZWFyQ3V0b2ZmLCAxMCkpO1xuXHRcdHJldHVybiB7c2hvcnRZZWFyQ3V0b2ZmOiBzaG9ydFllYXJDdXRvZmYsXG5cdFx0XHRkYXlOYW1lc1Nob3J0OiB0aGlzLl9nZXQoaW5zdCwgXCJkYXlOYW1lc1Nob3J0XCIpLCBkYXlOYW1lczogdGhpcy5fZ2V0KGluc3QsIFwiZGF5TmFtZXNcIiksXG5cdFx0XHRtb250aE5hbWVzU2hvcnQ6IHRoaXMuX2dldChpbnN0LCBcIm1vbnRoTmFtZXNTaG9ydFwiKSwgbW9udGhOYW1lczogdGhpcy5fZ2V0KGluc3QsIFwibW9udGhOYW1lc1wiKX07XG5cdH0sXG5cblx0LyogRm9ybWF0IHRoZSBnaXZlbiBkYXRlIGZvciBkaXNwbGF5LiAqL1xuXHRfZm9ybWF0RGF0ZTogZnVuY3Rpb24oaW5zdCwgZGF5LCBtb250aCwgeWVhcikge1xuXHRcdGlmICghZGF5KSB7XG5cdFx0XHRpbnN0LmN1cnJlbnREYXkgPSBpbnN0LnNlbGVjdGVkRGF5O1xuXHRcdFx0aW5zdC5jdXJyZW50TW9udGggPSBpbnN0LnNlbGVjdGVkTW9udGg7XG5cdFx0XHRpbnN0LmN1cnJlbnRZZWFyID0gaW5zdC5zZWxlY3RlZFllYXI7XG5cdFx0fVxuXHRcdHZhciBkYXRlID0gKGRheSA/ICh0eXBlb2YgZGF5ID09PSBcIm9iamVjdFwiID8gZGF5IDpcblx0XHRcdHRoaXMuX2RheWxpZ2h0U2F2aW5nQWRqdXN0KG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXkpKSkgOlxuXHRcdFx0dGhpcy5fZGF5bGlnaHRTYXZpbmdBZGp1c3QobmV3IERhdGUoaW5zdC5jdXJyZW50WWVhciwgaW5zdC5jdXJyZW50TW9udGgsIGluc3QuY3VycmVudERheSkpKTtcblx0XHRyZXR1cm4gdGhpcy5mb3JtYXREYXRlKHRoaXMuX2dldChpbnN0LCBcImRhdGVGb3JtYXRcIiksIGRhdGUsIHRoaXMuX2dldEZvcm1hdENvbmZpZyhpbnN0KSk7XG5cdH1cbn0pO1xuXG4vKlxuICogQmluZCBob3ZlciBldmVudHMgZm9yIGRhdGVwaWNrZXIgZWxlbWVudHMuXG4gKiBEb25lIHZpYSBkZWxlZ2F0ZSBzbyB0aGUgYmluZGluZyBvbmx5IG9jY3VycyBvbmNlIGluIHRoZSBsaWZldGltZSBvZiB0aGUgcGFyZW50IGRpdi5cbiAqIEdsb2JhbCBpbnN0QWN0aXZlLCBzZXQgYnkgX3VwZGF0ZURhdGVwaWNrZXIgYWxsb3dzIHRoZSBoYW5kbGVycyB0byBmaW5kIHRoZWlyIHdheSBiYWNrIHRvIHRoZSBhY3RpdmUgcGlja2VyLlxuICovXG5mdW5jdGlvbiBiaW5kSG92ZXIoZHBEaXYpIHtcblx0dmFyIHNlbGVjdG9yID0gXCJidXR0b24sIC51aS1kYXRlcGlja2VyLXByZXYsIC51aS1kYXRlcGlja2VyLW5leHQsIC51aS1kYXRlcGlja2VyLWNhbGVuZGFyIHRkIGFcIjtcblx0cmV0dXJuIGRwRGl2LmRlbGVnYXRlKHNlbGVjdG9yLCBcIm1vdXNlb3V0XCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLXN0YXRlLWhvdmVyXCIpO1xuXHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLXByZXZcIikgIT09IC0xKSB7XG5cdFx0XHRcdCQodGhpcykucmVtb3ZlQ2xhc3MoXCJ1aS1kYXRlcGlja2VyLXByZXYtaG92ZXJcIik7XG5cdFx0XHR9XG5cdFx0XHRpZiAodGhpcy5jbGFzc05hbWUuaW5kZXhPZihcInVpLWRhdGVwaWNrZXItbmV4dFwiKSAhPT0gLTEpIHtcblx0XHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcyhcInVpLWRhdGVwaWNrZXItbmV4dC1ob3ZlclwiKTtcblx0XHRcdH1cblx0XHR9KVxuXHRcdC5kZWxlZ2F0ZShzZWxlY3RvciwgXCJtb3VzZW92ZXJcIiwgZnVuY3Rpb24oKXtcblx0XHRcdGlmICghJC5kYXRlcGlja2VyLl9pc0Rpc2FibGVkRGF0ZXBpY2tlciggaW5zdEFjdGl2ZS5pbmxpbmUgPyBkcERpdi5wYXJlbnQoKVswXSA6IGluc3RBY3RpdmUuaW5wdXRbMF0pKSB7XG5cdFx0XHRcdCQodGhpcykucGFyZW50cyhcIi51aS1kYXRlcGlja2VyLWNhbGVuZGFyXCIpLmZpbmQoXCJhXCIpLnJlbW92ZUNsYXNzKFwidWktc3RhdGUtaG92ZXJcIik7XG5cdFx0XHRcdCQodGhpcykuYWRkQ2xhc3MoXCJ1aS1zdGF0ZS1ob3ZlclwiKTtcblx0XHRcdFx0aWYgKHRoaXMuY2xhc3NOYW1lLmluZGV4T2YoXCJ1aS1kYXRlcGlja2VyLXByZXZcIikgIT09IC0xKSB7XG5cdFx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcyhcInVpLWRhdGVwaWNrZXItcHJldi1ob3ZlclwiKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGhpcy5jbGFzc05hbWUuaW5kZXhPZihcInVpLWRhdGVwaWNrZXItbmV4dFwiKSAhPT0gLTEpIHtcblx0XHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKFwidWktZGF0ZXBpY2tlci1uZXh0LWhvdmVyXCIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG59XG5cbi8qIGpRdWVyeSBleHRlbmQgbm93IGlnbm9yZXMgbnVsbHMhICovXG5mdW5jdGlvbiBleHRlbmRSZW1vdmUodGFyZ2V0LCBwcm9wcykge1xuXHQkLmV4dGVuZCh0YXJnZXQsIHByb3BzKTtcblx0Zm9yICh2YXIgbmFtZSBpbiBwcm9wcykge1xuXHRcdGlmIChwcm9wc1tuYW1lXSA9PSBudWxsKSB7XG5cdFx0XHR0YXJnZXRbbmFtZV0gPSBwcm9wc1tuYW1lXTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHRhcmdldDtcbn1cblxuLyogSW52b2tlIHRoZSBkYXRlcGlja2VyIGZ1bmN0aW9uYWxpdHkuXG4gICBAcGFyYW0gIG9wdGlvbnMgIHN0cmluZyAtIGEgY29tbWFuZCwgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgb3Jcblx0XHRcdFx0XHRPYmplY3QgLSBzZXR0aW5ncyBmb3IgYXR0YWNoaW5nIG5ldyBkYXRlcGlja2VyIGZ1bmN0aW9uYWxpdHlcbiAgIEByZXR1cm4gIGpRdWVyeSBvYmplY3QgKi9cbiQuZm4uZGF0ZXBpY2tlciA9IGZ1bmN0aW9uKG9wdGlvbnMpe1xuXG5cdC8qIFZlcmlmeSBhbiBlbXB0eSBjb2xsZWN0aW9uIHdhc24ndCBwYXNzZWQgLSBGaXhlcyAjNjk3NiAqL1xuXHRpZiAoICF0aGlzLmxlbmd0aCApIHtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qIEluaXRpYWxpc2UgdGhlIGRhdGUgcGlja2VyLiAqL1xuXHRpZiAoISQuZGF0ZXBpY2tlci5pbml0aWFsaXplZCkge1xuXHRcdCQoZG9jdW1lbnQpLm1vdXNlZG93bigkLmRhdGVwaWNrZXIuX2NoZWNrRXh0ZXJuYWxDbGljayk7XG5cdFx0JC5kYXRlcGlja2VyLmluaXRpYWxpemVkID0gdHJ1ZTtcblx0fVxuXG5cdC8qIEFwcGVuZCBkYXRlcGlja2VyIG1haW4gY29udGFpbmVyIHRvIGJvZHkgaWYgbm90IGV4aXN0LiAqL1xuXHRpZiAoJChcIiNcIiskLmRhdGVwaWNrZXIuX21haW5EaXZJZCkubGVuZ3RoID09PSAwKSB7XG5cdFx0JChcImJvZHlcIikuYXBwZW5kKCQuZGF0ZXBpY2tlci5kcERpdik7XG5cdH1cblxuXHR2YXIgb3RoZXJBcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcblx0aWYgKHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiICYmIChvcHRpb25zID09PSBcImlzRGlzYWJsZWRcIiB8fCBvcHRpb25zID09PSBcImdldERhdGVcIiB8fCBvcHRpb25zID09PSBcIndpZGdldFwiKSkge1xuXHRcdHJldHVybiAkLmRhdGVwaWNrZXJbXCJfXCIgKyBvcHRpb25zICsgXCJEYXRlcGlja2VyXCJdLlxuXHRcdFx0YXBwbHkoJC5kYXRlcGlja2VyLCBbdGhpc1swXV0uY29uY2F0KG90aGVyQXJncykpO1xuXHR9XG5cdGlmIChvcHRpb25zID09PSBcIm9wdGlvblwiICYmIGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiYgdHlwZW9mIGFyZ3VtZW50c1sxXSA9PT0gXCJzdHJpbmdcIikge1xuXHRcdHJldHVybiAkLmRhdGVwaWNrZXJbXCJfXCIgKyBvcHRpb25zICsgXCJEYXRlcGlja2VyXCJdLlxuXHRcdFx0YXBwbHkoJC5kYXRlcGlja2VyLCBbdGhpc1swXV0uY29uY2F0KG90aGVyQXJncykpO1xuXHR9XG5cdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0dHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdFx0JC5kYXRlcGlja2VyW1wiX1wiICsgb3B0aW9ucyArIFwiRGF0ZXBpY2tlclwiXS5cblx0XHRcdFx0YXBwbHkoJC5kYXRlcGlja2VyLCBbdGhpc10uY29uY2F0KG90aGVyQXJncykpIDpcblx0XHRcdCQuZGF0ZXBpY2tlci5fYXR0YWNoRGF0ZXBpY2tlcih0aGlzLCBvcHRpb25zKTtcblx0fSk7XG59O1xuXG4kLmRhdGVwaWNrZXIgPSBuZXcgRGF0ZXBpY2tlcigpOyAvLyBzaW5nbGV0b24gaW5zdGFuY2VcbiQuZGF0ZXBpY2tlci5pbml0aWFsaXplZCA9IGZhbHNlO1xuJC5kYXRlcGlja2VyLnV1aWQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiQuZGF0ZXBpY2tlci52ZXJzaW9uID0gXCIxLjEwLjRcIjtcblxufSkoalF1ZXJ5KTtcbiIsIi8qIVxuICogalF1ZXJ5IEphdmFTY3JpcHQgTGlicmFyeSB2Mi4xLjFcbiAqIGh0dHA6Ly9qcXVlcnkuY29tL1xuICpcbiAqIEluY2x1ZGVzIFNpenpsZS5qc1xuICogaHR0cDovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgMjAwNSwgMjAxNCBqUXVlcnkgRm91bmRhdGlvbiwgSW5jLiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBEYXRlOiAyMDE0LTA1LTAxVDE3OjExWlxuICovXG5cbihmdW5jdGlvbiggZ2xvYmFsLCBmYWN0b3J5ICkge1xuXG5cdGlmICggdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0Ly8gRm9yIENvbW1vbkpTIGFuZCBDb21tb25KUy1saWtlIGVudmlyb25tZW50cyB3aGVyZSBhIHByb3BlciB3aW5kb3cgaXMgcHJlc2VudCxcblx0XHQvLyBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5XG5cdFx0Ly8gRm9yIGVudmlyb25tZW50cyB0aGF0IGRvIG5vdCBpbmhlcmVudGx5IHBvc3NlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcblx0XHQvLyAoc3VjaCBhcyBOb2RlLmpzKSwgZXhwb3NlIGEgalF1ZXJ5LW1ha2luZyBmYWN0b3J5IGFzIG1vZHVsZS5leHBvcnRzXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCB3aW5kb3dcblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mb1xuXHRcdG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsLmRvY3VtZW50ID9cblx0XHRcdGZhY3RvcnkoIGdsb2JhbCwgdHJ1ZSApIDpcblx0XHRcdGZ1bmN0aW9uKCB3ICkge1xuXHRcdFx0XHRpZiAoICF3LmRvY3VtZW50ICkge1xuXHRcdFx0XHRcdHRocm93IG5ldyBFcnJvciggXCJqUXVlcnkgcmVxdWlyZXMgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50XCIgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZmFjdG9yeSggdyApO1xuXHRcdFx0fTtcblx0fSBlbHNlIHtcblx0XHRmYWN0b3J5KCBnbG9iYWwgKTtcblx0fVxuXG4vLyBQYXNzIHRoaXMgaWYgd2luZG93IGlzIG5vdCBkZWZpbmVkIHlldFxufSh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24oIHdpbmRvdywgbm9HbG9iYWwgKSB7XG5cbi8vIENhbid0IGRvIHRoaXMgYmVjYXVzZSBzZXZlcmFsIGFwcHMgaW5jbHVkaW5nIEFTUC5ORVQgdHJhY2Vcbi8vIHRoZSBzdGFjayB2aWEgYXJndW1lbnRzLmNhbGxlci5jYWxsZWUgYW5kIEZpcmVmb3ggZGllcyBpZlxuLy8geW91IHRyeSB0byB0cmFjZSB0aHJvdWdoIFwidXNlIHN0cmljdFwiIGNhbGwgY2hhaW5zLiAoIzEzMzM1KVxuLy8gU3VwcG9ydDogRmlyZWZveCAxOCtcbi8vXG5cbnZhciBhcnIgPSBbXTtcblxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xuXG52YXIgY29uY2F0ID0gYXJyLmNvbmNhdDtcblxudmFyIHB1c2ggPSBhcnIucHVzaDtcblxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBzdXBwb3J0ID0ge307XG5cblxuXG52YXJcblx0Ly8gVXNlIHRoZSBjb3JyZWN0IGRvY3VtZW50IGFjY29yZGluZ2x5IHdpdGggd2luZG93IGFyZ3VtZW50IChzYW5kYm94KVxuXHRkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudCxcblxuXHR2ZXJzaW9uID0gXCIyLjEuMVwiLFxuXG5cdC8vIERlZmluZSBhIGxvY2FsIGNvcHkgb2YgalF1ZXJ5XG5cdGpRdWVyeSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcblx0XHQvLyBOZWVkIGluaXQgaWYgalF1ZXJ5IGlzIGNhbGxlZCAoanVzdCBhbGxvdyBlcnJvciB0byBiZSB0aHJvd24gaWYgbm90IGluY2x1ZGVkKVxuXHRcdHJldHVybiBuZXcgalF1ZXJ5LmZuLmluaXQoIHNlbGVjdG9yLCBjb250ZXh0ICk7XG5cdH0sXG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjFcblx0Ly8gTWFrZSBzdXJlIHdlIHRyaW0gQk9NIGFuZCBOQlNQXG5cdHJ0cmltID0gL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLFxuXG5cdC8vIE1hdGNoZXMgZGFzaGVkIHN0cmluZyBmb3IgY2FtZWxpemluZ1xuXHRybXNQcmVmaXggPSAvXi1tcy0vLFxuXHRyZGFzaEFscGhhID0gLy0oW1xcZGEtel0pL2dpLFxuXG5cdC8vIFVzZWQgYnkgalF1ZXJ5LmNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKClcblx0ZmNhbWVsQ2FzZSA9IGZ1bmN0aW9uKCBhbGwsIGxldHRlciApIHtcblx0XHRyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XG5cdH07XG5cbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XG5cdC8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWRcblx0anF1ZXJ5OiB2ZXJzaW9uLFxuXG5cdGNvbnN0cnVjdG9yOiBqUXVlcnksXG5cblx0Ly8gU3RhcnQgd2l0aCBhbiBlbXB0eSBzZWxlY3RvclxuXHRzZWxlY3RvcjogXCJcIixcblxuXHQvLyBUaGUgZGVmYXVsdCBsZW5ndGggb2YgYSBqUXVlcnkgb2JqZWN0IGlzIDBcblx0bGVuZ3RoOiAwLFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdH0sXG5cblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxuXHQvLyBHZXQgdGhlIHdob2xlIG1hdGNoZWQgZWxlbWVudCBzZXQgYXMgYSBjbGVhbiBhcnJheVxuXHRnZXQ6IGZ1bmN0aW9uKCBudW0gKSB7XG5cdFx0cmV0dXJuIG51bSAhPSBudWxsID9cblxuXHRcdFx0Ly8gUmV0dXJuIGp1c3QgdGhlIG9uZSBlbGVtZW50IGZyb20gdGhlIHNldFxuXHRcdFx0KCBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdICkgOlxuXG5cdFx0XHQvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBpbiBhIGNsZWFuIGFycmF5XG5cdFx0XHRzbGljZS5jYWxsKCB0aGlzICk7XG5cdH0sXG5cblx0Ly8gVGFrZSBhbiBhcnJheSBvZiBlbGVtZW50cyBhbmQgcHVzaCBpdCBvbnRvIHRoZSBzdGFja1xuXHQvLyAocmV0dXJuaW5nIHRoZSBuZXcgbWF0Y2hlZCBlbGVtZW50IHNldClcblx0cHVzaFN0YWNrOiBmdW5jdGlvbiggZWxlbXMgKSB7XG5cblx0XHQvLyBCdWlsZCBhIG5ldyBqUXVlcnkgbWF0Y2hlZCBlbGVtZW50IHNldFxuXHRcdHZhciByZXQgPSBqUXVlcnkubWVyZ2UoIHRoaXMuY29uc3RydWN0b3IoKSwgZWxlbXMgKTtcblxuXHRcdC8vIEFkZCB0aGUgb2xkIG9iamVjdCBvbnRvIHRoZSBzdGFjayAoYXMgYSByZWZlcmVuY2UpXG5cdFx0cmV0LnByZXZPYmplY3QgPSB0aGlzO1xuXHRcdHJldC5jb250ZXh0ID0gdGhpcy5jb250ZXh0O1xuXG5cdFx0Ly8gUmV0dXJuIHRoZSBuZXdseS1mb3JtZWQgZWxlbWVudCBzZXRcblx0XHRyZXR1cm4gcmV0O1xuXHR9LFxuXG5cdC8vIEV4ZWN1dGUgYSBjYWxsYmFjayBmb3IgZXZlcnkgZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBzZXQuXG5cdC8vIChZb3UgY2FuIHNlZWQgdGhlIGFyZ3VtZW50cyB3aXRoIGFuIGFycmF5IG9mIGFyZ3MsIGJ1dCB0aGlzIGlzXG5cdC8vIG9ubHkgdXNlZCBpbnRlcm5hbGx5Lilcblx0ZWFjaDogZnVuY3Rpb24oIGNhbGxiYWNrLCBhcmdzICkge1xuXHRcdHJldHVybiBqUXVlcnkuZWFjaCggdGhpcywgY2FsbGJhY2ssIGFyZ3MgKTtcblx0fSxcblxuXHRtYXA6IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5tYXAodGhpcywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gY2FsbGJhY2suY2FsbCggZWxlbSwgaSwgZWxlbSApO1xuXHRcdH0pKTtcblx0fSxcblxuXHRzbGljZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBzbGljZS5hcHBseSggdGhpcywgYXJndW1lbnRzICkgKTtcblx0fSxcblxuXHRmaXJzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIDAgKTtcblx0fSxcblxuXHRsYXN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggLTEgKTtcblx0fSxcblxuXHRlcTogZnVuY3Rpb24oIGkgKSB7XG5cdFx0dmFyIGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0aiA9ICtpICsgKCBpIDwgMCA/IGxlbiA6IDAgKTtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGogPj0gMCAmJiBqIDwgbGVuID8gWyB0aGlzW2pdIF0gOiBbXSApO1xuXHR9LFxuXG5cdGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHJldk9iamVjdCB8fCB0aGlzLmNvbnN0cnVjdG9yKG51bGwpO1xuXHR9LFxuXG5cdC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS5cblx0Ly8gQmVoYXZlcyBsaWtlIGFuIEFycmF5J3MgbWV0aG9kLCBub3QgbGlrZSBhIGpRdWVyeSBtZXRob2QuXG5cdHB1c2g6IHB1c2gsXG5cdHNvcnQ6IGFyci5zb3J0LFxuXHRzcGxpY2U6IGFyci5zcGxpY2Vcbn07XG5cbmpRdWVyeS5leHRlbmQgPSBqUXVlcnkuZm4uZXh0ZW5kID0gZnVuY3Rpb24oKSB7XG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbMF0gfHwge30sXG5cdFx0aSA9IDEsXG5cdFx0bGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcblx0XHRkZWVwID0gZmFsc2U7XG5cblx0Ly8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdGRlZXAgPSB0YXJnZXQ7XG5cblx0XHQvLyBza2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0XG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307XG5cdFx0aSsrO1xuXHR9XG5cblx0Ly8gSGFuZGxlIGNhc2Ugd2hlbiB0YXJnZXQgaXMgYSBzdHJpbmcgb3Igc29tZXRoaW5nIChwb3NzaWJsZSBpbiBkZWVwIGNvcHkpXG5cdGlmICggdHlwZW9mIHRhcmdldCAhPT0gXCJvYmplY3RcIiAmJiAhalF1ZXJ5LmlzRnVuY3Rpb24odGFyZ2V0KSApIHtcblx0XHR0YXJnZXQgPSB7fTtcblx0fVxuXG5cdC8vIGV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxuXHRpZiAoIGkgPT09IGxlbmd0aCApIHtcblx0XHR0YXJnZXQgPSB0aGlzO1xuXHRcdGktLTtcblx0fVxuXG5cdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdC8vIE9ubHkgZGVhbCB3aXRoIG5vbi1udWxsL3VuZGVmaW5lZCB2YWx1ZXNcblx0XHRpZiAoIChvcHRpb25zID0gYXJndW1lbnRzWyBpIF0pICE9IG51bGwgKSB7XG5cdFx0XHQvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XG5cdFx0XHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRcdHNyYyA9IHRhcmdldFsgbmFtZSBdO1xuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1sgbmFtZSBdO1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3Bcblx0XHRcdFx0aWYgKCB0YXJnZXQgPT09IGNvcHkgKSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcblx0XHRcdFx0aWYgKCBkZWVwICYmIGNvcHkgJiYgKCBqUXVlcnkuaXNQbGFpbk9iamVjdChjb3B5KSB8fCAoY29weUlzQXJyYXkgPSBqUXVlcnkuaXNBcnJheShjb3B5KSkgKSApIHtcblx0XHRcdFx0XHRpZiAoIGNvcHlJc0FycmF5ICkge1xuXHRcdFx0XHRcdFx0Y29weUlzQXJyYXkgPSBmYWxzZTtcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc0FycmF5KHNyYykgPyBzcmMgOiBbXTtcblxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBqUXVlcnkuaXNQbGFpbk9iamVjdChzcmMpID8gc3JjIDoge307XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gTmV2ZXIgbW92ZSBvcmlnaW5hbCBvYmplY3RzLCBjbG9uZSB0aGVtXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBqUXVlcnkuZXh0ZW5kKCBkZWVwLCBjbG9uZSwgY29weSApO1xuXG5cdFx0XHRcdC8vIERvbid0IGJyaW5nIGluIHVuZGVmaW5lZCB2YWx1ZXNcblx0XHRcdFx0fSBlbHNlIGlmICggY29weSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0gY29weTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0XG5cdHJldHVybiB0YXJnZXQ7XG59O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Ly8gVW5pcXVlIGZvciBlYWNoIGNvcHkgb2YgalF1ZXJ5IG9uIHRoZSBwYWdlXG5cdGV4cGFuZG86IFwialF1ZXJ5XCIgKyAoIHZlcnNpb24gKyBNYXRoLnJhbmRvbSgpICkucmVwbGFjZSggL1xcRC9nLCBcIlwiICksXG5cblx0Ly8gQXNzdW1lIGpRdWVyeSBpcyByZWFkeSB3aXRob3V0IHRoZSByZWFkeSBtb2R1bGVcblx0aXNSZWFkeTogdHJ1ZSxcblxuXHRlcnJvcjogZnVuY3Rpb24oIG1zZyApIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoIG1zZyApO1xuXHR9LFxuXG5cdG5vb3A6IGZ1bmN0aW9uKCkge30sXG5cblx0Ly8gU2VlIHRlc3QvdW5pdC9jb3JlLmpzIGZvciBkZXRhaWxzIGNvbmNlcm5pbmcgaXNGdW5jdGlvbi5cblx0Ly8gU2luY2UgdmVyc2lvbiAxLjMsIERPTSBtZXRob2RzIGFuZCBmdW5jdGlvbnMgbGlrZSBhbGVydFxuXHQvLyBhcmVuJ3Qgc3VwcG9ydGVkLiBUaGV5IHJldHVybiBmYWxzZSBvbiBJRSAoIzI5NjgpLlxuXHRpc0Z1bmN0aW9uOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHJldHVybiBqUXVlcnkudHlwZShvYmopID09PSBcImZ1bmN0aW9uXCI7XG5cdH0sXG5cblx0aXNBcnJheTogQXJyYXkuaXNBcnJheSxcblxuXHRpc1dpbmRvdzogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRyZXR1cm4gb2JqICE9IG51bGwgJiYgb2JqID09PSBvYmoud2luZG93O1xuXHR9LFxuXG5cdGlzTnVtZXJpYzogZnVuY3Rpb24oIG9iaiApIHtcblx0XHQvLyBwYXJzZUZsb2F0IE5hTnMgbnVtZXJpYy1jYXN0IGZhbHNlIHBvc2l0aXZlcyAobnVsbHx0cnVlfGZhbHNlfFwiXCIpXG5cdFx0Ly8gLi4uYnV0IG1pc2ludGVycHJldHMgbGVhZGluZy1udW1iZXIgc3RyaW5ncywgcGFydGljdWxhcmx5IGhleCBsaXRlcmFscyAoXCIweC4uLlwiKVxuXHRcdC8vIHN1YnRyYWN0aW9uIGZvcmNlcyBpbmZpbml0aWVzIHRvIE5hTlxuXHRcdHJldHVybiAhalF1ZXJ5LmlzQXJyYXkoIG9iaiApICYmIG9iaiAtIHBhcnNlRmxvYXQoIG9iaiApID49IDA7XG5cdH0sXG5cblx0aXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHQvLyBOb3QgcGxhaW4gb2JqZWN0czpcblx0XHQvLyAtIEFueSBvYmplY3Qgb3IgdmFsdWUgd2hvc2UgaW50ZXJuYWwgW1tDbGFzc11dIHByb3BlcnR5IGlzIG5vdCBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0Ly8gLSBET00gbm9kZXNcblx0XHQvLyAtIHdpbmRvd1xuXHRcdGlmICggalF1ZXJ5LnR5cGUoIG9iaiApICE9PSBcIm9iamVjdFwiIHx8IG9iai5ub2RlVHlwZSB8fCBqUXVlcnkuaXNXaW5kb3coIG9iaiApICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmICggb2JqLmNvbnN0cnVjdG9yICYmXG5cdFx0XHRcdCFoYXNPd24uY2FsbCggb2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgXCJpc1Byb3RvdHlwZU9mXCIgKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgZnVuY3Rpb24gaGFzbid0IHJldHVybmVkIGFscmVhZHksIHdlJ3JlIGNvbmZpZGVudCB0aGF0XG5cdFx0Ly8gfG9ianwgaXMgYSBwbGFpbiBvYmplY3QsIGNyZWF0ZWQgYnkge30gb3IgY29uc3RydWN0ZWQgd2l0aCBuZXcgT2JqZWN0XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIgbmFtZTtcblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0dHlwZTogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRpZiAoIG9iaiA9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIG9iaiArIFwiXCI7XG5cdFx0fVxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPCA0LjAsIGlPUyA8IDYgKGZ1bmN0aW9uaXNoIFJlZ0V4cClcblx0XHRyZXR1cm4gdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIgP1xuXHRcdFx0Y2xhc3MydHlwZVsgdG9TdHJpbmcuY2FsbChvYmopIF0gfHwgXCJvYmplY3RcIiA6XG5cdFx0XHR0eXBlb2Ygb2JqO1xuXHR9LFxuXG5cdC8vIEV2YWx1YXRlcyBhIHNjcmlwdCBpbiBhIGdsb2JhbCBjb250ZXh0XG5cdGdsb2JhbEV2YWw6IGZ1bmN0aW9uKCBjb2RlICkge1xuXHRcdHZhciBzY3JpcHQsXG5cdFx0XHRpbmRpcmVjdCA9IGV2YWw7XG5cblx0XHRjb2RlID0galF1ZXJ5LnRyaW0oIGNvZGUgKTtcblxuXHRcdGlmICggY29kZSApIHtcblx0XHRcdC8vIElmIHRoZSBjb2RlIGluY2x1ZGVzIGEgdmFsaWQsIHByb2xvZ3VlIHBvc2l0aW9uXG5cdFx0XHQvLyBzdHJpY3QgbW9kZSBwcmFnbWEsIGV4ZWN1dGUgY29kZSBieSBpbmplY3RpbmcgYVxuXHRcdFx0Ly8gc2NyaXB0IHRhZyBpbnRvIHRoZSBkb2N1bWVudC5cblx0XHRcdGlmICggY29kZS5pbmRleE9mKFwidXNlIHN0cmljdFwiKSA9PT0gMSApIHtcblx0XHRcdFx0c2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKTtcblx0XHRcdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHQgKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBPdGhlcndpc2UsIGF2b2lkIHRoZSBET00gbm9kZSBjcmVhdGlvbiwgaW5zZXJ0aW9uXG5cdFx0XHQvLyBhbmQgcmVtb3ZhbCBieSB1c2luZyBhbiBpbmRpcmVjdCBnbG9iYWwgZXZhbFxuXHRcdFx0XHRpbmRpcmVjdCggY29kZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHQvLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG5cdC8vIE1pY3Jvc29mdCBmb3Jnb3QgdG8gaHVtcCB0aGVpciB2ZW5kb3IgcHJlZml4ICgjOTU3Milcblx0Y2FtZWxDYXNlOiBmdW5jdGlvbiggc3RyaW5nICkge1xuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xuXHR9LFxuXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fSxcblxuXHQvLyBhcmdzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrLCBhcmdzICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHRcdGlzQXJyYXkgPSBpc0FycmF5bGlrZSggb2JqICk7XG5cblx0XHRpZiAoIGFyZ3MgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suYXBwbHkoIG9ialsgaSBdLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5hcHBseSggb2JqWyBpIF0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBIHNwZWNpYWwsIGZhc3QsIGNhc2UgZm9yIHRoZSBtb3N0IGNvbW1vbiB1c2Ugb2YgZWFjaFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMVxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcdFwiXCIgOlxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5bGlrZSggT2JqZWN0KGFycikgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHRyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7XG5cdH0sXG5cblx0bWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkge1xuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcblx0XHRcdGogPSAwLFxuXHRcdFx0aSA9IGZpcnN0Lmxlbmd0aDtcblxuXHRcdGZvciAoIDsgaiA8IGxlbjsgaisrICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqIF07XG5cdFx0fVxuXG5cdFx0Zmlyc3QubGVuZ3RoID0gaTtcblxuXHRcdHJldHVybiBmaXJzdDtcblx0fSxcblxuXHRncmVwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBpbnZlcnQgKSB7XG5cdFx0dmFyIGNhbGxiYWNrSW52ZXJzZSxcblx0XHRcdG1hdGNoZXMgPSBbXSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIG9ubHkgc2F2aW5nIHRoZSBpdGVtc1xuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXG5cdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRjYWxsYmFja0ludmVyc2UgPSAhY2FsbGJhY2soIGVsZW1zWyBpIF0sIGkgKTtcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcblx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBlbGVtc1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG1hdGNoZXM7XG5cdH0sXG5cblx0Ly8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoLFxuXHRcdFx0aXNBcnJheSA9IGlzQXJyYXlsaWtlKCBlbGVtcyApLFxuXHRcdFx0cmV0ID0gW107XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xuXHRcdGlmICggaXNBcnJheSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEdvIHRocm91Z2ggZXZlcnkga2V5IG9uIHRoZSBvYmplY3QsXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRyZXR1cm4gY29uY2F0LmFwcGx5KCBbXSwgcmV0ICk7XG5cdH0sXG5cblx0Ly8gQSBnbG9iYWwgR1VJRCBjb3VudGVyIGZvciBvYmplY3RzXG5cdGd1aWQ6IDEsXG5cblx0Ly8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG5cdC8vIGFyZ3VtZW50cy5cblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0XHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdFx0Y29udGV4dCA9IGZuO1xuXHRcdFx0Zm4gPSB0bXA7XG5cdFx0fVxuXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0XHQvLyB0aGlzIHRocm93cyBhIFR5cGVFcnJvciwgYnV0IHdlIHdpbGwganVzdCByZXR1cm4gdW5kZWZpbmVkLlxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCBmbiApICkge1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBTaW11bGF0ZWQgYmluZFxuXHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0XHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XG5cdFx0fTtcblxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRcdHByb3h5Lmd1aWQgPSBmbi5ndWlkID0gZm4uZ3VpZCB8fCBqUXVlcnkuZ3VpZCsrO1xuXG5cdFx0cmV0dXJuIHByb3h5O1xuXHR9LFxuXG5cdG5vdzogRGF0ZS5ub3csXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0pO1xuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvclwiLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oaSwgbmFtZSkge1xuXHRjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbn0pO1xuXG5mdW5jdGlvbiBpc0FycmF5bGlrZSggb2JqICkge1xuXHR2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHR0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xuXG5cdGlmICggdHlwZSA9PT0gXCJmdW5jdGlvblwiIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBvYmoubm9kZVR5cGUgPT09IDEgJiYgbGVuZ3RoICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcblx0XHR0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKCBsZW5ndGggLSAxICkgaW4gb2JqO1xufVxudmFyIFNpenpsZSA9XG4vKiFcbiAqIFNpenpsZSBDU1MgU2VsZWN0b3IgRW5naW5lIHYxLjEwLjE5XG4gKiBodHRwOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCAyMDEzIGpRdWVyeSBGb3VuZGF0aW9uLCBJbmMuIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cDovL2pxdWVyeS5vcmcvbGljZW5zZVxuICpcbiAqIERhdGU6IDIwMTQtMDQtMThcbiAqL1xuKGZ1bmN0aW9uKCB3aW5kb3cgKSB7XG5cbnZhciBpLFxuXHRzdXBwb3J0LFxuXHRFeHByLFxuXHRnZXRUZXh0LFxuXHRpc1hNTCxcblx0dG9rZW5pemUsXG5cdGNvbXBpbGUsXG5cdHNlbGVjdCxcblx0b3V0ZXJtb3N0Q29udGV4dCxcblx0c29ydElucHV0LFxuXHRoYXNEdXBsaWNhdGUsXG5cblx0Ly8gTG9jYWwgZG9jdW1lbnQgdmFyc1xuXHRzZXREb2N1bWVudCxcblx0ZG9jdW1lbnQsXG5cdGRvY0VsZW0sXG5cdGRvY3VtZW50SXNIVE1MLFxuXHRyYnVnZ3lRU0EsXG5cdHJidWdneU1hdGNoZXMsXG5cdG1hdGNoZXMsXG5cdGNvbnRhaW5zLFxuXG5cdC8vIEluc3RhbmNlLXNwZWNpZmljIGRhdGFcblx0ZXhwYW5kbyA9IFwic2l6emxlXCIgKyAtKG5ldyBEYXRlKCkpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0c29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0Ly8gR2VuZXJhbC1wdXJwb3NlIGNvbnN0YW50c1xuXHRzdHJ1bmRlZmluZWQgPSB0eXBlb2YgdW5kZWZpbmVkLFxuXHRNQVhfTkVHQVRJVkUgPSAxIDw8IDMxLFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcblx0YXJyID0gW10sXG5cdHBvcCA9IGFyci5wb3AsXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXG5cdHB1c2ggPSBhcnIucHVzaCxcblx0c2xpY2UgPSBhcnIuc2xpY2UsXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBpZiB3ZSBjYW4ndCB1c2UgYSBuYXRpdmUgb25lXG5cdGluZGV4T2YgPSBhcnIuaW5kZXhPZiB8fCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGlmICggdGhpc1tpXSA9PT0gZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAtMTtcblx0fSxcblxuXHRib29sZWFucyA9IFwiY2hlY2tlZHxzZWxlY3RlZHxhc3luY3xhdXRvZm9jdXN8YXV0b3BsYXl8Y29udHJvbHN8ZGVmZXJ8ZGlzYWJsZWR8aGlkZGVufGlzbWFwfGxvb3B8bXVsdGlwbGV8b3BlbnxyZWFkb25seXxyZXF1aXJlZHxzY29wZWRcIixcblxuXHQvLyBSZWd1bGFyIGV4cHJlc3Npb25zXG5cblx0Ly8gV2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc2VsZWN0b3JzLyN3aGl0ZXNwYWNlXG5cdHdoaXRlc3BhY2UgPSBcIltcXFxceDIwXFxcXHRcXFxcclxcXFxuXFxcXGZdXCIsXG5cdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc3ludGF4LyNjaGFyYWN0ZXJzXG5cdGNoYXJhY3RlckVuY29kaW5nID0gXCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXFxceDAwLVxcXFx4YTBdKStcIixcblxuXHQvLyBMb29zZWx5IG1vZGVsZWQgb24gQ1NTIGlkZW50aWZpZXIgY2hhcmFjdGVyc1xuXHQvLyBBbiB1bnF1b3RlZCB2YWx1ZSBzaG91bGQgYmUgYSBDU1MgaWRlbnRpZmllciBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHQvLyBQcm9wZXIgc3ludGF4OiBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyMS9zeW5kYXRhLmh0bWwjdmFsdWUtZGVmLWlkZW50aWZpZXJcblx0aWRlbnRpZmllciA9IGNoYXJhY3RlckVuY29kaW5nLnJlcGxhY2UoIFwid1wiLCBcIncjXCIgKSxcblxuXHQvLyBBdHRyaWJ1dGUgc2VsZWN0b3JzOiBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2F0dHJpYnV0ZS1zZWxlY3RvcnNcblx0YXR0cmlidXRlcyA9IFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIiooXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKSg/OlwiICsgd2hpdGVzcGFjZSArXG5cdFx0Ly8gT3BlcmF0b3IgKGNhcHR1cmUgMilcblx0XHRcIiooWypeJHwhfl0/PSlcIiArIHdoaXRlc3BhY2UgK1xuXHRcdC8vIFwiQXR0cmlidXRlIHZhbHVlcyBtdXN0IGJlIENTUyBpZGVudGlmaWVycyBbY2FwdHVyZSA1XSBvciBzdHJpbmdzIFtjYXB0dXJlIDMgb3IgY2FwdHVyZSA0XVwiXG5cdFx0XCIqKD86JygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwifChcIiArIGlkZW50aWZpZXIgKyBcIikpfClcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiKlxcXFxdXCIsXG5cblx0cHNldWRvcyA9IFwiOihcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpKD86XFxcXCgoXCIgK1xuXHRcdC8vIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHNlbGVjdG9ycyBuZWVkaW5nIHRva2VuaXplIGluIHRoZSBwcmVGaWx0ZXIsIHByZWZlciBhcmd1bWVudHM6XG5cdFx0Ly8gMS4gcXVvdGVkIChjYXB0dXJlIDM7IGNhcHR1cmUgNCBvciBjYXB0dXJlIDUpXG5cdFx0XCIoJygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwiKXxcIiArXG5cdFx0Ly8gMi4gc2ltcGxlIChjYXB0dXJlIDYpXG5cdFx0XCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKVtcXFxcXV18XCIgKyBhdHRyaWJ1dGVzICsgXCIpKil8XCIgK1xuXHRcdC8vIDMuIGFueXRoaW5nIGVsc2UgKGNhcHR1cmUgMilcblx0XHRcIi4qXCIgK1xuXHRcdFwiKVxcXFwpfClcIixcblxuXHQvLyBMZWFkaW5nIGFuZCBub24tZXNjYXBlZCB0cmFpbGluZyB3aGl0ZXNwYWNlLCBjYXB0dXJpbmcgc29tZSBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHByZWNlZGluZyB0aGUgbGF0dGVyXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICsgd2hpdGVzcGFjZSArIFwiKyRcIiwgXCJnXCIgKSxcblxuXHRyY29tbWEgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiosXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmNvbWJpbmF0b3JzID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFs+K35dfFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgd2hpdGVzcGFjZSArIFwiKlwiICksXG5cblx0cmF0dHJpYnV0ZVF1b3RlcyA9IG5ldyBSZWdFeHAoIFwiPVwiICsgd2hpdGVzcGFjZSArIFwiKihbXlxcXFxdJ1xcXCJdKj8pXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXF1cIiwgXCJnXCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpXCIgKSxcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiVEFHXCI6IG5ldyBSZWdFeHAoIFwiXihcIiArIGNoYXJhY3RlckVuY29kaW5nLnJlcGxhY2UoIFwid1wiLCBcIncqXCIgKSArIFwiKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cdFx0Ly8gRm9yIHVzZSBpbiBsaWJyYXJpZXMgaW1wbGVtZW50aW5nIC5pcygpXG5cdFx0Ly8gV2UgdXNlIHRoaXMgZm9yIFBPUyBtYXRjaGluZyBpbiBgc2VsZWN0YFxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXHRyZXNjYXBlID0gLyd8XFxcXC9nLFxuXG5cdC8vIENTUyBlc2NhcGVzIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXChbXFxcXGRhLWZdezEsNn1cIiArIHdoaXRlc3BhY2UgKyBcIj98KFwiICsgd2hpdGVzcGFjZSArIFwiKXwuKVwiLCBcImlnXCIgKSxcblx0ZnVuZXNjYXBlID0gZnVuY3Rpb24oIF8sIGVzY2FwZWQsIGVzY2FwZWRXaGl0ZXNwYWNlICkge1xuXHRcdHZhciBoaWdoID0gXCIweFwiICsgZXNjYXBlZCAtIDB4MTAwMDA7XG5cdFx0Ly8gTmFOIG1lYW5zIG5vbi1jb2RlcG9pbnRcblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI0XG5cdFx0Ly8gV29ya2Fyb3VuZCBlcnJvbmVvdXMgbnVtZXJpYyBpbnRlcnByZXRhdGlvbiBvZiArXCIweFwiXG5cdFx0cmV0dXJuIGhpZ2ggIT09IGhpZ2ggfHwgZXNjYXBlZFdoaXRlc3BhY2UgP1xuXHRcdFx0ZXNjYXBlZCA6XG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdC8vIEJNUCBjb2RlcG9pbnRcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCArIDB4MTAwMDAgKSA6XG5cdFx0XHRcdC8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKVxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fTtcblxuLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0IClcbnRyeSB7XG5cdHB1c2guYXBwbHkoXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXG5cdC8vIERldGVjdCBzaWxlbnRseSBmYWlsaW5nIHB1c2guYXBwbHlcblx0YXJyWyBwcmVmZXJyZWREb2MuY2hpbGROb2Rlcy5sZW5ndGggXS5ub2RlVHlwZTtcbn0gY2F0Y2ggKCBlICkge1xuXHRwdXNoID0geyBhcHBseTogYXJyLmxlbmd0aCA/XG5cblx0XHQvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHB1c2hfbmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoZWxzKSApO1xuXHRcdH0gOlxuXG5cdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHR2YXIgaiA9IHRhcmdldC5sZW5ndGgsXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0Ly8gQ2FuJ3QgdHJ1c3QgTm9kZUxpc3QubGVuZ3RoXG5cdFx0XHR3aGlsZSAoICh0YXJnZXRbaisrXSA9IGVsc1tpKytdKSApIHt9XG5cdFx0XHR0YXJnZXQubGVuZ3RoID0gaiAtIDE7XG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBTaXp6bGUoIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgbWF0Y2gsIGVsZW0sIG0sIG5vZGVUeXBlLFxuXHRcdC8vIFFTQSB2YXJzXG5cdFx0aSwgZ3JvdXBzLCBvbGQsIG5pZCwgbmV3Q29udGV4dCwgbmV3U2VsZWN0b3I7XG5cblx0aWYgKCAoIGNvbnRleHQgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IHByZWZlcnJlZERvYyApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cblx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdGlmICggIXNlbGVjdG9yIHx8IHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gcmVzdWx0cztcblx0fVxuXG5cdGlmICggKG5vZGVUeXBlID0gY29udGV4dC5ub2RlVHlwZSkgIT09IDEgJiYgbm9kZVR5cGUgIT09IDkgKSB7XG5cdFx0cmV0dXJuIFtdO1xuXHR9XG5cblx0aWYgKCBkb2N1bWVudElzSFRNTCAmJiAhc2VlZCApIHtcblxuXHRcdC8vIFNob3J0Y3V0c1xuXHRcdGlmICggKG1hdGNoID0gcnF1aWNrRXhwci5leGVjKCBzZWxlY3RvciApKSApIHtcblx0XHRcdC8vIFNwZWVkLXVwOiBTaXp6bGUoXCIjSURcIilcblx0XHRcdGlmICggKG0gPSBtYXRjaFsxXSkgKSB7XG5cdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKTtcblx0XHRcdFx0XHQvLyBDaGVjayBwYXJlbnROb2RlIHRvIGNhdGNoIHdoZW4gQmxhY2tiZXJyeSA0LjYgcmV0dXJuc1xuXHRcdFx0XHRcdC8vIG5vZGVzIHRoYXQgYXJlIG5vIGxvbmdlciBpbiB0aGUgZG9jdW1lbnQgKGpRdWVyeSAjNjk2Mylcblx0XHRcdFx0XHRpZiAoIGVsZW0gJiYgZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIElFLCBPcGVyYSwgYW5kIFdlYmtpdCByZXR1cm4gaXRlbXNcblx0XHRcdFx0XHRcdC8vIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyBDb250ZXh0IGlzIG5vdCBhIGRvY3VtZW50XG5cdFx0XHRcdFx0aWYgKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgJiYgKGVsZW0gPSBjb250ZXh0Lm93bmVyRG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgJiZcblx0XHRcdFx0XHRcdGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICkgJiYgZWxlbS5pZCA9PT0gbSApIHtcblx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFNwZWVkLXVwOiBTaXp6bGUoXCJUQUdcIilcblx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWzJdICkge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCBzZWxlY3RvciApICk7XG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXG5cdFx0XHQvLyBTcGVlZC11cDogU2l6emxlKFwiLkNMQVNTXCIpXG5cdFx0XHR9IGVsc2UgaWYgKCAobSA9IG1hdGNoWzNdKSAmJiBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICkge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIG0gKSApO1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBRU0EgcGF0aFxuXHRcdGlmICggc3VwcG9ydC5xc2EgJiYgKCFyYnVnZ3lRU0EgfHwgIXJidWdneVFTQS50ZXN0KCBzZWxlY3RvciApKSApIHtcblx0XHRcdG5pZCA9IG9sZCA9IGV4cGFuZG87XG5cdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcblx0XHRcdG5ld1NlbGVjdG9yID0gbm9kZVR5cGUgPT09IDkgJiYgc2VsZWN0b3I7XG5cblx0XHRcdC8vIHFTQSB3b3JrcyBzdHJhbmdlbHkgb24gRWxlbWVudC1yb290ZWQgcXVlcmllc1xuXHRcdFx0Ly8gV2UgY2FuIHdvcmsgYXJvdW5kIHRoaXMgYnkgc3BlY2lmeWluZyBhbiBleHRyYSBJRCBvbiB0aGUgcm9vdFxuXHRcdFx0Ly8gYW5kIHdvcmtpbmcgdXAgZnJvbSB0aGVyZSAoVGhhbmtzIHRvIEFuZHJldyBEdXBvbnQgZm9yIHRoZSB0ZWNobmlxdWUpXG5cdFx0XHQvLyBJRSA4IGRvZXNuJ3Qgd29yayBvbiBvYmplY3QgZWxlbWVudHNcblx0XHRcdGlmICggbm9kZVR5cGUgPT09IDEgJiYgY29udGV4dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9PSBcIm9iamVjdFwiICkge1xuXHRcdFx0XHRncm91cHMgPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblxuXHRcdFx0XHRpZiAoIChvbGQgPSBjb250ZXh0LmdldEF0dHJpYnV0ZShcImlkXCIpKSApIHtcblx0XHRcdFx0XHRuaWQgPSBvbGQucmVwbGFjZSggcmVzY2FwZSwgXCJcXFxcJCZcIiApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRleHQuc2V0QXR0cmlidXRlKCBcImlkXCIsIG5pZCApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5pZCA9IFwiW2lkPSdcIiArIG5pZCArIFwiJ10gXCI7XG5cblx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGdyb3Vwc1tpXSA9IG5pZCArIHRvU2VsZWN0b3IoIGdyb3Vwc1tpXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG5ld0NvbnRleHQgPSByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0O1xuXHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKFwiLFwiKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBuZXdTZWxlY3RvciApIHtcblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0bmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0fSBjYXRjaChxc2FFcnJvcikge1xuXHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdGlmICggIW9sZCApIHtcblx0XHRcdFx0XHRcdGNvbnRleHQucmVtb3ZlQXR0cmlidXRlKFwiaWRcIik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtGdW5jdGlvbihzdHJpbmcsIE9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cdFx0Ly8gVXNlIChrZXkgKyBcIiBcIikgdG8gYXZvaWQgY29sbGlzaW9uIHdpdGggbmF0aXZlIHByb3RvdHlwZSBwcm9wZXJ0aWVzIChzZWUgSXNzdWUgIzE1Nylcblx0XHRpZiAoIGtleXMucHVzaCgga2V5ICsgXCIgXCIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7XG5cdFx0XHQvLyBPbmx5IGtlZXAgdGhlIG1vc3QgcmVjZW50IGVudHJpZXNcblx0XHRcdGRlbGV0ZSBjYWNoZVsga2V5cy5zaGlmdCgpIF07XG5cdFx0fVxuXHRcdHJldHVybiAoY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZGl2IGFuZCBleHBlY3RzIGEgYm9vbGVhbiByZXN1bHRcbiAqL1xuZnVuY3Rpb24gYXNzZXJ0KCBmbiApIHtcblx0dmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG5cblx0dHJ5IHtcblx0XHRyZXR1cm4gISFmbiggZGl2ICk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH0gZmluYWxseSB7XG5cdFx0Ly8gUmVtb3ZlIGZyb20gaXRzIHBhcmVudCBieSBkZWZhdWx0XG5cdFx0aWYgKCBkaXYucGFyZW50Tm9kZSApIHtcblx0XHRcdGRpdi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBkaXYgKTtcblx0XHR9XG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcblx0XHRkaXYgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xuICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgbWV0aG9kIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKi9cbmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7XG5cdHZhciBhcnIgPSBhdHRycy5zcGxpdChcInxcIiksXG5cdFx0aSA9IGF0dHJzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRFeHByLmF0dHJIYW5kbGVbIGFycltpXSBdID0gaGFuZGxlcjtcblx0fVxufVxuXG4vKipcbiAqIENoZWNrcyBkb2N1bWVudCBvcmRlciBvZiB0d28gc2libGluZ3NcbiAqIEBwYXJhbSB7RWxlbWVudH0gYVxuICogQHBhcmFtIHtFbGVtZW50fSBiXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBSZXR1cm5zIGxlc3MgdGhhbiAwIGlmIGEgcHJlY2VkZXMgYiwgZ3JlYXRlciB0aGFuIDAgaWYgYSBmb2xsb3dzIGJcbiAqL1xuZnVuY3Rpb24gc2libGluZ0NoZWNrKCBhLCBiICkge1xuXHR2YXIgY3VyID0gYiAmJiBhLFxuXHRcdGRpZmYgPSBjdXIgJiYgYS5ub2RlVHlwZSA9PT0gMSAmJiBiLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHQoIH5iLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApIC1cblx0XHRcdCggfmEuc291cmNlSW5kZXggfHwgTUFYX05FR0FUSVZFICk7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKGN1ciA9IGN1ci5uZXh0U2libGluZykgKSB7XG5cdFx0XHRpZiAoIGN1ciA9PT0gYiApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBhID8gMSA6IC0xO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBidXR0b25zXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVCdXR0b25Qc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gKG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiKSAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBwb3NpdGlvbmFsc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZm4gKSB7XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIGFyZ3VtZW50ICkge1xuXHRcdGFyZ3VtZW50ID0gK2FyZ3VtZW50O1xuXHRcdHJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHR2YXIgaixcblx0XHRcdFx0bWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSxcblx0XHRcdFx0aSA9IG1hdGNoSW5kZXhlcy5sZW5ndGg7XG5cblx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlc1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggc2VlZFsgKGogPSBtYXRjaEluZGV4ZXNbaV0pIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFtqXSA9ICEobWF0Y2hlc1tqXSA9IHNlZWRbal0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBhIG5vZGUgZm9yIHZhbGlkaXR5IGFzIGEgU2l6emxlIGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RWxlbWVudHxPYmplY3R8Qm9vbGVhbn0gVGhlIGlucHV0IG5vZGUgaWYgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGEgZmFsc3kgdmFsdWVcbiAqL1xuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XG5cdHJldHVybiBjb250ZXh0ICYmIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBzdHJ1bmRlZmluZWQgJiYgY29udGV4dDtcbn1cblxuLy8gRXhwb3NlIHN1cHBvcnQgdmFycyBmb3IgY29udmVuaWVuY2VcbnN1cHBvcnQgPSBTaXp6bGUuc3VwcG9ydCA9IHt9O1xuXG4vKipcbiAqIERldGVjdHMgWE1MIG5vZGVzXG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBlbGVtIEFuIGVsZW1lbnQgb3IgYSBkb2N1bWVudFxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWZmIGVsZW0gaXMgYSBub24tSFRNTCBYTUwgbm9kZVxuICovXG5pc1hNTCA9IFNpenpsZS5pc1hNTCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHQvLyBkb2N1bWVudEVsZW1lbnQgaXMgdmVyaWZpZWQgZm9yIGNhc2VzIHdoZXJlIGl0IGRvZXNuJ3QgeWV0IGV4aXN0XG5cdC8vIChzdWNoIGFzIGxvYWRpbmcgaWZyYW1lcyBpbiBJRSAtICM0ODMzKVxuXHR2YXIgZG9jdW1lbnRFbGVtZW50ID0gZWxlbSAmJiAoZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0pLmRvY3VtZW50RWxlbWVudDtcblx0cmV0dXJuIGRvY3VtZW50RWxlbWVudCA/IGRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gXCJIVE1MXCIgOiBmYWxzZTtcbn07XG5cbi8qKlxuICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBbZG9jXSBBbiBlbGVtZW50IG9yIGRvY3VtZW50IG9iamVjdCB0byB1c2UgdG8gc2V0IHRoZSBkb2N1bWVudFxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxuICovXG5zZXREb2N1bWVudCA9IFNpenpsZS5zZXREb2N1bWVudCA9IGZ1bmN0aW9uKCBub2RlICkge1xuXHR2YXIgaGFzQ29tcGFyZSxcblx0XHRkb2MgPSBub2RlID8gbm9kZS5vd25lckRvY3VtZW50IHx8IG5vZGUgOiBwcmVmZXJyZWREb2MsXG5cdFx0cGFyZW50ID0gZG9jLmRlZmF1bHRWaWV3O1xuXG5cdC8vIElmIG5vIGRvY3VtZW50IGFuZCBkb2N1bWVudEVsZW1lbnQgaXMgYXZhaWxhYmxlLCByZXR1cm5cblx0aWYgKCBkb2MgPT09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHQvLyBTZXQgb3VyIGRvY3VtZW50XG5cdGRvY3VtZW50ID0gZG9jO1xuXHRkb2NFbGVtID0gZG9jLmRvY3VtZW50RWxlbWVudDtcblxuXHQvLyBTdXBwb3J0IHRlc3RzXG5cdGRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2MgKTtcblxuXHQvLyBTdXBwb3J0OiBJRT44XG5cdC8vIElmIGlmcmFtZSBkb2N1bWVudCBpcyBhc3NpZ25lZCB0byBcImRvY3VtZW50XCIgdmFyaWFibGUgYW5kIGlmIGlmcmFtZSBoYXMgYmVlbiByZWxvYWRlZCxcblx0Ly8gSUUgd2lsbCB0aHJvdyBcInBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBhY2Nlc3NpbmcgXCJkb2N1bWVudFwiIHZhcmlhYmxlLCBzZWUgalF1ZXJ5ICMxMzkzNlxuXHQvLyBJRTYtOCBkbyBub3Qgc3VwcG9ydCB0aGUgZGVmYXVsdFZpZXcgcHJvcGVydHkgc28gcGFyZW50IHdpbGwgYmUgdW5kZWZpbmVkXG5cdGlmICggcGFyZW50ICYmIHBhcmVudCAhPT0gcGFyZW50LnRvcCApIHtcblx0XHQvLyBJRTExIGRvZXMgbm90IGhhdmUgYXR0YWNoRXZlbnQsIHNvIGFsbCBtdXN0IHN1ZmZlclxuXHRcdGlmICggcGFyZW50LmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNldERvY3VtZW50KCk7XG5cdFx0XHR9LCBmYWxzZSApO1xuXHRcdH0gZWxzZSBpZiAoIHBhcmVudC5hdHRhY2hFdmVudCApIHtcblx0XHRcdHBhcmVudC5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2V0RG9jdW1lbnQoKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qIEF0dHJpYnV0ZXNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFN1cHBvcnQ6IElFPDhcblx0Ly8gVmVyaWZ5IHRoYXQgZ2V0QXR0cmlidXRlIHJlYWxseSByZXR1cm5zIGF0dHJpYnV0ZXMgYW5kIG5vdCBwcm9wZXJ0aWVzIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxuXHRzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0cmV0dXJuICFkaXYuZ2V0QXR0cmlidXRlKFwiY2xhc3NOYW1lXCIpO1xuXHR9KTtcblxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikgcmV0dXJucyBvbmx5IGVsZW1lbnRzXG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuYXBwZW5kQ2hpbGQoIGRvYy5jcmVhdGVDb21tZW50KFwiXCIpICk7XG5cdFx0cmV0dXJuICFkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpLmxlbmd0aDtcblx0fSk7XG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSBjYW4gYmUgdHJ1c3RlZFxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvYy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICkgJiYgYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmlubmVySFRNTCA9IFwiPGRpdiBjbGFzcz0nYSc+PC9kaXY+PGRpdiBjbGFzcz0nYSBpJz48L2Rpdj5cIjtcblxuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaTw0XG5cdFx0Ly8gQ2F0Y2ggY2xhc3Mgb3Zlci1jYWNoaW5nXG5cdFx0ZGl2LmZpcnN0Q2hpbGQuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0Ly8gU3VwcG9ydDogT3BlcmE8MTBcblx0XHQvLyBDYXRjaCBnRUJDTiBmYWlsdXJlIHRvIGZpbmQgbm9uLWxlYWRpbmcgY2xhc3Nlc1xuXHRcdHJldHVybiBkaXYuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShcImlcIikubGVuZ3RoID09PSAyO1xuXHR9KTtcblxuXHQvLyBTdXBwb3J0OiBJRTwxMFxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50QnlJZCByZXR1cm5zIGVsZW1lbnRzIGJ5IG5hbWVcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbWF0aWNhbGx5LXNldCBuYW1lcyxcblx0Ly8gc28gdXNlIGEgcm91bmRhYm91dCBnZXRFbGVtZW50c0J5TmFtZSB0ZXN0XG5cdHN1cHBvcnQuZ2V0QnlJZCA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlkID0gZXhwYW5kbztcblx0XHRyZXR1cm4gIWRvYy5nZXRFbGVtZW50c0J5TmFtZSB8fCAhZG9jLmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xuXHR9KTtcblxuXHQvLyBJRCBmaW5kIGFuZCBmaWx0ZXJcblx0aWYgKCBzdXBwb3J0LmdldEJ5SWQgKSB7XG5cdFx0RXhwci5maW5kW1wiSURcIl0gPSBmdW5jdGlvbiggaWQsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBzdHJ1bmRlZmluZWQgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblx0XHRcdFx0Ly8gQ2hlY2sgcGFyZW50Tm9kZSB0byBjYXRjaCB3aGVuIEJsYWNrYmVycnkgNC42IHJldHVybnNcblx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAjNjk2M1xuXHRcdFx0XHRyZXR1cm4gbSAmJiBtLnBhcmVudE5vZGUgPyBbIG0gXSA6IFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJpZFwiKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdC8vIFN1cHBvcnQ6IElFNi83XG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxuXHRcdGRlbGV0ZSBFeHByLmZpbmRbXCJJRFwiXTtcblxuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSAgZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gc3RydW5kZWZpbmVkICYmIGVsZW0uZ2V0QXR0cmlidXRlTm9kZShcImlkXCIpO1xuXHRcdFx0XHRyZXR1cm4gbm9kZSAmJiBub2RlLnZhbHVlID09PSBhdHRySWQ7XG5cdFx0XHR9O1xuXHRcdH07XG5cdH1cblxuXHQvLyBUYWdcblx0RXhwci5maW5kW1wiVEFHXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA/XG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0dG1wID0gW10sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIEZpbHRlciBvdXQgcG9zc2libGUgY29tbWVudHNcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0fTtcblxuXHQvLyBDbGFzc1xuXHRFeHByLmZpbmRbXCJDTEFTU1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkge1xuXHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gc3RydW5kZWZpbmVkICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggY2xhc3NOYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3Jcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcblxuXHQvLyBtYXRjaGVzU2VsZWN0b3IoOmFjdGl2ZSkgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKElFOS9PcGVyYSAxMS41KVxuXHRyYnVnZ3lNYXRjaGVzID0gW107XG5cblx0Ly8gcVNhKDpmb2N1cykgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKENocm9tZSAyMSlcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXG5cdC8vIHdoZW5ldmVyIGBkb2N1bWVudC5hY3RpdmVFbGVtZW50YCBpcyBhY2Nlc3NlZCBvbiBhbiBpZnJhbWVcblx0Ly8gU28sIHdlIGFsbG93IDpmb2N1cyB0byBwYXNzIHRocm91Z2ggUVNBIGFsbCB0aGUgdGltZSB0byBhdm9pZCB0aGUgSUUgZXJyb3Jcblx0Ly8gU2VlIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2MucXVlcnlTZWxlY3RvckFsbCApKSApIHtcblx0XHQvLyBCdWlsZCBRU0EgcmVnZXhcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBTZWxlY3QgaXMgc2V0IHRvIGVtcHR5IHN0cmluZyBvbiBwdXJwb3NlXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcblx0XHRcdC8vIHNldHRpbmcgYSBib29sZWFuIGNvbnRlbnQgYXR0cmlidXRlLFxuXHRcdFx0Ly8gc2luY2UgaXRzIHByZXNlbmNlIHNob3VsZCBiZSBlbm91Z2hcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XG5cdFx0XHRkaXYuaW5uZXJIVE1MID0gXCI8c2VsZWN0IG1zYWxsb3djbGlwPScnPjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+XCI7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTZcblx0XHRcdC8vIE5vdGhpbmcgc2hvdWxkIGJlIHNlbGVjdGVkIHdoZW4gZW1wdHkgc3RyaW5ncyBmb2xsb3cgXj0gb3IgJD0gb3IgKj1cblx0XHRcdC8vIFRoZSB0ZXN0IGF0dHJpYnV0ZSBtdXN0IGJlIHVua25vd24gaW4gT3BlcmEgYnV0IFwic2FmZVwiIGZvciBXaW5SVFxuXHRcdFx0Ly8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2hoNDY1Mzg4LmFzcHgjYXR0cmlidXRlX3NlY3Rpb25cblx0XHRcdGlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbXNhbGxvd2NsaXBePScnXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlsqXiRdPVwiICsgd2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGFuZCBcInZhbHVlXCIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseVxuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbc2VsZWN0ZWRdXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIiooPzp2YWx1ZXxcIiArIGJvb2xlYW5zICsgXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gV2Via2l0L09wZXJhIC0gOmNoZWNrZWQgc2hvdWxkIHJldHVybiBzZWxlY3RlZCBvcHRpb24gZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6Y2hlY2tlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwiOmNoZWNrZWRcIik7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIFN1cHBvcnQ6IFdpbmRvd3MgOCBOYXRpdmUgQXBwc1xuXHRcdFx0Ly8gVGhlIHR5cGUgYW5kIG5hbWUgYXR0cmlidXRlcyBhcmUgcmVzdHJpY3RlZCBkdXJpbmcgLmlubmVySFRNTCBhc3NpZ25tZW50XG5cdFx0XHR2YXIgaW5wdXQgPSBkb2MuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gRW5mb3JjZSBjYXNlLXNlbnNpdGl2aXR5IG9mIG5hbWUgYXR0cmlidXRlXG5cdFx0XHRpZiAoIGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW25hbWU9ZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqWypeJHwhfl0/PVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZGIDMuNSAtIDplbmFibGVkLzpkaXNhYmxlZCBhbmQgaGlkZGVuIGVsZW1lbnRzIChoaWRkZW4gZWxlbWVudHMgYXJlIHN0aWxsIGVuYWJsZWQpXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6ZW5hYmxlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3BlcmEgMTAtMTEgZG9lcyBub3QgdGhyb3cgb24gcG9zdC1jb21tYSBpbnZhbGlkIHBzZXVkb3Ncblx0XHRcdGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiKiw6eFwiKTtcblx0XHRcdHJidWdneVFTQS5wdXNoKFwiLC4qOlwiKTtcblx0XHR9KTtcblx0fVxuXG5cdGlmICggKHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yID0gcm5hdGl2ZS50ZXN0KCAobWF0Y2hlcyA9IGRvY0VsZW0ubWF0Y2hlcyB8fFxuXHRcdGRvY0VsZW0ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tb3pNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm9NYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1zTWF0Y2hlc1NlbGVjdG9yKSApKSApIHtcblxuXHRcdGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXG5cdFx0XHQvLyBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlIChJRSA5KVxuXHRcdFx0c3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCA9IG1hdGNoZXMuY2FsbCggZGl2LCBcImRpdlwiICk7XG5cblx0XHRcdC8vIFRoaXMgc2hvdWxkIGZhaWwgd2l0aCBhbiBleGNlcHRpb25cblx0XHRcdC8vIEdlY2tvIGRvZXMgbm90IGVycm9yLCByZXR1cm5zIGZhbHNlIGluc3RlYWRcblx0XHRcdG1hdGNoZXMuY2FsbCggZGl2LCBcIltzIT0nJ106eFwiICk7XG5cdFx0XHRyYnVnZ3lNYXRjaGVzLnB1c2goIFwiIT1cIiwgcHNldWRvcyApO1xuXHRcdH0pO1xuXHR9XG5cblx0cmJ1Z2d5UVNBID0gcmJ1Z2d5UVNBLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lRU0Euam9pbihcInxcIikgKTtcblx0cmJ1Z2d5TWF0Y2hlcyA9IHJidWdneU1hdGNoZXMubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneU1hdGNoZXMuam9pbihcInxcIikgKTtcblxuXHQvKiBDb250YWluc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGhhc0NvbXBhcmUgPSBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29tcGFyZURvY3VtZW50UG9zaXRpb24gKTtcblxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcblx0Ly8gUHVycG9zZWZ1bGx5IGRvZXMgbm90IGltcGxlbWVudCBpbmNsdXNpdmUgZGVzY2VuZGVudFxuXHQvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZlxuXHRjb250YWlucyA9IGhhc0NvbXBhcmUgfHwgcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbnRhaW5zICkgP1xuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0dmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSxcblx0XHRcdFx0YnVwID0gYiAmJiBiLnBhcmVudE5vZGU7XG5cdFx0XHRyZXR1cm4gYSA9PT0gYnVwIHx8ICEhKCBidXAgJiYgYnVwLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0YWRvd24uY29udGFpbnMgP1xuXHRcdFx0XHRcdGFkb3duLmNvbnRhaW5zKCBidXAgKSA6XG5cdFx0XHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAmJiBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBidXAgKSAmIDE2XG5cdFx0XHQpKTtcblx0XHR9IDpcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdGlmICggYiApIHtcblx0XHRcdFx0d2hpbGUgKCAoYiA9IGIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBiID09PSBhICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHQvKiBTb3J0aW5nXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBEb2N1bWVudCBvcmRlciBzb3J0aW5nXG5cdHNvcnRPcmRlciA9IGhhc0NvbXBhcmUgP1xuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdC8vIEZsYWcgZm9yIGR1cGxpY2F0ZSByZW1vdmFsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdC8vIFNvcnQgb24gbWV0aG9kIGV4aXN0ZW5jZSBpZiBvbmx5IG9uZSBpbnB1dCBoYXMgY29tcGFyZURvY3VtZW50UG9zaXRpb25cblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XG5cdFx0aWYgKCBjb21wYXJlICkge1xuXHRcdFx0cmV0dXJuIGNvbXBhcmU7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsY3VsYXRlIHBvc2l0aW9uIGlmIGJvdGggaW5wdXRzIGJlbG9uZyB0byB0aGUgc2FtZSBkb2N1bWVudFxuXHRcdGNvbXBhcmUgPSAoIGEub3duZXJEb2N1bWVudCB8fCBhICkgPT09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XG5cdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcblx0XHRcdDE7XG5cblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoIXN1cHBvcnQuc29ydERldGFjaGVkICYmIGIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGEgKSA9PT0gY29tcGFyZSkgKSB7XG5cblx0XHRcdC8vIENob29zZSB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IGlzIHJlbGF0ZWQgdG8gb3VyIHByZWZlcnJlZCBkb2N1bWVudFxuXHRcdFx0aWYgKCBhID09PSBkb2MgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBiID09PSBkb2MgfHwgYi5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBiKSApIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1haW50YWluIG9yaWdpbmFsIG9yZGVyXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cblx0XHRcdFx0KCBpbmRleE9mLmNhbGwoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZi5jYWxsKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF1cCA9IGEucGFyZW50Tm9kZSxcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcblx0XHRcdGFwID0gWyBhIF0sXG5cdFx0XHRicCA9IFsgYiBdO1xuXG5cdFx0Ly8gUGFyZW50bGVzcyBub2RlcyBhcmUgZWl0aGVyIGRvY3VtZW50cyBvciBkaXNjb25uZWN0ZWRcblx0XHRpZiAoICFhdXAgfHwgIWJ1cCApIHtcblx0XHRcdHJldHVybiBhID09PSBkb2MgPyAtMSA6XG5cdFx0XHRcdGIgPT09IGRvYyA/IDEgOlxuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YuY2FsbCggc29ydElucHV0LCBhICkgLSBpbmRleE9mLmNhbGwoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXG5cdFx0Ly8gSWYgdGhlIG5vZGVzIGFyZSBzaWJsaW5ncywgd2UgY2FuIGRvIGEgcXVpY2sgY2hlY2tcblx0XHR9IGVsc2UgaWYgKCBhdXAgPT09IGJ1cCApIHtcblx0XHRcdHJldHVybiBzaWJsaW5nQ2hlY2soIGEsIGIgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2Ugd2UgbmVlZCBmdWxsIGxpc3RzIG9mIHRoZWlyIGFuY2VzdG9ycyBmb3IgY29tcGFyaXNvblxuXHRcdGN1ciA9IGE7XG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLnBhcmVudE5vZGUpICkge1xuXHRcdFx0YXAudW5zaGlmdCggY3VyICk7XG5cdFx0fVxuXHRcdGN1ciA9IGI7XG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLnBhcmVudE5vZGUpICkge1xuXHRcdFx0YnAudW5zaGlmdCggY3VyICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2FsayBkb3duIHRoZSB0cmVlIGxvb2tpbmcgZm9yIGEgZGlzY3JlcGFuY3lcblx0XHR3aGlsZSAoIGFwW2ldID09PSBicFtpXSApIHtcblx0XHRcdGkrKztcblx0XHR9XG5cblx0XHRyZXR1cm4gaSA/XG5cdFx0XHQvLyBEbyBhIHNpYmxpbmcgY2hlY2sgaWYgdGhlIG5vZGVzIGhhdmUgYSBjb21tb24gYW5jZXN0b3Jcblx0XHRcdHNpYmxpbmdDaGVjayggYXBbaV0sIGJwW2ldICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugbm9kZXMgaW4gb3VyIGRvY3VtZW50IHNvcnQgZmlyc3Rcblx0XHRcdGFwW2ldID09PSBwcmVmZXJyZWREb2MgPyAtMSA6XG5cdFx0XHRicFtpXSA9PT0gcHJlZmVycmVkRG9jID8gMSA6XG5cdFx0XHQwO1xuXHR9O1xuXG5cdHJldHVybiBkb2M7XG59O1xuXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcblx0cmV0dXJuIFNpenpsZSggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTtcbn07XG5cblNpenpsZS5tYXRjaGVzU2VsZWN0b3IgPSBmdW5jdGlvbiggZWxlbSwgZXhwciApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0Ly8gTWFrZSBzdXJlIHRoYXQgYXR0cmlidXRlIHNlbGVjdG9ycyBhcmUgcXVvdGVkXG5cdGV4cHIgPSBleHByLnJlcGxhY2UoIHJhdHRyaWJ1dGVRdW90ZXMsIFwiPSckMSddXCIgKTtcblxuXHRpZiAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxuXHRcdCggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHtcblxuXHRcdHRyeSB7XG5cdFx0XHR2YXIgcmV0ID0gbWF0Y2hlcy5jYWxsKCBlbGVtLCBleHByICk7XG5cblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRcdGlmICggcmV0IHx8IHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggfHxcblx0XHRcdFx0XHQvLyBBcyB3ZWxsLCBkaXNjb25uZWN0ZWQgbm9kZXMgYXJlIHNhaWQgdG8gYmUgaW4gYSBkb2N1bWVudFxuXHRcdFx0XHRcdC8vIGZyYWdtZW50IGluIElFIDlcblx0XHRcdFx0XHRlbGVtLmRvY3VtZW50ICYmIGVsZW0uZG9jdW1lbnQubm9kZVR5cGUgIT09IDExICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2goZSkge31cblx0fVxuXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XG59O1xuXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0dmFyIGZuID0gRXhwci5hdHRySGFuZGxlWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSxcblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/XG5cdFx0dmFsIDpcblx0XHRzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWRvY3VtZW50SXNIVE1MID9cblx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgOlxuXHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG59O1xuXG5TaXp6bGUuZXJyb3IgPSBmdW5jdGlvbiggbXNnICkge1xuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcbn07XG5cbi8qKlxuICogRG9jdW1lbnQgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlc1xuICogQHBhcmFtIHtBcnJheUxpa2V9IHJlc3VsdHNcbiAqL1xuU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbiggcmVzdWx0cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxuXHRcdGogPSAwLFxuXHRcdGkgPSAwO1xuXG5cdC8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2Vcblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRpZiAoIGVsZW0gPT09IHJlc3VsdHNbIGkgXSApIHtcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdHJlc3VsdHMuc3BsaWNlKCBkdXBsaWNhdGVzWyBqIF0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDbGVhciBpbnB1dCBhZnRlciBzb3J0aW5nIHRvIHJlbGVhc2Ugb2JqZWN0c1xuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcblx0c29ydElucHV0ID0gbnVsbDtcblxuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdGV4dCB2YWx1ZSBvZiBhbiBhcnJheSBvZiBET00gbm9kZXNcbiAqIEBwYXJhbSB7QXJyYXl8RWxlbWVudH0gZWxlbVxuICovXG5nZXRUZXh0ID0gU2l6emxlLmdldFRleHQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0dmFyIG5vZGUsXG5cdFx0cmV0ID0gXCJcIixcblx0XHRpID0gMCxcblx0XHRub2RlVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0aWYgKCAhbm9kZVR5cGUgKSB7XG5cdFx0Ly8gSWYgbm8gbm9kZVR5cGUsIHRoaXMgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXlcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcblx0XHRcdC8vIERvIG5vdCB0cmF2ZXJzZSBjb21tZW50IG5vZGVzXG5cdFx0XHRyZXQgKz0gZ2V0VGV4dCggbm9kZSApO1xuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDkgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXHRcdC8vIFVzZSB0ZXh0Q29udGVudCBmb3IgZWxlbWVudHNcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxuXHRcdGlmICggdHlwZW9mIGVsZW0udGV4dENvbnRlbnQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS50ZXh0Q29udGVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gVHJhdmVyc2UgaXRzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVWYWx1ZTtcblx0fVxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcblxuXHRyZXR1cm4gcmV0O1xufTtcblxuRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0Ly8gTW92ZSB0aGUgZ2l2ZW4gdmFsdWUgdG8gbWF0Y2hbM10gd2hldGhlciBxdW90ZWQgb3IgdW5xdW90ZWRcblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsyXSA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0LyogbWF0Y2hlcyBmcm9tIG1hdGNoRXhwcltcIkNISUxEXCJdXG5cdFx0XHRcdDEgdHlwZSAob25seXxudGh8Li4uKVxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdDMgYXJndW1lbnQgKGV2ZW58b2RkfFxcZCp8XFxkKm4oWystXVxcZCspP3wuLi4pXG5cdFx0XHRcdDQgeG4tY29tcG9uZW50IG9mIHhuK3kgYXJndW1lbnQgKFsrLV0/XFxkKm58KVxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDYgeCBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NyBzaWduIG9mIHktY29tcG9uZW50XG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxuXHRcdFx0Ki9cblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsxXS5zbGljZSggMCwgMyApID09PSBcIm50aFwiICkge1xuXHRcdFx0XHQvLyBudGgtKiByZXF1aXJlcyBhcmd1bWVudFxuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBudW1lcmljIHggYW5kIHkgcGFyYW1ldGVycyBmb3IgRXhwci5maWx0ZXIuQ0hJTERcblx0XHRcdFx0Ly8gcmVtZW1iZXIgdGhhdCBmYWxzZS90cnVlIGNhc3QgcmVzcGVjdGl2ZWx5IHRvIDAvMVxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xuXHRcdFx0XHRtYXRjaFs1XSA9ICsoICggbWF0Y2hbN10gKyBtYXRjaFs4XSApIHx8IG1hdGNoWzNdID09PSBcIm9kZFwiICk7XG5cblx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHR2YXIgZXhjZXNzLFxuXHRcdFx0XHR1bnF1b3RlZCA9ICFtYXRjaFs2XSAmJiBtYXRjaFsyXTtcblxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbXCJDSElMRFwiXS50ZXN0KCBtYXRjaFswXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdG1hdGNoWzJdID0gbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIjtcblxuXHRcdFx0Ly8gU3RyaXAgZXhjZXNzIGNoYXJhY3RlcnMgZnJvbSB1bnF1b3RlZCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxuXHRcdFx0XHQvLyBHZXQgZXhjZXNzIGZyb20gdG9rZW5pemUgKHJlY3Vyc2l2ZWx5KVxuXHRcdFx0XHQoZXhjZXNzID0gdG9rZW5pemUoIHVucXVvdGVkLCB0cnVlICkpICYmXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xuXHRcdFx0XHQoZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoKSApIHtcblxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxuXHRcdFx0XHRtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdFx0bWF0Y2hbMl0gPSB1bnF1b3RlZC5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHVybiBvbmx5IGNhcHR1cmVzIG5lZWRlZCBieSB0aGUgcHNldWRvIGZpbHRlciBtZXRob2QgKHR5cGUgYW5kIGFyZ3VtZW50KVxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XG5cdFx0fVxuXHR9LFxuXG5cdGZpbHRlcjoge1xuXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBub2RlTmFtZVNlbGVjdG9yLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBub2RlTmFtZVNlbGVjdG9yID09PSBcIipcIiA/XG5cdFx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbm9kZU5hbWU7XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcblx0XHRcdHZhciBwYXR0ZXJuID0gY2xhc3NDYWNoZVsgY2xhc3NOYW1lICsgXCIgXCIgXTtcblxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcblx0XHRcdFx0KHBhdHRlcm4gPSBuZXcgUmVnRXhwKCBcIihefFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgY2xhc3NOYW1lICsgXCIoXCIgKyB3aGl0ZXNwYWNlICsgXCJ8JClcIiApKSAmJlxuXHRcdFx0XHRjbGFzc0NhY2hlKCBjbGFzc05hbWUsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoIHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IHN0cnVuZGVmaW5lZCAmJiBlbGVtLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpIHx8IFwiXCIgKTtcblx0XHRcdFx0fSk7XG5cdFx0fSxcblxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbmFtZSwgb3BlcmF0b3IsIGNoZWNrICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gU2l6emxlLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdFx0XHRpZiAoIHJlc3VsdCA9PSBudWxsICkge1xuXHRcdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCIhPVwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggIW9wZXJhdG9yICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmVzdWx0ICs9IFwiXCI7XG5cblx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIj1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiE9XCIgPyByZXN1bHQgIT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIio9XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIkPVwiID8gY2hlY2sgJiYgcmVzdWx0LnNsaWNlKCAtY2hlY2subGVuZ3RoICkgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdCArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ8PVwiID8gcmVzdWx0ID09PSBjaGVjayB8fCByZXN1bHQuc2xpY2UoIDAsIGNoZWNrLmxlbmd0aCArIDEgKSA9PT0gY2hlY2sgKyBcIi1cIiA6XG5cdFx0XHRcdFx0ZmFsc2U7XG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBhcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XG5cdFx0XHR2YXIgc2ltcGxlID0gdHlwZS5zbGljZSggMCwgMyApICE9PSBcIm50aFwiLFxuXHRcdFx0XHRmb3J3YXJkID0gdHlwZS5zbGljZSggLTQgKSAhPT0gXCJsYXN0XCIsXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xuXG5cdFx0XHRyZXR1cm4gZmlyc3QgPT09IDEgJiYgbGFzdCA9PT0gMCA/XG5cblx0XHRcdFx0Ly8gU2hvcnRjdXQgZm9yIDpudGgtKihuKVxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRcdH0gOlxuXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBkaWZmLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSBub2RlWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6IG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0Ly8gUmV2ZXJzZSBkaXJlY3Rpb24gZm9yIDpvbmx5LSogKGlmIHdlIGhhdmVuJ3QgeWV0IGRvbmUgc28pXG5cdFx0XHRcdFx0XHRcdFx0c3RhcnQgPSBkaXIgPSB0eXBlID09PSBcIm9ubHlcIiAmJiAhc3RhcnQgJiYgXCJuZXh0U2libGluZ1wiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdO1xuXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxuXHRcdFx0XHRcdFx0aWYgKCBmb3J3YXJkICYmIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHQvLyBTZWVrIGBlbGVtYCBmcm9tIGEgcHJldmlvdXNseS1jYWNoZWQgaW5kZXhcblx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IHBhcmVudFsgZXhwYW5kbyBdIHx8IChwYXJlbnRbIGV4cGFuZG8gXSA9IHt9KTtcblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSBvdXRlckNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWzBdID09PSBkaXJydW5zICYmIGNhY2hlWzFdO1xuXHRcdFx0XHRcdFx0XHRkaWZmID0gY2FjaGVbMF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbMl07XG5cdFx0XHRcdFx0XHRcdG5vZGUgPSBub2RlSW5kZXggJiYgcGFyZW50LmNoaWxkTm9kZXNbIG5vZGVJbmRleCBdO1xuXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBGYWxsYmFjayB0byBzZWVraW5nIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxuXHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdXNlQ2FjaGUgJiYgKGNhY2hlID0gKGVsZW1bIGV4cGFuZG8gXSB8fCAoZWxlbVsgZXhwYW5kbyBdID0ge30pKVsgdHlwZSBdKSAmJiBjYWNoZVswXSA9PT0gZGlycnVucyApIHtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IGNhY2hlWzFdO1xuXG5cdFx0XHRcdFx0XHQvLyB4bWwgOm50aC1jaGlsZCguLi4pIG9yIDpudGgtbGFzdC1jaGlsZCguLi4pIG9yIDpudGgoLWxhc3QpPy1vZi10eXBlKC4uLilcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0KGRpZmYgPSBub2RlSW5kZXggPSAwKSB8fCBzdGFydC5wb3AoKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRpZiAoICggb2ZUeXBlID8gbm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDogbm9kZS5ub2RlVHlwZSA9PT0gMSApICYmICsrZGlmZiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdC8vIENhY2hlIHRoZSBpbmRleCBvZiBlYWNoIGVuY291bnRlcmVkIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdChub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KSlbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxuXHRcdFx0XHRcdFx0ZGlmZiAtPSBsYXN0O1xuXHRcdFx0XHRcdFx0cmV0dXJuIGRpZmYgPT09IGZpcnN0IHx8ICggZGlmZiAlIGZpcnN0ID09PSAwICYmIGRpZmYgLyBmaXJzdCA+PSAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggcHNldWRvLCBhcmd1bWVudCApIHtcblx0XHRcdC8vIHBzZXVkby1jbGFzcyBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZVxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3Nlc1xuXHRcdFx0Ly8gUHJpb3JpdGl6ZSBieSBjYXNlIHNlbnNpdGl2aXR5IGluIGNhc2UgY3VzdG9tIHBzZXVkb3MgYXJlIGFkZGVkIHdpdGggdXBwZXJjYXNlIGxldHRlcnNcblx0XHRcdC8vIFJlbWVtYmVyIHRoYXQgc2V0RmlsdGVycyBpbmhlcml0cyBmcm9tIHBzZXVkb3Ncblx0XHRcdHZhciBhcmdzLFxuXHRcdFx0XHRmbiA9IEV4cHIucHNldWRvc1sgcHNldWRvIF0gfHwgRXhwci5zZXRGaWx0ZXJzWyBwc2V1ZG8udG9Mb3dlckNhc2UoKSBdIHx8XG5cdFx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIHBzZXVkbzogXCIgKyBwc2V1ZG8gKTtcblxuXHRcdFx0Ly8gVGhlIHVzZXIgbWF5IHVzZSBjcmVhdGVQc2V1ZG8gdG8gaW5kaWNhdGUgdGhhdFxuXHRcdFx0Ly8gYXJndW1lbnRzIGFyZSBuZWVkZWQgdG8gY3JlYXRlIHRoZSBmaWx0ZXIgZnVuY3Rpb25cblx0XHRcdC8vIGp1c3QgYXMgU2l6emxlIGRvZXNcblx0XHRcdGlmICggZm5bIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0cmV0dXJuIGZuKCBhcmd1bWVudCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBCdXQgbWFpbnRhaW4gc3VwcG9ydCBmb3Igb2xkIHNpZ25hdHVyZXNcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcblx0XHRcdFx0YXJncyA9IFsgcHNldWRvLCBwc2V1ZG8sIFwiXCIsIGFyZ3VtZW50IF07XG5cdFx0XHRcdHJldHVybiBFeHByLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoIHBzZXVkby50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdFx0XHRcdHZhciBpZHgsXG5cdFx0XHRcdFx0XHRcdG1hdGNoZWQgPSBmbiggc2VlZCwgYXJndW1lbnQgKSxcblx0XHRcdFx0XHRcdFx0aSA9IG1hdGNoZWQubGVuZ3RoO1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlkeCA9IGluZGV4T2YuY2FsbCggc2VlZCwgbWF0Y2hlZFtpXSApO1xuXHRcdFx0XHRcdFx0XHRzZWVkWyBpZHggXSA9ICEoIG1hdGNoZXNbIGlkeCBdID0gbWF0Y2hlZFtpXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pIDpcblx0XHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmbiggZWxlbSwgMCwgYXJncyApO1xuXHRcdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmbjtcblx0XHR9XG5cdH0sXG5cblx0cHNldWRvczoge1xuXHRcdC8vIFBvdGVudGlhbGx5IGNvbXBsZXggcHNldWRvc1xuXHRcdFwibm90XCI6IG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0XHQvLyBUcmltIHRoZSBzZWxlY3RvciBwYXNzZWQgdG8gY29tcGlsZVxuXHRcdFx0Ly8gdG8gYXZvaWQgdHJlYXRpbmcgbGVhZGluZyBhbmQgdHJhaWxpbmdcblx0XHRcdC8vIHNwYWNlcyBhcyBjb21iaW5hdG9yc1xuXHRcdFx0dmFyIGlucHV0ID0gW10sXG5cdFx0XHRcdHJlc3VsdHMgPSBbXSxcblx0XHRcdFx0bWF0Y2hlciA9IGNvbXBpbGUoIHNlbGVjdG9yLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSApO1xuXG5cdFx0XHRyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID9cblx0XHRcdFx0bWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXG5cdFx0XHRcdFx0XHRpID0gc2VlZC5sZW5ndGg7XG5cblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHtcblx0XHRcdFx0XHRcdFx0c2VlZFtpXSA9ICEobWF0Y2hlc1tpXSA9IGVsZW0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSkgOlxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdGlucHV0WzBdID0gZWxlbTtcblx0XHRcdFx0XHRtYXRjaGVyKCBpbnB1dCwgbnVsbCwgeG1sLCByZXN1bHRzICk7XG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xuXHRcdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJoYXNcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIFNpenpsZSggc2VsZWN0b3IsIGVsZW0gKS5sZW5ndGggPiAwO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdFwiY29udGFpbnNcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KGxhbmcgfHwgXCJcIikgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoXCJ4bWw6bGFuZ1wiKSB8fCBlbGVtLmdldEF0dHJpYnV0ZShcImxhbmdcIikpICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIE1pc2NlbGxhbmVvdXNcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBoYXNoID0gd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdFx0cmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkO1xuXHRcdH0sXG5cblx0XHRcInJvb3RcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcblx0XHR9LFxuXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmICghZG9jdW1lbnQuaGFzRm9jdXMgfHwgZG9jdW1lbnQuaGFzRm9jdXMoKSkgJiYgISEoZWxlbS50eXBlIHx8IGVsZW0uaHJlZiB8fCB+ZWxlbS50YWJJbmRleCk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdFwiZW5hYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZTtcblx0XHR9LFxuXG5cdFx0XCJkaXNhYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHRcImNoZWNrZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBJbiBDU1MzLCA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIGJvdGggY2hlY2tlZCBhbmQgc2VsZWN0ZWQgZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gKG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgISFlbGVtLmNoZWNrZWQpIHx8IChub2RlTmFtZSA9PT0gXCJvcHRpb25cIiAmJiAhIWVsZW0uc2VsZWN0ZWQpO1xuXHRcdH0sXG5cblx0XHRcInNlbGVjdGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxuXHRcdFx0Ly8gb3B0aW9ucyBpbiBTYWZhcmkgd29yayBwcm9wZXJseVxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG9cblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcblx0XHRcdC8vICAgYnV0IG5vdCBieSBvdGhlcnMgKGNvbW1lbnQ6IDg7IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb246IDc7IGV0Yy4pXG5cdFx0XHQvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRcInBhcmVudFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcblx0XHR9LFxuXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDhcblx0XHRcdFx0Ly8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sIFwic2VhcmNoXCIpIGFwcGVhciB3aXRoIGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XG5cdFx0fSxcblxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9KSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSlcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zW1wibnRoXCJdID0gRXhwci5wc2V1ZG9zW1wiZXFcIl07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cdFx0XHRcdC8vIERvbid0IGNvbnN1bWUgdHJhaWxpbmcgY29tbWFzIGFzIHZhbGlkXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2Vcblx0XHRcdFx0dHlwZTogbWF0Y2hbMF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0pO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGaWx0ZXJzXG5cdFx0Zm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHtcblx0XHRcdGlmICggKG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSkgJiYgKCFwcmVGaWx0ZXJzWyB0eXBlIF0gfHxcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XG5cdFx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXHRcdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XG59O1xuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zW2ldLnZhbHVlO1xuXHR9XG5cdHJldHVybiBzZWxlY3Rvcjtcbn1cblxuZnVuY3Rpb24gYWRkQ29tYmluYXRvciggbWF0Y2hlciwgY29tYmluYXRvciwgYmFzZSApIHtcblx0dmFyIGRpciA9IGNvbWJpbmF0b3IuZGlyLFxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGRpciA9PT0gXCJwYXJlbnROb2RlXCIsXG5cdFx0ZG9uZU5hbWUgPSBkb25lKys7XG5cblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xuXHRcdC8vIENoZWNrIGFnYWluc3QgY2xvc2VzdCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IDpcblxuXHRcdC8vIENoZWNrIGFnYWluc3QgYWxsIGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50c1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgb2xkQ2FjaGUsIG91dGVyQ2FjaGUsXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xuXG5cdFx0XHQvLyBXZSBjYW4ndCBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gWE1MIG5vZGVzLCBzbyB0aGV5IGRvbid0IGJlbmVmaXQgZnJvbSBkaXIgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8IChlbGVtWyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IG91dGVyQ2FjaGVbIGRpciBdKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyBkaXIgXSA9IG5ld0NhY2hlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEEgbWF0Y2ggbWVhbnMgd2UncmUgZG9uZTsgYSBmYWlsIG1lYW5zIHdlIGhhdmUgdG8ga2VlcCBjaGVja2luZ1xuXHRcdFx0XHRcdFx0XHRpZiAoIChuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcbn1cblxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xuXHRyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggIW1hdGNoZXJzW2ldKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWzBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRpZiAoICFmaWx0ZXIgfHwgZmlsdGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0aWYgKCBtYXBwZWQgKSB7XG5cdFx0XHRcdFx0bWFwLnB1c2goIGkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBuZXdVbm1hdGNoZWQ7XG59XG5cbmZ1bmN0aW9uIHNldE1hdGNoZXIoIHByZUZpbHRlciwgc2VsZWN0b3IsIG1hdGNoZXIsIHBvc3RGaWx0ZXIsIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApIHtcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTtcblx0fVxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmluZGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICk7XG5cdH1cblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxuXHRcdFx0ZWxlbXMgPSBzZWVkIHx8IG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yIHx8IFwiKlwiLCBjb250ZXh0Lm5vZGVUeXBlID8gWyBjb250ZXh0IF0gOiBjb250ZXh0LCBbXSApLFxuXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cblx0XHRcdG1hdGNoZXJJbiA9IHByZUZpbHRlciAmJiAoIHNlZWQgfHwgIXNlbGVjdG9yICkgP1xuXHRcdFx0XHRjb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdGVsZW1zLFxuXG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlciA/XG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHQvLyBGaW5kIHByaW1hcnkgbWF0Y2hlc1xuXHRcdGlmICggbWF0Y2hlciApIHtcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHQvLyBVbi1tYXRjaCBmYWlsaW5nIGVsZW1lbnRzIGJ5IG1vdmluZyB0aGVtIGJhY2sgdG8gbWF0Y2hlckluXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoZWxlbSA9IHRlbXBbaV0pICkge1xuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggc2VlZCApIHtcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XG5cdFx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0XHQvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHNcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaFxuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goIChtYXRjaGVySW5baV0gPSBlbGVtKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCAobWF0Y2hlck91dCA9IFtdKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBNb3ZlIG1hdGNoZWQgZWxlbWVudHMgZnJvbSBzZWVkIHRvIHJlc3VsdHMgdG8ga2VlcCB0aGVtIHN5bmNocm9uaXplZFxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSAmJlxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZi5jYWxsKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbaV0pID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbdGVtcF0gPSAhKHJlc3VsdHNbdGVtcF0gPSBlbGVtKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Ub2tlbnMoIHRva2VucyApIHtcblx0dmFyIGNoZWNrQ29udGV4dCwgbWF0Y2hlciwgaixcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdGxlYWRpbmdSZWxhdGl2ZSA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1swXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlW1wiIFwiXSxcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXG5cblx0XHQvLyBUaGUgZm91bmRhdGlvbmFsIG1hdGNoZXIgZW5zdXJlcyB0aGF0IGVsZW1lbnRzIGFyZSByZWFjaGFibGUgZnJvbSB0b3AtbGV2ZWwgY29udGV4dChzKVxuXHRcdG1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGNoZWNrQ29udGV4dDtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hBbnlDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaGVycyA9IFsgZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHJldHVybiAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxuXHRcdFx0XHQoY2hlY2tDb250ZXh0ID0gY29udGV4dCkubm9kZVR5cGUgP1xuXHRcdFx0XHRcdG1hdGNoQ29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcblx0XHR9IF07XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksIG1hdGNoZXIpIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zW2ldLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zW2ldLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHQvLyBGaW5kIHRoZSBuZXh0IHJlbGF0aXZlIG9wZXJhdG9yIChpZiBhbnkpIGZvciBwcm9wZXIgaGFuZGxpbmdcblx0XHRcdFx0aiA9ICsraTtcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyB0b2tlbnNbal0udHlwZSBdICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBzZXRNYXRjaGVyKFxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxuXHRcdFx0XHRcdGkgPiAxICYmIHRvU2VsZWN0b3IoXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGUgcHJlY2VkaW5nIHRva2VuIHdhcyBhIGRlc2NlbmRhbnQgY29tYmluYXRvciwgaW5zZXJ0IGFuIGltcGxpY2l0IGFueS1lbGVtZW50IGAqYFxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSlcblx0XHRcdFx0XHQpLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSxcblx0XHRcdFx0XHRtYXRjaGVyLFxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgbWF0Y2hlckZyb21Ub2tlbnMoICh0b2tlbnMgPSB0b2tlbnMuc2xpY2UoIGogKSkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIHRvU2VsZWN0b3IoIHRva2VucyApXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRtYXRjaGVycy5wdXNoKCBtYXRjaGVyICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XG5cdHZhciBieVNldCA9IHNldE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0YnlFbGVtZW50ID0gZWxlbWVudE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xuXHRcdFx0dmFyIGVsZW0sIGosIG1hdGNoZXIsXG5cdFx0XHRcdG1hdGNoZWRDb3VudCA9IDAsXG5cdFx0XHRcdGkgPSBcIjBcIixcblx0XHRcdFx0dW5tYXRjaGVkID0gc2VlZCAmJiBbXSxcblx0XHRcdFx0c2V0TWF0Y2hlZCA9IFtdLFxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcblx0XHRcdFx0Ly8gV2UgbXVzdCBhbHdheXMgaGF2ZSBlaXRoZXIgc2VlZCBlbGVtZW50cyBvciBvdXRlcm1vc3QgY29udGV4dFxuXHRcdFx0XHRlbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFtcIlRBR1wiXSggXCIqXCIsIG91dGVybW9zdCApLFxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxuXHRcdFx0XHRkaXJydW5zVW5pcXVlID0gKGRpcnJ1bnMgKz0gY29udGV4dEJhY2t1cCA9PSBudWxsID8gMSA6IE1hdGgucmFuZG9tKCkgfHwgMC4xKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHQgIT09IGRvY3VtZW50ICYmIGNvbnRleHQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBlbGVtZW50cyBwYXNzaW5nIGVsZW1lbnRNYXRjaGVycyBkaXJlY3RseSB0byByZXN1bHRzXG5cdFx0XHQvLyBLZWVwIGBpYCBhIHN0cmluZyBpZiB0aGVyZSBhcmUgbm8gZWxlbWVudHMgc28gYG1hdGNoZWRDb3VudGAgd2lsbCBiZSBcIjAwXCIgYmVsb3dcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUcmFjayB1bm1hdGNoZWQgZWxlbWVudHMgZm9yIHNldCBmaWx0ZXJzXG5cdFx0XHRcdGlmICggYnlTZXQgKSB7XG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSAhbWF0Y2hlciAmJiBlbGVtKSApIHtcblx0XHRcdFx0XHRcdG1hdGNoZWRDb3VudC0tO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIExlbmd0aGVuIHRoZSBhcnJheSBmb3IgZXZlcnkgZWxlbWVudCwgbWF0Y2hlZCBvciBub3Rcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBcHBseSBzZXQgZmlsdGVycyB0byB1bm1hdGNoZWQgZWxlbWVudHNcblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xuXHRcdFx0aWYgKCBieVNldCAmJiBpICE9PSBtYXRjaGVkQ291bnQgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gc2V0TWF0Y2hlcnNbaisrXSkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFtpXSA9IHBvcC5jYWxsKCByZXN1bHRzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xuXHRcdFx0XHRcdHNldE1hdGNoZWQgPSBjb25kZW5zZSggc2V0TWF0Y2hlZCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRkIG1hdGNoZXMgdG8gcmVzdWx0c1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZXRNYXRjaGVkICk7XG5cblx0XHRcdFx0Ly8gU2VlZGxlc3Mgc2V0IG1hdGNoZXMgc3VjY2VlZGluZyBtdWx0aXBsZSBzdWNjZXNzZnVsIG1hdGNoZXJzIHN0aXB1bGF0ZSBzb3J0aW5nXG5cdFx0XHRcdGlmICggb3V0ZXJtb3N0ICYmICFzZWVkICYmIHNldE1hdGNoZWQubGVuZ3RoID4gMCAmJlxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xuXG5cdFx0XHRcdFx0U2l6emxlLnVuaXF1ZVNvcnQoIHJlc3VsdHMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XG5cdFx0fTtcblxuXHRyZXR1cm4gYnlTZXQgP1xuXHRcdG1hcmtGdW5jdGlvbiggc3VwZXJNYXRjaGVyICkgOlxuXHRcdHN1cGVyTWF0Y2hlcjtcbn1cblxuY29tcGlsZSA9IFNpenpsZS5jb21waWxlID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBtYXRjaCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0dmFyIGksXG5cdFx0c2V0TWF0Y2hlcnMgPSBbXSxcblx0XHRlbGVtZW50TWF0Y2hlcnMgPSBbXSxcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCAhY2FjaGVkICkge1xuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxuXHRcdGlmICggIW1hdGNoICkge1xuXHRcdFx0bWF0Y2ggPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblx0XHR9XG5cdFx0aSA9IG1hdGNoLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFtpXSApO1xuXHRcdFx0aWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0c2V0TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FjaGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZSggc2VsZWN0b3IsIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApICk7XG5cblx0XHQvLyBTYXZlIHNlbGVjdG9yIGFuZCB0b2tlbml6YXRpb25cblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3Rvcjtcblx0fVxuXHRyZXR1cm4gY2FjaGVkO1xufTtcblxuLyoqXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb25zXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc2VsZWN0b3IgQSBzZWxlY3RvciBvciBhIHByZS1jb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcbiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGV4dFxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHNdXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxuICovXG5zZWxlY3QgPSBTaXp6bGUuc2VsZWN0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcblx0XHRjb21waWxlZCA9IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHNlbGVjdG9yLFxuXHRcdG1hdGNoID0gIXNlZWQgJiYgdG9rZW5pemUoIChzZWxlY3RvciA9IGNvbXBpbGVkLnNlbGVjdG9yIHx8IHNlbGVjdG9yKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG5vIHNlZWQgYW5kIG9ubHkgb25lIGdyb3VwXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xuXG5cdFx0Ly8gVGFrZSBhIHNob3J0Y3V0IGFuZCBzZXQgdGhlIGNvbnRleHQgaWYgdGhlIHJvb3Qgc2VsZWN0b3IgaXMgYW4gSURcblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAodG9rZW4gPSB0b2tlbnNbMF0pLnR5cGUgPT09IFwiSURcIiAmJlxuXHRcdFx0XHRzdXBwb3J0LmdldEJ5SWQgJiYgY29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbXCJJRFwiXSggdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKHJ1bmVzY2FwZSwgZnVuZXNjYXBlKSwgY29udGV4dCApIHx8IFtdIClbMF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRva2VuID0gdG9rZW5zW2ldO1xuXG5cdFx0XHQvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yXG5cdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbICh0eXBlID0gdG9rZW4udHlwZSkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIChmaW5kID0gRXhwci5maW5kWyB0eXBlIF0pICkge1xuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcblx0XHRcdFx0aWYgKCAoc2VlZCA9IGZpbmQoXG5cdFx0XHRcdFx0dG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLFxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0XHRcdFx0KSkgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcblx0XHRcdFx0XHR0b2tlbnMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHRcdFx0c2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTtcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNlZWQgKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ29tcGlsZSBhbmQgZXhlY3V0ZSBhIGZpbHRlcmluZyBmdW5jdGlvbiBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcblx0KCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKFxuXHRcdHNlZWQsXG5cdFx0Y29udGV4dCxcblx0XHQhZG9jdW1lbnRJc0hUTUwsXG5cdFx0cmVzdWx0cyxcblx0XHRyc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdCk7XG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gT25lLXRpbWUgYXNzaWdubWVudHNcblxuLy8gU29ydCBzdGFiaWxpdHlcbnN1cHBvcnQuc29ydFN0YWJsZSA9IGV4cGFuZG8uc3BsaXQoXCJcIikuc29ydCggc29ydE9yZGVyICkuam9pbihcIlwiKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lPDE0XG4vLyBBbHdheXMgYXNzdW1lIGR1cGxpY2F0ZXMgaWYgdGhleSBhcmVuJ3QgcGFzc2VkIHRvIHRoZSBjb21wYXJpc29uIGZ1bmN0aW9uXG5zdXBwb3J0LmRldGVjdER1cGxpY2F0ZXMgPSAhIWhhc0R1cGxpY2F0ZTtcblxuLy8gSW5pdGlhbGl6ZSBhZ2FpbnN0IHRoZSBkZWZhdWx0IGRvY3VtZW50XG5zZXREb2N1bWVudCgpO1xuXG4vLyBTdXBwb3J0OiBXZWJraXQ8NTM3LjMyIC0gU2FmYXJpIDYuMC4zL0Nocm9tZSAyNSAoZml4ZWQgaW4gQ2hyb21lIDI3KVxuLy8gRGV0YWNoZWQgbm9kZXMgY29uZm91bmRpbmdseSBmb2xsb3cgKmVhY2ggb3RoZXIqXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydChmdW5jdGlvbiggZGl2MSApIHtcblx0Ly8gU2hvdWxkIHJldHVybiAxLCBidXQgcmV0dXJucyA0IChmb2xsb3dpbmcpXG5cdHJldHVybiBkaXYxLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpICkgJiAxO1xufSk7XG5cbi8vIFN1cHBvcnQ6IElFPDhcbi8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5IFwiaW50ZXJwb2xhdGlvblwiXG4vLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY0MjklMjhWUy44NSUyOS5hc3B4XG5pZiAoICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0ZGl2LmlubmVySFRNTCA9IFwiPGEgaHJlZj0nIyc+PC9hPlwiO1xuXHRyZXR1cm4gZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKSA9PT0gXCIjXCIgO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSwgbmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInR5cGVcIiA/IDEgOiAyICk7XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGRlZmF1bHRWYWx1ZSBpbiBwbGFjZSBvZiBnZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKVxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0ZGl2LmlubmVySFRNTCA9IFwiPGlucHV0Lz5cIjtcblx0ZGl2LmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCBcInZhbHVlXCIsIFwiXCIgKTtcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IFwiXCI7XG59KSApIHtcblx0YWRkSGFuZGxlKCBcInZhbHVlXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLmRlZmF1bHRWYWx1ZTtcblx0XHR9XG5cdH0pO1xufVxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBVc2UgZ2V0QXR0cmlidXRlTm9kZSB0byBmZXRjaCBib29sZWFucyB3aGVuIGdldEF0dHJpYnV0ZSBsaWVzXG5pZiAoICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0cmV0dXJuIGRpdi5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSA9PSBudWxsO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggYm9vbGVhbnMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgdmFsO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdH1cblx0fSk7XG59XG5cbnJldHVybiBTaXp6bGU7XG5cbn0pKCB3aW5kb3cgKTtcblxuXG5cbmpRdWVyeS5maW5kID0gU2l6emxlO1xualF1ZXJ5LmV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzO1xualF1ZXJ5LmV4cHJbXCI6XCJdID0galF1ZXJ5LmV4cHIucHNldWRvcztcbmpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcbmpRdWVyeS50ZXh0ID0gU2l6emxlLmdldFRleHQ7XG5qUXVlcnkuaXNYTUxEb2MgPSBTaXp6bGUuaXNYTUw7XG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XG5cblxuXG52YXIgcm5lZWRzQ29udGV4dCA9IGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dDtcblxudmFyIHJzaW5nbGVUYWcgPSAoL148KFxcdyspXFxzKlxcLz8+KD86PFxcL1xcMT58KSQvKTtcblxuXG5cbnZhciByaXNTaW1wbGUgPSAvXi5bXjojXFxbXFwuLF0qJC87XG5cbi8vIEltcGxlbWVudCB0aGUgaWRlbnRpY2FsIGZ1bmN0aW9uYWxpdHkgZm9yIGZpbHRlciBhbmQgbm90XG5mdW5jdGlvbiB3aW5ub3coIGVsZW1lbnRzLCBxdWFsaWZpZXIsIG5vdCApIHtcblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHQvKiBqc2hpbnQgLVcwMTggKi9cblx0XHRcdHJldHVybiAhIXF1YWxpZmllci5jYWxsKCBlbGVtLCBpLCBlbGVtICkgIT09IG5vdDtcblx0XHR9KTtcblxuXHR9XG5cblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0pO1xuXG5cdH1cblxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0aWYgKCByaXNTaW1wbGUudGVzdCggcXVhbGlmaWVyICkgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cywgbm90ICk7XG5cdFx0fVxuXG5cdFx0cXVhbGlmaWVyID0galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cyApO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuICggaW5kZXhPZi5jYWxsKCBxdWFsaWZpZXIsIGVsZW0gKSA+PSAwICkgIT09IG5vdDtcblx0fSk7XG59XG5cbmpRdWVyeS5maWx0ZXIgPSBmdW5jdGlvbiggZXhwciwgZWxlbXMsIG5vdCApIHtcblx0dmFyIGVsZW0gPSBlbGVtc1sgMCBdO1xuXG5cdGlmICggbm90ICkge1xuXHRcdGV4cHIgPSBcIjpub3QoXCIgKyBleHByICsgXCIpXCI7XG5cdH1cblxuXHRyZXR1cm4gZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgP1xuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXSA6XG5cdFx0alF1ZXJ5LmZpbmQubWF0Y2hlcyggZXhwciwgalF1ZXJ5LmdyZXAoIGVsZW1zLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVUeXBlID09PSAxO1xuXHRcdH0pKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0c2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pICk7XG5cdFx0fVxuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGpRdWVyeS5maW5kKCBzZWxlY3Rvciwgc2VsZlsgaSBdLCByZXQgKTtcblx0XHR9XG5cblx0XHQvLyBOZWVkZWQgYmVjYXVzZSAkKCBzZWxlY3RvciwgY29udGV4dCApIGJlY29tZXMgJCggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yIClcblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggbGVuID4gMSA/IGpRdWVyeS51bmlxdWUoIHJldCApIDogcmV0ICk7XG5cdFx0cmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciA/IHRoaXMuc2VsZWN0b3IgKyBcIiBcIiArIHNlbGVjdG9yIDogc2VsZWN0b3I7XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3codGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyh0aGlzLCBzZWxlY3RvciB8fCBbXSwgdHJ1ZSkgKTtcblx0fSxcblx0aXM6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gISF3aW5ub3coXG5cdFx0XHR0aGlzLFxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XG5cdFx0XHQvLyBzbyAkKFwicDpmaXJzdFwiKS5pcyhcInA6bGFzdFwiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gXCJwXCIuXG5cdFx0XHR0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgJiYgcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0c2VsZWN0b3IgfHwgW10sXG5cdFx0XHRmYWxzZVxuXHRcdCkubGVuZ3RoO1xuXHR9XG59KTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncblx0Ly8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcblx0cnF1aWNrRXhwciA9IC9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSopKSQvLFxuXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblx0XHR2YXIgbWF0Y2gsIGVsZW07XG5cblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcblx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSBIVE1MIHN0cmluZ3Ncblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGlmICggc2VsZWN0b3JbMF0gPT09IFwiPFwiICYmIHNlbGVjdG9yWyBzZWxlY3Rvci5sZW5ndGggLSAxIF0gPT09IFwiPlwiICYmIHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xuXHRcdFx0XHRtYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0bWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE1hdGNoIGh0bWwgb3IgbWFrZSBzdXJlIG5vIGNvbnRleHQgaXMgc3BlY2lmaWVkIGZvciAjaWRcblx0XHRcdGlmICggbWF0Y2ggJiYgKG1hdGNoWzFdIHx8ICFjb250ZXh0KSApIHtcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcblx0XHRcdFx0aWYgKCBtYXRjaFsxXSApIHtcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbMF0gOiBjb250ZXh0O1xuXG5cdFx0XHRcdFx0Ly8gc2NyaXB0cyBpcyB0cnVlIGZvciBiYWNrLWNvbXBhdFxuXHRcdFx0XHRcdC8vIEludGVudGlvbmFsbHkgbGV0IHRoZSBlcnJvciBiZSB0aHJvd24gaWYgcGFyc2VIVE1MIGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxuXHRcdFx0XHRcdFx0bWF0Y2hbMV0sXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxuXHRcdFx0XHRcdFx0dHJ1ZVxuXHRcdFx0XHRcdCkgKTtcblxuXHRcdFx0XHRcdC8vIEhBTkRMRTogJChodG1sLCBwcm9wcylcblx0XHRcdFx0XHRpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbMV0gKSAmJiBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29udGV4dCApICkge1xuXHRcdFx0XHRcdFx0Zm9yICggbWF0Y2ggaW4gY29udGV4dCApIHtcblx0XHRcdFx0XHRcdFx0Ly8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB0aGlzWyBtYXRjaCBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBvdGhlcndpc2Ugc2V0IGFzIGF0dHJpYnV0ZXNcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmF0dHIoIG1hdGNoLCBjb250ZXh0WyBtYXRjaCBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoI2lkKVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGVsZW0gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbWF0Y2hbMl0gKTtcblxuXHRcdFx0XHRcdC8vIENoZWNrIHBhcmVudE5vZGUgdG8gY2F0Y2ggd2hlbiBCbGFja2JlcnJ5IDQuNiByZXR1cm5zXG5cdFx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAjNjk2M1xuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBJbmplY3QgdGhlIGVsZW1lbnQgZGlyZWN0bHkgaW50byB0aGUgalF1ZXJ5IG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdFx0dGhpc1swXSA9IGVsZW07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGhpcy5jb250ZXh0ID0gZG9jdW1lbnQ7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCAkKC4uLikpXG5cdFx0XHR9IGVsc2UgaWYgKCAhY29udGV4dCB8fCBjb250ZXh0LmpxdWVyeSApIHtcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290alF1ZXJ5ICkuZmluZCggc2VsZWN0b3IgKTtcblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsIGNvbnRleHQpXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdC8vIEhBTkRMRTogJChET01FbGVtZW50KVxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gdGhpc1swXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHNlbGVjdG9yICkgKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIHJvb3RqUXVlcnkucmVhZHkgIT09IFwidW5kZWZpbmVkXCIgP1xuXHRcdFx0XHRyb290alF1ZXJ5LnJlYWR5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRzZWxlY3RvciggalF1ZXJ5ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3Rvci5zZWxlY3RvciAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yLnNlbGVjdG9yO1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXHQvLyBtZXRob2RzIGd1YXJhbnRlZWQgdG8gcHJvZHVjZSBhIHVuaXF1ZSBzZXQgd2hlbiBzdGFydGluZyBmcm9tIGEgdW5pcXVlIHNldFxuXHRndWFyYW50ZWVkVW5pcXVlID0ge1xuXHRcdGNoaWxkcmVuOiB0cnVlLFxuXHRcdGNvbnRlbnRzOiB0cnVlLFxuXHRcdG5leHQ6IHRydWUsXG5cdFx0cHJldjogdHJ1ZVxuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0ZGlyOiBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IFtdLFxuXHRcdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xuXG5cdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSAmJiBlbGVtLm5vZGVUeXBlICE9PSA5ICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRpZiAoIHRydW5jYXRlICYmIGpRdWVyeSggZWxlbSApLmlzKCB1bnRpbCApICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHRcdG1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gbWF0Y2hlZDtcblx0fSxcblxuXHRzaWJsaW5nOiBmdW5jdGlvbiggbiwgZWxlbSApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IFtdO1xuXG5cdFx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcblx0XHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xuXHRcdFx0XHRtYXRjaGVkLnB1c2goIG4gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlZDtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRoYXM6IGZ1bmN0aW9uKCB0YXJnZXQgKSB7XG5cdFx0dmFyIHRhcmdldHMgPSBqUXVlcnkoIHRhcmdldCwgdGhpcyApLFxuXHRcdFx0bCA9IHRhcmdldHMubGVuZ3RoO1xuXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1tpXSApICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRtYXRjaGVkID0gW10sXG5cdFx0XHRwb3MgPSBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9ycyApIHx8IHR5cGVvZiBzZWxlY3RvcnMgIT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9ycywgY29udGV4dCB8fCB0aGlzLmNvbnRleHQgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRmb3IgKCBjdXIgPSB0aGlzW2ldOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0Ly8gQWx3YXlzIHNraXAgZG9jdW1lbnQgZnJhZ21lbnRzXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKHBvcyA/XG5cdFx0XHRcdFx0cG9zLmluZGV4KGN1cikgPiAtMSA6XG5cblx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRjdXIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvcihjdXIsIHNlbGVjdG9ycykpICkge1xuXG5cdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZSggbWF0Y2hlZCApIDogbWF0Y2hlZCApO1xuXHR9LFxuXG5cdC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCB3aXRoaW5cblx0Ly8gdGhlIG1hdGNoZWQgc2V0IG9mIGVsZW1lbnRzXG5cdGluZGV4OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIE5vIGFyZ3VtZW50LCByZXR1cm4gaW5kZXggaW4gcGFyZW50XG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybiAoIHRoaXNbIDAgXSAmJiB0aGlzWyAwIF0ucGFyZW50Tm9kZSApID8gdGhpcy5maXJzdCgpLnByZXZBbGwoKS5sZW5ndGggOiAtMTtcblx0XHR9XG5cblx0XHQvLyBpbmRleCBpbiBzZWxlY3RvclxuXHRcdGlmICggdHlwZW9mIGVsZW0gPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdGhpc1sgMCBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gTG9jYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZGVzaXJlZCBlbGVtZW50XG5cdFx0cmV0dXJuIGluZGV4T2YuY2FsbCggdGhpcyxcblxuXHRcdFx0Ly8gSWYgaXQgcmVjZWl2ZXMgYSBqUXVlcnkgb2JqZWN0LCB0aGUgZmlyc3QgZWxlbWVudCBpcyB1c2VkXG5cdFx0XHRlbGVtLmpxdWVyeSA/IGVsZW1bIDAgXSA6IGVsZW1cblx0XHQpO1xuXHR9LFxuXG5cdGFkZDogZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayhcblx0XHRcdGpRdWVyeS51bmlxdWUoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlcihzZWxlY3Rvcilcblx0XHQpO1xuXHR9XG59KTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKGN1ciA9IGN1cltkaXJdKSAmJiBjdXIubm9kZVR5cGUgIT09IDEgKSB7fVxuXHRyZXR1cm4gY3VyO1xufVxuXG5qUXVlcnkuZWFjaCh7XG5cdHBhcmVudDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRyZXR1cm4gcGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSAhPT0gMTEgPyBwYXJlbnQgOiBudWxsO1xuXHR9LFxuXHRwYXJlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwYXJlbnROb2RlXCIgKTtcblx0fSxcblx0cGFyZW50c1VudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiLCB1bnRpbCApO1xuXHR9LFxuXHRuZXh0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XG5cdH0sXG5cdHByZXY6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XG5cdH0sXG5cdG5leHRBbGw6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dFVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0cHJldlVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIsIHVudGlsICk7XG5cdH0sXG5cdHNpYmxpbmdzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnNpYmxpbmcoICggZWxlbS5wYXJlbnROb2RlIHx8IHt9ICkuZmlyc3RDaGlsZCwgZWxlbSApO1xuXHR9LFxuXHRjaGlsZHJlbjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5zaWJsaW5nKCBlbGVtLmZpcnN0Q2hpbGQgKTtcblx0fSxcblx0Y29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudCB8fCBqUXVlcnkubWVyZ2UoIFtdLCBlbGVtLmNoaWxkTm9kZXMgKTtcblx0fVxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCB1bnRpbCwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xuXHRcdFx0Ly8gUmVtb3ZlIGR1cGxpY2F0ZXNcblx0XHRcdGlmICggIWd1YXJhbnRlZWRVbmlxdWVbIG5hbWUgXSApIHtcblx0XHRcdFx0alF1ZXJ5LnVuaXF1ZSggbWF0Y2hlZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQgKTtcblx0fTtcbn0pO1xudmFyIHJub3R3aGl0ZSA9ICgvXFxTKy9nKTtcblxuXG5cbi8vIFN0cmluZyB0byBPYmplY3Qgb3B0aW9ucyBmb3JtYXQgY2FjaGVcbnZhciBvcHRpb25zQ2FjaGUgPSB7fTtcblxuLy8gQ29udmVydCBTdHJpbmctZm9ybWF0dGVkIG9wdGlvbnMgaW50byBPYmplY3QtZm9ybWF0dGVkIG9uZXMgYW5kIHN0b3JlIGluIGNhY2hlXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xuXHR2YXIgb2JqZWN0ID0gb3B0aW9uc0NhY2hlWyBvcHRpb25zIF0gPSB7fTtcblx0alF1ZXJ5LmVhY2goIG9wdGlvbnMubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdLCBmdW5jdGlvbiggXywgZmxhZyApIHtcblx0XHRvYmplY3RbIGZsYWcgXSA9IHRydWU7XG5cdH0pO1xuXHRyZXR1cm4gb2JqZWN0O1xufVxuXG4vKlxuICogQ3JlYXRlIGEgY2FsbGJhY2sgbGlzdCB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcbiAqXHRcdFx0dGhlIGNhbGxiYWNrIGxpc3QgYmVoYXZlcyBvciBhIG1vcmUgdHJhZGl0aW9uYWwgb3B0aW9uIG9iamVjdFxuICpcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXG4gKiBcImZpcmVkXCIgbXVsdGlwbGUgdGltZXMuXG4gKlxuICogUG9zc2libGUgb3B0aW9uczpcbiAqXG4gKlx0b25jZTpcdFx0XHR3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdG1lbW9yeTpcdFx0XHR3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkXG4gKlx0XHRcdFx0XHRhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCBcIm1lbW9yaXplZFwiXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0dW5pcXVlOlx0XHRcdHdpbGwgZW5zdXJlIGEgY2FsbGJhY2sgY2FuIG9ubHkgYmUgYWRkZWQgb25jZSAobm8gZHVwbGljYXRlIGluIHRoZSBsaXN0KVxuICpcbiAqXHRzdG9wT25GYWxzZTpcdGludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZVxuICpcbiAqL1xualF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcblx0Ly8gKHdlIGNoZWNrIGluIGNhY2hlIGZpcnN0KVxuXHRvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdCggb3B0aW9uc0NhY2hlWyBvcHRpb25zIF0gfHwgY3JlYXRlT3B0aW9ucyggb3B0aW9ucyApICkgOlxuXHRcdGpRdWVyeS5leHRlbmQoIHt9LCBvcHRpb25zICk7XG5cblx0dmFyIC8vIExhc3QgZmlyZSB2YWx1ZSAoZm9yIG5vbi1mb3JnZXR0YWJsZSBsaXN0cylcblx0XHRtZW1vcnksXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblx0XHQvLyBGbGFnIHRvIGtub3cgaWYgbGlzdCBpcyBjdXJyZW50bHkgZmlyaW5nXG5cdFx0ZmlyaW5nLFxuXHRcdC8vIEZpcnN0IGNhbGxiYWNrIHRvIGZpcmUgKHVzZWQgaW50ZXJuYWxseSBieSBhZGQgYW5kIGZpcmVXaXRoKVxuXHRcdGZpcmluZ1N0YXJ0LFxuXHRcdC8vIEVuZCBvZiB0aGUgbG9vcCB3aGVuIGZpcmluZ1xuXHRcdGZpcmluZ0xlbmd0aCxcblx0XHQvLyBJbmRleCBvZiBjdXJyZW50bHkgZmlyaW5nIGNhbGxiYWNrIChtb2RpZmllZCBieSByZW1vdmUgaWYgbmVlZGVkKVxuXHRcdGZpcmluZ0luZGV4LFxuXHRcdC8vIEFjdHVhbCBjYWxsYmFjayBsaXN0XG5cdFx0bGlzdCA9IFtdLFxuXHRcdC8vIFN0YWNrIG9mIGZpcmUgY2FsbHMgZm9yIHJlcGVhdGFibGUgbGlzdHNcblx0XHRzdGFjayA9ICFvcHRpb25zLm9uY2UgJiYgW10sXG5cdFx0Ly8gRmlyZSBjYWxsYmFja3Ncblx0XHRmaXJlID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdFx0XHRtZW1vcnkgPSBvcHRpb25zLm1lbW9yeSAmJiBkYXRhO1xuXHRcdFx0ZmlyZWQgPSB0cnVlO1xuXHRcdFx0ZmlyaW5nSW5kZXggPSBmaXJpbmdTdGFydCB8fCAwO1xuXHRcdFx0ZmlyaW5nU3RhcnQgPSAwO1xuXHRcdFx0ZmlyaW5nTGVuZ3RoID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRmaXJpbmcgPSB0cnVlO1xuXHRcdFx0Zm9yICggOyBsaXN0ICYmIGZpcmluZ0luZGV4IDwgZmlyaW5nTGVuZ3RoOyBmaXJpbmdJbmRleCsrICkge1xuXHRcdFx0XHRpZiAoIGxpc3RbIGZpcmluZ0luZGV4IF0uYXBwbHkoIGRhdGFbIDAgXSwgZGF0YVsgMSBdICkgPT09IGZhbHNlICYmIG9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7XG5cdFx0XHRcdFx0bWVtb3J5ID0gZmFsc2U7IC8vIFRvIHByZXZlbnQgZnVydGhlciBjYWxscyB1c2luZyBhZGRcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0ZmlyaW5nID0gZmFsc2U7XG5cdFx0XHRpZiAoIGxpc3QgKSB7XG5cdFx0XHRcdGlmICggc3RhY2sgKSB7XG5cdFx0XHRcdFx0aWYgKCBzdGFjay5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRmaXJlKCBzdGFjay5zaGlmdCgpICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2UgaWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHNlbGYuZGlzYWJsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblx0XHQvLyBBY3R1YWwgQ2FsbGJhY2tzIG9iamVjdFxuXHRcdHNlbGYgPSB7XG5cdFx0XHQvLyBBZGQgYSBjYWxsYmFjayBvciBhIGNvbGxlY3Rpb24gb2YgY2FsbGJhY2tzIHRvIHRoZSBsaXN0XG5cdFx0XHRhZGQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cdFx0XHRcdFx0Ly8gRmlyc3QsIHdlIHNhdmUgdGhlIGN1cnJlbnQgbGVuZ3RoXG5cdFx0XHRcdFx0dmFyIHN0YXJ0ID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0KGZ1bmN0aW9uIGFkZCggYXJncyApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmdzLCBmdW5jdGlvbiggXywgYXJnICkge1xuXHRcdFx0XHRcdFx0XHR2YXIgdHlwZSA9IGpRdWVyeS50eXBlKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ1bmN0aW9uXCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKCAhb3B0aW9ucy51bmlxdWUgfHwgIXNlbGYuaGFzKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGxpc3QucHVzaCggYXJnICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBhcmcgJiYgYXJnLmxlbmd0aCAmJiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIEluc3BlY3QgcmVjdXJzaXZlbHlcblx0XHRcdFx0XHRcdFx0XHRhZGQoIGFyZyApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHR9KSggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0Ly8gRG8gd2UgbmVlZCB0byBhZGQgdGhlIGNhbGxiYWNrcyB0byB0aGVcblx0XHRcdFx0XHQvLyBjdXJyZW50IGZpcmluZyBiYXRjaD9cblx0XHRcdFx0XHRpZiAoIGZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmluZ0xlbmd0aCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0XHRcdC8vIFdpdGggbWVtb3J5LCBpZiB3ZSdyZSBub3QgZmlyaW5nIHRoZW5cblx0XHRcdFx0XHQvLyB3ZSBzaG91bGQgY2FsbCByaWdodCBhd2F5XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggbWVtb3J5ICkge1xuXHRcdFx0XHRcdFx0ZmlyaW5nU3RhcnQgPSBzdGFydDtcblx0XHRcdFx0XHRcdGZpcmUoIG1lbW9yeSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBSZW1vdmUgYSBjYWxsYmFjayBmcm9tIHRoZSBsaXN0XG5cdFx0XHRyZW1vdmU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGxpc3QgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3VtZW50cywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdHZhciBpbmRleDtcblx0XHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRsaXN0LnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGZpcmluZyBpbmRleGVzXG5cdFx0XHRcdFx0XHRcdGlmICggZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggaW5kZXggPD0gZmlyaW5nTGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlyaW5nTGVuZ3RoLS07XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGlmICggaW5kZXggPD0gZmlyaW5nSW5kZXggKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRmaXJpbmdJbmRleC0tO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIENoZWNrIGlmIGEgZ2l2ZW4gY2FsbGJhY2sgaXMgaW4gdGhlIGxpc3QuXG5cdFx0XHQvLyBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgcmV0dXJuIHdoZXRoZXIgb3Igbm90IGxpc3QgaGFzIGNhbGxiYWNrcyBhdHRhY2hlZC5cblx0XHRcdGhhczogZnVuY3Rpb24oIGZuICkge1xuXHRcdFx0XHRyZXR1cm4gZm4gPyBqUXVlcnkuaW5BcnJheSggZm4sIGxpc3QgKSA+IC0xIDogISEoIGxpc3QgJiYgbGlzdC5sZW5ndGggKTtcblx0XHRcdH0sXG5cdFx0XHQvLyBSZW1vdmUgYWxsIGNhbGxiYWNrcyBmcm9tIHRoZSBsaXN0XG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxpc3QgPSBbXTtcblx0XHRcdFx0ZmlyaW5nTGVuZ3RoID0gMDtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gSGF2ZSB0aGUgbGlzdCBkbyBub3RoaW5nIGFueW1vcmVcblx0XHRcdGRpc2FibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRsaXN0ID0gc3RhY2sgPSBtZW1vcnkgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIElzIGl0IGRpc2FibGVkP1xuXHRcdFx0ZGlzYWJsZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gIWxpc3Q7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gTG9jayB0aGUgbGlzdCBpbiBpdHMgY3VycmVudCBzdGF0ZVxuXHRcdFx0bG9jazogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHN0YWNrID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRpZiAoICFtZW1vcnkgKSB7XG5cdFx0XHRcdFx0c2VsZi5kaXNhYmxlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gSXMgaXQgbG9ja2VkP1xuXHRcdFx0bG9ja2VkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICFzdGFjaztcblx0XHRcdH0sXG5cdFx0XHQvLyBDYWxsIGFsbCBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gY29udGV4dCBhbmQgYXJndW1lbnRzXG5cdFx0XHRmaXJlV2l0aDogZnVuY3Rpb24oIGNvbnRleHQsIGFyZ3MgKSB7XG5cdFx0XHRcdGlmICggbGlzdCAmJiAoICFmaXJlZCB8fCBzdGFjayApICkge1xuXHRcdFx0XHRcdGFyZ3MgPSBhcmdzIHx8IFtdO1xuXHRcdFx0XHRcdGFyZ3MgPSBbIGNvbnRleHQsIGFyZ3Muc2xpY2UgPyBhcmdzLnNsaWNlKCkgOiBhcmdzIF07XG5cdFx0XHRcdFx0aWYgKCBmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRzdGFjay5wdXNoKCBhcmdzICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGZpcmUoIGFyZ3MgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ2FsbCBhbGwgdGhlIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHNcblx0XHRcdGZpcmU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRzZWxmLmZpcmVXaXRoKCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXG5cdFx0XHRmaXJlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWZpcmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0cmV0dXJuIHNlbGY7XG59O1xuXG5cbmpRdWVyeS5leHRlbmQoe1xuXG5cdERlZmVycmVkOiBmdW5jdGlvbiggZnVuYyApIHtcblx0XHR2YXIgdHVwbGVzID0gW1xuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgbGlzdGVuZXIgbGlzdCwgZmluYWwgc3RhdGVcblx0XHRcdFx0WyBcInJlc29sdmVcIiwgXCJkb25lXCIsIGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKSwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKSwgXCJyZWplY3RlZFwiIF0sXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKFwibWVtb3J5XCIpIF1cblx0XHRcdF0sXG5cdFx0XHRzdGF0ZSA9IFwicGVuZGluZ1wiLFxuXHRcdFx0cHJvbWlzZSA9IHtcblx0XHRcdFx0c3RhdGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBzdGF0ZTtcblx0XHRcdFx0fSxcblx0XHRcdFx0YWx3YXlzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5kb25lKCBhcmd1bWVudHMgKS5mYWlsKCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblx0XHRcdFx0dGhlbjogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cdFx0XHRcdFx0cmV0dXJuIGpRdWVyeS5EZWZlcnJlZChmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciBmbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBmbnNbIGkgXSApICYmIGZuc1sgaSBdO1xuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZFsgZG9uZSB8IGZhaWwgfCBwcm9ncmVzcyBdIGZvciBmb3J3YXJkaW5nIGFjdGlvbnMgdG8gbmV3RGVmZXJcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzFdIF0oZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHJldHVybmVkLnByb21pc2UgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnByb21pc2UoKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZG9uZSggbmV3RGVmZXIucmVzb2x2ZSApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5mYWlsKCBuZXdEZWZlci5yZWplY3QgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIG5ld0RlZmVyLm5vdGlmeSApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlclsgdHVwbGVbIDAgXSArIFwiV2l0aFwiIF0oIHRoaXMgPT09IHByb21pc2UgPyBuZXdEZWZlci5wcm9taXNlKCkgOiB0aGlzLCBmbiA/IFsgcmV0dXJuZWQgXSA6IGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdGZucyA9IG51bGw7XG5cdFx0XHRcdFx0fSkucHJvbWlzZSgpO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHQvLyBHZXQgYSBwcm9taXNlIGZvciB0aGlzIGRlZmVycmVkXG5cdFx0XHRcdC8vIElmIG9iaiBpcyBwcm92aWRlZCwgdGhlIHByb21pc2UgYXNwZWN0IGlzIGFkZGVkIHRvIHRoZSBvYmplY3Rcblx0XHRcdFx0cHJvbWlzZTogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRcdFx0XHRyZXR1cm4gb2JqICE9IG51bGwgPyBqUXVlcnkuZXh0ZW5kKCBvYmosIHByb21pc2UgKSA6IHByb21pc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRkZWZlcnJlZCA9IHt9O1xuXG5cdFx0Ly8gS2VlcCBwaXBlIGZvciBiYWNrLWNvbXBhdFxuXHRcdHByb21pc2UucGlwZSA9IHByb21pc2UudGhlbjtcblxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcblx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cdFx0XHR2YXIgbGlzdCA9IHR1cGxlWyAyIF0sXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDMgXTtcblxuXHRcdFx0Ly8gcHJvbWlzZVsgZG9uZSB8IGZhaWwgfCBwcm9ncmVzcyBdID0gbGlzdC5hZGRcblx0XHRcdHByb21pc2VbIHR1cGxlWzFdIF0gPSBsaXN0LmFkZDtcblxuXHRcdFx0Ly8gSGFuZGxlIHN0YXRlXG5cdFx0XHRpZiAoIHN0YXRlU3RyaW5nICkge1xuXHRcdFx0XHRsaXN0LmFkZChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHQvLyBzdGF0ZSA9IFsgcmVzb2x2ZWQgfCByZWplY3RlZCBdXG5cdFx0XHRcdFx0c3RhdGUgPSBzdGF0ZVN0cmluZztcblxuXHRcdFx0XHQvLyBbIHJlamVjdF9saXN0IHwgcmVzb2x2ZV9saXN0IF0uZGlzYWJsZTsgcHJvZ3Jlc3NfbGlzdC5sb2NrXG5cdFx0XHRcdH0sIHR1cGxlc1sgaSBeIDEgXVsgMiBdLmRpc2FibGUsIHR1cGxlc1sgMiBdWyAyIF0ubG9jayApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBkZWZlcnJlZFsgcmVzb2x2ZSB8IHJlamVjdCB8IG5vdGlmeSBdXG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbMF0gXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkZWZlcnJlZFsgdHVwbGVbMF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBkZWZlcnJlZCA/IHByb21pc2UgOiB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9O1xuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzBdICsgXCJXaXRoXCIgXSA9IGxpc3QuZmlyZVdpdGg7XG5cdFx0fSk7XG5cblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2Vcblx0XHRwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7XG5cblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XG5cdFx0aWYgKCBmdW5jICkge1xuXHRcdFx0ZnVuYy5jYWxsKCBkZWZlcnJlZCwgZGVmZXJyZWQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgZG9uZSFcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XG5cdH0sXG5cblx0Ly8gRGVmZXJyZWQgaGVscGVyXG5cdHdoZW46IGZ1bmN0aW9uKCBzdWJvcmRpbmF0ZSAvKiAsIC4uLiwgc3Vib3JkaW5hdGVOICovICkge1xuXHRcdHZhciBpID0gMCxcblx0XHRcdHJlc29sdmVWYWx1ZXMgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcblx0XHRcdGxlbmd0aCA9IHJlc29sdmVWYWx1ZXMubGVuZ3RoLFxuXG5cdFx0XHQvLyB0aGUgY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXG5cdFx0XHRyZW1haW5pbmcgPSBsZW5ndGggIT09IDEgfHwgKCBzdWJvcmRpbmF0ZSAmJiBqUXVlcnkuaXNGdW5jdGlvbiggc3Vib3JkaW5hdGUucHJvbWlzZSApICkgPyBsZW5ndGggOiAwLFxuXG5cdFx0XHQvLyB0aGUgbWFzdGVyIERlZmVycmVkLiBJZiByZXNvbHZlVmFsdWVzIGNvbnNpc3Qgb2Ygb25seSBhIHNpbmdsZSBEZWZlcnJlZCwganVzdCB1c2UgdGhhdC5cblx0XHRcdGRlZmVycmVkID0gcmVtYWluaW5nID09PSAxID8gc3Vib3JkaW5hdGUgOiBqUXVlcnkuRGVmZXJyZWQoKSxcblxuXHRcdFx0Ly8gVXBkYXRlIGZ1bmN0aW9uIGZvciBib3RoIHJlc29sdmUgYW5kIHByb2dyZXNzIHZhbHVlc1xuXHRcdFx0dXBkYXRlRnVuYyA9IGZ1bmN0aW9uKCBpLCBjb250ZXh0cywgdmFsdWVzICkge1xuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0XHRcdGNvbnRleHRzWyBpIF0gPSB0aGlzO1xuXHRcdFx0XHRcdHZhbHVlc1sgaSBdID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSA6IHZhbHVlO1xuXHRcdFx0XHRcdGlmICggdmFsdWVzID09PSBwcm9ncmVzc1ZhbHVlcyApIHtcblx0XHRcdFx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGgoIGNvbnRleHRzLCB2YWx1ZXMgKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKCAhKCAtLXJlbWFpbmluZyApICkge1xuXHRcdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNvbnRleHRzLCB2YWx1ZXMgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0XHR9LFxuXG5cdFx0XHRwcm9ncmVzc1ZhbHVlcywgcHJvZ3Jlc3NDb250ZXh0cywgcmVzb2x2ZUNvbnRleHRzO1xuXG5cdFx0Ly8gYWRkIGxpc3RlbmVycyB0byBEZWZlcnJlZCBzdWJvcmRpbmF0ZXM7IHRyZWF0IG90aGVycyBhcyByZXNvbHZlZFxuXHRcdGlmICggbGVuZ3RoID4gMSApIHtcblx0XHRcdHByb2dyZXNzVmFsdWVzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcblx0XHRcdHByb2dyZXNzQ29udGV4dHMgPSBuZXcgQXJyYXkoIGxlbmd0aCApO1xuXHRcdFx0cmVzb2x2ZUNvbnRleHRzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIHJlc29sdmVWYWx1ZXNbIGkgXSAmJiBqUXVlcnkuaXNGdW5jdGlvbiggcmVzb2x2ZVZhbHVlc1sgaSBdLnByb21pc2UgKSApIHtcblx0XHRcdFx0XHRyZXNvbHZlVmFsdWVzWyBpIF0ucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHQuZG9uZSggdXBkYXRlRnVuYyggaSwgcmVzb2x2ZUNvbnRleHRzLCByZXNvbHZlVmFsdWVzICkgKVxuXHRcdFx0XHRcdFx0LmZhaWwoIGRlZmVycmVkLnJlamVjdCApXG5cdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIHVwZGF0ZUZ1bmMoIGksIHByb2dyZXNzQ29udGV4dHMsIHByb2dyZXNzVmFsdWVzICkgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQtLXJlbWFpbmluZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGlmIHdlJ3JlIG5vdCB3YWl0aW5nIG9uIGFueXRoaW5nLCByZXNvbHZlIHRoZSBtYXN0ZXJcblx0XHRpZiAoICFyZW1haW5pbmcgKSB7XG5cdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggcmVzb2x2ZUNvbnRleHRzLCByZXNvbHZlVmFsdWVzICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcblx0fVxufSk7XG5cblxuLy8gVGhlIGRlZmVycmVkIHVzZWQgb24gRE9NIHJlYWR5XG52YXIgcmVhZHlMaXN0O1xuXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XG5cdC8vIEFkZCB0aGUgY2FsbGJhY2tcblx0alF1ZXJ5LnJlYWR5LnByb21pc2UoKS5kb25lKCBmbiApO1xuXG5cdHJldHVybiB0aGlzO1xufTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIElzIHRoZSBET00gcmVhZHkgdG8gYmUgdXNlZD8gU2V0IHRvIHRydWUgb25jZSBpdCBvY2N1cnMuXG5cdGlzUmVhZHk6IGZhbHNlLFxuXG5cdC8vIEEgY291bnRlciB0byB0cmFjayBob3cgbWFueSBpdGVtcyB0byB3YWl0IGZvciBiZWZvcmVcblx0Ly8gdGhlIHJlYWR5IGV2ZW50IGZpcmVzLiBTZWUgIzY3ODFcblx0cmVhZHlXYWl0OiAxLFxuXG5cdC8vIEhvbGQgKG9yIHJlbGVhc2UpIHRoZSByZWFkeSBldmVudFxuXHRob2xkUmVhZHk6IGZ1bmN0aW9uKCBob2xkICkge1xuXHRcdGlmICggaG9sZCApIHtcblx0XHRcdGpRdWVyeS5yZWFkeVdhaXQrKztcblx0XHR9IGVsc2Uge1xuXHRcdFx0alF1ZXJ5LnJlYWR5KCB0cnVlICk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIEhhbmRsZSB3aGVuIHRoZSBET00gaXMgcmVhZHlcblx0cmVhZHk6IGZ1bmN0aW9uKCB3YWl0ICkge1xuXG5cdFx0Ly8gQWJvcnQgaWYgdGhlcmUgYXJlIHBlbmRpbmcgaG9sZHMgb3Igd2UncmUgYWxyZWFkeSByZWFkeVxuXHRcdGlmICggd2FpdCA9PT0gdHJ1ZSA/IC0talF1ZXJ5LnJlYWR5V2FpdCA6IGpRdWVyeS5pc1JlYWR5ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFJlbWVtYmVyIHRoYXQgdGhlIERPTSBpcyByZWFkeVxuXHRcdGpRdWVyeS5pc1JlYWR5ID0gdHJ1ZTtcblxuXHRcdC8vIElmIGEgbm9ybWFsIERPTSBSZWFkeSBldmVudCBmaXJlZCwgZGVjcmVtZW50LCBhbmQgd2FpdCBpZiBuZWVkIGJlXG5cdFx0aWYgKCB3YWl0ICE9PSB0cnVlICYmIC0talF1ZXJ5LnJlYWR5V2FpdCA+IDAgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlcmUgYXJlIGZ1bmN0aW9ucyBib3VuZCwgdG8gZXhlY3V0ZVxuXHRcdHJlYWR5TGlzdC5yZXNvbHZlV2l0aCggZG9jdW1lbnQsIFsgalF1ZXJ5IF0gKTtcblxuXHRcdC8vIFRyaWdnZXIgYW55IGJvdW5kIHJlYWR5IGV2ZW50c1xuXHRcdGlmICggalF1ZXJ5LmZuLnRyaWdnZXJIYW5kbGVyICkge1xuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLnRyaWdnZXJIYW5kbGVyKCBcInJlYWR5XCIgKTtcblx0XHRcdGpRdWVyeSggZG9jdW1lbnQgKS5vZmYoIFwicmVhZHlcIiApO1xuXHRcdH1cblx0fVxufSk7XG5cbi8qKlxuICogVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcbiAqL1xuZnVuY3Rpb24gY29tcGxldGVkKCkge1xuXHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXHR3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCwgZmFsc2UgKTtcblx0alF1ZXJ5LnJlYWR5KCk7XG59XG5cbmpRdWVyeS5yZWFkeS5wcm9taXNlID0gZnVuY3Rpb24oIG9iaiApIHtcblx0aWYgKCAhcmVhZHlMaXN0ICkge1xuXG5cdFx0cmVhZHlMaXN0ID0galF1ZXJ5LkRlZmVycmVkKCk7XG5cblx0XHQvLyBDYXRjaCBjYXNlcyB3aGVyZSAkKGRvY3VtZW50KS5yZWFkeSgpIGlzIGNhbGxlZCBhZnRlciB0aGUgYnJvd3NlciBldmVudCBoYXMgYWxyZWFkeSBvY2N1cnJlZC5cblx0XHQvLyB3ZSBvbmNlIHRyaWVkIHRvIHVzZSByZWFkeVN0YXRlIFwiaW50ZXJhY3RpdmVcIiBoZXJlLCBidXQgaXQgY2F1c2VkIGlzc3VlcyBsaWtlIHRoZSBvbmVcblx0XHQvLyBkaXNjb3ZlcmVkIGJ5IENocmlzUyBoZXJlOiBodHRwOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMjI4MiNjb21tZW50OjE1XG5cdFx0aWYgKCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIgKSB7XG5cdFx0XHQvLyBIYW5kbGUgaXQgYXN5bmNocm9ub3VzbHkgdG8gYWxsb3cgc2NyaXB0cyB0aGUgb3Bwb3J0dW5pdHkgdG8gZGVsYXkgcmVhZHlcblx0XHRcdHNldFRpbWVvdXQoIGpRdWVyeS5yZWFkeSApO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gVXNlIHRoZSBoYW5keSBldmVudCBjYWxsYmFja1xuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCwgZmFsc2UgKTtcblxuXHRcdFx0Ly8gQSBmYWxsYmFjayB0byB3aW5kb3cub25sb2FkLCB0aGF0IHdpbGwgYWx3YXlzIHdvcmtcblx0XHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gcmVhZHlMaXN0LnByb21pc2UoIG9iaiApO1xufTtcblxuLy8gS2ljayBvZmYgdGhlIERPTSByZWFkeSBjaGVjayBldmVuIGlmIHRoZSB1c2VyIGRvZXMgbm90XG5qUXVlcnkucmVhZHkucHJvbWlzZSgpO1xuXG5cblxuXG4vLyBNdWx0aWZ1bmN0aW9uYWwgbWV0aG9kIHRvIGdldCBhbmQgc2V0IHZhbHVlcyBvZiBhIGNvbGxlY3Rpb25cbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxudmFyIGFjY2VzcyA9IGpRdWVyeS5hY2Nlc3MgPSBmdW5jdGlvbiggZWxlbXMsIGZuLCBrZXksIHZhbHVlLCBjaGFpbmFibGUsIGVtcHR5R2V0LCByYXcgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBlbGVtcy5sZW5ndGgsXG5cdFx0YnVsayA9IGtleSA9PSBudWxsO1xuXG5cdC8vIFNldHMgbWFueSB2YWx1ZXNcblx0aWYgKCBqUXVlcnkudHlwZSgga2V5ICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblx0XHRmb3IgKCBpIGluIGtleSApIHtcblx0XHRcdGpRdWVyeS5hY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5W2ldLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmF3ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGJ1bGsgKSB7XG5cdFx0XHQvLyBCdWxrIG9wZXJhdGlvbnMgcnVuIGFnYWluc3QgdGhlIGVudGlyZSBzZXRcblx0XHRcdGlmICggcmF3ICkge1xuXHRcdFx0XHRmbi5jYWxsKCBlbGVtcywgdmFsdWUgKTtcblx0XHRcdFx0Zm4gPSBudWxsO1xuXG5cdFx0XHQvLyAuLi5leGNlcHQgd2hlbiBleGVjdXRpbmcgZnVuY3Rpb24gdmFsdWVzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRidWxrID0gZm47XG5cdFx0XHRcdGZuID0gZnVuY3Rpb24oIGVsZW0sIGtleSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGJ1bGsuY2FsbCggalF1ZXJ5KCBlbGVtICksIHZhbHVlICk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRmbiggZWxlbXNbaV0sIGtleSwgcmF3ID8gdmFsdWUgOiB2YWx1ZS5jYWxsKCBlbGVtc1tpXSwgaSwgZm4oIGVsZW1zW2ldLCBrZXkgKSApICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGNoYWluYWJsZSA/XG5cdFx0ZWxlbXMgOlxuXG5cdFx0Ly8gR2V0c1xuXHRcdGJ1bGsgP1xuXHRcdFx0Zm4uY2FsbCggZWxlbXMgKSA6XG5cdFx0XHRsZW4gPyBmbiggZWxlbXNbMF0sIGtleSApIDogZW1wdHlHZXQ7XG59O1xuXG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBjYW4gaGF2ZSBkYXRhXG4gKi9cbmpRdWVyeS5hY2NlcHREYXRhID0gZnVuY3Rpb24oIG93bmVyICkge1xuXHQvLyBBY2NlcHRzIG9ubHk6XG5cdC8vICAtIE5vZGVcblx0Ly8gICAgLSBOb2RlLkVMRU1FTlRfTk9ERVxuXHQvLyAgICAtIE5vZGUuRE9DVU1FTlRfTk9ERVxuXHQvLyAgLSBPYmplY3Rcblx0Ly8gICAgLSBBbnlcblx0LyoganNoaW50IC1XMDE4ICovXG5cdHJldHVybiBvd25lci5ub2RlVHlwZSA9PT0gMSB8fCBvd25lci5ub2RlVHlwZSA9PT0gOSB8fCAhKCArb3duZXIubm9kZVR5cGUgKTtcbn07XG5cblxuZnVuY3Rpb24gRGF0YSgpIHtcblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8IDQsXG5cdC8vIE9sZCBXZWJLaXQgZG9lcyBub3QgaGF2ZSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMvZnJlZXplIG1ldGhvZCxcblx0Ly8gcmV0dXJuIG5ldyBlbXB0eSBvYmplY3QgaW5zdGVhZCB3aXRoIG5vIFtbc2V0XV0gYWNjZXNzb3Jcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLmNhY2hlID0ge30sIDAsIHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHt9O1xuXHRcdH1cblx0fSk7XG5cblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBNYXRoLnJhbmRvbSgpO1xufVxuXG5EYXRhLnVpZCA9IDE7XG5EYXRhLmFjY2VwdHMgPSBqUXVlcnkuYWNjZXB0RGF0YTtcblxuRGF0YS5wcm90b3R5cGUgPSB7XG5cdGtleTogZnVuY3Rpb24oIG93bmVyICkge1xuXHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxuXHRcdC8vIGJ1dCB3ZSBzaG91bGQgbm90LCBzZWUgIzgzMzUuXG5cdFx0Ly8gQWx3YXlzIHJldHVybiB0aGUga2V5IGZvciBhIGZyb3plbiBvYmplY3QuXG5cdFx0aWYgKCAhRGF0YS5hY2NlcHRzKCBvd25lciApICkge1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGRlc2NyaXB0b3IgPSB7fSxcblx0XHRcdC8vIENoZWNrIGlmIHRoZSBvd25lciBvYmplY3QgYWxyZWFkeSBoYXMgYSBjYWNoZSBrZXlcblx0XHRcdHVubG9jayA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblxuXHRcdC8vIElmIG5vdCwgY3JlYXRlIG9uZVxuXHRcdGlmICggIXVubG9jayApIHtcblx0XHRcdHVubG9jayA9IERhdGEudWlkKys7XG5cblx0XHRcdC8vIFNlY3VyZSBpdCBpbiBhIG5vbi1lbnVtZXJhYmxlLCBub24td3JpdGFibGUgcHJvcGVydHlcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRlc2NyaXB0b3JbIHRoaXMuZXhwYW5kbyBdID0geyB2YWx1ZTogdW5sb2NrIH07XG5cdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBvd25lciwgZGVzY3JpcHRvciApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDwgNFxuXHRcdFx0Ly8gRmFsbGJhY2sgdG8gYSBsZXNzIHNlY3VyZSBkZWZpbml0aW9uXG5cdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0ZGVzY3JpcHRvclsgdGhpcy5leHBhbmRvIF0gPSB1bmxvY2s7XG5cdFx0XHRcdGpRdWVyeS5leHRlbmQoIG93bmVyLCBkZXNjcmlwdG9yICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRW5zdXJlIHRoZSBjYWNoZSBvYmplY3Rcblx0XHRpZiAoICF0aGlzLmNhY2hlWyB1bmxvY2sgXSApIHtcblx0XHRcdHRoaXMuY2FjaGVbIHVubG9jayBdID0ge307XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHVubG9jaztcblx0fSxcblx0c2V0OiBmdW5jdGlvbiggb3duZXIsIGRhdGEsIHZhbHVlICkge1xuXHRcdHZhciBwcm9wLFxuXHRcdFx0Ly8gVGhlcmUgbWF5IGJlIGFuIHVubG9jayBhc3NpZ25lZCB0byB0aGlzIG5vZGUsXG5cdFx0XHQvLyBpZiB0aGVyZSBpcyBubyBlbnRyeSBmb3IgdGhpcyBcIm93bmVyXCIsIGNyZWF0ZSBvbmUgaW5saW5lXG5cdFx0XHQvLyBhbmQgc2V0IHRoZSB1bmxvY2sgYXMgdGhvdWdoIGFuIG93bmVyIGVudHJ5IGhhZCBhbHdheXMgZXhpc3RlZFxuXHRcdFx0dW5sb2NrID0gdGhpcy5rZXkoIG93bmVyICksXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGVbIHVubG9jayBdO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCBrZXksIHZhbHVlIF0gYXJnc1xuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRjYWNoZVsgZGF0YSBdID0gdmFsdWU7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBGcmVzaCBhc3NpZ25tZW50cyBieSBvYmplY3QgYXJlIHNoYWxsb3cgY29waWVkXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApICkge1xuXHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLmNhY2hlWyB1bmxvY2sgXSwgZGF0YSApO1xuXHRcdFx0Ly8gT3RoZXJ3aXNlLCBjb3B5IHRoZSBwcm9wZXJ0aWVzIG9uZS1ieS1vbmUgdG8gdGhlIGNhY2hlIG9iamVjdFxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggcHJvcCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGNhY2hlWyBwcm9wIF0gPSBkYXRhWyBwcm9wIF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNhY2hlO1xuXHR9LFxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdC8vIEVpdGhlciBhIHZhbGlkIGNhY2hlIGlzIGZvdW5kLCBvciB3aWxsIGJlIGNyZWF0ZWQuXG5cdFx0Ly8gTmV3IGNhY2hlcyB3aWxsIGJlIGNyZWF0ZWQgYW5kIHRoZSB1bmxvY2sgcmV0dXJuZWQsXG5cdFx0Ly8gYWxsb3dpbmcgZGlyZWN0IGFjY2VzcyB0byB0aGUgbmV3bHkgY3JlYXRlZFxuXHRcdC8vIGVtcHR5IGRhdGEgb2JqZWN0LiBBIHZhbGlkIG93bmVyIG9iamVjdCBtdXN0IGJlIHByb3ZpZGVkLlxuXHRcdHZhciBjYWNoZSA9IHRoaXMuY2FjaGVbIHRoaXMua2V5KCBvd25lciApIF07XG5cblx0XHRyZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgP1xuXHRcdFx0Y2FjaGUgOiBjYWNoZVsga2V5IF07XG5cdH0sXG5cdGFjY2VzczogZnVuY3Rpb24oIG93bmVyLCBrZXksIHZhbHVlICkge1xuXHRcdHZhciBzdG9yZWQ7XG5cdFx0Ly8gSW4gY2FzZXMgd2hlcmUgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBObyBrZXkgd2FzIHNwZWNpZmllZFxuXHRcdC8vICAgMi4gQSBzdHJpbmcga2V5IHdhcyBzcGVjaWZpZWQsIGJ1dCBubyB2YWx1ZSBwcm92aWRlZFxuXHRcdC8vXG5cdFx0Ly8gVGFrZSB0aGUgXCJyZWFkXCIgcGF0aCBhbmQgYWxsb3cgdGhlIGdldCBtZXRob2QgdG8gZGV0ZXJtaW5lXG5cdFx0Ly8gd2hpY2ggdmFsdWUgdG8gcmV0dXJuLCByZXNwZWN0aXZlbHkgZWl0aGVyOlxuXHRcdC8vXG5cdFx0Ly8gICAxLiBUaGUgZW50aXJlIGNhY2hlIG9iamVjdFxuXHRcdC8vICAgMi4gVGhlIGRhdGEgc3RvcmVkIGF0IHRoZSBrZXlcblx0XHQvL1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgfHxcblx0XHRcdFx0KChrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIikgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCkgKSB7XG5cblx0XHRcdHN0b3JlZCA9IHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XG5cblx0XHRcdHJldHVybiBzdG9yZWQgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHN0b3JlZCA6IHRoaXMuZ2V0KCBvd25lciwgalF1ZXJ5LmNhbWVsQ2FzZShrZXkpICk7XG5cdFx0fVxuXG5cdFx0Ly8gWypdV2hlbiB0aGUga2V5IGlzIG5vdCBhIHN0cmluZywgb3IgYm90aCBhIGtleSBhbmQgdmFsdWVcblx0XHQvLyBhcmUgc3BlY2lmaWVkLCBzZXQgb3IgZXh0ZW5kIChleGlzdGluZyBvYmplY3RzKSB3aXRoIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gQW4gb2JqZWN0IG9mIHByb3BlcnRpZXNcblx0XHQvLyAgIDIuIEEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vXG5cdFx0dGhpcy5zZXQoIG93bmVyLCBrZXksIHZhbHVlICk7XG5cblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcblx0XHQvLyByZXR1cm4gdGhlIGV4cGVjdGVkIGRhdGEgYmFzZWQgb24gd2hpY2ggcGF0aCB3YXMgdGFrZW5bKl1cblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoga2V5O1xuXHR9LFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHZhciBpLCBuYW1lLCBjYW1lbCxcblx0XHRcdHVubG9jayA9IHRoaXMua2V5KCBvd25lciApLFxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlWyB1bmxvY2sgXTtcblxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0aGlzLmNhY2hlWyB1bmxvY2sgXSA9IHt9O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBrZXkgKSApIHtcblx0XHRcdFx0Ly8gSWYgXCJuYW1lXCIgaXMgYW4gYXJyYXkgb2Yga2V5cy4uLlxuXHRcdFx0XHQvLyBXaGVuIGRhdGEgaXMgaW5pdGlhbGx5IGNyZWF0ZWQsIHZpYSAoXCJrZXlcIiwgXCJ2YWxcIikgc2lnbmF0dXJlLFxuXHRcdFx0XHQvLyBrZXlzIHdpbGwgYmUgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cblx0XHRcdFx0Ly8gU2luY2UgdGhlcmUgaXMgbm8gd2F5IHRvIHRlbGwgX2hvd18gYSBrZXkgd2FzIGFkZGVkLCByZW1vdmVcblx0XHRcdFx0Ly8gYm90aCBwbGFpbiBrZXkgYW5kIGNhbWVsQ2FzZSBrZXkuICMxMjc4NlxuXHRcdFx0XHQvLyBUaGlzIHdpbGwgb25seSBwZW5hbGl6ZSB0aGUgYXJyYXkgYXJndW1lbnQgcGF0aC5cblx0XHRcdFx0bmFtZSA9IGtleS5jb25jYXQoIGtleS5tYXAoIGpRdWVyeS5jYW1lbENhc2UgKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2FtZWwgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcblx0XHRcdFx0Ly8gVHJ5IHRoZSBzdHJpbmcgYXMgYSBrZXkgYmVmb3JlIGFueSBtYW5pcHVsYXRpb25cblx0XHRcdFx0aWYgKCBrZXkgaW4gY2FjaGUgKSB7XG5cdFx0XHRcdFx0bmFtZSA9IFsga2V5LCBjYW1lbCBdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cblx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGNyZWF0ZSBhbiBhcnJheSBieSBtYXRjaGluZyBub24td2hpdGVzcGFjZVxuXHRcdFx0XHRcdG5hbWUgPSBjYW1lbDtcblx0XHRcdFx0XHRuYW1lID0gbmFtZSBpbiBjYWNoZSA/XG5cdFx0XHRcdFx0XHRbIG5hbWUgXSA6ICggbmFtZS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpID0gbmFtZS5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBuYW1lWyBpIF0gXTtcblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcblx0XHRyZXR1cm4gIWpRdWVyeS5pc0VtcHR5T2JqZWN0KFxuXHRcdFx0dGhpcy5jYWNoZVsgb3duZXJbIHRoaXMuZXhwYW5kbyBdIF0gfHwge31cblx0XHQpO1xuXHR9LFxuXHRkaXNjYXJkOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0aWYgKCBvd25lclsgdGhpcy5leHBhbmRvIF0gKSB7XG5cdFx0XHRkZWxldGUgdGhpcy5jYWNoZVsgb3duZXJbIHRoaXMuZXhwYW5kbyBdIF07XG5cdFx0fVxuXHR9XG59O1xudmFyIGRhdGFfcHJpdiA9IG5ldyBEYXRhKCk7XG5cbnZhciBkYXRhX3VzZXIgPSBuZXcgRGF0YSgpO1xuXG5cblxuLypcblx0SW1wbGVtZW50YXRpb24gU3VtbWFyeVxuXG5cdDEuIEVuZm9yY2UgQVBJIHN1cmZhY2UgYW5kIHNlbWFudGljIGNvbXBhdGliaWxpdHkgd2l0aCAxLjkueCBicmFuY2hcblx0Mi4gSW1wcm92ZSB0aGUgbW9kdWxlJ3MgbWFpbnRhaW5hYmlsaXR5IGJ5IHJlZHVjaW5nIHRoZSBzdG9yYWdlXG5cdFx0cGF0aHMgdG8gYSBzaW5nbGUgbWVjaGFuaXNtLlxuXHQzLiBVc2UgdGhlIHNhbWUgc2luZ2xlIG1lY2hhbmlzbSB0byBzdXBwb3J0IFwicHJpdmF0ZVwiIGFuZCBcInVzZXJcIiBkYXRhLlxuXHQ0LiBfTmV2ZXJfIGV4cG9zZSBcInByaXZhdGVcIiBkYXRhIHRvIHVzZXIgY29kZSAoVE9ETzogRHJvcCBfZGF0YSwgX3JlbW92ZURhdGEpXG5cdDUuIEF2b2lkIGV4cG9zaW5nIGltcGxlbWVudGF0aW9uIGRldGFpbHMgb24gdXNlciBvYmplY3RzIChlZy4gZXhwYW5kbyBwcm9wZXJ0aWVzKVxuXHQ2LiBQcm92aWRlIGEgY2xlYXIgcGF0aCBmb3IgaW1wbGVtZW50YXRpb24gdXBncmFkZSB0byBXZWFrTWFwIGluIDIwMTRcbiovXG52YXIgcmJyYWNlID0gL14oPzpcXHtbXFx3XFxXXSpcXH18XFxbW1xcd1xcV10qXFxdKSQvLFxuXHRybXVsdGlEYXNoID0gLyhbQS1aXSkvZztcblxuZnVuY3Rpb24gZGF0YUF0dHIoIGVsZW0sIGtleSwgZGF0YSApIHtcblx0dmFyIG5hbWU7XG5cblx0Ly8gSWYgbm90aGluZyB3YXMgZm91bmQgaW50ZXJuYWxseSwgdHJ5IHRvIGZldGNoIGFueVxuXHQvLyBkYXRhIGZyb20gdGhlIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGVcblx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRuYW1lID0gXCJkYXRhLVwiICsga2V5LnJlcGxhY2UoIHJtdWx0aURhc2gsIFwiLSQxXCIgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdGRhdGEgPSBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApO1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhID09PSBcInRydWVcIiA/IHRydWUgOlxuXHRcdFx0XHRcdGRhdGEgPT09IFwiZmFsc2VcIiA/IGZhbHNlIDpcblx0XHRcdFx0XHRkYXRhID09PSBcIm51bGxcIiA/IG51bGwgOlxuXHRcdFx0XHRcdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdFx0XHRcdFx0K2RhdGEgKyBcIlwiID09PSBkYXRhID8gK2RhdGEgOlxuXHRcdFx0XHRcdHJicmFjZS50ZXN0KCBkYXRhICkgPyBqUXVlcnkucGFyc2VKU09OKCBkYXRhICkgOlxuXHRcdFx0XHRcdGRhdGE7XG5cdFx0XHR9IGNhdGNoKCBlICkge31cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHNldCB0aGUgZGF0YSBzbyBpdCBpc24ndCBjaGFuZ2VkIGxhdGVyXG5cdFx0XHRkYXRhX3VzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGRhdGE7XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRoYXNEYXRhOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGF0YV91c2VyLmhhc0RhdGEoIGVsZW0gKSB8fCBkYXRhX3ByaXYuaGFzRGF0YSggZWxlbSApO1xuXHR9LFxuXG5cdGRhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhX3VzZXIuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YV91c2VyLnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9LFxuXG5cdC8vIFRPRE86IE5vdyB0aGF0IGFsbCBjYWxscyB0byBfZGF0YSBhbmQgX3JlbW92ZURhdGEgaGF2ZSBiZWVuIHJlcGxhY2VkXG5cdC8vIHdpdGggZGlyZWN0IGNhbGxzIHRvIGRhdGFfcHJpdiBtZXRob2RzLCB0aGVzZSBjYW4gYmUgZGVwcmVjYXRlZC5cblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xuXHRcdHJldHVybiBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0X3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRhdHRycyA9IGVsZW0gJiYgZWxlbS5hdHRyaWJ1dGVzO1xuXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggdGhpcy5sZW5ndGggKSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCBlbGVtICk7XG5cblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhX3ByaXYuZ2V0KCBlbGVtLCBcImhhc0RhdGFBdHRyc1wiICkgKSB7XG5cdFx0XHRcdFx0aSA9IGF0dHJzLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMStcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxuXHRcdFx0XHRcdFx0aWYgKCBhdHRyc1sgaSBdICkge1xuXHRcdFx0XHRcdFx0XHRuYW1lID0gYXR0cnNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUuc2xpY2UoNSkgKTtcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZGF0YV9wcml2LnNldCggZWxlbSwgXCJoYXNEYXRhQXR0cnNcIiwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBkYXRhO1xuXHRcdH1cblxuXHRcdC8vIFNldHMgbXVsdGlwbGUgdmFsdWVzXG5cdFx0aWYgKCB0eXBlb2Yga2V5ID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGF0YV91c2VyLnNldCggdGhpcywga2V5ICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgZGF0YSxcblx0XHRcdFx0Y2FtZWxLZXkgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcblxuXHRcdFx0Ly8gVGhlIGNhbGxpbmcgalF1ZXJ5IG9iamVjdCAoZWxlbWVudCBtYXRjaGVzKSBpcyBub3QgZW1wdHlcblx0XHRcdC8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlXG5cdFx0XHQvLyBgdmFsdWVgIHBhcmFtZXRlciB3YXMgbm90IHVuZGVmaW5lZC4gQW4gZW1wdHkgalF1ZXJ5IG9iamVjdFxuXHRcdFx0Ly8gd2lsbCByZXN1bHQgaW4gYHVuZGVmaW5lZGAgZm9yIGVsZW0gPSB0aGlzWyAwIF0gd2hpY2ggd2lsbFxuXHRcdFx0Ly8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS5cblx0XHRcdGlmICggZWxlbSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIGdldCBkYXRhIGZyb20gdGhlIGNhY2hlXG5cdFx0XHRcdC8vIHdpdGggdGhlIGtleSBhcy1pc1xuXHRcdFx0XHRkYXRhID0gZGF0YV91c2VyLmdldCggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgY2FtZWxpemVkXG5cdFx0XHRcdGRhdGEgPSBkYXRhX3VzZXIuZ2V0KCBlbGVtLCBjYW1lbEtleSApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gXCJkaXNjb3ZlclwiIHRoZSBkYXRhIGluXG5cdFx0XHRcdC8vIEhUTUw1IGN1c3RvbSBkYXRhLSogYXR0cnNcblx0XHRcdFx0ZGF0YSA9IGRhdGFBdHRyKCBlbGVtLCBjYW1lbEtleSwgdW5kZWZpbmVkICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBGaXJzdCwgYXR0ZW1wdCB0byBzdG9yZSBhIGNvcHkgb3IgcmVmZXJlbmNlIG9mIGFueVxuXHRcdFx0XHQvLyBkYXRhIHRoYXQgbWlnaHQndmUgYmVlbiBzdG9yZSB3aXRoIGEgY2FtZWxDYXNlZCBrZXkuXG5cdFx0XHRcdHZhciBkYXRhID0gZGF0YV91c2VyLmdldCggdGhpcywgY2FtZWxLZXkgKTtcblxuXHRcdFx0XHQvLyBGb3IgSFRNTDUgZGF0YS0qIGF0dHJpYnV0ZSBpbnRlcm9wLCB3ZSBoYXZlIHRvXG5cdFx0XHRcdC8vIHN0b3JlIHByb3BlcnR5IG5hbWVzIHdpdGggZGFzaGVzIGluIGEgY2FtZWxDYXNlIGZvcm0uXG5cdFx0XHRcdC8vIFRoaXMgbWlnaHQgbm90IGFwcGx5IHRvIGFsbCBwcm9wZXJ0aWVzLi4uKlxuXHRcdFx0XHRkYXRhX3VzZXIuc2V0KCB0aGlzLCBjYW1lbEtleSwgdmFsdWUgKTtcblxuXHRcdFx0XHQvLyAqLi4uIEluIHRoZSBjYXNlIG9mIHByb3BlcnRpZXMgdGhhdCBtaWdodCBfYWN0dWFsbHlfXG5cdFx0XHRcdC8vIGhhdmUgZGFzaGVzLCB3ZSBuZWVkIHRvIGFsc28gc3RvcmUgYSBjb3B5IG9mIHRoYXRcblx0XHRcdFx0Ly8gdW5jaGFuZ2VkIHByb3BlcnR5LlxuXHRcdFx0XHRpZiAoIGtleS5pbmRleE9mKFwiLVwiKSAhPT0gLTEgJiYgZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGRhdGFfdXNlci5zZXQoIHRoaXMsIGtleSwgdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxLCBudWxsLCB0cnVlICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGtleSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGF0YV91c2VyLnJlbW92ZSggdGhpcywga2V5ICk7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5leHRlbmQoe1xuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHF1ZXVlO1xuXG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0dHlwZSA9ICggdHlwZSB8fCBcImZ4XCIgKSArIFwicXVldWVcIjtcblx0XHRcdHF1ZXVlID0gZGF0YV9wcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IGpRdWVyeS5pc0FycmF5KCBkYXRhICkgKSB7XG5cdFx0XHRcdFx0cXVldWUgPSBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KGRhdGEpICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGNsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gbm90IGludGVuZGVkIGZvciBwdWJsaWMgY29uc3VtcHRpb24gLSBnZW5lcmF0ZXMgYSBxdWV1ZUhvb2tzIG9iamVjdCwgb3IgcmV0dXJucyB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFfcHJpdi5nZXQoIGVsZW0sIGtleSApIHx8IGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIGtleSwge1xuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKS5hZGQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRhdGFfcHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0pXG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0cXVldWU6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBzZXR0ZXIgPSAyO1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGRhdGEgPSB0eXBlO1xuXHRcdFx0dHlwZSA9IFwiZnhcIjtcblx0XHRcdHNldHRlci0tO1xuXHRcdH1cblxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCA8IHNldHRlciApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucXVldWUoIHRoaXNbMF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTtcblxuXHRcdFx0XHQvLyBlbnN1cmUgYSBob29rcyBmb3IgdGhpcyBxdWV1ZVxuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiAmJiBxdWV1ZVswXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH0sXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdH0pO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cdC8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGVcblx0Ly8gYXJlIGVtcHRpZWQgKGZ4IGlzIHRoZSB0eXBlIGJ5IGRlZmF1bHQpXG5cdHByb21pc2U6IGZ1bmN0aW9uKCB0eXBlLCBvYmogKSB7XG5cdFx0dmFyIHRtcCxcblx0XHRcdGNvdW50ID0gMSxcblx0XHRcdGRlZmVyID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRlbGVtZW50cyA9IHRoaXMsXG5cdFx0XHRpID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRyZXNvbHZlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggISggLS1jb3VudCApICkge1xuXHRcdFx0XHRcdGRlZmVyLnJlc29sdmVXaXRoKCBlbGVtZW50cywgWyBlbGVtZW50cyBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0b2JqID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG1wID0gZGF0YV9wcml2LmdldCggZWxlbWVudHNbIGkgXSwgdHlwZSArIFwicXVldWVIb29rc1wiICk7XG5cdFx0XHRpZiAoIHRtcCAmJiB0bXAuZW1wdHkgKSB7XG5cdFx0XHRcdGNvdW50Kys7XG5cdFx0XHRcdHRtcC5lbXB0eS5hZGQoIHJlc29sdmUgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmVzb2x2ZSgpO1xuXHRcdHJldHVybiBkZWZlci5wcm9taXNlKCBvYmogKTtcblx0fVxufSk7XG52YXIgcG51bSA9ICgvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLykuc291cmNlO1xuXG52YXIgY3NzRXhwYW5kID0gWyBcIlRvcFwiLCBcIlJpZ2h0XCIsIFwiQm90dG9tXCIsIFwiTGVmdFwiIF07XG5cbnZhciBpc0hpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblx0XHQvLyBpc0hpZGRlbiBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXHRcdHJldHVybiBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApID09PSBcIm5vbmVcIiB8fCAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblx0fTtcblxudmFyIHJjaGVja2FibGVUeXBlID0gKC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pKTtcblxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdGRpdiA9IGZyYWdtZW50LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKSxcblx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXG5cdC8vICMxMTIxNyAtIFdlYktpdCBsb3NlcyBjaGVjayB3aGVuIHRoZSBuYW1lIGlzIGFmdGVyIHRoZSBjaGVja2VkIGF0dHJpYnV0ZVxuXHQvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG5lZWQgLnNldEF0dHJpYnV0ZSBmb3IgV1dBXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwiY2hlY2tlZFwiLCBcImNoZWNrZWRcIiApO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcInRcIiApO1xuXG5cdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKTtcblxuXHQvLyBTdXBwb3J0OiBTYWZhcmkgNS4xLCBpT1MgNS4xLCBBbmRyb2lkIDQueCwgQW5kcm9pZCAyLjNcblx0Ly8gb2xkIFdlYktpdCBkb2Vzbid0IGNsb25lIGNoZWNrZWQgc3RhdGUgY29ycmVjdGx5IGluIGZyYWdtZW50c1xuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XG5cblx0Ly8gTWFrZSBzdXJlIHRleHRhcmVhIChhbmQgY2hlY2tib3gpIGRlZmF1bHRWYWx1ZSBpcyBwcm9wZXJseSBjbG9uZWRcblx0Ly8gU3VwcG9ydDogSUU5LUlFMTErXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcblx0c3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCA9ICEhZGl2LmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWU7XG59KSgpO1xudmFyIHN0cnVuZGVmaW5lZCA9IHR5cGVvZiB1bmRlZmluZWQ7XG5cblxuXG5zdXBwb3J0LmZvY3VzaW5CdWJibGVzID0gXCJvbmZvY3VzaW5cIiBpbiB3aW5kb3c7XG5cblxudmFyXG5cdHJrZXlFdmVudCA9IC9ea2V5Lyxcblx0cm1vdXNlRXZlbnQgPSAvXig/Om1vdXNlfHBvaW50ZXJ8Y29udGV4dG1lbnUpfGNsaWNrLyxcblx0cmZvY3VzTW9ycGggPSAvXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC8sXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpJC87XG5cbmZ1bmN0aW9uIHJldHVyblRydWUoKSB7XG5cdHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZXR1cm5GYWxzZSgpIHtcblx0cmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcblx0fSBjYXRjaCAoIGVyciApIHsgfVxufVxuXG4vKlxuICogSGVscGVyIGZ1bmN0aW9ucyBmb3IgbWFuYWdpbmcgZXZlbnRzIC0tIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgaW50ZXJmYWNlLlxuICogUHJvcHMgdG8gRGVhbiBFZHdhcmRzJyBhZGRFdmVudCBsaWJyYXJ5IGZvciBtYW55IG9mIHRoZSBpZGVhcy5cbiAqL1xualF1ZXJ5LmV2ZW50ID0ge1xuXG5cdGdsb2JhbDoge30sXG5cblx0YWRkOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIGRhdGEsIHNlbGVjdG9yICkge1xuXG5cdFx0dmFyIGhhbmRsZU9iakluLCBldmVudEhhbmRsZSwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFfcHJpdi5nZXQoIGVsZW0gKTtcblxuXHRcdC8vIERvbid0IGF0dGFjaCBldmVudHMgdG8gbm9EYXRhIG9yIHRleHQvY29tbWVudCBub2RlcyAoYnV0IGFsbG93IHBsYWluIG9iamVjdHMpXG5cdFx0aWYgKCAhZWxlbURhdGEgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGFuIG9iamVjdCBvZiBjdXN0b20gZGF0YSBpbiBsaWV1IG9mIHRoZSBoYW5kbGVyXG5cdFx0aWYgKCBoYW5kbGVyLmhhbmRsZXIgKSB7XG5cdFx0XHRoYW5kbGVPYmpJbiA9IGhhbmRsZXI7XG5cdFx0XHRoYW5kbGVyID0gaGFuZGxlT2JqSW4uaGFuZGxlcjtcblx0XHRcdHNlbGVjdG9yID0gaGFuZGxlT2JqSW4uc2VsZWN0b3I7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cykgKSB7XG5cdFx0XHRldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgPSB7fTtcblx0XHR9XG5cdFx0aWYgKCAhKGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlKSApIHtcblx0XHRcdGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlID0gZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdC8vIERpc2NhcmQgdGhlIHNlY29uZCBldmVudCBvZiBhIGpRdWVyeS5ldmVudC50cmlnZ2VyKCkgYW5kXG5cdFx0XHRcdC8vIHdoZW4gYW4gZXZlbnQgaXMgY2FsbGVkIGFmdGVyIGEgcGFnZSBoYXMgdW5sb2FkZWRcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IHN0cnVuZGVmaW5lZCAmJiBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICE9PSBlLnR5cGUgP1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSBtdWx0aXBsZSBldmVudHMgc2VwYXJhdGVkIGJ5IGEgc3BhY2Vcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbdF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsxXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsyXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBldmVudCBjaGFuZ2VzIGl0cyB0eXBlLCB1c2UgdGhlIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBjaGFuZ2VkIHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBJZiBzZWxlY3RvciBkZWZpbmVkLCBkZXRlcm1pbmUgc3BlY2lhbCBldmVudCBhcGkgdHlwZSwgb3RoZXJ3aXNlIGdpdmVuIHR5cGVcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblxuXHRcdFx0Ly8gVXBkYXRlIHNwZWNpYWwgYmFzZWQgb24gbmV3bHkgcmVzZXQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIGhhbmRsZU9iaiBpcyBwYXNzZWQgdG8gYWxsIGV2ZW50IGhhbmRsZXJzXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0b3JpZ1R5cGU6IG9yaWdUeXBlLFxuXHRcdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxuXHRcdFx0XHRndWlkOiBoYW5kbGVyLmd1aWQsXG5cdFx0XHRcdHNlbGVjdG9yOiBzZWxlY3Rvcixcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcblx0XHRcdFx0bmFtZXNwYWNlOiBuYW1lc3BhY2VzLmpvaW4oXCIuXCIpXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xuXG5cdFx0XHQvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdFxuXHRcdFx0aWYgKCAhKGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0pICkge1xuXHRcdFx0XHRoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdID0gW107XG5cdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwO1xuXG5cdFx0XHRcdC8vIE9ubHkgdXNlIGFkZEV2ZW50TGlzdGVuZXIgaWYgdGhlIHNwZWNpYWwgZXZlbnRzIGhhbmRsZXIgcmV0dXJucyBmYWxzZVxuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnNldHVwIHx8IHNwZWNpYWwuc2V0dXAuY2FsbCggZWxlbSwgZGF0YSwgbmFtZXNwYWNlcywgZXZlbnRIYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlLCBmYWxzZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNwZWNpYWwuYWRkICkge1xuXHRcdFx0XHRzcGVjaWFsLmFkZC5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblxuXHRcdFx0XHRpZiAoICFoYW5kbGVPYmouaGFuZGxlci5ndWlkICkge1xuXHRcdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyLmd1aWQgPSBoYW5kbGVyLmd1aWQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIHRvIHRoZSBlbGVtZW50J3MgaGFuZGxlciBsaXN0LCBkZWxlZ2F0ZXMgaW4gZnJvbnRcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XG5cdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaGFuZGxlcnMuZGVsZWdhdGVDb3VudCsrLCAwLCBoYW5kbGVPYmogKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIGV2ZW50cyBoYXZlIGV2ZXIgYmVlbiB1c2VkLCBmb3IgZXZlbnQgb3B0aW1pemF0aW9uXG5cdFx0XHRqUXVlcnkuZXZlbnQuZ2xvYmFsWyB0eXBlIF0gPSB0cnVlO1xuXHRcdH1cblxuXHR9LFxuXG5cdC8vIERldGFjaCBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzIGZyb20gYW4gZWxlbWVudFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgc2VsZWN0b3IsIG1hcHBlZFR5cGVzICkge1xuXG5cdFx0dmFyIGosIG9yaWdDb3VudCwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFfcHJpdi5oYXNEYXRhKCBlbGVtICkgJiYgZGF0YV9wcml2LmdldCggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgIShldmVudHMgPSBlbGVtRGF0YS5ldmVudHMpICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbdF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsxXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsyXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbMl0gJiYgbmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbihcIlxcXFwuKD86LipcXFxcLnwpXCIpICsgXCIoXFxcXC58JClcIiApO1xuXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXG5cdFx0XHRvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XG5cblx0XHRcdFx0aWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJlxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXG5cdFx0XHRcdFx0KCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJlxuXHRcdFx0XHRcdCggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09IFwiKipcIiAmJiBoYW5kbGVPYmouc2VsZWN0b3IgKSApIHtcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcblxuXHRcdFx0XHRcdGlmICggaGFuZGxlT2JqLnNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIHNwZWNpYWwucmVtb3ZlICkge1xuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBnZW5lcmljIGV2ZW50IGhhbmRsZXIgaWYgd2UgcmVtb3ZlZCBzb21ldGhpbmcgYW5kIG5vIG1vcmUgaGFuZGxlcnMgZXhpc3Rcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxuXHRcdFx0aWYgKCBvcmlnQ291bnQgJiYgIWhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC50ZWFyZG93biB8fCBzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkZWxldGUgZWxlbURhdGEuaGFuZGxlO1xuXHRcdFx0ZGF0YV9wcml2LnJlbW92ZSggZWxlbSwgXCJldmVudHNcIiApO1xuXHRcdH1cblx0fSxcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggZXZlbnQsIGRhdGEsIGVsZW0sIG9ubHlIYW5kbGVycyApIHtcblxuXHRcdHZhciBpLCBjdXIsIHRtcCwgYnViYmxlVHlwZSwgb250eXBlLCBoYW5kbGUsIHNwZWNpYWwsXG5cdFx0XHRldmVudFBhdGggPSBbIGVsZW0gfHwgZG9jdW1lbnQgXSxcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXG5cdFx0XHRuYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcIm5hbWVzcGFjZVwiICkgPyBldmVudC5uYW1lc3BhY2Uuc3BsaXQoXCIuXCIpIDogW107XG5cblx0XHRjdXIgPSB0bXAgPSBlbGVtID0gZWxlbSB8fCBkb2N1bWVudDtcblxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXG5cdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gZm9jdXMvYmx1ciBtb3JwaHMgdG8gZm9jdXNpbi9vdXQ7IGVuc3VyZSB3ZSdyZSBub3QgZmlyaW5nIHRoZW0gcmlnaHQgbm93XG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZS5pbmRleE9mKFwiLlwiKSA+PSAwICkge1xuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoXCIuXCIpO1xuXHRcdFx0dHlwZSA9IG5hbWVzcGFjZXMuc2hpZnQoKTtcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xuXHRcdH1cblx0XHRvbnR5cGUgPSB0eXBlLmluZGV4T2YoXCI6XCIpIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRldmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCB0eXBlLCB0eXBlb2YgZXZlbnQgPT09IFwib2JqZWN0XCIgJiYgZXZlbnQgKTtcblxuXHRcdC8vIFRyaWdnZXIgYml0bWFzazogJiAxIGZvciBuYXRpdmUgaGFuZGxlcnM7ICYgMiBmb3IgalF1ZXJ5IChhbHdheXMgdHJ1ZSlcblx0XHRldmVudC5pc1RyaWdnZXIgPSBvbmx5SGFuZGxlcnMgPyAyIDogMztcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oXCIuXCIpO1xuXHRcdGV2ZW50Lm5hbWVzcGFjZV9yZSA9IGV2ZW50Lm5hbWVzcGFjZSA/XG5cdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKFwiXFxcXC4oPzouKlxcXFwufClcIikgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xuXHRcdFx0aWYgKCAhcmZvY3VzTW9ycGgudGVzdCggYnViYmxlVHlwZSArIHR5cGUgKSApIHtcblx0XHRcdFx0Y3VyID0gY3VyLnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCA7IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0dG1wID0gY3VyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcblx0XHRcdGlmICggdG1wID09PSAoZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50KSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgaGFuZGxlcnMgb24gdGhlIGV2ZW50IHBhdGhcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChjdXIgPSBldmVudFBhdGhbaSsrXSkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cblx0XHRcdGV2ZW50LnR5cGUgPSBpID4gMSA/XG5cdFx0XHRcdGJ1YmJsZVR5cGUgOlxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XG5cblx0XHRcdC8vIGpRdWVyeSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSAoIGRhdGFfcHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSAmJiBkYXRhX3ByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcblx0XHRcdGlmICggaGFuZGxlICkge1xuXHRcdFx0XHRoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBOYXRpdmUgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XG5cdFx0XHRpZiAoIGhhbmRsZSAmJiBoYW5kbGUuYXBwbHkgJiYgalF1ZXJ5LmFjY2VwdERhdGEoIGN1ciApICkge1xuXHRcdFx0XHRldmVudC5yZXN1bHQgPSBoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRldmVudC50eXBlID0gdHlwZTtcblxuXHRcdC8vIElmIG5vYm9keSBwcmV2ZW50ZWQgdGhlIGRlZmF1bHQgYWN0aW9uLCBkbyBpdCBub3dcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xuXG5cdFx0XHRpZiAoICghc3BlY2lhbC5fZGVmYXVsdCB8fCBzcGVjaWFsLl9kZWZhdWx0LmFwcGx5KCBldmVudFBhdGgucG9wKCksIGRhdGEgKSA9PT0gZmFsc2UpICYmXG5cdFx0XHRcdGpRdWVyeS5hY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cblx0XHRcdFx0Ly8gQ2FsbCBhIG5hdGl2ZSBET00gbWV0aG9kIG9uIHRoZSB0YXJnZXQgd2l0aCB0aGUgc2FtZSBuYW1lIG5hbWUgYXMgdGhlIGV2ZW50LlxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAoIzYxNzApXG5cdFx0XHRcdGlmICggb250eXBlICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXG5cdFx0XHRcdFx0dG1wID0gZWxlbVsgb250eXBlIF07XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gbnVsbDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBQcmV2ZW50IHJlLXRyaWdnZXJpbmcgb2YgdGhlIHNhbWUgZXZlbnQsIHNpbmNlIHdlIGFscmVhZHkgYnViYmxlZCBpdCBhYm92ZVxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB0eXBlO1xuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPSB1bmRlZmluZWQ7XG5cblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcblx0XHRcdFx0XHRcdGVsZW1bIG9udHlwZSBdID0gdG1wO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0ZGlzcGF0Y2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxuXHRcdGV2ZW50ID0galF1ZXJ5LmV2ZW50LmZpeCggZXZlbnQgKTtcblxuXHRcdHZhciBpLCBqLCByZXQsIG1hdGNoZWQsIGhhbmRsZU9iaixcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLFxuXHRcdFx0aGFuZGxlcnMgPSAoIGRhdGFfcHJpdi5nZXQoIHRoaXMsIFwiZXZlbnRzXCIgKSB8fCB7fSApWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1swXSA9IGV2ZW50O1xuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XG5cblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0pICYmICFldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRcdC8vIFRyaWdnZXJlZCBldmVudCBtdXN0IGVpdGhlciAxKSBoYXZlIG5vIG5hbWVzcGFjZSwgb3Jcblx0XHRcdFx0Ly8gMikgaGF2ZSBuYW1lc3BhY2UocykgYSBzdWJzZXQgb3IgZXF1YWwgdG8gdGhvc2UgaW4gdGhlIGJvdW5kIGV2ZW50IChib3RoIGNhbiBoYXZlIG5vIG5hbWVzcGFjZSkuXG5cdFx0XHRcdGlmICggIWV2ZW50Lm5hbWVzcGFjZV9yZSB8fCBldmVudC5uYW1lc3BhY2VfcmUudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkge1xuXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xuXHRcdFx0XHRcdGV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTtcblxuXHRcdFx0XHRcdHJldCA9ICggKGpRdWVyeS5ldmVudC5zcGVjaWFsWyBoYW5kbGVPYmoub3JpZ1R5cGUgXSB8fCB7fSkuaGFuZGxlIHx8IGhhbmRsZU9iai5oYW5kbGVyIClcblx0XHRcdFx0XHRcdFx0LmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChldmVudC5yZXN1bHQgPSByZXQpID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxuXHRcdGlmICggc3BlY2lhbC5wb3N0RGlzcGF0Y2ggKSB7XG5cdFx0XHRzcGVjaWFsLnBvc3REaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0aGFuZGxlcnM6IGZ1bmN0aW9uKCBldmVudCwgaGFuZGxlcnMgKSB7XG5cdFx0dmFyIGksIG1hdGNoZXMsIHNlbCwgaGFuZGxlT2JqLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRkZWxlZ2F0ZUNvdW50ID0gaGFuZGxlcnMuZGVsZWdhdGVDb3VudCxcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcblxuXHRcdC8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnNcblx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAoIzEzMTgwKVxuXHRcdC8vIEF2b2lkIG5vbi1sZWZ0LWNsaWNrIGJ1YmJsaW5nIGluIEZpcmVmb3ggKCMzODYxKVxuXHRcdGlmICggZGVsZWdhdGVDb3VudCAmJiBjdXIubm9kZVR5cGUgJiYgKCFldmVudC5idXR0b24gfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiKSApIHtcblxuXHRcdFx0Zm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXG5cdFx0XHRcdGlmICggY3VyLmRpc2FibGVkICE9PSB0cnVlIHx8IGV2ZW50LnR5cGUgIT09IFwiY2xpY2tcIiApIHtcblx0XHRcdFx0XHRtYXRjaGVzID0gW107XG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBkZWxlZ2F0ZUNvdW50OyBpKysgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaSBdO1xuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBjb25mbGljdCB3aXRoIE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoIzEzMjAzKVxuXHRcdFx0XHRcdFx0c2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgXCIgXCI7XG5cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlc1sgc2VsIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID9cblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+PSAwIDpcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVzLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlcyB9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50IDwgaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goeyBlbGVtOiB0aGlzLCBoYW5kbGVyczogaGFuZGxlcnMuc2xpY2UoIGRlbGVnYXRlQ291bnQgKSB9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdC8vIEluY2x1ZGVzIHNvbWUgZXZlbnQgcHJvcHMgc2hhcmVkIGJ5IEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50XG5cdHByb3BzOiBcImFsdEtleSBidWJibGVzIGNhbmNlbGFibGUgY3RybEtleSBjdXJyZW50VGFyZ2V0IGV2ZW50UGhhc2UgbWV0YUtleSByZWxhdGVkVGFyZ2V0IHNoaWZ0S2V5IHRhcmdldCB0aW1lU3RhbXAgdmlldyB3aGljaFwiLnNwbGl0KFwiIFwiKSxcblxuXHRmaXhIb29rczoge30sXG5cblx0a2V5SG9va3M6IHtcblx0XHRwcm9wczogXCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblxuXHRcdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0XHRpZiAoIGV2ZW50LndoaWNoID09IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50LndoaWNoID0gb3JpZ2luYWwuY2hhckNvZGUgIT0gbnVsbCA/IG9yaWdpbmFsLmNoYXJDb2RlIDogb3JpZ2luYWwua2V5Q29kZTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV2ZW50O1xuXHRcdH1cblx0fSxcblxuXHRtb3VzZUhvb2tzOiB7XG5cdFx0cHJvcHM6IFwiYnV0dG9uIGJ1dHRvbnMgY2xpZW50WCBjbGllbnRZIG9mZnNldFggb2Zmc2V0WSBwYWdlWCBwYWdlWSBzY3JlZW5YIHNjcmVlblkgdG9FbGVtZW50XCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblx0XHRcdHZhciBldmVudERvYywgZG9jLCBib2R5LFxuXHRcdFx0XHRidXR0b24gPSBvcmlnaW5hbC5idXR0b247XG5cblx0XHRcdC8vIENhbGN1bGF0ZSBwYWdlWC9ZIGlmIG1pc3NpbmcgYW5kIGNsaWVudFgvWSBhdmFpbGFibGVcblx0XHRcdGlmICggZXZlbnQucGFnZVggPT0gbnVsbCAmJiBvcmlnaW5hbC5jbGllbnRYICE9IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50RG9jID0gZXZlbnQudGFyZ2V0Lm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XG5cdFx0XHRcdGRvYyA9IGV2ZW50RG9jLmRvY3VtZW50RWxlbWVudDtcblx0XHRcdFx0Ym9keSA9IGV2ZW50RG9jLmJvZHk7XG5cblx0XHRcdFx0ZXZlbnQucGFnZVggPSBvcmlnaW5hbC5jbGllbnRYICsgKCBkb2MgJiYgZG9jLnNjcm9sbExlZnQgfHwgYm9keSAmJiBib2R5LnNjcm9sbExlZnQgfHwgMCApIC0gKCBkb2MgJiYgZG9jLmNsaWVudExlZnQgfHwgYm9keSAmJiBib2R5LmNsaWVudExlZnQgfHwgMCApO1xuXHRcdFx0XHRldmVudC5wYWdlWSA9IG9yaWdpbmFsLmNsaWVudFkgKyAoIGRvYyAmJiBkb2Muc2Nyb2xsVG9wICB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsVG9wICB8fCAwICkgLSAoIGRvYyAmJiBkb2MuY2xpZW50VG9wICB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wICB8fCAwICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB3aGljaCBmb3IgY2xpY2s6IDEgPT09IGxlZnQ7IDIgPT09IG1pZGRsZTsgMyA9PT0gcmlnaHRcblx0XHRcdC8vIE5vdGU6IGJ1dHRvbiBpcyBub3Qgbm9ybWFsaXplZCwgc28gZG9uJ3QgdXNlIGl0XG5cdFx0XHRpZiAoICFldmVudC53aGljaCAmJiBidXR0b24gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSAoIGJ1dHRvbiAmIDEgPyAxIDogKCBidXR0b24gJiAyID8gMyA6ICggYnV0dG9uICYgNCA/IDIgOiAwICkgKSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXHR9LFxuXG5cdGZpeDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdGlmICggZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIGEgd3JpdGFibGUgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCBub3JtYWxpemUgc29tZSBwcm9wZXJ0aWVzXG5cdFx0dmFyIGksIHByb3AsIGNvcHksXG5cdFx0XHR0eXBlID0gZXZlbnQudHlwZSxcblx0XHRcdG9yaWdpbmFsRXZlbnQgPSBldmVudCxcblx0XHRcdGZpeEhvb2sgPSB0aGlzLmZpeEhvb2tzWyB0eXBlIF07XG5cblx0XHRpZiAoICFmaXhIb29rICkge1xuXHRcdFx0dGhpcy5maXhIb29rc1sgdHlwZSBdID0gZml4SG9vayA9XG5cdFx0XHRcdHJtb3VzZUV2ZW50LnRlc3QoIHR5cGUgKSA/IHRoaXMubW91c2VIb29rcyA6XG5cdFx0XHRcdHJrZXlFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLmtleUhvb2tzIDpcblx0XHRcdFx0e307XG5cdFx0fVxuXHRcdGNvcHkgPSBmaXhIb29rLnByb3BzID8gdGhpcy5wcm9wcy5jb25jYXQoIGZpeEhvb2sucHJvcHMgKSA6IHRoaXMucHJvcHM7XG5cblx0XHRldmVudCA9IG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblxuXHRcdGkgPSBjb3B5Lmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHByb3AgPSBjb3B5WyBpIF07XG5cdFx0XHRldmVudFsgcHJvcCBdID0gb3JpZ2luYWxFdmVudFsgcHJvcCBdO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IENvcmRvdmEgMi41IChXZWJLaXQpICgjMTMyNTUpXG5cdFx0Ly8gQWxsIGV2ZW50cyBzaG91bGQgaGF2ZSBhIHRhcmdldDsgQ29yZG92YSBkZXZpY2VyZWFkeSBkb2Vzbid0XG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xuXHRcdFx0ZXZlbnQudGFyZ2V0ID0gZG9jdW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDYuMCssIENocm9tZSA8IDI4XG5cdFx0Ly8gVGFyZ2V0IHNob3VsZCBub3QgYmUgYSB0ZXh0IG5vZGUgKCM1MDQsICMxMzE0Mylcblx0XHRpZiAoIGV2ZW50LnRhcmdldC5ub2RlVHlwZSA9PT0gMyApIHtcblx0XHRcdGV2ZW50LnRhcmdldCA9IGV2ZW50LnRhcmdldC5wYXJlbnROb2RlO1xuXHRcdH1cblxuXHRcdHJldHVybiBmaXhIb29rLmZpbHRlciA/IGZpeEhvb2suZmlsdGVyKCBldmVudCwgb3JpZ2luYWxFdmVudCApIDogZXZlbnQ7XG5cdH0sXG5cblx0c3BlY2lhbDoge1xuXHRcdGxvYWQ6IHtcblx0XHRcdC8vIFByZXZlbnQgdHJpZ2dlcmVkIGltYWdlLmxvYWQgZXZlbnRzIGZyb20gYnViYmxpbmcgdG8gd2luZG93LmxvYWRcblx0XHRcdG5vQnViYmxlOiB0cnVlXG5cdFx0fSxcblx0XHRmb2N1czoge1xuXHRcdFx0Ly8gRmlyZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCB0aGlzICE9PSBzYWZlQWN0aXZlRWxlbWVudCgpICYmIHRoaXMuZm9jdXMgKSB7XG5cdFx0XHRcdFx0dGhpcy5mb2N1cygpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlbGVnYXRlVHlwZTogXCJmb2N1c2luXCJcblx0XHR9LFxuXHRcdGJsdXI6IHtcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHRoaXMgPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5ibHVyICkge1xuXHRcdFx0XHRcdHRoaXMuYmx1cigpO1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGRlbGVnYXRlVHlwZTogXCJmb2N1c291dFwiXG5cdFx0fSxcblx0XHRjbGljazoge1xuXHRcdFx0Ly8gRm9yIGNoZWNrYm94LCBmaXJlIG5hdGl2ZSBldmVudCBzbyBjaGVja2VkIHN0YXRlIHdpbGwgYmUgcmlnaHRcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIHRoaXMudHlwZSA9PT0gXCJjaGVja2JveFwiICYmIHRoaXMuY2xpY2sgJiYgalF1ZXJ5Lm5vZGVOYW1lKCB0aGlzLCBcImlucHV0XCIgKSApIHtcblx0XHRcdFx0XHR0aGlzLmNsaWNrKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBGb3IgY3Jvc3MtYnJvd3NlciBjb25zaXN0ZW5jeSwgZG9uJ3QgZmlyZSBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3Ncblx0XHRcdF9kZWZhdWx0OiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdHJldHVybiBqUXVlcnkubm9kZU5hbWUoIGV2ZW50LnRhcmdldCwgXCJhXCIgKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0YmVmb3JldW5sb2FkOiB7XG5cdFx0XHRwb3N0RGlzcGF0Y2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDIwK1xuXHRcdFx0XHQvLyBGaXJlZm94IGRvZXNuJ3QgYWxlcnQgaWYgdGhlIHJldHVyblZhbHVlIGZpZWxkIGlzIG5vdCBzZXQuXG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHNpbXVsYXRlOiBmdW5jdGlvbiggdHlwZSwgZWxlbSwgZXZlbnQsIGJ1YmJsZSApIHtcblx0XHQvLyBQaWdneWJhY2sgb24gYSBkb25vciBldmVudCB0byBzaW11bGF0ZSBhIGRpZmZlcmVudCBvbmUuXG5cdFx0Ly8gRmFrZSBvcmlnaW5hbEV2ZW50IHRvIGF2b2lkIGRvbm9yJ3Mgc3RvcFByb3BhZ2F0aW9uLCBidXQgaWYgdGhlXG5cdFx0Ly8gc2ltdWxhdGVkIGV2ZW50IHByZXZlbnRzIGRlZmF1bHQgdGhlbiB3ZSBkbyB0aGUgc2FtZSBvbiB0aGUgZG9ub3IuXG5cdFx0dmFyIGUgPSBqUXVlcnkuZXh0ZW5kKFxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCgpLFxuXHRcdFx0ZXZlbnQsXG5cdFx0XHR7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdGlzU2ltdWxhdGVkOiB0cnVlLFxuXHRcdFx0XHRvcmlnaW5hbEV2ZW50OiB7fVxuXHRcdFx0fVxuXHRcdCk7XG5cdFx0aWYgKCBidWJibGUgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuZGlzcGF0Y2guY2FsbCggZWxlbSwgZSApO1xuXHRcdH1cblx0XHRpZiAoIGUuaXNEZWZhdWx0UHJldmVudGVkKCkgKSB7XG5cdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGhhbmRsZSApIHtcblx0aWYgKCBlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0ZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKCB0eXBlLCBoYW5kbGUsIGZhbHNlICk7XG5cdH1cbn07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXHQvLyBBbGxvdyBpbnN0YW50aWF0aW9uIHdpdGhvdXQgdGhlICduZXcnIGtleXdvcmRcblx0aWYgKCAhKHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQpICkge1xuXHRcdHJldHVybiBuZXcgalF1ZXJ5LkV2ZW50KCBzcmMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBFdmVudCBvYmplY3Rcblx0aWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7XG5cdFx0dGhpcy5vcmlnaW5hbEV2ZW50ID0gc3JjO1xuXHRcdHRoaXMudHlwZSA9IHNyYy50eXBlO1xuXG5cdFx0Ly8gRXZlbnRzIGJ1YmJsaW5nIHVwIHRoZSBkb2N1bWVudCBtYXkgaGF2ZSBiZWVuIG1hcmtlZCBhcyBwcmV2ZW50ZWRcblx0XHQvLyBieSBhIGhhbmRsZXIgbG93ZXIgZG93biB0aGUgdHJlZTsgcmVmbGVjdCB0aGUgY29ycmVjdCB2YWx1ZS5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHNyYy5kZWZhdWx0UHJldmVudGVkIHx8XG5cdFx0XHRcdHNyYy5kZWZhdWx0UHJldmVudGVkID09PSB1bmRlZmluZWQgJiZcblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8IDQuMFxuXHRcdFx0XHRzcmMucmV0dXJuVmFsdWUgPT09IGZhbHNlID9cblx0XHRcdHJldHVyblRydWUgOlxuXHRcdFx0cmV0dXJuRmFsc2U7XG5cblx0Ly8gRXZlbnQgdHlwZVxuXHR9IGVsc2Uge1xuXHRcdHRoaXMudHlwZSA9IHNyYztcblx0fVxuXG5cdC8vIFB1dCBleHBsaWNpdGx5IHByb3ZpZGVkIHByb3BlcnRpZXMgb250byB0aGUgZXZlbnQgb2JqZWN0XG5cdGlmICggcHJvcHMgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXG5cdHRoaXMudGltZVN0YW1wID0gc3JjICYmIHNyYy50aW1lU3RhbXAgfHwgalF1ZXJ5Lm5vdygpO1xuXG5cdC8vIE1hcmsgaXQgYXMgZml4ZWRcblx0dGhpc1sgalF1ZXJ5LmV4cGFuZG8gXSA9IHRydWU7XG59O1xuXG4vLyBqUXVlcnkuRXZlbnQgaXMgYmFzZWQgb24gRE9NMyBFdmVudHMgYXMgc3BlY2lmaWVkIGJ5IHRoZSBFQ01BU2NyaXB0IExhbmd1YWdlIEJpbmRpbmdcbi8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cblx0cHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmIGUucHJldmVudERlZmF1bHQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgZS5zdG9wUHJvcGFnYXRpb24gKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBDcmVhdGUgbW91c2VlbnRlci9sZWF2ZSBldmVudHMgdXNpbmcgbW91c2VvdmVyL291dCBhbmQgZXZlbnQtdGltZSBjaGVja3Ncbi8vIFN1cHBvcnQ6IENocm9tZSAxNStcbmpRdWVyeS5lYWNoKHtcblx0bW91c2VlbnRlcjogXCJtb3VzZW92ZXJcIixcblx0bW91c2VsZWF2ZTogXCJtb3VzZW91dFwiLFxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcblx0cG9pbnRlcmxlYXZlOiBcInBvaW50ZXJvdXRcIlxufSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcblx0XHRkZWxlZ2F0ZVR5cGU6IGZpeCxcblx0XHRiaW5kVHlwZTogZml4LFxuXG5cdFx0aGFuZGxlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxuXHRcdFx0XHRyZWxhdGVkID0gZXZlbnQucmVsYXRlZFRhcmdldCxcblx0XHRcdFx0aGFuZGxlT2JqID0gZXZlbnQuaGFuZGxlT2JqO1xuXG5cdFx0XHQvLyBGb3IgbW91c2VudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZFRhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAocmVsYXRlZCAhPT0gdGFyZ2V0ICYmICFqUXVlcnkuY29udGFpbnMoIHRhcmdldCwgcmVsYXRlZCApKSApIHtcblx0XHRcdFx0ZXZlbnQudHlwZSA9IGhhbmRsZU9iai5vcmlnVHlwZTtcblx0XHRcdFx0cmV0ID0gaGFuZGxlT2JqLmhhbmRsZXIuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cdH07XG59KTtcblxuLy8gQ3JlYXRlIFwiYnViYmxpbmdcIiBmb2N1cyBhbmQgYmx1ciBldmVudHNcbi8vIFN1cHBvcnQ6IEZpcmVmb3gsIENocm9tZSwgU2FmYXJpXG5pZiAoICFzdXBwb3J0LmZvY3VzaW5CdWJibGVzICkge1xuXHRqUXVlcnkuZWFjaCh7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XG5cblx0XHQvLyBBdHRhY2ggYSBzaW5nbGUgY2FwdHVyaW5nIGhhbmRsZXIgb24gdGhlIGRvY3VtZW50IHdoaWxlIHNvbWVvbmUgd2FudHMgZm9jdXNpbi9mb2N1c291dFxuXHRcdHZhciBoYW5kbGVyID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApLCB0cnVlICk7XG5cdFx0XHR9O1xuXG5cdFx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGZpeCBdID0ge1xuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMsXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhX3ByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xuXHRcdFx0fSxcblx0XHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhX3ByaXYucmVtb3ZlKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZGF0YV9wcml2LmFjY2VzcyggZG9jLCBmaXgsIGF0dGFjaGVzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9KTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cblx0b246IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAvKklOVEVSTkFMKi8gb25lICkge1xuXHRcdHZhciBvcmlnRm4sIHR5cGU7XG5cblx0XHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApXG5cdFx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gKCB0eXBlcy1PYmplY3QsIGRhdGEgKVxuXHRcdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0XHR0aGlzLm9uKCB0eXBlLCBzZWxlY3RvciwgZGF0YSwgdHlwZXNbIHR5cGUgXSwgb25lICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cblx0XHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXHRcdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRcdGRhdGEgPSBzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdC8vICggdHlwZXMsIHNlbGVjdG9yLCBmbiApXG5cdFx0XHRcdGZuID0gZGF0YTtcblx0XHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vICggdHlwZXMsIGRhdGEsIGZuIClcblx0XHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdFx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0XHRvcmlnRm4gPSBmbjtcblx0XHRcdGZuID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHQvLyBDYW4gdXNlIGFuIGVtcHR5IHNldCwgc2luY2UgZXZlbnQgY29udGFpbnMgdGhlIGluZm9cblx0XHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0XHRyZXR1cm4gb3JpZ0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdH07XG5cdFx0XHQvLyBVc2Ugc2FtZSBndWlkIHNvIGNhbGxlciBjYW4gcmVtb3ZlIHVzaW5nIG9yaWdGblxuXHRcdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHRcdH0pO1xuXHR9LFxuXHRvbmU6IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAxICk7XG5cdH0sXG5cdG9mZjogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZm4gKSB7XG5cdFx0dmFyIGhhbmRsZU9iaiwgdHlwZTtcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcblx0XHRcdC8vICggZXZlbnQgKSAgZGlzcGF0Y2hlZCBqUXVlcnkuRXZlbnRcblx0XHRcdGhhbmRsZU9iaiA9IHR5cGVzLmhhbmRsZU9iajtcblx0XHRcdGpRdWVyeSggdHlwZXMuZGVsZWdhdGVUYXJnZXQgKS5vZmYoXG5cdFx0XHRcdGhhbmRsZU9iai5uYW1lc3BhY2UgPyBoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOiBoYW5kbGVPYmoub3JpZ1R5cGUsXG5cdFx0XHRcdGhhbmRsZU9iai5zZWxlY3Rvcixcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcblx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHQvLyAoIHR5cGVzLW9iamVjdCBbLCBzZWxlY3Rvcl0gKVxuXHRcdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcblx0XHRcdFx0dGhpcy5vZmYoIHR5cGUsIHNlbGVjdG9yLCB0eXBlc1sgdHlwZSBdICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcztcblx0XHR9XG5cdFx0aWYgKCBzZWxlY3RvciA9PT0gZmFsc2UgfHwgdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgKSB7XG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIHRoaXMsIHR5cGVzLCBmbiwgc2VsZWN0b3IgKTtcblx0XHR9KTtcblx0fSxcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9KTtcblx0fSxcblx0dHJpZ2dlckhhbmRsZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBlbGVtID0gdGhpc1swXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0pO1xuXG5cbnZhclxuXHRyeGh0bWxUYWcgPSAvPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbXFx3Ol0rKVtePl0qKVxcLz4vZ2ksXG5cdHJ0YWdOYW1lID0gLzwoW1xcdzpdKykvLFxuXHRyaHRtbCA9IC88fCYjP1xcdys7Lyxcblx0cm5vSW5uZXJodG1sID0gLzwoPzpzY3JpcHR8c3R5bGV8bGluaykvaSxcblx0Ly8gY2hlY2tlZD1cImNoZWNrZWRcIiBvciBjaGVja2VkXG5cdHJjaGVja2VkID0gL2NoZWNrZWRcXHMqKD86W149XXw9XFxzKi5jaGVja2VkLikvaSxcblx0cnNjcmlwdFR5cGUgPSAvXiR8XFwvKD86amF2YXxlY21hKXNjcmlwdC9pLFxuXHRyc2NyaXB0VHlwZU1hc2tlZCA9IC9edHJ1ZVxcLyguKikvLFxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2csXG5cblx0Ly8gV2UgaGF2ZSB0byBjbG9zZSB0aGVzZSB0YWdzIHRvIHN1cHBvcnQgWEhUTUwgKCMxMzIwMClcblx0d3JhcE1hcCA9IHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDlcblx0XHRvcHRpb246IFsgMSwgXCI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+XCIsIFwiPC9zZWxlY3Q+XCIgXSxcblxuXHRcdHRoZWFkOiBbIDEsIFwiPHRhYmxlPlwiLCBcIjwvdGFibGU+XCIgXSxcblx0XHRjb2w6IFsgMiwgXCI8dGFibGU+PGNvbGdyb3VwPlwiLCBcIjwvY29sZ3JvdXA+PC90YWJsZT5cIiBdLFxuXHRcdHRyOiBbIDIsIFwiPHRhYmxlPjx0Ym9keT5cIiwgXCI8L3Rib2R5PjwvdGFibGU+XCIgXSxcblx0XHR0ZDogWyAzLCBcIjx0YWJsZT48dGJvZHk+PHRyPlwiLCBcIjwvdHI+PC90Ym9keT48L3RhYmxlPlwiIF0sXG5cblx0XHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cblx0fTtcblxuLy8gU3VwcG9ydDogSUUgOVxud3JhcE1hcC5vcHRncm91cCA9IHdyYXBNYXAub3B0aW9uO1xuXG53cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkO1xud3JhcE1hcC50aCA9IHdyYXBNYXAudGQ7XG5cbi8vIFN1cHBvcnQ6IDEueCBjb21wYXRpYmlsaXR5XG4vLyBNYW5pcHVsYXRpbmcgdGFibGVzIHJlcXVpcmVzIGEgdGJvZHlcbmZ1bmN0aW9uIG1hbmlwdWxhdGlvblRhcmdldCggZWxlbSwgY29udGVudCApIHtcblx0cmV0dXJuIGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJ0YWJsZVwiICkgJiZcblx0XHRqUXVlcnkubm9kZU5hbWUoIGNvbnRlbnQubm9kZVR5cGUgIT09IDExID8gY29udGVudCA6IGNvbnRlbnQuZmlyc3RDaGlsZCwgXCJ0clwiICkgP1xuXG5cdFx0ZWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInRib2R5XCIpWzBdIHx8XG5cdFx0XHRlbGVtLmFwcGVuZENoaWxkKCBlbGVtLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRib2R5XCIpICkgOlxuXHRcdGVsZW07XG59XG5cbi8vIFJlcGxhY2UvcmVzdG9yZSB0aGUgdHlwZSBhdHRyaWJ1dGUgb2Ygc2NyaXB0IGVsZW1lbnRzIGZvciBzYWZlIERPTSBtYW5pcHVsYXRpb25cbmZ1bmN0aW9uIGRpc2FibGVTY3JpcHQoIGVsZW0gKSB7XG5cdGVsZW0udHlwZSA9IChlbGVtLmdldEF0dHJpYnV0ZShcInR5cGVcIikgIT09IG51bGwpICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0dmFyIG1hdGNoID0gcnNjcmlwdFR5cGVNYXNrZWQuZXhlYyggZWxlbS50eXBlICk7XG5cblx0aWYgKCBtYXRjaCApIHtcblx0XHRlbGVtLnR5cGUgPSBtYXRjaFsgMSBdO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKFwidHlwZVwiKTtcblx0fVxuXG5cdHJldHVybiBlbGVtO1xufVxuXG4vLyBNYXJrIHNjcmlwdHMgYXMgaGF2aW5nIGFscmVhZHkgYmVlbiBldmFsdWF0ZWRcbmZ1bmN0aW9uIHNldEdsb2JhbEV2YWwoIGVsZW1zLCByZWZFbGVtZW50cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGRhdGFfcHJpdi5zZXQoXG5cdFx0XHRlbGVtc1sgaSBdLCBcImdsb2JhbEV2YWxcIiwgIXJlZkVsZW1lbnRzIHx8IGRhdGFfcHJpdi5nZXQoIHJlZkVsZW1lbnRzWyBpIF0sIFwiZ2xvYmFsRXZhbFwiIClcblx0XHQpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgcGRhdGFDdXIsIHVkYXRhT2xkLCB1ZGF0YUN1ciwgZXZlbnRzO1xuXG5cdGlmICggZGVzdC5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLlxuXHRpZiAoIGRhdGFfcHJpdi5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHRwZGF0YU9sZCA9IGRhdGFfcHJpdi5hY2Nlc3MoIHNyYyApO1xuXHRcdHBkYXRhQ3VyID0gZGF0YV9wcml2LnNldCggZGVzdCwgcGRhdGFPbGQgKTtcblx0XHRldmVudHMgPSBwZGF0YU9sZC5ldmVudHM7XG5cblx0XHRpZiAoIGV2ZW50cyApIHtcblx0XHRcdGRlbGV0ZSBwZGF0YUN1ci5oYW5kbGU7XG5cdFx0XHRwZGF0YUN1ci5ldmVudHMgPSB7fTtcblxuXHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwLCBsID0gZXZlbnRzWyB0eXBlIF0ubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIDIuIENvcHkgdXNlciBkYXRhXG5cdGlmICggZGF0YV91c2VyLmhhc0RhdGEoIHNyYyApICkge1xuXHRcdHVkYXRhT2xkID0gZGF0YV91c2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFfdXNlci5zZXQoIGRlc3QsIHVkYXRhQ3VyICk7XG5cdH1cbn1cblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cdHZhciByZXQgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lID8gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnIHx8IFwiKlwiICkgOlxuXHRcdFx0Y29udGV4dC5xdWVyeVNlbGVjdG9yQWxsID8gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgfHwgXCIqXCIgKSA6XG5cdFx0XHRbXTtcblxuXHRyZXR1cm4gdGFnID09PSB1bmRlZmluZWQgfHwgdGFnICYmIGpRdWVyeS5ub2RlTmFtZSggY29udGV4dCwgdGFnICkgP1xuXHRcdGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApIDpcblx0XHRyZXQ7XG59XG5cbi8vIFN1cHBvcnQ6IElFID49IDlcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA+PSA5XG5cdFx0Ly8gRml4IENsb25pbmcgaXNzdWVzXG5cdFx0aWYgKCAhc3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCAmJiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgZWxlbS5ub2RlVHlwZSA9PT0gMTEgKSAmJlxuXHRcdFx0XHQhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XG5cblx0XHRcdC8vIFdlIGVzY2hldyBTaXp6bGUgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczogaHR0cDovL2pzcGVyZi5jb20vZ2V0YWxsLXZzLXNpenpsZS8yXG5cdFx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lICk7XG5cdFx0XHRzcmNFbGVtZW50cyA9IGdldEFsbCggZWxlbSApO1xuXG5cdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zml4SW5wdXQoIHNyY0VsZW1lbnRzWyBpIF0sIGRlc3RFbGVtZW50c1sgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZVxuXHRcdGlmICggZGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdGlmICggZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0XHRcdHNyY0VsZW1lbnRzID0gc3JjRWxlbWVudHMgfHwgZ2V0QWxsKCBlbGVtICk7XG5cdFx0XHRcdGRlc3RFbGVtZW50cyA9IGRlc3RFbGVtZW50cyB8fCBnZXRBbGwoIGNsb25lICk7XG5cblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIHNyY0VsZW1lbnRzWyBpIF0sIGRlc3RFbGVtZW50c1sgaSBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNsb25lQ29weUV2ZW50KCBlbGVtLCBjbG9uZSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3Rvcnlcblx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lLCBcInNjcmlwdFwiICk7XG5cdFx0aWYgKCBkZXN0RWxlbWVudHMubGVuZ3RoID4gMCApIHtcblx0XHRcdHNldEdsb2JhbEV2YWwoIGRlc3RFbGVtZW50cywgIWluUGFnZSAmJiBnZXRBbGwoIGVsZW0sIFwic2NyaXB0XCIgKSApO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiB0aGUgY2xvbmVkIHNldFxuXHRcdHJldHVybiBjbG9uZTtcblx0fSxcblxuXHRidWlsZEZyYWdtZW50OiBmdW5jdGlvbiggZWxlbXMsIGNvbnRleHQsIHNjcmlwdHMsIHNlbGVjdGlvbiApIHtcblx0XHR2YXIgZWxlbSwgdG1wLCB0YWcsIHdyYXAsIGNvbnRhaW5zLCBqLFxuXHRcdFx0ZnJhZ21lbnQgPSBjb250ZXh0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxcblx0XHRcdG5vZGVzID0gW10sXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRlbGVtID0gZWxlbXNbIGkgXTtcblxuXHRcdFx0aWYgKCBlbGVtIHx8IGVsZW0gPT09IDAgKSB7XG5cblx0XHRcdFx0Ly8gQWRkIG5vZGVzIGRpcmVjdGx5XG5cdFx0XHRcdGlmICggalF1ZXJ5LnR5cGUoIGVsZW0gKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBRdFdlYktpdFxuXHRcdFx0XHRcdC8vIGpRdWVyeS5tZXJnZSBiZWNhdXNlIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Ncblx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCBlbGVtLm5vZGVUeXBlID8gWyBlbGVtIF0gOiBlbGVtICk7XG5cblx0XHRcdFx0Ly8gQ29udmVydCBub24taHRtbCBpbnRvIGEgdGV4dCBub2RlXG5cdFx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XG5cblx0XHRcdFx0Ly8gQ29udmVydCBodG1sIGludG8gRE9NIG5vZGVzXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dG1wID0gdG1wIHx8IGZyYWdtZW50LmFwcGVuZENoaWxkKCBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgKTtcblxuXHRcdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cblx0XHRcdFx0XHR0YWcgPSAoIHJ0YWdOYW1lLmV4ZWMoIGVsZW0gKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcblx0XHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgZWxlbS5yZXBsYWNlKCByeGh0bWxUYWcsIFwiPCQxPjwvJDI+XCIgKSArIHdyYXBbIDIgXTtcblxuXHRcdFx0XHRcdC8vIERlc2NlbmQgdGhyb3VnaCB3cmFwcGVycyB0byB0aGUgcmlnaHQgY29udGVudFxuXHRcdFx0XHRcdGogPSB3cmFwWyAwIF07XG5cdFx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSB0bXAubGFzdENoaWxkO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHRcdFx0Ly8galF1ZXJ5Lm1lcmdlIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7XG5cblx0XHRcdFx0XHQvLyBSZW1lbWJlciB0aGUgdG9wLWxldmVsIGNvbnRhaW5lclxuXHRcdFx0XHRcdHRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdFx0XHQvLyBGaXhlcyAjMTIzNDZcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBXZWJraXQsIElFXG5cdFx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB3cmFwcGVyIGZyb20gZnJhZ21lbnRcblx0XHRmcmFnbWVudC50ZXh0Q29udGVudCA9IFwiXCI7XG5cblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChlbGVtID0gbm9kZXNbIGkrKyBdKSApIHtcblxuXHRcdFx0Ly8gIzQwODcgLSBJZiBvcmlnaW4gYW5kIGRlc3RpbmF0aW9uIGVsZW1lbnRzIGFyZSB0aGUgc2FtZSwgYW5kIHRoaXMgaXNcblx0XHRcdC8vIHRoYXQgZWxlbWVudCwgZG8gbm90IGRvIGFueXRoaW5nXG5cdFx0XHRpZiAoIHNlbGVjdGlvbiAmJiBqUXVlcnkuaW5BcnJheSggZWxlbSwgc2VsZWN0aW9uICkgIT09IC0xICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Y29udGFpbnMgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXG5cdFx0XHQvLyBBcHBlbmQgdG8gZnJhZ21lbnRcblx0XHRcdHRtcCA9IGdldEFsbCggZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGVsZW0gKSwgXCJzY3JpcHRcIiApO1xuXG5cdFx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0XHRpZiAoIGNvbnRhaW5zICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdFx0aWYgKCBzY3JpcHRzICkge1xuXHRcdFx0XHRqID0gMDtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHRtcFsgaisrIF0pICkge1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRcdHNjcmlwdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmcmFnbWVudDtcblx0fSxcblxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblx0XHR2YXIgZGF0YSwgZWxlbSwgdHlwZSwga2V5LFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gZWxlbXNbIGkgXSkgIT09IHVuZGVmaW5lZDsgaSsrICkge1xuXHRcdFx0aWYgKCBqUXVlcnkuYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0XHRrZXkgPSBlbGVtWyBkYXRhX3ByaXYuZXhwYW5kbyBdO1xuXG5cdFx0XHRcdGlmICgga2V5ICYmIChkYXRhID0gZGF0YV9wcml2LmNhY2hlWyBrZXkgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdGZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggc3BlY2lhbFsgdHlwZSBdICkge1xuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKTtcblxuXHRcdFx0XHRcdFx0XHQvLyBUaGlzIGlzIGEgc2hvcnRjdXQgdG8gYXZvaWQgalF1ZXJ5LmV2ZW50LnJlbW92ZSdzIG92ZXJoZWFkXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBkYXRhLmhhbmRsZSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggZGF0YV9wcml2LmNhY2hlWyBrZXkgXSApIHtcblx0XHRcdFx0XHRcdC8vIERpc2NhcmQgYW55IHJlbWFpbmluZyBgcHJpdmF0ZWAgZGF0YVxuXHRcdFx0XHRcdFx0ZGVsZXRlIGRhdGFfcHJpdi5jYWNoZVsga2V5IF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHQvLyBEaXNjYXJkIGFueSByZW1haW5pbmcgYHVzZXJgIGRhdGFcblx0XHRcdGRlbGV0ZSBkYXRhX3VzZXIuY2FjaGVbIGVsZW1bIGRhdGFfdXNlci5leHBhbmRvIF0gXTtcblx0XHR9XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0dGV4dDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnRleHQoIHRoaXMgKSA6XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdFx0dGhpcy50ZXh0Q29udGVudCA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcblx0XHRcdFx0dGFyZ2V0LmFwcGVuZENoaWxkKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0cHJlcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGJlZm9yZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcyApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzLm5leHRTaWJsaW5nICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0cmVtb3ZlOiBmdW5jdGlvbiggc2VsZWN0b3IsIGtlZXBEYXRhIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHRcdHZhciBlbGVtLFxuXHRcdFx0ZWxlbXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCB0aGlzICkgOiB0aGlzLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggIWtlZXBEYXRhICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSApICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRpZiAoIGtlZXBEYXRhICYmIGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgKSB7XG5cdFx0XHRcdFx0c2V0R2xvYmFsRXZhbCggZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRlbGVtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSB0aGlzW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gUHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cblx0XHRcdFx0Ly8gUmVtb3ZlIGFueSByZW1haW5pbmcgbm9kZXNcblx0XHRcdFx0ZWxlbS50ZXh0Q29udGVudCA9IFwiXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRkYXRhQW5kRXZlbnRzID0gZGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZmFsc2UgOiBkYXRhQW5kRXZlbnRzO1xuXHRcdGRlZXBEYXRhQW5kRXZlbnRzID0gZGVlcERhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGRhdGFBbmRFdmVudHMgOiBkZWVwRGF0YUFuZEV2ZW50cztcblxuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY2xvbmUoIHRoaXMsIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICk7XG5cdFx0fSk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0gdmFsdWUucmVwbGFjZSggcnhodG1sVGFnLCBcIjwkMT48LyQyPlwiICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2goIGUgKSB7fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdHRoaXMuZW1wdHkoKS5hcHBlbmQoIHZhbHVlICk7XG5cdFx0XHR9XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRyZXBsYWNlV2l0aDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGFyZyA9IGFyZ3VtZW50c1sgMCBdO1xuXG5cdFx0Ly8gTWFrZSB0aGUgY2hhbmdlcywgcmVwbGFjaW5nIGVhY2ggY29udGV4dCBlbGVtZW50IHdpdGggdGhlIG5ldyBjb250ZW50XG5cdFx0dGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGFyZyA9IHRoaXMucGFyZW50Tm9kZTtcblxuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCB0aGlzICkgKTtcblxuXHRcdFx0aWYgKCBhcmcgKSB7XG5cdFx0XHRcdGFyZy5yZXBsYWNlQ2hpbGQoIGVsZW0sIHRoaXMgKTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIEZvcmNlIHJlbW92YWwgaWYgdGhlcmUgd2FzIG5vIG5ldyBjb250ZW50IChlLmcuLCBmcm9tIGVtcHR5IGFyZ3VtZW50cylcblx0XHRyZXR1cm4gYXJnICYmIChhcmcubGVuZ3RoIHx8IGFyZy5ub2RlVHlwZSkgPyB0aGlzIDogdGhpcy5yZW1vdmUoKTtcblx0fSxcblxuXHRkZXRhY2g6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5yZW1vdmUoIHNlbGVjdG9yLCB0cnVlICk7XG5cdH0sXG5cblx0ZG9tTWFuaXA6IGZ1bmN0aW9uKCBhcmdzLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcblx0XHRhcmdzID0gY29uY2F0LmFwcGx5KCBbXSwgYXJncyApO1xuXG5cdFx0dmFyIGZyYWdtZW50LCBmaXJzdCwgc2NyaXB0cywgaGFzU2NyaXB0cywgbm9kZSwgZG9jLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRzZXQgPSB0aGlzLFxuXHRcdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHRcdHZhbHVlID0gYXJnc1sgMCBdLFxuXHRcdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0Ly8gV2UgY2FuJ3QgY2xvbmVOb2RlIGZyYWdtZW50cyB0aGF0IGNvbnRhaW4gY2hlY2tlZCwgaW4gV2ViS2l0XG5cdFx0aWYgKCBpc0Z1bmN0aW9uIHx8XG5cdFx0XHRcdCggbCA+IDEgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcblx0XHRcdFx0dmFyIHNlbGYgPSBzZXQuZXEoIGluZGV4ICk7XG5cdFx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcblx0XHRcdFx0XHRhcmdzWyAwIF0gPSB2YWx1ZS5jYWxsKCB0aGlzLCBpbmRleCwgc2VsZi5odG1sKCkgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRzZWxmLmRvbU1hbmlwKCBhcmdzLCBjYWxsYmFjayApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCBsICkge1xuXHRcdFx0ZnJhZ21lbnQgPSBqUXVlcnkuYnVpbGRGcmFnbWVudCggYXJncywgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCB0aGlzICk7XG5cdFx0XHRmaXJzdCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdGlmICggZnJhZ21lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDEgKSB7XG5cdFx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggZmlyc3QgKSB7XG5cdFx0XHRcdHNjcmlwdHMgPSBqUXVlcnkubWFwKCBnZXRBbGwoIGZyYWdtZW50LCBcInNjcmlwdFwiICksIGRpc2FibGVTY3JpcHQgKTtcblx0XHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHRcdC8vIFVzZSB0aGUgb3JpZ2luYWwgZnJhZ21lbnQgZm9yIHRoZSBsYXN0IGl0ZW0gaW5zdGVhZCBvZiB0aGUgZmlyc3QgYmVjYXVzZSBpdCBjYW4gZW5kIHVwXG5cdFx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gZnJhZ21lbnQ7XG5cblx0XHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IGpRdWVyeS5jbG9uZSggbm9kZSwgdHJ1ZSwgdHJ1ZSApO1xuXG5cdFx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXG5cdFx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFF0V2ViS2l0XG5cdFx0XHRcdFx0XHRcdC8vIGpRdWVyeS5tZXJnZSBiZWNhdXNlIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Ncblx0XHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGNhbGxiYWNrLmNhbGwoIHRoaXNbIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0XHQvLyBSZWVuYWJsZSBzY3JpcHRzXG5cdFx0XHRcdFx0alF1ZXJ5Lm1hcCggc2NyaXB0cywgcmVzdG9yZVNjcmlwdCApO1xuXG5cdFx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgaGFzU2NyaXB0czsgaSsrICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IHNjcmlwdHNbIGkgXTtcblx0XHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0XHQhZGF0YV9wcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJiBqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkge1xuXG5cdFx0XHRcdFx0XHRcdGlmICggbm9kZS5zcmMgKSB7XG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5fZXZhbFVybCggbm9kZS5zcmMgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICkgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goe1xuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcblx0cHJlcGVuZFRvOiBcInByZXBlbmRcIixcblx0aW5zZXJ0QmVmb3JlOiBcImJlZm9yZVwiLFxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxuXHRyZXBsYWNlQWxsOiBcInJlcGxhY2VXaXRoXCJcbn0sIGZ1bmN0aW9uKCBuYW1lLCBvcmlnaW5hbCApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGVsZW1zLFxuXHRcdFx0cmV0ID0gW10sXG5cdFx0XHRpbnNlcnQgPSBqUXVlcnkoIHNlbGVjdG9yICksXG5cdFx0XHRsYXN0ID0gaW5zZXJ0Lmxlbmd0aCAtIDEsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgaSA8PSBsYXN0OyBpKysgKSB7XG5cdFx0XHRlbGVtcyA9IGkgPT09IGxhc3QgPyB0aGlzIDogdGhpcy5jbG9uZSggdHJ1ZSApO1xuXHRcdFx0alF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBRdFdlYktpdFxuXHRcdFx0Ly8gLmdldCgpIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xuXHRcdFx0cHVzaC5hcHBseSggcmV0LCBlbGVtcy5nZXQoKSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggcmV0ICk7XG5cdH07XG59KTtcblxuXG52YXIgaWZyYW1lLFxuXHRlbGVtZGlzcGxheSA9IHt9O1xuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBhY3R1YWwgZGlzcGxheSBvZiBhIGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5vZGVOYW1lIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gZG9jIERvY3VtZW50IG9iamVjdFxuICovXG4vLyBDYWxsZWQgb25seSBmcm9tIHdpdGhpbiBkZWZhdWx0RGlzcGxheVxuZnVuY3Rpb24gYWN0dWFsRGlzcGxheSggbmFtZSwgZG9jICkge1xuXHR2YXIgc3R5bGUsXG5cdFx0ZWxlbSA9IGpRdWVyeSggZG9jLmNyZWF0ZUVsZW1lbnQoIG5hbWUgKSApLmFwcGVuZFRvKCBkb2MuYm9keSApLFxuXG5cdFx0Ly8gZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUgbWlnaHQgYmUgcmVsaWFibHkgdXNlZCBvbmx5IG9uIGF0dGFjaGVkIGVsZW1lbnRcblx0XHRkaXNwbGF5ID0gd2luZG93LmdldERlZmF1bHRDb21wdXRlZFN0eWxlICYmICggc3R5bGUgPSB3aW5kb3cuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUoIGVsZW1bIDAgXSApICkgP1xuXG5cdFx0XHQvLyBVc2Ugb2YgdGhpcyBtZXRob2QgaXMgYSB0ZW1wb3JhcnkgZml4IChtb3JlIGxpa2Ugb3B0bWl6YXRpb24pIHVudGlsIHNvbWV0aGluZyBiZXR0ZXIgY29tZXMgYWxvbmcsXG5cdFx0XHQvLyBzaW5jZSBpdCB3YXMgcmVtb3ZlZCBmcm9tIHNwZWNpZmljYXRpb24gYW5kIHN1cHBvcnRlZCBvbmx5IGluIEZGXG5cdFx0XHRzdHlsZS5kaXNwbGF5IDogalF1ZXJ5LmNzcyggZWxlbVsgMCBdLCBcImRpc3BsYXlcIiApO1xuXG5cdC8vIFdlIGRvbid0IGhhdmUgYW55IGRhdGEgc3RvcmVkIG9uIHRoZSBlbGVtZW50LFxuXHQvLyBzbyB1c2UgXCJkZXRhY2hcIiBtZXRob2QgYXMgZmFzdCB3YXkgdG8gZ2V0IHJpZCBvZiB0aGUgZWxlbWVudFxuXHRlbGVtLmRldGFjaCgpO1xuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG4vKipcbiAqIFRyeSB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgZGlzcGxheSB2YWx1ZSBvZiBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge1N0cmluZ30gbm9kZU5hbWVcbiAqL1xuZnVuY3Rpb24gZGVmYXVsdERpc3BsYXkoIG5vZGVOYW1lICkge1xuXHR2YXIgZG9jID0gZG9jdW1lbnQsXG5cdFx0ZGlzcGxheSA9IGVsZW1kaXNwbGF5WyBub2RlTmFtZSBdO1xuXG5cdGlmICggIWRpc3BsYXkgKSB7XG5cdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcblxuXHRcdC8vIElmIHRoZSBzaW1wbGUgd2F5IGZhaWxzLCByZWFkIGZyb20gaW5zaWRlIGFuIGlmcmFtZVxuXHRcdGlmICggZGlzcGxheSA9PT0gXCJub25lXCIgfHwgIWRpc3BsYXkgKSB7XG5cblx0XHRcdC8vIFVzZSB0aGUgYWxyZWFkeS1jcmVhdGVkIGlmcmFtZSBpZiBwb3NzaWJsZVxuXHRcdFx0aWZyYW1lID0gKGlmcmFtZSB8fCBqUXVlcnkoIFwiPGlmcmFtZSBmcmFtZWJvcmRlcj0nMCcgd2lkdGg9JzAnIGhlaWdodD0nMCcvPlwiICkpLmFwcGVuZFRvKCBkb2MuZG9jdW1lbnRFbGVtZW50ICk7XG5cblx0XHRcdC8vIEFsd2F5cyB3cml0ZSBhIG5ldyBIVE1MIHNrZWxldG9uIHNvIFdlYmtpdCBhbmQgRmlyZWZveCBkb24ndCBjaG9rZSBvbiByZXVzZVxuXHRcdFx0ZG9jID0gaWZyYW1lWyAwIF0uY29udGVudERvY3VtZW50O1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdFx0ZG9jLndyaXRlKCk7XG5cdFx0XHRkb2MuY2xvc2UoKTtcblxuXHRcdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcblx0XHRcdGlmcmFtZS5kZXRhY2goKTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSB0aGUgY29ycmVjdCBkZWZhdWx0IGRpc3BsYXlcblx0XHRlbGVtZGlzcGxheVsgbm9kZU5hbWUgXSA9IGRpc3BsYXk7XG5cdH1cblxuXHRyZXR1cm4gZGlzcGxheTtcbn1cbnZhciBybWFyZ2luID0gKC9ebWFyZ2luLyk7XG5cbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSwgbnVsbCApO1xuXHR9O1xuXG5cblxuZnVuY3Rpb24gY3VyQ1NTKCBlbGVtLCBuYW1lLCBjb21wdXRlZCApIHtcblx0dmFyIHdpZHRoLCBtaW5XaWR0aCwgbWF4V2lkdGgsIHJldCxcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHQvLyBTdXBwb3J0OiBJRTlcblx0Ly8gZ2V0UHJvcGVydHlWYWx1ZSBpcyBvbmx5IG5lZWRlZCBmb3IgLmNzcygnZmlsdGVyJykgaW4gSUU5LCBzZWUgIzEyNTM3XG5cdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0cmV0ID0gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSggbmFtZSApIHx8IGNvbXB1dGVkWyBuYW1lIF07XG5cdH1cblxuXHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0aWYgKCByZXQgPT09IFwiXCIgJiYgIWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgKSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBpT1MgPCA2XG5cdFx0Ly8gQSB0cmlidXRlIHRvIHRoZSBcImF3ZXNvbWUgaGFjayBieSBEZWFuIEVkd2FyZHNcIlxuXHRcdC8vIGlPUyA8IDYgKGF0IGxlYXN0KSByZXR1cm5zIHBlcmNlbnRhZ2UgZm9yIGEgbGFyZ2VyIHNldCBvZiB2YWx1ZXMsIGJ1dCB3aWR0aCBzZWVtcyB0byBiZSByZWxpYWJseSBwaXhlbHNcblx0XHQvLyB0aGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6IGh0dHA6Ly9kZXYudzMub3JnL2Nzc3dnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRpZiAoIHJudW1ub25weC50ZXN0KCByZXQgKSAmJiBybWFyZ2luLnRlc3QoIG5hbWUgKSApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIG9yaWdpbmFsIHZhbHVlc1xuXHRcdFx0d2lkdGggPSBzdHlsZS53aWR0aDtcblx0XHRcdG1pbldpZHRoID0gc3R5bGUubWluV2lkdGg7XG5cdFx0XHRtYXhXaWR0aCA9IHN0eWxlLm1heFdpZHRoO1xuXG5cdFx0XHQvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IHN0eWxlLm1heFdpZHRoID0gc3R5bGUud2lkdGggPSByZXQ7XG5cdFx0XHRyZXQgPSBjb21wdXRlZC53aWR0aDtcblxuXHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xuXHRcdFx0c3R5bGUud2lkdGggPSB3aWR0aDtcblx0XHRcdHN0eWxlLm1pbldpZHRoID0gbWluV2lkdGg7XG5cdFx0XHRzdHlsZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiByZXQgIT09IHVuZGVmaW5lZCA/XG5cdFx0Ly8gU3VwcG9ydDogSUVcblx0XHQvLyBJRSByZXR1cm5zIHpJbmRleCB2YWx1ZSBhcyBhbiBpbnRlZ2VyLlxuXHRcdHJldCArIFwiXCIgOlxuXHRcdHJldDtcbn1cblxuXG5mdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7XG5cdC8vIERlZmluZSB0aGUgaG9vaywgd2UnbGwgY2hlY2sgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCdzIHJlYWxseSBuZWVkZWQuXG5cdHJldHVybiB7XG5cdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggY29uZGl0aW9uRm4oKSApIHtcblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlIHRvIG1pc3NpbmcgZGVwZW5kZW5jeSksXG5cdFx0XHRcdC8vIHJlbW92ZSBpdC5cblx0XHRcdFx0Ly8gU2luY2UgdGhlcmUgYXJlIG5vIG90aGVyIGhvb2tzIGZvciBtYXJnaW5SaWdodCwgcmVtb3ZlIHRoZSB3aG9sZSBvYmplY3QuXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmdldDtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBIb29rIG5lZWRlZDsgcmVkZWZpbmUgaXQgc28gdGhhdCB0aGUgc3VwcG9ydCB0ZXN0IGlzIG5vdCBleGVjdXRlZCBhZ2Fpbi5cblxuXHRcdFx0cmV0dXJuICh0aGlzLmdldCA9IGhvb2tGbikuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdH1cblx0fTtcbn1cblxuXG4oZnVuY3Rpb24oKSB7XG5cdHZhciBwaXhlbFBvc2l0aW9uVmFsLCBib3hTaXppbmdSZWxpYWJsZVZhbCxcblx0XHRkb2NFbGVtID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFxuXHRcdGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSxcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG5cblx0aWYgKCAhZGl2LnN0eWxlICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjA7d2lkdGg6MDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHg7bWFyZ2luLXRvcDoxcHg7XCIgK1xuXHRcdFwicG9zaXRpb246YWJzb2x1dGVcIjtcblx0Y29udGFpbmVyLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHQvLyBFeGVjdXRpbmcgYm90aCBwaXhlbFBvc2l0aW9uICYgYm94U2l6aW5nUmVsaWFibGUgdGVzdHMgcmVxdWlyZSBvbmx5IG9uZSBsYXlvdXRcblx0Ly8gc28gdGhleSdyZSBleGVjdXRlZCBhdCB0aGUgc2FtZSB0aW1lIHRvIHNhdmUgdGhlIHNlY29uZCBjb21wdXRhdGlvbi5cblx0ZnVuY3Rpb24gY29tcHV0ZVBpeGVsUG9zaXRpb25BbmRCb3hTaXppbmdSZWxpYWJsZSgpIHtcblx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9XG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xuXHRcdFx0Ly8gVmVuZG9yLXByZWZpeCBib3gtc2l6aW5nXG5cdFx0XHRcIi13ZWJraXQtYm94LXNpemluZzpib3JkZXItYm94Oy1tb3otYm94LXNpemluZzpib3JkZXItYm94O1wiICtcblx0XHRcdFwiYm94LXNpemluZzpib3JkZXItYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luLXRvcDoxJTt0b3A6MSU7XCIgK1xuXHRcdFx0XCJib3JkZXI6MXB4O3BhZGRpbmc6MXB4O3dpZHRoOjRweDtwb3NpdGlvbjphYnNvbHV0ZVwiO1xuXHRcdGRpdi5pbm5lckhUTUwgPSBcIlwiO1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiwgbnVsbCApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblx0XHRib3hTaXppbmdSZWxpYWJsZVZhbCA9IGRpdlN0eWxlLndpZHRoID09PSBcIjRweFwiO1xuXG5cdFx0ZG9jRWxlbS5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBub2RlLmpzIGpzZG9tXG5cdC8vIERvbid0IGFzc3VtZSB0aGF0IGdldENvbXB1dGVkU3R5bGUgaXMgYSBwcm9wZXJ0eSBvZiB0aGUgZ2xvYmFsIG9iamVjdFxuXHRpZiAoIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHN1cHBvcnQsIHtcblx0XHRcdHBpeGVsUG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBUaGlzIHRlc3QgaXMgZXhlY3V0ZWQgb25seSBvbmNlIGJ1dCB3ZSBzdGlsbCBkbyBtZW1vaXppbmdcblx0XHRcdFx0Ly8gc2luY2Ugd2UgY2FuIHVzZSB0aGUgYm94U2l6aW5nUmVsaWFibGUgcHJlLWNvbXB1dGluZy5cblx0XHRcdFx0Ly8gTm8gbmVlZCB0byBjaGVjayBpZiB0aGUgdGVzdCB3YXMgYWxyZWFkeSBwZXJmb3JtZWQsIHRob3VnaC5cblx0XHRcdFx0Y29tcHV0ZVBpeGVsUG9zaXRpb25BbmRCb3hTaXppbmdSZWxpYWJsZSgpO1xuXHRcdFx0XHRyZXR1cm4gcGl4ZWxQb3NpdGlvblZhbDtcblx0XHRcdH0sXG5cdFx0XHRib3hTaXppbmdSZWxpYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggYm94U2l6aW5nUmVsaWFibGVWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRjb21wdXRlUGl4ZWxQb3NpdGlvbkFuZEJveFNpemluZ1JlbGlhYmxlKCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGJveFNpemluZ1JlbGlhYmxlVmFsO1xuXHRcdFx0fSxcblx0XHRcdHJlbGlhYmxlTWFyZ2luUmlnaHQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuXHRcdFx0XHQvLyBDaGVjayBpZiBkaXYgd2l0aCBleHBsaWNpdCB3aWR0aCBhbmQgbm8gbWFyZ2luLXJpZ2h0IGluY29ycmVjdGx5XG5cdFx0XHRcdC8vIGdldHMgY29tcHV0ZWQgbWFyZ2luLXJpZ2h0IGJhc2VkIG9uIHdpZHRoIG9mIGNvbnRhaW5lci4gKCMzMzMzKVxuXHRcdFx0XHQvLyBXZWJLaXQgQnVnIDEzMzQzIC0gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBtYXJnaW4tcmlnaHRcblx0XHRcdFx0Ly8gVGhpcyBzdXBwb3J0IGZ1bmN0aW9uIGlzIG9ubHkgZXhlY3V0ZWQgb25jZSBzbyBubyBtZW1vaXppbmcgaXMgbmVlZGVkLlxuXHRcdFx0XHR2YXIgcmV0LFxuXHRcdFx0XHRcdG1hcmdpbkRpdiA9IGRpdi5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XG5cblx0XHRcdFx0Ly8gUmVzZXQgQ1NTOiBib3gtc2l6aW5nOyBkaXNwbGF5OyBtYXJnaW47IGJvcmRlcjsgcGFkZGluZ1xuXHRcdFx0XHRtYXJnaW5EaXYuc3R5bGUuY3NzVGV4dCA9IGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xuXHRcdFx0XHRcdC8vIFZlbmRvci1wcmVmaXggYm94LXNpemluZ1xuXHRcdFx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94Oy1tb3otYm94LXNpemluZzpjb250ZW50LWJveDtcIiArXG5cdFx0XHRcdFx0XCJib3gtc2l6aW5nOmNvbnRlbnQtYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjA7Ym9yZGVyOjA7cGFkZGluZzowXCI7XG5cdFx0XHRcdG1hcmdpbkRpdi5zdHlsZS5tYXJnaW5SaWdodCA9IG1hcmdpbkRpdi5zdHlsZS53aWR0aCA9IFwiMFwiO1xuXHRcdFx0XHRkaXYuc3R5bGUud2lkdGggPSBcIjFweFwiO1xuXHRcdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdFx0XHRyZXQgPSAhcGFyc2VGbG9hdCggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIG1hcmdpbkRpdiwgbnVsbCApLm1hcmdpblJpZ2h0ICk7XG5cblx0XHRcdFx0ZG9jRWxlbS5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSkoKTtcblxuXG4vLyBBIG1ldGhvZCBmb3IgcXVpY2tseSBzd2FwcGluZyBpbi9vdXQgQ1NTIHByb3BlcnRpZXMgdG8gZ2V0IGNvcnJlY3QgY2FsY3VsYXRpb25zLlxualF1ZXJ5LnN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2ssIGFyZ3MgKSB7XG5cdHZhciByZXQsIG5hbWUsXG5cdFx0b2xkID0ge307XG5cblx0Ly8gUmVtZW1iZXIgdGhlIG9sZCB2YWx1ZXMsIGFuZCBpbnNlcnQgdGhlIG5ldyBvbmVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF07XG5cdH1cblxuXHRyZXQgPSBjYWxsYmFjay5hcHBseSggZWxlbSwgYXJncyB8fCBbXSApO1xuXG5cdC8vIFJldmVydCB0aGUgb2xkIHZhbHVlc1xuXHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufTtcblxuXG52YXJcblx0Ly8gc3dhcHBhYmxlIGlmIGRpc3BsYXkgaXMgbm9uZSBvciBzdGFydHMgd2l0aCB0YWJsZSBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcblx0Ly8gc2VlIGhlcmUgZm9yIGRpc3BsYXkgdmFsdWVzOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0NTUy9kaXNwbGF5XG5cdHJkaXNwbGF5c3dhcCA9IC9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxcblx0cm51bXNwbGl0ID0gbmV3IFJlZ0V4cCggXCJeKFwiICsgcG51bSArIFwiKSguKikkXCIsIFwiaVwiICksXG5cdHJyZWxOdW0gPSBuZXcgUmVnRXhwKCBcIl4oWystXSk9KFwiICsgcG51bSArIFwiKVwiLCBcImlcIiApLFxuXG5cdGNzc1Nob3cgPSB7IHBvc2l0aW9uOiBcImFic29sdXRlXCIsIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsIGRpc3BsYXk6IFwiYmxvY2tcIiB9LFxuXHRjc3NOb3JtYWxUcmFuc2Zvcm0gPSB7XG5cdFx0bGV0dGVyU3BhY2luZzogXCIwXCIsXG5cdFx0Zm9udFdlaWdodDogXCI0MDBcIlxuXHR9LFxuXG5cdGNzc1ByZWZpeGVzID0gWyBcIldlYmtpdFwiLCBcIk9cIiwgXCJNb3pcIiwgXCJtc1wiIF07XG5cbi8vIHJldHVybiBhIGNzcyBwcm9wZXJ0eSBtYXBwZWQgdG8gYSBwb3RlbnRpYWxseSB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHlcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBzdHlsZSwgbmFtZSApIHtcblxuXHQvLyBzaG9ydGN1dCBmb3IgbmFtZXMgdGhhdCBhcmUgbm90IHZlbmRvciBwcmVmaXhlZFxuXHRpZiAoIG5hbWUgaW4gc3R5bGUgKSB7XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cblxuXHQvLyBjaGVjayBmb3IgdmVuZG9yIHByZWZpeGVkIG5hbWVzXG5cdHZhciBjYXBOYW1lID0gbmFtZVswXS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSgxKSxcblx0XHRvcmlnTmFtZSA9IG5hbWUsXG5cdFx0aSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRuYW1lID0gY3NzUHJlZml4ZXNbIGkgXSArIGNhcE5hbWU7XG5cdFx0aWYgKCBuYW1lIGluIHN0eWxlICkge1xuXHRcdFx0cmV0dXJuIG5hbWU7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG9yaWdOYW1lO1xufVxuXG5mdW5jdGlvbiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkge1xuXHR2YXIgbWF0Y2hlcyA9IHJudW1zcGxpdC5leGVjKCB2YWx1ZSApO1xuXHRyZXR1cm4gbWF0Y2hlcyA/XG5cdFx0Ly8gR3VhcmQgYWdhaW5zdCB1bmRlZmluZWQgXCJzdWJ0cmFjdFwiLCBlLmcuLCB3aGVuIHVzZWQgYXMgaW4gY3NzSG9va3Ncblx0XHRNYXRoLm1heCggMCwgbWF0Y2hlc1sgMSBdIC0gKCBzdWJ0cmFjdCB8fCAwICkgKSArICggbWF0Y2hlc1sgMiBdIHx8IFwicHhcIiApIDpcblx0XHR2YWx1ZTtcbn1cblxuZnVuY3Rpb24gYXVnbWVudFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhLCBpc0JvcmRlckJveCwgc3R5bGVzICkge1xuXHR2YXIgaSA9IGV4dHJhID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgP1xuXHRcdC8vIElmIHdlIGFscmVhZHkgaGF2ZSB0aGUgcmlnaHQgbWVhc3VyZW1lbnQsIGF2b2lkIGF1Z21lbnRhdGlvblxuXHRcdDQgOlxuXHRcdC8vIE90aGVyd2lzZSBpbml0aWFsaXplIGZvciBob3Jpem9udGFsIG9yIHZlcnRpY2FsIHByb3BlcnRpZXNcblx0XHRuYW1lID09PSBcIndpZHRoXCIgPyAxIDogMCxcblxuXHRcdHZhbCA9IDA7XG5cblx0Zm9yICggOyBpIDwgNDsgaSArPSAyICkge1xuXHRcdC8vIGJvdGggYm94IG1vZGVscyBleGNsdWRlIG1hcmdpbiwgc28gYWRkIGl0IGlmIHdlIHdhbnQgaXRcblx0XHRpZiAoIGV4dHJhID09PSBcIm1hcmdpblwiICkge1xuXHRcdFx0dmFsICs9IGpRdWVyeS5jc3MoIGVsZW0sIGV4dHJhICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdGlmICggaXNCb3JkZXJCb3ggKSB7XG5cdFx0XHQvLyBib3JkZXItYm94IGluY2x1ZGVzIHBhZGRpbmcsIHNvIHJlbW92ZSBpdCBpZiB3ZSB3YW50IGNvbnRlbnRcblx0XHRcdGlmICggZXh0cmEgPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGJvcmRlciBub3IgbWFyZ2luLCBzbyByZW1vdmUgYm9yZGVyXG5cdFx0XHRpZiAoIGV4dHJhICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gYXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgY29udGVudCwgc28gYWRkIHBhZGRpbmdcblx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gYXQgdGhpcyBwb2ludCwgZXh0cmEgaXNuJ3QgY29udGVudCBub3IgcGFkZGluZywgc28gYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBleHRyYSAhPT0gXCJwYWRkaW5nXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB2YWw7XG59XG5cbmZ1bmN0aW9uIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICkge1xuXG5cdC8vIFN0YXJ0IHdpdGggb2Zmc2V0IHByb3BlcnR5LCB3aGljaCBpcyBlcXVpdmFsZW50IHRvIHRoZSBib3JkZXItYm94IHZhbHVlXG5cdHZhciB2YWx1ZUlzQm9yZGVyQm94ID0gdHJ1ZSxcblx0XHR2YWwgPSBuYW1lID09PSBcIndpZHRoXCIgPyBlbGVtLm9mZnNldFdpZHRoIDogZWxlbS5vZmZzZXRIZWlnaHQsXG5cdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cdFx0aXNCb3JkZXJCb3ggPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiO1xuXG5cdC8vIHNvbWUgbm9uLWh0bWwgZWxlbWVudHMgcmV0dXJuIHVuZGVmaW5lZCBmb3Igb2Zmc2V0V2lkdGgsIHNvIGNoZWNrIGZvciBudWxsL3VuZGVmaW5lZFxuXHQvLyBzdmcgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02NDkyODVcblx0Ly8gTWF0aE1MIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDkxNjY4XG5cdGlmICggdmFsIDw9IDAgfHwgdmFsID09IG51bGwgKSB7XG5cdFx0Ly8gRmFsbCBiYWNrIHRvIGNvbXB1dGVkIHRoZW4gdW5jb21wdXRlZCBjc3MgaWYgbmVjZXNzYXJ5XG5cdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcblx0XHRpZiAoIHZhbCA8IDAgfHwgdmFsID09IG51bGwgKSB7XG5cdFx0XHR2YWwgPSBlbGVtLnN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gQ29tcHV0ZWQgdW5pdCBpcyBub3QgcGl4ZWxzLiBTdG9wIGhlcmUgYW5kIHJldHVybi5cblx0XHRpZiAoIHJudW1ub25weC50ZXN0KHZhbCkgKSB7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblxuXHRcdC8vIHdlIG5lZWQgdGhlIGNoZWNrIGZvciBzdHlsZSBpbiBjYXNlIGEgYnJvd3NlciB3aGljaCByZXR1cm5zIHVucmVsaWFibGUgdmFsdWVzXG5cdFx0Ly8gZm9yIGdldENvbXB1dGVkU3R5bGUgc2lsZW50bHkgZmFsbHMgYmFjayB0byB0aGUgcmVsaWFibGUgZWxlbS5zdHlsZVxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCAmJlxuXHRcdFx0KCBzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgdmFsID09PSBlbGVtLnN0eWxlWyBuYW1lIF0gKTtcblxuXHRcdC8vIE5vcm1hbGl6ZSBcIlwiLCBhdXRvLCBhbmQgcHJlcGFyZSBmb3IgZXh0cmFcblx0XHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXHR9XG5cblx0Ly8gdXNlIHRoZSBhY3RpdmUgYm94LXNpemluZyBtb2RlbCB0byBhZGQvc3VidHJhY3QgaXJyZWxldmFudCBzdHlsZXNcblx0cmV0dXJuICggdmFsICtcblx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcblx0XHRcdGVsZW0sXG5cdFx0XHRuYW1lLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlc1xuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxuZnVuY3Rpb24gc2hvd0hpZGUoIGVsZW1lbnRzLCBzaG93ICkge1xuXHR2YXIgZGlzcGxheSwgZWxlbSwgaGlkZGVuLFxuXHRcdHZhbHVlcyA9IFtdLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRlbGVtID0gZWxlbWVudHNbIGluZGV4IF07XG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdHZhbHVlc1sgaW5kZXggXSA9IGRhdGFfcHJpdi5nZXQoIGVsZW0sIFwib2xkZGlzcGxheVwiICk7XG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcblx0XHRpZiAoIHNob3cgKSB7XG5cdFx0XHQvLyBSZXNldCB0aGUgaW5saW5lIGRpc3BsYXkgb2YgdGhpcyBlbGVtZW50IHRvIGxlYXJuIGlmIGl0IGlzXG5cdFx0XHQvLyBiZWluZyBoaWRkZW4gYnkgY2FzY2FkZWQgcnVsZXMgb3Igbm90XG5cdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gJiYgZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBlbGVtZW50cyB3aGljaCBoYXZlIGJlZW4gb3ZlcnJpZGRlbiB3aXRoIGRpc3BsYXk6IG5vbmVcblx0XHRcdC8vIGluIGEgc3R5bGVzaGVldCB0byB3aGF0ZXZlciB0aGUgZGVmYXVsdCBicm93c2VyIHN0eWxlIGlzXG5cdFx0XHQvLyBmb3Igc3VjaCBhbiBlbGVtZW50XG5cdFx0XHRpZiAoIGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiAmJiBpc0hpZGRlbiggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhX3ByaXYuYWNjZXNzKCBlbGVtLCBcIm9sZGRpc3BsYXlcIiwgZGVmYXVsdERpc3BsYXkoZWxlbS5ub2RlTmFtZSkgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0aGlkZGVuID0gaXNIaWRkZW4oIGVsZW0gKTtcblxuXHRcdFx0aWYgKCBkaXNwbGF5ICE9PSBcIm5vbmVcIiB8fCAhaGlkZGVuICkge1xuXHRcdFx0XHRkYXRhX3ByaXYuc2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiwgaGlkZGVuID8gZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgbW9zdCBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcFxuXHQvLyB0byBhdm9pZCB0aGUgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0aWYgKCAhc2hvdyB8fCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiIHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IHNob3cgPyB2YWx1ZXNbIGluZGV4IF0gfHwgXCJcIiA6IFwibm9uZVwiO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50cztcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdFx0XHQvLyBXZSBzaG91bGQgYWx3YXlzIGdldCBhIG51bWJlciBiYWNrIGZyb20gb3BhY2l0eVxuXHRcdFx0XHRcdHZhciByZXQgPSBjdXJDU1MoIGVsZW0sIFwib3BhY2l0eVwiICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXG5cdGNzc051bWJlcjoge1xuXHRcdFwiY29sdW1uQ291bnRcIjogdHJ1ZSxcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJmbGV4R3Jvd1wiOiB0cnVlLFxuXHRcdFwiZmxleFNocmlua1wiOiB0cnVlLFxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxuXHRcdFwibGluZUhlaWdodFwiOiB0cnVlLFxuXHRcdFwib3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwib3JkZXJcIjogdHJ1ZSxcblx0XHRcIm9ycGhhbnNcIjogdHJ1ZSxcblx0XHRcIndpZG93c1wiOiB0cnVlLFxuXHRcdFwiekluZGV4XCI6IHRydWUsXG5cdFx0XCJ6b29tXCI6IHRydWVcblx0fSxcblxuXHQvLyBBZGQgaW4gcHJvcGVydGllcyB3aG9zZSBuYW1lcyB5b3Ugd2lzaCB0byBmaXggYmVmb3JlXG5cdC8vIHNldHRpbmcgb3IgZ2V0dGluZyB0aGUgdmFsdWVcblx0Y3NzUHJvcHM6IHtcblx0XHQvLyBub3JtYWxpemUgZmxvYXQgY3NzIHByb3BlcnR5XG5cdFx0XCJmbG9hdFwiOiBcImNzc0Zsb2F0XCJcblx0fSxcblxuXHQvLyBHZXQgYW5kIHNldCB0aGUgc3R5bGUgcHJvcGVydHkgb24gYSBET00gTm9kZVxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApLFxuXHRcdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdFx0bmFtZSA9IGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSB8fCAoIGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBzdHlsZSwgb3JpZ05hbWUgKSApO1xuXG5cdFx0Ly8gZ2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvblxuXHRcdC8vIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIHZlcnNpb25cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIENoZWNrIGlmIHdlJ3JlIHNldHRpbmcgYSB2YWx1ZVxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRcdC8vIGNvbnZlcnQgcmVsYXRpdmUgbnVtYmVyIHN0cmluZ3MgKCs9IG9yIC09KSB0byByZWxhdGl2ZSBudW1iZXJzLiAjNzM0NVxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICYmIChyZXQgPSBycmVsTnVtLmV4ZWMoIHZhbHVlICkpICkge1xuXHRcdFx0XHR2YWx1ZSA9ICggcmV0WzFdICsgMSApICogcmV0WzJdICsgcGFyc2VGbG9hdCggalF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApICk7XG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0LiBTZWU6ICM3MTE2XG5cdFx0XHRpZiAoIHZhbHVlID09IG51bGwgfHwgdmFsdWUgIT09IHZhbHVlICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgbnVtYmVyIHdhcyBwYXNzZWQgaW4sIGFkZCAncHgnIHRvIHRoZSAoZXhjZXB0IGZvciBjZXJ0YWluIENTUyBwcm9wZXJ0aWVzKVxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICYmICFqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdICkge1xuXHRcdFx0XHR2YWx1ZSArPSBcInB4XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZpeGVzICM4OTA4LCBpdCBjYW4gYmUgZG9uZSBtb3JlIGNvcnJlY3RseSBieSBzcGVjaWZ5aW5nIHNldHRlcnMgaW4gY3NzSG9va3MsXG5cdFx0XHQvLyBidXQgaXQgd291bGQgbWVhbiB0byBkZWZpbmUgZWlnaHQgKGZvciBldmVyeSBwcm9ibGVtYXRpYyBwcm9wZXJ0eSkgaWRlbnRpY2FsIGZ1bmN0aW9uc1xuXHRcdFx0aWYgKCAhc3VwcG9ydC5jbGVhckNsb25lU3R5bGUgJiYgdmFsdWUgPT09IFwiXCIgJiYgbmFtZS5pbmRleE9mKCBcImJhY2tncm91bmRcIiApID09PSAwICkge1xuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gXCJpbmhlcml0XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQsIHVzZSB0aGF0IHZhbHVlLCBvdGhlcndpc2UganVzdCBzZXQgdGhlIHNwZWNpZmllZCB2YWx1ZVxuXHRcdFx0aWYgKCAhaG9va3MgfHwgIShcInNldFwiIGluIGhvb2tzKSB8fCAodmFsdWUgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBleHRyYSApKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLmdldCggZWxlbSwgZmFsc2UsIGV4dHJhICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0XG5cdFx0XHRyZXR1cm4gc3R5bGVbIG5hbWUgXTtcblx0XHR9XG5cdH0sXG5cblx0Y3NzOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZXh0cmEsIHN0eWxlcyApIHtcblx0XHR2YXIgdmFsLCBudW0sIGhvb2tzLFxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHRuYW1lID0galF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdIHx8ICggalF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdID0gdmVuZG9yUHJvcE5hbWUoIGVsZW0uc3R5bGUsIG9yaWdOYW1lICkgKTtcblxuXHRcdC8vIGdldHMgaG9vayBmb3IgdGhlIHByZWZpeGVkIHZlcnNpb25cblx0XHQvLyBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCB2ZXJzaW9uXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vY29udmVydCBcIm5vcm1hbFwiIHRvIGNvbXB1dGVkIHZhbHVlXG5cdFx0aWYgKCB2YWwgPT09IFwibm9ybWFsXCIgJiYgbmFtZSBpbiBjc3NOb3JtYWxUcmFuc2Zvcm0gKSB7XG5cdFx0XHR2YWwgPSBjc3NOb3JtYWxUcmFuc2Zvcm1bIG5hbWUgXTtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4sIGNvbnZlcnRpbmcgdG8gbnVtYmVyIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGpRdWVyeS5pc051bWVyaWMoIG51bSApID8gbnVtIHx8IDAgOiB2YWw7XG5cdFx0fVxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaChbIFwiaGVpZ2h0XCIsIFwid2lkdGhcIiBdLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQsIGV4dHJhICkge1xuXHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdFx0Ly8gY2VydGFpbiBlbGVtZW50cyBjYW4gaGF2ZSBkaW1lbnNpb24gaW5mbyBpZiB3ZSBpbnZpc2libHkgc2hvdyB0aGVtXG5cdFx0XHRcdC8vIGhvd2V2ZXIsIGl0IG11c3QgaGF2ZSBhIGN1cnJlbnQgZGlzcGxheSBzdHlsZSB0aGF0IHdvdWxkIGJlbmVmaXQgZnJvbSB0aGlzXG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmIGVsZW0ub2Zmc2V0V2lkdGggPT09IDAgP1xuXHRcdFx0XHRcdGpRdWVyeS5zd2FwKCBlbGVtLCBjc3NTaG93LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHJldHVybiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApO1xuXHRcdFx0XHRcdH0pIDpcblx0XHRcdFx0XHRnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgc3R5bGVzID0gZXh0cmEgJiYgZ2V0U3R5bGVzKCBlbGVtICk7XG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBleHRyYSA/XG5cdFx0XHRcdGF1Z21lbnRXaWR0aE9ySGVpZ2h0KFxuXHRcdFx0XHRcdGVsZW0sXG5cdFx0XHRcdFx0bmFtZSxcblx0XHRcdFx0XHRleHRyYSxcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImJveFNpemluZ1wiLCBmYWxzZSwgc3R5bGVzICkgPT09IFwiYm9yZGVyLWJveFwiLFxuXHRcdFx0XHRcdHN0eWxlc1xuXHRcdFx0XHQpIDogMFxuXHRcdFx0KTtcblx0XHR9XG5cdH07XG59KTtcblxuLy8gU3VwcG9ydDogQW5kcm9pZCAyLjNcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5SaWdodCA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5yZWxpYWJsZU1hcmdpblJpZ2h0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdC8vIFdlYktpdCBCdWcgMTMzNDMgLSBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgd3JvbmcgdmFsdWUgZm9yIG1hcmdpbi1yaWdodFxuXHRcdFx0Ly8gV29yayBhcm91bmQgYnkgdGVtcG9yYXJpbHkgc2V0dGluZyBlbGVtZW50IGRpc3BsYXkgdG8gaW5saW5lLWJsb2NrXG5cdFx0XHRyZXR1cm4galF1ZXJ5LnN3YXAoIGVsZW0sIHsgXCJkaXNwbGF5XCI6IFwiaW5saW5lLWJsb2NrXCIgfSxcblx0XHRcdFx0Y3VyQ1NTLCBbIGVsZW0sIFwibWFyZ2luUmlnaHRcIiBdICk7XG5cdFx0fVxuXHR9XG4pO1xuXG4vLyBUaGVzZSBob29rcyBhcmUgdXNlZCBieSBhbmltYXRlIHRvIGV4cGFuZCBwcm9wZXJ0aWVzXG5qUXVlcnkuZWFjaCh7XG5cdG1hcmdpbjogXCJcIixcblx0cGFkZGluZzogXCJcIixcblx0Ym9yZGVyOiBcIldpZHRoXCJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHtcblx0XHRleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBpID0gMCxcblx0XHRcdFx0ZXhwYW5kZWQgPSB7fSxcblxuXHRcdFx0XHQvLyBhc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcblx0XHRcdFx0cGFydHMgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zcGxpdChcIiBcIikgOiBbIHZhbHVlIF07XG5cblx0XHRcdGZvciAoIDsgaSA8IDQ7IGkrKyApIHtcblx0XHRcdFx0ZXhwYW5kZWRbIHByZWZpeCArIGNzc0V4cGFuZFsgaSBdICsgc3VmZml4IF0gPVxuXHRcdFx0XHRcdHBhcnRzWyBpIF0gfHwgcGFydHNbIGkgLSAyIF0gfHwgcGFydHNbIDAgXTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV4cGFuZGVkO1xuXHRcdH1cblx0fTtcblxuXHRpZiAoICFybWFyZ2luLnRlc3QoIHByZWZpeCApICkge1xuXHRcdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0uc2V0ID0gc2V0UG9zaXRpdmVOdW1iZXI7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0Y3NzOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdFx0dmFyIHN0eWxlcywgbGVuLFxuXHRcdFx0XHRtYXAgPSB7fSxcblx0XHRcdFx0aSA9IDA7XG5cblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIG5hbWUgKSApIHtcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICk7XG5cdFx0XHRcdGxlbiA9IG5hbWUubGVuZ3RoO1xuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdG1hcFsgbmFtZVsgaSBdIF0gPSBqUXVlcnkuY3NzKCBlbGVtLCBuYW1lWyBpIF0sIGZhbHNlLCBzdHlsZXMgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBtYXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lLCB2YWx1ZSApIDpcblx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xuXHRcdH0sIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXHRzaG93OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMsIHRydWUgKTtcblx0fSxcblx0aGlkZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzICk7XG5cdH0sXG5cdHRvZ2dsZTogZnVuY3Rpb24oIHN0YXRlICkge1xuXHRcdGlmICggdHlwZW9mIHN0YXRlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZSA/IHRoaXMuc2hvdygpIDogdGhpcy5oaWRlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggaXNIaWRkZW4oIHRoaXMgKSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuc2hvdygpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuaGlkZSgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KTtcblxuXG5mdW5jdGlvbiBUd2VlbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKSB7XG5cdHJldHVybiBuZXcgVHdlZW4ucHJvdG90eXBlLmluaXQoIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICk7XG59XG5qUXVlcnkuVHdlZW4gPSBUd2VlbjtcblxuVHdlZW4ucHJvdG90eXBlID0ge1xuXHRjb25zdHJ1Y3RvcjogVHdlZW4sXG5cdGluaXQ6IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZywgdW5pdCApIHtcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xuXHRcdHRoaXMucHJvcCA9IHByb3A7XG5cdFx0dGhpcy5lYXNpbmcgPSBlYXNpbmcgfHwgXCJzd2luZ1wiO1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcblx0XHR0aGlzLmVuZCA9IGVuZDtcblx0XHR0aGlzLnVuaXQgPSB1bml0IHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApO1xuXHR9LFxuXHRjdXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRyZXR1cm4gaG9va3MgJiYgaG9va3MuZ2V0ID9cblx0XHRcdGhvb2tzLmdldCggdGhpcyApIDpcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcblx0fSxcblx0cnVuOiBmdW5jdGlvbiggcGVyY2VudCApIHtcblx0XHR2YXIgZWFzZWQsXG5cdFx0XHRob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBqUXVlcnkuZWFzaW5nWyB0aGlzLmVhc2luZyBdKFxuXHRcdFx0XHRwZXJjZW50LCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKiBwZXJjZW50LCAwLCAxLCB0aGlzLm9wdGlvbnMuZHVyYXRpb25cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBwZXJjZW50O1xuXHRcdH1cblx0XHR0aGlzLm5vdyA9ICggdGhpcy5lbmQgLSB0aGlzLnN0YXJ0ICkgKiBlYXNlZCArIHRoaXMuc3RhcnQ7XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xuXHRcdFx0dGhpcy5vcHRpb25zLnN0ZXAuY2FsbCggdGhpcy5lbGVtLCB0aGlzLm5vdywgdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgaG9va3Muc2V0ICkge1xuXHRcdFx0aG9va3Muc2V0KCB0aGlzICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5zZXQoIHRoaXMgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn07XG5cblR3ZWVuLnByb3RvdHlwZS5pbml0LnByb3RvdHlwZSA9IFR3ZWVuLnByb3RvdHlwZTtcblxuVHdlZW4ucHJvcEhvb2tzID0ge1xuXHRfZGVmYXVsdDoge1xuXHRcdGdldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0dmFyIHJlc3VsdDtcblxuXHRcdFx0aWYgKCB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gIT0gbnVsbCAmJlxuXHRcdFx0XHQoIXR3ZWVuLmVsZW0uc3R5bGUgfHwgdHdlZW4uZWxlbS5zdHlsZVsgdHdlZW4ucHJvcCBdID09IG51bGwpICkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBwYXNzaW5nIGFuIGVtcHR5IHN0cmluZyBhcyBhIDNyZCBwYXJhbWV0ZXIgdG8gLmNzcyB3aWxsIGF1dG9tYXRpY2FsbHlcblx0XHRcdC8vIGF0dGVtcHQgYSBwYXJzZUZsb2F0IGFuZCBmYWxsYmFjayB0byBhIHN0cmluZyBpZiB0aGUgcGFyc2UgZmFpbHNcblx0XHRcdC8vIHNvLCBzaW1wbGUgdmFsdWVzIHN1Y2ggYXMgXCIxMHB4XCIgYXJlIHBhcnNlZCB0byBGbG9hdC5cblx0XHRcdC8vIGNvbXBsZXggdmFsdWVzIHN1Y2ggYXMgXCJyb3RhdGUoMXJhZClcIiBhcmUgcmV0dXJuZWQgYXMgaXMuXG5cdFx0XHRyZXN1bHQgPSBqUXVlcnkuY3NzKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCBcIlwiICk7XG5cdFx0XHQvLyBFbXB0eSBzdHJpbmdzLCBudWxsLCB1bmRlZmluZWQgYW5kIFwiYXV0b1wiIGFyZSBjb252ZXJ0ZWQgdG8gMC5cblx0XHRcdHJldHVybiAhcmVzdWx0IHx8IHJlc3VsdCA9PT0gXCJhdXRvXCIgPyAwIDogcmVzdWx0O1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0XHQvLyB1c2Ugc3RlcCBob29rIGZvciBiYWNrIGNvbXBhdCAtIHVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZSAtIHVzZSAuc3R5bGUgaWYgaXRzXG5cdFx0XHQvLyBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZVxuXHRcdFx0aWYgKCBqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdICkge1xuXHRcdFx0XHRqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdKCB0d2VlbiApO1xuXHRcdFx0fSBlbHNlIGlmICggdHdlZW4uZWxlbS5zdHlsZSAmJiAoIHR3ZWVuLmVsZW0uc3R5bGVbIGpRdWVyeS5jc3NQcm9wc1sgdHdlZW4ucHJvcCBdIF0gIT0gbnVsbCB8fCBqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSApICkge1xuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIFN1cHBvcnQ6IElFOVxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXG5cblR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHtcblx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0aWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlICYmIHR3ZWVuLmVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5lYXNpbmcgPSB7XG5cdGxpbmVhcjogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIHA7XG5cdH0sXG5cdHN3aW5nOiBmdW5jdGlvbiggcCApIHtcblx0XHRyZXR1cm4gMC41IC0gTWF0aC5jb3MoIHAgKiBNYXRoLlBJICkgLyAyO1xuXHR9XG59O1xuXG5qUXVlcnkuZnggPSBUd2Vlbi5wcm90b3R5cGUuaW5pdDtcblxuLy8gQmFjayBDb21wYXQgPDEuOCBleHRlbnNpb24gcG9pbnRcbmpRdWVyeS5meC5zdGVwID0ge307XG5cblxuXG5cbnZhclxuXHRmeE5vdywgdGltZXJJZCxcblx0cmZ4dHlwZXMgPSAvXig/OnRvZ2dsZXxzaG93fGhpZGUpJC8sXG5cdHJmeG51bSA9IG5ldyBSZWdFeHAoIFwiXig/OihbKy1dKT18KShcIiArIHBudW0gKyBcIikoW2EteiVdKikkXCIsIFwiaVwiICksXG5cdHJydW4gPSAvcXVldWVIb29rcyQvLFxuXHRhbmltYXRpb25QcmVmaWx0ZXJzID0gWyBkZWZhdWx0UHJlZmlsdGVyIF0sXG5cdHR3ZWVuZXJzID0ge1xuXHRcdFwiKlwiOiBbIGZ1bmN0aW9uKCBwcm9wLCB2YWx1ZSApIHtcblx0XHRcdHZhciB0d2VlbiA9IHRoaXMuY3JlYXRlVHdlZW4oIHByb3AsIHZhbHVlICksXG5cdFx0XHRcdHRhcmdldCA9IHR3ZWVuLmN1cigpLFxuXHRcdFx0XHRwYXJ0cyA9IHJmeG51bS5leGVjKCB2YWx1ZSApLFxuXHRcdFx0XHR1bml0ID0gcGFydHMgJiYgcGFydHNbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKSxcblxuXHRcdFx0XHQvLyBTdGFydGluZyB2YWx1ZSBjb21wdXRhdGlvbiBpcyByZXF1aXJlZCBmb3IgcG90ZW50aWFsIHVuaXQgbWlzbWF0Y2hlc1xuXHRcdFx0XHRzdGFydCA9ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdIHx8IHVuaXQgIT09IFwicHhcIiAmJiArdGFyZ2V0ICkgJiZcblx0XHRcdFx0XHRyZnhudW0uZXhlYyggalF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgcHJvcCApICksXG5cdFx0XHRcdHNjYWxlID0gMSxcblx0XHRcdFx0bWF4SXRlcmF0aW9ucyA9IDIwO1xuXG5cdFx0XHRpZiAoIHN0YXJ0ICYmIHN0YXJ0WyAzIF0gIT09IHVuaXQgKSB7XG5cdFx0XHRcdC8vIFRydXN0IHVuaXRzIHJlcG9ydGVkIGJ5IGpRdWVyeS5jc3Ncblx0XHRcdFx0dW5pdCA9IHVuaXQgfHwgc3RhcnRbIDMgXTtcblxuXHRcdFx0XHQvLyBNYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSB0d2VlbiBwcm9wZXJ0aWVzIGxhdGVyIG9uXG5cdFx0XHRcdHBhcnRzID0gcGFydHMgfHwgW107XG5cblx0XHRcdFx0Ly8gSXRlcmF0aXZlbHkgYXBwcm94aW1hdGUgZnJvbSBhIG5vbnplcm8gc3RhcnRpbmcgcG9pbnRcblx0XHRcdFx0c3RhcnQgPSArdGFyZ2V0IHx8IDE7XG5cblx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdC8vIElmIHByZXZpb3VzIGl0ZXJhdGlvbiB6ZXJvZWQgb3V0LCBkb3VibGUgdW50aWwgd2UgZ2V0ICpzb21ldGhpbmcqXG5cdFx0XHRcdFx0Ly8gVXNlIGEgc3RyaW5nIGZvciBkb3VibGluZyBmYWN0b3Igc28gd2UgZG9uJ3QgYWNjaWRlbnRhbGx5IHNlZSBzY2FsZSBhcyB1bmNoYW5nZWQgYmVsb3dcblx0XHRcdFx0XHRzY2FsZSA9IHNjYWxlIHx8IFwiLjVcIjtcblxuXHRcdFx0XHRcdC8vIEFkanVzdCBhbmQgYXBwbHlcblx0XHRcdFx0XHRzdGFydCA9IHN0YXJ0IC8gc2NhbGU7XG5cdFx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCBwcm9wLCBzdGFydCArIHVuaXQgKTtcblxuXHRcdFx0XHQvLyBVcGRhdGUgc2NhbGUsIHRvbGVyYXRpbmcgemVybyBvciBOYU4gZnJvbSB0d2Vlbi5jdXIoKVxuXHRcdFx0XHQvLyBBbmQgYnJlYWtpbmcgdGhlIGxvb3AgaWYgc2NhbGUgaXMgdW5jaGFuZ2VkIG9yIHBlcmZlY3QsIG9yIGlmIHdlJ3ZlIGp1c3QgaGFkIGVub3VnaFxuXHRcdFx0XHR9IHdoaWxlICggc2NhbGUgIT09IChzY2FsZSA9IHR3ZWVuLmN1cigpIC8gdGFyZ2V0KSAmJiBzY2FsZSAhPT0gMSAmJiAtLW1heEl0ZXJhdGlvbnMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVXBkYXRlIHR3ZWVuIHByb3BlcnRpZXNcblx0XHRcdGlmICggcGFydHMgKSB7XG5cdFx0XHRcdHN0YXJ0ID0gdHdlZW4uc3RhcnQgPSArc3RhcnQgfHwgK3RhcmdldCB8fCAwO1xuXHRcdFx0XHR0d2Vlbi51bml0ID0gdW5pdDtcblx0XHRcdFx0Ly8gSWYgYSArPS8tPSB0b2tlbiB3YXMgcHJvdmlkZWQsIHdlJ3JlIGRvaW5nIGEgcmVsYXRpdmUgYW5pbWF0aW9uXG5cdFx0XHRcdHR3ZWVuLmVuZCA9IHBhcnRzWyAxIF0gP1xuXHRcdFx0XHRcdHN0YXJ0ICsgKCBwYXJ0c1sgMSBdICsgMSApICogcGFydHNbIDIgXSA6XG5cdFx0XHRcdFx0K3BhcnRzWyAyIF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHR9IF1cblx0fTtcblxuLy8gQW5pbWF0aW9ucyBjcmVhdGVkIHN5bmNocm9ub3VzbHkgd2lsbCBydW4gc3luY2hyb25vdXNseVxuZnVuY3Rpb24gY3JlYXRlRnhOb3coKSB7XG5cdHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XG5cdH0pO1xuXHRyZXR1cm4gKCBmeE5vdyA9IGpRdWVyeS5ub3coKSApO1xufVxuXG4vLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvblxuZnVuY3Rpb24gZ2VuRngoIHR5cGUsIGluY2x1ZGVXaWR0aCApIHtcblx0dmFyIHdoaWNoLFxuXHRcdGkgPSAwLFxuXHRcdGF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTtcblxuXHQvLyBpZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsXG5cdC8vIGlmIHdlIGRvbid0IGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMiB0byBza2lwIG92ZXIgTGVmdCBhbmQgUmlnaHRcblx0aW5jbHVkZVdpZHRoID0gaW5jbHVkZVdpZHRoID8gMSA6IDA7XG5cdGZvciAoIDsgaSA8IDQgOyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XG5cdFx0d2hpY2ggPSBjc3NFeHBhbmRbIGkgXTtcblx0XHRhdHRyc1sgXCJtYXJnaW5cIiArIHdoaWNoIF0gPSBhdHRyc1sgXCJwYWRkaW5nXCIgKyB3aGljaCBdID0gdHlwZTtcblx0fVxuXG5cdGlmICggaW5jbHVkZVdpZHRoICkge1xuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XG5cdH1cblxuXHRyZXR1cm4gYXR0cnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xuXHR2YXIgdHdlZW4sXG5cdFx0Y29sbGVjdGlvbiA9ICggdHdlZW5lcnNbIHByb3AgXSB8fCBbXSApLmNvbmNhdCggdHdlZW5lcnNbIFwiKlwiIF0gKSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gY29sbGVjdGlvbi5sZW5ndGg7XG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCAodHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSkgKSB7XG5cblx0XHRcdC8vIHdlJ3JlIGRvbmUgd2l0aCB0aGlzIHByb3BlcnR5XG5cdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRQcmVmaWx0ZXIoIGVsZW0sIHByb3BzLCBvcHRzICkge1xuXHQvKiBqc2hpbnQgdmFsaWR0aGlzOiB0cnVlICovXG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCB0d2VlbiwgaG9va3MsIG9sZGZpcmUsIGRpc3BsYXksIGNoZWNrRGlzcGxheSxcblx0XHRhbmltID0gdGhpcyxcblx0XHRvcmlnID0ge30sXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlLFxuXHRcdGhpZGRlbiA9IGVsZW0ubm9kZVR5cGUgJiYgaXNIaWRkZW4oIGVsZW0gKSxcblx0XHRkYXRhU2hvdyA9IGRhdGFfcHJpdi5nZXQoIGVsZW0sIFwiZnhzaG93XCIgKTtcblxuXHQvLyBoYW5kbGUgcXVldWU6IGZhbHNlIHByb21pc2VzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIGRvaW5nIHRoaXMgbWFrZXMgc3VyZSB0aGF0IHRoZSBjb21wbGV0ZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkXG5cdFx0XHQvLyBiZWZvcmUgdGhpcyBjb21wbGV0ZXNcblx0XHRcdGFuaW0uYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xuXHRcdFx0XHRpZiAoICFqUXVlcnkucXVldWUoIGVsZW0sIFwiZnhcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gaGVpZ2h0L3dpZHRoIG92ZXJmbG93IHBhc3Ncblx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCJoZWlnaHRcIiBpbiBwcm9wcyB8fCBcIndpZHRoXCIgaW4gcHJvcHMgKSApIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCBub3RoaW5nIHNuZWFrcyBvdXRcblx0XHQvLyBSZWNvcmQgYWxsIDMgb3ZlcmZsb3cgYXR0cmlidXRlcyBiZWNhdXNlIElFOS0xMCBkbyBub3Rcblx0XHQvLyBjaGFuZ2UgdGhlIG92ZXJmbG93IGF0dHJpYnV0ZSB3aGVuIG92ZXJmbG93WCBhbmRcblx0XHQvLyBvdmVyZmxvd1kgYXJlIHNldCB0byB0aGUgc2FtZSB2YWx1ZVxuXHRcdG9wdHMub3ZlcmZsb3cgPSBbIHN0eWxlLm92ZXJmbG93LCBzdHlsZS5vdmVyZmxvd1gsIHN0eWxlLm92ZXJmbG93WSBdO1xuXG5cdFx0Ly8gU2V0IGRpc3BsYXkgcHJvcGVydHkgdG8gaW5saW5lLWJsb2NrIGZvciBoZWlnaHQvd2lkdGhcblx0XHQvLyBhbmltYXRpb25zIG9uIGlubGluZSBlbGVtZW50cyB0aGF0IGFyZSBoYXZpbmcgd2lkdGgvaGVpZ2h0IGFuaW1hdGVkXG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cblx0XHQvLyBUZXN0IGRlZmF1bHQgZGlzcGxheSBpZiBkaXNwbGF5IGlzIGN1cnJlbnRseSBcIm5vbmVcIlxuXHRcdGNoZWNrRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID9cblx0XHRcdGRhdGFfcHJpdi5nZXQoIGVsZW0sIFwib2xkZGlzcGxheVwiICkgfHwgZGVmYXVsdERpc3BsYXkoIGVsZW0ubm9kZU5hbWUgKSA6IGRpc3BsYXk7XG5cblx0XHRpZiAoIGNoZWNrRGlzcGxheSA9PT0gXCJpbmxpbmVcIiAmJiBqUXVlcnkuY3NzKCBlbGVtLCBcImZsb2F0XCIgKSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRzdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIjtcblx0XHR9XG5cdH1cblxuXHRpZiAoIG9wdHMub3ZlcmZsb3cgKSB7XG5cdFx0c3R5bGUub3ZlcmZsb3cgPSBcImhpZGRlblwiO1xuXHRcdGFuaW0uYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0c3R5bGUub3ZlcmZsb3cgPSBvcHRzLm92ZXJmbG93WyAwIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1kgPSBvcHRzLm92ZXJmbG93WyAyIF07XG5cdFx0fSk7XG5cdH1cblxuXHQvLyBzaG93L2hpZGUgcGFzc1xuXHRmb3IgKCBwcm9wIGluIHByb3BzICkge1xuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcblx0XHRpZiAoIHJmeHR5cGVzLmV4ZWMoIHZhbHVlICkgKSB7XG5cdFx0XHRkZWxldGUgcHJvcHNbIHByb3AgXTtcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcblx0XHRcdGlmICggdmFsdWUgPT09ICggaGlkZGVuID8gXCJoaWRlXCIgOiBcInNob3dcIiApICkge1xuXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGRhdGFTaG93IGxlZnQgb3ZlciBmcm9tIGEgc3RvcHBlZCBoaWRlIG9yIHNob3cgYW5kIHdlIGFyZSBnb2luZyB0byBwcm9jZWVkIHdpdGggc2hvdywgd2Ugc2hvdWxkIHByZXRlbmQgdG8gYmUgaGlkZGVuXG5cdFx0XHRcdGlmICggdmFsdWUgPT09IFwic2hvd1wiICYmIGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSB0cnVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRvcmlnWyBwcm9wIF0gPSBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdIHx8IGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCApO1xuXG5cdFx0Ly8gQW55IG5vbi1meCB2YWx1ZSBzdG9wcyB1cyBmcm9tIHJlc3RvcmluZyB0aGUgb3JpZ2luYWwgZGlzcGxheSB2YWx1ZVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRkaXNwbGF5ID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXG5cdGlmICggIWpRdWVyeS5pc0VtcHR5T2JqZWN0KCBvcmlnICkgKSB7XG5cdFx0aWYgKCBkYXRhU2hvdyApIHtcblx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcblx0XHRcdFx0aGlkZGVuID0gZGF0YVNob3cuaGlkZGVuO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRkYXRhU2hvdyA9IGRhdGFfcHJpdi5hY2Nlc3MoIGVsZW0sIFwiZnhzaG93XCIsIHt9ICk7XG5cdFx0fVxuXG5cdFx0Ly8gc3RvcmUgc3RhdGUgaWYgaXRzIHRvZ2dsZSAtIGVuYWJsZXMgLnN0b3AoKS50b2dnbGUoKSB0byBcInJldmVyc2VcIlxuXHRcdGlmICggdG9nZ2xlICkge1xuXHRcdFx0ZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjtcblx0XHR9XG5cdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRqUXVlcnkoIGVsZW0gKS5zaG93KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFuaW0uZG9uZShmdW5jdGlvbigpIHtcblx0XHRcdFx0alF1ZXJ5KCBlbGVtICkuaGlkZSgpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdGFuaW0uZG9uZShmdW5jdGlvbigpIHtcblx0XHRcdHZhciBwcm9wO1xuXG5cdFx0XHRkYXRhX3ByaXYucmVtb3ZlKCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgb3JpZ1sgcHJvcCBdICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0dHdlZW4gPSBjcmVhdGVUd2VlbiggaGlkZGVuID8gZGF0YVNob3dbIHByb3AgXSA6IDAsIHByb3AsIGFuaW0gKTtcblxuXHRcdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XG5cdFx0XHRcdGRhdGFTaG93WyBwcm9wIF0gPSB0d2Vlbi5zdGFydDtcblx0XHRcdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRcdFx0dHdlZW4uZW5kID0gdHdlZW4uc3RhcnQ7XG5cdFx0XHRcdFx0dHdlZW4uc3RhcnQgPSBwcm9wID09PSBcIndpZHRoXCIgfHwgcHJvcCA9PT0gXCJoZWlnaHRcIiA/IDEgOiAwO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdC8vIElmIHRoaXMgaXMgYSBub29wIGxpa2UgLmhpZGUoKS5oaWRlKCksIHJlc3RvcmUgYW4gb3ZlcndyaXR0ZW4gZGlzcGxheSB2YWx1ZVxuXHR9IGVsc2UgaWYgKCAoZGlzcGxheSA9PT0gXCJub25lXCIgPyBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheSkgPT09IFwiaW5saW5lXCIgKSB7XG5cdFx0c3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XG5cdH1cbn1cblxuZnVuY3Rpb24gcHJvcEZpbHRlciggcHJvcHMsIHNwZWNpYWxFYXNpbmcgKSB7XG5cdHZhciBpbmRleCwgbmFtZSwgZWFzaW5nLCB2YWx1ZSwgaG9va3M7XG5cblx0Ly8gY2FtZWxDYXNlLCBzcGVjaWFsRWFzaW5nIGFuZCBleHBhbmQgY3NzSG9vayBwYXNzXG5cdGZvciAoIGluZGV4IGluIHByb3BzICkge1xuXHRcdG5hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBpbmRleCApO1xuXHRcdGVhc2luZyA9IHNwZWNpYWxFYXNpbmdbIG5hbWUgXTtcblx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdO1xuXHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRlYXNpbmcgPSB2YWx1ZVsgMSBdO1xuXHRcdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyAwIF07XG5cdFx0fVxuXG5cdFx0aWYgKCBpbmRleCAhPT0gbmFtZSApIHtcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgaW5kZXggXTtcblx0XHR9XG5cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdO1xuXHRcdGlmICggaG9va3MgJiYgXCJleHBhbmRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBuYW1lIF07XG5cblx0XHRcdC8vIG5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b250IG92ZXJ3cml0ZSBrZXlzIGFscmVhZHkgcHJlc2VudC5cblx0XHRcdC8vIGFsc28gLSByZXVzaW5nICdpbmRleCcgZnJvbSBhYm92ZSBiZWNhdXNlIHdlIGhhdmUgdGhlIGNvcnJlY3QgXCJuYW1lXCJcblx0XHRcdGZvciAoIGluZGV4IGluIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XG5cdFx0XHRcdFx0cHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgaW5kZXggXTtcblx0XHRcdFx0XHRzcGVjaWFsRWFzaW5nWyBpbmRleCBdID0gZWFzaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gQW5pbWF0aW9uKCBlbGVtLCBwcm9wZXJ0aWVzLCBvcHRpb25zICkge1xuXHR2YXIgcmVzdWx0LFxuXHRcdHN0b3BwZWQsXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGFuaW1hdGlvblByZWZpbHRlcnMubGVuZ3RoLFxuXHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHtcblx0XHRcdC8vIGRvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxuXHRcdFx0ZGVsZXRlIHRpY2suZWxlbTtcblx0XHR9KSxcblx0XHR0aWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHZhciBjdXJyZW50VGltZSA9IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRcdHJlbWFpbmluZyA9IE1hdGgubWF4KCAwLCBhbmltYXRpb24uc3RhcnRUaW1lICsgYW5pbWF0aW9uLmR1cmF0aW9uIC0gY3VycmVudFRpbWUgKSxcblx0XHRcdFx0Ly8gYXJjaGFpYyBjcmFzaCBidWcgd29uJ3QgYWxsb3cgdXMgdG8gdXNlIDEgLSAoIDAuNSB8fCAwICkgKCMxMjQ5Nylcblx0XHRcdFx0dGVtcCA9IHJlbWFpbmluZyAvIGFuaW1hdGlvbi5kdXJhdGlvbiB8fCAwLFxuXHRcdFx0XHRwZXJjZW50ID0gMSAtIHRlbXAsXG5cdFx0XHRcdGluZGV4ID0gMCxcblx0XHRcdFx0bGVuZ3RoID0gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGg7XG5cblx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0pO1xuXG5cdFx0XHRpZiAoIHBlcmNlbnQgPCAxICYmIGxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHJlbWFpbmluZztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiBdICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2Uoe1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwgeyBzcGVjaWFsRWFzaW5nOiB7fSB9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdFx0YW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZ1sgcHJvcCBdIHx8IGFuaW1hdGlvbi5vcHRzLmVhc2luZyApO1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zLnB1c2goIHR3ZWVuICk7XG5cdFx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHRcdH0sXG5cdFx0XHRzdG9wOiBmdW5jdGlvbiggZ290b0VuZCApIHtcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcblx0XHRcdFx0XHQvLyBpZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCAxICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyByZXNvbHZlIHdoZW4gd2UgcGxheWVkIHRoZSBsYXN0IGZyYW1lXG5cdFx0XHRcdC8vIG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH1cblx0XHR9KSxcblx0XHRwcm9wcyA9IGFuaW1hdGlvbi5wcm9wcztcblxuXHRwcm9wRmlsdGVyKCBwcm9wcywgYW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZyApO1xuXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdHJlc3VsdCA9IGFuaW1hdGlvblByZWZpbHRlcnNbIGluZGV4IF0uY2FsbCggYW5pbWF0aW9uLCBlbGVtLCBwcm9wcywgYW5pbWF0aW9uLm9wdHMgKTtcblx0XHRpZiAoIHJlc3VsdCApIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHR9XG5cblx0alF1ZXJ5Lm1hcCggcHJvcHMsIGNyZWF0ZVR3ZWVuLCBhbmltYXRpb24gKTtcblxuXHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhbmltYXRpb24ub3B0cy5zdGFydCApICkge1xuXHRcdGFuaW1hdGlvbi5vcHRzLnN0YXJ0LmNhbGwoIGVsZW0sIGFuaW1hdGlvbiApO1xuXHR9XG5cblx0alF1ZXJ5LmZ4LnRpbWVyKFxuXHRcdGpRdWVyeS5leHRlbmQoIHRpY2ssIHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRhbmltOiBhbmltYXRpb24sXG5cdFx0XHRxdWV1ZTogYW5pbWF0aW9uLm9wdHMucXVldWVcblx0XHR9KVxuXHQpO1xuXG5cdC8vIGF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdHJldHVybiBhbmltYXRpb24ucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcblx0XHQuZG9uZSggYW5pbWF0aW9uLm9wdHMuZG9uZSwgYW5pbWF0aW9uLm9wdHMuY29tcGxldGUgKVxuXHRcdC5mYWlsKCBhbmltYXRpb24ub3B0cy5mYWlsIClcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXG5cdHR3ZWVuZXI6IGZ1bmN0aW9uKCBwcm9wcywgY2FsbGJhY2sgKSB7XG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcHJvcHMgKSApIHtcblx0XHRcdGNhbGxiYWNrID0gcHJvcHM7XG5cdFx0XHRwcm9wcyA9IFsgXCIqXCIgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cHJvcHMgPSBwcm9wcy5zcGxpdChcIiBcIik7XG5cdFx0fVxuXG5cdFx0dmFyIHByb3AsXG5cdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoIDsgaW5kZXgrKyApIHtcblx0XHRcdHByb3AgPSBwcm9wc1sgaW5kZXggXTtcblx0XHRcdHR3ZWVuZXJzWyBwcm9wIF0gPSB0d2VlbmVyc1sgcHJvcCBdIHx8IFtdO1xuXHRcdFx0dHdlZW5lcnNbIHByb3AgXS51bnNoaWZ0KCBjYWxsYmFjayApO1xuXHRcdH1cblx0fSxcblxuXHRwcmVmaWx0ZXI6IGZ1bmN0aW9uKCBjYWxsYmFjaywgcHJlcGVuZCApIHtcblx0XHRpZiAoIHByZXBlbmQgKSB7XG5cdFx0XHRhbmltYXRpb25QcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFuaW1hdGlvblByZWZpbHRlcnMucHVzaCggY2FsbGJhY2sgKTtcblx0XHR9XG5cdH1cbn0pO1xuXG5qUXVlcnkuc3BlZWQgPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgZm4gKSB7XG5cdHZhciBvcHQgPSBzcGVlZCAmJiB0eXBlb2Ygc3BlZWQgPT09IFwib2JqZWN0XCIgPyBqUXVlcnkuZXh0ZW5kKCB7fSwgc3BlZWQgKSA6IHtcblx0XHRjb21wbGV0ZTogZm4gfHwgIWZuICYmIGVhc2luZyB8fFxuXHRcdFx0alF1ZXJ5LmlzRnVuY3Rpb24oIHNwZWVkICkgJiYgc3BlZWQsXG5cdFx0ZHVyYXRpb246IHNwZWVkLFxuXHRcdGVhc2luZzogZm4gJiYgZWFzaW5nIHx8IGVhc2luZyAmJiAhalF1ZXJ5LmlzRnVuY3Rpb24oIGVhc2luZyApICYmIGVhc2luZ1xuXHR9O1xuXG5cdG9wdC5kdXJhdGlvbiA9IGpRdWVyeS5meC5vZmYgPyAwIDogdHlwZW9mIG9wdC5kdXJhdGlvbiA9PT0gXCJudW1iZXJcIiA/IG9wdC5kdXJhdGlvbiA6XG5cdFx0b3B0LmR1cmF0aW9uIGluIGpRdWVyeS5meC5zcGVlZHMgPyBqUXVlcnkuZnguc3BlZWRzWyBvcHQuZHVyYXRpb24gXSA6IGpRdWVyeS5meC5zcGVlZHMuX2RlZmF1bHQ7XG5cblx0Ly8gbm9ybWFsaXplIG9wdC5xdWV1ZSAtIHRydWUvdW5kZWZpbmVkL251bGwgLT4gXCJmeFwiXG5cdGlmICggb3B0LnF1ZXVlID09IG51bGwgfHwgb3B0LnF1ZXVlID09PSB0cnVlICkge1xuXHRcdG9wdC5xdWV1ZSA9IFwiZnhcIjtcblx0fVxuXG5cdC8vIFF1ZXVlaW5nXG5cdG9wdC5vbGQgPSBvcHQuY29tcGxldGU7XG5cblx0b3B0LmNvbXBsZXRlID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggb3B0Lm9sZCApICkge1xuXHRcdFx0b3B0Lm9sZC5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHQucXVldWUgKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBvcHQ7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0ZmFkZVRvOiBmdW5jdGlvbiggc3BlZWQsIHRvLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXG5cdFx0Ly8gc2hvdyBhbnkgaGlkZGVuIGVsZW1lbnRzIGFmdGVyIHNldHRpbmcgb3BhY2l0eSB0byAwXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKCBpc0hpZGRlbiApLmNzcyggXCJvcGFjaXR5XCIsIDAgKS5zaG93KClcblxuXHRcdFx0Ly8gYW5pbWF0ZSB0byB0aGUgdmFsdWUgc3BlY2lmaWVkXG5cdFx0XHQuZW5kKCkuYW5pbWF0ZSh7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH0sXG5cdGFuaW1hdGU6IGZ1bmN0aW9uKCBwcm9wLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxuXHRcdFx0b3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLFxuXHRcdFx0ZG9BbmltYXRpb24gPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0Ly8gT3BlcmF0ZSBvbiBhIGNvcHkgb2YgcHJvcCBzbyBwZXItcHJvcGVydHkgZWFzaW5nIHdvbid0IGJlIGxvc3Rcblx0XHRcdFx0dmFyIGFuaW0gPSBBbmltYXRpb24oIHRoaXMsIGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wICksIG9wdGFsbCApO1xuXG5cdFx0XHRcdC8vIEVtcHR5IGFuaW1hdGlvbnMsIG9yIGZpbmlzaGluZyByZXNvbHZlcyBpbW1lZGlhdGVseVxuXHRcdFx0XHRpZiAoIGVtcHR5IHx8IGRhdGFfcHJpdi5nZXQoIHRoaXMsIFwiZmluaXNoXCIgKSApIHtcblx0XHRcdFx0XHRhbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdGRvQW5pbWF0aW9uLmZpbmlzaCA9IGRvQW5pbWF0aW9uO1xuXG5cdFx0cmV0dXJuIGVtcHR5IHx8IG9wdGFsbC5xdWV1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0dGhpcy5lYWNoKCBkb0FuaW1hdGlvbiApIDpcblx0XHRcdHRoaXMucXVldWUoIG9wdGFsbC5xdWV1ZSwgZG9BbmltYXRpb24gKTtcblx0fSxcblx0c3RvcDogZnVuY3Rpb24oIHR5cGUsIGNsZWFyUXVldWUsIGdvdG9FbmQgKSB7XG5cdFx0dmFyIHN0b3BRdWV1ZSA9IGZ1bmN0aW9uKCBob29rcyApIHtcblx0XHRcdHZhciBzdG9wID0gaG9va3Muc3RvcDtcblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0c3RvcCggZ290b0VuZCApO1xuXHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0Z290b0VuZCA9IGNsZWFyUXVldWU7XG5cdFx0XHRjbGVhclF1ZXVlID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggY2xlYXJRdWV1ZSAmJiB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZGVxdWV1ZSA9IHRydWUsXG5cdFx0XHRcdGluZGV4ID0gdHlwZSAhPSBudWxsICYmIHR5cGUgKyBcInF1ZXVlSG9va3NcIixcblx0XHRcdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycyxcblx0XHRcdFx0ZGF0YSA9IGRhdGFfcHJpdi5nZXQoIHRoaXMgKTtcblxuXHRcdFx0aWYgKCBpbmRleCApIHtcblx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCApIHtcblx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaW5kZXggaW4gZGF0YSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICYmIHJydW4udGVzdCggaW5kZXggKSApIHtcblx0XHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmICh0eXBlID09IG51bGwgfHwgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlKSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCBnb3RvRW5kICk7XG5cdFx0XHRcdFx0ZGVxdWV1ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gc3RhcnQgdGhlIG5leHQgaW4gdGhlIHF1ZXVlIGlmIHRoZSBsYXN0IHN0ZXAgd2Fzbid0IGZvcmNlZFxuXHRcdFx0Ly8gdGltZXJzIGN1cnJlbnRseSB3aWxsIGNhbGwgdGhlaXIgY29tcGxldGUgY2FsbGJhY2tzLCB3aGljaCB3aWxsIGRlcXVldWVcblx0XHRcdC8vIGJ1dCBvbmx5IGlmIHRoZXkgd2VyZSBnb3RvRW5kXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cdGZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0aWYgKCB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBpbmRleCxcblx0XHRcdFx0ZGF0YSA9IGRhdGFfcHJpdi5nZXQoIHRoaXMgKSxcblx0XHRcdFx0cXVldWUgPSBkYXRhWyB0eXBlICsgXCJxdWV1ZVwiIF0sXG5cdFx0XHRcdGhvb2tzID0gZGF0YVsgdHlwZSArIFwicXVldWVIb29rc1wiIF0sXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXG5cdFx0XHRcdGxlbmd0aCA9IHF1ZXVlID8gcXVldWUubGVuZ3RoIDogMDtcblxuXHRcdFx0Ly8gZW5hYmxlIGZpbmlzaGluZyBmbGFnIG9uIHByaXZhdGUgZGF0YVxuXHRcdFx0ZGF0YS5maW5pc2ggPSB0cnVlO1xuXG5cdFx0XHQvLyBlbXB0eSB0aGUgcXVldWUgZmlyc3Rcblx0XHRcdGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgW10gKTtcblxuXHRcdFx0aWYgKCBob29rcyAmJiBob29rcy5zdG9wICkge1xuXHRcdFx0XHRob29rcy5zdG9wLmNhbGwoIHRoaXMsIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gbG9vayBmb3IgYW55IGFjdGl2ZSBhbmltYXRpb25zLCBhbmQgZmluaXNoIHRoZW1cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIGxvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRpZiAoIHF1ZXVlWyBpbmRleCBdICYmIHF1ZXVlWyBpbmRleCBdLmZpbmlzaCApIHtcblx0XHRcdFx0XHRxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIHR1cm4gb2ZmIGZpbmlzaGluZyBmbGFnXG5cdFx0XHRkZWxldGUgZGF0YS5maW5pc2g7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZWFjaChbIFwidG9nZ2xlXCIsIFwic2hvd1wiLCBcImhpZGVcIiBdLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcblx0dmFyIGNzc0ZuID0galF1ZXJ5LmZuWyBuYW1lIF07XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBzcGVlZCA9PSBudWxsIHx8IHR5cGVvZiBzcGVlZCA9PT0gXCJib29sZWFuXCIgP1xuXHRcdFx0Y3NzRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIDpcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcblx0fTtcbn0pO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCh7XG5cdHNsaWRlRG93bjogZ2VuRngoXCJzaG93XCIpLFxuXHRzbGlkZVVwOiBnZW5GeChcImhpZGVcIiksXG5cdHNsaWRlVG9nZ2xlOiBnZW5GeChcInRvZ2dsZVwiKSxcblx0ZmFkZUluOiB7IG9wYWNpdHk6IFwic2hvd1wiIH0sXG5cdGZhZGVPdXQ6IHsgb3BhY2l0eTogXCJoaWRlXCIgfSxcblx0ZmFkZVRvZ2dsZTogeyBvcGFjaXR5OiBcInRvZ2dsZVwiIH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBwcm9wcyApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHRoaXMuYW5pbWF0ZSggcHJvcHMsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH07XG59KTtcblxualF1ZXJ5LnRpbWVycyA9IFtdO1xualF1ZXJ5LmZ4LnRpY2sgPSBmdW5jdGlvbigpIHtcblx0dmFyIHRpbWVyLFxuXHRcdGkgPSAwLFxuXHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnM7XG5cblx0ZnhOb3cgPSBqUXVlcnkubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cdFx0Ly8gQ2hlY2tzIHRoZSB0aW1lciBoYXMgbm90IGFscmVhZHkgYmVlbiByZW1vdmVkXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0aWYgKCB0aW1lcigpICkge1xuXHRcdGpRdWVyeS5meC5zdGFydCgpO1xuXHR9IGVsc2Uge1xuXHRcdGpRdWVyeS50aW1lcnMucG9wKCk7XG5cdH1cbn07XG5cbmpRdWVyeS5meC5pbnRlcnZhbCA9IDEzO1xuXG5qUXVlcnkuZnguc3RhcnQgPSBmdW5jdGlvbigpIHtcblx0aWYgKCAhdGltZXJJZCApIHtcblx0XHR0aW1lcklkID0gc2V0SW50ZXJ2YWwoIGpRdWVyeS5meC50aWNrLCBqUXVlcnkuZnguaW50ZXJ2YWwgKTtcblx0fVxufTtcblxualF1ZXJ5LmZ4LnN0b3AgPSBmdW5jdGlvbigpIHtcblx0Y2xlYXJJbnRlcnZhbCggdGltZXJJZCApO1xuXHR0aW1lcklkID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXHQvLyBEZWZhdWx0IHNwZWVkXG5cdF9kZWZhdWx0OiA0MDBcbn07XG5cblxuLy8gQmFzZWQgb2ZmIG9mIHRoZSBwbHVnaW4gYnkgQ2xpbnQgSGVsZmVycywgd2l0aCBwZXJtaXNzaW9uLlxuLy8gaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gc2V0VGltZW91dCggbmV4dCwgdGltZSApO1xuXHRcdGhvb2tzLnN0b3AgPSBmdW5jdGlvbigpIHtcblx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dCApO1xuXHRcdH07XG5cdH0pO1xufTtcblxuXG4oZnVuY3Rpb24oKSB7XG5cdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApLFxuXHRcdHNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwic2VsZWN0XCIgKSxcblx0XHRvcHQgPSBzZWxlY3QuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwib3B0aW9uXCIgKSApO1xuXG5cdGlucHV0LnR5cGUgPSBcImNoZWNrYm94XCI7XG5cblx0Ly8gU3VwcG9ydDogaU9TIDUuMSwgQW5kcm9pZCA0LngsIEFuZHJvaWQgMi4zXG5cdC8vIENoZWNrIHRoZSBkZWZhdWx0IGNoZWNrYm94L3JhZGlvIHZhbHVlIChcIlwiIG9uIG9sZCBXZWJLaXQ7IFwib25cIiBlbHNld2hlcmUpXG5cdHN1cHBvcnQuY2hlY2tPbiA9IGlucHV0LnZhbHVlICE9PSBcIlwiO1xuXG5cdC8vIE11c3QgYWNjZXNzIHRoZSBwYXJlbnQgdG8gbWFrZSBhbiBvcHRpb24gc2VsZWN0IHByb3Blcmx5XG5cdC8vIFN1cHBvcnQ6IElFOSwgSUUxMFxuXHRzdXBwb3J0Lm9wdFNlbGVjdGVkID0gb3B0LnNlbGVjdGVkO1xuXG5cdC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBvcHRpb25zIGluc2lkZSBkaXNhYmxlZCBzZWxlY3RzIGFyZW4ndCBtYXJrZWQgYXMgZGlzYWJsZWRcblx0Ly8gKFdlYktpdCBtYXJrcyB0aGVtIGFzIGRpc2FibGVkKVxuXHRzZWxlY3QuZGlzYWJsZWQgPSB0cnVlO1xuXHRzdXBwb3J0Lm9wdERpc2FibGVkID0gIW9wdC5kaXNhYmxlZDtcblxuXHQvLyBDaGVjayBpZiBhbiBpbnB1dCBtYWludGFpbnMgaXRzIHZhbHVlIGFmdGVyIGJlY29taW5nIGEgcmFkaW9cblx0Ly8gU3VwcG9ydDogSUU5LCBJRTEwXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0pKCk7XG5cblxudmFyIG5vZGVIb29rLCBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRhdHRyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggdGhpcywgbmFtZSApO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdGF0dHI6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIGRvbid0IGdldC9zZXQgYXR0cmlidXRlcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIHRvIHByb3Agd2hlbiBhdHRyaWJ1dGVzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgPT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgYXR0cmlidXRlcyBhcmUgbG93ZXJjYXNlXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdIHx8XG5cdFx0XHRcdCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgPyBib29sSG9vayA6IG5vZGVIb29rICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkpICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdC8vIE5vbi1leGlzdGVudCBhdHRyaWJ1dGVzIHJldHVybiBudWxsLCB3ZSBub3JtYWxpemUgdG8gdW5kZWZpbmVkXG5cdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgP1xuXHRcdFx0XHR1bmRlZmluZWQgOlxuXHRcdFx0XHRyZXQ7XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSwgcHJvcE5hbWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKTtcblxuXHRcdGlmICggYXR0ck5hbWVzICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHR3aGlsZSAoIChuYW1lID0gYXR0ck5hbWVzW2krK10pICkge1xuXHRcdFx0XHRwcm9wTmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblxuXHRcdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgZ2V0IHNwZWNpYWwgdHJlYXRtZW50ICgjMTA4NzApXG5cdFx0XHRcdGlmICggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHRcdFx0Ly8gU2V0IGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdG8gZmFsc2Vcblx0XHRcdFx0XHRlbGVtWyBwcm9wTmFtZSBdID0gZmFsc2U7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggbmFtZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHRcdC8vIFNldHRpbmcgdGhlIHR5cGUgb24gYSByYWRpbyBidXR0b24gYWZ0ZXIgdGhlIHZhbHVlIHJlc2V0cyB0aGUgdmFsdWUgaW4gSUU2LTlcblx0XHRcdFx0XHQvLyBSZXNldCB2YWx1ZSB0byBkZWZhdWx0IGluIGNhc2UgdHlwZSBpcyBzZXQgYWZ0ZXIgdmFsdWUgZHVyaW5nIGNyZWF0aW9uXG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gSG9va3MgZm9yIGJvb2xlYW4gYXR0cmlidXRlc1xuYm9vbEhvb2sgPSB7XG5cdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBuYW1lICkge1xuXHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5qUXVlcnkuZWFjaCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goIC9cXHcrL2cgKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdHZhciBnZXR0ZXIgPSBhdHRySGFuZGxlWyBuYW1lIF0gfHwgalF1ZXJ5LmZpbmQuYXR0cjtcblxuXHRhdHRySGFuZGxlWyBuYW1lIF0gPSBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHJldCwgaGFuZGxlO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxuXHRcdFx0aGFuZGxlID0gYXR0ckhhbmRsZVsgbmFtZSBdO1xuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gcmV0O1xuXHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xuXHRcdFx0XHRuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHRudWxsO1xuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gaGFuZGxlO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9O1xufSk7XG5cblxuXG5cbnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHByb3A6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkucHJvcCwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XG5cdH0sXG5cblx0cmVtb3ZlUHJvcDogZnVuY3Rpb24oIG5hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGRlbGV0ZSB0aGlzWyBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWUgXTtcblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH0sXG5cblx0cHJvcDogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLCBub3R4bWwsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBkb24ndCBnZXQvc2V0IHByb3BlcnRpZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCAhZWxlbSB8fCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRub3R4bWwgPSBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICk7XG5cblx0XHRpZiAoIG5vdHhtbCApIHtcblx0XHRcdC8vIEZpeCBuYW1lIGFuZCBhdHRhY2ggaG9va3Ncblx0XHRcdG5hbWUgPSBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWU7XG5cdFx0XHRob29rcyA9IGpRdWVyeS5wcm9wSG9va3NbIG5hbWUgXTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm4gaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApKSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0cmV0IDpcblx0XHRcdFx0KCBlbGVtWyBuYW1lIF0gPSB2YWx1ZSApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSkgIT09IG51bGwgP1xuXHRcdFx0XHRyZXQgOlxuXHRcdFx0XHRlbGVtWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdHByb3BIb29rczoge1xuXHRcdHRhYkluZGV4OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5oYXNBdHRyaWJ1dGUoIFwidGFiaW5kZXhcIiApIHx8IHJmb2N1c2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApIHx8IGVsZW0uaHJlZiA/XG5cdFx0XHRcdFx0ZWxlbS50YWJJbmRleCA6XG5cdFx0XHRcdFx0LTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gU3VwcG9ydDogSUU5K1xuLy8gU2VsZWN0ZWRuZXNzIGZvciBhbiBvcHRpb24gaW4gYW4gb3B0Z3JvdXAgY2FuIGJlIGluYWNjdXJhdGVcbmlmICggIXN1cHBvcnQub3B0U2VsZWN0ZWQgKSB7XG5cdGpRdWVyeS5wcm9wSG9va3Muc2VsZWN0ZWQgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goW1xuXHRcInRhYkluZGV4XCIsXG5cdFwicmVhZE9ubHlcIixcblx0XCJtYXhMZW5ndGhcIixcblx0XCJjZWxsU3BhY2luZ1wiLFxuXHRcImNlbGxQYWRkaW5nXCIsXG5cdFwicm93U3BhblwiLFxuXHRcImNvbFNwYW5cIixcblx0XCJ1c2VNYXBcIixcblx0XCJmcmFtZUJvcmRlclwiLFxuXHRcImNvbnRlbnRFZGl0YWJsZVwiXG5dLCBmdW5jdGlvbigpIHtcblx0alF1ZXJ5LnByb3BGaXhbIHRoaXMudG9Mb3dlckNhc2UoKSBdID0gdGhpcztcbn0pO1xuXG5cblxuXG52YXIgcmNsYXNzID0gL1tcXHRcXHJcXG5cXGZdL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGNsYXp6LCBqLCBmaW5hbFZhbHVlLFxuXHRcdFx0cHJvY2VlZCA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGg7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuYWRkQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIHRoaXMuY2xhc3NOYW1lICkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICggcHJvY2VlZCApIHtcblx0XHRcdC8vIFRoZSBkaXNqdW5jdGlvbiBoZXJlIGlzIGZvciBiZXR0ZXIgY29tcHJlc3NpYmlsaXR5IChzZWUgcmVtb3ZlQ2xhc3MpXG5cdFx0XHRjbGFzc2VzID0gKCB2YWx1ZSB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXTtcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIGVsZW0uY2xhc3NOYW1lID9cblx0XHRcdFx0XHQoIFwiIFwiICsgZWxlbS5jbGFzc05hbWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKSA6XG5cdFx0XHRcdFx0XCIgXCJcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChjbGF6eiA9IGNsYXNzZXNbaisrXSkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIG9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IGpRdWVyeS50cmltKCBjdXIgKTtcblx0XHRcdFx0XHRpZiAoIGVsZW0uY2xhc3NOYW1lICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5jbGFzc05hbWUgPSBmaW5hbFZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRwcm9jZWVkID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGogKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlbW92ZUNsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCB0aGlzLmNsYXNzTmFtZSApICk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKCBwcm9jZWVkICkge1xuXHRcdFx0Y2xhc3NlcyA9ICggdmFsdWUgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGVsZW0gPSB0aGlzWyBpIF07XG5cdFx0XHRcdC8vIFRoaXMgZXhwcmVzc2lvbiBpcyBoZXJlIGZvciBiZXR0ZXIgY29tcHJlc3NpYmlsaXR5IChzZWUgYWRkQ2xhc3MpXG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBlbGVtLmNsYXNzTmFtZSA/XG5cdFx0XHRcdFx0KCBcIiBcIiArIGVsZW0uY2xhc3NOYW1lICsgXCIgXCIgKS5yZXBsYWNlKCByY2xhc3MsIFwiIFwiICkgOlxuXHRcdFx0XHRcdFwiXCJcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoIChjbGF6eiA9IGNsYXNzZXNbaisrXSkgKSB7XG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+PSAwICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIG9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHZhbHVlID8galF1ZXJ5LnRyaW0oIGN1ciApIDogXCJcIjtcblx0XHRcdFx0XHRpZiAoIGVsZW0uY2xhc3NOYW1lICE9PSBmaW5hbFZhbHVlICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5jbGFzc05hbWUgPSBmaW5hbFZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xuXHRcdHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGVWYWwgPT09IFwiYm9vbGVhblwiICYmIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGVWYWwgPyB0aGlzLmFkZENsYXNzKCB2YWx1ZSApIDogdGhpcy5yZW1vdmVDbGFzcyggdmFsdWUgKTtcblx0XHR9XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkudG9nZ2xlQ2xhc3MoIHZhbHVlLmNhbGwodGhpcywgaSwgdGhpcy5jbGFzc05hbWUsIHN0YXRlVmFsKSwgc3RhdGVWYWwgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdC8vIHRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdHZhciBjbGFzc05hbWUsXG5cdFx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdFx0c2VsZiA9IGpRdWVyeSggdGhpcyApLFxuXHRcdFx0XHRcdGNsYXNzTmFtZXMgPSB2YWx1ZS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRcdFx0d2hpbGUgKCAoY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0pICkge1xuXHRcdFx0XHRcdC8vIGNoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB0eXBlID09PSBzdHJ1bmRlZmluZWQgfHwgdHlwZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRcdGlmICggdGhpcy5jbGFzc05hbWUgKSB7XG5cdFx0XHRcdFx0Ly8gc3RvcmUgY2xhc3NOYW1lIGlmIHNldFxuXHRcdFx0XHRcdGRhdGFfcHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCB0aGlzLmNsYXNzTmFtZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgXCJmYWxzZVwiLFxuXHRcdFx0XHQvLyB0aGVuIHJlbW92ZSB0aGUgd2hvbGUgY2xhc3NuYW1lIChpZiB0aGVyZSB3YXMgb25lLCB0aGUgYWJvdmUgc2F2ZWQgaXQpLlxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYnJpbmcgYmFjayB3aGF0ZXZlciB3YXMgcHJldmlvdXNseSBzYXZlZCAoaWYgYW55dGhpbmcpLFxuXHRcdFx0XHQvLyBmYWxsaW5nIGJhY2sgdG8gdGhlIGVtcHR5IHN0cmluZyBpZiBub3RoaW5nIHdhcyBzdG9yZWQuXG5cdFx0XHRcdHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUgfHwgdmFsdWUgPT09IGZhbHNlID8gXCJcIiA6IGRhdGFfcHJpdi5nZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiICkgfHwgXCJcIjtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRoYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRpZiAoIHRoaXNbaV0ubm9kZVR5cGUgPT09IDEgJiYgKFwiIFwiICsgdGhpc1tpXS5jbGFzc05hbWUgKyBcIiBcIikucmVwbGFjZShyY2xhc3MsIFwiIFwiKS5pbmRleE9mKCBjbGFzc05hbWUgKSA+PSAwICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0pO1xuXG5cblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHZhbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBob29rcywgcmV0LCBpc0Z1bmN0aW9uLFxuXHRcdFx0ZWxlbSA9IHRoaXNbMF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcblxuXHRcdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLmdldCggZWxlbSwgXCJ2YWx1ZVwiICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldCA9IGVsZW0udmFsdWU7XG5cblx0XHRcdFx0cmV0dXJuIHR5cGVvZiByZXQgPT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRcdC8vIGhhbmRsZSBtb3N0IGNvbW1vbiBzdHJpbmcgY2FzZXNcblx0XHRcdFx0XHRyZXQucmVwbGFjZShycmV0dXJuLCBcIlwiKSA6XG5cdFx0XHRcdFx0Ly8gaGFuZGxlIGNhc2VzIHdoZXJlIHZhbHVlIGlzIG51bGwvdW5kZWYgb3IgbnVtYmVyXG5cdFx0XHRcdFx0cmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdHZhciB2YWw7XG5cblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlLmNhbGwoIHRoaXMsIGksIGpRdWVyeSggdGhpcyApLnZhbCgpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJlYXQgbnVsbC91bmRlZmluZWQgYXMgXCJcIjsgY29udmVydCBudW1iZXJzIHRvIHN0cmluZ1xuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dmFsID0gXCJcIjtcblxuXHRcdFx0fSBlbHNlIGlmICggdHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0dmFsICs9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0aG9va3MgPSBqUXVlcnkudmFsSG9va3NbIHRoaXMudHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKFwic2V0XCIgaW4gaG9va3MpIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgdmFsID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgXCJ2YWx1ZVwiICk7XG5cdFx0XHRcdHJldHVybiB2YWwgIT0gbnVsbCA/XG5cdFx0XHRcdFx0dmFsIDpcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTEwLTExK1xuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICgjMTQ2ODYsICMxNDg1OClcblx0XHRcdFx0XHRqUXVlcnkudHJpbSggalF1ZXJ5LnRleHQoIGVsZW0gKSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c2VsZWN0OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgdmFsdWUsIG9wdGlvbixcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdGluZGV4ID0gZWxlbS5zZWxlY3RlZEluZGV4LFxuXHRcdFx0XHRcdG9uZSA9IGVsZW0udHlwZSA9PT0gXCJzZWxlY3Qtb25lXCIgfHwgaW5kZXggPCAwLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aCxcblx0XHRcdFx0XHRpID0gaW5kZXggPCAwID9cblx0XHRcdFx0XHRcdG1heCA6XG5cdFx0XHRcdFx0XHRvbmUgPyBpbmRleCA6IDA7XG5cblx0XHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgc2VsZWN0ZWQgb3B0aW9uc1xuXHRcdFx0XHRmb3IgKCA7IGkgPCBtYXg7IGkrKyApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvLyBJRTYtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblx0XHRcdFx0XHRcdFx0Ly8gRG9uJ3QgcmV0dXJuIG9wdGlvbnMgdGhhdCBhcmUgZGlzYWJsZWQgb3IgaW4gYSBkaXNhYmxlZCBvcHRncm91cFxuXHRcdFx0XHRcdFx0XHQoIHN1cHBvcnQub3B0RGlzYWJsZWQgPyAhb3B0aW9uLmRpc2FibGVkIDogb3B0aW9uLmdldEF0dHJpYnV0ZSggXCJkaXNhYmxlZFwiICkgPT09IG51bGwgKSAmJlxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fCAhalF1ZXJ5Lm5vZGVOYW1lKCBvcHRpb24ucGFyZW50Tm9kZSwgXCJvcHRncm91cFwiICkgKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gR2V0IHRoZSBzcGVjaWZpYyB2YWx1ZSBmb3IgdGhlIG9wdGlvblxuXHRcdFx0XHRcdFx0dmFsdWUgPSBqUXVlcnkoIG9wdGlvbiApLnZhbCgpO1xuXG5cdFx0XHRcdFx0XHQvLyBXZSBkb24ndCBuZWVkIGFuIGFycmF5IGZvciBvbmUgc2VsZWN0c1xuXHRcdFx0XHRcdFx0aWYgKCBvbmUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gTXVsdGktU2VsZWN0cyByZXR1cm4gYW4gYXJyYXlcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XG5cdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIG9wdGlvblNldCwgb3B0aW9uLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0dmFsdWVzID0galF1ZXJ5Lm1ha2VBcnJheSggdmFsdWUgKSxcblx0XHRcdFx0XHRpID0gb3B0aW9ucy5sZW5ndGg7XG5cblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXHRcdFx0XHRcdGlmICggKG9wdGlvbi5zZWxlY3RlZCA9IGpRdWVyeS5pbkFycmF5KCBvcHRpb24udmFsdWUsIHZhbHVlcyApID49IDApICkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBmb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBSYWRpb3MgYW5kIGNoZWNrYm94ZXMgZ2V0dGVyL3NldHRlclxualF1ZXJ5LmVhY2goWyBcInJhZGlvXCIsIFwiY2hlY2tib3hcIiBdLCBmdW5jdGlvbigpIHtcblx0alF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0gPSB7XG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLmNoZWNrZWQgPSBqUXVlcnkuaW5BcnJheSggalF1ZXJ5KGVsZW0pLnZhbCgpLCB2YWx1ZSApID49IDAgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdC8vIFN1cHBvcnQ6IFdlYmtpdFxuXHRcdFx0Ly8gXCJcIiBpcyByZXR1cm5lZCBpbnN0ZWFkIG9mIFwib25cIiBpZiBhIHZhbHVlIGlzbid0IHNwZWNpZmllZFxuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKFwidmFsdWVcIikgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xuXHRcdH07XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBSZXR1cm4galF1ZXJ5IGZvciBhdHRyaWJ1dGVzLW9ubHkgaW5jbHVzaW9uXG5cblxualF1ZXJ5LmVhY2goIChcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCBsb2FkIHJlc2l6ZSBzY3JvbGwgdW5sb2FkIGNsaWNrIGRibGNsaWNrIFwiICtcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXG5cdFwiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBlcnJvciBjb250ZXh0bWVudVwiKS5zcGxpdChcIiBcIiksIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXG5cdC8vIEhhbmRsZSBldmVudCBiaW5kaW5nXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMCA/XG5cdFx0XHR0aGlzLm9uKCBuYW1lLCBudWxsLCBkYXRhLCBmbiApIDpcblx0XHRcdHRoaXMudHJpZ2dlciggbmFtZSApO1xuXHR9O1xufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRob3ZlcjogZnVuY3Rpb24oIGZuT3ZlciwgZm5PdXQgKSB7XG5cdFx0cmV0dXJuIHRoaXMubW91c2VlbnRlciggZm5PdmVyICkubW91c2VsZWF2ZSggZm5PdXQgfHwgZm5PdmVyICk7XG5cdH0sXG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyB0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDogdGhpcy5vZmYoIHR5cGVzLCBzZWxlY3RvciB8fCBcIioqXCIsIGZuICk7XG5cdH1cbn0pO1xuXG5cbnZhciBub25jZSA9IGpRdWVyeS5ub3coKTtcblxudmFyIHJxdWVyeSA9ICgvXFw/Lyk7XG5cblxuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuLy8gV29ya2Fyb3VuZCBmYWlsdXJlIHRvIHN0cmluZy1jYXN0IG51bGwgaW5wdXRcbmpRdWVyeS5wYXJzZUpTT04gPSBmdW5jdGlvbiggZGF0YSApIHtcblx0cmV0dXJuIEpTT04ucGFyc2UoIGRhdGEgKyBcIlwiICk7XG59O1xuXG5cbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcbmpRdWVyeS5wYXJzZVhNTCA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHR2YXIgeG1sLCB0bXA7XG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRTlcblx0dHJ5IHtcblx0XHR0bXAgPSBuZXcgRE9NUGFyc2VyKCk7XG5cdFx0eG1sID0gdG1wLnBhcnNlRnJvbVN0cmluZyggZGF0YSwgXCJ0ZXh0L3htbFwiICk7XG5cdH0gY2F0Y2ggKCBlICkge1xuXHRcdHhtbCA9IHVuZGVmaW5lZDtcblx0fVxuXG5cdGlmICggIXhtbCB8fCB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZXJyb3IoIFwiSW52YWxpZCBYTUw6IFwiICsgZGF0YSApO1xuXHR9XG5cdHJldHVybiB4bWw7XG59O1xuXG5cbnZhclxuXHQvLyBEb2N1bWVudCBsb2NhdGlvblxuXHRhamF4TG9jUGFydHMsXG5cdGFqYXhMb2NhdGlvbixcblxuXHRyaGFzaCA9IC8jLiokLyxcblx0cnRzID0gLyhbPyZdKV89W14mXSovLFxuXHRyaGVhZGVycyA9IC9eKC4qPyk6WyBcXHRdKihbXlxcclxcbl0qKSQvbWcsXG5cdC8vICM3NjUzLCAjODEyNSwgIzgxNTI6IGxvY2FsIHByb3RvY29sIGRldGVjdGlvblxuXHRybG9jYWxQcm90b2NvbCA9IC9eKD86YWJvdXR8YXBwfGFwcC1zdG9yYWdlfC4rLWV4dGVuc2lvbnxmaWxlfHJlc3x3aWRnZXQpOiQvLFxuXHRybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLyxcblx0cnByb3RvY29sID0gL15cXC9cXC8vLFxuXHRydXJsID0gL14oW1xcdy4rLV0rOikoPzpcXC9cXC8oPzpbXlxcLz8jXSpAfCkoW15cXC8/IzpdKikoPzo6KFxcZCspfCl8KS8sXG5cblx0LyogUHJlZmlsdGVyc1xuXHQgKiAxKSBUaGV5IGFyZSB1c2VmdWwgdG8gaW50cm9kdWNlIGN1c3RvbSBkYXRhVHlwZXMgKHNlZSBhamF4L2pzb25wLmpzIGZvciBhbiBleGFtcGxlKVxuXHQgKiAyKSBUaGVzZSBhcmUgY2FsbGVkOlxuXHQgKiAgICAtIEJFRk9SRSBhc2tpbmcgZm9yIGEgdHJhbnNwb3J0XG5cdCAqICAgIC0gQUZURVIgcGFyYW0gc2VyaWFsaXphdGlvbiAocy5kYXRhIGlzIGEgc3RyaW5nIGlmIHMucHJvY2Vzc0RhdGEgaXMgdHJ1ZSlcblx0ICogMykga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiA0KSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDUpIGV4ZWN1dGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGNvbnRpbnVlIGRvd24gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHRwcmVmaWx0ZXJzID0ge30sXG5cblx0LyogVHJhbnNwb3J0cyBiaW5kaW5nc1xuXHQgKiAxKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDIpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogMykgc2VsZWN0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gZ28gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHR0cmFuc3BvcnRzID0ge30sXG5cblx0Ly8gQXZvaWQgY29tbWVudC1wcm9sb2cgY2hhciBzZXF1ZW5jZSAoIzEwMDk4KTsgbXVzdCBhcHBlYXNlIGxpbnQgYW5kIGV2YWRlIGNvbXByZXNzaW9uXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdChcIipcIik7XG5cbi8vICM4MTM4LCBJRSBtYXkgdGhyb3cgYW4gZXhjZXB0aW9uIHdoZW4gYWNjZXNzaW5nXG4vLyBhIGZpZWxkIGZyb20gd2luZG93LmxvY2F0aW9uIGlmIGRvY3VtZW50LmRvbWFpbiBoYXMgYmVlbiBzZXRcbnRyeSB7XG5cdGFqYXhMb2NhdGlvbiA9IGxvY2F0aW9uLmhyZWY7XG59IGNhdGNoKCBlICkge1xuXHQvLyBVc2UgdGhlIGhyZWYgYXR0cmlidXRlIG9mIGFuIEEgZWxlbWVudFxuXHQvLyBzaW5jZSBJRSB3aWxsIG1vZGlmeSBpdCBnaXZlbiBkb2N1bWVudC5sb2NhdGlvblxuXHRhamF4TG9jYXRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xuXHRhamF4TG9jYXRpb24uaHJlZiA9IFwiXCI7XG5cdGFqYXhMb2NhdGlvbiA9IGFqYXhMb2NhdGlvbi5ocmVmO1xufVxuXG4vLyBTZWdtZW50IGxvY2F0aW9uIGludG8gcGFydHNcbmFqYXhMb2NQYXJ0cyA9IHJ1cmwuZXhlYyggYWpheExvY2F0aW9uLnRvTG93ZXJDYXNlKCkgKSB8fCBbXTtcblxuLy8gQmFzZSBcImNvbnN0cnVjdG9yXCIgZm9yIGpRdWVyeS5hamF4UHJlZmlsdGVyIGFuZCBqUXVlcnkuYWpheFRyYW5zcG9ydFxuZnVuY3Rpb24gYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUgKSB7XG5cblx0Ly8gZGF0YVR5cGVFeHByZXNzaW9uIGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byBcIipcIlxuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGFUeXBlRXhwcmVzc2lvbiwgZnVuYyApIHtcblxuXHRcdGlmICggdHlwZW9mIGRhdGFUeXBlRXhwcmVzc2lvbiAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGZ1bmMgPSBkYXRhVHlwZUV4cHJlc3Npb247XG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcblx0XHR9XG5cblx0XHR2YXIgZGF0YVR5cGUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGRhdGFUeXBlcyA9IGRhdGFUeXBlRXhwcmVzc2lvbi50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGZ1bmMgKSApIHtcblx0XHRcdC8vIEZvciBlYWNoIGRhdGFUeXBlIGluIHRoZSBkYXRhVHlwZUV4cHJlc3Npb25cblx0XHRcdHdoaWxlICggKGRhdGFUeXBlID0gZGF0YVR5cGVzW2krK10pICkge1xuXHRcdFx0XHQvLyBQcmVwZW5kIGlmIHJlcXVlc3RlZFxuXHRcdFx0XHRpZiAoIGRhdGFUeXBlWzBdID09PSBcIitcIiApIHtcblx0XHRcdFx0XHRkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgXCIqXCI7XG5cdFx0XHRcdFx0KHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSkudW5zaGlmdCggZnVuYyApO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBhcHBlbmRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQoc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdKS5wdXNoKCBmdW5jICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xuZnVuY3Rpb24gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSwgb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApIHtcblxuXHR2YXIgaW5zcGVjdGVkID0ge30sXG5cdFx0c2Vla2luZ1RyYW5zcG9ydCA9ICggc3RydWN0dXJlID09PSB0cmFuc3BvcnRzICk7XG5cblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XG5cdFx0dmFyIHNlbGVjdGVkO1xuXHRcdGluc3BlY3RlZFsgZGF0YVR5cGUgXSA9IHRydWU7XG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcblx0XHRcdHZhciBkYXRhVHlwZU9yVHJhbnNwb3J0ID0gcHJlZmlsdGVyT3JGYWN0b3J5KCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICk7XG5cdFx0XHRpZiAoIHR5cGVvZiBkYXRhVHlwZU9yVHJhbnNwb3J0ID09PSBcInN0cmluZ1wiICYmICFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XG5cdFx0XHRcdHJldHVybiAhKCBzZWxlY3RlZCA9IGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XG5cdH1cblxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcbn1cblxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXG4vLyB0aGF0IHRha2VzIFwiZmxhdFwiIG9wdGlvbnMgKG5vdCB0byBiZSBkZWVwIGV4dGVuZGVkKVxuLy8gRml4ZXMgIzk4ODdcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xuXHR2YXIga2V5LCBkZWVwLFxuXHRcdGZsYXRPcHRpb25zID0galF1ZXJ5LmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9ucyB8fCB7fTtcblxuXHRmb3IgKCBrZXkgaW4gc3JjICkge1xuXHRcdGlmICggc3JjWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKGRlZXAgPSB7fSkgKSApWyBrZXkgXSA9IHNyY1sga2V5IF07XG5cdFx0fVxuXHR9XG5cdGlmICggZGVlcCApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0cnVlLCB0YXJnZXQsIGRlZXAgKTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbi8qIEhhbmRsZXMgcmVzcG9uc2VzIHRvIGFuIGFqYXggcmVxdWVzdDpcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXG4gKiAtIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcbiAqL1xuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcblxuXHR2YXIgY3QsIHR5cGUsIGZpbmFsRGF0YVR5cGUsIGZpcnN0RGF0YVR5cGUsXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzO1xuXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXG5cdHdoaWxlICggZGF0YVR5cGVzWyAwIF0gPT09IFwiKlwiICkge1xuXHRcdGRhdGFUeXBlcy5zaGlmdCgpO1xuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGN0ID0gcy5taW1lVHlwZSB8fCBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtVHlwZVwiKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcblx0aWYgKCBjdCApIHtcblx0XHRmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkge1xuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcblx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYSByZXNwb25zZSBmb3IgdGhlIGV4cGVjdGVkIGRhdGFUeXBlXG5cdGlmICggZGF0YVR5cGVzWyAwIF0gaW4gcmVzcG9uc2VzICkge1xuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcblx0fSBlbHNlIHtcblx0XHQvLyBUcnkgY29udmVydGlibGUgZGF0YVR5cGVzXG5cdFx0Zm9yICggdHlwZSBpbiByZXNwb25zZXMgKSB7XG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1swXSBdICkge1xuXHRcdFx0XHRmaW5hbERhdGFUeXBlID0gdHlwZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICFmaXJzdERhdGFUeXBlICkge1xuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gT3IganVzdCB1c2UgZmlyc3Qgb25lXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcblx0fVxuXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcblx0Ly8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWRcblx0Ly8gYW5kIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XG5cdFx0aWYgKCBmaW5hbERhdGFUeXBlICE9PSBkYXRhVHlwZXNbIDAgXSApIHtcblx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCBmaW5hbERhdGFUeXBlICk7XG5cdFx0fVxuXHRcdHJldHVybiByZXNwb25zZXNbIGZpbmFsRGF0YVR5cGUgXTtcblx0fVxufVxuXG4vKiBDaGFpbiBjb252ZXJzaW9ucyBnaXZlbiB0aGUgcmVxdWVzdCBhbmQgdGhlIG9yaWdpbmFsIHJlc3BvbnNlXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICkge1xuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcblx0XHRjb252ZXJ0ZXJzID0ge30sXG5cdFx0Ly8gV29yayB3aXRoIGEgY29weSBvZiBkYXRhVHlwZXMgaW4gY2FzZSB3ZSBuZWVkIHRvIG1vZGlmeSBpdCBmb3IgY29udmVyc2lvblxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzLnNsaWNlKCk7XG5cblx0Ly8gQ3JlYXRlIGNvbnZlcnRlcnMgbWFwIHdpdGggbG93ZXJjYXNlZCBrZXlzXG5cdGlmICggZGF0YVR5cGVzWyAxIF0gKSB7XG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XG5cdFx0XHRjb252ZXJ0ZXJzWyBjb252LnRvTG93ZXJDYXNlKCkgXSA9IHMuY29udmVydGVyc1sgY29udiBdO1xuXHRcdH1cblx0fVxuXG5cdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHQvLyBDb252ZXJ0IHRvIGVhY2ggc2VxdWVudGlhbCBkYXRhVHlwZVxuXHR3aGlsZSAoIGN1cnJlbnQgKSB7XG5cblx0XHRpZiAoIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSApIHtcblx0XHRcdGpxWEhSWyBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gXSA9IHJlc3BvbnNlO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xuXHRcdFx0cmVzcG9uc2UgPSBzLmRhdGFGaWx0ZXIoIHJlc3BvbnNlLCBzLmRhdGFUeXBlICk7XG5cdFx0fVxuXG5cdFx0cHJldiA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdFx0aWYgKCBjdXJyZW50ICkge1xuXG5cdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xuXHRcdFx0aWYgKCBjdXJyZW50ID09PSBcIipcIiApIHtcblxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcblxuXHRcdFx0Ly8gQ29udmVydCByZXNwb25zZSBpZiBwcmV2IGRhdGFUeXBlIGlzIG5vbi1hdXRvIGFuZCBkaWZmZXJzIGZyb20gY3VycmVudFxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcblxuXHRcdFx0XHQvLyBTZWVrIGEgZGlyZWN0IGNvbnZlcnRlclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcblxuXHRcdFx0XHQvLyBJZiBub25lIGZvdW5kLCBzZWVrIGEgcGFpclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xuXHRcdFx0XHRcdGZvciAoIGNvbnYyIGluIGNvbnZlcnRlcnMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxuXHRcdFx0XHRcdFx0dG1wID0gY29udjIuc3BsaXQoIFwiIFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIHRtcFsgMSBdID09PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIElmIHByZXYgY2FuIGJlIGNvbnZlcnRlZCB0byBhY2NlcHRlZCBpbnB1dFxuXHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgdG1wWyAwIF0gXSB8fFxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XG5cdFx0XHRcdFx0XHRcdGlmICggY29udiApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBDb25kZW5zZSBlcXVpdmFsZW5jZSBjb252ZXJ0ZXJzXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjb252ID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGluc2VydCB0aGUgaW50ZXJtZWRpYXRlIGRhdGFUeXBlXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnQgPSB0bXBbIDAgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0bXBbIDEgXSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFwcGx5IGNvbnZlcnRlciAoaWYgbm90IGFuIGVxdWl2YWxlbmNlKVxuXHRcdFx0XHRpZiAoIGNvbnYgIT09IHRydWUgKSB7XG5cblx0XHRcdFx0XHQvLyBVbmxlc3MgZXJyb3JzIGFyZSBhbGxvd2VkIHRvIGJ1YmJsZSwgY2F0Y2ggYW5kIHJldHVybiB0aGVtXG5cdFx0XHRcdFx0aWYgKCBjb252ICYmIHNbIFwidGhyb3dzXCIgXSApIHtcblx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB7IHN0YXRlOiBcInBhcnNlcmVycm9yXCIsIGVycm9yOiBjb252ID8gZSA6IFwiTm8gY29udmVyc2lvbiBmcm9tIFwiICsgcHJldiArIFwiIHRvIFwiICsgY3VycmVudCB9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7IHN0YXRlOiBcInN1Y2Nlc3NcIiwgZGF0YTogcmVzcG9uc2UgfTtcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cblx0Ly8gQ291bnRlciBmb3IgaG9sZGluZyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBxdWVyaWVzXG5cdGFjdGl2ZTogMCxcblxuXHQvLyBMYXN0LU1vZGlmaWVkIGhlYWRlciBjYWNoZSBmb3IgbmV4dCByZXF1ZXN0XG5cdGxhc3RNb2RpZmllZDoge30sXG5cdGV0YWc6IHt9LFxuXG5cdGFqYXhTZXR0aW5nczoge1xuXHRcdHVybDogYWpheExvY2F0aW9uLFxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0aXNMb2NhbDogcmxvY2FsUHJvdG9jb2wudGVzdCggYWpheExvY1BhcnRzWyAxIF0gKSxcblx0XHRnbG9iYWw6IHRydWUsXG5cdFx0cHJvY2Vzc0RhdGE6IHRydWUsXG5cdFx0YXN5bmM6IHRydWUsXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXG5cdFx0Lypcblx0XHR0aW1lb3V0OiAwLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0ZGF0YVR5cGU6IG51bGwsXG5cdFx0dXNlcm5hbWU6IG51bGwsXG5cdFx0cGFzc3dvcmQ6IG51bGwsXG5cdFx0Y2FjaGU6IG51bGwsXG5cdFx0dGhyb3dzOiBmYWxzZSxcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXG5cdFx0aGVhZGVyczoge30sXG5cdFx0Ki9cblxuXHRcdGFjY2VwdHM6IHtcblx0XHRcdFwiKlwiOiBhbGxUeXBlcyxcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxuXHRcdFx0aHRtbDogXCJ0ZXh0L2h0bWxcIixcblx0XHRcdHhtbDogXCJhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sXCIsXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXG5cdFx0fSxcblxuXHRcdGNvbnRlbnRzOiB7XG5cdFx0XHR4bWw6IC94bWwvLFxuXHRcdFx0aHRtbDogL2h0bWwvLFxuXHRcdFx0anNvbjogL2pzb24vXG5cdFx0fSxcblxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XG5cdFx0XHR4bWw6IFwicmVzcG9uc2VYTUxcIixcblx0XHRcdHRleHQ6IFwicmVzcG9uc2VUZXh0XCIsXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXG5cdFx0fSxcblxuXHRcdC8vIERhdGEgY29udmVydGVyc1xuXHRcdC8vIEtleXMgc2VwYXJhdGUgc291cmNlIChvciBjYXRjaGFsbCBcIipcIikgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIHdpdGggYSBzaW5nbGUgc3BhY2Vcblx0XHRjb252ZXJ0ZXJzOiB7XG5cblx0XHRcdC8vIENvbnZlcnQgYW55dGhpbmcgdG8gdGV4dFxuXHRcdFx0XCIqIHRleHRcIjogU3RyaW5nLFxuXG5cdFx0XHQvLyBUZXh0IHRvIGh0bWwgKHRydWUgPSBubyB0cmFuc2Zvcm1hdGlvbilcblx0XHRcdFwidGV4dCBodG1sXCI6IHRydWUsXG5cblx0XHRcdC8vIEV2YWx1YXRlIHRleHQgYXMgYSBqc29uIGV4cHJlc3Npb25cblx0XHRcdFwidGV4dCBqc29uXCI6IGpRdWVyeS5wYXJzZUpTT04sXG5cblx0XHRcdC8vIFBhcnNlIHRleHQgYXMgeG1sXG5cdFx0XHRcInRleHQgeG1sXCI6IGpRdWVyeS5wYXJzZVhNTFxuXHRcdH0sXG5cblx0XHQvLyBGb3Igb3B0aW9ucyB0aGF0IHNob3VsZG4ndCBiZSBkZWVwIGV4dGVuZGVkOlxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcblx0XHQvLyBhbmQgd2hlbiB5b3UgY3JlYXRlIG9uZSB0aGF0IHNob3VsZG4ndCBiZVxuXHRcdC8vIGRlZXAgZXh0ZW5kZWQgKHNlZSBhamF4RXh0ZW5kKVxuXHRcdGZsYXRPcHRpb25zOiB7XG5cdFx0XHR1cmw6IHRydWUsXG5cdFx0XHRjb250ZXh0OiB0cnVlXG5cdFx0fVxuXHR9LFxuXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XG5cdC8vIHdpdGggYm90aCBhamF4U2V0dGluZ3MgYW5kIHNldHRpbmdzIGZpZWxkcy5cblx0Ly8gSWYgdGFyZ2V0IGlzIG9taXR0ZWQsIHdyaXRlcyBpbnRvIGFqYXhTZXR0aW5ncy5cblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcblx0XHRyZXR1cm4gc2V0dGluZ3MgP1xuXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxuXHRcdFx0YWpheEV4dGVuZCggYWpheEV4dGVuZCggdGFyZ2V0LCBqUXVlcnkuYWpheFNldHRpbmdzICksIHNldHRpbmdzICkgOlxuXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXG5cdFx0XHRhamF4RXh0ZW5kKCBqUXVlcnkuYWpheFNldHRpbmdzLCB0YXJnZXQgKTtcblx0fSxcblxuXHRhamF4UHJlZmlsdGVyOiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMgKSxcblx0YWpheFRyYW5zcG9ydDogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzICksXG5cblx0Ly8gTWFpbiBtZXRob2Rcblx0YWpheDogZnVuY3Rpb24oIHVybCwgb3B0aW9ucyApIHtcblxuXHRcdC8vIElmIHVybCBpcyBhbiBvYmplY3QsIHNpbXVsYXRlIHByZS0xLjUgc2lnbmF0dXJlXG5cdFx0aWYgKCB0eXBlb2YgdXJsID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0b3B0aW9ucyA9IHVybDtcblx0XHRcdHVybCA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBGb3JjZSBvcHRpb25zIHRvIGJlIGFuIG9iamVjdFxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0dmFyIHRyYW5zcG9ydCxcblx0XHRcdC8vIFVSTCB3aXRob3V0IGFudGktY2FjaGUgcGFyYW1cblx0XHRcdGNhY2hlVVJMLFxuXHRcdFx0Ly8gUmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzLFxuXHRcdFx0Ly8gdGltZW91dCBoYW5kbGVcblx0XHRcdHRpbWVvdXRUaW1lcixcblx0XHRcdC8vIENyb3NzLWRvbWFpbiBkZXRlY3Rpb24gdmFyc1xuXHRcdFx0cGFydHMsXG5cdFx0XHQvLyBUbyBrbm93IGlmIGdsb2JhbCBldmVudHMgYXJlIHRvIGJlIGRpc3BhdGNoZWRcblx0XHRcdGZpcmVHbG9iYWxzLFxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxuXHRcdFx0aSxcblx0XHRcdC8vIENyZWF0ZSB0aGUgZmluYWwgb3B0aW9ucyBvYmplY3Rcblx0XHRcdHMgPSBqUXVlcnkuYWpheFNldHVwKCB7fSwgb3B0aW9ucyApLFxuXHRcdFx0Ly8gQ2FsbGJhY2tzIGNvbnRleHRcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxuXHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0ID0gcy5jb250ZXh0ICYmICggY2FsbGJhY2tDb250ZXh0Lm5vZGVUeXBlIHx8IGNhbGxiYWNrQ29udGV4dC5qcXVlcnkgKSA/XG5cdFx0XHRcdGpRdWVyeSggY2FsbGJhY2tDb250ZXh0ICkgOlxuXHRcdFx0XHRqUXVlcnkuZXZlbnQsXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyhcIm9uY2UgbWVtb3J5XCIpLFxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdHN0YXR1c0NvZGUgPSBzLnN0YXR1c0NvZGUgfHwge30sXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblx0XHRcdC8vIFRoZSBqcVhIUiBzdGF0ZVxuXHRcdFx0c3RhdGUgPSAwLFxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblx0XHRcdC8vIEZha2UgeGhyXG5cdFx0XHRqcVhIUiA9IHtcblx0XHRcdFx0cmVhZHlTdGF0ZTogMCxcblxuXHRcdFx0XHQvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkXG5cdFx0XHRcdGdldFJlc3BvbnNlSGVhZGVyOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdFx0XHRcdHZhciBtYXRjaDtcblx0XHRcdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2ggPSByaGVhZGVycy5leGVjKCByZXNwb25zZUhlYWRlcnNTdHJpbmcgKSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzWyBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpIF0gPSBtYXRjaFsgMiBdO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoID09IG51bGwgPyBudWxsIDogbWF0Y2g7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gUmF3IHN0cmluZ1xuXHRcdFx0XHRnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHJldHVybiBzdGF0ZSA9PT0gMiA/IHJlc3BvbnNlSGVhZGVyc1N0cmluZyA6IG51bGw7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FjaGVzIHRoZSBoZWFkZXJcblx0XHRcdFx0c2V0UmVxdWVzdEhlYWRlcjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdFx0XHRcdHZhciBsbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRpZiAoICFzdGF0ZSApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBsbmFtZSBdID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNbIG5hbWUgXSA9IHZhbHVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBPdmVycmlkZXMgcmVzcG9uc2UgY29udGVudC10eXBlIGhlYWRlclxuXHRcdFx0XHRvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRpZiAoICFzdGF0ZSApIHtcblx0XHRcdFx0XHRcdHMubWltZVR5cGUgPSB0eXBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0XHRzdGF0dXNDb2RlOiBmdW5jdGlvbiggbWFwICkge1xuXHRcdFx0XHRcdHZhciBjb2RlO1xuXHRcdFx0XHRcdGlmICggbWFwICkge1xuXHRcdFx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XG5cdFx0XHRcdFx0XHRcdGZvciAoIGNvZGUgaW4gbWFwICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2sgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0XHRzdGF0dXNDb2RlWyBjb2RlIF0gPSBbIHN0YXR1c0NvZGVbIGNvZGUgXSwgbWFwWyBjb2RlIF0gXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gRXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tzXG5cdFx0XHRcdFx0XHRcdGpxWEhSLmFsd2F5cyggbWFwWyBqcVhIUi5zdGF0dXMgXSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYW5jZWwgdGhlIHJlcXVlc3Rcblx0XHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCBzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHZhciBmaW5hbFRleHQgPSBzdGF0dXNUZXh0IHx8IHN0ckFib3J0O1xuXHRcdFx0XHRcdGlmICggdHJhbnNwb3J0ICkge1xuXHRcdFx0XHRcdFx0dHJhbnNwb3J0LmFib3J0KCBmaW5hbFRleHQgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZG9uZSggMCwgZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHQvLyBBdHRhY2ggZGVmZXJyZWRzXG5cdFx0ZGVmZXJyZWQucHJvbWlzZSgganFYSFIgKS5jb21wbGV0ZSA9IGNvbXBsZXRlRGVmZXJyZWQuYWRkO1xuXHRcdGpxWEhSLnN1Y2Nlc3MgPSBqcVhIUi5kb25lO1xuXHRcdGpxWEhSLmVycm9yID0ganFYSFIuZmFpbDtcblxuXHRcdC8vIFJlbW92ZSBoYXNoIGNoYXJhY3RlciAoIzc1MzE6IGFuZCBzdHJpbmcgcHJvbW90aW9uKVxuXHRcdC8vIEFkZCBwcm90b2NvbCBpZiBub3QgcHJvdmlkZWQgKHByZWZpbHRlcnMgbWlnaHQgZXhwZWN0IGl0KVxuXHRcdC8vIEhhbmRsZSBmYWxzeSB1cmwgaW4gdGhlIHNldHRpbmdzIG9iamVjdCAoIzEwMDkzOiBjb25zaXN0ZW5jeSB3aXRoIG9sZCBzaWduYXR1cmUpXG5cdFx0Ly8gV2UgYWxzbyB1c2UgdGhlIHVybCBwYXJhbWV0ZXIgaWYgYXZhaWxhYmxlXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGFqYXhMb2NhdGlvbiApICsgXCJcIiApLnJlcGxhY2UoIHJoYXNoLCBcIlwiIClcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGFqYXhMb2NQYXJ0c1sgMSBdICsgXCIvL1wiICk7XG5cblx0XHQvLyBBbGlhcyBtZXRob2Qgb3B0aW9uIHRvIHR5cGUgYXMgcGVyIHRpY2tldCAjMTIwMDRcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xuXG5cdFx0Ly8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdFxuXHRcdHMuZGF0YVR5cGVzID0galF1ZXJ5LnRyaW0oIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblxuXHRcdC8vIEEgY3Jvc3MtZG9tYWluIHJlcXVlc3QgaXMgaW4gb3JkZXIgd2hlbiB3ZSBoYXZlIGEgcHJvdG9jb2w6aG9zdDpwb3J0IG1pc21hdGNoXG5cdFx0aWYgKCBzLmNyb3NzRG9tYWluID09IG51bGwgKSB7XG5cdFx0XHRwYXJ0cyA9IHJ1cmwuZXhlYyggcy51cmwudG9Mb3dlckNhc2UoKSApO1xuXHRcdFx0cy5jcm9zc0RvbWFpbiA9ICEhKCBwYXJ0cyAmJlxuXHRcdFx0XHQoIHBhcnRzWyAxIF0gIT09IGFqYXhMb2NQYXJ0c1sgMSBdIHx8IHBhcnRzWyAyIF0gIT09IGFqYXhMb2NQYXJ0c1sgMiBdIHx8XG5cdFx0XHRcdFx0KCBwYXJ0c1sgMyBdIHx8ICggcGFydHNbIDEgXSA9PT0gXCJodHRwOlwiID8gXCI4MFwiIDogXCI0NDNcIiApICkgIT09XG5cdFx0XHRcdFx0XHQoIGFqYXhMb2NQYXJ0c1sgMyBdIHx8ICggYWpheExvY1BhcnRzWyAxIF0gPT09IFwiaHR0cDpcIiA/IFwiODBcIiA6IFwiNDQzXCIgKSApIClcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJiB0eXBlb2Ygcy5kYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0cy5kYXRhID0galF1ZXJ5LnBhcmFtKCBzLmRhdGEsIHMudHJhZGl0aW9uYWwgKTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSBwcmVmaWx0ZXJzXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhIHByZWZpbHRlciwgc3RvcCB0aGVyZVxuXHRcdGlmICggc3RhdGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0fVxuXG5cdFx0Ly8gV2UgY2FuIGZpcmUgZ2xvYmFsIGV2ZW50cyBhcyBvZiBub3cgaWYgYXNrZWQgdG9cblx0XHRmaXJlR2xvYmFscyA9IHMuZ2xvYmFsO1xuXG5cdFx0Ly8gV2F0Y2ggZm9yIGEgbmV3IHNldCBvZiByZXF1ZXN0c1xuXHRcdGlmICggZmlyZUdsb2JhbHMgJiYgalF1ZXJ5LmFjdGl2ZSsrID09PSAwICkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoXCJhamF4U3RhcnRcIik7XG5cdFx0fVxuXG5cdFx0Ly8gVXBwZXJjYXNlIHRoZSB0eXBlXG5cdFx0cy50eXBlID0gcy50eXBlLnRvVXBwZXJDYXNlKCk7XG5cblx0XHQvLyBEZXRlcm1pbmUgaWYgcmVxdWVzdCBoYXMgY29udGVudFxuXHRcdHMuaGFzQ29udGVudCA9ICFybm9Db250ZW50LnRlc3QoIHMudHlwZSApO1xuXG5cdFx0Ly8gU2F2ZSB0aGUgVVJMIGluIGNhc2Ugd2UncmUgdG95aW5nIHdpdGggdGhlIElmLU1vZGlmaWVkLVNpbmNlXG5cdFx0Ly8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uXG5cdFx0Y2FjaGVVUkwgPSBzLnVybDtcblxuXHRcdC8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50XG5cdFx0aWYgKCAhcy5oYXNDb250ZW50ICkge1xuXG5cdFx0XHQvLyBJZiBkYXRhIGlzIGF2YWlsYWJsZSwgYXBwZW5kIGRhdGEgdG8gdXJsXG5cdFx0XHRpZiAoIHMuZGF0YSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgPSAoIHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmRhdGEgKTtcblx0XHRcdFx0Ly8gIzk2ODI6IHJlbW92ZSBkYXRhIHNvIHRoYXQgaXQncyBub3QgdXNlZCBpbiBhbiBldmVudHVhbCByZXRyeVxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgYW50aS1jYWNoZSBpbiB1cmwgaWYgbmVlZGVkXG5cdFx0XHRpZiAoIHMuY2FjaGUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRzLnVybCA9IHJ0cy50ZXN0KCBjYWNoZVVSTCApID9cblxuXHRcdFx0XHRcdC8vIElmIHRoZXJlIGlzIGFscmVhZHkgYSAnXycgcGFyYW1ldGVyLCBzZXQgaXRzIHZhbHVlXG5cdFx0XHRcdFx0Y2FjaGVVUkwucmVwbGFjZSggcnRzLCBcIiQxXz1cIiArIG5vbmNlKysgKSA6XG5cblx0XHRcdFx0XHQvLyBPdGhlcndpc2UgYWRkIG9uZSB0byB0aGUgZW5kXG5cdFx0XHRcdFx0Y2FjaGVVUkwgKyAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgXCJfPVwiICsgbm9uY2UrKztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0aWYgKCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHRcdGlmICggalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgY29ycmVjdCBoZWFkZXIsIGlmIGRhdGEgaXMgYmVpbmcgc2VudFxuXHRcdGlmICggcy5kYXRhICYmIHMuaGFzQ29udGVudCAmJiBzLmNvbnRlbnRUeXBlICE9PSBmYWxzZSB8fCBvcHRpb25zLmNvbnRlbnRUeXBlICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcblx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKFxuXHRcdFx0XCJBY2NlcHRcIixcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1swXSBdID9cblx0XHRcdFx0cy5hY2NlcHRzWyBzLmRhdGFUeXBlc1swXSBdICsgKCBzLmRhdGFUeXBlc1sgMCBdICE9PSBcIipcIiA/IFwiLCBcIiArIGFsbFR5cGVzICsgXCI7IHE9MC4wMVwiIDogXCJcIiApIDpcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXG5cdFx0KTtcblxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxuXHRcdGZvciAoIGkgaW4gcy5oZWFkZXJzICkge1xuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggaSwgcy5oZWFkZXJzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBBbGxvdyBjdXN0b20gaGVhZGVycy9taW1ldHlwZXMgYW5kIGVhcmx5IGFib3J0XG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiYgKCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBzdGF0ZSA9PT0gMiApICkge1xuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXG5cdFx0XHRyZXR1cm4ganFYSFIuYWJvcnQoKTtcblx0XHR9XG5cblx0XHQvLyBhYm9ydGluZyBpcyBubyBsb25nZXIgYSBjYW5jZWxsYXRpb25cblx0XHRzdHJBYm9ydCA9IFwiYWJvcnRcIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tzIG9uIGRlZmVycmVkc1xuXHRcdGZvciAoIGkgaW4geyBzdWNjZXNzOiAxLCBlcnJvcjogMSwgY29tcGxldGU6IDEgfSApIHtcblx0XHRcdGpxWEhSWyBpIF0oIHNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEdldCB0cmFuc3BvcnRcblx0XHR0cmFuc3BvcnQgPSBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cywgcywgb3B0aW9ucywganFYSFIgKTtcblxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxuXHRcdGlmICggIXRyYW5zcG9ydCApIHtcblx0XHRcdGRvbmUoIC0xLCBcIk5vIFRyYW5zcG9ydFwiICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpxWEhSLnJlYWR5U3RhdGUgPSAxO1xuXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheFNlbmRcIiwgWyBqcVhIUiwgcyBdICk7XG5cdFx0XHR9XG5cdFx0XHQvLyBUaW1lb3V0XG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcblx0XHRcdFx0dGltZW91dFRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRqcVhIUi5hYm9ydChcInRpbWVvdXRcIik7XG5cdFx0XHRcdH0sIHMudGltZW91dCApO1xuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRzdGF0ZSA9IDE7XG5cdFx0XHRcdHRyYW5zcG9ydC5zZW5kKCByZXF1ZXN0SGVhZGVycywgZG9uZSApO1xuXHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdC8vIFByb3BhZ2F0ZSBleGNlcHRpb24gYXMgZXJyb3IgaWYgbm90IGRvbmVcblx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XG5cdFx0XHRcdFx0ZG9uZSggLTEsIGUgKTtcblx0XHRcdFx0Ly8gU2ltcGx5IHJldGhyb3cgb3RoZXJ3aXNlXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhyb3cgZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhbGxiYWNrIGZvciB3aGVuIGV2ZXJ5dGhpbmcgaXMgZG9uZVxuXHRcdGZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkge1xuXHRcdFx0dmFyIGlzU3VjY2Vzcywgc3VjY2VzcywgZXJyb3IsIHJlc3BvbnNlLCBtb2RpZmllZCxcblx0XHRcdFx0c3RhdHVzVGV4dCA9IG5hdGl2ZVN0YXR1c1RleHQ7XG5cblx0XHRcdC8vIENhbGxlZCBvbmNlXG5cdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXRlIGlzIFwiZG9uZVwiIG5vd1xuXHRcdFx0c3RhdGUgPSAyO1xuXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xuXHRcdFx0aWYgKCB0aW1lb3V0VGltZXIgKSB7XG5cdFx0XHRcdGNsZWFyVGltZW91dCggdGltZW91dFRpbWVyICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIERlcmVmZXJlbmNlIHRyYW5zcG9ydCBmb3IgZWFybHkgZ2FyYmFnZSBjb2xsZWN0aW9uXG5cdFx0XHQvLyAobm8gbWF0dGVyIGhvdyBsb25nIHRoZSBqcVhIUiBvYmplY3Qgd2lsbCBiZSB1c2VkKVxuXHRcdFx0dHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuXG5cdFx0XHQvLyBDYWNoZSByZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8IFwiXCI7XG5cblx0XHRcdC8vIFNldCByZWFkeVN0YXRlXG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gc3RhdHVzID4gMCA/IDQgOiAwO1xuXG5cdFx0XHQvLyBEZXRlcm1pbmUgaWYgc3VjY2Vzc2Z1bFxuXHRcdFx0aXNTdWNjZXNzID0gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDAgfHwgc3RhdHVzID09PSAzMDQ7XG5cblx0XHRcdC8vIEdldCByZXNwb25zZSBkYXRhXG5cdFx0XHRpZiAoIHJlc3BvbnNlcyApIHtcblx0XHRcdFx0cmVzcG9uc2UgPSBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgbm8gbWF0dGVyIHdoYXQgKHRoYXQgd2F5IHJlc3BvbnNlWFhYIGZpZWxkcyBhcmUgYWx3YXlzIHNldClcblx0XHRcdHJlc3BvbnNlID0gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICk7XG5cblx0XHRcdC8vIElmIHN1Y2Nlc3NmdWwsIGhhbmRsZSB0eXBlIGNoYWluaW5nXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblxuXHRcdFx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdFx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKFwiTGFzdC1Nb2RpZmllZFwiKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKFwiZXRhZ1wiKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XG5cdFx0XHRcdGlmICggc3RhdHVzID09PSAyMDQgfHwgcy50eXBlID09PSBcIkhFQURcIiApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub2NvbnRlbnRcIjtcblxuXHRcdFx0XHQvLyBpZiBub3QgbW9kaWZpZWRcblx0XHRcdFx0fSBlbHNlIGlmICggc3RhdHVzID09PSAzMDQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcblxuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGRhdGEsIGxldCdzIGNvbnZlcnQgaXRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdGU7XG5cdFx0XHRcdFx0c3VjY2VzcyA9IHJlc3BvbnNlLmRhdGE7XG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcblx0XHRcdFx0XHRpc1N1Y2Nlc3MgPSAhZXJyb3I7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIFdlIGV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0XG5cdFx0XHRcdC8vIHRoZW4gbm9ybWFsaXplIHN0YXR1c1RleHQgYW5kIHN0YXR1cyBmb3Igbm9uLWFib3J0c1xuXHRcdFx0XHRlcnJvciA9IHN0YXR1c1RleHQ7XG5cdFx0XHRcdGlmICggc3RhdHVzIHx8ICFzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcImVycm9yXCI7XG5cdFx0XHRcdFx0aWYgKCBzdGF0dXMgPCAwICkge1xuXHRcdFx0XHRcdFx0c3RhdHVzID0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IGRhdGEgZm9yIHRoZSBmYWtlIHhociBvYmplY3Rcblx0XHRcdGpxWEhSLnN0YXR1cyA9IHN0YXR1cztcblx0XHRcdGpxWEhSLnN0YXR1c1RleHQgPSAoIG5hdGl2ZVN0YXR1c1RleHQgfHwgc3RhdHVzVGV4dCApICsgXCJcIjtcblxuXHRcdFx0Ly8gU3VjY2Vzcy9FcnJvclxuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsgc3VjY2Vzcywgc3RhdHVzVGV4dCwganFYSFIgXSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0LCBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7XG5cdFx0XHRzdGF0dXNDb2RlID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggaXNTdWNjZXNzID8gXCJhamF4U3VjY2Vzc1wiIDogXCJhamF4RXJyb3JcIixcblx0XHRcdFx0XHRbIGpxWEhSLCBzLCBpc1N1Y2Nlc3MgPyBzdWNjZXNzIDogZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb21wbGV0ZVxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZC5maXJlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0IF0gKTtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheENvbXBsZXRlXCIsIFsganFYSFIsIHMgXSApO1xuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXJcblx0XHRcdFx0aWYgKCAhKCAtLWpRdWVyeS5hY3RpdmUgKSApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcihcImFqYXhTdG9wXCIpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpxWEhSO1xuXHR9LFxuXG5cdGdldEpTT046IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIGRhdGEsIGNhbGxiYWNrLCBcImpzb25cIiApO1xuXHR9LFxuXG5cdGdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgdW5kZWZpbmVkLCBjYWxsYmFjaywgXCJzY3JpcHRcIiApO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goIFsgXCJnZXRcIiwgXCJwb3N0XCIgXSwgZnVuY3Rpb24oIGksIG1ldGhvZCApIHtcblx0alF1ZXJ5WyBtZXRob2QgXSA9IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrLCB0eXBlICkge1xuXHRcdC8vIHNoaWZ0IGFyZ3VtZW50cyBpZiBkYXRhIGFyZ3VtZW50IHdhcyBvbWl0dGVkXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZGF0YSApICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgY2FsbGJhY2s7XG5cdFx0XHRjYWxsYmFjayA9IGRhdGE7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkuYWpheCh7XG5cdFx0XHR1cmw6IHVybCxcblx0XHRcdHR5cGU6IG1ldGhvZCxcblx0XHRcdGRhdGFUeXBlOiB0eXBlLFxuXHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdHN1Y2Nlc3M6IGNhbGxiYWNrXG5cdFx0fSk7XG5cdH07XG59KTtcblxuLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHNcbmpRdWVyeS5lYWNoKCBbIFwiYWpheFN0YXJ0XCIsIFwiYWpheFN0b3BcIiwgXCJhamF4Q29tcGxldGVcIiwgXCJhamF4RXJyb3JcIiwgXCJhamF4U3VjY2Vzc1wiLCBcImFqYXhTZW5kXCIgXSwgZnVuY3Rpb24oIGksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSk7XG5cblxualF1ZXJ5Ll9ldmFsVXJsID0gZnVuY3Rpb24oIHVybCApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KHtcblx0XHR1cmw6IHVybCxcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGRhdGFUeXBlOiBcInNjcmlwdFwiLFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRnbG9iYWw6IGZhbHNlLFxuXHRcdFwidGhyb3dzXCI6IHRydWVcblx0fSk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHR2YXIgd3JhcDtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzWyAwIF0gKSB7XG5cblx0XHRcdC8vIFRoZSBlbGVtZW50cyB0byB3cmFwIHRoZSB0YXJnZXQgYXJvdW5kXG5cdFx0XHR3cmFwID0galF1ZXJ5KCBodG1sLCB0aGlzWyAwIF0ub3duZXJEb2N1bWVudCApLmVxKCAwICkuY2xvbmUoIHRydWUgKTtcblxuXHRcdFx0aWYgKCB0aGlzWyAwIF0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0d3JhcC5pbnNlcnRCZWZvcmUoIHRoaXNbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHR3cmFwLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXG5cdFx0XHRcdHdoaWxlICggZWxlbS5maXJzdEVsZW1lbnRDaGlsZCApIHtcblx0XHRcdFx0XHRlbGVtID0gZWxlbS5maXJzdEVsZW1lbnRDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbGVtO1xuXHRcdFx0fSkuYXBwZW5kKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0d3JhcElubmVyOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwSW5uZXIoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xuXG5cdFx0XHRpZiAoIGNvbnRlbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRqUXVlcnkoIHRoaXMgKS53cmFwQWxsKCBpc0Z1bmN0aW9uID8gaHRtbC5jYWxsKHRoaXMsIGkpIDogaHRtbCApO1xuXHRcdH0pO1xuXHR9LFxuXG5cdHVud3JhcDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucGFyZW50KCkuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJib2R5XCIgKSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApO1xuXHRcdFx0fVxuXHRcdH0pLmVuZCgpO1xuXHR9XG59KTtcblxuXG5qUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHQvLyBTdXBwb3J0OiBPcGVyYSA8PSAxMi4xMlxuXHQvLyBPcGVyYSByZXBvcnRzIG9mZnNldFdpZHRocyBhbmQgb2Zmc2V0SGVpZ2h0cyBsZXNzIHRoYW4gemVybyBvbiBzb21lIGVsZW1lbnRzXG5cdHJldHVybiBlbGVtLm9mZnNldFdpZHRoIDw9IDAgJiYgZWxlbS5vZmZzZXRIZWlnaHQgPD0gMDtcbn07XG5qUXVlcnkuZXhwci5maWx0ZXJzLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICFqUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiggZWxlbSApO1xufTtcblxuXG5cblxudmFyIHIyMCA9IC8lMjAvZyxcblx0cmJyYWNrZXQgPSAvXFxbXFxdJC8sXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcblx0cnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLFxuXHRyc3VibWl0dGFibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxrZXlnZW4pL2k7XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zKCBwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCApIHtcblx0dmFyIG5hbWU7XG5cblx0aWYgKCBqUXVlcnkuaXNBcnJheSggb2JqICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIGFycmF5IGl0ZW0uXG5cdFx0alF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7XG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXG5cdFx0XHRcdGFkZCggcHJlZml4LCB2ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxuXHRcdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiID8gaSA6IFwiXCIgKSArIFwiXVwiLCB2LCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyBuYW1lICsgXCJdXCIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXG5cdFx0XHR2YWx1ZSA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApID8gdmFsdWUoKSA6ICggdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSApO1xuXHRcdFx0c1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudCgga2V5ICkgKyBcIj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgKTtcblx0XHR9O1xuXG5cdC8vIFNldCB0cmFkaXRpb25hbCB0byB0cnVlIGZvciBqUXVlcnkgPD0gMS4zLjIgYmVoYXZpb3IuXG5cdGlmICggdHJhZGl0aW9uYWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHR0cmFkaXRpb25hbCA9IGpRdWVyeS5hamF4U2V0dGluZ3MgJiYgalF1ZXJ5LmFqYXhTZXR0aW5ncy50cmFkaXRpb25hbDtcblx0fVxuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggalF1ZXJ5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIHRoZSBmb3JtIGVsZW1lbnRzXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xuXHRcdFx0YWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTtcblx0XHR9KTtcblxuXHR9IGVsc2Uge1xuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXG5cdFx0Ly8gZGlkIGl0KSwgb3RoZXJ3aXNlIGVuY29kZSBwYXJhbXMgcmVjdXJzaXZlbHkuXG5cdFx0Zm9yICggcHJlZml4IGluIGEgKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgcmVzdWx0aW5nIHNlcmlhbGl6YXRpb25cblx0cmV0dXJuIHMuam9pbiggXCImXCIgKS5yZXBsYWNlKCByMjAsIFwiK1wiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0c2VyaWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcblx0fSxcblx0c2VyaWFsaXplQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdC8vIENhbiBhZGQgcHJvcEhvb2sgZm9yIFwiZWxlbWVudHNcIiB0byBmaWx0ZXIgb3IgYWRkIGZvcm0gZWxlbWVudHNcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcblx0XHRcdHJldHVybiBlbGVtZW50cyA/IGpRdWVyeS5tYWtlQXJyYXkoIGVsZW1lbnRzICkgOiB0aGlzO1xuXHRcdH0pXG5cdFx0LmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXG5cdFx0XHQvLyBVc2UgLmlzKCBcIjpkaXNhYmxlZFwiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3Ncblx0XHRcdHJldHVybiB0aGlzLm5hbWUgJiYgIWpRdWVyeSggdGhpcyApLmlzKCBcIjpkaXNhYmxlZFwiICkgJiZcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxuXHRcdFx0XHQoIHRoaXMuY2hlY2tlZCB8fCAhcmNoZWNrYWJsZVR5cGUudGVzdCggdHlwZSApICk7XG5cdFx0fSlcblx0XHQubWFwKGZ1bmN0aW9uKCBpLCBlbGVtICkge1xuXHRcdFx0dmFyIHZhbCA9IGpRdWVyeSggdGhpcyApLnZhbCgpO1xuXG5cdFx0XHRyZXR1cm4gdmFsID09IG51bGwgP1xuXHRcdFx0XHRudWxsIDpcblx0XHRcdFx0alF1ZXJ5LmlzQXJyYXkoIHZhbCApID9cblx0XHRcdFx0XHRqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdFx0XHRcdH0pIDpcblx0XHRcdFx0XHR7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0fSkuZ2V0KCk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5hamF4U2V0dGluZ3MueGhyID0gZnVuY3Rpb24oKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuXHR9IGNhdGNoKCBlICkge31cbn07XG5cbnZhciB4aHJJZCA9IDAsXG5cdHhockNhbGxiYWNrcyA9IHt9LFxuXHR4aHJTdWNjZXNzU3RhdHVzID0ge1xuXHRcdC8vIGZpbGUgcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgY29kZSAwLCBhc3N1bWUgMjAwXG5cdFx0MDogMjAwLFxuXHRcdC8vIFN1cHBvcnQ6IElFOVxuXHRcdC8vICMxNDUwOiBzb21ldGltZXMgSUUgcmV0dXJucyAxMjIzIHdoZW4gaXQgc2hvdWxkIGJlIDIwNFxuXHRcdDEyMjM6IDIwNFxuXHR9LFxuXHR4aHJTdXBwb3J0ZWQgPSBqUXVlcnkuYWpheFNldHRpbmdzLnhocigpO1xuXG4vLyBTdXBwb3J0OiBJRTlcbi8vIE9wZW4gcmVxdWVzdHMgbXVzdCBiZSBtYW51YWxseSBhYm9ydGVkIG9uIHVubG9hZCAoIzUyODApXG5pZiAoIHdpbmRvdy5BY3RpdmVYT2JqZWN0ICkge1xuXHRqUXVlcnkoIHdpbmRvdyApLm9uKCBcInVubG9hZFwiLCBmdW5jdGlvbigpIHtcblx0XHRmb3IgKCB2YXIga2V5IGluIHhockNhbGxiYWNrcyApIHtcblx0XHRcdHhockNhbGxiYWNrc1sga2V5IF0oKTtcblx0XHR9XG5cdH0pO1xufVxuXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XG5zdXBwb3J0LmFqYXggPSB4aHJTdXBwb3J0ZWQgPSAhIXhoclN1cHBvcnRlZDtcblxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdHZhciBjYWxsYmFjaztcblxuXHQvLyBDcm9zcyBkb21haW4gb25seSBhbGxvd2VkIGlmIHN1cHBvcnRlZCB0aHJvdWdoIFhNTEh0dHBSZXF1ZXN0XG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIGhlYWRlcnMsIGNvbXBsZXRlICkge1xuXHRcdFx0XHR2YXIgaSxcblx0XHRcdFx0XHR4aHIgPSBvcHRpb25zLnhocigpLFxuXHRcdFx0XHRcdGlkID0gKyt4aHJJZDtcblxuXHRcdFx0XHR4aHIub3Blbiggb3B0aW9ucy50eXBlLCBvcHRpb25zLnVybCwgb3B0aW9ucy5hc3luYywgb3B0aW9ucy51c2VybmFtZSwgb3B0aW9ucy5wYXNzd29yZCApO1xuXG5cdFx0XHRcdC8vIEFwcGx5IGN1c3RvbSBmaWVsZHMgaWYgcHJvdmlkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdFx0eGhyWyBpIF0gPSBvcHRpb25zLnhockZpZWxkc1sgaSBdO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcblx0XHRcdFx0aWYgKCBvcHRpb25zLm1pbWVUeXBlICYmIHhoci5vdmVycmlkZU1pbWVUeXBlICkge1xuXHRcdFx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCBvcHRpb25zLm1pbWVUeXBlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBYLVJlcXVlc3RlZC1XaXRoIGhlYWRlclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXG5cdFx0XHRcdC8vIGFraW4gdG8gYSBqaWdzYXcgcHV6emxlLCB3ZSBzaW1wbHkgbmV2ZXIgc2V0IGl0IHRvIGJlIHN1cmUuXG5cdFx0XHRcdC8vIChpdCBjYW4gYWx3YXlzIGJlIHNldCBvbiBhIHBlci1yZXF1ZXN0IGJhc2lzIG9yIGV2ZW4gdXNpbmcgYWpheFNldHVwKVxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cblx0XHRcdFx0aWYgKCAhb3B0aW9ucy5jcm9zc0RvbWFpbiAmJiAhaGVhZGVyc1tcIlgtUmVxdWVzdGVkLVdpdGhcIl0gKSB7XG5cdFx0XHRcdFx0aGVhZGVyc1tcIlgtUmVxdWVzdGVkLVdpdGhcIl0gPSBcIlhNTEh0dHBSZXF1ZXN0XCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZXQgaGVhZGVyc1xuXHRcdFx0XHRmb3IgKCBpIGluIGhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0XHRkZWxldGUgeGhyQ2FsbGJhY2tzWyBpZCBdO1xuXHRcdFx0XHRcdFx0XHRjYWxsYmFjayA9IHhoci5vbmxvYWQgPSB4aHIub25lcnJvciA9IG51bGw7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlID09PSBcImFib3J0XCIgKSB7XG5cdFx0XHRcdFx0XHRcdFx0eGhyLmFib3J0KCk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IFwiZXJyb3JcIiApIHtcblx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3XG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1c1RleHRcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyU3VjY2Vzc1N0YXR1c1sgeGhyLnN0YXR1cyBdIHx8IHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dCxcblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFOVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gQWNjZXNzaW5nIGJpbmFyeS1kYXRhIHJlc3BvbnNlVGV4dCB0aHJvd3MgYW4gZXhjZXB0aW9uXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyAoIzExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0dHlwZW9mIHhoci5yZXNwb25zZVRleHQgPT09IFwic3RyaW5nXCIgPyB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRleHQ6IHhoci5yZXNwb25zZVRleHRcblx0XHRcdFx0XHRcdFx0XHRcdH0gOiB1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHR4aHIub25lcnJvciA9IGNhbGxiYWNrKFwiZXJyb3JcIik7XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIHRoZSBhYm9ydCBjYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IHhockNhbGxiYWNrc1sgaWQgXSA9IGNhbGxiYWNrKFwiYWJvcnRcIik7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pXG5cdFx0XHRcdFx0eGhyLnNlbmQoIG9wdGlvbnMuaGFzQ29udGVudCAmJiBvcHRpb25zLmRhdGEgfHwgbnVsbCApO1xuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHQvLyAjMTQ2ODM6IE9ubHkgcmV0aHJvdyBpZiB0aGlzIGhhc24ndCBiZWVuIG5vdGlmaWVkIGFzIGFuIGVycm9yIHlldFxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHR0aHJvdyBlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSxcblxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXHR9XG59KTtcblxuXG5cblxuLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGVcbmpRdWVyeS5hamF4U2V0dXAoe1xuXHRhY2NlcHRzOiB7XG5cdFx0c2NyaXB0OiBcInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcblx0fSxcblx0Y29udGVudHM6IHtcblx0XHRzY3JpcHQ6IC8oPzpqYXZhfGVjbWEpc2NyaXB0L1xuXHR9LFxuXHRjb252ZXJ0ZXJzOiB7XG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7XG5cdFx0XHRyZXR1cm4gdGV4dDtcblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jYWNoZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdHMuY2FjaGUgPSBmYWxzZTtcblx0fVxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy50eXBlID0gXCJHRVRcIjtcblx0fVxufSk7XG5cbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXHQvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIHJlcXVlc3RzXG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIF8sIGNvbXBsZXRlICkge1xuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoXCI8c2NyaXB0PlwiKS5wcm9wKHtcblx0XHRcdFx0XHRhc3luYzogdHJ1ZSxcblx0XHRcdFx0XHRjaGFyc2V0OiBzLnNjcmlwdENoYXJzZXQsXG5cdFx0XHRcdFx0c3JjOiBzLnVybFxuXHRcdFx0XHR9KS5vbihcblx0XHRcdFx0XHRcImxvYWQgZXJyb3JcIixcblx0XHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRzY3JpcHQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XG5cdFx0XHRcdFx0XHRpZiAoIGV2dCApIHtcblx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIGV2dC50eXBlID09PSBcImVycm9yXCIgPyA0MDQgOiAyMDAsIGV2dC50eXBlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpO1xuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHRbIDAgXSApO1xuXHRcdFx0fSxcblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcblx0cmpzb25wID0gLyg9KVxcPyg/PSZ8JCl8XFw/XFw/LztcblxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xualF1ZXJ5LmFqYXhTZXR1cCh7XG5cdGpzb25wOiBcImNhbGxiYWNrXCIsXG5cdGpzb25wQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlKysgKSApO1xuXHRcdHRoaXNbIGNhbGxiYWNrIF0gPSB0cnVlO1xuXHRcdHJldHVybiBjYWxsYmFjaztcblx0fVxufSk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiYgISggcy5jb250ZW50VHlwZSB8fCBcIlwiICkuaW5kZXhPZihcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKSAmJiByanNvbnAudGVzdCggcy5kYXRhICkgJiYgXCJkYXRhXCJcblx0XHQpO1xuXG5cdC8vIEhhbmRsZSBpZmYgdGhlIGV4cGVjdGVkIGRhdGEgdHlwZSBpcyBcImpzb25wXCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXRcblx0aWYgKCBqc29uUHJvcCB8fCBzLmRhdGFUeXBlc1sgMCBdID09PSBcImpzb25wXCIgKSB7XG5cblx0XHQvLyBHZXQgY2FsbGJhY2sgbmFtZSwgcmVtZW1iZXJpbmcgcHJlZXhpc3RpbmcgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0XG5cdFx0Y2FsbGJhY2tOYW1lID0gcy5qc29ucENhbGxiYWNrID0galF1ZXJ5LmlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID9cblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcblx0XHRcdHMuanNvbnBDYWxsYmFjaztcblxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcblx0XHRpZiAoIGpzb25Qcm9wICkge1xuXHRcdFx0c1sganNvblByb3AgXSA9IHNbIGpzb25Qcm9wIF0ucmVwbGFjZSggcmpzb25wLCBcIiQxXCIgKyBjYWxsYmFja05hbWUgKTtcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcblx0XHRcdHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIHMudXJsICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmpzb25wICsgXCI9XCIgKyBjYWxsYmFja05hbWU7XG5cdFx0fVxuXG5cdFx0Ly8gVXNlIGRhdGEgY29udmVydGVyIHRvIHJldHJpZXZlIGpzb24gYWZ0ZXIgc2NyaXB0IGV4ZWN1dGlvblxuXHRcdHMuY29udmVydGVyc1tcInNjcmlwdCBqc29uXCJdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHtcblx0XHRcdFx0alF1ZXJ5LmVycm9yKCBjYWxsYmFja05hbWUgKyBcIiB3YXMgbm90IGNhbGxlZFwiICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTtcblx0XHR9O1xuXG5cdFx0Ly8gZm9yY2UganNvbiBkYXRhVHlwZVxuXHRcdHMuZGF0YVR5cGVzWyAwIF0gPSBcImpzb25cIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tcblx0XHRvdmVyd3JpdHRlbiA9IHdpbmRvd1sgY2FsbGJhY2tOYW1lIF07XG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBhcmd1bWVudHM7XG5cdFx0fTtcblxuXHRcdC8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKVxuXHRcdGpxWEhSLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIFJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcblx0XHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBvdmVyd3JpdHRlbjtcblxuXHRcdFx0Ly8gU2F2ZSBiYWNrIGFzIGZyZWVcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XG5cdFx0XHRcdC8vIG1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxuXHRcdFx0XHRzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHRcdFx0Ly8gc2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxuXHRcdFx0XHRvbGRDYWxsYmFja3MucHVzaCggY2FsbGJhY2tOYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbGwgaWYgaXQgd2FzIGEgZnVuY3Rpb24gYW5kIHdlIGhhdmUgYSByZXNwb25zZVxuXHRcdFx0aWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBqUXVlcnkuaXNGdW5jdGlvbiggb3ZlcndyaXR0ZW4gKSApIHtcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcblx0XHR9KTtcblxuXHRcdC8vIERlbGVnYXRlIHRvIHNjcmlwdFxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xuXHR9XG59KTtcblxuXG5cblxuLy8gZGF0YTogc3RyaW5nIG9mIGh0bWxcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCwgZGVmYXVsdHMgdG8gZG9jdW1lbnRcbi8vIGtlZXBTY3JpcHRzIChvcHRpb25hbCk6IElmIHRydWUsIHdpbGwgaW5jbHVkZSBzY3JpcHRzIHBhc3NlZCBpbiB0aGUgaHRtbCBzdHJpbmdcbmpRdWVyeS5wYXJzZUhUTUwgPSBmdW5jdGlvbiggZGF0YSwgY29udGV4dCwga2VlcFNjcmlwdHMgKSB7XG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblxuXHR2YXIgcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICksXG5cdFx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWzFdICkgXTtcblx0fVxuXG5cdHBhcnNlZCA9IGpRdWVyeS5idWlsZEZyYWdtZW50KCBbIGRhdGEgXSwgY29udGV4dCwgc2NyaXB0cyApO1xuXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkoIHNjcmlwdHMgKS5yZW1vdmUoKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBwYXJzZWQuY2hpbGROb2RlcyApO1xufTtcblxuXG4vLyBLZWVwIGEgY29weSBvZiB0aGUgb2xkIGxvYWQgbWV0aG9kXG52YXIgX2xvYWQgPSBqUXVlcnkuZm4ubG9hZDtcblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0aWYgKCB0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiICYmIF9sb2FkICkge1xuXHRcdHJldHVybiBfbG9hZC5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdH1cblxuXHR2YXIgc2VsZWN0b3IsIHR5cGUsIHJlc3BvbnNlLFxuXHRcdHNlbGYgPSB0aGlzLFxuXHRcdG9mZiA9IHVybC5pbmRleE9mKFwiIFwiKTtcblxuXHRpZiAoIG9mZiA+PSAwICkge1xuXHRcdHNlbGVjdG9yID0galF1ZXJ5LnRyaW0oIHVybC5zbGljZSggb2ZmICkgKTtcblx0XHR1cmwgPSB1cmwuc2xpY2UoIDAsIG9mZiApO1xuXHR9XG5cblx0Ly8gSWYgaXQncyBhIGZ1bmN0aW9uXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xuXG5cdFx0Ly8gV2UgYXNzdW1lIHRoYXQgaXQncyB0aGUgY2FsbGJhY2tcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcblx0XHRwYXJhbXMgPSB1bmRlZmluZWQ7XG5cblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xuXHR9IGVsc2UgaWYgKCBwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHR0eXBlID0gXCJQT1NUXCI7XG5cdH1cblxuXHQvLyBJZiB3ZSBoYXZlIGVsZW1lbnRzIHRvIG1vZGlmeSwgbWFrZSB0aGUgcmVxdWVzdFxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcblx0XHRqUXVlcnkuYWpheCh7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gaWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcblx0XHRcdGRhdGE6IHBhcmFtc1xuXHRcdH0pLmRvbmUoZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoXCI8ZGl2PlwiKS5hcHBlbmQoIGpRdWVyeS5wYXJzZUhUTUwoIHJlc3BvbnNlVGV4dCApICkuZmluZCggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcblx0XHRcdFx0cmVzcG9uc2VUZXh0ICk7XG5cblx0XHR9KS5jb21wbGV0ZSggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGNhbGxiYWNrLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gdGhpcztcbn07XG5cblxuXG5cbmpRdWVyeS5leHByLmZpbHRlcnMuYW5pbWF0ZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5ncmVwKGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTtcblx0fSkubGVuZ3RoO1xufTtcblxuXG5cblxudmFyIGRvY0VsZW0gPSB3aW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4vKipcbiAqIEdldHMgYSB3aW5kb3cgZnJvbSBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldFdpbmRvdyggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApID8gZWxlbSA6IGVsZW0ubm9kZVR5cGUgPT09IDkgJiYgZWxlbS5kZWZhdWx0Vmlldztcbn1cblxualF1ZXJ5Lm9mZnNldCA9IHtcblx0c2V0T2Zmc2V0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgaSApIHtcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxuXHRcdFx0cG9zaXRpb24gPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSxcblx0XHRcdGN1ckVsZW0gPSBqUXVlcnkoIGVsZW0gKSxcblx0XHRcdHByb3BzID0ge307XG5cblx0XHQvLyBTZXQgcG9zaXRpb24gZmlyc3QsIGluLWNhc2UgdG9wL2xlZnQgYXJlIHNldCBldmVuIG9uIHN0YXRpYyBlbGVtXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cdFx0fVxuXG5cdFx0Y3VyT2Zmc2V0ID0gY3VyRWxlbS5vZmZzZXQoKTtcblx0XHRjdXJDU1NUb3AgPSBqUXVlcnkuY3NzKCBlbGVtLCBcInRvcFwiICk7XG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XG5cdFx0Y2FsY3VsYXRlUG9zaXRpb24gPSAoIHBvc2l0aW9uID09PSBcImFic29sdXRlXCIgfHwgcG9zaXRpb24gPT09IFwiZml4ZWRcIiApICYmXG5cdFx0XHQoIGN1ckNTU1RvcCArIGN1ckNTU0xlZnQgKS5pbmRleE9mKFwiYXV0b1wiKSA+IC0xO1xuXG5cdFx0Ly8gTmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXIgdG9wIG9yIGxlZnQgaXMgYXV0byBhbmQgcG9zaXRpb24gaXMgZWl0aGVyIGFic29sdXRlIG9yIGZpeGVkXG5cdFx0aWYgKCBjYWxjdWxhdGVQb3NpdGlvbiApIHtcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xuXHRcdFx0Y3VyVG9wID0gY3VyUG9zaXRpb24udG9wO1xuXHRcdFx0Y3VyTGVmdCA9IGN1clBvc2l0aW9uLmxlZnQ7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Y3VyVG9wID0gcGFyc2VGbG9hdCggY3VyQ1NTVG9wICkgfHwgMDtcblx0XHRcdGN1ckxlZnQgPSBwYXJzZUZsb2F0KCBjdXJDU1NMZWZ0ICkgfHwgMDtcblx0XHR9XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XG5cdFx0XHRvcHRpb25zID0gb3B0aW9ucy5jYWxsKCBlbGVtLCBpLCBjdXJPZmZzZXQgKTtcblx0XHR9XG5cblx0XHRpZiAoIG9wdGlvbnMudG9wICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xuXHRcdH1cblx0XHRpZiAoIG9wdGlvbnMubGVmdCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XG5cdFx0fVxuXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcblx0XHRcdG9wdGlvbnMudXNpbmcuY2FsbCggZWxlbSwgcHJvcHMgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiBvcHRpb25zID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHR0aGlzIDpcblx0XHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRcdGpRdWVyeS5vZmZzZXQuc2V0T2Zmc2V0KCB0aGlzLCBvcHRpb25zLCBpICk7XG5cdFx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHZhciBkb2NFbGVtLCB3aW4sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0Ym94ID0geyB0b3A6IDAsIGxlZnQ6IDAgfSxcblx0XHRcdGRvYyA9IGVsZW0gJiYgZWxlbS5vd25lckRvY3VtZW50O1xuXG5cdFx0aWYgKCAhZG9jICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0Ly8gTWFrZSBzdXJlIGl0J3Mgbm90IGEgZGlzY29ubmVjdGVkIERPTSBub2RlXG5cdFx0aWYgKCAhalF1ZXJ5LmNvbnRhaW5zKCBkb2NFbGVtLCBlbGVtICkgKSB7XG5cdFx0XHRyZXR1cm4gYm94O1xuXHRcdH1cblxuXHRcdC8vIElmIHdlIGRvbid0IGhhdmUgZ0JDUiwganVzdCB1c2UgMCwwIHJhdGhlciB0aGFuIGVycm9yXG5cdFx0Ly8gQmxhY2tCZXJyeSA1LCBpT1MgMyAob3JpZ2luYWwgaVBob25lKVxuXHRcdGlmICggdHlwZW9mIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0ICE9PSBzdHJ1bmRlZmluZWQgKSB7XG5cdFx0XHRib3ggPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdH1cblx0XHR3aW4gPSBnZXRXaW5kb3coIGRvYyApO1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IGJveC50b3AgKyB3aW4ucGFnZVlPZmZzZXQgLSBkb2NFbGVtLmNsaWVudFRvcCxcblx0XHRcdGxlZnQ6IGJveC5sZWZ0ICsgd2luLnBhZ2VYT2Zmc2V0IC0gZG9jRWxlbS5jbGllbnRMZWZ0XG5cdFx0fTtcblx0fSxcblxuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpc1sgMCBdICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBvZmZzZXRQYXJlbnQsIG9mZnNldCxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXG5cdFx0XHRwYXJlbnRPZmZzZXQgPSB7IHRvcDogMCwgbGVmdDogMCB9O1xuXG5cdFx0Ly8gRml4ZWQgZWxlbWVudHMgYXJlIG9mZnNldCBmcm9tIHdpbmRvdyAocGFyZW50T2Zmc2V0ID0ge3RvcDowLCBsZWZ0OiAwfSwgYmVjYXVzZSBpdCBpcyBpdHMgb25seSBvZmZzZXQgcGFyZW50XG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xuXHRcdFx0Ly8gV2UgYXNzdW1lIHRoYXQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGlzIGF2YWlsYWJsZSB3aGVuIGNvbXB1dGVkIHBvc2l0aW9uIGlzIGZpeGVkXG5cdFx0XHRvZmZzZXQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50XG5cdFx0XHRvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCgpO1xuXG5cdFx0XHQvLyBHZXQgY29ycmVjdCBvZmZzZXRzXG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXHRcdFx0aWYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJodG1sXCIgKSApIHtcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcblx0XHRcdHBhcmVudE9mZnNldC50b3AgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50WyAwIF0sIFwiYm9yZGVyVG9wV2lkdGhcIiwgdHJ1ZSApO1xuXHRcdFx0cGFyZW50T2Zmc2V0LmxlZnQgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50WyAwIF0sIFwiYm9yZGVyTGVmdFdpZHRoXCIsIHRydWUgKTtcblx0XHR9XG5cblx0XHQvLyBTdWJ0cmFjdCBwYXJlbnQgb2Zmc2V0cyBhbmQgZWxlbWVudCBtYXJnaW5zXG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogb2Zmc2V0LnRvcCAtIHBhcmVudE9mZnNldC50b3AgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpblRvcFwiLCB0cnVlICksXG5cdFx0XHRsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0IC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIsIHRydWUgKVxuXHRcdH07XG5cdH0sXG5cblx0b2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQgfHwgZG9jRWxlbTtcblxuXHRcdFx0d2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnQsIFwiaHRtbFwiICkgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApICkge1xuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0UGFyZW50O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gb2Zmc2V0UGFyZW50IHx8IGRvY0VsZW07XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cdFx0XHR2YXIgd2luID0gZ2V0V2luZG93KCBlbGVtICk7XG5cblx0XHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiB3aW5kb3cucGFnZVhPZmZzZXQsXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luZG93LnBhZ2VZT2Zmc2V0XG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoLCBudWxsICk7XG5cdH07XG59KTtcblxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cbi8vIFdlYmtpdCBidWc6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yOTA4NFxuLy8gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHBlcmNlbnQgd2hlbiBzcGVjaWZpZWQgZm9yIHRvcC9sZWZ0L2JvdHRvbS9yaWdodFxuLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIHdlIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmVcbmpRdWVyeS5lYWNoKCBbIFwidG9wXCIsIFwibGVmdFwiIF0sIGZ1bmN0aW9uKCBpLCBwcm9wICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XG5cdFx0XHRcdC8vIGlmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSk7XG5cblxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXG5qUXVlcnkuZWFjaCggeyBIZWlnaHQ6IFwiaGVpZ2h0XCIsIFdpZHRoOiBcIndpZHRoXCIgfSwgZnVuY3Rpb24oIG5hbWUsIHR5cGUgKSB7XG5cdGpRdWVyeS5lYWNoKCB7IHBhZGRpbmc6IFwiaW5uZXJcIiArIG5hbWUsIGNvbnRlbnQ6IHR5cGUsIFwiXCI6IFwib3V0ZXJcIiArIG5hbWUgfSwgZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cdFx0Ly8gbWFyZ2luIGlzIG9ubHkgZm9yIG91dGVySGVpZ2h0LCBvdXRlcldpZHRoXG5cdFx0alF1ZXJ5LmZuWyBmdW5jTmFtZSBdID0gZnVuY3Rpb24oIG1hcmdpbiwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgY2hhaW5hYmxlID0gYXJndW1lbnRzLmxlbmd0aCAmJiAoIGRlZmF1bHRFeHRyYSB8fCB0eXBlb2YgbWFyZ2luICE9PSBcImJvb2xlYW5cIiApLFxuXHRcdFx0XHRleHRyYSA9IGRlZmF1bHRFeHRyYSB8fCAoIG1hcmdpbiA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gdHJ1ZSA/IFwibWFyZ2luXCIgOiBcImJvcmRlclwiICk7XG5cblx0XHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIGRvYztcblxuXHRcdFx0XHRpZiAoIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXHRcdFx0XHRcdC8vIEFzIG9mIDUvOC8yMDEyIHRoaXMgd2lsbCB5aWVsZCBpbmNvcnJlY3QgcmVzdWx0cyBmb3IgTW9iaWxlIFNhZmFyaSwgYnV0IHRoZXJlXG5cdFx0XHRcdFx0Ly8gaXNuJ3QgYSB3aG9sZSBsb3Qgd2UgY2FuIGRvLiBTZWUgcHVsbCByZXF1ZXN0IGF0IHRoaXMgVVJMIGZvciBkaXNjdXNzaW9uOlxuXHRcdFx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNzY0XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyBcImNsaWVudFwiICsgbmFtZSBdO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gR2V0IGRvY3VtZW50IHdpZHRoIG9yIGhlaWdodFxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0ZG9jID0gZWxlbS5kb2N1bWVudEVsZW1lbnQ7XG5cblx0XHRcdFx0XHQvLyBFaXRoZXIgc2Nyb2xsW1dpZHRoL0hlaWdodF0gb3Igb2Zmc2V0W1dpZHRoL0hlaWdodF0gb3IgY2xpZW50W1dpZHRoL0hlaWdodF0sXG5cdFx0XHRcdFx0Ly8gd2hpY2hldmVyIGlzIGdyZWF0ZXN0XG5cdFx0XHRcdFx0cmV0dXJuIE1hdGgubWF4KFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcInNjcm9sbFwiICsgbmFtZSBdLCBkb2NbIFwic2Nyb2xsXCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwib2Zmc2V0XCIgKyBuYW1lIF0sIGRvY1sgXCJvZmZzZXRcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGRvY1sgXCJjbGllbnRcIiArIG5hbWUgXVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSwgbnVsbCApO1xuXHRcdH07XG5cdH0pO1xufSk7XG5cblxuLy8gVGhlIG51bWJlciBvZiBlbGVtZW50cyBjb250YWluZWQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXRcbmpRdWVyeS5mbi5zaXplID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzLmxlbmd0aDtcbn07XG5cbmpRdWVyeS5mbi5hbmRTZWxmID0galF1ZXJ5LmZuLmFkZEJhY2s7XG5cblxuXG5cbi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlclxuLy8gZmlsZXMgdGhhdCBtYXkgdXNlIGRlZmluZSwgYnV0IG5vdCB2aWEgYSBwcm9wZXIgY29uY2F0ZW5hdGlvbiBzY3JpcHQgdGhhdFxuLy8gdW5kZXJzdGFuZHMgYW5vbnltb3VzIEFNRCBtb2R1bGVzLiBBIG5hbWVkIEFNRCBpcyBzYWZlc3QgYW5kIG1vc3Qgcm9idXN0XG4vLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlXG4vLyBkZXJpdmVkIGZyb20gZmlsZSBuYW1lcywgYW5kIGpRdWVyeSBpcyBub3JtYWxseSBkZWxpdmVyZWQgaW4gYSBsb3dlcmNhc2Vcbi8vIGZpbGUgbmFtZS4gRG8gdGhpcyBhZnRlciBjcmVhdGluZyB0aGUgZ2xvYmFsIHNvIHRoYXQgaWYgYW4gQU1EIG1vZHVsZSB3YW50c1xuLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLlxuXG4vLyBOb3RlIHRoYXQgZm9yIG1heGltdW0gcG9ydGFiaWxpdHksIGxpYnJhcmllcyB0aGF0IGFyZSBub3QgalF1ZXJ5IHNob3VsZFxuLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhblxuLy8gQU1EIGxvYWRlciBpcyBwcmVzZW50LiBqUXVlcnkgaXMgYSBzcGVjaWFsIGNhc2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL3JlcXVpcmVqcy93aWtpL1VwZGF0aW5nLWV4aXN0aW5nLWxpYnJhcmllcyN3aWtpLWFub25cblxuaWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblx0ZGVmaW5lKCBcImpxdWVyeVwiLCBbXSwgZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeTtcblx0fSk7XG59XG5cblxuXG5cbnZhclxuXHQvLyBNYXAgb3ZlciBqUXVlcnkgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0X2pRdWVyeSA9IHdpbmRvdy5qUXVlcnksXG5cblx0Ly8gTWFwIG92ZXIgdGhlICQgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0XyQgPSB3aW5kb3cuJDtcblxualF1ZXJ5Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiggZGVlcCApIHtcblx0aWYgKCB3aW5kb3cuJCA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy4kID0gXyQ7XG5cdH1cblxuXHRpZiAoIGRlZXAgJiYgd2luZG93LmpRdWVyeSA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy5qUXVlcnkgPSBfalF1ZXJ5O1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeTtcbn07XG5cbi8vIEV4cG9zZSBqUXVlcnkgYW5kICQgaWRlbnRpZmllcnMsIGV2ZW4gaW5cbi8vIEFNRCAoIzcxMDIjY29tbWVudDoxMCwgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvcHVsbC81NTcpXG4vLyBhbmQgQ29tbW9uSlMgZm9yIGJyb3dzZXIgZW11bGF0b3JzICgjMTM1NjYpXG5pZiAoIHR5cGVvZiBub0dsb2JhbCA9PT0gc3RydW5kZWZpbmVkICkge1xuXHR3aW5kb3cualF1ZXJ5ID0gd2luZG93LiQgPSBqUXVlcnk7XG59XG5cblxuXG5cbnJldHVybiBqUXVlcnk7XG5cbn0pKTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8vISBtb21lbnQuanNcbi8vISB2ZXJzaW9uIDogMi44LjRcbi8vISBhdXRob3JzIDogVGltIFdvb2QsIElza3JlbiBDaGVybmV2LCBNb21lbnQuanMgY29udHJpYnV0b3JzXG4vLyEgbGljZW5zZSA6IE1JVFxuLy8hIG1vbWVudGpzLmNvbVxuXG4oZnVuY3Rpb24gKHVuZGVmaW5lZCkge1xuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgQ29uc3RhbnRzXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgdmFyIG1vbWVudCxcbiAgICAgICAgVkVSU0lPTiA9ICcyLjguNCcsXG4gICAgICAgIC8vIHRoZSBnbG9iYWwtc2NvcGUgdGhpcyBpcyBOT1QgdGhlIGdsb2JhbCBvYmplY3QgaW4gTm9kZS5qc1xuICAgICAgICBnbG9iYWxTY29wZSA9IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdGhpcyxcbiAgICAgICAgb2xkR2xvYmFsTW9tZW50LFxuICAgICAgICByb3VuZCA9IE1hdGgucm91bmQsXG4gICAgICAgIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcbiAgICAgICAgaSxcblxuICAgICAgICBZRUFSID0gMCxcbiAgICAgICAgTU9OVEggPSAxLFxuICAgICAgICBEQVRFID0gMixcbiAgICAgICAgSE9VUiA9IDMsXG4gICAgICAgIE1JTlVURSA9IDQsXG4gICAgICAgIFNFQ09ORCA9IDUsXG4gICAgICAgIE1JTExJU0VDT05EID0gNixcblxuICAgICAgICAvLyBpbnRlcm5hbCBzdG9yYWdlIGZvciBsb2NhbGUgY29uZmlnIGZpbGVzXG4gICAgICAgIGxvY2FsZXMgPSB7fSxcblxuICAgICAgICAvLyBleHRyYSBtb21lbnQgaW50ZXJuYWwgcHJvcGVydGllcyAocGx1Z2lucyByZWdpc3RlciBwcm9wcyBoZXJlKVxuICAgICAgICBtb21lbnRQcm9wZXJ0aWVzID0gW10sXG5cbiAgICAgICAgLy8gY2hlY2sgZm9yIG5vZGVKU1xuICAgICAgICBoYXNNb2R1bGUgPSAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgbW9kdWxlICYmIG1vZHVsZS5leHBvcnRzKSxcblxuICAgICAgICAvLyBBU1AuTkVUIGpzb24gZGF0ZSBmb3JtYXQgcmVnZXhcbiAgICAgICAgYXNwTmV0SnNvblJlZ2V4ID0gL15cXC8/RGF0ZVxcKChcXC0/XFxkKykvaSxcbiAgICAgICAgYXNwTmV0VGltZVNwYW5Kc29uUmVnZXggPSAvKFxcLSk/KD86KFxcZCopXFwuKT8oXFxkKylcXDooXFxkKykoPzpcXDooXFxkKylcXC4/KFxcZHszfSk/KT8vLFxuXG4gICAgICAgIC8vIGZyb20gaHR0cDovL2RvY3MuY2xvc3VyZS1saWJyYXJ5Lmdvb2dsZWNvZGUuY29tL2dpdC9jbG9zdXJlX2dvb2dfZGF0ZV9kYXRlLmpzLnNvdXJjZS5odG1sXG4gICAgICAgIC8vIHNvbWV3aGF0IG1vcmUgaW4gbGluZSB3aXRoIDQuNC4zLjIgMjAwNCBzcGVjLCBidXQgYWxsb3dzIGRlY2ltYWwgYW55d2hlcmVcbiAgICAgICAgaXNvRHVyYXRpb25SZWdleCA9IC9eKC0pP1AoPzooPzooWzAtOSwuXSopWSk/KD86KFswLTksLl0qKU0pPyg/OihbMC05LC5dKilEKT8oPzpUKD86KFswLTksLl0qKUgpPyg/OihbMC05LC5dKilNKT8oPzooWzAtOSwuXSopUyk/KT98KFswLTksLl0qKVcpJC8sXG5cbiAgICAgICAgLy8gZm9ybWF0IHRva2Vuc1xuICAgICAgICBmb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KE1vfE1NP00/TT98RG98REREb3xERD9EP0Q/fGRkZD9kP3xkbz98d1tvfHddP3xXW298V10/fFF8WVlZWVlZfFlZWVlZfFlZWVl8WVl8Z2coZ2dnPyk/fEdHKEdHRz8pP3xlfEV8YXxBfGhoP3xISD98bW0/fHNzP3xTezEsNH18eHxYfHp6P3xaWj98LikvZyxcbiAgICAgICAgbG9jYWxGb3JtYXR0aW5nVG9rZW5zID0gLyhcXFtbXlxcW10qXFxdKXwoXFxcXCk/KExUU3xMVHxMTD9MP0w/fGx7MSw0fSkvZyxcblxuICAgICAgICAvLyBwYXJzaW5nIHRva2VuIHJlZ2V4ZXNcbiAgICAgICAgcGFyc2VUb2tlbk9uZU9yVHdvRGlnaXRzID0gL1xcZFxcZD8vLCAvLyAwIC0gOTlcbiAgICAgICAgcGFyc2VUb2tlbk9uZVRvVGhyZWVEaWdpdHMgPSAvXFxkezEsM30vLCAvLyAwIC0gOTk5XG4gICAgICAgIHBhcnNlVG9rZW5PbmVUb0ZvdXJEaWdpdHMgPSAvXFxkezEsNH0vLCAvLyAwIC0gOTk5OVxuICAgICAgICBwYXJzZVRva2VuT25lVG9TaXhEaWdpdHMgPSAvWytcXC1dP1xcZHsxLDZ9LywgLy8gLTk5OSw5OTkgLSA5OTksOTk5XG4gICAgICAgIHBhcnNlVG9rZW5EaWdpdHMgPSAvXFxkKy8sIC8vIG5vbnplcm8gbnVtYmVyIG9mIGRpZ2l0c1xuICAgICAgICBwYXJzZVRva2VuV29yZCA9IC9bMC05XSpbJ2EtelxcdTAwQTAtXFx1MDVGRlxcdTA3MDAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0rfFtcXHUwNjAwLVxcdTA2RkZcXC9dKyhcXHMqP1tcXHUwNjAwLVxcdTA2RkZdKyl7MSwyfS9pLCAvLyBhbnkgd29yZCAob3IgdHdvKSBjaGFyYWN0ZXJzIG9yIG51bWJlcnMgaW5jbHVkaW5nIHR3by90aHJlZSB3b3JkIG1vbnRoIGluIGFyYWJpYy5cbiAgICAgICAgcGFyc2VUb2tlblRpbWV6b25lID0gL1p8W1xcK1xcLV1cXGRcXGQ6P1xcZFxcZC9naSwgLy8gKzAwOjAwIC0wMDowMCArMDAwMCAtMDAwMCBvciBaXG4gICAgICAgIHBhcnNlVG9rZW5UID0gL1QvaSwgLy8gVCAoSVNPIHNlcGFyYXRvcilcbiAgICAgICAgcGFyc2VUb2tlbk9mZnNldE1zID0gL1tcXCtcXC1dP1xcZCsvLCAvLyAxMjM0NTY3ODkwMTIzXG4gICAgICAgIHBhcnNlVG9rZW5UaW1lc3RhbXBNcyA9IC9bXFwrXFwtXT9cXGQrKFxcLlxcZHsxLDN9KT8vLCAvLyAxMjM0NTY3ODkgMTIzNDU2Nzg5LjEyM1xuXG4gICAgICAgIC8vc3RyaWN0IHBhcnNpbmcgcmVnZXhlc1xuICAgICAgICBwYXJzZVRva2VuT25lRGlnaXQgPSAvXFxkLywgLy8gMCAtIDlcbiAgICAgICAgcGFyc2VUb2tlblR3b0RpZ2l0cyA9IC9cXGRcXGQvLCAvLyAwMCAtIDk5XG4gICAgICAgIHBhcnNlVG9rZW5UaHJlZURpZ2l0cyA9IC9cXGR7M30vLCAvLyAwMDAgLSA5OTlcbiAgICAgICAgcGFyc2VUb2tlbkZvdXJEaWdpdHMgPSAvXFxkezR9LywgLy8gMDAwMCAtIDk5OTlcbiAgICAgICAgcGFyc2VUb2tlblNpeERpZ2l0cyA9IC9bKy1dP1xcZHs2fS8sIC8vIC05OTksOTk5IC0gOTk5LDk5OVxuICAgICAgICBwYXJzZVRva2VuU2lnbmVkTnVtYmVyID0gL1srLV0/XFxkKy8sIC8vIC1pbmYgLSBpbmZcblxuICAgICAgICAvLyBpc28gODYwMSByZWdleFxuICAgICAgICAvLyAwMDAwLTAwLTAwIDAwMDAtVzAwIG9yIDAwMDAtVzAwLTAgKyBUICsgMDAgb3IgMDA6MDAgb3IgMDA6MDA6MDAgb3IgMDA6MDA6MDAuMDAwICsgKzAwOjAwIG9yICswMDAwIG9yICswMClcbiAgICAgICAgaXNvUmVnZXggPSAvXlxccyooPzpbKy1dXFxkezZ9fFxcZHs0fSktKD86KFxcZFxcZC1cXGRcXGQpfChXXFxkXFxkJCl8KFdcXGRcXGQtXFxkKXwoXFxkXFxkXFxkKSkoKFR8ICkoXFxkXFxkKDpcXGRcXGQoOlxcZFxcZChcXC5cXGQrKT8pPyk/KT8oW1xcK1xcLV1cXGRcXGQoPzo6P1xcZFxcZCk/fFxccypaKT8pPyQvLFxuXG4gICAgICAgIGlzb0Zvcm1hdCA9ICdZWVlZLU1NLUREVEhIOm1tOnNzWicsXG5cbiAgICAgICAgaXNvRGF0ZXMgPSBbXG4gICAgICAgICAgICBbJ1lZWVlZWS1NTS1ERCcsIC9bKy1dXFxkezZ9LVxcZHsyfS1cXGR7Mn0vXSxcbiAgICAgICAgICAgIFsnWVlZWS1NTS1ERCcsIC9cXGR7NH0tXFxkezJ9LVxcZHsyfS9dLFxuICAgICAgICAgICAgWydHR0dHLVtXXVdXLUUnLCAvXFxkezR9LVdcXGR7Mn0tXFxkL10sXG4gICAgICAgICAgICBbJ0dHR0ctW1ddV1cnLCAvXFxkezR9LVdcXGR7Mn0vXSxcbiAgICAgICAgICAgIFsnWVlZWS1EREQnLCAvXFxkezR9LVxcZHszfS9dXG4gICAgICAgIF0sXG5cbiAgICAgICAgLy8gaXNvIHRpbWUgZm9ybWF0cyBhbmQgcmVnZXhlc1xuICAgICAgICBpc29UaW1lcyA9IFtcbiAgICAgICAgICAgIFsnSEg6bW06c3MuU1NTUycsIC8oVHwgKVxcZFxcZDpcXGRcXGQ6XFxkXFxkXFwuXFxkKy9dLFxuICAgICAgICAgICAgWydISDptbTpzcycsIC8oVHwgKVxcZFxcZDpcXGRcXGQ6XFxkXFxkL10sXG4gICAgICAgICAgICBbJ0hIOm1tJywgLyhUfCApXFxkXFxkOlxcZFxcZC9dLFxuICAgICAgICAgICAgWydISCcsIC8oVHwgKVxcZFxcZC9dXG4gICAgICAgIF0sXG5cbiAgICAgICAgLy8gdGltZXpvbmUgY2h1bmtlciAnKzEwOjAwJyA+IFsnMTAnLCAnMDAnXSBvciAnLTE1MzAnID4gWyctMTUnLCAnMzAnXVxuICAgICAgICBwYXJzZVRpbWV6b25lQ2h1bmtlciA9IC8oW1xcK1xcLV18XFxkXFxkKS9naSxcblxuICAgICAgICAvLyBnZXR0ZXIgYW5kIHNldHRlciBuYW1lc1xuICAgICAgICBwcm94eUdldHRlcnNBbmRTZXR0ZXJzID0gJ0RhdGV8SG91cnN8TWludXRlc3xTZWNvbmRzfE1pbGxpc2Vjb25kcycuc3BsaXQoJ3wnKSxcbiAgICAgICAgdW5pdE1pbGxpc2Vjb25kRmFjdG9ycyA9IHtcbiAgICAgICAgICAgICdNaWxsaXNlY29uZHMnIDogMSxcbiAgICAgICAgICAgICdTZWNvbmRzJyA6IDFlMyxcbiAgICAgICAgICAgICdNaW51dGVzJyA6IDZlNCxcbiAgICAgICAgICAgICdIb3VycycgOiAzNmU1LFxuICAgICAgICAgICAgJ0RheXMnIDogODY0ZTUsXG4gICAgICAgICAgICAnTW9udGhzJyA6IDI1OTJlNixcbiAgICAgICAgICAgICdZZWFycycgOiAzMTUzNmU2XG4gICAgICAgIH0sXG5cbiAgICAgICAgdW5pdEFsaWFzZXMgPSB7XG4gICAgICAgICAgICBtcyA6ICdtaWxsaXNlY29uZCcsXG4gICAgICAgICAgICBzIDogJ3NlY29uZCcsXG4gICAgICAgICAgICBtIDogJ21pbnV0ZScsXG4gICAgICAgICAgICBoIDogJ2hvdXInLFxuICAgICAgICAgICAgZCA6ICdkYXknLFxuICAgICAgICAgICAgRCA6ICdkYXRlJyxcbiAgICAgICAgICAgIHcgOiAnd2VlaycsXG4gICAgICAgICAgICBXIDogJ2lzb1dlZWsnLFxuICAgICAgICAgICAgTSA6ICdtb250aCcsXG4gICAgICAgICAgICBRIDogJ3F1YXJ0ZXInLFxuICAgICAgICAgICAgeSA6ICd5ZWFyJyxcbiAgICAgICAgICAgIERERCA6ICdkYXlPZlllYXInLFxuICAgICAgICAgICAgZSA6ICd3ZWVrZGF5JyxcbiAgICAgICAgICAgIEUgOiAnaXNvV2Vla2RheScsXG4gICAgICAgICAgICBnZzogJ3dlZWtZZWFyJyxcbiAgICAgICAgICAgIEdHOiAnaXNvV2Vla1llYXInXG4gICAgICAgIH0sXG5cbiAgICAgICAgY2FtZWxGdW5jdGlvbnMgPSB7XG4gICAgICAgICAgICBkYXlvZnllYXIgOiAnZGF5T2ZZZWFyJyxcbiAgICAgICAgICAgIGlzb3dlZWtkYXkgOiAnaXNvV2Vla2RheScsXG4gICAgICAgICAgICBpc293ZWVrIDogJ2lzb1dlZWsnLFxuICAgICAgICAgICAgd2Vla3llYXIgOiAnd2Vla1llYXInLFxuICAgICAgICAgICAgaXNvd2Vla3llYXIgOiAnaXNvV2Vla1llYXInXG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gZm9ybWF0IGZ1bmN0aW9uIHN0cmluZ3NcbiAgICAgICAgZm9ybWF0RnVuY3Rpb25zID0ge30sXG5cbiAgICAgICAgLy8gZGVmYXVsdCByZWxhdGl2ZSB0aW1lIHRocmVzaG9sZHNcbiAgICAgICAgcmVsYXRpdmVUaW1lVGhyZXNob2xkcyA9IHtcbiAgICAgICAgICAgIHM6IDQ1LCAgLy8gc2Vjb25kcyB0byBtaW51dGVcbiAgICAgICAgICAgIG06IDQ1LCAgLy8gbWludXRlcyB0byBob3VyXG4gICAgICAgICAgICBoOiAyMiwgIC8vIGhvdXJzIHRvIGRheVxuICAgICAgICAgICAgZDogMjYsICAvLyBkYXlzIHRvIG1vbnRoXG4gICAgICAgICAgICBNOiAxMSAgIC8vIG1vbnRocyB0byB5ZWFyXG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gdG9rZW5zIHRvIG9yZGluYWxpemUgYW5kIHBhZFxuICAgICAgICBvcmRpbmFsaXplVG9rZW5zID0gJ0RERCB3IFcgTSBEIGQnLnNwbGl0KCcgJyksXG4gICAgICAgIHBhZGRlZFRva2VucyA9ICdNIEQgSCBoIG0gcyB3IFcnLnNwbGl0KCcgJyksXG5cbiAgICAgICAgZm9ybWF0VG9rZW5GdW5jdGlvbnMgPSB7XG4gICAgICAgICAgICBNICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1vbnRoKCkgKyAxO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIE1NTSAgOiBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1vbnRoc1Nob3J0KHRoaXMsIGZvcm1hdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgTU1NTSA6IGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkubW9udGhzKHRoaXMsIGZvcm1hdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgRCAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRlKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgREREICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kYXlPZlllYXIoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRheSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRkICAgOiBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzTWluKHRoaXMsIGZvcm1hdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGRkICA6IGZ1bmN0aW9uIChmb3JtYXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkud2Vla2RheXNTaG9ydCh0aGlzLCBmb3JtYXQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRkZGQgOiBmdW5jdGlvbiAoZm9ybWF0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLndlZWtkYXlzKHRoaXMsIGZvcm1hdCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdyAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53ZWVrKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgVyAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pc29XZWVrKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgWVkgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMueWVhcigpICUgMTAwLCAyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBZWVlZIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy55ZWFyKCksIDQpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFlZWVlZIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy55ZWFyKCksIDUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFlZWVlZWSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgeSA9IHRoaXMueWVhcigpLCBzaWduID0geSA+PSAwID8gJysnIDogJy0nO1xuICAgICAgICAgICAgICAgIHJldHVybiBzaWduICsgbGVmdFplcm9GaWxsKE1hdGguYWJzKHkpLCA2KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZyAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy53ZWVrWWVhcigpICUgMTAwLCAyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZ2dnIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy53ZWVrWWVhcigpLCA0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZ2dnZyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMud2Vla1llYXIoKSwgNSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgR0cgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMuaXNvV2Vla1llYXIoKSAlIDEwMCwgMik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgR0dHRyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRoaXMuaXNvV2Vla1llYXIoKSwgNCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgR0dHR0cgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLmlzb1dlZWtZZWFyKCksIDUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGUgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud2Vla2RheSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIEUgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNvV2Vla2RheSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGEgICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIHRydWUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIEEgICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlRGF0YSgpLm1lcmlkaWVtKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIGZhbHNlKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBIICAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmhvdXJzKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaCAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5ob3VycygpICUgMTIgfHwgMTI7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbSAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5taW51dGVzKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcyAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZWNvbmRzKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUyAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdG9JbnQodGhpcy5taWxsaXNlY29uZHMoKSAvIDEwMCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgU1MgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFplcm9GaWxsKHRvSW50KHRoaXMubWlsbGlzZWNvbmRzKCkgLyAxMCksIDIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFNTUyAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRaZXJvRmlsbCh0aGlzLm1pbGxpc2Vjb25kcygpLCAzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBTU1NTIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwodGhpcy5taWxsaXNlY29uZHMoKSwgMyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgWiAgICA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgYSA9IC10aGlzLnpvbmUoKSxcbiAgICAgICAgICAgICAgICAgICAgYiA9ICcrJztcbiAgICAgICAgICAgICAgICBpZiAoYSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgYSA9IC1hO1xuICAgICAgICAgICAgICAgICAgICBiID0gJy0nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYiArIGxlZnRaZXJvRmlsbCh0b0ludChhIC8gNjApLCAyKSArICc6JyArIGxlZnRaZXJvRmlsbCh0b0ludChhKSAlIDYwLCAyKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBaWiAgIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBhID0gLXRoaXMuem9uZSgpLFxuICAgICAgICAgICAgICAgICAgICBiID0gJysnO1xuICAgICAgICAgICAgICAgIGlmIChhIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICBhID0gLWE7XG4gICAgICAgICAgICAgICAgICAgIGIgPSAnLSc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBiICsgbGVmdFplcm9GaWxsKHRvSW50KGEgLyA2MCksIDIpICsgbGVmdFplcm9GaWxsKHRvSW50KGEpICUgNjAsIDIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHogOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuem9uZUFiYnIoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB6eiA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy56b25lTmFtZSgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHggICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFggICAgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5peCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIFEgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucXVhcnRlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGRlcHJlY2F0aW9ucyA9IHt9LFxuXG4gICAgICAgIGxpc3RzID0gWydtb250aHMnLCAnbW9udGhzU2hvcnQnLCAnd2Vla2RheXMnLCAnd2Vla2RheXNTaG9ydCcsICd3ZWVrZGF5c01pbiddO1xuXG4gICAgLy8gUGljayB0aGUgZmlyc3QgZGVmaW5lZCBvZiB0d28gb3IgdGhyZWUgYXJndW1lbnRzLiBkZmwgY29tZXMgZnJvbVxuICAgIC8vIGRlZmF1bHQuXG4gICAgZnVuY3Rpb24gZGZsKGEsIGIsIGMpIHtcbiAgICAgICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDI6IHJldHVybiBhICE9IG51bGwgPyBhIDogYjtcbiAgICAgICAgICAgIGNhc2UgMzogcmV0dXJuIGEgIT0gbnVsbCA/IGEgOiBiICE9IG51bGwgPyBiIDogYztcbiAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignSW1wbGVtZW50IG1lJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBoYXNPd25Qcm9wKGEsIGIpIHtcbiAgICAgICAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoYSwgYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVmYXVsdFBhcnNpbmdGbGFncygpIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBkZWVwIGNsb25lIHRoaXMgb2JqZWN0LCBhbmQgZXM1IHN0YW5kYXJkIGlzIG5vdCB2ZXJ5XG4gICAgICAgIC8vIGhlbHBmdWwuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBlbXB0eSA6IGZhbHNlLFxuICAgICAgICAgICAgdW51c2VkVG9rZW5zIDogW10sXG4gICAgICAgICAgICB1bnVzZWRJbnB1dCA6IFtdLFxuICAgICAgICAgICAgb3ZlcmZsb3cgOiAtMixcbiAgICAgICAgICAgIGNoYXJzTGVmdE92ZXIgOiAwLFxuICAgICAgICAgICAgbnVsbElucHV0IDogZmFsc2UsXG4gICAgICAgICAgICBpbnZhbGlkTW9udGggOiBudWxsLFxuICAgICAgICAgICAgaW52YWxpZEZvcm1hdCA6IGZhbHNlLFxuICAgICAgICAgICAgdXNlckludmFsaWRhdGVkIDogZmFsc2UsXG4gICAgICAgICAgICBpc286IGZhbHNlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcHJpbnRNc2cobXNnKSB7XG4gICAgICAgIGlmIChtb21lbnQuc3VwcHJlc3NEZXByZWNhdGlvbldhcm5pbmdzID09PSBmYWxzZSAmJlxuICAgICAgICAgICAgICAgIHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlLndhcm4pIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignRGVwcmVjYXRpb24gd2FybmluZzogJyArIG1zZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkZXByZWNhdGUobXNnLCBmbikge1xuICAgICAgICB2YXIgZmlyc3RUaW1lID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGV4dGVuZChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoZmlyc3RUaW1lKSB7XG4gICAgICAgICAgICAgICAgcHJpbnRNc2cobXNnKTtcbiAgICAgICAgICAgICAgICBmaXJzdFRpbWUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9LCBmbik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGVwcmVjYXRlU2ltcGxlKG5hbWUsIG1zZykge1xuICAgICAgICBpZiAoIWRlcHJlY2F0aW9uc1tuYW1lXSkge1xuICAgICAgICAgICAgcHJpbnRNc2cobXNnKTtcbiAgICAgICAgICAgIGRlcHJlY2F0aW9uc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwYWRUb2tlbihmdW5jLCBjb3VudCkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgICAgIHJldHVybiBsZWZ0WmVyb0ZpbGwoZnVuYy5jYWxsKHRoaXMsIGEpLCBjb3VudCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIGZ1bmN0aW9uIG9yZGluYWxpemVUb2tlbihmdW5jLCBwZXJpb2QpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkub3JkaW5hbChmdW5jLmNhbGwodGhpcywgYSksIHBlcmlvZCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgd2hpbGUgKG9yZGluYWxpemVUb2tlbnMubGVuZ3RoKSB7XG4gICAgICAgIGkgPSBvcmRpbmFsaXplVG9rZW5zLnBvcCgpO1xuICAgICAgICBmb3JtYXRUb2tlbkZ1bmN0aW9uc1tpICsgJ28nXSA9IG9yZGluYWxpemVUb2tlbihmb3JtYXRUb2tlbkZ1bmN0aW9uc1tpXSwgaSk7XG4gICAgfVxuICAgIHdoaWxlIChwYWRkZWRUb2tlbnMubGVuZ3RoKSB7XG4gICAgICAgIGkgPSBwYWRkZWRUb2tlbnMucG9wKCk7XG4gICAgICAgIGZvcm1hdFRva2VuRnVuY3Rpb25zW2kgKyBpXSA9IHBhZFRva2VuKGZvcm1hdFRva2VuRnVuY3Rpb25zW2ldLCAyKTtcbiAgICB9XG4gICAgZm9ybWF0VG9rZW5GdW5jdGlvbnMuRERERCA9IHBhZFRva2VuKGZvcm1hdFRva2VuRnVuY3Rpb25zLkRERCwgMyk7XG5cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgQ29uc3RydWN0b3JzXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4gICAgZnVuY3Rpb24gTG9jYWxlKCkge1xuICAgIH1cblxuICAgIC8vIE1vbWVudCBwcm90b3R5cGUgb2JqZWN0XG4gICAgZnVuY3Rpb24gTW9tZW50KGNvbmZpZywgc2tpcE92ZXJmbG93KSB7XG4gICAgICAgIGlmIChza2lwT3ZlcmZsb3cgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICBjaGVja092ZXJmbG93KGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgY29weUNvbmZpZyh0aGlzLCBjb25maWcpO1xuICAgICAgICB0aGlzLl9kID0gbmV3IERhdGUoK2NvbmZpZy5fZCk7XG4gICAgfVxuXG4gICAgLy8gRHVyYXRpb24gQ29uc3RydWN0b3JcbiAgICBmdW5jdGlvbiBEdXJhdGlvbihkdXJhdGlvbikge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0ID0gbm9ybWFsaXplT2JqZWN0VW5pdHMoZHVyYXRpb24pLFxuICAgICAgICAgICAgeWVhcnMgPSBub3JtYWxpemVkSW5wdXQueWVhciB8fCAwLFxuICAgICAgICAgICAgcXVhcnRlcnMgPSBub3JtYWxpemVkSW5wdXQucXVhcnRlciB8fCAwLFxuICAgICAgICAgICAgbW9udGhzID0gbm9ybWFsaXplZElucHV0Lm1vbnRoIHx8IDAsXG4gICAgICAgICAgICB3ZWVrcyA9IG5vcm1hbGl6ZWRJbnB1dC53ZWVrIHx8IDAsXG4gICAgICAgICAgICBkYXlzID0gbm9ybWFsaXplZElucHV0LmRheSB8fCAwLFxuICAgICAgICAgICAgaG91cnMgPSBub3JtYWxpemVkSW5wdXQuaG91ciB8fCAwLFxuICAgICAgICAgICAgbWludXRlcyA9IG5vcm1hbGl6ZWRJbnB1dC5taW51dGUgfHwgMCxcbiAgICAgICAgICAgIHNlY29uZHMgPSBub3JtYWxpemVkSW5wdXQuc2Vjb25kIHx8IDAsXG4gICAgICAgICAgICBtaWxsaXNlY29uZHMgPSBub3JtYWxpemVkSW5wdXQubWlsbGlzZWNvbmQgfHwgMDtcblxuICAgICAgICAvLyByZXByZXNlbnRhdGlvbiBmb3IgZGF0ZUFkZFJlbW92ZVxuICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgPSArbWlsbGlzZWNvbmRzICtcbiAgICAgICAgICAgIHNlY29uZHMgKiAxZTMgKyAvLyAxMDAwXG4gICAgICAgICAgICBtaW51dGVzICogNmU0ICsgLy8gMTAwMCAqIDYwXG4gICAgICAgICAgICBob3VycyAqIDM2ZTU7IC8vIDEwMDAgKiA2MCAqIDYwXG4gICAgICAgIC8vIEJlY2F1c2Ugb2YgZGF0ZUFkZFJlbW92ZSB0cmVhdHMgMjQgaG91cnMgYXMgZGlmZmVyZW50IGZyb20gYVxuICAgICAgICAvLyBkYXkgd2hlbiB3b3JraW5nIGFyb3VuZCBEU1QsIHdlIG5lZWQgdG8gc3RvcmUgdGhlbSBzZXBhcmF0ZWx5XG4gICAgICAgIHRoaXMuX2RheXMgPSArZGF5cyArXG4gICAgICAgICAgICB3ZWVrcyAqIDc7XG4gICAgICAgIC8vIEl0IGlzIGltcG9zc2libGUgdHJhbnNsYXRlIG1vbnRocyBpbnRvIGRheXMgd2l0aG91dCBrbm93aW5nXG4gICAgICAgIC8vIHdoaWNoIG1vbnRocyB5b3UgYXJlIGFyZSB0YWxraW5nIGFib3V0LCBzbyB3ZSBoYXZlIHRvIHN0b3JlXG4gICAgICAgIC8vIGl0IHNlcGFyYXRlbHkuXG4gICAgICAgIHRoaXMuX21vbnRocyA9ICttb250aHMgK1xuICAgICAgICAgICAgcXVhcnRlcnMgKiAzICtcbiAgICAgICAgICAgIHllYXJzICogMTI7XG5cbiAgICAgICAgdGhpcy5fZGF0YSA9IHt9O1xuXG4gICAgICAgIHRoaXMuX2xvY2FsZSA9IG1vbWVudC5sb2NhbGVEYXRhKCk7XG5cbiAgICAgICAgdGhpcy5fYnViYmxlKCk7XG4gICAgfVxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBIZWxwZXJzXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICBmdW5jdGlvbiBleHRlbmQoYSwgYikge1xuICAgICAgICBmb3IgKHZhciBpIGluIGIpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wKGIsIGkpKSB7XG4gICAgICAgICAgICAgICAgYVtpXSA9IGJbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzT3duUHJvcChiLCAndG9TdHJpbmcnKSkge1xuICAgICAgICAgICAgYS50b1N0cmluZyA9IGIudG9TdHJpbmc7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzT3duUHJvcChiLCAndmFsdWVPZicpKSB7XG4gICAgICAgICAgICBhLnZhbHVlT2YgPSBiLnZhbHVlT2Y7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb3B5Q29uZmlnKHRvLCBmcm9tKSB7XG4gICAgICAgIHZhciBpLCBwcm9wLCB2YWw7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9pc0FNb21lbnRPYmplY3QgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5faXNBTW9tZW50T2JqZWN0ID0gZnJvbS5faXNBTW9tZW50T2JqZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5faSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl9pID0gZnJvbS5faTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX2YgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fZiA9IGZyb20uX2Y7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9sICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX2wgPSBmcm9tLl9sO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5fc3RyaWN0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX3N0cmljdCA9IGZyb20uX3N0cmljdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX3R6bSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl90em0gPSBmcm9tLl90em07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9pc1VUQyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRvLl9pc1VUQyA9IGZyb20uX2lzVVRDO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZnJvbS5fb2Zmc2V0ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX29mZnNldCA9IGZyb20uX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGZyb20uX3BmICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdG8uX3BmID0gZnJvbS5fcGY7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBmcm9tLl9sb2NhbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0by5fbG9jYWxlID0gZnJvbS5fbG9jYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1vbWVudFByb3BlcnRpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZm9yIChpIGluIG1vbWVudFByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgICAgICBwcm9wID0gbW9tZW50UHJvcGVydGllc1tpXTtcbiAgICAgICAgICAgICAgICB2YWwgPSBmcm9tW3Byb3BdO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgICAgICB0b1twcm9wXSA9IHZhbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdG87XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWJzUm91bmQobnVtYmVyKSB7XG4gICAgICAgIGlmIChudW1iZXIgPCAwKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKG51bWJlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihudW1iZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gbGVmdCB6ZXJvIGZpbGwgYSBudW1iZXJcbiAgICAvLyBzZWUgaHR0cDovL2pzcGVyZi5jb20vbGVmdC16ZXJvLWZpbGxpbmcgZm9yIHBlcmZvcm1hbmNlIGNvbXBhcmlzb25cbiAgICBmdW5jdGlvbiBsZWZ0WmVyb0ZpbGwobnVtYmVyLCB0YXJnZXRMZW5ndGgsIGZvcmNlU2lnbikge1xuICAgICAgICB2YXIgb3V0cHV0ID0gJycgKyBNYXRoLmFicyhudW1iZXIpLFxuICAgICAgICAgICAgc2lnbiA9IG51bWJlciA+PSAwO1xuXG4gICAgICAgIHdoaWxlIChvdXRwdXQubGVuZ3RoIDwgdGFyZ2V0TGVuZ3RoKSB7XG4gICAgICAgICAgICBvdXRwdXQgPSAnMCcgKyBvdXRwdXQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChzaWduID8gKGZvcmNlU2lnbiA/ICcrJyA6ICcnKSA6ICctJykgKyBvdXRwdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9zaXRpdmVNb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzID0ge21pbGxpc2Vjb25kczogMCwgbW9udGhzOiAwfTtcblxuICAgICAgICByZXMubW9udGhzID0gb3RoZXIubW9udGgoKSAtIGJhc2UubW9udGgoKSArXG4gICAgICAgICAgICAob3RoZXIueWVhcigpIC0gYmFzZS55ZWFyKCkpICogMTI7XG4gICAgICAgIGlmIChiYXNlLmNsb25lKCkuYWRkKHJlcy5tb250aHMsICdNJykuaXNBZnRlcihvdGhlcikpIHtcbiAgICAgICAgICAgIC0tcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSArb3RoZXIgLSArKGJhc2UuY2xvbmUoKS5hZGQocmVzLm1vbnRocywgJ00nKSk7XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcikge1xuICAgICAgICB2YXIgcmVzO1xuICAgICAgICBvdGhlciA9IG1ha2VBcyhvdGhlciwgYmFzZSk7XG4gICAgICAgIGlmIChiYXNlLmlzQmVmb3JlKG90aGVyKSkge1xuICAgICAgICAgICAgcmVzID0gcG9zaXRpdmVNb21lbnRzRGlmZmVyZW5jZShiYXNlLCBvdGhlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMgPSBwb3NpdGl2ZU1vbWVudHNEaWZmZXJlbmNlKG90aGVyLCBiYXNlKTtcbiAgICAgICAgICAgIHJlcy5taWxsaXNlY29uZHMgPSAtcmVzLm1pbGxpc2Vjb25kcztcbiAgICAgICAgICAgIHJlcy5tb250aHMgPSAtcmVzLm1vbnRocztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogcmVtb3ZlICduYW1lJyBhcmcgYWZ0ZXIgZGVwcmVjYXRpb24gaXMgcmVtb3ZlZFxuICAgIGZ1bmN0aW9uIGNyZWF0ZUFkZGVyKGRpcmVjdGlvbiwgbmFtZSkge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKHZhbCwgcGVyaW9kKSB7XG4gICAgICAgICAgICB2YXIgZHVyLCB0bXA7XG4gICAgICAgICAgICAvL2ludmVydCB0aGUgYXJndW1lbnRzLCBidXQgY29tcGxhaW4gYWJvdXQgaXRcbiAgICAgICAgICAgIGlmIChwZXJpb2QgIT09IG51bGwgJiYgIWlzTmFOKCtwZXJpb2QpKSB7XG4gICAgICAgICAgICAgICAgZGVwcmVjYXRlU2ltcGxlKG5hbWUsICdtb21lbnQoKS4nICsgbmFtZSAgKyAnKHBlcmlvZCwgbnVtYmVyKSBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIG1vbWVudCgpLicgKyBuYW1lICsgJyhudW1iZXIsIHBlcmlvZCkuJyk7XG4gICAgICAgICAgICAgICAgdG1wID0gdmFsOyB2YWwgPSBwZXJpb2Q7IHBlcmlvZCA9IHRtcDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFsID0gdHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgPyArdmFsIDogdmFsO1xuICAgICAgICAgICAgZHVyID0gbW9tZW50LmR1cmF0aW9uKHZhbCwgcGVyaW9kKTtcbiAgICAgICAgICAgIGFkZE9yU3VidHJhY3REdXJhdGlvbkZyb21Nb21lbnQodGhpcywgZHVyLCBkaXJlY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYWRkT3JTdWJ0cmFjdER1cmF0aW9uRnJvbU1vbWVudChtb20sIGR1cmF0aW9uLCBpc0FkZGluZywgdXBkYXRlT2Zmc2V0KSB7XG4gICAgICAgIHZhciBtaWxsaXNlY29uZHMgPSBkdXJhdGlvbi5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgZGF5cyA9IGR1cmF0aW9uLl9kYXlzLFxuICAgICAgICAgICAgbW9udGhzID0gZHVyYXRpb24uX21vbnRocztcbiAgICAgICAgdXBkYXRlT2Zmc2V0ID0gdXBkYXRlT2Zmc2V0ID09IG51bGwgPyB0cnVlIDogdXBkYXRlT2Zmc2V0O1xuXG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMpIHtcbiAgICAgICAgICAgIG1vbS5fZC5zZXRUaW1lKCttb20uX2QgKyBtaWxsaXNlY29uZHMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRheXMpIHtcbiAgICAgICAgICAgIHJhd1NldHRlcihtb20sICdEYXRlJywgcmF3R2V0dGVyKG1vbSwgJ0RhdGUnKSArIGRheXMgKiBpc0FkZGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1vbnRocykge1xuICAgICAgICAgICAgcmF3TW9udGhTZXR0ZXIobW9tLCByYXdHZXR0ZXIobW9tLCAnTW9udGgnKSArIG1vbnRocyAqIGlzQWRkaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodXBkYXRlT2Zmc2V0KSB7XG4gICAgICAgICAgICBtb21lbnQudXBkYXRlT2Zmc2V0KG1vbSwgZGF5cyB8fCBtb250aHMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2hlY2sgaWYgaXMgYW4gYXJyYXlcbiAgICBmdW5jdGlvbiBpc0FycmF5KGlucHV0KSB7XG4gICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaW5wdXQpID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzRGF0ZShpbnB1dCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGlucHV0KSA9PT0gJ1tvYmplY3QgRGF0ZV0nIHx8XG4gICAgICAgICAgICBpbnB1dCBpbnN0YW5jZW9mIERhdGU7XG4gICAgfVxuXG4gICAgLy8gY29tcGFyZSB0d28gYXJyYXlzLCByZXR1cm4gdGhlIG51bWJlciBvZiBkaWZmZXJlbmNlc1xuICAgIGZ1bmN0aW9uIGNvbXBhcmVBcnJheXMoYXJyYXkxLCBhcnJheTIsIGRvbnRDb252ZXJ0KSB7XG4gICAgICAgIHZhciBsZW4gPSBNYXRoLm1pbihhcnJheTEubGVuZ3RoLCBhcnJheTIubGVuZ3RoKSxcbiAgICAgICAgICAgIGxlbmd0aERpZmYgPSBNYXRoLmFicyhhcnJheTEubGVuZ3RoIC0gYXJyYXkyLmxlbmd0aCksXG4gICAgICAgICAgICBkaWZmcyA9IDAsXG4gICAgICAgICAgICBpO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICgoZG9udENvbnZlcnQgJiYgYXJyYXkxW2ldICE9PSBhcnJheTJbaV0pIHx8XG4gICAgICAgICAgICAgICAgKCFkb250Q29udmVydCAmJiB0b0ludChhcnJheTFbaV0pICE9PSB0b0ludChhcnJheTJbaV0pKSkge1xuICAgICAgICAgICAgICAgIGRpZmZzKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRpZmZzICsgbGVuZ3RoRGlmZjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBub3JtYWxpemVVbml0cyh1bml0cykge1xuICAgICAgICBpZiAodW5pdHMpIHtcbiAgICAgICAgICAgIHZhciBsb3dlcmVkID0gdW5pdHMudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC8oLilzJC8sICckMScpO1xuICAgICAgICAgICAgdW5pdHMgPSB1bml0QWxpYXNlc1t1bml0c10gfHwgY2FtZWxGdW5jdGlvbnNbbG93ZXJlZF0gfHwgbG93ZXJlZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5pdHM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbm9ybWFsaXplT2JqZWN0VW5pdHMoaW5wdXRPYmplY3QpIHtcbiAgICAgICAgdmFyIG5vcm1hbGl6ZWRJbnB1dCA9IHt9LFxuICAgICAgICAgICAgbm9ybWFsaXplZFByb3AsXG4gICAgICAgICAgICBwcm9wO1xuXG4gICAgICAgIGZvciAocHJvcCBpbiBpbnB1dE9iamVjdCkge1xuICAgICAgICAgICAgaWYgKGhhc093blByb3AoaW5wdXRPYmplY3QsIHByb3ApKSB7XG4gICAgICAgICAgICAgICAgbm9ybWFsaXplZFByb3AgPSBub3JtYWxpemVVbml0cyhwcm9wKTtcbiAgICAgICAgICAgICAgICBpZiAobm9ybWFsaXplZFByb3ApIHtcbiAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZElucHV0W25vcm1hbGl6ZWRQcm9wXSA9IGlucHV0T2JqZWN0W3Byb3BdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub3JtYWxpemVkSW5wdXQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZUxpc3QoZmllbGQpIHtcbiAgICAgICAgdmFyIGNvdW50LCBzZXR0ZXI7XG5cbiAgICAgICAgaWYgKGZpZWxkLmluZGV4T2YoJ3dlZWsnKSA9PT0gMCkge1xuICAgICAgICAgICAgY291bnQgPSA3O1xuICAgICAgICAgICAgc2V0dGVyID0gJ2RheSc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZmllbGQuaW5kZXhPZignbW9udGgnKSA9PT0gMCkge1xuICAgICAgICAgICAgY291bnQgPSAxMjtcbiAgICAgICAgICAgIHNldHRlciA9ICdtb250aCc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBtb21lbnRbZmllbGRdID0gZnVuY3Rpb24gKGZvcm1hdCwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBpLCBnZXR0ZXIsXG4gICAgICAgICAgICAgICAgbWV0aG9kID0gbW9tZW50Ll9sb2NhbGVbZmllbGRdLFxuICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmb3JtYXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmb3JtYXQ7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnZXR0ZXIgPSBmdW5jdGlvbiAoaSkge1xuICAgICAgICAgICAgICAgIHZhciBtID0gbW9tZW50KCkudXRjKCkuc2V0KHNldHRlciwgaSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1ldGhvZC5jYWxsKG1vbWVudC5fbG9jYWxlLCBtLCBmb3JtYXQgfHwgJycpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKGluZGV4ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0dGVyKGluZGV4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChnZXR0ZXIoaSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b0ludChhcmd1bWVudEZvckNvZXJjaW9uKSB7XG4gICAgICAgIHZhciBjb2VyY2VkTnVtYmVyID0gK2FyZ3VtZW50Rm9yQ29lcmNpb24sXG4gICAgICAgICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgICAgaWYgKGNvZXJjZWROdW1iZXIgIT09IDAgJiYgaXNGaW5pdGUoY29lcmNlZE51bWJlcikpIHtcbiAgICAgICAgICAgIGlmIChjb2VyY2VkTnVtYmVyID49IDApIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IE1hdGguZmxvb3IoY29lcmNlZE51bWJlcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gTWF0aC5jZWlsKGNvZXJjZWROdW1iZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRheXNJbk1vbnRoKHllYXIsIG1vbnRoKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyh5ZWFyLCBtb250aCArIDEsIDApKS5nZXRVVENEYXRlKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Vla3NJblllYXIoeWVhciwgZG93LCBkb3kpIHtcbiAgICAgICAgcmV0dXJuIHdlZWtPZlllYXIobW9tZW50KFt5ZWFyLCAxMSwgMzEgKyBkb3cgLSBkb3ldKSwgZG93LCBkb3kpLndlZWs7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZGF5c0luWWVhcih5ZWFyKSB7XG4gICAgICAgIHJldHVybiBpc0xlYXBZZWFyKHllYXIpID8gMzY2IDogMzY1O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzTGVhcFllYXIoeWVhcikge1xuICAgICAgICByZXR1cm4gKHllYXIgJSA0ID09PSAwICYmIHllYXIgJSAxMDAgIT09IDApIHx8IHllYXIgJSA0MDAgPT09IDA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2tPdmVyZmxvdyhtKSB7XG4gICAgICAgIHZhciBvdmVyZmxvdztcbiAgICAgICAgaWYgKG0uX2EgJiYgbS5fcGYub3ZlcmZsb3cgPT09IC0yKSB7XG4gICAgICAgICAgICBvdmVyZmxvdyA9XG4gICAgICAgICAgICAgICAgbS5fYVtNT05USF0gPCAwIHx8IG0uX2FbTU9OVEhdID4gMTEgPyBNT05USCA6XG4gICAgICAgICAgICAgICAgbS5fYVtEQVRFXSA8IDEgfHwgbS5fYVtEQVRFXSA+IGRheXNJbk1vbnRoKG0uX2FbWUVBUl0sIG0uX2FbTU9OVEhdKSA/IERBVEUgOlxuICAgICAgICAgICAgICAgIG0uX2FbSE9VUl0gPCAwIHx8IG0uX2FbSE9VUl0gPiAyNCB8fFxuICAgICAgICAgICAgICAgICAgICAobS5fYVtIT1VSXSA9PT0gMjQgJiYgKG0uX2FbTUlOVVRFXSAhPT0gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uX2FbU0VDT05EXSAhPT0gMCB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0uX2FbTUlMTElTRUNPTkRdICE9PSAwKSkgPyBIT1VSIDpcbiAgICAgICAgICAgICAgICBtLl9hW01JTlVURV0gPCAwIHx8IG0uX2FbTUlOVVRFXSA+IDU5ID8gTUlOVVRFIDpcbiAgICAgICAgICAgICAgICBtLl9hW1NFQ09ORF0gPCAwIHx8IG0uX2FbU0VDT05EXSA+IDU5ID8gU0VDT05EIDpcbiAgICAgICAgICAgICAgICBtLl9hW01JTExJU0VDT05EXSA8IDAgfHwgbS5fYVtNSUxMSVNFQ09ORF0gPiA5OTkgPyBNSUxMSVNFQ09ORCA6XG4gICAgICAgICAgICAgICAgLTE7XG5cbiAgICAgICAgICAgIGlmIChtLl9wZi5fb3ZlcmZsb3dEYXlPZlllYXIgJiYgKG92ZXJmbG93IDwgWUVBUiB8fCBvdmVyZmxvdyA+IERBVEUpKSB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3cgPSBEQVRFO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtLl9wZi5vdmVyZmxvdyA9IG92ZXJmbG93O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXNWYWxpZChtKSB7XG4gICAgICAgIGlmIChtLl9pc1ZhbGlkID09IG51bGwpIHtcbiAgICAgICAgICAgIG0uX2lzVmFsaWQgPSAhaXNOYU4obS5fZC5nZXRUaW1lKCkpICYmXG4gICAgICAgICAgICAgICAgbS5fcGYub3ZlcmZsb3cgPCAwICYmXG4gICAgICAgICAgICAgICAgIW0uX3BmLmVtcHR5ICYmXG4gICAgICAgICAgICAgICAgIW0uX3BmLmludmFsaWRNb250aCAmJlxuICAgICAgICAgICAgICAgICFtLl9wZi5udWxsSW5wdXQgJiZcbiAgICAgICAgICAgICAgICAhbS5fcGYuaW52YWxpZEZvcm1hdCAmJlxuICAgICAgICAgICAgICAgICFtLl9wZi51c2VySW52YWxpZGF0ZWQ7XG5cbiAgICAgICAgICAgIGlmIChtLl9zdHJpY3QpIHtcbiAgICAgICAgICAgICAgICBtLl9pc1ZhbGlkID0gbS5faXNWYWxpZCAmJlxuICAgICAgICAgICAgICAgICAgICBtLl9wZi5jaGFyc0xlZnRPdmVyID09PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIG0uX3BmLnVudXNlZFRva2Vucy5sZW5ndGggPT09IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgbS5fcGYuYmlnSG91ciA9PT0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtLl9pc1ZhbGlkO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG5vcm1hbGl6ZUxvY2FsZShrZXkpIHtcbiAgICAgICAgcmV0dXJuIGtleSA/IGtleS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoJ18nLCAnLScpIDoga2V5O1xuICAgIH1cblxuICAgIC8vIHBpY2sgdGhlIGxvY2FsZSBmcm9tIHRoZSBhcnJheVxuICAgIC8vIHRyeSBbJ2VuLWF1JywgJ2VuLWdiJ10gYXMgJ2VuLWF1JywgJ2VuLWdiJywgJ2VuJywgYXMgaW4gbW92ZSB0aHJvdWdoIHRoZSBsaXN0IHRyeWluZyBlYWNoXG4gICAgLy8gc3Vic3RyaW5nIGZyb20gbW9zdCBzcGVjaWZpYyB0byBsZWFzdCwgYnV0IG1vdmUgdG8gdGhlIG5leHQgYXJyYXkgaXRlbSBpZiBpdCdzIGEgbW9yZSBzcGVjaWZpYyB2YXJpYW50IHRoYW4gdGhlIGN1cnJlbnQgcm9vdFxuICAgIGZ1bmN0aW9uIGNob29zZUxvY2FsZShuYW1lcykge1xuICAgICAgICB2YXIgaSA9IDAsIGosIG5leHQsIGxvY2FsZSwgc3BsaXQ7XG5cbiAgICAgICAgd2hpbGUgKGkgPCBuYW1lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHNwbGl0ID0gbm9ybWFsaXplTG9jYWxlKG5hbWVzW2ldKS5zcGxpdCgnLScpO1xuICAgICAgICAgICAgaiA9IHNwbGl0Lmxlbmd0aDtcbiAgICAgICAgICAgIG5leHQgPSBub3JtYWxpemVMb2NhbGUobmFtZXNbaSArIDFdKTtcbiAgICAgICAgICAgIG5leHQgPSBuZXh0ID8gbmV4dC5zcGxpdCgnLScpIDogbnVsbDtcbiAgICAgICAgICAgIHdoaWxlIChqID4gMCkge1xuICAgICAgICAgICAgICAgIGxvY2FsZSA9IGxvYWRMb2NhbGUoc3BsaXQuc2xpY2UoMCwgaikuam9pbignLScpKTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChuZXh0ICYmIG5leHQubGVuZ3RoID49IGogJiYgY29tcGFyZUFycmF5cyhzcGxpdCwgbmV4dCwgdHJ1ZSkgPj0gaiAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgLy90aGUgbmV4dCBhcnJheSBpdGVtIGlzIGJldHRlciB0aGFuIGEgc2hhbGxvd2VyIHN1YnN0cmluZyBvZiB0aGlzIG9uZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgai0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxvYWRMb2NhbGUobmFtZSkge1xuICAgICAgICB2YXIgb2xkTG9jYWxlID0gbnVsbDtcbiAgICAgICAgaWYgKCFsb2NhbGVzW25hbWVdICYmIGhhc01vZHVsZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBvbGRMb2NhbGUgPSBtb21lbnQubG9jYWxlKCk7XG4gICAgICAgICAgICAgICAgcmVxdWlyZSgnLi9sb2NhbGUvJyArIG5hbWUpO1xuICAgICAgICAgICAgICAgIC8vIGJlY2F1c2UgZGVmaW5lTG9jYWxlIGN1cnJlbnRseSBhbHNvIHNldHMgdGhlIGdsb2JhbCBsb2NhbGUsIHdlIHdhbnQgdG8gdW5kbyB0aGF0IGZvciBsYXp5IGxvYWRlZCBsb2NhbGVzXG4gICAgICAgICAgICAgICAgbW9tZW50LmxvY2FsZShvbGRMb2NhbGUpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGEgbW9tZW50IGZyb20gaW5wdXQsIHRoYXQgaXMgbG9jYWwvdXRjL3pvbmUgZXF1aXZhbGVudCB0byBtb2RlbC5cbiAgICBmdW5jdGlvbiBtYWtlQXMoaW5wdXQsIG1vZGVsKSB7XG4gICAgICAgIHZhciByZXMsIGRpZmY7XG4gICAgICAgIGlmIChtb2RlbC5faXNVVEMpIHtcbiAgICAgICAgICAgIHJlcyA9IG1vZGVsLmNsb25lKCk7XG4gICAgICAgICAgICBkaWZmID0gKG1vbWVudC5pc01vbWVudChpbnB1dCkgfHwgaXNEYXRlKGlucHV0KSA/XG4gICAgICAgICAgICAgICAgICAgICtpbnB1dCA6ICttb21lbnQoaW5wdXQpKSAtICgrcmVzKTtcbiAgICAgICAgICAgIC8vIFVzZSBsb3ctbGV2ZWwgYXBpLCBiZWNhdXNlIHRoaXMgZm4gaXMgbG93LWxldmVsIGFwaS5cbiAgICAgICAgICAgIHJlcy5fZC5zZXRUaW1lKCtyZXMuX2QgKyBkaWZmKTtcbiAgICAgICAgICAgIG1vbWVudC51cGRhdGVPZmZzZXQocmVzLCBmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudChpbnB1dCkubG9jYWwoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgTG9jYWxlXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICBleHRlbmQoTG9jYWxlLnByb3RvdHlwZSwge1xuXG4gICAgICAgIHNldCA6IGZ1bmN0aW9uIChjb25maWcpIHtcbiAgICAgICAgICAgIHZhciBwcm9wLCBpO1xuICAgICAgICAgICAgZm9yIChpIGluIGNvbmZpZykge1xuICAgICAgICAgICAgICAgIHByb3AgPSBjb25maWdbaV07XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbaV0gPSBwcm9wO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbJ18nICsgaV0gPSBwcm9wO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIExlbmllbnQgb3JkaW5hbCBwYXJzaW5nIGFjY2VwdHMganVzdCBhIG51bWJlciBpbiBhZGRpdGlvbiB0b1xuICAgICAgICAgICAgLy8gbnVtYmVyICsgKHBvc3NpYmx5KSBzdHVmZiBjb21pbmcgZnJvbSBfb3JkaW5hbFBhcnNlTGVuaWVudC5cbiAgICAgICAgICAgIHRoaXMuX29yZGluYWxQYXJzZUxlbmllbnQgPSBuZXcgUmVnRXhwKHRoaXMuX29yZGluYWxQYXJzZS5zb3VyY2UgKyAnfCcgKyAvXFxkezEsMn0vLnNvdXJjZSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgX21vbnRocyA6ICdKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyJy5zcGxpdCgnXycpLFxuICAgICAgICBtb250aHMgOiBmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vbnRoc1ttLm1vbnRoKCldO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9tb250aHNTaG9ydCA6ICdKYW5fRmViX01hcl9BcHJfTWF5X0p1bl9KdWxfQXVnX1NlcF9PY3RfTm92X0RlYycuc3BsaXQoJ18nKSxcbiAgICAgICAgbW9udGhzU2hvcnQgOiBmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21vbnRoc1Nob3J0W20ubW9udGgoKV07XG4gICAgICAgIH0sXG5cbiAgICAgICAgbW9udGhzUGFyc2UgOiBmdW5jdGlvbiAobW9udGhOYW1lLCBmb3JtYXQsIHN0cmljdCkge1xuICAgICAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5fbW9udGhzUGFyc2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZSA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Nob3J0TW9udGhzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDEyOyBpKyspIHtcbiAgICAgICAgICAgICAgICAvLyBtYWtlIHRoZSByZWdleCBpZiB3ZSBkb24ndCBoYXZlIGl0IGFscmVhZHlcbiAgICAgICAgICAgICAgICBtb20gPSBtb21lbnQudXRjKFsyMDAwLCBpXSk7XG4gICAgICAgICAgICAgICAgaWYgKHN0cmljdCAmJiAhdGhpcy5fbG9uZ01vbnRoc1BhcnNlW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvbmdNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHMobW9tLCAnJykucmVwbGFjZSgnLicsICcnKSArICckJywgJ2knKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc2hvcnRNb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAoJ14nICsgdGhpcy5tb250aHNTaG9ydChtb20sICcnKS5yZXBsYWNlKCcuJywgJycpICsgJyQnLCAnaScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXN0cmljdCAmJiAhdGhpcy5fbW9udGhzUGFyc2VbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVnZXggPSAnXicgKyB0aGlzLm1vbnRocyhtb20sICcnKSArICd8XicgKyB0aGlzLm1vbnRoc1Nob3J0KG1vbSwgJycpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9tb250aHNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgICAgICBpZiAoc3RyaWN0ICYmIGZvcm1hdCA9PT0gJ01NTU0nICYmIHRoaXMuX2xvbmdNb250aHNQYXJzZVtpXS50ZXN0KG1vbnRoTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzdHJpY3QgJiYgZm9ybWF0ID09PSAnTU1NJyAmJiB0aGlzLl9zaG9ydE1vbnRoc1BhcnNlW2ldLnRlc3QobW9udGhOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFzdHJpY3QgJiYgdGhpcy5fbW9udGhzUGFyc2VbaV0udGVzdChtb250aE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBfd2Vla2RheXMgOiAnU3VuZGF5X01vbmRheV9UdWVzZGF5X1dlZG5lc2RheV9UaHVyc2RheV9GcmlkYXlfU2F0dXJkYXknLnNwbGl0KCdfJyksXG4gICAgICAgIHdlZWtkYXlzIDogZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl93ZWVrZGF5c1ttLmRheSgpXTtcbiAgICAgICAgfSxcblxuICAgICAgICBfd2Vla2RheXNTaG9ydCA6ICdTdW5fTW9uX1R1ZV9XZWRfVGh1X0ZyaV9TYXQnLnNwbGl0KCdfJyksXG4gICAgICAgIHdlZWtkYXlzU2hvcnQgOiBmdW5jdGlvbiAobSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3dlZWtkYXlzU2hvcnRbbS5kYXkoKV07XG4gICAgICAgIH0sXG5cbiAgICAgICAgX3dlZWtkYXlzTWluIDogJ1N1X01vX1R1X1dlX1RoX0ZyX1NhJy5zcGxpdCgnXycpLFxuICAgICAgICB3ZWVrZGF5c01pbiA6IGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fd2Vla2RheXNNaW5bbS5kYXkoKV07XG4gICAgICAgIH0sXG5cbiAgICAgICAgd2Vla2RheXNQYXJzZSA6IGZ1bmN0aW9uICh3ZWVrZGF5TmFtZSkge1xuICAgICAgICAgICAgdmFyIGksIG1vbSwgcmVnZXg7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5fd2Vla2RheXNQYXJzZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dlZWtkYXlzUGFyc2UgPSBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgICAgIC8vIG1ha2UgdGhlIHJlZ2V4IGlmIHdlIGRvbid0IGhhdmUgaXQgYWxyZWFkeVxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fd2Vla2RheXNQYXJzZVtpXSkge1xuICAgICAgICAgICAgICAgICAgICBtb20gPSBtb21lbnQoWzIwMDAsIDFdKS5kYXkoaSk7XG4gICAgICAgICAgICAgICAgICAgIHJlZ2V4ID0gJ14nICsgdGhpcy53ZWVrZGF5cyhtb20sICcnKSArICd8XicgKyB0aGlzLndlZWtkYXlzU2hvcnQobW9tLCAnJykgKyAnfF4nICsgdGhpcy53ZWVrZGF5c01pbihtb20sICcnKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2Vla2RheXNQYXJzZVtpXSA9IG5ldyBSZWdFeHAocmVnZXgucmVwbGFjZSgnLicsICcnKSwgJ2knKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gdGVzdCB0aGUgcmVnZXhcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fd2Vla2RheXNQYXJzZVtpXS50ZXN0KHdlZWtkYXlOYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgX2xvbmdEYXRlRm9ybWF0IDoge1xuICAgICAgICAgICAgTFRTIDogJ2g6bW06c3MgQScsXG4gICAgICAgICAgICBMVCA6ICdoOm1tIEEnLFxuICAgICAgICAgICAgTCA6ICdNTS9ERC9ZWVlZJyxcbiAgICAgICAgICAgIExMIDogJ01NTU0gRCwgWVlZWScsXG4gICAgICAgICAgICBMTEwgOiAnTU1NTSBELCBZWVlZIExUJyxcbiAgICAgICAgICAgIExMTEwgOiAnZGRkZCwgTU1NTSBELCBZWVlZIExUJ1xuICAgICAgICB9LFxuICAgICAgICBsb25nRGF0ZUZvcm1hdCA6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHZhciBvdXRwdXQgPSB0aGlzLl9sb25nRGF0ZUZvcm1hdFtrZXldO1xuICAgICAgICAgICAgaWYgKCFvdXRwdXQgJiYgdGhpcy5fbG9uZ0RhdGVGb3JtYXRba2V5LnRvVXBwZXJDYXNlKCldKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0ID0gdGhpcy5fbG9uZ0RhdGVGb3JtYXRba2V5LnRvVXBwZXJDYXNlKCldLnJlcGxhY2UoL01NTU18TU18RER8ZGRkZC9nLCBmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWwuc2xpY2UoMSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbG9uZ0RhdGVGb3JtYXRba2V5XSA9IG91dHB1dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNQTSA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgLy8gSUU4IFF1aXJrcyBNb2RlICYgSUU3IFN0YW5kYXJkcyBNb2RlIGRvIG5vdCBhbGxvdyBhY2Nlc3Npbmcgc3RyaW5ncyBsaWtlIGFycmF5c1xuICAgICAgICAgICAgLy8gVXNpbmcgY2hhckF0IHNob3VsZCBiZSBtb3JlIGNvbXBhdGlibGUuXG4gICAgICAgICAgICByZXR1cm4gKChpbnB1dCArICcnKS50b0xvd2VyQ2FzZSgpLmNoYXJBdCgwKSA9PT0gJ3AnKTtcbiAgICAgICAgfSxcblxuICAgICAgICBfbWVyaWRpZW1QYXJzZSA6IC9bYXBdXFwuP20/XFwuPy9pLFxuICAgICAgICBtZXJpZGllbSA6IGZ1bmN0aW9uIChob3VycywgbWludXRlcywgaXNMb3dlcikge1xuICAgICAgICAgICAgaWYgKGhvdXJzID4gMTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNMb3dlciA/ICdwbScgOiAnUE0nO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaXNMb3dlciA/ICdhbScgOiAnQU0nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIF9jYWxlbmRhciA6IHtcbiAgICAgICAgICAgIHNhbWVEYXkgOiAnW1RvZGF5IGF0XSBMVCcsXG4gICAgICAgICAgICBuZXh0RGF5IDogJ1tUb21vcnJvdyBhdF0gTFQnLFxuICAgICAgICAgICAgbmV4dFdlZWsgOiAnZGRkZCBbYXRdIExUJyxcbiAgICAgICAgICAgIGxhc3REYXkgOiAnW1llc3RlcmRheSBhdF0gTFQnLFxuICAgICAgICAgICAgbGFzdFdlZWsgOiAnW0xhc3RdIGRkZGQgW2F0XSBMVCcsXG4gICAgICAgICAgICBzYW1lRWxzZSA6ICdMJ1xuICAgICAgICB9LFxuICAgICAgICBjYWxlbmRhciA6IGZ1bmN0aW9uIChrZXksIG1vbSwgbm93KSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gdGhpcy5fY2FsZW5kYXJba2V5XTtcbiAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygb3V0cHV0ID09PSAnZnVuY3Rpb24nID8gb3V0cHV0LmFwcGx5KG1vbSwgW25vd10pIDogb3V0cHV0O1xuICAgICAgICB9LFxuXG4gICAgICAgIF9yZWxhdGl2ZVRpbWUgOiB7XG4gICAgICAgICAgICBmdXR1cmUgOiAnaW4gJXMnLFxuICAgICAgICAgICAgcGFzdCA6ICclcyBhZ28nLFxuICAgICAgICAgICAgcyA6ICdhIGZldyBzZWNvbmRzJyxcbiAgICAgICAgICAgIG0gOiAnYSBtaW51dGUnLFxuICAgICAgICAgICAgbW0gOiAnJWQgbWludXRlcycsXG4gICAgICAgICAgICBoIDogJ2FuIGhvdXInLFxuICAgICAgICAgICAgaGggOiAnJWQgaG91cnMnLFxuICAgICAgICAgICAgZCA6ICdhIGRheScsXG4gICAgICAgICAgICBkZCA6ICclZCBkYXlzJyxcbiAgICAgICAgICAgIE0gOiAnYSBtb250aCcsXG4gICAgICAgICAgICBNTSA6ICclZCBtb250aHMnLFxuICAgICAgICAgICAgeSA6ICdhIHllYXInLFxuICAgICAgICAgICAgeXkgOiAnJWQgeWVhcnMnXG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVsYXRpdmVUaW1lIDogZnVuY3Rpb24gKG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dCA9IHRoaXMuX3JlbGF0aXZlVGltZVtzdHJpbmddO1xuICAgICAgICAgICAgcmV0dXJuICh0eXBlb2Ygb3V0cHV0ID09PSAnZnVuY3Rpb24nKSA/XG4gICAgICAgICAgICAgICAgb3V0cHV0KG51bWJlciwgd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSkgOlxuICAgICAgICAgICAgICAgIG91dHB1dC5yZXBsYWNlKC8lZC9pLCBudW1iZXIpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHBhc3RGdXR1cmUgOiBmdW5jdGlvbiAoZGlmZiwgb3V0cHV0KSB7XG4gICAgICAgICAgICB2YXIgZm9ybWF0ID0gdGhpcy5fcmVsYXRpdmVUaW1lW2RpZmYgPiAwID8gJ2Z1dHVyZScgOiAncGFzdCddO1xuICAgICAgICAgICAgcmV0dXJuIHR5cGVvZiBmb3JtYXQgPT09ICdmdW5jdGlvbicgPyBmb3JtYXQob3V0cHV0KSA6IGZvcm1hdC5yZXBsYWNlKC8lcy9pLCBvdXRwdXQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIG9yZGluYWwgOiBmdW5jdGlvbiAobnVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JkaW5hbC5yZXBsYWNlKCclZCcsIG51bWJlcik7XG4gICAgICAgIH0sXG4gICAgICAgIF9vcmRpbmFsIDogJyVkJyxcbiAgICAgICAgX29yZGluYWxQYXJzZSA6IC9cXGR7MSwyfS8sXG5cbiAgICAgICAgcHJlcGFyc2UgOiBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgICB9LFxuXG4gICAgICAgIHBvc3Rmb3JtYXQgOiBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RyaW5nO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdlZWsgOiBmdW5jdGlvbiAobW9tKSB7XG4gICAgICAgICAgICByZXR1cm4gd2Vla09mWWVhcihtb20sIHRoaXMuX3dlZWsuZG93LCB0aGlzLl93ZWVrLmRveSkud2VlaztcbiAgICAgICAgfSxcblxuICAgICAgICBfd2VlayA6IHtcbiAgICAgICAgICAgIGRvdyA6IDAsIC8vIFN1bmRheSBpcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLlxuICAgICAgICAgICAgZG95IDogNiAgLy8gVGhlIHdlZWsgdGhhdCBjb250YWlucyBKYW4gMXN0IGlzIHRoZSBmaXJzdCB3ZWVrIG9mIHRoZSB5ZWFyLlxuICAgICAgICB9LFxuXG4gICAgICAgIF9pbnZhbGlkRGF0ZTogJ0ludmFsaWQgZGF0ZScsXG4gICAgICAgIGludmFsaWREYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW52YWxpZERhdGU7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgRm9ybWF0dGluZ1xuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG4gICAgZnVuY3Rpb24gcmVtb3ZlRm9ybWF0dGluZ1Rva2VucyhpbnB1dCkge1xuICAgICAgICBpZiAoaW5wdXQubWF0Y2goL1xcW1tcXHNcXFNdLykpIHtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKC9eXFxbfFxcXSQvZywgJycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnB1dC5yZXBsYWNlKC9cXFxcL2csICcnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlRm9ybWF0RnVuY3Rpb24oZm9ybWF0KSB7XG4gICAgICAgIHZhciBhcnJheSA9IGZvcm1hdC5tYXRjaChmb3JtYXR0aW5nVG9rZW5zKSwgaSwgbGVuZ3RoO1xuXG4gICAgICAgIGZvciAoaSA9IDAsIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoZm9ybWF0VG9rZW5GdW5jdGlvbnNbYXJyYXlbaV1dKSB7XG4gICAgICAgICAgICAgICAgYXJyYXlbaV0gPSBmb3JtYXRUb2tlbkZ1bmN0aW9uc1thcnJheVtpXV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFycmF5W2ldID0gcmVtb3ZlRm9ybWF0dGluZ1Rva2VucyhhcnJheVtpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1vbSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dCA9ICcnO1xuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgb3V0cHV0ICs9IGFycmF5W2ldIGluc3RhbmNlb2YgRnVuY3Rpb24gPyBhcnJheVtpXS5jYWxsKG1vbSwgZm9ybWF0KSA6IGFycmF5W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQgZGF0ZSB1c2luZyBuYXRpdmUgZGF0ZSBvYmplY3RcbiAgICBmdW5jdGlvbiBmb3JtYXRNb21lbnQobSwgZm9ybWF0KSB7XG4gICAgICAgIGlmICghbS5pc1ZhbGlkKCkpIHtcbiAgICAgICAgICAgIHJldHVybiBtLmxvY2FsZURhdGEoKS5pbnZhbGlkRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9ybWF0ID0gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbS5sb2NhbGVEYXRhKCkpO1xuXG4gICAgICAgIGlmICghZm9ybWF0RnVuY3Rpb25zW2Zvcm1hdF0pIHtcbiAgICAgICAgICAgIGZvcm1hdEZ1bmN0aW9uc1tmb3JtYXRdID0gbWFrZUZvcm1hdEZ1bmN0aW9uKGZvcm1hdCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ybWF0RnVuY3Rpb25zW2Zvcm1hdF0obSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXhwYW5kRm9ybWF0KGZvcm1hdCwgbG9jYWxlKSB7XG4gICAgICAgIHZhciBpID0gNTtcblxuICAgICAgICBmdW5jdGlvbiByZXBsYWNlTG9uZ0RhdGVGb3JtYXRUb2tlbnMoaW5wdXQpIHtcbiAgICAgICAgICAgIHJldHVybiBsb2NhbGUubG9uZ0RhdGVGb3JtYXQoaW5wdXQpIHx8IGlucHV0O1xuICAgICAgICB9XG5cbiAgICAgICAgbG9jYWxGb3JtYXR0aW5nVG9rZW5zLmxhc3RJbmRleCA9IDA7XG4gICAgICAgIHdoaWxlIChpID49IDAgJiYgbG9jYWxGb3JtYXR0aW5nVG9rZW5zLnRlc3QoZm9ybWF0KSkge1xuICAgICAgICAgICAgZm9ybWF0ID0gZm9ybWF0LnJlcGxhY2UobG9jYWxGb3JtYXR0aW5nVG9rZW5zLCByZXBsYWNlTG9uZ0RhdGVGb3JtYXRUb2tlbnMpO1xuICAgICAgICAgICAgbG9jYWxGb3JtYXR0aW5nVG9rZW5zLmxhc3RJbmRleCA9IDA7XG4gICAgICAgICAgICBpIC09IDE7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ybWF0O1xuICAgIH1cblxuXG4gICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAgICAgICBQYXJzaW5nXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICAvLyBnZXQgdGhlIHJlZ2V4IHRvIGZpbmQgdGhlIG5leHQgdG9rZW5cbiAgICBmdW5jdGlvbiBnZXRQYXJzZVJlZ2V4Rm9yVG9rZW4odG9rZW4sIGNvbmZpZykge1xuICAgICAgICB2YXIgYSwgc3RyaWN0ID0gY29uZmlnLl9zdHJpY3Q7XG4gICAgICAgIHN3aXRjaCAodG9rZW4pIHtcbiAgICAgICAgY2FzZSAnUSc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbk9uZURpZ2l0O1xuICAgICAgICBjYXNlICdEREREJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuVGhyZWVEaWdpdHM7XG4gICAgICAgIGNhc2UgJ1lZWVknOlxuICAgICAgICBjYXNlICdHR0dHJzpcbiAgICAgICAgY2FzZSAnZ2dnZyc6XG4gICAgICAgICAgICByZXR1cm4gc3RyaWN0ID8gcGFyc2VUb2tlbkZvdXJEaWdpdHMgOiBwYXJzZVRva2VuT25lVG9Gb3VyRGlnaXRzO1xuICAgICAgICBjYXNlICdZJzpcbiAgICAgICAgY2FzZSAnRyc6XG4gICAgICAgIGNhc2UgJ2cnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5TaWduZWROdW1iZXI7XG4gICAgICAgIGNhc2UgJ1lZWVlZWSc6XG4gICAgICAgIGNhc2UgJ1lZWVlZJzpcbiAgICAgICAgY2FzZSAnR0dHR0cnOlxuICAgICAgICBjYXNlICdnZ2dnZyc6XG4gICAgICAgICAgICByZXR1cm4gc3RyaWN0ID8gcGFyc2VUb2tlblNpeERpZ2l0cyA6IHBhcnNlVG9rZW5PbmVUb1NpeERpZ2l0cztcbiAgICAgICAgY2FzZSAnUyc6XG4gICAgICAgICAgICBpZiAoc3RyaWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5PbmVEaWdpdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgY2FzZSAnU1MnOlxuICAgICAgICAgICAgaWYgKHN0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuVHdvRGlnaXRzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICBjYXNlICdTU1MnOlxuICAgICAgICAgICAgaWYgKHN0cmljdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuVGhyZWVEaWdpdHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgIGNhc2UgJ0RERCc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlbk9uZVRvVGhyZWVEaWdpdHM7XG4gICAgICAgIGNhc2UgJ01NTSc6XG4gICAgICAgIGNhc2UgJ01NTU0nOlxuICAgICAgICBjYXNlICdkZCc6XG4gICAgICAgIGNhc2UgJ2RkZCc6XG4gICAgICAgIGNhc2UgJ2RkZGQnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5Xb3JkO1xuICAgICAgICBjYXNlICdhJzpcbiAgICAgICAgY2FzZSAnQSc6XG4gICAgICAgICAgICByZXR1cm4gY29uZmlnLl9sb2NhbGUuX21lcmlkaWVtUGFyc2U7XG4gICAgICAgIGNhc2UgJ3gnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5PZmZzZXRNcztcbiAgICAgICAgY2FzZSAnWCc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlblRpbWVzdGFtcE1zO1xuICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgY2FzZSAnWlonOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5UaW1lem9uZTtcbiAgICAgICAgY2FzZSAnVCc6XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VUb2tlblQ7XG4gICAgICAgIGNhc2UgJ1NTU1MnOlxuICAgICAgICAgICAgcmV0dXJuIHBhcnNlVG9rZW5EaWdpdHM7XG4gICAgICAgIGNhc2UgJ01NJzpcbiAgICAgICAgY2FzZSAnREQnOlxuICAgICAgICBjYXNlICdZWSc6XG4gICAgICAgIGNhc2UgJ0dHJzpcbiAgICAgICAgY2FzZSAnZ2cnOlxuICAgICAgICBjYXNlICdISCc6XG4gICAgICAgIGNhc2UgJ2hoJzpcbiAgICAgICAgY2FzZSAnbW0nOlxuICAgICAgICBjYXNlICdzcyc6XG4gICAgICAgIGNhc2UgJ3d3JzpcbiAgICAgICAgY2FzZSAnV1cnOlxuICAgICAgICAgICAgcmV0dXJuIHN0cmljdCA/IHBhcnNlVG9rZW5Ud29EaWdpdHMgOiBwYXJzZVRva2VuT25lT3JUd29EaWdpdHM7XG4gICAgICAgIGNhc2UgJ00nOlxuICAgICAgICBjYXNlICdEJzpcbiAgICAgICAgY2FzZSAnZCc6XG4gICAgICAgIGNhc2UgJ0gnOlxuICAgICAgICBjYXNlICdoJzpcbiAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgIGNhc2UgJ3MnOlxuICAgICAgICBjYXNlICd3JzpcbiAgICAgICAgY2FzZSAnVyc6XG4gICAgICAgIGNhc2UgJ2UnOlxuICAgICAgICBjYXNlICdFJzpcbiAgICAgICAgICAgIHJldHVybiBwYXJzZVRva2VuT25lT3JUd29EaWdpdHM7XG4gICAgICAgIGNhc2UgJ0RvJzpcbiAgICAgICAgICAgIHJldHVybiBzdHJpY3QgPyBjb25maWcuX2xvY2FsZS5fb3JkaW5hbFBhcnNlIDogY29uZmlnLl9sb2NhbGUuX29yZGluYWxQYXJzZUxlbmllbnQ7XG4gICAgICAgIGRlZmF1bHQgOlxuICAgICAgICAgICAgYSA9IG5ldyBSZWdFeHAocmVnZXhwRXNjYXBlKHVuZXNjYXBlRm9ybWF0KHRva2VuLnJlcGxhY2UoJ1xcXFwnLCAnJykpLCAnaScpKTtcbiAgICAgICAgICAgIHJldHVybiBhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGltZXpvbmVNaW51dGVzRnJvbVN0cmluZyhzdHJpbmcpIHtcbiAgICAgICAgc3RyaW5nID0gc3RyaW5nIHx8ICcnO1xuICAgICAgICB2YXIgcG9zc2libGVUek1hdGNoZXMgPSAoc3RyaW5nLm1hdGNoKHBhcnNlVG9rZW5UaW1lem9uZSkgfHwgW10pLFxuICAgICAgICAgICAgdHpDaHVuayA9IHBvc3NpYmxlVHpNYXRjaGVzW3Bvc3NpYmxlVHpNYXRjaGVzLmxlbmd0aCAtIDFdIHx8IFtdLFxuICAgICAgICAgICAgcGFydHMgPSAodHpDaHVuayArICcnKS5tYXRjaChwYXJzZVRpbWV6b25lQ2h1bmtlcikgfHwgWyctJywgMCwgMF0sXG4gICAgICAgICAgICBtaW51dGVzID0gKyhwYXJ0c1sxXSAqIDYwKSArIHRvSW50KHBhcnRzWzJdKTtcblxuICAgICAgICByZXR1cm4gcGFydHNbMF0gPT09ICcrJyA/IC1taW51dGVzIDogbWludXRlcztcbiAgICB9XG5cbiAgICAvLyBmdW5jdGlvbiB0byBjb252ZXJ0IHN0cmluZyBpbnB1dCB0byBkYXRlXG4gICAgZnVuY3Rpb24gYWRkVGltZVRvQXJyYXlGcm9tVG9rZW4odG9rZW4sIGlucHV0LCBjb25maWcpIHtcbiAgICAgICAgdmFyIGEsIGRhdGVQYXJ0QXJyYXkgPSBjb25maWcuX2E7XG5cbiAgICAgICAgc3dpdGNoICh0b2tlbikge1xuICAgICAgICAvLyBRVUFSVEVSXG4gICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkYXRlUGFydEFycmF5W01PTlRIXSA9ICh0b0ludChpbnB1dCkgLSAxKSAqIDM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gTU9OVEhcbiAgICAgICAgY2FzZSAnTScgOiAvLyBmYWxsIHRocm91Z2ggdG8gTU1cbiAgICAgICAgY2FzZSAnTU0nIDpcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtNT05USF0gPSB0b0ludChpbnB1dCkgLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ01NTScgOiAvLyBmYWxsIHRocm91Z2ggdG8gTU1NTVxuICAgICAgICBjYXNlICdNTU1NJyA6XG4gICAgICAgICAgICBhID0gY29uZmlnLl9sb2NhbGUubW9udGhzUGFyc2UoaW5wdXQsIHRva2VuLCBjb25maWcuX3N0cmljdCk7XG4gICAgICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZmluZCBhIG1vbnRoIG5hbWUsIG1hcmsgdGhlIGRhdGUgYXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkYXRlUGFydEFycmF5W01PTlRIXSA9IGE7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fcGYuaW52YWxpZE1vbnRoID0gaW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gREFZIE9GIE1PTlRIXG4gICAgICAgIGNhc2UgJ0QnIDogLy8gZmFsbCB0aHJvdWdoIHRvIEREXG4gICAgICAgIGNhc2UgJ0REJyA6XG4gICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbREFURV0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRG8nIDpcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtEQVRFXSA9IHRvSW50KHBhcnNlSW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Lm1hdGNoKC9cXGR7MSwyfS8pWzBdLCAxMCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIERBWSBPRiBZRUFSXG4gICAgICAgIGNhc2UgJ0RERCcgOiAvLyBmYWxsIHRocm91Z2ggdG8gRERERFxuICAgICAgICBjYXNlICdEREREJyA6XG4gICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdG9JbnQoaW5wdXQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gWUVBUlxuICAgICAgICBjYXNlICdZWScgOlxuICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtZRUFSXSA9IG1vbWVudC5wYXJzZVR3b0RpZ2l0WWVhcihpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnWVlZWScgOlxuICAgICAgICBjYXNlICdZWVlZWScgOlxuICAgICAgICBjYXNlICdZWVlZWVknIDpcbiAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbWUVBUl0gPSB0b0ludChpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gQU0gLyBQTVxuICAgICAgICBjYXNlICdhJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBBXG4gICAgICAgIGNhc2UgJ0EnIDpcbiAgICAgICAgICAgIGNvbmZpZy5faXNQbSA9IGNvbmZpZy5fbG9jYWxlLmlzUE0oaW5wdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIEhPVVJcbiAgICAgICAgY2FzZSAnaCcgOiAvLyBmYWxsIHRocm91Z2ggdG8gaGhcbiAgICAgICAgY2FzZSAnaGgnIDpcbiAgICAgICAgICAgIGNvbmZpZy5fcGYuYmlnSG91ciA9IHRydWU7XG4gICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgIGNhc2UgJ0gnIDogLy8gZmFsbCB0aHJvdWdoIHRvIEhIXG4gICAgICAgIGNhc2UgJ0hIJyA6XG4gICAgICAgICAgICBkYXRlUGFydEFycmF5W0hPVVJdID0gdG9JbnQoaW5wdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIE1JTlVURVxuICAgICAgICBjYXNlICdtJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBtbVxuICAgICAgICBjYXNlICdtbScgOlxuICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtNSU5VVEVdID0gdG9JbnQoaW5wdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIFNFQ09ORFxuICAgICAgICBjYXNlICdzJyA6IC8vIGZhbGwgdGhyb3VnaCB0byBzc1xuICAgICAgICBjYXNlICdzcycgOlxuICAgICAgICAgICAgZGF0ZVBhcnRBcnJheVtTRUNPTkRdID0gdG9JbnQoaW5wdXQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC8vIE1JTExJU0VDT05EXG4gICAgICAgIGNhc2UgJ1MnIDpcbiAgICAgICAgY2FzZSAnU1MnIDpcbiAgICAgICAgY2FzZSAnU1NTJyA6XG4gICAgICAgIGNhc2UgJ1NTU1MnIDpcbiAgICAgICAgICAgIGRhdGVQYXJ0QXJyYXlbTUlMTElTRUNPTkRdID0gdG9JbnQoKCcwLicgKyBpbnB1dCkgKiAxMDAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAvLyBVTklYIE9GRlNFVCAoTUlMTElTRUNPTkRTKVxuICAgICAgICBjYXNlICd4JzpcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHRvSW50KGlucHV0KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gVU5JWCBUSU1FU1RBTVAgV0lUSCBNU1xuICAgICAgICBjYXNlICdYJzpcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKHBhcnNlRmxvYXQoaW5wdXQpICogMTAwMCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gVElNRVpPTkVcbiAgICAgICAgY2FzZSAnWicgOiAvLyBmYWxsIHRocm91Z2ggdG8gWlpcbiAgICAgICAgY2FzZSAnWlonIDpcbiAgICAgICAgICAgIGNvbmZpZy5fdXNlVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbmZpZy5fdHptID0gdGltZXpvbmVNaW51dGVzRnJvbVN0cmluZyhpbnB1dCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gV0VFS0RBWSAtIGh1bWFuXG4gICAgICAgIGNhc2UgJ2RkJzpcbiAgICAgICAgY2FzZSAnZGRkJzpcbiAgICAgICAgY2FzZSAnZGRkZCc6XG4gICAgICAgICAgICBhID0gY29uZmlnLl9sb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgICAgICAvLyBpZiB3ZSBkaWRuJ3QgZ2V0IGEgd2Vla2RheSBuYW1lLCBtYXJrIHRoZSBkYXRlIGFzIGludmFsaWRcbiAgICAgICAgICAgIGlmIChhICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX3cgPSBjb25maWcuX3cgfHwge307XG4gICAgICAgICAgICAgICAgY29uZmlnLl93WydkJ10gPSBhO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25maWcuX3BmLmludmFsaWRXZWVrZGF5ID0gaW5wdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgLy8gV0VFSywgV0VFSyBEQVkgLSBudW1lcmljXG4gICAgICAgIGNhc2UgJ3cnOlxuICAgICAgICBjYXNlICd3dyc6XG4gICAgICAgIGNhc2UgJ1cnOlxuICAgICAgICBjYXNlICdXVyc6XG4gICAgICAgIGNhc2UgJ2QnOlxuICAgICAgICBjYXNlICdlJzpcbiAgICAgICAgY2FzZSAnRSc6XG4gICAgICAgICAgICB0b2tlbiA9IHRva2VuLnN1YnN0cigwLCAxKTtcbiAgICAgICAgICAgIC8qIGZhbGxzIHRocm91Z2ggKi9cbiAgICAgICAgY2FzZSAnZ2dnZyc6XG4gICAgICAgIGNhc2UgJ0dHR0cnOlxuICAgICAgICBjYXNlICdHR0dHRyc6XG4gICAgICAgICAgICB0b2tlbiA9IHRva2VuLnN1YnN0cigwLCAyKTtcbiAgICAgICAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fdyA9IGNvbmZpZy5fdyB8fCB7fTtcbiAgICAgICAgICAgICAgICBjb25maWcuX3dbdG9rZW5dID0gdG9JbnQoaW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2dnJzpcbiAgICAgICAgY2FzZSAnR0cnOlxuICAgICAgICAgICAgY29uZmlnLl93ID0gY29uZmlnLl93IHx8IHt9O1xuICAgICAgICAgICAgY29uZmlnLl93W3Rva2VuXSA9IG1vbWVudC5wYXJzZVR3b0RpZ2l0WWVhcihpbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkYXlPZlllYXJGcm9tV2Vla0luZm8oY29uZmlnKSB7XG4gICAgICAgIHZhciB3LCB3ZWVrWWVhciwgd2Vlaywgd2Vla2RheSwgZG93LCBkb3ksIHRlbXA7XG5cbiAgICAgICAgdyA9IGNvbmZpZy5fdztcbiAgICAgICAgaWYgKHcuR0cgIT0gbnVsbCB8fCB3LlcgIT0gbnVsbCB8fCB3LkUgIT0gbnVsbCkge1xuICAgICAgICAgICAgZG93ID0gMTtcbiAgICAgICAgICAgIGRveSA9IDQ7XG5cbiAgICAgICAgICAgIC8vIFRPRE86IFdlIG5lZWQgdG8gdGFrZSB0aGUgY3VycmVudCBpc29XZWVrWWVhciwgYnV0IHRoYXQgZGVwZW5kcyBvblxuICAgICAgICAgICAgLy8gaG93IHdlIGludGVycHJldCBub3cgKGxvY2FsLCB1dGMsIGZpeGVkIG9mZnNldCkuIFNvIGNyZWF0ZVxuICAgICAgICAgICAgLy8gYSBub3cgdmVyc2lvbiBvZiBjdXJyZW50IGNvbmZpZyAodGFrZSBsb2NhbC91dGMvb2Zmc2V0IGZsYWdzLCBhbmRcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBub3cpLlxuICAgICAgICAgICAgd2Vla1llYXIgPSBkZmwody5HRywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKG1vbWVudCgpLCAxLCA0KS55ZWFyKTtcbiAgICAgICAgICAgIHdlZWsgPSBkZmwody5XLCAxKTtcbiAgICAgICAgICAgIHdlZWtkYXkgPSBkZmwody5FLCAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRvdyA9IGNvbmZpZy5fbG9jYWxlLl93ZWVrLmRvdztcbiAgICAgICAgICAgIGRveSA9IGNvbmZpZy5fbG9jYWxlLl93ZWVrLmRveTtcblxuICAgICAgICAgICAgd2Vla1llYXIgPSBkZmwody5nZywgY29uZmlnLl9hW1lFQVJdLCB3ZWVrT2ZZZWFyKG1vbWVudCgpLCBkb3csIGRveSkueWVhcik7XG4gICAgICAgICAgICB3ZWVrID0gZGZsKHcudywgMSk7XG5cbiAgICAgICAgICAgIGlmICh3LmQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIHdlZWtkYXkgLS0gbG93IGRheSBudW1iZXJzIGFyZSBjb25zaWRlcmVkIG5leHQgd2Vla1xuICAgICAgICAgICAgICAgIHdlZWtkYXkgPSB3LmQ7XG4gICAgICAgICAgICAgICAgaWYgKHdlZWtkYXkgPCBkb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgKyt3ZWVrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAody5lICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBsb2NhbCB3ZWVrZGF5IC0tIGNvdW50aW5nIHN0YXJ0cyBmcm9tIGJlZ2luaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gdy5lICsgZG93O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHRvIGJlZ2luaW5nIG9mIHdlZWtcbiAgICAgICAgICAgICAgICB3ZWVrZGF5ID0gZG93O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRlbXAgPSBkYXlPZlllYXJGcm9tV2Vla3Mod2Vla1llYXIsIHdlZWssIHdlZWtkYXksIGRveSwgZG93KTtcblxuICAgICAgICBjb25maWcuX2FbWUVBUl0gPSB0ZW1wLnllYXI7XG4gICAgICAgIGNvbmZpZy5fZGF5T2ZZZWFyID0gdGVtcC5kYXlPZlllYXI7XG4gICAgfVxuXG4gICAgLy8gY29udmVydCBhbiBhcnJheSB0byBhIGRhdGUuXG4gICAgLy8gdGhlIGFycmF5IHNob3VsZCBtaXJyb3IgdGhlIHBhcmFtZXRlcnMgYmVsb3dcbiAgICAvLyBub3RlOiBhbGwgdmFsdWVzIHBhc3QgdGhlIHllYXIgYXJlIG9wdGlvbmFsIGFuZCB3aWxsIGRlZmF1bHQgdG8gdGhlIGxvd2VzdCBwb3NzaWJsZSB2YWx1ZS5cbiAgICAvLyBbeWVhciwgbW9udGgsIGRheSAsIGhvdXIsIG1pbnV0ZSwgc2Vjb25kLCBtaWxsaXNlY29uZF1cbiAgICBmdW5jdGlvbiBkYXRlRnJvbUNvbmZpZyhjb25maWcpIHtcbiAgICAgICAgdmFyIGksIGRhdGUsIGlucHV0ID0gW10sIGN1cnJlbnREYXRlLCB5ZWFyVG9Vc2U7XG5cbiAgICAgICAgaWYgKGNvbmZpZy5fZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY3VycmVudERhdGUgPSBjdXJyZW50RGF0ZUFycmF5KGNvbmZpZyk7XG5cbiAgICAgICAgLy9jb21wdXRlIGRheSBvZiB0aGUgeWVhciBmcm9tIHdlZWtzIGFuZCB3ZWVrZGF5c1xuICAgICAgICBpZiAoY29uZmlnLl93ICYmIGNvbmZpZy5fYVtEQVRFXSA9PSBudWxsICYmIGNvbmZpZy5fYVtNT05USF0gPT0gbnVsbCkge1xuICAgICAgICAgICAgZGF5T2ZZZWFyRnJvbVdlZWtJbmZvKGNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvL2lmIHRoZSBkYXkgb2YgdGhlIHllYXIgaXMgc2V0LCBmaWd1cmUgb3V0IHdoYXQgaXQgaXNcbiAgICAgICAgaWYgKGNvbmZpZy5fZGF5T2ZZZWFyKSB7XG4gICAgICAgICAgICB5ZWFyVG9Vc2UgPSBkZmwoY29uZmlnLl9hW1lFQVJdLCBjdXJyZW50RGF0ZVtZRUFSXSk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuX2RheU9mWWVhciA+IGRheXNJblllYXIoeWVhclRvVXNlKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fcGYuX292ZXJmbG93RGF5T2ZZZWFyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGF0ZSA9IG1ha2VVVENEYXRlKHllYXJUb1VzZSwgMCwgY29uZmlnLl9kYXlPZlllYXIpO1xuICAgICAgICAgICAgY29uZmlnLl9hW01PTlRIXSA9IGRhdGUuZ2V0VVRDTW9udGgoKTtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtEQVRFXSA9IGRhdGUuZ2V0VVRDRGF0ZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGVmYXVsdCB0byBjdXJyZW50IGRhdGUuXG4gICAgICAgIC8vICogaWYgbm8geWVhciwgbW9udGgsIGRheSBvZiBtb250aCBhcmUgZ2l2ZW4sIGRlZmF1bHQgdG8gdG9kYXlcbiAgICAgICAgLy8gKiBpZiBkYXkgb2YgbW9udGggaXMgZ2l2ZW4sIGRlZmF1bHQgbW9udGggYW5kIHllYXJcbiAgICAgICAgLy8gKiBpZiBtb250aCBpcyBnaXZlbiwgZGVmYXVsdCBvbmx5IHllYXJcbiAgICAgICAgLy8gKiBpZiB5ZWFyIGlzIGdpdmVuLCBkb24ndCBkZWZhdWx0IGFueXRoaW5nXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCAzICYmIGNvbmZpZy5fYVtpXSA9PSBudWxsOyArK2kpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gY3VycmVudERhdGVbaV07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBaZXJvIG91dCB3aGF0ZXZlciB3YXMgbm90IGRlZmF1bHRlZCwgaW5jbHVkaW5nIHRpbWVcbiAgICAgICAgZm9yICg7IGkgPCA3OyBpKyspIHtcbiAgICAgICAgICAgIGNvbmZpZy5fYVtpXSA9IGlucHV0W2ldID0gKGNvbmZpZy5fYVtpXSA9PSBudWxsKSA/IChpID09PSAyID8gMSA6IDApIDogY29uZmlnLl9hW2ldO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIDI0OjAwOjAwLjAwMFxuICAgICAgICBpZiAoY29uZmlnLl9hW0hPVVJdID09PSAyNCAmJlxuICAgICAgICAgICAgICAgIGNvbmZpZy5fYVtNSU5VVEVdID09PSAwICYmXG4gICAgICAgICAgICAgICAgY29uZmlnLl9hW1NFQ09ORF0gPT09IDAgJiZcbiAgICAgICAgICAgICAgICBjb25maWcuX2FbTUlMTElTRUNPTkRdID09PSAwKSB7XG4gICAgICAgICAgICBjb25maWcuX25leHREYXkgPSB0cnVlO1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fZCA9IChjb25maWcuX3VzZVVUQyA/IG1ha2VVVENEYXRlIDogbWFrZURhdGUpLmFwcGx5KG51bGwsIGlucHV0KTtcbiAgICAgICAgLy8gQXBwbHkgdGltZXpvbmUgb2Zmc2V0IGZyb20gaW5wdXQuIFRoZSBhY3R1YWwgem9uZSBjYW4gYmUgY2hhbmdlZFxuICAgICAgICAvLyB3aXRoIHBhcnNlWm9uZS5cbiAgICAgICAgaWYgKGNvbmZpZy5fdHptICE9IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZC5zZXRVVENNaW51dGVzKGNvbmZpZy5fZC5nZXRVVENNaW51dGVzKCkgKyBjb25maWcuX3R6bSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29uZmlnLl9uZXh0RGF5KSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAyNDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGRhdGVGcm9tT2JqZWN0KGNvbmZpZykge1xuICAgICAgICB2YXIgbm9ybWFsaXplZElucHV0O1xuXG4gICAgICAgIGlmIChjb25maWcuX2QpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG5vcm1hbGl6ZWRJbnB1dCA9IG5vcm1hbGl6ZU9iamVjdFVuaXRzKGNvbmZpZy5faSk7XG4gICAgICAgIGNvbmZpZy5fYSA9IFtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJbnB1dC55ZWFyLFxuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0Lm1vbnRoLFxuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0LmRheSB8fCBub3JtYWxpemVkSW5wdXQuZGF0ZSxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJbnB1dC5ob3VyLFxuICAgICAgICAgICAgbm9ybWFsaXplZElucHV0Lm1pbnV0ZSxcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRJbnB1dC5zZWNvbmQsXG4gICAgICAgICAgICBub3JtYWxpemVkSW5wdXQubWlsbGlzZWNvbmRcbiAgICAgICAgXTtcblxuICAgICAgICBkYXRlRnJvbUNvbmZpZyhjb25maWcpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGN1cnJlbnREYXRlQXJyYXkoY29uZmlnKSB7XG4gICAgICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBpZiAoY29uZmlnLl91c2VVVEMpIHtcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgbm93LmdldFVUQ0Z1bGxZZWFyKCksXG4gICAgICAgICAgICAgICAgbm93LmdldFVUQ01vbnRoKCksXG4gICAgICAgICAgICAgICAgbm93LmdldFVUQ0RhdGUoKVxuICAgICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBbbm93LmdldEZ1bGxZZWFyKCksIG5vdy5nZXRNb250aCgpLCBub3cuZ2V0RGF0ZSgpXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIGRhdGUgZnJvbSBzdHJpbmcgYW5kIGZvcm1hdCBzdHJpbmdcbiAgICBmdW5jdGlvbiBtYWtlRGF0ZUZyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKSB7XG4gICAgICAgIGlmIChjb25maWcuX2YgPT09IG1vbWVudC5JU09fODYwMSkge1xuICAgICAgICAgICAgcGFyc2VJU08oY29uZmlnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbmZpZy5fYSA9IFtdO1xuICAgICAgICBjb25maWcuX3BmLmVtcHR5ID0gdHJ1ZTtcblxuICAgICAgICAvLyBUaGlzIGFycmF5IGlzIHVzZWQgdG8gbWFrZSBhIERhdGUsIGVpdGhlciB3aXRoIGBuZXcgRGF0ZWAgb3IgYERhdGUuVVRDYFxuICAgICAgICB2YXIgc3RyaW5nID0gJycgKyBjb25maWcuX2ksXG4gICAgICAgICAgICBpLCBwYXJzZWRJbnB1dCwgdG9rZW5zLCB0b2tlbiwgc2tpcHBlZCxcbiAgICAgICAgICAgIHN0cmluZ0xlbmd0aCA9IHN0cmluZy5sZW5ndGgsXG4gICAgICAgICAgICB0b3RhbFBhcnNlZElucHV0TGVuZ3RoID0gMDtcblxuICAgICAgICB0b2tlbnMgPSBleHBhbmRGb3JtYXQoY29uZmlnLl9mLCBjb25maWcuX2xvY2FsZSkubWF0Y2goZm9ybWF0dGluZ1Rva2VucykgfHwgW107XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdG9rZW4gPSB0b2tlbnNbaV07XG4gICAgICAgICAgICBwYXJzZWRJbnB1dCA9IChzdHJpbmcubWF0Y2goZ2V0UGFyc2VSZWdleEZvclRva2VuKHRva2VuLCBjb25maWcpKSB8fCBbXSlbMF07XG4gICAgICAgICAgICBpZiAocGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICBza2lwcGVkID0gc3RyaW5nLnN1YnN0cigwLCBzdHJpbmcuaW5kZXhPZihwYXJzZWRJbnB1dCkpO1xuICAgICAgICAgICAgICAgIGlmIChza2lwcGVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9wZi51bnVzZWRJbnB1dC5wdXNoKHNraXBwZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzdHJpbmcgPSBzdHJpbmcuc2xpY2Uoc3RyaW5nLmluZGV4T2YocGFyc2VkSW5wdXQpICsgcGFyc2VkSW5wdXQubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICB0b3RhbFBhcnNlZElucHV0TGVuZ3RoICs9IHBhcnNlZElucHV0Lmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRvbid0IHBhcnNlIGlmIGl0J3Mgbm90IGEga25vd24gdG9rZW5cbiAgICAgICAgICAgIGlmIChmb3JtYXRUb2tlbkZ1bmN0aW9uc1t0b2tlbl0pIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyc2VkSW5wdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9wZi5lbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnLl9wZi51bnVzZWRUb2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFkZFRpbWVUb0FycmF5RnJvbVRva2VuKHRva2VuLCBwYXJzZWRJbnB1dCwgY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbmZpZy5fc3RyaWN0ICYmICFwYXJzZWRJbnB1dCkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fcGYudW51c2VkVG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRkIHJlbWFpbmluZyB1bnBhcnNlZCBpbnB1dCBsZW5ndGggdG8gdGhlIHN0cmluZ1xuICAgICAgICBjb25maWcuX3BmLmNoYXJzTGVmdE92ZXIgPSBzdHJpbmdMZW5ndGggLSB0b3RhbFBhcnNlZElucHV0TGVuZ3RoO1xuICAgICAgICBpZiAoc3RyaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbmZpZy5fcGYudW51c2VkSW5wdXQucHVzaChzdHJpbmcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2xlYXIgXzEyaCBmbGFnIGlmIGhvdXIgaXMgPD0gMTJcbiAgICAgICAgaWYgKGNvbmZpZy5fcGYuYmlnSG91ciA9PT0gdHJ1ZSAmJiBjb25maWcuX2FbSE9VUl0gPD0gMTIpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fcGYuYmlnSG91ciA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBoYW5kbGUgYW0gcG1cbiAgICAgICAgaWYgKGNvbmZpZy5faXNQbSAmJiBjb25maWcuX2FbSE9VUl0gPCAxMikge1xuICAgICAgICAgICAgY29uZmlnLl9hW0hPVVJdICs9IDEyO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGlzIDEyIGFtLCBjaGFuZ2UgaG91cnMgdG8gMFxuICAgICAgICBpZiAoY29uZmlnLl9pc1BtID09PSBmYWxzZSAmJiBjb25maWcuX2FbSE9VUl0gPT09IDEyKSB7XG4gICAgICAgICAgICBjb25maWcuX2FbSE9VUl0gPSAwO1xuICAgICAgICB9XG4gICAgICAgIGRhdGVGcm9tQ29uZmlnKGNvbmZpZyk7XG4gICAgICAgIGNoZWNrT3ZlcmZsb3coY29uZmlnKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB1bmVzY2FwZUZvcm1hdChzKSB7XG4gICAgICAgIHJldHVybiBzLnJlcGxhY2UoL1xcXFwoXFxbKXxcXFxcKFxcXSl8XFxbKFteXFxdXFxbXSopXFxdfFxcXFwoLikvZywgZnVuY3Rpb24gKG1hdGNoZWQsIHAxLCBwMiwgcDMsIHA0KSB7XG4gICAgICAgICAgICByZXR1cm4gcDEgfHwgcDIgfHwgcDMgfHwgcDQ7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENvZGUgZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1NjE0OTMvaXMtdGhlcmUtYS1yZWdleHAtZXNjYXBlLWZ1bmN0aW9uLWluLWphdmFzY3JpcHRcbiAgICBmdW5jdGlvbiByZWdleHBFc2NhcGUocykge1xuICAgICAgICByZXR1cm4gcy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcbiAgICB9XG5cbiAgICAvLyBkYXRlIGZyb20gc3RyaW5nIGFuZCBhcnJheSBvZiBmb3JtYXQgc3RyaW5nc1xuICAgIGZ1bmN0aW9uIG1ha2VEYXRlRnJvbVN0cmluZ0FuZEFycmF5KGNvbmZpZykge1xuICAgICAgICB2YXIgdGVtcENvbmZpZyxcbiAgICAgICAgICAgIGJlc3RNb21lbnQsXG5cbiAgICAgICAgICAgIHNjb3JlVG9CZWF0LFxuICAgICAgICAgICAgaSxcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZTtcblxuICAgICAgICBpZiAoY29uZmlnLl9mLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgY29uZmlnLl9wZi5pbnZhbGlkRm9ybWF0ID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKE5hTik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY29uZmlnLl9mLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjdXJyZW50U2NvcmUgPSAwO1xuICAgICAgICAgICAgdGVtcENvbmZpZyA9IGNvcHlDb25maWcoe30sIGNvbmZpZyk7XG4gICAgICAgICAgICBpZiAoY29uZmlnLl91c2VVVEMgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRlbXBDb25maWcuX3VzZVVUQyA9IGNvbmZpZy5fdXNlVVRDO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGVtcENvbmZpZy5fcGYgPSBkZWZhdWx0UGFyc2luZ0ZsYWdzKCk7XG4gICAgICAgICAgICB0ZW1wQ29uZmlnLl9mID0gY29uZmlnLl9mW2ldO1xuICAgICAgICAgICAgbWFrZURhdGVGcm9tU3RyaW5nQW5kRm9ybWF0KHRlbXBDb25maWcpO1xuXG4gICAgICAgICAgICBpZiAoIWlzVmFsaWQodGVtcENvbmZpZykpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW55IGlucHV0IHRoYXQgd2FzIG5vdCBwYXJzZWQgYWRkIGEgcGVuYWx0eSBmb3IgdGhhdCBmb3JtYXRcbiAgICAgICAgICAgIGN1cnJlbnRTY29yZSArPSB0ZW1wQ29uZmlnLl9wZi5jaGFyc0xlZnRPdmVyO1xuXG4gICAgICAgICAgICAvL29yIHRva2Vuc1xuICAgICAgICAgICAgY3VycmVudFNjb3JlICs9IHRlbXBDb25maWcuX3BmLnVudXNlZFRva2Vucy5sZW5ndGggKiAxMDtcblxuICAgICAgICAgICAgdGVtcENvbmZpZy5fcGYuc2NvcmUgPSBjdXJyZW50U2NvcmU7XG5cbiAgICAgICAgICAgIGlmIChzY29yZVRvQmVhdCA9PSBudWxsIHx8IGN1cnJlbnRTY29yZSA8IHNjb3JlVG9CZWF0KSB7XG4gICAgICAgICAgICAgICAgc2NvcmVUb0JlYXQgPSBjdXJyZW50U2NvcmU7XG4gICAgICAgICAgICAgICAgYmVzdE1vbWVudCA9IHRlbXBDb25maWc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBleHRlbmQoY29uZmlnLCBiZXN0TW9tZW50IHx8IHRlbXBDb25maWcpO1xuICAgIH1cblxuICAgIC8vIGRhdGUgZnJvbSBpc28gZm9ybWF0XG4gICAgZnVuY3Rpb24gcGFyc2VJU08oY29uZmlnKSB7XG4gICAgICAgIHZhciBpLCBsLFxuICAgICAgICAgICAgc3RyaW5nID0gY29uZmlnLl9pLFxuICAgICAgICAgICAgbWF0Y2ggPSBpc29SZWdleC5leGVjKHN0cmluZyk7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICBjb25maWcuX3BmLmlzbyA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvRGF0ZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzb0RhdGVzW2ldWzFdLmV4ZWMoc3RyaW5nKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBtYXRjaFs1XSBzaG91bGQgYmUgJ1QnIG9yIHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICBjb25maWcuX2YgPSBpc29EYXRlc1tpXVswXSArIChtYXRjaFs2XSB8fCAnICcpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsID0gaXNvVGltZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzb1RpbWVzW2ldWzFdLmV4ZWMoc3RyaW5nKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25maWcuX2YgKz0gaXNvVGltZXNbaV1bMF07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzdHJpbmcubWF0Y2gocGFyc2VUb2tlblRpbWV6b25lKSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZy5fZiArPSAnWic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYWtlRGF0ZUZyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbmZpZy5faXNWYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0ZSBmcm9tIGlzbyBmb3JtYXQgb3IgZmFsbGJhY2tcbiAgICBmdW5jdGlvbiBtYWtlRGF0ZUZyb21TdHJpbmcoY29uZmlnKSB7XG4gICAgICAgIHBhcnNlSVNPKGNvbmZpZyk7XG4gICAgICAgIGlmIChjb25maWcuX2lzVmFsaWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkZWxldGUgY29uZmlnLl9pc1ZhbGlkO1xuICAgICAgICAgICAgbW9tZW50LmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYXAoYXJyLCBmbikge1xuICAgICAgICB2YXIgcmVzID0gW10sIGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIHJlcy5wdXNoKGZuKGFycltpXSwgaSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZURhdGVGcm9tSW5wdXQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faSwgbWF0Y2hlZDtcbiAgICAgICAgaWYgKGlucHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNEYXRlKGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoK2lucHV0KTtcbiAgICAgICAgfSBlbHNlIGlmICgobWF0Y2hlZCA9IGFzcE5ldEpzb25SZWdleC5leGVjKGlucHV0KSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbmZpZy5fZCA9IG5ldyBEYXRlKCttYXRjaGVkWzFdKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBtYWtlRGF0ZUZyb21TdHJpbmcoY29uZmlnKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KGlucHV0KSkge1xuICAgICAgICAgICAgY29uZmlnLl9hID0gbWFwKGlucHV0LnNsaWNlKDApLCBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KG9iaiwgMTApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkYXRlRnJvbUNvbmZpZyhjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZihpbnB1dCkgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBkYXRlRnJvbU9iamVjdChjb25maWcpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZihpbnB1dCkgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAvLyBmcm9tIG1pbGxpc2Vjb25kc1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoaW5wdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbW9tZW50LmNyZWF0ZUZyb21JbnB1dEZhbGxiYWNrKGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBtYWtlRGF0ZSh5LCBtLCBkLCBoLCBNLCBzLCBtcykge1xuICAgICAgICAvL2Nhbid0IGp1c3QgYXBwbHkoKSB0byBjcmVhdGUgYSBkYXRlOlxuICAgICAgICAvL2h0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTgxMzQ4L2luc3RhbnRpYXRpbmctYS1qYXZhc2NyaXB0LW9iamVjdC1ieS1jYWxsaW5nLXByb3RvdHlwZS1jb25zdHJ1Y3Rvci1hcHBseVxuICAgICAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHksIG0sIGQsIGgsIE0sIHMsIG1zKTtcblxuICAgICAgICAvL3RoZSBkYXRlIGNvbnN0cnVjdG9yIGRvZXNuJ3QgYWNjZXB0IHllYXJzIDwgMTk3MFxuICAgICAgICBpZiAoeSA8IDE5NzApIHtcbiAgICAgICAgICAgIGRhdGUuc2V0RnVsbFllYXIoeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZVVUQ0RhdGUoeSkge1xuICAgICAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKERhdGUuVVRDLmFwcGx5KG51bGwsIGFyZ3VtZW50cykpO1xuICAgICAgICBpZiAoeSA8IDE5NzApIHtcbiAgICAgICAgICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGFyc2VXZWVrZGF5KGlucHV0LCBsb2NhbGUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmICghaXNOYU4oaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBwYXJzZUludChpbnB1dCwgMTApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBsb2NhbGUud2Vla2RheXNQYXJzZShpbnB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnB1dDtcbiAgICB9XG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICAgIFJlbGF0aXZlIFRpbWVcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIC8vIGhlbHBlciBmdW5jdGlvbiBmb3IgbW9tZW50LmZuLmZyb20sIG1vbWVudC5mbi5mcm9tTm93LCBhbmQgbW9tZW50LmR1cmF0aW9uLmZuLmh1bWFuaXplXG4gICAgZnVuY3Rpb24gc3Vic3RpdHV0ZVRpbWVBZ28oc3RyaW5nLCBudW1iZXIsIHdpdGhvdXRTdWZmaXgsIGlzRnV0dXJlLCBsb2NhbGUpIHtcbiAgICAgICAgcmV0dXJuIGxvY2FsZS5yZWxhdGl2ZVRpbWUobnVtYmVyIHx8IDEsICEhd2l0aG91dFN1ZmZpeCwgc3RyaW5nLCBpc0Z1dHVyZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVsYXRpdmVUaW1lKHBvc05lZ0R1cmF0aW9uLCB3aXRob3V0U3VmZml4LCBsb2NhbGUpIHtcbiAgICAgICAgdmFyIGR1cmF0aW9uID0gbW9tZW50LmR1cmF0aW9uKHBvc05lZ0R1cmF0aW9uKS5hYnMoKSxcbiAgICAgICAgICAgIHNlY29uZHMgPSByb3VuZChkdXJhdGlvbi5hcygncycpKSxcbiAgICAgICAgICAgIG1pbnV0ZXMgPSByb3VuZChkdXJhdGlvbi5hcygnbScpKSxcbiAgICAgICAgICAgIGhvdXJzID0gcm91bmQoZHVyYXRpb24uYXMoJ2gnKSksXG4gICAgICAgICAgICBkYXlzID0gcm91bmQoZHVyYXRpb24uYXMoJ2QnKSksXG4gICAgICAgICAgICBtb250aHMgPSByb3VuZChkdXJhdGlvbi5hcygnTScpKSxcbiAgICAgICAgICAgIHllYXJzID0gcm91bmQoZHVyYXRpb24uYXMoJ3knKSksXG5cbiAgICAgICAgICAgIGFyZ3MgPSBzZWNvbmRzIDwgcmVsYXRpdmVUaW1lVGhyZXNob2xkcy5zICYmIFsncycsIHNlY29uZHNdIHx8XG4gICAgICAgICAgICAgICAgbWludXRlcyA9PT0gMSAmJiBbJ20nXSB8fFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPCByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzLm0gJiYgWydtbScsIG1pbnV0ZXNdIHx8XG4gICAgICAgICAgICAgICAgaG91cnMgPT09IDEgJiYgWydoJ10gfHxcbiAgICAgICAgICAgICAgICBob3VycyA8IHJlbGF0aXZlVGltZVRocmVzaG9sZHMuaCAmJiBbJ2hoJywgaG91cnNdIHx8XG4gICAgICAgICAgICAgICAgZGF5cyA9PT0gMSAmJiBbJ2QnXSB8fFxuICAgICAgICAgICAgICAgIGRheXMgPCByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzLmQgJiYgWydkZCcsIGRheXNdIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzID09PSAxICYmIFsnTSddIHx8XG4gICAgICAgICAgICAgICAgbW9udGhzIDwgcmVsYXRpdmVUaW1lVGhyZXNob2xkcy5NICYmIFsnTU0nLCBtb250aHNdIHx8XG4gICAgICAgICAgICAgICAgeWVhcnMgPT09IDEgJiYgWyd5J10gfHwgWyd5eScsIHllYXJzXTtcblxuICAgICAgICBhcmdzWzJdID0gd2l0aG91dFN1ZmZpeDtcbiAgICAgICAgYXJnc1szXSA9ICtwb3NOZWdEdXJhdGlvbiA+IDA7XG4gICAgICAgIGFyZ3NbNF0gPSBsb2NhbGU7XG4gICAgICAgIHJldHVybiBzdWJzdGl0dXRlVGltZUFnby5hcHBseSh7fSwgYXJncyk7XG4gICAgfVxuXG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICAgIFdlZWsgb2YgWWVhclxuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG4gICAgLy8gZmlyc3REYXlPZldlZWsgICAgICAgMCA9IHN1biwgNiA9IHNhdFxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgIHRoZSBkYXkgb2YgdGhlIHdlZWsgdGhhdCBzdGFydHMgdGhlIHdlZWtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAodXN1YWxseSBzdW5kYXkgb3IgbW9uZGF5KVxuICAgIC8vIGZpcnN0RGF5T2ZXZWVrT2ZZZWFyIDAgPSBzdW4sIDYgPSBzYXRcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICB0aGUgZmlyc3Qgd2VlayBpcyB0aGUgd2VlayB0aGF0IGNvbnRhaW5zIHRoZSBmaXJzdFxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgIG9mIHRoaXMgZGF5IG9mIHRoZSB3ZWVrXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgKGVnLiBJU08gd2Vla3MgdXNlIHRodXJzZGF5ICg0KSlcbiAgICBmdW5jdGlvbiB3ZWVrT2ZZZWFyKG1vbSwgZmlyc3REYXlPZldlZWssIGZpcnN0RGF5T2ZXZWVrT2ZZZWFyKSB7XG4gICAgICAgIHZhciBlbmQgPSBmaXJzdERheU9mV2Vla09mWWVhciAtIGZpcnN0RGF5T2ZXZWVrLFxuICAgICAgICAgICAgZGF5c1RvRGF5T2ZXZWVrID0gZmlyc3REYXlPZldlZWtPZlllYXIgLSBtb20uZGF5KCksXG4gICAgICAgICAgICBhZGp1c3RlZE1vbWVudDtcblxuXG4gICAgICAgIGlmIChkYXlzVG9EYXlPZldlZWsgPiBlbmQpIHtcbiAgICAgICAgICAgIGRheXNUb0RheU9mV2VlayAtPSA3O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGRheXNUb0RheU9mV2VlayA8IGVuZCAtIDcpIHtcbiAgICAgICAgICAgIGRheXNUb0RheU9mV2VlayArPSA3O1xuICAgICAgICB9XG5cbiAgICAgICAgYWRqdXN0ZWRNb21lbnQgPSBtb21lbnQobW9tKS5hZGQoZGF5c1RvRGF5T2ZXZWVrLCAnZCcpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2VlazogTWF0aC5jZWlsKGFkanVzdGVkTW9tZW50LmRheU9mWWVhcigpIC8gNyksXG4gICAgICAgICAgICB5ZWFyOiBhZGp1c3RlZE1vbWVudC55ZWFyKClcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvL2h0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPX3dlZWtfZGF0ZSNDYWxjdWxhdGluZ19hX2RhdGVfZ2l2ZW5fdGhlX3llYXIuMkNfd2Vla19udW1iZXJfYW5kX3dlZWtkYXlcbiAgICBmdW5jdGlvbiBkYXlPZlllYXJGcm9tV2Vla3MoeWVhciwgd2Vlaywgd2Vla2RheSwgZmlyc3REYXlPZldlZWtPZlllYXIsIGZpcnN0RGF5T2ZXZWVrKSB7XG4gICAgICAgIHZhciBkID0gbWFrZVVUQ0RhdGUoeWVhciwgMCwgMSkuZ2V0VVRDRGF5KCksIGRheXNUb0FkZCwgZGF5T2ZZZWFyO1xuXG4gICAgICAgIGQgPSBkID09PSAwID8gNyA6IGQ7XG4gICAgICAgIHdlZWtkYXkgPSB3ZWVrZGF5ICE9IG51bGwgPyB3ZWVrZGF5IDogZmlyc3REYXlPZldlZWs7XG4gICAgICAgIGRheXNUb0FkZCA9IGZpcnN0RGF5T2ZXZWVrIC0gZCArIChkID4gZmlyc3REYXlPZldlZWtPZlllYXIgPyA3IDogMCkgLSAoZCA8IGZpcnN0RGF5T2ZXZWVrID8gNyA6IDApO1xuICAgICAgICBkYXlPZlllYXIgPSA3ICogKHdlZWsgLSAxKSArICh3ZWVrZGF5IC0gZmlyc3REYXlPZldlZWspICsgZGF5c1RvQWRkICsgMTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcjogZGF5T2ZZZWFyID4gMCA/IHllYXIgOiB5ZWFyIC0gMSxcbiAgICAgICAgICAgIGRheU9mWWVhcjogZGF5T2ZZZWFyID4gMCA/ICBkYXlPZlllYXIgOiBkYXlzSW5ZZWFyKHllYXIgLSAxKSArIGRheU9mWWVhclxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgVG9wIExldmVsIEZ1bmN0aW9uc1xuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGZ1bmN0aW9uIG1ha2VNb21lbnQoY29uZmlnKSB7XG4gICAgICAgIHZhciBpbnB1dCA9IGNvbmZpZy5faSxcbiAgICAgICAgICAgIGZvcm1hdCA9IGNvbmZpZy5fZixcbiAgICAgICAgICAgIHJlcztcblxuICAgICAgICBjb25maWcuX2xvY2FsZSA9IGNvbmZpZy5fbG9jYWxlIHx8IG1vbWVudC5sb2NhbGVEYXRhKGNvbmZpZy5fbCk7XG5cbiAgICAgICAgaWYgKGlucHV0ID09PSBudWxsIHx8IChmb3JtYXQgPT09IHVuZGVmaW5lZCAmJiBpbnB1dCA9PT0gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gbW9tZW50LmludmFsaWQoe251bGxJbnB1dDogdHJ1ZX0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGNvbmZpZy5faSA9IGlucHV0ID0gY29uZmlnLl9sb2NhbGUucHJlcGFyc2UoaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1vbWVudC5pc01vbWVudChpbnB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgTW9tZW50KGlucHV0LCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChmb3JtYXQpIHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGZvcm1hdCkpIHtcbiAgICAgICAgICAgICAgICBtYWtlRGF0ZUZyb21TdHJpbmdBbmRBcnJheShjb25maWcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtYWtlRGF0ZUZyb21TdHJpbmdBbmRGb3JtYXQoY29uZmlnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1ha2VEYXRlRnJvbUlucHV0KGNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXMgPSBuZXcgTW9tZW50KGNvbmZpZyk7XG4gICAgICAgIGlmIChyZXMuX25leHREYXkpIHtcbiAgICAgICAgICAgIC8vIEFkZGluZyBpcyBzbWFydCBlbm91Z2ggYXJvdW5kIERTVFxuICAgICAgICAgICAgcmVzLmFkZCgxLCAnZCcpO1xuICAgICAgICAgICAgcmVzLl9uZXh0RGF5ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBtb21lbnQgPSBmdW5jdGlvbiAoaW5wdXQsIGZvcm1hdCwgbG9jYWxlLCBzdHJpY3QpIHtcbiAgICAgICAgdmFyIGM7XG5cbiAgICAgICAgaWYgKHR5cGVvZihsb2NhbGUpID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHN0cmljdCA9IGxvY2FsZTtcbiAgICAgICAgICAgIGxvY2FsZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBvYmplY3QgY29uc3RydWN0aW9uIG11c3QgYmUgZG9uZSB0aGlzIHdheS5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE0MjNcbiAgICAgICAgYyA9IHt9O1xuICAgICAgICBjLl9pc0FNb21lbnRPYmplY3QgPSB0cnVlO1xuICAgICAgICBjLl9pID0gaW5wdXQ7XG4gICAgICAgIGMuX2YgPSBmb3JtYXQ7XG4gICAgICAgIGMuX2wgPSBsb2NhbGU7XG4gICAgICAgIGMuX3N0cmljdCA9IHN0cmljdDtcbiAgICAgICAgYy5faXNVVEMgPSBmYWxzZTtcbiAgICAgICAgYy5fcGYgPSBkZWZhdWx0UGFyc2luZ0ZsYWdzKCk7XG5cbiAgICAgICAgcmV0dXJuIG1ha2VNb21lbnQoYyk7XG4gICAgfTtcblxuICAgIG1vbWVudC5zdXBwcmVzc0RlcHJlY2F0aW9uV2FybmluZ3MgPSBmYWxzZTtcblxuICAgIG1vbWVudC5jcmVhdGVGcm9tSW5wdXRGYWxsYmFjayA9IGRlcHJlY2F0ZShcbiAgICAgICAgJ21vbWVudCBjb25zdHJ1Y3Rpb24gZmFsbHMgYmFjayB0byBqcyBEYXRlLiBUaGlzIGlzICcgK1xuICAgICAgICAnZGlzY291cmFnZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiB1cGNvbWluZyBtYWpvciAnICtcbiAgICAgICAgJ3JlbGVhc2UuIFBsZWFzZSByZWZlciB0byAnICtcbiAgICAgICAgJ2h0dHBzOi8vZ2l0aHViLmNvbS9tb21lbnQvbW9tZW50L2lzc3Vlcy8xNDA3IGZvciBtb3JlIGluZm8uJyxcbiAgICAgICAgZnVuY3Rpb24gKGNvbmZpZykge1xuICAgICAgICAgICAgY29uZmlnLl9kID0gbmV3IERhdGUoY29uZmlnLl9pICsgKGNvbmZpZy5fdXNlVVRDID8gJyBVVEMnIDogJycpKTtcbiAgICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBQaWNrIGEgbW9tZW50IG0gZnJvbSBtb21lbnRzIHNvIHRoYXQgbVtmbl0ob3RoZXIpIGlzIHRydWUgZm9yIGFsbFxuICAgIC8vIG90aGVyLiBUaGlzIHJlbGllcyBvbiB0aGUgZnVuY3Rpb24gZm4gdG8gYmUgdHJhbnNpdGl2ZS5cbiAgICAvL1xuICAgIC8vIG1vbWVudHMgc2hvdWxkIGVpdGhlciBiZSBhbiBhcnJheSBvZiBtb21lbnQgb2JqZWN0cyBvciBhbiBhcnJheSwgd2hvc2VcbiAgICAvLyBmaXJzdCBlbGVtZW50IGlzIGFuIGFycmF5IG9mIG1vbWVudCBvYmplY3RzLlxuICAgIGZ1bmN0aW9uIHBpY2tCeShmbiwgbW9tZW50cykge1xuICAgICAgICB2YXIgcmVzLCBpO1xuICAgICAgICBpZiAobW9tZW50cy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShtb21lbnRzWzBdKSkge1xuICAgICAgICAgICAgbW9tZW50cyA9IG1vbWVudHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFtb21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudCgpO1xuICAgICAgICB9XG4gICAgICAgIHJlcyA9IG1vbWVudHNbMF07XG4gICAgICAgIGZvciAoaSA9IDE7IGkgPCBtb21lbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAobW9tZW50c1tpXVtmbl0ocmVzKSkge1xuICAgICAgICAgICAgICAgIHJlcyA9IG1vbWVudHNbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG5cbiAgICBtb21lbnQubWluID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcblxuICAgICAgICByZXR1cm4gcGlja0J5KCdpc0JlZm9yZScsIGFyZ3MpO1xuICAgIH07XG5cbiAgICBtb21lbnQubWF4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcblxuICAgICAgICByZXR1cm4gcGlja0J5KCdpc0FmdGVyJywgYXJncyk7XG4gICAgfTtcblxuICAgIC8vIGNyZWF0aW5nIHdpdGggdXRjXG4gICAgbW9tZW50LnV0YyA9IGZ1bmN0aW9uIChpbnB1dCwgZm9ybWF0LCBsb2NhbGUsIHN0cmljdCkge1xuICAgICAgICB2YXIgYztcblxuICAgICAgICBpZiAodHlwZW9mKGxvY2FsZSkgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgc3RyaWN0ID0gbG9jYWxlO1xuICAgICAgICAgICAgbG9jYWxlID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIC8vIG9iamVjdCBjb25zdHJ1Y3Rpb24gbXVzdCBiZSBkb25lIHRoaXMgd2F5LlxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50L21vbWVudC9pc3N1ZXMvMTQyM1xuICAgICAgICBjID0ge307XG4gICAgICAgIGMuX2lzQU1vbWVudE9iamVjdCA9IHRydWU7XG4gICAgICAgIGMuX3VzZVVUQyA9IHRydWU7XG4gICAgICAgIGMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgYy5fbCA9IGxvY2FsZTtcbiAgICAgICAgYy5faSA9IGlucHV0O1xuICAgICAgICBjLl9mID0gZm9ybWF0O1xuICAgICAgICBjLl9zdHJpY3QgPSBzdHJpY3Q7XG4gICAgICAgIGMuX3BmID0gZGVmYXVsdFBhcnNpbmdGbGFncygpO1xuXG4gICAgICAgIHJldHVybiBtYWtlTW9tZW50KGMpLnV0YygpO1xuICAgIH07XG5cbiAgICAvLyBjcmVhdGluZyB3aXRoIHVuaXggdGltZXN0YW1wIChpbiBzZWNvbmRzKVxuICAgIG1vbWVudC51bml4ID0gZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgIHJldHVybiBtb21lbnQoaW5wdXQgKiAxMDAwKTtcbiAgICB9O1xuXG4gICAgLy8gZHVyYXRpb25cbiAgICBtb21lbnQuZHVyYXRpb24gPSBmdW5jdGlvbiAoaW5wdXQsIGtleSkge1xuICAgICAgICB2YXIgZHVyYXRpb24gPSBpbnB1dCxcbiAgICAgICAgICAgIC8vIG1hdGNoaW5nIGFnYWluc3QgcmVnZXhwIGlzIGV4cGVuc2l2ZSwgZG8gaXQgb24gZGVtYW5kXG4gICAgICAgICAgICBtYXRjaCA9IG51bGwsXG4gICAgICAgICAgICBzaWduLFxuICAgICAgICAgICAgcmV0LFxuICAgICAgICAgICAgcGFyc2VJc28sXG4gICAgICAgICAgICBkaWZmUmVzO1xuXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbihpbnB1dCkpIHtcbiAgICAgICAgICAgIGR1cmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIG1zOiBpbnB1dC5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGQ6IGlucHV0Ll9kYXlzLFxuICAgICAgICAgICAgICAgIE06IGlucHV0Ll9tb250aHNcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlucHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBkdXJhdGlvbltrZXldID0gaW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uLm1pbGxpc2Vjb25kcyA9IGlucHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCEhKG1hdGNoID0gYXNwTmV0VGltZVNwYW5Kc29uUmVnZXguZXhlYyhpbnB1dCkpKSB7XG4gICAgICAgICAgICBzaWduID0gKG1hdGNoWzFdID09PSAnLScpID8gLTEgOiAxO1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeTogMCxcbiAgICAgICAgICAgICAgICBkOiB0b0ludChtYXRjaFtEQVRFXSkgKiBzaWduLFxuICAgICAgICAgICAgICAgIGg6IHRvSW50KG1hdGNoW0hPVVJdKSAqIHNpZ24sXG4gICAgICAgICAgICAgICAgbTogdG9JbnQobWF0Y2hbTUlOVVRFXSkgKiBzaWduLFxuICAgICAgICAgICAgICAgIHM6IHRvSW50KG1hdGNoW1NFQ09ORF0pICogc2lnbixcbiAgICAgICAgICAgICAgICBtczogdG9JbnQobWF0Y2hbTUlMTElTRUNPTkRdKSAqIHNpZ25cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoISEobWF0Y2ggPSBpc29EdXJhdGlvblJlZ2V4LmV4ZWMoaW5wdXQpKSkge1xuICAgICAgICAgICAgc2lnbiA9IChtYXRjaFsxXSA9PT0gJy0nKSA/IC0xIDogMTtcbiAgICAgICAgICAgIHBhcnNlSXNvID0gZnVuY3Rpb24gKGlucCkge1xuICAgICAgICAgICAgICAgIC8vIFdlJ2Qgbm9ybWFsbHkgdXNlIH5+aW5wIGZvciB0aGlzLCBidXQgdW5mb3J0dW5hdGVseSBpdCBhbHNvXG4gICAgICAgICAgICAgICAgLy8gY29udmVydHMgZmxvYXRzIHRvIGludHMuXG4gICAgICAgICAgICAgICAgLy8gaW5wIG1heSBiZSB1bmRlZmluZWQsIHNvIGNhcmVmdWwgY2FsbGluZyByZXBsYWNlIG9uIGl0LlxuICAgICAgICAgICAgICAgIHZhciByZXMgPSBpbnAgJiYgcGFyc2VGbG9hdChpbnAucmVwbGFjZSgnLCcsICcuJykpO1xuICAgICAgICAgICAgICAgIC8vIGFwcGx5IHNpZ24gd2hpbGUgd2UncmUgYXQgaXRcbiAgICAgICAgICAgICAgICByZXR1cm4gKGlzTmFOKHJlcykgPyAwIDogcmVzKSAqIHNpZ247XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZHVyYXRpb24gPSB7XG4gICAgICAgICAgICAgICAgeTogcGFyc2VJc28obWF0Y2hbMl0pLFxuICAgICAgICAgICAgICAgIE06IHBhcnNlSXNvKG1hdGNoWzNdKSxcbiAgICAgICAgICAgICAgICBkOiBwYXJzZUlzbyhtYXRjaFs0XSksXG4gICAgICAgICAgICAgICAgaDogcGFyc2VJc28obWF0Y2hbNV0pLFxuICAgICAgICAgICAgICAgIG06IHBhcnNlSXNvKG1hdGNoWzZdKSxcbiAgICAgICAgICAgICAgICBzOiBwYXJzZUlzbyhtYXRjaFs3XSksXG4gICAgICAgICAgICAgICAgdzogcGFyc2VJc28obWF0Y2hbOF0pXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBkdXJhdGlvbiA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgICAgICAoJ2Zyb20nIGluIGR1cmF0aW9uIHx8ICd0bycgaW4gZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBkaWZmUmVzID0gbW9tZW50c0RpZmZlcmVuY2UobW9tZW50KGR1cmF0aW9uLmZyb20pLCBtb21lbnQoZHVyYXRpb24udG8pKTtcblxuICAgICAgICAgICAgZHVyYXRpb24gPSB7fTtcbiAgICAgICAgICAgIGR1cmF0aW9uLm1zID0gZGlmZlJlcy5taWxsaXNlY29uZHM7XG4gICAgICAgICAgICBkdXJhdGlvbi5NID0gZGlmZlJlcy5tb250aHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXQgPSBuZXcgRHVyYXRpb24oZHVyYXRpb24pO1xuXG4gICAgICAgIGlmIChtb21lbnQuaXNEdXJhdGlvbihpbnB1dCkgJiYgaGFzT3duUHJvcChpbnB1dCwgJ19sb2NhbGUnKSkge1xuICAgICAgICAgICAgcmV0Ll9sb2NhbGUgPSBpbnB1dC5fbG9jYWxlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9O1xuXG4gICAgLy8gdmVyc2lvbiBudW1iZXJcbiAgICBtb21lbnQudmVyc2lvbiA9IFZFUlNJT047XG5cbiAgICAvLyBkZWZhdWx0IGZvcm1hdFxuICAgIG1vbWVudC5kZWZhdWx0Rm9ybWF0ID0gaXNvRm9ybWF0O1xuXG4gICAgLy8gY29uc3RhbnQgdGhhdCByZWZlcnMgdG8gdGhlIElTTyBzdGFuZGFyZFxuICAgIG1vbWVudC5JU09fODYwMSA9IGZ1bmN0aW9uICgpIHt9O1xuXG4gICAgLy8gUGx1Z2lucyB0aGF0IGFkZCBwcm9wZXJ0aWVzIHNob3VsZCBhbHNvIGFkZCB0aGUga2V5IGhlcmUgKG51bGwgdmFsdWUpLFxuICAgIC8vIHNvIHdlIGNhbiBwcm9wZXJseSBjbG9uZSBvdXJzZWx2ZXMuXG4gICAgbW9tZW50Lm1vbWVudFByb3BlcnRpZXMgPSBtb21lbnRQcm9wZXJ0aWVzO1xuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCB3aGVuZXZlciBhIG1vbWVudCBpcyBtdXRhdGVkLlxuICAgIC8vIEl0IGlzIGludGVuZGVkIHRvIGtlZXAgdGhlIG9mZnNldCBpbiBzeW5jIHdpdGggdGhlIHRpbWV6b25lLlxuICAgIG1vbWVudC51cGRhdGVPZmZzZXQgPSBmdW5jdGlvbiAoKSB7fTtcblxuICAgIC8vIFRoaXMgZnVuY3Rpb24gYWxsb3dzIHlvdSB0byBzZXQgYSB0aHJlc2hvbGQgZm9yIHJlbGF0aXZlIHRpbWUgc3RyaW5nc1xuICAgIG1vbWVudC5yZWxhdGl2ZVRpbWVUaHJlc2hvbGQgPSBmdW5jdGlvbiAodGhyZXNob2xkLCBsaW1pdCkge1xuICAgICAgICBpZiAocmVsYXRpdmVUaW1lVGhyZXNob2xkc1t0aHJlc2hvbGRdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGltaXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlbGF0aXZlVGltZVRocmVzaG9sZHNbdGhyZXNob2xkXTtcbiAgICAgICAgfVxuICAgICAgICByZWxhdGl2ZVRpbWVUaHJlc2hvbGRzW3RocmVzaG9sZF0gPSBsaW1pdDtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIG1vbWVudC5sYW5nID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50LmxhbmcgaXMgZGVwcmVjYXRlZC4gVXNlIG1vbWVudC5sb2NhbGUgaW5zdGVhZC4nLFxuICAgICAgICBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG1vbWVudC5sb2NhbGUoa2V5LCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIGxvYWQgbG9jYWxlIGFuZCB0aGVuIHNldCB0aGUgZ2xvYmFsIGxvY2FsZS4gIElmXG4gICAgLy8gbm8gYXJndW1lbnRzIGFyZSBwYXNzZWQgaW4sIGl0IHdpbGwgc2ltcGx5IHJldHVybiB0aGUgY3VycmVudCBnbG9iYWxcbiAgICAvLyBsb2NhbGUga2V5LlxuICAgIG1vbWVudC5sb2NhbGUgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZXMpIHtcbiAgICAgICAgdmFyIGRhdGE7XG4gICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YodmFsdWVzKSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gbW9tZW50LmRlZmluZUxvY2FsZShrZXksIHZhbHVlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gbW9tZW50LmxvY2FsZURhdGEoa2V5KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICBtb21lbnQuZHVyYXRpb24uX2xvY2FsZSA9IG1vbWVudC5fbG9jYWxlID0gZGF0YTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBtb21lbnQuX2xvY2FsZS5fYWJicjtcbiAgICB9O1xuXG4gICAgbW9tZW50LmRlZmluZUxvY2FsZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWVzLmFiYnIgPSBuYW1lO1xuICAgICAgICAgICAgaWYgKCFsb2NhbGVzW25hbWVdKSB7XG4gICAgICAgICAgICAgICAgbG9jYWxlc1tuYW1lXSA9IG5ldyBMb2NhbGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxvY2FsZXNbbmFtZV0uc2V0KHZhbHVlcyk7XG5cbiAgICAgICAgICAgIC8vIGJhY2t3YXJkcyBjb21wYXQgZm9yIG5vdzogYWxzbyBzZXQgdGhlIGxvY2FsZVxuICAgICAgICAgICAgbW9tZW50LmxvY2FsZShuYW1lKTtcblxuICAgICAgICAgICAgcmV0dXJuIGxvY2FsZXNbbmFtZV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyB1c2VmdWwgZm9yIHRlc3RpbmdcbiAgICAgICAgICAgIGRlbGV0ZSBsb2NhbGVzW25hbWVdO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgbW9tZW50LmxhbmdEYXRhID0gZGVwcmVjYXRlKFxuICAgICAgICAnbW9tZW50LmxhbmdEYXRhIGlzIGRlcHJlY2F0ZWQuIFVzZSBtb21lbnQubG9jYWxlRGF0YSBpbnN0ZWFkLicsXG4gICAgICAgIGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBtb21lbnQubG9jYWxlRGF0YShrZXkpO1xuICAgICAgICB9XG4gICAgKTtcblxuICAgIC8vIHJldHVybnMgbG9jYWxlIGRhdGFcbiAgICBtb21lbnQubG9jYWxlRGF0YSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgdmFyIGxvY2FsZTtcblxuICAgICAgICBpZiAoa2V5ICYmIGtleS5fbG9jYWxlICYmIGtleS5fbG9jYWxlLl9hYmJyKSB7XG4gICAgICAgICAgICBrZXkgPSBrZXkuX2xvY2FsZS5fYWJicjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgha2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gbW9tZW50Ll9sb2NhbGU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlzQXJyYXkoa2V5KSkge1xuICAgICAgICAgICAgLy9zaG9ydC1jaXJjdWl0IGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICAgICAgbG9jYWxlID0gbG9hZExvY2FsZShrZXkpO1xuICAgICAgICAgICAgaWYgKGxvY2FsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBsb2NhbGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBrZXkgPSBba2V5XTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjaG9vc2VMb2NhbGUoa2V5KTtcbiAgICB9O1xuXG4gICAgLy8gY29tcGFyZSBtb21lbnQgb2JqZWN0XG4gICAgbW9tZW50LmlzTW9tZW50ID0gZnVuY3Rpb24gKG9iaikge1xuICAgICAgICByZXR1cm4gb2JqIGluc3RhbmNlb2YgTW9tZW50IHx8XG4gICAgICAgICAgICAob2JqICE9IG51bGwgJiYgaGFzT3duUHJvcChvYmosICdfaXNBTW9tZW50T2JqZWN0JykpO1xuICAgIH07XG5cbiAgICAvLyBmb3IgdHlwZWNoZWNraW5nIER1cmF0aW9uIG9iamVjdHNcbiAgICBtb21lbnQuaXNEdXJhdGlvbiA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIG9iaiBpbnN0YW5jZW9mIER1cmF0aW9uO1xuICAgIH07XG5cbiAgICBmb3IgKGkgPSBsaXN0cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICBtYWtlTGlzdChsaXN0c1tpXSk7XG4gICAgfVxuXG4gICAgbW9tZW50Lm5vcm1hbGl6ZVVuaXRzID0gZnVuY3Rpb24gKHVuaXRzKSB7XG4gICAgICAgIHJldHVybiBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgfTtcblxuICAgIG1vbWVudC5pbnZhbGlkID0gZnVuY3Rpb24gKGZsYWdzKSB7XG4gICAgICAgIHZhciBtID0gbW9tZW50LnV0YyhOYU4pO1xuICAgICAgICBpZiAoZmxhZ3MgIT0gbnVsbCkge1xuICAgICAgICAgICAgZXh0ZW5kKG0uX3BmLCBmbGFncyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtLl9wZi51c2VySW52YWxpZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG07XG4gICAgfTtcblxuICAgIG1vbWVudC5wYXJzZVpvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQuYXBwbHkobnVsbCwgYXJndW1lbnRzKS5wYXJzZVpvbmUoKTtcbiAgICB9O1xuXG4gICAgbW9tZW50LnBhcnNlVHdvRGlnaXRZZWFyID0gZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgIHJldHVybiB0b0ludChpbnB1dCkgKyAodG9JbnQoaW5wdXQpID4gNjggPyAxOTAwIDogMjAwMCk7XG4gICAgfTtcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgTW9tZW50IFByb3RvdHlwZVxuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuXG4gICAgZXh0ZW5kKG1vbWVudC5mbiA9IE1vbWVudC5wcm90b3R5cGUsIHtcblxuICAgICAgICBjbG9uZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBtb21lbnQodGhpcyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgdmFsdWVPZiA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiArdGhpcy5fZCArICgodGhpcy5fb2Zmc2V0IHx8IDApICogNjAwMDApO1xuICAgICAgICB9LFxuXG4gICAgICAgIHVuaXggOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcigrdGhpcyAvIDEwMDApO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRvU3RyaW5nIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xvbmUoKS5sb2NhbGUoJ2VuJykuZm9ybWF0KCdkZGQgTU1NIEREIFlZWVkgSEg6bW06c3MgW0dNVF1aWicpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRvRGF0ZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vZmZzZXQgPyBuZXcgRGF0ZSgrdGhpcykgOiB0aGlzLl9kO1xuICAgICAgICB9LFxuXG4gICAgICAgIHRvSVNPU3RyaW5nIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIG0gPSBtb21lbnQodGhpcykudXRjKCk7XG4gICAgICAgICAgICBpZiAoMCA8IG0ueWVhcigpICYmIG0ueWVhcigpIDw9IDk5OTkpIHtcbiAgICAgICAgICAgICAgICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpcyB+NTB4IGZhc3RlciwgdXNlIGl0IHdoZW4gd2UgY2FuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCAnWVlZWS1NTS1ERFtUXUhIOm1tOnNzLlNTU1taXScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE1vbWVudChtLCAnWVlZWVlZLU1NLUREW1RdSEg6bW06c3MuU1NTW1pdJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgdG9BcnJheSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBtID0gdGhpcztcbiAgICAgICAgICAgIHJldHVybiBbXG4gICAgICAgICAgICAgICAgbS55ZWFyKCksXG4gICAgICAgICAgICAgICAgbS5tb250aCgpLFxuICAgICAgICAgICAgICAgIG0uZGF0ZSgpLFxuICAgICAgICAgICAgICAgIG0uaG91cnMoKSxcbiAgICAgICAgICAgICAgICBtLm1pbnV0ZXMoKSxcbiAgICAgICAgICAgICAgICBtLnNlY29uZHMoKSxcbiAgICAgICAgICAgICAgICBtLm1pbGxpc2Vjb25kcygpXG4gICAgICAgICAgICBdO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzVmFsaWQgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gaXNWYWxpZCh0aGlzKTtcbiAgICAgICAgfSxcblxuICAgICAgICBpc0RTVFNoaWZ0ZWQgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fYSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSAmJiBjb21wYXJlQXJyYXlzKHRoaXMuX2EsICh0aGlzLl9pc1VUQyA/IG1vbWVudC51dGModGhpcy5fYSkgOiBtb21lbnQodGhpcy5fYSkpLnRvQXJyYXkoKSkgPiAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcGFyc2luZ0ZsYWdzIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGV4dGVuZCh7fSwgdGhpcy5fcGYpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGludmFsaWRBdDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BmLm92ZXJmbG93O1xuICAgICAgICB9LFxuXG4gICAgICAgIHV0YyA6IGZ1bmN0aW9uIChrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy56b25lKDAsIGtlZXBMb2NhbFRpbWUpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGxvY2FsIDogZnVuY3Rpb24gKGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc1VUQykge1xuICAgICAgICAgICAgICAgIHRoaXMuem9uZSgwLCBrZWVwTG9jYWxUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc1VUQyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgaWYgKGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGQodGhpcy5fZGF0ZVR6T2Zmc2V0KCksICdtJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZm9ybWF0IDogZnVuY3Rpb24gKGlucHV0U3RyaW5nKSB7XG4gICAgICAgICAgICB2YXIgb3V0cHV0ID0gZm9ybWF0TW9tZW50KHRoaXMsIGlucHV0U3RyaW5nIHx8IG1vbWVudC5kZWZhdWx0Rm9ybWF0KTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsZURhdGEoKS5wb3N0Zm9ybWF0KG91dHB1dCk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYWRkIDogY3JlYXRlQWRkZXIoMSwgJ2FkZCcpLFxuXG4gICAgICAgIHN1YnRyYWN0IDogY3JlYXRlQWRkZXIoLTEsICdzdWJ0cmFjdCcpLFxuXG4gICAgICAgIGRpZmYgOiBmdW5jdGlvbiAoaW5wdXQsIHVuaXRzLCBhc0Zsb2F0KSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IG1ha2VBcyhpbnB1dCwgdGhpcyksXG4gICAgICAgICAgICAgICAgem9uZURpZmYgPSAodGhpcy56b25lKCkgLSB0aGF0LnpvbmUoKSkgKiA2ZTQsXG4gICAgICAgICAgICAgICAgZGlmZiwgb3V0cHV0LCBkYXlzQWRqdXN0O1xuXG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcblxuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAneWVhcicgfHwgdW5pdHMgPT09ICdtb250aCcpIHtcbiAgICAgICAgICAgICAgICAvLyBhdmVyYWdlIG51bWJlciBvZiBkYXlzIGluIHRoZSBtb250aHMgaW4gdGhlIGdpdmVuIGRhdGVzXG4gICAgICAgICAgICAgICAgZGlmZiA9ICh0aGlzLmRheXNJbk1vbnRoKCkgKyB0aGF0LmRheXNJbk1vbnRoKCkpICogNDMyZTU7IC8vIDI0ICogNjAgKiA2MCAqIDEwMDAgLyAyXG4gICAgICAgICAgICAgICAgLy8gZGlmZmVyZW5jZSBpbiBtb250aHNcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSAoKHRoaXMueWVhcigpIC0gdGhhdC55ZWFyKCkpICogMTIpICsgKHRoaXMubW9udGgoKSAtIHRoYXQubW9udGgoKSk7XG4gICAgICAgICAgICAgICAgLy8gYWRqdXN0IGJ5IHRha2luZyBkaWZmZXJlbmNlIGluIGRheXMsIGF2ZXJhZ2UgbnVtYmVyIG9mIGRheXNcbiAgICAgICAgICAgICAgICAvLyBhbmQgZHN0IGluIHRoZSBnaXZlbiBtb250aHMuXG4gICAgICAgICAgICAgICAgZGF5c0FkanVzdCA9ICh0aGlzIC0gbW9tZW50KHRoaXMpLnN0YXJ0T2YoJ21vbnRoJykpIC1cbiAgICAgICAgICAgICAgICAgICAgKHRoYXQgLSBtb21lbnQodGhhdCkuc3RhcnRPZignbW9udGgnKSk7XG4gICAgICAgICAgICAgICAgLy8gc2FtZSBhcyBhYm92ZSBidXQgd2l0aCB6b25lcywgdG8gbmVnYXRlIGFsbCBkc3RcbiAgICAgICAgICAgICAgICBkYXlzQWRqdXN0IC09ICgodGhpcy56b25lKCkgLSBtb21lbnQodGhpcykuc3RhcnRPZignbW9udGgnKS56b25lKCkpIC1cbiAgICAgICAgICAgICAgICAgICAgICAgICh0aGF0LnpvbmUoKSAtIG1vbWVudCh0aGF0KS5zdGFydE9mKCdtb250aCcpLnpvbmUoKSkpICogNmU0O1xuICAgICAgICAgICAgICAgIG91dHB1dCArPSBkYXlzQWRqdXN0IC8gZGlmZjtcbiAgICAgICAgICAgICAgICBpZiAodW5pdHMgPT09ICd5ZWFyJykge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXQgPSBvdXRwdXQgLyAxMjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRpZmYgPSAodGhpcyAtIHRoYXQpO1xuICAgICAgICAgICAgICAgIG91dHB1dCA9IHVuaXRzID09PSAnc2Vjb25kJyA/IGRpZmYgLyAxZTMgOiAvLyAxMDAwXG4gICAgICAgICAgICAgICAgICAgIHVuaXRzID09PSAnbWludXRlJyA/IGRpZmYgLyA2ZTQgOiAvLyAxMDAwICogNjBcbiAgICAgICAgICAgICAgICAgICAgdW5pdHMgPT09ICdob3VyJyA/IGRpZmYgLyAzNmU1IDogLy8gMTAwMCAqIDYwICogNjBcbiAgICAgICAgICAgICAgICAgICAgdW5pdHMgPT09ICdkYXknID8gKGRpZmYgLSB6b25lRGlmZikgLyA4NjRlNSA6IC8vIDEwMDAgKiA2MCAqIDYwICogMjQsIG5lZ2F0ZSBkc3RcbiAgICAgICAgICAgICAgICAgICAgdW5pdHMgPT09ICd3ZWVrJyA/IChkaWZmIC0gem9uZURpZmYpIC8gNjA0OGU1IDogLy8gMTAwMCAqIDYwICogNjAgKiAyNCAqIDcsIG5lZ2F0ZSBkc3RcbiAgICAgICAgICAgICAgICAgICAgZGlmZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhc0Zsb2F0ID8gb3V0cHV0IDogYWJzUm91bmQob3V0cHV0KTtcbiAgICAgICAgfSxcblxuICAgICAgICBmcm9tIDogZnVuY3Rpb24gKHRpbWUsIHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgICAgIHJldHVybiBtb21lbnQuZHVyYXRpb24oe3RvOiB0aGlzLCBmcm9tOiB0aW1lfSkubG9jYWxlKHRoaXMubG9jYWxlKCkpLmh1bWFuaXplKCF3aXRob3V0U3VmZml4KTtcbiAgICAgICAgfSxcblxuICAgICAgICBmcm9tTm93IDogZnVuY3Rpb24gKHdpdGhvdXRTdWZmaXgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZyb20obW9tZW50KCksIHdpdGhvdXRTdWZmaXgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGNhbGVuZGFyIDogZnVuY3Rpb24gKHRpbWUpIHtcbiAgICAgICAgICAgIC8vIFdlIHdhbnQgdG8gY29tcGFyZSB0aGUgc3RhcnQgb2YgdG9kYXksIHZzIHRoaXMuXG4gICAgICAgICAgICAvLyBHZXR0aW5nIHN0YXJ0LW9mLXRvZGF5IGRlcGVuZHMgb24gd2hldGhlciB3ZSdyZSB6b25lJ2Qgb3Igbm90LlxuICAgICAgICAgICAgdmFyIG5vdyA9IHRpbWUgfHwgbW9tZW50KCksXG4gICAgICAgICAgICAgICAgc29kID0gbWFrZUFzKG5vdywgdGhpcykuc3RhcnRPZignZGF5JyksXG4gICAgICAgICAgICAgICAgZGlmZiA9IHRoaXMuZGlmZihzb2QsICdkYXlzJywgdHJ1ZSksXG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gZGlmZiA8IC02ID8gJ3NhbWVFbHNlJyA6XG4gICAgICAgICAgICAgICAgICAgIGRpZmYgPCAtMSA/ICdsYXN0V2VlaycgOlxuICAgICAgICAgICAgICAgICAgICBkaWZmIDwgMCA/ICdsYXN0RGF5JyA6XG4gICAgICAgICAgICAgICAgICAgIGRpZmYgPCAxID8gJ3NhbWVEYXknIDpcbiAgICAgICAgICAgICAgICAgICAgZGlmZiA8IDIgPyAnbmV4dERheScgOlxuICAgICAgICAgICAgICAgICAgICBkaWZmIDwgNyA/ICduZXh0V2VlaycgOiAnc2FtZUVsc2UnO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHRoaXMubG9jYWxlRGF0YSgpLmNhbGVuZGFyKGZvcm1hdCwgdGhpcywgbW9tZW50KG5vdykpKTtcbiAgICAgICAgfSxcblxuICAgICAgICBpc0xlYXBZZWFyIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGlzTGVhcFllYXIodGhpcy55ZWFyKCkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzRFNUIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICh0aGlzLnpvbmUoKSA8IHRoaXMuY2xvbmUoKS5tb250aCgwKS56b25lKCkgfHxcbiAgICAgICAgICAgICAgICB0aGlzLnpvbmUoKSA8IHRoaXMuY2xvbmUoKS5tb250aCg1KS56b25lKCkpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGRheSA6IGZ1bmN0aW9uIChpbnB1dCkge1xuICAgICAgICAgICAgdmFyIGRheSA9IHRoaXMuX2lzVVRDID8gdGhpcy5fZC5nZXRVVENEYXkoKSA6IHRoaXMuX2QuZ2V0RGF5KCk7XG4gICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlucHV0ID0gcGFyc2VXZWVrZGF5KGlucHV0LCB0aGlzLmxvY2FsZURhdGEoKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRkKGlucHV0IC0gZGF5LCAnZCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF5O1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIG1vbnRoIDogbWFrZUFjY2Vzc29yKCdNb250aCcsIHRydWUpLFxuXG4gICAgICAgIHN0YXJ0T2YgOiBmdW5jdGlvbiAodW5pdHMpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICAgICAgLy8gdGhlIGZvbGxvd2luZyBzd2l0Y2ggaW50ZW50aW9uYWxseSBvbWl0cyBicmVhayBrZXl3b3Jkc1xuICAgICAgICAgICAgLy8gdG8gdXRpbGl6ZSBmYWxsaW5nIHRocm91Z2ggdGhlIGNhc2VzLlxuICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGhpcy5tb250aCgwKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGUoMSk7XG4gICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgICAgICBjYXNlICdpc29XZWVrJzpcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICAgICAgdGhpcy5ob3VycygwKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgICAgICB0aGlzLm1pbnV0ZXMoMCk7XG4gICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICAgICAgY2FzZSAnbWludXRlJzpcbiAgICAgICAgICAgICAgICB0aGlzLnNlY29uZHMoMCk7XG4gICAgICAgICAgICAgICAgLyogZmFsbHMgdGhyb3VnaCAqL1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgICB0aGlzLm1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgICAvKiBmYWxscyB0aHJvdWdoICovXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHdlZWtzIGFyZSBhIHNwZWNpYWwgY2FzZVxuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAnd2VlaycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLndlZWtkYXkoMCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHVuaXRzID09PSAnaXNvV2VlaycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzb1dlZWtkYXkoMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHF1YXJ0ZXJzIGFyZSBhbHNvIHNwZWNpYWxcbiAgICAgICAgICAgIGlmICh1bml0cyA9PT0gJ3F1YXJ0ZXInKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tb250aChNYXRoLmZsb29yKHRoaXMubW9udGgoKSAvIDMpICogMyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGVuZE9mOiBmdW5jdGlvbiAodW5pdHMpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICAgICAgaWYgKHVuaXRzID09PSB1bmRlZmluZWQgfHwgdW5pdHMgPT09ICdtaWxsaXNlY29uZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0T2YodW5pdHMpLmFkZCgxLCAodW5pdHMgPT09ICdpc29XZWVrJyA/ICd3ZWVrJyA6IHVuaXRzKSkuc3VidHJhY3QoMSwgJ21zJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNBZnRlcjogZnVuY3Rpb24gKGlucHV0LCB1bml0cykge1xuICAgICAgICAgICAgdmFyIGlucHV0TXM7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHR5cGVvZiB1bml0cyAhPT0gJ3VuZGVmaW5lZCcgPyB1bml0cyA6ICdtaWxsaXNlY29uZCcpO1xuICAgICAgICAgICAgaWYgKHVuaXRzID09PSAnbWlsbGlzZWNvbmQnKSB7XG4gICAgICAgICAgICAgICAgaW5wdXQgPSBtb21lbnQuaXNNb21lbnQoaW5wdXQpID8gaW5wdXQgOiBtb21lbnQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiArdGhpcyA+ICtpbnB1dDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5wdXRNcyA9IG1vbWVudC5pc01vbWVudChpbnB1dCkgPyAraW5wdXQgOiArbW9tZW50KGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRNcyA8ICt0aGlzLmNsb25lKCkuc3RhcnRPZih1bml0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgaXNCZWZvcmU6IGZ1bmN0aW9uIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgICAgIHZhciBpbnB1dE1zO1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh0eXBlb2YgdW5pdHMgIT09ICd1bmRlZmluZWQnID8gdW5pdHMgOiAnbWlsbGlzZWNvbmQnKTtcbiAgICAgICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgICAgIGlucHV0ID0gbW9tZW50LmlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogbW9tZW50KGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gK3RoaXMgPCAraW5wdXQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlucHV0TXMgPSBtb21lbnQuaXNNb21lbnQoaW5wdXQpID8gK2lucHV0IDogK21vbWVudChpbnB1dCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuICt0aGlzLmNsb25lKCkuZW5kT2YodW5pdHMpIDwgaW5wdXRNcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBpc1NhbWU6IGZ1bmN0aW9uIChpbnB1dCwgdW5pdHMpIHtcbiAgICAgICAgICAgIHZhciBpbnB1dE1zO1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyB8fCAnbWlsbGlzZWNvbmQnKTtcbiAgICAgICAgICAgIGlmICh1bml0cyA9PT0gJ21pbGxpc2Vjb25kJykge1xuICAgICAgICAgICAgICAgIGlucHV0ID0gbW9tZW50LmlzTW9tZW50KGlucHV0KSA/IGlucHV0IDogbW9tZW50KGlucHV0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gK3RoaXMgPT09ICtpbnB1dDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5wdXRNcyA9ICttb21lbnQoaW5wdXQpO1xuICAgICAgICAgICAgICAgIHJldHVybiArKHRoaXMuY2xvbmUoKS5zdGFydE9mKHVuaXRzKSkgPD0gaW5wdXRNcyAmJiBpbnB1dE1zIDw9ICsodGhpcy5jbG9uZSgpLmVuZE9mKHVuaXRzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgbWluOiBkZXByZWNhdGUoXG4gICAgICAgICAgICAgICAgICdtb21lbnQoKS5taW4gaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5taW4gaW5zdGVhZC4gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE1NDgnLFxuICAgICAgICAgICAgICAgICBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgIG90aGVyID0gbW9tZW50LmFwcGx5KG51bGwsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPCB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgICAgICB9XG4gICAgICAgICApLFxuXG4gICAgICAgIG1heDogZGVwcmVjYXRlKFxuICAgICAgICAgICAgICAgICdtb21lbnQoKS5tYXggaXMgZGVwcmVjYXRlZCwgdXNlIG1vbWVudC5tYXggaW5zdGVhZC4gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvaXNzdWVzLzE1NDgnLFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICAgICAgICAgICAgICBvdGhlciA9IG1vbWVudC5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3RoZXIgPiB0aGlzID8gdGhpcyA6IG90aGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgKSxcblxuICAgICAgICAvLyBrZWVwTG9jYWxUaW1lID0gdHJ1ZSBtZWFucyBvbmx5IGNoYW5nZSB0aGUgdGltZXpvbmUsIHdpdGhvdXRcbiAgICAgICAgLy8gYWZmZWN0aW5nIHRoZSBsb2NhbCBob3VyLiBTbyA1OjMxOjI2ICswMzAwIC0tW3pvbmUoMiwgdHJ1ZSldLS0+XG4gICAgICAgIC8vIDU6MzE6MjYgKzAyMDAgSXQgaXMgcG9zc2libGUgdGhhdCA1OjMxOjI2IGRvZXNuJ3QgZXhpc3QgaW50IHpvbmVcbiAgICAgICAgLy8gKzAyMDAsIHNvIHdlIGFkanVzdCB0aGUgdGltZSBhcyBuZWVkZWQsIHRvIGJlIHZhbGlkLlxuICAgICAgICAvL1xuICAgICAgICAvLyBLZWVwaW5nIHRoZSB0aW1lIGFjdHVhbGx5IGFkZHMvc3VidHJhY3RzIChvbmUgaG91cilcbiAgICAgICAgLy8gZnJvbSB0aGUgYWN0dWFsIHJlcHJlc2VudGVkIHRpbWUuIFRoYXQgaXMgd2h5IHdlIGNhbGwgdXBkYXRlT2Zmc2V0XG4gICAgICAgIC8vIGEgc2Vjb25kIHRpbWUuIEluIGNhc2UgaXQgd2FudHMgdXMgdG8gY2hhbmdlIHRoZSBvZmZzZXQgYWdhaW5cbiAgICAgICAgLy8gX2NoYW5nZUluUHJvZ3Jlc3MgPT0gdHJ1ZSBjYXNlLCB0aGVuIHdlIGhhdmUgdG8gYWRqdXN0LCBiZWNhdXNlXG4gICAgICAgIC8vIHRoZXJlIGlzIG5vIHN1Y2ggdGltZSBpbiB0aGUgZ2l2ZW4gdGltZXpvbmUuXG4gICAgICAgIHpvbmUgOiBmdW5jdGlvbiAoaW5wdXQsIGtlZXBMb2NhbFRpbWUpIHtcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSB0aGlzLl9vZmZzZXQgfHwgMCxcbiAgICAgICAgICAgICAgICBsb2NhbEFkanVzdDtcbiAgICAgICAgICAgIGlmIChpbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQgPSB0aW1lem9uZU1pbnV0ZXNGcm9tU3RyaW5nKGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKGlucHV0KSA8IDE2KSB7XG4gICAgICAgICAgICAgICAgICAgIGlucHV0ID0gaW5wdXQgKiA2MDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9pc1VUQyAmJiBrZWVwTG9jYWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvY2FsQWRqdXN0ID0gdGhpcy5fZGF0ZVR6T2Zmc2V0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX29mZnNldCA9IGlucHV0O1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzVVRDID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAobG9jYWxBZGp1c3QgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN1YnRyYWN0KGxvY2FsQWRqdXN0LCAnbScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ICE9PSBpbnB1dCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWtlZXBMb2NhbFRpbWUgfHwgdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkT3JTdWJ0cmFjdER1cmF0aW9uRnJvbU1vbWVudCh0aGlzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb21lbnQuZHVyYXRpb24ob2Zmc2V0IC0gaW5wdXQsICdtJyksIDEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb21lbnQudXBkYXRlT2Zmc2V0KHRoaXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlSW5Qcm9ncmVzcyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9pc1VUQyA/IG9mZnNldCA6IHRoaXMuX2RhdGVUek9mZnNldCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgem9uZUFiYnIgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faXNVVEMgPyAnVVRDJyA6ICcnO1xuICAgICAgICB9LFxuXG4gICAgICAgIHpvbmVOYW1lIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2lzVVRDID8gJ0Nvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lJyA6ICcnO1xuICAgICAgICB9LFxuXG4gICAgICAgIHBhcnNlWm9uZSA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl90em0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnpvbmUodGhpcy5fdHptKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2kgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy56b25lKHRoaXMuX2kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgaGFzQWxpZ25lZEhvdXJPZmZzZXQgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIGlmICghaW5wdXQpIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnB1dCA9IG1vbWVudChpbnB1dCkuem9uZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKHRoaXMuem9uZSgpIC0gaW5wdXQpICUgNjAgPT09IDA7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGF5c0luTW9udGggOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF5c0luTW9udGgodGhpcy55ZWFyKCksIHRoaXMubW9udGgoKSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZGF5T2ZZZWFyIDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgZGF5T2ZZZWFyID0gcm91bmQoKG1vbWVudCh0aGlzKS5zdGFydE9mKCdkYXknKSAtIG1vbWVudCh0aGlzKS5zdGFydE9mKCd5ZWFyJykpIC8gODY0ZTUpICsgMTtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gZGF5T2ZZZWFyIDogdGhpcy5hZGQoKGlucHV0IC0gZGF5T2ZZZWFyKSwgJ2QnKTtcbiAgICAgICAgfSxcblxuICAgICAgICBxdWFydGVyIDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgPT0gbnVsbCA/IE1hdGguY2VpbCgodGhpcy5tb250aCgpICsgMSkgLyAzKSA6IHRoaXMubW9udGgoKGlucHV0IC0gMSkgKiAzICsgdGhpcy5tb250aCgpICUgMyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgd2Vla1llYXIgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB5ZWFyID0gd2Vla09mWWVhcih0aGlzLCB0aGlzLmxvY2FsZURhdGEoKS5fd2Vlay5kb3csIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRveSkueWVhcjtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8geWVhciA6IHRoaXMuYWRkKChpbnB1dCAtIHllYXIpLCAneScpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzb1dlZWtZZWFyIDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgeWVhciA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkueWVhcjtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8geWVhciA6IHRoaXMuYWRkKChpbnB1dCAtIHllYXIpLCAneScpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHdlZWsgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrID0gdGhpcy5sb2NhbGVEYXRhKCkud2Vlayh0aGlzKTtcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICAgICAgfSxcblxuICAgICAgICBpc29XZWVrIDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgd2VlayA9IHdlZWtPZlllYXIodGhpcywgMSwgNCkud2VlaztcbiAgICAgICAgICAgIHJldHVybiBpbnB1dCA9PSBudWxsID8gd2VlayA6IHRoaXMuYWRkKChpbnB1dCAtIHdlZWspICogNywgJ2QnKTtcbiAgICAgICAgfSxcblxuICAgICAgICB3ZWVrZGF5IDogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgICAgICAgICB2YXIgd2Vla2RheSA9ICh0aGlzLmRheSgpICsgNyAtIHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrLmRvdykgJSA3O1xuICAgICAgICAgICAgcmV0dXJuIGlucHV0ID09IG51bGwgPyB3ZWVrZGF5IDogdGhpcy5hZGQoaW5wdXQgLSB3ZWVrZGF5LCAnZCcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzb1dlZWtkYXkgOiBmdW5jdGlvbiAoaW5wdXQpIHtcbiAgICAgICAgICAgIC8vIGJlaGF2ZXMgdGhlIHNhbWUgYXMgbW9tZW50I2RheSBleGNlcHRcbiAgICAgICAgICAgIC8vIGFzIGEgZ2V0dGVyLCByZXR1cm5zIDcgaW5zdGVhZCBvZiAwICgxLTcgcmFuZ2UgaW5zdGVhZCBvZiAwLTYpXG4gICAgICAgICAgICAvLyBhcyBhIHNldHRlciwgc3VuZGF5IHNob3VsZCBiZWxvbmcgdG8gdGhlIHByZXZpb3VzIHdlZWsuXG4gICAgICAgICAgICByZXR1cm4gaW5wdXQgPT0gbnVsbCA/IHRoaXMuZGF5KCkgfHwgNyA6IHRoaXMuZGF5KHRoaXMuZGF5KCkgJSA3ID8gaW5wdXQgOiBpbnB1dCAtIDcpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGlzb1dlZWtzSW5ZZWFyIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCAxLCA0KTtcbiAgICAgICAgfSxcblxuICAgICAgICB3ZWVrc0luWWVhciA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB3ZWVrSW5mbyA9IHRoaXMubG9jYWxlRGF0YSgpLl93ZWVrO1xuICAgICAgICAgICAgcmV0dXJuIHdlZWtzSW5ZZWFyKHRoaXMueWVhcigpLCB3ZWVrSW5mby5kb3csIHdlZWtJbmZvLmRveSk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgZ2V0IDogZnVuY3Rpb24gKHVuaXRzKSB7XG4gICAgICAgICAgICB1bml0cyA9IG5vcm1hbGl6ZVVuaXRzKHVuaXRzKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzW3VuaXRzXSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHNldCA6IGZ1bmN0aW9uICh1bml0cywgdmFsdWUpIHtcbiAgICAgICAgICAgIHVuaXRzID0gbm9ybWFsaXplVW5pdHModW5pdHMpO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzW3VuaXRzXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRoaXNbdW5pdHNdKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIElmIHBhc3NlZCBhIGxvY2FsZSBrZXksIGl0IHdpbGwgc2V0IHRoZSBsb2NhbGUgZm9yIHRoaXNcbiAgICAgICAgLy8gaW5zdGFuY2UuICBPdGhlcndpc2UsIGl0IHdpbGwgcmV0dXJuIHRoZSBsb2NhbGUgY29uZmlndXJhdGlvblxuICAgICAgICAvLyB2YXJpYWJsZXMgZm9yIHRoaXMgaW5zdGFuY2UuXG4gICAgICAgIGxvY2FsZSA6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgIHZhciBuZXdMb2NhbGVEYXRhO1xuXG4gICAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlLl9hYmJyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdMb2NhbGVEYXRhID0gbW9tZW50LmxvY2FsZURhdGEoa2V5KTtcbiAgICAgICAgICAgICAgICBpZiAobmV3TG9jYWxlRGF0YSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xvY2FsZSA9IG5ld0xvY2FsZURhdGE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGxhbmcgOiBkZXByZWNhdGUoXG4gICAgICAgICAgICAnbW9tZW50KCkubGFuZygpIGlzIGRlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZSBtb21lbnQoKS5sb2NhbGVEYXRhKCkgdG8gZ2V0IHRoZSBsYW5ndWFnZSBjb25maWd1cmF0aW9uLiBVc2UgbW9tZW50KCkubG9jYWxlKCkgdG8gY2hhbmdlIGxhbmd1YWdlcy4nLFxuICAgICAgICAgICAgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubG9jYWxlKGtleSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICApLFxuXG4gICAgICAgIGxvY2FsZURhdGEgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbG9jYWxlO1xuICAgICAgICB9LFxuXG4gICAgICAgIF9kYXRlVHpPZmZzZXQgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBPbiBGaXJlZm94LjI0IERhdGUjZ2V0VGltZXpvbmVPZmZzZXQgcmV0dXJucyBhIGZsb2F0aW5nIHBvaW50LlxuICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbWVudC9tb21lbnQvcHVsbC8xODcxXG4gICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9kLmdldFRpbWV6b25lT2Zmc2V0KCkgLyAxNSkgKiAxNTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gcmF3TW9udGhTZXR0ZXIobW9tLCB2YWx1ZSkge1xuICAgICAgICB2YXIgZGF5T2ZNb250aDtcblxuICAgICAgICAvLyBUT0RPOiBNb3ZlIHRoaXMgb3V0IG9mIGhlcmUhXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IG1vbS5sb2NhbGVEYXRhKCkubW9udGhzUGFyc2UodmFsdWUpO1xuICAgICAgICAgICAgLy8gVE9ETzogQW5vdGhlciBzaWxlbnQgZmFpbHVyZT9cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1vbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGRheU9mTW9udGggPSBNYXRoLm1pbihtb20uZGF0ZSgpLFxuICAgICAgICAgICAgICAgIGRheXNJbk1vbnRoKG1vbS55ZWFyKCksIHZhbHVlKSk7XG4gICAgICAgIG1vbS5fZFsnc2V0JyArIChtb20uX2lzVVRDID8gJ1VUQycgOiAnJykgKyAnTW9udGgnXSh2YWx1ZSwgZGF5T2ZNb250aCk7XG4gICAgICAgIHJldHVybiBtb207XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmF3R2V0dGVyKG1vbSwgdW5pdCkge1xuICAgICAgICByZXR1cm4gbW9tLl9kWydnZXQnICsgKG1vbS5faXNVVEMgPyAnVVRDJyA6ICcnKSArIHVuaXRdKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmF3U2V0dGVyKG1vbSwgdW5pdCwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHVuaXQgPT09ICdNb250aCcpIHtcbiAgICAgICAgICAgIHJldHVybiByYXdNb250aFNldHRlcihtb20sIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBtb20uX2RbJ3NldCcgKyAobW9tLl9pc1VUQyA/ICdVVEMnIDogJycpICsgdW5pdF0odmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbWFrZUFjY2Vzc29yKHVuaXQsIGtlZXBUaW1lKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmF3U2V0dGVyKHRoaXMsIHVuaXQsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICBtb21lbnQudXBkYXRlT2Zmc2V0KHRoaXMsIGtlZXBUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJhd0dldHRlcih0aGlzLCB1bml0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBtb21lbnQuZm4ubWlsbGlzZWNvbmQgPSBtb21lbnQuZm4ubWlsbGlzZWNvbmRzID0gbWFrZUFjY2Vzc29yKCdNaWxsaXNlY29uZHMnLCBmYWxzZSk7XG4gICAgbW9tZW50LmZuLnNlY29uZCA9IG1vbWVudC5mbi5zZWNvbmRzID0gbWFrZUFjY2Vzc29yKCdTZWNvbmRzJywgZmFsc2UpO1xuICAgIG1vbWVudC5mbi5taW51dGUgPSBtb21lbnQuZm4ubWludXRlcyA9IG1ha2VBY2Nlc3NvcignTWludXRlcycsIGZhbHNlKTtcbiAgICAvLyBTZXR0aW5nIHRoZSBob3VyIHNob3VsZCBrZWVwIHRoZSB0aW1lLCBiZWNhdXNlIHRoZSB1c2VyIGV4cGxpY2l0bHlcbiAgICAvLyBzcGVjaWZpZWQgd2hpY2ggaG91ciBoZSB3YW50cy4gU28gdHJ5aW5nIHRvIG1haW50YWluIHRoZSBzYW1lIGhvdXIgKGluXG4gICAgLy8gYSBuZXcgdGltZXpvbmUpIG1ha2VzIHNlbnNlLiBBZGRpbmcvc3VidHJhY3RpbmcgaG91cnMgZG9lcyBub3QgZm9sbG93XG4gICAgLy8gdGhpcyBydWxlLlxuICAgIG1vbWVudC5mbi5ob3VyID0gbW9tZW50LmZuLmhvdXJzID0gbWFrZUFjY2Vzc29yKCdIb3VycycsIHRydWUpO1xuICAgIC8vIG1vbWVudC5mbi5tb250aCBpcyBkZWZpbmVkIHNlcGFyYXRlbHlcbiAgICBtb21lbnQuZm4uZGF0ZSA9IG1ha2VBY2Nlc3NvcignRGF0ZScsIHRydWUpO1xuICAgIG1vbWVudC5mbi5kYXRlcyA9IGRlcHJlY2F0ZSgnZGF0ZXMgYWNjZXNzb3IgaXMgZGVwcmVjYXRlZC4gVXNlIGRhdGUgaW5zdGVhZC4nLCBtYWtlQWNjZXNzb3IoJ0RhdGUnLCB0cnVlKSk7XG4gICAgbW9tZW50LmZuLnllYXIgPSBtYWtlQWNjZXNzb3IoJ0Z1bGxZZWFyJywgdHJ1ZSk7XG4gICAgbW9tZW50LmZuLnllYXJzID0gZGVwcmVjYXRlKCd5ZWFycyBhY2Nlc3NvciBpcyBkZXByZWNhdGVkLiBVc2UgeWVhciBpbnN0ZWFkLicsIG1ha2VBY2Nlc3NvcignRnVsbFllYXInLCB0cnVlKSk7XG5cbiAgICAvLyBhZGQgcGx1cmFsIG1ldGhvZHNcbiAgICBtb21lbnQuZm4uZGF5cyA9IG1vbWVudC5mbi5kYXk7XG4gICAgbW9tZW50LmZuLm1vbnRocyA9IG1vbWVudC5mbi5tb250aDtcbiAgICBtb21lbnQuZm4ud2Vla3MgPSBtb21lbnQuZm4ud2VlaztcbiAgICBtb21lbnQuZm4uaXNvV2Vla3MgPSBtb21lbnQuZm4uaXNvV2VlaztcbiAgICBtb21lbnQuZm4ucXVhcnRlcnMgPSBtb21lbnQuZm4ucXVhcnRlcjtcblxuICAgIC8vIGFkZCBhbGlhc2VkIGZvcm1hdCBtZXRob2RzXG4gICAgbW9tZW50LmZuLnRvSlNPTiA9IG1vbWVudC5mbi50b0lTT1N0cmluZztcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgRHVyYXRpb24gUHJvdG90eXBlXG4gICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5cbiAgICBmdW5jdGlvbiBkYXlzVG9ZZWFycyAoZGF5cykge1xuICAgICAgICAvLyA0MDAgeWVhcnMgaGF2ZSAxNDYwOTcgZGF5cyAodGFraW5nIGludG8gYWNjb3VudCBsZWFwIHllYXIgcnVsZXMpXG4gICAgICAgIHJldHVybiBkYXlzICogNDAwIC8gMTQ2MDk3O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHllYXJzVG9EYXlzICh5ZWFycykge1xuICAgICAgICAvLyB5ZWFycyAqIDM2NSArIGFic1JvdW5kKHllYXJzIC8gNCkgLVxuICAgICAgICAvLyAgICAgYWJzUm91bmQoeWVhcnMgLyAxMDApICsgYWJzUm91bmQoeWVhcnMgLyA0MDApO1xuICAgICAgICByZXR1cm4geWVhcnMgKiAxNDYwOTcgLyA0MDA7XG4gICAgfVxuXG4gICAgZXh0ZW5kKG1vbWVudC5kdXJhdGlvbi5mbiA9IER1cmF0aW9uLnByb3RvdHlwZSwge1xuXG4gICAgICAgIF9idWJibGUgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgbWlsbGlzZWNvbmRzID0gdGhpcy5fbWlsbGlzZWNvbmRzLFxuICAgICAgICAgICAgICAgIGRheXMgPSB0aGlzLl9kYXlzLFxuICAgICAgICAgICAgICAgIG1vbnRocyA9IHRoaXMuX21vbnRocyxcbiAgICAgICAgICAgICAgICBkYXRhID0gdGhpcy5fZGF0YSxcbiAgICAgICAgICAgICAgICBzZWNvbmRzLCBtaW51dGVzLCBob3VycywgeWVhcnMgPSAwO1xuXG4gICAgICAgICAgICAvLyBUaGUgZm9sbG93aW5nIGNvZGUgYnViYmxlcyB1cCB2YWx1ZXMsIHNlZSB0aGUgdGVzdHMgZm9yXG4gICAgICAgICAgICAvLyBleGFtcGxlcyBvZiB3aGF0IHRoYXQgbWVhbnMuXG4gICAgICAgICAgICBkYXRhLm1pbGxpc2Vjb25kcyA9IG1pbGxpc2Vjb25kcyAlIDEwMDA7XG5cbiAgICAgICAgICAgIHNlY29uZHMgPSBhYnNSb3VuZChtaWxsaXNlY29uZHMgLyAxMDAwKTtcbiAgICAgICAgICAgIGRhdGEuc2Vjb25kcyA9IHNlY29uZHMgJSA2MDtcblxuICAgICAgICAgICAgbWludXRlcyA9IGFic1JvdW5kKHNlY29uZHMgLyA2MCk7XG4gICAgICAgICAgICBkYXRhLm1pbnV0ZXMgPSBtaW51dGVzICUgNjA7XG5cbiAgICAgICAgICAgIGhvdXJzID0gYWJzUm91bmQobWludXRlcyAvIDYwKTtcbiAgICAgICAgICAgIGRhdGEuaG91cnMgPSBob3VycyAlIDI0O1xuXG4gICAgICAgICAgICBkYXlzICs9IGFic1JvdW5kKGhvdXJzIC8gMjQpO1xuXG4gICAgICAgICAgICAvLyBBY2N1cmF0ZWx5IGNvbnZlcnQgZGF5cyB0byB5ZWFycywgYXNzdW1lIHN0YXJ0IGZyb20geWVhciAwLlxuICAgICAgICAgICAgeWVhcnMgPSBhYnNSb3VuZChkYXlzVG9ZZWFycyhkYXlzKSk7XG4gICAgICAgICAgICBkYXlzIC09IGFic1JvdW5kKHllYXJzVG9EYXlzKHllYXJzKSk7XG5cbiAgICAgICAgICAgIC8vIDMwIGRheXMgdG8gYSBtb250aFxuICAgICAgICAgICAgLy8gVE9ETyAoaXNrcmVuKTogVXNlIGFuY2hvciBkYXRlIChsaWtlIDFzdCBKYW4pIHRvIGNvbXB1dGUgdGhpcy5cbiAgICAgICAgICAgIG1vbnRocyArPSBhYnNSb3VuZChkYXlzIC8gMzApO1xuICAgICAgICAgICAgZGF5cyAlPSAzMDtcblxuICAgICAgICAgICAgLy8gMTIgbW9udGhzIC0+IDEgeWVhclxuICAgICAgICAgICAgeWVhcnMgKz0gYWJzUm91bmQobW9udGhzIC8gMTIpO1xuICAgICAgICAgICAgbW9udGhzICU9IDEyO1xuXG4gICAgICAgICAgICBkYXRhLmRheXMgPSBkYXlzO1xuICAgICAgICAgICAgZGF0YS5tb250aHMgPSBtb250aHM7XG4gICAgICAgICAgICBkYXRhLnllYXJzID0geWVhcnM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgYWJzIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5fbWlsbGlzZWNvbmRzID0gTWF0aC5hYnModGhpcy5fbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgICAgIHRoaXMuX2RheXMgPSBNYXRoLmFicyh0aGlzLl9kYXlzKTtcbiAgICAgICAgICAgIHRoaXMuX21vbnRocyA9IE1hdGguYWJzKHRoaXMuX21vbnRocyk7XG5cbiAgICAgICAgICAgIHRoaXMuX2RhdGEubWlsbGlzZWNvbmRzID0gTWF0aC5hYnModGhpcy5fZGF0YS5taWxsaXNlY29uZHMpO1xuICAgICAgICAgICAgdGhpcy5fZGF0YS5zZWNvbmRzID0gTWF0aC5hYnModGhpcy5fZGF0YS5zZWNvbmRzKTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEubWludXRlcyA9IE1hdGguYWJzKHRoaXMuX2RhdGEubWludXRlcyk7XG4gICAgICAgICAgICB0aGlzLl9kYXRhLmhvdXJzID0gTWF0aC5hYnModGhpcy5fZGF0YS5ob3Vycyk7XG4gICAgICAgICAgICB0aGlzLl9kYXRhLm1vbnRocyA9IE1hdGguYWJzKHRoaXMuX2RhdGEubW9udGhzKTtcbiAgICAgICAgICAgIHRoaXMuX2RhdGEueWVhcnMgPSBNYXRoLmFicyh0aGlzLl9kYXRhLnllYXJzKTtcblxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0sXG5cbiAgICAgICAgd2Vla3MgOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gYWJzUm91bmQodGhpcy5kYXlzKCkgLyA3KTtcbiAgICAgICAgfSxcblxuICAgICAgICB2YWx1ZU9mIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21pbGxpc2Vjb25kcyArXG4gICAgICAgICAgICAgIHRoaXMuX2RheXMgKiA4NjRlNSArXG4gICAgICAgICAgICAgICh0aGlzLl9tb250aHMgJSAxMikgKiAyNTkyZTYgK1xuICAgICAgICAgICAgICB0b0ludCh0aGlzLl9tb250aHMgLyAxMikgKiAzMTUzNmU2O1xuICAgICAgICB9LFxuXG4gICAgICAgIGh1bWFuaXplIDogZnVuY3Rpb24gKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgICAgIHZhciBvdXRwdXQgPSByZWxhdGl2ZVRpbWUodGhpcywgIXdpdGhTdWZmaXgsIHRoaXMubG9jYWxlRGF0YSgpKTtcblxuICAgICAgICAgICAgaWYgKHdpdGhTdWZmaXgpIHtcbiAgICAgICAgICAgICAgICBvdXRwdXQgPSB0aGlzLmxvY2FsZURhdGEoKS5wYXN0RnV0dXJlKCt0aGlzLCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5sb2NhbGVEYXRhKCkucG9zdGZvcm1hdChvdXRwdXQpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFkZCA6IGZ1bmN0aW9uIChpbnB1dCwgdmFsKSB7XG4gICAgICAgICAgICAvLyBzdXBwb3J0cyBvbmx5IDIuMC1zdHlsZSBhZGQoMSwgJ3MnKSBvciBhZGQobW9tZW50KVxuICAgICAgICAgICAgdmFyIGR1ciA9IG1vbWVudC5kdXJhdGlvbihpbnB1dCwgdmFsKTtcblxuICAgICAgICAgICAgdGhpcy5fbWlsbGlzZWNvbmRzICs9IGR1ci5fbWlsbGlzZWNvbmRzO1xuICAgICAgICAgICAgdGhpcy5fZGF5cyArPSBkdXIuX2RheXM7XG4gICAgICAgICAgICB0aGlzLl9tb250aHMgKz0gZHVyLl9tb250aHM7XG5cbiAgICAgICAgICAgIHRoaXMuX2J1YmJsZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSxcblxuICAgICAgICBzdWJ0cmFjdCA6IGZ1bmN0aW9uIChpbnB1dCwgdmFsKSB7XG4gICAgICAgICAgICB2YXIgZHVyID0gbW9tZW50LmR1cmF0aW9uKGlucHV0LCB2YWwpO1xuXG4gICAgICAgICAgICB0aGlzLl9taWxsaXNlY29uZHMgLT0gZHVyLl9taWxsaXNlY29uZHM7XG4gICAgICAgICAgICB0aGlzLl9kYXlzIC09IGR1ci5fZGF5cztcbiAgICAgICAgICAgIHRoaXMuX21vbnRocyAtPSBkdXIuX21vbnRocztcblxuICAgICAgICAgICAgdGhpcy5fYnViYmxlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9LFxuXG4gICAgICAgIGdldCA6IGZ1bmN0aW9uICh1bml0cykge1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1t1bml0cy50b0xvd2VyQ2FzZSgpICsgJ3MnXSgpO1xuICAgICAgICB9LFxuXG4gICAgICAgIGFzIDogZnVuY3Rpb24gKHVuaXRzKSB7XG4gICAgICAgICAgICB2YXIgZGF5cywgbW9udGhzO1xuICAgICAgICAgICAgdW5pdHMgPSBub3JtYWxpemVVbml0cyh1bml0cyk7XG5cbiAgICAgICAgICAgIGlmICh1bml0cyA9PT0gJ21vbnRoJyB8fCB1bml0cyA9PT0gJ3llYXInKSB7XG4gICAgICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyB0aGlzLl9taWxsaXNlY29uZHMgLyA4NjRlNTtcbiAgICAgICAgICAgICAgICBtb250aHMgPSB0aGlzLl9tb250aHMgKyBkYXlzVG9ZZWFycyhkYXlzKSAqIDEyO1xuICAgICAgICAgICAgICAgIHJldHVybiB1bml0cyA9PT0gJ21vbnRoJyA/IG1vbnRocyA6IG1vbnRocyAvIDEyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBoYW5kbGUgbWlsbGlzZWNvbmRzIHNlcGFyYXRlbHkgYmVjYXVzZSBvZiBmbG9hdGluZyBwb2ludCBtYXRoIGVycm9ycyAoaXNzdWUgIzE4NjcpXG4gICAgICAgICAgICAgICAgZGF5cyA9IHRoaXMuX2RheXMgKyBNYXRoLnJvdW5kKHllYXJzVG9EYXlzKHRoaXMuX21vbnRocyAvIDEyKSk7XG4gICAgICAgICAgICAgICAgc3dpdGNoICh1bml0cykge1xuICAgICAgICAgICAgICAgICAgICBjYXNlICd3ZWVrJzogcmV0dXJuIGRheXMgLyA3ICsgdGhpcy5fbWlsbGlzZWNvbmRzIC8gNjA0OGU1O1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdkYXknOiByZXR1cm4gZGF5cyArIHRoaXMuX21pbGxpc2Vjb25kcyAvIDg2NGU1O1xuICAgICAgICAgICAgICAgICAgICBjYXNlICdob3VyJzogcmV0dXJuIGRheXMgKiAyNCArIHRoaXMuX21pbGxpc2Vjb25kcyAvIDM2ZTU7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6IHJldHVybiBkYXlzICogMjQgKiA2MCArIHRoaXMuX21pbGxpc2Vjb25kcyAvIDZlNDtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzogcmV0dXJuIGRheXMgKiAyNCAqIDYwICogNjAgKyB0aGlzLl9taWxsaXNlY29uZHMgLyAxMDAwO1xuICAgICAgICAgICAgICAgICAgICAvLyBNYXRoLmZsb29yIHByZXZlbnRzIGZsb2F0aW5nIHBvaW50IG1hdGggZXJyb3JzIGhlcmVcbiAgICAgICAgICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOiByZXR1cm4gTWF0aC5mbG9vcihkYXlzICogMjQgKiA2MCAqIDYwICogMTAwMCkgKyB0aGlzLl9taWxsaXNlY29uZHM7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFcnJvcignVW5rbm93biB1bml0ICcgKyB1bml0cyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGxhbmcgOiBtb21lbnQuZm4ubGFuZyxcbiAgICAgICAgbG9jYWxlIDogbW9tZW50LmZuLmxvY2FsZSxcblxuICAgICAgICB0b0lzb1N0cmluZyA6IGRlcHJlY2F0ZShcbiAgICAgICAgICAgICd0b0lzb1N0cmluZygpIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgdG9JU09TdHJpbmcoKSBpbnN0ZWFkICcgK1xuICAgICAgICAgICAgJyhub3RpY2UgdGhlIGNhcGl0YWxzKScsXG4gICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKSxcblxuICAgICAgICB0b0lTT1N0cmluZyA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vIGluc3BpcmVkIGJ5IGh0dHBzOi8vZ2l0aHViLmNvbS9kb3JkaWxsZS9tb21lbnQtaXNvZHVyYXRpb24vYmxvYi9tYXN0ZXIvbW9tZW50Lmlzb2R1cmF0aW9uLmpzXG4gICAgICAgICAgICB2YXIgeWVhcnMgPSBNYXRoLmFicyh0aGlzLnllYXJzKCkpLFxuICAgICAgICAgICAgICAgIG1vbnRocyA9IE1hdGguYWJzKHRoaXMubW9udGhzKCkpLFxuICAgICAgICAgICAgICAgIGRheXMgPSBNYXRoLmFicyh0aGlzLmRheXMoKSksXG4gICAgICAgICAgICAgICAgaG91cnMgPSBNYXRoLmFicyh0aGlzLmhvdXJzKCkpLFxuICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSBNYXRoLmFicyh0aGlzLm1pbnV0ZXMoKSksXG4gICAgICAgICAgICAgICAgc2Vjb25kcyA9IE1hdGguYWJzKHRoaXMuc2Vjb25kcygpICsgdGhpcy5taWxsaXNlY29uZHMoKSAvIDEwMDApO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuYXNTZWNvbmRzKCkpIHtcbiAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHRoZSBzYW1lIGFzIEMjJ3MgKE5vZGEpIGFuZCBweXRob24gKGlzb2RhdGUpLi4uXG4gICAgICAgICAgICAgICAgLy8gYnV0IG5vdCBvdGhlciBKUyAoZ29vZy5kYXRlKVxuICAgICAgICAgICAgICAgIHJldHVybiAnUDBEJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuICh0aGlzLmFzU2Vjb25kcygpIDwgMCA/ICctJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgJ1AnICtcbiAgICAgICAgICAgICAgICAoeWVhcnMgPyB5ZWFycyArICdZJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgKG1vbnRocyA/IG1vbnRocyArICdNJyA6ICcnKSArXG4gICAgICAgICAgICAgICAgKGRheXMgPyBkYXlzICsgJ0QnIDogJycpICtcbiAgICAgICAgICAgICAgICAoKGhvdXJzIHx8IG1pbnV0ZXMgfHwgc2Vjb25kcykgPyAnVCcgOiAnJykgK1xuICAgICAgICAgICAgICAgIChob3VycyA/IGhvdXJzICsgJ0gnIDogJycpICtcbiAgICAgICAgICAgICAgICAobWludXRlcyA/IG1pbnV0ZXMgKyAnTScgOiAnJykgK1xuICAgICAgICAgICAgICAgIChzZWNvbmRzID8gc2Vjb25kcyArICdTJyA6ICcnKTtcbiAgICAgICAgfSxcblxuICAgICAgICBsb2NhbGVEYXRhIDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xvY2FsZTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLnRvU3RyaW5nID0gbW9tZW50LmR1cmF0aW9uLmZuLnRvSVNPU3RyaW5nO1xuXG4gICAgZnVuY3Rpb24gbWFrZUR1cmF0aW9uR2V0dGVyKG5hbWUpIHtcbiAgICAgICAgbW9tZW50LmR1cmF0aW9uLmZuW25hbWVdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGFbbmFtZV07XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZm9yIChpIGluIHVuaXRNaWxsaXNlY29uZEZhY3RvcnMpIHtcbiAgICAgICAgaWYgKGhhc093blByb3AodW5pdE1pbGxpc2Vjb25kRmFjdG9ycywgaSkpIHtcbiAgICAgICAgICAgIG1ha2VEdXJhdGlvbkdldHRlcihpLnRvTG93ZXJDYXNlKCkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzTWlsbGlzZWNvbmRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcygnbXMnKTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5hc1NlY29uZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdzJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNNaW51dGVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcygnbScpO1xuICAgIH07XG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzSG91cnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCdoJyk7XG4gICAgfTtcbiAgICBtb21lbnQuZHVyYXRpb24uZm4uYXNEYXlzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcygnZCcpO1xuICAgIH07XG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzV2Vla3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCd3ZWVrcycpO1xuICAgIH07XG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzTW9udGhzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcygnTScpO1xuICAgIH07XG4gICAgbW9tZW50LmR1cmF0aW9uLmZuLmFzWWVhcnMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFzKCd5Jyk7XG4gICAgfTtcblxuICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAgICAgICAgRGVmYXVsdCBMb2NhbGVcbiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cblxuICAgIC8vIFNldCBkZWZhdWx0IGxvY2FsZSwgb3RoZXIgbG9jYWxlIHdpbGwgaW5oZXJpdCBmcm9tIEVuZ2xpc2guXG4gICAgbW9tZW50LmxvY2FsZSgnZW4nLCB7XG4gICAgICAgIG9yZGluYWxQYXJzZTogL1xcZHsxLDJ9KHRofHN0fG5kfHJkKS8sXG4gICAgICAgIG9yZGluYWwgOiBmdW5jdGlvbiAobnVtYmVyKSB7XG4gICAgICAgICAgICB2YXIgYiA9IG51bWJlciAlIDEwLFxuICAgICAgICAgICAgICAgIG91dHB1dCA9ICh0b0ludChudW1iZXIgJSAxMDAgLyAxMCkgPT09IDEpID8gJ3RoJyA6XG4gICAgICAgICAgICAgICAgKGIgPT09IDEpID8gJ3N0JyA6XG4gICAgICAgICAgICAgICAgKGIgPT09IDIpID8gJ25kJyA6XG4gICAgICAgICAgICAgICAgKGIgPT09IDMpID8gJ3JkJyA6ICd0aCc7XG4gICAgICAgICAgICByZXR1cm4gbnVtYmVyICsgb3V0cHV0O1xuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICAvKiBFTUJFRF9MT0NBTEVTICovXG5cbiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gICAgICAgIEV4cG9zaW5nIE1vbWVudFxuICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuICAgIGZ1bmN0aW9uIG1ha2VHbG9iYWwoc2hvdWxkRGVwcmVjYXRlKSB7XG4gICAgICAgIC8qZ2xvYmFsIGVuZGVyOmZhbHNlICovXG4gICAgICAgIGlmICh0eXBlb2YgZW5kZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgb2xkR2xvYmFsTW9tZW50ID0gZ2xvYmFsU2NvcGUubW9tZW50O1xuICAgICAgICBpZiAoc2hvdWxkRGVwcmVjYXRlKSB7XG4gICAgICAgICAgICBnbG9iYWxTY29wZS5tb21lbnQgPSBkZXByZWNhdGUoXG4gICAgICAgICAgICAgICAgICAgICdBY2Nlc3NpbmcgTW9tZW50IHRocm91Z2ggdGhlIGdsb2JhbCBzY29wZSBpcyAnICtcbiAgICAgICAgICAgICAgICAgICAgJ2RlcHJlY2F0ZWQsIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gYW4gdXBjb21pbmcgJyArXG4gICAgICAgICAgICAgICAgICAgICdyZWxlYXNlLicsXG4gICAgICAgICAgICAgICAgICAgIG1vbWVudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBnbG9iYWxTY29wZS5tb21lbnQgPSBtb21lbnQ7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDb21tb25KUyBtb2R1bGUgaXMgZGVmaW5lZFxuICAgIGlmIChoYXNNb2R1bGUpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBtb21lbnQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKCdtb21lbnQnLCBmdW5jdGlvbiAocmVxdWlyZSwgZXhwb3J0cywgbW9kdWxlKSB7XG4gICAgICAgICAgICBpZiAobW9kdWxlLmNvbmZpZyAmJiBtb2R1bGUuY29uZmlnKCkgJiYgbW9kdWxlLmNvbmZpZygpLm5vR2xvYmFsID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgLy8gcmVsZWFzZSB0aGUgZ2xvYmFsIHZhcmlhYmxlXG4gICAgICAgICAgICAgICAgZ2xvYmFsU2NvcGUubW9tZW50ID0gb2xkR2xvYmFsTW9tZW50O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbW9tZW50O1xuICAgICAgICB9KTtcbiAgICAgICAgbWFrZUdsb2JhbCh0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBtYWtlR2xvYmFsKCk7XG4gICAgfVxufSkuY2FsbCh0aGlzKTtcbiIsIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi8nKTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciB1cmwgPSByZXF1aXJlKCcuL3VybCcpO1xudmFyIHBhcnNlciA9IHJlcXVpcmUoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBNYW5hZ2VyID0gcmVxdWlyZSgnLi9tYW5hZ2VyJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50Jyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gbG9va3VwO1xuXG4vKipcbiAqIE1hbmFnZXJzIGNhY2hlLlxuICovXG5cbnZhciBjYWNoZSA9IGV4cG9ydHMubWFuYWdlcnMgPSB7fTtcblxuLyoqXG4gKiBMb29rcyB1cCBhbiBleGlzdGluZyBgTWFuYWdlcmAgZm9yIG11bHRpcGxleGluZy5cbiAqIElmIHRoZSB1c2VyIHN1bW1vbnM6XG4gKlxuICogICBgaW8oJ2h0dHA6Ly9sb2NhbGhvc3QvYScpO2BcbiAqICAgYGlvKCdodHRwOi8vbG9jYWxob3N0L2InKTtgXG4gKlxuICogV2UgcmV1c2UgdGhlIGV4aXN0aW5nIGluc3RhbmNlIGJhc2VkIG9uIHNhbWUgc2NoZW1lL3BvcnQvaG9zdCxcbiAqIGFuZCB3ZSBpbml0aWFsaXplIHNvY2tldHMgZm9yIGVhY2ggbmFtZXNwYWNlLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gbG9va3VwKHVyaSwgb3B0cykge1xuICBpZiAodHlwZW9mIHVyaSA9PSAnb2JqZWN0Jykge1xuICAgIG9wdHMgPSB1cmk7XG4gICAgdXJpID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgdmFyIHBhcnNlZCA9IHVybCh1cmkpO1xuICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgdmFyIGlkID0gcGFyc2VkLmlkO1xuICB2YXIgaW87XG5cbiAgaWYgKG9wdHMuZm9yY2VOZXcgfHwgb3B0c1snZm9yY2UgbmV3IGNvbm5lY3Rpb24nXSB8fCBmYWxzZSA9PT0gb3B0cy5tdWx0aXBsZXgpIHtcbiAgICBkZWJ1ZygnaWdub3Jpbmcgc29ja2V0IGNhY2hlIGZvciAlcycsIHNvdXJjZSk7XG4gICAgaW8gPSBNYW5hZ2VyKHNvdXJjZSwgb3B0cyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFjYWNoZVtpZF0pIHtcbiAgICAgIGRlYnVnKCduZXcgaW8gaW5zdGFuY2UgZm9yICVzJywgc291cmNlKTtcbiAgICAgIGNhY2hlW2lkXSA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgICB9XG4gICAgaW8gPSBjYWNoZVtpZF07XG4gIH1cblxuICByZXR1cm4gaW8uc29ja2V0KHBhcnNlZC5wYXRoKTtcbn1cblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5wcm90b2NvbCA9IHBhcnNlci5wcm90b2NvbDtcblxuLyoqXG4gKiBgY29ubmVjdGAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHVyaVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmNvbm5lY3QgPSBsb29rdXA7XG5cbi8qKlxuICogRXhwb3NlIGNvbnN0cnVjdG9ycyBmb3Igc3RhbmRhbG9uZSBidWlsZC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuTWFuYWdlciA9IHJlcXVpcmUoJy4vbWFuYWdlcicpO1xuZXhwb3J0cy5Tb2NrZXQgPSByZXF1aXJlKCcuL3NvY2tldCcpO1xuIiwiXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHVybCA9IHJlcXVpcmUoJy4vdXJsJyk7XG52YXIgZWlvID0gcmVxdWlyZSgnZW5naW5lLmlvLWNsaWVudCcpO1xudmFyIFNvY2tldCA9IHJlcXVpcmUoJy4vc29ja2V0Jyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgcGFyc2VyID0gcmVxdWlyZSgnc29ja2V0LmlvLXBhcnNlcicpO1xudmFyIG9uID0gcmVxdWlyZSgnLi9vbicpO1xudmFyIGJpbmQgPSByZXF1aXJlKCdjb21wb25lbnQtYmluZCcpO1xudmFyIG9iamVjdCA9IHJlcXVpcmUoJ29iamVjdC1jb21wb25lbnQnKTtcbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6bWFuYWdlcicpO1xudmFyIGluZGV4T2YgPSByZXF1aXJlKCdpbmRleG9mJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbi8qKlxuICogYE1hbmFnZXJgIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBlbmdpbmUgaW5zdGFuY2Ugb3IgZW5naW5lIHVyaS9vcHRzXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBNYW5hZ2VyKHVyaSwgb3B0cyl7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBNYW5hZ2VyKSkgcmV0dXJuIG5ldyBNYW5hZ2VyKHVyaSwgb3B0cyk7XG4gIGlmICh1cmkgJiYgKCdvYmplY3QnID09IHR5cGVvZiB1cmkpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSB1bmRlZmluZWQ7XG4gIH1cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgb3B0cy5wYXRoID0gb3B0cy5wYXRoIHx8ICcvc29ja2V0LmlvJztcbiAgdGhpcy5uc3BzID0ge307XG4gIHRoaXMuc3VicyA9IFtdO1xuICB0aGlzLm9wdHMgPSBvcHRzO1xuICB0aGlzLnJlY29ubmVjdGlvbihvcHRzLnJlY29ubmVjdGlvbiAhPT0gZmFsc2UpO1xuICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5KG9wdHMucmVjb25uZWN0aW9uRGVsYXkgfHwgMTAwMCk7XG4gIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgob3B0cy5yZWNvbm5lY3Rpb25EZWxheU1heCB8fCA1MDAwKTtcbiAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgdGhpcy51cmkgPSB1cmk7XG4gIHRoaXMuY29ubmVjdGVkID0gW107XG4gIHRoaXMuYXR0ZW1wdHMgPSAwO1xuICB0aGlzLmVuY29kaW5nID0gZmFsc2U7XG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RlciA9IG5ldyBwYXJzZXIuRW5jb2RlcigpO1xuICB0aGlzLmRlY29kZXIgPSBuZXcgcGFyc2VyLkRlY29kZXIoKTtcbiAgdGhpcy5hdXRvQ29ubmVjdCA9IG9wdHMuYXV0b0Nvbm5lY3QgIT09IGZhbHNlO1xuICBpZiAodGhpcy5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG59XG5cbi8qKlxuICogUHJvcGFnYXRlIGdpdmVuIGV2ZW50IHRvIHNvY2tldHMgYW5kIGVtaXQgb24gYHRoaXNgXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuZW1pdEFsbCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmVtaXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgZm9yICh2YXIgbnNwIGluIHRoaXMubnNwcykge1xuICAgIHRoaXMubnNwc1tuc3BdLmVtaXQuYXBwbHkodGhpcy5uc3BzW25zcF0sIGFyZ3VtZW50cyk7XG4gIH1cbn07XG5cbi8qKlxuICogTWl4IGluIGBFbWl0dGVyYC5cbiAqL1xuXG5FbWl0dGVyKE1hbmFnZXIucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gKlxuICogQHBhcmFtIHtCb29sZWFufSB0cnVlL2ZhbHNlIGlmIGl0IHNob3VsZCBhdXRvbWF0aWNhbGx5IHJlY29ubmVjdFxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbih2KXtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uO1xuICB0aGlzLl9yZWNvbm5lY3Rpb24gPSAhIXY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSByZWNvbm5lY3Rpb24gYXR0ZW1wdHMgY29uZmlnLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtYXggcmVjb25uZWN0aW9uIGF0dGVtcHRzIGJlZm9yZSBnaXZpbmcgdXBcbiAqIEByZXR1cm4ge01hbmFnZXJ9IHNlbGYgb3IgdmFsdWVcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucmVjb25uZWN0aW9uQXR0ZW1wdHMgPSBmdW5jdGlvbih2KXtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHM7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkF0dGVtcHRzID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGRlbGF5IGJldHdlZW4gcmVjb25uZWN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gZGVsYXlcbiAqIEByZXR1cm4ge01hbmFnZXJ9IHNlbGYgb3IgdmFsdWVcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucmVjb25uZWN0aW9uRGVsYXkgPSBmdW5jdGlvbih2KXtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uRGVsYXk7XG4gIHRoaXMuX3JlY29ubmVjdGlvbkRlbGF5ID0gdjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIG1heGltdW0gZGVsYXkgYmV0d2VlbiByZWNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25EZWxheU1heCA9IGZ1bmN0aW9uKHYpe1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heDtcbiAgdGhpcy5fcmVjb25uZWN0aW9uRGVsYXlNYXggPSB2O1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgY29ubmVjdGlvbiB0aW1lb3V0LiBgZmFsc2VgIHRvIGRpc2FibGVcbiAqXG4gKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnRpbWVvdXQgPSBmdW5jdGlvbih2KXtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fdGltZW91dDtcbiAgdGhpcy5fdGltZW91dCA9IHY7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTdGFydHMgdHJ5aW5nIHRvIHJlY29ubmVjdCBpZiByZWNvbm5lY3Rpb24gaXMgZW5hYmxlZCBhbmQgd2UgaGF2ZSBub3RcbiAqIHN0YXJ0ZWQgcmVjb25uZWN0aW5nIHlldFxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm1heWJlUmVjb25uZWN0T25PcGVuID0gZnVuY3Rpb24oKSB7XG4gIC8vIE9ubHkgdHJ5IHRvIHJlY29ubmVjdCBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIHdlJ3JlIGNvbm5lY3RpbmdcbiAgaWYgKCF0aGlzLm9wZW5SZWNvbm5lY3QgJiYgIXRoaXMucmVjb25uZWN0aW5nICYmIHRoaXMuX3JlY29ubmVjdGlvbiAmJiB0aGlzLmF0dGVtcHRzID09PSAwKSB7XG4gICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgIHRoaXMub3BlblJlY29ubmVjdCA9IHRydWU7XG4gICAgdGhpcy5yZWNvbm5lY3QoKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0IGBzb2NrZXRgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbmFsLCBjYWxsYmFja1xuICogQHJldHVybiB7TWFuYWdlcn0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vcGVuID1cbk1hbmFnZXIucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbihmbil7XG4gIGRlYnVnKCdyZWFkeVN0YXRlICVzJywgdGhpcy5yZWFkeVN0YXRlKTtcbiAgaWYgKH50aGlzLnJlYWR5U3RhdGUuaW5kZXhPZignb3BlbicpKSByZXR1cm4gdGhpcztcblxuICBkZWJ1Zygnb3BlbmluZyAlcycsIHRoaXMudXJpKTtcbiAgdGhpcy5lbmdpbmUgPSBlaW8odGhpcy51cmksIHRoaXMub3B0cyk7XG4gIHZhciBzb2NrZXQgPSB0aGlzLmVuZ2luZTtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnb3BlbmluZyc7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IGZhbHNlO1xuXG4gIC8vIGVtaXQgYG9wZW5gXG4gIHZhciBvcGVuU3ViID0gb24oc29ja2V0LCAnb3BlbicsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYub25vcGVuKCk7XG4gICAgZm4gJiYgZm4oKTtcbiAgfSk7XG5cbiAgLy8gZW1pdCBgY29ubmVjdF9lcnJvcmBcbiAgdmFyIGVycm9yU3ViID0gb24oc29ja2V0LCAnZXJyb3InLCBmdW5jdGlvbihkYXRhKXtcbiAgICBkZWJ1ZygnY29ubmVjdF9lcnJvcicpO1xuICAgIHNlbGYuY2xlYW51cCgpO1xuICAgIHNlbGYucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICAgIHNlbGYuZW1pdEFsbCgnY29ubmVjdF9lcnJvcicsIGRhdGEpO1xuICAgIGlmIChmbikge1xuICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignQ29ubmVjdGlvbiBlcnJvcicpO1xuICAgICAgZXJyLmRhdGEgPSBkYXRhO1xuICAgICAgZm4oZXJyKTtcbiAgICB9XG5cbiAgICBzZWxmLm1heWJlUmVjb25uZWN0T25PcGVuKCk7XG4gIH0pO1xuXG4gIC8vIGVtaXQgYGNvbm5lY3RfdGltZW91dGBcbiAgaWYgKGZhbHNlICE9PSB0aGlzLl90aW1lb3V0KSB7XG4gICAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICAgIGRlYnVnKCdjb25uZWN0IGF0dGVtcHQgd2lsbCB0aW1lb3V0IGFmdGVyICVkJywgdGltZW91dCk7XG5cbiAgICAvLyBzZXQgdGltZXJcbiAgICB2YXIgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBkZWJ1ZygnY29ubmVjdCBhdHRlbXB0IHRpbWVkIG91dCBhZnRlciAlZCcsIHRpbWVvdXQpO1xuICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICBzb2NrZXQuY2xvc2UoKTtcbiAgICAgIHNvY2tldC5lbWl0KCdlcnJvcicsICd0aW1lb3V0Jyk7XG4gICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgIH0sIHRpbWVvdXQpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHRoaXMuc3Vicy5wdXNoKG9wZW5TdWIpO1xuICB0aGlzLnN1YnMucHVzaChlcnJvclN1Yik7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHRyYW5zcG9ydCBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9ub3BlbiA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCdvcGVuJyk7XG5cbiAgLy8gY2xlYXIgb2xkIHN1YnNcbiAgdGhpcy5jbGVhbnVwKCk7XG5cbiAgLy8gbWFyayBhcyBvcGVuXG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG5cbiAgLy8gYWRkIG5ldyBzdWJzXG4gIHZhciBzb2NrZXQgPSB0aGlzLmVuZ2luZTtcbiAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAnZGF0YScsIGJpbmQodGhpcywgJ29uZGF0YScpKSk7XG4gIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdlcnJvcicsIGJpbmQodGhpcywgJ29uZXJyb3InKSkpO1xuICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdjbG9zZScsIGJpbmQodGhpcywgJ29uY2xvc2UnKSkpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2l0aCBkYXRhLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uKGRhdGEpe1xuICB0aGlzLmRlY29kZXIuYWRkKGRhdGEpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgd2hlbiBwYXJzZXIgZnVsbHkgZGVjb2RlcyBhIHBhY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbmRlY29kZWQgPSBmdW5jdGlvbihwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25lcnJvciA9IGZ1bmN0aW9uKGVycil7XG4gIGRlYnVnKCdlcnJvcicsIGVycik7XG4gIHRoaXMuZW1pdEFsbCgnZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHNvY2tldCBmb3IgdGhlIGdpdmVuIGBuc3BgLlxuICpcbiAqIEByZXR1cm4ge1NvY2tldH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuc29ja2V0ID0gZnVuY3Rpb24obnNwKXtcbiAgdmFyIHNvY2tldCA9IHRoaXMubnNwc1tuc3BdO1xuICBpZiAoIXNvY2tldCkge1xuICAgIHNvY2tldCA9IG5ldyBTb2NrZXQodGhpcywgbnNwKTtcbiAgICB0aGlzLm5zcHNbbnNwXSA9IHNvY2tldDtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24oKXtcbiAgICAgIGlmICghfmluZGV4T2Yoc2VsZi5jb25uZWN0ZWQsIHNvY2tldCkpIHtcbiAgICAgICAgc2VsZi5jb25uZWN0ZWQucHVzaChzb2NrZXQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHJldHVybiBzb2NrZXQ7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc29ja2V0IGNsb3NlLlxuICpcbiAqIEBwYXJhbSB7U29ja2V0fSBzb2NrZXRcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oc29ja2V0KXtcbiAgdmFyIGluZGV4ID0gaW5kZXhPZih0aGlzLmNvbm5lY3RlZCwgc29ja2V0KTtcbiAgaWYgKH5pbmRleCkgdGhpcy5jb25uZWN0ZWQuc3BsaWNlKGluZGV4LCAxKTtcbiAgaWYgKHRoaXMuY29ubmVjdGVkLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cbi8qKlxuICogV3JpdGVzIGEgcGFja2V0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uKHBhY2tldCl7XG4gIGRlYnVnKCd3cml0aW5nIHBhY2tldCAlaicsIHBhY2tldCk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoIXNlbGYuZW5jb2RpbmcpIHtcbiAgICAvLyBlbmNvZGUsIHRoZW4gd3JpdGUgdG8gZW5naW5lIHdpdGggcmVzdWx0XG4gICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgdGhpcy5lbmNvZGVyLmVuY29kZShwYWNrZXQsIGZ1bmN0aW9uKGVuY29kZWRQYWNrZXRzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVuY29kZWRQYWNrZXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHNlbGYuZW5naW5lLndyaXRlKGVuY29kZWRQYWNrZXRzW2ldKTtcbiAgICAgIH1cbiAgICAgIHNlbGYuZW5jb2RpbmcgPSBmYWxzZTtcbiAgICAgIHNlbGYucHJvY2Vzc1BhY2tldFF1ZXVlKCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7IC8vIGFkZCBwYWNrZXQgdG8gdGhlIHF1ZXVlXG4gICAgc2VsZi5wYWNrZXRCdWZmZXIucHVzaChwYWNrZXQpO1xuICB9XG59O1xuXG4vKipcbiAqIElmIHBhY2tldCBidWZmZXIgaXMgbm9uLWVtcHR5LCBiZWdpbnMgZW5jb2RpbmcgdGhlXG4gKiBuZXh0IHBhY2tldCBpbiBsaW5lLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbk1hbmFnZXIucHJvdG90eXBlLnByb2Nlc3NQYWNrZXRRdWV1ZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgIHZhciBwYWNrID0gdGhpcy5wYWNrZXRCdWZmZXIuc2hpZnQoKTtcbiAgICB0aGlzLnBhY2tldChwYWNrKTtcbiAgfVxufTtcblxuLyoqXG4gKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5jbGVhbnVwID0gZnVuY3Rpb24oKXtcbiAgdmFyIHN1YjtcbiAgd2hpbGUgKHN1YiA9IHRoaXMuc3Vicy5zaGlmdCgpKSBzdWIuZGVzdHJveSgpO1xuXG4gIHRoaXMucGFja2V0QnVmZmVyID0gW107XG4gIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcblxuICB0aGlzLmRlY29kZXIuZGVzdHJveSgpO1xufTtcblxuLyoqXG4gKiBDbG9zZSB0aGUgY3VycmVudCBzb2NrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUuY2xvc2UgPVxuTWFuYWdlci5wcm90b3R5cGUuZGlzY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICB0aGlzLmVuZ2luZSAmJiB0aGlzLmVuZ2luZS5jbG9zZSgpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlbmdpbmUgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUub25jbG9zZSA9IGZ1bmN0aW9uKHJlYXNvbil7XG4gIGRlYnVnKCdjbG9zZScpO1xuICB0aGlzLmNsZWFudXAoKTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24pO1xuICBpZiAodGhpcy5fcmVjb25uZWN0aW9uICYmICF0aGlzLnNraXBSZWNvbm5lY3QpIHtcbiAgICB0aGlzLnJlY29ubmVjdCgpO1xuICB9XG59O1xuXG4vKipcbiAqIEF0dGVtcHQgYSByZWNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuTWFuYWdlci5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMucmVjb25uZWN0aW5nIHx8IHRoaXMuc2tpcFJlY29ubmVjdCkgcmV0dXJuIHRoaXM7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmF0dGVtcHRzKys7XG5cbiAgaWYgKHRoaXMuYXR0ZW1wdHMgPiB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cykge1xuICAgIGRlYnVnKCdyZWNvbm5lY3QgZmFpbGVkJyk7XG4gICAgdGhpcy5lbWl0QWxsKCdyZWNvbm5lY3RfZmFpbGVkJyk7XG4gICAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZGVsYXkgPSB0aGlzLmF0dGVtcHRzICogdGhpcy5yZWNvbm5lY3Rpb25EZWxheSgpO1xuICAgIGRlbGF5ID0gTWF0aC5taW4oZGVsYXksIHRoaXMucmVjb25uZWN0aW9uRGVsYXlNYXgoKSk7XG4gICAgZGVidWcoJ3dpbGwgd2FpdCAlZG1zIGJlZm9yZSByZWNvbm5lY3QgYXR0ZW1wdCcsIGRlbGF5KTtcblxuICAgIHRoaXMucmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICB2YXIgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIGRlYnVnKCdhdHRlbXB0aW5nIHJlY29ubmVjdCcpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RfYXR0ZW1wdCcsIHNlbGYuYXR0ZW1wdHMpO1xuICAgICAgc2VsZi5lbWl0QWxsKCdyZWNvbm5lY3RpbmcnLCBzZWxmLmF0dGVtcHRzKTtcblxuICAgICAgLy8gY2hlY2sgYWdhaW4gZm9yIHRoZSBjYXNlIHNvY2tldCBjbG9zZWQgaW4gYWJvdmUgZXZlbnRzXG4gICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgIHNlbGYub3BlbihmdW5jdGlvbihlcnIpe1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBhdHRlbXB0IGVycm9yJyk7XG4gICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLnJlY29ubmVjdCgpO1xuICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2Vycm9yJywgZXJyLmRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3Qgc3VjY2VzcycpO1xuICAgICAgICAgIHNlbGYub25yZWNvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwgZGVsYXkpO1xuXG4gICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzdWNjZXNzZnVsIHJlY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5NYW5hZ2VyLnByb3RvdHlwZS5vbnJlY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBhdHRlbXB0ID0gdGhpcy5hdHRlbXB0cztcbiAgdGhpcy5hdHRlbXB0cyA9IDA7XG4gIHRoaXMucmVjb25uZWN0aW5nID0gZmFsc2U7XG4gIHRoaXMuZW1pdEFsbCgncmVjb25uZWN0JywgYXR0ZW1wdCk7XG59O1xuIiwiXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gb247XG5cbi8qKlxuICogSGVscGVyIGZvciBzdWJzY3JpcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEV2ZW50RW1pdHRlcn0gb2JqIHdpdGggYEVtaXR0ZXJgIG1peGluIG9yIGBFdmVudEVtaXR0ZXJgXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgbmFtZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gb24ob2JqLCBldiwgZm4pIHtcbiAgb2JqLm9uKGV2LCBmbik7XG4gIHJldHVybiB7XG4gICAgZGVzdHJveTogZnVuY3Rpb24oKXtcbiAgICAgIG9iai5yZW1vdmVMaXN0ZW5lcihldiwgZm4pO1xuICAgIH1cbiAgfTtcbn1cbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBwYXJzZXIgPSByZXF1aXJlKCdzb2NrZXQuaW8tcGFyc2VyJyk7XG52YXIgRW1pdHRlciA9IHJlcXVpcmUoJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG52YXIgdG9BcnJheSA9IHJlcXVpcmUoJ3RvLWFycmF5Jyk7XG52YXIgb24gPSByZXF1aXJlKCcuL29uJyk7XG52YXIgYmluZCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1iaW5kJyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50OnNvY2tldCcpO1xudmFyIGhhc0JpbiA9IHJlcXVpcmUoJ2hhcy1iaW5hcnknKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBTb2NrZXQ7XG5cbi8qKlxuICogSW50ZXJuYWwgZXZlbnRzIChibGFja2xpc3RlZCkuXG4gKiBUaGVzZSBldmVudHMgY2FuJ3QgYmUgZW1pdHRlZCBieSB0aGUgdXNlci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgZXZlbnRzID0ge1xuICBjb25uZWN0OiAxLFxuICBjb25uZWN0X2Vycm9yOiAxLFxuICBjb25uZWN0X3RpbWVvdXQ6IDEsXG4gIGRpc2Nvbm5lY3Q6IDEsXG4gIGVycm9yOiAxLFxuICByZWNvbm5lY3Q6IDEsXG4gIHJlY29ubmVjdF9hdHRlbXB0OiAxLFxuICByZWNvbm5lY3RfZmFpbGVkOiAxLFxuICByZWNvbm5lY3RfZXJyb3I6IDEsXG4gIHJlY29ubmVjdGluZzogMVxufTtcblxuLyoqXG4gKiBTaG9ydGN1dCB0byBgRW1pdHRlciNlbWl0YC5cbiAqL1xuXG52YXIgZW1pdCA9IEVtaXR0ZXIucHJvdG90eXBlLmVtaXQ7XG5cbi8qKlxuICogYFNvY2tldGAgY29uc3RydWN0b3IuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBTb2NrZXQoaW8sIG5zcCl7XG4gIHRoaXMuaW8gPSBpbztcbiAgdGhpcy5uc3AgPSBuc3A7XG4gIHRoaXMuanNvbiA9IHRoaXM7IC8vIGNvbXBhdFxuICB0aGlzLmlkcyA9IDA7XG4gIHRoaXMuYWNrcyA9IHt9O1xuICBpZiAodGhpcy5pby5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG4gIHRoaXMucmVjZWl2ZUJ1ZmZlciA9IFtdO1xuICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbiAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgdGhpcy5kaXNjb25uZWN0ZWQgPSB0cnVlO1xufVxuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBTdWJzY3JpYmUgdG8gb3BlbiwgY2xvc2UgYW5kIHBhY2tldCBldmVudHNcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnN1YkV2ZW50cyA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5zdWJzKSByZXR1cm47XG5cbiAgdmFyIGlvID0gdGhpcy5pbztcbiAgdGhpcy5zdWJzID0gW1xuICAgIG9uKGlvLCAnb3BlbicsIGJpbmQodGhpcywgJ29ub3BlbicpKSxcbiAgICBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLFxuICAgIG9uKGlvLCAnY2xvc2UnLCBiaW5kKHRoaXMsICdvbmNsb3NlJykpXG4gIF07XG59O1xuXG4vKipcbiAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vcGVuID1cblNvY2tldC5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIGlmICh0aGlzLmNvbm5lY3RlZCkgcmV0dXJuIHRoaXM7XG5cbiAgdGhpcy5zdWJFdmVudHMoKTtcbiAgdGhpcy5pby5vcGVuKCk7IC8vIGVuc3VyZSBvcGVuXG4gIGlmICgnb3BlbicgPT0gdGhpcy5pby5yZWFkeVN0YXRlKSB0aGlzLm9ub3BlbigpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgYSBgbWVzc2FnZWAgZXZlbnQuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICBhcmdzLnVuc2hpZnQoJ21lc3NhZ2UnKTtcbiAgdGhpcy5lbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYGVtaXRgLlxuICogSWYgdGhlIGV2ZW50IGlzIGluIGBldmVudHNgLCBpdCdzIGVtaXR0ZWQgbm9ybWFsbHkuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbihldil7XG4gIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoZXYpKSB7XG4gICAgZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgdmFyIGFyZ3MgPSB0b0FycmF5KGFyZ3VtZW50cyk7XG4gIHZhciBwYXJzZXJUeXBlID0gcGFyc2VyLkVWRU5UOyAvLyBkZWZhdWx0XG4gIGlmIChoYXNCaW4oYXJncykpIHsgcGFyc2VyVHlwZSA9IHBhcnNlci5CSU5BUllfRVZFTlQ7IH0gLy8gYmluYXJ5XG4gIHZhciBwYWNrZXQgPSB7IHR5cGU6IHBhcnNlclR5cGUsIGRhdGE6IGFyZ3MgfTtcblxuICAvLyBldmVudCBhY2sgY2FsbGJhY2tcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGFyZ3NbYXJncy5sZW5ndGggLSAxXSkge1xuICAgIGRlYnVnKCdlbWl0dGluZyBwYWNrZXQgd2l0aCBhY2sgaWQgJWQnLCB0aGlzLmlkcyk7XG4gICAgdGhpcy5hY2tzW3RoaXMuaWRzXSA9IGFyZ3MucG9wKCk7XG4gICAgcGFja2V0LmlkID0gdGhpcy5pZHMrKztcbiAgfVxuXG4gIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgIHRoaXMucGFja2V0KHBhY2tldCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5zZW5kQnVmZmVyLnB1c2gocGFja2V0KTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBTZW5kcyBhIHBhY2tldC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uKHBhY2tldCl7XG4gIHBhY2tldC5uc3AgPSB0aGlzLm5zcDtcbiAgdGhpcy5pby5wYWNrZXQocGFja2V0KTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBvcGVuYC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9ub3BlbiA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCd0cmFuc3BvcnQgaXMgb3BlbiAtIGNvbm5lY3RpbmcnKTtcblxuICAvLyB3cml0ZSBjb25uZWN0IHBhY2tldCBpZiBuZWNlc3NhcnlcbiAgaWYgKCcvJyAhPSB0aGlzLm5zcCkge1xuICAgIHRoaXMucGFja2V0KHsgdHlwZTogcGFyc2VyLkNPTk5FQ1QgfSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gZW5naW5lIGBjbG9zZWAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHJlYXNvblxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmNsb3NlID0gZnVuY3Rpb24ocmVhc29uKXtcbiAgZGVidWcoJ2Nsb3NlICglcyknLCByZWFzb24pO1xuICB0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbnBhY2tldCA9IGZ1bmN0aW9uKHBhY2tldCl7XG4gIGlmIChwYWNrZXQubnNwICE9IHRoaXMubnNwKSByZXR1cm47XG5cbiAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICB0aGlzLm9uY29ubmVjdCgpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICB0aGlzLm9uZXZlbnQocGFja2V0KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgdGhpcy5vbmFjayhwYWNrZXQpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgdGhpcy5vbmRpc2Nvbm5lY3QoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgcGFja2V0LmRhdGEpO1xuICAgICAgYnJlYWs7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbmV2ZW50ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgdmFyIGFyZ3MgPSBwYWNrZXQuZGF0YSB8fCBbXTtcbiAgZGVidWcoJ2VtaXR0aW5nIGV2ZW50ICVqJywgYXJncyk7XG5cbiAgaWYgKG51bGwgIT0gcGFja2V0LmlkKSB7XG4gICAgZGVidWcoJ2F0dGFjaGluZyBhY2sgY2FsbGJhY2sgdG8gZXZlbnQnKTtcbiAgICBhcmdzLnB1c2godGhpcy5hY2socGFja2V0LmlkKSk7XG4gIH1cblxuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVjZWl2ZUJ1ZmZlci5wdXNoKGFyZ3MpO1xuICB9XG59O1xuXG4vKipcbiAqIFByb2R1Y2VzIGFuIGFjayBjYWxsYmFjayB0byBlbWl0IHdpdGggYW4gZXZlbnQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5hY2sgPSBmdW5jdGlvbihpZCl7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHNlbnQgPSBmYWxzZTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgaWYgKHNlbnQpIHJldHVybjtcbiAgICBzZW50ID0gdHJ1ZTtcbiAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICBkZWJ1Zygnc2VuZGluZyBhY2sgJWonLCBhcmdzKTtcblxuICAgIHZhciB0eXBlID0gaGFzQmluKGFyZ3MpID8gcGFyc2VyLkJJTkFSWV9BQ0sgOiBwYXJzZXIuQUNLO1xuICAgIHNlbGYucGFja2V0KHtcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBpZDogaWQsXG4gICAgICBkYXRhOiBhcmdzXG4gICAgfSk7XG4gIH07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGEgc2VydmVyIGFja25vd2xlZ2VtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25hY2sgPSBmdW5jdGlvbihwYWNrZXQpe1xuICBkZWJ1ZygnY2FsbGluZyBhY2sgJXMgd2l0aCAlaicsIHBhY2tldC5pZCwgcGFja2V0LmRhdGEpO1xuICB2YXIgZm4gPSB0aGlzLmFja3NbcGFja2V0LmlkXTtcbiAgZm4uYXBwbHkodGhpcywgcGFja2V0LmRhdGEpO1xuICBkZWxldGUgdGhpcy5hY2tzW3BhY2tldC5pZF07XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIHNlcnZlciBjb25uZWN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUub25jb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICB0aGlzLmRpc2Nvbm5lY3RlZCA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbn07XG5cbi8qKlxuICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmVtaXRCdWZmZXJlZCA9IGZ1bmN0aW9uKCl7XG4gIHZhciBpO1xuICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5yZWNlaXZlQnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgZW1pdC5hcHBseSh0aGlzLCB0aGlzLnJlY2VpdmVCdWZmZXJbaV0pO1xuICB9XG4gIHRoaXMucmVjZWl2ZUJ1ZmZlciA9IFtdO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0aGlzLnNlbmRCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLnBhY2tldCh0aGlzLnNlbmRCdWZmZXJbaV0pO1xuICB9XG4gIHRoaXMuc2VuZEJ1ZmZlciA9IFtdO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBzZXJ2ZXIgZGlzY29ubmVjdC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uZGlzY29ubmVjdCA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCdzZXJ2ZXIgZGlzY29ubmVjdCAoJXMpJywgdGhpcy5uc3ApO1xuICB0aGlzLmRlc3Ryb3koKTtcbiAgdGhpcy5vbmNsb3NlKCdpbyBzZXJ2ZXIgZGlzY29ubmVjdCcpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBmb3JjZWQgY2xpZW50L3NlcnZlciBzaWRlIGRpc2Nvbm5lY3Rpb25zLFxuICogdGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgbWFuYWdlciBzdG9wcyB0cmFja2luZyB1cyBhbmRcbiAqIHRoYXQgcmVjb25uZWN0aW9ucyBkb24ndCBnZXQgdHJpZ2dlcmVkIGZvciB0aGlzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZS5cbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpe1xuICBpZiAodGhpcy5zdWJzKSB7XG4gICAgLy8gY2xlYW4gc3Vic2NyaXB0aW9ucyB0byBhdm9pZCByZWNvbm5lY3Rpb25zXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnN1YnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHRoaXMuc3VicyA9IG51bGw7XG4gIH1cblxuICB0aGlzLmlvLmRlc3Ryb3kodGhpcyk7XG59O1xuXG4vKipcbiAqIERpc2Nvbm5lY3RzIHRoZSBzb2NrZXQgbWFudWFsbHkuXG4gKlxuICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPVxuU29ja2V0LnByb3RvdHlwZS5kaXNjb25uZWN0ID0gZnVuY3Rpb24oKXtcbiAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgZGVidWcoJ3BlcmZvcm1pbmcgZGlzY29ubmVjdCAoJXMpJywgdGhpcy5uc3ApO1xuICAgIHRoaXMucGFja2V0KHsgdHlwZTogcGFyc2VyLkRJU0NPTk5FQ1QgfSk7XG4gIH1cblxuICAvLyByZW1vdmUgc29ja2V0IGZyb20gcG9vbFxuICB0aGlzLmRlc3Ryb3koKTtcblxuICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICAvLyBmaXJlIGV2ZW50c1xuICAgIHRoaXMub25jbG9zZSgnaW8gY2xpZW50IGRpc2Nvbm5lY3QnKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTtcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgcGFyc2V1cmkgPSByZXF1aXJlKCdwYXJzZXVyaScpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudDp1cmwnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IHVybDtcblxuLyoqXG4gKiBVUkwgcGFyc2VyLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAqIEBwYXJhbSB7T2JqZWN0fSBBbiBvYmplY3QgbWVhbnQgdG8gbWltaWMgd2luZG93LmxvY2F0aW9uLlxuICogICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIHdpbmRvdy5sb2NhdGlvbi5cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gdXJsKHVyaSwgbG9jKXtcbiAgdmFyIG9iaiA9IHVyaTtcblxuICAvLyBkZWZhdWx0IHRvIHdpbmRvdy5sb2NhdGlvblxuICB2YXIgbG9jID0gbG9jIHx8IGdsb2JhbC5sb2NhdGlvbjtcbiAgaWYgKG51bGwgPT0gdXJpKSB1cmkgPSBsb2MucHJvdG9jb2wgKyAnLy8nICsgbG9jLmhvc3RuYW1lO1xuXG4gIC8vIHJlbGF0aXZlIHBhdGggc3VwcG9ydFxuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIHVyaSkge1xuICAgIGlmICgnLycgPT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgaWYgKCcvJyA9PSB1cmkuY2hhckF0KDEpKSB7XG4gICAgICAgIHVyaSA9IGxvYy5wcm90b2NvbCArIHVyaTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVyaSA9IGxvYy5ob3N0bmFtZSArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgZGVidWcoJ3Byb3RvY29sLWxlc3MgdXJsICVzJywgdXJpKTtcbiAgICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgbG9jKSB7XG4gICAgICAgIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyB1cmk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cmkgPSAnaHR0cHM6Ly8nICsgdXJpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHBhcnNlXG4gICAgZGVidWcoJ3BhcnNlICVzJywgdXJpKTtcbiAgICBvYmogPSBwYXJzZXVyaSh1cmkpO1xuICB9XG5cbiAgLy8gbWFrZSBzdXJlIHdlIHRyZWF0IGBsb2NhbGhvc3Q6ODBgIGFuZCBgbG9jYWxob3N0YCBlcXVhbGx5XG4gIGlmICghb2JqLnBvcnQpIHtcbiAgICBpZiAoL14oaHR0cHx3cykkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgIG9iai5wb3J0ID0gJzgwJztcbiAgICB9XG4gICAgZWxzZSBpZiAoL14oaHR0cHx3cylzJC8udGVzdChvYmoucHJvdG9jb2wpKSB7XG4gICAgICBvYmoucG9ydCA9ICc0NDMnO1xuICAgIH1cbiAgfVxuXG4gIG9iai5wYXRoID0gb2JqLnBhdGggfHwgJy8nO1xuXG4gIC8vIGRlZmluZSB1bmlxdWUgaWRcbiAgb2JqLmlkID0gb2JqLnByb3RvY29sICsgJzovLycgKyBvYmouaG9zdCArICc6JyArIG9iai5wb3J0O1xuICAvLyBkZWZpbmUgaHJlZlxuICBvYmouaHJlZiA9IG9iai5wcm90b2NvbCArICc6Ly8nICsgb2JqLmhvc3QgKyAobG9jICYmIGxvYy5wb3J0ID09IG9iai5wb3J0ID8gJycgOiAoJzonICsgb2JqLnBvcnQpKTtcblxuICByZXR1cm4gb2JqO1xufVxuIiwiLyoqXG4gKiBTbGljZSByZWZlcmVuY2UuXG4gKi9cblxudmFyIHNsaWNlID0gW10uc2xpY2U7XG5cbi8qKlxuICogQmluZCBgb2JqYCB0byBgZm5gLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7RnVuY3Rpb258U3RyaW5nfSBmbiBvciBzdHJpbmdcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9iaiwgZm4pe1xuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIGZuKSBmbiA9IG9ialtmbl07XG4gIGlmICgnZnVuY3Rpb24nICE9IHR5cGVvZiBmbikgdGhyb3cgbmV3IEVycm9yKCdiaW5kKCkgcmVxdWlyZXMgYSBmdW5jdGlvbicpO1xuICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCl7XG4gICAgcmV0dXJuIGZuLmFwcGx5KG9iaiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gIH1cbn07XG4iLCJcbi8qKlxuICogRXhwb3NlIGBFbWl0dGVyYC5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICBpZiAob2JqKSByZXR1cm4gbWl4aW4ob2JqKTtcbn07XG5cbi8qKlxuICogTWl4aW4gdGhlIGVtaXR0ZXIgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBtaXhpbihvYmopIHtcbiAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICB9XG4gIHJldHVybiBvYmo7XG59XG5cbi8qKlxuICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtFbWl0dGVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9XG5FbWl0dGVyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAodGhpcy5fY2FsbGJhY2tzW2V2ZW50XSA9IHRoaXMuX2NhbGxiYWNrc1tldmVudF0gfHwgW10pXG4gICAgLnB1c2goZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgZm4pe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICBmdW5jdGlvbiBvbigpIHtcbiAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBvbi5mbiA9IGZuO1xuICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBgZXZlbnRgIG9yIGFsbFxuICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUub2ZmID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID1cbkVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9XG5FbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGZuKXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gIC8vIGFsbFxuICBpZiAoMCA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBzcGVjaWZpYyBldmVudFxuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgaWYgKCFjYWxsYmFja3MpIHJldHVybiB0aGlzO1xuXG4gIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIGRlbGV0ZSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gcmVtb3ZlIHNwZWNpZmljIGhhbmRsZXJcbiAgdmFyIGNiO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgIGNiID0gY2FsbGJhY2tzW2ldO1xuICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbWl0IGBldmVudGAgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAqIEBwYXJhbSB7TWl4ZWR9IC4uLlxuICogQHJldHVybiB7RW1pdHRlcn1cbiAqL1xuXG5FbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24oZXZlbnQpe1xuICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpXG4gICAgLCBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuXG4gIGlmIChjYWxsYmFja3MpIHtcbiAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGNhbGxiYWNrcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKGV2ZW50KXtcbiAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24oZXZlbnQpe1xuICByZXR1cm4gISEgdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbn07XG4iLCJcbi8qKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gZGVidWc7XG5cbi8qKlxuICogQ3JlYXRlIGEgZGVidWdnZXIgd2l0aCB0aGUgZ2l2ZW4gYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtUeXBlfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBkZWJ1ZyhuYW1lKSB7XG4gIGlmICghZGVidWcuZW5hYmxlZChuYW1lKSkgcmV0dXJuIGZ1bmN0aW9uKCl7fTtcblxuICByZXR1cm4gZnVuY3Rpb24oZm10KXtcbiAgICBmbXQgPSBjb2VyY2UoZm10KTtcblxuICAgIHZhciBjdXJyID0gbmV3IERhdGU7XG4gICAgdmFyIG1zID0gY3VyciAtIChkZWJ1Z1tuYW1lXSB8fCBjdXJyKTtcbiAgICBkZWJ1Z1tuYW1lXSA9IGN1cnI7XG5cbiAgICBmbXQgPSBuYW1lXG4gICAgICArICcgJ1xuICAgICAgKyBmbXRcbiAgICAgICsgJyArJyArIGRlYnVnLmh1bWFuaXplKG1zKTtcblxuICAgIC8vIFRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4XG4gICAgLy8gd2hlcmUgYGNvbnNvbGUubG9nYCBkb2Vzbid0IGhhdmUgJ2FwcGx5J1xuICAgIHdpbmRvdy5jb25zb2xlXG4gICAgICAmJiBjb25zb2xlLmxvZ1xuICAgICAgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgY3VycmVudGx5IGFjdGl2ZSBkZWJ1ZyBtb2RlIG5hbWVzLlxuICovXG5cbmRlYnVnLm5hbWVzID0gW107XG5kZWJ1Zy5za2lwcyA9IFtdO1xuXG4vKipcbiAqIEVuYWJsZXMgYSBkZWJ1ZyBtb2RlIGJ5IG5hbWUuIFRoaXMgY2FuIGluY2x1ZGUgbW9kZXNcbiAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZGVidWcuZW5hYmxlID0gZnVuY3Rpb24obmFtZSkge1xuICB0cnkge1xuICAgIGxvY2FsU3RvcmFnZS5kZWJ1ZyA9IG5hbWU7XG4gIH0gY2F0Y2goZSl7fVxuXG4gIHZhciBzcGxpdCA9IChuYW1lIHx8ICcnKS5zcGxpdCgvW1xccyxdKy8pXG4gICAgLCBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIG5hbWUgPSBzcGxpdFtpXS5yZXBsYWNlKCcqJywgJy4qPycpO1xuICAgIGlmIChuYW1lWzBdID09PSAnLScpIHtcbiAgICAgIGRlYnVnLnNraXBzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lLnN1YnN0cigxKSArICckJykpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGRlYnVnLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lICsgJyQnKSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIERpc2FibGUgZGVidWcgb3V0cHV0LlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZGVidWcuZGlzYWJsZSA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnLmVuYWJsZSgnJyk7XG59O1xuXG4vKipcbiAqIEh1bWFuaXplIHRoZSBnaXZlbiBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5kZWJ1Zy5odW1hbml6ZSA9IGZ1bmN0aW9uKG1zKSB7XG4gIHZhciBzZWMgPSAxMDAwXG4gICAgLCBtaW4gPSA2MCAqIDEwMDBcbiAgICAsIGhvdXIgPSA2MCAqIG1pbjtcblxuICBpZiAobXMgPj0gaG91cikgcmV0dXJuIChtcyAvIGhvdXIpLnRvRml4ZWQoMSkgKyAnaCc7XG4gIGlmIChtcyA+PSBtaW4pIHJldHVybiAobXMgLyBtaW4pLnRvRml4ZWQoMSkgKyAnbSc7XG4gIGlmIChtcyA+PSBzZWMpIHJldHVybiAobXMgLyBzZWMgfCAwKSArICdzJztcbiAgcmV0dXJuIG1zICsgJ21zJztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBtb2RlIG5hbWUgaXMgZW5hYmxlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5kZWJ1Zy5lbmFibGVkID0gZnVuY3Rpb24obmFtZSkge1xuICBmb3IgKHZhciBpID0gMCwgbGVuID0gZGVidWcuc2tpcHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoZGVidWcuc2tpcHNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBmb3IgKHZhciBpID0gMCwgbGVuID0gZGVidWcubmFtZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBpZiAoZGVidWcubmFtZXNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbi8qKlxuICogQ29lcmNlIGB2YWxgLlxuICovXG5cbmZ1bmN0aW9uIGNvZXJjZSh2YWwpIHtcbiAgaWYgKHZhbCBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gdmFsLnN0YWNrIHx8IHZhbC5tZXNzYWdlO1xuICByZXR1cm4gdmFsO1xufVxuXG4vLyBwZXJzaXN0XG5cbnRyeSB7XG4gIGlmICh3aW5kb3cubG9jYWxTdG9yYWdlKSBkZWJ1Zy5lbmFibGUobG9jYWxTdG9yYWdlLmRlYnVnKTtcbn0gY2F0Y2goZSl7fVxuIiwiXG5tb2R1bGUuZXhwb3J0cyA9ICByZXF1aXJlKCcuL2xpYi8nKTtcbiIsIlxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL3NvY2tldCcpO1xuXG4vKipcbiAqIEV4cG9ydHMgcGFyc2VyXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqXG4gKi9cbm1vZHVsZS5leHBvcnRzLnBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgdHJhbnNwb3J0cyA9IHJlcXVpcmUoJy4vdHJhbnNwb3J0cycpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpzb2NrZXQnKTtcbnZhciBpbmRleCA9IHJlcXVpcmUoJ2luZGV4b2YnKTtcbnZhciBwYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG52YXIgcGFyc2V1cmkgPSByZXF1aXJlKCdwYXJzZXVyaScpO1xudmFyIHBhcnNlanNvbiA9IHJlcXVpcmUoJ3BhcnNlanNvbicpO1xudmFyIHBhcnNlcXMgPSByZXF1aXJlKCdwYXJzZXFzJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBTb2NrZXQ7XG5cbi8qKlxuICogTm9vcCBmdW5jdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBub29wKCl7fVxuXG4vKipcbiAqIFNvY2tldCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xPYmplY3R9IHVyaSBvciBvcHRpb25zXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBTb2NrZXQodXJpLCBvcHRzKXtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFNvY2tldCkpIHJldHVybiBuZXcgU29ja2V0KHVyaSwgb3B0cyk7XG5cbiAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgaWYgKHVyaSAmJiAnb2JqZWN0JyA9PSB0eXBlb2YgdXJpKSB7XG4gICAgb3B0cyA9IHVyaTtcbiAgICB1cmkgPSBudWxsO1xuICB9XG5cbiAgaWYgKHVyaSkge1xuICAgIHVyaSA9IHBhcnNldXJpKHVyaSk7XG4gICAgb3B0cy5ob3N0ID0gdXJpLmhvc3Q7XG4gICAgb3B0cy5zZWN1cmUgPSB1cmkucHJvdG9jb2wgPT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT0gJ3dzcyc7XG4gICAgb3B0cy5wb3J0ID0gdXJpLnBvcnQ7XG4gICAgaWYgKHVyaS5xdWVyeSkgb3B0cy5xdWVyeSA9IHVyaS5xdWVyeTtcbiAgfVxuXG4gIHRoaXMuc2VjdXJlID0gbnVsbCAhPSBvcHRzLnNlY3VyZSA/IG9wdHMuc2VjdXJlIDpcbiAgICAoZ2xvYmFsLmxvY2F0aW9uICYmICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sKTtcblxuICBpZiAob3B0cy5ob3N0KSB7XG4gICAgdmFyIHBpZWNlcyA9IG9wdHMuaG9zdC5zcGxpdCgnOicpO1xuICAgIG9wdHMuaG9zdG5hbWUgPSBwaWVjZXMuc2hpZnQoKTtcbiAgICBpZiAocGllY2VzLmxlbmd0aCkgb3B0cy5wb3J0ID0gcGllY2VzLnBvcCgpO1xuICB9XG5cbiAgdGhpcy5hZ2VudCA9IG9wdHMuYWdlbnQgfHwgZmFsc2U7XG4gIHRoaXMuaG9zdG5hbWUgPSBvcHRzLmhvc3RuYW1lIHx8XG4gICAgKGdsb2JhbC5sb2NhdGlvbiA/IGxvY2F0aW9uLmhvc3RuYW1lIDogJ2xvY2FsaG9zdCcpO1xuICB0aGlzLnBvcnQgPSBvcHRzLnBvcnQgfHwgKGdsb2JhbC5sb2NhdGlvbiAmJiBsb2NhdGlvbi5wb3J0ID9cbiAgICAgICBsb2NhdGlvbi5wb3J0IDpcbiAgICAgICAodGhpcy5zZWN1cmUgPyA0NDMgOiA4MCkpO1xuICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeSB8fCB7fTtcbiAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB0aGlzLnF1ZXJ5KSB0aGlzLnF1ZXJ5ID0gcGFyc2Vxcy5kZWNvZGUodGhpcy5xdWVyeSk7XG4gIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gIHRoaXMucGF0aCA9IChvcHRzLnBhdGggfHwgJy9lbmdpbmUuaW8nKS5yZXBsYWNlKC9cXC8kLywgJycpICsgJy8nO1xuICB0aGlzLmZvcmNlSlNPTlAgPSAhIW9wdHMuZm9yY2VKU09OUDtcbiAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICB0aGlzLmZvcmNlQmFzZTY0ID0gISFvcHRzLmZvcmNlQmFzZTY0O1xuICB0aGlzLmVuYWJsZXNYRFIgPSAhIW9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgdGhpcy50cmFuc3BvcnRzID0gb3B0cy50cmFuc3BvcnRzIHx8IFsncG9sbGluZycsICd3ZWJzb2NrZXQnXTtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gIHRoaXMud3JpdGVCdWZmZXIgPSBbXTtcbiAgdGhpcy5jYWxsYmFja0J1ZmZlciA9IFtdO1xuICB0aGlzLnBvbGljeVBvcnQgPSBvcHRzLnBvbGljeVBvcnQgfHwgODQzO1xuICB0aGlzLnJlbWVtYmVyVXBncmFkZSA9IG9wdHMucmVtZW1iZXJVcGdyYWRlIHx8IGZhbHNlO1xuICB0aGlzLm9wZW4oKTtcbiAgdGhpcy5iaW5hcnlUeXBlID0gbnVsbDtcbiAgdGhpcy5vbmx5QmluYXJ5VXBncmFkZXMgPSBvcHRzLm9ubHlCaW5hcnlVcGdyYWRlcztcbn1cblxuU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAuXG4gKi9cblxuRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuLyoqXG4gKiBQcm90b2NvbCB2ZXJzaW9uLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4vKipcbiAqIEV4cG9zZSBkZXBzIGZvciBsZWdhY3kgY29tcGF0aWJpbGl0eVxuICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gKi9cblxuU29ja2V0LlNvY2tldCA9IFNvY2tldDtcblNvY2tldC5UcmFuc3BvcnQgPSByZXF1aXJlKCcuL3RyYW5zcG9ydCcpO1xuU29ja2V0LnRyYW5zcG9ydHMgPSByZXF1aXJlKCcuL3RyYW5zcG9ydHMnKTtcblNvY2tldC5wYXJzZXIgPSByZXF1aXJlKCdlbmdpbmUuaW8tcGFyc2VyJyk7XG5cbi8qKlxuICogQ3JlYXRlcyB0cmFuc3BvcnQgb2YgdGhlIGdpdmVuIHR5cGUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmNyZWF0ZVRyYW5zcG9ydCA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gIGRlYnVnKCdjcmVhdGluZyB0cmFuc3BvcnQgXCIlc1wiJywgbmFtZSk7XG4gIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gIC8vIGFwcGVuZCBlbmdpbmUuaW8gcHJvdG9jb2wgaWRlbnRpZmllclxuICBxdWVyeS5FSU8gPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgcXVlcnkudHJhbnNwb3J0ID0gbmFtZTtcblxuICAvLyBzZXNzaW9uIGlkIGlmIHdlIGFscmVhZHkgaGF2ZSBvbmVcbiAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgdmFyIHRyYW5zcG9ydCA9IG5ldyB0cmFuc3BvcnRzW25hbWVdKHtcbiAgICBhZ2VudDogdGhpcy5hZ2VudCxcbiAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICBwb3J0OiB0aGlzLnBvcnQsXG4gICAgc2VjdXJlOiB0aGlzLnNlY3VyZSxcbiAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgcXVlcnk6IHF1ZXJ5LFxuICAgIGZvcmNlSlNPTlA6IHRoaXMuZm9yY2VKU09OUCxcbiAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICBmb3JjZUJhc2U2NDogdGhpcy5mb3JjZUJhc2U2NCxcbiAgICBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIsXG4gICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgdGltZXN0YW1wUGFyYW06IHRoaXMudGltZXN0YW1wUGFyYW0sXG4gICAgcG9saWN5UG9ydDogdGhpcy5wb2xpY3lQb3J0LFxuICAgIHNvY2tldDogdGhpc1xuICB9KTtcblxuICByZXR1cm4gdHJhbnNwb3J0O1xufTtcblxuZnVuY3Rpb24gY2xvbmUgKG9iaikge1xuICB2YXIgbyA9IHt9O1xuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgfVxuICB9XG4gIHJldHVybiBvO1xufVxuXG4vKipcbiAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuU29ja2V0LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdHJhbnNwb3J0O1xuICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT0gLTEpIHtcbiAgICB0cmFuc3BvcnQgPSAnd2Vic29ja2V0JztcbiAgfSBlbHNlIGlmICgwID09IHRoaXMudHJhbnNwb3J0cy5sZW5ndGgpIHtcbiAgICAvLyBFbWl0IGVycm9yIG9uIG5leHQgdGljayBzbyBpdCBjYW4gYmUgbGlzdGVuZWQgdG9cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuZW1pdCgnZXJyb3InLCAnTm8gdHJhbnNwb3J0cyBhdmFpbGFibGUnKTtcbiAgICB9LCAwKTtcbiAgICByZXR1cm47XG4gIH0gZWxzZSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICB9XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuaW5nJztcblxuICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gIHZhciB0cmFuc3BvcnQ7XG4gIHRyeSB7XG4gICAgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMudHJhbnNwb3J0cy5zaGlmdCgpO1xuICAgIHRoaXMub3BlbigpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyYW5zcG9ydC5vcGVuKCk7XG4gIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2V0VHJhbnNwb3J0ID0gZnVuY3Rpb24odHJhbnNwb3J0KXtcbiAgZGVidWcoJ3NldHRpbmcgdHJhbnNwb3J0ICVzJywgdHJhbnNwb3J0Lm5hbWUpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHRoaXMudHJhbnNwb3J0KSB7XG4gICAgZGVidWcoJ2NsZWFyaW5nIGV4aXN0aW5nIHRyYW5zcG9ydCAlcycsIHRoaXMudHJhbnNwb3J0Lm5hbWUpO1xuICAgIHRoaXMudHJhbnNwb3J0LnJlbW92ZUFsbExpc3RlbmVycygpO1xuICB9XG5cbiAgLy8gc2V0IHVwIHRyYW5zcG9ydFxuICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcblxuICAvLyBzZXQgdXAgdHJhbnNwb3J0IGxpc3RlbmVyc1xuICB0cmFuc3BvcnRcbiAgLm9uKCdkcmFpbicsIGZ1bmN0aW9uKCl7XG4gICAgc2VsZi5vbkRyYWluKCk7XG4gIH0pXG4gIC5vbigncGFja2V0JywgZnVuY3Rpb24ocGFja2V0KXtcbiAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gIH0pXG4gIC5vbignZXJyb3InLCBmdW5jdGlvbihlKXtcbiAgICBzZWxmLm9uRXJyb3IoZSk7XG4gIH0pXG4gIC5vbignY2xvc2UnLCBmdW5jdGlvbigpe1xuICAgIHNlbGYub25DbG9zZSgndHJhbnNwb3J0IGNsb3NlJyk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBQcm9iZXMgYSB0cmFuc3BvcnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgZGVidWcoJ3Byb2JpbmcgdHJhbnNwb3J0IFwiJXNcIicsIG5hbWUpO1xuICB2YXIgdHJhbnNwb3J0ID0gdGhpcy5jcmVhdGVUcmFuc3BvcnQobmFtZSwgeyBwcm9iZTogMSB9KVxuICAgICwgZmFpbGVkID0gZmFsc2VcbiAgICAsIHNlbGYgPSB0aGlzO1xuXG4gIFNvY2tldC5wcmlvcldlYnNvY2tldFN1Y2Nlc3MgPSBmYWxzZTtcblxuICBmdW5jdGlvbiBvblRyYW5zcG9ydE9wZW4oKXtcbiAgICBpZiAoc2VsZi5vbmx5QmluYXJ5VXBncmFkZXMpIHtcbiAgICAgIHZhciB1cGdyYWRlTG9zZXNCaW5hcnkgPSAhdGhpcy5zdXBwb3J0c0JpbmFyeSAmJiBzZWxmLnRyYW5zcG9ydC5zdXBwb3J0c0JpbmFyeTtcbiAgICAgIGZhaWxlZCA9IGZhaWxlZCB8fCB1cGdyYWRlTG9zZXNCaW5hcnk7XG4gICAgfVxuICAgIGlmIChmYWlsZWQpIHJldHVybjtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIG9wZW5lZCcsIG5hbWUpO1xuICAgIHRyYW5zcG9ydC5zZW5kKFt7IHR5cGU6ICdwaW5nJywgZGF0YTogJ3Byb2JlJyB9XSk7XG4gICAgdHJhbnNwb3J0Lm9uY2UoJ3BhY2tldCcsIGZ1bmN0aW9uIChtc2cpIHtcbiAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgIGlmICgncG9uZycgPT0gbXNnLnR5cGUgJiYgJ3Byb2JlJyA9PSBtc2cuZGF0YSkge1xuICAgICAgICBkZWJ1ZygncHJvYmUgdHJhbnNwb3J0IFwiJXNcIiBwb25nJywgbmFtZSk7XG4gICAgICAgIHNlbGYudXBncmFkaW5nID0gdHJ1ZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRpbmcnLCB0cmFuc3BvcnQpO1xuICAgICAgICBpZiAoIXRyYW5zcG9ydCkgcmV0dXJuO1xuICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gJ3dlYnNvY2tldCcgPT0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICAgICAgZGVidWcoJ3BhdXNpbmcgY3VycmVudCB0cmFuc3BvcnQgXCIlc1wiJywgc2VsZi50cmFuc3BvcnQubmFtZSk7XG4gICAgICAgIHNlbGYudHJhbnNwb3J0LnBhdXNlKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAoZmFpbGVkKSByZXR1cm47XG4gICAgICAgICAgaWYgKCdjbG9zZWQnID09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgIGRlYnVnKCdjaGFuZ2luZyB0cmFuc3BvcnQgYW5kIHNlbmRpbmcgdXBncmFkZSBwYWNrZXQnKTtcblxuICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgIHNlbGYuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgdHJhbnNwb3J0LnNlbmQoW3sgdHlwZTogJ3VwZ3JhZGUnIH1dKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgIHRyYW5zcG9ydCA9IG51bGw7XG4gICAgICAgICAgc2VsZi51cGdyYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yJyk7XG4gICAgICAgIGVyci50cmFuc3BvcnQgPSB0cmFuc3BvcnQubmFtZTtcbiAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZnJlZXplVHJhbnNwb3J0KCkge1xuICAgIGlmIChmYWlsZWQpIHJldHVybjtcblxuICAgIC8vIEFueSBjYWxsYmFjayBjYWxsZWQgYnkgdHJhbnNwb3J0IHNob3VsZCBiZSBpZ25vcmVkIHNpbmNlIG5vd1xuICAgIGZhaWxlZCA9IHRydWU7XG5cbiAgICBjbGVhbnVwKCk7XG5cbiAgICB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICB0cmFuc3BvcnQgPSBudWxsO1xuICB9XG5cbiAgLy9IYW5kbGUgYW55IGVycm9yIHRoYXQgaGFwcGVucyB3aGlsZSBwcm9iaW5nXG4gIGZ1bmN0aW9uIG9uZXJyb3IoZXJyKSB7XG4gICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcjogJyArIGVycik7XG4gICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICBmcmVlemVUcmFuc3BvcnQoKTtcblxuICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIGZhaWxlZCBiZWNhdXNlIG9mIGVycm9yOiAlcycsIG5hbWUsIGVycik7XG5cbiAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uVHJhbnNwb3J0Q2xvc2UoKXtcbiAgICBvbmVycm9yKFwidHJhbnNwb3J0IGNsb3NlZFwiKTtcbiAgfVxuXG4gIC8vV2hlbiB0aGUgc29ja2V0IGlzIGNsb3NlZCB3aGlsZSB3ZSdyZSBwcm9iaW5nXG4gIGZ1bmN0aW9uIG9uY2xvc2UoKXtcbiAgICBvbmVycm9yKFwic29ja2V0IGNsb3NlZFwiKTtcbiAgfVxuXG4gIC8vV2hlbiB0aGUgc29ja2V0IGlzIHVwZ3JhZGVkIHdoaWxlIHdlJ3JlIHByb2JpbmdcbiAgZnVuY3Rpb24gb251cGdyYWRlKHRvKXtcbiAgICBpZiAodHJhbnNwb3J0ICYmIHRvLm5hbWUgIT0gdHJhbnNwb3J0Lm5hbWUpIHtcbiAgICAgIGRlYnVnKCdcIiVzXCIgd29ya3MgLSBhYm9ydGluZyBcIiVzXCInLCB0by5uYW1lLCB0cmFuc3BvcnQubmFtZSk7XG4gICAgICBmcmVlemVUcmFuc3BvcnQoKTtcbiAgICB9XG4gIH1cblxuICAvL1JlbW92ZSBhbGwgbGlzdGVuZXJzIG9uIHRoZSB0cmFuc3BvcnQgYW5kIG9uIHNlbGZcbiAgZnVuY3Rpb24gY2xlYW51cCgpe1xuICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignb3BlbicsIG9uVHJhbnNwb3J0T3Blbik7XG4gICAgdHJhbnNwb3J0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpO1xuICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcbiAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ3VwZ3JhZGluZycsIG9udXBncmFkZSk7XG4gIH1cblxuICB0cmFuc3BvcnQub25jZSgnb3BlbicsIG9uVHJhbnNwb3J0T3Blbik7XG4gIHRyYW5zcG9ydC5vbmNlKCdlcnJvcicsIG9uZXJyb3IpO1xuICB0cmFuc3BvcnQub25jZSgnY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcblxuICB0aGlzLm9uY2UoJ2Nsb3NlJywgb25jbG9zZSk7XG4gIHRoaXMub25jZSgndXBncmFkaW5nJywgb251cGdyYWRlKTtcblxuICB0cmFuc3BvcnQub3BlbigpO1xuXG59O1xuXG4vKipcbiAqIENhbGxlZCB3aGVuIGNvbm5lY3Rpb24gaXMgZGVlbWVkIG9wZW4uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdvcGVuJztcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9ICd3ZWJzb2NrZXQnID09IHRoaXMudHJhbnNwb3J0Lm5hbWU7XG4gIHRoaXMuZW1pdCgnb3BlbicpO1xuICB0aGlzLmZsdXNoKCk7XG5cbiAgLy8gd2UgY2hlY2sgZm9yIGByZWFkeVN0YXRlYCBpbiBjYXNlIGFuIGBvcGVuYFxuICAvLyBsaXN0ZW5lciBhbHJlYWR5IGNsb3NlZCB0aGUgc29ja2V0XG4gIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudXBncmFkZSAmJiB0aGlzLnRyYW5zcG9ydC5wYXVzZSkge1xuICAgIGRlYnVnKCdzdGFydGluZyB1cGdyYWRlIHByb2JlcycpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy51cGdyYWRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRoaXMucHJvYmUodGhpcy51cGdyYWRlc1tpXSk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIEhhbmRsZXMgYSBwYWNrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vblBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIGRlYnVnKCdzb2NrZXQgcmVjZWl2ZTogdHlwZSBcIiVzXCIsIGRhdGEgXCIlc1wiJywgcGFja2V0LnR5cGUsIHBhY2tldC5kYXRhKTtcblxuICAgIHRoaXMuZW1pdCgncGFja2V0JywgcGFja2V0KTtcblxuICAgIC8vIFNvY2tldCBpcyBsaXZlIC0gYW55IHBhY2tldCBjb3VudHNcbiAgICB0aGlzLmVtaXQoJ2hlYXJ0YmVhdCcpO1xuXG4gICAgc3dpdGNoIChwYWNrZXQudHlwZSkge1xuICAgICAgY2FzZSAnb3Blbic6XG4gICAgICAgIHRoaXMub25IYW5kc2hha2UocGFyc2Vqc29uKHBhY2tldC5kYXRhKSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdwb25nJzpcbiAgICAgICAgdGhpcy5zZXRQaW5nKCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdlcnJvcic6XG4gICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ3NlcnZlciBlcnJvcicpO1xuICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGhhbmRzaGFrZSBjb21wbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgdGhpcy5lbWl0KCdoYW5kc2hha2UnLCBkYXRhKTtcbiAgdGhpcy5pZCA9IGRhdGEuc2lkO1xuICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgdGhpcy51cGdyYWRlcyA9IHRoaXMuZmlsdGVyVXBncmFkZXMoZGF0YS51cGdyYWRlcyk7XG4gIHRoaXMucGluZ0ludGVydmFsID0gZGF0YS5waW5nSW50ZXJ2YWw7XG4gIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICB0aGlzLm9uT3BlbigpO1xuICAvLyBJbiBjYXNlIG9wZW4gaGFuZGxlciBjbG9zZXMgc29ja2V0XG4gIGlmICAoJ2Nsb3NlZCcgPT0gdGhpcy5yZWFkeVN0YXRlKSByZXR1cm47XG4gIHRoaXMuc2V0UGluZygpO1xuXG4gIC8vIFByb2xvbmcgbGl2ZW5lc3Mgb2Ygc29ja2V0IG9uIGhlYXJ0YmVhdFxuICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdoZWFydGJlYXQnLCB0aGlzLm9uSGVhcnRiZWF0KTtcbiAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG59O1xuXG4vKipcbiAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkhlYXJ0YmVhdCA9IGZ1bmN0aW9uICh0aW1lb3V0KSB7XG4gIGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lb3V0VGltZXIpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHNlbGYucGluZ1RpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGlmICgnY2xvc2VkJyA9PSBzZWxmLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICBzZWxmLm9uQ2xvc2UoJ3BpbmcgdGltZW91dCcpO1xuICB9LCB0aW1lb3V0IHx8IChzZWxmLnBpbmdJbnRlcnZhbCArIHNlbGYucGluZ1RpbWVvdXQpKTtcbn07XG5cbi8qKlxuICogUGluZ3Mgc2VydmVyIGV2ZXJ5IGB0aGlzLnBpbmdJbnRlcnZhbGAgYW5kIGV4cGVjdHMgcmVzcG9uc2VcbiAqIHdpdGhpbiBgdGhpcy5waW5nVGltZW91dGAgb3IgY2xvc2VzIGNvbm5lY3Rpb24uXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5zZXRQaW5nID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGNsZWFyVGltZW91dChzZWxmLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgc2VsZi5waW5nSW50ZXJ2YWxUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgIGRlYnVnKCd3cml0aW5nIHBpbmcgcGFja2V0IC0gZXhwZWN0aW5nIHBvbmcgd2l0aGluICVzbXMnLCBzZWxmLnBpbmdUaW1lb3V0KTtcbiAgICBzZWxmLnBpbmcoKTtcbiAgICBzZWxmLm9uSGVhcnRiZWF0KHNlbGYucGluZ1RpbWVvdXQpO1xuICB9LCBzZWxmLnBpbmdJbnRlcnZhbCk7XG59O1xuXG4vKipcbiogU2VuZHMgYSBwaW5nIHBhY2tldC5cbipcbiogQGFwaSBwdWJsaWNcbiovXG5cblNvY2tldC5wcm90b3R5cGUucGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5zZW5kUGFja2V0KCdwaW5nJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkRyYWluID0gZnVuY3Rpb24oKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5wcmV2QnVmZmVyTGVuOyBpKyspIHtcbiAgICBpZiAodGhpcy5jYWxsYmFja0J1ZmZlcltpXSkge1xuICAgICAgdGhpcy5jYWxsYmFja0J1ZmZlcltpXSgpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMud3JpdGVCdWZmZXIuc3BsaWNlKDAsIHRoaXMucHJldkJ1ZmZlckxlbik7XG4gIHRoaXMuY2FsbGJhY2tCdWZmZXIuc3BsaWNlKDAsIHRoaXMucHJldkJ1ZmZlckxlbik7XG5cbiAgLy8gc2V0dGluZyBwcmV2QnVmZmVyTGVuID0gMCBpcyB2ZXJ5IGltcG9ydGFudFxuICAvLyBmb3IgZXhhbXBsZSwgd2hlbiB1cGdyYWRpbmcsIHVwZ3JhZGUgcGFja2V0IGlzIHNlbnQgb3ZlcixcbiAgLy8gYW5kIGEgbm9uemVybyBwcmV2QnVmZmVyTGVuIGNvdWxkIGNhdXNlIHByb2JsZW1zIG9uIGBkcmFpbmBcbiAgdGhpcy5wcmV2QnVmZmVyTGVuID0gMDtcblxuICBpZiAodGhpcy53cml0ZUJ1ZmZlci5sZW5ndGggPT0gMCkge1xuICAgIHRoaXMuZW1pdCgnZHJhaW4nKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmZsdXNoKCk7XG4gIH1cbn07XG5cbi8qKlxuICogRmx1c2ggd3JpdGUgYnVmZmVycy5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24gKCkge1xuICBpZiAoJ2Nsb3NlZCcgIT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmXG4gICAgIXRoaXMudXBncmFkaW5nICYmIHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgZGVidWcoJ2ZsdXNoaW5nICVkIHBhY2tldHMgaW4gc29ja2V0JywgdGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpO1xuICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgLy8ga2VlcCB0cmFjayBvZiBjdXJyZW50IGxlbmd0aCBvZiB3cml0ZUJ1ZmZlclxuICAgIC8vIHNwbGljZSB3cml0ZUJ1ZmZlciBhbmQgY2FsbGJhY2tCdWZmZXIgb24gYGRyYWluYFxuICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgIHRoaXMuZW1pdCgnZmx1c2gnKTtcbiAgfVxufTtcblxuLyoqXG4gKiBTZW5kcyBhIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge1NvY2tldH0gZm9yIGNoYWluaW5nLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Tb2NrZXQucHJvdG90eXBlLndyaXRlID1cblNvY2tldC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChtc2csIGZuKSB7XG4gIHRoaXMuc2VuZFBhY2tldCgnbWVzc2FnZScsIG1zZywgZm4pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2VuZHMgYSBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHBhY2tldCB0eXBlLlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGEuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuc2VuZFBhY2tldCA9IGZ1bmN0aW9uICh0eXBlLCBkYXRhLCBmbikge1xuICBpZiAoJ2Nsb3NpbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFja2V0ID0geyB0eXBlOiB0eXBlLCBkYXRhOiBkYXRhIH07XG4gIHRoaXMuZW1pdCgncGFja2V0Q3JlYXRlJywgcGFja2V0KTtcbiAgdGhpcy53cml0ZUJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gIHRoaXMuY2FsbGJhY2tCdWZmZXIucHVzaChmbik7XG4gIHRoaXMuZmx1c2goKTtcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICB0aGlzLnJlYWR5U3RhdGUgPSAnY2xvc2luZyc7XG5cbiAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgIHNlbGYub25DbG9zZSgnZm9yY2VkIGNsb3NlJyk7XG4gICAgICBkZWJ1Zygnc29ja2V0IGNsb3NpbmcgLSB0ZWxsaW5nIHRyYW5zcG9ydCB0byBjbG9zZScpO1xuICAgICAgc2VsZi50cmFuc3BvcnQuY2xvc2UoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjbGVhbnVwQW5kQ2xvc2UoKSB7XG4gICAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgICBjbG9zZSgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdhaXRGb3JVcGdyYWRlKCkge1xuICAgICAgLy8gd2FpdCBmb3IgdXBncmFkZSB0byBmaW5pc2ggc2luY2Ugd2UgY2FuJ3Qgc2VuZCBwYWNrZXRzIHdoaWxlIHBhdXNpbmcgYSB0cmFuc3BvcnRcbiAgICAgIHNlbGYub25jZSgndXBncmFkZScsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgICBzZWxmLm9uY2UoJ3VwZ3JhZGVFcnJvcicsIGNsZWFudXBBbmRDbG9zZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoKSB7XG4gICAgICB0aGlzLm9uY2UoJ2RyYWluJywgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLnVwZ3JhZGluZykge1xuICAgICAgICAgIHdhaXRGb3JVcGdyYWRlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2xvc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnVwZ3JhZGluZykge1xuICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICBkZWJ1Zygnc29ja2V0IGVycm9yICVqJywgZXJyKTtcbiAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgdGhpcy5vbkNsb3NlKCd0cmFuc3BvcnQgZXJyb3InLCBlcnIpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiB0cmFuc3BvcnQgY2xvc2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICBpZiAoJ29wZW5pbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdjbG9zaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICBkZWJ1Zygnc29ja2V0IGNsb3NlIHdpdGggcmVhc29uOiBcIiVzXCInLCByZWFzb24pO1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIC8vIGNsZWFyIHRpbWVyc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgIC8vIGNsZWFuIGJ1ZmZlcnMgaW4gbmV4dCB0aWNrLCBzbyBkZXZlbG9wZXJzIGNhbiBzdGlsbFxuICAgIC8vIGdyYWIgdGhlIGJ1ZmZlcnMgb24gYGNsb3NlYCBldmVudFxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICBzZWxmLndyaXRlQnVmZmVyID0gW107XG4gICAgICBzZWxmLmNhbGxiYWNrQnVmZmVyID0gW107XG4gICAgICBzZWxmLnByZXZCdWZmZXJMZW4gPSAwO1xuICAgIH0sIDApO1xuXG4gICAgLy8gc3RvcCBldmVudCBmcm9tIGZpcmluZyBhZ2FpbiBmb3IgdHJhbnNwb3J0XG4gICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCdjbG9zZScpO1xuXG4gICAgLy8gZW5zdXJlIHRyYW5zcG9ydCB3b24ndCBzdGF5IG9wZW5cbiAgICB0aGlzLnRyYW5zcG9ydC5jbG9zZSgpO1xuXG4gICAgLy8gaWdub3JlIGZ1cnRoZXIgdHJhbnNwb3J0IGNvbW11bmljYXRpb25cbiAgICB0aGlzLnRyYW5zcG9ydC5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcblxuICAgIC8vIHNldCByZWFkeSBzdGF0ZVxuICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuXG4gICAgLy8gY2xlYXIgc2Vzc2lvbiBpZFxuICAgIHRoaXMuaWQgPSBudWxsO1xuXG4gICAgLy8gZW1pdCBjbG9zZSBldmVudFxuICAgIHRoaXMuZW1pdCgnY2xvc2UnLCByZWFzb24sIGRlc2MpO1xuICB9XG59O1xuXG4vKipcbiAqIEZpbHRlcnMgdXBncmFkZXMsIHJldHVybmluZyBvbmx5IHRob3NlIG1hdGNoaW5nIGNsaWVudCB0cmFuc3BvcnRzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHNlcnZlciB1cGdyYWRlc1xuICogQGFwaSBwcml2YXRlXG4gKlxuICovXG5cblNvY2tldC5wcm90b3R5cGUuZmlsdGVyVXBncmFkZXMgPSBmdW5jdGlvbiAodXBncmFkZXMpIHtcbiAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDAsIGogPSB1cGdyYWRlcy5sZW5ndGg7IGk8ajsgaSsrKSB7XG4gICAgaWYgKH5pbmRleCh0aGlzLnRyYW5zcG9ydHMsIHVwZ3JhZGVzW2ldKSkgZmlsdGVyZWRVcGdyYWRlcy5wdXNoKHVwZ3JhZGVzW2ldKTtcbiAgfVxuICByZXR1cm4gZmlsdGVyZWRVcGdyYWRlcztcbn07XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIHBhcnNlciA9IHJlcXVpcmUoJ2VuZ2luZS5pby1wYXJzZXInKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnY29tcG9uZW50LWVtaXR0ZXInKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRyYW5zcG9ydDtcblxuLyoqXG4gKiBUcmFuc3BvcnQgYWJzdHJhY3QgY29uc3RydWN0b3IuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBUcmFuc3BvcnQgKG9wdHMpIHtcbiAgdGhpcy5wYXRoID0gb3B0cy5wYXRoO1xuICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZTtcbiAgdGhpcy5wb3J0ID0gb3B0cy5wb3J0O1xuICB0aGlzLnNlY3VyZSA9IG9wdHMuc2VjdXJlO1xuICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW07XG4gIHRoaXMudGltZXN0YW1wUmVxdWVzdHMgPSBvcHRzLnRpbWVzdGFtcFJlcXVlc3RzO1xuICB0aGlzLnJlYWR5U3RhdGUgPSAnJztcbiAgdGhpcy5hZ2VudCA9IG9wdHMuYWdlbnQgfHwgZmFsc2U7XG4gIHRoaXMuc29ja2V0ID0gb3B0cy5zb2NrZXQ7XG4gIHRoaXMuZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoVHJhbnNwb3J0LnByb3RvdHlwZSk7XG5cbi8qKlxuICogQSBjb3VudGVyIHVzZWQgdG8gcHJldmVudCBjb2xsaXNpb25zIGluIHRoZSB0aW1lc3RhbXBzIHVzZWRcbiAqIGZvciBjYWNoZSBidXN0aW5nLlxuICovXG5cblRyYW5zcG9ydC50aW1lc3RhbXBzID0gMDtcblxuLyoqXG4gKiBFbWl0cyBhbiBlcnJvci5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtUcmFuc3BvcnR9IGZvciBjaGFpbmluZ1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uRXJyb3IgPSBmdW5jdGlvbiAobXNnLCBkZXNjKSB7XG4gIHZhciBlcnIgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyLnR5cGUgPSAnVHJhbnNwb3J0RXJyb3InO1xuICBlcnIuZGVzY3JpcHRpb24gPSBkZXNjO1xuICB0aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIE9wZW5zIHRoZSB0cmFuc3BvcnQuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICgnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJycgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICAgIHRoaXMuZG9PcGVuKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2xvc2VzIHRoZSB0cmFuc3BvcnQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgIHRoaXMub25DbG9zZSgpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24ocGFja2V0cyl7XG4gIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgdGhpcy53cml0ZShwYWNrZXRzKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1RyYW5zcG9ydCBub3Qgb3BlbicpO1xuICB9XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIG9wZW5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW4nO1xuICB0aGlzLndyaXRhYmxlID0gdHJ1ZTtcbiAgdGhpcy5lbWl0KCdvcGVuJyk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGRhdGEuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGRhdGFcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHZhciBwYWNrZXQgPSBwYXJzZXIuZGVjb2RlUGFja2V0KGRhdGEsIHRoaXMuc29ja2V0LmJpbmFyeVR5cGUpO1xuICB0aGlzLm9uUGFja2V0KHBhY2tldCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCB3aXRoIGEgZGVjb2RlZCBwYWNrZXQuXG4gKi9cblxuVHJhbnNwb3J0LnByb3RvdHlwZS5vblBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBjbG9zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5UcmFuc3BvcnQucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICB0aGlzLmVtaXQoJ2Nsb3NlJyk7XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzXG4gKi9cblxudmFyIFhNTEh0dHBSZXF1ZXN0ID0gcmVxdWlyZSgneG1saHR0cHJlcXVlc3QnKTtcbnZhciBYSFIgPSByZXF1aXJlKCcuL3BvbGxpbmcteGhyJyk7XG52YXIgSlNPTlAgPSByZXF1aXJlKCcuL3BvbGxpbmctanNvbnAnKTtcbnZhciB3ZWJzb2NrZXQgPSByZXF1aXJlKCcuL3dlYnNvY2tldCcpO1xuXG4vKipcbiAqIEV4cG9ydCB0cmFuc3BvcnRzLlxuICovXG5cbmV4cG9ydHMucG9sbGluZyA9IHBvbGxpbmc7XG5leHBvcnRzLndlYnNvY2tldCA9IHdlYnNvY2tldDtcblxuLyoqXG4gKiBQb2xsaW5nIHRyYW5zcG9ydCBwb2x5bW9ycGhpYyBjb25zdHJ1Y3Rvci5cbiAqIERlY2lkZXMgb24geGhyIHZzIGpzb25wIGJhc2VkIG9uIGZlYXR1cmUgZGV0ZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBvbGxpbmcob3B0cyl7XG4gIHZhciB4aHI7XG4gIHZhciB4ZCA9IGZhbHNlO1xuICB2YXIgeHMgPSBmYWxzZTtcbiAgdmFyIGpzb25wID0gZmFsc2UgIT09IG9wdHMuanNvbnA7XG5cbiAgaWYgKGdsb2JhbC5sb2NhdGlvbikge1xuICAgIHZhciBpc1NTTCA9ICdodHRwczonID09IGxvY2F0aW9uLnByb3RvY29sO1xuICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgIC8vIHNvbWUgdXNlciBhZ2VudHMgaGF2ZSBlbXB0eSBgbG9jYXRpb24ucG9ydGBcbiAgICBpZiAoIXBvcnQpIHtcbiAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgIH1cblxuICAgIHhkID0gb3B0cy5ob3N0bmFtZSAhPSBsb2NhdGlvbi5ob3N0bmFtZSB8fCBwb3J0ICE9IG9wdHMucG9ydDtcbiAgICB4cyA9IG9wdHMuc2VjdXJlICE9IGlzU1NMO1xuICB9XG5cbiAgb3B0cy54ZG9tYWluID0geGQ7XG4gIG9wdHMueHNjaGVtZSA9IHhzO1xuICB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3Qob3B0cyk7XG5cbiAgaWYgKCdvcGVuJyBpbiB4aHIgJiYgIW9wdHMuZm9yY2VKU09OUCkge1xuICAgIHJldHVybiBuZXcgWEhSKG9wdHMpO1xuICB9IGVsc2Uge1xuICAgIGlmICghanNvbnApIHRocm93IG5ldyBFcnJvcignSlNPTlAgZGlzYWJsZWQnKTtcbiAgICByZXR1cm4gbmV3IEpTT05QKG9wdHMpO1xuICB9XG59XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTtcbi8qKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgUG9sbGluZyA9IHJlcXVpcmUoJy4vcG9sbGluZycpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gSlNPTlBQb2xsaW5nO1xuXG4vKipcbiAqIENhY2hlZCByZWd1bGFyIGV4cHJlc3Npb25zLlxuICovXG5cbnZhciByTmV3bGluZSA9IC9cXG4vZztcbnZhciByRXNjYXBlZE5ld2xpbmUgPSAvXFxcXG4vZztcblxuLyoqXG4gKiBHbG9iYWwgSlNPTlAgY2FsbGJhY2tzLlxuICovXG5cbnZhciBjYWxsYmFja3M7XG5cbi8qKlxuICogQ2FsbGJhY2tzIGNvdW50LlxuICovXG5cbnZhciBpbmRleCA9IDA7XG5cbi8qKlxuICogTm9vcC5cbiAqL1xuXG5mdW5jdGlvbiBlbXB0eSAoKSB7IH1cblxuLyoqXG4gKiBKU09OUCBQb2xsaW5nIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBKU09OUFBvbGxpbmcgKG9wdHMpIHtcbiAgUG9sbGluZy5jYWxsKHRoaXMsIG9wdHMpO1xuXG4gIHRoaXMucXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuXG4gIC8vIGRlZmluZSBnbG9iYWwgY2FsbGJhY2tzIGFycmF5IGlmIG5vdCBwcmVzZW50XG4gIC8vIHdlIGRvIHRoaXMgaGVyZSAobGF6aWx5KSB0byBhdm9pZCB1bm5lZWRlZCBnbG9iYWwgcG9sbHV0aW9uXG4gIGlmICghY2FsbGJhY2tzKSB7XG4gICAgLy8gd2UgbmVlZCB0byBjb25zaWRlciBtdWx0aXBsZSBlbmdpbmVzIGluIHRoZSBzYW1lIHBhZ2VcbiAgICBpZiAoIWdsb2JhbC5fX19laW8pIGdsb2JhbC5fX19laW8gPSBbXTtcbiAgICBjYWxsYmFja3MgPSBnbG9iYWwuX19fZWlvO1xuICB9XG5cbiAgLy8gY2FsbGJhY2sgaWRlbnRpZmllclxuICB0aGlzLmluZGV4ID0gY2FsbGJhY2tzLmxlbmd0aDtcblxuICAvLyBhZGQgY2FsbGJhY2sgdG8ganNvbnAgZ2xvYmFsXG4gIHZhciBzZWxmID0gdGhpcztcbiAgY2FsbGJhY2tzLnB1c2goZnVuY3Rpb24gKG1zZykge1xuICAgIHNlbGYub25EYXRhKG1zZyk7XG4gIH0pO1xuXG4gIC8vIGFwcGVuZCB0byBxdWVyeSBzdHJpbmdcbiAgdGhpcy5xdWVyeS5qID0gdGhpcy5pbmRleDtcblxuICAvLyBwcmV2ZW50IHNwdXJpb3VzIGVycm9ycyBmcm9tIGJlaW5nIGVtaXR0ZWQgd2hlbiB0aGUgd2luZG93IGlzIHVubG9hZGVkXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQgJiYgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKHNlbGYuc2NyaXB0KSBzZWxmLnNjcmlwdC5vbmVycm9yID0gZW1wdHk7XG4gICAgfSwgZmFsc2UpO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICovXG5cbmluaGVyaXQoSlNPTlBQb2xsaW5nLCBQb2xsaW5nKTtcblxuLypcbiAqIEpTT05QIG9ubHkgc3VwcG9ydHMgYmluYXJ5IGFzIGJhc2U2NCBlbmNvZGVkIHN0cmluZ3NcbiAqL1xuXG5KU09OUFBvbGxpbmcucHJvdG90eXBlLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG5cbi8qKlxuICogQ2xvc2VzIHRoZSBzb2NrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zY3JpcHQpIHtcbiAgICB0aGlzLnNjcmlwdC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc2NyaXB0KTtcbiAgICB0aGlzLnNjcmlwdCA9IG51bGw7XG4gIH1cblxuICBpZiAodGhpcy5mb3JtKSB7XG4gICAgdGhpcy5mb3JtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5mb3JtKTtcbiAgICB0aGlzLmZvcm0gPSBudWxsO1xuICAgIHRoaXMuaWZyYW1lID0gbnVsbDtcbiAgfVxuXG4gIFBvbGxpbmcucHJvdG90eXBlLmRvQ2xvc2UuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogU3RhcnRzIGEgcG9sbCBjeWNsZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5KU09OUFBvbGxpbmcucHJvdG90eXBlLmRvUG9sbCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG5cbiAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgdGhpcy5zY3JpcHQgPSBudWxsO1xuICB9XG5cbiAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgc2NyaXB0LnNyYyA9IHRoaXMudXJpKCk7XG4gIHNjcmlwdC5vbmVycm9yID0gZnVuY3Rpb24oZSl7XG4gICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsIGVycm9yJyxlKTtcbiAgfTtcblxuICB2YXIgaW5zZXJ0QXQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF07XG4gIGluc2VydEF0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdCwgaW5zZXJ0QXQpO1xuICB0aGlzLnNjcmlwdCA9IHNjcmlwdDtcblxuICB2YXIgaXNVQWdlY2tvID0gJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIG5hdmlnYXRvciAmJiAvZ2Vja28vaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICBcbiAgaWYgKGlzVUFnZWNrbykge1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lmcmFtZScpO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChpZnJhbWUpO1xuICAgIH0sIDEwMCk7XG4gIH1cbn07XG5cbi8qKlxuICogV3JpdGVzIHdpdGggYSBoaWRkZW4gaWZyYW1lLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxlZCB1cG9uIGZsdXNoLlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1dyaXRlID0gZnVuY3Rpb24gKGRhdGEsIGZuKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoIXRoaXMuZm9ybSkge1xuICAgIHZhciBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZm9ybScpO1xuICAgIHZhciBhcmVhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGV4dGFyZWEnKTtcbiAgICB2YXIgaWQgPSB0aGlzLmlmcmFtZUlkID0gJ2Vpb19pZnJhbWVfJyArIHRoaXMuaW5kZXg7XG4gICAgdmFyIGlmcmFtZTtcblxuICAgIGZvcm0uY2xhc3NOYW1lID0gJ3NvY2tldGlvJztcbiAgICBmb3JtLnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBmb3JtLnN0eWxlLnRvcCA9ICctMTAwMHB4JztcbiAgICBmb3JtLnN0eWxlLmxlZnQgPSAnLTEwMDBweCc7XG4gICAgZm9ybS50YXJnZXQgPSBpZDtcbiAgICBmb3JtLm1ldGhvZCA9ICdQT1NUJztcbiAgICBmb3JtLnNldEF0dHJpYnV0ZSgnYWNjZXB0LWNoYXJzZXQnLCAndXRmLTgnKTtcbiAgICBhcmVhLm5hbWUgPSAnZCc7XG4gICAgZm9ybS5hcHBlbmRDaGlsZChhcmVhKTtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGZvcm0pO1xuXG4gICAgdGhpcy5mb3JtID0gZm9ybTtcbiAgICB0aGlzLmFyZWEgPSBhcmVhO1xuICB9XG5cbiAgdGhpcy5mb3JtLmFjdGlvbiA9IHRoaXMudXJpKCk7XG5cbiAgZnVuY3Rpb24gY29tcGxldGUgKCkge1xuICAgIGluaXRJZnJhbWUoKTtcbiAgICBmbigpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5pdElmcmFtZSAoKSB7XG4gICAgaWYgKHNlbGYuaWZyYW1lKSB7XG4gICAgICB0cnkge1xuICAgICAgICBzZWxmLmZvcm0ucmVtb3ZlQ2hpbGQoc2VsZi5pZnJhbWUpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBzZWxmLm9uRXJyb3IoJ2pzb25wIHBvbGxpbmcgaWZyYW1lIHJlbW92YWwgZXJyb3InLCBlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gaWU2IGR5bmFtaWMgaWZyYW1lcyB3aXRoIHRhcmdldD1cIlwiIHN1cHBvcnQgKHRoYW5rcyBDaHJpcyBMYW1iYWNoZXIpXG4gICAgICB2YXIgaHRtbCA9ICc8aWZyYW1lIHNyYz1cImphdmFzY3JpcHQ6MFwiIG5hbWU9XCInKyBzZWxmLmlmcmFtZUlkICsnXCI+JztcbiAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6MCc7XG4gICAgfVxuXG4gICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgIHNlbGYuZm9ybS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgIHNlbGYuaWZyYW1lID0gaWZyYW1lO1xuICB9XG5cbiAgaW5pdElmcmFtZSgpO1xuXG4gIC8vIGVzY2FwZSBcXG4gdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNvbnZlcnRlZCBpbnRvIFxcclxcbiBieSBzb21lIFVBc1xuICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UockVzY2FwZWROZXdsaW5lLCAnXFxcXFxcbicpO1xuICB0aGlzLmFyZWEudmFsdWUgPSBkYXRhLnJlcGxhY2Uock5ld2xpbmUsICdcXFxcbicpO1xuXG4gIHRyeSB7XG4gICAgdGhpcy5mb3JtLnN1Ym1pdCgpO1xuICB9IGNhdGNoKGUpIHt9XG5cbiAgaWYgKHRoaXMuaWZyYW1lLmF0dGFjaEV2ZW50KSB7XG4gICAgdGhpcy5pZnJhbWUub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKXtcbiAgICAgIGlmIChzZWxmLmlmcmFtZS5yZWFkeVN0YXRlID09ICdjb21wbGV0ZScpIHtcbiAgICAgICAgY29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHRoaXMuaWZyYW1lLm9ubG9hZCA9IGNvbXBsZXRlO1xuICB9XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBNb2R1bGUgcmVxdWlyZW1lbnRzLlxuICovXG5cbnZhciBYTUxIdHRwUmVxdWVzdCA9IHJlcXVpcmUoJ3htbGh0dHByZXF1ZXN0Jyk7XG52YXIgUG9sbGluZyA9IHJlcXVpcmUoJy4vcG9sbGluZycpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpwb2xsaW5nLXhocicpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gWEhSO1xubW9kdWxlLmV4cG9ydHMuUmVxdWVzdCA9IFJlcXVlc3Q7XG5cbi8qKlxuICogRW1wdHkgZnVuY3Rpb25cbiAqL1xuXG5mdW5jdGlvbiBlbXB0eSgpe31cblxuLyoqXG4gKiBYSFIgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBYSFIob3B0cyl7XG4gIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICBpZiAoZ2xvYmFsLmxvY2F0aW9uKSB7XG4gICAgdmFyIGlzU1NMID0gJ2h0dHBzOicgPT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgdmFyIHBvcnQgPSBsb2NhdGlvbi5wb3J0O1xuXG4gICAgLy8gc29tZSB1c2VyIGFnZW50cyBoYXZlIGVtcHR5IGBsb2NhdGlvbi5wb3J0YFxuICAgIGlmICghcG9ydCkge1xuICAgICAgcG9ydCA9IGlzU1NMID8gNDQzIDogODA7XG4gICAgfVxuXG4gICAgdGhpcy54ZCA9IG9wdHMuaG9zdG5hbWUgIT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8XG4gICAgICBwb3J0ICE9IG9wdHMucG9ydDtcbiAgICB0aGlzLnhzID0gb3B0cy5zZWN1cmUgIT0gaXNTU0w7XG4gIH1cbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFBvbGxpbmcuXG4gKi9cblxuaW5oZXJpdChYSFIsIFBvbGxpbmcpO1xuXG4vKipcbiAqIFhIUiBzdXBwb3J0cyBiaW5hcnlcbiAqL1xuXG5YSFIucHJvdG90eXBlLnN1cHBvcnRzQmluYXJ5ID0gdHJ1ZTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5YSFIucHJvdG90eXBlLnJlcXVlc3QgPSBmdW5jdGlvbihvcHRzKXtcbiAgb3B0cyA9IG9wdHMgfHwge307XG4gIG9wdHMudXJpID0gdGhpcy51cmkoKTtcbiAgb3B0cy54ZCA9IHRoaXMueGQ7XG4gIG9wdHMueHMgPSB0aGlzLnhzO1xuICBvcHRzLmFnZW50ID0gdGhpcy5hZ2VudCB8fCBmYWxzZTtcbiAgb3B0cy5zdXBwb3J0c0JpbmFyeSA9IHRoaXMuc3VwcG9ydHNCaW5hcnk7XG4gIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KG9wdHMpO1xufTtcblxuLyoqXG4gKiBTZW5kcyBkYXRhLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsZWQgdXBvbiBmbHVzaC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblhIUi5wcm90b3R5cGUuZG9Xcml0ZSA9IGZ1bmN0aW9uKGRhdGEsIGZuKXtcbiAgdmFyIGlzQmluYXJ5ID0gdHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnICYmIGRhdGEgIT09IHVuZGVmaW5lZDtcbiAgdmFyIHJlcSA9IHRoaXMucmVxdWVzdCh7IG1ldGhvZDogJ1BPU1QnLCBkYXRhOiBkYXRhLCBpc0JpbmFyeTogaXNCaW5hcnkgfSk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdzdWNjZXNzJywgZm4pO1xuICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKXtcbiAgICBzZWxmLm9uRXJyb3IoJ3hociBwb3N0IGVycm9yJywgZXJyKTtcbiAgfSk7XG4gIHRoaXMuc2VuZFhociA9IHJlcTtcbn07XG5cbi8qKlxuICogU3RhcnRzIGEgcG9sbCBjeWNsZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5YSFIucHJvdG90eXBlLmRvUG9sbCA9IGZ1bmN0aW9uKCl7XG4gIGRlYnVnKCd4aHIgcG9sbCcpO1xuICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmVxLm9uKCdkYXRhJywgZnVuY3Rpb24oZGF0YSl7XG4gICAgc2VsZi5vbkRhdGEoZGF0YSk7XG4gIH0pO1xuICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyKXtcbiAgICBzZWxmLm9uRXJyb3IoJ3hociBwb2xsIGVycm9yJywgZXJyKTtcbiAgfSk7XG4gIHRoaXMucG9sbFhociA9IHJlcTtcbn07XG5cbi8qKlxuICogUmVxdWVzdCBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIFJlcXVlc3Qob3B0cyl7XG4gIHRoaXMubWV0aG9kID0gb3B0cy5tZXRob2QgfHwgJ0dFVCc7XG4gIHRoaXMudXJpID0gb3B0cy51cmk7XG4gIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gIHRoaXMueHMgPSAhIW9wdHMueHM7XG4gIHRoaXMuYXN5bmMgPSBmYWxzZSAhPT0gb3B0cy5hc3luYztcbiAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9IG9wdHMuZGF0YSA/IG9wdHMuZGF0YSA6IG51bGw7XG4gIHRoaXMuYWdlbnQgPSBvcHRzLmFnZW50O1xuICB0aGlzLmlzQmluYXJ5ID0gb3B0cy5pc0JpbmFyeTtcbiAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IG9wdHMuc3VwcG9ydHNCaW5hcnk7XG4gIHRoaXMuZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcbiAgdGhpcy5jcmVhdGUoKTtcbn1cblxuLyoqXG4gKiBNaXggaW4gYEVtaXR0ZXJgLlxuICovXG5cbkVtaXR0ZXIoUmVxdWVzdC5wcm90b3R5cGUpO1xuXG4vKipcbiAqIENyZWF0ZXMgdGhlIFhIUiBvYmplY3QgYW5kIHNlbmRzIHRoZSByZXF1ZXN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uKCl7XG4gIHZhciB4aHIgPSB0aGlzLnhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCh7IGFnZW50OiB0aGlzLmFnZW50LCB4ZG9tYWluOiB0aGlzLnhkLCB4c2NoZW1lOiB0aGlzLnhzLCBlbmFibGVzWERSOiB0aGlzLmVuYWJsZXNYRFIgfSk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0cnkge1xuICAgIGRlYnVnKCd4aHIgb3BlbiAlczogJXMnLCB0aGlzLm1ldGhvZCwgdGhpcy51cmkpO1xuICAgIHhoci5vcGVuKHRoaXMubWV0aG9kLCB0aGlzLnVyaSwgdGhpcy5hc3luYyk7XG4gICAgaWYgKHRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICAgIC8vIFRoaXMgaGFzIHRvIGJlIGRvbmUgYWZ0ZXIgb3BlbiBiZWNhdXNlIEZpcmVmb3ggaXMgc3R1cGlkXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEzMjE2OTAzL2dldC1iaW5hcnktZGF0YS13aXRoLXhtbGh0dHByZXF1ZXN0LWluLWEtZmlyZWZveC1leHRlbnNpb25cbiAgICAgIHhoci5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInO1xuICAgIH1cblxuICAgIGlmICgnUE9TVCcgPT0gdGhpcy5tZXRob2QpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICh0aGlzLmlzQmluYXJ5KSB7XG4gICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCcpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7fVxuICAgIH1cblxuICAgIC8vIGllNiBjaGVja1xuICAgIGlmICgnd2l0aENyZWRlbnRpYWxzJyBpbiB4aHIpIHtcbiAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhhc1hEUigpKSB7XG4gICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24oKXtcbiAgICAgICAgc2VsZi5vbkxvYWQoKTtcbiAgICAgIH07XG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCl7XG4gICAgICAgIHNlbGYub25FcnJvcih4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpe1xuICAgICAgICBpZiAoNCAhPSB4aHIucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICBpZiAoMjAwID09IHhoci5zdGF0dXMgfHwgMTIyMyA9PSB4aHIuc3RhdHVzKSB7XG4gICAgICAgICAgc2VsZi5vbkxvYWQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGBlcnJvcmAgZXZlbnQgaGFuZGxlciB0aGF0J3MgdXNlci1zZXRcbiAgICAgICAgICAvLyBkb2VzIG5vdCB0aHJvdyBpbiB0aGUgc2FtZSB0aWNrIGFuZCBnZXRzIGNhdWdodCBoZXJlXG4gICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgICAgICAgc2VsZi5vbkVycm9yKHhoci5zdGF0dXMpO1xuICAgICAgICAgIH0sIDApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIGRlYnVnKCd4aHIgZGF0YSAlcycsIHRoaXMuZGF0YSk7XG4gICAgeGhyLnNlbmQodGhpcy5kYXRhKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIE5lZWQgdG8gZGVmZXIgc2luY2UgLmNyZWF0ZSgpIGlzIGNhbGxlZCBkaXJlY3RseSBmaHJvbSB0aGUgY29uc3RydWN0b3JcbiAgICAvLyBhbmQgdGh1cyB0aGUgJ2Vycm9yJyBldmVudCBjYW4gb25seSBiZSBvbmx5IGJvdW5kICphZnRlciogdGhpcyBleGNlcHRpb25cbiAgICAvLyBvY2N1cnMuICBUaGVyZWZvcmUsIGFsc28sIHdlIGNhbm5vdCB0aHJvdyBoZXJlIGF0IGFsbC5cbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5vbkVycm9yKGUpO1xuICAgIH0sIDApO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChnbG9iYWwuZG9jdW1lbnQpIHtcbiAgICB0aGlzLmluZGV4ID0gUmVxdWVzdC5yZXF1ZXN0c0NvdW50Kys7XG4gICAgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XSA9IHRoaXM7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gc3VjY2Vzc2Z1bCByZXNwb25zZS5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vblN1Y2Nlc3MgPSBmdW5jdGlvbigpe1xuICB0aGlzLmVtaXQoJ3N1Y2Nlc3MnKTtcbiAgdGhpcy5jbGVhbnVwKCk7XG59O1xuXG4vKipcbiAqIENhbGxlZCBpZiB3ZSBoYXZlIGRhdGEuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gIHRoaXMuZW1pdCgnZGF0YScsIGRhdGEpO1xuICB0aGlzLm9uU3VjY2VzcygpO1xufTtcblxuLyoqXG4gKiBDYWxsZWQgdXBvbiBlcnJvci5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5SZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24oZXJyKXtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gIHRoaXMuY2xlYW51cCgpO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgaG91c2UuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uKCl7XG4gIGlmICgndW5kZWZpbmVkJyA9PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgLy8geG1saHR0cHJlcXVlc3RcbiAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICB0aGlzLnhoci5vbmxvYWQgPSB0aGlzLnhoci5vbmVycm9yID0gZW1wdHk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy54aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZW1wdHk7XG4gIH1cblxuICB0cnkge1xuICAgIHRoaXMueGhyLmFib3J0KCk7XG4gIH0gY2F0Y2goZSkge31cblxuICBpZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gICAgZGVsZXRlIFJlcXVlc3QucmVxdWVzdHNbdGhpcy5pbmRleF07XG4gIH1cblxuICB0aGlzLnhociA9IG51bGw7XG59O1xuXG4vKipcbiAqIENhbGxlZCB1cG9uIGxvYWQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUmVxdWVzdC5wcm90b3R5cGUub25Mb2FkID0gZnVuY3Rpb24oKXtcbiAgdmFyIGRhdGE7XG4gIHRyeSB7XG4gICAgdmFyIGNvbnRlbnRUeXBlO1xuICAgIHRyeSB7XG4gICAgICBjb250ZW50VHlwZSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdDb250ZW50LVR5cGUnKS5zcGxpdCgnOycpWzBdO1xuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgaWYgKGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJykge1xuICAgICAgZGF0YSA9IHRoaXMueGhyLnJlc3BvbnNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkpIHtcbiAgICAgICAgZGF0YSA9IHRoaXMueGhyLnJlc3BvbnNlVGV4dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGEgPSAnb2snO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIHRoaXMub25FcnJvcihlKTtcbiAgfVxuICBpZiAobnVsbCAhPSBkYXRhKSB7XG4gICAgdGhpcy5vbkRhdGEoZGF0YSk7XG4gIH1cbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgaXQgaGFzIFhEb21haW5SZXF1ZXN0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmhhc1hEUiA9IGZ1bmN0aW9uKCl7XG4gIHJldHVybiAndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGdsb2JhbC5YRG9tYWluUmVxdWVzdCAmJiAhdGhpcy54cyAmJiB0aGlzLmVuYWJsZXNYRFI7XG59O1xuXG4vKipcbiAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cblJlcXVlc3QucHJvdG90eXBlLmFib3J0ID0gZnVuY3Rpb24oKXtcbiAgdGhpcy5jbGVhbnVwKCk7XG59O1xuXG4vKipcbiAqIEFib3J0cyBwZW5kaW5nIHJlcXVlc3RzIHdoZW4gdW5sb2FkaW5nIHRoZSB3aW5kb3cuIFRoaXMgaXMgbmVlZGVkIHRvIHByZXZlbnRcbiAqIG1lbW9yeSBsZWFrcyAoZS5nLiB3aGVuIHVzaW5nIElFKSBhbmQgdG8gZW5zdXJlIHRoYXQgbm8gc3B1cmlvdXMgZXJyb3IgaXNcbiAqIGVtaXR0ZWQuXG4gKi9cblxuaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICBSZXF1ZXN0LnJlcXVlc3RzQ291bnQgPSAwO1xuICBSZXF1ZXN0LnJlcXVlc3RzID0ge307XG4gIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICBnbG9iYWwuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgdW5sb2FkSGFuZGxlcik7XG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVubG9hZEhhbmRsZXIoKSB7XG4gIGZvciAodmFyIGkgaW4gUmVxdWVzdC5yZXF1ZXN0cykge1xuICAgIGlmIChSZXF1ZXN0LnJlcXVlc3RzLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICBSZXF1ZXN0LnJlcXVlc3RzW2ldLmFib3J0KCk7XG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxudmFyIFRyYW5zcG9ydCA9IHJlcXVpcmUoJy4uL3RyYW5zcG9ydCcpO1xudmFyIHBhcnNlcXMgPSByZXF1aXJlKCdwYXJzZXFzJyk7XG52YXIgcGFyc2VyID0gcmVxdWlyZSgnZW5naW5lLmlvLXBhcnNlcicpO1xudmFyIGluaGVyaXQgPSByZXF1aXJlKCdjb21wb25lbnQtaW5oZXJpdCcpO1xudmFyIGRlYnVnID0gcmVxdWlyZSgnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpwb2xsaW5nJyk7XG5cbi8qKlxuICogTW9kdWxlIGV4cG9ydHMuXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBQb2xsaW5nO1xuXG4vKipcbiAqIElzIFhIUjIgc3VwcG9ydGVkP1xuICovXG5cbnZhciBoYXNYSFIyID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgWE1MSHR0cFJlcXVlc3QgPSByZXF1aXJlKCd4bWxodHRwcmVxdWVzdCcpO1xuICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KHsgeGRvbWFpbjogZmFsc2UgfSk7XG4gIHJldHVybiBudWxsICE9IHhoci5yZXNwb25zZVR5cGU7XG59KSgpO1xuXG4vKipcbiAqIFBvbGxpbmcgaW50ZXJmYWNlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBQb2xsaW5nKG9wdHMpe1xuICB2YXIgZm9yY2VCYXNlNjQgPSAob3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0KTtcbiAgaWYgKCFoYXNYSFIyIHx8IGZvcmNlQmFzZTY0KSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG4gIFRyYW5zcG9ydC5jYWxsKHRoaXMsIG9wdHMpO1xufVxuXG4vKipcbiAqIEluaGVyaXRzIGZyb20gVHJhbnNwb3J0LlxuICovXG5cbmluaGVyaXQoUG9sbGluZywgVHJhbnNwb3J0KTtcblxuLyoqXG4gKiBUcmFuc3BvcnQgbmFtZS5cbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5uYW1lID0gJ3BvbGxpbmcnO1xuXG4vKipcbiAqIE9wZW5zIHRoZSBzb2NrZXQgKHRyaWdnZXJzIHBvbGxpbmcpLiBXZSB3cml0ZSBhIFBJTkcgbWVzc2FnZSB0byBkZXRlcm1pbmVcbiAqIHdoZW4gdGhlIHRyYW5zcG9ydCBpcyBvcGVuLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uKCl7XG4gIHRoaXMucG9sbCgpO1xufTtcblxuLyoqXG4gKiBQYXVzZXMgcG9sbGluZy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayB1cG9uIGJ1ZmZlcnMgYXJlIGZsdXNoZWQgYW5kIHRyYW5zcG9ydCBpcyBwYXVzZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24ob25QYXVzZSl7XG4gIHZhciBwZW5kaW5nID0gMDtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucmVhZHlTdGF0ZSA9ICdwYXVzaW5nJztcblxuICBmdW5jdGlvbiBwYXVzZSgpe1xuICAgIGRlYnVnKCdwYXVzZWQnKTtcbiAgICBzZWxmLnJlYWR5U3RhdGUgPSAncGF1c2VkJztcbiAgICBvblBhdXNlKCk7XG4gIH1cblxuICBpZiAodGhpcy5wb2xsaW5nIHx8ICF0aGlzLndyaXRhYmxlKSB7XG4gICAgdmFyIHRvdGFsID0gMDtcblxuICAgIGlmICh0aGlzLnBvbGxpbmcpIHtcbiAgICAgIGRlYnVnKCd3ZSBhcmUgY3VycmVudGx5IHBvbGxpbmcgLSB3YWl0aW5nIHRvIHBhdXNlJyk7XG4gICAgICB0b3RhbCsrO1xuICAgICAgdGhpcy5vbmNlKCdwb2xsQ29tcGxldGUnLCBmdW5jdGlvbigpe1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHBvbGxpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICBkZWJ1Zygnd2UgYXJlIGN1cnJlbnRseSB3cml0aW5nIC0gd2FpdGluZyB0byBwYXVzZScpO1xuICAgICAgdG90YWwrKztcbiAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbigpe1xuICAgICAgICBkZWJ1ZygncHJlLXBhdXNlIHdyaXRpbmcgY29tcGxldGUnKTtcbiAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHBhdXNlKCk7XG4gIH1cbn07XG5cbi8qKlxuICogU3RhcnRzIHBvbGxpbmcgY3ljbGUuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS5wb2xsID0gZnVuY3Rpb24oKXtcbiAgZGVidWcoJ3BvbGxpbmcnKTtcbiAgdGhpcy5wb2xsaW5nID0gdHJ1ZTtcbiAgdGhpcy5kb1BvbGwoKTtcbiAgdGhpcy5lbWl0KCdwb2xsJyk7XG59O1xuXG4vKipcbiAqIE92ZXJsb2FkcyBvbkRhdGEgdG8gZGV0ZWN0IHBheWxvYWRzLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cblBvbGxpbmcucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uKGRhdGEpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKHBhY2tldCwgaW5kZXgsIHRvdGFsKSB7XG4gICAgLy8gaWYgaXRzIHRoZSBmaXJzdCBtZXNzYWdlIHdlIGNvbnNpZGVyIHRoZSB0cmFuc3BvcnQgb3BlblxuICAgIGlmICgnb3BlbmluZycgPT0gc2VsZi5yZWFkeVN0YXRlKSB7XG4gICAgICBzZWxmLm9uT3BlbigpO1xuICAgIH1cblxuICAgIC8vIGlmIGl0cyBhIGNsb3NlIHBhY2tldCwgd2UgY2xvc2UgdGhlIG9uZ29pbmcgcmVxdWVzdHNcbiAgICBpZiAoJ2Nsb3NlJyA9PSBwYWNrZXQudHlwZSkge1xuICAgICAgc2VsZi5vbkNsb3NlKCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlIGJ5cGFzcyBvbkRhdGEgYW5kIGhhbmRsZSB0aGUgbWVzc2FnZVxuICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgfTtcblxuICAvLyBkZWNvZGUgcGF5bG9hZFxuICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgLy8gaWYgYW4gZXZlbnQgZGlkIG5vdCB0cmlnZ2VyIGNsb3NpbmdcbiAgaWYgKCdjbG9zZWQnICE9IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIC8vIGlmIHdlIGdvdCBkYXRhIHdlJ3JlIG5vdCBwb2xsaW5nXG4gICAgdGhpcy5wb2xsaW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWl0KCdwb2xsQ29tcGxldGUnKTtcblxuICAgIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgICB0aGlzLnBvbGwoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWcoJ2lnbm9yaW5nIHBvbGwgLSB0cmFuc3BvcnQgc3RhdGUgXCIlc1wiJywgdGhpcy5yZWFkeVN0YXRlKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogRm9yIHBvbGxpbmcsIHNlbmQgYSBjbG9zZSBwYWNrZXQuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uKCl7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBjbG9zZSgpe1xuICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgIHNlbGYud3JpdGUoW3sgdHlwZTogJ2Nsb3NlJyB9XSk7XG4gIH1cblxuICBpZiAoJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgIGRlYnVnKCd0cmFuc3BvcnQgb3BlbiAtIGNsb3NpbmcnKTtcbiAgICBjbG9zZSgpO1xuICB9IGVsc2Uge1xuICAgIC8vIGluIGNhc2Ugd2UncmUgdHJ5aW5nIHRvIGNsb3NlIHdoaWxlXG4gICAgLy8gaGFuZHNoYWtpbmcgaXMgaW4gcHJvZ3Jlc3MgKEdILTE2NClcbiAgICBkZWJ1ZygndHJhbnNwb3J0IG5vdCBvcGVuIC0gZGVmZXJyaW5nIGNsb3NlJyk7XG4gICAgdGhpcy5vbmNlKCdvcGVuJywgY2xvc2UpO1xuICB9XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHBhY2tldHMgcGF5bG9hZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBkYXRhIHBhY2tldHNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRyYWluIGNhbGxiYWNrXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHBhY2tldHMpe1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMud3JpdGFibGUgPSBmYWxzZTtcbiAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbigpIHtcbiAgICBzZWxmLndyaXRhYmxlID0gdHJ1ZTtcbiAgICBzZWxmLmVtaXQoJ2RyYWluJyk7XG4gIH07XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBwYXJzZXIuZW5jb2RlUGF5bG9hZChwYWNrZXRzLCB0aGlzLnN1cHBvcnRzQmluYXJ5LCBmdW5jdGlvbihkYXRhKSB7XG4gICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICB9KTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5Qb2xsaW5nLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbigpe1xuICB2YXIgcXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuICB2YXIgc2NoZW1hID0gdGhpcy5zZWN1cmUgPyAnaHR0cHMnIDogJ2h0dHAnO1xuICB2YXIgcG9ydCA9ICcnO1xuXG4gIC8vIGNhY2hlIGJ1c3RpbmcgaXMgZm9yY2VkXG4gIGlmIChmYWxzZSAhPT0gdGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0gK25ldyBEYXRlICsgJy0nICsgVHJhbnNwb3J0LnRpbWVzdGFtcHMrKztcbiAgfVxuXG4gIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSAmJiAhcXVlcnkuc2lkKSB7XG4gICAgcXVlcnkuYjY0ID0gMTtcbiAgfVxuXG4gIHF1ZXJ5ID0gcGFyc2Vxcy5lbmNvZGUocXVlcnkpO1xuXG4gIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gIGlmICh0aGlzLnBvcnQgJiYgKCgnaHR0cHMnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gNDQzKSB8fFxuICAgICAoJ2h0dHAnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBwcmVwZW5kID8gdG8gcXVlcnlcbiAgaWYgKHF1ZXJ5Lmxlbmd0aCkge1xuICAgIHF1ZXJ5ID0gJz8nICsgcXVlcnk7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hICsgJzovLycgKyB0aGlzLmhvc3RuYW1lICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcbiIsIi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgVHJhbnNwb3J0ID0gcmVxdWlyZSgnLi4vdHJhbnNwb3J0Jyk7XG52YXIgcGFyc2VyID0gcmVxdWlyZSgnZW5naW5lLmlvLXBhcnNlcicpO1xudmFyIHBhcnNlcXMgPSByZXF1aXJlKCdwYXJzZXFzJyk7XG52YXIgaW5oZXJpdCA9IHJlcXVpcmUoJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG52YXIgZGVidWcgPSByZXF1aXJlKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OndlYnNvY2tldCcpO1xuXG4vKipcbiAqIGB3c2AgZXhwb3NlcyBhIFdlYlNvY2tldC1jb21wYXRpYmxlIGludGVyZmFjZSBpblxuICogTm9kZSwgb3IgdGhlIGBXZWJTb2NrZXRgIG9yIGBNb3pXZWJTb2NrZXRgIGdsb2JhbHNcbiAqIGluIHRoZSBicm93c2VyLlxuICovXG5cbnZhciBXZWJTb2NrZXQgPSByZXF1aXJlKCd3cycpO1xuXG4vKipcbiAqIE1vZHVsZSBleHBvcnRzLlxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gV1M7XG5cbi8qKlxuICogV2ViU29ja2V0IHRyYW5zcG9ydCBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHtPYmplY3R9IGNvbm5lY3Rpb24gb3B0aW9uc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBXUyhvcHRzKXtcbiAgdmFyIGZvcmNlQmFzZTY0ID0gKG9wdHMgJiYgb3B0cy5mb3JjZUJhc2U2NCk7XG4gIGlmIChmb3JjZUJhc2U2NCkge1xuICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcbiAgfVxuICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbn1cblxuLyoqXG4gKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAqL1xuXG5pbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4vKipcbiAqIFRyYW5zcG9ydCBuYW1lLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuLypcbiAqIFdlYlNvY2tldHMgc3VwcG9ydCBiaW5hcnlcbiAqL1xuXG5XUy5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4vKipcbiAqIE9wZW5zIHNvY2tldC5cbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUuZG9PcGVuID0gZnVuY3Rpb24oKXtcbiAgaWYgKCF0aGlzLmNoZWNrKCkpIHtcbiAgICAvLyBsZXQgcHJvYmUgdGltZW91dFxuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gIHZhciBwcm90b2NvbHMgPSB2b2lkKDApO1xuICB2YXIgb3B0cyA9IHsgYWdlbnQ6IHRoaXMuYWdlbnQgfTtcblxuICB0aGlzLndzID0gbmV3IFdlYlNvY2tldCh1cmksIHByb3RvY29scywgb3B0cyk7XG5cbiAgaWYgKHRoaXMud3MuYmluYXJ5VHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG5cbiAgdGhpcy53cy5iaW5hcnlUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xufTtcblxuLyoqXG4gKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuV1MucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXJzID0gZnVuY3Rpb24oKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMud3Mub25vcGVuID0gZnVuY3Rpb24oKXtcbiAgICBzZWxmLm9uT3BlbigpO1xuICB9O1xuICB0aGlzLndzLm9uY2xvc2UgPSBmdW5jdGlvbigpe1xuICAgIHNlbGYub25DbG9zZSgpO1xuICB9O1xuICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKGV2KXtcbiAgICBzZWxmLm9uRGF0YShldi5kYXRhKTtcbiAgfTtcbiAgdGhpcy53cy5vbmVycm9yID0gZnVuY3Rpb24oZSl7XG4gICAgc2VsZi5vbkVycm9yKCd3ZWJzb2NrZXQgZXJyb3InLCBlKTtcbiAgfTtcbn07XG5cbi8qKlxuICogT3ZlcnJpZGUgYG9uRGF0YWAgdG8gdXNlIGEgdGltZXIgb24gaU9TLlxuICogU2VlOiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9tbG91Z2hyYW4vMjA1MjAwNlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgbmF2aWdhdG9yXG4gICYmIC9pUGFkfGlQaG9uZXxpUG9kL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSkge1xuICBXUy5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24oZGF0YSl7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIFRyYW5zcG9ydC5wcm90b3R5cGUub25EYXRhLmNhbGwoc2VsZiwgZGF0YSk7XG4gICAgfSwgMCk7XG4gIH07XG59XG5cbi8qKlxuICogV3JpdGVzIGRhdGEgdG8gc29ja2V0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IG9mIHBhY2tldHMuXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihwYWNrZXRzKXtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG4gIC8vIGVuY29kZVBhY2tldCBlZmZpY2llbnQgYXMgaXQgdXNlcyBXUyBmcmFtaW5nXG4gIC8vIG5vIG5lZWQgZm9yIGVuY29kZVBheWxvYWRcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYWNrZXRzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIHBhcnNlci5lbmNvZGVQYWNrZXQocGFja2V0c1tpXSwgdGhpcy5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24oZGF0YSkge1xuICAgICAgLy9Tb21ldGltZXMgdGhlIHdlYnNvY2tldCBoYXMgYWxyZWFkeSBiZWVuIGNsb3NlZCBidXQgdGhlIGJyb3dzZXIgZGlkbid0XG4gICAgICAvL2hhdmUgYSBjaGFuY2Ugb2YgaW5mb3JtaW5nIHVzIGFib3V0IGl0IHlldCwgaW4gdGhhdCBjYXNlIHNlbmQgd2lsbFxuICAgICAgLy90aHJvdyBhbiBlcnJvclxuICAgICAgdHJ5IHtcbiAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSl7XG4gICAgICAgIGRlYnVnKCd3ZWJzb2NrZXQgY2xvc2VkIGJlZm9yZSBvbmNsb3NlIGV2ZW50Jyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBvbmRyYWluKCkge1xuICAgIHNlbGYud3JpdGFibGUgPSB0cnVlO1xuICAgIHNlbGYuZW1pdCgnZHJhaW4nKTtcbiAgfVxuICAvLyBmYWtlIGRyYWluXG4gIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgc2V0VGltZW91dChvbmRyYWluLCAwKTtcbn07XG5cbi8qKlxuICogQ2FsbGVkIHVwb24gY2xvc2VcbiAqXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5XUy5wcm90b3R5cGUub25DbG9zZSA9IGZ1bmN0aW9uKCl7XG4gIFRyYW5zcG9ydC5wcm90b3R5cGUub25DbG9zZS5jYWxsKHRoaXMpO1xufTtcblxuLyoqXG4gKiBDbG9zZXMgc29ja2V0LlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24oKXtcbiAgaWYgKHR5cGVvZiB0aGlzLndzICE9PSAndW5kZWZpbmVkJykge1xuICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgfVxufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgdXJpIGZvciBjb25uZWN0aW9uLlxuICpcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbldTLnByb3RvdHlwZS51cmkgPSBmdW5jdGlvbigpe1xuICB2YXIgcXVlcnkgPSB0aGlzLnF1ZXJ5IHx8IHt9O1xuICB2YXIgc2NoZW1hID0gdGhpcy5zZWN1cmUgPyAnd3NzJyA6ICd3cyc7XG4gIHZhciBwb3J0ID0gJyc7XG5cbiAgLy8gYXZvaWQgcG9ydCBpZiBkZWZhdWx0IGZvciBzY2hlbWFcbiAgaWYgKHRoaXMucG9ydCAmJiAoKCd3c3MnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gNDQzKVxuICAgIHx8ICgnd3MnID09IHNjaGVtYSAmJiB0aGlzLnBvcnQgIT0gODApKSkge1xuICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gIH1cblxuICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICBpZiAodGhpcy50aW1lc3RhbXBSZXF1ZXN0cykge1xuICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0gK25ldyBEYXRlO1xuICB9XG5cbiAgLy8gY29tbXVuaWNhdGUgYmluYXJ5IHN1cHBvcnQgY2FwYWJpbGl0aWVzXG4gIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgIHF1ZXJ5LmI2NCA9IDE7XG4gIH1cblxuICBxdWVyeSA9IHBhcnNlcXMuZW5jb2RlKHF1ZXJ5KTtcblxuICAvLyBwcmVwZW5kID8gdG8gcXVlcnlcbiAgaWYgKHF1ZXJ5Lmxlbmd0aCkge1xuICAgIHF1ZXJ5ID0gJz8nICsgcXVlcnk7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hICsgJzovLycgKyB0aGlzLmhvc3RuYW1lICsgcG9ydCArIHRoaXMucGF0aCArIHF1ZXJ5O1xufTtcblxuLyoqXG4gKiBGZWF0dXJlIGRldGVjdGlvbiBmb3IgV2ViU29ja2V0LlxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59IHdoZXRoZXIgdGhpcyB0cmFuc3BvcnQgaXMgYXZhaWxhYmxlLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5XUy5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbigpe1xuICByZXR1cm4gISFXZWJTb2NrZXQgJiYgISgnX19pbml0aWFsaXplJyBpbiBXZWJTb2NrZXQgJiYgdGhpcy5uYW1lID09PSBXUy5wcm90b3R5cGUubmFtZSk7XG59O1xuIiwiLy8gYnJvd3NlciBzaGltIGZvciB4bWxodHRwcmVxdWVzdCBtb2R1bGVcbnZhciBoYXNDT1JTID0gcmVxdWlyZSgnaGFzLWNvcnMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihvcHRzKSB7XG4gIHZhciB4ZG9tYWluID0gb3B0cy54ZG9tYWluO1xuXG4gIC8vIHNjaGVtZSBtdXN0IGJlIHNhbWUgd2hlbiB1c2lnbiBYRG9tYWluUmVxdWVzdFxuICAvLyBodHRwOi8vYmxvZ3MubXNkbi5jb20vYi9pZWludGVybmFscy9hcmNoaXZlLzIwMTAvMDUvMTMveGRvbWFpbnJlcXVlc3QtcmVzdHJpY3Rpb25zLWxpbWl0YXRpb25zLWFuZC13b3JrYXJvdW5kcy5hc3B4XG4gIHZhciB4c2NoZW1lID0gb3B0cy54c2NoZW1lO1xuXG4gIC8vIFhEb21haW5SZXF1ZXN0IGhhcyBhIGZsb3cgb2Ygbm90IHNlbmRpbmcgY29va2llLCB0aGVyZWZvcmUgaXQgc2hvdWxkIGJlIGRpc2FibGVkIGFzIGEgZGVmYXVsdC5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvZW5naW5lLmlvLWNsaWVudC9wdWxsLzIxN1xuICB2YXIgZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcblxuICAvLyBYTUxIdHRwUmVxdWVzdCBjYW4gYmUgZGlzYWJsZWQgb24gSUVcbiAgdHJ5IHtcbiAgICBpZiAoJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICYmICgheGRvbWFpbiB8fCBoYXNDT1JTKSkge1xuICAgICAgcmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gIC8vIGJlY2F1c2UgbG9hZGluZyBiYXIga2VlcHMgZmxhc2hpbmcgd2hlbiB1c2luZyBqc29ucC1wb2xsaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS95dWppb3Nha2Evc29ja2UuaW8taWU4LWxvYWRpbmctZXhhbXBsZVxuICB0cnkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgWERvbWFpblJlcXVlc3QgJiYgIXhzY2hlbWUgJiYgZW5hYmxlc1hEUikge1xuICAgICAgcmV0dXJuIG5ldyBYRG9tYWluUmVxdWVzdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkgeyB9XG5cbiAgaWYgKCF4ZG9tYWluKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTEhUVFAnKTtcbiAgICB9IGNhdGNoKGUpIHsgfVxuICB9XG59XG4iLCJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYSwgYil7XG4gIHZhciBmbiA9IGZ1bmN0aW9uKCl7fTtcbiAgZm4ucHJvdG90eXBlID0gYi5wcm90b3R5cGU7XG4gIGEucHJvdG90eXBlID0gbmV3IGZuO1xuICBhLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGE7XG59OyIsIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gKlxuICogRXhwb3NlIGBkZWJ1ZygpYCBhcyB0aGUgbW9kdWxlLlxuICovXG5cbmV4cG9ydHMgPSBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vZGVidWcnKTtcbmV4cG9ydHMubG9nID0gbG9nO1xuZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbmV4cG9ydHMuc2F2ZSA9IHNhdmU7XG5leHBvcnRzLmxvYWQgPSBsb2FkO1xuZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG5cbi8qKlxuICogQ29sb3JzLlxuICovXG5cbmV4cG9ydHMuY29sb3JzID0gW1xuICAnbGlnaHRzZWFncmVlbicsXG4gICdmb3Jlc3RncmVlbicsXG4gICdnb2xkZW5yb2QnLFxuICAnZG9kZ2VyYmx1ZScsXG4gICdkYXJrb3JjaGlkJyxcbiAgJ2NyaW1zb24nXG5dO1xuXG4vKipcbiAqIEN1cnJlbnRseSBvbmx5IFdlYktpdC1iYXNlZCBXZWIgSW5zcGVjdG9ycywgRmlyZWZveCA+PSB2MzEsXG4gKiBhbmQgdGhlIEZpcmVidWcgZXh0ZW5zaW9uIChhbnkgRmlyZWZveCB2ZXJzaW9uKSBhcmUga25vd25cbiAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAqXG4gKiBUT0RPOiBhZGQgYSBgbG9jYWxTdG9yYWdlYCB2YXJpYWJsZSB0byBleHBsaWNpdGx5IGVuYWJsZS9kaXNhYmxlIGNvbG9yc1xuICovXG5cbmZ1bmN0aW9uIHVzZUNvbG9ycygpIHtcbiAgLy8gaXMgd2Via2l0PyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNjQ1OTYwNi8zNzY3NzNcbiAgcmV0dXJuICgnV2Via2l0QXBwZWFyYW5jZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlKSB8fFxuICAgIC8vIGlzIGZpcmVidWc/IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM5ODEyMC8zNzY3NzNcbiAgICAod2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCAoY29uc29sZS5leGNlcHRpb24gJiYgY29uc29sZS50YWJsZSkpKSB8fFxuICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCkubWF0Y2goL2ZpcmVmb3hcXC8oXFxkKykvKSAmJiBwYXJzZUludChSZWdFeHAuJDEsIDEwKSA+PSAzMSk7XG59XG5cbi8qKlxuICogTWFwICVqIHRvIGBKU09OLnN0cmluZ2lmeSgpYCwgc2luY2Ugbm8gV2ViIEluc3BlY3RvcnMgZG8gdGhhdCBieSBkZWZhdWx0LlxuICovXG5cbmV4cG9ydHMuZm9ybWF0dGVycy5qID0gZnVuY3Rpb24odikge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodik7XG59O1xuXG5cbi8qKlxuICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZm9ybWF0QXJncygpIHtcbiAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICBhcmdzWzBdID0gKHVzZUNvbG9ycyA/ICclYycgOiAnJylcbiAgICArIHRoaXMubmFtZXNwYWNlXG4gICAgKyAodXNlQ29sb3JzID8gJyAlYycgOiAnICcpXG4gICAgKyBhcmdzWzBdXG4gICAgKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpXG4gICAgKyAnKycgKyBleHBvcnRzLmh1bWFuaXplKHRoaXMuZGlmZik7XG5cbiAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gIHZhciBjID0gJ2NvbG9yOiAnICsgdGhpcy5jb2xvcjtcbiAgYXJncyA9IFthcmdzWzBdLCBjLCAnY29sb3I6IGluaGVyaXQnXS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJncywgMSkpO1xuXG4gIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gIC8vIGFyZ3VtZW50cyBwYXNzZWQgZWl0aGVyIGJlZm9yZSBvciBhZnRlciB0aGUgJWMsIHNvIHdlIG5lZWQgdG9cbiAgLy8gZmlndXJlIG91dCB0aGUgY29ycmVjdCBpbmRleCB0byBpbnNlcnQgdGhlIENTUyBpbnRvXG4gIHZhciBpbmRleCA9IDA7XG4gIHZhciBsYXN0QyA9IDA7XG4gIGFyZ3NbMF0ucmVwbGFjZSgvJVthLXolXS9nLCBmdW5jdGlvbihtYXRjaCkge1xuICAgIGlmICgnJSUnID09PSBtYXRjaCkgcmV0dXJuO1xuICAgIGluZGV4Kys7XG4gICAgaWYgKCclYycgPT09IG1hdGNoKSB7XG4gICAgICAvLyB3ZSBvbmx5IGFyZSBpbnRlcmVzdGVkIGluIHRoZSAqbGFzdCogJWNcbiAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICBsYXN0QyA9IGluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJncy5zcGxpY2UobGFzdEMsIDAsIGMpO1xuICByZXR1cm4gYXJncztcbn1cblxuLyoqXG4gKiBJbnZva2VzIGBjb25zb2xlLmxvZygpYCB3aGVuIGF2YWlsYWJsZS5cbiAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBsb2coKSB7XG4gIC8vIFRoaXMgaGFja2VyeSBpcyByZXF1aXJlZCBmb3IgSUU4LFxuICAvLyB3aGVyZSB0aGUgYGNvbnNvbGUubG9nYCBmdW5jdGlvbiBkb2Vzbid0IGhhdmUgJ2FwcGx5J1xuICByZXR1cm4gJ29iamVjdCcgPT0gdHlwZW9mIGNvbnNvbGVcbiAgICAmJiAnZnVuY3Rpb24nID09IHR5cGVvZiBjb25zb2xlLmxvZ1xuICAgICYmIEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGNvbnNvbGUubG9nLCBjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG4vKipcbiAqIFNhdmUgYG5hbWVzcGFjZXNgLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgdHJ5IHtcbiAgICBpZiAobnVsbCA9PSBuYW1lc3BhY2VzKSB7XG4gICAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9jYWxTdG9yYWdlLmRlYnVnID0gbmFtZXNwYWNlcztcbiAgICB9XG4gIH0gY2F0Y2goZSkge31cbn1cblxuLyoqXG4gKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IHJldHVybnMgdGhlIHByZXZpb3VzbHkgcGVyc2lzdGVkIGRlYnVnIG1vZGVzXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb2FkKCkge1xuICB2YXIgcjtcbiAgdHJ5IHtcbiAgICByID0gbG9jYWxTdG9yYWdlLmRlYnVnO1xuICB9IGNhdGNoKGUpIHt9XG4gIHJldHVybiByO1xufVxuXG4vKipcbiAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gKi9cblxuZXhwb3J0cy5lbmFibGUobG9hZCgpKTtcbiIsIlxuLyoqXG4gKiBUaGlzIGlzIHRoZSBjb21tb24gbG9naWMgZm9yIGJvdGggdGhlIE5vZGUuanMgYW5kIHdlYiBicm93c2VyXG4gKiBpbXBsZW1lbnRhdGlvbnMgb2YgYGRlYnVnKClgLlxuICpcbiAqIEV4cG9zZSBgZGVidWcoKWAgYXMgdGhlIG1vZHVsZS5cbiAqL1xuXG5leHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBkZWJ1ZztcbmV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuZXhwb3J0cy5kaXNhYmxlID0gZGlzYWJsZTtcbmV4cG9ydHMuZW5hYmxlID0gZW5hYmxlO1xuZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbmV4cG9ydHMuaHVtYW5pemUgPSByZXF1aXJlKCdtcycpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICovXG5cbmV4cG9ydHMubmFtZXMgPSBbXTtcbmV4cG9ydHMuc2tpcHMgPSBbXTtcblxuLyoqXG4gKiBNYXAgb2Ygc3BlY2lhbCBcIiVuXCIgaGFuZGxpbmcgZnVuY3Rpb25zLCBmb3IgdGhlIGRlYnVnIFwiZm9ybWF0XCIgYXJndW1lbnQuXG4gKlxuICogVmFsaWQga2V5IG5hbWVzIGFyZSBhIHNpbmdsZSwgbG93ZXJjYXNlZCBsZXR0ZXIsIGkuZS4gXCJuXCIuXG4gKi9cblxuZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbi8qKlxuICogUHJldmlvdXNseSBhc3NpZ25lZCBjb2xvci5cbiAqL1xuXG52YXIgcHJldkNvbG9yID0gMDtcblxuLyoqXG4gKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICovXG5cbnZhciBwcmV2VGltZTtcblxuLyoqXG4gKiBTZWxlY3QgYSBjb2xvci5cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgcmV0dXJuIGV4cG9ydHMuY29sb3JzW3ByZXZDb2xvcisrICUgZXhwb3J0cy5jb2xvcnMubGVuZ3RoXTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBkZWJ1Z2dlciB3aXRoIHRoZSBnaXZlbiBgbmFtZXNwYWNlYC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gZGVidWcobmFtZXNwYWNlKSB7XG5cbiAgLy8gZGVmaW5lIHRoZSBgZGlzYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7XG4gIH1cbiAgZGlzYWJsZWQuZW5hYmxlZCA9IGZhbHNlO1xuXG4gIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgZnVuY3Rpb24gZW5hYmxlZCgpIHtcblxuICAgIHZhciBzZWxmID0gZW5hYmxlZDtcblxuICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgdmFyIGN1cnIgPSArbmV3IERhdGUoKTtcbiAgICB2YXIgbXMgPSBjdXJyIC0gKHByZXZUaW1lIHx8IGN1cnIpO1xuICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgIHNlbGYucHJldiA9IHByZXZUaW1lO1xuICAgIHNlbGYuY3VyciA9IGN1cnI7XG4gICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgLy8gYWRkIHRoZSBgY29sb3JgIGlmIG5vdCBzZXRcbiAgICBpZiAobnVsbCA9PSBzZWxmLnVzZUNvbG9ycykgc2VsZi51c2VDb2xvcnMgPSBleHBvcnRzLnVzZUNvbG9ycygpO1xuICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXG4gICAgYXJnc1swXSA9IGV4cG9ydHMuY29lcmNlKGFyZ3NbMF0pO1xuXG4gICAgaWYgKCdzdHJpbmcnICE9PSB0eXBlb2YgYXJnc1swXSkge1xuICAgICAgLy8gYW55dGhpbmcgZWxzZSBsZXQncyBpbnNwZWN0IHdpdGggJW9cbiAgICAgIGFyZ3MgPSBbJyVvJ10uY29uY2F0KGFyZ3MpO1xuICAgIH1cblxuICAgIC8vIGFwcGx5IGFueSBgZm9ybWF0dGVyc2AgdHJhbnNmb3JtYXRpb25zXG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICBhcmdzWzBdID0gYXJnc1swXS5yZXBsYWNlKC8lKFthLXolXSkvZywgZnVuY3Rpb24obWF0Y2gsIGZvcm1hdCkge1xuICAgICAgLy8gaWYgd2UgZW5jb3VudGVyIGFuIGVzY2FwZWQgJSB0aGVuIGRvbid0IGluY3JlYXNlIHRoZSBhcnJheSBpbmRleFxuICAgICAgaWYgKG1hdGNoID09PSAnJSUnKSByZXR1cm4gbWF0Y2g7XG4gICAgICBpbmRleCsrO1xuICAgICAgdmFyIGZvcm1hdHRlciA9IGV4cG9ydHMuZm9ybWF0dGVyc1tmb3JtYXRdO1xuICAgICAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBmb3JtYXR0ZXIpIHtcbiAgICAgICAgdmFyIHZhbCA9IGFyZ3NbaW5kZXhdO1xuICAgICAgICBtYXRjaCA9IGZvcm1hdHRlci5jYWxsKHNlbGYsIHZhbCk7XG5cbiAgICAgICAgLy8gbm93IHdlIG5lZWQgdG8gcmVtb3ZlIGBhcmdzW2luZGV4XWAgc2luY2UgaXQncyBpbmxpbmVkIGluIHRoZSBgZm9ybWF0YFxuICAgICAgICBhcmdzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIGluZGV4LS07XG4gICAgICB9XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfSk7XG5cbiAgICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIGV4cG9ydHMuZm9ybWF0QXJncykge1xuICAgICAgYXJncyA9IGV4cG9ydHMuZm9ybWF0QXJncy5hcHBseShzZWxmLCBhcmdzKTtcbiAgICB9XG4gICAgdmFyIGxvZ0ZuID0gZW5hYmxlZC5sb2cgfHwgZXhwb3J0cy5sb2cgfHwgY29uc29sZS5sb2cuYmluZChjb25zb2xlKTtcbiAgICBsb2dGbi5hcHBseShzZWxmLCBhcmdzKTtcbiAgfVxuICBlbmFibGVkLmVuYWJsZWQgPSB0cnVlO1xuXG4gIHZhciBmbiA9IGV4cG9ydHMuZW5hYmxlZChuYW1lc3BhY2UpID8gZW5hYmxlZCA6IGRpc2FibGVkO1xuXG4gIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICByZXR1cm4gZm47XG59XG5cbi8qKlxuICogRW5hYmxlcyBhIGRlYnVnIG1vZGUgYnkgbmFtZXNwYWNlcy4gVGhpcyBjYW4gaW5jbHVkZSBtb2Rlc1xuICogc2VwYXJhdGVkIGJ5IGEgY29sb24gYW5kIHdpbGRjYXJkcy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBlbmFibGUobmFtZXNwYWNlcykge1xuICBleHBvcnRzLnNhdmUobmFtZXNwYWNlcyk7XG5cbiAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gIHZhciBsZW4gPSBzcGxpdC5sZW5ndGg7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgIG5hbWVzcGFjZXMgPSBzcGxpdFtpXS5yZXBsYWNlKC9cXCovZywgJy4qPycpO1xuICAgIGlmIChuYW1lc3BhY2VzWzBdID09PSAnLScpIHtcbiAgICAgIGV4cG9ydHMuc2tpcHMucHVzaChuZXcgUmVnRXhwKCdeJyArIG5hbWVzcGFjZXMuc3Vic3RyKDEpICsgJyQnKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cG9ydHMubmFtZXMucHVzaChuZXcgUmVnRXhwKCdeJyArIG5hbWVzcGFjZXMgKyAnJCcpKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBEaXNhYmxlIGRlYnVnIG91dHB1dC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGRpc2FibGUoKSB7XG4gIGV4cG9ydHMuZW5hYmxlKCcnKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIG1vZGUgbmFtZSBpcyBlbmFibGVkLCBmYWxzZSBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGVuYWJsZWQobmFtZSkge1xuICB2YXIgaSwgbGVuO1xuICBmb3IgKGkgPSAwLCBsZW4gPSBleHBvcnRzLnNraXBzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGV4cG9ydHMuc2tpcHNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICBmb3IgKGkgPSAwLCBsZW4gPSBleHBvcnRzLm5hbWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgaWYgKGV4cG9ydHMubmFtZXNbaV0udGVzdChuYW1lKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBDb2VyY2UgYHZhbGAuXG4gKlxuICogQHBhcmFtIHtNaXhlZH0gdmFsXG4gKiBAcmV0dXJuIHtNaXhlZH1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGNvZXJjZSh2YWwpIHtcbiAgaWYgKHZhbCBpbnN0YW5jZW9mIEVycm9yKSByZXR1cm4gdmFsLnN0YWNrIHx8IHZhbC5tZXNzYWdlO1xuICByZXR1cm4gdmFsO1xufVxuIiwiLyoqXG4gKiBIZWxwZXJzLlxuICovXG5cbnZhciBzID0gMTAwMDtcbnZhciBtID0gcyAqIDYwO1xudmFyIGggPSBtICogNjA7XG52YXIgZCA9IGggKiAyNDtcbnZhciB5ID0gZCAqIDM2NS4yNTtcblxuLyoqXG4gKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICpcbiAqIE9wdGlvbnM6XG4gKlxuICogIC0gYGxvbmdgIHZlcmJvc2UgZm9ybWF0dGluZyBbZmFsc2VdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtTdHJpbmd8TnVtYmVyfVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHZhbCwgb3B0aW9ucyl7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIHZhbCkgcmV0dXJuIHBhcnNlKHZhbCk7XG4gIHJldHVybiBvcHRpb25zLmxvbmdcbiAgICA/IGxvbmcodmFsKVxuICAgIDogc2hvcnQodmFsKTtcbn07XG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIGBzdHJgIGFuZCByZXR1cm4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHBhcnNlKHN0cikge1xuICB2YXIgbWF0Y2ggPSAvXigoPzpcXGQrKT9cXC4/XFxkKykgKihtc3xzZWNvbmRzP3xzfG1pbnV0ZXM/fG18aG91cnM/fGh8ZGF5cz98ZHx5ZWFycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuICB2YXIgbiA9IHBhcnNlRmxvYXQobWF0Y2hbMV0pO1xuICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICd5ZWFycyc6XG4gICAgY2FzZSAneWVhcic6XG4gICAgY2FzZSAneSc6XG4gICAgICByZXR1cm4gbiAqIHk7XG4gICAgY2FzZSAnZGF5cyc6XG4gICAgY2FzZSAnZGF5JzpcbiAgICBjYXNlICdkJzpcbiAgICAgIHJldHVybiBuICogZDtcbiAgICBjYXNlICdob3Vycyc6XG4gICAgY2FzZSAnaG91cic6XG4gICAgY2FzZSAnaCc6XG4gICAgICByZXR1cm4gbiAqIGg7XG4gICAgY2FzZSAnbWludXRlcyc6XG4gICAgY2FzZSAnbWludXRlJzpcbiAgICBjYXNlICdtJzpcbiAgICAgIHJldHVybiBuICogbTtcbiAgICBjYXNlICdzZWNvbmRzJzpcbiAgICBjYXNlICdzZWNvbmQnOlxuICAgIGNhc2UgJ3MnOlxuICAgICAgcmV0dXJuIG4gKiBzO1xuICAgIGNhc2UgJ21zJzpcbiAgICAgIHJldHVybiBuO1xuICB9XG59XG5cbi8qKlxuICogU2hvcnQgZm9ybWF0IGZvciBgbXNgLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICogQHJldHVybiB7U3RyaW5nfVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gc2hvcnQobXMpIHtcbiAgaWYgKG1zID49IGQpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gZCkgKyAnZCc7XG4gIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgJ2gnO1xuICBpZiAobXMgPj0gbSkgcmV0dXJuIE1hdGgucm91bmQobXMgLyBtKSArICdtJztcbiAgaWYgKG1zID49IHMpIHJldHVybiBNYXRoLnJvdW5kKG1zIC8gcykgKyAncyc7XG4gIHJldHVybiBtcyArICdtcyc7XG59XG5cbi8qKlxuICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG1zXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBsb25nKG1zKSB7XG4gIHJldHVybiBwbHVyYWwobXMsIGQsICdkYXknKVxuICAgIHx8IHBsdXJhbChtcywgaCwgJ2hvdXInKVxuICAgIHx8IHBsdXJhbChtcywgbSwgJ21pbnV0ZScpXG4gICAgfHwgcGx1cmFsKG1zLCBzLCAnc2Vjb25kJylcbiAgICB8fCBtcyArICcgbXMnO1xufVxuXG4vKipcbiAqIFBsdXJhbGl6YXRpb24gaGVscGVyLlxuICovXG5cbmZ1bmN0aW9uIHBsdXJhbChtcywgbiwgbmFtZSkge1xuICBpZiAobXMgPCBuKSByZXR1cm47XG4gIGlmIChtcyA8IG4gKiAxLjUpIHJldHVybiBNYXRoLmZsb29yKG1zIC8gbikgKyAnICcgKyBuYW1lO1xuICByZXR1cm4gTWF0aC5jZWlsKG1zIC8gbikgKyAnICcgKyBuYW1lICsgJ3MnO1xufVxuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG52YXIgc2xpY2VCdWZmZXIgPSByZXF1aXJlKCdhcnJheWJ1ZmZlci5zbGljZScpO1xudmFyIGJhc2U2NGVuY29kZXIgPSByZXF1aXJlKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbnZhciBhZnRlciA9IHJlcXVpcmUoJ2FmdGVyJyk7XG52YXIgdXRmOCA9IHJlcXVpcmUoJ3V0ZjgnKTtcblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBhbiBhbmRyb2lkIGJyb3dzZXIuIFRoYXQgcmVxdWlyZXMgdXMgdG8gdXNlXG4gKiBBcnJheUJ1ZmZlciB3aXRoIHBvbGxpbmcgdHJhbnNwb3J0cy4uLlxuICpcbiAqIGh0dHA6Ly9naGluZGEubmV0L2pwZWctYmxvYi1hamF4LWFuZHJvaWQvXG4gKi9cblxudmFyIGlzQW5kcm9pZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSk7XG5cbi8qKlxuICogQ3VycmVudCBwcm90b2NvbCB2ZXJzaW9uLlxuICovXG5cbmV4cG9ydHMucHJvdG9jb2wgPSAzO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlcy5cbiAqL1xuXG52YXIgcGFja2V0cyA9IGV4cG9ydHMucGFja2V0cyA9IHtcbiAgICBvcGVuOiAgICAgMCAgICAvLyBub24td3NcbiAgLCBjbG9zZTogICAgMSAgICAvLyBub24td3NcbiAgLCBwaW5nOiAgICAgMlxuICAsIHBvbmc6ICAgICAzXG4gICwgbWVzc2FnZTogIDRcbiAgLCB1cGdyYWRlOiAgNVxuICAsIG5vb3A6ICAgICA2XG59O1xuXG52YXIgcGFja2V0c2xpc3QgPSBrZXlzKHBhY2tldHMpO1xuXG4vKipcbiAqIFByZW1hZGUgZXJyb3IgcGFja2V0LlxuICovXG5cbnZhciBlcnIgPSB7IHR5cGU6ICdlcnJvcicsIGRhdGE6ICdwYXJzZXIgZXJyb3InIH07XG5cbi8qKlxuICogQ3JlYXRlIGEgYmxvYiBhcGkgZXZlbiBmb3IgYmxvYiBidWlsZGVyIHdoZW4gdmVuZG9yIHByZWZpeGVzIGV4aXN0XG4gKi9cblxudmFyIEJsb2IgPSByZXF1aXJlKCdibG9iJyk7XG5cbi8qKlxuICogRW5jb2RlcyBhIHBhY2tldC5cbiAqXG4gKiAgICAgPHBhY2tldCB0eXBlIGlkPiBbIDxkYXRhPiBdXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiAgICAgNWhlbGxvIHdvcmxkXG4gKiAgICAgM1xuICogICAgIDRcbiAqXG4gKiBCaW5hcnkgaXMgZW5jb2RlZCBpbiBhbiBpZGVudGljYWwgcHJpbmNpcGxlXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdXRmOGVuY29kZSwgY2FsbGJhY2spIHtcbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHN1cHBvcnRzQmluYXJ5KSB7XG4gICAgY2FsbGJhY2sgPSBzdXBwb3J0c0JpbmFyeTtcbiAgICBzdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHV0ZjhlbmNvZGUpIHtcbiAgICBjYWxsYmFjayA9IHV0ZjhlbmNvZGU7XG4gICAgdXRmOGVuY29kZSA9IG51bGw7XG4gIH1cblxuICB2YXIgZGF0YSA9IChwYWNrZXQuZGF0YSA9PT0gdW5kZWZpbmVkKVxuICAgID8gdW5kZWZpbmVkXG4gICAgOiBwYWNrZXQuZGF0YS5idWZmZXIgfHwgcGFja2V0LmRhdGE7XG5cbiAgaWYgKGdsb2JhbC5BcnJheUJ1ZmZlciAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICByZXR1cm4gZW5jb2RlQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9IGVsc2UgaWYgKEJsb2IgJiYgZGF0YSBpbnN0YW5jZW9mIGdsb2JhbC5CbG9iKSB7XG4gICAgcmV0dXJuIGVuY29kZUJsb2IocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy8gU2VuZGluZyBkYXRhIGFzIGEgdXRmLTggc3RyaW5nXG4gIHZhciBlbmNvZGVkID0gcGFja2V0c1twYWNrZXQudHlwZV07XG5cbiAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICBpZiAodW5kZWZpbmVkICE9PSBwYWNrZXQuZGF0YSkge1xuICAgIGVuY29kZWQgKz0gdXRmOGVuY29kZSA/IHV0ZjguZW5jb2RlKFN0cmluZyhwYWNrZXQuZGF0YSkpIDogU3RyaW5nKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHJldHVybiBjYWxsYmFjaygnJyArIGVuY29kZWQpO1xuXG59O1xuXG4vKipcbiAqIEVuY29kZSBwYWNrZXQgaGVscGVycyBmb3IgYmluYXJ5IHR5cGVzXG4gKi9cblxuZnVuY3Rpb24gZW5jb2RlQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gcGFja2V0LmRhdGE7XG4gIHZhciBjb250ZW50QXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgdmFyIHJlc3VsdEJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDEgKyBkYXRhLmJ5dGVMZW5ndGgpO1xuXG4gIHJlc3VsdEJ1ZmZlclswXSA9IHBhY2tldHNbcGFja2V0LnR5cGVdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRlbnRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgIHJlc3VsdEJ1ZmZlcltpKzFdID0gY29udGVudEFycmF5W2ldO1xuICB9XG5cbiAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEJ1ZmZlci5idWZmZXIpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iQXNBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICB9XG5cbiAgdmFyIGZyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgcGFja2V0LmRhdGEgPSBmci5yZXN1bHQ7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdHJ1ZSwgY2FsbGJhY2spO1xuICB9O1xuICByZXR1cm4gZnIucmVhZEFzQXJyYXlCdWZmZXIocGFja2V0LmRhdGEpO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVCbG9iKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gIH1cblxuICBpZiAoaXNBbmRyb2lkKSB7XG4gICAgcmV0dXJuIGVuY29kZUJsb2JBc0FycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKTtcbiAgfVxuXG4gIHZhciBsZW5ndGggPSBuZXcgVWludDhBcnJheSgxKTtcbiAgbGVuZ3RoWzBdID0gcGFja2V0c1twYWNrZXQudHlwZV07XG4gIHZhciBibG9iID0gbmV3IEJsb2IoW2xlbmd0aC5idWZmZXIsIHBhY2tldC5kYXRhXSk7XG5cbiAgcmV0dXJuIGNhbGxiYWNrKGJsb2IpO1xufVxuXG4vKipcbiAqIEVuY29kZXMgYSBwYWNrZXQgd2l0aCBiaW5hcnkgZGF0YSBpbiBhIGJhc2U2NCBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0LCBoYXMgYHR5cGVgIGFuZCBgZGF0YWBcbiAqIEByZXR1cm4ge1N0cmluZ30gYmFzZTY0IGVuY29kZWQgbWVzc2FnZVxuICovXG5cbmV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0LCBjYWxsYmFjaykge1xuICB2YXIgbWVzc2FnZSA9ICdiJyArIGV4cG9ydHMucGFja2V0c1twYWNrZXQudHlwZV07XG4gIGlmIChCbG9iICYmIHBhY2tldC5kYXRhIGluc3RhbmNlb2YgQmxvYikge1xuICAgIHZhciBmciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgZnIub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYjY0ID0gZnIucmVzdWx0LnNwbGl0KCcsJylbMV07XG4gICAgICBjYWxsYmFjayhtZXNzYWdlICsgYjY0KTtcbiAgICB9O1xuICAgIHJldHVybiBmci5yZWFkQXNEYXRhVVJMKHBhY2tldC5kYXRhKTtcbiAgfVxuXG4gIHZhciBiNjRkYXRhO1xuICB0cnkge1xuICAgIGI2NGRhdGEgPSBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB3aXRoIHR5cGVkIGFycmF5c1xuICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KHBhY2tldC5kYXRhKTtcbiAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHR5cGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICBiYXNpY1tpXSA9IHR5cGVkW2ldO1xuICAgIH1cbiAgICBiNjRkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBiYXNpYyk7XG4gIH1cbiAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgcmV0dXJuIGNhbGxiYWNrKG1lc3NhZ2UpO1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0LiBDaGFuZ2VzIGZvcm1hdCB0byBCbG9iIGlmIHJlcXVlc3RlZC5cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgLy8gU3RyaW5nIGRhdGFcbiAgaWYgKHR5cGVvZiBkYXRhID09ICdzdHJpbmcnIHx8IGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkYXRhLmNoYXJBdCgwKSA9PSAnYicpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmRlY29kZUJhc2U2NFBhY2tldChkYXRhLnN1YnN0cigxKSwgYmluYXJ5VHlwZSk7XG4gICAgfVxuXG4gICAgaWYgKHV0ZjhkZWNvZGUpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSB1dGY4LmRlY29kZShkYXRhKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGVycjtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHR5cGUgPSBkYXRhLmNoYXJBdCgwKTtcblxuICAgIGlmIChOdW1iZXIodHlwZSkgIT0gdHlwZSB8fCAhcGFja2V0c2xpc3RbdHlwZV0pIHtcbiAgICAgIHJldHVybiBlcnI7XG4gICAgfVxuXG4gICAgaWYgKGRhdGEubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0sIGRhdGE6IGRhdGEuc3Vic3RyaW5nKDEpIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIGFzQXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgdmFyIHR5cGUgPSBhc0FycmF5WzBdO1xuICB2YXIgcmVzdCA9IHNsaWNlQnVmZmVyKGRhdGEsIDEpO1xuICBpZiAoQmxvYiAmJiBiaW5hcnlUeXBlID09PSAnYmxvYicpIHtcbiAgICByZXN0ID0gbmV3IEJsb2IoW3Jlc3RdKTtcbiAgfVxuICByZXR1cm4geyB0eXBlOiBwYWNrZXRzbGlzdFt0eXBlXSwgZGF0YTogcmVzdCB9O1xufTtcblxuLyoqXG4gKiBEZWNvZGVzIGEgcGFja2V0IGVuY29kZWQgaW4gYSBiYXNlNjQgc3RyaW5nXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGJhc2U2NCBlbmNvZGVkIG1lc3NhZ2VcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCBgdHlwZWAgYW5kIGBkYXRhYCAoaWYgYW55KVxuICovXG5cbmV4cG9ydHMuZGVjb2RlQmFzZTY0UGFja2V0ID0gZnVuY3Rpb24obXNnLCBiaW5hcnlUeXBlKSB7XG4gIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gIGlmICghZ2xvYmFsLkFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogdHlwZSwgZGF0YTogeyBiYXNlNjQ6IHRydWUsIGRhdGE6IG1zZy5zdWJzdHIoMSkgfSB9O1xuICB9XG5cbiAgdmFyIGRhdGEgPSBiYXNlNjRlbmNvZGVyLmRlY29kZShtc2cuc3Vic3RyKDEpKTtcblxuICBpZiAoYmluYXJ5VHlwZSA9PT0gJ2Jsb2InICYmIEJsb2IpIHtcbiAgICBkYXRhID0gbmV3IEJsb2IoW2RhdGFdKTtcbiAgfVxuXG4gIHJldHVybiB7IHR5cGU6IHR5cGUsIGRhdGE6IGRhdGEgfTtcbn07XG5cbi8qKlxuICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkuXG4gKlxuICogICAgIDxsZW5ndGg+OmRhdGFcbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqICAgICAxMTpoZWxsbyB3b3JsZDI6aGlcbiAqXG4gKiBJZiBhbnkgY29udGVudHMgYXJlIGJpbmFyeSwgdGhleSB3aWxsIGJlIGVuY29kZWQgYXMgYmFzZTY0IHN0cmluZ3MuIEJhc2U2NFxuICogZW5jb2RlZCBzdHJpbmdzIGFyZSBtYXJrZWQgd2l0aCBhIGIgYmVmb3JlIHRoZSBsZW5ndGggc3BlY2lmaWVyXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcGFja2V0c1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGVQYXlsb2FkID0gZnVuY3Rpb24gKHBhY2tldHMsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIHN1cHBvcnRzQmluYXJ5ID09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgIHN1cHBvcnRzQmluYXJ5ID0gbnVsbDtcbiAgfVxuXG4gIGlmIChzdXBwb3J0c0JpbmFyeSkge1xuICAgIGlmIChCbG9iICYmICFpc0FuZHJvaWQpIHtcbiAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0Jsb2IocGFja2V0cywgY2FsbGJhY2spO1xuICAgIH1cblxuICAgIHJldHVybiBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyKHBhY2tldHMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gY2FsbGJhY2soJzA6Jyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgIHJldHVybiBtZXNzYWdlLmxlbmd0aCArICc6JyArIG1lc3NhZ2U7XG4gIH1cblxuICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICBleHBvcnRzLmVuY29kZVBhY2tldChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB0cnVlLCBmdW5jdGlvbihtZXNzYWdlKSB7XG4gICAgICBkb25lQ2FsbGJhY2sobnVsbCwgc2V0TGVuZ3RoSGVhZGVyKG1lc3NhZ2UpKTtcbiAgICB9KTtcbiAgfVxuXG4gIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICAgIHJldHVybiBjYWxsYmFjayhyZXN1bHRzLmpvaW4oJycpKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEFzeW5jIGFycmF5IG1hcCB1c2luZyBhZnRlclxuICovXG5cbmZ1bmN0aW9uIG1hcChhcnksIGVhY2gsIGRvbmUpIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShhcnkubGVuZ3RoKTtcbiAgdmFyIG5leHQgPSBhZnRlcihhcnkubGVuZ3RoLCBkb25lKTtcblxuICB2YXIgZWFjaFdpdGhJbmRleCA9IGZ1bmN0aW9uKGksIGVsLCBjYikge1xuICAgIGVhY2goZWwsIGZ1bmN0aW9uKGVycm9yLCBtc2cpIHtcbiAgICAgIHJlc3VsdFtpXSA9IG1zZztcbiAgICAgIGNiKGVycm9yLCByZXN1bHQpO1xuICAgIH0pO1xuICB9O1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgZWFjaFdpdGhJbmRleChpLCBhcnlbaV0sIG5leHQpO1xuICB9XG59XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFBvc3NpYmxlIGJpbmFyeSBjb250ZW50cyBhcmVcbiAqIGRlY29kZWQgZnJvbSB0aGVpciBiYXNlNjQgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGRhdGEgIT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZXhwb3J0cy5kZWNvZGVQYXlsb2FkQXNCaW5hcnkoZGF0YSwgYmluYXJ5VHlwZSwgY2FsbGJhY2spO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBiaW5hcnlUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY2FsbGJhY2sgPSBiaW5hcnlUeXBlO1xuICAgIGJpbmFyeVR5cGUgPSBudWxsO1xuICB9XG5cbiAgdmFyIHBhY2tldDtcbiAgaWYgKGRhdGEgPT0gJycpIHtcbiAgICAvLyBwYXJzZXIgZXJyb3IgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gIH1cblxuICB2YXIgbGVuZ3RoID0gJydcbiAgICAsIG4sIG1zZztcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IGRhdGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgdmFyIGNociA9IGRhdGEuY2hhckF0KGkpO1xuXG4gICAgaWYgKCc6JyAhPSBjaHIpIHtcbiAgICAgIGxlbmd0aCArPSBjaHI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICgnJyA9PSBsZW5ndGggfHwgKGxlbmd0aCAhPSAobiA9IE51bWJlcihsZW5ndGgpKSkpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgbXNnID0gZGF0YS5zdWJzdHIoaSArIDEsIG4pO1xuXG4gICAgICBpZiAobGVuZ3RoICE9IG1zZy5sZW5ndGgpIHtcbiAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1zZy5sZW5ndGgpIHtcbiAgICAgICAgcGFja2V0ID0gZXhwb3J0cy5kZWNvZGVQYWNrZXQobXNnLCBiaW5hcnlUeXBlLCB0cnVlKTtcblxuICAgICAgICBpZiAoZXJyLnR5cGUgPT0gcGFja2V0LnR5cGUgJiYgZXJyLmRhdGEgPT0gcGFja2V0LmRhdGEpIHtcbiAgICAgICAgICAvLyBwYXJzZXIgZXJyb3IgaW4gaW5kaXZpZHVhbCBwYWNrZXQgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmV0ID0gY2FsbGJhY2socGFja2V0LCBpICsgbiwgbCk7XG4gICAgICAgIGlmIChmYWxzZSA9PT0gcmV0KSByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIGFkdmFuY2UgY3Vyc29yXG4gICAgICBpICs9IG47XG4gICAgICBsZW5ndGggPSAnJztcbiAgICB9XG4gIH1cblxuICBpZiAobGVuZ3RoICE9ICcnKSB7XG4gICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICB9XG5cbn07XG5cbi8qKlxuICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkgYXMgYmluYXJ5LlxuICpcbiAqIDwxID0gYmluYXJ5LCAwID0gc3RyaW5nPjxudW1iZXIgZnJvbSAwLTk+PG51bWJlciBmcm9tIDAtOT5bLi4uXTxudW1iZXJcbiAqIDI1NT48ZGF0YT5cbiAqXG4gKiBFeGFtcGxlOlxuICogMSAzIDI1NSAxIDIgMywgaWYgdGhlIGJpbmFyeSBjb250ZW50cyBhcmUgaW50ZXJwcmV0ZWQgYXMgOCBiaXQgaW50ZWdlcnNcbiAqXG4gKiBAcGFyYW0ge0FycmF5fSBwYWNrZXRzXG4gKiBAcmV0dXJuIHtBcnJheUJ1ZmZlcn0gZW5jb2RlZCBwYXlsb2FkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyID0gZnVuY3Rpb24ocGFja2V0cywgY2FsbGJhY2spIHtcbiAgaWYgKCFwYWNrZXRzLmxlbmd0aCkge1xuICAgIHJldHVybiBjYWxsYmFjayhuZXcgQXJyYXlCdWZmZXIoMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbihkYXRhKSB7XG4gICAgICByZXR1cm4gZG9uZUNhbGxiYWNrKG51bGwsIGRhdGEpO1xuICAgIH0pO1xuICB9XG5cbiAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24oZXJyLCBlbmNvZGVkUGFja2V0cykge1xuICAgIHZhciB0b3RhbExlbmd0aCA9IGVuY29kZWRQYWNrZXRzLnJlZHVjZShmdW5jdGlvbihhY2MsIHApIHtcbiAgICAgIHZhciBsZW47XG4gICAgICBpZiAodHlwZW9mIHAgPT09ICdzdHJpbmcnKXtcbiAgICAgICAgbGVuID0gcC5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZW4gPSBwLmJ5dGVMZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjICsgbGVuLnRvU3RyaW5nKCkubGVuZ3RoICsgbGVuICsgMjsgLy8gc3RyaW5nL2JpbmFyeSBpZGVudGlmaWVyICsgc2VwYXJhdG9yID0gMlxuICAgIH0sIDApO1xuXG4gICAgdmFyIHJlc3VsdEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuXG4gICAgdmFyIGJ1ZmZlckluZGV4ID0gMDtcbiAgICBlbmNvZGVkUGFja2V0cy5mb3JFYWNoKGZ1bmN0aW9uKHApIHtcbiAgICAgIHZhciBpc1N0cmluZyA9IHR5cGVvZiBwID09PSAnc3RyaW5nJztcbiAgICAgIHZhciBhYiA9IHA7XG4gICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShwLmxlbmd0aCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZpZXdbaV0gPSBwLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIH1cbiAgICAgICAgYWIgPSB2aWV3LmJ1ZmZlcjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU3RyaW5nKSB7IC8vIG5vdCB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDA7XG4gICAgICB9IGVsc2UgeyAvLyB0cnVlIGJpbmFyeVxuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDE7XG4gICAgICB9XG5cbiAgICAgIHZhciBsZW5TdHIgPSBhYi5ieXRlTGVuZ3RoLnRvU3RyaW5nKCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICB9XG4gICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDI1NTtcblxuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShhYik7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzdWx0QXJyYXlbYnVmZmVySW5kZXgrK10gPSB2aWV3W2ldO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEFycmF5LmJ1ZmZlcik7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBFbmNvZGUgYXMgQmxvYlxuICovXG5cbmV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQmxvYiA9IGZ1bmN0aW9uKHBhY2tldHMsIGNhbGxiYWNrKSB7XG4gIGZ1bmN0aW9uIGVuY29kZU9uZShwYWNrZXQsIGRvbmVDYWxsYmFjaykge1xuICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgdHJ1ZSwgdHJ1ZSwgZnVuY3Rpb24oZW5jb2RlZCkge1xuICAgICAgdmFyIGJpbmFyeUlkZW50aWZpZXIgPSBuZXcgVWludDhBcnJheSgxKTtcbiAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAxO1xuICAgICAgaWYgKHR5cGVvZiBlbmNvZGVkID09PSAnc3RyaW5nJykge1xuICAgICAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGVuY29kZWQubGVuZ3RoKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmlld1tpXSA9IGVuY29kZWQuY2hhckNvZGVBdChpKTtcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGVkID0gdmlldy5idWZmZXI7XG4gICAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAwO1xuICAgICAgfVxuXG4gICAgICB2YXIgbGVuID0gKGVuY29kZWQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilcbiAgICAgICAgPyBlbmNvZGVkLmJ5dGVMZW5ndGhcbiAgICAgICAgOiBlbmNvZGVkLnNpemU7XG5cbiAgICAgIHZhciBsZW5TdHIgPSBsZW4udG9TdHJpbmcoKTtcbiAgICAgIHZhciBsZW5ndGhBcnkgPSBuZXcgVWludDhBcnJheShsZW5TdHIubGVuZ3RoICsgMSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZW5ndGhBcnlbaV0gPSBwYXJzZUludChsZW5TdHJbaV0pO1xuICAgICAgfVxuICAgICAgbGVuZ3RoQXJ5W2xlblN0ci5sZW5ndGhdID0gMjU1O1xuXG4gICAgICBpZiAoQmxvYikge1xuICAgICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtiaW5hcnlJZGVudGlmaWVyLmJ1ZmZlciwgbGVuZ3RoQXJ5LmJ1ZmZlciwgZW5jb2RlZF0pO1xuICAgICAgICBkb25lQ2FsbGJhY2sobnVsbCwgYmxvYik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAgICByZXR1cm4gY2FsbGJhY2sobmV3IEJsb2IocmVzdWx0cykpO1xuICB9KTtcbn07XG5cbi8qXG4gKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFN0cmluZ3MgYXJlIGRlY29kZWQgYnlcbiAqIGludGVycHJldGluZyBlYWNoIGJ5dGUgYXMgYSBrZXkgY29kZSBmb3IgZW50cmllcyBtYXJrZWQgdG8gc3RhcnQgd2l0aCAwLiBTZWVcbiAqIGRlc2NyaXB0aW9uIG9mIGVuY29kZVBheWxvYWRBc0JpbmFyeVxuICpcbiAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGEsIGNhbGxiYWNrIG1ldGhvZFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeSA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGJpbmFyeVR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gIH1cblxuICB2YXIgYnVmZmVyVGFpbCA9IGRhdGE7XG4gIHZhciBidWZmZXJzID0gW107XG5cbiAgdmFyIG51bWJlclRvb0xvbmcgPSBmYWxzZTtcbiAgd2hpbGUgKGJ1ZmZlclRhaWwuYnl0ZUxlbmd0aCA+IDApIHtcbiAgICB2YXIgdGFpbEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyVGFpbCk7XG4gICAgdmFyIGlzU3RyaW5nID0gdGFpbEFycmF5WzBdID09PSAwO1xuICAgIHZhciBtc2dMZW5ndGggPSAnJztcblxuICAgIGZvciAodmFyIGkgPSAxOyA7IGkrKykge1xuICAgICAgaWYgKHRhaWxBcnJheVtpXSA9PSAyNTUpIGJyZWFrO1xuXG4gICAgICBpZiAobXNnTGVuZ3RoLmxlbmd0aCA+IDMxMCkge1xuICAgICAgICBudW1iZXJUb29Mb25nID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIG1zZ0xlbmd0aCArPSB0YWlsQXJyYXlbaV07XG4gICAgfVxuXG4gICAgaWYobnVtYmVyVG9vTG9uZykgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG5cbiAgICBidWZmZXJUYWlsID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMiArIG1zZ0xlbmd0aC5sZW5ndGgpO1xuICAgIG1zZ0xlbmd0aCA9IHBhcnNlSW50KG1zZ0xlbmd0aCk7XG5cbiAgICB2YXIgbXNnID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMCwgbXNnTGVuZ3RoKTtcbiAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1zZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkobXNnKSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGlQaG9uZSBTYWZhcmkgZG9lc24ndCBsZXQgeW91IGFwcGx5IHRvIHR5cGVkIGFycmF5c1xuICAgICAgICB2YXIgdHlwZWQgPSBuZXcgVWludDhBcnJheShtc2cpO1xuICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIG1zZyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHR5cGVkW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGJ1ZmZlcnMucHVzaChtc2cpO1xuICAgIGJ1ZmZlclRhaWwgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCBtc2dMZW5ndGgpO1xuICB9XG5cbiAgdmFyIHRvdGFsID0gYnVmZmVycy5sZW5ndGg7XG4gIGJ1ZmZlcnMuZm9yRWFjaChmdW5jdGlvbihidWZmZXIsIGkpIHtcbiAgICBjYWxsYmFjayhleHBvcnRzLmRlY29kZVBhY2tldChidWZmZXIsIGJpbmFyeVR5cGUsIHRydWUpLCBpLCB0b3RhbCk7XG4gIH0pO1xufTtcbiIsIlxuLyoqXG4gKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gKlxuICogQHJldHVybiB7QXJyYXl9IGtleXNcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ga2V5cyAob2JqKXtcbiAgdmFyIGFyciA9IFtdO1xuICB2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICBhcnIucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFycjtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGFmdGVyXG5cbmZ1bmN0aW9uIGFmdGVyKGNvdW50LCBjYWxsYmFjaywgZXJyX2NiKSB7XG4gICAgdmFyIGJhaWwgPSBmYWxzZVxuICAgIGVycl9jYiA9IGVycl9jYiB8fCBub29wXG4gICAgcHJveHkuY291bnQgPSBjb3VudFxuXG4gICAgcmV0dXJuIChjb3VudCA9PT0gMCkgPyBjYWxsYmFjaygpIDogcHJveHlcblxuICAgIGZ1bmN0aW9uIHByb3h5KGVyciwgcmVzdWx0KSB7XG4gICAgICAgIGlmIChwcm94eS5jb3VudCA8PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FmdGVyIGNhbGxlZCB0b28gbWFueSB0aW1lcycpXG4gICAgICAgIH1cbiAgICAgICAgLS1wcm94eS5jb3VudFxuXG4gICAgICAgIC8vIGFmdGVyIGZpcnN0IGVycm9yLCByZXN0IGFyZSBwYXNzZWQgdG8gZXJyX2NiXG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGJhaWwgPSB0cnVlXG4gICAgICAgICAgICBjYWxsYmFjayhlcnIpXG4gICAgICAgICAgICAvLyBmdXR1cmUgZXJyb3IgY2FsbGJhY2tzIHdpbGwgZ28gdG8gZXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgY2FsbGJhY2sgPSBlcnJfY2JcbiAgICAgICAgfSBlbHNlIGlmIChwcm94eS5jb3VudCA9PT0gMCAmJiAhYmFpbCkge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0KVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBub29wKCkge31cbiIsIi8qKlxuICogQW4gYWJzdHJhY3Rpb24gZm9yIHNsaWNpbmcgYW4gYXJyYXlidWZmZXIgZXZlbiB3aGVuXG4gKiBBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgaXMgbm90IHN1cHBvcnRlZFxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnJheWJ1ZmZlciwgc3RhcnQsIGVuZCkge1xuICB2YXIgYnl0ZXMgPSBhcnJheWJ1ZmZlci5ieXRlTGVuZ3RoO1xuICBzdGFydCA9IHN0YXJ0IHx8IDA7XG4gIGVuZCA9IGVuZCB8fCBieXRlcztcblxuICBpZiAoYXJyYXlidWZmZXIuc2xpY2UpIHsgcmV0dXJuIGFycmF5YnVmZmVyLnNsaWNlKHN0YXJ0LCBlbmQpOyB9XG5cbiAgaWYgKHN0YXJ0IDwgMCkgeyBzdGFydCArPSBieXRlczsgfVxuICBpZiAoZW5kIDwgMCkgeyBlbmQgKz0gYnl0ZXM7IH1cbiAgaWYgKGVuZCA+IGJ5dGVzKSB7IGVuZCA9IGJ5dGVzOyB9XG5cbiAgaWYgKHN0YXJ0ID49IGJ5dGVzIHx8IHN0YXJ0ID49IGVuZCB8fCBieXRlcyA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQXJyYXlCdWZmZXIoMCk7XG4gIH1cblxuICB2YXIgYWJ2ID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpO1xuICB2YXIgcmVzdWx0ID0gbmV3IFVpbnQ4QXJyYXkoZW5kIC0gc3RhcnQpO1xuICBmb3IgKHZhciBpID0gc3RhcnQsIGlpID0gMDsgaSA8IGVuZDsgaSsrLCBpaSsrKSB7XG4gICAgcmVzdWx0W2lpXSA9IGFidltpXTtcbiAgfVxuICByZXR1cm4gcmVzdWx0LmJ1ZmZlcjtcbn07XG4iLCIvKlxuICogYmFzZTY0LWFycmF5YnVmZmVyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vbmlrbGFzdmgvYmFzZTY0LWFycmF5YnVmZmVyXG4gKlxuICogQ29weXJpZ2h0IChjKSAyMDEyIE5pa2xhcyB2b24gSGVydHplblxuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICovXG4oZnVuY3Rpb24oY2hhcnMpe1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBleHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uKGFycmF5YnVmZmVyKSB7XG4gICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpLFxuICAgIGksIGxlbiA9IGJ5dGVzLmxlbmd0aCwgYmFzZTY0ID0gXCJcIjtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrPTMpIHtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1tieXRlc1tpXSA+PiAyXTtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2ldICYgMykgPDwgNCkgfCAoYnl0ZXNbaSArIDFdID4+IDQpXTtcbiAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2kgKyAxXSAmIDE1KSA8PCAyKSB8IChieXRlc1tpICsgMl0gPj4gNildO1xuICAgICAgYmFzZTY0ICs9IGNoYXJzW2J5dGVzW2kgKyAyXSAmIDYzXTtcbiAgICB9XG5cbiAgICBpZiAoKGxlbiAlIDMpID09PSAyKSB7XG4gICAgICBiYXNlNjQgPSBiYXNlNjQuc3Vic3RyaW5nKDAsIGJhc2U2NC5sZW5ndGggLSAxKSArIFwiPVwiO1xuICAgIH0gZWxzZSBpZiAobGVuICUgMyA9PT0gMSkge1xuICAgICAgYmFzZTY0ID0gYmFzZTY0LnN1YnN0cmluZygwLCBiYXNlNjQubGVuZ3RoIC0gMikgKyBcIj09XCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJhc2U2NDtcbiAgfTtcblxuICBleHBvcnRzLmRlY29kZSA9ICBmdW5jdGlvbihiYXNlNjQpIHtcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYmFzZTY0Lmxlbmd0aCAqIDAuNzUsXG4gICAgbGVuID0gYmFzZTY0Lmxlbmd0aCwgaSwgcCA9IDAsXG4gICAgZW5jb2RlZDEsIGVuY29kZWQyLCBlbmNvZGVkMywgZW5jb2RlZDQ7XG5cbiAgICBpZiAoYmFzZTY0W2Jhc2U2NC5sZW5ndGggLSAxXSA9PT0gXCI9XCIpIHtcbiAgICAgIGJ1ZmZlckxlbmd0aC0tO1xuICAgICAgaWYgKGJhc2U2NFtiYXNlNjQubGVuZ3RoIC0gMl0gPT09IFwiPVwiKSB7XG4gICAgICAgIGJ1ZmZlckxlbmd0aC0tO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBhcnJheWJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXJMZW5ndGgpLFxuICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpO1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSs9NCkge1xuICAgICAgZW5jb2RlZDEgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpXSk7XG4gICAgICBlbmNvZGVkMiA9IGNoYXJzLmluZGV4T2YoYmFzZTY0W2krMV0pO1xuICAgICAgZW5jb2RlZDMgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpKzJdKTtcbiAgICAgIGVuY29kZWQ0ID0gY2hhcnMuaW5kZXhPZihiYXNlNjRbaSszXSk7XG5cbiAgICAgIGJ5dGVzW3ArK10gPSAoZW5jb2RlZDEgPDwgMikgfCAoZW5jb2RlZDIgPj4gNCk7XG4gICAgICBieXRlc1twKytdID0gKChlbmNvZGVkMiAmIDE1KSA8PCA0KSB8IChlbmNvZGVkMyA+PiAyKTtcbiAgICAgIGJ5dGVzW3ArK10gPSAoKGVuY29kZWQzICYgMykgPDwgNikgfCAoZW5jb2RlZDQgJiA2Myk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFycmF5YnVmZmVyO1xuICB9O1xufSkoXCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIpO1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LyoqXG4gKiBDcmVhdGUgYSBibG9iIGJ1aWxkZXIgZXZlbiB3aGVuIHZlbmRvciBwcmVmaXhlcyBleGlzdFxuICovXG5cbnZhciBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlclxuICB8fCBnbG9iYWwuV2ViS2l0QmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLk1TQmxvYkJ1aWxkZXJcbiAgfHwgZ2xvYmFsLk1vekJsb2JCdWlsZGVyO1xuXG4vKipcbiAqIENoZWNrIGlmIEJsb2IgY29uc3RydWN0b3IgaXMgc3VwcG9ydGVkXG4gKi9cblxudmFyIGJsb2JTdXBwb3J0ZWQgPSAoZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgdmFyIGIgPSBuZXcgQmxvYihbJ2hpJ10pO1xuICAgIHJldHVybiBiLnNpemUgPT0gMjtcbiAgfSBjYXRjaChlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59KSgpO1xuXG4vKipcbiAqIENoZWNrIGlmIEJsb2JCdWlsZGVyIGlzIHN1cHBvcnRlZFxuICovXG5cbnZhciBibG9iQnVpbGRlclN1cHBvcnRlZCA9IEJsb2JCdWlsZGVyXG4gICYmIEJsb2JCdWlsZGVyLnByb3RvdHlwZS5hcHBlbmRcbiAgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmdldEJsb2I7XG5cbmZ1bmN0aW9uIEJsb2JCdWlsZGVyQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBiYiA9IG5ldyBCbG9iQnVpbGRlcigpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyeS5sZW5ndGg7IGkrKykge1xuICAgIGJiLmFwcGVuZChhcnlbaV0pO1xuICB9XG4gIHJldHVybiAob3B0aW9ucy50eXBlKSA/IGJiLmdldEJsb2Iob3B0aW9ucy50eXBlKSA6IGJiLmdldEJsb2IoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gKGZ1bmN0aW9uKCkge1xuICBpZiAoYmxvYlN1cHBvcnRlZCkge1xuICAgIHJldHVybiBnbG9iYWwuQmxvYjtcbiAgfSBlbHNlIGlmIChibG9iQnVpbGRlclN1cHBvcnRlZCkge1xuICAgIHJldHVybiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn0pKCk7XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTsvKiEgaHR0cDovL210aHMuYmUvdXRmOGpzIHYyLjAuMCBieSBAbWF0aGlhcyAqL1xuOyhmdW5jdGlvbihyb290KSB7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGVzIGBleHBvcnRzYFxuXHR2YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzO1xuXG5cdC8vIERldGVjdCBmcmVlIHZhcmlhYmxlIGBtb2R1bGVgXG5cdHZhciBmcmVlTW9kdWxlID0gdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiZcblx0XHRtb2R1bGUuZXhwb3J0cyA9PSBmcmVlRXhwb3J0cyAmJiBtb2R1bGU7XG5cblx0Ly8gRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGdsb2JhbGAsIGZyb20gTm9kZS5qcyBvciBCcm93c2VyaWZpZWQgY29kZSxcblx0Ly8gYW5kIHVzZSBpdCBhcyBgcm9vdGBcblx0dmFyIGZyZWVHbG9iYWwgPSB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbDtcblx0aWYgKGZyZWVHbG9iYWwuZ2xvYmFsID09PSBmcmVlR2xvYmFsIHx8IGZyZWVHbG9iYWwud2luZG93ID09PSBmcmVlR2xvYmFsKSB7XG5cdFx0cm9vdCA9IGZyZWVHbG9iYWw7XG5cdH1cblxuXHQvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuXHR2YXIgc3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuXHQvLyBUYWtlbiBmcm9tIGh0dHA6Ly9tdGhzLmJlL3B1bnljb2RlXG5cdGZ1bmN0aW9uIHVjczJkZWNvZGUoc3RyaW5nKSB7XG5cdFx0dmFyIG91dHB1dCA9IFtdO1xuXHRcdHZhciBjb3VudGVyID0gMDtcblx0XHR2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcblx0XHR2YXIgdmFsdWU7XG5cdFx0dmFyIGV4dHJhO1xuXHRcdHdoaWxlIChjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHR2YWx1ZSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRpZiAodmFsdWUgPj0gMHhEODAwICYmIHZhbHVlIDw9IDB4REJGRiAmJiBjb3VudGVyIDwgbGVuZ3RoKSB7XG5cdFx0XHRcdC8vIGhpZ2ggc3Vycm9nYXRlLCBhbmQgdGhlcmUgaXMgYSBuZXh0IGNoYXJhY3RlclxuXHRcdFx0XHRleHRyYSA9IHN0cmluZy5jaGFyQ29kZUF0KGNvdW50ZXIrKyk7XG5cdFx0XHRcdGlmICgoZXh0cmEgJiAweEZDMDApID09IDB4REMwMCkgeyAvLyBsb3cgc3Vycm9nYXRlXG5cdFx0XHRcdFx0b3V0cHV0LnB1c2goKCh2YWx1ZSAmIDB4M0ZGKSA8PCAxMCkgKyAoZXh0cmEgJiAweDNGRikgKyAweDEwMDAwKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQvLyB1bm1hdGNoZWQgc3Vycm9nYXRlOyBvbmx5IGFwcGVuZCB0aGlzIGNvZGUgdW5pdCwgaW4gY2FzZSB0aGUgbmV4dFxuXHRcdFx0XHRcdC8vIGNvZGUgdW5pdCBpcyB0aGUgaGlnaCBzdXJyb2dhdGUgb2YgYSBzdXJyb2dhdGUgcGFpclxuXHRcdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdFx0XHRjb3VudGVyLS07XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG91dHB1dC5wdXNoKHZhbHVlKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxuXG5cdC8vIFRha2VuIGZyb20gaHR0cDovL210aHMuYmUvcHVueWNvZGVcblx0ZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuXHRcdHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cdFx0dmFyIGluZGV4ID0gLTE7XG5cdFx0dmFyIHZhbHVlO1xuXHRcdHZhciBvdXRwdXQgPSAnJztcblx0XHR3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuXHRcdFx0dmFsdWUgPSBhcnJheVtpbmRleF07XG5cdFx0XHRpZiAodmFsdWUgPiAweEZGRkYpIHtcblx0XHRcdFx0dmFsdWUgLT0gMHgxMDAwMDtcblx0XHRcdFx0b3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG5cdFx0XHRcdHZhbHVlID0gMHhEQzAwIHwgdmFsdWUgJiAweDNGRjtcblx0XHRcdH1cblx0XHRcdG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuXHRcdH1cblx0XHRyZXR1cm4gb3V0cHV0O1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0ZnVuY3Rpb24gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIHNoaWZ0KSB7XG5cdFx0cmV0dXJuIHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiBzaGlmdCkgJiAweDNGKSB8IDB4ODApO1xuXHR9XG5cblx0ZnVuY3Rpb24gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCkge1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRkY4MCkgPT0gMCkgeyAvLyAxLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHJldHVybiBzdHJpbmdGcm9tQ2hhckNvZGUoY29kZVBvaW50KTtcblx0XHR9XG5cdFx0dmFyIHN5bWJvbCA9ICcnO1xuXHRcdGlmICgoY29kZVBvaW50ICYgMHhGRkZGRjgwMCkgPT0gMCkgeyAvLyAyLWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiA2KSAmIDB4MUYpIHwgMHhDMCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKChjb2RlUG9pbnQgJiAweEZGRkYwMDAwKSA9PSAwKSB7IC8vIDMtYnl0ZSBzZXF1ZW5jZVxuXHRcdFx0c3ltYm9sID0gc3RyaW5nRnJvbUNoYXJDb2RlKCgoY29kZVBvaW50ID4+IDEyKSAmIDB4MEYpIHwgMHhFMCk7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRlbHNlIGlmICgoY29kZVBvaW50ICYgMHhGRkUwMDAwMCkgPT0gMCkgeyAvLyA0LWJ5dGUgc2VxdWVuY2Vcblx0XHRcdHN5bWJvbCA9IHN0cmluZ0Zyb21DaGFyQ29kZSgoKGNvZGVQb2ludCA+PiAxOCkgJiAweDA3KSB8IDB4RjApO1xuXHRcdFx0c3ltYm9sICs9IGNyZWF0ZUJ5dGUoY29kZVBvaW50LCAxMik7XG5cdFx0XHRzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuXHRcdH1cblx0XHRzeW1ib2wgKz0gc3RyaW5nRnJvbUNoYXJDb2RlKChjb2RlUG9pbnQgJiAweDNGKSB8IDB4ODApO1xuXHRcdHJldHVybiBzeW1ib2w7XG5cdH1cblxuXHRmdW5jdGlvbiB1dGY4ZW5jb2RlKHN0cmluZykge1xuXHRcdHZhciBjb2RlUG9pbnRzID0gdWNzMmRlY29kZShzdHJpbmcpO1xuXG5cdFx0Ly8gY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoY29kZVBvaW50cy5tYXAoZnVuY3Rpb24oeCkge1xuXHRcdC8vIFx0cmV0dXJuICdVKycgKyB4LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuXHRcdC8vIH0pKSk7XG5cblx0XHR2YXIgbGVuZ3RoID0gY29kZVBvaW50cy5sZW5ndGg7XG5cdFx0dmFyIGluZGV4ID0gLTE7XG5cdFx0dmFyIGNvZGVQb2ludDtcblx0XHR2YXIgYnl0ZVN0cmluZyA9ICcnO1xuXHRcdHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG5cdFx0XHRjb2RlUG9pbnQgPSBjb2RlUG9pbnRzW2luZGV4XTtcblx0XHRcdGJ5dGVTdHJpbmcgKz0gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCk7XG5cdFx0fVxuXHRcdHJldHVybiBieXRlU3RyaW5nO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0ZnVuY3Rpb24gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKSB7XG5cdFx0aWYgKGJ5dGVJbmRleCA+PSBieXRlQ291bnQpIHtcblx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGJ5dGUgaW5kZXgnKTtcblx0XHR9XG5cblx0XHR2YXIgY29udGludWF0aW9uQnl0ZSA9IGJ5dGVBcnJheVtieXRlSW5kZXhdICYgMHhGRjtcblx0XHRieXRlSW5kZXgrKztcblxuXHRcdGlmICgoY29udGludWF0aW9uQnl0ZSAmIDB4QzApID09IDB4ODApIHtcblx0XHRcdHJldHVybiBjb250aW51YXRpb25CeXRlICYgMHgzRjtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBlbmQgdXAgaGVyZSwgaXTigJlzIG5vdCBhIGNvbnRpbnVhdGlvbiBieXRlXG5cdFx0dGhyb3cgRXJyb3IoJ0ludmFsaWQgY29udGludWF0aW9uIGJ5dGUnKTtcblx0fVxuXG5cdGZ1bmN0aW9uIGRlY29kZVN5bWJvbCgpIHtcblx0XHR2YXIgYnl0ZTE7XG5cdFx0dmFyIGJ5dGUyO1xuXHRcdHZhciBieXRlMztcblx0XHR2YXIgYnl0ZTQ7XG5cdFx0dmFyIGNvZGVQb2ludDtcblxuXHRcdGlmIChieXRlSW5kZXggPiBieXRlQ291bnQpIHtcblx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGJ5dGUgaW5kZXgnKTtcblx0XHR9XG5cblx0XHRpZiAoYnl0ZUluZGV4ID09IGJ5dGVDb3VudCkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdC8vIFJlYWQgZmlyc3QgYnl0ZVxuXHRcdGJ5dGUxID0gYnl0ZUFycmF5W2J5dGVJbmRleF0gJiAweEZGO1xuXHRcdGJ5dGVJbmRleCsrO1xuXG5cdFx0Ly8gMS1ieXRlIHNlcXVlbmNlIChubyBjb250aW51YXRpb24gYnl0ZXMpXG5cdFx0aWYgKChieXRlMSAmIDB4ODApID09IDApIHtcblx0XHRcdHJldHVybiBieXRlMTtcblx0XHR9XG5cblx0XHQvLyAyLWJ5dGUgc2VxdWVuY2Vcblx0XHRpZiAoKGJ5dGUxICYgMHhFMCkgPT0gMHhDMCkge1xuXHRcdFx0dmFyIGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGNvZGVQb2ludCA9ICgoYnl0ZTEgJiAweDFGKSA8PCA2KSB8IGJ5dGUyO1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDgwKSB7XG5cdFx0XHRcdHJldHVybiBjb2RlUG9pbnQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIDMtYnl0ZSBzZXF1ZW5jZSAobWF5IGluY2x1ZGUgdW5wYWlyZWQgc3Vycm9nYXRlcylcblx0XHRpZiAoKGJ5dGUxICYgMHhGMCkgPT0gMHhFMCkge1xuXHRcdFx0Ynl0ZTIgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuXHRcdFx0Ynl0ZTMgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuXHRcdFx0Y29kZVBvaW50ID0gKChieXRlMSAmIDB4MEYpIDw8IDEyKSB8IChieXRlMiA8PCA2KSB8IGJ5dGUzO1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDA4MDApIHtcblx0XHRcdFx0cmV0dXJuIGNvZGVQb2ludDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRocm93IEVycm9yKCdJbnZhbGlkIGNvbnRpbnVhdGlvbiBieXRlJyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gNC1ieXRlIHNlcXVlbmNlXG5cdFx0aWYgKChieXRlMSAmIDB4RjgpID09IDB4RjApIHtcblx0XHRcdGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGJ5dGUzID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGJ5dGU0ID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcblx0XHRcdGNvZGVQb2ludCA9ICgoYnl0ZTEgJiAweDBGKSA8PCAweDEyKSB8IChieXRlMiA8PCAweDBDKSB8XG5cdFx0XHRcdChieXRlMyA8PCAweDA2KSB8IGJ5dGU0O1xuXHRcdFx0aWYgKGNvZGVQb2ludCA+PSAweDAxMDAwMCAmJiBjb2RlUG9pbnQgPD0gMHgxMEZGRkYpIHtcblx0XHRcdFx0cmV0dXJuIGNvZGVQb2ludDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aHJvdyBFcnJvcignSW52YWxpZCBVVEYtOCBkZXRlY3RlZCcpO1xuXHR9XG5cblx0dmFyIGJ5dGVBcnJheTtcblx0dmFyIGJ5dGVDb3VudDtcblx0dmFyIGJ5dGVJbmRleDtcblx0ZnVuY3Rpb24gdXRmOGRlY29kZShieXRlU3RyaW5nKSB7XG5cdFx0Ynl0ZUFycmF5ID0gdWNzMmRlY29kZShieXRlU3RyaW5nKTtcblx0XHRieXRlQ291bnQgPSBieXRlQXJyYXkubGVuZ3RoO1xuXHRcdGJ5dGVJbmRleCA9IDA7XG5cdFx0dmFyIGNvZGVQb2ludHMgPSBbXTtcblx0XHR2YXIgdG1wO1xuXHRcdHdoaWxlICgodG1wID0gZGVjb2RlU3ltYm9sKCkpICE9PSBmYWxzZSkge1xuXHRcdFx0Y29kZVBvaW50cy5wdXNoKHRtcCk7XG5cdFx0fVxuXHRcdHJldHVybiB1Y3MyZW5jb2RlKGNvZGVQb2ludHMpO1xuXHR9XG5cblx0LyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblx0dmFyIHV0ZjggPSB7XG5cdFx0J3ZlcnNpb24nOiAnMi4wLjAnLFxuXHRcdCdlbmNvZGUnOiB1dGY4ZW5jb2RlLFxuXHRcdCdkZWNvZGUnOiB1dGY4ZGVjb2RlXG5cdH07XG5cblx0Ly8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3Igc3BlY2lmaWMgY29uZGl0aW9uIHBhdHRlcm5zXG5cdC8vIGxpa2UgdGhlIGZvbGxvd2luZzpcblx0aWYgKFxuXHRcdHR5cGVvZiBkZWZpbmUgPT0gJ2Z1bmN0aW9uJyAmJlxuXHRcdHR5cGVvZiBkZWZpbmUuYW1kID09ICdvYmplY3QnICYmXG5cdFx0ZGVmaW5lLmFtZFxuXHQpIHtcblx0XHRkZWZpbmUoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdXRmODtcblx0XHR9KTtcblx0fVx0ZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG5cdFx0aWYgKGZyZWVNb2R1bGUpIHsgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcblx0XHRcdGZyZWVNb2R1bGUuZXhwb3J0cyA9IHV0Zjg7XG5cdFx0fSBlbHNlIHsgLy8gaW4gTmFyd2hhbCBvciBSaW5nb0pTIHYwLjcuMC1cblx0XHRcdHZhciBvYmplY3QgPSB7fTtcblx0XHRcdHZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdC5oYXNPd25Qcm9wZXJ0eTtcblx0XHRcdGZvciAodmFyIGtleSBpbiB1dGY4KSB7XG5cdFx0XHRcdGhhc093blByb3BlcnR5LmNhbGwodXRmOCwga2V5KSAmJiAoZnJlZUV4cG9ydHNba2V5XSA9IHV0Zjhba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgeyAvLyBpbiBSaGlubyBvciBhIHdlYiBicm93c2VyXG5cdFx0cm9vdC51dGY4ID0gdXRmODtcblx0fVxuXG59KHRoaXMpKTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBnbG9iYWwgPSByZXF1aXJlKCdnbG9iYWwnKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqXG4gKiBMb2dpYyBib3Jyb3dlZCBmcm9tIE1vZGVybml6cjpcbiAqXG4gKiAgIC0gaHR0cHM6Ly9naXRodWIuY29tL01vZGVybml6ci9Nb2Rlcm5penIvYmxvYi9tYXN0ZXIvZmVhdHVyZS1kZXRlY3RzL2NvcnMuanNcbiAqL1xuXG50cnkge1xuICBtb2R1bGUuZXhwb3J0cyA9ICdYTUxIdHRwUmVxdWVzdCcgaW4gZ2xvYmFsICYmXG4gICAgJ3dpdGhDcmVkZW50aWFscycgaW4gbmV3IGdsb2JhbC5YTUxIdHRwUmVxdWVzdCgpO1xufSBjYXRjaCAoZXJyKSB7XG4gIC8vIGlmIFhNTEh0dHAgc3VwcG9ydCBpcyBkaXNhYmxlZCBpbiBJRSB0aGVuIGl0IHdpbGwgdGhyb3dcbiAgLy8gd2hlbiB0cnlpbmcgdG8gY3JlYXRlXG4gIG1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG59XG4iLCJcbi8qKlxuICogUmV0dXJucyBgdGhpc2AuIEV4ZWN1dGUgdGhpcyB3aXRob3V0IGEgXCJjb250ZXh0XCIgKGkuZS4gd2l0aG91dCBpdCBiZWluZ1xuICogYXR0YWNoZWQgdG8gYW4gb2JqZWN0IG9mIHRoZSBsZWZ0LWhhbmQgc2lkZSksIGFuZCBgdGhpc2AgcG9pbnRzIHRvIHRoZVxuICogXCJnbG9iYWxcIiBzY29wZSBvZiB0aGUgY3VycmVudCBKUyBleGVjdXRpb24uXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSAoZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSkoKTtcbiIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogSlNPTiBwYXJzZS5cbiAqXG4gKiBAc2VlIEJhc2VkIG9uIGpRdWVyeSNwYXJzZUpTT04gKE1JVCkgYW5kIEpTT04yXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcnZhbGlkY2hhcnMgPSAvXltcXF0sOnt9XFxzXSokLztcbnZhciBydmFsaWRlc2NhcGUgPSAvXFxcXCg/OltcIlxcXFxcXC9iZm5ydF18dVswLTlhLWZBLUZdezR9KS9nO1xudmFyIHJ2YWxpZHRva2VucyA9IC9cIlteXCJcXFxcXFxuXFxyXSpcInx0cnVlfGZhbHNlfG51bGx8LT9cXGQrKD86XFwuXFxkKik/KD86W2VFXVsrXFwtXT9cXGQrKT8vZztcbnZhciBydmFsaWRicmFjZXMgPSAvKD86Xnw6fCwpKD86XFxzKlxcWykrL2c7XG52YXIgcnRyaW1MZWZ0ID0gL15cXHMrLztcbnZhciBydHJpbVJpZ2h0ID0gL1xccyskLztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZWpzb24oZGF0YSkge1xuICBpZiAoJ3N0cmluZycgIT0gdHlwZW9mIGRhdGEgfHwgIWRhdGEpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGRhdGEgPSBkYXRhLnJlcGxhY2UocnRyaW1MZWZ0LCAnJykucmVwbGFjZShydHJpbVJpZ2h0LCAnJyk7XG5cbiAgLy8gQXR0ZW1wdCB0byBwYXJzZSB1c2luZyB0aGUgbmF0aXZlIEpTT04gcGFyc2VyIGZpcnN0XG4gIGlmIChnbG9iYWwuSlNPTiAmJiBKU09OLnBhcnNlKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gIH1cblxuICBpZiAocnZhbGlkY2hhcnMudGVzdChkYXRhLnJlcGxhY2UocnZhbGlkZXNjYXBlLCAnQCcpXG4gICAgICAucmVwbGFjZShydmFsaWR0b2tlbnMsICddJylcbiAgICAgIC5yZXBsYWNlKHJ2YWxpZGJyYWNlcywgJycpKSkge1xuICAgIHJldHVybiAobmV3IEZ1bmN0aW9uKCdyZXR1cm4gJyArIGRhdGEpKSgpO1xuICB9XG59OyIsIi8qKlxuICogQ29tcGlsZXMgYSBxdWVyeXN0cmluZ1xuICogUmV0dXJucyBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBzdHIgPSAnJztcblxuICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgIGlmIChzdHIubGVuZ3RoKSBzdHIgKz0gJyYnO1xuICAgICAgc3RyICs9IGVuY29kZVVSSUNvbXBvbmVudChpKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbaV0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdHI7XG59O1xuXG4vKipcbiAqIFBhcnNlcyBhIHNpbXBsZSBxdWVyeXN0cmluZyBpbnRvIGFuIG9iamVjdFxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBxc1xuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbihxcyl7XG4gIHZhciBxcnkgPSB7fTtcbiAgdmFyIHBhaXJzID0gcXMuc3BsaXQoJyYnKTtcbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYWlycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICB2YXIgcGFpciA9IHBhaXJzW2ldLnNwbGl0KCc9Jyk7XG4gICAgcXJ5W2RlY29kZVVSSUNvbXBvbmVudChwYWlyWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFpclsxXSk7XG4gIH1cbiAgcmV0dXJuIHFyeTtcbn07XG4iLCIvKipcbiAqIFBhcnNlcyBhbiBVUklcbiAqXG4gKiBAYXV0aG9yIFN0ZXZlbiBMZXZpdGhhbiA8c3RldmVubGV2aXRoYW4uY29tPiAoTUlUIGxpY2Vuc2UpXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcmUgPSAvXig/Oig/IVteOkBdKzpbXjpAXFwvXSpAKShodHRwfGh0dHBzfHdzfHdzcyk6XFwvXFwvKT8oKD86KChbXjpAXSopKD86OihbXjpAXSopKT8pP0ApPygoPzpbYS1mMC05XXswLDR9Oil7Miw3fVthLWYwLTldezAsNH18W146XFwvPyNdKikoPzo6KFxcZCopKT8pKCgoXFwvKD86W14/I10oPyFbXj8jXFwvXSpcXC5bXj8jXFwvLl0rKD86Wz8jXXwkKSkpKlxcLz8pPyhbXj8jXFwvXSopKSg/OlxcPyhbXiNdKikpPyg/OiMoLiopKT8pLztcblxudmFyIHBhcnRzID0gW1xuICAgICdzb3VyY2UnLCAncHJvdG9jb2wnLCAnYXV0aG9yaXR5JywgJ3VzZXJJbmZvJywgJ3VzZXInLCAncGFzc3dvcmQnLCAnaG9zdCcsICdwb3J0JywgJ3JlbGF0aXZlJywgJ3BhdGgnLCAnZGlyZWN0b3J5JywgJ2ZpbGUnLCAncXVlcnknLCAnYW5jaG9yJ1xuXTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZXVyaShzdHIpIHtcbiAgICB2YXIgc3JjID0gc3RyLFxuICAgICAgICBiID0gc3RyLmluZGV4T2YoJ1snKSxcbiAgICAgICAgZSA9IHN0ci5pbmRleE9mKCddJyk7XG5cbiAgICBpZiAoYiAhPSAtMSAmJiBlICE9IC0xKSB7XG4gICAgICAgIHN0ciA9IHN0ci5zdWJzdHJpbmcoMCwgYikgKyBzdHIuc3Vic3RyaW5nKGIsIGUpLnJlcGxhY2UoLzovZywgJzsnKSArIHN0ci5zdWJzdHJpbmcoZSwgc3RyLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgdmFyIG0gPSByZS5leGVjKHN0ciB8fCAnJyksXG4gICAgICAgIHVyaSA9IHt9LFxuICAgICAgICBpID0gMTQ7XG5cbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgIHVyaVtwYXJ0c1tpXV0gPSBtW2ldIHx8ICcnO1xuICAgIH1cblxuICAgIGlmIChiICE9IC0xICYmIGUgIT0gLTEpIHtcbiAgICAgICAgdXJpLnNvdXJjZSA9IHNyYztcbiAgICAgICAgdXJpLmhvc3QgPSB1cmkuaG9zdC5zdWJzdHJpbmcoMSwgdXJpLmhvc3QubGVuZ3RoIC0gMSkucmVwbGFjZSgvOy9nLCAnOicpO1xuICAgICAgICB1cmkuYXV0aG9yaXR5ID0gdXJpLmF1dGhvcml0eS5yZXBsYWNlKCdbJywgJycpLnJlcGxhY2UoJ10nLCAnJykucmVwbGFjZSgvOy9nLCAnOicpO1xuICAgICAgICB1cmkuaXB2NnVyaSA9IHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHVyaTtcbn07XG4iLCJcbi8qKlxuICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAqL1xuXG52YXIgZ2xvYmFsID0gKGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSkoKTtcblxuLyoqXG4gKiBXZWJTb2NrZXQgY29uc3RydWN0b3IuXG4gKi9cblxudmFyIFdlYlNvY2tldCA9IGdsb2JhbC5XZWJTb2NrZXQgfHwgZ2xvYmFsLk1veldlYlNvY2tldDtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlNvY2tldCA/IHdzIDogbnVsbDtcblxuLyoqXG4gKiBXZWJTb2NrZXQgY29uc3RydWN0b3IuXG4gKlxuICogVGhlIHRoaXJkIGBvcHRzYCBvcHRpb25zIG9iamVjdCBnZXRzIGlnbm9yZWQgaW4gd2ViIGJyb3dzZXJzLCBzaW5jZSBpdCdzXG4gKiBub24tc3RhbmRhcmQsIGFuZCB0aHJvd3MgYSBUeXBlRXJyb3IgaWYgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAqIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2VpbmFyb3Mvd3MvaXNzdWVzLzIyN1xuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSB1cmlcbiAqIEBwYXJhbSB7QXJyYXl9IHByb3RvY29scyAob3B0aW9uYWwpXG4gKiBAcGFyYW0ge09iamVjdCkgb3B0cyAob3B0aW9uYWwpXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIHdzKHVyaSwgcHJvdG9jb2xzLCBvcHRzKSB7XG4gIHZhciBpbnN0YW5jZTtcbiAgaWYgKHByb3RvY29scykge1xuICAgIGluc3RhbmNlID0gbmV3IFdlYlNvY2tldCh1cmksIHByb3RvY29scyk7XG4gIH0gZWxzZSB7XG4gICAgaW5zdGFuY2UgPSBuZXcgV2ViU29ja2V0KHVyaSk7XG4gIH1cbiAgcmV0dXJuIGluc3RhbmNlO1xufVxuXG5pZiAoV2ViU29ja2V0KSB3cy5wcm90b3R5cGUgPSBXZWJTb2NrZXQucHJvdG90eXBlO1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307XG4vKlxuICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAqL1xuXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzYXJyYXknKTtcblxuLyoqXG4gKiBNb2R1bGUgZXhwb3J0cy5cbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc0JpbmFyeTtcblxuLyoqXG4gKiBDaGVja3MgZm9yIGJpbmFyeSBkYXRhLlxuICpcbiAqIFJpZ2h0IG5vdyBvbmx5IEJ1ZmZlciBhbmQgQXJyYXlCdWZmZXIgYXJlIHN1cHBvcnRlZC4uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFueXRoaW5nXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIGhhc0JpbmFyeShkYXRhKSB7XG5cbiAgZnVuY3Rpb24gX2hhc0JpbmFyeShvYmopIHtcbiAgICBpZiAoIW9iaikgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCAoZ2xvYmFsLkJ1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB8fFxuICAgICAgICAgKGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IpIHx8XG4gICAgICAgICAoZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSlcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmIChfaGFzQmluYXJ5KG9ialtpXSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAob2JqICYmICdvYmplY3QnID09IHR5cGVvZiBvYmopIHtcbiAgICAgIGlmIChvYmoudG9KU09OKSB7XG4gICAgICAgIG9iaiA9IG9iai50b0pTT04oKTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KGtleSkgJiYgX2hhc0JpbmFyeShvYmpba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBfaGFzQmluYXJ5KGRhdGEpO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuIiwiXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59OyIsIlxuLyoqXG4gKiBIT1AgcmVmLlxuICovXG5cbnZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFJldHVybiBvd24ga2V5cyBpbiBgb2JqYC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5rZXlzID0gT2JqZWN0LmtleXMgfHwgZnVuY3Rpb24ob2JqKXtcbiAgdmFyIGtleXMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIGtleXMucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ga2V5cztcbn07XG5cbi8qKlxuICogUmV0dXJuIG93biB2YWx1ZXMgaW4gYG9iamAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHJldHVybiB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMudmFsdWVzID0gZnVuY3Rpb24ob2JqKXtcbiAgdmFyIHZhbHMgPSBbXTtcbiAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgIGlmIChoYXMuY2FsbChvYmosIGtleSkpIHtcbiAgICAgIHZhbHMucHVzaChvYmpba2V5XSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWxzO1xufTtcblxuLyoqXG4gKiBNZXJnZSBgYmAgaW50byBgYWAuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBiXG4gKiBAcmV0dXJuIHtPYmplY3R9IGFcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5tZXJnZSA9IGZ1bmN0aW9uKGEsIGIpe1xuICBmb3IgKHZhciBrZXkgaW4gYikge1xuICAgIGlmIChoYXMuY2FsbChiLCBrZXkpKSB7XG4gICAgICBhW2tleV0gPSBiW2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBhO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gbGVuZ3RoIG9mIGBvYmpgLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5sZW5ndGggPSBmdW5jdGlvbihvYmope1xuICByZXR1cm4gZXhwb3J0cy5rZXlzKG9iaikubGVuZ3RoO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBgb2JqYCBpcyBlbXB0eS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmlzRW1wdHkgPSBmdW5jdGlvbihvYmope1xuICByZXR1cm4gMCA9PSBleHBvcnRzLmxlbmd0aChvYmopO1xufTsiLCIvKipcbiAqIFBhcnNlcyBhbiBVUklcbiAqXG4gKiBAYXV0aG9yIFN0ZXZlbiBMZXZpdGhhbiA8c3RldmVubGV2aXRoYW4uY29tPiAoTUlUIGxpY2Vuc2UpXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG52YXIgcmUgPSAvXig/Oig/IVteOkBdKzpbXjpAXFwvXSpAKShodHRwfGh0dHBzfHdzfHdzcyk6XFwvXFwvKT8oKD86KChbXjpAXSopKD86OihbXjpAXSopKT8pP0ApPygoPzpbYS1mMC05XXswLDR9Oil7Miw3fVthLWYwLTldezAsNH18W146XFwvPyNdKikoPzo6KFxcZCopKT8pKCgoXFwvKD86W14/I10oPyFbXj8jXFwvXSpcXC5bXj8jXFwvLl0rKD86Wz8jXXwkKSkpKlxcLz8pPyhbXj8jXFwvXSopKSg/OlxcPyhbXiNdKikpPyg/OiMoLiopKT8pLztcblxudmFyIHBhcnRzID0gW1xuICAgICdzb3VyY2UnLCAncHJvdG9jb2wnLCAnYXV0aG9yaXR5JywgJ3VzZXJJbmZvJywgJ3VzZXInLCAncGFzc3dvcmQnLCAnaG9zdCdcbiAgLCAncG9ydCcsICdyZWxhdGl2ZScsICdwYXRoJywgJ2RpcmVjdG9yeScsICdmaWxlJywgJ3F1ZXJ5JywgJ2FuY2hvcidcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2V1cmkoc3RyKSB7XG4gIHZhciBtID0gcmUuZXhlYyhzdHIgfHwgJycpXG4gICAgLCB1cmkgPSB7fVxuICAgICwgaSA9IDE0O1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICB1cmlbcGFydHNbaV1dID0gbVtpXSB8fCAnJztcbiAgfVxuXG4gIHJldHVybiB1cmk7XG59O1xuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307LypnbG9iYWwgQmxvYixGaWxlKi9cblxuLyoqXG4gKiBNb2R1bGUgcmVxdWlyZW1lbnRzXG4gKi9cblxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdpc2FycmF5Jyk7XG52YXIgaXNCdWYgPSByZXF1aXJlKCcuL2lzLWJ1ZmZlcicpO1xuXG4vKipcbiAqIFJlcGxhY2VzIGV2ZXJ5IEJ1ZmZlciB8IEFycmF5QnVmZmVyIGluIHBhY2tldCB3aXRoIGEgbnVtYmVyZWQgcGxhY2Vob2xkZXIuXG4gKiBBbnl0aGluZyB3aXRoIGJsb2JzIG9yIGZpbGVzIHNob3VsZCBiZSBmZWQgdGhyb3VnaCByZW1vdmVCbG9icyBiZWZvcmUgY29taW5nXG4gKiBoZXJlLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBzb2NrZXQuaW8gZXZlbnQgcGFja2V0XG4gKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggZGVjb25zdHJ1Y3RlZCBwYWNrZXQgYW5kIGxpc3Qgb2YgYnVmZmVyc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLmRlY29uc3RydWN0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0KXtcbiAgdmFyIGJ1ZmZlcnMgPSBbXTtcbiAgdmFyIHBhY2tldERhdGEgPSBwYWNrZXQuZGF0YTtcblxuICBmdW5jdGlvbiBfZGVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgIGlmICghZGF0YSkgcmV0dXJuIGRhdGE7XG5cbiAgICBpZiAoaXNCdWYoZGF0YSkpIHtcbiAgICAgIHZhciBwbGFjZWhvbGRlciA9IHsgX3BsYWNlaG9sZGVyOiB0cnVlLCBudW06IGJ1ZmZlcnMubGVuZ3RoIH07XG4gICAgICBidWZmZXJzLnB1c2goZGF0YSk7XG4gICAgICByZXR1cm4gcGxhY2Vob2xkZXI7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICB2YXIgbmV3RGF0YSA9IG5ldyBBcnJheShkYXRhLmxlbmd0aCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbmV3RGF0YVtpXSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXdEYXRhO1xuICAgIH0gZWxzZSBpZiAoJ29iamVjdCcgPT0gdHlwZW9mIGRhdGEgJiYgIShkYXRhIGluc3RhbmNlb2YgRGF0ZSkpIHtcbiAgICAgIHZhciBuZXdEYXRhID0ge307XG4gICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICBuZXdEYXRhW2tleV0gPSBfZGVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtrZXldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXdEYXRhO1xuICAgIH1cbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHZhciBwYWNrID0gcGFja2V0O1xuICBwYWNrLmRhdGEgPSBfZGVjb25zdHJ1Y3RQYWNrZXQocGFja2V0RGF0YSk7XG4gIHBhY2suYXR0YWNobWVudHMgPSBidWZmZXJzLmxlbmd0aDsgLy8gbnVtYmVyIG9mIGJpbmFyeSAnYXR0YWNobWVudHMnXG4gIHJldHVybiB7cGFja2V0OiBwYWNrLCBidWZmZXJzOiBidWZmZXJzfTtcbn07XG5cbi8qKlxuICogUmVjb25zdHJ1Y3RzIGEgYmluYXJ5IHBhY2tldCBmcm9tIGl0cyBwbGFjZWhvbGRlciBwYWNrZXQgYW5kIGJ1ZmZlcnNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0IC0gZXZlbnQgcGFja2V0IHdpdGggcGxhY2Vob2xkZXJzXG4gKiBAcGFyYW0ge0FycmF5fSBidWZmZXJzIC0gYmluYXJ5IGJ1ZmZlcnMgdG8gcHV0IGluIHBsYWNlaG9sZGVyIHBvc2l0aW9uc1xuICogQHJldHVybiB7T2JqZWN0fSByZWNvbnN0cnVjdGVkIHBhY2tldFxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnJlY29uc3RydWN0UGFja2V0ID0gZnVuY3Rpb24ocGFja2V0LCBidWZmZXJzKSB7XG4gIHZhciBjdXJQbGFjZUhvbGRlciA9IDA7XG5cbiAgZnVuY3Rpb24gX3JlY29uc3RydWN0UGFja2V0KGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLl9wbGFjZWhvbGRlcikge1xuICAgICAgdmFyIGJ1ZiA9IGJ1ZmZlcnNbZGF0YS5udW1dOyAvLyBhcHByb3ByaWF0ZSBidWZmZXIgKHNob3VsZCBiZSBuYXR1cmFsIG9yZGVyIGFueXdheSlcbiAgICAgIHJldHVybiBidWY7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZGF0YVtpXSA9IF9yZWNvbnN0cnVjdFBhY2tldChkYXRhW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0gZWxzZSBpZiAoZGF0YSAmJiAnb2JqZWN0JyA9PSB0eXBlb2YgZGF0YSkge1xuICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgICAgZGF0YVtrZXldID0gX3JlY29uc3RydWN0UGFja2V0KGRhdGFba2V5XSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBwYWNrZXQuZGF0YSA9IF9yZWNvbnN0cnVjdFBhY2tldChwYWNrZXQuZGF0YSk7XG4gIHBhY2tldC5hdHRhY2htZW50cyA9IHVuZGVmaW5lZDsgLy8gbm8gbG9uZ2VyIHVzZWZ1bFxuICByZXR1cm4gcGFja2V0O1xufTtcblxuLyoqXG4gKiBBc3luY2hyb25vdXNseSByZW1vdmVzIEJsb2JzIG9yIEZpbGVzIGZyb20gZGF0YSB2aWFcbiAqIEZpbGVSZWFkZXIncyByZWFkQXNBcnJheUJ1ZmZlciBtZXRob2QuIFVzZWQgYmVmb3JlIGVuY29kaW5nXG4gKiBkYXRhIGFzIG1zZ3BhY2suIENhbGxzIGNhbGxiYWNrIHdpdGggdGhlIGJsb2JsZXNzIGRhdGEuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5leHBvcnRzLnJlbW92ZUJsb2JzID0gZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2spIHtcbiAgZnVuY3Rpb24gX3JlbW92ZUJsb2JzKG9iaiwgY3VyS2V5LCBjb250YWluaW5nT2JqZWN0KSB7XG4gICAgaWYgKCFvYmopIHJldHVybiBvYmo7XG5cbiAgICAvLyBjb252ZXJ0IGFueSBibG9iXG4gICAgaWYgKChnbG9iYWwuQmxvYiAmJiBvYmogaW5zdGFuY2VvZiBCbG9iKSB8fFxuICAgICAgICAoZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSkpIHtcbiAgICAgIHBlbmRpbmdCbG9icysrO1xuXG4gICAgICAvLyBhc3luYyBmaWxlcmVhZGVyXG4gICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKCkgeyAvLyB0aGlzLnJlc3VsdCA9PSBhcnJheWJ1ZmZlclxuICAgICAgICBpZiAoY29udGFpbmluZ09iamVjdCkge1xuICAgICAgICAgIGNvbnRhaW5pbmdPYmplY3RbY3VyS2V5XSA9IHRoaXMucmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGJsb2JsZXNzRGF0YSA9IHRoaXMucmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgbm90aGluZyBwZW5kaW5nIGl0cyBjYWxsYmFjayB0aW1lXG4gICAgICAgIGlmKCEgLS1wZW5kaW5nQmxvYnMpIHtcbiAgICAgICAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKG9iaik7IC8vIGJsb2IgLT4gYXJyYXlidWZmZXJcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkob2JqKSkgeyAvLyBoYW5kbGUgYXJyYXlcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIF9yZW1vdmVCbG9icyhvYmpbaV0sIGksIG9iaik7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvYmogJiYgJ29iamVjdCcgPT0gdHlwZW9mIG9iaiAmJiAhaXNCdWYob2JqKSkgeyAvLyBhbmQgb2JqZWN0XG4gICAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICAgIF9yZW1vdmVCbG9icyhvYmpba2V5XSwga2V5LCBvYmopO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhciBwZW5kaW5nQmxvYnMgPSAwO1xuICB2YXIgYmxvYmxlc3NEYXRhID0gZGF0YTtcbiAgX3JlbW92ZUJsb2JzKGJsb2JsZXNzRGF0YSk7XG4gIGlmICghcGVuZGluZ0Jsb2JzKSB7XG4gICAgY2FsbGJhY2soYmxvYmxlc3NEYXRhKTtcbiAgfVxufTtcbiIsIlxuLyoqXG4gKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICovXG5cbnZhciBkZWJ1ZyA9IHJlcXVpcmUoJ2RlYnVnJykoJ3NvY2tldC5pby1wYXJzZXInKTtcbnZhciBqc29uID0gcmVxdWlyZSgnanNvbjMnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnaXNhcnJheScpO1xudmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdjb21wb25lbnQtZW1pdHRlcicpO1xudmFyIGJpbmFyeSA9IHJlcXVpcmUoJy4vYmluYXJ5Jyk7XG52YXIgaXNCdWYgPSByZXF1aXJlKCcuL2lzLWJ1ZmZlcicpO1xuXG4vKipcbiAqIFByb3RvY29sIHZlcnNpb24uXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnByb3RvY29sID0gNDtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZXMuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLnR5cGVzID0gW1xuICAnQ09OTkVDVCcsXG4gICdESVNDT05ORUNUJyxcbiAgJ0VWRU5UJyxcbiAgJ0JJTkFSWV9FVkVOVCcsXG4gICdBQ0snLFxuICAnQklOQVJZX0FDSycsXG4gICdFUlJPUidcbl07XG5cbi8qKlxuICogUGFja2V0IHR5cGUgYGNvbm5lY3RgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5DT05ORUNUID0gMDtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZGlzY29ubmVjdGAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkRJU0NPTk5FQ1QgPSAxO1xuXG4vKipcbiAqIFBhY2tldCB0eXBlIGBldmVudGAuXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5leHBvcnRzLkVWRU5UID0gMjtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgYWNrYC5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQUNLID0gMztcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgZXJyb3JgLlxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZXhwb3J0cy5FUlJPUiA9IDQ7XG5cbi8qKlxuICogUGFja2V0IHR5cGUgJ2JpbmFyeSBldmVudCdcbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQklOQVJZX0VWRU5UID0gNTtcblxuLyoqXG4gKiBQYWNrZXQgdHlwZSBgYmluYXJ5IGFja2AuIEZvciBhY2tzIHdpdGggYmluYXJ5IGFyZ3VtZW50cy5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuQklOQVJZX0FDSyA9IDY7XG5cbi8qKlxuICogRW5jb2RlciBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRW5jb2RlciA9IEVuY29kZXI7XG5cbi8qKlxuICogRGVjb2RlciBjb25zdHJ1Y3Rvci5cbiAqXG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmV4cG9ydHMuRGVjb2RlciA9IERlY29kZXI7XG5cbi8qKlxuICogQSBzb2NrZXQuaW8gRW5jb2RlciBpbnN0YW5jZVxuICpcbiAqIEBhcGkgcHVibGljXG4gKi9cblxuZnVuY3Rpb24gRW5jb2RlcigpIHt9XG5cbi8qKlxuICogRW5jb2RlIGEgcGFja2V0IGFzIGEgc2luZ2xlIHN0cmluZyBpZiBub24tYmluYXJ5LCBvciBhcyBhXG4gKiBidWZmZXIgc2VxdWVuY2UsIGRlcGVuZGluZyBvbiBwYWNrZXQgdHlwZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqIC0gcGFja2V0IG9iamVjdFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBmdW5jdGlvbiB0byBoYW5kbGUgZW5jb2RpbmdzIChsaWtlbHkgZW5naW5lLndyaXRlKVxuICogQHJldHVybiBDYWxscyBjYWxsYmFjayB3aXRoIEFycmF5IG9mIGVuY29kaW5nc1xuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5FbmNvZGVyLnByb3RvdHlwZS5lbmNvZGUgPSBmdW5jdGlvbihvYmosIGNhbGxiYWNrKXtcbiAgZGVidWcoJ2VuY29kaW5nIHBhY2tldCAlaicsIG9iaik7XG5cbiAgaWYgKGV4cG9ydHMuQklOQVJZX0VWRU5UID09IG9iai50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBvYmoudHlwZSkge1xuICAgIGVuY29kZUFzQmluYXJ5KG9iaiwgY2FsbGJhY2spO1xuICB9XG4gIGVsc2Uge1xuICAgIHZhciBlbmNvZGluZyA9IGVuY29kZUFzU3RyaW5nKG9iaik7XG4gICAgY2FsbGJhY2soW2VuY29kaW5nXSk7XG4gIH1cbn07XG5cbi8qKlxuICogRW5jb2RlIHBhY2tldCBhcyBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICogQHJldHVybiB7U3RyaW5nfSBlbmNvZGVkXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBlbmNvZGVBc1N0cmluZyhvYmopIHtcbiAgdmFyIHN0ciA9ICcnO1xuICB2YXIgbnNwID0gZmFsc2U7XG5cbiAgLy8gZmlyc3QgaXMgdHlwZVxuICBzdHIgKz0gb2JqLnR5cGU7XG5cbiAgLy8gYXR0YWNobWVudHMgaWYgd2UgaGF2ZSB0aGVtXG4gIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICBzdHIgKz0gb2JqLmF0dGFjaG1lbnRzO1xuICAgIHN0ciArPSAnLSc7XG4gIH1cblxuICAvLyBpZiB3ZSBoYXZlIGEgbmFtZXNwYWNlIG90aGVyIHRoYW4gYC9gXG4gIC8vIHdlIGFwcGVuZCBpdCBmb2xsb3dlZCBieSBhIGNvbW1hIGAsYFxuICBpZiAob2JqLm5zcCAmJiAnLycgIT0gb2JqLm5zcCkge1xuICAgIG5zcCA9IHRydWU7XG4gICAgc3RyICs9IG9iai5uc3A7XG4gIH1cblxuICAvLyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSB0aGUgaWRcbiAgaWYgKG51bGwgIT0gb2JqLmlkKSB7XG4gICAgaWYgKG5zcCkge1xuICAgICAgc3RyICs9ICcsJztcbiAgICAgIG5zcCA9IGZhbHNlO1xuICAgIH1cbiAgICBzdHIgKz0gb2JqLmlkO1xuICB9XG5cbiAgLy8ganNvbiBkYXRhXG4gIGlmIChudWxsICE9IG9iai5kYXRhKSB7XG4gICAgaWYgKG5zcCkgc3RyICs9ICcsJztcbiAgICBzdHIgKz0ganNvbi5zdHJpbmdpZnkob2JqLmRhdGEpO1xuICB9XG5cbiAgZGVidWcoJ2VuY29kZWQgJWogYXMgJXMnLCBvYmosIHN0cik7XG4gIHJldHVybiBzdHI7XG59XG5cbi8qKlxuICogRW5jb2RlIHBhY2tldCBhcyAnYnVmZmVyIHNlcXVlbmNlJyBieSByZW1vdmluZyBibG9icywgYW5kXG4gKiBkZWNvbnN0cnVjdGluZyBwYWNrZXQgaW50byBvYmplY3Qgd2l0aCBwbGFjZWhvbGRlcnMgYW5kXG4gKiBhIGxpc3Qgb2YgYnVmZmVycy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcGFja2V0XG4gKiBAcmV0dXJuIHtCdWZmZXJ9IGVuY29kZWRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGVuY29kZUFzQmluYXJ5KG9iaiwgY2FsbGJhY2spIHtcblxuICBmdW5jdGlvbiB3cml0ZUVuY29kaW5nKGJsb2JsZXNzRGF0YSkge1xuICAgIHZhciBkZWNvbnN0cnVjdGlvbiA9IGJpbmFyeS5kZWNvbnN0cnVjdFBhY2tldChibG9ibGVzc0RhdGEpO1xuICAgIHZhciBwYWNrID0gZW5jb2RlQXNTdHJpbmcoZGVjb25zdHJ1Y3Rpb24ucGFja2V0KTtcbiAgICB2YXIgYnVmZmVycyA9IGRlY29uc3RydWN0aW9uLmJ1ZmZlcnM7XG5cbiAgICBidWZmZXJzLnVuc2hpZnQocGFjayk7IC8vIGFkZCBwYWNrZXQgaW5mbyB0byBiZWdpbm5pbmcgb2YgZGF0YSBsaXN0XG4gICAgY2FsbGJhY2soYnVmZmVycyk7IC8vIHdyaXRlIGFsbCB0aGUgYnVmZmVyc1xuICB9XG5cbiAgYmluYXJ5LnJlbW92ZUJsb2JzKG9iaiwgd3JpdGVFbmNvZGluZyk7XG59XG5cbi8qKlxuICogQSBzb2NrZXQuaW8gRGVjb2RlciBpbnN0YW5jZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZGVjb2RlclxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBEZWNvZGVyKCkge1xuICB0aGlzLnJlY29uc3RydWN0b3IgPSBudWxsO1xufVxuXG4vKipcbiAqIE1peCBpbiBgRW1pdHRlcmAgd2l0aCBEZWNvZGVyLlxuICovXG5cbkVtaXR0ZXIoRGVjb2Rlci5wcm90b3R5cGUpO1xuXG4vKipcbiAqIERlY29kZXMgYW4gZWNvZGVkIHBhY2tldCBzdHJpbmcgaW50byBwYWNrZXQgSlNPTi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gb2JqIC0gZW5jb2RlZCBwYWNrZXRcbiAqIEByZXR1cm4ge09iamVjdH0gcGFja2V0XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkRlY29kZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKG9iaikge1xuICB2YXIgcGFja2V0O1xuICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIG9iaikge1xuICAgIHBhY2tldCA9IGRlY29kZVN0cmluZyhvYmopO1xuICAgIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBwYWNrZXQudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gcGFja2V0LnR5cGUpIHsgLy8gYmluYXJ5IHBhY2tldCdzIGpzb25cbiAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG5ldyBCaW5hcnlSZWNvbnN0cnVjdG9yKHBhY2tldCk7XG5cbiAgICAgIC8vIG5vIGF0dGFjaG1lbnRzLCBsYWJlbGVkIGJpbmFyeSBidXQgbm8gYmluYXJ5IGRhdGEgdG8gZm9sbG93XG4gICAgICBpZiAodGhpcy5yZWNvbnN0cnVjdG9yLnJlY29uUGFjay5hdHRhY2htZW50cyA9PSAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHsgLy8gbm9uLWJpbmFyeSBmdWxsIHBhY2tldFxuICAgICAgdGhpcy5lbWl0KCdkZWNvZGVkJywgcGFja2V0KTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoaXNCdWYob2JqKSB8fCBvYmouYmFzZTY0KSB7IC8vIHJhdyBiaW5hcnkgZGF0YVxuICAgIGlmICghdGhpcy5yZWNvbnN0cnVjdG9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2dvdCBiaW5hcnkgZGF0YSB3aGVuIG5vdCByZWNvbnN0cnVjdGluZyBhIHBhY2tldCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwYWNrZXQgPSB0aGlzLnJlY29uc3RydWN0b3IudGFrZUJpbmFyeURhdGEob2JqKTtcbiAgICAgIGlmIChwYWNrZXQpIHsgLy8gcmVjZWl2ZWQgZmluYWwgYnVmZmVyXG4gICAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biB0eXBlOiAnICsgb2JqKTtcbiAgfVxufTtcblxuLyoqXG4gKiBEZWNvZGUgYSBwYWNrZXQgU3RyaW5nIChKU09OIGRhdGEpXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICogQHJldHVybiB7T2JqZWN0fSBwYWNrZXRcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIGRlY29kZVN0cmluZyhzdHIpIHtcbiAgdmFyIHAgPSB7fTtcbiAgdmFyIGkgPSAwO1xuXG4gIC8vIGxvb2sgdXAgdHlwZVxuICBwLnR5cGUgPSBOdW1iZXIoc3RyLmNoYXJBdCgwKSk7XG4gIGlmIChudWxsID09IGV4cG9ydHMudHlwZXNbcC50eXBlXSkgcmV0dXJuIGVycm9yKCk7XG5cbiAgLy8gbG9vayB1cCBhdHRhY2htZW50cyBpZiB0eXBlIGJpbmFyeVxuICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcC50eXBlIHx8IGV4cG9ydHMuQklOQVJZX0FDSyA9PSBwLnR5cGUpIHtcbiAgICBwLmF0dGFjaG1lbnRzID0gJyc7XG4gICAgd2hpbGUgKHN0ci5jaGFyQXQoKytpKSAhPSAnLScpIHtcbiAgICAgIHAuYXR0YWNobWVudHMgKz0gc3RyLmNoYXJBdChpKTtcbiAgICB9XG4gICAgcC5hdHRhY2htZW50cyA9IE51bWJlcihwLmF0dGFjaG1lbnRzKTtcbiAgfVxuXG4gIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gIGlmICgnLycgPT0gc3RyLmNoYXJBdChpICsgMSkpIHtcbiAgICBwLm5zcCA9ICcnO1xuICAgIHdoaWxlICgrK2kpIHtcbiAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgIGlmICgnLCcgPT0gYykgYnJlYWs7XG4gICAgICBwLm5zcCArPSBjO1xuICAgICAgaWYgKGkgKyAxID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBwLm5zcCA9ICcvJztcbiAgfVxuXG4gIC8vIGxvb2sgdXAgaWRcbiAgdmFyIG5leHQgPSBzdHIuY2hhckF0KGkgKyAxKTtcbiAgaWYgKCcnICE9IG5leHQgJiYgTnVtYmVyKG5leHQpID09IG5leHQpIHtcbiAgICBwLmlkID0gJyc7XG4gICAgd2hpbGUgKCsraSkge1xuICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAtLWk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgcC5pZCArPSBzdHIuY2hhckF0KGkpO1xuICAgICAgaWYgKGkgKyAxID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgIH1cbiAgICBwLmlkID0gTnVtYmVyKHAuaWQpO1xuICB9XG5cbiAgLy8gbG9vayB1cCBqc29uIGRhdGFcbiAgaWYgKHN0ci5jaGFyQXQoKytpKSkge1xuICAgIHRyeSB7XG4gICAgICBwLmRhdGEgPSBqc29uLnBhcnNlKHN0ci5zdWJzdHIoaSkpO1xuICAgIH0gY2F0Y2goZSl7XG4gICAgICByZXR1cm4gZXJyb3IoKTtcbiAgICB9XG4gIH1cblxuICBkZWJ1ZygnZGVjb2RlZCAlcyBhcyAlaicsIHN0ciwgcCk7XG4gIHJldHVybiBwO1xufVxuXG4vKipcbiAqIERlYWxsb2NhdGVzIGEgcGFyc2VyJ3MgcmVzb3VyY2VzXG4gKlxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5EZWNvZGVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICB0aGlzLnJlY29uc3RydWN0b3IuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICB9XG59O1xuXG4vKipcbiAqIEEgbWFuYWdlciBvZiBhIGJpbmFyeSBldmVudCdzICdidWZmZXIgc2VxdWVuY2UnLiBTaG91bGRcbiAqIGJlIGNvbnN0cnVjdGVkIHdoZW5ldmVyIGEgcGFja2V0IG9mIHR5cGUgQklOQVJZX0VWRU5UIGlzXG4gKiBkZWNvZGVkLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAqIEByZXR1cm4ge0JpbmFyeVJlY29uc3RydWN0b3J9IGluaXRpYWxpemVkIHJlY29uc3RydWN0b3JcbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIEJpbmFyeVJlY29uc3RydWN0b3IocGFja2V0KSB7XG4gIHRoaXMucmVjb25QYWNrID0gcGFja2V0O1xuICB0aGlzLmJ1ZmZlcnMgPSBbXTtcbn1cblxuLyoqXG4gKiBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYmluYXJ5IGRhdGEgcmVjZWl2ZWQgZnJvbSBjb25uZWN0aW9uXG4gKiBhZnRlciBhIEJJTkFSWV9FVkVOVCBwYWNrZXQuXG4gKlxuICogQHBhcmFtIHtCdWZmZXIgfCBBcnJheUJ1ZmZlcn0gYmluRGF0YSAtIHRoZSByYXcgYmluYXJ5IGRhdGEgcmVjZWl2ZWRcbiAqIEByZXR1cm4ge251bGwgfCBPYmplY3R9IHJldHVybnMgbnVsbCBpZiBtb3JlIGJpbmFyeSBkYXRhIGlzIGV4cGVjdGVkIG9yXG4gKiAgIGEgcmVjb25zdHJ1Y3RlZCBwYWNrZXQgb2JqZWN0IGlmIGFsbCBidWZmZXJzIGhhdmUgYmVlbiByZWNlaXZlZC5cbiAqIEBhcGkgcHJpdmF0ZVxuICovXG5cbkJpbmFyeVJlY29uc3RydWN0b3IucHJvdG90eXBlLnRha2VCaW5hcnlEYXRhID0gZnVuY3Rpb24oYmluRGF0YSkge1xuICB0aGlzLmJ1ZmZlcnMucHVzaChiaW5EYXRhKTtcbiAgaWYgKHRoaXMuYnVmZmVycy5sZW5ndGggPT0gdGhpcy5yZWNvblBhY2suYXR0YWNobWVudHMpIHsgLy8gZG9uZSB3aXRoIGJ1ZmZlciBsaXN0XG4gICAgdmFyIHBhY2tldCA9IGJpbmFyeS5yZWNvbnN0cnVjdFBhY2tldCh0aGlzLnJlY29uUGFjaywgdGhpcy5idWZmZXJzKTtcbiAgICB0aGlzLmZpbmlzaGVkUmVjb25zdHJ1Y3Rpb24oKTtcbiAgICByZXR1cm4gcGFja2V0O1xuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxuLyoqXG4gKiBDbGVhbnMgdXAgYmluYXJ5IHBhY2tldCByZWNvbnN0cnVjdGlvbiB2YXJpYWJsZXMuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQmluYXJ5UmVjb25zdHJ1Y3Rvci5wcm90b3R5cGUuZmluaXNoZWRSZWNvbnN0cnVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnJlY29uUGFjayA9IG51bGw7XG4gIHRoaXMuYnVmZmVycyA9IFtdO1xufTtcblxuZnVuY3Rpb24gZXJyb3IoZGF0YSl7XG4gIHJldHVybiB7XG4gICAgdHlwZTogZXhwb3J0cy5FUlJPUixcbiAgICBkYXRhOiAncGFyc2VyIGVycm9yJ1xuICB9O1xufVxuIiwidmFyIGdsb2JhbD10eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge307XG5tb2R1bGUuZXhwb3J0cyA9IGlzQnVmO1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiBvYmogaXMgYSBidWZmZXIgb3IgYW4gYXJyYXlidWZmZXIuXG4gKlxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuZnVuY3Rpb24gaXNCdWYob2JqKSB7XG4gIHJldHVybiAoZ2xvYmFsLkJ1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikpIHx8XG4gICAgICAgICAoZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKTtcbn1cbiIsIi8qISBKU09OIHYzLjIuNiB8IGh0dHA6Ly9iZXN0aWVqcy5naXRodWIuaW8vanNvbjMgfCBDb3B5cmlnaHQgMjAxMi0yMDEzLCBLaXQgQ2FtYnJpZGdlIHwgaHR0cDovL2tpdC5taXQtbGljZW5zZS5vcmcgKi9cbjsoZnVuY3Rpb24gKHdpbmRvdykge1xuICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLlxuICB2YXIgZ2V0Q2xhc3MgPSB7fS50b1N0cmluZywgaXNQcm9wZXJ0eSwgZm9yRWFjaCwgdW5kZWY7XG5cbiAgLy8gRGV0ZWN0IHRoZSBgZGVmaW5lYCBmdW5jdGlvbiBleHBvc2VkIGJ5IGFzeW5jaHJvbm91cyBtb2R1bGUgbG9hZGVycy4gVGhlXG4gIC8vIHN0cmljdCBgZGVmaW5lYCBjaGVjayBpcyBuZWNlc3NhcnkgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBgci5qc2AuXG4gIHZhciBpc0xvYWRlciA9IHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kO1xuXG4gIC8vIERldGVjdCBuYXRpdmUgaW1wbGVtZW50YXRpb25zLlxuICB2YXIgbmF0aXZlSlNPTiA9IHR5cGVvZiBKU09OID09IFwib2JqZWN0XCIgJiYgSlNPTjtcblxuICAvLyBTZXQgdXAgdGhlIEpTT04gMyBuYW1lc3BhY2UsIHByZWZlcnJpbmcgdGhlIENvbW1vbkpTIGBleHBvcnRzYCBvYmplY3QgaWZcbiAgLy8gYXZhaWxhYmxlLlxuICB2YXIgSlNPTjMgPSB0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIGV4cG9ydHMgJiYgIWV4cG9ydHMubm9kZVR5cGUgJiYgZXhwb3J0cztcblxuICBpZiAoSlNPTjMgJiYgbmF0aXZlSlNPTikge1xuICAgIC8vIEV4cGxpY2l0bHkgZGVsZWdhdGUgdG8gdGhlIG5hdGl2ZSBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAgIC8vIGltcGxlbWVudGF0aW9ucyBpbiBDb21tb25KUyBlbnZpcm9ubWVudHMuXG4gICAgSlNPTjMuc3RyaW5naWZ5ID0gbmF0aXZlSlNPTi5zdHJpbmdpZnk7XG4gICAgSlNPTjMucGFyc2UgPSBuYXRpdmVKU09OLnBhcnNlO1xuICB9IGVsc2Uge1xuICAgIC8vIEV4cG9ydCBmb3Igd2ViIGJyb3dzZXJzLCBKYXZhU2NyaXB0IGVuZ2luZXMsIGFuZCBhc3luY2hyb25vdXMgbW9kdWxlXG4gICAgLy8gbG9hZGVycywgdXNpbmcgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGlmIGF2YWlsYWJsZS5cbiAgICBKU09OMyA9IHdpbmRvdy5KU09OID0gbmF0aXZlSlNPTiB8fCB7fTtcbiAgfVxuXG4gIC8vIFRlc3QgdGhlIGBEYXRlI2dldFVUQypgIG1ldGhvZHMuIEJhc2VkIG9uIHdvcmsgYnkgQFlhZmZsZS5cbiAgdmFyIGlzRXh0ZW5kZWQgPSBuZXcgRGF0ZSgtMzUwOTgyNzMzNDU3MzI5Mik7XG4gIHRyeSB7XG4gICAgLy8gVGhlIGBnZXRVVENGdWxsWWVhcmAsIGBNb250aGAsIGFuZCBgRGF0ZWAgbWV0aG9kcyByZXR1cm4gbm9uc2Vuc2ljYWxcbiAgICAvLyByZXN1bHRzIGZvciBjZXJ0YWluIGRhdGVzIGluIE9wZXJhID49IDEwLjUzLlxuICAgIGlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkLmdldFVUQ0Z1bGxZZWFyKCkgPT0gLTEwOTI1MiAmJiBpc0V4dGVuZGVkLmdldFVUQ01vbnRoKCkgPT09IDAgJiYgaXNFeHRlbmRlZC5nZXRVVENEYXRlKCkgPT09IDEgJiZcbiAgICAgIC8vIFNhZmFyaSA8IDIuMC4yIHN0b3JlcyB0aGUgaW50ZXJuYWwgbWlsbGlzZWNvbmQgdGltZSB2YWx1ZSBjb3JyZWN0bHksXG4gICAgICAvLyBidXQgY2xpcHMgdGhlIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgZGF0ZSBtZXRob2RzIHRvIHRoZSByYW5nZSBvZlxuICAgICAgLy8gc2lnbmVkIDMyLWJpdCBpbnRlZ2VycyAoWy0yICoqIDMxLCAyICoqIDMxIC0gMV0pLlxuICAgICAgaXNFeHRlbmRlZC5nZXRVVENIb3VycygpID09IDEwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDTWludXRlcygpID09IDM3ICYmIGlzRXh0ZW5kZWQuZ2V0VVRDU2Vjb25kcygpID09IDYgJiYgaXNFeHRlbmRlZC5nZXRVVENNaWxsaXNlY29uZHMoKSA9PSA3MDg7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cblxuICAvLyBJbnRlcm5hbDogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBuYXRpdmUgYEpTT04uc3RyaW5naWZ5YCBhbmQgYHBhcnNlYFxuICAvLyBpbXBsZW1lbnRhdGlvbnMgYXJlIHNwZWMtY29tcGxpYW50LiBCYXNlZCBvbiB3b3JrIGJ5IEtlbiBTbnlkZXIuXG4gIGZ1bmN0aW9uIGhhcyhuYW1lKSB7XG4gICAgaWYgKGhhc1tuYW1lXSAhPT0gdW5kZWYpIHtcbiAgICAgIC8vIFJldHVybiBjYWNoZWQgZmVhdHVyZSB0ZXN0IHJlc3VsdC5cbiAgICAgIHJldHVybiBoYXNbbmFtZV07XG4gICAgfVxuXG4gICAgdmFyIGlzU3VwcG9ydGVkO1xuICAgIGlmIChuYW1lID09IFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpIHtcbiAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmVcbiAgICAgIC8vIGJyYWNrZXQgbm90YXRpb24uIElFIDggb25seSBzdXBwb3J0cyB0aGlzIGZvciBwcmltaXRpdmVzLlxuICAgICAgaXNTdXBwb3J0ZWQgPSBcImFcIlswXSAhPSBcImFcIjtcbiAgICB9IGVsc2UgaWYgKG5hbWUgPT0gXCJqc29uXCIpIHtcbiAgICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGJvdGggYEpTT04uc3RyaW5naWZ5YCBhbmQgYEpTT04ucGFyc2VgIGFyZVxuICAgICAgLy8gc3VwcG9ydGVkLlxuICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSAmJiBoYXMoXCJqc29uLXBhcnNlXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdmFsdWUsIHNlcmlhbGl6ZWQgPSAne1wiYVwiOlsxLHRydWUsZmFsc2UsbnVsbCxcIlxcXFx1MDAwMFxcXFxiXFxcXG5cXFxcZlxcXFxyXFxcXHRcIl19JztcbiAgICAgIC8vIFRlc3QgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgIGlmIChuYW1lID09IFwianNvbi1zdHJpbmdpZnlcIikge1xuICAgICAgICB2YXIgc3RyaW5naWZ5ID0gSlNPTjMuc3RyaW5naWZ5LCBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09IFwiZnVuY3Rpb25cIiAmJiBpc0V4dGVuZGVkO1xuICAgICAgICBpZiAoc3RyaW5naWZ5U3VwcG9ydGVkKSB7XG4gICAgICAgICAgLy8gQSB0ZXN0IGZ1bmN0aW9uIG9iamVjdCB3aXRoIGEgY3VzdG9tIGB0b0pTT05gIG1ldGhvZC5cbiAgICAgICAgICAodmFsdWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KS50b0pTT04gPSB2YWx1ZTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID1cbiAgICAgICAgICAgICAgLy8gRmlyZWZveCAzLjFiMSBhbmQgYjIgc2VyaWFsaXplIHN0cmluZywgbnVtYmVyLCBhbmQgYm9vbGVhblxuICAgICAgICAgICAgICAvLyBwcmltaXRpdmVzIGFzIG9iamVjdCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KDApID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIsIGFuZCBKU09OIDIgc2VyaWFsaXplIHdyYXBwZWQgcHJpbWl0aXZlcyBhcyBvYmplY3RcbiAgICAgICAgICAgICAgLy8gbGl0ZXJhbHMuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShuZXcgTnVtYmVyKCkpID09PSBcIjBcIiAmJlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IFN0cmluZygpKSA9PSAnXCJcIicgJiZcbiAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHZhbHVlIGlzIGBudWxsYCwgYHVuZGVmaW5lZGAsIG9yXG4gICAgICAgICAgICAgIC8vIGRvZXMgbm90IGRlZmluZSBhIGNhbm9uaWNhbCBKU09OIHJlcHJlc2VudGF0aW9uICh0aGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGB0b0pTT05gIHByb3BlcnRpZXMgYXMgd2VsbCwgKnVubGVzcyogdGhleSBhcmUgbmVzdGVkXG4gICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvYmplY3Qgb3IgYXJyYXkpLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkoZ2V0Q2xhc3MpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBJRSA4IHNlcmlhbGl6ZXMgYHVuZGVmaW5lZGAgYXMgYFwidW5kZWZpbmVkXCJgLiBTYWZhcmkgPD0gNS4xLjcgYW5kXG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIzIHBhc3MgdGhpcyB0ZXN0LlxuICAgICAgICAgICAgICBzdHJpbmdpZnkodW5kZWYpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjcgYW5kIEZGIDMuMWIzIHRocm93IGBFcnJvcmBzIGFuZCBgVHlwZUVycm9yYHMsXG4gICAgICAgICAgICAgIC8vIHJlc3BlY3RpdmVseSwgaWYgdGhlIHZhbHVlIGlzIG9taXR0ZWQgZW50aXJlbHkuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeSgpID09PSB1bmRlZiAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgbm90IGEgbnVtYmVyLFxuICAgICAgICAgICAgICAvLyBzdHJpbmcsIGFycmF5LCBvYmplY3QsIEJvb2xlYW4sIG9yIGBudWxsYCBsaXRlcmFsLiBUaGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgLy8gb2JqZWN0cyB3aXRoIGN1c3RvbSBgdG9KU09OYCBtZXRob2RzIGFzIHdlbGwsIHVubGVzcyB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgLy8gaW5zaWRlIG9iamVjdCBvciBhcnJheSBsaXRlcmFscy4gWVVJIDMuMC4wYjEgaWdub3JlcyBjdXN0b20gYHRvSlNPTmBcbiAgICAgICAgICAgICAgLy8gbWV0aG9kcyBlbnRpcmVseS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KHZhbHVlKSA9PT0gXCIxXCIgJiZcbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt2YWx1ZV0pID09IFwiWzFdXCIgJiZcbiAgICAgICAgICAgICAgLy8gUHJvdG90eXBlIDw9IDEuNi4xIHNlcmlhbGl6ZXMgYFt1bmRlZmluZWRdYCBhcyBgXCJbXVwiYCBpbnN0ZWFkIG9mXG4gICAgICAgICAgICAgIC8vIGBcIltudWxsXVwiYC5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZl0pID09IFwiW251bGxdXCIgJiZcbiAgICAgICAgICAgICAgLy8gWVVJIDMuMC4wYjEgZmFpbHMgdG8gc2VyaWFsaXplIGBudWxsYCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwpID09IFwibnVsbFwiICYmXG4gICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIGhhbHRzIHNlcmlhbGl6YXRpb24gaWYgYW4gYXJyYXkgY29udGFpbnMgYSBmdW5jdGlvbjpcbiAgICAgICAgICAgICAgLy8gYFsxLCB0cnVlLCBnZXRDbGFzcywgMV1gIHNlcmlhbGl6ZXMgYXMgXCJbMSx0cnVlLF0sXCIuIEZGIDMuMWIzXG4gICAgICAgICAgICAgIC8vIGVsaWRlcyBub24tSlNPTiB2YWx1ZXMgZnJvbSBvYmplY3RzIGFuZCBhcnJheXMsIHVubGVzcyB0aGV5XG4gICAgICAgICAgICAgIC8vIGRlZmluZSBjdXN0b20gYHRvSlNPTmAgbWV0aG9kcy5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KFt1bmRlZiwgZ2V0Q2xhc3MsIG51bGxdKSA9PSBcIltudWxsLG51bGwsbnVsbF1cIiAmJlxuICAgICAgICAgICAgICAvLyBTaW1wbGUgc2VyaWFsaXphdGlvbiB0ZXN0LiBGRiAzLjFiMSB1c2VzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlc1xuICAgICAgICAgICAgICAvLyB3aGVyZSBjaGFyYWN0ZXIgZXNjYXBlIGNvZGVzIGFyZSBleHBlY3RlZCAoZS5nLiwgYFxcYmAgPT4gYFxcdTAwMDhgKS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KHsgXCJhXCI6IFt2YWx1ZSwgdHJ1ZSwgZmFsc2UsIG51bGwsIFwiXFx4MDBcXGJcXG5cXGZcXHJcXHRcIl0gfSkgPT0gc2VyaWFsaXplZCAmJlxuICAgICAgICAgICAgICAvLyBGRiAzLjFiMSBhbmQgYjIgaWdub3JlIHRoZSBgZmlsdGVyYCBhbmQgYHdpZHRoYCBhcmd1bWVudHMuXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShudWxsLCB2YWx1ZSkgPT09IFwiMVwiICYmXG4gICAgICAgICAgICAgIHN0cmluZ2lmeShbMSwgMl0sIG51bGwsIDEpID09IFwiW1xcbiAxLFxcbiAyXFxuXVwiICYmXG4gICAgICAgICAgICAgIC8vIEpTT04gMiwgUHJvdG90eXBlIDw9IDEuNywgYW5kIG9sZGVyIFdlYktpdCBidWlsZHMgaW5jb3JyZWN0bHlcbiAgICAgICAgICAgICAgLy8gc2VyaWFsaXplIGV4dGVuZGVkIHllYXJzLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTguNjRlMTUpKSA9PSAnXCItMjcxODIxLTA0LTIwVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgLy8gVGhlIG1pbGxpc2Vjb25kcyBhcmUgb3B0aW9uYWwgaW4gRVMgNSwgYnV0IHJlcXVpcmVkIGluIDUuMS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKDguNjRlMTUpKSA9PSAnXCIrMjc1NzYwLTA5LTEzVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgLy8gRmlyZWZveCA8PSAxMS4wIGluY29ycmVjdGx5IHNlcmlhbGl6ZXMgeWVhcnMgcHJpb3IgdG8gMCBhcyBuZWdhdGl2ZVxuICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IHllYXJzIGluc3RlYWQgb2Ygc2l4LWRpZ2l0IHllYXJzLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTYyMTk4NzU1MmU1KSkgPT0gJ1wiLTAwMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNSBhbmQgT3BlcmEgPj0gMTAuNTMgaW5jb3JyZWN0bHkgc2VyaWFsaXplIG1pbGxpc2Vjb25kXG4gICAgICAgICAgICAgIC8vIHZhbHVlcyBsZXNzIHRoYW4gMTAwMC4gQ3JlZGl0czogQFlhZmZsZS5cbiAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC0xKSkgPT0gJ1wiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaXCInO1xuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlzU3VwcG9ydGVkID0gc3RyaW5naWZ5U3VwcG9ydGVkO1xuICAgICAgfVxuICAgICAgLy8gVGVzdCBgSlNPTi5wYXJzZWAuXG4gICAgICBpZiAobmFtZSA9PSBcImpzb24tcGFyc2VcIikge1xuICAgICAgICB2YXIgcGFyc2UgPSBKU09OMy5wYXJzZTtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJzZSA9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRkYgMy4xYjEsIGIyIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGEgYmFyZSBsaXRlcmFsIGlzIHByb3ZpZGVkLlxuICAgICAgICAgICAgLy8gQ29uZm9ybWluZyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIGFsc28gY29lcmNlIHRoZSBpbml0aWFsIGFyZ3VtZW50IHRvXG4gICAgICAgICAgICAvLyBhIHN0cmluZyBwcmlvciB0byBwYXJzaW5nLlxuICAgICAgICAgICAgaWYgKHBhcnNlKFwiMFwiKSA9PT0gMCAmJiAhcGFyc2UoZmFsc2UpKSB7XG4gICAgICAgICAgICAgIC8vIFNpbXBsZSBwYXJzaW5nIHRlc3QuXG4gICAgICAgICAgICAgIHZhbHVlID0gcGFyc2Uoc2VyaWFsaXplZCk7XG4gICAgICAgICAgICAgIHZhciBwYXJzZVN1cHBvcnRlZCA9IHZhbHVlW1wiYVwiXS5sZW5ndGggPT0gNSAmJiB2YWx1ZVtcImFcIl1bMF0gPT09IDE7XG4gICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjIgYW5kIEZGIDMuMWIxIGFsbG93IHVuZXNjYXBlZCB0YWJzIGluIHN0cmluZ3MuXG4gICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9ICFwYXJzZSgnXCJcXHRcIicpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge31cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCBhbmQgNC4wLjEgYWxsb3cgbGVhZGluZyBgK2Agc2lnbnMgYW5kIGxlYWRpbmdcbiAgICAgICAgICAgICAgICAgICAgLy8gZGVjaW1hbCBwb2ludHMuIEZGIDQuMCwgNC4wLjEsIGFuZCBJRSA5LTEwIGFsc28gYWxsb3dcbiAgICAgICAgICAgICAgICAgICAgLy8gY2VydGFpbiBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjAxXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocGFyc2VTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZGIDQuMCwgNC4wLjEsIGFuZCBSaGlubyAxLjdSMy1SNCBhbGxvdyB0cmFpbGluZyBkZWNpbWFsXG4gICAgICAgICAgICAgICAgICAgIC8vIHBvaW50cy4gVGhlc2UgZW52aXJvbm1lbnRzLCBhbG9uZyB3aXRoIEZGIDMuMWIxIGFuZCAyLFxuICAgICAgICAgICAgICAgICAgICAvLyBhbHNvIGFsbG93IHRyYWlsaW5nIGNvbW1hcyBpbiBKU09OIG9iamVjdHMgYW5kIGFycmF5cy5cbiAgICAgICAgICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBwYXJzZShcIjEuXCIpICE9PSAxO1xuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgcGFyc2VTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaXNTdXBwb3J0ZWQgPSBwYXJzZVN1cHBvcnRlZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGhhc1tuYW1lXSA9ICEhaXNTdXBwb3J0ZWQ7XG4gIH1cblxuICBpZiAoIWhhcyhcImpzb25cIikpIHtcbiAgICAvLyBDb21tb24gYFtbQ2xhc3NdXWAgbmFtZSBhbGlhc2VzLlxuICAgIHZhciBmdW5jdGlvbkNsYXNzID0gXCJbb2JqZWN0IEZ1bmN0aW9uXVwiO1xuICAgIHZhciBkYXRlQ2xhc3MgPSBcIltvYmplY3QgRGF0ZV1cIjtcbiAgICB2YXIgbnVtYmVyQ2xhc3MgPSBcIltvYmplY3QgTnVtYmVyXVwiO1xuICAgIHZhciBzdHJpbmdDbGFzcyA9IFwiW29iamVjdCBTdHJpbmddXCI7XG4gICAgdmFyIGFycmF5Q2xhc3MgPSBcIltvYmplY3QgQXJyYXldXCI7XG4gICAgdmFyIGJvb2xlYW5DbGFzcyA9IFwiW29iamVjdCBCb29sZWFuXVwiO1xuXG4gICAgLy8gRGV0ZWN0IGluY29tcGxldGUgc3VwcG9ydCBmb3IgYWNjZXNzaW5nIHN0cmluZyBjaGFyYWN0ZXJzIGJ5IGluZGV4LlxuICAgIHZhciBjaGFySW5kZXhCdWdneSA9IGhhcyhcImJ1Zy1zdHJpbmctY2hhci1pbmRleFwiKTtcblxuICAgIC8vIERlZmluZSBhZGRpdGlvbmFsIHV0aWxpdHkgbWV0aG9kcyBpZiB0aGUgYERhdGVgIG1ldGhvZHMgYXJlIGJ1Z2d5LlxuICAgIGlmICghaXNFeHRlbmRlZCkge1xuICAgICAgdmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbiAgICAgIC8vIEEgbWFwcGluZyBiZXR3ZWVuIHRoZSBtb250aHMgb2YgdGhlIHllYXIgYW5kIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuXG4gICAgICAvLyBKYW51YXJ5IDFzdCBhbmQgdGhlIGZpcnN0IG9mIHRoZSByZXNwZWN0aXZlIG1vbnRoLlxuICAgICAgdmFyIE1vbnRocyA9IFswLCAzMSwgNTksIDkwLCAxMjAsIDE1MSwgMTgxLCAyMTIsIDI0MywgMjczLCAzMDQsIDMzNF07XG4gICAgICAvLyBJbnRlcm5hbDogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIGRheXMgYmV0d2VlbiB0aGUgVW5peCBlcG9jaCBhbmQgdGhlXG4gICAgICAvLyBmaXJzdCBkYXkgb2YgdGhlIGdpdmVuIG1vbnRoLlxuICAgICAgdmFyIGdldERheSA9IGZ1bmN0aW9uICh5ZWFyLCBtb250aCkge1xuICAgICAgICByZXR1cm4gTW9udGhzW21vbnRoXSArIDM2NSAqICh5ZWFyIC0gMTk3MCkgKyBmbG9vcigoeWVhciAtIDE5NjkgKyAobW9udGggPSArKG1vbnRoID4gMSkpKSAvIDQpIC0gZmxvb3IoKHllYXIgLSAxOTAxICsgbW9udGgpIC8gMTAwKSArIGZsb29yKCh5ZWFyIC0gMTYwMSArIG1vbnRoKSAvIDQwMCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIGlmIGEgcHJvcGVydHkgaXMgYSBkaXJlY3QgcHJvcGVydHkgb2YgdGhlIGdpdmVuXG4gICAgLy8gb2JqZWN0LiBEZWxlZ2F0ZXMgdG8gdGhlIG5hdGl2ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBtZXRob2QuXG4gICAgaWYgKCEoaXNQcm9wZXJ0eSA9IHt9Lmhhc093blByb3BlcnR5KSkge1xuICAgICAgaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xuICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBjb25zdHJ1Y3RvcjtcbiAgICAgICAgaWYgKChtZW1iZXJzLl9fcHJvdG9fXyA9IG51bGwsIG1lbWJlcnMuX19wcm90b19fID0ge1xuICAgICAgICAgIC8vIFRoZSAqcHJvdG8qIHByb3BlcnR5IGNhbm5vdCBiZSBzZXQgbXVsdGlwbGUgdGltZXMgaW4gcmVjZW50XG4gICAgICAgICAgLy8gdmVyc2lvbnMgb2YgRmlyZWZveCBhbmQgU2VhTW9ua2V5LlxuICAgICAgICAgIFwidG9TdHJpbmdcIjogMVxuICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykge1xuICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuMyBkb2Vzbid0IGltcGxlbWVudCBgT2JqZWN0I2hhc093blByb3BlcnR5YCwgYnV0XG4gICAgICAgICAgLy8gc3VwcG9ydHMgdGhlIG11dGFibGUgKnByb3RvKiBwcm9wZXJ0eS5cbiAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAvLyBDYXB0dXJlIGFuZCBicmVhayB0aGUgb2JqZWN0J3MgcHJvdG90eXBlIGNoYWluIChzZWUgc2VjdGlvbiA4LjYuMlxuICAgICAgICAgICAgLy8gb2YgdGhlIEVTIDUuMSBzcGVjKS4gVGhlIHBhcmVudGhlc2l6ZWQgZXhwcmVzc2lvbiBwcmV2ZW50cyBhblxuICAgICAgICAgICAgLy8gdW5zYWZlIHRyYW5zZm9ybWF0aW9uIGJ5IHRoZSBDbG9zdXJlIENvbXBpbGVyLlxuICAgICAgICAgICAgdmFyIG9yaWdpbmFsID0gdGhpcy5fX3Byb3RvX18sIHJlc3VsdCA9IHByb3BlcnR5IGluICh0aGlzLl9fcHJvdG9fXyA9IG51bGwsIHRoaXMpO1xuICAgICAgICAgICAgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgcHJvdG90eXBlIGNoYWluLlxuICAgICAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBvcmlnaW5hbDtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBDYXB0dXJlIGEgcmVmZXJlbmNlIHRvIHRoZSB0b3AtbGV2ZWwgYE9iamVjdGAgY29uc3RydWN0b3IuXG4gICAgICAgICAgY29uc3RydWN0b3IgPSBtZW1iZXJzLmNvbnN0cnVjdG9yO1xuICAgICAgICAgIC8vIFVzZSB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSB0byBzaW11bGF0ZSBgT2JqZWN0I2hhc093blByb3BlcnR5YCBpblxuICAgICAgICAgIC8vIG90aGVyIGVudmlyb25tZW50cy5cbiAgICAgICAgICBpc1Byb3BlcnR5ID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTtcbiAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eSBpbiB0aGlzICYmICEocHJvcGVydHkgaW4gcGFyZW50ICYmIHRoaXNbcHJvcGVydHldID09PSBwYXJlbnRbcHJvcGVydHldKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIG1lbWJlcnMgPSBudWxsO1xuICAgICAgICByZXR1cm4gaXNQcm9wZXJ0eS5jYWxsKHRoaXMsIHByb3BlcnR5KTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSW50ZXJuYWw6IEEgc2V0IG9mIHByaW1pdGl2ZSB0eXBlcyB1c2VkIGJ5IGBpc0hvc3RUeXBlYC5cbiAgICB2YXIgUHJpbWl0aXZlVHlwZXMgPSB7XG4gICAgICAnYm9vbGVhbic6IDEsXG4gICAgICAnbnVtYmVyJzogMSxcbiAgICAgICdzdHJpbmcnOiAxLFxuICAgICAgJ3VuZGVmaW5lZCc6IDFcbiAgICB9O1xuXG4gICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgdGhlIGdpdmVuIG9iamVjdCBgcHJvcGVydHlgIHZhbHVlIGlzIGFcbiAgICAvLyBub24tcHJpbWl0aXZlLlxuICAgIHZhciBpc0hvc3RUeXBlID0gZnVuY3Rpb24gKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICAgIHZhciB0eXBlID0gdHlwZW9mIG9iamVjdFtwcm9wZXJ0eV07XG4gICAgICByZXR1cm4gdHlwZSA9PSAnb2JqZWN0JyA/ICEhb2JqZWN0W3Byb3BlcnR5XSA6ICFQcmltaXRpdmVUeXBlc1t0eXBlXTtcbiAgICB9O1xuXG4gICAgLy8gSW50ZXJuYWw6IE5vcm1hbGl6ZXMgdGhlIGBmb3IuLi5pbmAgaXRlcmF0aW9uIGFsZ29yaXRobSBhY3Jvc3NcbiAgICAvLyBlbnZpcm9ubWVudHMuIEVhY2ggZW51bWVyYXRlZCBrZXkgaXMgeWllbGRlZCB0byBhIGBjYWxsYmFja2AgZnVuY3Rpb24uXG4gICAgZm9yRWFjaCA9IGZ1bmN0aW9uIChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgc2l6ZSA9IDAsIFByb3BlcnRpZXMsIG1lbWJlcnMsIHByb3BlcnR5O1xuXG4gICAgICAvLyBUZXN0cyBmb3IgYnVncyBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCdzIGBmb3IuLi5pbmAgYWxnb3JpdGhtLiBUaGVcbiAgICAgIC8vIGB2YWx1ZU9mYCBwcm9wZXJ0eSBpbmhlcml0cyB0aGUgbm9uLWVudW1lcmFibGUgZmxhZyBmcm9tXG4gICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS5cbiAgICAgIChQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnZhbHVlT2YgPSAwO1xuICAgICAgfSkucHJvdG90eXBlLnZhbHVlT2YgPSAwO1xuXG4gICAgICAvLyBJdGVyYXRlIG92ZXIgYSBuZXcgaW5zdGFuY2Ugb2YgdGhlIGBQcm9wZXJ0aWVzYCBjbGFzcy5cbiAgICAgIG1lbWJlcnMgPSBuZXcgUHJvcGVydGllcygpO1xuICAgICAgZm9yIChwcm9wZXJ0eSBpbiBtZW1iZXJzKSB7XG4gICAgICAgIC8vIElnbm9yZSBhbGwgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgIGlmIChpc1Byb3BlcnR5LmNhbGwobWVtYmVycywgcHJvcGVydHkpKSB7XG4gICAgICAgICAgc2l6ZSsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBQcm9wZXJ0aWVzID0gbWVtYmVycyA9IG51bGw7XG5cbiAgICAgIC8vIE5vcm1hbGl6ZSB0aGUgaXRlcmF0aW9uIGFsZ29yaXRobS5cbiAgICAgIGlmICghc2l6ZSkge1xuICAgICAgICAvLyBBIGxpc3Qgb2Ygbm9uLWVudW1lcmFibGUgcHJvcGVydGllcyBpbmhlcml0ZWQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuXG4gICAgICAgIG1lbWJlcnMgPSBbXCJ2YWx1ZU9mXCIsIFwidG9TdHJpbmdcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInByb3BlcnR5SXNFbnVtZXJhYmxlXCIsIFwiaXNQcm90b3R5cGVPZlwiLCBcImhhc093blByb3BlcnR5XCIsIFwiY29uc3RydWN0b3JcIl07XG4gICAgICAgIC8vIElFIDw9IDgsIE1vemlsbGEgMS4wLCBhbmQgTmV0c2NhcGUgNi4yIGlnbm9yZSBzaGFkb3dlZCBub24tZW51bWVyYWJsZVxuICAgICAgICAvLyBwcm9wZXJ0aWVzLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgbGVuZ3RoO1xuICAgICAgICAgIHZhciBoYXNQcm9wZXJ0eSA9ICFpc0Z1bmN0aW9uICYmIHR5cGVvZiBvYmplY3QuY29uc3RydWN0b3IgIT0gJ2Z1bmN0aW9uJyAmJiBpc0hvc3RUeXBlKG9iamVjdCwgJ2hhc093blByb3BlcnR5JykgPyBvYmplY3QuaGFzT3duUHJvcGVydHkgOiBpc1Byb3BlcnR5O1xuICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAvLyBHZWNrbyA8PSAxLjAgZW51bWVyYXRlcyB0aGUgYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIHVuZGVyXG4gICAgICAgICAgICAvLyBjZXJ0YWluIGNvbmRpdGlvbnM7IElFIGRvZXMgbm90LlxuICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgZWFjaCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eS5cbiAgICAgICAgICBmb3IgKGxlbmd0aCA9IG1lbWJlcnMubGVuZ3RoOyBwcm9wZXJ0eSA9IG1lbWJlcnNbLS1sZW5ndGhdOyBoYXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmIGNhbGxiYWNrKHByb3BlcnR5KSk7XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikge1xuICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjQgZW51bWVyYXRlcyBzaGFkb3dlZCBwcm9wZXJ0aWVzIHR3aWNlLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAvLyBDcmVhdGUgYSBzZXQgb2YgaXRlcmF0ZWQgcHJvcGVydGllcy5cbiAgICAgICAgICB2YXIgbWVtYmVycyA9IHt9LCBpc0Z1bmN0aW9uID0gZ2V0Q2xhc3MuY2FsbChvYmplY3QpID09IGZ1bmN0aW9uQ2xhc3MsIHByb3BlcnR5O1xuICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgICAvLyBTdG9yZSBlYWNoIHByb3BlcnR5IG5hbWUgdG8gcHJldmVudCBkb3VibGUgZW51bWVyYXRpb24uIFRoZVxuICAgICAgICAgICAgLy8gYHByb3RvdHlwZWAgcHJvcGVydHkgb2YgZnVuY3Rpb25zIGlzIG5vdCBlbnVtZXJhdGVkIGR1ZSB0byBjcm9zcy1cbiAgICAgICAgICAgIC8vIGVudmlyb25tZW50IGluY29uc2lzdGVuY2llcy5cbiAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgIWlzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkgJiYgKG1lbWJlcnNbcHJvcGVydHldID0gMSkgJiYgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBObyBidWdzIGRldGVjdGVkOyB1c2UgdGhlIHN0YW5kYXJkIGBmb3IuLi5pbmAgYWxnb3JpdGhtLlxuICAgICAgICBmb3JFYWNoID0gZnVuY3Rpb24gKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLCBwcm9wZXJ0eSwgaXNDb25zdHJ1Y3RvcjtcbiAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBpc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkgJiYgIShpc0NvbnN0cnVjdG9yID0gcHJvcGVydHkgPT09IFwiY29uc3RydWN0b3JcIikpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2socHJvcGVydHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBNYW51YWxseSBpbnZva2UgdGhlIGNhbGxiYWNrIGZvciB0aGUgYGNvbnN0cnVjdG9yYCBwcm9wZXJ0eSBkdWUgdG9cbiAgICAgICAgICAvLyBjcm9zcy1lbnZpcm9ubWVudCBpbmNvbnNpc3RlbmNpZXMuXG4gICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IgfHwgaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgKHByb3BlcnR5ID0gXCJjb25zdHJ1Y3RvclwiKSkpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgLy8gUHVibGljOiBTZXJpYWxpemVzIGEgSmF2YVNjcmlwdCBgdmFsdWVgIGFzIGEgSlNPTiBzdHJpbmcuIFRoZSBvcHRpb25hbFxuICAgIC8vIGBmaWx0ZXJgIGFyZ3VtZW50IG1heSBzcGVjaWZ5IGVpdGhlciBhIGZ1bmN0aW9uIHRoYXQgYWx0ZXJzIGhvdyBvYmplY3QgYW5kXG4gICAgLy8gYXJyYXkgbWVtYmVycyBhcmUgc2VyaWFsaXplZCwgb3IgYW4gYXJyYXkgb2Ygc3RyaW5ncyBhbmQgbnVtYmVycyB0aGF0XG4gICAgLy8gaW5kaWNhdGVzIHdoaWNoIHByb3BlcnRpZXMgc2hvdWxkIGJlIHNlcmlhbGl6ZWQuIFRoZSBvcHRpb25hbCBgd2lkdGhgXG4gICAgLy8gYXJndW1lbnQgbWF5IGJlIGVpdGhlciBhIHN0cmluZyBvciBudW1iZXIgdGhhdCBzcGVjaWZpZXMgdGhlIGluZGVudGF0aW9uXG4gICAgLy8gbGV2ZWwgb2YgdGhlIG91dHB1dC5cbiAgICBpZiAoIWhhcyhcImpzb24tc3RyaW5naWZ5XCIpKSB7XG4gICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgY29udHJvbCBjaGFyYWN0ZXJzIGFuZCB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLlxuICAgICAgdmFyIEVzY2FwZXMgPSB7XG4gICAgICAgIDkyOiBcIlxcXFxcXFxcXCIsXG4gICAgICAgIDM0OiAnXFxcXFwiJyxcbiAgICAgICAgODogXCJcXFxcYlwiLFxuICAgICAgICAxMjogXCJcXFxcZlwiLFxuICAgICAgICAxMDogXCJcXFxcblwiLFxuICAgICAgICAxMzogXCJcXFxcclwiLFxuICAgICAgICA5OiBcIlxcXFx0XCJcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBDb252ZXJ0cyBgdmFsdWVgIGludG8gYSB6ZXJvLXBhZGRlZCBzdHJpbmcgc3VjaCB0aGF0IGl0c1xuICAgICAgLy8gbGVuZ3RoIGlzIGF0IGxlYXN0IGVxdWFsIHRvIGB3aWR0aGAuIFRoZSBgd2lkdGhgIG11c3QgYmUgPD0gNi5cbiAgICAgIHZhciBsZWFkaW5nWmVyb2VzID0gXCIwMDAwMDBcIjtcbiAgICAgIHZhciB0b1BhZGRlZFN0cmluZyA9IGZ1bmN0aW9uICh3aWR0aCwgdmFsdWUpIHtcbiAgICAgICAgLy8gVGhlIGB8fCAwYCBleHByZXNzaW9uIGlzIG5lY2Vzc2FyeSB0byB3b3JrIGFyb3VuZCBhIGJ1ZyBpblxuICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgd2hlcmUgYDAgPT0gLTBgLCBidXQgYFN0cmluZygtMCkgIT09IFwiMFwiYC5cbiAgICAgICAgcmV0dXJuIChsZWFkaW5nWmVyb2VzICsgKHZhbHVlIHx8IDApKS5zbGljZSgtd2lkdGgpO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IERvdWJsZS1xdW90ZXMgYSBzdHJpbmcgYHZhbHVlYCwgcmVwbGFjaW5nIGFsbCBBU0NJSSBjb250cm9sXG4gICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoXG4gICAgICAvLyB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgLy8gYFF1b3RlKHZhbHVlKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gXCJcXFxcdTAwXCI7XG4gICAgICB2YXIgcXVvdGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9ICdcIicsIGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoLCBpc0xhcmdlID0gbGVuZ3RoID4gMTAgJiYgY2hhckluZGV4QnVnZ3ksIHN5bWJvbHM7XG4gICAgICAgIGlmIChpc0xhcmdlKSB7XG4gICAgICAgICAgc3ltYm9scyA9IHZhbHVlLnNwbGl0KFwiXCIpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgIHZhciBjaGFyQ29kZSA9IHZhbHVlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yXG4gICAgICAgICAgLy8gc2hvcnRoYW5kIGVzY2FwZSBzZXF1ZW5jZTsgb3RoZXJ3aXNlLCBhcHBlbmQgdGhlIGNoYXJhY3RlciBhcy1pcy5cbiAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICBjYXNlIDg6IGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMjogY2FzZSAxMzogY2FzZSAzNDogY2FzZSA5MjpcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IEVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVuaWNvZGVQcmVmaXggKyB0b1BhZGRlZFN0cmluZygyLCBjaGFyQ29kZS50b1N0cmluZygxNikpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBpc0xhcmdlID8gc3ltYm9sc1tpbmRleF0gOiBjaGFySW5kZXhCdWdneSA/IHZhbHVlLmNoYXJBdChpbmRleCkgOiB2YWx1ZVtpbmRleF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgKyAnXCInO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZXMgYW4gb2JqZWN0LiBJbXBsZW1lbnRzIHRoZVxuICAgICAgLy8gYFN0cihrZXksIGhvbGRlcilgLCBgSk8odmFsdWUpYCwgYW5kIGBKQSh2YWx1ZSlgIG9wZXJhdGlvbnMuXG4gICAgICB2YXIgc2VyaWFsaXplID0gZnVuY3Rpb24gKHByb3BlcnR5LCBvYmplY3QsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spIHtcbiAgICAgICAgdmFyIHZhbHVlLCBjbGFzc05hbWUsIHllYXIsIG1vbnRoLCBkYXRlLCB0aW1lLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzLCByZXN1bHRzLCBlbGVtZW50LCBpbmRleCwgbGVuZ3RoLCBwcmVmaXgsIHJlc3VsdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIGhvc3Qgb2JqZWN0IHN1cHBvcnQuXG4gICAgICAgICAgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIiAmJiB2YWx1ZSkge1xuICAgICAgICAgIGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpO1xuICAgICAgICAgIGlmIChjbGFzc05hbWUgPT0gZGF0ZUNsYXNzICYmICFpc1Byb3BlcnR5LmNhbGwodmFsdWUsIFwidG9KU09OXCIpKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkge1xuICAgICAgICAgICAgICAvLyBEYXRlcyBhcmUgc2VyaWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGBEYXRlI3RvSlNPTmAgbWV0aG9kXG4gICAgICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS45LjUuNDQuIFNlZSBzZWN0aW9uIDE1LjkuMS4xNVxuICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LlxuICAgICAgICAgICAgICBpZiAoZ2V0RGF5KSB7XG4gICAgICAgICAgICAgICAgLy8gTWFudWFsbHkgY29tcHV0ZSB0aGUgeWVhciwgbW9udGgsIGRhdGUsIGhvdXJzLCBtaW51dGVzLFxuICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZVxuICAgICAgICAgICAgICAgIC8vIGJ1Z2d5LiBBZGFwdGVkIGZyb20gQFlhZmZsZSdzIGBkYXRlLXNoaW1gIHByb2plY3QuXG4gICAgICAgICAgICAgICAgZGF0ZSA9IGZsb29yKHZhbHVlIC8gODY0ZTUpO1xuICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspO1xuICAgICAgICAgICAgICAgIGZvciAobW9udGggPSBmbG9vcigoZGF0ZSAtIGdldERheSh5ZWFyLCAwKSkgLyAzMC40Mik7IGdldERheSh5ZWFyLCBtb250aCArIDEpIDw9IGRhdGU7IG1vbnRoKyspO1xuICAgICAgICAgICAgICAgIGRhdGUgPSAxICsgZGF0ZSAtIGdldERheSh5ZWFyLCBtb250aCk7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGB0aW1lYCB2YWx1ZSBzcGVjaWZpZXMgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkgKHNlZSBFU1xuICAgICAgICAgICAgICAgIC8vIDUuMSBzZWN0aW9uIDE1LjkuMS4yKS4gVGhlIGZvcm11bGEgYChBICUgQiArIEIpICUgQmAgaXMgdXNlZFxuICAgICAgICAgICAgICAgIC8vIHRvIGNvbXB1dGUgYEEgbW9kdWxvIEJgLCBhcyB0aGUgYCVgIG9wZXJhdG9yIGRvZXMgbm90XG4gICAgICAgICAgICAgICAgLy8gY29ycmVzcG9uZCB0byB0aGUgYG1vZHVsb2Agb3BlcmF0aW9uIGZvciBuZWdhdGl2ZSBudW1iZXJzLlxuICAgICAgICAgICAgICAgIHRpbWUgPSAodmFsdWUgJSA4NjRlNSArIDg2NGU1KSAlIDg2NGU1O1xuICAgICAgICAgICAgICAgIC8vIFRoZSBob3VycywgbWludXRlcywgc2Vjb25kcywgYW5kIG1pbGxpc2Vjb25kcyBhcmUgb2J0YWluZWQgYnlcbiAgICAgICAgICAgICAgICAvLyBkZWNvbXBvc2luZyB0aGUgdGltZSB3aXRoaW4gdGhlIGRheS4gU2VlIHNlY3Rpb24gMTUuOS4xLjEwLlxuICAgICAgICAgICAgICAgIGhvdXJzID0gZmxvb3IodGltZSAvIDM2ZTUpICUgMjQ7XG4gICAgICAgICAgICAgICAgbWludXRlcyA9IGZsb29yKHRpbWUgLyA2ZTQpICUgNjA7XG4gICAgICAgICAgICAgICAgc2Vjb25kcyA9IGZsb29yKHRpbWUgLyAxZTMpICUgNjA7XG4gICAgICAgICAgICAgICAgbWlsbGlzZWNvbmRzID0gdGltZSAlIDFlMztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB5ZWFyID0gdmFsdWUuZ2V0VVRDRnVsbFllYXIoKTtcbiAgICAgICAgICAgICAgICBtb250aCA9IHZhbHVlLmdldFVUQ01vbnRoKCk7XG4gICAgICAgICAgICAgICAgZGF0ZSA9IHZhbHVlLmdldFVUQ0RhdGUoKTtcbiAgICAgICAgICAgICAgICBob3VycyA9IHZhbHVlLmdldFVUQ0hvdXJzKCk7XG4gICAgICAgICAgICAgICAgbWludXRlcyA9IHZhbHVlLmdldFVUQ01pbnV0ZXMoKTtcbiAgICAgICAgICAgICAgICBzZWNvbmRzID0gdmFsdWUuZ2V0VVRDU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHZhbHVlLmdldFVUQ01pbGxpc2Vjb25kcygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFNlcmlhbGl6ZSBleHRlbmRlZCB5ZWFycyBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgIHZhbHVlID0gKHllYXIgPD0gMCB8fCB5ZWFyID49IDFlNCA/ICh5ZWFyIDwgMCA/IFwiLVwiIDogXCIrXCIpICsgdG9QYWRkZWRTdHJpbmcoNiwgeWVhciA8IDAgPyAteWVhciA6IHllYXIpIDogdG9QYWRkZWRTdHJpbmcoNCwgeWVhcikpICtcbiAgICAgICAgICAgICAgICBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1vbnRoICsgMSkgKyBcIi1cIiArIHRvUGFkZGVkU3RyaW5nKDIsIGRhdGUpICtcbiAgICAgICAgICAgICAgICAvLyBNb250aHMsIGRhdGVzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgc2hvdWxkIGhhdmUgdHdvXG4gICAgICAgICAgICAgICAgLy8gZGlnaXRzOyBtaWxsaXNlY29uZHMgc2hvdWxkIGhhdmUgdGhyZWUuXG4gICAgICAgICAgICAgICAgXCJUXCIgKyB0b1BhZGRlZFN0cmluZygyLCBob3VycykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIG1pbnV0ZXMpICsgXCI6XCIgKyB0b1BhZGRlZFN0cmluZygyLCBzZWNvbmRzKSArXG4gICAgICAgICAgICAgICAgLy8gTWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LjAsIGJ1dCByZXF1aXJlZCBpbiA1LjEuXG4gICAgICAgICAgICAgICAgXCIuXCIgKyB0b1BhZGRlZFN0cmluZygzLCBtaWxsaXNlY29uZHMpICsgXCJaXCI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB2YWx1ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUudG9KU09OID09IFwiZnVuY3Rpb25cIiAmJiAoKGNsYXNzTmFtZSAhPSBudW1iZXJDbGFzcyAmJiBjbGFzc05hbWUgIT0gc3RyaW5nQ2xhc3MgJiYgY2xhc3NOYW1lICE9IGFycmF5Q2xhc3MpIHx8IGlzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpKSB7XG4gICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgYWRkcyBub24tc3RhbmRhcmQgYHRvSlNPTmAgbWV0aG9kcyB0byB0aGVcbiAgICAgICAgICAgIC8vIGBOdW1iZXJgLCBgU3RyaW5nYCwgYERhdGVgLCBhbmQgYEFycmF5YCBwcm90b3R5cGVzLiBKU09OIDNcbiAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmVcbiAgICAgICAgICAgIC8vIGRlZmluZWQgZGlyZWN0bHkgb24gYW4gaW5zdGFuY2UuXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvSlNPTihwcm9wZXJ0eSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWVcbiAgICAgICAgICAvLyBmb3Igc2VyaWFsaXphdGlvbi5cbiAgICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgfVxuICAgICAgICBjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKTtcbiAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHtcbiAgICAgICAgICAvLyBCb29sZWFucyBhcmUgcmVwcmVzZW50ZWQgbGl0ZXJhbGx5LlxuICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgLy8gSlNPTiBudW1iZXJzIG11c3QgYmUgZmluaXRlLiBgSW5maW5pdHlgIGFuZCBgTmFOYCBhcmUgc2VyaWFsaXplZCBhc1xuICAgICAgICAgIC8vIGBcIm51bGxcImAuXG4gICAgICAgICAgcmV0dXJuIHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDAgPyBcIlwiICsgdmFsdWUgOiBcIm51bGxcIjtcbiAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAvLyBTdHJpbmdzIGFyZSBkb3VibGUtcXVvdGVkIGFuZCBlc2NhcGVkLlxuICAgICAgICAgIHJldHVybiBxdW90ZShcIlwiICsgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIC8vIENoZWNrIGZvciBjeWNsaWMgc3RydWN0dXJlcy4gVGhpcyBpcyBhIGxpbmVhciBzZWFyY2g7IHBlcmZvcm1hbmNlXG4gICAgICAgICAgLy8gaXMgaW52ZXJzZWx5IHByb3BvcnRpb25hbCB0byB0aGUgbnVtYmVyIG9mIHVuaXF1ZSBuZXN0ZWQgb2JqZWN0cy5cbiAgICAgICAgICBmb3IgKGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICBpZiAoc3RhY2tbbGVuZ3RoXSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgLy8gQ3ljbGljIHN0cnVjdHVyZXMgY2Fubm90IGJlIHNlcmlhbGl6ZWQgYnkgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEFkZCB0aGUgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcbiAgICAgICAgICByZXN1bHRzID0gW107XG4gICAgICAgICAgLy8gU2F2ZSB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbCBhbmQgaW5kZW50IG9uZSBhZGRpdGlvbmFsIGxldmVsLlxuICAgICAgICAgIHByZWZpeCA9IGluZGVudGF0aW9uO1xuICAgICAgICAgIGluZGVudGF0aW9uICs9IHdoaXRlc3BhY2U7XG4gICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgYXJyYXkgZWxlbWVudHMuXG4gICAgICAgICAgICBmb3IgKGluZGV4ID0gMCwgbGVuZ3RoID0gdmFsdWUubGVuZ3RoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICBlbGVtZW50ID0gc2VyaWFsaXplKGluZGV4LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaChlbGVtZW50ID09PSB1bmRlZiA/IFwibnVsbFwiIDogZWxlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgPSByZXN1bHRzLmxlbmd0aCA/ICh3aGl0ZXNwYWNlID8gXCJbXFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIl1cIiA6IChcIltcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIl1cIikpIDogXCJbXVwiO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBzZXJpYWxpemUgb2JqZWN0IG1lbWJlcnMuIE1lbWJlcnMgYXJlIHNlbGVjdGVkIGZyb21cbiAgICAgICAgICAgIC8vIGVpdGhlciBhIHVzZXItc3BlY2lmaWVkIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMsIG9yIHRoZSBvYmplY3RcbiAgICAgICAgICAgIC8vIGl0c2VsZi5cbiAgICAgICAgICAgIGZvckVhY2gocHJvcGVydGllcyB8fCB2YWx1ZSwgZnVuY3Rpb24gKHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gc2VyaWFsaXplKHByb3BlcnR5LCB2YWx1ZSwgY2FsbGJhY2ssIHByb3BlcnRpZXMsIHdoaXRlc3BhY2UsIGluZGVudGF0aW9uLCBzdGFjayk7XG4gICAgICAgICAgICAgIGlmIChlbGVtZW50ICE9PSB1bmRlZikge1xuICAgICAgICAgICAgICAgIC8vIEFjY29yZGluZyB0byBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zOiBcIklmIGBnYXBgIHt3aGl0ZXNwYWNlfVxuICAgICAgICAgICAgICAgIC8vIGlzIG5vdCB0aGUgZW1wdHkgc3RyaW5nLCBsZXQgYG1lbWJlcmAge3F1b3RlKHByb3BlcnR5KSArIFwiOlwifVxuICAgICAgICAgICAgICAgIC8vIGJlIHRoZSBjb25jYXRlbmF0aW9uIG9mIGBtZW1iZXJgIGFuZCB0aGUgYHNwYWNlYCBjaGFyYWN0ZXIuXCJcbiAgICAgICAgICAgICAgICAvLyBUaGUgXCJgc3BhY2VgIGNoYXJhY3RlclwiIHJlZmVycyB0byB0aGUgbGl0ZXJhbCBzcGFjZVxuICAgICAgICAgICAgICAgIC8vIGNoYXJhY3Rlciwgbm90IHRoZSBgc3BhY2VgIHt3aWR0aH0gYXJndW1lbnQgcHJvdmlkZWQgdG9cbiAgICAgICAgICAgICAgICAvLyBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChxdW90ZShwcm9wZXJ0eSkgKyBcIjpcIiArICh3aGl0ZXNwYWNlID8gXCIgXCIgOiBcIlwiKSArIGVsZW1lbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID8gKHdoaXRlc3BhY2UgPyBcIntcXG5cIiArIGluZGVudGF0aW9uICsgcmVzdWx0cy5qb2luKFwiLFxcblwiICsgaW5kZW50YXRpb24pICsgXCJcXG5cIiArIHByZWZpeCArIFwifVwiIDogKFwie1wiICsgcmVzdWx0cy5qb2luKFwiLFwiKSArIFwifVwiKSkgOiBcInt9XCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFJlbW92ZSB0aGUgb2JqZWN0IGZyb20gdGhlIHRyYXZlcnNlZCBvYmplY3Qgc3RhY2suXG4gICAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gUHVibGljOiBgSlNPTi5zdHJpbmdpZnlgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgIEpTT04zLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChzb3VyY2UsIGZpbHRlciwgd2lkdGgpIHtcbiAgICAgICAgdmFyIHdoaXRlc3BhY2UsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCBjbGFzc05hbWU7XG4gICAgICAgIGlmICh0eXBlb2YgZmlsdGVyID09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgZmlsdGVyID09IFwib2JqZWN0XCIgJiYgZmlsdGVyKSB7XG4gICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKGZpbHRlcikpID09IGZ1bmN0aW9uQ2xhc3MpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHByb3BlcnR5IG5hbWVzIGFycmF5IGludG8gYSBtYWtlc2hpZnQgc2V0LlxuICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGggPSBmaWx0ZXIubGVuZ3RoLCB2YWx1ZTsgaW5kZXggPCBsZW5ndGg7IHZhbHVlID0gZmlsdGVyW2luZGV4KytdLCAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwodmFsdWUpKSwgY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzIHx8IGNsYXNzTmFtZSA9PSBudW1iZXJDbGFzcykgJiYgKHByb3BlcnRpZXNbdmFsdWVdID0gMSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod2lkdGgpIHtcbiAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwod2lkdGgpKSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgLy8gYHdpZHRoYCBudW1iZXIgb2Ygc3BhY2UgY2hhcmFjdGVycy5cbiAgICAgICAgICAgIGlmICgod2lkdGggLT0gd2lkdGggJSAxKSA+IDApIHtcbiAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IHN0cmluZ0NsYXNzKSB7XG4gICAgICAgICAgICB3aGl0ZXNwYWNlID0gd2lkdGgubGVuZ3RoIDw9IDEwID8gd2lkdGggOiB3aWR0aC5zbGljZSgwLCAxMCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIE9wZXJhIDw9IDcuNTR1MiBkaXNjYXJkcyB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBlbXB0eSBzdHJpbmcga2V5c1xuICAgICAgICAvLyAoYFwiXCJgKSBvbmx5IGlmIHRoZXkgYXJlIHVzZWQgZGlyZWN0bHkgd2l0aGluIGFuIG9iamVjdCBtZW1iZXIgbGlzdFxuICAgICAgICAvLyAoZS5nLiwgYCEoXCJcIiBpbiB7IFwiXCI6IDF9KWApLlxuICAgICAgICByZXR1cm4gc2VyaWFsaXplKFwiXCIsICh2YWx1ZSA9IHt9LCB2YWx1ZVtcIlwiXSA9IHNvdXJjZSwgdmFsdWUpLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgXCJcIiwgW10pO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBQdWJsaWM6IFBhcnNlcyBhIEpTT04gc291cmNlIHN0cmluZy5cbiAgICBpZiAoIWhhcyhcImpzb24tcGFyc2VcIikpIHtcbiAgICAgIHZhciBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlO1xuXG4gICAgICAvLyBJbnRlcm5hbDogQSBtYXAgb2YgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMgYW5kIHRoZWlyIHVuZXNjYXBlZFxuICAgICAgLy8gZXF1aXZhbGVudHMuXG4gICAgICB2YXIgVW5lc2NhcGVzID0ge1xuICAgICAgICA5MjogXCJcXFxcXCIsXG4gICAgICAgIDM0OiAnXCInLFxuICAgICAgICA0NzogXCIvXCIsXG4gICAgICAgIDk4OiBcIlxcYlwiLFxuICAgICAgICAxMTY6IFwiXFx0XCIsXG4gICAgICAgIDExMDogXCJcXG5cIixcbiAgICAgICAgMTAyOiBcIlxcZlwiLFxuICAgICAgICAxMTQ6IFwiXFxyXCJcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBTdG9yZXMgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgIHZhciBJbmRleCwgU291cmNlO1xuXG4gICAgICAvLyBJbnRlcm5hbDogUmVzZXRzIHRoZSBwYXJzZXIgc3RhdGUgYW5kIHRocm93cyBhIGBTeW50YXhFcnJvcmAuXG4gICAgICB2YXIgYWJvcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICB0aHJvdyBTeW50YXhFcnJvcigpO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJldHVybnMgdGhlIG5leHQgdG9rZW4sIG9yIGBcIiRcImAgaWYgdGhlIHBhcnNlciBoYXMgcmVhY2hlZFxuICAgICAgLy8gdGhlIGVuZCBvZiB0aGUgc291cmNlIHN0cmluZy4gQSB0b2tlbiBtYXkgYmUgYSBzdHJpbmcsIG51bWJlciwgYG51bGxgXG4gICAgICAvLyBsaXRlcmFsLCBvciBCb29sZWFuIGxpdGVyYWwuXG4gICAgICB2YXIgbGV4ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc291cmNlID0gU291cmNlLCBsZW5ndGggPSBzb3VyY2UubGVuZ3RoLCB2YWx1ZSwgYmVnaW4sIHBvc2l0aW9uLCBpc1NpZ25lZCwgY2hhckNvZGU7XG4gICAgICAgIHdoaWxlIChJbmRleCA8IGxlbmd0aCkge1xuICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgIHN3aXRjaCAoY2hhckNvZGUpIHtcbiAgICAgICAgICAgIGNhc2UgOTogY2FzZSAxMDogY2FzZSAxMzogY2FzZSAzMjpcbiAgICAgICAgICAgICAgLy8gU2tpcCB3aGl0ZXNwYWNlIHRva2VucywgaW5jbHVkaW5nIHRhYnMsIGNhcnJpYWdlIHJldHVybnMsIGxpbmVcbiAgICAgICAgICAgICAgLy8gZmVlZHMsIGFuZCBzcGFjZSBjaGFyYWN0ZXJzLlxuICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgMTIzOiBjYXNlIDEyNTogY2FzZSA5MTogY2FzZSA5MzogY2FzZSA1ODogY2FzZSA0NDpcbiAgICAgICAgICAgICAgLy8gUGFyc2UgYSBwdW5jdHVhdG9yIHRva2VuIChge2AsIGB9YCwgYFtgLCBgXWAsIGA6YCwgb3IgYCxgKSBhdFxuICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgdmFsdWUgPSBjaGFySW5kZXhCdWdneSA/IHNvdXJjZS5jaGFyQXQoSW5kZXgpIDogc291cmNlW0luZGV4XTtcbiAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgICAgLy8gYFwiYCBkZWxpbWl0cyBhIEpTT04gc3RyaW5nOyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmRcbiAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAvLyBzZW50aW5lbCBgQGAgY2hhcmFjdGVyIHRvIGRpc3Rpbmd1aXNoIHRoZW0gZnJvbSBwdW5jdHVhdG9ycyBhbmRcbiAgICAgICAgICAgICAgLy8gZW5kLW9mLXN0cmluZyB0b2tlbnMuXG4gICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhhbiB0aGUgc3BhY2UgY2hhcmFjdGVyKSBhcmUgbm90IHBlcm1pdHRlZC5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgLy8gQSByZXZlcnNlIHNvbGlkdXMgKGBcXGApIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYW4gZXNjYXBlZFxuICAgICAgICAgICAgICAgICAgLy8gY29udHJvbCBjaGFyYWN0ZXIgKGluY2x1ZGluZyBgXCJgLCBgXFxgLCBhbmQgYC9gKSBvciBVbmljb2RlXG4gICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOiBjYXNlIDM0OiBjYXNlIDQ3OiBjYXNlIDk4OiBjYXNlIDExNjogY2FzZSAxMTA6IGNhc2UgMTAyOiBjYXNlIDExNDpcbiAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgZXNjYXBlZCBjb250cm9sIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gVW5lc2NhcGVzW2NoYXJDb2RlXTtcbiAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIDExNzpcbiAgICAgICAgICAgICAgICAgICAgICAvLyBgXFx1YCBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIGEgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCB2YWxpZGF0ZSB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBmb3VyLWRpZ2l0IGNvZGUgcG9pbnQuXG4gICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSArK0luZGV4O1xuICAgICAgICAgICAgICAgICAgICAgIGZvciAocG9zaXRpb24gPSBJbmRleCArIDQ7IEluZGV4IDwgcG9zaXRpb247IEluZGV4KyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSB2YWxpZCBzZXF1ZW5jZSBjb21wcmlzZXMgZm91ciBoZXhkaWdpdHMgKGNhc2UtXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnNlbnNpdGl2ZSkgdGhhdCBmb3JtIGEgc2luZ2xlIGhleGFkZWNpbWFsIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcgfHwgY2hhckNvZGUgPj0gOTcgJiYgY2hhckNvZGUgPD0gMTAyIHx8IGNoYXJDb2RlID49IDY1ICYmIGNoYXJDb2RlIDw9IDcwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAvLyBSZXZpdmUgdGhlIGVzY2FwZWQgY2hhcmFjdGVyLlxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICs9IGZyb21DaGFyQ29kZShcIjB4XCIgKyBzb3VyY2Uuc2xpY2UoYmVnaW4sIEluZGV4KSk7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEFuIHVuZXNjYXBlZCBkb3VibGUtcXVvdGUgY2hhcmFjdGVyIG1hcmtzIHRoZSBlbmQgb2YgdGhlXG4gICAgICAgICAgICAgICAgICAgIC8vIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAvLyBPcHRpbWl6ZSBmb3IgdGhlIGNvbW1vbiBjYXNlIHdoZXJlIGEgc3RyaW5nIGlzIHZhbGlkLlxuICAgICAgICAgICAgICAgICAgd2hpbGUgKGNoYXJDb2RlID49IDMyICYmIGNoYXJDb2RlICE9IDkyICYmIGNoYXJDb2RlICE9IDM0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBBcHBlbmQgdGhlIHN0cmluZyBhcy1pcy5cbiAgICAgICAgICAgICAgICAgIHZhbHVlICs9IHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpID09IDM0KSB7XG4gICAgICAgICAgICAgICAgLy8gQWR2YW5jZSB0byB0aGUgbmV4dCBjaGFyYWN0ZXIgYW5kIHJldHVybiB0aGUgcmV2aXZlZCBzdHJpbmcuXG4gICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gVW50ZXJtaW5hdGVkIHN0cmluZy5cbiAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIC8vIFBhcnNlIG51bWJlcnMgYW5kIGxpdGVyYWxzLlxuICAgICAgICAgICAgICBiZWdpbiA9IEluZGV4O1xuICAgICAgICAgICAgICAvLyBBZHZhbmNlIHBhc3QgdGhlIG5lZ2F0aXZlIHNpZ24sIGlmIG9uZSBpcyBzcGVjaWZpZWQuXG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0NSkge1xuICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIFBhcnNlIGFuIGludGVnZXIgb3IgZmxvYXRpbmctcG9pbnQgdmFsdWUuXG4gICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1Nykge1xuICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgemVyb2VzIGFyZSBpbnRlcnByZXRlZCBhcyBvY3RhbCBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gNDggJiYgKChjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4ICsgMSkpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgb2N0YWwgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBJbmRleCsrKTtcbiAgICAgICAgICAgICAgICAvLyBGbG9hdHMgY2Fubm90IGNvbnRhaW4gYSBsZWFkaW5nIGRlY2ltYWwgcG9pbnQ7IGhvd2V2ZXIsIHRoaXNcbiAgICAgICAgICAgICAgICAvLyBjYXNlIGlzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSB0aGUgcGFyc2VyLlxuICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gKytJbmRleDtcbiAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkZWNpbWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIHRyYWlsaW5nIGRlY2ltYWwuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBQYXJzZSBleHBvbmVudHMuIFRoZSBgZWAgZGVub3RpbmcgdGhlIGV4cG9uZW50IGlzXG4gICAgICAgICAgICAgICAgLy8gY2FzZS1pbnNlbnNpdGl2ZS5cbiAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMTAxIHx8IGNoYXJDb2RlID09IDY5KSB7XG4gICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkLlxuICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQzIHx8IGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZXhwb25lbnRpYWwgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoKGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQocG9zaXRpb24pKSwgY2hhckNvZGUgPj0gNDggJiYgY2hhckNvZGUgPD0gNTcpOyBwb3NpdGlvbisrKTtcbiAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIGVtcHR5IGV4cG9uZW50LlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQ29lcmNlIHRoZSBwYXJzZWQgdmFsdWUgdG8gYSBKYXZhU2NyaXB0IG51bWJlci5cbiAgICAgICAgICAgICAgICByZXR1cm4gK3NvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIEEgbmVnYXRpdmUgc2lnbiBtYXkgb25seSBwcmVjZWRlIG51bWJlcnMuXG4gICAgICAgICAgICAgIGlmIChpc1NpZ25lZCkge1xuICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gYHRydWVgLCBgZmFsc2VgLCBhbmQgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyBVbnJlY29nbml6ZWQgdG9rZW4uXG4gICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFJldHVybiB0aGUgc2VudGluZWwgYCRgIGNoYXJhY3RlciBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgIHJldHVybiBcIiRcIjtcbiAgICAgIH07XG5cbiAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICB2YXIgZ2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHZhciByZXN1bHRzLCBoYXNNZW1iZXJzO1xuICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAvLyBVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dC5cbiAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIGlmICgoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgPT0gXCJAXCIpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICBpZiAodmFsdWUgPT0gXCJbXCIpIHtcbiAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gYXJyYXksIHJldHVybmluZyBhIG5ldyBKYXZhU2NyaXB0IGFycmF5LlxuICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIl1cIikge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIElmIHRoZSBhcnJheSBsaXRlcmFsIGNvbnRhaW5zIGVsZW1lbnRzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0aW5nIHRoZSBwcmV2aW91cyBlbGVtZW50IGZyb20gdGhlXG4gICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gRWxpc2lvbnMgYW5kIGxlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaChnZXQodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gXCJ7XCIpIHtcbiAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICByZXN1bHRzID0ge307XG4gICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAvLyBBIGNsb3NpbmcgY3VybHkgYnJhY2UgbWFya3MgdGhlIGVuZCBvZiB0aGUgb2JqZWN0IGxpdGVyYWwuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIElmIHRoZSBvYmplY3QgbGl0ZXJhbCBjb250YWlucyBtZW1iZXJzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIG9iamVjdCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vIExlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLCBvYmplY3QgcHJvcGVydHkgbmFtZXMgbXVzdCBiZVxuICAgICAgICAgICAgICAvLyBkb3VibGUtcXVvdGVkIHN0cmluZ3MsIGFuZCBhIGA6YCBtdXN0IHNlcGFyYXRlIGVhY2ggcHJvcGVydHlcbiAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIiB8fCB0eXBlb2YgdmFsdWUgIT0gXCJzdHJpbmdcIiB8fCAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgIT0gXCJAXCIgfHwgbGV4KCkgIT0gXCI6XCIpIHtcbiAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdHNbdmFsdWUuc2xpY2UoMSldID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRva2VuIGVuY291bnRlcmVkLlxuICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFVwZGF0ZXMgYSB0cmF2ZXJzZWQgb2JqZWN0IG1lbWJlci5cbiAgICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbihzb3VyY2UsIHByb3BlcnR5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IHdhbGsoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICBpZiAoZWxlbWVudCA9PT0gdW5kZWYpIHtcbiAgICAgICAgICBkZWxldGUgc291cmNlW3Byb3BlcnR5XTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzb3VyY2VbcHJvcGVydHldID0gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBhIHBhcnNlZCBKU09OIG9iamVjdCwgaW52b2tpbmcgdGhlXG4gICAgICAvLyBgY2FsbGJhY2tgIGZ1bmN0aW9uIGZvciBlYWNoIHZhbHVlLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgLy8gYFdhbGsoaG9sZGVyLCBuYW1lKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgIHZhciB3YWxrID0gZnVuY3Rpb24gKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHNvdXJjZVtwcm9wZXJ0eV0sIGxlbmd0aDtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlKSB7XG4gICAgICAgICAgLy8gYGZvckVhY2hgIGNhbid0IGJlIHVzZWQgdG8gdHJhdmVyc2UgYW4gYXJyYXkgaW4gT3BlcmEgPD0gOC41NFxuICAgICAgICAgIC8vIGJlY2F1c2UgaXRzIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIGltcGxlbWVudGF0aW9uIHJldHVybnMgYGZhbHNlYFxuICAgICAgICAgIC8vIGZvciBhcnJheSBpbmRpY2VzIChlLmcuLCBgIVsxLCAyLCAzXS5oYXNPd25Qcm9wZXJ0eShcIjBcIilgKS5cbiAgICAgICAgICBpZiAoZ2V0Q2xhc3MuY2FsbCh2YWx1ZSkgPT0gYXJyYXlDbGFzcykge1xuICAgICAgICAgICAgZm9yIChsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGxlbmd0aC0tOykge1xuICAgICAgICAgICAgICB1cGRhdGUodmFsdWUsIGxlbmd0aCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHNvdXJjZSwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgIH07XG5cbiAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgIEpTT04zLnBhcnNlID0gZnVuY3Rpb24gKHNvdXJjZSwgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHJlc3VsdCwgdmFsdWU7XG4gICAgICAgIEluZGV4ID0gMDtcbiAgICAgICAgU291cmNlID0gXCJcIiArIHNvdXJjZTtcbiAgICAgICAgcmVzdWx0ID0gZ2V0KGxleCgpKTtcbiAgICAgICAgLy8gSWYgYSBKU09OIHN0cmluZyBjb250YWlucyBtdWx0aXBsZSB0b2tlbnMsIGl0IGlzIGludmFsaWQuXG4gICAgICAgIGlmIChsZXgoKSAhPSBcIiRcIikge1xuICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVzZXQgdGhlIHBhcnNlciBzdGF0ZS5cbiAgICAgICAgSW5kZXggPSBTb3VyY2UgPSBudWxsO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sgJiYgZ2V0Q2xhc3MuY2FsbChjYWxsYmFjaykgPT0gZnVuY3Rpb25DbGFzcyA/IHdhbGsoKHZhbHVlID0ge30sIHZhbHVlW1wiXCJdID0gcmVzdWx0LCB2YWx1ZSksIFwiXCIsIGNhbGxiYWNrKSA6IHJlc3VsdDtcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgLy8gRXhwb3J0IGZvciBhc3luY2hyb25vdXMgbW9kdWxlIGxvYWRlcnMuXG4gIGlmIChpc0xvYWRlcikge1xuICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gSlNPTjM7XG4gICAgfSk7XG4gIH1cbn0odGhpcykpO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB0b0FycmF5XG5cbmZ1bmN0aW9uIHRvQXJyYXkobGlzdCwgaW5kZXgpIHtcbiAgICB2YXIgYXJyYXkgPSBbXVxuXG4gICAgaW5kZXggPSBpbmRleCB8fCAwXG5cbiAgICBmb3IgKHZhciBpID0gaW5kZXggfHwgMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJyYXlbaSAtIGluZGV4XSA9IGxpc3RbaV1cbiAgICB9XG5cbiAgICByZXR1cm4gYXJyYXlcbn1cbiIsInZhciB0cmF2ZXJzZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBuZXcgVHJhdmVyc2Uob2JqKTtcbn07XG5cbmZ1bmN0aW9uIFRyYXZlcnNlIChvYmopIHtcbiAgICB0aGlzLnZhbHVlID0gb2JqO1xufVxuXG5UcmF2ZXJzZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBzKSB7XG4gICAgdmFyIG5vZGUgPSB0aGlzLnZhbHVlO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcHMubGVuZ3RoOyBpICsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBwc1tpXTtcbiAgICAgICAgaWYgKCFub2RlIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUsIGtleSkpIHtcbiAgICAgICAgICAgIG5vZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZVtrZXldO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZTtcbn07XG5cblRyYXZlcnNlLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAocHMpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMudmFsdWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcy5sZW5ndGg7IGkgKyspIHtcbiAgICAgICAgdmFyIGtleSA9IHBzW2ldO1xuICAgICAgICBpZiAoIW5vZGUgfHwgIWhhc093blByb3BlcnR5LmNhbGwobm9kZSwga2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIG5vZGUgPSBub2RlW2tleV07XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uIChwcywgdmFsdWUpIHtcbiAgICB2YXIgbm9kZSA9IHRoaXMudmFsdWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcy5sZW5ndGggLSAxOyBpICsrKSB7XG4gICAgICAgIHZhciBrZXkgPSBwc1tpXTtcbiAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eS5jYWxsKG5vZGUsIGtleSkpIG5vZGVba2V5XSA9IHt9O1xuICAgICAgICBub2RlID0gbm9kZVtrZXldO1xuICAgIH1cbiAgICBub2RlW3BzW2ldXSA9IHZhbHVlO1xuICAgIHJldHVybiB2YWx1ZTtcbn07XG5cblRyYXZlcnNlLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICByZXR1cm4gd2Fsayh0aGlzLnZhbHVlLCBjYiwgdHJ1ZSk7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChjYikge1xuICAgIHRoaXMudmFsdWUgPSB3YWxrKHRoaXMudmFsdWUsIGNiLCBmYWxzZSk7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUucmVkdWNlID0gZnVuY3Rpb24gKGNiLCBpbml0KSB7XG4gICAgdmFyIHNraXAgPSBhcmd1bWVudHMubGVuZ3RoID09PSAxO1xuICAgIHZhciBhY2MgPSBza2lwID8gdGhpcy52YWx1ZSA6IGluaXQ7XG4gICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgIGlmICghdGhpcy5pc1Jvb3QgfHwgIXNraXApIHtcbiAgICAgICAgICAgIGFjYyA9IGNiLmNhbGwodGhpcywgYWNjLCB4KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBhY2M7XG59O1xuXG5UcmF2ZXJzZS5wcm90b3R5cGUucGF0aHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoeCkge1xuICAgICAgICBhY2MucHVzaCh0aGlzLnBhdGgpOyBcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLm5vZGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKHgpIHtcbiAgICAgICAgYWNjLnB1c2godGhpcy5ub2RlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWNjO1xufTtcblxuVHJhdmVyc2UucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBwYXJlbnRzID0gW10sIG5vZGVzID0gW107XG4gICAgXG4gICAgcmV0dXJuIChmdW5jdGlvbiBjbG9uZSAoc3JjKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFyZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHBhcmVudHNbaV0gPT09IHNyYykge1xuICAgICAgICAgICAgICAgIHJldHVybiBub2Rlc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYgKHR5cGVvZiBzcmMgPT09ICdvYmplY3QnICYmIHNyYyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdmFyIGRzdCA9IGNvcHkoc3JjKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50cy5wdXNoKHNyYyk7XG4gICAgICAgICAgICBub2Rlcy5wdXNoKGRzdCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvckVhY2gob2JqZWN0S2V5cyhzcmMpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICAgICAgZHN0W2tleV0gPSBjbG9uZShzcmNba2V5XSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcGFyZW50cy5wb3AoKTtcbiAgICAgICAgICAgIG5vZGVzLnBvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIGRzdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzcmM7XG4gICAgICAgIH1cbiAgICB9KSh0aGlzLnZhbHVlKTtcbn07XG5cbmZ1bmN0aW9uIHdhbGsgKHJvb3QsIGNiLCBpbW11dGFibGUpIHtcbiAgICB2YXIgcGF0aCA9IFtdO1xuICAgIHZhciBwYXJlbnRzID0gW107XG4gICAgdmFyIGFsaXZlID0gdHJ1ZTtcbiAgICBcbiAgICByZXR1cm4gKGZ1bmN0aW9uIHdhbGtlciAobm9kZV8pIHtcbiAgICAgICAgdmFyIG5vZGUgPSBpbW11dGFibGUgPyBjb3B5KG5vZGVfKSA6IG5vZGVfO1xuICAgICAgICB2YXIgbW9kaWZpZXJzID0ge307XG4gICAgICAgIFxuICAgICAgICB2YXIga2VlcEdvaW5nID0gdHJ1ZTtcbiAgICAgICAgXG4gICAgICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgICAgICAgIG5vZGUgOiBub2RlLFxuICAgICAgICAgICAgbm9kZV8gOiBub2RlXyxcbiAgICAgICAgICAgIHBhdGggOiBbXS5jb25jYXQocGF0aCksXG4gICAgICAgICAgICBwYXJlbnQgOiBwYXJlbnRzW3BhcmVudHMubGVuZ3RoIC0gMV0sXG4gICAgICAgICAgICBwYXJlbnRzIDogcGFyZW50cyxcbiAgICAgICAgICAgIGtleSA6IHBhdGguc2xpY2UoLTEpWzBdLFxuICAgICAgICAgICAgaXNSb290IDogcGF0aC5sZW5ndGggPT09IDAsXG4gICAgICAgICAgICBsZXZlbCA6IHBhdGgubGVuZ3RoLFxuICAgICAgICAgICAgY2lyY3VsYXIgOiBudWxsLFxuICAgICAgICAgICAgdXBkYXRlIDogZnVuY3Rpb24gKHgsIHN0b3BIZXJlKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5pc1Jvb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUucGFyZW50Lm5vZGVbc3RhdGUua2V5XSA9IHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN0YXRlLm5vZGUgPSB4O1xuICAgICAgICAgICAgICAgIGlmIChzdG9wSGVyZSkga2VlcEdvaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgJ2RlbGV0ZScgOiBmdW5jdGlvbiAoc3RvcEhlcmUpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc3RhdGUucGFyZW50Lm5vZGVbc3RhdGUua2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoc3RvcEhlcmUpIGtlZXBHb2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZSA6IGZ1bmN0aW9uIChzdG9wSGVyZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHN0YXRlLnBhcmVudC5ub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5wYXJlbnQubm9kZS5zcGxpY2Uoc3RhdGUua2V5LCAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBzdGF0ZS5wYXJlbnQubm9kZVtzdGF0ZS5rZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcEhlcmUpIGtlZXBHb2luZyA9IGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGtleXMgOiBudWxsLFxuICAgICAgICAgICAgYmVmb3JlIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLmJlZm9yZSA9IGYgfSxcbiAgICAgICAgICAgIGFmdGVyIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLmFmdGVyID0gZiB9LFxuICAgICAgICAgICAgcHJlIDogZnVuY3Rpb24gKGYpIHsgbW9kaWZpZXJzLnByZSA9IGYgfSxcbiAgICAgICAgICAgIHBvc3QgOiBmdW5jdGlvbiAoZikgeyBtb2RpZmllcnMucG9zdCA9IGYgfSxcbiAgICAgICAgICAgIHN0b3AgOiBmdW5jdGlvbiAoKSB7IGFsaXZlID0gZmFsc2UgfSxcbiAgICAgICAgICAgIGJsb2NrIDogZnVuY3Rpb24gKCkgeyBrZWVwR29pbmcgPSBmYWxzZSB9XG4gICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICBpZiAoIWFsaXZlKSByZXR1cm4gc3RhdGU7XG4gICAgICAgIFxuICAgICAgICBmdW5jdGlvbiB1cGRhdGVTdGF0ZSgpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RhdGUubm9kZSA9PT0gJ29iamVjdCcgJiYgc3RhdGUubm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICghc3RhdGUua2V5cyB8fCBzdGF0ZS5ub2RlXyAhPT0gc3RhdGUubm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5rZXlzID0gb2JqZWN0S2V5cyhzdGF0ZS5ub2RlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBzdGF0ZS5pc0xlYWYgPSBzdGF0ZS5rZXlzLmxlbmd0aCA9PSAwO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFyZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50c1tpXS5ub2RlXyA9PT0gbm9kZV8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmNpcmN1bGFyID0gcGFyZW50c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhdGUuaXNMZWFmID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5rZXlzID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgc3RhdGUubm90TGVhZiA9ICFzdGF0ZS5pc0xlYWY7XG4gICAgICAgICAgICBzdGF0ZS5ub3RSb290ID0gIXN0YXRlLmlzUm9vdDtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgdXBkYXRlU3RhdGUoKTtcbiAgICAgICAgXG4gICAgICAgIC8vIHVzZSByZXR1cm4gdmFsdWVzIHRvIHVwZGF0ZSBpZiBkZWZpbmVkXG4gICAgICAgIHZhciByZXQgPSBjYi5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkICYmIHN0YXRlLnVwZGF0ZSkgc3RhdGUudXBkYXRlKHJldCk7XG4gICAgICAgIFxuICAgICAgICBpZiAobW9kaWZpZXJzLmJlZm9yZSkgbW9kaWZpZXJzLmJlZm9yZS5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgXG4gICAgICAgIGlmICgha2VlcEdvaW5nKSByZXR1cm4gc3RhdGU7XG4gICAgICAgIFxuICAgICAgICBpZiAodHlwZW9mIHN0YXRlLm5vZGUgPT0gJ29iamVjdCdcbiAgICAgICAgJiYgc3RhdGUubm9kZSAhPT0gbnVsbCAmJiAhc3RhdGUuY2lyY3VsYXIpIHtcbiAgICAgICAgICAgIHBhcmVudHMucHVzaChzdGF0ZSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHVwZGF0ZVN0YXRlKCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGZvckVhY2goc3RhdGUua2V5cywgZnVuY3Rpb24gKGtleSwgaSkge1xuICAgICAgICAgICAgICAgIHBhdGgucHVzaChrZXkpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChtb2RpZmllcnMucHJlKSBtb2RpZmllcnMucHJlLmNhbGwoc3RhdGUsIHN0YXRlLm5vZGVba2V5XSwga2V5KTtcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSB3YWxrZXIoc3RhdGUubm9kZVtrZXldKTtcbiAgICAgICAgICAgICAgICBpZiAoaW1tdXRhYmxlICYmIGhhc093blByb3BlcnR5LmNhbGwoc3RhdGUubm9kZSwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZS5ub2RlW2tleV0gPSBjaGlsZC5ub2RlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICBjaGlsZC5pc0xhc3QgPSBpID09IHN0YXRlLmtleXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICBjaGlsZC5pc0ZpcnN0ID0gaSA9PSAwO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChtb2RpZmllcnMucG9zdCkgbW9kaWZpZXJzLnBvc3QuY2FsbChzdGF0ZSwgY2hpbGQpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIHBhdGgucG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhcmVudHMucG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmIChtb2RpZmllcnMuYWZ0ZXIpIG1vZGlmaWVycy5hZnRlci5jYWxsKHN0YXRlLCBzdGF0ZS5ub2RlKTtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9KShyb290KS5ub2RlO1xufVxuXG5mdW5jdGlvbiBjb3B5IChzcmMpIHtcbiAgICBpZiAodHlwZW9mIHNyYyA9PT0gJ29iamVjdCcgJiYgc3JjICE9PSBudWxsKSB7XG4gICAgICAgIHZhciBkc3Q7XG4gICAgICAgIFxuICAgICAgICBpZiAoaXNBcnJheShzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0RhdGUoc3JjKSkge1xuICAgICAgICAgICAgZHN0ID0gbmV3IERhdGUoc3JjLmdldFRpbWUgPyBzcmMuZ2V0VGltZSgpIDogc3JjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1JlZ0V4cChzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSBuZXcgUmVnRXhwKHNyYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNFcnJvcihzcmMpKSB7XG4gICAgICAgICAgICBkc3QgPSB7IG1lc3NhZ2U6IHNyYy5tZXNzYWdlIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNCb29sZWFuKHNyYykpIHtcbiAgICAgICAgICAgIGRzdCA9IG5ldyBCb29sZWFuKHNyYyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNOdW1iZXIoc3JjKSkge1xuICAgICAgICAgICAgZHN0ID0gbmV3IE51bWJlcihzcmMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHNyYykpIHtcbiAgICAgICAgICAgIGRzdCA9IG5ldyBTdHJpbmcoc3JjKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChPYmplY3QuY3JlYXRlICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZikge1xuICAgICAgICAgICAgZHN0ID0gT2JqZWN0LmNyZWF0ZShPYmplY3QuZ2V0UHJvdG90eXBlT2Yoc3JjKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc3JjLmNvbnN0cnVjdG9yID09PSBPYmplY3QpIHtcbiAgICAgICAgICAgIGRzdCA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIHByb3RvID1cbiAgICAgICAgICAgICAgICAoc3JjLmNvbnN0cnVjdG9yICYmIHNyYy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUpXG4gICAgICAgICAgICAgICAgfHwgc3JjLl9fcHJvdG9fX1xuICAgICAgICAgICAgICAgIHx8IHt9XG4gICAgICAgICAgICA7XG4gICAgICAgICAgICB2YXIgVCA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgVC5wcm90b3R5cGUgPSBwcm90bztcbiAgICAgICAgICAgIGRzdCA9IG5ldyBUO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBmb3JFYWNoKG9iamVjdEtleXMoc3JjKSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgZHN0W2tleV0gPSBzcmNba2V5XTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkc3Q7XG4gICAgfVxuICAgIGVsc2UgcmV0dXJuIHNyYztcbn1cblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzIChvYmopIHtcbiAgICB2YXIgcmVzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgcmVzLnB1c2goa2V5KVxuICAgIHJldHVybiByZXM7XG59O1xuXG5mdW5jdGlvbiB0b1MgKG9iaikgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG9iaikgfVxuZnVuY3Rpb24gaXNEYXRlIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBEYXRlXScgfVxuZnVuY3Rpb24gaXNSZWdFeHAgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IFJlZ0V4cF0nIH1cbmZ1bmN0aW9uIGlzRXJyb3IgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IEVycm9yXScgfVxuZnVuY3Rpb24gaXNCb29sZWFuIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBCb29sZWFuXScgfVxuZnVuY3Rpb24gaXNOdW1iZXIgKG9iaikgeyByZXR1cm4gdG9TKG9iaikgPT09ICdbb2JqZWN0IE51bWJlcl0nIH1cbmZ1bmN0aW9uIGlzU3RyaW5nIChvYmopIHsgcmV0dXJuIHRvUyhvYmopID09PSAnW29iamVjdCBTdHJpbmddJyB9XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5ICh4cykge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoeHMpID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGZvckVhY2ggPSBmdW5jdGlvbiAoeHMsIGZuKSB7XG4gICAgaWYgKHhzLmZvckVhY2gpIHJldHVybiB4cy5mb3JFYWNoKGZuKVxuICAgIGVsc2UgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBmbih4c1tpXSwgaSwgeHMpO1xuICAgIH1cbn07XG5cbmZvckVhY2gob2JqZWN0S2V5cyhUcmF2ZXJzZS5wcm90b3R5cGUpLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgdHJhdmVyc2Vba2V5XSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIHZhciB0ID0gbmV3IFRyYXZlcnNlKG9iaik7XG4gICAgICAgIHJldHVybiB0W2tleV0uYXBwbHkodCwgYXJncyk7XG4gICAgfTtcbn0pO1xuXG52YXIgaGFzT3duUHJvcGVydHkgPSBPYmplY3QuaGFzT3duUHJvcGVydHkgfHwgZnVuY3Rpb24gKG9iaiwga2V5KSB7XG4gICAgcmV0dXJuIGtleSBpbiBvYmo7XG59O1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgbGFuZztcblxuICBsYW5nID0gZnVuY3Rpb24obW9tZW50LCBUd2l4KSB7XG4gICAgdmFyIGJlZm9yZTtcbiAgICBiZWZvcmUgPSBtb21lbnQubGFuZygpO1xuICAgIFR3aXgucmVnaXN0ZXJMYW5nKFwiZnJcIiwge1xuICAgICAgdHdlbnR5Rm91ckhvdXI6IHRydWUsXG4gICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMuZGF5Rm9ybWF0ICsgXCIgXCIgKyBvcHRpb25zLm1vbnRoRm9ybWF0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBzbG90OiAzXG4gICAgICB9LFxuICAgICAgbW9udGg6IHtcbiAgICAgICAgc2xvdDogM1xuICAgICAgfSxcbiAgICAgIGRhdGU6IHtcbiAgICAgICAgc2xvdDogMlxuICAgICAgfVxuICAgIH0pO1xuICAgIFR3aXgucmVnaXN0ZXJMYW5nKFwiZnItY2FcIiwge1xuICAgICAgdHdlbnR5Rm91ckhvdXI6IHRydWUsXG4gICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMuZGF5Rm9ybWF0ICsgXCIgXCIgKyBvcHRpb25zLm1vbnRoRm9ybWF0KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9LFxuICAgICAgICBzbG90OiAzXG4gICAgICB9LFxuICAgICAgbW9udGg6IHtcbiAgICAgICAgc2xvdDogM1xuICAgICAgfSxcbiAgICAgIGRhdGU6IHtcbiAgICAgICAgc2xvdDogMlxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtb21lbnQubGFuZyhiZWZvcmUpO1xuICB9O1xuXG4gIGlmICgodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUgIT09IG51bGwpICYmIChtb2R1bGUuZXhwb3J0cyAhPSBudWxsKSkge1xuICAgIG1vZHVsZS5leHBvcnRzID0gbGFuZztcbiAgfVxuXG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXCJtb21lbnRcIiwgXCJ0d2l4XCJdLCBmdW5jdGlvbihtb21lbnQsIFR3aXgpIHtcbiAgICAgIHJldHVybiBsYW5nKG1vbWVudCwgVHdpeCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAodGhpcy5Ud2l4ICYmIHRoaXMubW9tZW50KSB7XG4gICAgbGFuZyh0aGlzLm1vbWVudCwgdGhpcy5Ud2l4KTtcbiAgfVxuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjcuMVxuKGZ1bmN0aW9uKCkge1xuICB2YXIgZGVwcmVjYXRlLCBoYXNNb2R1bGUsIG1ha2VUd2l4LFxuICAgIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuICBoYXNNb2R1bGUgPSAodHlwZW9mIG1vZHVsZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBtb2R1bGUgIT09IG51bGwpICYmIChtb2R1bGUuZXhwb3J0cyAhPSBudWxsKTtcblxuICBkZXByZWNhdGUgPSBmdW5jdGlvbihuYW1lLCBpbnN0ZWFkLCBmbikge1xuICAgIHZhciBhbHJlYWR5RG9uZTtcbiAgICBhbHJlYWR5RG9uZSA9IGZhbHNlO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzO1xuICAgICAgYXJncyA9IDEgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDApIDogW107XG4gICAgICBpZiAoIWFscmVhZHlEb25lKSB7XG4gICAgICAgIGlmICgodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29uc29sZSAhPT0gbnVsbCkgJiYgKGNvbnNvbGUud2FybiAhPSBudWxsKSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcIiNcIiArIG5hbWUgKyBcIiBpcyBkZXByZWNhdGVkLiBVc2UgI1wiICsgaW5zdGVhZCArIFwiIGluc3RlYWQuXCIpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhbHJlYWR5RG9uZSA9IHRydWU7XG4gICAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfTtcbiAgfTtcblxuICBtYWtlVHdpeCA9IGZ1bmN0aW9uKG1vbWVudCkge1xuICAgIHZhciBUd2l4LCBnZXRQcm90b3R5cGVPZiwgbGFuZ3VhZ2VzTG9hZGVkO1xuICAgIGlmIChtb21lbnQgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgXCJDYW4ndCBmaW5kIG1vbWVudFwiO1xuICAgIH1cbiAgICBsYW5ndWFnZXNMb2FkZWQgPSBmYWxzZTtcbiAgICBUd2l4ID0gKGZ1bmN0aW9uKCkge1xuICAgICAgZnVuY3Rpb24gVHdpeChzdGFydCwgZW5kLCBwYXJzZUZvcm1hdCwgb3B0aW9ucykge1xuICAgICAgICB2YXIgX3JlZjtcbiAgICAgICAgaWYgKG9wdGlvbnMgPT0gbnVsbCkge1xuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhcnNlRm9ybWF0ICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IHBhcnNlRm9ybWF0ICE9IG51bGwgPyBwYXJzZUZvcm1hdCA6IHt9O1xuICAgICAgICAgIHBhcnNlRm9ybWF0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIGFsbERheTogb3B0aW9uc1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGFydCA9IG1vbWVudChzdGFydCwgcGFyc2VGb3JtYXQsIG9wdGlvbnMucGFyc2VTdHJpY3QpO1xuICAgICAgICB0aGlzLmVuZCA9IG1vbWVudChlbmQsIHBhcnNlRm9ybWF0LCBvcHRpb25zLnBhcnNlU3RyaWN0KTtcbiAgICAgICAgdGhpcy5hbGxEYXkgPSAoX3JlZiA9IG9wdGlvbnMuYWxsRGF5KSAhPSBudWxsID8gX3JlZiA6IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBUd2l4Ll9leHRlbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGF0dHIsIGZpcnN0LCBvdGhlciwgb3RoZXJzLCBfaSwgX2xlbjtcbiAgICAgICAgZmlyc3QgPSBhcmd1bWVudHNbMF0sIG90aGVycyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpIDogW107XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gb3RoZXJzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgb3RoZXIgPSBvdGhlcnNbX2ldO1xuICAgICAgICAgIGZvciAoYXR0ciBpbiBvdGhlcikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBvdGhlclthdHRyXSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICBmaXJzdFthdHRyXSA9IG90aGVyW2F0dHJdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlyc3Q7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LmRlZmF1bHRzID0ge1xuICAgICAgICB0d2VudHlGb3VySG91cjogZmFsc2UsXG4gICAgICAgIGFsbERheVNpbXBsZToge1xuICAgICAgICAgIGZuOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmFsbERheTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiAwLFxuICAgICAgICAgIHByZTogXCIgXCJcbiAgICAgICAgfSxcbiAgICAgICAgZGF5T2ZXZWVrOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChvcHRpb25zLndlZWtkYXlGb3JtYXQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDEsXG4gICAgICAgICAgcHJlOiBcIiBcIlxuICAgICAgICB9LFxuICAgICAgICBhbGxEYXlNb250aDoge1xuICAgICAgICAgIGZuOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZGF0ZSkge1xuICAgICAgICAgICAgICByZXR1cm4gZGF0ZS5mb3JtYXQoXCJcIiArIG9wdGlvbnMubW9udGhGb3JtYXQgKyBcIiBcIiArIG9wdGlvbnMuZGF5Rm9ybWF0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiAyLFxuICAgICAgICAgIHByZTogXCIgXCJcbiAgICAgICAgfSxcbiAgICAgICAgbW9udGg6IHtcbiAgICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRhdGUuZm9ybWF0KG9wdGlvbnMubW9udGhGb3JtYXQpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDIsXG4gICAgICAgICAgcHJlOiBcIiBcIlxuICAgICAgICB9LFxuICAgICAgICBkYXRlOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBkYXRlLmZvcm1hdChvcHRpb25zLmRheUZvcm1hdCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2xvdDogMyxcbiAgICAgICAgICBwcmU6IFwiIFwiXG4gICAgICAgIH0sXG4gICAgICAgIHllYXI6IHtcbiAgICAgICAgICBmbjogZnVuY3Rpb24ob3B0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGRhdGUuZm9ybWF0KG9wdGlvbnMueWVhckZvcm1hdCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgc2xvdDogNCxcbiAgICAgICAgICBwcmU6IFwiLCBcIlxuICAgICAgICB9LFxuICAgICAgICB0aW1lOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbihkYXRlKSB7XG4gICAgICAgICAgICAgIHZhciBzdHI7XG4gICAgICAgICAgICAgIHN0ciA9IGRhdGUubWludXRlcygpID09PSAwICYmIG9wdGlvbnMuaW1wbGljaXRNaW51dGVzICYmICFvcHRpb25zLnR3ZW50eUZvdXJIb3VyID8gZGF0ZS5mb3JtYXQob3B0aW9ucy5ob3VyRm9ybWF0KSA6IGRhdGUuZm9ybWF0KFwiXCIgKyBvcHRpb25zLmhvdXJGb3JtYXQgKyBcIjpcIiArIG9wdGlvbnMubWludXRlRm9ybWF0KTtcbiAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmdyb3VwTWVyaWRpZW1zICYmICFvcHRpb25zLnR3ZW50eUZvdXJIb3VyKSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc3BhY2VCZWZvcmVNZXJpZGllbSkge1xuICAgICAgICAgICAgICAgICAgc3RyICs9IFwiIFwiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzdHIgKz0gZGF0ZS5mb3JtYXQob3B0aW9ucy5tZXJpZGllbUZvcm1hdCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgICBzbG90OiA1LFxuICAgICAgICAgIHByZTogXCIsIFwiXG4gICAgICAgIH0sXG4gICAgICAgIG1lcmlkaWVtOiB7XG4gICAgICAgICAgZm46IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdC5mb3JtYXQob3B0aW9ucy5tZXJpZGllbUZvcm1hdCk7XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNsb3Q6IDYsXG4gICAgICAgICAgcHJlOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zcGFjZUJlZm9yZU1lcmlkaWVtKSB7XG4gICAgICAgICAgICAgIHJldHVybiBcIiBcIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgVHdpeC5yZWdpc3RlckxhbmcgPSBmdW5jdGlvbihuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBtb21lbnQubGFuZyhuYW1lLCB7XG4gICAgICAgICAgdHdpeDogVHdpeC5fZXh0ZW5kKHt9LCBUd2l4LmRlZmF1bHRzLCBvcHRpb25zKVxuICAgICAgICB9KTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmlzU2FtZSA9IGZ1bmN0aW9uKHBlcmlvZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5pc1NhbWUodGhpcy5lbmQsIHBlcmlvZCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbihwZXJpb2QpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RydWVFbmQodHJ1ZSkuZGlmZih0aGlzLl90cnVlU3RhcnQoKSwgcGVyaW9kKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmNvdW50ID0gZnVuY3Rpb24ocGVyaW9kKSB7XG4gICAgICAgIHZhciBlbmQsIHN0YXJ0O1xuICAgICAgICBzdGFydCA9IHRoaXMuc3RhcnQuY2xvbmUoKS5zdGFydE9mKHBlcmlvZCk7XG4gICAgICAgIGVuZCA9IHRoaXMuZW5kLmNsb25lKCkuc3RhcnRPZihwZXJpb2QpO1xuICAgICAgICByZXR1cm4gZW5kLmRpZmYoc3RhcnQsIHBlcmlvZCkgKyAxO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuY291bnRJbm5lciA9IGZ1bmN0aW9uKHBlcmlvZCkge1xuICAgICAgICB2YXIgZW5kLCBzdGFydCwgX3JlZjtcbiAgICAgICAgX3JlZiA9IHRoaXMuX2lubmVyKHBlcmlvZCksIHN0YXJ0ID0gX3JlZlswXSwgZW5kID0gX3JlZlsxXTtcbiAgICAgICAgaWYgKHN0YXJ0ID49IGVuZCkge1xuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlbmQuZGlmZihzdGFydCwgcGVyaW9kKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLml0ZXJhdGUgPSBmdW5jdGlvbihpbnRlcnZhbEFtb3VudCwgcGVyaW9kLCBtaW5Ib3Vycykge1xuICAgICAgICB2YXIgZW5kLCBoYXNOZXh0LCBzdGFydCwgX3JlZjtcbiAgICAgICAgaWYgKGludGVydmFsQW1vdW50ID09IG51bGwpIHtcbiAgICAgICAgICBpbnRlcnZhbEFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgX3JlZiA9IHRoaXMuX3ByZXBJdGVyYXRlSW5wdXRzKGludGVydmFsQW1vdW50LCBwZXJpb2QsIG1pbkhvdXJzKSwgaW50ZXJ2YWxBbW91bnQgPSBfcmVmWzBdLCBwZXJpb2QgPSBfcmVmWzFdLCBtaW5Ib3VycyA9IF9yZWZbMl07XG4gICAgICAgIHN0YXJ0ID0gdGhpcy5zdGFydC5jbG9uZSgpLnN0YXJ0T2YocGVyaW9kKTtcbiAgICAgICAgZW5kID0gdGhpcy5lbmQuY2xvbmUoKS5zdGFydE9mKHBlcmlvZCk7XG4gICAgICAgIGhhc05leHQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnQgPD0gZW5kICYmICghbWluSG91cnMgfHwgc3RhcnQudmFsdWVPZigpICE9PSBlbmQudmFsdWVPZigpIHx8IF90aGlzLmVuZC5ob3VycygpID4gbWluSG91cnMgfHwgX3RoaXMuYWxsRGF5KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXJhdGVIZWxwZXIocGVyaW9kLCBzdGFydCwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaXRlcmF0ZUlubmVyID0gZnVuY3Rpb24oaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCkge1xuICAgICAgICB2YXIgZW5kLCBoYXNOZXh0LCBzdGFydCwgX3JlZiwgX3JlZjE7XG4gICAgICAgIGlmIChpbnRlcnZhbEFtb3VudCA9PSBudWxsKSB7XG4gICAgICAgICAgaW50ZXJ2YWxBbW91bnQgPSAxO1xuICAgICAgICB9XG4gICAgICAgIF9yZWYgPSB0aGlzLl9wcmVwSXRlcmF0ZUlucHV0cyhpbnRlcnZhbEFtb3VudCwgcGVyaW9kKSwgaW50ZXJ2YWxBbW91bnQgPSBfcmVmWzBdLCBwZXJpb2QgPSBfcmVmWzFdO1xuICAgICAgICBfcmVmMSA9IHRoaXMuX2lubmVyKHBlcmlvZCwgaW50ZXJ2YWxBbW91bnQpLCBzdGFydCA9IF9yZWYxWzBdLCBlbmQgPSBfcmVmMVsxXTtcbiAgICAgICAgaGFzTmV4dCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBzdGFydCA8IGVuZDtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2l0ZXJhdGVIZWxwZXIocGVyaW9kLCBzdGFydCwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaHVtYW5pemVMZW5ndGggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgaWYgKHRoaXMuaXNTYW1lKFwiZGF5XCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJhbGwgZGF5XCI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0LmZyb20odGhpcy5lbmQuY2xvbmUoKS5hZGQoMSwgXCJkYXlcIiksIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5mcm9tKHRoaXMuZW5kLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuYXNEdXJhdGlvbiA9IGZ1bmN0aW9uKHVuaXRzKSB7XG4gICAgICAgIHZhciBkaWZmO1xuICAgICAgICBkaWZmID0gdGhpcy5lbmQuZGlmZih0aGlzLnN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIG1vbWVudC5kdXJhdGlvbihkaWZmKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmlzUGFzdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbmQuY2xvbmUoKS5lbmRPZihcImRheVwiKSA8IG1vbWVudCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVuZCA8IG1vbWVudCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc0Z1dHVyZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5jbG9uZSgpLnN0YXJ0T2YoXCJkYXlcIikgPiBtb21lbnQoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydCA+IG1vbWVudCgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc0N1cnJlbnQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzUGFzdCgpICYmICF0aGlzLmlzRnV0dXJlKCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKG1vbSkge1xuICAgICAgICBtb20gPSBtb21lbnQobW9tKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RydWVTdGFydCgpIDw9IG1vbSAmJiB0aGlzLl90cnVlRW5kKCkgPj0gbW9tO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZVN0YXJ0KCkudmFsdWVPZigpID09PSB0aGlzLl90cnVlRW5kKCkudmFsdWVPZigpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUub3ZlcmxhcHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZUVuZCgpLmlzQWZ0ZXIob3RoZXIuX3RydWVTdGFydCgpKSAmJiB0aGlzLl90cnVlU3RhcnQoKS5pc0JlZm9yZShvdGhlci5fdHJ1ZUVuZCgpKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmVuZ3VsZnMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJ1ZVN0YXJ0KCkgPD0gb3RoZXIuX3RydWVTdGFydCgpICYmIHRoaXMuX3RydWVFbmQoKSA+PSBvdGhlci5fdHJ1ZUVuZCgpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUudW5pb24gPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICB2YXIgYWxsRGF5LCBuZXdFbmQsIG5ld1N0YXJ0O1xuICAgICAgICBhbGxEYXkgPSB0aGlzLmFsbERheSAmJiBvdGhlci5hbGxEYXk7XG4gICAgICAgIGlmIChhbGxEYXkpIHtcbiAgICAgICAgICBuZXdTdGFydCA9IHRoaXMuc3RhcnQgPCBvdGhlci5zdGFydCA/IHRoaXMuc3RhcnQgOiBvdGhlci5zdGFydDtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLmVuZCA+IG90aGVyLmVuZCA/IHRoaXMuZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1N0YXJ0ID0gdGhpcy5fdHJ1ZVN0YXJ0KCkgPCBvdGhlci5fdHJ1ZVN0YXJ0KCkgPyB0aGlzLl90cnVlU3RhcnQoKSA6IG90aGVyLl90cnVlU3RhcnQoKTtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLl90cnVlRW5kKCkgPiBvdGhlci5fdHJ1ZUVuZCgpID8gdGhpcy5fdHJ1ZUVuZCgpIDogb3RoZXIuX3RydWVFbmQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFR3aXgobmV3U3RhcnQsIG5ld0VuZCwgYWxsRGF5KTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICAgIHZhciBhbGxEYXksIGVuZCwgbmV3RW5kLCBuZXdTdGFydDtcbiAgICAgICAgbmV3U3RhcnQgPSB0aGlzLnN0YXJ0ID4gb3RoZXIuc3RhcnQgPyB0aGlzLnN0YXJ0IDogb3RoZXIuc3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSkge1xuICAgICAgICAgIGVuZCA9IG1vbWVudCh0aGlzLmVuZCk7XG4gICAgICAgICAgZW5kLmFkZCgxLCBcImRheVwiKTtcbiAgICAgICAgICBlbmQuc3VidHJhY3QoMSwgXCJtaWxsaXNlY29uZFwiKTtcbiAgICAgICAgICBpZiAob3RoZXIuYWxsRGF5KSB7XG4gICAgICAgICAgICBuZXdFbmQgPSBlbmQgPCBvdGhlci5lbmQgPyB0aGlzLmVuZCA6IG90aGVyLmVuZDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbmV3RW5kID0gZW5kIDwgb3RoZXIuZW5kID8gZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdFbmQgPSB0aGlzLmVuZCA8IG90aGVyLmVuZCA/IHRoaXMuZW5kIDogb3RoZXIuZW5kO1xuICAgICAgICB9XG4gICAgICAgIGFsbERheSA9IHRoaXMuYWxsRGF5ICYmIG90aGVyLmFsbERheTtcbiAgICAgICAgcmV0dXJuIG5ldyBUd2l4KG5ld1N0YXJ0LCBuZXdFbmQsIGFsbERheSk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5pc1ZhbGlkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cnVlU3RhcnQoKSA8PSB0aGlzLl90cnVlRW5kKCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbihvdGhlcikge1xuICAgICAgICByZXR1cm4gKG90aGVyIGluc3RhbmNlb2YgVHdpeCkgJiYgdGhpcy5hbGxEYXkgPT09IG90aGVyLmFsbERheSAmJiB0aGlzLnN0YXJ0LnZhbHVlT2YoKSA9PT0gb3RoZXIuc3RhcnQudmFsdWVPZigpICYmIHRoaXMuZW5kLnZhbHVlT2YoKSA9PT0gb3RoZXIuZW5kLnZhbHVlT2YoKTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBfcmVmO1xuICAgICAgICByZXR1cm4gXCJ7c3RhcnQ6IFwiICsgKHRoaXMuc3RhcnQuZm9ybWF0KCkpICsgXCIsIGVuZDogXCIgKyAodGhpcy5lbmQuZm9ybWF0KCkpICsgXCIsIGFsbERheTogXCIgKyAoKF9yZWYgPSB0aGlzLmFsbERheSkgIT0gbnVsbCA/IF9yZWYgOiB7XG4gICAgICAgICAgXCJ0cnVlXCI6IFwiZmFsc2VcIlxuICAgICAgICB9KSArIFwifVwiO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuc2ltcGxlRm9ybWF0ID0gZnVuY3Rpb24obW9tZW50T3B0cywgaW5vcHRzKSB7XG4gICAgICAgIHZhciBvcHRpb25zLCBzO1xuICAgICAgICBvcHRpb25zID0ge1xuICAgICAgICAgIGFsbERheTogXCIoYWxsIGRheSlcIixcbiAgICAgICAgICB0ZW1wbGF0ZTogVHdpeC5mb3JtYXRUZW1wbGF0ZVxuICAgICAgICB9O1xuICAgICAgICBUd2l4Ll9leHRlbmQob3B0aW9ucywgaW5vcHRzIHx8IHt9KTtcbiAgICAgICAgcyA9IG9wdGlvbnMudGVtcGxhdGUodGhpcy5zdGFydC5mb3JtYXQobW9tZW50T3B0cyksIHRoaXMuZW5kLmZvcm1hdChtb21lbnRPcHRzKSk7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSAmJiBvcHRpb25zLmFsbERheSkge1xuICAgICAgICAgIHMgKz0gXCIgXCIgKyBvcHRpb25zLmFsbERheTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcztcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uKGlub3B0cykge1xuICAgICAgICB2YXIgY29tbW9uX2J1Y2tldCwgZW5kX2J1Y2tldCwgZm9sZCwgZm9ybWF0LCBmcywgZ2xvYmFsX2ZpcnN0LCBnb2VzSW50b1RoZU1vcm5pbmcsIG5lZWREYXRlLCBvcHRpb25zLCBwcm9jZXNzLCBzdGFydF9idWNrZXQsIHRvZ2V0aGVyLCBfaSwgX2xlbjtcbiAgICAgICAgdGhpcy5fbGF6eUxhbmcoKTtcbiAgICAgICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgICBncm91cE1lcmlkaWVtczogdHJ1ZSxcbiAgICAgICAgICBzcGFjZUJlZm9yZU1lcmlkaWVtOiB0cnVlLFxuICAgICAgICAgIHNob3dEYXRlOiB0cnVlLFxuICAgICAgICAgIHNob3dEYXlPZldlZWs6IGZhbHNlLFxuICAgICAgICAgIHR3ZW50eUZvdXJIb3VyOiB0aGlzLmxhbmdEYXRhLnR3ZW50eUZvdXJIb3VyLFxuICAgICAgICAgIGltcGxpY2l0TWludXRlczogdHJ1ZSxcbiAgICAgICAgICBpbXBsaWNpdFllYXI6IHRydWUsXG4gICAgICAgICAgeWVhckZvcm1hdDogXCJZWVlZXCIsXG4gICAgICAgICAgbW9udGhGb3JtYXQ6IFwiTU1NXCIsXG4gICAgICAgICAgd2Vla2RheUZvcm1hdDogXCJkZGRcIixcbiAgICAgICAgICBkYXlGb3JtYXQ6IFwiRFwiLFxuICAgICAgICAgIG1lcmlkaWVtRm9ybWF0OiBcIkFcIixcbiAgICAgICAgICBob3VyRm9ybWF0OiBcImhcIixcbiAgICAgICAgICBtaW51dGVGb3JtYXQ6IFwibW1cIixcbiAgICAgICAgICBhbGxEYXk6IFwiYWxsIGRheVwiLFxuICAgICAgICAgIGV4cGxpY2l0QWxsRGF5OiBmYWxzZSxcbiAgICAgICAgICBsYXN0TmlnaHRFbmRzQXQ6IDAsXG4gICAgICAgICAgdGVtcGxhdGU6IFR3aXguZm9ybWF0VGVtcGxhdGVcbiAgICAgICAgfTtcbiAgICAgICAgVHdpeC5fZXh0ZW5kKG9wdGlvbnMsIGlub3B0cyB8fCB7fSk7XG4gICAgICAgIGZzID0gW107XG4gICAgICAgIGlmIChvcHRpb25zLnR3ZW50eUZvdXJIb3VyKSB7XG4gICAgICAgICAgb3B0aW9ucy5ob3VyRm9ybWF0ID0gb3B0aW9ucy5ob3VyRm9ybWF0LnJlcGxhY2UoXCJoXCIsIFwiSFwiKTtcbiAgICAgICAgfVxuICAgICAgICBnb2VzSW50b1RoZU1vcm5pbmcgPSBvcHRpb25zLmxhc3ROaWdodEVuZHNBdCA+IDAgJiYgIXRoaXMuYWxsRGF5ICYmIHRoaXMuZW5kLmNsb25lKCkuc3RhcnRPZihcImRheVwiKS52YWx1ZU9mKCkgPT09IHRoaXMuc3RhcnQuY2xvbmUoKS5hZGQoMSwgXCJkYXlcIikuc3RhcnRPZihcImRheVwiKS52YWx1ZU9mKCkgJiYgdGhpcy5zdGFydC5ob3VycygpID4gMTIgJiYgdGhpcy5lbmQuaG91cnMoKSA8IG9wdGlvbnMubGFzdE5pZ2h0RW5kc0F0O1xuICAgICAgICBuZWVkRGF0ZSA9IG9wdGlvbnMuc2hvd0RhdGUgfHwgKCF0aGlzLmlzU2FtZShcImRheVwiKSAmJiAhZ29lc0ludG9UaGVNb3JuaW5nKTtcbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5ICYmIHRoaXMuaXNTYW1lKFwiZGF5XCIpICYmICghb3B0aW9ucy5zaG93RGF0ZSB8fCBvcHRpb25zLmV4cGxpY2l0QWxsRGF5KSkge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJhbGwgZGF5IHNpbXBsZVwiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdhbGxEYXlTaW1wbGUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCdhbGxEYXlTaW1wbGUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ2FsbERheVNpbXBsZScpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lZWREYXRlICYmICghb3B0aW9ucy5pbXBsaWNpdFllYXIgfHwgdGhpcy5zdGFydC55ZWFyKCkgIT09IG1vbWVudCgpLnllYXIoKSB8fCAhdGhpcy5pc1NhbWUoXCJ5ZWFyXCIpKSkge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJ5ZWFyXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ3llYXInLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCd5ZWFyJywgb3B0aW9ucyksXG4gICAgICAgICAgICBzbG90OiB0aGlzLl9mb3JtYXRTbG90KCd5ZWFyJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuYWxsRGF5ICYmIG5lZWREYXRlKSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcImFsbCBkYXkgbW9udGhcIixcbiAgICAgICAgICAgIGZuOiB0aGlzLl9mb3JtYXRGbignYWxsRGF5TW9udGgnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIGlnbm9yZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIHJldHVybiBnb2VzSW50b1RoZU1vcm5pbmc7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcHJlOiB0aGlzLl9mb3JtYXRQcmUoJ2FsbERheU1vbnRoJywgb3B0aW9ucyksXG4gICAgICAgICAgICBzbG90OiB0aGlzLl9mb3JtYXRTbG90KCdhbGxEYXlNb250aCcpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYWxsRGF5ICYmIG5lZWREYXRlKSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcIm1vbnRoXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ21vbnRoJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnbW9udGgnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ21vbnRoJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbGxEYXkgJiYgbmVlZERhdGUpIHtcbiAgICAgICAgICBmcy5wdXNoKHtcbiAgICAgICAgICAgIG5hbWU6IFwiZGF0ZVwiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdkYXRlJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnZGF0ZScsIG9wdGlvbnMpLFxuICAgICAgICAgICAgc2xvdDogdGhpcy5fZm9ybWF0U2xvdCgnZGF0ZScpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5lZWREYXRlICYmIG9wdGlvbnMuc2hvd0RheU9mV2Vlaykge1xuICAgICAgICAgIGZzLnB1c2goe1xuICAgICAgICAgICAgbmFtZTogXCJkYXkgb2Ygd2Vla1wiLFxuICAgICAgICAgICAgZm46IHRoaXMuX2Zvcm1hdEZuKCdkYXlPZldlZWsnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHByZTogdGhpcy5fZm9ybWF0UHJlKCdkYXlPZldlZWsnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ2RheU9mV2VlaycpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuZ3JvdXBNZXJpZGllbXMgJiYgIW9wdGlvbnMudHdlbnR5Rm91ckhvdXIgJiYgIXRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcIm1lcmlkaWVtXCIsXG4gICAgICAgICAgICBmbjogdGhpcy5fZm9ybWF0Rm4oJ21lcmlkaWVtJywgb3B0aW9ucyksXG4gICAgICAgICAgICBwcmU6IHRoaXMuX2Zvcm1hdFByZSgnbWVyaWRpZW0nLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ21lcmlkaWVtJylcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuYWxsRGF5KSB7XG4gICAgICAgICAgZnMucHVzaCh7XG4gICAgICAgICAgICBuYW1lOiBcInRpbWVcIixcbiAgICAgICAgICAgIGZuOiB0aGlzLl9mb3JtYXRGbigndGltZScsIG9wdGlvbnMpLFxuICAgICAgICAgICAgcHJlOiB0aGlzLl9mb3JtYXRQcmUoJ3RpbWUnLCBvcHRpb25zKSxcbiAgICAgICAgICAgIHNsb3Q6IHRoaXMuX2Zvcm1hdFNsb3QoJ3RpbWUnKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0X2J1Y2tldCA9IFtdO1xuICAgICAgICBlbmRfYnVja2V0ID0gW107XG4gICAgICAgIGNvbW1vbl9idWNrZXQgPSBbXTtcbiAgICAgICAgdG9nZXRoZXIgPSB0cnVlO1xuICAgICAgICBwcm9jZXNzID0gKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGZvcm1hdCkge1xuICAgICAgICAgICAgdmFyIGVuZF9zdHIsIHN0YXJ0X2dyb3VwLCBzdGFydF9zdHI7XG4gICAgICAgICAgICBzdGFydF9zdHIgPSBmb3JtYXQuZm4oX3RoaXMuc3RhcnQpO1xuICAgICAgICAgICAgZW5kX3N0ciA9IGZvcm1hdC5pZ25vcmVFbmQgJiYgZm9ybWF0Lmlnbm9yZUVuZCgpID8gc3RhcnRfc3RyIDogZm9ybWF0LmZuKF90aGlzLmVuZCk7XG4gICAgICAgICAgICBzdGFydF9ncm91cCA9IHtcbiAgICAgICAgICAgICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RhcnRfc3RyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGVuZF9zdHIgPT09IHN0YXJ0X3N0ciAmJiB0b2dldGhlcikge1xuICAgICAgICAgICAgICByZXR1cm4gY29tbW9uX2J1Y2tldC5wdXNoKHN0YXJ0X2dyb3VwKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICh0b2dldGhlcikge1xuICAgICAgICAgICAgICAgIHRvZ2V0aGVyID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgY29tbW9uX2J1Y2tldC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIGZvcm1hdDoge1xuICAgICAgICAgICAgICAgICAgICBzbG90OiBmb3JtYXQuc2xvdCxcbiAgICAgICAgICAgICAgICAgICAgcHJlOiBcIlwiXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy50ZW1wbGF0ZShmb2xkKHN0YXJ0X2J1Y2tldCksIGZvbGQoZW5kX2J1Y2tldCwgdHJ1ZSkudHJpbSgpKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzdGFydF9idWNrZXQucHVzaChzdGFydF9ncm91cCk7XG4gICAgICAgICAgICAgIHJldHVybiBlbmRfYnVja2V0LnB1c2goe1xuICAgICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlbmRfc3RyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcyk7XG4gICAgICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZnMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgICBmb3JtYXQgPSBmc1tfaV07XG4gICAgICAgICAgcHJvY2Vzcyhmb3JtYXQpO1xuICAgICAgICB9XG4gICAgICAgIGdsb2JhbF9maXJzdCA9IHRydWU7XG4gICAgICAgIGZvbGQgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYXJyYXksIHNraXBfcHJlKSB7XG4gICAgICAgICAgICB2YXIgbG9jYWxfZmlyc3QsIHNlY3Rpb24sIHN0ciwgX2osIF9sZW4xLCBfcmVmO1xuICAgICAgICAgICAgbG9jYWxfZmlyc3QgPSB0cnVlO1xuICAgICAgICAgICAgc3RyID0gXCJcIjtcbiAgICAgICAgICAgIF9yZWYgPSBhcnJheS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGEuZm9ybWF0LnNsb3QgLSBiLmZvcm1hdC5zbG90O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmb3IgKF9qID0gMCwgX2xlbjEgPSBfcmVmLmxlbmd0aDsgX2ogPCBfbGVuMTsgX2orKykge1xuICAgICAgICAgICAgICBzZWN0aW9uID0gX3JlZltfal07XG4gICAgICAgICAgICAgIGlmICghZ2xvYmFsX2ZpcnN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGxvY2FsX2ZpcnN0ICYmIHNraXBfcHJlKSB7XG4gICAgICAgICAgICAgICAgICBzdHIgKz0gXCIgXCI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHN0ciArPSBzZWN0aW9uLmZvcm1hdC5wcmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0ciArPSBzZWN0aW9uLnZhbHVlKCk7XG4gICAgICAgICAgICAgIGdsb2JhbF9maXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgICBsb2NhbF9maXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHN0cjtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIGZvbGQoY29tbW9uX2J1Y2tldCk7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fdHJ1ZVN0YXJ0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmFsbERheSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0LmNsb25lKCkuc3RhcnRPZihcImRheVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydC5jbG9uZSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fdHJ1ZUVuZCA9IGZ1bmN0aW9uKGRpZmZhYmxlRW5kKSB7XG4gICAgICAgIGlmIChkaWZmYWJsZUVuZCA9PSBudWxsKSB7XG4gICAgICAgICAgZGlmZmFibGVFbmQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbGxEYXkpIHtcbiAgICAgICAgICBpZiAoZGlmZmFibGVFbmQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVuZC5jbG9uZSgpLmFkZCgxLCBcImRheVwiKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW5kLmNsb25lKCkuZW5kT2YoXCJkYXlcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVuZC5jbG9uZSgpO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5faXRlcmF0ZUhlbHBlciA9IGZ1bmN0aW9uKHBlcmlvZCwgaXRlciwgaGFzTmV4dCwgaW50ZXJ2YWxBbW91bnQpIHtcbiAgICAgICAgaWYgKGludGVydmFsQW1vdW50ID09IG51bGwpIHtcbiAgICAgICAgICBpbnRlcnZhbEFtb3VudCA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuZXh0OiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHZhbDtcbiAgICAgICAgICAgICAgaWYgKCFoYXNOZXh0KCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWwgPSBpdGVyLmNsb25lKCk7XG4gICAgICAgICAgICAgICAgaXRlci5hZGQoaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSh0aGlzKSxcbiAgICAgICAgICBoYXNOZXh0OiBoYXNOZXh0XG4gICAgICAgIH07XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fcHJlcEl0ZXJhdGVJbnB1dHMgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGlucHV0cywgaW50ZXJ2YWxBbW91bnQsIG1pbkhvdXJzLCBwZXJpb2QsIF9yZWYsIF9yZWYxO1xuICAgICAgICBpbnB1dHMgPSAxIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSA6IFtdO1xuICAgICAgICBpZiAodHlwZW9mIGlucHV0c1swXSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICByZXR1cm4gaW5wdXRzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXRzWzBdID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHBlcmlvZCA9IGlucHV0cy5zaGlmdCgpO1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gKF9yZWYgPSBpbnB1dHMucG9wKCkpICE9IG51bGwgPyBfcmVmIDogMTtcbiAgICAgICAgICBpZiAoaW5wdXRzLmxlbmd0aCkge1xuICAgICAgICAgICAgbWluSG91cnMgPSAoX3JlZjEgPSBpbnB1dHNbMF0pICE9IG51bGwgPyBfcmVmMSA6IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAobW9tZW50LmlzRHVyYXRpb24oaW5wdXRzWzBdKSkge1xuICAgICAgICAgIHBlcmlvZCA9ICdtaWxsaXNlY29uZHMnO1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gaW5wdXRzWzBdLmFzKHBlcmlvZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtpbnRlcnZhbEFtb3VudCwgcGVyaW9kLCBtaW5Ib3Vyc107XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5faW5uZXIgPSBmdW5jdGlvbihwZXJpb2QsIGludGVydmFsQW1vdW50KSB7XG4gICAgICAgIHZhciBkdXJhdGlvbkNvdW50LCBkdXJhdGlvblBlcmlvZCwgZW5kLCBtb2R1bHVzLCBzdGFydDtcbiAgICAgICAgaWYgKHBlcmlvZCA9PSBudWxsKSB7XG4gICAgICAgICAgcGVyaW9kID0gXCJtaWxsaXNlY29uZHNcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW50ZXJ2YWxBbW91bnQgPT0gbnVsbCkge1xuICAgICAgICAgIGludGVydmFsQW1vdW50ID0gMTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCA9IHRoaXMuX3RydWVTdGFydCgpO1xuICAgICAgICBlbmQgPSB0aGlzLl90cnVlRW5kKHRydWUpO1xuICAgICAgICBpZiAoc3RhcnQgPiBzdGFydC5jbG9uZSgpLnN0YXJ0T2YocGVyaW9kKSkge1xuICAgICAgICAgIHN0YXJ0LnN0YXJ0T2YocGVyaW9kKS5hZGQoaW50ZXJ2YWxBbW91bnQsIHBlcmlvZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZCA8IGVuZC5jbG9uZSgpLmVuZE9mKHBlcmlvZCkpIHtcbiAgICAgICAgICBlbmQuc3RhcnRPZihwZXJpb2QpO1xuICAgICAgICB9XG4gICAgICAgIGR1cmF0aW9uUGVyaW9kID0gc3RhcnQudHdpeChlbmQpLmFzRHVyYXRpb24ocGVyaW9kKTtcbiAgICAgICAgZHVyYXRpb25Db3VudCA9IGR1cmF0aW9uUGVyaW9kLmdldChwZXJpb2QpO1xuICAgICAgICBtb2R1bHVzID0gZHVyYXRpb25Db3VudCAlIGludGVydmFsQW1vdW50O1xuICAgICAgICBlbmQuc3VidHJhY3QobW9kdWx1cywgcGVyaW9kKTtcbiAgICAgICAgcmV0dXJuIFtzdGFydCwgZW5kXTtcbiAgICAgIH07XG5cbiAgICAgIFR3aXgucHJvdG90eXBlLl9sYXp5TGFuZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgZSwgbGFuZ0RhdGEsIGxhbmd1YWdlcywgX3JlZjtcbiAgICAgICAgbGFuZ0RhdGEgPSB0aGlzLnN0YXJ0LmxhbmcoKTtcbiAgICAgICAgaWYgKChsYW5nRGF0YSAhPSBudWxsKSAmJiB0aGlzLmVuZC5sYW5nKCkuX2FiYnIgIT09IGxhbmdEYXRhLl9hYmJyKSB7XG4gICAgICAgICAgdGhpcy5lbmQubGFuZyhsYW5nRGF0YS5fYWJicik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCh0aGlzLmxhbmdEYXRhICE9IG51bGwpICYmIHRoaXMubGFuZ0RhdGEuX2FiYnIgPT09IGxhbmdEYXRhLl9hYmJyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNNb2R1bGUgJiYgIShsYW5ndWFnZXNMb2FkZWQgfHwgbGFuZ0RhdGEuX2FiYnIgPT09IFwiZW5cIikpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGFuZ3VhZ2VzID0gcmVxdWlyZShcIi4vbGFuZ1wiKTtcbiAgICAgICAgICAgIGxhbmd1YWdlcyhtb21lbnQsIFR3aXgpO1xuICAgICAgICAgIH0gY2F0Y2ggKF9lcnJvcikge1xuICAgICAgICAgICAgZSA9IF9lcnJvcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgbGFuZ3VhZ2VzTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5sYW5nRGF0YSA9IChfcmVmID0gbGFuZ0RhdGEgIT0gbnVsbCA/IGxhbmdEYXRhLl90d2l4IDogdm9pZCAwKSAhPSBudWxsID8gX3JlZiA6IFR3aXguZGVmYXVsdHM7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fZm9ybWF0Rm4gPSBmdW5jdGlvbihuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhbmdEYXRhW25hbWVdLmZuKG9wdGlvbnMpO1xuICAgICAgfTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuX2Zvcm1hdFNsb3QgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxhbmdEYXRhW25hbWVdLnNsb3Q7XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5fZm9ybWF0UHJlID0gZnVuY3Rpb24obmFtZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMubGFuZ0RhdGFbbmFtZV0ucHJlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5sYW5nRGF0YVtuYW1lXS5wcmUob3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMubGFuZ0RhdGFbbmFtZV0ucHJlO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5zYW1lRGF5ID0gZGVwcmVjYXRlKFwic2FtZURheVwiLCBcImlzU2FtZSgnZGF5JylcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU2FtZShcImRheVwiKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5zYW1lWWVhciA9IGRlcHJlY2F0ZShcInNhbWVZZWFyXCIsIFwiaXNTYW1lKCd5ZWFyJylcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzU2FtZShcInllYXJcIik7XG4gICAgICB9KTtcblxuICAgICAgVHdpeC5wcm90b3R5cGUuY291bnREYXlzID0gZGVwcmVjYXRlKFwiY291bnREYXlzXCIsIFwiY291bnRPdXRlcignZGF5cycpXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb3VudE91dGVyKFwiZGF5c1wiKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5kYXlzSW4gPSBkZXByZWNhdGUoXCJkYXlzSW5cIiwgXCJpdGVyYXRlKCdkYXlzJyBbLG1pbkhvdXJzXSlcIiwgZnVuY3Rpb24obWluSG91cnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlcmF0ZSgnZGF5cycsIG1pbkhvdXJzKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5wYXN0ID0gZGVwcmVjYXRlKFwicGFzdFwiLCBcImlzUGFzdCgpXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc1Bhc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5kdXJhdGlvbiA9IGRlcHJlY2F0ZShcImR1cmF0aW9uXCIsIFwiaHVtYW5pemVMZW5ndGgoKVwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaHVtYW5pemVMZW5ndGgoKTtcbiAgICAgIH0pO1xuXG4gICAgICBUd2l4LnByb3RvdHlwZS5tZXJnZSA9IGRlcHJlY2F0ZShcIm1lcmdlXCIsIFwidW5pb24ob3RoZXIpXCIsIGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuaW9uKG90aGVyKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gVHdpeDtcblxuICAgIH0pKCk7XG4gICAgZ2V0UHJvdG90eXBlT2YgPSBmdW5jdGlvbihvKSB7XG4gICAgICBpZiAodHlwZW9mIE9iamVjdC5nZXRQcm90b3R5cGVPZiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2Yobyk7XG4gICAgICB9IGVsc2UgaWYgKFwiXCIuX19wcm90b19fID09PSBTdHJpbmcucHJvdG90eXBlKSB7XG4gICAgICAgIHJldHVybiBvLl9fcHJvdG9fXztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBvLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIFR3aXguX2V4dGVuZChtb21lbnQuX2xvY2FsZSB8fCBnZXRQcm90b3R5cGVPZihtb21lbnQuZm4uX2xhbmcpLCB7XG4gICAgICBfdHdpeDogVHdpeC5kZWZhdWx0c1xuICAgIH0pO1xuICAgIFR3aXguZm9ybWF0VGVtcGxhdGUgPSBmdW5jdGlvbihsZWZ0U2lkZSwgcmlnaHRTaWRlKSB7XG4gICAgICByZXR1cm4gXCJcIiArIGxlZnRTaWRlICsgXCIgLSBcIiArIHJpZ2h0U2lkZTtcbiAgICB9O1xuICAgIG1vbWVudC50d2l4ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gKGZ1bmN0aW9uKGZ1bmMsIGFyZ3MsIGN0b3IpIHtcbiAgICAgICAgY3Rvci5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcbiAgICAgICAgdmFyIGNoaWxkID0gbmV3IGN0b3IsIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY2hpbGQsIGFyZ3MpO1xuICAgICAgICByZXR1cm4gT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCA/IHJlc3VsdCA6IGNoaWxkO1xuICAgICAgfSkoVHdpeCwgYXJndW1lbnRzLCBmdW5jdGlvbigpe30pO1xuICAgIH07XG4gICAgbW9tZW50LmZuLnR3aXggPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiAoZnVuY3Rpb24oZnVuYywgYXJncywgY3Rvcikge1xuICAgICAgICBjdG9yLnByb3RvdHlwZSA9IGZ1bmMucHJvdG90eXBlO1xuICAgICAgICB2YXIgY2hpbGQgPSBuZXcgY3RvciwgcmVzdWx0ID0gZnVuYy5hcHBseShjaGlsZCwgYXJncyk7XG4gICAgICAgIHJldHVybiBPYmplY3QocmVzdWx0KSA9PT0gcmVzdWx0ID8gcmVzdWx0IDogY2hpbGQ7XG4gICAgICB9KShUd2l4LCBbdGhpc10uY29uY2F0KF9fc2xpY2UuY2FsbChhcmd1bWVudHMpKSwgZnVuY3Rpb24oKXt9KTtcbiAgICB9O1xuICAgIG1vbWVudC5mbi5mb3JEdXJhdGlvbiA9IGZ1bmN0aW9uKGR1cmF0aW9uLCBhbGxEYXkpIHtcbiAgICAgIHJldHVybiBuZXcgVHdpeCh0aGlzLCB0aGlzLmNsb25lKCkuYWRkKGR1cmF0aW9uKSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5hZnRlck1vbWVudCA9IGZ1bmN0aW9uKHN0YXJ0aW5nVGltZSwgYWxsRGF5KSB7XG4gICAgICByZXR1cm4gbmV3IFR3aXgoc3RhcnRpbmdUaW1lLCBtb21lbnQoc3RhcnRpbmdUaW1lKS5jbG9uZSgpLmFkZCh0aGlzKSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC5kdXJhdGlvbi5mbi5iZWZvcmVNb21lbnQgPSBmdW5jdGlvbihzdGFydGluZ1RpbWUsIGFsbERheSkge1xuICAgICAgcmV0dXJuIG5ldyBUd2l4KG1vbWVudChzdGFydGluZ1RpbWUpLmNsb25lKCkuc3VidHJhY3QodGhpcyksIHN0YXJ0aW5nVGltZSwgYWxsRGF5KTtcbiAgICB9O1xuICAgIG1vbWVudC50d2l4Q2xhc3MgPSBUd2l4O1xuICAgIHJldHVybiBUd2l4O1xuICB9O1xuXG4gIGlmIChoYXNNb2R1bGUpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IG1ha2VUd2l4KHJlcXVpcmUoXCJtb21lbnRcIikpO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGRlZmluZShcInR3aXhcIiwgW1wibW9tZW50XCJdLCBmdW5jdGlvbihtb21lbnQpIHtcbiAgICAgIHJldHVybiBtYWtlVHdpeChtb21lbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHRoaXMubW9tZW50ICE9IG51bGwpIHtcbiAgICB0aGlzLlR3aXggPSBtYWtlVHdpeCh0aGlzLm1vbWVudCk7XG4gIH1cblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vICAgICBVbmRlcnNjb3JlLmpzIDEuNS4yXG4vLyAgICAgaHR0cDovL3VuZGVyc2NvcmVqcy5vcmdcbi8vICAgICAoYykgMjAwOS0yMDEzIEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4vLyAgICAgVW5kZXJzY29yZSBtYXkgYmUgZnJlZWx5IGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBNSVQgbGljZW5zZS5cblxuKGZ1bmN0aW9uKCkge1xuXG4gIC8vIEJhc2VsaW5lIHNldHVwXG4gIC8vIC0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gRXN0YWJsaXNoIHRoZSByb290IG9iamVjdCwgYHdpbmRvd2AgaW4gdGhlIGJyb3dzZXIsIG9yIGBleHBvcnRzYCBvbiB0aGUgc2VydmVyLlxuICB2YXIgcm9vdCA9IHRoaXM7XG5cbiAgLy8gU2F2ZSB0aGUgcHJldmlvdXMgdmFsdWUgb2YgdGhlIGBfYCB2YXJpYWJsZS5cbiAgdmFyIHByZXZpb3VzVW5kZXJzY29yZSA9IHJvb3QuXztcblxuICAvLyBFc3RhYmxpc2ggdGhlIG9iamVjdCB0aGF0IGdldHMgcmV0dXJuZWQgdG8gYnJlYWsgb3V0IG9mIGEgbG9vcCBpdGVyYXRpb24uXG4gIHZhciBicmVha2VyID0ge307XG5cbiAgLy8gU2F2ZSBieXRlcyBpbiB0aGUgbWluaWZpZWQgKGJ1dCBub3QgZ3ppcHBlZCkgdmVyc2lvbjpcbiAgdmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGUsIE9ialByb3RvID0gT2JqZWN0LnByb3RvdHlwZSwgRnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIC8vIENyZWF0ZSBxdWljayByZWZlcmVuY2UgdmFyaWFibGVzIGZvciBzcGVlZCBhY2Nlc3MgdG8gY29yZSBwcm90b3R5cGVzLlxuICB2YXJcbiAgICBwdXNoICAgICAgICAgICAgID0gQXJyYXlQcm90by5wdXNoLFxuICAgIHNsaWNlICAgICAgICAgICAgPSBBcnJheVByb3RvLnNsaWNlLFxuICAgIGNvbmNhdCAgICAgICAgICAgPSBBcnJheVByb3RvLmNvbmNhdCxcbiAgICB0b1N0cmluZyAgICAgICAgID0gT2JqUHJvdG8udG9TdHJpbmcsXG4gICAgaGFzT3duUHJvcGVydHkgICA9IE9ialByb3RvLmhhc093blByb3BlcnR5O1xuXG4gIC8vIEFsbCAqKkVDTUFTY3JpcHQgNSoqIG5hdGl2ZSBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgdGhhdCB3ZSBob3BlIHRvIHVzZVxuICAvLyBhcmUgZGVjbGFyZWQgaGVyZS5cbiAgdmFyXG4gICAgbmF0aXZlRm9yRWFjaCAgICAgID0gQXJyYXlQcm90by5mb3JFYWNoLFxuICAgIG5hdGl2ZU1hcCAgICAgICAgICA9IEFycmF5UHJvdG8ubWFwLFxuICAgIG5hdGl2ZVJlZHVjZSAgICAgICA9IEFycmF5UHJvdG8ucmVkdWNlLFxuICAgIG5hdGl2ZVJlZHVjZVJpZ2h0ICA9IEFycmF5UHJvdG8ucmVkdWNlUmlnaHQsXG4gICAgbmF0aXZlRmlsdGVyICAgICAgID0gQXJyYXlQcm90by5maWx0ZXIsXG4gICAgbmF0aXZlRXZlcnkgICAgICAgID0gQXJyYXlQcm90by5ldmVyeSxcbiAgICBuYXRpdmVTb21lICAgICAgICAgPSBBcnJheVByb3RvLnNvbWUsXG4gICAgbmF0aXZlSW5kZXhPZiAgICAgID0gQXJyYXlQcm90by5pbmRleE9mLFxuICAgIG5hdGl2ZUxhc3RJbmRleE9mICA9IEFycmF5UHJvdG8ubGFzdEluZGV4T2YsXG4gICAgbmF0aXZlSXNBcnJheSAgICAgID0gQXJyYXkuaXNBcnJheSxcbiAgICBuYXRpdmVLZXlzICAgICAgICAgPSBPYmplY3Qua2V5cyxcbiAgICBuYXRpdmVCaW5kICAgICAgICAgPSBGdW5jUHJvdG8uYmluZDtcblxuICAvLyBDcmVhdGUgYSBzYWZlIHJlZmVyZW5jZSB0byB0aGUgVW5kZXJzY29yZSBvYmplY3QgZm9yIHVzZSBiZWxvdy5cbiAgdmFyIF8gPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqIGluc3RhbmNlb2YgXykgcmV0dXJuIG9iajtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgXykpIHJldHVybiBuZXcgXyhvYmopO1xuICAgIHRoaXMuX3dyYXBwZWQgPSBvYmo7XG4gIH07XG5cbiAgLy8gRXhwb3J0IHRoZSBVbmRlcnNjb3JlIG9iamVjdCBmb3IgKipOb2RlLmpzKiosIHdpdGhcbiAgLy8gYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgZm9yIHRoZSBvbGQgYHJlcXVpcmUoKWAgQVBJLiBJZiB3ZSdyZSBpblxuICAvLyB0aGUgYnJvd3NlciwgYWRkIGBfYCBhcyBhIGdsb2JhbCBvYmplY3QgdmlhIGEgc3RyaW5nIGlkZW50aWZpZXIsXG4gIC8vIGZvciBDbG9zdXJlIENvbXBpbGVyIFwiYWR2YW5jZWRcIiBtb2RlLlxuICBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBfO1xuICAgIH1cbiAgICBleHBvcnRzLl8gPSBfO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuXyA9IF87XG4gIH1cblxuICAvLyBDdXJyZW50IHZlcnNpb24uXG4gIF8uVkVSU0lPTiA9ICcxLjUuMic7XG5cbiAgLy8gQ29sbGVjdGlvbiBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBUaGUgY29ybmVyc3RvbmUsIGFuIGBlYWNoYCBpbXBsZW1lbnRhdGlvbiwgYWthIGBmb3JFYWNoYC5cbiAgLy8gSGFuZGxlcyBvYmplY3RzIHdpdGggdGhlIGJ1aWx0LWluIGBmb3JFYWNoYCwgYXJyYXlzLCBhbmQgcmF3IG9iamVjdHMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBmb3JFYWNoYCBpZiBhdmFpbGFibGUuXG4gIHZhciBlYWNoID0gXy5lYWNoID0gXy5mb3JFYWNoID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuO1xuICAgIGlmIChuYXRpdmVGb3JFYWNoICYmIG9iai5mb3JFYWNoID09PSBuYXRpdmVGb3JFYWNoKSB7XG4gICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iai5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaikgPT09IGJyZWFrZXIpIHJldHVybjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9ialtrZXlzW2ldXSwga2V5c1tpXSwgb2JqKSA9PT0gYnJlYWtlcikgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIHJlc3VsdHMgb2YgYXBwbHlpbmcgdGhlIGl0ZXJhdG9yIHRvIGVhY2ggZWxlbWVudC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYG1hcGAgaWYgYXZhaWxhYmxlLlxuICBfLm1hcCA9IF8uY29sbGVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdHM7XG4gICAgaWYgKG5hdGl2ZU1hcCAmJiBvYmoubWFwID09PSBuYXRpdmVNYXApIHJldHVybiBvYmoubWFwKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICB2YXIgcmVkdWNlRXJyb3IgPSAnUmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZSc7XG5cbiAgLy8gKipSZWR1Y2UqKiBidWlsZHMgdXAgYSBzaW5nbGUgcmVzdWx0IGZyb20gYSBsaXN0IG9mIHZhbHVlcywgYWthIGBpbmplY3RgLFxuICAvLyBvciBgZm9sZGxgLiBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgcmVkdWNlYCBpZiBhdmFpbGFibGUuXG4gIF8ucmVkdWNlID0gXy5mb2xkbCA9IF8uaW5qZWN0ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgbWVtbywgY29udGV4dCkge1xuICAgIHZhciBpbml0aWFsID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgaWYgKG9iaiA9PSBudWxsKSBvYmogPSBbXTtcbiAgICBpZiAobmF0aXZlUmVkdWNlICYmIG9iai5yZWR1Y2UgPT09IG5hdGl2ZVJlZHVjZSkge1xuICAgICAgaWYgKGNvbnRleHQpIGl0ZXJhdG9yID0gXy5iaW5kKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICAgIHJldHVybiBpbml0aWFsID8gb2JqLnJlZHVjZShpdGVyYXRvciwgbWVtbykgOiBvYmoucmVkdWNlKGl0ZXJhdG9yKTtcbiAgICB9XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKCFpbml0aWFsKSB7XG4gICAgICAgIG1lbW8gPSB2YWx1ZTtcbiAgICAgICAgaW5pdGlhbCA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZW1vID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBtZW1vLCB2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghaW5pdGlhbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihyZWR1Y2VFcnJvcik7XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gVGhlIHJpZ2h0LWFzc29jaWF0aXZlIHZlcnNpb24gb2YgcmVkdWNlLCBhbHNvIGtub3duIGFzIGBmb2xkcmAuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGByZWR1Y2VSaWdodGAgaWYgYXZhaWxhYmxlLlxuICBfLnJlZHVjZVJpZ2h0ID0gXy5mb2xkciA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIG1lbW8sIGNvbnRleHQpIHtcbiAgICB2YXIgaW5pdGlhbCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xuICAgIGlmIChvYmogPT0gbnVsbCkgb2JqID0gW107XG4gICAgaWYgKG5hdGl2ZVJlZHVjZVJpZ2h0ICYmIG9iai5yZWR1Y2VSaWdodCA9PT0gbmF0aXZlUmVkdWNlUmlnaHQpIHtcbiAgICAgIGlmIChjb250ZXh0KSBpdGVyYXRvciA9IF8uYmluZChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgICByZXR1cm4gaW5pdGlhbCA/IG9iai5yZWR1Y2VSaWdodChpdGVyYXRvciwgbWVtbykgOiBvYmoucmVkdWNlUmlnaHQoaXRlcmF0b3IpO1xuICAgIH1cbiAgICB2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoICE9PSArbGVuZ3RoKSB7XG4gICAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgICAgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgfVxuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIGluZGV4ID0ga2V5cyA/IGtleXNbLS1sZW5ndGhdIDogLS1sZW5ndGg7XG4gICAgICBpZiAoIWluaXRpYWwpIHtcbiAgICAgICAgbWVtbyA9IG9ialtpbmRleF07XG4gICAgICAgIGluaXRpYWwgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWVtbyA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgbWVtbywgb2JqW2luZGV4XSwgaW5kZXgsIGxpc3QpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghaW5pdGlhbCkgdGhyb3cgbmV3IFR5cGVFcnJvcihyZWR1Y2VFcnJvcik7XG4gICAgcmV0dXJuIG1lbW87XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBmaXJzdCB2YWx1ZSB3aGljaCBwYXNzZXMgYSB0cnV0aCB0ZXN0LiBBbGlhc2VkIGFzIGBkZXRlY3RgLlxuICBfLmZpbmQgPSBfLmRldGVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIGFueShvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkge1xuICAgICAgICByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyB0aGF0IHBhc3MgYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgZmlsdGVyYCBpZiBhdmFpbGFibGUuXG4gIC8vIEFsaWFzZWQgYXMgYHNlbGVjdGAuXG4gIF8uZmlsdGVyID0gXy5zZWxlY3QgPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHRzO1xuICAgIGlmIChuYXRpdmVGaWx0ZXIgJiYgb2JqLmZpbHRlciA9PT0gbmF0aXZlRmlsdGVyKSByZXR1cm4gb2JqLmZpbHRlcihpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBmb3Igd2hpY2ggYSB0cnV0aCB0ZXN0IGZhaWxzLlxuICBfLnJlamVjdCA9IGZ1bmN0aW9uKG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gXy5maWx0ZXIob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiAhaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpO1xuICAgIH0sIGNvbnRleHQpO1xuICB9O1xuXG4gIC8vIERldGVybWluZSB3aGV0aGVyIGFsbCBvZiB0aGUgZWxlbWVudHMgbWF0Y2ggYSB0cnV0aCB0ZXN0LlxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgZXZlcnlgIGlmIGF2YWlsYWJsZS5cbiAgLy8gQWxpYXNlZCBhcyBgYWxsYC5cbiAgXy5ldmVyeSA9IF8uYWxsID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yIHx8IChpdGVyYXRvciA9IF8uaWRlbnRpdHkpO1xuICAgIHZhciByZXN1bHQgPSB0cnVlO1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHJlc3VsdDtcbiAgICBpZiAobmF0aXZlRXZlcnkgJiYgb2JqLmV2ZXJ5ID09PSBuYXRpdmVFdmVyeSkgcmV0dXJuIG9iai5ldmVyeShpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKCEocmVzdWx0ID0gcmVzdWx0ICYmIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSkpIHJldHVybiBicmVha2VyO1xuICAgIH0pO1xuICAgIHJldHVybiAhIXJlc3VsdDtcbiAgfTtcblxuICAvLyBEZXRlcm1pbmUgaWYgYXQgbGVhc3Qgb25lIGVsZW1lbnQgaW4gdGhlIG9iamVjdCBtYXRjaGVzIGEgdHJ1dGggdGVzdC5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYHNvbWVgIGlmIGF2YWlsYWJsZS5cbiAgLy8gQWxpYXNlZCBhcyBgYW55YC5cbiAgdmFyIGFueSA9IF8uc29tZSA9IF8uYW55ID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yIHx8IChpdGVyYXRvciA9IF8uaWRlbnRpdHkpO1xuICAgIHZhciByZXN1bHQgPSBmYWxzZTtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiByZXN1bHQ7XG4gICAgaWYgKG5hdGl2ZVNvbWUgJiYgb2JqLnNvbWUgPT09IG5hdGl2ZVNvbWUpIHJldHVybiBvYmouc29tZShpdGVyYXRvciwgY29udGV4dCk7XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgaWYgKHJlc3VsdCB8fCAocmVzdWx0ID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpKSkgcmV0dXJuIGJyZWFrZXI7XG4gICAgfSk7XG4gICAgcmV0dXJuICEhcmVzdWx0O1xuICB9O1xuXG4gIC8vIERldGVybWluZSBpZiB0aGUgYXJyYXkgb3Igb2JqZWN0IGNvbnRhaW5zIGEgZ2l2ZW4gdmFsdWUgKHVzaW5nIGA9PT1gKS5cbiAgLy8gQWxpYXNlZCBhcyBgaW5jbHVkZWAuXG4gIF8uY29udGFpbnMgPSBfLmluY2x1ZGUgPSBmdW5jdGlvbihvYmosIHRhcmdldCkge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChuYXRpdmVJbmRleE9mICYmIG9iai5pbmRleE9mID09PSBuYXRpdmVJbmRleE9mKSByZXR1cm4gb2JqLmluZGV4T2YodGFyZ2V0KSAhPSAtMTtcbiAgICByZXR1cm4gYW55KG9iaiwgZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSA9PT0gdGFyZ2V0O1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIEludm9rZSBhIG1ldGhvZCAod2l0aCBhcmd1bWVudHMpIG9uIGV2ZXJ5IGl0ZW0gaW4gYSBjb2xsZWN0aW9uLlxuICBfLmludm9rZSA9IGZ1bmN0aW9uKG9iaiwgbWV0aG9kKSB7XG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgdmFyIGlzRnVuYyA9IF8uaXNGdW5jdGlvbihtZXRob2QpO1xuICAgIHJldHVybiBfLm1hcChvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gKGlzRnVuYyA/IG1ldGhvZCA6IHZhbHVlW21ldGhvZF0pLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBtYXBgOiBmZXRjaGluZyBhIHByb3BlcnR5LlxuICBfLnBsdWNrID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSl7IHJldHVybiB2YWx1ZVtrZXldOyB9KTtcbiAgfTtcblxuICAvLyBDb252ZW5pZW5jZSB2ZXJzaW9uIG9mIGEgY29tbW9uIHVzZSBjYXNlIG9mIGBmaWx0ZXJgOiBzZWxlY3Rpbmcgb25seSBvYmplY3RzXG4gIC8vIGNvbnRhaW5pbmcgc3BlY2lmaWMgYGtleTp2YWx1ZWAgcGFpcnMuXG4gIF8ud2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzLCBmaXJzdCkge1xuICAgIGlmIChfLmlzRW1wdHkoYXR0cnMpKSByZXR1cm4gZmlyc3QgPyB2b2lkIDAgOiBbXTtcbiAgICByZXR1cm4gX1tmaXJzdCA/ICdmaW5kJyA6ICdmaWx0ZXInXShvYmosIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBmb3IgKHZhciBrZXkgaW4gYXR0cnMpIHtcbiAgICAgICAgaWYgKGF0dHJzW2tleV0gIT09IHZhbHVlW2tleV0pIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIENvbnZlbmllbmNlIHZlcnNpb24gb2YgYSBjb21tb24gdXNlIGNhc2Ugb2YgYGZpbmRgOiBnZXR0aW5nIHRoZSBmaXJzdCBvYmplY3RcbiAgLy8gY29udGFpbmluZyBzcGVjaWZpYyBga2V5OnZhbHVlYCBwYWlycy5cbiAgXy5maW5kV2hlcmUgPSBmdW5jdGlvbihvYmosIGF0dHJzKSB7XG4gICAgcmV0dXJuIF8ud2hlcmUob2JqLCBhdHRycywgdHJ1ZSk7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBtYXhpbXVtIGVsZW1lbnQgb3IgKGVsZW1lbnQtYmFzZWQgY29tcHV0YXRpb24pLlxuICAvLyBDYW4ndCBvcHRpbWl6ZSBhcnJheXMgb2YgaW50ZWdlcnMgbG9uZ2VyIHRoYW4gNjUsNTM1IGVsZW1lbnRzLlxuICAvLyBTZWUgW1dlYktpdCBCdWcgODA3OTddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD04MDc5NylcbiAgXy5tYXggPSBmdW5jdGlvbihvYmosIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKCFpdGVyYXRvciAmJiBfLmlzQXJyYXkob2JqKSAmJiBvYmpbMF0gPT09ICtvYmpbMF0gJiYgb2JqLmxlbmd0aCA8IDY1NTM1KSB7XG4gICAgICByZXR1cm4gTWF0aC5tYXguYXBwbHkoTWF0aCwgb2JqKTtcbiAgICB9XG4gICAgaWYgKCFpdGVyYXRvciAmJiBfLmlzRW1wdHkob2JqKSkgcmV0dXJuIC1JbmZpbml0eTtcbiAgICB2YXIgcmVzdWx0ID0ge2NvbXB1dGVkIDogLUluZmluaXR5LCB2YWx1ZTogLUluZmluaXR5fTtcbiAgICBlYWNoKG9iaiwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBsaXN0KSB7XG4gICAgICB2YXIgY29tcHV0ZWQgPSBpdGVyYXRvciA/IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBsaXN0KSA6IHZhbHVlO1xuICAgICAgY29tcHV0ZWQgPiByZXN1bHQuY29tcHV0ZWQgJiYgKHJlc3VsdCA9IHt2YWx1ZSA6IHZhbHVlLCBjb21wdXRlZCA6IGNvbXB1dGVkfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdC52YWx1ZTtcbiAgfTtcblxuICAvLyBSZXR1cm4gdGhlIG1pbmltdW0gZWxlbWVudCAob3IgZWxlbWVudC1iYXNlZCBjb21wdXRhdGlvbikuXG4gIF8ubWluID0gZnVuY3Rpb24ob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGlmICghaXRlcmF0b3IgJiYgXy5pc0FycmF5KG9iaikgJiYgb2JqWzBdID09PSArb2JqWzBdICYmIG9iai5sZW5ndGggPCA2NTUzNSkge1xuICAgICAgcmV0dXJuIE1hdGgubWluLmFwcGx5KE1hdGgsIG9iaik7XG4gICAgfVxuICAgIGlmICghaXRlcmF0b3IgJiYgXy5pc0VtcHR5KG9iaikpIHJldHVybiBJbmZpbml0eTtcbiAgICB2YXIgcmVzdWx0ID0ge2NvbXB1dGVkIDogSW5maW5pdHksIHZhbHVlOiBJbmZpbml0eX07XG4gICAgZWFjaChvYmosIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgbGlzdCkge1xuICAgICAgdmFyIGNvbXB1dGVkID0gaXRlcmF0b3IgPyBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgbGlzdCkgOiB2YWx1ZTtcbiAgICAgIGNvbXB1dGVkIDwgcmVzdWx0LmNvbXB1dGVkICYmIChyZXN1bHQgPSB7dmFsdWUgOiB2YWx1ZSwgY29tcHV0ZWQgOiBjb21wdXRlZH0pO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQudmFsdWU7XG4gIH07XG5cbiAgLy8gU2h1ZmZsZSBhbiBhcnJheSwgdXNpbmcgdGhlIG1vZGVybiB2ZXJzaW9uIG9mIHRoZSBcbiAgLy8gW0Zpc2hlci1ZYXRlcyBzaHVmZmxlXShodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0Zpc2hlcuKAk1lhdGVzX3NodWZmbGUpLlxuICBfLnNodWZmbGUgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmFuZDtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBzaHVmZmxlZCA9IFtdO1xuICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmFuZCA9IF8ucmFuZG9tKGluZGV4KyspO1xuICAgICAgc2h1ZmZsZWRbaW5kZXggLSAxXSA9IHNodWZmbGVkW3JhbmRdO1xuICAgICAgc2h1ZmZsZWRbcmFuZF0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gc2h1ZmZsZWQ7XG4gIH07XG5cbiAgLy8gU2FtcGxlICoqbioqIHJhbmRvbSB2YWx1ZXMgZnJvbSBhbiBhcnJheS5cbiAgLy8gSWYgKipuKiogaXMgbm90IHNwZWNpZmllZCwgcmV0dXJucyBhIHNpbmdsZSByYW5kb20gZWxlbWVudCBmcm9tIHRoZSBhcnJheS5cbiAgLy8gVGhlIGludGVybmFsIGBndWFyZGAgYXJndW1lbnQgYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgbWFwYC5cbiAgXy5zYW1wbGUgPSBmdW5jdGlvbihvYmosIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyIHx8IGd1YXJkKSB7XG4gICAgICByZXR1cm4gb2JqW18ucmFuZG9tKG9iai5sZW5ndGggLSAxKV07XG4gICAgfVxuICAgIHJldHVybiBfLnNodWZmbGUob2JqKS5zbGljZSgwLCBNYXRoLm1heCgwLCBuKSk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgbG9va3VwIGl0ZXJhdG9ycy5cbiAgdmFyIGxvb2t1cEl0ZXJhdG9yID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlIDogZnVuY3Rpb24ob2JqKXsgcmV0dXJuIG9ialt2YWx1ZV07IH07XG4gIH07XG5cbiAgLy8gU29ydCB0aGUgb2JqZWN0J3MgdmFsdWVzIGJ5IGEgY3JpdGVyaW9uIHByb2R1Y2VkIGJ5IGFuIGl0ZXJhdG9yLlxuICBfLnNvcnRCeSA9IGZ1bmN0aW9uKG9iaiwgdmFsdWUsIGNvbnRleHQpIHtcbiAgICB2YXIgaXRlcmF0b3IgPSBsb29rdXBJdGVyYXRvcih2YWx1ZSk7XG4gICAgcmV0dXJuIF8ucGx1Y2soXy5tYXAob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGxpc3QpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgaW5kZXg6IGluZGV4LFxuICAgICAgICBjcml0ZXJpYTogaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIGxpc3QpXG4gICAgICB9O1xuICAgIH0pLnNvcnQoZnVuY3Rpb24obGVmdCwgcmlnaHQpIHtcbiAgICAgIHZhciBhID0gbGVmdC5jcml0ZXJpYTtcbiAgICAgIHZhciBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICBpZiAoYSAhPT0gYikge1xuICAgICAgICBpZiAoYSA+IGIgfHwgYSA9PT0gdm9pZCAwKSByZXR1cm4gMTtcbiAgICAgICAgaWYgKGEgPCBiIHx8IGIgPT09IHZvaWQgMCkgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxlZnQuaW5kZXggLSByaWdodC5pbmRleDtcbiAgICB9KSwgJ3ZhbHVlJyk7XG4gIH07XG5cbiAgLy8gQW4gaW50ZXJuYWwgZnVuY3Rpb24gdXNlZCBmb3IgYWdncmVnYXRlIFwiZ3JvdXAgYnlcIiBvcGVyYXRpb25zLlxuICB2YXIgZ3JvdXAgPSBmdW5jdGlvbihiZWhhdmlvcikge1xuICAgIHJldHVybiBmdW5jdGlvbihvYmosIHZhbHVlLCBjb250ZXh0KSB7XG4gICAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgICB2YXIgaXRlcmF0b3IgPSB2YWx1ZSA9PSBudWxsID8gXy5pZGVudGl0eSA6IGxvb2t1cEl0ZXJhdG9yKHZhbHVlKTtcbiAgICAgIGVhY2gob2JqLCBmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgICAgdmFyIGtleSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCBvYmopO1xuICAgICAgICBiZWhhdmlvcihyZXN1bHQsIGtleSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gR3JvdXBzIHRoZSBvYmplY3QncyB2YWx1ZXMgYnkgYSBjcml0ZXJpb24uIFBhc3MgZWl0aGVyIGEgc3RyaW5nIGF0dHJpYnV0ZVxuICAvLyB0byBncm91cCBieSwgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGNyaXRlcmlvbi5cbiAgXy5ncm91cEJ5ID0gZ3JvdXAoZnVuY3Rpb24ocmVzdWx0LCBrZXksIHZhbHVlKSB7XG4gICAgKF8uaGFzKHJlc3VsdCwga2V5KSA/IHJlc3VsdFtrZXldIDogKHJlc3VsdFtrZXldID0gW10pKS5wdXNoKHZhbHVlKTtcbiAgfSk7XG5cbiAgLy8gSW5kZXhlcyB0aGUgb2JqZWN0J3MgdmFsdWVzIGJ5IGEgY3JpdGVyaW9uLCBzaW1pbGFyIHRvIGBncm91cEJ5YCwgYnV0IGZvclxuICAvLyB3aGVuIHlvdSBrbm93IHRoYXQgeW91ciBpbmRleCB2YWx1ZXMgd2lsbCBiZSB1bmlxdWUuXG4gIF8uaW5kZXhCeSA9IGdyb3VwKGZ1bmN0aW9uKHJlc3VsdCwga2V5LCB2YWx1ZSkge1xuICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gIH0pO1xuXG4gIC8vIENvdW50cyBpbnN0YW5jZXMgb2YgYW4gb2JqZWN0IHRoYXQgZ3JvdXAgYnkgYSBjZXJ0YWluIGNyaXRlcmlvbi4gUGFzc1xuICAvLyBlaXRoZXIgYSBzdHJpbmcgYXR0cmlidXRlIHRvIGNvdW50IGJ5LCBvciBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGVcbiAgLy8gY3JpdGVyaW9uLlxuICBfLmNvdW50QnkgPSBncm91cChmdW5jdGlvbihyZXN1bHQsIGtleSkge1xuICAgIF8uaGFzKHJlc3VsdCwga2V5KSA/IHJlc3VsdFtrZXldKysgOiByZXN1bHRba2V5XSA9IDE7XG4gIH0pO1xuXG4gIC8vIFVzZSBhIGNvbXBhcmF0b3IgZnVuY3Rpb24gdG8gZmlndXJlIG91dCB0aGUgc21hbGxlc3QgaW5kZXggYXQgd2hpY2hcbiAgLy8gYW4gb2JqZWN0IHNob3VsZCBiZSBpbnNlcnRlZCBzbyBhcyB0byBtYWludGFpbiBvcmRlci4gVXNlcyBiaW5hcnkgc2VhcmNoLlxuICBfLnNvcnRlZEluZGV4ID0gZnVuY3Rpb24oYXJyYXksIG9iaiwgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yID09IG51bGwgPyBfLmlkZW50aXR5IDogbG9va3VwSXRlcmF0b3IoaXRlcmF0b3IpO1xuICAgIHZhciB2YWx1ZSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgb2JqKTtcbiAgICB2YXIgbG93ID0gMCwgaGlnaCA9IGFycmF5Lmxlbmd0aDtcbiAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgdmFyIG1pZCA9IChsb3cgKyBoaWdoKSA+Pj4gMTtcbiAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgYXJyYXlbbWlkXSkgPCB2YWx1ZSA/IGxvdyA9IG1pZCArIDEgOiBoaWdoID0gbWlkO1xuICAgIH1cbiAgICByZXR1cm4gbG93O1xuICB9O1xuXG4gIC8vIFNhZmVseSBjcmVhdGUgYSByZWFsLCBsaXZlIGFycmF5IGZyb20gYW55dGhpbmcgaXRlcmFibGUuXG4gIF8udG9BcnJheSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmICghb2JqKSByZXR1cm4gW107XG4gICAgaWYgKF8uaXNBcnJheShvYmopKSByZXR1cm4gc2xpY2UuY2FsbChvYmopO1xuICAgIGlmIChvYmoubGVuZ3RoID09PSArb2JqLmxlbmd0aCkgcmV0dXJuIF8ubWFwKG9iaiwgXy5pZGVudGl0eSk7XG4gICAgcmV0dXJuIF8udmFsdWVzKG9iaik7XG4gIH07XG5cbiAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgaW4gYW4gb2JqZWN0LlxuICBfLnNpemUgPSBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqID09IG51bGwpIHJldHVybiAwO1xuICAgIHJldHVybiAob2JqLmxlbmd0aCA9PT0gK29iai5sZW5ndGgpID8gb2JqLmxlbmd0aCA6IF8ua2V5cyhvYmopLmxlbmd0aDtcbiAgfTtcblxuICAvLyBBcnJheSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gR2V0IHRoZSBmaXJzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBOXG4gIC8vIHZhbHVlcyBpbiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYGhlYWRgIGFuZCBgdGFrZWAuIFRoZSAqKmd1YXJkKiogY2hlY2tcbiAgLy8gYWxsb3dzIGl0IHRvIHdvcmsgd2l0aCBgXy5tYXBgLlxuICBfLmZpcnN0ID0gXy5oZWFkID0gXy50YWtlID0gZnVuY3Rpb24oYXJyYXksIG4sIGd1YXJkKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgcmV0dXJuIChuID09IG51bGwpIHx8IGd1YXJkID8gYXJyYXlbMF0gOiBzbGljZS5jYWxsKGFycmF5LCAwLCBuKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBsYXN0IGVudHJ5IG9mIHRoZSBhcnJheS4gRXNwZWNpYWxseSB1c2VmdWwgb25cbiAgLy8gdGhlIGFyZ3VtZW50cyBvYmplY3QuIFBhc3NpbmcgKipuKiogd2lsbCByZXR1cm4gYWxsIHRoZSB2YWx1ZXMgaW5cbiAgLy8gdGhlIGFycmF5LCBleGNsdWRpbmcgdGhlIGxhc3QgTi4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoXG4gIC8vIGBfLm1hcGAuXG4gIF8uaW5pdGlhbCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAwLCBhcnJheS5sZW5ndGggLSAoKG4gPT0gbnVsbCkgfHwgZ3VhcmQgPyAxIDogbikpO1xuICB9O1xuXG4gIC8vIEdldCB0aGUgbGFzdCBlbGVtZW50IG9mIGFuIGFycmF5LiBQYXNzaW5nICoqbioqIHdpbGwgcmV0dXJuIHRoZSBsYXN0IE5cbiAgLy8gdmFsdWVzIGluIHRoZSBhcnJheS4gVGhlICoqZ3VhcmQqKiBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8ubGFzdCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gdm9pZCAwO1xuICAgIGlmICgobiA9PSBudWxsKSB8fCBndWFyZCkge1xuICAgICAgcmV0dXJuIGFycmF5W2FycmF5Lmxlbmd0aCAtIDFdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc2xpY2UuY2FsbChhcnJheSwgTWF0aC5tYXgoYXJyYXkubGVuZ3RoIC0gbiwgMCkpO1xuICAgIH1cbiAgfTtcblxuICAvLyBSZXR1cm5zIGV2ZXJ5dGhpbmcgYnV0IHRoZSBmaXJzdCBlbnRyeSBvZiB0aGUgYXJyYXkuIEFsaWFzZWQgYXMgYHRhaWxgIGFuZCBgZHJvcGAuXG4gIC8vIEVzcGVjaWFsbHkgdXNlZnVsIG9uIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBQYXNzaW5nIGFuICoqbioqIHdpbGwgcmV0dXJuXG4gIC8vIHRoZSByZXN0IE4gdmFsdWVzIGluIHRoZSBhcnJheS4gVGhlICoqZ3VhcmQqKlxuICAvLyBjaGVjayBhbGxvd3MgaXQgdG8gd29yayB3aXRoIGBfLm1hcGAuXG4gIF8ucmVzdCA9IF8udGFpbCA9IF8uZHJvcCA9IGZ1bmN0aW9uKGFycmF5LCBuLCBndWFyZCkge1xuICAgIHJldHVybiBzbGljZS5jYWxsKGFycmF5LCAobiA9PSBudWxsKSB8fCBndWFyZCA/IDEgOiBuKTtcbiAgfTtcblxuICAvLyBUcmltIG91dCBhbGwgZmFsc3kgdmFsdWVzIGZyb20gYW4gYXJyYXkuXG4gIF8uY29tcGFjdCA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgcmV0dXJuIF8uZmlsdGVyKGFycmF5LCBfLmlkZW50aXR5KTtcbiAgfTtcblxuICAvLyBJbnRlcm5hbCBpbXBsZW1lbnRhdGlvbiBvZiBhIHJlY3Vyc2l2ZSBgZmxhdHRlbmAgZnVuY3Rpb24uXG4gIHZhciBmbGF0dGVuID0gZnVuY3Rpb24oaW5wdXQsIHNoYWxsb3csIG91dHB1dCkge1xuICAgIGlmIChzaGFsbG93ICYmIF8uZXZlcnkoaW5wdXQsIF8uaXNBcnJheSkpIHtcbiAgICAgIHJldHVybiBjb25jYXQuYXBwbHkob3V0cHV0LCBpbnB1dCk7XG4gICAgfVxuICAgIGVhY2goaW5wdXQsIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoXy5pc0FycmF5KHZhbHVlKSB8fCBfLmlzQXJndW1lbnRzKHZhbHVlKSkge1xuICAgICAgICBzaGFsbG93ID8gcHVzaC5hcHBseShvdXRwdXQsIHZhbHVlKSA6IGZsYXR0ZW4odmFsdWUsIHNoYWxsb3csIG91dHB1dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQucHVzaCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfTtcblxuICAvLyBGbGF0dGVuIG91dCBhbiBhcnJheSwgZWl0aGVyIHJlY3Vyc2l2ZWx5IChieSBkZWZhdWx0KSwgb3IganVzdCBvbmUgbGV2ZWwuXG4gIF8uZmxhdHRlbiA9IGZ1bmN0aW9uKGFycmF5LCBzaGFsbG93KSB7XG4gICAgcmV0dXJuIGZsYXR0ZW4oYXJyYXksIHNoYWxsb3csIFtdKTtcbiAgfTtcblxuICAvLyBSZXR1cm4gYSB2ZXJzaW9uIG9mIHRoZSBhcnJheSB0aGF0IGRvZXMgbm90IGNvbnRhaW4gdGhlIHNwZWNpZmllZCB2YWx1ZShzKS5cbiAgXy53aXRob3V0ID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICByZXR1cm4gXy5kaWZmZXJlbmNlKGFycmF5LCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICB9O1xuXG4gIC8vIFByb2R1Y2UgYSBkdXBsaWNhdGUtZnJlZSB2ZXJzaW9uIG9mIHRoZSBhcnJheS4gSWYgdGhlIGFycmF5IGhhcyBhbHJlYWR5XG4gIC8vIGJlZW4gc29ydGVkLCB5b3UgaGF2ZSB0aGUgb3B0aW9uIG9mIHVzaW5nIGEgZmFzdGVyIGFsZ29yaXRobS5cbiAgLy8gQWxpYXNlZCBhcyBgdW5pcXVlYC5cbiAgXy51bmlxID0gXy51bmlxdWUgPSBmdW5jdGlvbihhcnJheSwgaXNTb3J0ZWQsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaWYgKF8uaXNGdW5jdGlvbihpc1NvcnRlZCkpIHtcbiAgICAgIGNvbnRleHQgPSBpdGVyYXRvcjtcbiAgICAgIGl0ZXJhdG9yID0gaXNTb3J0ZWQ7XG4gICAgICBpc1NvcnRlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB2YXIgaW5pdGlhbCA9IGl0ZXJhdG9yID8gXy5tYXAoYXJyYXksIGl0ZXJhdG9yLCBjb250ZXh0KSA6IGFycmF5O1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdmFyIHNlZW4gPSBbXTtcbiAgICBlYWNoKGluaXRpYWwsIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKGlzU29ydGVkID8gKCFpbmRleCB8fCBzZWVuW3NlZW4ubGVuZ3RoIC0gMV0gIT09IHZhbHVlKSA6ICFfLmNvbnRhaW5zKHNlZW4sIHZhbHVlKSkge1xuICAgICAgICBzZWVuLnB1c2godmFsdWUpO1xuICAgICAgICByZXN1bHRzLnB1c2goYXJyYXlbaW5kZXhdKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdGhlIHVuaW9uOiBlYWNoIGRpc3RpbmN0IGVsZW1lbnQgZnJvbSBhbGwgb2ZcbiAgLy8gdGhlIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8udW5pb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXy51bmlxKF8uZmxhdHRlbihhcmd1bWVudHMsIHRydWUpKTtcbiAgfTtcblxuICAvLyBQcm9kdWNlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgZXZlcnkgaXRlbSBzaGFyZWQgYmV0d2VlbiBhbGwgdGhlXG4gIC8vIHBhc3NlZC1pbiBhcnJheXMuXG4gIF8uaW50ZXJzZWN0aW9uID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gXy5maWx0ZXIoXy51bmlxKGFycmF5KSwgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgcmV0dXJuIF8uZXZlcnkocmVzdCwgZnVuY3Rpb24ob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIF8uaW5kZXhPZihvdGhlciwgaXRlbSkgPj0gMDtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIFRha2UgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBvbmUgYXJyYXkgYW5kIGEgbnVtYmVyIG9mIG90aGVyIGFycmF5cy5cbiAgLy8gT25seSB0aGUgZWxlbWVudHMgcHJlc2VudCBpbiBqdXN0IHRoZSBmaXJzdCBhcnJheSB3aWxsIHJlbWFpbi5cbiAgXy5kaWZmZXJlbmNlID0gZnVuY3Rpb24oYXJyYXkpIHtcbiAgICB2YXIgcmVzdCA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIHJldHVybiBfLmZpbHRlcihhcnJheSwgZnVuY3Rpb24odmFsdWUpeyByZXR1cm4gIV8uY29udGFpbnMocmVzdCwgdmFsdWUpOyB9KTtcbiAgfTtcblxuICAvLyBaaXAgdG9nZXRoZXIgbXVsdGlwbGUgbGlzdHMgaW50byBhIHNpbmdsZSBhcnJheSAtLSBlbGVtZW50cyB0aGF0IHNoYXJlXG4gIC8vIGFuIGluZGV4IGdvIHRvZ2V0aGVyLlxuICBfLnppcCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBsZW5ndGggPSBfLm1heChfLnBsdWNrKGFyZ3VtZW50cywgXCJsZW5ndGhcIikuY29uY2F0KDApKTtcbiAgICB2YXIgcmVzdWx0cyA9IG5ldyBBcnJheShsZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHJlc3VsdHNbaV0gPSBfLnBsdWNrKGFyZ3VtZW50cywgJycgKyBpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH07XG5cbiAgLy8gQ29udmVydHMgbGlzdHMgaW50byBvYmplY3RzLiBQYXNzIGVpdGhlciBhIHNpbmdsZSBhcnJheSBvZiBgW2tleSwgdmFsdWVdYFxuICAvLyBwYWlycywgb3IgdHdvIHBhcmFsbGVsIGFycmF5cyBvZiB0aGUgc2FtZSBsZW5ndGggLS0gb25lIG9mIGtleXMsIGFuZCBvbmUgb2ZcbiAgLy8gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWVzLlxuICBfLm9iamVjdCA9IGZ1bmN0aW9uKGxpc3QsIHZhbHVlcykge1xuICAgIGlmIChsaXN0ID09IG51bGwpIHJldHVybiB7fTtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGxpc3QubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh2YWx1ZXMpIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1dID0gdmFsdWVzW2ldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0W2xpc3RbaV1bMF1dID0gbGlzdFtpXVsxXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICAvLyBJZiB0aGUgYnJvd3NlciBkb2Vzbid0IHN1cHBseSB1cyB3aXRoIGluZGV4T2YgKEknbSBsb29raW5nIGF0IHlvdSwgKipNU0lFKiopLFxuICAvLyB3ZSBuZWVkIHRoaXMgZnVuY3Rpb24uIFJldHVybiB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW5cbiAgLy8gaXRlbSBpbiBhbiBhcnJheSwgb3IgLTEgaWYgdGhlIGl0ZW0gaXMgbm90IGluY2x1ZGVkIGluIHRoZSBhcnJheS5cbiAgLy8gRGVsZWdhdGVzIHRvICoqRUNNQVNjcmlwdCA1KioncyBuYXRpdmUgYGluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgLy8gSWYgdGhlIGFycmF5IGlzIGxhcmdlIGFuZCBhbHJlYWR5IGluIHNvcnQgb3JkZXIsIHBhc3MgYHRydWVgXG4gIC8vIGZvciAqKmlzU29ydGVkKiogdG8gdXNlIGJpbmFyeSBzZWFyY2guXG4gIF8uaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBpc1NvcnRlZCkge1xuICAgIGlmIChhcnJheSA9PSBudWxsKSByZXR1cm4gLTE7XG4gICAgdmFyIGkgPSAwLCBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gICAgaWYgKGlzU29ydGVkKSB7XG4gICAgICBpZiAodHlwZW9mIGlzU29ydGVkID09ICdudW1iZXInKSB7XG4gICAgICAgIGkgPSAoaXNTb3J0ZWQgPCAwID8gTWF0aC5tYXgoMCwgbGVuZ3RoICsgaXNTb3J0ZWQpIDogaXNTb3J0ZWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IF8uc29ydGVkSW5kZXgoYXJyYXksIGl0ZW0pO1xuICAgICAgICByZXR1cm4gYXJyYXlbaV0gPT09IGl0ZW0gPyBpIDogLTE7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChuYXRpdmVJbmRleE9mICYmIGFycmF5LmluZGV4T2YgPT09IG5hdGl2ZUluZGV4T2YpIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0sIGlzU29ydGVkKTtcbiAgICBmb3IgKDsgaSA8IGxlbmd0aDsgaSsrKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBEZWxlZ2F0ZXMgdG8gKipFQ01BU2NyaXB0IDUqKidzIG5hdGl2ZSBgbGFzdEluZGV4T2ZgIGlmIGF2YWlsYWJsZS5cbiAgXy5sYXN0SW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBmcm9tKSB7XG4gICAgaWYgKGFycmF5ID09IG51bGwpIHJldHVybiAtMTtcbiAgICB2YXIgaGFzSW5kZXggPSBmcm9tICE9IG51bGw7XG4gICAgaWYgKG5hdGl2ZUxhc3RJbmRleE9mICYmIGFycmF5Lmxhc3RJbmRleE9mID09PSBuYXRpdmVMYXN0SW5kZXhPZikge1xuICAgICAgcmV0dXJuIGhhc0luZGV4ID8gYXJyYXkubGFzdEluZGV4T2YoaXRlbSwgZnJvbSkgOiBhcnJheS5sYXN0SW5kZXhPZihpdGVtKTtcbiAgICB9XG4gICAgdmFyIGkgPSAoaGFzSW5kZXggPyBmcm9tIDogYXJyYXkubGVuZ3RoKTtcbiAgICB3aGlsZSAoaS0tKSBpZiAoYXJyYXlbaV0gPT09IGl0ZW0pIHJldHVybiBpO1xuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhbiBpbnRlZ2VyIEFycmF5IGNvbnRhaW5pbmcgYW4gYXJpdGhtZXRpYyBwcm9ncmVzc2lvbi4gQSBwb3J0IG9mXG4gIC8vIHRoZSBuYXRpdmUgUHl0aG9uIGByYW5nZSgpYCBmdW5jdGlvbi4gU2VlXG4gIC8vIFt0aGUgUHl0aG9uIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9kb2NzLnB5dGhvbi5vcmcvbGlicmFyeS9mdW5jdGlvbnMuaHRtbCNyYW5nZSkuXG4gIF8ucmFuZ2UgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDw9IDEpIHtcbiAgICAgIHN0b3AgPSBzdGFydCB8fCAwO1xuICAgICAgc3RhcnQgPSAwO1xuICAgIH1cbiAgICBzdGVwID0gYXJndW1lbnRzWzJdIHx8IDE7XG5cbiAgICB2YXIgbGVuZ3RoID0gTWF0aC5tYXgoTWF0aC5jZWlsKChzdG9wIC0gc3RhcnQpIC8gc3RlcCksIDApO1xuICAgIHZhciBpZHggPSAwO1xuICAgIHZhciByYW5nZSA9IG5ldyBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUoaWR4IDwgbGVuZ3RoKSB7XG4gICAgICByYW5nZVtpZHgrK10gPSBzdGFydDtcbiAgICAgIHN0YXJ0ICs9IHN0ZXA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJhbmdlO1xuICB9O1xuXG4gIC8vIEZ1bmN0aW9uIChhaGVtKSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV1c2FibGUgY29uc3RydWN0b3IgZnVuY3Rpb24gZm9yIHByb3RvdHlwZSBzZXR0aW5nLlxuICB2YXIgY3RvciA9IGZ1bmN0aW9uKCl7fTtcblxuICAvLyBDcmVhdGUgYSBmdW5jdGlvbiBib3VuZCB0byBhIGdpdmVuIG9iamVjdCAoYXNzaWduaW5nIGB0aGlzYCwgYW5kIGFyZ3VtZW50cyxcbiAgLy8gb3B0aW9uYWxseSkuIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBGdW5jdGlvbi5iaW5kYCBpZlxuICAvLyBhdmFpbGFibGUuXG4gIF8uYmluZCA9IGZ1bmN0aW9uKGZ1bmMsIGNvbnRleHQpIHtcbiAgICB2YXIgYXJncywgYm91bmQ7XG4gICAgaWYgKG5hdGl2ZUJpbmQgJiYgZnVuYy5iaW5kID09PSBuYXRpdmVCaW5kKSByZXR1cm4gbmF0aXZlQmluZC5hcHBseShmdW5jLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGlmICghXy5pc0Z1bmN0aW9uKGZ1bmMpKSB0aHJvdyBuZXcgVHlwZUVycm9yO1xuICAgIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMik7XG4gICAgcmV0dXJuIGJvdW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgYm91bmQpKSByZXR1cm4gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbiAgICAgIGN0b3IucHJvdG90eXBlID0gZnVuYy5wcm90b3R5cGU7XG4gICAgICB2YXIgc2VsZiA9IG5ldyBjdG9yO1xuICAgICAgY3Rvci5wcm90b3R5cGUgPSBudWxsO1xuICAgICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkoc2VsZiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICBpZiAoT2JqZWN0KHJlc3VsdCkgPT09IHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgIHJldHVybiBzZWxmO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUGFydGlhbGx5IGFwcGx5IGEgZnVuY3Rpb24gYnkgY3JlYXRpbmcgYSB2ZXJzaW9uIHRoYXQgaGFzIGhhZCBzb21lIG9mIGl0c1xuICAvLyBhcmd1bWVudHMgcHJlLWZpbGxlZCwgd2l0aG91dCBjaGFuZ2luZyBpdHMgZHluYW1pYyBgdGhpc2AgY29udGV4dC5cbiAgXy5wYXJ0aWFsID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MuY29uY2F0KHNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gQmluZCBhbGwgb2YgYW4gb2JqZWN0J3MgbWV0aG9kcyB0byB0aGF0IG9iamVjdC4gVXNlZnVsIGZvciBlbnN1cmluZyB0aGF0XG4gIC8vIGFsbCBjYWxsYmFja3MgZGVmaW5lZCBvbiBhbiBvYmplY3QgYmVsb25nIHRvIGl0LlxuICBfLmJpbmRBbGwgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgZnVuY3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgaWYgKGZ1bmNzLmxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IEVycm9yKFwiYmluZEFsbCBtdXN0IGJlIHBhc3NlZCBmdW5jdGlvbiBuYW1lc1wiKTtcbiAgICBlYWNoKGZ1bmNzLCBmdW5jdGlvbihmKSB7IG9ialtmXSA9IF8uYmluZChvYmpbZl0sIG9iaik7IH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gTWVtb2l6ZSBhbiBleHBlbnNpdmUgZnVuY3Rpb24gYnkgc3RvcmluZyBpdHMgcmVzdWx0cy5cbiAgXy5tZW1vaXplID0gZnVuY3Rpb24oZnVuYywgaGFzaGVyKSB7XG4gICAgdmFyIG1lbW8gPSB7fTtcbiAgICBoYXNoZXIgfHwgKGhhc2hlciA9IF8uaWRlbnRpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBrZXkgPSBoYXNoZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiBfLmhhcyhtZW1vLCBrZXkpID8gbWVtb1trZXldIDogKG1lbW9ba2V5XSA9IGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgfTtcbiAgfTtcblxuICAvLyBEZWxheXMgYSBmdW5jdGlvbiBmb3IgdGhlIGdpdmVuIG51bWJlciBvZiBtaWxsaXNlY29uZHMsIGFuZCB0aGVuIGNhbGxzXG4gIC8vIGl0IHdpdGggdGhlIGFyZ3VtZW50cyBzdXBwbGllZC5cbiAgXy5kZWxheSA9IGZ1bmN0aW9uKGZ1bmMsIHdhaXQpIHtcbiAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICByZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpeyByZXR1cm4gZnVuYy5hcHBseShudWxsLCBhcmdzKTsgfSwgd2FpdCk7XG4gIH07XG5cbiAgLy8gRGVmZXJzIGEgZnVuY3Rpb24sIHNjaGVkdWxpbmcgaXQgdG8gcnVuIGFmdGVyIHRoZSBjdXJyZW50IGNhbGwgc3RhY2sgaGFzXG4gIC8vIGNsZWFyZWQuXG4gIF8uZGVmZXIgPSBmdW5jdGlvbihmdW5jKSB7XG4gICAgcmV0dXJuIF8uZGVsYXkuYXBwbHkoXywgW2Z1bmMsIDFdLmNvbmNhdChzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpKTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24sIHRoYXQsIHdoZW4gaW52b2tlZCwgd2lsbCBvbmx5IGJlIHRyaWdnZXJlZCBhdCBtb3N0IG9uY2VcbiAgLy8gZHVyaW5nIGEgZ2l2ZW4gd2luZG93IG9mIHRpbWUuIE5vcm1hbGx5LCB0aGUgdGhyb3R0bGVkIGZ1bmN0aW9uIHdpbGwgcnVuXG4gIC8vIGFzIG11Y2ggYXMgaXQgY2FuLCB3aXRob3V0IGV2ZXIgZ29pbmcgbW9yZSB0aGFuIG9uY2UgcGVyIGB3YWl0YCBkdXJhdGlvbjtcbiAgLy8gYnV0IGlmIHlvdSdkIGxpa2UgdG8gZGlzYWJsZSB0aGUgZXhlY3V0aW9uIG9uIHRoZSBsZWFkaW5nIGVkZ2UsIHBhc3NcbiAgLy8gYHtsZWFkaW5nOiBmYWxzZX1gLiBUbyBkaXNhYmxlIGV4ZWN1dGlvbiBvbiB0aGUgdHJhaWxpbmcgZWRnZSwgZGl0dG8uXG4gIF8udGhyb3R0bGUgPSBmdW5jdGlvbihmdW5jLCB3YWl0LCBvcHRpb25zKSB7XG4gICAgdmFyIGNvbnRleHQsIGFyZ3MsIHJlc3VsdDtcbiAgICB2YXIgdGltZW91dCA9IG51bGw7XG4gICAgdmFyIHByZXZpb3VzID0gMDtcbiAgICBvcHRpb25zIHx8IChvcHRpb25zID0ge30pO1xuICAgIHZhciBsYXRlciA9IGZ1bmN0aW9uKCkge1xuICAgICAgcHJldmlvdXMgPSBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlID8gMCA6IG5ldyBEYXRlO1xuICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICAgIH07XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG5vdyA9IG5ldyBEYXRlO1xuICAgICAgaWYgKCFwcmV2aW91cyAmJiBvcHRpb25zLmxlYWRpbmcgPT09IGZhbHNlKSBwcmV2aW91cyA9IG5vdztcbiAgICAgIHZhciByZW1haW5pbmcgPSB3YWl0IC0gKG5vdyAtIHByZXZpb3VzKTtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHRpbWVvdXQgPSBudWxsO1xuICAgICAgICBwcmV2aW91cyA9IG5vdztcbiAgICAgICAgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIH0gZWxzZSBpZiAoIXRpbWVvdXQgJiYgb3B0aW9ucy50cmFpbGluZyAhPT0gZmFsc2UpIHtcbiAgICAgICAgdGltZW91dCA9IHNldFRpbWVvdXQobGF0ZXIsIHJlbWFpbmluZyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uLCB0aGF0LCBhcyBsb25nIGFzIGl0IGNvbnRpbnVlcyB0byBiZSBpbnZva2VkLCB3aWxsIG5vdFxuICAvLyBiZSB0cmlnZ2VyZWQuIFRoZSBmdW5jdGlvbiB3aWxsIGJlIGNhbGxlZCBhZnRlciBpdCBzdG9wcyBiZWluZyBjYWxsZWQgZm9yXG4gIC8vIE4gbWlsbGlzZWNvbmRzLiBJZiBgaW1tZWRpYXRlYCBpcyBwYXNzZWQsIHRyaWdnZXIgdGhlIGZ1bmN0aW9uIG9uIHRoZVxuICAvLyBsZWFkaW5nIGVkZ2UsIGluc3RlYWQgb2YgdGhlIHRyYWlsaW5nLlxuICBfLmRlYm91bmNlID0gZnVuY3Rpb24oZnVuYywgd2FpdCwgaW1tZWRpYXRlKSB7XG4gICAgdmFyIHRpbWVvdXQsIGFyZ3MsIGNvbnRleHQsIHRpbWVzdGFtcCwgcmVzdWx0O1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGNvbnRleHQgPSB0aGlzO1xuICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICAgIHRpbWVzdGFtcCA9IG5ldyBEYXRlKCk7XG4gICAgICB2YXIgbGF0ZXIgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxhc3QgPSAobmV3IERhdGUoKSkgLSB0aW1lc3RhbXA7XG4gICAgICAgIGlmIChsYXN0IDwgd2FpdCkge1xuICAgICAgICAgIHRpbWVvdXQgPSBzZXRUaW1lb3V0KGxhdGVyLCB3YWl0IC0gbGFzdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGltZW91dCA9IG51bGw7XG4gICAgICAgICAgaWYgKCFpbW1lZGlhdGUpIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICB2YXIgY2FsbE5vdyA9IGltbWVkaWF0ZSAmJiAhdGltZW91dDtcbiAgICAgIGlmICghdGltZW91dCkge1xuICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dChsYXRlciwgd2FpdCk7XG4gICAgICB9XG4gICAgICBpZiAoY2FsbE5vdykgcmVzdWx0ID0gZnVuYy5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIGJlIGV4ZWN1dGVkIGF0IG1vc3Qgb25lIHRpbWUsIG5vIG1hdHRlciBob3dcbiAgLy8gb2Z0ZW4geW91IGNhbGwgaXQuIFVzZWZ1bCBmb3IgbGF6eSBpbml0aWFsaXphdGlvbi5cbiAgXy5vbmNlID0gZnVuY3Rpb24oZnVuYykge1xuICAgIHZhciByYW4gPSBmYWxzZSwgbWVtbztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAocmFuKSByZXR1cm4gbWVtbztcbiAgICAgIHJhbiA9IHRydWU7XG4gICAgICBtZW1vID0gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgZnVuYyA9IG51bGw7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9O1xuICB9O1xuXG4gIC8vIFJldHVybnMgdGhlIGZpcnN0IGZ1bmN0aW9uIHBhc3NlZCBhcyBhbiBhcmd1bWVudCB0byB0aGUgc2Vjb25kLFxuICAvLyBhbGxvd2luZyB5b3UgdG8gYWRqdXN0IGFyZ3VtZW50cywgcnVuIGNvZGUgYmVmb3JlIGFuZCBhZnRlciwgYW5kXG4gIC8vIGNvbmRpdGlvbmFsbHkgZXhlY3V0ZSB0aGUgb3JpZ2luYWwgZnVuY3Rpb24uXG4gIF8ud3JhcCA9IGZ1bmN0aW9uKGZ1bmMsIHdyYXBwZXIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJncyA9IFtmdW5jXTtcbiAgICAgIHB1c2guYXBwbHkoYXJncywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB3cmFwcGVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH07XG4gIH07XG5cbiAgLy8gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIGEgbGlzdCBvZiBmdW5jdGlvbnMsIGVhY2hcbiAgLy8gY29uc3VtaW5nIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXQgZm9sbG93cy5cbiAgXy5jb21wb3NlID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZ1bmNzID0gYXJndW1lbnRzO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgZm9yICh2YXIgaSA9IGZ1bmNzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGFyZ3MgPSBbZnVuY3NbaV0uYXBwbHkodGhpcywgYXJncyldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFyZ3NbMF07XG4gICAgfTtcbiAgfTtcblxuICAvLyBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCB3aWxsIG9ubHkgYmUgZXhlY3V0ZWQgYWZ0ZXIgYmVpbmcgY2FsbGVkIE4gdGltZXMuXG4gIF8uYWZ0ZXIgPSBmdW5jdGlvbih0aW1lcywgZnVuYykge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICgtLXRpbWVzIDwgMSkge1xuICAgICAgICByZXR1cm4gZnVuYy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgLy8gT2JqZWN0IEZ1bmN0aW9uc1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gUmV0cmlldmUgdGhlIG5hbWVzIG9mIGFuIG9iamVjdCdzIHByb3BlcnRpZXMuXG4gIC8vIERlbGVnYXRlcyB0byAqKkVDTUFTY3JpcHQgNSoqJ3MgbmF0aXZlIGBPYmplY3Qua2V5c2BcbiAgXy5rZXlzID0gbmF0aXZlS2V5cyB8fCBmdW5jdGlvbihvYmopIHtcbiAgICBpZiAob2JqICE9PSBPYmplY3Qob2JqKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignSW52YWxpZCBvYmplY3QnKTtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIGlmIChfLmhhcyhvYmosIGtleSkpIGtleXMucHVzaChrZXkpO1xuICAgIHJldHVybiBrZXlzO1xuICB9O1xuXG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZXMgb2YgYW4gb2JqZWN0J3MgcHJvcGVydGllcy5cbiAgXy52YWx1ZXMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIga2V5cyA9IF8ua2V5cyhvYmopO1xuICAgIHZhciBsZW5ndGggPSBrZXlzLmxlbmd0aDtcbiAgICB2YXIgdmFsdWVzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgdmFsdWVzW2ldID0gb2JqW2tleXNbaV1dO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9O1xuXG4gIC8vIENvbnZlcnQgYW4gb2JqZWN0IGludG8gYSBsaXN0IG9mIGBba2V5LCB2YWx1ZV1gIHBhaXJzLlxuICBfLnBhaXJzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIHBhaXJzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcGFpcnNbaV0gPSBba2V5c1tpXSwgb2JqW2tleXNbaV1dXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhaXJzO1xuICB9O1xuXG4gIC8vIEludmVydCB0aGUga2V5cyBhbmQgdmFsdWVzIG9mIGFuIG9iamVjdC4gVGhlIHZhbHVlcyBtdXN0IGJlIHNlcmlhbGl6YWJsZS5cbiAgXy5pbnZlcnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdmFyIGtleXMgPSBfLmtleXMob2JqKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0ga2V5cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgcmVzdWx0W29ialtrZXlzW2ldXV0gPSBrZXlzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHNvcnRlZCBsaXN0IG9mIHRoZSBmdW5jdGlvbiBuYW1lcyBhdmFpbGFibGUgb24gdGhlIG9iamVjdC5cbiAgLy8gQWxpYXNlZCBhcyBgbWV0aG9kc2BcbiAgXy5mdW5jdGlvbnMgPSBfLm1ldGhvZHMgPSBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgbmFtZXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoXy5pc0Z1bmN0aW9uKG9ialtrZXldKSkgbmFtZXMucHVzaChrZXkpO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZXMuc29ydCgpO1xuICB9O1xuXG4gIC8vIEV4dGVuZCBhIGdpdmVuIG9iamVjdCB3aXRoIGFsbCB0aGUgcHJvcGVydGllcyBpbiBwYXNzZWQtaW4gb2JqZWN0KHMpLlxuICBfLmV4dGVuZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBvYmpbcHJvcF0gPSBzb3VyY2VbcHJvcF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIGNvcHkgb2YgdGhlIG9iamVjdCBvbmx5IGNvbnRhaW5pbmcgdGhlIHdoaXRlbGlzdGVkIHByb3BlcnRpZXMuXG4gIF8ucGljayA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHZhciBjb3B5ID0ge307XG4gICAgdmFyIGtleXMgPSBjb25jYXQuYXBwbHkoQXJyYXlQcm90bywgc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKTtcbiAgICBlYWNoKGtleXMsIGZ1bmN0aW9uKGtleSkge1xuICAgICAgaWYgKGtleSBpbiBvYmopIGNvcHlba2V5XSA9IG9ialtrZXldO1xuICAgIH0pO1xuICAgIHJldHVybiBjb3B5O1xuICB9O1xuXG4gICAvLyBSZXR1cm4gYSBjb3B5IG9mIHRoZSBvYmplY3Qgd2l0aG91dCB0aGUgYmxhY2tsaXN0ZWQgcHJvcGVydGllcy5cbiAgXy5vbWl0ID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgdmFyIGNvcHkgPSB7fTtcbiAgICB2YXIga2V5cyA9IGNvbmNhdC5hcHBseShBcnJheVByb3RvLCBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSkpO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmICghXy5jb250YWlucyhrZXlzLCBrZXkpKSBjb3B5W2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGNvcHk7XG4gIH07XG5cbiAgLy8gRmlsbCBpbiBhIGdpdmVuIG9iamVjdCB3aXRoIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgXy5kZWZhdWx0cyA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLCBmdW5jdGlvbihzb3VyY2UpIHtcbiAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcbiAgICAgICAgICBpZiAob2JqW3Byb3BdID09PSB2b2lkIDApIG9ialtwcm9wXSA9IHNvdXJjZVtwcm9wXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG4gIH07XG5cbiAgLy8gQ3JlYXRlIGEgKHNoYWxsb3ctY2xvbmVkKSBkdXBsaWNhdGUgb2YgYW4gb2JqZWN0LlxuICBfLmNsb25lID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKCFfLmlzT2JqZWN0KG9iaikpIHJldHVybiBvYmo7XG4gICAgcmV0dXJuIF8uaXNBcnJheShvYmopID8gb2JqLnNsaWNlKCkgOiBfLmV4dGVuZCh7fSwgb2JqKTtcbiAgfTtcblxuICAvLyBJbnZva2VzIGludGVyY2VwdG9yIHdpdGggdGhlIG9iaiwgYW5kIHRoZW4gcmV0dXJucyBvYmouXG4gIC8vIFRoZSBwcmltYXJ5IHB1cnBvc2Ugb2YgdGhpcyBtZXRob2QgaXMgdG8gXCJ0YXAgaW50b1wiIGEgbWV0aG9kIGNoYWluLCBpblxuICAvLyBvcmRlciB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaW50ZXJtZWRpYXRlIHJlc3VsdHMgd2l0aGluIHRoZSBjaGFpbi5cbiAgXy50YXAgPSBmdW5jdGlvbihvYmosIGludGVyY2VwdG9yKSB7XG4gICAgaW50ZXJjZXB0b3Iob2JqKTtcbiAgICByZXR1cm4gb2JqO1xuICB9O1xuXG4gIC8vIEludGVybmFsIHJlY3Vyc2l2ZSBjb21wYXJpc29uIGZ1bmN0aW9uIGZvciBgaXNFcXVhbGAuXG4gIHZhciBlcSA9IGZ1bmN0aW9uKGEsIGIsIGFTdGFjaywgYlN0YWNrKSB7XG4gICAgLy8gSWRlbnRpY2FsIG9iamVjdHMgYXJlIGVxdWFsLiBgMCA9PT0gLTBgLCBidXQgdGhleSBhcmVuJ3QgaWRlbnRpY2FsLlxuICAgIC8vIFNlZSB0aGUgW0hhcm1vbnkgYGVnYWxgIHByb3Bvc2FsXShodHRwOi8vd2lraS5lY21hc2NyaXB0Lm9yZy9kb2t1LnBocD9pZD1oYXJtb255OmVnYWwpLlxuICAgIGlmIChhID09PSBiKSByZXR1cm4gYSAhPT0gMCB8fCAxIC8gYSA9PSAxIC8gYjtcbiAgICAvLyBBIHN0cmljdCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGBudWxsID09IHVuZGVmaW5lZGAuXG4gICAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwpIHJldHVybiBhID09PSBiO1xuICAgIC8vIFVud3JhcCBhbnkgd3JhcHBlZCBvYmplY3RzLlxuICAgIGlmIChhIGluc3RhbmNlb2YgXykgYSA9IGEuX3dyYXBwZWQ7XG4gICAgaWYgKGIgaW5zdGFuY2VvZiBfKSBiID0gYi5fd3JhcHBlZDtcbiAgICAvLyBDb21wYXJlIGBbW0NsYXNzXV1gIG5hbWVzLlxuICAgIHZhciBjbGFzc05hbWUgPSB0b1N0cmluZy5jYWxsKGEpO1xuICAgIGlmIChjbGFzc05hbWUgIT0gdG9TdHJpbmcuY2FsbChiKSkgcmV0dXJuIGZhbHNlO1xuICAgIHN3aXRjaCAoY2xhc3NOYW1lKSB7XG4gICAgICAvLyBTdHJpbmdzLCBudW1iZXJzLCBkYXRlcywgYW5kIGJvb2xlYW5zIGFyZSBjb21wYXJlZCBieSB2YWx1ZS5cbiAgICAgIGNhc2UgJ1tvYmplY3QgU3RyaW5nXSc6XG4gICAgICAgIC8vIFByaW1pdGl2ZXMgYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgb2JqZWN0IHdyYXBwZXJzIGFyZSBlcXVpdmFsZW50OyB0aHVzLCBgXCI1XCJgIGlzXG4gICAgICAgIC8vIGVxdWl2YWxlbnQgdG8gYG5ldyBTdHJpbmcoXCI1XCIpYC5cbiAgICAgICAgcmV0dXJuIGEgPT0gU3RyaW5nKGIpO1xuICAgICAgY2FzZSAnW29iamVjdCBOdW1iZXJdJzpcbiAgICAgICAgLy8gYE5hTmBzIGFyZSBlcXVpdmFsZW50LCBidXQgbm9uLXJlZmxleGl2ZS4gQW4gYGVnYWxgIGNvbXBhcmlzb24gaXMgcGVyZm9ybWVkIGZvclxuICAgICAgICAvLyBvdGhlciBudW1lcmljIHZhbHVlcy5cbiAgICAgICAgcmV0dXJuIGEgIT0gK2EgPyBiICE9ICtiIDogKGEgPT0gMCA/IDEgLyBhID09IDEgLyBiIDogYSA9PSArYik7XG4gICAgICBjYXNlICdbb2JqZWN0IERhdGVdJzpcbiAgICAgIGNhc2UgJ1tvYmplY3QgQm9vbGVhbl0nOlxuICAgICAgICAvLyBDb2VyY2UgZGF0ZXMgYW5kIGJvb2xlYW5zIHRvIG51bWVyaWMgcHJpbWl0aXZlIHZhbHVlcy4gRGF0ZXMgYXJlIGNvbXBhcmVkIGJ5IHRoZWlyXG4gICAgICAgIC8vIG1pbGxpc2Vjb25kIHJlcHJlc2VudGF0aW9ucy4gTm90ZSB0aGF0IGludmFsaWQgZGF0ZXMgd2l0aCBtaWxsaXNlY29uZCByZXByZXNlbnRhdGlvbnNcbiAgICAgICAgLy8gb2YgYE5hTmAgYXJlIG5vdCBlcXVpdmFsZW50LlxuICAgICAgICByZXR1cm4gK2EgPT0gK2I7XG4gICAgICAvLyBSZWdFeHBzIGFyZSBjb21wYXJlZCBieSB0aGVpciBzb3VyY2UgcGF0dGVybnMgYW5kIGZsYWdzLlxuICAgICAgY2FzZSAnW29iamVjdCBSZWdFeHBdJzpcbiAgICAgICAgcmV0dXJuIGEuc291cmNlID09IGIuc291cmNlICYmXG4gICAgICAgICAgICAgICBhLmdsb2JhbCA9PSBiLmdsb2JhbCAmJlxuICAgICAgICAgICAgICAgYS5tdWx0aWxpbmUgPT0gYi5tdWx0aWxpbmUgJiZcbiAgICAgICAgICAgICAgIGEuaWdub3JlQ2FzZSA9PSBiLmlnbm9yZUNhc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSAhPSAnb2JqZWN0JyB8fCB0eXBlb2YgYiAhPSAnb2JqZWN0JykgcmV0dXJuIGZhbHNlO1xuICAgIC8vIEFzc3VtZSBlcXVhbGl0eSBmb3IgY3ljbGljIHN0cnVjdHVyZXMuIFRoZSBhbGdvcml0aG0gZm9yIGRldGVjdGluZyBjeWNsaWNcbiAgICAvLyBzdHJ1Y3R1cmVzIGlzIGFkYXB0ZWQgZnJvbSBFUyA1LjEgc2VjdGlvbiAxNS4xMi4zLCBhYnN0cmFjdCBvcGVyYXRpb24gYEpPYC5cbiAgICB2YXIgbGVuZ3RoID0gYVN0YWNrLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIC8vIExpbmVhciBzZWFyY2guIFBlcmZvcm1hbmNlIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIG51bWJlciBvZlxuICAgICAgLy8gdW5pcXVlIG5lc3RlZCBzdHJ1Y3R1cmVzLlxuICAgICAgaWYgKGFTdGFja1tsZW5ndGhdID09IGEpIHJldHVybiBiU3RhY2tbbGVuZ3RoXSA9PSBiO1xuICAgIH1cbiAgICAvLyBPYmplY3RzIHdpdGggZGlmZmVyZW50IGNvbnN0cnVjdG9ycyBhcmUgbm90IGVxdWl2YWxlbnQsIGJ1dCBgT2JqZWN0YHNcbiAgICAvLyBmcm9tIGRpZmZlcmVudCBmcmFtZXMgYXJlLlxuICAgIHZhciBhQ3RvciA9IGEuY29uc3RydWN0b3IsIGJDdG9yID0gYi5jb25zdHJ1Y3RvcjtcbiAgICBpZiAoYUN0b3IgIT09IGJDdG9yICYmICEoXy5pc0Z1bmN0aW9uKGFDdG9yKSAmJiAoYUN0b3IgaW5zdGFuY2VvZiBhQ3RvcikgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5pc0Z1bmN0aW9uKGJDdG9yKSAmJiAoYkN0b3IgaW5zdGFuY2VvZiBiQ3RvcikpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIEFkZCB0aGUgZmlyc3Qgb2JqZWN0IHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0cy5cbiAgICBhU3RhY2sucHVzaChhKTtcbiAgICBiU3RhY2sucHVzaChiKTtcbiAgICB2YXIgc2l6ZSA9IDAsIHJlc3VsdCA9IHRydWU7XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgaWYgKGNsYXNzTmFtZSA9PSAnW29iamVjdCBBcnJheV0nKSB7XG4gICAgICAvLyBDb21wYXJlIGFycmF5IGxlbmd0aHMgdG8gZGV0ZXJtaW5lIGlmIGEgZGVlcCBjb21wYXJpc29uIGlzIG5lY2Vzc2FyeS5cbiAgICAgIHNpemUgPSBhLmxlbmd0aDtcbiAgICAgIHJlc3VsdCA9IHNpemUgPT0gYi5sZW5ndGg7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vIERlZXAgY29tcGFyZSB0aGUgY29udGVudHMsIGlnbm9yaW5nIG5vbi1udW1lcmljIHByb3BlcnRpZXMuXG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgPSBlcShhW3NpemVdLCBiW3NpemVdLCBhU3RhY2ssIGJTdGFjaykpKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBEZWVwIGNvbXBhcmUgb2JqZWN0cy5cbiAgICAgIGZvciAodmFyIGtleSBpbiBhKSB7XG4gICAgICAgIGlmIChfLmhhcyhhLCBrZXkpKSB7XG4gICAgICAgICAgLy8gQ291bnQgdGhlIGV4cGVjdGVkIG51bWJlciBvZiBwcm9wZXJ0aWVzLlxuICAgICAgICAgIHNpemUrKztcbiAgICAgICAgICAvLyBEZWVwIGNvbXBhcmUgZWFjaCBtZW1iZXIuXG4gICAgICAgICAgaWYgKCEocmVzdWx0ID0gXy5oYXMoYiwga2V5KSAmJiBlcShhW2tleV0sIGJba2V5XSwgYVN0YWNrLCBiU3RhY2spKSkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEVuc3VyZSB0aGF0IGJvdGggb2JqZWN0cyBjb250YWluIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzLlxuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICBmb3IgKGtleSBpbiBiKSB7XG4gICAgICAgICAgaWYgKF8uaGFzKGIsIGtleSkgJiYgIShzaXplLS0pKSBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSAhc2l6ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIHRoZSBmaXJzdCBvYmplY3QgZnJvbSB0aGUgc3RhY2sgb2YgdHJhdmVyc2VkIG9iamVjdHMuXG4gICAgYVN0YWNrLnBvcCgpO1xuICAgIGJTdGFjay5wb3AoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIFBlcmZvcm0gYSBkZWVwIGNvbXBhcmlzb24gdG8gY2hlY2sgaWYgdHdvIG9iamVjdHMgYXJlIGVxdWFsLlxuICBfLmlzRXF1YWwgPSBmdW5jdGlvbihhLCBiKSB7XG4gICAgcmV0dXJuIGVxKGEsIGIsIFtdLCBbXSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiBhcnJheSwgc3RyaW5nLCBvciBvYmplY3QgZW1wdHk/XG4gIC8vIEFuIFwiZW1wdHlcIiBvYmplY3QgaGFzIG5vIGVudW1lcmFibGUgb3duLXByb3BlcnRpZXMuXG4gIF8uaXNFbXB0eSA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChvYmogPT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gICAgaWYgKF8uaXNBcnJheShvYmopIHx8IF8uaXNTdHJpbmcob2JqKSkgcmV0dXJuIG9iai5sZW5ndGggPT09IDA7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikgaWYgKF8uaGFzKG9iaiwga2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9O1xuXG4gIC8vIElzIGEgZ2l2ZW4gdmFsdWUgYSBET00gZWxlbWVudD9cbiAgXy5pc0VsZW1lbnQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gISEob2JqICYmIG9iai5ub2RlVHlwZSA9PT0gMSk7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YWx1ZSBhbiBhcnJheT9cbiAgLy8gRGVsZWdhdGVzIHRvIEVDTUE1J3MgbmF0aXZlIEFycmF5LmlzQXJyYXlcbiAgXy5pc0FycmF5ID0gbmF0aXZlSXNBcnJheSB8fCBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09ICdbb2JqZWN0IEFycmF5XSc7XG4gIH07XG5cbiAgLy8gSXMgYSBnaXZlbiB2YXJpYWJsZSBhbiBvYmplY3Q/XG4gIF8uaXNPYmplY3QgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSBPYmplY3Qob2JqKTtcbiAgfTtcblxuICAvLyBBZGQgc29tZSBpc1R5cGUgbWV0aG9kczogaXNBcmd1bWVudHMsIGlzRnVuY3Rpb24sIGlzU3RyaW5nLCBpc051bWJlciwgaXNEYXRlLCBpc1JlZ0V4cC5cbiAgZWFjaChbJ0FyZ3VtZW50cycsICdGdW5jdGlvbicsICdTdHJpbmcnLCAnTnVtYmVyJywgJ0RhdGUnLCAnUmVnRXhwJ10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBfWydpcycgKyBuYW1lXSA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PSAnW29iamVjdCAnICsgbmFtZSArICddJztcbiAgICB9O1xuICB9KTtcblxuICAvLyBEZWZpbmUgYSBmYWxsYmFjayB2ZXJzaW9uIG9mIHRoZSBtZXRob2QgaW4gYnJvd3NlcnMgKGFoZW0sIElFKSwgd2hlcmVcbiAgLy8gdGhlcmUgaXNuJ3QgYW55IGluc3BlY3RhYmxlIFwiQXJndW1lbnRzXCIgdHlwZS5cbiAgaWYgKCFfLmlzQXJndW1lbnRzKGFyZ3VtZW50cykpIHtcbiAgICBfLmlzQXJndW1lbnRzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gISEob2JqICYmIF8uaGFzKG9iaiwgJ2NhbGxlZScpKTtcbiAgICB9O1xuICB9XG5cbiAgLy8gT3B0aW1pemUgYGlzRnVuY3Rpb25gIGlmIGFwcHJvcHJpYXRlLlxuICBpZiAodHlwZW9mICgvLi8pICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgXy5pc0Z1bmN0aW9uID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIG9iaiA9PT0gJ2Z1bmN0aW9uJztcbiAgICB9O1xuICB9XG5cbiAgLy8gSXMgYSBnaXZlbiBvYmplY3QgYSBmaW5pdGUgbnVtYmVyP1xuICBfLmlzRmluaXRlID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIGlzRmluaXRlKG9iaikgJiYgIWlzTmFOKHBhcnNlRmxvYXQob2JqKSk7XG4gIH07XG5cbiAgLy8gSXMgdGhlIGdpdmVuIHZhbHVlIGBOYU5gPyAoTmFOIGlzIHRoZSBvbmx5IG51bWJlciB3aGljaCBkb2VzIG5vdCBlcXVhbCBpdHNlbGYpLlxuICBfLmlzTmFOID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIF8uaXNOdW1iZXIob2JqKSAmJiBvYmogIT0gK29iajtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGEgYm9vbGVhbj9cbiAgXy5pc0Jvb2xlYW4gPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gb2JqID09PSB0cnVlIHx8IG9iaiA9PT0gZmFsc2UgfHwgdG9TdHJpbmcuY2FsbChvYmopID09ICdbb2JqZWN0IEJvb2xlYW5dJztcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhbHVlIGVxdWFsIHRvIG51bGw/XG4gIF8uaXNOdWxsID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIG9iaiA9PT0gbnVsbDtcbiAgfTtcblxuICAvLyBJcyBhIGdpdmVuIHZhcmlhYmxlIHVuZGVmaW5lZD9cbiAgXy5pc1VuZGVmaW5lZCA9IGZ1bmN0aW9uKG9iaikge1xuICAgIHJldHVybiBvYmogPT09IHZvaWQgMDtcbiAgfTtcblxuICAvLyBTaG9ydGN1dCBmdW5jdGlvbiBmb3IgY2hlY2tpbmcgaWYgYW4gb2JqZWN0IGhhcyBhIGdpdmVuIHByb3BlcnR5IGRpcmVjdGx5XG4gIC8vIG9uIGl0c2VsZiAoaW4gb3RoZXIgd29yZHMsIG5vdCBvbiBhIHByb3RvdHlwZSkuXG4gIF8uaGFzID0gZnVuY3Rpb24ob2JqLCBrZXkpIHtcbiAgICByZXR1cm4gaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSk7XG4gIH07XG5cbiAgLy8gVXRpbGl0eSBGdW5jdGlvbnNcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBSdW4gVW5kZXJzY29yZS5qcyBpbiAqbm9Db25mbGljdCogbW9kZSwgcmV0dXJuaW5nIHRoZSBgX2AgdmFyaWFibGUgdG8gaXRzXG4gIC8vIHByZXZpb3VzIG93bmVyLiBSZXR1cm5zIGEgcmVmZXJlbmNlIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oKSB7XG4gICAgcm9vdC5fID0gcHJldmlvdXNVbmRlcnNjb3JlO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8vIEtlZXAgdGhlIGlkZW50aXR5IGZ1bmN0aW9uIGFyb3VuZCBmb3IgZGVmYXVsdCBpdGVyYXRvcnMuXG4gIF8uaWRlbnRpdHkgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfTtcblxuICAvLyBSdW4gYSBmdW5jdGlvbiAqKm4qKiB0aW1lcy5cbiAgXy50aW1lcyA9IGZ1bmN0aW9uKG4sIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIGFjY3VtID0gQXJyYXkoTWF0aC5tYXgoMCwgbikpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSBhY2N1bVtpXSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgaSk7XG4gICAgcmV0dXJuIGFjY3VtO1xuICB9O1xuXG4gIC8vIFJldHVybiBhIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gbWluIGFuZCBtYXggKGluY2x1c2l2ZSkuXG4gIF8ucmFuZG9tID0gZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgICBpZiAobWF4ID09IG51bGwpIHtcbiAgICAgIG1heCA9IG1pbjtcbiAgICAgIG1pbiA9IDA7XG4gICAgfVxuICAgIHJldHVybiBtaW4gKyBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAobWF4IC0gbWluICsgMSkpO1xuICB9O1xuXG4gIC8vIExpc3Qgb2YgSFRNTCBlbnRpdGllcyBmb3IgZXNjYXBpbmcuXG4gIHZhciBlbnRpdHlNYXAgPSB7XG4gICAgZXNjYXBlOiB7XG4gICAgICAnJic6ICcmYW1wOycsXG4gICAgICAnPCc6ICcmbHQ7JyxcbiAgICAgICc+JzogJyZndDsnLFxuICAgICAgJ1wiJzogJyZxdW90OycsXG4gICAgICBcIidcIjogJyYjeDI3OydcbiAgICB9XG4gIH07XG4gIGVudGl0eU1hcC51bmVzY2FwZSA9IF8uaW52ZXJ0KGVudGl0eU1hcC5lc2NhcGUpO1xuXG4gIC8vIFJlZ2V4ZXMgY29udGFpbmluZyB0aGUga2V5cyBhbmQgdmFsdWVzIGxpc3RlZCBpbW1lZGlhdGVseSBhYm92ZS5cbiAgdmFyIGVudGl0eVJlZ2V4ZXMgPSB7XG4gICAgZXNjYXBlOiAgIG5ldyBSZWdFeHAoJ1snICsgXy5rZXlzKGVudGl0eU1hcC5lc2NhcGUpLmpvaW4oJycpICsgJ10nLCAnZycpLFxuICAgIHVuZXNjYXBlOiBuZXcgUmVnRXhwKCcoJyArIF8ua2V5cyhlbnRpdHlNYXAudW5lc2NhcGUpLmpvaW4oJ3wnKSArICcpJywgJ2cnKVxuICB9O1xuXG4gIC8vIEZ1bmN0aW9ucyBmb3IgZXNjYXBpbmcgYW5kIHVuZXNjYXBpbmcgc3RyaW5ncyB0by9mcm9tIEhUTUwgaW50ZXJwb2xhdGlvbi5cbiAgXy5lYWNoKFsnZXNjYXBlJywgJ3VuZXNjYXBlJ10sIGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgIF9bbWV0aG9kXSA9IGZ1bmN0aW9uKHN0cmluZykge1xuICAgICAgaWYgKHN0cmluZyA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgICByZXR1cm4gKCcnICsgc3RyaW5nKS5yZXBsYWNlKGVudGl0eVJlZ2V4ZXNbbWV0aG9kXSwgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIGVudGl0eU1hcFttZXRob2RdW21hdGNoXTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH0pO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBvZiB0aGUgbmFtZWQgYHByb3BlcnR5YCBpcyBhIGZ1bmN0aW9uIHRoZW4gaW52b2tlIGl0IHdpdGggdGhlXG4gIC8vIGBvYmplY3RgIGFzIGNvbnRleHQ7IG90aGVyd2lzZSwgcmV0dXJuIGl0LlxuICBfLnJlc3VsdCA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHtcbiAgICBpZiAob2JqZWN0ID09IG51bGwpIHJldHVybiB2b2lkIDA7XG4gICAgdmFyIHZhbHVlID0gb2JqZWN0W3Byb3BlcnR5XTtcbiAgICByZXR1cm4gXy5pc0Z1bmN0aW9uKHZhbHVlKSA/IHZhbHVlLmNhbGwob2JqZWN0KSA6IHZhbHVlO1xuICB9O1xuXG4gIC8vIEFkZCB5b3VyIG93biBjdXN0b20gZnVuY3Rpb25zIHRvIHRoZSBVbmRlcnNjb3JlIG9iamVjdC5cbiAgXy5taXhpbiA9IGZ1bmN0aW9uKG9iaikge1xuICAgIGVhY2goXy5mdW5jdGlvbnMob2JqKSwgZnVuY3Rpb24obmFtZSkge1xuICAgICAgdmFyIGZ1bmMgPSBfW25hbWVdID0gb2JqW25hbWVdO1xuICAgICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBbdGhpcy5fd3JhcHBlZF07XG4gICAgICAgIHB1c2guYXBwbHkoYXJncywgYXJndW1lbnRzKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdC5jYWxsKHRoaXMsIGZ1bmMuYXBwbHkoXywgYXJncykpO1xuICAgICAgfTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBHZW5lcmF0ZSBhIHVuaXF1ZSBpbnRlZ2VyIGlkICh1bmlxdWUgd2l0aGluIHRoZSBlbnRpcmUgY2xpZW50IHNlc3Npb24pLlxuICAvLyBVc2VmdWwgZm9yIHRlbXBvcmFyeSBET00gaWRzLlxuICB2YXIgaWRDb3VudGVyID0gMDtcbiAgXy51bmlxdWVJZCA9IGZ1bmN0aW9uKHByZWZpeCkge1xuICAgIHZhciBpZCA9ICsraWRDb3VudGVyICsgJyc7XG4gICAgcmV0dXJuIHByZWZpeCA/IHByZWZpeCArIGlkIDogaWQ7XG4gIH07XG5cbiAgLy8gQnkgZGVmYXVsdCwgVW5kZXJzY29yZSB1c2VzIEVSQi1zdHlsZSB0ZW1wbGF0ZSBkZWxpbWl0ZXJzLCBjaGFuZ2UgdGhlXG4gIC8vIGZvbGxvd2luZyB0ZW1wbGF0ZSBzZXR0aW5ncyB0byB1c2UgYWx0ZXJuYXRpdmUgZGVsaW1pdGVycy5cbiAgXy50ZW1wbGF0ZVNldHRpbmdzID0ge1xuICAgIGV2YWx1YXRlICAgIDogLzwlKFtcXHNcXFNdKz8pJT4vZyxcbiAgICBpbnRlcnBvbGF0ZSA6IC88JT0oW1xcc1xcU10rPyklPi9nLFxuICAgIGVzY2FwZSAgICAgIDogLzwlLShbXFxzXFxTXSs/KSU+L2dcbiAgfTtcblxuICAvLyBXaGVuIGN1c3RvbWl6aW5nIGB0ZW1wbGF0ZVNldHRpbmdzYCwgaWYgeW91IGRvbid0IHdhbnQgdG8gZGVmaW5lIGFuXG4gIC8vIGludGVycG9sYXRpb24sIGV2YWx1YXRpb24gb3IgZXNjYXBpbmcgcmVnZXgsIHdlIG5lZWQgb25lIHRoYXQgaXNcbiAgLy8gZ3VhcmFudGVlZCBub3QgdG8gbWF0Y2guXG4gIHZhciBub01hdGNoID0gLyguKV4vO1xuXG4gIC8vIENlcnRhaW4gY2hhcmFjdGVycyBuZWVkIHRvIGJlIGVzY2FwZWQgc28gdGhhdCB0aGV5IGNhbiBiZSBwdXQgaW50byBhXG4gIC8vIHN0cmluZyBsaXRlcmFsLlxuICB2YXIgZXNjYXBlcyA9IHtcbiAgICBcIidcIjogICAgICBcIidcIixcbiAgICAnXFxcXCc6ICAgICAnXFxcXCcsXG4gICAgJ1xccic6ICAgICAncicsXG4gICAgJ1xcbic6ICAgICAnbicsXG4gICAgJ1xcdCc6ICAgICAndCcsXG4gICAgJ1xcdTIwMjgnOiAndTIwMjgnLFxuICAgICdcXHUyMDI5JzogJ3UyMDI5J1xuICB9O1xuXG4gIHZhciBlc2NhcGVyID0gL1xcXFx8J3xcXHJ8XFxufFxcdHxcXHUyMDI4fFxcdTIwMjkvZztcblxuICAvLyBKYXZhU2NyaXB0IG1pY3JvLXRlbXBsYXRpbmcsIHNpbWlsYXIgdG8gSm9obiBSZXNpZydzIGltcGxlbWVudGF0aW9uLlxuICAvLyBVbmRlcnNjb3JlIHRlbXBsYXRpbmcgaGFuZGxlcyBhcmJpdHJhcnkgZGVsaW1pdGVycywgcHJlc2VydmVzIHdoaXRlc3BhY2UsXG4gIC8vIGFuZCBjb3JyZWN0bHkgZXNjYXBlcyBxdW90ZXMgd2l0aGluIGludGVycG9sYXRlZCBjb2RlLlxuICBfLnRlbXBsYXRlID0gZnVuY3Rpb24odGV4dCwgZGF0YSwgc2V0dGluZ3MpIHtcbiAgICB2YXIgcmVuZGVyO1xuICAgIHNldHRpbmdzID0gXy5kZWZhdWx0cyh7fSwgc2V0dGluZ3MsIF8udGVtcGxhdGVTZXR0aW5ncyk7XG5cbiAgICAvLyBDb21iaW5lIGRlbGltaXRlcnMgaW50byBvbmUgcmVndWxhciBleHByZXNzaW9uIHZpYSBhbHRlcm5hdGlvbi5cbiAgICB2YXIgbWF0Y2hlciA9IG5ldyBSZWdFeHAoW1xuICAgICAgKHNldHRpbmdzLmVzY2FwZSB8fCBub01hdGNoKS5zb3VyY2UsXG4gICAgICAoc2V0dGluZ3MuaW50ZXJwb2xhdGUgfHwgbm9NYXRjaCkuc291cmNlLFxuICAgICAgKHNldHRpbmdzLmV2YWx1YXRlIHx8IG5vTWF0Y2gpLnNvdXJjZVxuICAgIF0uam9pbignfCcpICsgJ3wkJywgJ2cnKTtcblxuICAgIC8vIENvbXBpbGUgdGhlIHRlbXBsYXRlIHNvdXJjZSwgZXNjYXBpbmcgc3RyaW5nIGxpdGVyYWxzIGFwcHJvcHJpYXRlbHkuXG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgc291cmNlID0gXCJfX3ArPSdcIjtcbiAgICB0ZXh0LnJlcGxhY2UobWF0Y2hlciwgZnVuY3Rpb24obWF0Y2gsIGVzY2FwZSwgaW50ZXJwb2xhdGUsIGV2YWx1YXRlLCBvZmZzZXQpIHtcbiAgICAgIHNvdXJjZSArPSB0ZXh0LnNsaWNlKGluZGV4LCBvZmZzZXQpXG4gICAgICAgIC5yZXBsYWNlKGVzY2FwZXIsIGZ1bmN0aW9uKG1hdGNoKSB7IHJldHVybiAnXFxcXCcgKyBlc2NhcGVzW21hdGNoXTsgfSk7XG5cbiAgICAgIGlmIChlc2NhcGUpIHtcbiAgICAgICAgc291cmNlICs9IFwiJytcXG4oKF9fdD0oXCIgKyBlc2NhcGUgKyBcIikpPT1udWxsPycnOl8uZXNjYXBlKF9fdCkpK1xcbidcIjtcbiAgICAgIH1cbiAgICAgIGlmIChpbnRlcnBvbGF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInK1xcbigoX190PShcIiArIGludGVycG9sYXRlICsgXCIpKT09bnVsbD8nJzpfX3QpK1xcbidcIjtcbiAgICAgIH1cbiAgICAgIGlmIChldmFsdWF0ZSkge1xuICAgICAgICBzb3VyY2UgKz0gXCInO1xcblwiICsgZXZhbHVhdGUgKyBcIlxcbl9fcCs9J1wiO1xuICAgICAgfVxuICAgICAgaW5kZXggPSBvZmZzZXQgKyBtYXRjaC5sZW5ndGg7XG4gICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfSk7XG4gICAgc291cmNlICs9IFwiJztcXG5cIjtcblxuICAgIC8vIElmIGEgdmFyaWFibGUgaXMgbm90IHNwZWNpZmllZCwgcGxhY2UgZGF0YSB2YWx1ZXMgaW4gbG9jYWwgc2NvcGUuXG4gICAgaWYgKCFzZXR0aW5ncy52YXJpYWJsZSkgc291cmNlID0gJ3dpdGgob2JqfHx7fSl7XFxuJyArIHNvdXJjZSArICd9XFxuJztcblxuICAgIHNvdXJjZSA9IFwidmFyIF9fdCxfX3A9JycsX19qPUFycmF5LnByb3RvdHlwZS5qb2luLFwiICtcbiAgICAgIFwicHJpbnQ9ZnVuY3Rpb24oKXtfX3ArPV9fai5jYWxsKGFyZ3VtZW50cywnJyk7fTtcXG5cIiArXG4gICAgICBzb3VyY2UgKyBcInJldHVybiBfX3A7XFxuXCI7XG5cbiAgICB0cnkge1xuICAgICAgcmVuZGVyID0gbmV3IEZ1bmN0aW9uKHNldHRpbmdzLnZhcmlhYmxlIHx8ICdvYmonLCAnXycsIHNvdXJjZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZS5zb3VyY2UgPSBzb3VyY2U7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIGlmIChkYXRhKSByZXR1cm4gcmVuZGVyKGRhdGEsIF8pO1xuICAgIHZhciB0ZW1wbGF0ZSA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIHJldHVybiByZW5kZXIuY2FsbCh0aGlzLCBkYXRhLCBfKTtcbiAgICB9O1xuXG4gICAgLy8gUHJvdmlkZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24gc291cmNlIGFzIGEgY29udmVuaWVuY2UgZm9yIHByZWNvbXBpbGF0aW9uLlxuICAgIHRlbXBsYXRlLnNvdXJjZSA9ICdmdW5jdGlvbignICsgKHNldHRpbmdzLnZhcmlhYmxlIHx8ICdvYmonKSArICcpe1xcbicgKyBzb3VyY2UgKyAnfSc7XG5cbiAgICByZXR1cm4gdGVtcGxhdGU7XG4gIH07XG5cbiAgLy8gQWRkIGEgXCJjaGFpblwiIGZ1bmN0aW9uLCB3aGljaCB3aWxsIGRlbGVnYXRlIHRvIHRoZSB3cmFwcGVyLlxuICBfLmNoYWluID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgcmV0dXJuIF8ob2JqKS5jaGFpbigpO1xuICB9O1xuXG4gIC8vIE9PUFxuICAvLyAtLS0tLS0tLS0tLS0tLS1cbiAgLy8gSWYgVW5kZXJzY29yZSBpcyBjYWxsZWQgYXMgYSBmdW5jdGlvbiwgaXQgcmV0dXJucyBhIHdyYXBwZWQgb2JqZWN0IHRoYXRcbiAgLy8gY2FuIGJlIHVzZWQgT08tc3R5bGUuIFRoaXMgd3JhcHBlciBob2xkcyBhbHRlcmVkIHZlcnNpb25zIG9mIGFsbCB0aGVcbiAgLy8gdW5kZXJzY29yZSBmdW5jdGlvbnMuIFdyYXBwZWQgb2JqZWN0cyBtYXkgYmUgY2hhaW5lZC5cblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gY29udGludWUgY2hhaW5pbmcgaW50ZXJtZWRpYXRlIHJlc3VsdHMuXG4gIHZhciByZXN1bHQgPSBmdW5jdGlvbihvYmopIHtcbiAgICByZXR1cm4gdGhpcy5fY2hhaW4gPyBfKG9iaikuY2hhaW4oKSA6IG9iajtcbiAgfTtcblxuICAvLyBBZGQgYWxsIG9mIHRoZSBVbmRlcnNjb3JlIGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlciBvYmplY3QuXG4gIF8ubWl4aW4oXyk7XG5cbiAgLy8gQWRkIGFsbCBtdXRhdG9yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgZWFjaChbJ3BvcCcsICdwdXNoJywgJ3JldmVyc2UnLCAnc2hpZnQnLCAnc29ydCcsICdzcGxpY2UnLCAndW5zaGlmdCddLCBmdW5jdGlvbihuYW1lKSB7XG4gICAgdmFyIG1ldGhvZCA9IEFycmF5UHJvdG9bbmFtZV07XG4gICAgXy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvYmogPSB0aGlzLl93cmFwcGVkO1xuICAgICAgbWV0aG9kLmFwcGx5KG9iaiwgYXJndW1lbnRzKTtcbiAgICAgIGlmICgobmFtZSA9PSAnc2hpZnQnIHx8IG5hbWUgPT0gJ3NwbGljZScpICYmIG9iai5sZW5ndGggPT09IDApIGRlbGV0ZSBvYmpbMF07XG4gICAgICByZXR1cm4gcmVzdWx0LmNhbGwodGhpcywgb2JqKTtcbiAgICB9O1xuICB9KTtcblxuICAvLyBBZGQgYWxsIGFjY2Vzc29yIEFycmF5IGZ1bmN0aW9ucyB0byB0aGUgd3JhcHBlci5cbiAgZWFjaChbJ2NvbmNhdCcsICdqb2luJywgJ3NsaWNlJ10sIGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgbWV0aG9kID0gQXJyYXlQcm90b1tuYW1lXTtcbiAgICBfLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHJlc3VsdC5jYWxsKHRoaXMsIG1ldGhvZC5hcHBseSh0aGlzLl93cmFwcGVkLCBhcmd1bWVudHMpKTtcbiAgICB9O1xuICB9KTtcblxuICBfLmV4dGVuZChfLnByb3RvdHlwZSwge1xuXG4gICAgLy8gU3RhcnQgY2hhaW5pbmcgYSB3cmFwcGVkIFVuZGVyc2NvcmUgb2JqZWN0LlxuICAgIGNoYWluOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuX2NoYWluID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvLyBFeHRyYWN0cyB0aGUgcmVzdWx0IGZyb20gYSB3cmFwcGVkIGFuZCBjaGFpbmVkIG9iamVjdC5cbiAgICB2YWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5fd3JhcHBlZDtcbiAgICB9XG5cbiAgfSk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwibmFtZVwiOiBcImpvb2xhLnNka1wiLFxuICBcInByZWZlckdsb2JhbFwiOiBmYWxzZSxcbiAgXCJ2ZXJzaW9uXCI6IFwiMC44LjItZGV2ZWxvcFwiLFxuICBcImF1dGhvclwiOiBcIkpvb2xhIDxpbmZvQGpvby5sYT5cIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcImpvb2xhJ3Mgc29mdHdhcmUgZGV2ZWxvcG1lbnQga2l0IChTREspXCIsXG4gIFwiZW5naW5lXCI6IFwibm9kZSA+PSAwLjEwLnhcIixcbiAgXCJwcml2YXRlXCI6IGZhbHNlLFxuICBcInJlcG9zaXRvcnlcIjoge1xuICAgIFwidHlwZVwiOiBcImdpdFwiLFxuICAgIFwidXJsXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL2pvb2xhL2pvb2xhLnNkay5naXRcIlxuICB9LFxuICBcImJ1Z3NcIjogXCJodHRwczovL2dpdGh1Yi5jb20vam9vbGEvam9vbGEuc2RrL2lzc3Vlc1wiLFxuICBcImNvbnRyaWJ1dG9yc1wiOiBbXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiSXRheSBXZWluYmVyZ2VyXCIsXG4gICAgICBcImVtYWlsXCI6IFwiaXRheUBqb28ubGFcIixcbiAgICAgIFwidXJsXCI6IFwiaHR0cDovL2pvby5sYVwiXG4gICAgfSxcbiAgICB7XG4gICAgICBcIm5hbWVcIjogXCJPciBXZWluYmVyZ2VyXCIsXG4gICAgICBcImVtYWlsXCI6IFwib3JAam9vLmxhXCIsXG4gICAgICBcInVybFwiOiBcImh0dHA6Ly9qb28ubGFcIlxuICAgIH1cbiAgXSxcbiAgXCJtYWluXCI6IFwiLi9zcmMvbGliL2luZGV4LmpzXCIsXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJ0ZXN0XCI6IFwibWFrZSB0ZXN0XCIsXG4gICAgXCJjb3ZlcmFsbHNcIjogXCJtb2NoYSAtLXJlcXVpcmUgYmxhbmtldCAtLXJlcG9ydGVyIG1vY2hhLWxjb3YtcmVwb3J0ZXIgfCBub2RlIC4vbm9kZV9tb2R1bGVzL2NvdmVyYWxscy9iaW4vY292ZXJhbGxzLmpzXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYXN5bmNcIjogXCJ+MC4yLjEwXCIsXG4gICAgXCJjbG9uZWV4dGVuZFwiOiBcIl4wLjAuM1wiLFxuICAgIFwiZGVlcC1leHRlbmRcIjogXCJeMC4yLjEwXCIsXG4gICAgXCJldmVudGVtaXR0ZXIyXCI6IFwifjAuNC4xM1wiLFxuICAgIFwianF1ZXJ5XCI6IFwiXjIuMS4xXCIsXG4gICAgXCJqcXVlcnktdWlcIjogXCJeMS4xMC41XCIsXG4gICAgXCJtb21lbnRcIjogXCJeMi44LjRcIixcbiAgICBcInNvY2tldC5pby1jbGllbnRcIjogXCJeMS4wLjJcIixcbiAgICBcInRyYXZlcnNlXCI6IFwiXjAuNi42XCIsXG4gICAgXCJ0d2l4XCI6IFwiXjAuNS4xXCIsXG4gICAgXCJ1bmRlcnNjb3JlXCI6IFwifjEuNS4yXCJcbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiY2hhaVwiOiBcIn4xLjkuMVwiLFxuICAgIFwiZ3J1bnQtYnJvd3NlcmlmeVwiOiBcIn4yLjAuOFwiLFxuICAgIFwiZ3J1bnQtY29udHJpYi1jbGVhblwiOiBcIn4wLjUuMFwiLFxuICAgIFwiZ3J1bnQtY29udHJpYi1jb25jYXRcIjogXCJ+MC40LjBcIixcbiAgICBcImdydW50LWNvbnRyaWItY29ubmVjdFwiOiBcIn4wLjcuMVwiLFxuICAgIFwiZ3J1bnQtY29udHJpYi1jb3B5XCI6IFwifjAuNS4wXCIsXG4gICAgXCJncnVudC1jb250cmliLWpzaGludFwiOiBcIn4wLjEwLjBcIixcbiAgICBcImdydW50LWNvbnRyaWItdWdsaWZ5XCI6IFwifjAuNC4wXCIsXG4gICAgXCJncnVudC1jc3NcIjogXCJ+MC41LjRcIixcbiAgICBcImdydW50LWh0dHBcIjogXCJeMS40LjJcIixcbiAgICBcImdydW50LW1vY2hhXCI6IFwifjAuNC4xMFwiLFxuICAgIFwiZ3J1bnQtc2F1Y2VsYWJzXCI6IFwifjUuMS4zXCIsXG4gICAgXCJncnVudC13YXRjaGlmeVwiOiBcIn4wLjEuMFwiLFxuICAgIFwibW9jaGFcIjogXCJ+MS4xOS4wXCIsXG4gICAgXCJtb2NoYS1waGFudG9tLWNvdmVyYWdlLXJlcG9ydGVyXCI6IFwifjAuMS4wXCIsXG4gICAgXCJzaW5vblwiOiBcIn4xLjEwLjBcIlxuICB9LFxuICBcImxpY2Vuc2VcIjogXCJHUEwtMy4wXCJcbn1cbiIsIi8qKlxuICogIEB0aXRsZSBqb29sYS9saWIvc2RrL2NvbW1vbi9hcGlcbiAqICBAY29weXJpZ2h0IChjKSBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+LiBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlNcbiAqXG4gKiAgUHJvdmlkZXMgdGhlIFNESyB3aXRoIGEgY2VudHJhbGl6ZWQgbWFuYWdlbWVudCBmb3IgY29uc3VtaW5nIGRhdGEgZnJvbSBhIGpvb2xhXG4gKiAgbm9kZS4gQWxsIEFQSSBjYWxscyBhcmUgcm91dGVkIHRocm91Z2ggdGhpcyBpbnRlcmZhY2UuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG5cblxuICBodHRwID0gcmVxdWlyZSgnaHR0cCcpLFxuICBodHRwcyA9IHJlcXVpcmUoJ2h0dHBzJyksXG4gIHF1ZXJ5c3RyaW5nID0gcmVxdWlyZSgncXVlcnlzdHJpbmcnKTtcblxudmFyIGFwaSA9IGV4cG9ydHM7XG5hcGkuX2lkID0gJ2FwaSc7XG5cbi8qIEFkZCBzdXBwb3J0IGZvciBKU09OIHBhcnNpbmcgb2YgcXVlcnkgc3RyaW5nICovXG5xdWVyeXN0cmluZy5lc2NhcGUgPSBmdW5jdGlvbiAoc3RyKSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQoc3RyKTtcbn07XG5cbnZhciBzdHJpbmdpZnlQcmltaXRpdmUgPSBmdW5jdGlvbiAodikge1xuICBzd2l0Y2ggKHR5cGVvZiB2KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiB2O1xuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgcmV0dXJuIHYgPyAndHJ1ZScgOiAnZmFsc2UnO1xuICAgIGNhc2UgJ251bWJlcic6XG4gICAgICByZXR1cm4gaXNGaW5pdGUodikgPyB2IDogJyc7XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2KTtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJyc7XG4gIH1cbn07XG5cbnF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSA9IHF1ZXJ5c3RyaW5nLmVuY29kZSA9IGZ1bmN0aW9uIChvYmosIHNlcCwgZXEsIG5hbWUpIHtcbiAgc2VwID0gc2VwIHx8ICcmJztcbiAgZXEgPSBlcSB8fCAnPSc7XG4gIG9iaiA9IChvYmogPT09IG51bGwpID8gdW5kZWZpbmVkIDogb2JqO1xuXG4gIHRyeSB7XG4gICAgc3dpdGNoICh0eXBlb2Ygb2JqKSB7XG4gICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5tYXAoZnVuY3Rpb24gKGspIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmpba10pKSB7XG4gICAgICAgICAgICByZXR1cm4gb2JqW2tdLm1hcChmdW5jdGlvbiAodikge1xuICAgICAgICAgICAgICByZXR1cm4gcXVlcnlzdHJpbmcuZXNjYXBlKHN0cmluZ2lmeVByaW1pdGl2ZShrKSkgK1xuICAgICAgICAgICAgICAgIGVxICtcbiAgICAgICAgICAgICAgICBxdWVyeXN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKHYpKTtcbiAgICAgICAgICAgIH0pLmpvaW4oc2VwKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHF1ZXJ5c3RyaW5nLmVzY2FwZShzdHJpbmdpZnlQcmltaXRpdmUoaykpICtcbiAgICAgICAgICAgICAgZXEgK1xuICAgICAgICAgICAgICBxdWVyeXN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKG9ialtrXSkpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmpvaW4oc2VwKTtcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKCFuYW1lKSByZXR1cm4gJyc7XG4gICAgICAgIHJldHVybiBxdWVyeXN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKG5hbWUpKSArIGVxICtcbiAgICAgICAgICBxdWVyeXN0cmluZy5lc2NhcGUoc3RyaW5naWZ5UHJpbWl0aXZlKG9iaikpO1xuICAgIH1cbiAgfVxuICBjYXRjaCAoZXgpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGNvbnNvbGUubG9nKGV4KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gbGVuZ3RoSW5VdGY4Qnl0ZXMoc3RyKSB7XG4gIC8vIE1hdGNoZXMgb25seSB0aGUgMTAuLiBieXRlcyB0aGF0IGFyZSBub24taW5pdGlhbCBjaGFyYWN0ZXJzIGluIGEgbXVsdGktYnl0ZSBzZXF1ZW5jZS5cbiAgdmFyIG0gPSBlbmNvZGVVUklDb21wb25lbnQoc3RyKS5tYXRjaCgvJVs4OUFCYWJdL2cpO1xuICByZXR1cm4gc3RyLmxlbmd0aCArIChtID8gbS5sZW5ndGggOiAwKTtcbn1cbi8qIEVORCBPRiBBZGQgc3VwcG9ydCBmb3IgSlNPTiBwYXJzaW5nIG9mIHF1ZXJ5IHN0cmluZyAqL1xuXG5cbmFwaS5yZXF1ZXN0Q291bnQgPSAwO1xuYXBpLndhaXRpbmdSZXF1ZXN0cyA9IFtdO1xuXG4vKipcbiAqIENvbnN1bWVzIGFuIEFQSSBlbmRwb2ludCBiYXNlZCBvbiBvcHRpb25zIHBhc3NlZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBlbmRwb2ludCB0aGUgZW5kcG9pbnQgdG8gY29uc3VtZVxuICogQHBhcmFtIHtvYmplY3R9IG9iak9wdGlvbnMgb3B0aW9ucyBmb3IgdGhlIGFjdHVhbCBlbmRwb2ludCBwYXJhbWV0ZXJzXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsZWQgd2hlbiB0aGUgcmVzdWx0IGFycml2ZXMvZXJyb3JcbiAqL1xuYXBpLmZldGNoID0gZnVuY3Rpb24gKHRva2VucywgZW5kcG9pbnQsIG9iak9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gYXBpO1xuICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2sgPSBvYmpPcHRpb25zO1xuICAgIG9iak9wdGlvbnMgPSBlbmRwb2ludDtcbiAgICBlbmRwb2ludCA9IHRva2VucztcbiAgICB0b2tlbnMgPSB7XzogbnVsbCwgX186IG51bGx9O1xuICB9XG5cbiAgaWYgKGFwaS5yZXF1ZXN0Q291bnQgPCAoam9vbGEub3B0aW9ucy5tYXhSZXF1ZXN0cyB8fCAxMDApKSB7XG4gICAgYXBpLnJlcXVlc3RDb3VudCsrO1xuICAgIHRyeSB7XG4gICAgICB2YXIgcGFydHMgPSByZXF1aXJlKCd1cmwnKS5wYXJzZShqb29sYS5vcHRpb25zLmhvc3QpO1xuICAgICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICAgIHRva2VuczogdG9rZW5zLFxuICAgICAgICBob3N0OiBwYXJ0cy5ob3N0bmFtZSxcbiAgICAgICAgcG9ydDogcGFydHMucG9ydCxcbiAgICAgICAgc2VjdXJlOiBwYXJ0cy5wcm90b2NvbCAhPT0gJ2h0dHA6JyxcbiAgICAgICAgcGF0aDogZW5kcG9pbnQsXG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHNlbGYuZ2V0SlNPTihvcHRpb25zLCBvYmpPcHRpb25zLCBmdW5jdGlvbiAoZXJyLCByZXN1bHQsIGhlYWRlcnMpIHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIGlmICghcmVzdWx0LnJlYWx0aW1lKVxuICAgICAgICAgICAgYXBpLnJlcXVlc3RDb3VudC0tO1xuICAgICAgICB9XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBhcGkucmVxdWVzdENvdW50LS07XG5cbiAgICAgICAgaWYgKHNlbGYucmVxdWVzdENvdW50IDwgMClcbiAgICAgICAgICBzZWxmLnJlcXVlc3RDb3VudCA9IDA7XG5cbiAgICAgICAgaWYgKGFwaS53YWl0aW5nUmVxdWVzdHMubGVuZ3RoKVxuICAgICAgICAgIGFwaS5mZXRjaC5hcHBseShudWxsLCBhcGkud2FpdGluZ1JlcXVlc3RzLnNoaWZ0KCkpO1xuXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIHJlc3VsdCwgaGVhZGVycyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgY2F0Y2ggKGV4KSB7XG4gICAgICBjb25zb2xlLmxvZyhleCk7XG4gICAgICBjb25zb2xlLmxvZyhleC5zdGFjayk7XG4gICAgICByZXR1cm4gY2FsbGJhY2soZXgpO1xuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGFwaS53YWl0aW5nUmVxdWVzdHMucHVzaChhcmd1bWVudHMpO1xuICB9XG59O1xuXG4vKipcbiAqIFRoZSBhY3R1YWwgd29ya2VyIGZvciBnZXR0aW5nIGEganNvbiBvYmplY3QgZnJvbSB0aGUgQVBJIHNlcnZpY2UgYmFzZWQgb24gdGhlIG9wdGlvbnMgcGFzc2VkLlxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgb3B0aW9ucyByZWxhdGluZyB0byB0aGUgY29ubmVjdGlvbiBhbmQgZW5kcG9pbnRcbiAqIEBwYXJhbSB7b2JqZWN0fSBvYmpPcHRpb25zIG9wdGlvbnMgZm9yIHRoZSBhY3R1YWwgZW5kcG9pbnQgcGFyYW1ldGVyc1xuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHJlc3VsdCBhcnJpdmVzL2Vycm9yXG4gKi9cbmFwaS5nZXRKU09OID0gZnVuY3Rpb24gKG9wdGlvbnMsIG9iak9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIHZhciBwcm90ID0gb3B0aW9ucy5zZWN1cmUgPyBodHRwcyA6IGh0dHA7XG4gIGpvb2xhLmxvZ2dlci5zaWxseSgnW2FwaV0gRmV0Y2hpbmcgSlNPTiBmcm9tICcgKyBvcHRpb25zLmhvc3QgKyAnOicgKyBvcHRpb25zLnBvcnQgKyBvcHRpb25zLnBhdGggKyAnQCcgKyAoam9vbGEuQVBJVE9LRU4gfHwgam9vbGEuVE9LRU4gKSk7XG5cbiAgaWYgKCFqb29sYS5pbyB8fCBqb29sYS5vcHRpb25zLmFqYXggfHwgb3B0aW9ucy5hamF4KSB7XG4gICAgdmFyIHFzID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KG9iak9wdGlvbnMpO1xuICAgIG9wdGlvbnMucGF0aCArPSAnPycgKyBxcztcbiAgICB2YXIgdGltZXJJRCwgYWJvcnRlZDtcbiAgICB0cnkge1xuICAgICAgdmFyIHJlcSA9IHByb3QucmVxdWVzdChvcHRpb25zLCBmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgIHZhciBvdXRwdXQgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgb3V0cHV0ICs9IGNodW5rO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXMub24oJ2VuZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXJJRCk7XG4gICAgICAgICAgaWYgKGFib3J0ZWQpXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdbYXBpXSBUaW1lb3V0IHdoaWxlIGZldGNoaW5nOiAnICsgb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0ICsgb3B0aW9ucy5wYXRoKSk7XG5cbiAgICAgICAgICB2YXIgb2JqO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBvdXRwdXQgPT09ICdvYmplY3QnKSB7XG5cbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSBpZiAocmVzLnN0YXR1c0NvZGUgPT0gMjAwKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBvYmogPSBKU09OLnBhcnNlKG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgICAgam9vbGEubG9nZ2VyLmVycm9yKCdbYXBpXSBFcnJvcjogJyArIG9wdGlvbnMuaG9zdCArICc6JyArIG9wdGlvbnMucG9ydCArIG9wdGlvbnMucGF0aCArICcuIEVycm9yOiAnICsgZXgubWVzc2FnZSk7XG4gICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ1thcGldIEVycm9yOiAnICsgb3B0aW9ucy5ob3N0ICsgJzonICsgb3B0aW9ucy5wb3J0ICsgb3B0aW9ucy5wYXRoICsgJy4gRXJyb3I6ICcgKyBleC5tZXNzYWdlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXMuc3RhdHVzQ29kZSA9PSAyMDApIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBvYmopO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIGlmIChyZXMuc3RhdHVzQ29kZSA9PSAzMDIpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIHJlcXVlc3QgWycgKyByZXMuc3RhdHVzQ29kZSArICddOiBBdXRoZW50aWNhdGlvbiBGYWlsZWQnKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYgKHJlcy5zdGF0dXNDb2RlID09IDQwMSkge1xuICAgICAgICAgICAgLy9sZXQncyByZWRpcmVjdCB0byBsb2dpblxuICAgICAgICAgICAgaWYgKGpvb2xhLm9wdGlvbnMubG9nb3V0dXJsKVxuICAgICAgICAgICAgICBsb2NhdGlvbi5ocmVmID0gam9vbGEub3B0aW9ucy5sb2dvdXR1cmw7XG5cbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIHJlcXVlc3QgWycgKyByZXMuc3RhdHVzQ29kZSArICddOiAnICsgKG9iaiAmJiBvYmoubWVzc2FnZSAhPT0gJ3VuZGVmaW5lZCcgPyBvYmoubWVzc2FnZSA6ICdVbmF1dGhvcml6ZWQnKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ0ZhaWxlZCB0byBleGVjdXRlIHJlcXVlc3QgWycgKyByZXMuc3RhdHVzQ29kZSArICddOiAnICsgKG9iaiAmJiBvYmoubWVzc2FnZSA/IG9iai5tZXNzYWdlIDogb2JqIHx8ICduL2EnKSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgdGltZXJJRCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICBhYm9ydGVkID0gdHJ1ZTtcbiAgICAgICAgLy9BYm9ydGluZyB0aGUgeGhyIG9mIGh0dHAocyktYnJvd3NlcmlmeVxuICAgICAgICBpZiAocmVxLnhocilcbiAgICAgICAgICByZXEueGhyLmFib3J0KCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICByZXEuYWJvcnQoKTtcbiAgICAgIH0sIG9wdGlvbnMudGltZW91dCB8fCBqb29sYS5vcHRpb25zLnRpbWVvdXQgfHwgMTUwMDApO1xuXG4gICAgICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIH0pO1xuXG4gICAgICAvL3JlcS53cml0ZShxcyk7XG4gICAgICByZXEuZW5kKCk7XG4gICAgfVxuICAgIGNhdGNoIChleCkge1xuICAgICAgY29uc29sZS5sb2coZXgpO1xuICAgIH1cbiAgfVxuICBlbHNlIHtcbiAgICBvcHRpb25zLnBhdGggPSBvcHRpb25zLnBhdGguc3Vic3RyaW5nKDEpO1xuXG4gICAgdmFyIHByb2Nlc3NSZXNwb25zZSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICB2YXIgaGVhZGVycyA9IGRhdGEuaGVhZGVycztcbiAgICAgIHZhciBtZXNzYWdlID0gZGF0YS5tZXNzYWdlO1xuXG4gICAgICBpZiAobWVzc2FnZSAmJiAhbWVzc2FnZS5oYXNPd25Qcm9wZXJ0eSgncmVhbHRpbWUnKSkge1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncnBjOmRvbmUnLCAxKTtcbiAgICAgICAgLy9qb29sYS5ldmVudHMuZW1pdCgnYmFuZHdpZHRoJywgbGVuZ3RoSW5VdGY4Qnl0ZXMoSlNPTi5zdHJpbmdpZnkob2JqT3B0aW9ucykpKTtcbiAgICAgICAgaWYgKGhlYWRlcnMgJiYgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddKVxuICAgICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCd3YWl0dGltZScsIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSk7XG4gICAgICAgIGlmIChoZWFkZXJzICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24tRnVsZmlsbGVkJ10gJiYgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddKVxuICAgICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdsYXRlbmN5JywgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddIC0gaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbi1GdWxmaWxsZWQnXSk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmICghbWVzc2FnZSkge1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncnBjOmRvbmUnLCAxKTtcbiAgICAgICAgLy9qb29sYS5ldmVudHMuZW1pdCgnYmFuZHdpZHRoJywgbGVuZ3RoSW5VdGY4Qnl0ZXMoSlNPTi5zdHJpbmdpZnkob2JqT3B0aW9ucykpKTtcbiAgICAgICAgaWYgKGhlYWRlcnMgJiYgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddKVxuICAgICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCd3YWl0dGltZScsIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24nXSk7XG4gICAgICAgIGlmIChoZWFkZXJzICYmIGhlYWRlcnNbJ1gtam9vbGEtRHVyYXRpb24tRnVsZmlsbGVkJ10gJiYgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddKVxuICAgICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdsYXRlbmN5JywgaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbiddIC0gaGVhZGVyc1snWC1qb29sYS1EdXJhdGlvbi1GdWxmaWxsZWQnXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChoZWFkZXJzICYmIGhlYWRlcnMuU3RhdHVzQ29kZSAmJiBoZWFkZXJzLlN0YXR1c0NvZGUgPT0gNDAxKSB7XG4gICAgICAgIC8vbGV0J3MgcmVkaXJlY3QgdG8gbG9naW5cbiAgICAgICAgaWYgKGpvb2xhLm9wdGlvbnMubG9nb3V0dXJsKVxuICAgICAgICAgIGxvY2F0aW9uLmhyZWYgPSBqb29sYS5vcHRpb25zLmxvZ291dHVybDtcblxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKCdGYWlsZWQgdG8gZXhlY3V0ZSByZXF1ZXN0OiAnICsgZGF0YS5tZXNzYWdlLm1lc3NhZ2UpKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGhlYWRlcnMgJiYgaGVhZGVycy5TdGF0dXNDb2RlICYmIGhlYWRlcnMuU3RhdHVzQ29kZSA9PSA1MDApXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhtZXNzYWdlLm1lc3NhZ2UgPyBtZXNzYWdlLm1lc3NhZ2UgOiAndW5rbm93biBlcnJvcicpO1xuXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbWVzc2FnZSwgaGVhZGVycyk7XG4gICAgfTtcblxuXG4gICAgdmFyIHJvdXRlSUQgPSBvcHRpb25zLnBhdGggKyAnLScgKyBqb29sYS5jb21tb24udXVpZCgpO1xuXG4gICAgaWYgKGpvb2xhLlRPS0VOKVxuICAgICAgb2JqT3B0aW9ucy5fdG9rZW4gPSBqb29sYS5UT0tFTjtcbiAgICBpZiAoIW9iak9wdGlvbnMuX3Rva2VuKVxuICAgICAgb2JqT3B0aW9ucy5BUElUb2tlbiA9IGpvb2xhLkFQSVRPS0VOO1xuXG4gICAgaWYgKG9wdGlvbnMudG9rZW5zICYmIChvcHRpb25zLnRva2Vucy5fIHx8IG9wdGlvbnMudG9rZW5zLl9fKSkge1xuICAgICAgb2JqT3B0aW9ucy5fdG9rZW4gPSBudWxsO1xuICAgICAgb2JqT3B0aW9ucy5BUElUb2tlbiA9IG51bGw7XG4gICAgICBpZiAob3B0aW9ucy50b2tlbnMuXylcbiAgICAgICAgb2JqT3B0aW9ucy5fdG9rZW4gPSBvcHRpb25zLnRva2Vucy5fO1xuICAgICAgaWYgKG9wdGlvbnMudG9rZW5zLl9fKVxuICAgICAgICBvYmpPcHRpb25zLkFQSVRva2VuID0gb3B0aW9ucy50b2tlbnMuX187XG4gICAgfVxuXG4gICAgb2JqT3B0aW9ucy5fcGF0aCA9IG9wdGlvbnMucGF0aDtcblxuICAgIGpvb2xhLmlvLnNvY2tldC5lbWl0KHJvdXRlSUQsIG9iak9wdGlvbnMpO1xuICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdycGM6c3RhcnQnLCAxKTtcbiAgICBqb29sYS5ldmVudHMuZW1pdCgnYmFuZHdpZHRoJywgbGVuZ3RoSW5VdGY4Qnl0ZXMoSlNPTi5zdHJpbmdpZnkob2JqT3B0aW9ucykpKTtcbiAgICBpZiAob2JqT3B0aW9ucyAmJiAob2JqT3B0aW9ucy5yZWFsdGltZSB8fCAob2JqT3B0aW9ucy5vcHRpb25zICYmIEFycmF5LmlzQXJyYXkob2JqT3B0aW9ucy5vcHRpb25zKSAmJiBvYmpPcHRpb25zLm9wdGlvbnMubGVuZ3RoID4gMCAmJiBvYmpPcHRpb25zLm9wdGlvbnNbMF0ucmVhbHRpbWUpKSkge1xuICAgICAgam9vbGEuaW8uc29ja2V0Lm9uKHJvdXRlSUQgKyAnOmRvbmUnLCBwcm9jZXNzUmVzcG9uc2UpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGpvb2xhLmlvLnNvY2tldC5vbmNlKHJvdXRlSUQgKyAnOmRvbmUnLCBwcm9jZXNzUmVzcG9uc2UpO1xuICAgIH1cbiAgfVxufTtcblxuam9vbGEuZXZlbnRzLm9uKCdycGM6c3RhcnQnLCBmdW5jdGlvbiAoKSB7XG4gIGlmICgham9vbGEudXNhZ2UpXG4gICAgam9vbGEudXNhZ2UgPSB7Y3VycmVudENhbGxzOiAwfTtcbiAgam9vbGEudXNhZ2UuY3VycmVudENhbGxzKys7XG59KTtcblxuam9vbGEuZXZlbnRzLm9uKCdycGM6ZG9uZScsIGZ1bmN0aW9uICgpIHtcbiAgaWYgKCFqb29sYS51c2FnZSlcbiAgICBqb29sYS51c2FnZSA9IHtjdXJyZW50Q2FsbHM6IDB9O1xuICBqb29sYS51c2FnZS5jdXJyZW50Q2FsbHMtLTtcbn0pOyIsIi8qKlxuICogIGpvb2xhXG4gKlxuICogIENvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICpcbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKTtcblxudmFyIGRpc3BhdGNoID0gZXhwb3J0cztcbmRpc3BhdGNoLl9pZCA9ICdkaXNwYXRjaCc7XG5cbmRpc3BhdGNoLmZldGNoTWV0YSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICB2YXIgbWV0YSA9IHJlcXVpcmUoJy4uLy4uLy4uL2J1aWxkL3RlbXAvbWV0YS5qc29uJyk7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBtZXRhKTtcbn07XG5cbmRpc3BhdGNoLmJ1aWxkc3R1YiA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGVtcHR5ZnVuYztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZGlzcGF0Y2guZmV0Y2hNZXRhKGZ1bmN0aW9uIChlcnIsIHJlc3VsdCkge1xuICAgIGpvb2xhLmFwaS5kZXNjcmliZSA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHJlc3VsdCkuZm9yRWFjaChmdW5jdGlvbiAoZW5kcG9pbnRzKSB7XG4gICAgICBkaXNwYXRjaFtlbmRwb2ludHNdID0ge307XG4gICAgICBPYmplY3Qua2V5cyhyZXN1bHRbZW5kcG9pbnRzXSkuZm9yRWFjaChmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgaWYgKCFqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXSlcbiAgICAgICAgICBqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXSA9IHt9O1xuICAgICAgICBqb29sYS5hcGkuZGVzY3JpYmVbZW5kcG9pbnRzXVtmbl0gPSBjZS5jbG9uZWV4dGVuZChyZXN1bHRbZW5kcG9pbnRzXVtmbl0pO1xuXG4gICAgICAgIHZhciBfZm4gPSByZXN1bHRbZW5kcG9pbnRzXVtmbl07XG4gICAgICAgIGRpc3BhdGNoW2VuZHBvaW50c11bZm5dID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciB0b2tlbnMgPSB7XG4gICAgICAgICAgICBfOiBudWxsLFxuICAgICAgICAgICAgX186IG51bGxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcbiAgICAgICAgICBpZiAoYXJncyAmJiBhcmdzLmxlbmd0aCA+IDAgJiYgYXJnc1swXSAmJiAoYXJnc1swXS5fIHx8IGFyZ3NbMF0uX18pKSB7XG4gICAgICAgICAgICB0b2tlbnMuXyA9IGFyZ3NbMF0uXztcbiAgICAgICAgICAgIHRva2Vucy5fXyA9IGFyZ3NbMF0uX187XG4gICAgICAgICAgICBhcmdzLnNwbGljZSgwLCAxKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjYWxsYmFjayA9IGVtcHR5ZnVuYztcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZ3NbT2JqZWN0LmtleXMoYXJncykubGVuZ3RoIC0gMV0gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrID0gYXJnc1tPYmplY3Qua2V5cyhhcmdzKS5sZW5ndGggLSAxXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFsndmVyaWZ5QVBJVG9rZW4nLCAnZ2V0QnlUb2tlbiddLmluZGV4T2YoZm4pID09PSAtMSkge1xuICAgICAgICAgICAgaWYgKCFqb29sYS5jb25uZWN0ZWQpXG4gICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoJ0pvb2xhIG5vdCBjb25uZWN0ZWQuJykpO1xuICAgICAgICAgICAgaWYgKCFqb29sYS5VU0VSKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGZuKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignSm9vbGEgbm90IGNvbm5lY3RlZCwgaW52YWxpZCB1c2VyLicpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGFyZ0NvdW50ZXIgPSAwO1xuICAgICAgICAgIHZhciBfYXJncyA9IHt9O1xuICAgICAgICAgIGlmIChfZm4uaW5wdXRzLnJlcXVpcmVkKVxuICAgICAgICAgICAgX2ZuLmlucHV0cyA9IF9mbi5pbnB1dHMucmVxdWlyZWQuY29uY2F0KF9mbi5pbnB1dHMub3B0aW9uYWwpO1xuXG4gICAgICAgICAgdmFyIHNob3VsZEFwcGVuZFdvcmtzcGFjZSA9IDA7XG5cbiAgICAgICAgICAvL2lmICgoYXJncy5sZW5ndGggLSAxID09IF9mbi5pbnB1dHMubGVuZ3RoIC0gMSB8fCAoYXJncy5sZW5ndGggLSAxID09IF9mbi5pbnB1dHMubGVuZ3RoIC0gMiAmJiBfZm4uaW5wdXRzW19mbi5pbnB1dHMubGVuZ3RoIC0gMV0gPT0gJ29wdGlvbnMnKSkgJiYgX2ZuLmlucHV0c1swXSAmJiAoX2ZuLmlucHV0c1swXSA9PT0gJ3dvcmtzcGFjZScpKSB7XG4gICAgICAgICAgaWYgKF9mbi5pbnB1dHNbMF0gPT09ICd3b3Jrc3BhY2UnICYmIGFyZ3MubGVuZ3RoIC0gMSA8IF9mbi5pbnB1dHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBzaG91bGRBcHBlbmRXb3Jrc3BhY2UgPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc2hvdWxkQXBwZW5kV29ya3NwYWNlID4gMClcbiAgICAgICAgICAgIF9hcmdzW19mbi5pbnB1dHNbMF1dID0gam9vbGEuVVNFUi53b3Jrc3BhY2U7XG4gICAgICAgICAgT2JqZWN0LmtleXMoYXJncykuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICBpZiAoYXJnQ291bnRlciA8IF9mbi5pbnB1dHMubGVuZ3RoIC0gc2hvdWxkQXBwZW5kV29ya3NwYWNlKSB7XG4gICAgICAgICAgICAgIGFyZ3NbX2ZuLmlucHV0c1thcmdDb3VudGVyICsgc2hvdWxkQXBwZW5kV29ya3NwYWNlXV0gPSBhcmdzW2FyZ107XG4gICAgICAgICAgICAgIF9hcmdzW19mbi5pbnB1dHNbYXJnQ291bnRlciArIHNob3VsZEFwcGVuZFdvcmtzcGFjZV1dID0gYXJnc1thcmddO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZWxldGUgYXJnc1thcmddO1xuICAgICAgICAgICAgYXJnQ291bnRlcisrO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgYXJncyA9IF9hcmdzO1xuICAgICAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnWycgKyBlbmRwb2ludHMgKyAnOicgKyBmbiArICddIGNhbGxlZCB3aXRoOiAnICsgSlNPTi5zdHJpbmdpZnkoYXJncykpO1xuXG4gICAgICAgICAgdmFyIF9jYWxsYmFjayA9IGNlLmNsb25lKGNhbGxiYWNrKTsvLy5jbG9uZSgpO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBqb29sYS5hcGkuZmV0Y2godG9rZW5zLCBfZm4ubmFtZSwgYXJncywgZnVuY3Rpb24gKGVyciwgcmVzdWx0LCBoZWFkZXJzKSB7XG4gICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NhbGxiYWNrKGVyciwgcmVzdWx0LCBoZWFkZXJzKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXRjaCAoZXgpIHtcbiAgICAgICAgICAgIHJldHVybiBfY2FsbGJhY2soZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKCFqb29sYVtlbmRwb2ludHNdKVxuICAgICAgICAgIGpvb2xhW2VuZHBvaW50c10gPSB7fTtcbiAgICAgICAgaWYgKCFqb29sYVtlbmRwb2ludHNdW2ZuXSlcbiAgICAgICAgICBqb29sYVtlbmRwb2ludHNdW2ZuXSA9IGRpc3BhdGNoW2VuZHBvaW50c11bZm5dO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvL21hcCBhbGlhc2VzXG4gICAgam9vbGEuaW5zZXJ0ID0gam9vbGEuYmVhY29uLmluc2VydDtcbiAgICBqb29sYS5mZXRjaCA9IGpvb2xhLnF1ZXJ5LmZldGNoO1xuXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICB9KTtcbn07XG5cbiIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgRXZlbnRFbWl0dGVyMiA9IHJlcXVpcmUoJ2V2ZW50ZW1pdHRlcjInKS5FdmVudEVtaXR0ZXIyO1xuXG52YXIgX2V2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXIyKHt3aWxkY2FyZDogdHJ1ZSwgbmV3TGlzdGVuZXI6IHRydWV9KTtcbl9ldmVudHMuX2lkID0gJ2V2ZW50cyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cyA9IF9ldmVudHM7XG4iLCJ2YXIgZ2xvYmFsPXR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fTsvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXIgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpO1xuXG5nbG9iYWwuZW1wdHlmdW5jID0gZnVuY3Rpb24gKCkge1xuXG59O1xuXG5qb29sYS50aW1lem9uZSA9IGZ1bmN0aW9uICh0eikge1xuICBpZiAodHopXG4gICAgam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCA9IHR6O1xuXG4gIHZhciBvZmZzZXQgPSAwO1xuICBpZiAoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldClcbiAgICBvZmZzZXQgPSBqb29sYS5vcHRpb25zLnRpbWV6b25lT2Zmc2V0IHx8IChuZXcgRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCkgLyA2MCAqIC0xKTtcblxuICByZXR1cm4gb2Zmc2V0O1xufTsiLCJ2YXIgQnVmZmVyPXJlcXVpcmUoXCJfX2Jyb3dzZXJpZnlfQnVmZmVyXCIpLkJ1ZmZlcjsvKmpzaGludCAtVzA4MyAqL1xuXG4vKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyksXG4gIGRlID0gcmVxdWlyZSgnZGVlcC1leHRlbmQnKSxcbiAgdHJhdmVyc2UgPSByZXF1aXJlKCd0cmF2ZXJzZScpLFxuICBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpOy8vLFxuLy9KU09OU3RyZWFtID0gcmVxdWlyZSgnSlNPTlN0cmVhbScpO1xuXG52YXIgY29tbW9uID0gY2UuY2xvbmUodXRpbCk7XG5jb21tb24uX2lkID0gJ2NvbW1vbic7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHMgPSBjb21tb247XG5jb21tb24uZXh0ZW5kID0gY29tbW9uLl9leHRlbmQ7XG5jb21tb24uXyA9IF87XG5cbnJlcXVpcmUoJy4vbW9kaWZpZXJzJyk7XG5cbmNvbW1vbi5taXhpbiA9IGZ1bmN0aW9uIChvcmlnaW4sIGFkZCwgb3ZlcndyaXRlKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgdHlwZW9mIGFkZCAhPT0gJ29iamVjdCcpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IDA7Ly9rZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGkgPCBrZXlzLmxlbmd0aCkge1xuICAgIGlmIChvcmlnaW4uaGFzT3duUHJvcGVydHkoa2V5c1tpXSkpIHtcbiAgICAgIGlmIChvdmVyd3JpdGUpXG4gICAgICAgIG9yaWdpbltrZXlzW2ldXSA9IGFkZFtrZXlzW2ldXTtcbiAgICAgIC8vZWxzZVxuICAgICAgLy9jb21tb24uZXh0ZW5kKG9yaWdpbltrZXlzW2ldXSwgYWRkW2tleXNbaV1dKTtcblxuICAgIH1cbiAgICBlbHNlXG4gICAgICBvcmlnaW5ba2V5c1tpXV0gPSBhZGRba2V5c1tpXV07XG4gICAgaSsrO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5jb21tb24uX21peGluID0gZnVuY3Rpb24gKGRlc3RpbmF0aW9uLCBzb3VyY2UpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAxIHx8IHR5cGVvZiBhcmd1bWVudHNbMF0gIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSByZXR1cm4gYXJndW1lbnRzWzBdO1xuXG4gIHZhciB0YXJnZXQgPSBhcmd1bWVudHNbMF07XG5cbiAgLy8gY29udmVydCBhcmd1bWVudHMgdG8gYXJyYXkgYW5kIGN1dCBvZmYgdGFyZ2V0IG9iamVjdFxuICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cbiAgdmFyIGtleSwgdmFsLCBzcmMsIGNsb25lLCB0bXBCdWY7XG5cbiAgYXJncy5mb3JFYWNoKGZ1bmN0aW9uIChvYmopIHtcbiAgICBpZiAodHlwZW9mIG9iaiAhPT0gJ29iamVjdCcpIHJldHVybjtcblxuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgIGlmICghKGtleSBpbiBvYmopKSBjb250aW51ZTtcblxuICAgICAgc3JjID0gdGFyZ2V0W2tleV07XG4gICAgICB2YWwgPSBvYmpba2V5XTtcblxuICAgICAgaWYgKHZhbCA9PT0gdGFyZ2V0KSBjb250aW51ZTtcblxuICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIGtleSA9PT0gJ2NvbnRhaW5lcicpIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSB2YWw7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIHZhbCAhPT0gJ29iamVjdCcgfHwgdmFsID09PSBudWxsKSB7XG4gICAgICAgIHRhcmdldFtrZXldID0gdmFsO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgIHRtcEJ1ZiA9IG5ldyBCdWZmZXIodmFsLmxlbmd0aCk7XG4gICAgICAgIHZhbC5jb3B5KHRtcEJ1Zik7XG4gICAgICAgIHRhcmdldFtrZXldID0gdG1wQnVmO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBzcmMgIT09ICdvYmplY3QnIHx8IHNyYyA9PT0gbnVsbCkge1xuICAgICAgICBjbG9uZSA9IChBcnJheS5pc0FycmF5KHZhbCkpID8gW10gOiB7fTtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBjb21tb24uX21peGluKGNsb25lLCB2YWwpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICBjbG9uZSA9IChBcnJheS5pc0FycmF5KHNyYykpID8gc3JjIDogW107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjbG9uZSA9ICghQXJyYXkuaXNBcnJheShzcmMpKSA/IHNyYyA6IHt9O1xuICAgICAgfVxuXG4gICAgICB0YXJnZXRba2V5XSA9IGNvbW1vbi5fbWl4aW4oY2xvbmUsIHZhbCk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHRhcmdldDtcbn07XG5cbi8vaG9vayBmdW5jdGlvbnMgZm9yIHRpbWluZ3Ncbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5jb21tb24uaG9va0V2ZW50cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgaWYgKCFvYmopXG4gICAgcmV0dXJuO1xuICB2YXIgbmFtZSwgZm4sIG9ial9pZDtcblxuICBpZiAob2JqLl9pZClcbiAgICBvYmpfaWQgPSBvYmouX2lkO1xuXG4gIGZvciAobmFtZSBpbiBvYmopIHtcbiAgICBmbiA9IG9ialtuYW1lXTtcbiAgICBpZiAobmFtZS5zdWJzdHJpbmcoMCwgMSkgPT0gJ18nKVxuICAgICAgY29udGludWU7XG5cbiAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIG5hbWUgIT09ICdob29rRXZlbnRzJykge1xuICAgICAgb2JqW25hbWVdID0gZnVuY3Rpb24gKG5hbWUsIGZuKSB7XG4gICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICB2YXIgdGltZUlEID0gJ0Z1bmN0aW9uICcgKyAob2JqX2lkID8gb2JqX2lkICsgJy4nIDogJycpICsgbmFtZTtcblxuICAgICAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkICYmIGNvbnNvbGUudGltZSlcbiAgICAgICAgICAgIGNvbnNvbGUudGltZSh0aW1lSUQpO1xuICAgICAgICAgIHZhciByZXN1bHQgPSBmbi5hcHBseShzZWxmLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkICYmIGNvbnNvbGUudGltZSkge1xuICAgICAgICAgICAgY29uc29sZS50aW1lRW5kKHRpbWVJRCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH07XG4gICAgICB9KG5hbWUsIGZuKTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGZuID09PSAnb2JqZWN0JylcbiAgICAgIHRoaXMuaG9va0V2ZW50cyhmbik7XG4gIH1cbn07XG5cbmNvbW1vbi51dWlkID0gZnVuY3Rpb24gKGxlbmd0aCkge1xuICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzg4NTU2ODcvc2VjdXJlLXJhbmRvbS10b2tlbi1pbi1ub2RlLWpzXG4gIGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhsZW5ndGgsIGNoYXJzKSB7XG4gICAgdmFyIGNoYXJzTGVuZ3RoID0gY2hhcnMubGVuZ3RoO1xuICAgIHZhciByYW5kb21CeXRlcyA9IGNyeXB0by5yYW5kb21CeXRlcyhsZW5ndGgpO1xuICAgIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobGVuZ3RoKTtcbiAgICB2YXIgY3Vyc29yID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjdXJzb3IgKz0gcmFuZG9tQnl0ZXNbaV07XG4gICAgICByZXN1bHRbaV0gPSBjaGFyc1tjdXJzb3IgJSBjaGFyc0xlbmd0aF07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQuam9pbignJyk7XG4gIH1cblxuICByZXR1cm4gcmFuZG9tU3RyaW5nKGxlbmd0aCB8fCAzMiwgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXd4eXpBQkNERUZHSElKS0xNTk9QUVJTVFVXWFlaMDEyMzQ1Njc4OScpO1xufTtcblxuY29tbW9uLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBKU09OLnN0cmluZ2lmeShvYmopKTtcbn07XG5cbmNvbW1vbi5wYXJzZSA9IGZ1bmN0aW9uIChzdHJpbmcsIGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayhudWxsLCBKU09OLnBhcnNlKHN0cmluZykpO1xufTtcblxuY29tbW9uLmhhc2ggPSBmdW5jdGlvbiAoc3RyaW5nKSB7XG4gIHJldHVybiByZXF1aXJlKCdjcnlwdG8nKS5jcmVhdGVIYXNoKCdtZDUnKS51cGRhdGUoc3RyaW5nKS5kaWdlc3QoXCJoZXhcIik7XG59O1xuXG5jb21tb24uZW5zdXJlTGVuZ3RoID0gZnVuY3Rpb24gKHN0cmluZywgbGVuZ3RoKSB7XG4gIGlmICghc3RyaW5nKVxuICAgIHJldHVybiBzdHJpbmc7XG4gIGlmICh0eXBlb2Ygc3RyaW5nICE9PSAnc3RyaW5nJylcbiAgICByZXR1cm4gc3RyaW5nO1xuICBpZiAoc3RyaW5nID09PSAnJylcbiAgICByZXR1cm47XG4gIHZhciBjb3VudGVyID0gMDtcbiAgd2hpbGUgKHN0cmluZy5sZW5ndGggPiBsZW5ndGggJiYgY291bnRlciA8IDEwMCkge1xuICAgIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKCcuLi4nLCAnJyk7XG4gICAgc3RyaW5nID0gc3RyaW5nLnN1YnN0cmluZygwLCBzdHJpbmcubGVuZ3RoIC0gMSkgKyAnLi4uJztcbiAgICBjb3VudGVyKys7XG4gIH1cbiAgcmV0dXJuIHN0cmluZztcbn07XG5cbmNvbW1vbi5mbGF0R2V0U2V0ID0gZnVuY3Rpb24gKG9iaiwgaXMsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgaXMgPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gY29tbW9uLmZsYXRHZXRTZXQob2JqLCBpcy5zcGxpdCgnLicpLCB2YWx1ZSk7XG4gIH1cbiAgZWxzZSBpZiAoaXMubGVuZ3RoID09IDEgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGRlbGV0ZSBvYmpbaXNbMF1dO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIG9ialtpc1swXV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAoaXMubGVuZ3RoID09PSAwKSB7XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIE9iamVjdC5rZXlzKG9iaikubGVuZ3RoID09PSAwKVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgZWxzZSB7XG4gICAgICAvL2NoZWNrIGlmIGNvbnZlcnRlZCBhcnJheVxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdvYmplY3QnICYmIE9iamVjdC5rZXlzKG9iailbMF0gPT09ICcwJylcbiAgICAgICAgcmV0dXJuIGNvbW1vbi5vYmpUb0FycmF5KG9iaik7XG5cbiAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICB9XG4gIGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSAndW5kZWZpbmVkJyB8fCBvYmogPT09IG51bGwpXG4gICAgICBvYmogPSB7fTtcbiAgICBpZiAodHlwZW9mIG9ialtpc1swXV0gPT09ICd1bmRlZmluZWQnIHx8IG9ialtpc1swXV0gPT09IG51bGwpXG4gICAgICBvYmpbaXNbMF1dID0ge307XG4gICAgcmV0dXJuIGNvbW1vbi5mbGF0R2V0U2V0KG9ialtpc1swXV0sIGlzLnNsaWNlKDEpLCB2YWx1ZSk7XG4gIH1cbn07XG5cbmNvbW1vbi5pc051bWVyaWMgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShvYmopICYmIChvYmogLSBwYXJzZUZsb2F0KG9iaikgKyAxKSA+PSAwO1xufTtcblxuY29tbW9uLmZvcm1hdERpbWVuc2lvbiA9IGZ1bmN0aW9uICh2YWx1ZSwgZGltZW5zaW9uKSB7XG4gIHZhciByZXN1bHQgPSB2YWx1ZTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbW1vbi5mb3JtYXRNZXRyaWMgPSBmdW5jdGlvbiAodmFsdWUsIG1ldHJpYykge1xuICBpZiAoIW1ldHJpYylcbiAgICBtZXRyaWMgPSB7fTtcbiAgdmFyIHJlc3VsdCA9IHBhcnNlRmxvYXQodmFsdWUpO1xuICBpZiAobWV0cmljLmRlY2ltYWxzKVxuICAgIHJlc3VsdCA9IHJlc3VsdC50b0ZpeGVkKG1ldHJpYy5kZWNpbWFscyk7XG4gIGlmICgobWV0cmljLmhhc093blByb3BlcnR5KCdjb21tYXMnKSAmJiBtZXRyaWMuY29tbWFzICkgfHwgdHJ1ZSkge1xuICAgIHJlc3VsdCA9IHJlc3VsdC5jb21tYXMoKTtcbiAgfVxuICBpZiAobWV0cmljLnByZWZpeClcbiAgICByZXN1bHQgPSBtZXRyaWMucHJlZml4ICsgcmVzdWx0O1xuICBpZiAobWV0cmljLnN1ZmZpeClcbiAgICByZXN1bHQgKz0gbWV0cmljLnN1ZmZpeDtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbW1vbi5wZXJjZW50YWdlQ2hhbmdlID0gZnVuY3Rpb24gKG51bTEsIG51bTIpIHtcbiAgdmFyIHJlc3VsdCA9ICgobnVtMiAtIG51bTEpIC8gbnVtMSAqIDEwMCkudG9GaXhlZCgyKTtcbiAgXG4gIGlmIChudW0xID09PSAwKVxuICAgIHJlc3VsdCA9ICfiiJ4nO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuY29tbW9uLmZvcm1hdERhdGUgPSBmdW5jdGlvbiAoZGF0ZSkge1xuICB2YXIgZm9ybWF0ID0gZnVuY3Rpb24gKGRhdGUsIGZvcm1hdFN0cmluZykge1xuICAgIHZhciBmb3JtYXREYXRlID0gZGF0ZTtcbiAgICB2YXIgbW9udGhzID0gW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdO1xuICAgIHZhciB5eXl5ID0gZm9ybWF0RGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIHZhciB5eSA9IHl5eXkudG9TdHJpbmcoKS5zdWJzdHJpbmcoMik7XG4gICAgdmFyIG0gPSBmb3JtYXREYXRlLmdldE1vbnRoKCkgKyAxO1xuICAgIHZhciBtbSA9IG0gPCAxMCA/IFwiMFwiICsgbSA6IG07XG4gICAgdmFyIG1tbSA9IG1vbnRoc1ttIC0gMV07XG4gICAgdmFyIGQgPSBmb3JtYXREYXRlLmdldERhdGUoKTtcbiAgICB2YXIgZGQgPSBkIDwgMTAgPyBcIjBcIiArIGQgOiBkO1xuICAgIHZhciBmZmYgPSBmb3JtYXREYXRlLmdldE1pbGxpc2Vjb25kcygpLnRvU3RyaW5nKCk7XG4gICAgZmZmID0gKGZmZiA8IDEwMCA/IGZmZiA8IDEwID8gJzAwJyArIGZmZiA6ICsnMCcgKyBmZmYgOiBmZmYpO1xuICAgIHZhciBoID0gZm9ybWF0RGF0ZS5nZXRIb3VycygpO1xuICAgIHZhciBoaCA9IGggPCAxMCA/IFwiMFwiICsgaCA6IGg7XG4gICAgdmFyIG4gPSBmb3JtYXREYXRlLmdldE1pbnV0ZXMoKTtcbiAgICB2YXIgbm4gPSBuIDwgMTAgPyBcIjBcIiArIG4gOiBuO1xuICAgIHZhciBzID0gZm9ybWF0RGF0ZS5nZXRTZWNvbmRzKCk7XG4gICAgdmFyIHNzID0gcyA8IDEwID8gXCIwXCIgKyBzIDogcztcblxuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC95eXl5L2ksIHl5eXkpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC95eS9pLCB5eSk7XG4gICAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL21tbS9pLCBtbW0pO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9tbS9pLCBtbSk7XG4gICAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbS9pLCBtKTtcbiAgICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvZGQvaSwgZGQpO1xuICAgIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2QvaSwgZCk7XG4gICAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2hoL2ksIGhoKTtcbiAgICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9oL2ksIGgpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9ubi9pLCBubik7XG4gICAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbi9pLCBuKTtcbiAgICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvc3MvaSwgc3MpO1xuICAgIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9mZmYvaSwgZmZmKTtcbiAgICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9zL2ksIHMpO1xuXG4gICAgcmV0dXJuIGZvcm1hdFN0cmluZztcbiAgfTtcblxuICByZXR1cm4gZm9ybWF0KGRhdGUsICdtbW0gZGQsIHl5eXknKTtcbn07IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKTtcbiAgXG52YXIgbG9nZ2VyID0gZXhwb3J0cztcbmxvZ2dlci5faWQgPSAnbG9nZ2VyJztcblxubG9nZ2VyLl9sb2cgPSBmdW5jdGlvbiAobGV2ZWwsIG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdkZWJ1Zyc6XG4gICAgY2FzZSAnaW5mbyc6XG4gICAgY2FzZSAnd2Fybic6XG4gICAgY2FzZSAnZXJyb3InOlxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2lsbHknOlxuICAgICAgbGV2ZWwgPSAnZGVidWcnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndHJhY2UnOlxuICAgICAgbGV2ZWwgPSAnZGVidWcnO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKCFqb29sYS5vcHRpb25zLmRlYnVnLmVuYWJsZWQpXG4gICAgcmV0dXJuO1xuXG4gIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ29iamVjdCcpXG4gICAgbWVzc2FnZSA9ICdbJyArIG5ldyBEYXRlKCkuZm9ybWF0KCdoaDpubjpzcy5mZmYnKSArICddICcgKyBKU09OLnN0cmluZ2lmeShtZXNzYWdlKTtcbiAgZWxzZVxuICAgIG1lc3NhZ2UgPSAnWycgKyBuZXcgRGF0ZSgpLmZvcm1hdCgnaGg6bm46c3MuZmZmJykgKyAnXSAnICsgbWVzc2FnZTtcblxuICBpZiAoam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIgJiYgY29uc29sZS5kZWJ1Zykge1xuICAgIGlmIChbJ3NpbGx5JywgJ2RlYnVnJ10uaW5kZXhPZihsZXZlbCkgPT0gLTEpXG4gICAgICBjb25zb2xlW2xldmVsXShtZXNzYWdlKTtcbiAgICBlbHNlIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmVuYWJsZWQgJiYgWydzaWxseScsICdkZWJ1ZyddLmluZGV4T2YobGV2ZWwpID4gLTEpXG4gICAgICBjb25zb2xlW2xldmVsXShtZXNzYWdlKTtcbiAgfVxuICBlbHNlXG4gICAgY29uc29sZS5sb2cobWVzc2FnZSk7XG5cbiAgaWYgKGNhbGxiYWNrKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbn07XG5cbmxvZ2dlci50cmFjZSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCd0cmFjZScsIG1lc3NhZ2UsIGNhbGxiYWNrKTtcbn07XG5cbmxvZ2dlci5zaWxseSA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCdzaWxseScsIG1lc3NhZ2UsIGNhbGxiYWNrKTtcbn07XG5cbmxvZ2dlci5pbmZvID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9sb2coJ2luZm8nLCBtZXNzYWdlLCBjYWxsYmFjayk7XG59O1xuXG5sb2dnZXIuZGVidWcgPSBmdW5jdGlvbiAobWVzc2FnZSwgY2FsbGJhY2spIHtcbiAgcmV0dXJuIHRoaXMuX2xvZygnZGVidWcnLCBtZXNzYWdlLCBjYWxsYmFjayk7XG59O1xuXG5sb2dnZXIud2FybiA9IGZ1bmN0aW9uIChtZXNzYWdlLCBjYWxsYmFjaykge1xuICByZXR1cm4gdGhpcy5fbG9nKCd3YXJuJywgbWVzc2FnZSwgY2FsbGJhY2spO1xufTtcblxubG9nZ2VyLmVycm9yID0gZnVuY3Rpb24gKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHJldHVybiB0aGlzLl9sb2coJ2Vycm9yJywgbWVzc2FnZSwgY2FsbGJhY2spO1xufTtcblxuIiwidmFyIG1lbW9yeSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5jb250ZW50ID0ge307XG5cbiAgdGhpcy5zZXQgPSBmdW5jdGlvbiAoa2V5LCBkYXRhLCBleHBpcmUpIHtcbiAgICBleHBpcmUgPSBleHBpcmUgfHwgMTAwMDtcbiAgICB0aGlzLnJlbW92ZShrZXkpO1xuICAgIHRoaXMuY29udGVudFtrZXldID0ge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIHRpbWVyOiBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoa2V5KTtcbiAgICAgIH0uYmluZCh0aGlzKSwgZXhwaXJlKVxuICAgIH07XG4gIH07XG5cbiAgdGhpcy5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKHR5cGVvZih0aGlzLmNvbnRlbnRba2V5XSkgIT09IFwidW5kZWZpbmVkXCIgJiYgdGhpcy5jb250ZW50W2tleV0gIT09IG51bGwgJiYgdHlwZW9mKHRoaXMuY29udGVudFtrZXldLmRhdGEpICE9PSBcInVuZGVmaW5lZFwiICYmIHRoaXMuY29udGVudFtrZXldLmRhdGEgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRba2V5XS5kYXRhO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLnJlbW92ZSA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgICBpZiAodHlwZW9mKHRoaXMuY29udGVudFtrZXldKSAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0aGlzLmNvbnRlbnRba2V5XSAhPT0gbnVsbCAmJiB0eXBlb2YodGhpcy5jb250ZW50W2tleV0udGltZXIpICE9PSBcInVuZGVmaW5lZFwiICYmIHRoaXMuY29udGVudFtrZXldLnRpbWVyICE9PSBudWxsKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5jb250ZW50W2tleV0udGltZXIpO1xuICAgICAgZGVsZXRlIHRoaXMuY29udGVudFtrZXldO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldFN0b3JlQ29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50O1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgbWVtb3J5KCk7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhL2xpYi9jb21tb24vbW9kaWZpZXJzXG4gKiAgQG92ZXJ2aWV3IEluY2x1ZGVzIGRpZmZlcmVudCBwcm90b3R5cGUgbW9kaWZpZXJzIHVzZWQgYnkgam9vbGFcbiAqICBAZGVzY3JpcHRpb25cbiAqICBqb29sYSByZXF1aXJlcyBzb21lIGFkZGl0aW9uYWwgc3VwcG9ydCBmb3IgcHJvdG90eXBlIG1vZGlmaWNhdGlvbiwgZm9yIGV4YW1wbGUsIGV4dGVuZGluZyBEYXRlIHRvIHN1cHBvcnQgZm9ybWF0LlxuICpcbiAqICBAY29weXJpZ2h0IChjKSBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+LiBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlNcbiAqKi9cblxuLyoqXG4gKiBAZnVuY3Rpb24gRGF0ZS5wcm90b3R5cGUuZm9ybWF0XG4gKiBNb2RpZmllcyBEYXRlIHRvIHN1cHBvcnQgZm9ybWF0dGluZ1xuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdFN0cmluZyBob2xkcyB0aGUgZm9ybWF0dGluZyBzdHJpbmcgdG8gYXBwbHkgb24gdGhlIGRhdGVcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGZvcm1hdHRlZCBzdHJpbmcgZnJvbSB0aGUgZGF0ZS5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBvbiBjb21wbGV0aW9uIGEgZm9ybWF0dGVkIHN0cmluZyBiYXNlZCBvbiBgZm9ybWF0U3RyaW5nYCBmcm9tIHRoZSBEYXRlIG9iamVjdDpcbiAqXG4gKiBgYGBqc1xuICogdmFyIGZvcm1hdHRlZCA9IG5ldyBEYXRlKCkuZm9ybWF0KCd5eXl5LW1tLWRkIGhoOm1tOnNzLmZmZicpO1xuICogYGBgXG4gKi9cbkRhdGUucHJvdG90eXBlLmZvcm1hdCA9IGZ1bmN0aW9uIChmb3JtYXRTdHJpbmcpIHtcbiAgdmFyIGZvcm1hdERhdGUgPSB0aGlzO1xuICB2YXIgbW9udGhzID0gW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdO1xuICB2YXIgeXl5eSA9IGZvcm1hdERhdGUuZ2V0RnVsbFllYXIoKTtcbiAgdmFyIHl5ID0geXl5eS50b1N0cmluZygpLnN1YnN0cmluZygyKTtcbiAgdmFyIG0gPSBmb3JtYXREYXRlLmdldE1vbnRoKCkgKyAxO1xuICB2YXIgbW0gPSBtIDwgMTAgPyBcIjBcIiArIG0gOiBtO1xuICB2YXIgbW1tID0gbW9udGhzW20gLSAxXTtcbiAgdmFyIGQgPSBmb3JtYXREYXRlLmdldERhdGUoKTtcbiAgdmFyIGRkID0gZCA8IDEwID8gXCIwXCIgKyBkIDogZDtcbiAgdmFyIGZmZiA9IGZvcm1hdERhdGUuZ2V0TWlsbGlzZWNvbmRzKCkudG9TdHJpbmcoKTtcbiAgZmZmID0gKGZmZiA8IDEwMCA/IGZmZiA8IDEwID8gJzAwJyArIGZmZiA6ICsnMCcgKyBmZmYgOiBmZmYpO1xuICB2YXIgaCA9IGZvcm1hdERhdGUuZ2V0SG91cnMoKTtcbiAgdmFyIGhoID0gaCA8IDEwID8gXCIwXCIgKyBoIDogaDtcbiAgdmFyIG4gPSBmb3JtYXREYXRlLmdldE1pbnV0ZXMoKTtcbiAgdmFyIG5uID0gbiA8IDEwID8gXCIwXCIgKyBuIDogbjtcbiAgdmFyIHMgPSBmb3JtYXREYXRlLmdldFNlY29uZHMoKTtcbiAgdmFyIHNzID0gcyA8IDEwID8gXCIwXCIgKyBzIDogcztcblxuICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgveXl5eS9pLCB5eXl5KTtcbiAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL3l5L2ksIHl5KTtcbiAgZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL21tbS9pLCBtbW0pO1xuICBmb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvbW0vaSwgbW0pO1xuICAvL2Zvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9tLywgbSk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9kZC9pLCBkZCk7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2QvaSwgZCk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9oaC9pLCBoaCk7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL2gvaSwgaCk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9ubi9pLCBubik7XG4gIC8vZm9ybWF0U3RyaW5nID0gZm9ybWF0U3RyaW5nLnJlcGxhY2UoL24vaSwgbik7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9zcy9pLCBzcyk7XG4gIGZvcm1hdFN0cmluZyA9IGZvcm1hdFN0cmluZy5yZXBsYWNlKC9mZmYvaSwgZmZmKTtcbiAgLy9mb3JtYXRTdHJpbmcgPSBmb3JtYXRTdHJpbmcucmVwbGFjZSgvcy9pLCBzKTtcblxuICByZXR1cm4gZm9ybWF0U3RyaW5nO1xufTtcblxuRGF0ZS5kYXRlRGlmZiA9IGZ1bmN0aW9uIChkYXRlcGFydCwgZnJvbWRhdGUsIHRvZGF0ZSkge1xuICBkYXRlcGFydCA9IGRhdGVwYXJ0LnRvTG93ZXJDYXNlKCk7XG4gIHZhciBkaWZmID0gdG9kYXRlIC0gZnJvbWRhdGU7XG4gIHZhciBkaXZpZGVCeSA9IHsgdzogNjA0ODAwMDAwLFxuICAgIGQ6IDg2NDAwMDAwLFxuICAgIGg6IDM2MDAwMDAsXG4gICAgbjogNjAwMDAsXG4gICAgczogMTAwMCB9O1xuXG4gIHJldHVybiBNYXRoLmZsb29yKGRpZmYgLyBkaXZpZGVCeVtkYXRlcGFydF0pO1xufTtcblxuLyoqXG4gKiBAZnVuY3Rpb24gT2JqZWN0LmRlZmluZVByb3BlcnR5LnRvSlNPTlxuICogTW9kaWZpZXMgdGhlIGJ1aWx0LWluIGB0b0pTT05gIHByb3BlcnR5IG9mIHRoZSBgRXJyb3JgIG9iamVjdC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gZXh0ZW5kcyB0aGUgYEVycm9yYCBwcm90b3R5cGUgYW5kIGNoYW5nZXMgdGhlIGB0b0pTT05gIGZ1bmN0aW9uXG4gKiB0byBzdXBwb3J0IEpTT04uc3RyaW5naWZ5IG9mIEVycm9yIG9iamVjdC5cbiAqXG4gKiBgYGBqc1xuICogbmV3IEVycm9yKCdUZXN0IGVycm9yJykudG9KU09OKCk7XG4gKiBgYGBcbiAqL1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEVycm9yLnByb3RvdHlwZSwgJ3RvSlNPTicsIHtcbiAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgYWx0ID0ge307XG5cbiAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGFsdFtrZXldID0gdGhpc1trZXldO1xuICAgIH0sIHRoaXMpO1xuXG4gICAgcmV0dXJuIGFsdDtcbiAgfSxcbiAgY29uZmlndXJhYmxlOiB0cnVlXG59KTtcbi8qXG4gQXJyYXkucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24gKCkge1xuIHJldHVybiB0aGlzLnNsaWNlKDApO1xuIH07XG5cblxuIHZhciBzdHJpbmdpZnkgPSByZXF1aXJlKCdqc29uLXN0cmluZ2lmeS1zYWZlJyk7XG5cblxuIEpTT04uX3BhcnNlID0gSlNPTi5wYXJzZS5jbG9uZSgpO1xuIEpTT04ucGFyc2UgPSBmdW5jdGlvbiAob2JqKSB7XG4gdmFyIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gdmFyIHJlc3VsdCA9IEpTT04uX3BhcnNlKG9iaik7XG4gdmFyIGVuZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuIGlmIChlbmQgLSBzdGFydCA+IDUwKSB7XG4gY29uc29sZS5sb2coJ0JMT0NLSU5HIFBBUlNFOiAnICsgKGVuZCAtIHN0YXJ0KS50b1N0cmluZygpICsgJ21zJyk7XG4gY29uc29sZS50cmFjZSgpO1xuIH1cbiByZXR1cm4gcmVzdWx0O1xuIH07XG5cblxuIEpTT04uX3N0cmluZ2lmeSA9IHN0cmluZ2lmeS5jbG9uZSgpO1xuIEpTT04uc3RyaW5naWZ5ID0gZnVuY3Rpb24gKG9iaikge1xuIHZhciBzdGFydCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuIHZhciByZXN1bHQgPSBKU09OLl9zdHJpbmdpZnkob2JqKTtcbiB2YXIgZW5kID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gaWYgKGVuZCAtIHN0YXJ0ID4gNTApIHtcbiBjb25zb2xlLmxvZygnQkxPQ0tJTkcgU1RSSU5HSUZZOiAnICsgKGVuZCAtIHN0YXJ0KS50b1N0cmluZygpICsgJ21zJyk7XG4gY29uc29sZS50cmFjZSgpO1xuIH1cbiByZXR1cm4gcmVzdWx0O1xuIH07XG4gKi9cblxuLy8gYXR0YWNoIHRoZSAuZXF1YWxzIG1ldGhvZCB0byBBcnJheSdzIHByb3RvdHlwZSB0byBjYWxsIGl0IG9uIGFueSBhcnJheVxuQXJyYXkucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChhcnJheSkge1xuICAvLyBpZiB0aGUgb3RoZXIgYXJyYXkgaXMgYSBmYWxzeSB2YWx1ZSwgcmV0dXJuXG4gIGlmICghYXJyYXkpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIGNvbXBhcmUgbGVuZ3RocyAtIGNhbiBzYXZlIGEgbG90IG9mIHRpbWUgXG4gIGlmICh0aGlzLmxlbmd0aCAhPSBhcnJheS5sZW5ndGgpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIG5lc3RlZCBhcnJheXNcbiAgICBpZiAodGhpc1tpXSBpbnN0YW5jZW9mIEFycmF5ICYmIGFycmF5W2ldIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIC8vIHJlY3Vyc2UgaW50byB0aGUgbmVzdGVkIGFycmF5c1xuICAgICAgaWYgKCF0aGlzW2ldLmVxdWFscyhhcnJheVtpXSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZWxzZSBpZiAodGhpc1tpXSAhPSBhcnJheVtpXSkge1xuICAgICAgLy8gV2FybmluZyAtIHR3byBkaWZmZXJlbnQgb2JqZWN0IGluc3RhbmNlcyB3aWxsIG5ldmVyIGJlIGVxdWFsOiB7eDoyMH0gIT0ge3g6MjB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuTnVtYmVyLnByb3RvdHlwZS5jb21tYXMgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciB4ID0gdGhpcztcbiAgdmFyIHBhcnRzID0geC50b1N0cmluZygpLnNwbGl0KFwiLlwiKTtcbiAgcGFydHNbMF0gPSBwYXJ0c1swXS5yZXBsYWNlKC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLCBcIixcIik7XG4gIHJldHVybiBwYXJ0cy5qb2luKFwiLlwiKTtcbn07XG5cblN0cmluZy5wcm90b3R5cGUuY29tbWFzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgeCA9IHRoaXM7XG4gIHZhciBwYXJ0cyA9IHgudG9TdHJpbmcoKS5zcGxpdChcIi5cIik7XG4gIHBhcnRzWzBdID0gcGFydHNbMF0ucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgXCIsXCIpO1xuICByZXR1cm4gcGFydHMuam9pbihcIi5cIik7XG59OyIsInZhciBnbG9iYWw9dHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9Oy8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbi8vVEhFIE9CSkVDVFxudmFyIGpvb2xhID0gZXhwb3J0cztcblxuLy90cnkgaW5qZWN0aW5nIGdsb2JhbFxuaWYgKCFnbG9iYWwuam9vbGEpIHtcbiAgZ2xvYmFsLmpvb2xhID0gam9vbGE7XG59XG5cbi8vYmFzZSBvcHRpb25zXG5qb29sYS5vcHRpb25zID0ge1xuICB0b2tlbjogbnVsbCxcbiAgaG9zdDogbnVsbCxcbiAgaW5jbHVkZWNzczogdHJ1ZSxcbiAgdGhlbWU6ICdkZWZhdWx0JyxcbiAgY3NzSG9zdDogJycsXG4gIEFQSVRva2VuOiBudWxsLFxuICBsb2dvdXR1cmw6IG51bGwsXG4gIGlzQnJvd3NlcjogZnVuY3Rpb24gaXNCcm93c2VyKCkge1xuICAgIHJldHVybiB0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCc7XG4gIH0oKSxcbiAgbWF4UmVxdWVzdHM6IDEwMDAsXG4gIGRlYnVnOiB7XG4gICAgZW5hYmxlZDogZmFsc2UsXG4gICAgZXZlbnRzOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZSxcbiAgICAgIHRyYWNlOiBmYWxzZVxuICAgIH0sXG4gICAgZnVuY3Rpb25zOiB7XG4gICAgICBlbmFibGVkOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgdGltZXpvbmVPZmZzZXQ6IG51bGxcblxufTtcbmpvb2xhLmNvbm5lY3RlZCA9IGZhbHNlO1xuLy9saWJyYXJpZXNcbmpvb2xhLmdsb2JhbHMgPSByZXF1aXJlKCcuL2NvbW1vbi9nbG9iYWxzJyk7XG5qb29sYS5sb2dnZXIgPSByZXF1aXJlKCcuL2NvbW1vbi9sb2dnZXInKTtcbmpvb2xhLmRpc3BhdGNoID0gcmVxdWlyZSgnLi9jb21tb24vZGlzcGF0Y2gnKTtcbmpvb2xhLmNvbW1vbiA9IHJlcXVpcmUoJy4vY29tbW9uL2luZGV4Jyk7XG5qb29sYS5tZW1vcnkgPSByZXF1aXJlKCcuL2NvbW1vbi9tZW1vcnknKTtcbmpvb2xhLmV2ZW50cyA9IHJlcXVpcmUoJy4vY29tbW9uL2V2ZW50cycpO1xuam9vbGEuZXZlbnRzLnNldE1heExpc3RlbmVycygxMDApO1xuam9vbGEub24gPSBmdW5jdGlvbiAoZXZlbnQsIGNiKSB7XG4gIGpvb2xhLmV2ZW50cy5vbihldmVudCwgY2IpO1xufTtcbmpvb2xhLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQsIG1lc3NhZ2UpIHtcbiAgam9vbGEuZXZlbnRzLmVtaXQoZXZlbnQsIG1lc3NhZ2UpO1xufTtcbmpvb2xhLmFwaSA9IHJlcXVpcmUoJy4vY29tbW9uL2FwaScpO1xuam9vbGEuc3RhdGUgPSB7fTtcbmpvb2xhLnZpeiA9IHJlcXVpcmUoJy4vdml6L2luZGV4Jyk7XG5cbmpvb2xhLlZFUlNJT04gPSByZXF1aXJlKCcuLy4uLy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG5qb29sYS5fdG9rZW4gPSBudWxsO1xuam9vbGEuX2FwaXRva2VuID0gbnVsbDtcblxucmVxdWlyZSgnLi9jb21tb24vbW9kaWZpZXJzJyk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShqb29sYSwgJ1RPS0VOJywge1xuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gam9vbGEuX3Rva2VuO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIGpvb2xhLl90b2tlbiA9IHZhbHVlO1xuICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdjb3JlLmluaXQuZmluaXNoJyk7XG4gICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JlYWR5Jyk7XG4gIH1cbn0pO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoam9vbGEsICdBUElUT0tFTicsIHtcbiAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGpvb2xhLl9hcGl0b2tlbjtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICBqb29sYS5fYXBpdG9rZW4gPSB2YWx1ZTtcbiAgICBqb29sYS5VU0VSID0gbnVsbDtcbiAgICBqb29sYS5fdG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuQVBJVE9LRU4sIGZ1bmN0aW9uIChlcnIsIHVzZXIpIHtcbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgLy9qb29sYS5UT0tFTiA9IHVzZXIudG9rZW4uXztcbiAgICB9KTtcbiAgfVxufSk7XG5cbnJlcXVpcmUoJy4vY29tbW9uL2dsb2JhbHMnKTtcblxuLy9wYXJzZSB0aGUgcXVlcnlzdHJpbmcgaWYgYnJvd3NlciBmb3IgZGVmYXVsdCBvcHRpb25zXG5mdW5jdGlvbiBpc0Jyb3dzZXIoKSB7XG4gIHJldHVybiB0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCc7XG59XG5cbmlmIChpc0Jyb3dzZXIoKSkge1xuICB2YXIgZWxlbXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0Jyk7XG5cbiAgT2JqZWN0LmtleXMoZWxlbXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBzY3IgPSBlbGVtc1trZXldO1xuICAgIGlmIChzY3Iuc3JjKSB7XG4gICAgICBpZiAoc2NyLnNyYy5pbmRleE9mKCdqb29sYS5qcycpID4gLTEgfHwgc2NyLnNyYy5pbmRleE9mKCdqb29sYS5taW4uanMnKSA+IC0xKSB7XG4gICAgICAgIHZhciBwYXJ0cyA9IHJlcXVpcmUoJ3VybCcpLnBhcnNlKHNjci5zcmMpO1xuICAgICAgICB2YXIgcHJvdG9jb2wgPSBwYXJ0cy5wcm90b2NvbDtcbiAgICAgICAgdmFyIGhvc3QgPSBwYXJ0cy5ob3N0O1xuICAgICAgICB2YXIgcG9ydCA9IHBhcnRzLnBvcnQ7XG4gICAgICAgIGlmICghcG9ydCkge1xuICAgICAgICAgIHBvcnQgPSA0NDM7XG4gICAgICAgICAgaWYgKHByb3RvY29sICE9PSAnaHR0cHM6JylcbiAgICAgICAgICAgIHBvcnQgPSA4MDtcbiAgICAgICAgfVxuICAgICAgICBqb29sYS5vcHRpb25zLmhvc3QgPSBwYXJ0cy5wcm90b2NvbCArICcvLycgKyBwYXJ0cy5ob3N0bmFtZSArICc6JyArIHBvcnQ7XG4gICAgICAgIGlmIChwYXJ0cy5xdWVyeSkge1xuICAgICAgICAgIHZhciBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJykucGFyc2UocGFydHMucXVlcnkpO1xuICAgICAgICAgIGlmIChxcyAmJiBxcy5BUElUb2tlbikge1xuICAgICAgICAgICAgam9vbGEub3B0aW9ucy5BUElUb2tlbiA9IHFzLkFQSVRva2VuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocXMgJiYgcXMudG9rZW4pIHtcbiAgICAgICAgICAgIGpvb2xhLm9wdGlvbnMudG9rZW4gPSBxcy50b2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHFzICYmIHFzLmhvc3QpIHtcbiAgICAgICAgICAgIHBhcnRzID0gcmVxdWlyZSgndXJsJykucGFyc2UocXMuaG9zdCk7XG4gICAgICAgICAgICBwcm90b2NvbCA9IHBhcnRzLnByb3RvY29sO1xuICAgICAgICAgICAgaG9zdCA9IHBhcnRzLmhvc3Q7XG4gICAgICAgICAgICBwb3J0ID0gNDQzO1xuICAgICAgICAgICAgaWYgKHByb3RvY29sICE9PSAnaHR0cHM6JylcbiAgICAgICAgICAgICAgcG9ydCA9IDgwO1xuICAgICAgICAgICAgam9vbGEub3B0aW9ucy5ob3N0ID0gcGFydHMucHJvdG9jb2wgKyAnLy8nICsgcGFydHMuaG9zdG5hbWUgKyAnOicgKyBwb3J0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbmpvb2xhLmRpc3BhdGNoLmJ1aWxkc3R1YigpO1xuXG4vL2luaXQgcHJvY2VkdXJlXG5qb29sYS5pbml0ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGNhbGxiYWNrID0gY2FsbGJhY2sgfHwgZW1wdHlmdW5jO1xuICBqb29sYS5vcHRpb25zID0gam9vbGEuY29tbW9uLl9taXhpbihqb29sYS5vcHRpb25zLCBvcHRpb25zKTtcbiAgam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIgPSBpc0Jyb3dzZXIoKTtcblxuICBpZiAob3B0aW9ucy50b2tlbikge1xuICAgIGpvb2xhLl90b2tlbiA9IG9wdGlvbnMudG9rZW47XG4gIH1cbiAgZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBsb2NhdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHZhciBxcyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG4gICAgICB2YXIgcGFydHMgPSBxcy5wYXJzZShsb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEsIGxvY2F0aW9uLnNlYXJjaC5sZW5ndGgpKTtcbiAgICAgIGlmIChwYXJ0cy50b2tlbilcbiAgICAgICAgam9vbGEuX3Rva2VuID0gcGFydHMudG9rZW47XG4gICAgfVxuICB9XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdjb3JlLmluaXQuc3RhcnQnKTtcbiAgam9vbGEubG9nZ2VyLmluZm8oJ1N0YXJ0aW5nIGpvb2xhIGNsaWVudCBTREssIHZlcnNpb24gJyArIGpvb2xhLlZFUlNJT04pO1xuXG4gIGlmICgham9vbGEub3B0aW9ucy5ob3N0ICYmIGpvb2xhLm9wdGlvbnMuaXNCcm93c2VyKSB7XG4gICAgam9vbGEub3B0aW9ucy5ob3N0ID0gbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgbG9jYXRpb24uaG9zdDtcbiAgfVxuICBpZiAoIWpvb2xhLm9wdGlvbnMuaG9zdClcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2pvb2xhIGhvc3Qgbm90IHNwZWNpZmllZCcpO1xuXG4gIHZhciBpbyA9IHJlcXVpcmUoJ3NvY2tldC5pby1jbGllbnQnKTtcbiAgam9vbGEuaW8gPSBpbztcbiAgam9vbGEuaW8uc29ja2V0ID0gam9vbGEuaW8uY29ubmVjdChqb29sYS5vcHRpb25zLmhvc3QpO1xuICBqb29sYS5pby5zb2NrZXQub24oJ2V2ZW50JywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgfSk7XG4gIGpvb2xhLmlvLnNvY2tldC5vbignZGlzY29ubmVjdCcsIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBqb29sYS5lbWl0KCdkaXNjb25uZWN0ZWQnLCByZWFzb24pO1xuICB9KTtcbiAgam9vbGEuaW8uc29ja2V0Lm9uKCdjb25uZWN0X2Vycm9yJywgZnVuY3Rpb24gKGVycikge1xuICAgIGpvb2xhLmNvbm5lY3RlZCA9IGZhbHNlO1xuICAgIGlmICgham9vbGEub25saW5lKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY29ubmVjdCB0byBKb29sYSBlbmdpbmU6ICcgKyBlcnIpO1xuICAgIGpvb2xhLmVtaXQoJ2Rpc2Nvbm5lY3RlZCcsIGVycik7XG4gIH0pO1xuICBqb29sYS5pby5zb2NrZXQub24oJ2Nvbm5lY3RfdGltZW91dCcsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICBpZiAoIWpvb2xhLm9ubGluZSlcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGNvbm5lY3QgdG8gSm9vbGEgZW5naW5lOiBUaW1lb3V0Jyk7XG4gICAgam9vbGEuZW1pdCgnZGlzY29ubmVjdGVkJywgJ3RpbWVvdXQnKTtcbiAgfSk7XG4gIGpvb2xhLmlvLnNvY2tldC5vbignY29ubmVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS5jb25uZWN0ZWQgPSB0cnVlO1xuICAgIGlmICgham9vbGEub25saW5lKSB7XG4gICAgICBqb29sYS5vbmxpbmUgPSB0cnVlO1xuICAgICAgam9vbGEuYnJpbmdPbmxpbmUoY2FsbGJhY2spO1xuICAgIH1cbiAgICBqb29sYS5lbWl0KCdjb25uZWN0ZWQnKTtcbiAgfSk7XG5cbiAgLy9nbG9iYWwgZnVuY3Rpb24gaG9vayAoZm9yIGRlYnVnKVxuICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1ZyAmJiBqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucyAmJiBqb29sYS5vcHRpb25zLmRlYnVnLmZ1bmN0aW9ucy5lbmFibGVkKVxuICAgIFtqb29sYV0uZm9yRWFjaChmdW5jdGlvbiAob2JqKSB7XG4gICAgICBqb29sYS5jb21tb24uaG9va0V2ZW50cyhvYmosIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgLy9nbG9iYWwgZXZlbnQgY2F0Y2hlciAoZm9yIGRlYnVnKVxuICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1Zy5lbmFibGVkICYmIGpvb2xhLm9wdGlvbnMuZGVidWcuZXZlbnRzKVxuICAgIGpvb2xhLmV2ZW50cy5vbkFueShmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoam9vbGEub3B0aW9ucy5kZWJ1Zy5ldmVudHMuZW5hYmxlZClcbiAgICAgICAgam9vbGEubG9nZ2VyLmRlYnVnKCdFdmVudCByYWlzZWQ6ICcgKyB0aGlzLmV2ZW50KTtcbiAgICAgIGlmIChqb29sYS5vcHRpb25zLmRlYnVnLmV2ZW50cy5lbmFibGVkICYmIGpvb2xhLm9wdGlvbnMuZGVidWcuZXZlbnRzLnRyYWNlKVxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgfSk7XG59O1xuXG5pZiAoam9vbGEub3B0aW9ucy5BUElUb2tlbiB8fCBqb29sYS5vcHRpb25zLnRva2VuKSB7XG4gIGpvb2xhLmluaXQoe30pO1xufVxuXG5qb29sYS5icm93c2VyM3JkID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIHZhciBleHBlY3RlZCA9IDA7XG5cbiAgZnVuY3Rpb24gZG9uZSh3aGljaCkge1xuICAgIGV4cGVjdGVkLS07XG4gICAgaWYgKGV4cGVjdGVkIDw9IDApIHtcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICB9XG4gIH1cblxuICB2YXIgc2NyaXB0O1xuICBpZiAoam9vbGEub3B0aW9ucy5pc0Jyb3dzZXIpIHtcblxuICAgIC8vY3NzXG4gICAgaWYgKGpvb2xhLm9wdGlvbnMuaW5jbHVkZWNzcykge1xuICAgICAgdmFyIGNzcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcbiAgICAgIC8vZXhwZWN0ZWQrKztcbiAgICAgIGNzcy5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8valF1ZXJ5Lm5vQ29uZmxpY3QodHJ1ZSk7XG4gICAgICAgIC8vZG9uZSgnY3NzJyk7XG4gICAgICB9O1xuICAgICAgY3NzLnJlbCA9ICdzdHlsZXNoZWV0JztcbiAgICAgIGNzcy5ocmVmID0gam9vbGEub3B0aW9ucy5ob3N0ICsgJy9qb29sYS5taW4uY3NzJztcbiAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoY3NzKTtcbiAgICAgIC8vZG9uZSgnY3NzJyk7XG4gICAgfVxuICAgIC8vaWYgKGV4cGVjdGVkID09PSAwKVxuICAgIHJldHVybiBkb25lKCdub25lJyk7XG4gIH1cbiAgZWxzZSB7XG4gICAgcmV0dXJuIGRvbmUoJ25vdCBicm93c2VyJyk7XG4gIH1cbn07XG5cbmpvb2xhLmJyaW5nT25saW5lID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGpvb2xhLmJyb3dzZXIzcmQoZnVuY3Rpb24gKCkge1xuICAgIGlmIChqb29sYS5vcHRpb25zLnRva2VuKSB7XG4gICAgICBqb29sYS5kaXNwYXRjaC51c2Vycy5nZXRCeVRva2VuKGpvb2xhLl90b2tlbiwgZnVuY3Rpb24gKGVyciwgdXNlcikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgICBqb29sYS5UT0tFTiA9IGpvb2xhLl90b2tlbjtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2NvcmUuaW5pdC5maW5pc2gnKTtcbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIGlmIChjYWxsYmFjaylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgam9vbGEpO1xuXG4gICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoam9vbGEub3B0aW9ucy5BUElUb2tlbikge1xuICAgICAgam9vbGEuX2FwaXRva2VuID0gam9vbGEub3B0aW9ucy5BUElUb2tlbjtcbiAgICAgIGpvb2xhLlVTRVIgPSBudWxsO1xuICAgICAgam9vbGEuX3Rva2VuID0gbnVsbDtcblxuICAgICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuX2FwaXRva2VuLCBmdW5jdGlvbiAoZXJyLCB1c2VyKSB7XG4gICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnY29yZS5pbml0LmZpbmlzaCcpO1xuICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgncmVhZHknKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgam9vbGEpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2NvcmUuaW5pdC5maW5pc2gnKTtcbiAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdyZWFkeScpO1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGpvb2xhKTtcbiAgICB9XG4gIH0pO1xufTtcblxuam9vbGEuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUsIGNhbGxiYWNrKSB7XG4gIGpvb2xhLm9wdGlvbnNba2V5XSA9IHZhbHVlO1xuICBpZiAoa2V5ID09PSAnQVBJVG9rZW4nKSB7XG4gICAgam9vbGEuX2FwaXRva2VuID0gam9vbGEub3B0aW9ucy5BUElUb2tlbjtcbiAgICBqb29sYS5VU0VSID0gbnVsbDtcbiAgICBqb29sYS5fdG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMudmVyaWZ5QVBJVG9rZW4oam9vbGEuX2FwaXRva2VuLCBmdW5jdGlvbiAoZXJyLCB1c2VyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIGlmICghdXNlcilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignRmFpbGVkIHRvIHZlcmlmeSBBUEkgVG9rZW4nKSk7XG5cbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgZWxzZSBpZiAoa2V5ID09PSAndG9rZW4nKSB7XG4gICAgam9vbGEuX3Rva2VuID0gam9vbGEub3B0aW9ucy5fdG9rZW47XG4gICAgam9vbGEuVVNFUiA9IG51bGw7XG4gICAgam9vbGEuQVBJVG9rZW4gPSBudWxsO1xuXG4gICAgam9vbGEuZGlzcGF0Y2gudXNlcnMuZ2V0QnlUb2tlbihqb29sYS5fdG9rZW4sIGZ1bmN0aW9uIChlcnIsIHVzZXIpIHtcbiAgICAgIGpvb2xhLlVTRVIgPSB1c2VyO1xuICAgICAgam9vbGEuVE9LRU4gPSB1c2VyLnRva2VuLl87XG4gICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgfSk7XG4gIH1cbn07XG5cbmpvb2xhLmdldCA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIGpvb2xhLm9wdGlvbnNba2V5XTtcbn07XG5cbmpvb2xhLmNvbG9ycyA9IFsnIzA1OERDNycsICcjNTBCNDMyJywgJyNFRDdFMTcnLCAnI0FGNDlDNScsICcjRURFRjAwJywgJyM4MDgwRkYnLCAnI0EwQTQyNCcsICcjRTMwNzFDJywgJyM2QUY5QzQnLCAnI0IyREVGRicsICcjNjRFNTcyJywgJyNDQ0NDQ0MnXTtcbmpvb2xhLm9mZmNvbG9ycyA9IFsnI0FBREZGMycsICcjQzlFN0JFJywgJyNGMkQ1QkQnLCAnI0UxQzlFOCcsICcjRjZGM0IxJywgJyNEQURCRkInLCAnI0U3RTZCNCcsICcjRjRCM0JDJywgJyNBQURGRjMnLCAnI0YyRDVCRCcsICcjQzlFN0JFJywgJyNFRUVFRUUnXTtcblxudmFyIHN0YXJ0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5qb29sYS5vbigncmVhZHknLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBlbmQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbn0pO1xuIiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIEJhclRhYmxlID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vbWl4aW5cbiAgdGhpcy50eXBlID0gJ2JhcnRhYmxlJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICB0aGlzLmRhdGEgPSBbXTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICBjb2xvcnM6IFtdLFxuICAgIG9mZmNvbG9yczogW10sXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwiYmFydGFibGUtY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgJzx0YWJsZSBjbGFzcz1cImppbyBiYXJ0YWJsZSB0YWJsZVwiPicgK1xuICAgICAgJzx0aGVhZD4nICtcbiAgICAgICc8L3RoZWFkPicgK1xuICAgICAgJzx0Ym9keT4nICtcbiAgICAgICc8L3Rib2R5PicgK1xuICAgICAgJzwvdGFibGU+JyxcbiAgICBxdWVyeTogbnVsbCxcbiAgICBzdHJpbmdzOiB7XG4gICAgICBsb2FkaW5nOiAnTm8gZGF0YSBhdmFpbGFibGUuJyxcbiAgICAgIG5vZGF0YTogJ05vIGRhdGEgYXZhaWxhYmxlLicsXG4gICAgICBub3Rfc2hvd246ICdOb3Qgc2hvd24nXG4gICAgfSxcbiAgICBsaW1pdDogMTAsXG4gICAgaGVhZGVyczogZmFsc2UsXG4gICAgaW5jbHVkZV9ub3Rfc2hvd246IHRydWUsXG4gICAgYWxsb3dTZWxlY3Q6IHRydWVcbiAgfTtcbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IFtvcHRpb25zXS4nO1xuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkgPSBbc2VsZi5vcHRpb25zLnF1ZXJ5XTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5sZW5ndGggPT09IDAgfHwgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMubGVuZ3RoID4gMSlcbiAgICAgICAgcmV0dXJuICdQbGVhc2Ugc3BlY2lmeSBhIHNpbmdsZSBkaW1lbnNpb24uJztcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5sZW5ndGggPT09IDAgfHwgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MubGVuZ3RoID4gMSlcbiAgICAgICAgcmV0dXJuICdQbGVhc2Ugc3BlY2lmeSBhIHNpbmdsZSBtZXRyaWMuJztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgdGhpcy5lbnRlciA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgX3F1ZXJ5ID0gX3F1ZXJ5WzBdO1xuICAgIHZhciBkaW1lbnNpb25rZXkgPSBfcXVlcnkuZGltZW5zaW9uc1swXS5rZXkgfHwgX3F1ZXJ5LmRpbWVuc2lvbnNbMF07XG4gICAgdmFyIG1ldHJpY2tleSA9IF9xdWVyeS5tZXRyaWNzWzBdLmtleSB8fCBfcXVlcnkubWV0cmljc1swXTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcblxuICAgIGZ1bmN0aW9uIGFkZFJvdyhwb2ludCwgdG90YWwsIHNob3duLCBub3RzaG93bikge1xuICAgICAgdmFyICR0YWJsZSA9ICQkKCQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3RhYmxlJylbMF0pO1xuICAgICAgdmFyICR0Ym9keSA9ICQkKCR0YWJsZS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICAgIHZhciBwZXJjZW50YWdlLCAkdHI7XG4gICAgICBpZiAoJHRib2R5LmZpbmQoJ3RyLm5vZGF0YScpLmxlbmd0aCA+IDApXG4gICAgICAgICR0Ym9keS5maW5kKCd0ci5ub2RhdGEnKS5yZW1vdmUoKTtcbiAgICAgIGlmICgkdGJvZHkuZmluZCgndHIubG9hZGluZycpLmxlbmd0aCA+IDApXG4gICAgICAgICR0Ym9keS5maW5kKCd0ci5sb2FkaW5nJykucmVtb3ZlKCk7XG4gICAgICBpZiAocG9pbnQubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHBvaW50ID0gcG9pbnRbMF07XG4gICAgICAgIGlmICgkdGJvZHkuZmluZCgndHInKS5sZW5ndGggPj0gc2VsZi5vcHRpb25zLmxpbWl0KSB7XG4gICAgICAgICAgaWYgKCR0Ym9keS5maW5kKCd0ZC5ub3RzaG93bicpLmxlbmd0aCA+IDAgfHwgIXNlbGYub3B0aW9ucy5pbmNsdWRlX25vdF9zaG93bilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgIHBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KG5vdHNob3duWzBdKSAvIHRvdGFsWzBdICogMTAwO1xuICAgICAgICAgIGlmIChwZXJjZW50YWdlID4gMTAwKVxuICAgICAgICAgICAgcGVyY2VudGFnZSA9IDEwMDtcbiAgICAgICAgICAkdHIgPSAkJCgnPHRyIGRhdGEtaWQ9XCJvdGhlclwiIGRhdGEtdmFsdWU9XCInICsgbm90c2hvd25bMF0gKyAnXCIgZGF0YS1uYW1lPVwiJyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biArICdcIiBkYXRhLXZhbHVlLXNvcnQ9XCInICsgcGVyY2VudGFnZSArICdcIj48L3RyPicpO1xuICAgICAgICAgIE9iamVjdC5rZXlzKHBvaW50Lm1ldHJpY3MpLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiamlvIGJhcnRhYmxlIHZhbHVlIG1ldHJpY1wiPicgK1xuICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cImJhcndyYXBwZXJcIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJ0YWJsZWJhclwiIHN0eWxlPVwid2lkdGg6JyArIHBlcmNlbnRhZ2UgKyAnJVwiIHRpdGxlPVwiJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMobm90c2hvd25bMF0sIGRhdGFbMF0ubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUpXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8L2Rpdj4nICtcbiAgICAgICAgICAgICAgJzwvdGQ+Jyk7XG4gICAgICAgICAgICAkdGQuZmluZCgnLnRhYmxlYmFyJykuY3NzKHsnYmFja2dyb3VuZC1jb2xvcic6IHNlbGYub3B0aW9ucy5jb2xvcnNbMTFdfSk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBPYmplY3Qua2V5cyhwb2ludC5kaW1lbnNpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICB2YXIgZGltZW5zaW9ua2V5ID0gZC5rZXkgfHwgZDtcbiAgICAgICAgICAgIHZhciB0aXRsZSA9IHBvaW50Lm1ldGFbZGltZW5zaW9ua2V5XTtcbiAgICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb24gbm90c2hvd25cIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJjYXB0aW9uXCIgdGl0bGU9XCInICsgdGl0bGUgKyAnXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgICAgJHRkLmZpbmQoJy5jYXB0aW9uJykudGV4dChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biB8fCAnTm90IHNob3duJykpO1xuICAgICAgICAgICAgJHRkLmZpbmQoJy5zdWJjYXB0aW9uJykudGV4dChqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKG5vdHNob3duWzBdLCBwb2ludC5tZXRhW21ldHJpY2tleV0pICsgJyAnICsgbWV0cmljbmFtZSk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy93ZSBoYXZlIGEgc2ltcGxlIHJvd1xuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICBwZXJjZW50YWdlID0gcGFyc2VGbG9hdChwb2ludC5tZXRyaWNzW21ldHJpY2tleV0pIC8gdG90YWxbaW5kZXhdICogMTAwO1xuICAgICAgICAkdHIgPSAkJCgnPHRyIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcG9pbnQubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiIGRhdGEtbmFtZT1cIicgKyBwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gKyAnXCIgZGF0YS12YWx1ZS1zb3J0PVwiJyArIHBlcmNlbnRhZ2UgKyAnXCIgZGF0YS1zZWxlY3RhYmxlPVwiJyArIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QgIT09IGZhbHNlICkgKyAnXCI+PC90cj4nKTtcblxuICAgICAgICAvL3Nob3VsZCB3ZSBtYXJrIHRoaXMgcm93IGFzIGFjdGl2ZT9cbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMgJiYgc2VsZi5vcHRpb25zLmNhbnZhcy5vcHRpb25zLmZpbHRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMub3B0aW9ucy5maWx0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgICAgICAgaWYgKGZpbHRlci5rZXkgPT09IHBvaW50LmtleSlcbiAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZVwiPicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyXCI+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyXCIgc3R5bGU9XCJ3aWR0aDonICsgcGVyY2VudGFnZSArICclO2JhY2tncm91bmQtY29sb3I6JyArIHNlbGYub3B0aW9ucy5jb2xvcnNbMF0gKyAnXCIgdGl0bGU9XCInICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhwb2ludC5tZXRyaWNzW21ldHJpY2tleV0sIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lICsgJyAoJyArIHBlcmNlbnRhZ2UudG9GaXhlZCgyKSArICclKVwiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgJzwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QpIHtcbiAgICAgICAgICAgICR0ZC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGlmICgkdHIuaGFzQ2xhc3MoJ2FjdGl2ZScpKVxuICAgICAgICAgICAgICAgICR0ci5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAkdHIuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3NlbGVjdCcsIFtwb2ludF0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtwb2ludF0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBfcXVlcnkuZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgdmFyIHRpdGxlID0gcG9pbnQubWV0YVtkaW1lbnNpb25rZXldO1xuICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGUudGl0bGUgfHwgdGl0bGUubmFtZSB8fCB0aXRsZS5rZXk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJqaW8gYmFydGFibGUgdmFsdWUgZGltZW5zaW9uXCI+JyArXG4gICAgICAgICAgICAnPGRpdiBjbGFzcz1cImNhcHRpb25cIiB0aXRsZT1cIicgKyB0aXRsZSArICdcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzwvdGQ+Jyk7XG5cbiAgICAgICAgICAkdGQuZmluZCgnLmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5lbnN1cmVMZW5ndGgocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArIChwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpLCAyMykpO1xuICAgICAgICAgICR0ZC5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhwb2ludC5tZXRyaWNzW21ldHJpY2tleV0sIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lKTtcbiAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5hbGxvd1NlbGVjdCkge1xuICAgICAgICAgICAgJHRkLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaWYgKCR0ci5oYXNDbGFzcygnYWN0aXZlJykpXG4gICAgICAgICAgICAgICAgJHRyLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICR0ci5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdlbWl0Jyk7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnc2VsZWN0JywgW3BvaW50XSk7XG4gICAgICAgICAgICAgIGlmIChzZWxmLm9wdGlvbnMuc2VsZWN0KVxuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5zZWxlY3QuYXBwbHkodGhpcywgW3BvaW50XSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy93ZSBoYXZlIGEgY29tcGFyaXNvblxuICAgICAgICB2YXIgYmFzZSA9IHBvaW50WzBdO1xuICAgICAgICB2YXIgY29tcGFyZSA9IHBvaW50WzFdO1xuXG4gICAgICAgIHZhciBiYXNlX3BlcmNlbnRhZ2UsIGNvbXBhcmVfcGVyY2VudGFnZTtcblxuICAgICAgICBpZiAoJHRib2R5LmZpbmQoJ3RyJykubGVuZ3RoID49IHNlbGYub3B0aW9ucy5saW1pdCkge1xuICAgICAgICAgIGlmICgkdGJvZHkuZmluZCgndGQubm90c2hvd24nKS5sZW5ndGggPiAwIHx8ICFzZWxmLm9wdGlvbnMuaW5jbHVkZV9ub3Rfc2hvd24pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgJHRyID0gJCQoJzx0cj48L3RyPicpO1xuICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQobm90c2hvd25bMF0pIC8gdG90YWxbMF0gKiAxMDA7XG4gICAgICAgICAgaWYgKGJhc2VfcGVyY2VudGFnZSA+IDEwMClcbiAgICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IDEwMDtcbiAgICAgICAgICBjb21wYXJlX3BlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KG5vdHNob3duWzFdKSAvIHRvdGFsWzFdICogMTAwO1xuICAgICAgICAgIGlmIChjb21wYXJlX3BlcmNlbnRhZ2UgPiAxMDApXG4gICAgICAgICAgICBjb21wYXJlX3BlcmNlbnRhZ2UgPSAxMDA7XG4gICAgICAgICAgT2JqZWN0LmtleXMoYmFzZS5tZXRyaWNzKS5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZVwiPicgK1xuICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyIGNvbXBhcmVcIj4nICtcbiAgICAgICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwidGFibGViYXJcIiBzdHlsZT1cIndpZHRoOicgKyAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhiYXNlX3BlcmNlbnRhZ2UpID8gKGJhc2VfcGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IGJhc2VfcGVyY2VudGFnZSArICclJykgOiAwKSArICc7YmFja2dyb3VuZC1jb2xvcjogJyArIHNlbGYub3B0aW9ucy5jb2xvcnNbMF0gKyAnO1wiIHRpdGxlPVwiJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgYmFzZV9wZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSlcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAgICc8ZGl2IHN0eWxlPVwiY2xlYXI6Ym90aFwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJ0YWJsZWJhciBjb21wYXJlX3JhdGlvXCIgc3R5bGU9XCJ3aWR0aDonICsgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMoY29tcGFyZV9wZXJjZW50YWdlKSA/IChjb21wYXJlX3BlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBjb21wYXJlX3BlcmNlbnRhZ2UgKyAnJScpIDogMCkgKyAnO2JhY2tncm91bmQtY29sb3I6ICcgKyBzZWxmLm9wdGlvbnMub2ZmY29sb3JzWzBdICsgJ1wiICB0aXRsZT1cIicgKyAoY29tcGFyZS5tZXRyaWNzICYmIGNvbXBhcmUubWV0cmljc1ttZXRyaWNrZXldID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSwgY29tcGFyZS5tZXRhW21ldHJpY2tleV0pIDogJ04vQScpICsgJyAnICsgbWV0cmljbmFtZSArICcgKCcgKyAoY29tcGFyZV9wZXJjZW50YWdlID8gY29tcGFyZV9wZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJScgOiAnTi9BJykgKyAnKVwiPiZuYnNwOzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzwvZGl2PicgK1xuICAgICAgICAgICAgICAgICAgJzwvdGQ+J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIE9iamVjdC5rZXlzKGJhc2UuZGltZW5zaW9ucykuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgICB2YXIgdGl0bGUgPSBiYXNlLm1ldGFbZGltZW5zaW9ua2V5XTtcbiAgICAgICAgICAgIGlmICh0aXRsZSlcbiAgICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgdGl0bGUgPSBkLm5hbWUgfHwgZC5rZXk7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb24gbm90c2hvd25cIj4nICtcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJjYXB0aW9uXCIgdGl0bGU9XCInICsgdGl0bGUgKyAnXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwic3ViY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgICAgJHRkLmZpbmQoJy5jYXB0aW9uJykudGV4dCgnTi9BICcgKyAoc2VsZi5vcHRpb25zLnN0cmluZ3Mubm90X3Nob3duIHx8ICdOb3Qgc2hvd24nKSk7XG4gICAgICAgICAgICAkdGQuZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMobm90c2hvd25bMF0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgdnMuICcgKyAoY29tcGFyZS5taXNzaW5nID8gJ04vQScgOiBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKG5vdHNob3duWzFdLCBiZXRhLm1ldGFbbWV0cmlja2V5XSkpKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmFzZS5taXNzaW5nIHx8IGNvbXBhcmUubWlzc2luZylcbiAgICAgICAgICBwZXJjZW50YWdlID0gbnVsbDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHBlcmNlbnRhZ2UgPSAoKGJhc2UubWV0cmljc1ttZXRyaWNrZXldIC0gY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0pIC8gY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0gKiAxMDApO1xuXG4gICAgICAgIGlmICghYmFzZS5taXNzaW5nKVxuICAgICAgICAgICR0ciA9ICQkKCc8dHIgZGF0YS1pZD1cIicgKyBiYXNlLmtleSArICdcIiBkYXRhLXZhbHVlPVwiJyArIGJhc2UubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiIGRhdGEtbmFtZT1cIicgKyBiYXNlLmRpbWVuc2lvbnNbZGltZW5zaW9ua2V5XSArICdcIiBkYXRhLXZhbHVlLXNvcnQ9XCInICsgcGVyY2VudGFnZSArICdcIiBkYXRhLXNlbGVjdGFibGU9XCInICsgKHNlbGYub3B0aW9ucy5hbGxvd1NlbGVjdCAhPT0gZmFsc2UgKSArICdcIj48L3RyPicpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgJHRyID0gJCQoJzx0ciBkYXRhLWlkPVwiJyArIGNvbXBhcmUua2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0gKyAnXCIgZGF0YS1uYW1lPVwiJyArIGNvbXBhcmUuZGltZW5zaW9uc1tkaW1lbnNpb25rZXldICsgJ1wiIGRhdGEtdmFsdWUtc29ydD1cIicgKyBwZXJjZW50YWdlICsgJ1wiIGRhdGEtc2VsZWN0YWJsZT1cIicgKyAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0ICE9PSBmYWxzZSApICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgIC8vc2hvdWxkIHdlIG1hcmsgdGhpcyByb3cgYXMgYWN0aXZlP1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcyAmJiBzZWxmLm9wdGlvbnMuY2FudmFzLm9wdGlvbnMuZmlsdGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5vcHRpb25zLmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICBpZiAoZmlsdGVyLmtleSA9PT0gYmFzZS5rZXkpXG4gICAgICAgICAgICAgICR0ci5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFiYXNlLm1pc3NpbmcpXG4gICAgICAgICAgYmFzZV9wZXJjZW50YWdlID0gcGFyc2VGbG9hdChiYXNlLm1ldHJpY3NbbWV0cmlja2V5XSkgLyB0b3RhbFswXSAqIDEwMDtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGJhc2VfcGVyY2VudGFnZSA9IG51bGw7XG4gICAgICAgIGlmIChiYXNlX3BlcmNlbnRhZ2UgPiAxMDApXG4gICAgICAgICAgYmFzZV9wZXJjZW50YWdlID0gMTAwO1xuICAgICAgICBpZiAoIWNvbXBhcmUubWlzc2luZykge1xuICAgICAgICAgIGNvbXBhcmVfcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0pIC8gdG90YWxbMV0gKiAxMDA7XG4gICAgICAgICAgaWYgKGNvbXBhcmVfcGVyY2VudGFnZSA+IDEwMCkge1xuICAgICAgICAgICAgY29tcGFyZV9wZXJjZW50YWdlID0gMTAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlXG4gICAgICAgICAgY29tcGFyZV9wZXJjZW50YWdlID0gbnVsbDtcbiAgICAgICAgX3F1ZXJ5Lm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSkge1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiamlvIGJhcnRhYmxlIHZhbHVlXCI+JyArXG4gICAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJiYXJ3cmFwcGVyIGNvbXBhcmVcIj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyXCIgc3R5bGU9XCJ3aWR0aDonICsgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMoYmFzZV9wZXJjZW50YWdlKSA/IChiYXNlX3BlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBiYXNlX3BlcmNlbnRhZ2UgKyAnJScpIDogMCkgKyAnO2JhY2tncm91bmQtY29sb3I6ICcgKyBzZWxmLm9wdGlvbnMuY29sb3JzWzBdICsgJztcIiB0aXRsZT1cIicgKyAoIWJhc2UubWlzc2luZyA/IGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgKGJhc2VfcGVyY2VudGFnZSA/IGJhc2VfcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUnIDogJ04vQScpICsgJylcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBzdHlsZT1cImNsZWFyOmJvdGhcIj48L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPGRpdiBjbGFzcz1cInRhYmxlYmFyIGNvbXBhcmVfcmF0aW9cIiBzdHlsZT1cIndpZHRoOicgKyAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhjb21wYXJlX3BlcmNlbnRhZ2UpID8gKGNvbXBhcmVfcGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IGNvbXBhcmVfcGVyY2VudGFnZSArICclJykgOiAwKSArICc7YmFja2dyb3VuZC1jb2xvcjogJyArIHNlbGYub3B0aW9ucy5vZmZjb2xvcnNbMF0gKyAnXCIgdGl0bGU9XCInICsgKGNvbXBhcmUubWV0cmljcyAmJiBjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSA/IGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0sIGNvbXBhcmUubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcgJyArIG1ldHJpY25hbWUgKyAnICgnICsgKGNvbXBhcmVfcGVyY2VudGFnZSA/IGNvbXBhcmVfcGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUnIDogJ04vQScpICsgJylcIj4mbmJzcDs8L2Rpdj4nICtcbiAgICAgICAgICAgICAgICAnPC9kaXY+JyArXG4gICAgICAgICAgICAgICAgJzwvdGQ+J1xuICAgICAgICAgICAgKVxuICAgICAgICAgICAgO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0KSB7XG4gICAgICAgICAgICAkdGQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoJHRyLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICAkdHIucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdzZWxlY3QnLCBbYmFzZSwgY29tcGFyZV0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtiYXNlLCBjb21wYXJlXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBfcXVlcnkuZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgdmFyIHRpdGxlID0gYmFzZS5tZXRhW2RpbWVuc2lvbmtleV07XG4gICAgICAgICAgaWYgKHRpdGxlKVxuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZS50aXRsZSB8fCB0aXRsZS5uYW1lIHx8IHRpdGxlLmtleTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aXRsZSA9IGQubmFtZSB8fCBkLmtleTtcbiAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cImppbyBiYXJ0YWJsZSB2YWx1ZSBkaW1lbnNpb25cIj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiY2FwdGlvblwiIHRpdGxlPVwiJyArIHRpdGxlICsgJ1wiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJzdWJjYXB0aW9uXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAnPC90ZD4nKTtcblxuICAgICAgICAgIHZhciB0ZXh0O1xuICAgICAgICAgIGlmIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpKVxuICAgICAgICAgICAgdGV4dCA9IGpvb2xhLmNvbW1vbi5lbnN1cmVMZW5ndGgocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArICghYmFzZS5taXNzaW5nID8gYmFzZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gOiAoY29tcGFyZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpKSwgMjMpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKCdOL0EgJyArICghYmFzZS5taXNzaW5nID8gYmFzZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gOiAoY29tcGFyZS5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gfHwgJyhub3Qgc2V0KScpKSwgMjMpO1xuICAgICAgICAgICR0ZC5maW5kKCcuY2FwdGlvbicpLnRleHQodGV4dCk7XG4gICAgICAgICAgaWYgKCFiYXNlLm1pc3NpbmcgJiYgIWNvbXBhcmUubWlzc2luZylcbiAgICAgICAgICAgICR0ZC5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhiYXNlLm1ldHJpY3NbbWV0cmlja2V5XSwgYmFzZS5tZXRhW21ldHJpY2tleV0pICsgJyB2cy4gJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoY29tcGFyZS5tZXRyaWNzW21ldHJpY2tleV0sIGNvbXBhcmUubWV0YVttZXRyaWNrZXldKSk7XG4gICAgICAgICAgZWxzZSBpZiAoYmFzZS5taXNzaW5nKVxuICAgICAgICAgICAgJHRkLmZpbmQoJy5zdWJjYXB0aW9uJykudGV4dCgnTi9BIHZzLiAnICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlLm1ldHJpY3NbbWV0cmlja2V5XSwgY29tcGFyZS5tZXRhW21ldHJpY2tleV0pKTtcbiAgICAgICAgICBlbHNlIGlmIChjb21wYXJlLm1pc3NpbmcpXG4gICAgICAgICAgICAkdGQuZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWMoYmFzZS5tZXRyaWNzW21ldHJpY2tleV0sIGJhc2UubWV0YVttZXRyaWNrZXldKSArICcgdnMuIE4vQScpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmFsbG93U2VsZWN0KSB7XG4gICAgICAgICAgICAkdGQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoJHRyLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICAkdHIucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgJHRyLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdzZWxlY3QnLCBbYmFzZSwgY29tcGFyZV0pO1xuICAgICAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLnNlbGVjdClcbiAgICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0LmFwcGx5KHRoaXMsIFtiYXNlLCBjb21wYXJlXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIHRvdGFsID0gWzAsIDBdO1xuICAgIHZhciBzaG93biA9IFswLCAwXTtcbiAgICB2YXIgbm90c2hvd24gPSBbMCwgMF07XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgYWxsZGF0YVtpbmRleF0uZm9yRWFjaChmdW5jdGlvbiAocG9pbnQsIGkpIHtcbiAgICAgICAgdG90YWxbaW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICAgaWYgKGkgPCAoc2VsZi5vcHRpb25zLmxpbWl0ICYmIHNlbGYub3B0aW9ucy5saW1pdCA8IGRhdGEubGVuZ3RoID8gc2VsZi5vcHRpb25zLmxpbWl0IC0gMSA6IHNlbGYub3B0aW9ucy5saW1pdCApKVxuICAgICAgICAgIHNob3duW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICAgIGVsc2VcbiAgICAgICAgICBub3RzaG93bltpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgaWYgKCFzZWxmLm9wdGlvbnMuaW5jbHVkZV9ub3Rfc2hvd24pIHtcbiAgICAgIHRvdGFsID0gc2hvd247XG4gICAgICBub3RzaG93biA9IFswLCAwXTtcbiAgICB9XG4gICAgYWRkUm93KGRhdGEsIHRvdGFsLCBzaG93biwgbm90c2hvd24pO1xuICAgIC8vc2VsZi5zb3J0KCk7XG4gIH07XG4gIHRoaXMuZXhpdCA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgX3F1ZXJ5ID0gX3F1ZXJ5WzBdO1xuICAgIHZhciBkaW1lbnNpb25rZXkgPSBfcXVlcnkuZGltZW5zaW9uc1swXS5rZXkgfHwgX3F1ZXJ5LmRpbWVuc2lvbnNbMF07XG4gICAgdmFyIG1ldHJpY2tleSA9IF9xdWVyeS5tZXRyaWNzWzBdLmtleSB8fCBfcXVlcnkubWV0cmljc1swXTtcbiAgICB2YXIgbWV0cmljbmFtZSA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcblxuICAgIHZhciB0b3RhbCA9IFswLCAwXTtcbiAgICB2YXIgc2hvd24gPSBbMCwgMF07XG4gICAgdmFyIG5vdHNob3duID0gWzAsIDBdO1xuXG4gICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgaW5kZXgpIHtcbiAgICAgIGFsbGRhdGFbaW5kZXhdLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpKSB7XG4gICAgICAgIHRvdGFsW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICAgIGlmIChpIDwgKHNlbGYub3B0aW9ucy5saW1pdCAmJiBzZWxmLm9wdGlvbnMubGltaXQgPCBkYXRhLmxlbmd0aCA/IHNlbGYub3B0aW9ucy5saW1pdCAtIDEgOiBzZWxmLm9wdGlvbnMubGltaXQgKSlcbiAgICAgICAgICBzaG93bltpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgbm90c2hvd25baW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIGlmICghc2VsZi5vcHRpb25zLmluY2x1ZGVfbm90X3Nob3duKSB7XG4gICAgICB0b3RhbCA9IHNob3duO1xuICAgICAgbm90c2hvd24gPSBbMCwgMF07XG4gICAgfVxuXG4gICAgaWYgKGRhdGEubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgcG9pbnQgPSBkYXRhWzBdO1xuICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0cicpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBlbGVtKSB7XG4gICAgICAgIC8vdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCdbZGF0YS1pZD1cIicgKyBwb2ludC5rZXkgKyAnXCJdJylbMF07XG4gICAgICAgIHZhciAkZWxlbSA9ICQkKGVsZW0pO1xuICAgICAgICB2YXIgcGVyY2VudGFnZSwgdGV4dDtcbiAgICAgICAgdmFyIG5hbWUgPSAkZWxlbS5hdHRyKCdkYXRhLW5hbWUnKTtcbiAgICAgICAgdmFyIHZhbHVlID0gcGFyc2VGbG9hdCgkZWxlbS5hdHRyKCdkYXRhLXZhbHVlJykpO1xuICAgICAgICBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSBwb2ludC5rZXkpIHtcbiAgICAgICAgICAkZWxlbS5yZW1vdmUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgkZWxlbS5hdHRyKCdkYXRhLWlkJykgPT09ICdvdGhlcicpIHtcbiAgICAgICAgICB2YWx1ZSA9IG5vdHNob3duWzBdO1xuICAgICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcGVyY2VudGFnZSA9IHBhcnNlRmxvYXQodmFsdWUgLyB0b3RhbFswXSAqIDEwMCk7XG4gICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUtc29ydCcsIHBlcmNlbnRhZ2UpO1xuXG4gICAgICAgIGlmIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpKVxuICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKHBlcmNlbnRhZ2UudG9GaXhlZCgyKSArICclICcgKyAobmFtZSB8fCAnKG5vdCBzZXQpJyksIDIzKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHRleHQgPSBqb29sYS5jb21tb24uZW5zdXJlTGVuZ3RoKCdOL0EgJyArIChuYW1lIHx8ICcobm90IHNldCknKSwgMjMpO1xuICAgICAgICAkZWxlbS5maW5kKCcudGFibGViYXInKS5jc3MoJ3dpZHRoJywgKGpvb2xhLmNvbW1vbi5pc051bWVyaWMocGVyY2VudGFnZSkgPyAocGVyY2VudGFnZSA+IDEwMCA/ICcxMDAlJyA6IHBlcmNlbnRhZ2UgKyAnJScpIDogMCkpO1xuICAgICAgICBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSAnb3RoZXInKVxuICAgICAgICAgICRlbGVtLmZpbmQoJy5jYXB0aW9uJykudGV4dChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93biB8fCAnTm90IHNob3duJykpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgJGVsZW0uZmluZCgnLmNhcHRpb24nKS50ZXh0KHRleHQpO1xuICAgICAgICAkZWxlbS5maW5kKCcuc3ViY2FwdGlvbicpLnRleHQoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh2YWx1ZSwgcG9pbnQubWV0YVttZXRyaWNrZXldKSArICcgJyArIG1ldHJpY25hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHNlbGYuc29ydCgpO1xuICAgIGlmIChzZWxmLmRhdGFbMF0ubGVuZ3RoID09PSAwKSB7XG4gICAgICB2YXIgJHRib2R5ID0gJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgndGJvZHknKTtcbiAgICAgICR0Ym9keSA9ICQkKCR0Ym9keSk7XG4gICAgICAkdGJvZHkuZW1wdHkoKTtcbiAgICAgIHZhciAkdHIgPSAkJCgnPHRyIGNsYXNzPVwibm9kYXRhXCI+PC90cj4nKTtcbiAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNvbHNwYW49XCIyXCI+JyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vZGF0YSArICc8L3RkPicpO1xuICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgIH1cbiAgfTtcbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIHZhciBfcXVlcnkgPSBzZWxmLm9wdGlvbnMucXVlcnk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgIF9xdWVyeSA9IF9xdWVyeVswXTtcbiAgICB2YXIgZGltZW5zaW9ua2V5ID0gX3F1ZXJ5LmRpbWVuc2lvbnNbMF0ua2V5IHx8IF9xdWVyeS5kaW1lbnNpb25zWzBdO1xuICAgIHZhciBtZXRyaWNrZXkgPSBfcXVlcnkubWV0cmljc1swXS5rZXkgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG4gICAgdmFyIG1ldHJpY25hbWUgPSBkYXRhWzBdLm1ldGFbbWV0cmlja2V5XS5uYW1lIHx8IF9xdWVyeS5tZXRyaWNzWzBdLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG5cbiAgICB2YXIgdG90YWwgPSBbMCwgMF07XG4gICAgdmFyIHNob3duID0gWzAsIDBdO1xuICAgIHZhciBub3RzaG93biA9IFswLCAwXTtcblxuICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQsIGluZGV4KSB7XG4gICAgICBhbGxkYXRhW2luZGV4XS5mb3JFYWNoKGZ1bmN0aW9uIChwb2ludCwgaSkge1xuICAgICAgICB0b3RhbFtpbmRleF0gKz0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICBpZiAoaSA8IChzZWxmLm9wdGlvbnMubGltaXQgJiYgc2VsZi5vcHRpb25zLmxpbWl0IDwgZGF0YS5sZW5ndGggPyBzZWxmLm9wdGlvbnMubGltaXQgLSAxIDogc2VsZi5vcHRpb25zLmxpbWl0ICkpXG4gICAgICAgICAgc2hvd25baW5kZXhdICs9IHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIG5vdHNob3duW2luZGV4XSArPSBwb2ludC5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAoIXNlbGYub3B0aW9ucy5pbmNsdWRlX25vdF9zaG93bikge1xuICAgICAgdG90YWwgPSBzaG93bjtcbiAgICAgIG5vdHNob3duID0gWzAsIDBdO1xuICAgIH1cblxuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdmFyIHBvaW50ID0gZGF0YVswXTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3RyJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGVsZW0pIHtcbiAgICAgICAgLy92YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ1tkYXRhLWlkPVwiJyArIHBvaW50LmtleSArICdcIl0nKVswXTtcbiAgICAgICAgdmFyICRlbGVtID0gJCQoZWxlbSk7XG4gICAgICAgIHZhciBwZXJjZW50YWdlLCB0ZXh0O1xuICAgICAgICB2YXIgbmFtZSA9ICRlbGVtLmF0dHIoJ2RhdGEtbmFtZScpO1xuICAgICAgICB2YXIgdmFsdWUgPSBwYXJzZUZsb2F0KCRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnKSk7XG4gICAgICAgIGlmICgkZWxlbS5hdHRyKCdkYXRhLWlkJykgPT09IHBvaW50LmtleSkge1xuICAgICAgICAgIHZhbHVlID0gcG9pbnQubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICAgICRlbGVtLmF0dHIoJ2RhdGEtdmFsdWUnLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoJGVsZW0uYXR0cignZGF0YS1pZCcpID09PSAnb3RoZXInKSB7XG4gICAgICAgICAgdmFsdWUgPSBub3RzaG93blswXTtcbiAgICAgICAgICAkZWxlbS5hdHRyKCdkYXRhLXZhbHVlJywgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHBlcmNlbnRhZ2UgPSBwYXJzZUZsb2F0KHZhbHVlIC8gdG90YWxbMF0gKiAxMDApO1xuICAgICAgICAkZWxlbS5hdHRyKCdkYXRhLXZhbHVlLXNvcnQnLCBwZXJjZW50YWdlKTtcblxuICAgICAgICBpZiAoam9vbGEuY29tbW9uLmlzTnVtZXJpYyhwZXJjZW50YWdlKSlcbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmVuc3VyZUxlbmd0aChwZXJjZW50YWdlLnRvRml4ZWQoMikgKyAnJSAnICsgKG5hbWUgfHwgJyhub3Qgc2V0KScpLCAyMyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmVuc3VyZUxlbmd0aCgnTi9BICcgKyAobmFtZSB8fCAnKG5vdCBzZXQpJyksIDIzKTtcbiAgICAgICAgJGVsZW0uZmluZCgnLnRhYmxlYmFyJykuY3NzKCd3aWR0aCcsIChqb29sYS5jb21tb24uaXNOdW1lcmljKHBlcmNlbnRhZ2UpID8gKHBlcmNlbnRhZ2UgPiAxMDAgPyAnMTAwJScgOiBwZXJjZW50YWdlICsgJyUnKSA6IDApKTtcbiAgICAgICAgaWYgKCRlbGVtLmF0dHIoJ2RhdGEtaWQnKSA9PT0gJ290aGVyJylcbiAgICAgICAgICAkZWxlbS5maW5kKCcuY2FwdGlvbicpLnRleHQocGVyY2VudGFnZS50b0ZpeGVkKDIpICsgJyUgJyArIChzZWxmLm9wdGlvbnMuc3RyaW5ncy5ub3Rfc2hvd24gfHwgJ05vdCBzaG93bicpKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICRlbGVtLmZpbmQoJy5jYXB0aW9uJykudGV4dCh0ZXh0KTtcbiAgICAgICAgJGVsZW0uZmluZCgnLnN1YmNhcHRpb24nKS50ZXh0KGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModmFsdWUsIHBvaW50Lm1ldGFbbWV0cmlja2V5XSkgKyAnICcgKyBtZXRyaWNuYW1lKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBzZWxmLnNvcnQoKTtcbiAgICBpZiAoc2VsZi5kYXRhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdmFyICR0Ym9keSA9ICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJ3Rib2R5Jyk7XG4gICAgICAkdGJvZHkgPSAkJCgkdGJvZHkpO1xuICAgICAgJHRib2R5LmVtcHR5KCk7XG4gICAgICB2YXIgJHRyID0gJCgnPHRyIGNsYXNzPVwibm9kYXRhXCI+PC90cj4nKTtcbiAgICAgIHZhciAkdGQgPSAkKCc8dGQgY29sc3Bhbj1cIjJcIj4nICsgc2VsZi5vcHRpb25zLnN0cmluZ3Mubm9kYXRhICsgJzwvdGQ+Jyk7XG4gICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS52aXouc3RvcChzZWxmKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0YWJsZScpLmVtcHR5KCk7XG4gIH07XG5cbiAgdGhpcy5zb3J0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciAkdGJvZHkgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICB2YXIgJHJvd3MgPSAkdGJvZHkuZmluZCgndHInKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8ICRyb3dzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCAkcm93cy5sZW5ndGggLSAoaSArIDEpOyBqKyspIHtcbiAgICAgICAgdmFyICRyb3cgPSAkJCgkcm93c1tqXSk7XG4gICAgICAgIHZhciB2YWx1ZSA9ICRyb3cuYXR0cignZGF0YS12YWx1ZS1zb3J0Jyk7XG4gICAgICAgIHZhciAkbmV4dHJvdyA9ICQkKCRyb3dzW2ogKyAxXSk7XG4gICAgICAgIHZhciBuZXh0dmFsdWUgPSAkbmV4dHJvdy5hdHRyKCdkYXRhLXZhbHVlLXNvcnQnKTtcblxuICAgICAgICBpZiAoJG5leHRyb3cuYXR0cignZGF0YS1uYW1lJykgIT09IHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vdF9zaG93bikge1xuICAgICAgICAgIGlmIChwYXJzZUZsb2F0KG5leHR2YWx1ZSkgPiBwYXJzZUZsb2F0KHZhbHVlKSlcbiAgICAgICAgICAgICRyb3cuYmVmb3JlKCRuZXh0cm93KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIC8vd2UgZHJhdyB0aGUgdGVtcGxhdGUgaW50byB0aGUgY29udGFpbmVyXG4gICAgdmFyICRodG1sID0gJCQoc2VsZi5vcHRpb25zLnRlbXBsYXRlKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5odG1sKCRodG1sKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhcHRpb24pXG4gICAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuYmFydGFibGUtY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24pO1xuICAgIC8vdmlzdWFsaXphdGlvbiBzcGVjaWZpYyBkcmF3aW5nXG4gICAgaWYgKHNlbGYub3B0aW9ucy5oZWFkZXJzKSB7XG4gICAgICB2YXIgJHRoZWFkID0gJCQoJGh0bWwuZmluZCgndGhlYWQnKSk7XG4gICAgICB2YXIgJGhlYWRfdHIgPSAkJCgnPHRyIGNsYXNzPVwiamlvIGJhcnRhYmxlIGNhcHRpb25zXCI+PC90cj4nKTtcbiAgICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJqaW8gYmFydGFibGUgY2FwdGlvbiBtZXRyaWNcIj48L3RoPicpO1xuICAgICAgICAvLyR0aC50ZXh0KG0ubmFtZSB8fCBtLmtleSB8fCBtKTtcbiAgICAgICAgJGhlYWRfdHIuYXBwZW5kKCR0aCk7XG4gICAgICB9KTtcbiAgICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJqaW8gYmFydGFibGUgY2FwdGlvbiBkaW1lbnNpb25cIj48L3RoPicpO1xuICAgICAgICAkdGgudGV4dChkLm5hbWUgfHwgZC5rZXkgfHwgZCk7XG4gICAgICAgICRoZWFkX3RyLmFwcGVuZCgkdGgpO1xuICAgICAgfSk7XG5cbiAgICAgICR0aGVhZC5hcHBlbmQoJGhlYWRfdHIpO1xuICAgICAgJGh0bWwuZmluZCgndGFibGUnKS5hcHBlbmQoJHRoZWFkKTtcbiAgICB9XG4gICAgdmFyICR0Ym9keSA9ICRodG1sLmZpbmQoJ3Rib2R5Jyk7XG4gICAgJHRib2R5ID0gJCQoJHRib2R5KTtcbiAgICAkdGJvZHkuZW1wdHkoKTtcbiAgICB2YXIgJHRyID0gJCQoJzx0ciBjbGFzcz1cImxvYWRpbmdcIj48L3RyPicpO1xuICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwibG9hZGluZ1wiIGNvbHNwYW49XCIyXCI+JyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLmxvYWRpbmcgKyAnPC90ZD4nKTtcbiAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICRodG1sLmZpbmQoJ3RhYmxlJykuYXBwZW5kKCR0Ym9keSk7XG4gIH07XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5xdWVyeSAmJiAhQXJyYXkuaXNBcnJheShvcHRpb25zLnF1ZXJ5KSlcbiAgICBvcHRpb25zLnF1ZXJ5ID0gW29wdGlvbnMucXVlcnldO1xuICAvL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG5cbiAgaWYgKHNlbGYub3B0aW9ucy5jb2xvcnMubGVuZ3RoID09PSAwKVxuICAgIHNlbGYub3B0aW9ucy5jb2xvcnMgPSBqb29sYS5jb2xvcnM7XG4gIGlmIChzZWxmLm9wdGlvbnMub2ZmY29sb3JzLmxlbmd0aCA9PT0gMClcbiAgICBzZWxmLm9wdGlvbnMub2ZmY29sb3JzID0gam9vbGEub2ZmY29sb3JzO1xuXG4gIHNlbGYuZHJhdygpO1xuXG4gIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICBpZiAoIXNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJCQoZWxlbSkuQ2FudmFzKCk7XG4gICAgfVxuICB9XG4gIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICB9XG5cbiAgLy93cmFwIHVwXG4gIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcblxuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZvdW5kO1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5CYXJUYWJsZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5CYXJUYWJsZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBiYXJ0YWJsZSkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoQmFyVGFibGUsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpLFxuICBjZSA9IHJlcXVpcmUoJ2Nsb25lZXh0ZW5kJyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbnZhciBDYW52YXMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdjYW52YXMuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5faWQgPSAnX2NhbnZhcyc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICB2aXN1YWxpemF0aW9uczoge30sXG4gICAgbWV0cmljczogW10sXG4gICAgZGltZW5zaW9uczogW10sXG4gICAgZmlsdGVyczogW10sXG4gICAgc3RhdGU6IHt9XG4gIH07XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMucHJlcGFyZVF1ZXJ5ID0gZnVuY3Rpb24gKHF1ZXJ5LCBkYXRlcykge1xuICAgIHZhciBfcXVlcnk7XG4gICAgaWYgKCFkYXRlcylcbiAgICAgIGRhdGVzID0ge307XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocXVlcnkpKVxuICAgICAgX3F1ZXJ5ID0gW2NlLmV4dGVuZCh7fSwgcXVlcnlbMF0pXTtcbiAgICBlbHNlIHtcbiAgICAgIF9xdWVyeSA9IGNlLmV4dGVuZCh7fSwgcXVlcnkpO1xuICAgICAgX3F1ZXJ5ID0gW19xdWVyeV07XG4gICAgfVxuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkpIHtcbiAgICAgIF9xdWVyeVswXSA9IGpvb2xhLmNvbW1vbi5fZXh0ZW5kKGNlLmNsb25lKHNlbGYub3B0aW9ucy5xdWVyeSksIF9xdWVyeVswXSk7XG4gICAgfVxuXG4gICAgaWYgKF9xdWVyeVswXS5kaW1lbnNpb25zICYmIF9xdWVyeVswXS5kaW1lbnNpb25zLmxlbmd0aCA+IDAgJiYgX3F1ZXJ5WzBdLmRpbWVuc2lvbnMgJiYgX3F1ZXJ5WzBdLmRpbWVuc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgX3F1ZXJ5WzBdLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZGltZW5zaW9uLCBpKSB7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGlmICh0eXBlb2YgZGltZW5zaW9uID09PSAnc3RyaW5nJylcbiAgICAgICAgICBrZXkgPSBkaW1lbnNpb247XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkaW1lbnNpb24gPT09ICdvYmplY3QnKVxuICAgICAgICAgIGtleSA9IGRpbWVuc2lvbi5rZXk7XG5cbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChfcXVlcnlbMF0uZGltZW5zaW9ucywgZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHJldHVybiAobS5rZXkgfHwgbSkgPT09IGtleTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICBfcXVlcnlbMF0uZGltZW5zaW9uc1tpXSA9IGV4aXN0O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoX3F1ZXJ5WzBdLm1ldHJpY3MgJiYgX3F1ZXJ5WzBdLm1ldHJpY3MubGVuZ3RoID4gMCAmJiBfcXVlcnlbMF0ubWV0cmljcyAmJiBfcXVlcnlbMF0ubWV0cmljcy5sZW5ndGggPiAwKSB7XG4gICAgICBfcXVlcnlbMF0ubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtZXRyaWMsIGkpIHtcbiAgICAgICAgdmFyIGtleTtcbiAgICAgICAgaWYgKHR5cGVvZiBtZXRyaWMgPT09ICdzdHJpbmcnKVxuICAgICAgICAgIGtleSA9IG1ldHJpYztcbiAgICAgICAgLy9lbHNlIGlmICh0eXBlb2YgbWV0cmljID09PSAnb2JqZWN0JylcbiAgICAgICAgLy8gIGtleSA9IG1ldHJpYy5rZXk7XG5cbiAgICAgICAgaWYgKGtleSkge1xuICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChzZWxmLm9wdGlvbnMubWV0cmljcywgZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHJldHVybiAobS5rZXkgfHwgbSkgPT09IGtleTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICBfcXVlcnlbMF0ubWV0cmljc1tpXSA9IGV4aXN0O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgX3F1ZXJ5WzBdLnR5cGUgPSAnYmFzZSc7XG4gICAgX3F1ZXJ5WzBdLmhhc2ggPSAnJztcbiAgICBpZiAoX3F1ZXJ5WzBdLmRpbWVuc2lvbnMgJiYgQXJyYXkuaXNBcnJheShfcXVlcnlbMF0uZGltZW5zaW9ucykpIHtcbiAgICAgIF9xdWVyeVswXS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgX3F1ZXJ5WzBdLmhhc2ggKz0gZC5rZXkgfHwgZDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoX3F1ZXJ5WzBdLm1ldHJpY3MgJiYgQXJyYXkuaXNBcnJheShfcXVlcnlbMF0ubWV0cmljcykpXG4gICAgICBfcXVlcnlbMF0ubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgIF9xdWVyeVswXS5oYXNoICs9IG0ua2V5IHx8IG07XG4gICAgICB9KTtcbiAgICBfcXVlcnlbMF0uaGFzaCA9IGpvb2xhLmNvbW1vbi5oYXNoKF9xdWVyeVswXS5oYXNoKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIgJiYgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuY29udGFpbmVyKSB7XG4gICAgICBkYXRlcyA9IHtcbiAgICAgICAgYmFzZV9mcm9tZGF0ZTogc2VsZi5vcHRpb25zLiRkYXRlcGlja2VyLmJhc2VfZnJvbWRhdGUsXG4gICAgICAgIGJhc2VfdG9kYXRlOiBzZWxmLm9wdGlvbnMuJGRhdGVwaWNrZXIuYmFzZV90b2RhdGUsXG4gICAgICAgIGNvbXBhcmVfZnJvbWRhdGU6IHNlbGYub3B0aW9ucy4kZGF0ZXBpY2tlci5jb21wYXJlX2Zyb21kYXRlLFxuICAgICAgICBjb21wYXJlX3RvZGF0ZTogc2VsZi5vcHRpb25zLiRkYXRlcGlja2VyLmNvbXBhcmVfdG9kYXRlXG4gICAgICB9O1xuICAgICAgX3F1ZXJ5WzBdLnRpbWVmcmFtZSA9IHt9O1xuICAgICAgX3F1ZXJ5WzBdLnRpbWVmcmFtZS5zdGFydCA9IGRhdGVzLmJhc2VfZnJvbWRhdGUgfHwgc2VsZi5fZGF0ZXBpY2tlci5iYXNlX2Zyb21kYXRlO1xuICAgICAgX3F1ZXJ5WzBdLnRpbWVmcmFtZS5lbmQgPSBkYXRlcy5iYXNlX3RvZGF0ZSB8fCBzZWxmLl9kYXRlcGlja2VyLmJhc2VfdG9kYXRlO1xuICAgICAgX3F1ZXJ5WzBdLmludGVydmFsID0gJ2RheSc7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIgJiYgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsKVxuICAgICAgICBfcXVlcnlbMF0uaW50ZXJ2YWwgPSBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5faW50ZXJ2YWw7XG4gICAgfVxuICAgIF9xdWVyeVswXS5yZWFsdGltZSA9IF9xdWVyeVswXS5yZWFsdGltZSB8fCBzZWxmLm9wdGlvbnMucmVhbHRpbWUgfHwgZmFsc2U7XG4gICAgaWYgKHNlbGYuX2RhdGVwaWNrZXIgJiYgc2VsZi5fZGF0ZXBpY2tlci5jb21wYXJlUGVyaW9kKSB7XG4gICAgICBfcXVlcnlbMF0ucmVhbHRpbWUgPSBmYWxzZTtcbiAgICAgIHZhciBjcXVlcnkgPSBjZS5jbG9uZShfcXVlcnlbMF0pO1xuICAgICAgY3F1ZXJ5LnR5cGUgPSAnY29tcGFyZSc7XG4gICAgICBjcXVlcnkudGltZWZyYW1lID0ge307XG4gICAgICBjcXVlcnkudGltZWZyYW1lLnN0YXJ0ID0gZGF0ZXMuY29tcGFyZV9mcm9tZGF0ZSB8fCBzZWxmLl9kYXRlcGlja2VyLmNvbXBhcmVfZnJvbWRhdGU7XG4gICAgICBjcXVlcnkudGltZWZyYW1lLmVuZCA9IGRhdGVzLmNvbXBhcmVfdG9kYXRlIHx8IHNlbGYuX2RhdGVwaWNrZXIuY29tcGFyZV90b2RhdGU7XG4gICAgICBjcXVlcnkuaW50ZXJ2YWwgPSAnZGF5JztcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlciAmJiBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5faW50ZXJ2YWwpXG4gICAgICAgIGNxdWVyeS5pbnRlcnZhbCA9IHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLl9pbnRlcnZhbDtcbiAgICAgIF9xdWVyeSA9IFtfcXVlcnlbMF0sIGNxdWVyeV07XG4gICAgfVxuXG4gICAgcmV0dXJuIF9xdWVyeTtcbiAgfTtcblxuICB0aGlzLnBhcnNlSW50ZXJ2YWwgPSBmdW5jdGlvbiAoJGNvbnRhaW5lcikge1xuICAgIHJldHVybiAkY29udGFpbmVyLmZpbmQoJy5hY3RpdmUnKS5hdHRyKCdkYXRhLWlkJyk7XG4gIH07XG5cbiAgdGhpcy5idWlsZEZpbHRlciA9IGZ1bmN0aW9uIChwb2ludCwgZGltZW5zaW9ua2V5KSB7XG4gICAgdmFyIGZpbHRlcnMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhwb2ludC5kaW1lbnNpb25zKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIGlmIChkaW1lbnNpb25rZXkgJiYgZGltZW5zaW9ua2V5ID09PSBrZXkgfHwgIWRpbWVuc2lvbmtleSkge1xuICAgICAgICB2YXIgZGltZW5zaW9uID0gcG9pbnQubWV0YVtrZXldO1xuICAgICAgICB2YXIgdmFsdWUgPSBwb2ludC5kaW1lbnNpb25zW2tleV07XG4gICAgICAgIHZhciBmaWx0ZXIgPSBbZGltZW5zaW9uLmtleSwgJ2VxJywgZGltZW5zaW9uLmRhdGF0eXBlID09PSAnZGF0ZScgPyBuZXcgRGF0ZSh2YWx1ZSkgOiB2YWx1ZV07XG4gICAgICAgIGZpbHRlcnMucHVzaChmaWx0ZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBmaWx0ZXJzO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBpZiAoc2VsZi5vcHRpb25zLm9uRHJhdylcbiAgICAgIHdpbmRvd1tzZWxmLm9wdGlvbnMub25EcmF3XShzZWxmKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmZpbHRlcmJveCAmJiBzZWxmLm9wdGlvbnMuZmlsdGVyYm94LmNvbnRhaW5lcikge1xuICAgICAgc2VsZi5vcHRpb25zLmZpbHRlcmJveC5jYW52YXMgPSBzZWxmO1xuICAgICAgbmV3IGpvb2xhLnZpei5GaWx0ZXJCb3goc2VsZi5vcHRpb25zLmZpbHRlcmJveCwgZnVuY3Rpb24gKGVyciwgcmVmKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy5maWx0ZXJib3gucmVmID0gcmVmO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlciAmJiBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5jb250YWluZXIpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLmNhbnZhcyA9IHNlbGY7XG4gICAgICBuZXcgam9vbGEudml6LkRhdGVQaWNrZXIoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIsIGZ1bmN0aW9uIChlcnIsIHJlZikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgc2VsZi5fZGF0ZXBpY2tlciA9IHJlZjtcbiAgICAgICAgc2VsZi5vcHRpb25zLiRkYXRlcGlja2VyID0gcmVmO1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuaW50ZXJ2YWwpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci4kaW50ZXJ2YWwgPSAkJChzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5pbnRlcnZhbCk7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsID0gc2VsZi5wYXJzZUludGVydmFsKHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLiRpbnRlcnZhbCk7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuJGludGVydmFsLmZpbmQoJy5idG4nKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5kYXRlcGlja2VyLiRpbnRlcnZhbC5maW5kKCcuYnRuJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgJHRoaXMuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuZGF0ZXBpY2tlci5faW50ZXJ2YWwgPSAkdGhpcy5hdHRyKCdkYXRhLWlkJyk7XG4gICAgICAgICAgICBzZWxmLmVtaXQoJ2ludGVydmFsY2hhbmdlJywgc2VsZi5vcHRpb25zLmRhdGVwaWNrZXIuX2ludGVydmFsKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIE9iamVjdC5rZXlzKHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgdmFyIHZpeiA9IHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9uc1trZXldO1xuICAgICAgICAgIGlmICh2aXouY29udGFpbmVyKSB7XG4gICAgICAgICAgICB2aXoucXVlcnkgPSBzZWxmLnByZXBhcmVRdWVyeSh2aXoucXVlcnkpO1xuICAgICAgICAgICAgdml6LmZvcmNlID0gdHJ1ZTtcbiAgICAgICAgICAgIHZpei5jYW52YXMgPSBzZWxmO1xuICAgICAgICAgICAgc3dpdGNoICh2aXoudHlwZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3RpbWVsaW5lJzpcbiAgICAgICAgICAgICAgICBuZXcgam9vbGEudml6LlRpbWVsaW5lKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ21ldHJpYyc6XG4gICAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5NZXRyaWModml6KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAndGFibGUnOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouVGFibGUodml6KS5vbignc2VsZWN0JywgZnVuY3Rpb24gKHBvaW50LCBkaW1lbnNpb25rZXkpIHtcbiAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBzZWxmLmJ1aWxkRmlsdGVyKHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgdmFyIGV4aXN0ID0gXy5maW5kKHNlbGYub3B0aW9ucy5maWx0ZXJzLCBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIua2V5ID09PSBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGlmIChleGlzdClcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdyZW1vdmVmaWx0ZXInLCBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgnYWRkZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5LCBwb2ludC5tZXRhLCBmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdtaW5pdGFibGUnOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouTWluaVRhYmxlKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ2JhcnRhYmxlJzpcbiAgICAgICAgICAgICAgICBuZXcgam9vbGEudml6LkJhclRhYmxlKHZpeikub24oJ3NlbGVjdCcsIGZ1bmN0aW9uIChwb2ludCwgZGltZW5zaW9ua2V5KSB7XG4gICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwb2ludCkpXG4gICAgICAgICAgICAgICAgICAgIHBvaW50ID0gcG9pbnRbMF07XG4gICAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0gc2VsZi5idWlsZEZpbHRlcihwb2ludCwgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChzZWxmLm9wdGlvbnMuZmlsdGVycywgZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyLmtleSA9PT0gcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5O1xuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgncmVtb3ZlZmlsdGVyJywgcG9pbnQua2V5ICsgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ2FkZGZpbHRlcicsIHBvaW50LmtleSArIGRpbWVuc2lvbmtleSwgcG9pbnQubWV0YSwgZmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAncGllJzpcbiAgICAgICAgICAgICAgICBuZXcgam9vbGEudml6LlBpZSh2aXopO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdnZW8nOlxuICAgICAgICAgICAgICAgIG5ldyBqb29sYS52aXouR2VvKHZpeik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIE9iamVjdC5rZXlzKHNlbGYub3B0aW9ucy52aXN1YWxpemF0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHZhciB2aXogPSBzZWxmLm9wdGlvbnMudmlzdWFsaXphdGlvbnNba2V5XTtcbiAgICAgICAgaWYgKHZpei5jb250YWluZXIpIHtcbiAgICAgICAgICB2aXoucXVlcnkgPSBzZWxmLnByZXBhcmVRdWVyeSh2aXoucXVlcnkpO1xuICAgICAgICAgIHZpei5mb3JjZSA9IHRydWU7XG4gICAgICAgICAgdml6LmNhbnZhcyA9IHNlbGY7XG4gICAgICAgICAgc3dpdGNoICh2aXoudHlwZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICBjYXNlICd0aW1lbGluZSc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouVGltZWxpbmUodml6KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtZXRyaWMnOlxuICAgICAgICAgICAgICBuZXcgam9vbGEudml6Lk1ldHJpYyh2aXopO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3RhYmxlJzpcbiAgICAgICAgICAgICAgbmV3IGpvb2xhLnZpei5UYWJsZSh2aXopLm9uKCdzZWxlY3QnLCBmdW5jdGlvbiAocG9pbnQsIGRpbWVuc2lvbmtleSkge1xuICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSBzZWxmLmJ1aWxkRmlsdGVyKHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChzZWxmLm9wdGlvbnMuZmlsdGVycywgZnVuY3Rpb24gKGZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlci5rZXkgPT09IHBvaW50LmtleSArIGRpbWVuc2lvbmtleTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoZXhpc3QpXG4gICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3JlbW92ZWZpbHRlcicsIHBvaW50LmtleSArIGRpbWVuc2lvbmtleSk7XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ2FkZGZpbHRlcicsIHBvaW50LmtleSArIGRpbWVuc2lvbmtleSwgcG9pbnQubWV0YSwgZmlsdGVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21pbml0YWJsZSc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouTWluaVRhYmxlKHZpeik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnYmFydGFibGUnOlxuICAgICAgICAgICAgICBuZXcgam9vbGEudml6LkJhclRhYmxlKHZpeikub24oJ3NlbGVjdCcsIGZ1bmN0aW9uIChwb2ludCwgZGltZW5zaW9ua2V5KSB7XG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnQpKVxuICAgICAgICAgICAgICAgICAgcG9pbnQgPSBwb2ludFswXTtcbiAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0gc2VsZi5idWlsZEZpbHRlcihwb2ludCwgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgICAgICB2YXIgZXhpc3QgPSBfLmZpbmQoc2VsZi5vcHRpb25zLmZpbHRlcnMsIGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXIua2V5ID09PSBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0KVxuICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdyZW1vdmVmaWx0ZXInLCBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdhZGRmaWx0ZXInLCBwb2ludC5rZXkgKyBkaW1lbnNpb25rZXksIHBvaW50Lm1ldGEsIGZpbHRlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwaWUnOlxuICAgICAgICAgICAgICBuZXcgam9vbGEudml6LlBpZSh2aXopO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2dlbyc6XG4gICAgICAgICAgICAgIG5ldyBqb29sYS52aXouR2VvKHZpeik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBzZWxmLm9uKCdhZGRmaWx0ZXInLCBmdW5jdGlvbiAoa2V5LCBtZXRhLCBmaWx0ZXIpIHtcbiAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZWxmLm9wdGlvbnMuZmlsdGVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmZpbHRlcnNbaV0ua2V5ID09PSBrZXkpIHtcbiAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLmZpbHRlcnMucHVzaCh7a2V5OiBrZXksIGZpbHRlcnM6IGZpbHRlcn0pO1xuICAgICAgICBmaWx0ZXIuZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgIHZhciAkZmlsdGVyID0gJCQoJzxkaXYgZGF0YS1pZD1cIicgKyBrZXkgKyAnXCIgY2xhc3M9XCJmaWx0ZXJcIj48L2Rpdj4nKTtcbiAgICAgICAgICB2YXIgdGV4dCA9IG1ldGFbZlswXV0ubmFtZSArICc6IDxzdHJvbmcgY2xhc3M9XCJ2YWx1ZVwiPicgKyBmWzJdICsgJzwvc3Ryb25nPic7XG4gICAgICAgICAgdmFyICRpbm5lciA9ICQkKCc8c3BhbiBjbGFzcz1cImNhcHRpb25cIj4nICsgdGV4dCArICc8L3NwYW4+Jyk7XG4gICAgICAgICAgdmFyICRjbG9zZSA9ICQkKCc8c3BhbiBjbGFzcz1cImNsb3NlIGljb24tY2xvc2VcIj48L3NwYW4+Jyk7XG4gICAgICAgICAgJGNsb3NlLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYuZW1pdCgncmVtb3ZlZmlsdGVyJywga2V5KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAkZmlsdGVyLmFwcGVuZCgkaW5uZXIpO1xuICAgICAgICAgICRmaWx0ZXIuYXBwZW5kKCRjbG9zZSk7XG4gICAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5maWx0ZXJib3ggJiYgc2VsZi5vcHRpb25zLmZpbHRlcmJveC5yZWYpXG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuZmlsdGVyYm94LnJlZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmZpbHRlcmJveCcpLmFwcGVuZCgkZmlsdGVyKTtcbiAgICAgICAgICBzZWxmLmVtaXQoJ2ZpbHRlcmNoYW5nZScpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBzZWxmLm9uKCdyZW1vdmVmaWx0ZXInLCBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGYub3B0aW9ucy5maWx0ZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMuZmlsdGVyc1tpXS5rZXkgPT09IGtleSkge1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5maWx0ZXJzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmZpbHRlcmJveCAmJiBzZWxmLm9wdGlvbnMuZmlsdGVyYm94LnJlZilcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5maWx0ZXJib3gucmVmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCdbZGF0YS1pZD1cIicgKyBrZXkgKyAnXCJdJykucmVtb3ZlKCk7XG4gICAgICAgICAgaSA9IHNlbGYub3B0aW9ucy5maWx0ZXJzLmxlbmd0aDtcbiAgICAgICAgICBzZWxmLmVtaXQoJ2ZpbHRlcmNoYW5nZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmFkZFZpc3VhbGl6YXRpb24gPSBmdW5jdGlvbiAodml6KSB7XG4gICAgaWYgKCF0aGlzLm9wdGlvbnMudmlzdWFsaXphdGlvbnMpXG4gICAgICB0aGlzLm9wdGlvbnMudmlzdWFsaXphdGlvbnMgPSB7fTtcbiAgICB0aGlzLm9wdGlvbnMudmlzdWFsaXphdGlvbnNbdml6LnV1aWRdID0gdml6O1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcblxuICBzZWxmLmRyYXcobnVsbCwgZnVuY3Rpb24gKGVyciwgcmVmKSB7XG4gICAgaWYgKGVycilcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICAgIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgICB9XG5cbiAgICAvL3dyYXAgdXBcbiAgICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlZik7XG4gIH0pO1xuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uQ2FudmFzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5DYW52YXMob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgY2FudmFzKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGluaXRpYWxpemUgY2FudmFzLicsIGVycik7XG4gICAgICAgICAgLy9jYW52YXMuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgICAgaWYgKGNhbGxiYWNrKVxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGNhbnZhcyk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pO1xuXG51dGlsLmluaGVyaXRzKENhbnZhcywgZXZlbnRzLkV2ZW50RW1pdHRlcik7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIERhdGVQaWNrZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG5cbiAgcmVxdWlyZSgnanF1ZXJ5LXVpL2RhdGVwaWNrZXInKTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ2RhdGVwaWNrZXIuaW5pdC5zdGFydCcpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLmFkZERheXMgPSBmdW5jdGlvbiAobywgZGF5cykge1xuLy8ga2VlcCBpbiBtaW5kLCBtb250aHMgaW4gamF2YXNjcmlwdCBhcmUgMC0xMVxuICAgIHJldHVybiBuZXcgRGF0ZShvLmdldEZ1bGxZZWFyKCksIG8uZ2V0TW9udGgoKSwgby5nZXREYXRlKCkgKyBkYXlzKTtcbiAgfTtcblxuICB0aGlzLmZpeERhdGUgPSBmdW5jdGlvbiAodGltZXN0YW1wLCB6ZXJvKSB7XG4gICAgdmFyIG9mZnNldCA9IC0xICogKHRpbWVzdGFtcC5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjApO1xuXG4gICAgLy8gTXVsdGlwbHkgYnkgMTAwMCBiZWNhdXNlIEpTIHdvcmtzIGluIG1pbGxpc2Vjb25kcyBpbnN0ZWFkIG9mIHRoZSBVTklYIHNlY29uZHNcbiAgICB2YXIgZGF0ZSA9IHRpbWVzdGFtcDsvLyBuZXcgRGF0ZSh0aW1lc3RhbXAgKiAxMDAwKTtcblxuICAgIHZhciB5ZWFyID0gZGF0ZS5nZXRVVENGdWxsWWVhcigpO1xuICAgIHZhciBtb250aCA9IGRhdGUuZ2V0VVRDTW9udGgoKSArIDE7IC8vIGdldE1vbnRoKCkgaXMgemVyby1pbmRleGVkLCBzbyB3ZSdsbCBpbmNyZW1lbnQgdG8gZ2V0IHRoZSBjb3JyZWN0IG1vbnRoIG51bWJlclxuICAgIHZhciBkYXkgPSBkYXRlLmdldFVUQ0RhdGUoKTtcbiAgICB2YXIgaG91cnMgPSBkYXRlLmdldFVUQ0hvdXJzKCk7XG4gICAgdmFyIG1pbnV0ZXMgPSBkYXRlLmdldFVUQ01pbnV0ZXMoKTtcbiAgICB2YXIgc2Vjb25kcyA9IGRhdGUuZ2V0VVRDU2Vjb25kcygpO1xuXG4gICAgdmFyIGJBZGREYXkgPSBmYWxzZTtcbiAgICBob3VycyA9IGhvdXJzICsgb2Zmc2V0OyAvL2dtdFxuXG4gICAgdmFyIGZpeGVkRGF0ZSA9IG51bGw7XG4gICAgaWYgKCF6ZXJvKVxuICAgICAgZml4ZWREYXRlID0gbmV3IERhdGUoeWVhciArICctJyArIG1vbnRoICsgJy0nICsgZGF5ICsgJyAnICsgaG91cnMgKyAnOicgKyBtaW51dGVzICsgJyBHTVQnKTtcbiAgICBlbHNlXG4gICAgICBmaXhlZERhdGUgPSBuZXcgRGF0ZSh5ZWFyICsgJy0nICsgbW9udGggKyAnLScgKyBkYXkgKyAnICcgKyAnMDAnICsgJzonICsgJzAwJyArICcgR01UJyk7XG4gICAgaWYgKGZpeGVkRGF0ZSA9PSAnSW52YWxpZCBEYXRlJykge1xuICAgICAgaWYgKCF6ZXJvKSB7XG4gICAgICAgIGZpeGVkRGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRGdWxsWWVhcih5ZWFyLCBtb250aCAtIDEsIGRheSk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRIb3VycyhwYXJzZUludChob3VycykpO1xuICAgICAgICBmaXhlZERhdGUuc2V0TWludXRlcyhwYXJzZUludChtaW51dGVzKSk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRTZWNvbmRzKHBhcnNlSW50KHNlY29uZHMpKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBmaXhlZERhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICBmaXhlZERhdGUuc2V0RnVsbFllYXIoeWVhciwgbW9udGggLSAxLCBkYXkpO1xuICAgICAgICBmaXhlZERhdGUuc2V0SG91cnMocGFyc2VJbnQoaG91cnMpKTtcbiAgICAgICAgZml4ZWREYXRlLnNldE1pbnV0ZXMoMCk7XG4gICAgICAgIGZpeGVkRGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgfVxuICAgIH1cblxuXG4gICAgaWYgKGJBZGREYXkpXG4gICAgICBmaXhlZERhdGUuc2V0RGF0ZShmaXhlZERhdGUuZ2V0RGF0ZSgpICsgMSk7XG5cbiAgICB2YXIgZml4ZWREYXRlX3V0YyA9IG5ldyBEYXRlKGZpeGVkRGF0ZS5nZXRVVENGdWxsWWVhcigpLCBmaXhlZERhdGUuZ2V0VVRDTW9udGgoKSwgZml4ZWREYXRlLmdldFVUQ0RhdGUoKSwgZml4ZWREYXRlLmdldFVUQ0hvdXJzKCksIGZpeGVkRGF0ZS5nZXRVVENNaW51dGVzKCksIGZpeGVkRGF0ZS5nZXRVVENTZWNvbmRzKCkpO1xuXG5cbiAgICByZXR1cm4gZml4ZWREYXRlO1xuICB9O1xuXG4gIHRoaXMudHlwZSA9ICdkYXRlcGlja2VyJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNhbnZhczogbnVsbCxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBjb21wYXJlUGVyaW9kOiBmYWxzZSxcbiAgICBkaXNhYmxlQ29tcGFyZTogZmFsc2VcbiAgfTtcblxuICB0aGlzLmN1cnJlbnRNb2RlID0gJ2Jhc2UtZnJvbSc7XG5cbiAgdGhpcy5vcmlnaW5hbF9iYXNlX2Zyb21kYXRlID0gbnVsbDtcbiAgdGhpcy5vcmlnaW5hbF9iYXNlX3RvZGF0ZSA9IG51bGw7XG4gIHRoaXMub3JpZ2luYWxfY29tcGFyZV9mcm9tZGF0ZSA9IG51bGw7XG4gIHRoaXMub3JpZ2luYWxfY29tcGFyZV90b2RhdGUgPSBudWxsO1xuXG4gIGlmIChvcHRpb25zLm1pbmRhdGUpXG4gICAgdGhpcy5taW5fZGF0ZSA9IG9wdGlvbnMubWluX2RhdGU7XG4gIC8vdGhpcy5taW5fZGF0ZSA9IG5ldyBEYXRlKCk7Ly9uZXcgam9vbGEub2JqZWN0cy5RdWVyeSgpLlN5c3RlbVN0YXJ0RGF0ZSgpO1xuICAvL3RoaXMubWluX2RhdGUuc2V0TW9udGgodGhpcy5taW5fZGF0ZS5nZXRNb250aCgpIC0gNik7XG4gIGlmIChvcHRpb25zLm1heGRhdGUpXG4gICAgdGhpcy5tYXhfZGF0ZSA9IG9wdGlvbnMubWF4ZGF0ZTtcbiAgZWxzZVxuICAgIHRoaXMubWF4X2RhdGUgPSBuZXcgRGF0ZSgpOy8vbmV3IGpvb2xhLm9iamVjdHMuUXVlcnkoKS5TeXN0ZW1FbmREYXRlKCk7XG4gIHRoaXMubWF4X2RhdGUuc2V0SG91cnMoMjMpO1xuICB0aGlzLm1heF9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICB0aGlzLm1heF9kYXRlLnNldFNlY29uZHMoNTkpO1xuICB0aGlzLm1heF9kYXRlLnNldE1pbGxpc2Vjb25kcyg5OTkpO1xuXG4gIGlmIChvcHRpb25zLnRvZGF0ZSlcbiAgICB0aGlzLmJhc2VfdG9kYXRlID0gbmV3IERhdGUob3B0aW9ucy50b2RhdGUpO1xuICBlbHNlXG4gICAgdGhpcy5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKHRoaXMubWF4X2RhdGUpO1xuICBpZiAob3B0aW9ucy5mcm9tZGF0ZSlcbiAgICB0aGlzLmJhc2VfZnJvbWRhdGUgPSBuZXcgRGF0ZShvcHRpb25zLmZyb21kYXRlKTtcbiAgZWxzZVxuICAgIHRoaXMuYmFzZV9mcm9tZGF0ZSA9IHNlbGYuYWRkRGF5cyh0aGlzLmJhc2VfdG9kYXRlLCAtMzApO1xuXG4gIGlmICh0aGlzLmJhc2VfZnJvbWRhdGUgPCB0aGlzLm1pbl9kYXRlKSB7XG4gICAgdGhpcy5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoKTsvL3RoaXMubWluX2RhdGUuZml4RGF0ZSh0cnVlLCBmYWxzZSk7XG4gICAgdGhpcy5iYXNlX2Zyb21kYXRlLnNldERhdGUodGhpcy5iYXNlX2Zyb21kYXRlLmdldERhdGUoKSAtIDEpO1xuICAgIHRoaXMuZGlzYWJsZUNvbXBhcmUgPSB0cnVlO1xuICB9XG5cbiAgdmFyIHJhbmdlbGVuZ3RoID0gRGF0ZS5kYXRlRGlmZignZCcsIHRoaXMuYmFzZV9mcm9tZGF0ZSwgdGhpcy5iYXNlX3RvZGF0ZSk7XG4gIGlmIChvcHRpb25zLmNvbXBhcmVfdG9kYXRlKVxuICAgIHRoaXMuY29tcGFyZV90b2RhdGUgPSBvcHRpb25zLmNvbXBhcmVfdG9kYXRlO1xuICBlbHNlXG4gICAgdGhpcy5jb21wYXJlX3RvZGF0ZSA9IHNlbGYuYWRkRGF5cyh0aGlzLmJhc2VfZnJvbWRhdGUsIC0xKTtcbiAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gIHRoaXMuY29tcGFyZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gIHRoaXMuY29tcGFyZV90b2RhdGUuc2V0U2Vjb25kcyg1OSk7XG4gIHRoaXMuY29tcGFyZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gIGlmIChvcHRpb25zLmNvbXBhcmVfZnJvbWRhdGUpXG4gICAgdGhpcy5jb21wYXJlX2Zyb21kYXRlID0gb3B0aW9ucy5jb21wYXJlX2Zyb21kYXRlO1xuICBlbHNlXG4gICAgdGhpcy5jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5hZGREYXlzKHRoaXMuY29tcGFyZV90b2RhdGUsICgtMSAqIHJhbmdlbGVuZ3RoKSk7XG5cbiAgdGhpcy5vcmlnaW5hbF9iYXNlX2Zyb21kYXRlID0gdGhpcy5iYXNlX2Zyb21kYXRlO1xuICB0aGlzLm9yaWdpbmFsX2Jhc2VfdG9kYXRlID0gdGhpcy5iYXNlX3RvZGF0ZTtcbiAgdGhpcy5vcmlnaW5hbF9jb21wYXJlX2Zyb21kYXRlID0gdGhpcy5jb21wYXJlX2Zyb21kYXRlO1xuICB0aGlzLm9yaWdpbmFsX2NvbXBhcmVfdG9kYXRlID0gdGhpcy5jb21wYXJlX3RvZGF0ZTtcblxuICB0aGlzLmFwcGxpZWRfYmFzZV9mcm9tZGF0ZSA9IHRoaXMuYmFzZV9mcm9tZGF0ZTtcbiAgdGhpcy5hcHBsaWVkX2Jhc2VfdG9kYXRlID0gdGhpcy5iYXNlX3RvZGF0ZTtcbiAgdGhpcy5hcHBsaWVkX2NvbXBhcmVfZnJvbWRhdGUgPSB0aGlzLmNvbXBhcmVfZnJvbWRhdGU7XG4gIHRoaXMuYXBwbGllZF9jb21wYXJlX3RvZGF0ZSA9IHRoaXMuY29tcGFyZV90b2RhdGU7XG5cbiAgdGhpcy5jb21wYXJlUGVyaW9kID0gb3B0aW9ucy5jb21wYXJlIHx8IGZhbHNlO1xuICB0aGlzLmlzQ29tcGFyZUNoZWNrZWQgPSBvcHRpb25zLmNvbXBhcmUgfHwgZmFsc2U7XG5cbiAgLy9zZWxmLmdldFN0YXRlKHNlbGYpO1xuXG4gIHRoaXMub2Zmc2V0WCA9IDA7XG4gIHRoaXMub2Zmc2V0WSA9IDA7XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICBpZiAoY2FsbGJhY2spXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cblxuICB0aGlzLnRlbXBsYXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBiaW5kS2V5ID0gZnVuY3Rpb24gKGJ0bikge1xuICAgICAgdmFyICRidG4gPSAkJChidG4pO1xuICAgICAgJGJ0bi5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5idG4nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICRidG4uYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gJGJ0bjtcbiAgICB9O1xuXG4gICAgdmFyIGJpbmRQb3BVcCA9IGZ1bmN0aW9uIChidG4pIHtcbiAgICAgIHZhciAkYnRuID0gJCQoYnRuKTtcbiAgICAgICRidG4ub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuYnRuJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkYnRuLmFkZENsYXNzKCdhY3RpdmUgb3BlbicpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gJGJ0bjtcbiAgICB9O1xuXG4gICAgdmFyICRncm91cCA9ICQkKCc8ZGl2IGNsYXNzPVwiamlvIGRhdGVwaWNrZXIgYnRuLWdyb3VwXCI+PC9kaXY+Jyk7XG4gICAgdmFyICRsYXN0X2RheSA9ICQkKCc8ZGl2IGNsYXNzPVwiamlvIGRhdGVwaWNrZXIgb3B0aW9uIGJ0biBidG4tZGVmYXVsdCBsYXN0X2RheVwiPlBhc3QgRGF5PC9kaXY+Jyk7XG4gICAgdmFyICRsYXN0X3dlZWsgPSAkJCgnPGRpdiBjbGFzcz1cImppbyBkYXRlcGlja2VyIG9wdGlvbiBidG4gYnRuLWRlZmF1bHQgbGFzdF93ZWVrXCI+UGFzdCBXZWVrPC9kaXY+Jyk7XG4gICAgdmFyICRsYXN0X21vbnRoID0gJCQoJzxkaXYgY2xhc3M9XCJqaW8gZGF0ZXBpY2tlciBvcHRpb24gYnRuIGJ0bi1kZWZhdWx0IGxhc3RfbW9udGhcIj5QYXN0IE1vbnRoPC9kaXY+Jyk7XG4gICAgdmFyICRjdXN0b20gPSAkJCgnPGRpdiBjbGFzcz1cImppbyBkYXRlcGlja2VyIG9wdGlvbiBidG4gYnRuLWRlZmF1bHQgY3VzdG9tXCI+Q3VzdG9tPC9kaXY+Jyk7XG5cbiAgICAkZ3JvdXAuYXBwZW5kKGJpbmRLZXkoJGxhc3RfZGF5KSk7XG4gICAgJGdyb3VwLmFwcGVuZChiaW5kS2V5KCRsYXN0X3dlZWspKTtcbiAgICAkZ3JvdXAuYXBwZW5kKGJpbmRLZXkoJGxhc3RfbW9udGgpKTtcbiAgICAkZ3JvdXAuYXBwZW5kKGJpbmRQb3BVcCgkY3VzdG9tKSk7XG5cbiAgICByZXR1cm4gJGdyb3VwO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIGlmIChzZWxmLm9wdGlvbnMub25EcmF3KVxuICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vbkRyYXddKHNlbGYub3B0aW9ucy5jb250YWluZXIsIHNlbGYpO1xuXG4gICAgdmFyICRjb250YWluZXIgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAkY29udGFpbmVyLmVtcHR5KCk7XG4gICAgLy9zZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hcHBlbmQoc2VsZi50ZW1wbGF0ZSgpKTtcbiAgICB2YXIgJHRhYmxlID0gJCQoJzxkaXYgY2xhc3M9XCJkYXRlYm94IGpjb250YWluZXJcIj48dGFibGUgY2xhc3M9XCJkYXRldGFibGUgdW5zZWxlY3RhYmxlXCI+JyArXG4gICAgICAnPHRyPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImRhdGVzXCI+PC90ZD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJkcm9wZG93bm1hcmtlci13cmFwcGVyXCI+PGRpdiBjbGFzcz1cImRyb3Bkb3dubWFya2VyXCI+PC9kaXY+PC90ZD4nICtcbiAgICAgICc8L3RyPicgK1xuICAgICAgJzwvdGFibGU+PC9kaXY+PC9kaXY+Jyk7XG5cbiAgICAkY29udGFpbmVyLmFwcGVuZCgkdGFibGUpO1xuXG4gICAgdmFyICRkYXRlcyA9ICR0YWJsZS5maW5kKCcuZGF0ZXMnKTtcbiAgICAkZGF0ZXMuYXBwZW5kKCc8c3BhbiBjbGFzcz1cImRhdGVsYWJlbCBmcm9tZGF0ZVwiPicgKyBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpICsgJzwvc3Bhbj4nKTtcbiAgICAkZGF0ZXMuYXBwZW5kKCcgLSAnKTtcbiAgICAkZGF0ZXMuYXBwZW5kKCc8c3BhbiBjbGFzcz1cImRhdGVsYWJlbCB0b2RhdGVcIj4nICsgam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX3RvZGF0ZSkgKyAnPC9zcGFuPicpO1xuICAgICRkYXRlcy5hcHBlbmQoJzxkaXYgY2xhc3M9XCJjb21wYXJlXCIgc3R5bGU9XCJkaXNwbGF5Om5vbmVcIj5Db21wYXJlIHRvOiA8c3BhbiBjbGFzcz1cImRhdGVsYWJlbCBjb21wYXJlIGZyb21kYXRlXCI+JyArIGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkgKyAnPC9zcGFuPiAtIDxzcGFuIGNsYXNzPVwiZGF0ZWxhYmVsIGNvbXBhcmUgdG9kYXRlXCI+JyArIGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpICsgJzwvc3Bhbj48L2Rpdj4nKTtcblxuICAgIGlmIChzZWxmLmNvbXBhcmVQZXJpb2QpIHtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmRhdGVzIC5jb21wYXJlJykuc2hvdygpO1xuICAgICAgJGNvbnRhaW5lci5hZGRDbGFzcygnY29tcGFyZScpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICRjb250YWluZXIucmVtb3ZlQ2xhc3MoJ2NvbXBhcmUnKTtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmRhdGVzIC5jb21wYXJlJykuaGlkZSgpO1xuICAgIH1cbiAgICB2YXIgJGl0ZW0gPSAkJCgnPGRpdiBjbGFzcz1cInBpY2tlclwiIHN0eWxlPVwiZGlzcGxheTpub25lXCI+PC9kaXY+Jyk7XG5cbiAgICAkaXRlbS5hcHBlbmQoJzx0YWJsZSBjbGFzcz1cIndyYXBwZXJcIj48dHIgdmFsaWduPXRvcD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJjYWxlbmRhcnNcIj48L3RkPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImNvbnRyb2xcIj48ZGl2IGNsYXNzPVwib3B0aW9uc2NvbnRhaW5lclwiPjwvZGl2PjwvdGQ+JyArXG4gICAgICAnPC90cj48L3RhYmxlPicpO1xuXG4gICAgJGNvbnRhaW5lci5hcHBlbmQoJGl0ZW0pO1xuICAgIHZhciAkb3B0aW9uc2NvbnRhaW5lciA9ICRjb250YWluZXIuZmluZCgnLm9wdGlvbnNjb250YWluZXInKTtcbiAgICAkb3B0aW9uc2NvbnRhaW5lci5hcHBlbmQoJzxkaXYgY2xhc3M9XCJjdXN0b21kYXRlXCI+RGF0ZSBSYW5nZTonICtcbiAgICAgICc8c2VsZWN0IGNsYXNzPVwic2VsZWN0b3JcIj48b3B0aW9uIHZhbHVlPVwiY3VzdG9tXCI+Q3VzdG9tPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cInRvZGF5XCI+VG9kYXk8L29wdGlvbj48b3B0aW9uIHZhbHVlPVwieWVzdGVyZGF5XCI+WWVzdGVyZGF5PC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cImxhc3R3ZWVrXCI+TGFzdCB3ZWVrPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT1cImxhc3Rtb250aFwiPkxhc3QgTW9udGg8L29wdGlvbj48L3NlbGVjdD4nICtcbiAgICAgICc8L2Rpdj4nKTtcbiAgICAkb3B0aW9uc2NvbnRhaW5lci5hcHBlbmQoJzxociBjbGFzcz1cImRpdmlkZXJcIiBzdHlsZT1cIm1hcmdpbi1ib3R0b206IDVweDtcIj4nKTtcblxuICAgICRvcHRpb25zY29udGFpbmVyLmFwcGVuZCgnPGRpdiBjbGFzcz1cImRhdGVyYW5nZSBiYXNlcmFuZ2VcIlwiPicgK1xuICAgICAgJzxpbnB1dCBjbGFzcz1cImRhdGVvcHRpb24gYWN0aXZlXCIgdHlwZT1cInRleHRcIiB2YWx1ZT1cIkphbiAxLCAyMDEyXCI+JyArXG4gICAgICAnIC0gJyArXG4gICAgICAnPGlucHV0IGNsYXNzPVwiZGF0ZW9wdGlvblwiIHR5cGU9XCJ0ZXh0XCIgdmFsdWU9XCJKYW4gMSwgMjAxMlwiPicgK1xuICAgICAgJzwvZGl2PicpO1xuXG4gICAgJG9wdGlvbnNjb250YWluZXIuYXBwZW5kKCc8ZGl2IGNsYXNzPVwiY29tcGFyZW9wdGlvbiB2aXNpYmxlXCJcIj4nICtcbiAgICAgICc8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJjaGVja2VyXCIvPjxzcGFuIHN0eWxlPVwicGFkZGluZy1sZWZ0OjVweDtcIj5Db21wYXJlIHRvIHBhc3Q8L3NwYW4+JyArXG4gICAgICAnPC9kaXY+Jyk7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5kaXNhYmxlQ29tcGFyZSkge1xuICAgICAgJG9wdGlvbnNjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24nKS5yZW1vdmVDbGFzcygndmlzaWJsZScpO1xuICAgIH1cbiAgICAkb3B0aW9uc2NvbnRhaW5lci5hcHBlbmQoJzxkaXYgY2xhc3M9XCJkYXRlcmFuZ2UgY29tcGFyZXJhbmdlXCJcIj4nICtcbiAgICAgICc8aW5wdXQgY2xhc3M9XCJkYXRlb3B0aW9uIGFjdGl2ZVwiIHR5cGU9XCJ0ZXh0XCIgdmFsdWU9XCJKYW4gMSwgMjAxMlwiPicgK1xuICAgICAgJyAtICcgK1xuICAgICAgJzxpbnB1dCBjbGFzcz1cImRhdGVvcHRpb25cIiB0eXBlPVwidGV4dFwiIHZhbHVlPVwiSmFuIDEsIDIwMTJcIj4nICtcbiAgICAgICc8L2Rpdj4nKTtcblxuICAgICRvcHRpb25zY29udGFpbmVyLmFwcGVuZCgnJyArXG4gICAgICAnPGhyIGNsYXNzPVwiZGl2aWRlclwiPicgK1xuICAgICAgJzxkaXYgY2xhc3M9XCJfYnV0dG9uc1wiPjxidXR0b24gY2xhc3M9XCJidG4gYXBwbHlcIiB2YWx1ZT1cIkFwcGx5XCI+QXBwbHk8L2J1dHRvbj4nICtcbiAgICAgICc8c3BhbiBjbGFzcz1cImNhbmNlbFwiPkNhbmNlbDwvc3Bhbj48L2Rpdj4nKTtcblxuICAgIHZhciAkY2FsZW5kYXJzID0gJGNvbnRhaW5lci5maW5kKCcuY2FsZW5kYXJzJyk7XG4gICAgLy8kaXRlbSA9ICQkKCc8ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlclwiPjwvZGl2PicpO1xuXG4gICAgJGl0ZW0gPSAkJCgnPHRhYmxlPjx0ciB2YWxpZ249dG9wPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImRhdGV0YWJsZS1wcmV2IHVuc2VsZWN0YWJsZVwiPjwvdGQ+JyArXG4gICAgICAnPHRkIGNsYXNzPVwiZGF0ZXRhYmxlXCI+PGRpdiBjbGFzcz1cImRhdGVwaWNrZXIgZHAxXCI+PC9kaXY+PC90ZD4nICtcbiAgICAgICc8dGQgY2xhc3M9XCJkYXRldGFibGVcIj48ZGl2IGNsYXNzPVwiZGF0ZXBpY2tlciBkcDJcIj48L2Rpdj48L3RkPicgK1xuICAgICAgJzx0ZCBjbGFzcz1cImRhdGV0YWJsZVwiPjxkaXYgY2xhc3M9XCJkYXRlcGlja2VyIGRwM1wiPjwvZGl2PjwvdGQ+JyArXG4gICAgICAnPHRkIGNsYXNzPVwiZGF0ZXRhYmxlLW5leHQgdW5zZWxlY3RhYmxlXCI+PC90ZD4nICtcbiAgICAgICc8L3RyPjwvdGFibGU+Jyk7XG4gICAgJGNhbGVuZGFycy5hcHBlbmQoJGl0ZW0pO1xuXG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLXByZXYnKS5hcHBlbmQoJzxkaXYgY2xhc3M9XCJwcmV2XCI+JyArXG4gICAgICAnPGRpdiBjbGFzcz1cImlubGluZS1ibG9jayBwcmV2XCI+JyArXG4gICAgICAnPC9kaXY+JyArXG4gICAgICAnPC9kaXY+Jyk7XG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLXByZXYgLnByZXYnKS5vZmYoJ2NsaWNrJyk7XG4gICAgJGNvbnRhaW5lci5maW5kKCcuZGF0ZXRhYmxlLXByZXYgLnByZXYnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgdmFyIGN1cnJlbnRMZWZ0Q2VsbERhdGUgPSAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJylbMF0pLmRhdGVwaWNrZXIoJ2dldERhdGUnKTtcbiAgICAgIGlmIChjdXJyZW50TGVmdENlbGxEYXRlLnNldE1vbnRoKGN1cnJlbnRMZWZ0Q2VsbERhdGUuZ2V0TW9udGgoKSkgPCBzZWxmLm1pbl9kYXRlKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIHZhciBjdXJyZW50UmlnaHRDZWxsRGF0ZSA9ICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVwaWNrZXInKVsyXSkuZGF0ZXBpY2tlcignZ2V0RGF0ZScpO1xuICAgICAgY3VycmVudFJpZ2h0Q2VsbERhdGUgPSBuZXcgRGF0ZShjdXJyZW50UmlnaHRDZWxsRGF0ZSk7XG4gICAgICBjdXJyZW50UmlnaHRDZWxsRGF0ZS5zZXRNb250aChjdXJyZW50UmlnaHRDZWxsRGF0ZS5nZXRNb250aCgpIC0gMSk7XG4gICAgICB2YXIgc2VsZWN0ZWREYXRlID0gbmV3IERhdGUoY3VycmVudFJpZ2h0Q2VsbERhdGUpO1xuXG5cbiAgICAgICRjb250YWluZXIuZmluZCgnLmRhdGVwaWNrZXInKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xuICAgICAgICB2YXIgbG9jYWxkYXRlID0gbmV3IERhdGUoc2VsZWN0ZWREYXRlKTtcblxuICAgICAgICBsb2NhbGRhdGUuc2V0TW9udGgobG9jYWxkYXRlLmdldE1vbnRoKCkgLSAoMiAtIGluZGV4KSk7XG4gICAgICAgICQkKGl0ZW0pLmRhdGVwaWNrZXIoJ3NldERhdGUnLCBsb2NhbGRhdGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRldGFibGUtbmV4dCcpLmFwcGVuZCgnPGRpdiBjbGFzcz1cIm5leHRcIj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwiaW5saW5lLWJsb2NrIG5leHRcIj4nICtcbiAgICAgICc8L2Rpdj4nICtcbiAgICAgICc8L2Rpdj4nKTtcbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRldGFibGUtbmV4dCAubmV4dCcpLm9mZignY2xpY2snKTtcbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRldGFibGUtbmV4dCAubmV4dCcpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICB2YXIgY3VycmVudFJpZ2h0Q2VsbERhdGUgPSAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJylbMl0pLmRhdGVwaWNrZXIoJ2dldERhdGUnKTtcbiAgICAgIGlmIChjdXJyZW50UmlnaHRDZWxsRGF0ZS5zZXRNb250aChjdXJyZW50UmlnaHRDZWxsRGF0ZS5nZXRNb250aCgpICsgMSkgPiBzZWxmLm1heF9kYXRlKVxuICAgICAgICByZXR1cm47XG5cbiAgICAgIGN1cnJlbnRSaWdodENlbGxEYXRlID0gbmV3IERhdGUoY3VycmVudFJpZ2h0Q2VsbERhdGUpO1xuXG4gICAgICB2YXIgc2VsZWN0ZWREYXRlID0gbmV3IERhdGUoY3VycmVudFJpZ2h0Q2VsbERhdGUpO1xuXG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcblxuICAgICAgICB2YXIgbG9jYWxkYXRlID0gbmV3IERhdGUoc2VsZWN0ZWREYXRlKTtcbiAgICAgICAgbG9jYWxkYXRlLnNldE1vbnRoKGxvY2FsZGF0ZS5nZXRNb250aCgpIC0gKDIgLSBpbmRleCkpO1xuICAgICAgICAkJChpdGVtKS5kYXRlcGlja2VyKCdzZXREYXRlJywgbG9jYWxkYXRlKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdmFyIGN1cnJlbnRDbGlja0luZGV4ID0gMDtcbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykuZGF0ZXBpY2tlcih7XG4gICAgICBkYXlOYW1lc01pbjogW1wiU1wiLCBcIk1cIiwgXCJUXCIsIFwiV1wiLCBcIlRcIiwgXCJGXCIsIFwiU1wiXSxcbiAgICAgIGZpcnN0RGF5OiAwLFxuICAgICAgYmVmb3JlU2hvd0RheTogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZHJhd0NlbGwoZGF0ZSk7XG4gICAgICB9LFxuICAgICAgb25TZWxlY3Q6IGZ1bmN0aW9uIChkYXRlVGV4dCwgaW5zdCkge1xuICAgICAgICAkb3B0aW9uc2NvbnRhaW5lci5maW5kKCcuc2VsZWN0b3InKS52YWwoJ2N1c3RvbScpO1xuICAgICAgICBzd2l0Y2ggKHNlbGYuY3VycmVudE1vZGUpIHtcbiAgICAgICAgICBjYXNlICdiYXNlLWZyb20nOlxuXG4gICAgICAgICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2Jhc2UtdG8nO1xuICAgICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldE1pbnV0ZXMoMCk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG5cbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZShkYXRlVGV4dCk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcblxuICAgICAgICAgICAgdmFyIF9jaGVja0xpbWl0ID0gbmV3IERhdGUoc2VsZi5taW5fZGF0ZSk7XG4gICAgICAgICAgICBfY2hlY2tMaW1pdC5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbiAgICAgICAgICAgIF9jaGVja0xpbWl0LnNldERhdGUoX2NoZWNrTGltaXQuZ2V0RGF0ZSgpICsgMSk7XG5cbiAgICAgICAgICAgIGlmIChzZWxmLmJhc2VfZnJvbWRhdGUuZ2V0VGltZSgpIDw9IF9jaGVja0xpbWl0LmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uIC5jaGVja2VyJykuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBpZiAoJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLmlzKCc6ZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgICRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5yZW1vdmVBdHRyKCdkaXNhYmxlZCcpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICAgICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdiYXNlLXRvJzpcbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBuZXcgRGF0ZShkYXRlVGV4dCk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgICAgIGlmIChzZWxmLmlzQ29tcGFyZUNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdjb21wYXJlLWZyb20nO1xuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcblxuICAgICAgICAgICAgICBzZWxmLmN1cnJlbnRNb2RlID0gJ2Jhc2UtZnJvbSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdjb21wYXJlLWZyb20nOlxuICAgICAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gbmV3IERhdGUoZGF0ZVRleHQpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlLnNldE1pbnV0ZXMoMCk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUuc2V0U2Vjb25kcygwKTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG5cbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBuZXcgRGF0ZShkYXRlVGV4dCk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAgICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuXG4gICAgICAgICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS10byc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdjb21wYXJlLXRvJzpcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBuZXcgRGF0ZShkYXRlVGV4dCk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUuc2V0TWludXRlcyg1OSk7XG4gICAgICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcbiAgICAgICAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2ludmFsaWQnKTtcbiAgICAgICAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS1mcm9tJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG5cbiAgICAkY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykuZmluZCgnYVtocmVmPVwiI1wiXScpLmVhY2goZnVuY3Rpb24gKGluZGV4LCBpdGVtKSB7XG4gICAgICAkJCh0aGlzKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICRjb250YWluZXIuZmluZCgnLmRhdGVwaWNrZXInKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgaXRlbSkge1xuICAgICAgdmFyIHNlbGVjdGVkRGF0ZSA9IG5ldyBEYXRlKHNlbGYuYmFzZV90b2RhdGUuZ2V0RnVsbFllYXIoKSwgc2VsZi5iYXNlX3RvZGF0ZS5nZXRNb250aCgpLCAxKTtcbiAgICAgIHNlbGVjdGVkRGF0ZS5zZXRNb250aChzZWxlY3RlZERhdGUuZ2V0TW9udGgoKSAtICgyIC0gaW5kZXgpKTtcbiAgICAgICQkKGl0ZW0pLmRhdGVwaWNrZXIoJ3NldERhdGUnLCBzZWxlY3RlZERhdGUpO1xuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5mb2N1cyhmdW5jdGlvbiAoZSkge1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLWZyb20nO1xuICAgICAgc2VsZi5oYW5kbGVDaGFuZ2UoKTtcbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkuYmx1cihmdW5jdGlvbiAoZSkge1xuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSk7XG4gICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnYmFzZS1mcm9tJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmtleXVwKGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAobmV3IERhdGUoJCQodGhpcykudmFsKCkpID09ICdJbnZhbGlkIERhdGUnIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYuYmFzZV90b2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpID4gc2VsZi5tYXhfZGF0ZSB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICQkKHRoaXMpLmFkZENsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICQkKHRoaXMpLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoJCQodGhpcykudmFsKCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5mb2N1cyhmdW5jdGlvbiAoZSkge1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLXRvJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLmJsdXIoZnVuY3Rpb24gKGUpIHtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAgICQkKHRoaXMpLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLXRvJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5rZXl1cChmdW5jdGlvbiAoZSkge1xuICAgICAgaWYgKG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA9PSAnSW52YWxpZCBEYXRlJyB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPCBzZWxmLmJhc2VfZnJvbWRhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpID4gc2VsZi5tYXhfZGF0ZSB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICQkKHRoaXMpLmFkZENsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICQkKHRoaXMpLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKTtcbiAgICAgIH1cblxuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5mb2N1cyhmdW5jdGlvbiAoZSkge1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdjb21wYXJlLWZyb20nO1xuICAgICAgc2VsZi5oYW5kbGVDaGFuZ2UoKTtcbiAgICB9KTtcblxuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkuYmx1cihmdW5jdGlvbiAoZSkge1xuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS1mcm9tJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmtleXVwKGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAobmV3IERhdGUoJCQodGhpcykudmFsKCkpID09ICdJbnZhbGlkIERhdGUnIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYuY29tcGFyZV90b2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpID4gc2VsZi5tYXhfZGF0ZSB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgICQkKHRoaXMpLmFkZENsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICQkKHRoaXMpLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnJlbW92ZUNsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5wcm9wKCdkaXNhYmxlZCcsIGZhbHNlKTtcbiAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gbmV3IERhdGUoJCQodGhpcykudmFsKCkpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5mb2N1cyhmdW5jdGlvbiAoZSkge1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdjb21wYXJlLXRvJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLmJsdXIoZnVuY3Rpb24gKGUpIHtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcbiAgICAgICQkKHRoaXMpLnJlbW92ZUNsYXNzKCdpbnZhbGlkJyk7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICRjb250YWluZXIuZmluZCgnLmJ0bi5hcHBseScpLnByb3AoJ2Rpc2FibGVkJywgZmFsc2UpO1xuICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdjb21wYXJlLXRvJztcbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLmtleXVwKGZ1bmN0aW9uIChlKSB7XG4gICAgICBpZiAobmV3IERhdGUoJCQodGhpcykudmFsKCkpID09ICdJbnZhbGlkIERhdGUnIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA8IHNlbGYuY29tcGFyZV9mcm9tZGF0ZSB8fCBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSkgPiBzZWxmLmJhc2VfdG9kYXRlIHx8IG5ldyBEYXRlKCQkKHRoaXMpLnZhbCgpKSA+IHNlbGYubWF4X2RhdGUgfHwgbmV3IERhdGUoJCQodGhpcykudmFsKCkpIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICAkJCh0aGlzKS5hZGRDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnaW52YWxpZCcpO1xuICAgICAgICAkY29udGFpbmVyLmZpbmQoJy5idG4uYXBwbHknKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuYnRuLmFwcGx5JykucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBuZXcgRGF0ZSgkJCh0aGlzKS52YWwoKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgJG9wdGlvbnNjb250YWluZXIuZmluZCgnLmNhbmNlbCcpLmNsaWNrKGZ1bmN0aW9uIChlKSB7XG5cbiAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IHNlbGYub3JpZ2luYWxfYmFzZV9mcm9tZGF0ZTtcbiAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBzZWxmLm9yaWdpbmFsX2Jhc2VfdG9kYXRlO1xuXG4gICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLm9yaWdpbmFsX2NvbXBhcmVfZnJvbWRhdGU7XG4gICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gc2VsZi5vcmlnaW5hbF9jb21wYXJlX3RvZGF0ZTtcblxuICAgICAgaWYgKCFzZWxmLmNvbXBhcmVQZXJpb2QpIHtcbiAgICAgICAgaWYgKCRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5pcyhcIjpjaGVja2VkXCIpKSB7XG4gICAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLmNsaWNrKCk7XG4gICAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAoISRjb250YWluZXIuZmluZCgnLmNvbXBhcmVvcHRpb24gLmNoZWNrZXInKS5pcyhcIjpjaGVja2VkXCIpKSB7XG4gICAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLmNsaWNrKCk7XG4gICAgICAgICAgJGNvbnRhaW5lci5maW5kKCcuY29tcGFyZW9wdGlvbiAuY2hlY2tlcicpLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlKSk7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcblxuICAgICAgc2VsZi5oYW5kbGVDaGFuZ2UoKTtcblxuICAgICAgJGRhdGVib3hjb250YWluZXIuY2xpY2soKTtcbiAgICB9KTtcbiAgICAkb3B0aW9uc2NvbnRhaW5lci5maW5kKCcuc2VsZWN0b3InKS5jaGFuZ2UoZnVuY3Rpb24gKGUpIHtcbiAgICAgIHN3aXRjaCAodGhpcy52YWx1ZSkge1xuICAgICAgICBjYXNlICd0b2RheSc6XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoc2VsZi5iYXNlX3RvZGF0ZSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3llc3RlcmRheSc6XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXREYXRlKHNlbGYuYmFzZV90b2RhdGUuZ2V0RGF0ZSgpIC0gMSk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoc2VsZi5iYXNlX3RvZGF0ZSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xhc3R3ZWVrJzpcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gbmV3IERhdGUoKTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0U2Vjb25kcyg1OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUgPSBuZXcgRGF0ZShzZWxmLmJhc2VfdG9kYXRlKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUuZ2V0RGF0ZSgpIC0gNik7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldEhvdXJzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaW51dGVzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZS5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ2xhc3Rtb250aCc6XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgICAgICAgc2VsZi5iYXNlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gbmV3IERhdGUoc2VsZi5iYXNlX3RvZGF0ZSk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldERhdGUoc2VsZi5iYXNlX2Zyb21kYXRlLmdldERhdGUoKSAtIDMwKTtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUuc2V0SG91cnMoMCk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldE1pbnV0ZXMoMCk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHZhciByYW5nZWxlbmd0aCA9IERhdGUuZGF0ZURpZmYoJ2QnLCBzZWxmLmJhc2VfZnJvbWRhdGUsIHNlbGYuYmFzZV90b2RhdGUpO1xuICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZSA9IHNlbGYuYWRkRGF5cyhzZWxmLmJhc2VfZnJvbWRhdGUsIC0xKTtcbiAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYuYWRkRGF5cyhzZWxmLmNvbXBhcmVfdG9kYXRlLCAoLTEgKiByYW5nZWxlbmd0aCkpO1xuXG4gICAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAgJCQoJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuXG4gICAgICBzZWxmLmhhbmRsZUNoYW5nZSgpO1xuICAgIH0pO1xuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICQkKCRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV90b2RhdGUpKTtcbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAkJCgkY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG5cbiAgICB2YXIgJGRhdGVib3hjb250YWluZXIgPSAkY29udGFpbmVyLmZpbmQoJy5qY29udGFpbmVyJyk7XG4gICAgJGRhdGVib3hjb250YWluZXIub2ZmKCdjbGljaycpO1xuICAgIHZhciAkcGlja2VyID0gJGNvbnRhaW5lci5maW5kKCcucGlja2VyJyk7XG4gICAgJGRhdGVib3hjb250YWluZXIub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgIGlmICgkJCh0aGlzKS5oYXNDbGFzcygnZXhwYW5kZWQnKSkge1xuICAgICAgICAkJCh0aGlzKS5yZW1vdmVDbGFzcygnZXhwYW5kZWQnKTtcbiAgICAgICAgJHBpY2tlci5oaWRlKCk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgJCQodGhpcykuYWRkQ2xhc3MoJ2V4cGFuZGVkJyk7XG5cbiAgICAgICAgc2VsZi5iYXNlX2Zyb21kYXRlID0gc2VsZi5hcHBsaWVkX2Jhc2VfZnJvbWRhdGU7XG4gICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBzZWxmLmFwcGxpZWRfYmFzZV90b2RhdGU7XG4gICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYuYXBwbGllZF9jb21wYXJlX2Zyb21kYXRlO1xuICAgICAgICBzZWxmLmNvbXBhcmVfdG9kYXRlID0gc2VsZi5hcHBsaWVkX2NvbXBhcmVfdG9kYXRlO1xuXG4gICAgICAgIHNlbGYub3JpZ2luYWxfYmFzZV9mcm9tZGF0ZSA9IHNlbGYuYXBwbGllZF9iYXNlX2Zyb21kYXRlO1xuICAgICAgICBzZWxmLm9yaWdpbmFsX2Jhc2VfdG9kYXRlID0gc2VsZi5hcHBsaWVkX2Jhc2VfdG9kYXRlO1xuICAgICAgICBzZWxmLm9yaWdpbmFsX2NvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFwcGxpZWRfY29tcGFyZV9mcm9tZGF0ZTtcbiAgICAgICAgc2VsZi5vcmlnaW5hbF9jb21wYXJlX3RvZGF0ZSA9IHNlbGYuYXBwbGllZF9jb21wYXJlX3RvZGF0ZTtcblxuICAgICAgICAkcGlja2VyLnNob3coKTtcbiAgICAgICAgJHBpY2tlci5vZmZzZXQoe1xuICAgICAgICAgIHRvcDogJGNvbnRhaW5lci5vZmZzZXQoKS50b3AgKyAkY29udGFpbmVyLmhlaWdodCgpIC0gMSxcbiAgICAgICAgICBsZWZ0OiAkZGF0ZWJveGNvbnRhaW5lci5vZmZzZXQoKS5sZWZ0IC0gJHBpY2tlci5vdXRlcldpZHRoKCkgKyAkZGF0ZWJveGNvbnRhaW5lci5vdXRlcldpZHRoKClcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgJHRhYmxlLmNsaWNrKGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0pO1xuXG4gICAgJHBpY2tlci5jbGljayhmdW5jdGlvbiAoZSkge1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9KTtcblxuICAgICQkKCdib2R5JykuY2xpY2soZnVuY3Rpb24gKGUpIHtcbiAgICAgICRkYXRlYm94Y29udGFpbmVyLnJlbW92ZUNsYXNzKCdleHBhbmRlZCcpO1xuICAgICAgJHBpY2tlci5oaWRlKCk7XG4gICAgfSk7XG5cbiAgICAkb3B0aW9uc2NvbnRhaW5lci5maW5kKCcuYXBwbHknKS5jbGljayhmdW5jdGlvbiAoZSkge1xuICAgICAgJGRhdGVib3hjb250YWluZXIucmVtb3ZlQ2xhc3MoJ2V4cGFuZGVkJyk7XG4gICAgICAkcGlja2VyLmhpZGUoKTtcbiAgICAgIHNlbGYuY29tcGFyZVBlcmlvZCA9IHNlbGYuaXNDb21wYXJlQ2hlY2tlZDtcblxuICAgICAgLy9pZiAoc2VsZi5vcHRpb25zLmNhbnZhcylcbiAgICAgIC8vICBzZWxmLm9wdGlvbnMuY2FudmFzLmVtaXQoJ2RhdGVjaGFuZ2UnLCBzZWxmKTtcblxuXG4gICAgICBzZWxmLkRhdGVVcGRhdGUoKTtcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmNvbXBhcmVQZXJpb2QpXG4gICAgICB0aGlzLmlzQ29tcGFyZUNoZWNrZWQgPSB0cnVlO1xuXG4gICAgaWYgKHRoaXMuZGlzYWJsZUNvbXBhcmUpXG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5jb21wYXJlb3B0aW9uIC5jaGVja2VyJykuYXR0cignZGlzYWJsZWQnLCAnZGlzYWJsZWQnKTtcblxuICAgIGlmIChzZWxmLm9wdGlvbnMub25BZnRlckRyYXcpXG4gICAgICB3aW5kb3dbc2VsZi5vcHRpb25zLm9uQWZ0ZXJEcmF3XShzZWxmLm9wdGlvbnMuY29udGFpbmVyLCBzZWxmKTtcblxuICAgIC8vdGhpcy5yZWdpc3RlckRhdGVVcGRhdGUodGhpcy51cGRhdGVMYWJlbHMpO1xuICAgIHRoaXMuaGFuZGxlQ2hhbmdlKCk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG5cbiAgfTtcblxuICB0aGlzLkRhdGVVcGRhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF90aGlzID0gdGhpcztcbiAgICB2YXIgb3B0aW9ucyA9IHt9O1xuXG4gICAgdGhpcy5iYXNlX3RvZGF0ZS5zZXRIb3VycygyMyk7XG4gICAgdGhpcy5iYXNlX3RvZGF0ZS5zZXRNaW51dGVzKDU5KTtcbiAgICB0aGlzLmJhc2VfdG9kYXRlLnNldFNlY29uZHMoNTkpO1xuICAgIHRoaXMuYmFzZV90b2RhdGUuc2V0TWlsbGlzZWNvbmRzKDk5OSk7XG5cbiAgICB0aGlzLmNvbXBhcmVfdG9kYXRlLnNldEhvdXJzKDIzKTtcbiAgICB0aGlzLmNvbXBhcmVfdG9kYXRlLnNldE1pbnV0ZXMoNTkpO1xuICAgIHRoaXMuY29tcGFyZV90b2RhdGUuc2V0U2Vjb25kcyg1OSk7XG4gICAgdGhpcy5jb21wYXJlX3RvZGF0ZS5zZXRNaWxsaXNlY29uZHMoOTk5KTtcblxuICAgIF90aGlzLmFwcGxpZWRfYmFzZV9mcm9tZGF0ZSA9IHRoaXMuYmFzZV9mcm9tZGF0ZTtcbiAgICBfdGhpcy5hcHBsaWVkX2Jhc2VfdG9kYXRlID0gdGhpcy5iYXNlX3RvZGF0ZTtcbiAgICBfdGhpcy5hcHBsaWVkX2NvbXBhcmVfZnJvbWRhdGUgPSB0aGlzLmNvbXBhcmVfZnJvbWRhdGU7XG4gICAgX3RoaXMuYXBwbGllZF9jb21wYXJlX3RvZGF0ZSA9IHRoaXMuY29tcGFyZV90b2RhdGU7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIGJhc2VfZnJvbWRhdGU6IHRoaXMuYXBwbGllZF9iYXNlX2Zyb21kYXRlLFxuICAgICAgYmFzZV90b2RhdGU6IHRoaXMuYXBwbGllZF9iYXNlX3RvZGF0ZSxcbiAgICAgIGNvbXBhcmVfZnJvbWRhdGU6IHRoaXMuYXBwbGllZF9jb21wYXJlX2Zyb21kYXRlLFxuICAgICAgY29tcGFyZV90b2RhdGU6IHRoaXMuYXBwbGllZF9jb21wYXJlX3RvZGF0ZSxcbiAgICAgIGNvbXBhcmU6IHRoaXMuY29tcGFyZVBlcmlvZFxuICAgIH07XG5cbiAgICBpZiAoc2VsZi5jb21wYXJlUGVyaW9kKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXMgLmNvbXBhcmUnKS5zaG93KCk7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5hZGRDbGFzcygnY29tcGFyZScpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLnJlbW92ZUNsYXNzKCdjb21wYXJlJyk7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXMgLmNvbXBhcmUnKS5oaWRlKCk7XG4gICAgfVxuXG4gICAgdmFyICRmcm9tZGF0ZSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcyAuZGF0ZWxhYmVsLmZyb21kYXRlJylbMF0pO1xuICAgIHZhciB0b2RhdGUgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXMgLmRhdGVsYWJlbC50b2RhdGUnKVswXSk7XG5cbiAgICAkZnJvbWRhdGUudGV4dChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfdGhpcy5hcHBsaWVkX2Jhc2VfZnJvbWRhdGUpKTtcbiAgICB0b2RhdGUudGV4dChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfdGhpcy5hcHBsaWVkX2Jhc2VfdG9kYXRlKSk7XG5cbiAgICAkJCh0aGlzLmNhbGxiYWNrcykuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGl0ZW0pIHtcbiAgICAgIF90aGlzLmNhbGxiYWNrc1tpbmRleF0uY2FsbGJhY2soX3RoaXMsIG9wdGlvbnMpO1xuICAgIH0pO1xuICAgIC8vX3RoaXMuc2V0U3RhdGUoX3RoaXMpO1xuICAgIGlmIChzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmVtaXQoJ2RhdGVjaGFuZ2UnLCBvcHRpb25zKTtcbiAgICB9XG4gICAgJCQoc2VsZikudHJpZ2dlcihcImRhdGVjaGFuZ2VcIiwgb3B0aW9ucyk7XG4gICAgLy8kJChqb29sYSkudHJpZ2dlcihcImRhdGVjaGFuZ2VcIiwgb3B0aW9ucyk7XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLm9uVXBkYXRlKVxuICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vblVwZGF0ZV0oc2VsZi5jb250YWluZXIsIHNlbGYpO1xuICB9O1xuXG4gIHRoaXMuZHJhd0NlbGwgPSBmdW5jdGlvbiAoZGF0ZSkge1xuICAgIGlmIChkYXRlID49IHRoaXMubWF4X2RhdGUpXG4gICAgICByZXR1cm4gW2ZhbHNlLCAnZGF5Y2VsbCBkaXNhYmxlZCddO1xuXG4gICAgaWYgKGRhdGUgPD0gdGhpcy5taW5fZGF0ZSlcbiAgICAgIHJldHVybiBbZmFsc2UsICdkYXljZWxsIGRpc2FibGVkJ107XG5cbiAgICBpZiAodGhpcy5jdXJyZW50TW9kZSA9PSAnYmFzZS10bycpIHtcbiAgICAgIGlmIChkYXRlIDwgdGhpcy5iYXNlX2Zyb21kYXRlKVxuICAgICAgICByZXR1cm4gW2ZhbHNlLCAnZGF5Y2VsbCBkaXNhYmxlZCddO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmN1cnJlbnRNb2RlID09ICdjb21wYXJlLXRvJykge1xuICAgICAgaWYgKGRhdGUgPCB0aGlzLmNvbXBhcmVfZnJvbWRhdGUpXG4gICAgICAgIHJldHVybiBbZmFsc2UsICdkYXljZWxsIGNvbXBhcmUgZGlzYWJsZWQnXTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0NvbXBhcmVDaGVja2VkKSB7XG4gICAgICBpZiAoZGF0ZSA9PSB0aGlzLmNvbXBhcmVfZnJvbWRhdGUpXG4gICAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgY29tcGFyZSBpbnJhbmdlIHNlbGVjdGVkIGZyb21kYXRlJ107XG4gICAgICBpZiAoZGF0ZSA9PSB0aGlzLmNvbXBhcmVfdG9kYXRlKVxuICAgICAgICByZXR1cm4gW3RydWUsICdkYXljZWxsIGNvbXBhcmUgaW5yYW5nZSBzZWxlY3RlZCB0b2RhdGUnXTtcbiAgICAgIGlmICgoZGF0ZSA+PSB0aGlzLmJhc2VfZnJvbWRhdGUgJiYgZGF0ZSA8PSB0aGlzLmJhc2VfdG9kYXRlKSAmJiAoZGF0ZSA+PSB0aGlzLmNvbXBhcmVfZnJvbWRhdGUgJiYgZGF0ZSA8PSB0aGlzLmNvbXBhcmVfdG9kYXRlKSlcbiAgICAgICAgcmV0dXJuIFt0cnVlLCAnZGF5Y2VsbCBiYXNlbmNvbXBhcmUgaW5yYW5nZSddO1xuICAgICAgaWYgKGRhdGUgPj0gdGhpcy5jb21wYXJlX2Zyb21kYXRlICYmIGRhdGUgPD0gdGhpcy5jb21wYXJlX3RvZGF0ZSlcbiAgICAgICAgcmV0dXJuIFt0cnVlLCAnZGF5Y2VsbCBjb21wYXJlIGlucmFuZ2UnXTtcbiAgICAgIGlmIChkYXRlID4gdGhpcy5iYXNlX3RvZGF0ZSAmJiB0aGlzLmN1cnJlbnRNb2RlICE9ICdiYXNlLXRvJykge1xuICAgICAgICByZXR1cm4gW2ZhbHNlLCAnZGF5Y2VsbCBjb21wYXJlIGRpc2FibGVkJ107XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGRhdGUgPT0gdGhpcy5iYXNlX2Zyb21kYXRlKVxuICAgICAgcmV0dXJuIFt0cnVlLCAnZGF5Y2VsbCBpbnJhbmdlIHNlbGVjdGVkIGZyb21kYXRlJ107XG4gICAgaWYgKGRhdGUgPT0gdGhpcy5iYXNlX3RvZGF0ZSlcbiAgICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwgaW5yYW5nZSBzZWxlY3RlZCB0b2RhdGUnXTtcbiAgICBpZiAoZGF0ZSA+PSB0aGlzLmJhc2VfZnJvbWRhdGUgJiYgZGF0ZSA8PSB0aGlzLmJhc2VfdG9kYXRlKVxuICAgICAgcmV0dXJuIFt0cnVlLCAnZGF5Y2VsbCBpbnJhbmdlJ107XG5cblxuICAgIHN3aXRjaCAodGhpcy5jdXJyZW50TW9kZSkge1xuICAgICAgY2FzZSAnYmFzZS1mcm9tJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdiYXNlLXRvJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjb21wYXJlLWZyb20nOlxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2NvbXBhcmUtdG8nOlxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBbdHJ1ZSwgJ2RheWNlbGwnXTtcbiAgfTtcblxuICB0aGlzLmhhbmRsZUNoYW5nZSA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgdmFyICRkYXRlYm94ID0gc2VsZi5vcHRpb25zLiRjb250YWluZXI7Ly8uZmluZCgnW2ppby10eXBlPVwiZGF0ZXBpY2tlclwiXScpO1xuICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcGlja2VyJykubm90KHRoaXMpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgJCQodGhpcykuZGF0ZXBpY2tlcigncmVmcmVzaCcpO1xuICAgIH0pO1xuXG4gICAgLypcbiAgICAgJCQoJCQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChmb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICAkJCgkJCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGZvcm1hdERhdGUoc2VsZi5iYXNlX3RvZGF0ZSkpO1xuICAgICAkJCgkJCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICQkKCQkKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG4gICAgICovXG5cbiAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuICAgIHN3aXRjaCAodGhpcy5jdXJyZW50TW9kZSkge1xuICAgICAgY2FzZSAnYmFzZS1mcm9tJzpcbiAgICAgICAgaWYgKHNlbGYuYmFzZV9mcm9tZGF0ZSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmJhc2VfZnJvbWRhdGUgPSBzZWxmLm1pbl9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfZnJvbWRhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZi5iYXNlX2Zyb21kYXRlID4gc2VsZi5tYXhfZGF0ZSkge1xuICAgICAgICAgIHNlbGYuYmFzZV9mcm9tZGF0ZSA9IHNlbGYubWF4X2RhdGU7XG4gICAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuYmFzZV9mcm9tZGF0ZSkpO1xuICAgICAgICB9XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Jhc2UtdG8nOlxuICAgICAgICBpZiAoc2VsZi5iYXNlX3RvZGF0ZSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmJhc2VfdG9kYXRlID0gc2VsZi5taW5fZGF0ZTtcbiAgICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5iYXNlX3RvZGF0ZSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxmLmJhc2VfdG9kYXRlID4gc2VsZi5tYXhfZGF0ZSkge1xuICAgICAgICAgIHNlbGYuYmFzZV90b2RhdGUgPSBzZWxmLm1heF9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmJhc2VfdG9kYXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY29tcGFyZS1mcm9tJzpcbiAgICAgICAgaWYgKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLm1pbl9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsZi5jb21wYXJlX2Zyb21kYXRlID4gc2VsZi5tYXhfZGF0ZSkge1xuICAgICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYubWF4X2RhdGU7XG4gICAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVswXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmJhc2VyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY29tcGFyZS10byc6XG4gICAgICAgIGlmIChzZWxmLmNvbXBhcmVfdG9kYXRlIDwgc2VsZi5taW5fZGF0ZSkge1xuICAgICAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBzZWxmLm1pbl9kYXRlO1xuICAgICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGYuY29tcGFyZV90b2RhdGUgPiBzZWxmLm1heF9kYXRlKSB7XG4gICAgICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZSA9IHNlbGYubWF4X2RhdGU7XG4gICAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkudmFsKGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKHNlbGYuY29tcGFyZV90b2RhdGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuYmFzZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5iYXNlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLmFkZENsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIGlmICgoc2VsZi5jb21wYXJlX2Zyb21kYXRlID4gc2VsZi5iYXNlX3RvZGF0ZSB8fCBzZWxmLmNvbXBhcmVfdG9kYXRlID4gc2VsZi5iYXNlX3RvZGF0ZSkgJiYgdGhpcy5pc0NvbXBhcmVDaGVja2VkKSB7XG4gICAgICB2YXIgcmFuZ2VsZW5ndGggPSBEYXRlLmRhdGVEaWZmKCdkJywgc2VsZi5iYXNlX2Zyb21kYXRlLCBzZWxmLmJhc2VfdG9kYXRlKTtcbiAgICAgIHNlbGYuY29tcGFyZV90b2RhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5iYXNlX2Zyb21kYXRlLCAtMSk7XG4gICAgICBzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPSBzZWxmLmFkZERheXMoc2VsZi5jb21wYXJlX3RvZGF0ZSwgKC0xICogcmFuZ2VsZW5ndGgpKTtcbiAgICAgIGlmIChzZWxmLmNvbXBhcmVfZnJvbWRhdGUgPCBzZWxmLm1pbl9kYXRlKSB7XG4gICAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYubWluX2RhdGU7XG4gICAgICB9XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzBdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX2Zyb21kYXRlKSk7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZSAuZGF0ZW9wdGlvbicpWzFdKS52YWwoam9vbGEuY29tbW9uLmZvcm1hdERhdGUoc2VsZi5jb21wYXJlX3RvZGF0ZSkpO1xuXG5cbiAgICAgIGlmICh0aGlzLmN1cnJlbnRNb2RlID09ICdjb21wYXJlLXRvJylcbiAgICAgICAgJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmRhdGVyYW5nZS5jb21wYXJlcmFuZ2UgLmRhdGVvcHRpb24nKVsxXSkuZm9jdXMoKTtcbiAgICAgIGVsc2UgaWYgKHRoaXMuY3VycmVudE1vZGUgPT0gJ2NvbXBhcmUtZnJvbScpXG4gICAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNDb21wYXJlQ2hlY2tlZCkge1xuICAgICAgJGRhdGVib3guZmluZCgnLm9wdGlvbnNjb250YWluZXIgLmNoZWNrZXInKS5wcm9wKFwiY2hlY2tlZFwiLCB0cnVlKTtcbiAgICAgICRkYXRlYm94LmZpbmQoJy5vcHRpb25zY29udGFpbmVyIC5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlJykuc2hvdygpO1xuXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJGRhdGVib3guZmluZCgnLm9wdGlvbnNjb250YWluZXIgLmNoZWNrZXInKS5wcm9wKFwiY2hlY2tlZFwiLCBmYWxzZSk7XG4gICAgICAkZGF0ZWJveC5maW5kKCcub3B0aW9uc2NvbnRhaW5lciAuZGF0ZXJhbmdlLmNvbXBhcmVyYW5nZScpLmhpZGUoKTtcbiAgICB9XG5cbiAgICAkZGF0ZWJveC5maW5kKCcub3B0aW9uc2NvbnRhaW5lciAuY2hlY2tlcicpLm9mZignY2xpY2snKTtcbiAgICAkZGF0ZWJveC5maW5kKCcub3B0aW9uc2NvbnRhaW5lciAuY2hlY2tlcicpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgc2VsZi5pc0NvbXBhcmVDaGVja2VkID0gIXNlbGYuaXNDb21wYXJlQ2hlY2tlZDtcbiAgICAgIGlmIChzZWxmLmlzQ29tcGFyZUNoZWNrZWQpXG4gICAgICAgIHNlbGYuY3VycmVudE1vZGUgPSAnY29tcGFyZS1mcm9tJztcbiAgICAgIGVsc2VcbiAgICAgICAgc2VsZi5jdXJyZW50TW9kZSA9ICdiYXNlLWZyb20nO1xuXG4gICAgICB2YXIgcmFuZ2VsZW5ndGggPSBEYXRlLmRhdGVEaWZmKCdkJywgc2VsZi5iYXNlX2Zyb21kYXRlLCBzZWxmLmJhc2VfdG9kYXRlKTtcblxuICAgICAgc2VsZi5jb21wYXJlX3RvZGF0ZSA9IHNlbGYuYWRkRGF5cyhzZWxmLmJhc2VfZnJvbWRhdGUsIC0xKTtcbiAgICAgIHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA9IHNlbGYuYWRkRGF5cyhzZWxmLmNvbXBhcmVfdG9kYXRlLCAoLTEgKiByYW5nZWxlbmd0aCkpO1xuICAgICAgaWYgKHNlbGYuY29tcGFyZV9mcm9tZGF0ZSA8IHNlbGYubWluX2RhdGUpIHtcbiAgICAgICAgc2VsZi5jb21wYXJlX2Zyb21kYXRlID0gc2VsZi5taW5fZGF0ZTtcbiAgICAgIH1cbiAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMF0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfZnJvbWRhdGUpKTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5kYXRlcmFuZ2UuY29tcGFyZXJhbmdlIC5kYXRlb3B0aW9uJylbMV0pLnZhbChqb29sYS5jb21tb24uZm9ybWF0RGF0ZShzZWxmLmNvbXBhcmVfdG9kYXRlKSk7XG5cbiAgICAgIHNlbGYuaGFuZGxlQ2hhbmdlKCk7XG4gICAgfSk7XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5lbWl0KCdkYXRlY2hhbmdpbmcnLCBzZWxmKTtcbiAgICB9XG4gICAgJCQoc2VsZikudHJpZ2dlcignZGF0ZWNoYW5naW5nJywgc2VsZik7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIC8qdHJ5IHtcbiAgICBqb29sYS5jb21tb24uX2V4dGVuZChzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICAgIGNvbnNvbGUubG9nKHNlbGYub3B0aW9ucyk7XG4gICAgc2VsZi52ZXJpZnkoc2VsZi5vcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYubWFya0NvbnRhaW5lcihzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciwgW1xuICAgICAgICB7J3R5cGUnOiAnZGF0ZXBpY2tlcid9LFxuICAgICAgICB7J3V1aWQnOiBzZWxmLnV1aWR9LFxuICAgICAgICB7Y3NzOiBzZWxmLm9wdGlvbnMuY3NzfVxuICAgICAgXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICAgICAgICBpZiAoIXNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgICAgICB2YXIgZWxlbSA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLnBhcmVudCgpO1xuICAgICAgICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5kcmF3KG9wdGlvbnMsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBqb29sYS5ldmVudHMuZW1pdCgnZGF0ZXBpY2tlci5pbml0LmZpbmlzaCcsIHNlbGYpO1xuICAgICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY2F0Y2ggKGVycikge1xuICAgIGNhbGxiYWNrKGVycik7XG4gICAgcmV0dXJuIHNlbGYub25FcnJvcihlcnIsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8vY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gIHJldHVybiBzZWxmOyovXG4vL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG4gIHNlbGYuZHJhdyhzZWxmLm9wdGlvbnMsZnVuY3Rpb24oKXt9KTtcblxuICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgfVxuXG4vL3dyYXAgdXBcbiAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9PSAndW5kZWZpbmVkJyB8fCB0eXBlb2YgKCQpICE9PSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uRGF0ZVBpY2tlciA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LkRhdGVQaWNrZXIob3B0aW9ucywgZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgLy9iYXJ0YWJsZS5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxudXRpbC5pbmhlcml0cyhEYXRlUGlja2VyLCBldmVudHMuRXZlbnRFbWl0dGVyKTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG5cbnZhclxuICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpLFxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbnZhciBEaW1lbnNpb25QaWNrZXIgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdkaW1lbnNpb25waWNrZXIuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy50eXBlID0gJ2RpbWVuc2lvbnBpY2tlcic7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBjYW52YXM6IG51bGwsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgZGltZW5zaW9uczogW10sXG4gICAgZGlzYWJsZWQ6IFtdLFxuICAgIHNlbGVjdGVkOiBudWxsLFxuICAgIGFsbG93UmVtb3ZlOiB0cnVlLFxuICAgIGFsbG93U2VsZWN0OiB0cnVlLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImppby1kaW1lbnNpb25waWNrZXItd3JhcHBlclwiPlxcbicgK1xuICAgICAgJyAgPGJ1dHRvbiBjbGFzcz1cImJ0biBqaW8tZGltZW5zaW9ucGlja2VyLWJ1dHRvblwiPicgK1xuICAgICAgJyAgIDxzcGFuIGNsYXNzPVwiY2FwdGlvblwiPjwvc3Bhbj4nICtcbiAgICAgICcgICA8c3BhbiBjbGFzcz1cImNsb3NlXCI+w5c8L3NwYW4+JyArXG4gICAgICAnICA8L2J1dHRvbj4nICtcbiAgICAgICcgIDxkaXYgY2xhc3M9XCJwaWNrZXItY29udGFpbmVyXCI+JyArXG4gICAgICAnICAgIDxkaXYgY2xhc3M9XCJzZWFyY2ggaW5wdXQtcHJlcGVuZFwiPjxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwicXVpY2tzZWFyY2hcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiPjxzcGFuIGNsYXNzPVwiYWRkLW9uXCI+PGkgY2xhc3M9XCJzZWFyY2hpY29uIGljb24tc2VhcmNoXCI+PC9pPjwvc3Bhbj48L2Rpdj4nICtcbiAgICAgICcgICAgPGRpdiBjbGFzcz1cImNsZWFyXCI+PC9kaXY+JyArXG4gICAgICAnICA8L2Rpdj4nICtcbiAgICAgICcgIDxkaXYgY2xhc3M9XCJjbGVhclwiPjwvZGl2PicgK1xuICAgICAgJzwvZGl2PidcbiAgfTtcbiAgdGhpcy5kcmF3biA9IGZhbHNlO1xuXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcblxuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIGlmICghc2VsZi5kcmF3bikge1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmFwcGVuZChzZWxmLm9wdGlvbnMudGVtcGxhdGUgfHwgc2VsZi50ZW1wbGF0ZSgpKTtcbiAgICAgIHZhciAkdWwgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcucGlja2VyLWNvbnRhaW5lcicpKTtcbiAgICAgIHZhciAkYnRuID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmppby1kaW1lbnNpb25waWNrZXItYnV0dG9uJykpO1xuICAgICAgdmFyICRjbG9zZSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpKTtcbiAgICAgIGlmICghc2VsZi5vcHRpb25zLmFsbG93UmVtb3ZlKVxuICAgICAgICAkY2xvc2UucmVtb3ZlKCk7XG4gICAgICB2YXIgJHNlYXJjaCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5xdWlja3NlYXJjaCcpKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbilcbiAgICAgICAgJGJ0bi5maW5kKCcuY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24pO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5kaW1lbnNpb25zLmxlbmd0aCA9PT0gMClcbiAgICAgICAgam9vbGEuZGltZW5zaW9ucy5saXN0KGZ1bmN0aW9uIChlcnIsIGxpc3QpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuXG4gICAgICAgICAgdmFyIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgdmFyIG1Ta2lwT25lID0gZmFsc2U7XG4gICAgICAgICAgdmFyIG1sYXN0dGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICAgIHZhciBrZXlzID0gW107XG4gICAgICAgICAgbGlzdCA9IGxpc3QuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpZiAoa2V5cy5pbmRleE9mKGl0ZW0ua2V5KSA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgaWYgKGl0ZW0ua2V5ICE9PSAndGltZXN0YW1wJykge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChpdGVtLmtleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGxpc3QuZm9yRWFjaChmdW5jdGlvbiAoZGltZW5zaW9uKSB7XG4gICAgICAgICAgICB2YXIgY29sbGVjdGlvbiA9IHtrZXk6IGRpbWVuc2lvbi5jb2xsZWN0aW9ufTtcbiAgICAgICAgICAgIHZhciAkbGkgPSAkJCgnPGRpdiBjbGFzcz1cImRpbWVuc2lvbk9wdGlvblwiIGRhdGEtbWVtYmVyPVwiJyArIGRpbWVuc2lvbi5rZXkgKyAnXCI+JyArIGRpbWVuc2lvbi5uYW1lICsgJzwvZGl2PicpO1xuICAgICAgICAgICAgJGxpLm9mZignY2xpY2snKTtcbiAgICAgICAgICAgICRsaS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgICBpZiAoJHRoaXMuaGFzQ2xhc3MoJ2FjdGl2ZScpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgaWYgKCR0aGlzLmhhc0NsYXNzKCdkaXNhYmxlZCcpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICAgICAgICBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQgPSBkaW1lbnNpb247XG4gICAgICAgICAgICAgIC8vdmFyICRjb250ZW50ID0gJzxzcGFuIGNsYXNzPVwibmFtZVwiPicgKyBkaW1lbnNpb24ubmFtZSArICc8L3NwYW4+JztcbiAgICAgICAgICAgICAgLy8kYnRuLmZpbmQoJy5jYXB0aW9uJykuaHRtbCgoc2VsZi5vcHRpb25zLnByZWZpeCB8fCAnJyApICsgJGNvbnRlbnQpO1xuICAgICAgICAgICAgICAkYnRuLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbU9wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuXG4gICAgICAgICAgICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG5cbiAgICAgICAgICAgICAgc2VsZi5lbWl0KCdjaGFuZ2UnLCBkaW1lbnNpb24pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAkdWwuYXBwZW5kKCRsaSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkY2xvc2Uub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5zZWxlY3RlZCA9IG51bGw7XG4gICAgICAgICAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuICAgICAgICAgICAgc2VsZi5lbWl0KCdjaGFuZ2UnLCBudWxsKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRzZWFyY2gua2V5dXAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICB2YXIgdmFsID0gJHRoaXMudmFsKCk7XG4gICAgICAgICAgICBpZiAodmFsLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgICAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXJdJykuaGlkZSgpO1xuICAgICAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyKj1cIicgKyB2YWwgKyAnXCJdJykuc2hvdygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyXScpLnNob3coKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICRidG4ub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQkKHRoaXMpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgaWYgKG1PcGVuICYmIG1sYXN0dGFyZ2V0ID09IHRoaXMuaWQpIHtcbiAgICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAobVNraXBPbmUpIHtcbiAgICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSBudWxsO1xuICAgICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICBtU2tpcE9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICR1bC5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gdGhpcy5pZDtcbiAgICAgICAgICAgICAgbU9wZW4gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG9mZnNldCA9ICRidG4ucG9zaXRpb24oKTtcbiAgICAgICAgICAgICR1bC5jc3MoJ3RvcCcsIG9mZnNldC50b3AgKyAkYnRuLm91dGVySGVpZ2h0KCkgLSAxKTtcbiAgICAgICAgICAgICR1bC5jc3MoJ2xlZnQnLCBvZmZzZXQubGVmdCk7XG4gICAgICAgICAgICAkdWwuZmluZCgndWwuYWN0aXZlJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuXG4gICAgICAgICAgICAkdWwuYXR0cignZGF0YS10YXJnZXQnLCB0aGlzLmlkKTtcblxuICAgICAgICAgICAgLy9zZXQgc2VsZWN0ZWRcbiAgICAgICAgICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkdWwub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgJCQoJ2JvZHknKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkYnRuLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICBtbGFzdHRhcmdldCA9IG51bGw7XG4gICAgICAgICAgICBtT3BlbiA9IGZhbHNlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJGJ0bi5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgICR0aGlzLnRvZ2dsZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICAgIH0pO1xuICAgICAgZWxzZSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcblxuICAgIH1cblxuICAgIHNlbGYubWFya1NlbGVjdGVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgJHVsLmZpbmQoJ2RpdicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuYWxsb3dTZWxlY3QmJnNlbGYub3B0aW9ucy5zZWxlY3RlZCkge1xuICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyPVwiJyArIHNlbGYub3B0aW9ucy5zZWxlY3RlZC5rZXkgKyAnXCJdJykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLWRpbWVuc2lvbnBpY2tlci1idXR0b24nKS5maW5kKCcuY2FwdGlvbicpLmh0bWwoKHNlbGYub3B0aW9ucy5wcmVmaXggfHwgJycgKSArICc8c3BhbiBjbGFzcz1cIm5hbWVcIj4nICsgKHNlbGYub3B0aW9ucy5zZWxlY3RlZC5uYW1lIHx8IHNlbGYub3B0aW9ucy5zZWxlY3RlZC5rZXkgfHwgc2VsZi5vcHRpb25zLnNlbGVjdGVkKSArICc8L3NwYW4+Jyk7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpLnNob3coKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLWRpbWVuc2lvbnBpY2tlci1idXR0b24nKS5maW5kKCcuY2FwdGlvbicpLmh0bWwoJ0Nob29zZSBhIGRpbWVuc2lvbi4uLicgKyAnJyk7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpLmhpZGUoKTtcbiAgICAgIH1cblxuICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcl0nKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGlzYWJsZWQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5kaXNhYmxlZCkpXG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRpc2FibGVkID0gW3NlbGYub3B0aW9ucy5kaXNhYmxlZF07XG5cbiAgICAgICAgc2VsZi5vcHRpb25zLmRpc2FibGVkLmZvckVhY2goZnVuY3Rpb24gKGRpc2FibGUpIHtcbiAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyPVwiJyArIGRpc2FibGUua2V5ICsgJ1wiXScpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcbiAgLy93ZSBjYWxsIHRoZSBjb3JlIGluaXRpYWxpemUgb3B0aW9uXG4gIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIG9wdGlvbnMgfHwge30pO1xuICBzZWxmLmRyYXcoKTtcblxuICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgfVxuXG4gIC8vd3JhcCB1cFxuICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uRGltZW5zaW9uUGlja2VyID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgKG9wdGlvbnMgJiYgb3B0aW9ucy5mb3JjZSkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouRGltZW5zaW9uUGlja2VyKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIGRpbWVuc2lvbnBpY2tlcikge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgZGltZW5zaW9ucGlja2VyLmRyYXcob3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pO1xuXG51dGlsLmluaGVyaXRzKERpbWVuc2lvblBpY2tlciwgZXZlbnRzLkV2ZW50RW1pdHRlcik7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIEZpbHRlckJveCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvL21peGluXG4gIHRoaXMudHlwZSA9ICdmaWx0ZXJib3gnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG4gIHRoaXMuZGF0YSA9IFtdO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cImZpbHRlcmJveFwiPicgK1xuICAgICc8L2Rpdj4nXG4gIH07XG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZW1wdHkoKTtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIC8vd2UgZHJhdyB0aGUgdGVtcGxhdGUgaW50byB0aGUgY29udGFpbmVyXG4gICAgdmFyICRodG1sID0gJCQoc2VsZi5vcHRpb25zLnRlbXBsYXRlKTtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5odG1sKCRodG1sKTtcbiAgICAvL3Zpc3VhbGl6YXRpb24gc3BlY2lmaWMgZHJhd2luZ1xuICB9O1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcbiAgLy93ZSBjYWxsIHRoZSBjb3JlIGluaXRpYWxpemUgb3B0aW9uXG4gIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIG9wdGlvbnMgfHwge30pO1xuXG4gIHNlbGYuZHJhdygpO1xuICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgfVxuXG4gIC8vd3JhcCB1cFxuICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uRmlsdGVyQm94ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LkZpbHRlckJveChvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBmaWx0ZXJib3gpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhciBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4Jyk7XG4gIFxudmFyIEdlbyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ2dlby5pbml0LnN0YXJ0Jyk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9pZCA9ICdfZ2VvJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGxlZ2VuZDogdHJ1ZSxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBxdWVyeTogbnVsbFxuICB9O1xuICB0aGlzLmNoYXJ0RHJhd24gPSBmYWxzZTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci52ZXJpZnkob3B0aW9ucywgY2FsbGJhY2spO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci5mZXRjaCh0aGlzLm9wdGlvbnMucXVlcnksIGZ1bmN0aW9uIChlcnIsIG1lc3NhZ2UpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgICByZXR1cm47XG4gICAgICAgIC8vZWxzZVxuICAgICAgICAvLyAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgICAgdmFyIG9wdGlvbnMgPSB7XG4gICAgICAgIGtlZXBBc3BlY3RSYXRpbzogdHJ1ZSxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiB7XG4gICAgICAgICAgZmlsbDogJ3RyYW5zcGFyZW50J1xuICAgICAgICB9LFxuICAgICAgICBkYXRhbGVzc1JlZ2lvbkNvbG9yOiAnd2hpdGUnXG5cbiAgICAgIH07XG5cbiAgICAgIHZhciBzZXJpZXMgPSBzZWxmLl9zdXBlci5tYWtlR2VvU2VyaWVzKG1lc3NhZ2UuZGltZW5zaW9ucywgbWVzc2FnZS5tZXRyaWNzLCBtZXNzYWdlLmRvY3VtZW50cyk7XG4gICAgICBpZiAoIXNlbGYuZHJhd24pIHtcblxuXG4gICAgICAgIHNlbGYuZHJhd24gPSB0cnVlO1xuICAgICAgICBzZWxmLmNoYXJ0ID0gbmV3IGdvb2dsZS52aXN1YWxpemF0aW9uLkdlb0NoYXJ0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmF0dHIoJ2lkJykpKTtcbiAgICAgICAgc2VsZi5jaGFydC5kcmF3KHNlcmllcywgb3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChzZWxmLm9wdGlvbnMucXVlcnkucmVhbHRpbWUpIHtcbiAgICAgICAgLy93ZSdyZSBkZWFsaW5nIHdpdGggcmVhbHRpbWVcblxuICAgICAgICBzZWxmLmNoYXJ0LmRyYXcoc2VyaWVzLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvL2hlcmUgd2UgZ29cbiAgdHJ5IHtcbiAgICBqb29sYS5jb21tb24ubWl4aW4oc2VsZi5vcHRpb25zLCBvcHRpb25zLCB0cnVlKTtcbiAgICBzZWxmLnZlcmlmeShzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciA9ICQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgICBzZWxmLm1hcmtDb250YWluZXIoc2VsZi5vcHRpb25zLiRjb250YWluZXIsIFtcbiAgICAgICAgeyd0eXBlJzogJ2dlbyd9LFxuICAgICAgICB7J3V1aWQnOiBzZWxmLnV1aWR9XG4gICAgICBdLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG5cbiAgICAgICAgam9vbGEuZXZlbnRzLmVtaXQoJ2dlby5pbml0LmZpbmlzaCcsIHNlbGYpO1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIGNhdGNoIChlcnIpIHtcbiAgICBjYWxsYmFjayhlcnIpO1xuICAgIHJldHVybiBzZWxmLm9uRXJyb3IoZXJyLCBjYWxsYmFjayk7XG4gIH1cblxuICAvL2NhbGxiYWNrKG51bGwsIHNlbGYpO1xuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uR2VvID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkKSB7XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LkdlbyhvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBnZW8pIHtcbiAgICAgICAgICBnZW8uZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBldmVudHMgPSByZXF1aXJlKCdldmVudHMnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpLFxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gICQkID0gcmVxdWlyZSgnanF1ZXJ5JyksXG4gIF8gPSByZXF1aXJlKCd1bmRlcnNjb3JlJyk7XG5cbnZhciBNZXRyaWMgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy50eXBlID0gJ21ldHJpYyc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgdGhpcy5kYXRhID0gW107XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgY2FwdGlvbjogJycsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwiamlvIG1ldHJpY2JveFwiPicgK1xuICAgICc8ZGl2IGNsYXNzPVwidmFsdWVcIj48L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cInN1bW1hcnlcIiBzdHlsZT1cImRpc3BsYXk6bm9uZTtcIj4nICtcbiAgICAnPHNwYW4gY2xhc3M9XCJiYXNlXCI+PC9zcGFuPicgK1xuICAgICc8c3BhbiBjbGFzcz1cInNlcFwiPnZzLjwvc3Bhbj4nICtcbiAgICAnPHNwYW4gY2xhc3M9XCJjb21wYXJlXCI+PC9zcGFuPicgK1xuICAgICc8L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImNhcHRpb25cIj48L2Rpdj4nICtcbiAgICAnPC9kaXY+JyxcbiAgICBxdWVyeTogbnVsbCxcbiAgICBzdHJpbmdzOiB7XG4gICAgICBsb2FkaW5nOiAnLS0tJyxcbiAgICAgIG5vZGF0YTogJy0tLSdcbiAgICB9XG4gIH07XG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICBpZiAoIXNlbGYub3B0aW9ucylcbiAgICAgIHJldHVybiAnRmFpbGVkIHRvIHZlcmlmeSBbb3B0aW9uc10uJztcbiAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5KSB7XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5ID0gW3NlbGYub3B0aW9ucy5xdWVyeV07XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMgJiYgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMubGVuZ3RoID4gMClcbiAgICAgICAgcmV0dXJuICdQbGVhc2UgZG9uXFwndCBzcGVjaWZ5IGEgZGltZW5zaW9uLic7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MgJiYgKHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLmxlbmd0aCA9PT0gMCB8fCBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcy5sZW5ndGggPiAxKSB8fCAhc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MpXG4gICAgICAgIHJldHVybiAnUGxlYXNlIHNwZWNpZnkgYSBzaW5nbGUgbWV0cmljLic7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMuZW50ZXIgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIHZhciBfcXVlcnkgPSBzZWxmLm9wdGlvbnMucXVlcnk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgIF9xdWVyeSA9IF9xdWVyeVswXTtcblxuICAgIHZhciBtZXRyaWNrZXkgPSBfcXVlcnkubWV0cmljc1swXS5rZXkgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG4gICAgdmFyIG1ldHJpYyA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldO1xuICAgIHZhciBtZXRyaWNuYW1lID0gbWV0cmljLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmVudGVyKVxuICAgICAgc2VsZi5vcHRpb25zLmVudGVyLmFwcGx5KHNlbGYsIFtkYXRhLCBhbGxkYXRhXSk7XG5cbiAgICB2YXIgdmFsdWUsICQkc3VtbWFyeSwgdG90YWw7XG4gICAgaWYgKGRhdGEubGVuZ3RoID09PSAxKSB7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmZpbHRlciAmJiBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZmlsdGVyLmxlbmd0aCA+IDApXG4gICAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5zdW1tYXJ5Jykuc2hvdygpO1xuICAgICAgdmFsdWUgPSBkYXRhWzBdLm1ldHJpY3NbbWV0cmlja2V5XTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy52YWx1ZScpLmh0bWwoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh2YWx1ZSwgbWV0cmljKSk7XG4gICAgICAkJHN1bW1hcnkgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuc3VtbWFyeScpKTtcbiAgICAgIHRvdGFsID0gZGF0YVswXS5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICBpZiAobWV0cmljLmFnZ3JlZ2F0aW9uID09PSAnc3VtJylcbiAgICAgICAgJCRzdW1tYXJ5Lmh0bWwoJyUgb2YgdG90YWw6IDEwMCUgKCcgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHRvdGFsLCBtZXRyaWMpICsgJyknKTtcbiAgICAgIGVsc2UgaWYgKG1ldHJpYy5hZ2dyZWdhdGlvbiA9PT0gJ2F2ZycpXG4gICAgICAgICQkc3VtbWFyeS5odG1sKCdPdmVyYWxsIGF2ZzogJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModG90YWwsIG1ldHJpYykgKyAnICgwJSknKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZGF0YS5sZW5ndGggPT09IDIgJiYgZGF0YVsxXS50eXBlID09PSAnb3ZlcmFsbCcpIHtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5zdW1tYXJ5Jykuc2hvdygpO1xuICAgICAgaWYgKCFkYXRhWzBdLm1pc3NpbmcpXG4gICAgICAgIHZhbHVlID0gZGF0YVswXS5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICBlbHNlXG4gICAgICAgIHZhbHVlID0gMDtcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy52YWx1ZScpLmh0bWwoam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh2YWx1ZSwgbWV0cmljKSk7XG4gICAgICAkJHN1bW1hcnkgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuc3VtbWFyeScpKTtcbiAgICAgIGlmIChkYXRhWzFdLnR5cGUgPT09ICdvdmVyYWxsJykge1xuICAgICAgICB0b3RhbCA9IGRhdGFbMV0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgICB2YXIgcGVyY2VudGFnZTtcbiAgICAgICAgaWYgKG1ldHJpYy5hZ2dyZWdhdGlvbiA9PT0gJ3N1bScpIHtcbiAgICAgICAgICBwZXJjZW50YWdlID0gKHZhbHVlIC8gdG90YWwgKiAxMDApLnRvRml4ZWQoKSArICclJztcbiAgICAgICAgICAkJHN1bW1hcnkuaHRtbCgnJSBvZiB0b3RhbDogJyArIHBlcmNlbnRhZ2UgKyAnICgnICsgam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyh0b3RhbCwgbWV0cmljKSArICcpJyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobWV0cmljLmFnZ3JlZ2F0aW9uID09PSAnYXZnJykge1xuICAgICAgICAgIHBlcmNlbnRhZ2UgPSBqb29sYS5jb21tb24ucGVyY2VudGFnZUNoYW5nZSh0b3RhbCwgdmFsdWUpO1xuICAgICAgICAgICQkc3VtbWFyeS5odG1sKCdPdmVyYWxsIGF2ZzogJyArIGpvb2xhLmNvbW1vbi5mb3JtYXRNZXRyaWModG90YWwsIG1ldHJpYykgKyAnICgnICsgcGVyY2VudGFnZSArICclKScpO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5zcGxpY2UoMSwgMSk7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnN1bW1hcnknKS5zaG93KCk7XG4gICAgICB2YXIgYmFzZSwgY29tcGFyZSwgY2hhbmdlID0gMDtcbiAgICAgIGlmICghZGF0YVswXS5taXNzaW5nKVxuICAgICAgICBiYXNlID0gZGF0YVswXS5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgICBpZiAoIWRhdGFbMV0ubWlzc2luZylcbiAgICAgICAgY29tcGFyZSA9IGRhdGFbMV0ubWV0cmljc1ttZXRyaWNrZXldO1xuICAgICAgaWYgKGJhc2UgJiYgY29tcGFyZSlcbiAgICAgICAgY2hhbmdlID0gam9vbGEuY29tbW9uLnBlcmNlbnRhZ2VDaGFuZ2UoY29tcGFyZSwgYmFzZSkgKyAnJSc7XG4gICAgICBlbHNlXG4gICAgICAgIGNoYW5nZSA9ICdOL0EnO1xuXG4gICAgICAkJHN1bW1hcnkgPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcuc3VtbWFyeScpKTtcbiAgICAgICQkc3VtbWFyeS5odG1sKCc8c3BhbiBjbGFzcz1cImJhc2VcIj48L3NwYW4+JyArXG4gICAgICAnPHNwYW4gY2xhc3M9XCJzZXBcIj52cy48L3NwYW4+JyArXG4gICAgICAnPHNwYW4gY2xhc3M9XCJjb21wYXJlXCI+PC9zcGFuPicpO1xuICAgICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnZhbHVlJykuaHRtbChjaGFuZ2UpO1xuICAgICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLmJhc2UnKS5odG1sKGJhc2UgPyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKGJhc2UsIG1ldHJpYykgOiAnTi9BJyk7XG5cbiAgICAgIGlmIChjb21wYXJlKSB7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5jb21wYXJlJykuaHRtbChqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKGNvbXBhcmUsIG1ldHJpYykpO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy5jb21wYXJlJykuaHRtbCgnTi9BJyk7XG4gICAgICB9XG5cbiAgICB9XG4gIH07XG5cbiAgdGhpcy5leGl0ID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCcudmFsdWUnKS5odG1sKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vZGF0YSk7XG4gIH07XG5cbiAgdGhpcy51cGRhdGUgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIHZhciBfcXVlcnkgPSBzZWxmLm9wdGlvbnMucXVlcnk7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSlcbiAgICAgIF9xdWVyeSA9IF9xdWVyeVswXTtcblxuICAgIHZhciBtZXRyaWNrZXkgPSBfcXVlcnkubWV0cmljc1swXS5rZXkgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF07XG4gICAgdmFyIG1ldHJpYyA9IGRhdGFbMF0ubWV0YVttZXRyaWNrZXldO1xuICAgIHZhciBtZXRyaWNuYW1lID0gbWV0cmljLm5hbWUgfHwgX3F1ZXJ5Lm1ldHJpY3NbMF0ubmFtZSB8fCBfcXVlcnkubWV0cmljc1swXTtcblxuICAgIGlmIChzZWxmLm9wdGlvbnMudXBkYXRlKVxuICAgICAgc2VsZi5vcHRpb25zLnVwZGF0ZS5hcHBseShzZWxmLCBbZGF0YSwgYWxsZGF0YV0pO1xuXG4gICAgdmFyIHZhbHVlID0gZGF0YVswXS5tZXRyaWNzW21ldHJpY2tleV07XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgnLnZhbHVlJykuaHRtbChqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHZhbHVlLCBtZXRyaWMpKTtcbiAgfTtcblxuICB0aGlzLmRvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5lbWl0KCdkb25lJyk7XG4gIH07XG5cbiAgdGhpcy5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgIGpvb2xhLnZpei5zdG9wKHNlbGYpO1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmVtcHR5KCk7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICAvL3dlIGRyYXcgdGhlIHRlbXBsYXRlIGludG8gdGhlIGNvbnRhaW5lclxuICAgIHZhciAkaHRtbCA9ICQkKHNlbGYub3B0aW9ucy50ZW1wbGF0ZSk7XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuaHRtbCgkaHRtbCk7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5jYXB0aW9uKSB7XG4gICAgICAkaHRtbC5maW5kKCcuY2FwdGlvbicpLmh0bWwoc2VsZi5vcHRpb25zLmNhcHRpb24pO1xuICAgIH1cbiAgICAkaHRtbC5maW5kKCcudmFsdWUnKS5odG1sKHNlbGYub3B0aW9ucy5zdHJpbmdzLm5vZGF0YSk7XG4gICAgLy92aXN1YWxpemF0aW9uIHNwZWNpZmljIGRyYXdpbmdcbiAgICAvL2lmIHdlIGhhdmUgYSBmaWx0ZXIsIGxldCdzIGFkZCBhIHF1ZXJ5IGZvciB0aGUgb3ZlcmFsbFxuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkubGVuZ3RoID09PSAxKSB7XG4gICAgICB2YXIgcSA9IHNlbGYub3B0aW9ucy5xdWVyeVswXTtcbiAgICAgIGlmICghcS5maWx0ZXIpXG4gICAgICAgIHEuZmlsdGVyID0gW107XG4gICAgICBpZiAocS5maWx0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgX3EgPSBjZS5jbG9uZShxKTtcbiAgICAgICAgX3EuZmlsdGVyID0gW107XG4gICAgICAgIF9xLnR5cGUgPSAnb3ZlcmFsbCc7XG4gICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5wdXNoKF9xKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5xdWVyeSAmJiAhQXJyYXkuaXNBcnJheShvcHRpb25zLnF1ZXJ5KSlcbiAgICBvcHRpb25zLnF1ZXJ5ID0gW29wdGlvbnMucXVlcnldO1xuXG4gIC8vd2UgY2FsbCB0aGUgY29yZSBpbml0aWFsaXplIG9wdGlvblxuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcblxuICBzZWxmLmRyYXcoKTtcbiAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHZhciBlbGVtID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIpLnBhcmVudCgpO1xuICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICB9XG4gIH1cbiAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICBzZWxmLm9wdGlvbnMuY2FudmFzLmFkZFZpc3VhbGl6YXRpb24oc2VsZik7XG4gIH1cblxuICAvL3dyYXAgdXBcbiAgc2VsZi5pbml0aWFsaXplZCA9IHRydWU7XG4gIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuXG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLk1ldHJpYyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5NZXRyaWMob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgbWV0cmljKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxudXRpbC5pbmhlcml0cyhNZXRyaWMsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cblxudmFyXG4gIGV2ZW50cyA9IHJlcXVpcmUoJ2V2ZW50cycpLFxuICB1dGlsID0gcmVxdWlyZSgndXRpbCcpLFxuICBjZSA9IHJlcXVpcmUoJ2Nsb25lZXh0ZW5kJyksXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKTtcblxudmFyIE1ldHJpY1BpY2tlciA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ21ldHJpY3BpY2tlci5pbml0LnN0YXJ0Jyk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLnR5cGUgPSAnbWV0cmljcGlja2VyJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNhbnZhczogbnVsbCxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBtZXRyaWNzOiBbXSxcbiAgICBkaXNhYmxlZDogW10sXG4gICAgc2VsZWN0ZWQ6IG51bGwsXG4gICAgYWxsb3dSZW1vdmU6IHRydWUsXG4gICAgYWxsb3dTZWxlY3Q6IHRydWUsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwiamlvLW1ldHJpY3BpY2tlci13cmFwcGVyXCI+XFxuJyArXG4gICAgICAnICA8YnV0dG9uIGNsYXNzPVwiYnRuIGppby1tZXRyaWNwaWNrZXItYnV0dG9uXCI+JyArXG4gICAgICAnICAgPHNwYW4gY2xhc3M9XCJjYXB0aW9uXCI+PC9zcGFuPicgK1xuICAgICAgJyAgIDxzcGFuIGNsYXNzPVwiY2xvc2VcIj7Dlzwvc3Bhbj4nICtcbiAgICAgICcgIDwvYnV0dG9uPicgK1xuICAgICAgJyAgPGRpdiBjbGFzcz1cInBpY2tlci1jb250YWluZXJcIj4nICtcbiAgICAgICcgICAgPGRpdiBjbGFzcz1cInNlYXJjaCBpbnB1dC1wcmVwZW5kXCI+PGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJxdWlja3NlYXJjaFwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoLi4uXCI+PHNwYW4gY2xhc3M9XCJhZGQtb25cIj48aSBjbGFzcz1cInNlYXJjaGljb24gaWNvbi1zZWFyY2hcIj48L2k+PC9zcGFuPjwvZGl2PicgK1xuICAgICAgJyAgICA8ZGl2IGNsYXNzPVwiY2xlYXJcIj48L2Rpdj4nICtcbiAgICAgICcgIDwvZGl2PicgK1xuICAgICAgJyAgPGRpdiBjbGFzcz1cImNsZWFyXCI+PC9kaXY+JyArXG4gICAgICAnPC9kaXY+J1xuICB9O1xuICB0aGlzLmRyYXduID0gZmFsc2U7XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuXG4gICAgcmV0dXJuIG51bGw7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgaWYgKCFzZWxmLmRyYXduKSB7XG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciA9ICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpO1xuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuYXBwZW5kKHNlbGYub3B0aW9ucy50ZW1wbGF0ZSB8fCBzZWxmLnRlbXBsYXRlKCkpO1xuICAgICAgdmFyICR1bCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5waWNrZXItY29udGFpbmVyJykpO1xuICAgICAgdmFyICRidG4gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLW1ldHJpY3BpY2tlci1idXR0b24nKSk7XG4gICAgICB2YXIgJGNsb3NlID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLmNsb3NlJykpO1xuICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuYWxsb3dSZW1vdmUpXG4gICAgICAgICRjbG9zZS5yZW1vdmUoKTtcbiAgICAgIHZhciAkc2VhcmNoID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnF1aWNrc2VhcmNoJykpO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYXB0aW9uKVxuICAgICAgICAkYnRuLmZpbmQoJy5jYXB0aW9uJykudGV4dChzZWxmLm9wdGlvbnMuY2FwdGlvbik7XG4gICAgICBpZiAoc2VsZi5vcHRpb25zLm1ldHJpY3MubGVuZ3RoID09PSAwKVxuICAgICAgICBqb29sYS5tZXRyaWNzLmxpc3QoZnVuY3Rpb24gKGVyciwgbGlzdCkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG5cbiAgICAgICAgICB2YXIgbU9wZW4gPSBmYWxzZTtcbiAgICAgICAgICB2YXIgbVNraXBPbmUgPSBmYWxzZTtcbiAgICAgICAgICB2YXIgbWxhc3R0YXJnZXQgPSBudWxsO1xuXG4gICAgICAgICAgbGlzdC5mb3JFYWNoKGZ1bmN0aW9uIChtZXRyaWMpIHtcbiAgICAgICAgICAgIHZhciBjb2xsZWN0aW9uID0ge2tleTogbWV0cmljLmNvbGxlY3Rpb259O1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjb2xsZWN0aW9uICE9PSAnb2JqZWN0JylcbiAgICAgICAgICAgICAgY29sbGVjdGlvbiA9IHtrZXk6IGNvbGxlY3Rpb259O1xuXG4gICAgICAgICAgICB2YXIgJGxpID0gJCQoJzxkaXYgY2xhc3M9XCJtZXRyaWNPcHRpb25cIiBkYXRhLW1lbWJlcj1cIicgKyBjb2xsZWN0aW9uLmtleSArICcuJyArIG1ldHJpYy5rZXkgKyAnXCI+JyArIChtZXRyaWMubmFtZSB8fCBtZXRyaWMua2V5KSArICc8L2Rpdj4nKTtcbiAgICAgICAgICAgICRsaS5vZmYoJ2NsaWNrJyk7XG4gICAgICAgICAgICAkbGkub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICAgICAgICAgICAgaWYgKCR0aGlzLmhhc0NsYXNzKCdhY3RpdmUnKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIGlmICgkdGhpcy5oYXNDbGFzcygnZGlzYWJsZWQnKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnNlbGVjdGVkID0gbWV0cmljO1xuICAgICAgICAgICAgICAvL3ZhciAkY29udGVudCA9ICc8c3BhbiBjbGFzcz1cIm5hbWVcIj4nICsgbWV0cmljLm5hbWUgKyAnPC9zcGFuPic7XG4gICAgICAgICAgICAgIC8vJGJ0bi5maW5kKCcuY2FwdGlvbicpLmh0bWwoKHNlbGYub3B0aW9ucy5wcmVmaXggfHwgJycgKSArICRjb250ZW50KTtcbiAgICAgICAgICAgICAgJGJ0bi5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgICR1bC5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgICAgICAgIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gbnVsbDtcblxuICAgICAgICAgICAgICBzZWxmLm1hcmtTZWxlY3RlZCgpO1xuXG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnY2hhbmdlJywgbWV0cmljKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJHVsLmFwcGVuZCgkbGkpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJGNsb3NlLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgc2VsZi5vcHRpb25zLnNlbGVjdGVkID0gbnVsbDtcbiAgICAgICAgICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgICBzZWxmLmVtaXQoJ2NoYW5nZScsIG51bGwpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJHNlYXJjaC5rZXl1cChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgJHRoaXMgPSAkJCh0aGlzKTtcbiAgICAgICAgICAgIHZhciB2YWwgPSAkdGhpcy52YWwoKTtcbiAgICAgICAgICAgIGlmICh2YWwubGVuZ3RoID49IDIpIHtcbiAgICAgICAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcl0nKS5oaWRlKCk7XG4gICAgICAgICAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXIqPVwiJyArIHZhbCArICdcIl0nKS5zaG93KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICR1bC5maW5kKCdkaXZbZGF0YS1tZW1iZXJdJykuc2hvdygpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgJGJ0bi5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyICR0aGlzID0gJCQodGhpcyk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAgICAgICBpZiAobU9wZW4gJiYgbWxhc3R0YXJnZXQgPT0gdGhpcy5pZCkge1xuICAgICAgICAgICAgICAkdWwucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBtbGFzdHRhcmdldCA9IG51bGw7XG4gICAgICAgICAgICAgIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChtU2tpcE9uZSkge1xuICAgICAgICAgICAgICAkdWwucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICBtbGFzdHRhcmdldCA9IG51bGw7XG4gICAgICAgICAgICAgIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgIG1Ta2lwT25lID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgJHVsLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgICAgbWxhc3R0YXJnZXQgPSB0aGlzLmlkO1xuICAgICAgICAgICAgICBtT3BlbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gJGJ0bi5wb3NpdGlvbigpO1xuICAgICAgICAgICAgJHVsLmNzcygndG9wJywgb2Zmc2V0LnRvcCArICRidG4ub3V0ZXJIZWlnaHQoKSAtIDEpO1xuICAgICAgICAgICAgJHVsLmNzcygnbGVmdCcsIG9mZnNldC5sZWZ0KTtcbiAgICAgICAgICAgICR1bC5maW5kKCd1bC5hY3RpdmUnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG5cbiAgICAgICAgICAgICR1bC5hdHRyKCdkYXRhLXRhcmdldCcsIHRoaXMuaWQpO1xuXG4gICAgICAgICAgICAvL3NldCBzZWxlY3RlZFxuICAgICAgICAgICAgc2VsZi5tYXJrU2VsZWN0ZWQoKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICR1bC5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAkJCgnYm9keScpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICRidG4ucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgJHVsLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIG1sYXN0dGFyZ2V0ID0gbnVsbDtcbiAgICAgICAgICAgIG1PcGVuID0gZmFsc2U7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAkYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciAkdGhpcyA9ICQkKHRoaXMpO1xuICAgICAgICAgICAgJHRoaXMudG9nZ2xlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgICAgICAgfSk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuXG4gICAgfVxuXG4gICAgc2VsZi5tYXJrU2VsZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAkdWwuZmluZCgnZGl2JykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5hbGxvd1NlbGVjdCAmJiBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQpIHtcbiAgICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcj1cIicgKyBzZWxmLm9wdGlvbnMuc2VsZWN0ZWQuY29sbGVjdGlvbiArICcuJyArIHNlbGYub3B0aW9ucy5zZWxlY3RlZC5rZXkgKyAnXCJdJykuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLW1ldHJpY3BpY2tlci1idXR0b24nKS5maW5kKCcuY2FwdGlvbicpLmh0bWwoKHNlbGYub3B0aW9ucy5wcmVmaXggfHwgJycgKSArICc8c3BhbiBjbGFzcz1cIm5hbWVcIj4nICsgKHNlbGYub3B0aW9ucy5zZWxlY3RlZC5uYW1lIHx8IHNlbGYub3B0aW9ucy5zZWxlY3RlZC5rZXkgfHwgc2VsZi5vcHRpb25zLnNlbGVjdGVkKSArICc8L3NwYW4+Jyk7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpLnNob3coKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuamlvLW1ldHJpY3BpY2tlci1idXR0b24nKS5maW5kKCcuY2FwdGlvbicpLmh0bWwoJ0Nob29zZSBhIG1ldHJpYy4uLicgKyAnJyk7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jbG9zZScpLmhpZGUoKTtcbiAgICAgIH1cblxuICAgICAgJHVsLmZpbmQoJ2RpdltkYXRhLW1lbWJlcl0nKS5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgIGlmIChzZWxmLm9wdGlvbnMuZGlzYWJsZWQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5kaXNhYmxlZCkpXG4gICAgICAgICAgc2VsZi5vcHRpb25zLmRpc2FibGVkID0gW3NlbGYub3B0aW9ucy5kaXNhYmxlZF07XG5cbiAgICAgICAgc2VsZi5vcHRpb25zLmRpc2FibGVkLmZvckVhY2goZnVuY3Rpb24gKGRpc2FibGUpIHtcbiAgICAgICAgICAkdWwuZmluZCgnZGl2W2RhdGEtbWVtYmVyPVwiJyArIGRpc2FibGUuY29sbGVjdGlvbiArICcuJyArIGRpc2FibGUua2V5ICsgJ1wiXScpLmFkZENsYXNzKCdkaXNhYmxlZCcpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHNlbGYubWFya1NlbGVjdGVkKCk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcbiAgLy93ZSBjYWxsIHRoZSBjb3JlIGluaXRpYWxpemUgb3B0aW9uXG4gIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIG9wdGlvbnMgfHwge30pO1xuICBzZWxmLmRyYXcoKTtcblxuICBqb29sYS52aXoub25zY3JlZW4ucHVzaChzZWxmKTtcbiAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgaWYgKGVsZW0uYXR0cignamlvLXR5cGUnKSA9PSAnY2FudmFzJykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgfVxuXG4gIC8vd3JhcCB1cFxuICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uTWV0cmljUGlja2VyID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgKG9wdGlvbnMgJiYgb3B0aW9ucy5mb3JjZSkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy9jcmVhdGUgbmV3XG4gICAgICAgIGlmICghb3B0aW9ucylcbiAgICAgICAgICBvcHRpb25zID0ge307XG4gICAgICAgIG9wdGlvbnMuY29udGFpbmVyID0gdGhpcy5nZXQoMCk7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBqb29sYS52aXouTWV0cmljUGlja2VyKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIG1ldHJpY3BpY2tlcikge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgbWV0cmljcGlja2VyLmRyYXcob3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pO1xuXG51dGlsLmluaGVyaXRzKE1ldHJpY1BpY2tlciwgZXZlbnRzLkV2ZW50RW1pdHRlcik7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIE1pbmlUYWJsZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ21pbml0YWJsZS5pbml0LnN0YXJ0Jyk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9pZCA9ICdfbWluaXRhYmxlJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGxlZ2VuZDogdHJ1ZSxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBxdWVyeTogbnVsbFxuICB9O1xuICB0aGlzLmNoYXJ0RHJhd24gPSBmYWxzZTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci52ZXJpZnkob3B0aW9ucywgY2FsbGJhY2spO1xuICB9O1xuXG4gIHRoaXMudGVtcGxhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyICRodG1sID0gJCgnPHRhYmxlIGNsYXNzPVwiamlvIG1pbml0YWJsZSB0YWJsZVwiPicgK1xuICAgICAgJzx0aGVhZD4nICtcbiAgICAgICc8L3RoZWFkPicgK1xuICAgICAgJzx0Ym9keT4nICtcbiAgICAgICc8L3Rib2R5PicgK1xuICAgICAgJzwvdGFibGU+Jyk7XG4gICAgcmV0dXJuICRodG1sO1xuICB9O1xuXG4gIHRoaXMuc29ydCA9IGZ1bmN0aW9uIChrZXksIGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgfTtcblxuICB0aGlzLl9kcmF3ID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICBzZWxmLnN0b3AoKTtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIuZmV0Y2godGhpcy5vcHRpb25zLnF1ZXJ5LCBmdW5jdGlvbiAoZXJyLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShtZXNzYWdlKSlcbiAgICAgICAgbWVzc2FnZSA9IG1lc3NhZ2VbMF07XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgJGNvbCwgJHRyLCB0cnM7XG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5fc3VwZXIubWFrZVRhYmxlQ2hhcnRTZXJpZXMobWVzc2FnZS5kaW1lbnNpb25zLCBtZXNzYWdlLm1ldHJpY3MsIG1lc3NhZ2UuZG9jdW1lbnRzKTtcbiAgICAgIGlmICghc2VsZi5jaGFydERyYXduKSB7XG4gICAgICAgIHNlbGYuY2hhcnREcmF3biA9IHRydWU7XG5cbiAgICAgICAgdmFyICRodG1sID0gc2VsZi50ZW1wbGF0ZSgpO1xuXG4gICAgICAgIHZhciAkdGhlYWQgPSAkKCRodG1sLmZpbmQoJ3RoZWFkJykpO1xuICAgICAgICB2YXIgJGhlYWRfdHIgPSAkKCc8dHIgY2xhc3M9XCJqaW8gbWluaXRhYmxlIGNhcHRpb25zXCI+PC90cj4nKTtcblxuICAgICAgICBtZXNzYWdlLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgIHZhciAkdGggPSAkKCc8dGggY2xhc3M9XCJqaW8gbWluaXRhYmxlIGNhcHRpb24gZGltZW5zaW9uXCI+PC90aD4nKTtcbiAgICAgICAgICAkdGgudGV4dChkLm5hbWUpO1xuICAgICAgICAgICRoZWFkX3RyLmFwcGVuZCgkdGgpO1xuICAgICAgICB9KTtcbiAgICAgICAgbWVzc2FnZS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICB2YXIgJHRoID0gJCgnPHRoIGNsYXNzPVwiamlvIG1pbml0YWJsZSBjYXB0aW9uIG1ldHJpY1wiPjwvdGg+Jyk7XG4gICAgICAgICAgJHRoLnRleHQobS5uYW1lKTtcbiAgICAgICAgICAkaGVhZF90ci5hcHBlbmQoJHRoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJHRoZWFkLmFwcGVuZCgkaGVhZF90cik7XG4gICAgICAgICRodG1sLmFwcGVuZCgkdGhlYWQpO1xuXG4gICAgICAgIHZhciAkdGJvZHkgPSAkKCRodG1sLmZpbmQoJ3Rib2R5JykpO1xuICAgICAgICBzZXJpZXMuZm9yRWFjaChmdW5jdGlvbiAoc2VyLCBzZXJJbmRleCkge1xuICAgICAgICAgIHNlci5kYXRhLmZvckVhY2goZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICB2YXIgJHRyID0gJCgnPHRyPjwvdHI+Jyk7XG5cbiAgICAgICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgICAgICBtZXNzYWdlLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICB2YXIgJHRkID0gJCgnPHRkIGNsYXNzPVwiamlvIG1pbml0YWJsZSB2YWx1ZSBkaW1lbnNpb25cIj48L3RkPicpO1xuICAgICAgICAgICAgICAkdGQudGV4dChwb2ludFtpbmRleCsrXSk7XG4gICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbWVzc2FnZS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgdmFyICR0ZCA9ICQoJzx0ZCBjbGFzcz1cImppbyBtaW5pdGFibGUgdmFsdWUgbWV0cmljXCI+PC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRkLnRleHQocG9pbnRbaW5kZXgrK10pO1xuICAgICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgJGh0bWwuYXBwZW5kKCR0Ym9keSk7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmFwcGVuZCgkaHRtbCk7XG5cbiAgICAgICAgc2VsZi50YWJsZXNvcnQgPSBuZXcgVGFibGVzb3J0KCRodG1sLmdldCgwKSwge1xuICAgICAgICAgIGRlc2NlbmRpbmc6IHRydWUsXG4gICAgICAgICAgY3VycmVudDogJGh0bWwuZmluZCgndGgnKVsxXVxuICAgICAgICB9KTtcblxuXG4gICAgICAgIGlmIChzZWxmLm9wdGlvbnMub25EcmF3KVxuICAgICAgICAgIHdpbmRvd1tzZWxmLm9wdGlvbnMub25EcmF3XShzZWxmKTtcblxuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHNlbGYub3B0aW9ucy5xdWVyeS5yZWFsdGltZSkge1xuICAgICAgICAvL3dlJ3JlIGRlYWxpbmcgd2l0aCByZWFsdGltZVxuICAgICAgICB0cnMgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCd0Ym9keScpLmZpbmQoJ3RyJyk7XG4gICAgICAgIHZhciBleGlzdGluZ2tleXMgPSBbXTtcbiAgICAgICAgc2VyaWVzWzBdLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICAgIHZhciBrZXkgPSAnJztcbiAgICAgICAgICB2YXIgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBtZXNzYWdlLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAga2V5ICs9IHBvaW50W2luZGV4KytdO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZXhpc3RpbmdrZXlzLnB1c2goa2V5KTtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAkdHIgPSAkKHRyc1tpXSk7XG4gICAgICAgICAgICB2YXIgY29scyA9ICR0ci5maW5kKCd0ZCcpO1xuXG4gICAgICAgICAgICB2YXIgX2tleSA9ICcnO1xuICAgICAgICAgICAgdmFyIGo7XG4gICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgbWVzc2FnZS5kaW1lbnNpb25zLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICRjb2wgPSAkKGNvbHNbal0pO1xuICAgICAgICAgICAgICBfa2V5ICs9ICRjb2wudGV4dCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoX2tleSA9PSBrZXkpIHtcbiAgICAgICAgICAgICAgZm9yICg7IGogPCBtZXNzYWdlLmRpbWVuc2lvbnMubGVuZ3RoICsgbWVzc2FnZS5tZXRyaWNzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgJGNvbCA9ICQoY29sc1tqXSk7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gJGNvbC50ZXh0KCk7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IHBvaW50W2pdKVxuICAgICAgICAgICAgICAgICAgJGNvbC50ZXh0KHBvaW50W2pdKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICAgIC8vYWRkXG4gICAgICAgICAgICB2YXIgJHRib2R5ID0gJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCd0Ym9keScpWzBdKTtcbiAgICAgICAgICAgICR0ciA9ICQoJzx0cj48L3RyPicpO1xuXG4gICAgICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgICAgICBtZXNzYWdlLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICB2YXIgJHRkID0gJCgnPHRkIGNsYXNzPVwiamlvIG1pbml0YWJsZSB2YWx1ZSBkaW1lbnNpb25cIj48L3RkPicpO1xuICAgICAgICAgICAgICAkdGQudGV4dChwb2ludFtpbmRleCsrXSk7XG4gICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbWVzc2FnZS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgdmFyICR0ZCA9ICQoJzx0ZCBjbGFzcz1cImppbyBtaW5pdGFibGUgdmFsdWUgbWV0cmljXCI+PC90ZD4nKTtcbiAgICAgICAgICAgICAgJHRkLnRleHQocG9pbnRbaW5kZXgrK10pO1xuICAgICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgJHRyID0gJCh0cnNbaV0pO1xuICAgICAgICAgIHZhciBjb2xzID0gJHRyLmZpbmQoJ3RkJyk7XG5cbiAgICAgICAgICB2YXIgX2tleSA9ICcnO1xuICAgICAgICAgIHZhciBqO1xuICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBtZXNzYWdlLmRpbWVuc2lvbnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgICRjb2wgPSAkKGNvbHNbal0pO1xuICAgICAgICAgICAgX2tleSArPSAkY29sLnRleHQoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZXhpc3RpbmdrZXlzLmluZGV4T2YoX2tleSkgPT0gLTEpXG4gICAgICAgICAgICAkdHIucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHNlcmllc1swXS5kYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc2VsZi50YWJsZXNvcnQucmVmcmVzaCgpO1xuXG4gICAgICAgIHZhciBsaW1pdCA9IDU7XG4gICAgICAgIHRycyA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJ3Rib2R5IHRyJyk7XG4gICAgICAgIGZvciAodmFyIHogPSAwOyB6IDwgdHJzLmxlbmd0aDsgeisrKSB7XG4gICAgICAgICAgdmFyIGVsZW0gPSB0cnNbel07XG4gICAgICAgICAgdmFyICRlbGVtID0gJChlbGVtKTtcbiAgICAgICAgICBpZiAoeiArIDEgPiBsaW1pdClcbiAgICAgICAgICAgICRlbGVtLnJlbW92ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIHRyeSB7XG4gICAgam9vbGEuY29tbW9uLm1peGluKHNlbGYub3B0aW9ucywgb3B0aW9ucywgdHJ1ZSk7XG4gICAgc2VsZi52ZXJpZnkoc2VsZi5vcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkKHNlbGYub3B0aW9ucy5jb250YWluZXIpO1xuICAgICAgc2VsZi5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLCBbXG4gICAgICAgIHsndHlwZSc6ICdtaW5pdGFibGUnfSxcbiAgICAgICAgeyd1dWlkJzogc2VsZi51dWlkfSxcbiAgICAgICAgeydjc3MnOiBzZWxmLm9wdGlvbnMuY3NzfVxuICAgICAgXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuXG4gICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdtaW5pdGFibGUuaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjYXRjaCAoZXJyKSB7XG4gICAgY2FsbGJhY2soZXJyKTtcbiAgICByZXR1cm4gc2VsZi5vbkVycm9yKGVyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy9jYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uTWluaVRhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6Lk1pbmlUYWJsZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBtaW5pdGFibGUpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIG1pbml0YWJsZS5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXJcbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpO1xuXG5cbnZhciBQaWUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCdwaWUuaW5pdC5zdGFydCcpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5faWQgPSAnX3BpZSc7XG4gIHRoaXMudXVpZCA9IGpvb2xhLmNvbW1vbi51dWlkKCk7XG4gIHRoaXMub3B0aW9ucyA9IHtcbiAgICBsZWdlbmQ6IHRydWUsXG4gICAgbGltaXQ6IDUsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgICRjb250YWluZXI6IG51bGwsXG4gICAgcXVlcnk6IG51bGxcbiAgfTtcbiAgdGhpcy5jaGFydERyYXduID0gZmFsc2U7XG4gIHRoaXMucmVhbHRpbWVRdWVyaWVzID0gW107XG5cbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIudmVyaWZ5KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfTtcblxuICB0aGlzLmRyYXcgPSBmdW5jdGlvbiAob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgICBzZWxmLnN0b3AoKTtcbiAgICByZXR1cm4gdGhpcy5fc3VwZXIuZmV0Y2godGhpcy5vcHRpb25zLnF1ZXJ5LCBmdW5jdGlvbiAoZXJyLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAobWVzc2FnZS5yZWFsdGltZSAmJiBzZWxmLnJlYWx0aW1lUXVlcmllcy5pbmRleE9mKG1lc3NhZ2UucmVhbHRpbWUpID09IC0xKVxuICAgICAgICBzZWxmLnJlYWx0aW1lUXVlcmllcy5wdXNoKG1lc3NhZ2UucmVhbHRpbWUpO1xuXG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5fc3VwZXIubWFrZVBpZUNoYXJ0U2VyaWVzKG1lc3NhZ2UuZGltZW5zaW9ucywgbWVzc2FnZS5tZXRyaWNzLCBtZXNzYWdlLmRvY3VtZW50cyk7XG4gICAgICBpZiAoIXNlbGYuY2hhcnREcmF3bikge1xuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLm9uRHJhdylcbiAgICAgICAgICB3aW5kb3dbc2VsZi5vcHRpb25zLm9uRHJhd10oc2VsZik7XG4gICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmFwcGVuZChzZWxmLm9wdGlvbnMudGVtcGxhdGUgfHwgUGllLnRlbXBsYXRlKCkpO1xuICAgICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuY2FwdGlvbicpLnRleHQoc2VsZi5vcHRpb25zLmNhcHRpb24gfHwgJycpO1xuICAgICAgICB2YXIgY2hhcnRPcHRpb25zID0gam9vbGEuY29tbW9uLl9taXhpbih7XG4gICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNoYXJ0OiB7XG4gICAgICAgICAgICAvKm1hcmdpblRvcDogMCxcbiAgICAgICAgICAgICBtYXJnaW5Cb3R0b206IDAsXG4gICAgICAgICAgICAgbWFyZ2luTGVmdDogMCxcbiAgICAgICAgICAgICBtYXJnaW5SaWdodDogMCxcbiAgICAgICAgICAgICBzcGFjaW5nVG9wOiAwLFxuICAgICAgICAgICAgIHNwYWNpbmdCb3R0b206IDAsXG4gICAgICAgICAgICAgc3BhY2luZ0xlZnQ6IDAsXG4gICAgICAgICAgICAgc3BhY2luZ1JpZ2h0OiAwLCovXG4gICAgICAgICAgICBib3JkZXJXaWR0aDogMCxcbiAgICAgICAgICAgIHBsb3RCb3JkZXJXaWR0aDogMCxcbiAgICAgICAgICAgIHR5cGU6ICdwaWUnLFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAndHJhbnNwYXJlbnQnXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXJpZXM6IHNlcmllcyxcblxuICAgICAgICAgIGxlZ2VuZDoge2VuYWJsZWQ6IHNlbGYub3B0aW9ucy5sZWdlbmR9LFxuICAgICAgICAgIGNyZWRpdHM6IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICAgICAgZXhwb3J0aW5nOiB7ZW5hYmxlZDogdHJ1ZX0sXG4gICAgICAgICAgcGxvdE9wdGlvbnM6IHtcbiAgICAgICAgICAgIHBpZToge1xuICAgICAgICAgICAgICBhbGxvd1BvaW50U2VsZWN0OiB0cnVlLFxuICAgICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgICAgICAgICAgZGF0YUxhYmVsczoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAnIzAwMDAwMCcsXG4gICAgICAgICAgICAgICAgY29ubmVjdG9yQ29sb3I6ICcjMDAwMDAwJyxcbiAgICAgICAgICAgICAgICBmb3JtYXQ6ICc8Yj57cG9pbnQubmFtZX08L2I+OiB7cG9pbnQucGVyY2VudGFnZTouMWZ9ICUnXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHNob3dJbkxlZ2VuZDogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgc2VsZi5vcHRpb25zLmNoYXJ0KTtcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5jYXB0aW9uKVxuICAgICAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5qaW8tcGllLWNhcHRpb24nKS50ZXh0KHNlbGYub3B0aW9ucy5jYXB0aW9uKTtcbiAgICAgICAgc2VsZi5jaGFydCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5qaW8tcGllLWNoYXJ0JykuaGlnaGNoYXJ0cyhjaGFydE9wdGlvbnMpO1xuXG4gICAgICAgIHNlbGYuY2hhcnQgPSBzZWxmLmNoYXJ0LmhpZ2hjaGFydHMoKTtcbiAgICAgICAgc2VsZi5jaGFydERyYXduID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChzZWxmLm9wdGlvbnMucXVlcnkucmVhbHRpbWUpIHtcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5vblVwZGF0ZSlcbiAgICAgICAgICB3aW5kb3dbc2VsZi5vcHRpb25zLm9uVXBkYXRlXShzZWxmKTtcbiAgICAgICAgLy93ZSdyZSBkZWFsaW5nIHdpdGggcmVhbHRpbWVcbiAgICAgICAgc2VyaWVzLmZvckVhY2goZnVuY3Rpb24gKHNlciwgc2VySW5kZXgpIHtcbiAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0ucG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKHBvaW50KSB7XG4gICAgICAgICAgICB2YXIgZXhpc3QgPSBfLmZpbmQoc2VyLmRhdGEsIGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgIHJldHVybiBwWzBdID09IHBvaW50Lm5hbWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChleGlzdClcbiAgICAgICAgICAgICAgcG9pbnQudXBkYXRlKGV4aXN0WzFdLCBmYWxzZSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIHBvaW50LnJlbW92ZShmYWxzZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2VyLmRhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgICAgIHZhciBleGlzdCA9IF8uZmluZChzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0ucG9pbnRzLCBmdW5jdGlvbiAocCkge1xuICAgICAgICAgICAgICByZXR1cm4gcC5uYW1lID09IHBvaW50WzBdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoIWV4aXN0KVxuICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uYWRkUG9pbnQoW3BvaW50WzBdLCBwb2ludFsxXV0sIGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBzZWxmLmNoYXJ0LnJlZHJhdygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIC8vaGVyZSB3ZSBnb1xuICB0cnkge1xuICAgIGpvb2xhLmNvbW1vbi5taXhpbihzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICAgIHNlbGYudmVyaWZ5KHNlbGYub3B0aW9ucywgZnVuY3Rpb24gKGVycikge1xuICAgICAgaWYgKGVycilcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyID0gJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICAgIHNlbGYubWFya0NvbnRhaW5lcihzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciwge1xuICAgICAgICBhdHRyOiBbXG4gICAgICAgICAgeyd0eXBlJzogJ3BpZSd9LFxuICAgICAgICAgIHsndXVpZCc6IHNlbGYudXVpZH0sXG4gICAgICAgICAge2Nzczogc2VsZi5vcHRpb25zLmNzc31cbiAgICAgICAgXSxcbiAgICAgICAgY3NzOiBzZWxmLm9wdGlvbnMuY3NzfSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuXG4gICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdwaWUuaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjYXRjaCAoZXJyKSB7XG4gICAgY2FsbGJhY2soZXJyKTtcbiAgICByZXR1cm4gc2VsZi5vbkVycm9yKGVyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy9jYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uUGllID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LlBpZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCBwaWUpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIHBpZS5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgfSkub3B0aW9ucy4kY29udGFpbmVyO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIC8vcmV0dXJuIGV4aXN0aW5nXG4gICAgICAgIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxuUGllLnRlbXBsYXRlID0gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgdmFyIGh0bWwgPSAnPGRpdiBqaW8tZG9tYWluPVwiam9vbGFcIiBqaW8tdHlwZT1cInBpZVwiPlxcbicgK1xuICAgICcgIDxkaXYgY2xhc3M9XCJqaW8tcGllLWNhcHRpb25cIj48L2Rpdj5cXG4nICtcbiAgICAnICA8ZGl2IGNsYXNzPVwiamlvLXBpZS1jaGFydFwiPjwvZGl2PlxcbicgK1xuICAgICc8L2Rpdj4nO1xuICByZXR1cm4gaHRtbDtcbn07XG4iLCIvKmpzaGludCAtVzA4MyAqL1xuXG4vKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXIgXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxudmFyIFB1bmNoQ2FyZCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ3B1bmNoY2FyZC5pbml0LnN0YXJ0Jyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuX2lkID0gJ19wdW5jaGNhcmQnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgbGVnZW5kOiB0cnVlLFxuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAkY29udGFpbmVyOiBudWxsLFxuICAgIHF1ZXJ5OiBudWxsXG4gIH07XG4gIHRoaXMuY2hhcnREcmF3biA9IGZhbHNlO1xuXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N1cGVyLnZlcmlmeShvcHRpb25zLCBjYWxsYmFjayk7XG4gIH07XG5cbiAgdGhpcy5tYWtlU2VyaWVzID0gZnVuY3Rpb24gKGRpbWVuc2lvbnMsIG1ldHJpY3MsIGRvY3VtZW50cykge1xuICAgIHZhciBtYXhWYWx1ZTtcbiAgICB2YXIgbWluVmFsdWU7XG5cbiAgICBkb2N1bWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZG9jdW1lbnQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGRvY3VtZW50LnZhbHVlc1ttZXRyaWNzWzBdLmtleV07XG4gICAgICBpZiAoIW1heFZhbHVlKVxuICAgICAgICBtYXhWYWx1ZSA9IHZhbHVlO1xuICAgICAgaWYgKCFtaW5WYWx1ZSlcbiAgICAgICAgbWluVmFsdWUgPSB2YWx1ZTtcbiAgICAgIGlmICh2YWx1ZSA+IG1heFZhbHVlKVxuICAgICAgICBtYXhWYWx1ZSA9IHZhbHVlO1xuICAgICAgaWYgKHZhbHVlIDwgbWluVmFsdWUpXG4gICAgICAgIG1pblZhbHVlID0gdmFsdWU7XG4gICAgfSk7XG5cbiAgICB2YXIgc2NhbGVTaXplID0gZnVuY3Rpb24gKG1pbiwgbWF4LCB0YXJnZXRtaW4sIHRhcmdldG1heCwgeCkge1xuICAgICAgdmFyIHJlc3VsdCA9ICgoKHRhcmdldG1heCAtIHRhcmdldG1pbikgKiAoeCAtIG1pbikpIC8gKG1heCAtIG1pbikpICsgdGFyZ2V0bWluO1xuICAgICAgaWYgKGlzTmFOKHJlc3VsdCkpXG4gICAgICAgIHJlc3VsdCA9IHg7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICB2YXIgc2VyaWVzID0gW1xuICAgICAge1xuICAgICAgICBuYW1lOiBtZXRyaWNzWzBdLm5hbWUsXG4gICAgICAgIGRhdGE6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgX2RhdGEgPSBbXTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDc7IGkrKykge1xuICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCAyNDsgaisrKSB7XG4gICAgICAgICAgICAgIHZhciBwb2ludCA9IHtcbiAgICAgICAgICAgICAgICB5OiBpLFxuICAgICAgICAgICAgICAgIHg6IDM2MDAwMDAgKiBqLFxuXG4gICAgICAgICAgICAgICAgbWFya2VyOiB7cmFkaXVzOiAwIH1cbiAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICB2YXIgZXhpc3RzID0gXy5maW5kKGRvY3VtZW50cywgZnVuY3Rpb24gKGRvY3VtZW50KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LnZhbHVlc1tkaW1lbnNpb25zWzBdLmtleV0gPT09IGkgJiYgZG9jdW1lbnQudmFsdWVzW2RpbWVuc2lvbnNbMV0ua2V5XSA9PT0gajtcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgaWYgKGV4aXN0cylcbiAgICAgICAgICAgICAgICBwb2ludC5tYXJrZXIgPSB7IHJhZGl1czogc2NhbGVTaXplKG1pblZhbHVlLCBtYXhWYWx1ZSwgMywgMTEsIGV4aXN0cy52YWx1ZXNbbWV0cmljc1swXS5rZXldKSB9O1xuXG4gICAgICAgICAgICAgIF9kYXRhLnB1c2gocG9pbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX2RhdGE7XG5cbiAgICAgICAgfSgpXG4gICAgICB9XG4gICAgXTtcblxuICAgIHJldHVybiBzZXJpZXM7XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N1cGVyLmZldGNoKHRoaXMub3B0aW9ucy5xdWVyeSwgZnVuY3Rpb24gKGVyciwgbWVzc2FnZSkge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHZhciBzZXJpZXMgPSBzZWxmLm1ha2VTZXJpZXMobWVzc2FnZS5kaW1lbnNpb25zLCBtZXNzYWdlLm1ldHJpY3MsIG1lc3NhZ2UuZG9jdW1lbnRzKTtcbiAgICAgIGlmICghc2VsZi5jaGFydERyYXduKSB7XG4gICAgICAgIHZhciBjaGFydE9wdGlvbnMgPSBqb29sYS5jb21tb24ubWl4aW4oe1xuICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICB0ZXh0OiBudWxsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjaGFydDoge1xuXG4gICAgICAgICAgICBkZWZhdWx0U2VyaWVzVHlwZTogJ3NjYXR0ZXInXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzZXJpZXM6IHNlcmllcyxcbiAgICAgICAgICB4QXhpczoge1xuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgdGV4dDogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGU6IFwiZGF0ZXRpbWVcIixcbiAgICAgICAgICAgIGRhdGVUaW1lTGFiZWxGb3JtYXRzOiB7XG4gICAgICAgICAgICAgIGhvdXI6ICclSSAlUCdcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aWNrSW50ZXJ2YWw6IDM2MDAwMDAgKiAxXG4gICAgICAgICAgfSxcbiAgICAgICAgICB5QXhpczoge1xuICAgICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgICAgdGV4dDogbnVsbFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhdGVnb3JpZXM6IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgbGVnZW5kOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgICAgIGNyZWRpdHM6IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICAgICAgZXhwb3J0aW5nOiB7ZW5hYmxlZDogdHJ1ZX1cbiAgICAgICAgfSwgc2VsZi5vcHRpb25zLmNoYXJ0KTtcbiAgICAgICAgc2VsZi5jaGFydCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmhpZ2hjaGFydHMoY2hhcnRPcHRpb25zKTtcblxuICAgICAgICBzZWxmLmNoYXJ0ID0gc2VsZi5jaGFydC5oaWdoY2hhcnRzKCk7XG4gICAgICAgIHNlbGYuY2hhcnREcmF3biA9IHRydWU7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5LnJlYWx0aW1lKSB7XG4gICAgICAgIC8vd2UncmUgZGVhbGluZyB3aXRoIHJlYWx0aW1lXG4gICAgICAgIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uIChzZXIsIHNlckluZGV4KSB7XG4gICAgICAgICAgc2VyLmRhdGEuc3BsaWNlKDAsIHNlci5kYXRhLmxlbmd0aCAtIDEpO1xuXG4gICAgICAgICAgdmFyIHBvaW50ID0gc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLnBvaW50c1tzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0ucG9pbnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIGlmIChwb2ludCkge1xuICAgICAgICAgICAgaWYgKHBvaW50LnguZ2V0VGltZSgpID09IHNlci5kYXRhWzBdLnguZ2V0VGltZSgpKVxuICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uZGF0YVtzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uZGF0YS5sZW5ndGggLSAxXS51cGRhdGUoc2VyLmRhdGFbMF0ueSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5hZGRQb2ludCh7eDogc2VyLmRhdGFbMF0ueCwgeTogc2VyLmRhdGFbMF0ueX0sIHRydWUsIHRydWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgLy9oZXJlIHdlIGdvXG4gIHRyeSB7XG4gICAgam9vbGEuY29tbW9uLm1peGluKHNlbGYub3B0aW9ucywgb3B0aW9ucywgdHJ1ZSk7XG4gICAgc2VsZi52ZXJpZnkoc2VsZi5vcHRpb25zLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcblxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkKHNlbGYub3B0aW9ucy5jb250YWluZXIpO1xuICAgICAgc2VsZi5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLCBbXG4gICAgICAgIHsndHlwZSc6ICdwdW5jaGNhcmQnfSxcbiAgICAgICAgeyd1dWlkJzogc2VsZi51dWlkfVxuICAgICAgXSwgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuXG4gICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdwdW5jaGNhcmQuaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjYXRjaCAoZXJyKSB7XG4gICAgY2FsbGJhY2soZXJyKTtcbiAgICByZXR1cm4gc2VsZi5vbkVycm9yKGVyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy9jYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLlB1bmNoQ2FyZCA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgICB2YXIgdXVpZCA9IHRoaXMuYXR0cignamlvLXV1aWQnKTtcbiAgICAgIGlmICghdXVpZCkge1xuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5QdW5jaENhcmQob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgcHVuY2hjYXJkKSB7XG4gICAgICAgICAgcHVuY2hjYXJkLmRyYXcob3B0aW9ucywgY2FsbGJhY2spO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIHJlc3VsdCA9IHZpejtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuICB9XG59KTtcblxuIiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKTtcblxudmFyIFNwYXJrbGluZSA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgam9vbGEuZXZlbnRzLmVtaXQoJ3NwYXJrbGluZS5pbml0LnN0YXJ0Jyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuX2lkID0gJ19zcGFya2xpbmUnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgbGVnZW5kOiB0cnVlLFxuICAgIGNhbnZhczogbnVsbCxcbiAgICBjb250YWluZXI6IG51bGwsXG4gICAgJGNvbnRhaW5lcjogbnVsbCxcbiAgICBxdWVyeTogbnVsbFxuICB9O1xuICB0aGlzLmNoYXJ0RHJhd24gPSBmYWxzZTtcbiAgdGhpcy5yZWFsdGltZVF1ZXJpZXMgPSBbXTtcblxuICB0aGlzLnZlcmlmeSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aGlzLl9zdXBlci52ZXJpZnkob3B0aW9ucywgY2FsbGJhY2spO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgIHNlbGYuc3RvcCgpO1xuICAgIHJldHVybiB0aGlzLl9zdXBlci5mZXRjaChzZWxmLCB0aGlzLm9wdGlvbnMucXVlcnksIGZ1bmN0aW9uIChlcnIsIG1lc3NhZ2UpIHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2VycicsIGVycik7XG4gICAgICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIC8vZWxzZVxuICAgICAgICAvL3Rocm93IGVycjtcblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmIChtZXNzYWdlLnJlYWx0aW1lICYmIHNlbGYucmVhbHRpbWVRdWVyaWVzLmluZGV4T2YobWVzc2FnZS5yZWFsdGltZSkgPT0gLTEpXG4gICAgICAgIHNlbGYucmVhbHRpbWVRdWVyaWVzLnB1c2gobWVzc2FnZS5yZWFsdGltZSk7XG5cbiAgICAgIHZhciBzZXJpZXMgPSBzZWxmLl9zdXBlci5tYWtlQ2hhcnRUaW1lbGluZVNlcmllcyhtZXNzYWdlLmRpbWVuc2lvbnMsIG1lc3NhZ2UubWV0cmljcywgbWVzc2FnZS5kb2N1bWVudHMpO1xuICAgICAgaWYgKCFzZWxmLmNoYXJ0RHJhd24pIHtcbiAgICAgICAgdmFyIGNoYXJ0T3B0aW9ucyA9IGpvb2xhLmNvbW1vbi5taXhpbih7XG4gICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNoYXJ0OiB7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDAsXG4gICAgICAgICAgICBtYXJnaW5Cb3R0b206IChtZXNzYWdlLmRpbWVuc2lvbnNbMF0uZGF0YXR5cGUgPT09ICdkYXRlJyA/IDAgOiAyMCksXG4gICAgICAgICAgICBtYXJnaW5MZWZ0OiAwLFxuICAgICAgICAgICAgbWFyZ2luUmlnaHQ6IDAsXG4gICAgICAgICAgICBzcGFjaW5nVG9wOiAwLFxuICAgICAgICAgICAgc3BhY2luZ0JvdHRvbTogMCxcbiAgICAgICAgICAgIHNwYWNpbmdMZWZ0OiAwLFxuICAgICAgICAgICAgc3BhY2luZ1JpZ2h0OiAwLFxuICAgICAgICAgICAgYm9yZGVyV2lkdGg6IDAsXG4gICAgICAgICAgICBwbG90Qm9yZGVyV2lkdGg6IDAsXG4gICAgICAgICAgICB0eXBlOiAnYXJlYSdcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNlcmllczogc2VyaWVzLFxuICAgICAgICAgIHhBeGlzOiB7XG4gICAgICAgICAgICB0eXBlOiAobWVzc2FnZS5kaW1lbnNpb25zWzBdLmRhdGF0eXBlID09PSAnZGF0ZScgPyAnZGF0ZXRpbWUnIDogJ2NhdGVnb3J5JyksXG4gICAgICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICAgICAgZW5hYmxlZDogKG1lc3NhZ2UuZGltZW5zaW9uc1swXS5kYXRhdHlwZSAhPT0gJ2RhdGUnKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgeUF4aXM6IHtcbiAgICAgICAgICAgIHRpdGxlOiB7XG4gICAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsYWJlbHM6IHtcbiAgICAgICAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGxlZ2VuZDoge2VuYWJsZWQ6IGZhbHNlfSxcbiAgICAgICAgICBjcmVkaXRzOiB7ZW5hYmxlZDogZmFsc2V9LFxuICAgICAgICAgIGV4cG9ydGluZzoge2VuYWJsZWQ6IHRydWV9LFxuICAgICAgICAgIHBsb3RPcHRpb25zOiB7XG4gICAgICAgICAgICBjb2x1bW46IHthbGxvd1BvaW50U2VsZWN0OiB0cnVlfSxcbiAgICAgICAgICAgIHNlcmllczoge1xuICAgICAgICAgICAgICB0dXJib1RocmVzaG9sZDogbWVzc2FnZS5kb2N1bWVudHMubGVuZ3RoICsgMTAwMCxcbiAgICAgICAgICAgICAgY29sb3I6ICcjMzMzMzMzJyxcbiAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDAuMSxcbiAgICAgICAgICAgICAgbGluZVdpZHRoOiAzLFxuICAgICAgICAgICAgICBjb25uZWN0TnVsbHM6IHRydWUsXG4gICAgICAgICAgICAgIG1hcmtlcjoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHN5bWJvbDogJ2NpcmNsZScsXG4gICAgICAgICAgICAgICAgc3RhdGVzOiB7XG4gICAgICAgICAgICAgICAgICBob3Zlcjoge1xuICAgICAgICAgICAgICAgICAgICBlbmFibGVkOiB0cnVlXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBzZWxmLm9wdGlvbnMuY2hhcnQpO1xuICAgICAgICBzZWxmLmNoYXJ0ID0gc2VsZi5vcHRpb25zLiRjb250YWluZXIuaGlnaGNoYXJ0cyhjaGFydE9wdGlvbnMpO1xuXG4gICAgICAgIHNlbGYuY2hhcnQgPSBzZWxmLmNoYXJ0LmhpZ2hjaGFydHMoKTtcbiAgICAgICAgc2VsZi5jaGFydERyYXduID0gdHJ1ZTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG4gICAgICB9XG4gICAgICBlbHNlIGlmIChzZWxmLm9wdGlvbnMucXVlcnkucmVhbHRpbWUpIHtcbiAgICAgICAgLy93ZSdyZSBkZWFsaW5nIHdpdGggcmVhbHRpbWVcbiAgICAgICAgc2VyaWVzLmZvckVhY2goZnVuY3Rpb24gKHNlciwgc2VySW5kZXgpIHtcbiAgICAgICAgICBzZXIuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChkYXRhcG9pbnQpIHtcbiAgICAgICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIG5hbWVCYXNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIHk7XG4gICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0ucG9pbnRzLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBwSW5kZXgpIHtcbiAgICAgICAgICAgICAgaWYgKHBvaW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGFwb2ludC54KSB7XG4gICAgICAgICAgICAgICAgICBpZiAocG9pbnQueC5nZXRUaW1lKCkgPT0gZGF0YXBvaW50LnguZ2V0VGltZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHkgPSBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uZGF0YVtwSW5kZXhdLnk7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHkgIT0gZGF0YXBvaW50LnkpXG4gICAgICAgICAgICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmRhdGFbcEluZGV4XS51cGRhdGUoZGF0YXBvaW50LnkpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIG5hbWVCYXNlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICBpZiAocG9pbnQubmFtZSA9PSBkYXRhcG9pbnQubmFtZSkge1xuICAgICAgICAgICAgICAgICAgICB5ID0gc2VsZi5jaGFydC5zZXJpZXNbc2VySW5kZXhdLmRhdGFbcEluZGV4XS55O1xuICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh5ICE9IGRhdGFwb2ludC55KVxuICAgICAgICAgICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5kYXRhW3BJbmRleF0udXBkYXRlKGRhdGFwb2ludC55KTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICAgICAgICBpZiAobmFtZUJhc2VkKVxuICAgICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzW3NlckluZGV4XS5hZGRQb2ludCh7bmFtZTogZGF0YXBvaW50Lm5hbWUsIHk6IGRhdGFwb2ludC55fSwgdHJ1ZSk7XG4gICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBzZWxmLmNoYXJ0LnNlcmllc1tzZXJJbmRleF0uYWRkUG9pbnQoe3g6IGRhdGFwb2ludC54LCB5OiBkYXRhcG9pbnQueX0sIHRydWUsIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvL2hlcmUgd2UgZ29cbiAgdHJ5IHtcbiAgICBqb29sYS5jb21tb24ubWl4aW4oc2VsZi5vcHRpb25zLCBvcHRpb25zLCB0cnVlKTtcbiAgICBzZWxmLnZlcmlmeShzZWxmLm9wdGlvbnMsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXG4gICAgICBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lciA9ICQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcik7XG4gICAgICBzZWxmLm1hcmtDb250YWluZXIoc2VsZi5vcHRpb25zLiRjb250YWluZXIsIFtcbiAgICAgICAgeyd0eXBlJzogJ3NwYXJrbGluZSd9LFxuICAgICAgICB7J3V1aWQnOiBzZWxmLnV1aWR9XG4gICAgICBdLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG5cbiAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICAgICAgdmFyIGVsZW0gPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5wYXJlbnQoKTtcbiAgICAgICAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzID0gJChlbGVtKS5DYW52YXMoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLm9uKCdkYXRlY2hhbmdlJywgZnVuY3Rpb24gKGRhdGVzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnc3BhcmtsaW5lJywgJ2RhdGVjaGFuZ2UnLCBkYXRlcyk7XG5cbiAgICAgICAgICAgIC8vbGV0J3MgY2hhbmdlIG91ciBxdWVyeSBhbmQgZmV0Y2ggYWdhaW5cbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS50aW1lZnJhbWUgPSB7fTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS50aW1lZnJhbWUuc3RhcnQgPSBuZXcgRGF0ZShkYXRlcy5iYXNlX2Zyb21kYXRlKTtcbiAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS50aW1lZnJhbWUuZW5kID0gbmV3IERhdGUoZGF0ZXMuYmFzZV90b2RhdGUpO1xuXG4gICAgICAgICAgICBzZWxmLmRyYXcoc2VsZi5vcHRpb25zKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGpvb2xhLmV2ZW50cy5lbWl0KCdzcGFya2xpbmUuaW5pdC5maW5pc2gnLCBzZWxmKTtcbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgc2VsZik7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICBjYXRjaCAoZXJyKSB7XG4gICAgY2FsbGJhY2soZXJyKTtcbiAgICByZXR1cm4gc2VsZi5vbkVycm9yKGVyciwgY2FsbGJhY2spO1xuICB9XG5cbiAgLy9jYWxsYmFjayhudWxsLCBzZWxmKTtcbiAgcmV0dXJuIHNlbGY7XG59O1xuXG5qb29sYS5ldmVudHMub24oJ2NvcmUuaW5pdC5maW5pc2gnLCBmdW5jdGlvbiAoKSB7XG4gIHZhciBmb3VuZDtcbiAgaWYgKHR5cGVvZiAoalF1ZXJ5KSAhPSAndW5kZWZpbmVkJykge1xuICAgICQuZm4uU3BhcmtsaW5lID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5TcGFya2xpbmUob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgc3BhcmtsaW5lKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBzcGFya2xpbmUuZHJhdyhvcHRpb25zLCBjYWxsYmFjayk7XG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7IiwiLyoqXG4gKiAgQHRpdGxlIGpvb2xhXG4gKiAgQG92ZXJ2aWV3IHRoZSBvcGVuLXNvdXJjZSBkYXRhIGFuYWx5dGljcyBmcmFtZXdvcmtcbiAqICBAY29weXJpZ2h0IEpvb2xhIFNtYXJ0IFNvbHV0aW9ucywgTHRkLiA8aW5mb0Bqb28ubGE+XG4gKiAgQGxpY2Vuc2UgR1BMLTMuMCsgPGh0dHA6Ly9zcGR4Lm9yZy9saWNlbnNlcy9HUEwtMy4wKz5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgMy4wIG9yIGxhdGVyLlxuICogIFNvbWUgcmlnaHRzIHJlc2VydmVkLiBTZWUgTElDRU5TRSwgQVVUSE9SUy5cbiAqKi9cblxudmFyXG4gIGpvb2xhID0gcmVxdWlyZSgnLi4vaW5kZXgnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKSxcbiAgdXRpbCA9IHJlcXVpcmUoJ3V0aWwnKSxcbiAgYXN5bmMgPSByZXF1aXJlKCdhc3luYycpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpO1xuXG52YXIgVGFibGUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy50eXBlID0gJ3RhYmxlJztcbiAgdGhpcy51dWlkID0gam9vbGEuY29tbW9uLnV1aWQoKTtcbiAgdGhpcy5pbml0aWFsaXplZCA9IGZhbHNlO1xuICB0aGlzLmRhdGEgPSBbXTtcbiAgdGhpcy5zb3J0SW5kZXggPSAtMTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICBjb2xvcnM6IFtdLFxuICAgIG9mZmNvbG9yczogW10sXG4gICAgcGFnaW5nOiB7XG4gICAgICBjdXJyZW50UGFnZTogMSxcbiAgICAgIHNpemVzOiBbMTAsIDI1LCA1MCwgMTAwLCAyNTAsIDUwMCwgMTAwMF0sXG4gICAgICBjdXJyZW50U2l6ZTogMTBcbiAgICB9LFxuICAgIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cInRhYmxlLWNhcHRpb25cIj48L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImNvbnRyb2xzXCI+JyArXG4gICAgJyA8ZGl2IGNsYXNzPVwicHJpbWFyeS1kaW1lbnNpb24tcGlja2VyXCI+PC9kaXY+JyArXG4gICAgJyA8ZGl2IGNsYXNzPVwiYWRkLWRpbWVuc2lvbi1waWNrZXJcIj48L2Rpdj4nICtcbiAgICAnIDxkaXYgY2xhc3M9XCJhZGQtbWV0cmljLXBpY2tlclwiPjwvZGl2PicgK1xuICAgICcgPGRpdiBjbGFzcz1cInNlYXJjaC13cmFwcGVyXCI+JyArXG4gICAgJyAgIDxpbnB1dCBjbGFzcz1cInNlYXJjaFwiIHR5cGU9XCJ0ZXh0XCIgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIi8+JyArXG4gICAgJyA8L2Rpdj4nICtcbiAgICAnIDxkaXYgY2xhc3M9XCJjbGVhcmZpeFwiPjwvZGl2PicgK1xuICAgICc8L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cInRhYmxlLXdyYXBwZXJcIj4nICtcbiAgICAnIDx0YWJsZSBjbGFzcz1cImppbyB0YWJsZVwiPicgK1xuICAgICcgICA8dGhlYWQ+PC90aGVhZD4nICtcbiAgICAnICAgPHRib2R5PjwvdGJvZHk+JyArXG4gICAgJyA8L3RhYmxlPicgK1xuICAgICc8L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cInBhZ2luZ1wiPicgK1xuICAgICcgPGRpdiBjbGFzcz1cInBhZ2luZy13cmFwcGVyXCI+JyArXG4gICAgJyAgIDxkaXYgY2xhc3M9XCJwYWdlLXNpemVcIj4nICtcbiAgICAnICAgICA8c3BhbiBjbGFzcz1cImNhcHRpb25cIj5QYWdlIHNpemU6IDwvc3Bhbj4nICtcbiAgICAnICAgICA8c2VsZWN0PicgK1xuICAgICcgICAgIDwvc2VsZWN0PicgK1xuICAgICcgICA8L2Rpdj4nICtcbiAgICAnIDwvZGl2PicgK1xuICAgICcgPGRpdiBjbGFzcz1cInNob3dpbmdcIj48L2Rpdj4nICtcbiAgICAnIDxkaXYgY2xhc3M9XCJuYXZpZ2F0aW9uXCI+JyArXG4gICAgJyAgIDxkaXYgY2xhc3M9XCJwcmV2IGNoZXZyb24gbGVmdFwiPjwvZGl2PicgK1xuICAgICcgICA8ZGl2IGNsYXNzPVwibmV4dCBjaGV2cm9uIHJpZ2h0XCI+PC9kaXY+JyArXG4gICAgJyA8L2Rpdj4nICtcbiAgICAnPC9kaXY+JyxcbiAgICBxdWVyeTogbnVsbCxcbiAgICBzdHJpbmdzOiB7XG4gICAgICBsb2FkaW5nOiAnTm8gZGF0YSBhdmFpbGFibGUuJyxcbiAgICAgIG5vZGF0YTogJ05vIGRhdGEgYXZhaWxhYmxlLicsXG4gICAgICBub3Rfc2hvd246ICdOb3Qgc2hvd24nXG4gICAgfSxcbiAgICBsaW1pdDogMTAwMCxcbiAgICBoZWFkZXJzOiBmYWxzZSxcbiAgICBpbmNsdWRlX25vdF9zaG93bjogdHJ1ZSxcbiAgICBzdW1tYXJ5OiB7XG4gICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgcGxhY2VtZW50OiAndG9wJ1xuICAgIH1cbiAgfTtcbiAgdGhpcy52ZXJpZnkgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IFtvcHRpb25zXS4nO1xuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkgPSBbc2VsZi5vcHRpb25zLnF1ZXJ5XTtcblxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfTtcblxuICB0aGlzLmVudGVyID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcblxuICB9XG4gIDtcbiAgdGhpcy5leGl0ID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcblxuICB9O1xuICB0aGlzLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG5cbiAgfTtcblxuICB0aGlzLmRlc3Ryb3kgPSBmdW5jdGlvbiAoKSB7XG4gICAgam9vbGEudml6LnN0b3Aoc2VsZik7XG4gICAgT2JqZWN0LmtleXMoc2VsZi5zdW1tYXJpZXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSwgaW5kZXgpIHtcbiAgICAgIHZhciBzdW1tYXJ5ID0gc2VsZi5zdW1tYXJpZXNba2V5XTtcbiAgICAgIHN1bW1hcnkuZGVzdHJveSgpO1xuICAgIH0pO1xuXG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgndGFibGUnKS5lbXB0eSgpO1xuICB9O1xuXG4gIHRoaXMuZmlsdGVyID0gZnVuY3Rpb24gKGRhdGEsIGZpbHRlcikge1xuICAgIHJldHVybiBfLmZpbHRlcihkYXRhLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgICBPYmplY3Qua2V5cyhpdGVtLmRpbWVuc2lvbnMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoaXRlbS5kaW1lbnNpb25zW2tleV0udG9Mb3dlckNhc2UoKS5pbmRleE9mKGZpbHRlci50b0xvd2VyQ2FzZSgpKSA+IC0xKVxuICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH0pO1xuICB9O1xuXG4gIHRoaXMucGFpbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIF9xdWVyeSA9IHNlbGYub3B0aW9ucy5xdWVyeVswXTtcbiAgICB2YXIgJHRhYmxlID0gJCQoJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZmluZCgndGFibGUnKVswXSk7XG4gICAgdmFyICRzZWFyY2ggPSAkJCgkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKS5maW5kKCdpbnB1dC5zZWFyY2gnKVswXSk7XG4gICAgdmFyICR0Ym9keSA9ICQkKCR0YWJsZS5maW5kKCd0Ym9keScpWzBdKTtcbiAgICBpZiAoc2VsZi5kYXRhWzBdLmxlbmd0aCA+IDAgfHwgKHNlbGYuZGF0YS5sZW5ndGggPiAxICYmIHNlbGYuZGF0YVsxXS5sZW5ndGggPiAwKSkge1xuICAgICAgJHRib2R5LmZpbmQoJ3RyLmRhdGEtcm93JykucmVtb3ZlKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuXG4gICAgfVxuXG4gICAgaWYgKHNlbGYuc29ydEluZGV4ID09PSAtMSkge1xuICAgICAgc2VsZi5zb3J0SW5kZXggPSBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5sZW5ndGggKyAxO1xuICAgICAgc2VsZi5zb3J0RGlyID0gJ2Rlc2MnO1xuICAgIH1cblxuICAgIHZhciBzdGFydCA9ICgoc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSAtIDEpICogc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50U2l6ZSkgKyAxO1xuICAgIHZhciBsZW5ndGggPSBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplO1xuICAgIHZhciBzZWFyY2gsIHRleHQ7XG4gICAgaWYgKHNlbGYuZGF0YS5sZW5ndGggPT09IDEpIHtcbiAgICAgIHZhciBfZGF0YTtcbiAgICAgIHZhciBfdG90YWwgPSBbXTtcbiAgICAgIHNlYXJjaCA9ICRzZWFyY2gudmFsKCk7XG4gICAgICBpZiAoc2VhcmNoICYmIHNlYXJjaC5sZW5ndGggPiAyKVxuICAgICAgICBfZGF0YSA9IHNlbGYuZmlsdGVyKHNlbGYuZGF0YVswXSwgc2VhcmNoKTtcbiAgICAgIGVsc2VcbiAgICAgICAgX2RhdGEgPSBzZWxmLmRhdGFbMF07XG4gICAgICBzZWxmLl9kYXRhID0gW107XG4gICAgICBzZWxmLl9kYXRhWzBdID0gX2RhdGEuc2xpY2UoMCk7XG4gICAgICBfZGF0YSA9IF9kYXRhLnNsaWNlKHN0YXJ0IC0gMSwgKHN0YXJ0IC0gMSkgKyBsZW5ndGgpO1xuICAgICAgX2RhdGEuZm9yRWFjaChmdW5jdGlvbiAocG9pbnQpIHtcbiAgICAgICAgLy93ZSBoYXZlIGEgc2ltcGxlIHJvd1xuICAgICAgICB2YXIgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyBwb2ludC5rZXkgKyAnXCI+PC90cj4nKTtcbiAgICAgICAgdmFyIGxhc3RJbmRleCA9IDA7XG4gICAgICAgIF9xdWVyeS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQsIGRpKSB7XG4gICAgICAgICAgbGFzdEluZGV4Kys7XG4gICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBkaW1lbnNpb25cIj48YSBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApO1wiIGNsYXNzPVwiZmlsdGVyXCI+JyArIHBvaW50LmRpbWVuc2lvbnNbZGltZW5zaW9ua2V5XSArICc8L2E+PC90ZD4nKTtcbiAgICAgICAgICAkdGQuZmluZCgnLmZpbHRlcicpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYuZW1pdCgnc2VsZWN0JywgcG9pbnQsIGRpbWVuc2lvbmtleSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGRpID09PSBzZWxmLnNvcnRJbmRleClcbiAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICB9KTtcbiAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICBfcXVlcnkubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtLCBtaSkge1xuICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljXCIgZGF0YS1rZXk9XCInICsgbWV0cmlja2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcG9pbnQubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiPicgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSwgcG9pbnQubWV0YVttZXRyaWNrZXldKSArICcnICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPicgK1xuICAgICAgICAgICc8L3RkPicpO1xuICAgICAgICAgIGlmIChsYXN0SW5kZXggKyBtaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2VsZi5kYXRhLmxlbmd0aCA9PT0gMikge1xuICAgICAgdmFyIF9jb21wYXJlcXVlcnkgPSBzZWxmLm9wdGlvbnMucXVlcnlbMV07XG4gICAgICB2YXIgYmFzZTtcbiAgICAgIHZhciBjb21wYXJlO1xuICAgICAgc2VhcmNoID0gJHNlYXJjaC52YWwoKTtcbiAgICAgIGlmIChzZWFyY2ggJiYgc2VhcmNoLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgYmFzZSA9IHNlbGYuZmlsdGVyKHNlbGYuZGF0YVswXSwgc2VhcmNoKTtcbiAgICAgICAgY29tcGFyZSA9IHNlbGYuZmlsdGVyKHNlbGYuZGF0YVsxXSwgc2VhcmNoKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBiYXNlID0gc2VsZi5kYXRhWzBdO1xuICAgICAgICBjb21wYXJlID0gc2VsZi5kYXRhWzFdO1xuICAgICAgfVxuICAgICAgc2VsZi5fZGF0YSA9IFtdO1xuICAgICAgc2VsZi5fZGF0YVswXSA9IHNlbGYuZGF0YVswXS5zbGljZSgwKTtcbiAgICAgIHNlbGYuX2RhdGFbMV0gPSBzZWxmLmRhdGFbMV0uc2xpY2UoMCk7XG4gICAgICBiYXNlID0gYmFzZS5zbGljZShzdGFydCAtIDEsIChzdGFydCAtIDEpICsgbGVuZ3RoKTtcbiAgICAgIHZhciBoYW5kbGVkID0gW107XG4gICAgICBiYXNlLmZvckVhY2goZnVuY3Rpb24gKHBvaW50LCBpbmRleCkge1xuICAgICAgICBoYW5kbGVkLnB1c2gocG9pbnQua2V5KTtcbiAgICAgICAgdmFyICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgIHZhciBsYXN0SW5kZXggPSAwO1xuICAgICAgICBfcXVlcnkuZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkLCBkaSkge1xuICAgICAgICAgIHZhciBkaW1lbnNpb25rZXkgPSBkLmtleSB8fCBkO1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgZGltZW5zaW9uXCI+PGEgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiBjbGFzcz1cImZpbHRlclwiPicgKyBwb2ludC5kaW1lbnNpb25zW2RpbWVuc2lvbmtleV0gKyAnPC9hPjwvdGQ+Jyk7XG4gICAgICAgICAgbGFzdEluZGV4Kys7XG4gICAgICAgICAgaWYgKGRpID09PSBzZWxmLnNvcnRJbmRleClcbiAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgJHRkLmZpbmQoJy5maWx0ZXInKS5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZWxmLmVtaXQoJ3NlbGVjdCcsIHBvaW50LCBkaW1lbnNpb25rZXkpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWMgZW1wdHlcIj48L3RkPicpO1xuICAgICAgICAgIGlmIChsYXN0SW5kZXggKyBtaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgfSk7XG4gICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcblxuICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3F1ZXJ5LnRpbWVmcmFtZS5zdGFydCkgKyAnIC0gJztcbiAgICAgICAgdGV4dCArPSBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfcXVlcnkudGltZWZyYW1lLmVuZCk7XG4gICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgcG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgZGltZW5zaW9uXCIgY29sc3Bhbj1cIicgKyBfcXVlcnkuZGltZW5zaW9ucy5sZW5ndGggKyAnXCI+JyArIHRleHQgKyAnPC90ZD4nKTtcbiAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuXG4gICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgICAgbGFzdEluZGV4ID0gX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoO1xuICAgICAgICBfcXVlcnkubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtLCBtaSkge1xuICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljXCIgZGF0YS1rZXk9XCInICsgbWV0cmlja2V5ICsgJ1wiIGRhdGEtdmFsdWU9XCInICsgcG9pbnQubWV0cmljc1ttZXRyaWNrZXldICsgJ1wiPicgKyBqb29sYS5jb21tb24uZm9ybWF0TWV0cmljKHBvaW50Lm1ldHJpY3NbbWV0cmlja2V5XSwgcG9pbnQubWV0YVttZXRyaWNrZXldKSArICcnICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPicgK1xuICAgICAgICAgICc8L3RkPicpO1xuICAgICAgICAgIGlmIChsYXN0SW5kZXggKyBtaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGNvbXBhcmVQb2ludCA9IGNvbXBhcmVbaW5kZXhdO1xuICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX2NvbXBhcmVxdWVyeS50aW1lZnJhbWUuc3RhcnQpICsgJyAtICc7XG4gICAgICAgIHRleHQgKz0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX2NvbXBhcmVxdWVyeS50aW1lZnJhbWUuZW5kKTtcbiAgICAgICAgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyAoY29tcGFyZVBvaW50ID8gY29tcGFyZVBvaW50LmtleSA6ICdtaXNzaW5nJykgKyAnXCI+PC90cj4nKTtcbiAgICAgICAgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPicgKyB0ZXh0ICsgJzwvdGQ+Jyk7XG4gICAgICAgICR0ci5hcHBlbmQoJHRkKTtcblxuICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICAgICAgdmFyIG1ldHJpY2tleSA9IG0ua2V5IHx8IG07XG4gICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWMgY29tcGFyZVwiIGRhdGEta2V5PVwiJyArIG1ldHJpY2tleSArICdcIiBkYXRhLXZhbHVlPVwiJyArIChjb21wYXJlUG9pbnQgPyBjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldIDogJ04vQScpICsgJ1wiPicgKyAoY29tcGFyZVBvaW50ID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldLCBjb21wYXJlUG9pbnQubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcnICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPjwvdGQ+Jyk7XG4gICAgICAgICAgaWYgKGxhc3RJbmRleCArIG1pID09PSBzZWxmLnNvcnRJbmRleClcbiAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAkdHIgPSAkJCgnPHRyIGNsYXNzPVwiZGF0YS1yb3dcIiBkYXRhLWlkPVwiJyArIHBvaW50LmtleSArICdcIj48L3RyPicpO1xuICAgICAgICAkdGQgPSAkJCgnPHRkIGNsYXNzPVwiY2FwdGlvbiBjaGFuZ2VcIiBjb2xzcGFuPVwiJyArIF9xdWVyeS5kaW1lbnNpb25zLmxlbmd0aCArICdcIj4lIENoYW5nZTwvdGQ+Jyk7XG4gICAgICAgICR0ci5hcHBlbmQoJHRkKTtcblxuICAgICAgICBfcXVlcnkubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtLCBtaSkge1xuICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgY2hhbmdlXCI+JyArIChwb2ludCAmJiBjb21wYXJlUG9pbnQgPyBqb29sYS5jb21tb24ucGVyY2VudGFnZUNoYW5nZShjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldLCBwb2ludC5tZXRyaWNzW21ldHJpY2tleV0pIDogJ04vQScpICsgJyU8L3RkPicpO1xuICAgICAgICAgIGlmIChsYXN0SW5kZXggKyBtaSA9PT0gc2VsZi5zb3J0SW5kZXgpXG4gICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ3NvcnRlZCcpO1xuICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgfSk7XG4gICAgICAgICR0Ym9keS5hcHBlbmQoJHRyKTtcbiAgICAgIH0pO1xuXG4gICAgICBjb21wYXJlLmZvckVhY2goZnVuY3Rpb24gKGNvbXBhcmVQb2ludCwgaW5kZXgpIHtcbiAgICAgICAgaWYgKGhhbmRsZWQuaW5kZXhPZihjb21wYXJlUG9pbnQua2V5KSA9PT0gLTEpIHtcbiAgICAgICAgICB2YXIgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93XCIgZGF0YS1pZD1cIicgKyBjb21wYXJlUG9pbnQua2V5ICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgX3F1ZXJ5LmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgdmFyIGRpbWVuc2lvbmtleSA9IGQua2V5IHx8IGQ7XG4gICAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiPjxhIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgY2xhc3M9XCJmaWx0ZXJcIj4nICsgY29tcGFyZVBvaW50LmRpbWVuc2lvbnNbZGltZW5zaW9ua2V5XSArICc8L2E+PC90ZD4nKTtcbiAgICAgICAgICAgICR0ZC5maW5kKCcuZmlsdGVyJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3NlbGVjdCcsIGNvbXBhcmVQb2ludCwgZGltZW5zaW9ua2V5KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgbWV0cmljIGVtcHR5XCI+PC90ZD4nKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG5cbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX3F1ZXJ5LnRpbWVmcmFtZS5zdGFydCkgKyAnIC0gJztcbiAgICAgICAgICB0ZXh0ICs9IGpvb2xhLmNvbW1vbi5mb3JtYXREYXRlKF9xdWVyeS50aW1lZnJhbWUuZW5kKTtcbiAgICAgICAgICAkdHIgPSAkJCgnPHRyIGNsYXNzPVwiZGF0YS1yb3dcIiBkYXRhLWlkPVwiJyArIGNvbXBhcmVQb2ludC5rZXkgKyAnXCI+PC90cj4nKTtcbiAgICAgICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPicgKyB0ZXh0ICsgJzwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuXG4gICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWNcIiBkYXRhLWtleT1cIicgKyBtZXRyaWNrZXkgKyAnXCIgZGF0YS12YWx1ZT1cIicgKyAnTi9BJyArICdcIj4nICsgJ04vQScgKyAnJyArXG4gICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJzdW1tYXJ5XCI+PC9zcGFuPicgK1xuICAgICAgICAgICAgJzwvdGQ+Jyk7XG4gICAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICB0ZXh0ID0gam9vbGEuY29tbW9uLmZvcm1hdERhdGUoX2NvbXBhcmVxdWVyeS50aW1lZnJhbWUuc3RhcnQpICsgJyAtICc7XG4gICAgICAgICAgdGV4dCArPSBqb29sYS5jb21tb24uZm9ybWF0RGF0ZShfY29tcGFyZXF1ZXJ5LnRpbWVmcmFtZS5lbmQpO1xuICAgICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgKGNvbXBhcmVQb2ludCA/IGNvbXBhcmVQb2ludC5rZXkgOiAnbWlzc2luZycpICsgJ1wiPjwvdHI+Jyk7XG4gICAgICAgICAgJHRkID0gJCQoJzx0ZCBjbGFzcz1cInZhbHVlIGRpbWVuc2lvblwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPicgKyB0ZXh0ICsgJzwvdGQ+Jyk7XG4gICAgICAgICAgJHRyLmFwcGVuZCgkdGQpO1xuXG4gICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICAgICAgIF9xdWVyeS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgIHZhciBtZXRyaWNrZXkgPSBtLmtleSB8fCBtO1xuICAgICAgICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJ2YWx1ZSBtZXRyaWMgY29tcGFyZVwiIGRhdGEta2V5PVwiJyArIG1ldHJpY2tleSArICdcIiBkYXRhLXZhbHVlPVwiJyArIChjb21wYXJlUG9pbnQgPyBjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldIDogJ04vQScpICsgJ1wiPicgKyAoY29tcGFyZVBvaW50ID8gam9vbGEuY29tbW9uLmZvcm1hdE1ldHJpYyhjb21wYXJlUG9pbnQubWV0cmljc1ttZXRyaWNrZXldLCBjb21wYXJlUG9pbnQubWV0YVttZXRyaWNrZXldKSA6ICdOL0EnKSArICcnICtcbiAgICAgICAgICAgICc8c3BhbiBjbGFzcz1cInN1bW1hcnlcIj48L3NwYW4+PC90ZD4nKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgICR0ciA9ICQkKCc8dHIgY2xhc3M9XCJkYXRhLXJvd1wiIGRhdGEtaWQ9XCInICsgY29tcGFyZVBvaW50LmtleSArICdcIj48L3RyPicpO1xuICAgICAgICAgICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJjYXB0aW9uIGNoYW5nZVwiIGNvbHNwYW49XCInICsgX3F1ZXJ5LmRpbWVuc2lvbnMubGVuZ3RoICsgJ1wiPiUgQ2hhbmdlPC90ZD4nKTtcbiAgICAgICAgICAkdHIuYXBwZW5kKCR0ZCk7XG5cbiAgICAgICAgICBfcXVlcnkubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICB2YXIgbWV0cmlja2V5ID0gbS5rZXkgfHwgbTtcbiAgICAgICAgICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwidmFsdWUgY2hhbmdlXCI+Ti9BPC90ZD4nKTtcbiAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAkdGJvZHkuYXBwZW5kKCR0cik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHNlbGYuaGFuZGxlSGVhZGVycygpO1xuICAgIHNlbGYuc3VtbWFyaXplKCk7XG4gICAgc2VsZi5oYW5kbGVQYWdpbmcoKTtcbiAgfTtcblxuICB0aGlzLmRvbmUgPSBmdW5jdGlvbiAoKSB7XG4gICAgc2VsZi5wYWludCgpO1xuICB9O1xuXG4gIHRoaXMuaGFuZGxlSGVhZGVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbGFzdEluZGV4ID0gMDtcbiAgICBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkLCBpKSB7XG4gICAgICB2YXIgbmFtZSA9IGQubmFtZSB8fCBkLmtleSB8fCBkO1xuICAgICAgdmFyICR0aCA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJ3RhYmxlIHRoJylbaV0pO1xuICAgICAgaWYgKCEkdGguaGFzQ2xhc3MoJ2RpbWVuc2lvbicpKSB7XG4gICAgICAgICR0aC5hZnRlcigkdGguY2xvbmUodHJ1ZSkpO1xuICAgICAgfVxuICAgICAgJHRoLmZpbmQoJy5uYW1lJykudGV4dChuYW1lKTtcbiAgICAgIGlmICghZC5kZXNjcmlwdGlvbilcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5oaWRlKCk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5zaG93KCk7XG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwIHNwYW4nKS50ZXh0KGQuZGVzY3JpcHRpb24pO1xuICAgICAgfVxuICAgICAgbGFzdEluZGV4Kys7XG4gICAgfSk7XG4gICAgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobSwgaSkge1xuICAgICAgdmFyIG5hbWUgPSBtLm5hbWUgfHwgbS5rZXkgfHwgbTtcbiAgICAgIHZhciAkdGggPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCd0YWJsZSB0aCcpW2kgKyBsYXN0SW5kZXhdKTtcbiAgICAgIGlmICghbS5kZXNjcmlwdGlvbilcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5oaWRlKCk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5zaG93KCk7XG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwIHNwYW4nKS50ZXh0KG0uZGVzY3JpcHRpb24pO1xuICAgICAgfVxuICAgICAgJHRoLmZpbmQoJy5uYW1lJykudGV4dChuYW1lKTtcbiAgICB9KTtcblxuICAgIHZhciAkaHRtbCA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyO1xuICAgIHZhciAkdGhlYWQgPSAkJCgkaHRtbC5maW5kKCd0aGVhZCcpKTtcbiAgICB2YXIgJGhlYWRfdHIgPSAkJCgnPHRyIGNsYXNzPVwiY2FwdGlvbnNcIj48L3RyPicpO1xuICAgIGxhc3RJbmRleCA9IDA7XG4gICAgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoZCwgZGkpIHtcbiAgICAgIGxhc3RJbmRleCsrO1xuICAgICAgdmFyICR0aCA9ICQkKCc8dGggY2xhc3M9XCJjYXB0aW9uIGRpbWVuc2lvblwiPjxzcGFuIGNsYXNzPVwibmFtZVwiPjwvc3Bhbj48c3BhbiBjbGFzcz1cImljb24taGVscFwiPjxzcGFuPjwvc3Bhbj48L3NwYW4+PHNwYW4gY2xhc3M9XCJpY29uLWNsb3NlXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwiY2FyZXQtc29ydFwiPjwvc3Bhbj48L3RoPicpO1xuICAgICAgJHRoLmZpbmQoJy5uYW1lJykudGV4dChkLm5hbWUgfHwgZC5rZXkgfHwgZCk7XG4gICAgICBpZiAoZC5hbGxvd3JlbW92ZSkge1xuICAgICAgICAkdGguZmluZCgnLmljb24tY2xvc2UnKS5vZmYoJ2NsaWNrJyk7XG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1jbG9zZScpLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICAgICAgICBxLmRpbWVuc2lvbnMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSwgaSkge1xuICAgICAgICAgICAgICBpZiAoaXRlbS5rZXkgPT09IGQua2V5KVxuICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGluZGV4ID4gLTEpXG4gICAgICAgICAgICAgIHEuZGltZW5zaW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgICAgIHNlbGYuc29ydEluZGV4LS07XG4gICAgICAgICAgc2VsZi5oYW5kbGVNZXRyaWNCb3hlcygpO1xuICAgICAgICAgIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgZWxzZVxuICAgICAgICAkdGguZmluZCgnLmljb24tY2xvc2UnKS5yZW1vdmUoKTtcbiAgICAgIGlmICghZC5kZXNjcmlwdGlvbilcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5oaWRlKCk7XG4gICAgICBlbHNlIHtcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5zaG93KCk7XG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1oZWxwIHNwYW4nKS50ZXh0KGQuZGVzY3JpcHRpb24pO1xuICAgICAgfVxuICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAnKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgfSk7XG4gICAgICAkdGguYXR0cignZGF0YS1zb3J0LWRpcicsIG51bGwpO1xuICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydCcsIG51bGwpO1xuICAgICAgJHRoLmZpbmQoJy5jYXJldC1zb3J0JykucmVtb3ZlQ2xhc3MoJ2ljb24tc29ydC1kZXNjJyk7XG4gICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5yZW1vdmVDbGFzcygnaWNvbi1zb3J0LWFzYycpO1xuICAgICAgaWYgKGRpID09PSBzZWxmLnNvcnRJbmRleCkge1xuICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0JywgdHJ1ZSk7XG4gICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJywgc2VsZi5zb3J0RGlyKTtcbiAgICAgICAgJHRoLmZpbmQoJy5jYXJldC1zb3J0JykuYWRkQ2xhc3MoJ2ljb24tc29ydC0nICsgc2VsZi5zb3J0RGlyKTtcbiAgICAgIH1cbiAgICAgICR0aC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHNlbGYuc29ydEluZGV4ID0gZGk7XG4gICAgICAgIE9iamVjdC5rZXlzKHNlbGYuc3VtbWFyaWVzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXksIGluZGV4KSB7XG4gICAgICAgICAgdmFyIHN1bW1hcnkgPSBzZWxmLnN1bW1hcmllc1trZXldO1xuICAgICAgICAgIHN1bW1hcnkub3B0aW9ucy4kY29udGFpbmVyLnJlbW92ZUNsYXNzKCdzb3J0ZWQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgc2VsZi5kYXRhWzBdID0gXy5zb3J0Qnkoc2VsZi5kYXRhWzBdLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgIHJldHVybiBpdGVtLmRpbWVuc2lvbnNbZC5rZXkgfHwgZF07XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgc29ydERpciA9ICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJykgfHwgJ2Rlc2MnO1xuICAgICAgICBpZiAoc29ydERpciA9PT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgc29ydERpciA9ICdhc2MnO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHNlbGYuZGF0YVswXSA9IF8uc29ydEJ5KHNlbGYuZGF0YVswXSwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICAgIHJldHVybiBpdGVtLmRpbWVuc2lvbnNbZC5rZXkgfHwgZF07XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2VsZi5kYXRhWzBdLnJldmVyc2UoKTtcbiAgICAgICAgICBzb3J0RGlyID0gJ2Rlc2MnO1xuICAgICAgICB9XG4gICAgICAgIHNlbGYuc29ydERpciA9IHNvcnREaXI7XG4gICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoJykuYXR0cignZGF0YS1zb3J0LWRpcicsIG51bGwpO1xuICAgICAgICAkaGVhZF90ci5maW5kKCd0aCcpLmF0dHIoJ2RhdGEtc29ydCcsIG51bGwpO1xuICAgICAgICAkaGVhZF90ci5maW5kKCd0aCAuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtZGVzYycpO1xuICAgICAgICAkaGVhZF90ci5maW5kKCd0aCAuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtYXNjJyk7XG4gICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQnLCB0cnVlKTtcbiAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInLCBzZWxmLnNvcnREaXIpO1xuICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5hZGRDbGFzcygnaWNvbi1zb3J0LScgKyBzZWxmLnNvcnREaXIpO1xuICAgICAgICBzZWxmLnBhaW50KCk7XG4gICAgICB9KTtcbiAgICAgICRoZWFkX3RyLmFwcGVuZCgkdGgpO1xuICAgIH0pO1xuICAgIHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLmZvckVhY2goZnVuY3Rpb24gKG0sIG1pKSB7XG4gICAgICB2YXIgJHRoID0gJCQoJzx0aCBjbGFzcz1cImNhcHRpb24gbWV0cmljXCI+PHNwYW4gY2xhc3M9XCJuYW1lXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwiaWNvbi1oZWxwXCI+PHNwYW4+PC9zcGFuPjwvc3Bhbj48c3BhbiBjbGFzcz1cImljb24tY2xvc2VcIj48L3NwYW4+PHNwYW4gY2xhc3M9XCJjYXJldC1zb3J0XCI+PC9zcGFuPjwvdGg+Jyk7XG4gICAgICAkdGguZmluZCgnLm5hbWUnKS50ZXh0KG0ubmFtZSB8fCBtLmtleSB8fCBtKTtcbiAgICAgIGlmIChtLmFsbG93cmVtb3ZlKSB7XG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1jbG9zZScpLm9mZignY2xpY2snKTtcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWNsb3NlJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxKSB7XG4gICAgICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIHEubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtLCBpKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVtLmtleSA9PT0gbS5rZXkpXG4gICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAtMSlcbiAgICAgICAgICAgICAgcS5tZXRyaWNzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdmFyIF9zdW1tYXJpZXMgPSB7fTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpdGVtID0gc2VsZi5zdW1tYXJpZXNba2V5XTtcbiAgICAgICAgICAgIGlmICgoaXRlbS5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbMF0ua2V5IHx8IGl0ZW0ub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzWzBdKSA9PT0gbS5rZXkpIHtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgX3N1bW1hcmllc1trZXldID0gc2VsZi5zdW1tYXJpZXNba2V5XTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzZWxmLnN1bW1hcmllcyA9IF9zdW1tYXJpZXM7XG4gICAgICAgICAgc2VsZi5kYXRhID0gW107XG4gICAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICAgICAgc2VsZi5zb3J0SW5kZXgtLTtcbiAgICAgICAgICBzZWxmLmhhbmRsZU1ldHJpY0JveGVzKCk7XG4gICAgICAgICAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBlbHNlXG4gICAgICAgICR0aC5maW5kKCcuaWNvbi1jbG9zZScpLnJlbW92ZSgpO1xuICAgICAgaWYgKCFtLmRlc2NyaXB0aW9uKVxuICAgICAgICAkdGguZmluZCgnLmljb24taGVscCcpLmhpZGUoKTtcbiAgICAgIGVsc2Uge1xuICAgICAgICAkdGguZmluZCgnLmljb24taGVscCcpLnNob3coKTtcbiAgICAgICAgJHRoLmZpbmQoJy5pY29uLWhlbHAgc3BhbicpLnRleHQobS5kZXNjcmlwdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAoc2VsZi5zb3J0SW5kZXggPT09IC0xKSB7XG4gICAgICAgIHNlbGYuc29ydEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICBzZWxmLnNvcnREaXIgPSAnZGVzYyc7XG4gICAgICB9XG5cbiAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQtZGlyJywgbnVsbCk7XG4gICAgICAkdGguYXR0cignZGF0YS1zb3J0JywgbnVsbCk7XG4gICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5yZW1vdmVDbGFzcygnaWNvbi1zb3J0LWRlc2MnKTtcbiAgICAgICR0aC5maW5kKCcuY2FyZXQtc29ydCcpLnJlbW92ZUNsYXNzKCdpY29uLXNvcnQtYXNjJyk7XG4gICAgICBpZiAobGFzdEluZGV4ICsgbWkgPT09IHNlbGYuc29ydEluZGV4KSB7XG4gICAgICAgICR0aC5hdHRyKCdkYXRhLXNvcnQnLCB0cnVlKTtcbiAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInLCBzZWxmLnNvcnREaXIpO1xuICAgICAgICAkdGguZmluZCgnLmNhcmV0LXNvcnQnKS5hZGRDbGFzcygnaWNvbi1zb3J0LScgKyBzZWxmLnNvcnREaXIpO1xuICAgICAgfVxuXG4gICAgICAkdGgub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBzZWxmLnNvcnRJbmRleCA9IGxhc3RJbmRleCArIG1pO1xuICAgICAgICBPYmplY3Qua2V5cyhzZWxmLnN1bW1hcmllcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgdmFyIHN1bW1hcnkgPSBzZWxmLnN1bW1hcmllc1trZXldO1xuICAgICAgICAgIHN1bW1hcnkub3B0aW9ucy4kY29udGFpbmVyLnJlbW92ZUNsYXNzKCdzb3J0ZWQnKTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAobS5rZXkgfHwgbSkpXG4gICAgICAgICAgICBzdW1tYXJ5Lm9wdGlvbnMuJGNvbnRhaW5lci5hZGRDbGFzcygnc29ydGVkJyk7XG4gICAgICAgIH0pO1xuICAgICAgICBzZWxmLmRhdGFbMF0gPSBfLnNvcnRCeShzZWxmLmRhdGFbMF0sIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgcmV0dXJuIGl0ZW0ubWV0cmljc1ttLmtleSB8fCBtXTtcbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBzb3J0RGlyID0gJHRoLmF0dHIoJ2RhdGEtc29ydC1kaXInKSB8fCAnZGVzYyc7XG4gICAgICAgIGlmIChzb3J0RGlyID09PSAnZGVzYycpIHtcbiAgICAgICAgICBzb3J0RGlyID0gJ2FzYyc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgc2VsZi5kYXRhWzBdID0gXy5zb3J0Qnkoc2VsZi5kYXRhWzBdLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW0ubWV0cmljc1ttLmtleSB8fCBtXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBzZWxmLmRhdGFbMF0ucmV2ZXJzZSgpO1xuICAgICAgICAgIHNvcnREaXIgPSAnZGVzYyc7XG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5zb3J0RGlyID0gc29ydERpcjtcbiAgICAgICAgJGhlYWRfdHIuZmluZCgndGgnKS5hdHRyKCdkYXRhLXNvcnQtZGlyJywgbnVsbCk7XG4gICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoJykuYXR0cignZGF0YS1zb3J0JywgbnVsbCk7XG4gICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoIC5jYXJldC1zb3J0JykucmVtb3ZlQ2xhc3MoJ2ljb24tc29ydC1kZXNjJyk7XG4gICAgICAgICRoZWFkX3RyLmZpbmQoJ3RoIC5jYXJldC1zb3J0JykucmVtb3ZlQ2xhc3MoJ2ljb24tc29ydC1hc2MnKTtcbiAgICAgICAgJHRoLmF0dHIoJ2RhdGEtc29ydCcsIHRydWUpO1xuICAgICAgICAkdGguYXR0cignZGF0YS1zb3J0LWRpcicsIHNlbGYuc29ydERpcik7XG4gICAgICAgICR0aC5maW5kKCcuY2FyZXQtc29ydCcpLmFkZENsYXNzKCdpY29uLXNvcnQtJyArIHNlbGYuc29ydERpcik7XG4gICAgICAgIHNlbGYucGFpbnQoKTtcbiAgICAgIH0pO1xuICAgICAgJGhlYWRfdHIuYXBwZW5kKCR0aCk7XG4gICAgfSk7XG4gICAgJHRoZWFkLmh0bWwoJGhlYWRfdHIpO1xuICAgICRodG1sLmZpbmQoJ3RhYmxlIHRib2R5JykuYmVmb3JlKCR0aGVhZCk7XG4gIH07XG5cbiAgdGhpcy5oYW5kbGVNZXRyaWNCb3hlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGh0bWwgPSBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICB2YXIgJHRib2R5ID0gJGh0bWwuZmluZCgndGJvZHknKTtcbiAgICAkdGJvZHkgPSAkJCgkdGJvZHkpO1xuICAgIHZhciAkbWV0cmljX3RyID0gJCQoJzx0ciBjbGFzcz1cIm1ldHJpY2JveGVzXCI+PC90cj4nKTtcbiAgICB2YXIgbGFzdEluZGV4ID0gMDtcbiAgICBzZWxmLm9wdGlvbnMucXVlcnlbMF0uZGltZW5zaW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChkKSB7XG4gICAgICB2YXIgJHRkID0gJCQoJzx0ZCBjbGFzcz1cIm1ldHJpY2JveCBkaW1lbnNpb25cIj48L3RkPicpO1xuICAgICAgJG1ldHJpY190ci5hcHBlbmQoJHRkKTtcbiAgICAgIGxhc3RJbmRleCsrO1xuICAgIH0pO1xuXG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICBhc3luYy5tYXBTZXJpZXMoc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3MsIGZ1bmN0aW9uIChtLCBjYikge1xuICAgICAgdmFyICR0ZCA9ICQkKCc8dGQgY2xhc3M9XCJtZXRyaWNib3ggbWV0cmljXCI+PC90ZD4nKTtcbiAgICAgICRtZXRyaWNfdHIuYXBwZW5kKCR0ZCk7XG4gICAgICB2YXIgX3F1ZXJ5ID0gY2UuY2xvbmUoc2VsZi5vcHRpb25zLnF1ZXJ5KTtcbiAgICAgIF9xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxKSB7XG4gICAgICAgIHEuZGltZW5zaW9ucyA9IFtdO1xuICAgICAgICBxLm1ldHJpY3MgPSBbbV07XG4gICAgICAgIGlmICghcS5maWx0ZXIpXG4gICAgICAgICAgcS5maWx0ZXIgPSBbXTtcbiAgICAgICAgaWYgKHEuZmlsdGVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB2YXIgX3EgPSBjZS5jbG9uZShxKTtcbiAgICAgICAgICBfcS5maWx0ZXIgPSBbXTtcbiAgICAgICAgICBfcS50eXBlID0gJ292ZXJhbGwnO1xuICAgICAgICAgIF9xdWVyeS5wdXNoKF9xKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICghc2VsZi5zdW1tYXJpZXMpXG4gICAgICAgIHNlbGYuc3VtbWFyaWVzID0ge307XG4gICAgICBzZWxmLnN1bW1hcmllc1ttLmtleV0gPSBuZXcgam9vbGEudml6Lk1ldHJpYyh7XG4gICAgICAgIGNvbnRhaW5lcjogJHRkLmdldCgwKSxcbiAgICAgICAgY3NzOiBsYXN0SW5kZXggKyBpbmRleCA9PT0gc2VsZi5zb3J0SW5kZXggPyAnc29ydGVkJyA6ICcnLFxuICAgICAgICBxdWVyeTogX3F1ZXJ5XG4gICAgICB9KTtcbiAgICAgIHNlbGYuc3VtbWFyaWVzW20ua2V5XS5vbignZG9uZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgc2VsZi5zdW1tYXJpZXNbbS5rZXldLm9wdGlvbnMuJGNvbnRhaW5lci5hZGRDbGFzcyhsYXN0SW5kZXggKyBpbmRleCA9PT0gc2VsZi5zb3J0SW5kZXggPyAnc29ydGVkJyA6ICcnKTtcbiAgICAgICAgc2VsZi5zdW1tYXJpemUoKTtcbiAgICAgICAgcmV0dXJuIGNiKG51bGwpO1xuICAgICAgfSk7XG4gICAgICBpbmRleCsrO1xuICAgIH0sIGZ1bmN0aW9uIChlcnIsIHJlc3VsdHMpIHtcbiAgICB9KTtcbiAgICBpZiAoJHRib2R5LmZpbmQoJy5tZXRyaWNib3hlcycpLmxlbmd0aCA+IDApXG4gICAgICAkdGJvZHkuZmluZCgnLm1ldHJpY2JveGVzJykucmVwbGFjZVdpdGgoJG1ldHJpY190cik7XG4gICAgZWxzZVxuICAgICAgJCQoJHRib2R5LmZpbmQoJ3RyLmRhdGEtcm93JylbMF0pLmJlZm9yZSgkbWV0cmljX3RyKTtcbiAgfTtcblxuICB0aGlzLmhhbmRsZVBhZ2luZyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJHNob3dpbmcgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuc2hvd2luZycpKTtcblxuICAgIHZhciB0b3RhbCA9IHNlbGYuX2RhdGFbMF0ubGVuZ3RoO1xuICAgIHZhciB0byA9IHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgKiBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplO1xuICAgIGlmICh0byA+IHRvdGFsKVxuICAgICAgdG8gPSB0b3RhbDtcbiAgICB2YXIgc2hvd2luZ1RleHQgPSAoKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgLSAxKSAqIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFNpemUgKyAxKSArICcgLSAnICsgdG8gKyAnIG9mICcgKyB0b3RhbDtcblxuICAgICRzaG93aW5nLnRleHQoc2hvd2luZ1RleHQpO1xuXG4gICAgdmFyICRwcmV2ID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnByZXYnKSk7XG4gICAgdmFyICRuZXh0ID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLm5leHQnKSk7XG4gICAgaWYgKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPiAxKSB7XG4gICAgICAkcHJldi5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICRwcmV2Lm9mZignY2xpY2snKTtcbiAgICAgICRwcmV2Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPiAxKSB7XG4gICAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZS0tO1xuICAgICAgICAgIHNlbGYucGFpbnQoKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgJHByZXYuYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkcHJldi5vZmYoJ2NsaWNrJyk7XG4gICAgfVxuICAgIHZhciBuZXh0SW5kZXggPSAoKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgKSAqIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFNpemUpO1xuICAgIGlmIChuZXh0SW5kZXggPCBzZWxmLl9kYXRhWzBdLmxlbmd0aCkge1xuICAgICAgJG5leHQucmVtb3ZlQ2xhc3MoJ2Rpc2FibGVkJyk7XG4gICAgICAkbmV4dC5vZmYoJ2NsaWNrJyk7XG4gICAgICAkbmV4dC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBuZXh0SW5kZXggPSAoKHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgKSAqIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFNpemUpO1xuICAgICAgICBpZiAobmV4dEluZGV4IDwgc2VsZi5fZGF0YVswXS5sZW5ndGgpIHtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlKys7XG4gICAgICAgICAgc2VsZi5wYWludCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAkbmV4dC5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICRuZXh0Lm9mZignY2xpY2snKTtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5zb3J0ID0gZnVuY3Rpb24gKCkge1xuXG4gIH07XG5cbiAgdGhpcy5zdW1tYXJpemUgPSBmdW5jdGlvbiAoKSB7XG4gICAgT2JqZWN0LmtleXMoc2VsZi5zdW1tYXJpZXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSwgbWluZGV4KSB7XG4gICAgICB2YXIgcmVmID0gc2VsZi5zdW1tYXJpZXNba2V5XTtcbiAgICAgIHZhciBtID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbbWluZGV4XTtcblxuICAgICAgaWYgKChtLmFnZ3JlZ2F0aW9uIHx8ICdzdW0nKSA9PT0gJ3N1bScgJiYgcmVmLmRhdGEubGVuZ3RoID4gMCkge1xuICAgICAgICB2YXIgdG90YWwsIGNvbXBhcmV0b3RhbDtcbiAgICAgICAgaWYgKHJlZi5kYXRhWzBdLmxlbmd0aCA+IDApXG4gICAgICAgICAgdG90YWwgPSByZWYuZGF0YVswXVswXS5tZXRyaWNzW20ua2V5XTtcbiAgICAgICAgaWYgKHJlZi5kYXRhLmxlbmd0aCA+IDEgJiYgcmVmLmRhdGFbMV0ubGVuZ3RoID4gMCAmJiByZWYuZGF0YVsxXS50eXBlICE9PSAnb3ZlcmFsbCcpIHtcbiAgICAgICAgICBjb21wYXJldG90YWwgPSByZWYuZGF0YVsxXVswXS5tZXRyaWNzW20ua2V5XTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgJHN1bW1hcmllcyA9ICQkKCcudmFsdWUubWV0cmljW2RhdGEta2V5PVwiJyArIG0ua2V5ICsgJ1wiXScpO1xuICAgICAgICAkc3VtbWFyaWVzLmVhY2goZnVuY3Rpb24gKGluZGV4LCBzdW1tYXJ5KSB7XG4gICAgICAgICAgdmFyICRzdW1tYXJ5ID0gJCQoc3VtbWFyeSk7XG4gICAgICAgICAgdmFyIHZhbHVlID0gJHN1bW1hcnkuYXR0cignZGF0YS12YWx1ZScpO1xuICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ04vQScpIHtcbiAgICAgICAgICAgICRzdW1tYXJ5LmZpbmQoJ3NwYW4uc3VtbWFyeScpLnRleHQoJyAoTi9BKScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICgkc3VtbWFyeS5oYXNDbGFzcygnY29tcGFyZScpKVxuICAgICAgICAgICAgICB2YWx1ZSA9ICh2YWx1ZSAvIGNvbXBhcmV0b3RhbCAqIDEwMCkudG9GaXhlZCgyKSArICclJztcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgdmFsdWUgPSAodmFsdWUgLyB0b3RhbCAqIDEwMCkudG9GaXhlZCgyKSArICclJztcbiAgICAgICAgICAgICRzdW1tYXJ5LmZpbmQoJ3NwYW4uc3VtbWFyeScpLnRleHQoJyAoJyArIHZhbHVlICsgJyknKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIHRoaXMuZHJhdyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgLy93ZSBkcmF3IHRoZSB0ZW1wbGF0ZSBpbnRvIHRoZSBjb250YWluZXJcbiAgICB2YXIgJGh0bWwgPSAkJChzZWxmLm9wdGlvbnMudGVtcGxhdGUpO1xuICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmh0bWwoJGh0bWwpO1xuICAgIGlmIChzZWxmLm9wdGlvbnMuY2FwdGlvbilcbiAgICAgICQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLmZpbmQoJy50YWJsZS1jYXB0aW9uJykudGV4dChzZWxmLm9wdGlvbnMuY2FwdGlvbik7XG4gICAgLy92aXN1YWxpemF0aW9uIHNwZWNpZmljIGRyYXdpbmdcbiAgICBpZiAoc2VsZi5vcHRpb25zLnBpY2tlcnMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMucHJpbWFyeSAmJiBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmVuYWJsZWQpIHtcbiAgICAgIHZhciAkcHJpbWFyeV9kaW1lbnNpb25fcGlja2VyID0gJCQoJGh0bWwuZmluZCgnLnByaW1hcnktZGltZW5zaW9uLXBpY2tlcicpKTtcbiAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLnByaW1hcnkuY3NzID0gJ3RhYmxlLXBpY2tlcic7XG4gICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmNvbnRhaW5lciA9ICRwcmltYXJ5X2RpbWVuc2lvbl9waWNrZXIuZ2V0KDApO1xuICAgICAgdmFyIGRpbWVuc2lvbiA9IHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zWzBdO1xuICAgICAgaWYgKCFkaW1lbnNpb24ua2V5KVxuICAgICAgICBkaW1lbnNpb24gPSB7a2V5OiBkaW1lbnNpb259O1xuICAgICAgaWYgKCFkaW1lbnNpb24uY29sbGVjdGlvbilcbiAgICAgICAgZGltZW5zaW9uLmNvbGxlY3Rpb24gPSBzZWxmLm9wdGlvbnMucXVlcnlbMF0uY29sbGVjdGlvbjtcbiAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLnByaW1hcnkuc2VsZWN0ZWQgPSBkaW1lbnNpb247XG4gICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LmRpc2FibGVkID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnM7XG4gICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5wcmltYXJ5LnByZWZpeCA9ICdQcmltYXJ5IGRpbWVuc2lvbjogJztcbiAgICAgIHNlbGYucHJpbWFyeV9kaW1lbnNpb25fcGlja2VyID0gbmV3IGpvb2xhLnZpei5EaW1lbnNpb25QaWNrZXIoc2VsZi5vcHRpb25zLnBpY2tlcnMucHJpbWFyeSkub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChkaW1lbnNpb24pIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5LmZvckVhY2goZnVuY3Rpb24gKHEpIHtcbiAgICAgICAgICBpZiAoZGltZW5zaW9uKVxuICAgICAgICAgICAgcS5kaW1lbnNpb25zWzBdID0gZGltZW5zaW9uO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHEuZGltZW5zaW9ucy5zcGxpY2UoMCwgMSk7XG4gICAgICAgIH0pO1xuICAgICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlID0gMTtcbiAgICAgICAgc2VsZi5kYXRhID0gW107XG4gICAgICAgIGpvb2xhLnZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24gJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5lbmFibGVkKSB7XG4gICAgICB2YXIgJGFkZF9kaW1lbnNpb25fcGlja2VyID0gJCQoJGh0bWwuZmluZCgnLmFkZC1kaW1lbnNpb24tcGlja2VyJykpO1xuICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbi5jc3MgPSAndGFibGUtcGlja2VyJztcbiAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24uY29udGFpbmVyID0gJGFkZF9kaW1lbnNpb25fcGlja2VyLmdldCgwKTtcbiAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24uY2FwdGlvbiA9IHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9kaW1lbnNpb24uY2FwdGlvbiB8fCAnQWRkIGRpbWVuc2lvbi4uLic7XG4gICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5hZGRfZGltZW5zaW9uLmRpc2FibGVkID0gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnM7XG4gICAgICBzZWxmLmFkZF9kaW1lbnNpb25fcGlja2VyID0gbmV3IGpvb2xhLnZpei5EaW1lbnNpb25QaWNrZXIoc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX2RpbWVuc2lvbikub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChkaW1lbnNpb24pIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5LmZvckVhY2goZnVuY3Rpb24gKHEpIHtcbiAgICAgICAgICBpZiAoZGltZW5zaW9uKSB7XG4gICAgICAgICAgICBkaW1lbnNpb24uYWxsb3dyZW1vdmUgPSB0cnVlO1xuICAgICAgICAgICAgcS5kaW1lbnNpb25zLnB1c2goZGltZW5zaW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBzZWxmLmRhdGEgPSBbXTtcbiAgICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICAgIHNlbGYuc29ydEluZGV4Kys7XG4gICAgICAgIHNlbGYuaGFuZGxlTWV0cmljQm94ZXMoKTtcbiAgICAgICAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoc2VsZi5vcHRpb25zLnBpY2tlcnMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYyAmJiBzZWxmLm9wdGlvbnMucGlja2Vycy5hZGRfbWV0cmljLmVuYWJsZWQpIHtcbiAgICAgIHZhciAkYWRkX21ldHJpY19waWNrZXIgPSAkJCgkaHRtbC5maW5kKCcuYWRkLW1ldHJpYy1waWNrZXInKSk7XG4gICAgICBzZWxmLm9wdGlvbnMucGlja2Vycy5hZGRfbWV0cmljLmNzcyA9ICd0YWJsZS1waWNrZXInO1xuICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5jb250YWluZXIgPSAkYWRkX21ldHJpY19waWNrZXIuZ2V0KDApO1xuICAgICAgc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5jYXB0aW9uID0gc2VsZi5vcHRpb25zLnBpY2tlcnMuYWRkX21ldHJpYy5jYXB0aW9uIHx8ICdBZGQgbWV0cmljLi4uJztcbiAgICAgIHNlbGYub3B0aW9ucy5waWNrZXJzLmFkZF9tZXRyaWMuZGlzYWJsZWQgPSBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljcztcbiAgICAgIHNlbGYuYWRkX21ldHJpY19waWNrZXIgPSBuZXcgam9vbGEudml6Lk1ldHJpY1BpY2tlcihzZWxmLm9wdGlvbnMucGlja2Vycy5hZGRfbWV0cmljKS5vbignY2hhbmdlJywgZnVuY3Rpb24gKG1ldHJpYykge1xuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocSkge1xuICAgICAgICAgIGlmIChtZXRyaWMpIHtcbiAgICAgICAgICAgIG1ldHJpYy5hbGxvd3JlbW92ZSA9IHRydWU7XG4gICAgICAgICAgICBxLm1ldHJpY3MucHVzaChtZXRyaWMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRQYWdlID0gMTtcbiAgICAgICAgc2VsZi5zb3J0SW5kZXgrKztcbiAgICAgICAgc2VsZi5oYW5kbGVNZXRyaWNCb3hlcygpO1xuICAgICAgICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBzZWxmLm9wdGlvbnMpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHZhciAkdGhlYWQgPSAkJCgkaHRtbC5maW5kKCd0aGVhZCcpKTtcbiAgICAkaHRtbC5maW5kKCd0YWJsZScpLmFwcGVuZCgkdGhlYWQpO1xuXG4gICAgdmFyICR0Ym9keSA9ICRodG1sLmZpbmQoJ3Rib2R5Jyk7XG4gICAgJHRib2R5ID0gJCQoJHRib2R5KTtcbiAgICAkdGJvZHkuZW1wdHkoKTtcblxuICAgIHZhciAkbWV0cmljX3RyID0gJCQoJzx0ciBjbGFzcz1cIm1ldHJpY2JveGVzXCI+PC90cj4nKTtcbiAgICAkdGJvZHkuYXBwZW5kKCRtZXRyaWNfdHIpO1xuICAgIHNlbGYuaGFuZGxlSGVhZGVycygpO1xuICAgIHNlbGYuaGFuZGxlTWV0cmljQm94ZXMoKTtcbiAgICB2YXIgJHRyID0gJCQoJzx0ciBjbGFzcz1cImRhdGEtcm93IGxvYWRpbmdcIj48L3RyPicpO1xuICAgIHZhciAkdGQgPSAkJCgnPHRkIGNsYXNzPVwibG9hZGluZ1wiIGNvbHNwYW49XCInICsgKHNlbGYub3B0aW9ucy5xdWVyeVswXS5kaW1lbnNpb25zLmxlbmd0aCArIHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzLmxlbmd0aCkgKyAnXCI+JyArIHNlbGYub3B0aW9ucy5zdHJpbmdzLmxvYWRpbmcgKyAnPC90ZD4nKTtcbiAgICAkdHIuYXBwZW5kKCR0ZCk7XG4gICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuICAgICRodG1sLmZpbmQoJ3RhYmxlJykuYXBwZW5kKCR0Ym9keSk7XG5cbiAgICB2YXIgJHBhZ2VTaXplID0gJCQoJGh0bWwuZmluZCgnLnBhZ2Utc2l6ZSBzZWxlY3QnKSk7XG4gICAgc2VsZi5vcHRpb25zLnBhZ2luZy5zaXplcy5mb3JFYWNoKGZ1bmN0aW9uIChzaXplKSB7XG4gICAgICB2YXIgJG9wdGlvbiA9ICQkKCc8b3B0aW9uIHZhbHVlPVwiJyArIHNpemUgKyAnXCI+JyArIHNpemUgKyAnPC9vcHRpb24+Jyk7XG4gICAgICAkcGFnZVNpemUuYXBwZW5kKCRvcHRpb24pO1xuICAgIH0pO1xuICAgICRwYWdlU2l6ZS5vbignY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgc2VsZi5vcHRpb25zLnBhZ2luZy5jdXJyZW50UGFnZSA9IDE7XG4gICAgICBzZWxmLm9wdGlvbnMucGFnaW5nLmN1cnJlbnRTaXplID0gcGFyc2VJbnQoJHBhZ2VTaXplLnZhbCgpLCAxMCk7XG4gICAgICBzZWxmLnBhaW50KCk7XG4gICAgfSk7XG5cbiAgICB2YXIgJHNlYXJjaCA9ICQkKCRodG1sLmZpbmQoJ2lucHV0LnNlYXJjaCcpKTtcbiAgICAkc2VhcmNoLm9uKCdrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmICgkc2VhcmNoLnZhbCgpLmxlbmd0aCA+IDIpXG4gICAgICAgIHNlbGYub3B0aW9ucy5wYWdpbmcuY3VycmVudFBhZ2UgPSAxO1xuICAgICAgc2VsZi5wYWludCgpO1xuICAgIH0pO1xuICB9O1xuXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMucXVlcnkgJiYgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5xdWVyeSkpXG4gICAgb3B0aW9ucy5xdWVyeSA9IFtvcHRpb25zLnF1ZXJ5XTtcblxuICBvcHRpb25zLnF1ZXJ5WzBdLnNvcnQgPSBbXG4gICAgW29wdGlvbnMucXVlcnlbMF0ubWV0cmljc1swXS5rZXkgfHwgb3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzWzBdLCAnREVTQyddXG4gIF07XG4vL3dlIGNhbGwgdGhlIGNvcmUgaW5pdGlhbGl6ZSBvcHRpb25cbiAgam9vbGEudml6LmluaXRpYWxpemUoc2VsZiwgb3B0aW9ucyB8fCB7fSk7XG5cbiAgaWYgKHNlbGYub3B0aW9ucy5jb2xvcnMubGVuZ3RoID09PSAwKVxuICAgIHNlbGYub3B0aW9ucy5jb2xvcnMgPSBqb29sYS5jb2xvcnM7XG4gIGlmIChzZWxmLm9wdGlvbnMub2ZmY29sb3JzLmxlbmd0aCA9PT0gMClcbiAgICBzZWxmLm9wdGlvbnMub2ZmY29sb3JzID0gam9vbGEub2ZmY29sb3JzO1xuXG4gIHNlbGYuZHJhdyhudWxsLCBmdW5jdGlvbiAoZXJyLCByZWYpIHtcbiAgICBpZiAoZXJyKVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgam9vbGEudml6Lm9uc2NyZWVuLnB1c2goc2VsZik7XG4gICAgaWYgKCFzZWxmLm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICB2YXIgZWxlbSA9ICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyKS5wYXJlbnQoKTtcbiAgICAgIGlmIChlbGVtLmF0dHIoJ2ppby10eXBlJykgPT0gJ2NhbnZhcycpIHtcbiAgICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcyA9ICQkKGVsZW0pLkNhbnZhcygpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICAgIH1cblxuICAgIC8vd3JhcCB1cFxuICAgIHNlbGYuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgPT09ICdmdW5jdGlvbicpXG4gICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgcmVmKTtcbiAgfSk7XG4gIHJldHVybiBzZWxmO1xufTtcblxuam9vbGEuZXZlbnRzLm9uKCdjb3JlLmluaXQuZmluaXNoJywgZnVuY3Rpb24gKCkge1xuICB2YXIgZm91bmQ7XG4gIGlmICh0eXBlb2YgKGpRdWVyeSkgIT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAkLmZuLlRhYmxlID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgIG9wdGlvbnMgPSB7Zm9yY2U6IGZhbHNlfTtcbiAgICAgIGVsc2UgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KCdmb3JjZScpKVxuICAgICAgICBvcHRpb25zLmZvcmNlID0gdHJ1ZTtcbiAgICAgIHZhciByZXN1bHQgPSBudWxsO1xuICAgICAgdmFyIHV1aWQgPSB0aGlzLmF0dHIoJ2ppby11dWlkJyk7XG4gICAgICBpZiAoIXV1aWQgfHwgb3B0aW9ucy5mb3JjZSkge1xuICAgICAgICBpZiAob3B0aW9ucy5mb3JjZSAmJiB1dWlkKSB7XG4gICAgICAgICAgdmFyIGV4aXN0aW5nID0gbnVsbDtcbiAgICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICAgIGpvb2xhLnZpei5vbnNjcmVlbi5mb3JFYWNoKGZ1bmN0aW9uICh2aXopIHtcbiAgICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGV4aXN0aW5nID0gdml6O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZvdW5kICYmIGV4aXN0aW5nKSB7XG4gICAgICAgICAgICBleGlzdGluZy5kZXN0cm95KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vY3JlYXRlIG5ld1xuICAgICAgICBpZiAoIW9wdGlvbnMpXG4gICAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgICAgICBvcHRpb25zLmNvbnRhaW5lciA9IHRoaXMuZ2V0KDApO1xuICAgICAgICByZXN1bHQgPSBuZXcgam9vbGEudml6LlRhYmxlKG9wdGlvbnMsIGZ1bmN0aW9uIChlcnIsIHRhYmxlKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBpZiAoY2FsbGJhY2spXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdGFibGUpO1xuICAgICAgICB9KS5vcHRpb25zLiRjb250YWluZXI7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgLy9yZXR1cm4gZXhpc3RpbmdcbiAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgam9vbGEudml6Lm9uc2NyZWVuLmZvckVhY2goZnVuY3Rpb24gKHZpeikge1xuICAgICAgICAgIGlmICh2aXoudXVpZCA9PSB1dWlkICYmICFmb3VuZCkge1xuICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzdWx0ID0gdml6O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG4gIH1cbn0pO1xuXG51dGlsLmluaGVyaXRzKFRhYmxlLCBldmVudHMuRXZlbnRFbWl0dGVyKTsiLCIvKipcbiAqICBAdGl0bGUgam9vbGFcbiAqICBAb3ZlcnZpZXcgdGhlIG9wZW4tc291cmNlIGRhdGEgYW5hbHl0aWNzIGZyYW1ld29ya1xuICogIEBjb3B5cmlnaHQgSm9vbGEgU21hcnQgU29sdXRpb25zLCBMdGQuIDxpbmZvQGpvby5sYT5cbiAqICBAbGljZW5zZSBHUEwtMy4wKyA8aHR0cDovL3NwZHgub3JnL2xpY2Vuc2VzL0dQTC0zLjArPlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAzLjAgb3IgbGF0ZXIuXG4gKiAgU29tZSByaWdodHMgcmVzZXJ2ZWQuIFNlZSBMSUNFTlNFLCBBVVRIT1JTLlxuICoqL1xuXG52YXJcbiAgZXZlbnRzID0gcmVxdWlyZSgnZXZlbnRzJyksXG4gIHV0aWwgPSByZXF1aXJlKCd1dGlsJyksXG4gIGNlID0gcmVxdWlyZSgnY2xvbmVleHRlbmQnKSxcbiAgJCQgPSByZXF1aXJlKCdqcXVlcnknKSxcbiAgam9vbGEgPSByZXF1aXJlKCcuLi9pbmRleCcpLFxuICBtb21lbnQgPSByZXF1aXJlKCdtb21lbnQnKSxcbiAgXyA9IHJlcXVpcmUoJ3VuZGVyc2NvcmUnKTtcblxucmVxdWlyZSgndHdpeCcpO1xuXG52YXIgVGltZWxpbmUgPSBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICBpZiAoIWNhbGxiYWNrKVxuICAgIGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gIGpvb2xhLmV2ZW50cy5lbWl0KCd0aW1lbGluZS5pbml0LnN0YXJ0Jyk7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLnR5cGUgPSAndGltZWxpbmUnO1xuICB0aGlzLnV1aWQgPSBqb29sYS5jb21tb24udXVpZCgpO1xuICB0aGlzLmRhdGEgPSBbXTtcbiAgdGhpcy5vcHRpb25zID0ge1xuICAgIGxlZ2VuZDogdHJ1ZSxcbiAgICBjYW52YXM6IG51bGwsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwiY2FwdGlvblwiPjwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwiY2hhcnR3cmFwcGVyXCI+JyArXG4gICAgJyA8ZGl2IGNsYXNzPVwiY29udHJvbHNcIj4nICtcbiAgICAnICAgPGRpdiBjbGFzcz1cInByaW1hcnktbWV0cmljLXBpY2tlclwiPjwvZGl2PicgK1xuICAgICcgICA8ZGl2IGNsYXNzPVwic2VwXCI+dnMuPC9kaXY+JyArXG4gICAgJyAgIDxkaXYgY2xhc3M9XCJzZWNvbmRhcnktbWV0cmljLXBpY2tlclwiPjwvZGl2PicgK1xuICAgICcgPC9kaXY+JyArXG4gICAgJyAnICtcbiAgICAnIDxkaXYgY2xhc3M9XCJ0aGVjaGFydFwiPjwvZGl2PicgK1xuICAgICc8L2Rpdj4nLFxuICAgIGNvbnRhaW5lcjogbnVsbCxcbiAgICAkY29udGFpbmVyOiBudWxsLFxuICAgIHF1ZXJ5OiBudWxsLFxuICAgIHBpY2tlcnM6IHtcbiAgICAgIG1haW46IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICBzZWNvbmRhcnk6IHtlbmFibGVkOiBmYWxzZX1cbiAgICB9XG4gIH07XG4gIHRoaXMuY2hhcnREcmF3biA9IGZhbHNlO1xuXG4gIHRoaXMudmVyaWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IFtvcHRpb25zXS4nO1xuICAgIGlmIChzZWxmLm9wdGlvbnMucXVlcnkpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKVxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkgPSBbc2VsZi5vcHRpb25zLnF1ZXJ5XTtcbiAgICB9XG4gICAgZWxzZVxuICAgICAgcmV0dXJuICdGYWlsZWQgdG8gdmVyaWZ5IHF1ZXJ5IFtvcHRpb25zLnF1ZXJ5XS4nO1xuXG4gICAgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmRpbWVuc2lvbnMgPSBbJ3RpbWVzdGFtcCddO1xuICAgIHJldHVybiBudWxsO1xuICB9O1xuXG4gIHRoaXMuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICBqb29sYS52aXouc3RvcChzZWxmKTtcbiAgICBzZWxmLmluaXRpYWxDaGFydERyYXduID0gZmFsc2U7XG4gICAgJCQoc2VsZi5vcHRpb25zLmNvbnRhaW5lcikuZW1wdHkoKTtcbiAgfTtcblxuICB0aGlzLnJlcGx5ID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBpZiAoc2VsZi5pbml0aWFsQ2hhcnREcmF3biAmJiBzZWxmLm9wdGlvbnMucXVlcnlbMF0ucmVhbHRpbWUgPT09IHRydWUgJiYgc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmludGVydmFsLmluZGV4T2YoJ3NlY29uZCcpID4gLTEpIHtcbiAgICAgIHNlbGYuY2hhcnQuc2VyaWVzLmZvckVhY2goZnVuY3Rpb24gKHNlcmllcywgc2VySW5kZXgpIHtcbiAgICAgICAgc2VyaWVzLmFkZFBvaW50KHt4OiBuZXcgRGF0ZSgpLCB5OiAwfSwgZmFsc2UsIHRydWUsIGZhbHNlKTtcbiAgICAgIH0pO1xuICAgICAgc2VsZi5jaGFydC5yZWRyYXcodHJ1ZSk7XG4gICAgfVxuICB9O1xuXG4gIHRoaXMuZW50ZXIgPSBmdW5jdGlvbiAoZGF0YSwgYWxsZGF0YSkge1xuICAgIGlmIChzZWxmLmNoYXJ0LnNlcmllcy5sZW5ndGggPT09IDApXG4gICAgICByZXR1cm47XG4gICAgaWYgKHNlbGYuZGF0YS5sZW5ndGggPiAxKVxuICAgICAgcmV0dXJuO1xuICAgIE9iamVjdC5rZXlzKGRhdGFbMF0ubWV0cmljcykuZm9yRWFjaChmdW5jdGlvbiAoa2V5LCBwb2ludEluZGV4KSB7XG4gICAgICB2YXIgcG9pbnQgPSBkYXRhWzBdO1xuICAgICAgdmFyIHNlcmllcyA9IHNlbGYuY2hhcnQuc2VyaWVzW3BvaW50SW5kZXhdO1xuICAgICAgc2VyaWVzLmRhdGFbc2VyaWVzLmRhdGEubGVuZ3RoIC0gMV0udXBkYXRlKHBvaW50Lm1ldHJpY3Nba2V5XSk7XG4gICAgfSk7XG4gICAgLy9zZWxmLmNoYXJ0LnJlZHJhdygpO1xuICAgIC8qZXh0cmVtZXNfMCA9IHNlbGYuY2hhcnQueUF4aXNbMF0uZ2V0RXh0cmVtZXMoKTtcbiAgICAgZXh0cmVtZXNfMC5taW4gPSAwO1xuICAgICBleHRyZW1lc18wLm1heCA9IGV4dHJlbWVzXzAuZGF0YU1heCAqIDEuMTtcbiAgICAgaWYgKGV4dHJlbWVzXzAuZGF0YU1pbiA9PT0gMCAmJiBleHRyZW1lc18wLmRhdGFNYXggPT09IDApIHtcbiAgICAgZXh0cmVtZXNfMC5taW4gPSAwO1xuICAgICBleHRyZW1lc18wLm1heCA9IDE7XG4gICAgIH1cblxuICAgICBzZWxmLmNoYXJ0LnlBeGlzWzBdLnNldEV4dHJlbWVzKGV4dHJlbWVzXzAubWluLCBleHRyZW1lc18wLm1heCk7XG4gICAgIGlmIChzZWxmLmNoYXJ0LnlBeGlzLmxlbmd0aCA+IDEpIHtcbiAgICAgZXh0cmVtZXNfMSA9IHNlbGYuY2hhcnQueUF4aXNbMV0uZ2V0RXh0cmVtZXMoKTtcbiAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICBleHRyZW1lc18xLm1heCA9IGV4dHJlbWVzXzEuZGF0YU1heCAqIDEuMTtcbiAgICAgaWYgKGV4dHJlbWVzXzEuZGF0YU1pbiA9PT0gMCAmJiBleHRyZW1lc18xLmRhdGFNYXggPT09IDApIHtcbiAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICBleHRyZW1lc18xLm1heCA9IDE7XG4gICAgIH1cbiAgICAgc2VsZi5jaGFydC55QXhpc1sxXS5zZXRFeHRyZW1lcyhleHRyZW1lc18xLm1pbiwgZXh0cmVtZXNfMS5tYXgpO1xuICAgICB9Ki9cbiAgfTtcblxuICB0aGlzLnVwZGF0ZSA9IGZ1bmN0aW9uIChkYXRhLCBhbGxkYXRhKSB7XG4gICAgaWYgKHNlbGYuY2hhcnQuc2VyaWVzLmxlbmd0aCA9PT0gMClcbiAgICAgIHJldHVybjtcbiAgICBpZiAoc2VsZi5kYXRhLmxlbmd0aCA+IDEpXG4gICAgICByZXR1cm47XG4gICAgT2JqZWN0LmtleXMoZGF0YVswXS5tZXRyaWNzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXksIHBvaW50SW5kZXgpIHtcbiAgICAgIHZhciBwb2ludCA9IGRhdGFbMF07XG4gICAgICB2YXIgc2VyaWVzID0gc2VsZi5jaGFydC5zZXJpZXNbcG9pbnRJbmRleF07XG4gICAgICBzZXJpZXMuZGF0YVtzZXJpZXMuZGF0YS5sZW5ndGggLSAxXS51cGRhdGUocG9pbnQubWV0cmljc1trZXldKTtcbiAgICB9KTtcbiAgICBzZWxmLmNoYXJ0LnJlZHJhdyh0cnVlKTtcbiAgICBleHRyZW1lc18wID0gc2VsZi5jaGFydC55QXhpc1swXS5nZXRFeHRyZW1lcygpO1xuICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICBleHRyZW1lc18wLm1heCA9IGV4dHJlbWVzXzAuZGF0YU1heCAqIDEuMTtcbiAgICBpZiAoZXh0cmVtZXNfMC5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzAuZGF0YU1heCA9PT0gMCkge1xuICAgICAgZXh0cmVtZXNfMC5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMC5tYXggPSAxO1xuICAgIH1cblxuICAgIHNlbGYuY2hhcnQueUF4aXNbMF0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMC5taW4sIGV4dHJlbWVzXzAubWF4KTtcbiAgICBpZiAoc2VsZi5jaGFydC55QXhpcy5sZW5ndGggPiAxKSB7XG4gICAgICBleHRyZW1lc18xID0gc2VsZi5jaGFydC55QXhpc1sxXS5nZXRFeHRyZW1lcygpO1xuICAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMS5tYXggPSBleHRyZW1lc18xLmRhdGFNYXggKiAxLjE7XG4gICAgICBpZiAoZXh0cmVtZXNfMS5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzEuZGF0YU1heCA9PT0gMCkge1xuICAgICAgICBleHRyZW1lc18xLm1pbiA9IDA7XG4gICAgICAgIGV4dHJlbWVzXzEubWF4ID0gMTtcbiAgICAgIH1cbiAgICAgIHNlbGYuY2hhcnQueUF4aXNbMV0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMS5taW4sIGV4dHJlbWVzXzEubWF4KTtcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5leGl0ID0gZnVuY3Rpb24gKGRhdGEsIGFsbGRhdGEpIHtcbiAgICAvL2NvbnNvbGUubG9nKCdleGl0JywgZGF0YSk7XG4gIH07XG5cbiAgdGhpcy5kb25lID0gZnVuY3Rpb24gKGRhdGEsIHJhdykge1xuICAgIGlmIChzZWxmLmluaXRpYWxDaGFydERyYXduKVxuICAgICAgcmV0dXJuO1xuICAgIHNlbGYuaW5pdGlhbENoYXJ0RHJhd24gPSB0cnVlO1xuICAgIHNlbGYuY2hhcnREYXRhID0gc2VsZi5tYWtlQ2hhcnRUaW1lbGluZVNlcmllcyhyYXcpO1xuICAgIHNlbGYucGFpbnQoKTtcbiAgfTtcblxuICB0aGlzLm1ha2VDaGFydFRpbWVsaW5lU2VyaWVzID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICBpZiAobWVzc2FnZVswXS5tZXRyaWNzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6ICdsaW5lJyxcbiAgICAgICAgICBuYW1lOiAnbm8gZGF0YScsXG4gICAgICAgICAgZGF0YTogW11cbiAgICAgICAgfVxuICAgICAgXTtcbiAgICB9XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciB5QXhpcyA9IFtudWxsLCBudWxsXTtcbiAgICB2YXIgc2VyaWVzID0gW107XG4gICAgdmFyIHNlcmllc0luZGV4ID0gLTE7XG4gICAgdmFyIGludGVydmFsID0gQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpID8gc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLmludGVydmFsIDogc2VsZi5vcHRpb25zLnF1ZXJ5LmludGVydmFsO1xuXG4gICAgdmFyIGNoZWNrRXhpc3RzID0gZnVuY3Rpb24gKHRpbWVzdGFtcERpbWVuc2lvbiwgZG9jdW1lbnRzLCBkYXRlKSB7XG4gICAgICByZXR1cm4gXy5maW5kKGRvY3VtZW50cywgZnVuY3Rpb24gKGRvY3VtZW50KSB7XG4gICAgICAgIGlmICghZG9jdW1lbnQudmFsdWVzW3RpbWVzdGFtcERpbWVuc2lvbi5rZXldKVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHZhciBfZGF0ZSA9IG5ldyBEYXRlKGRhdGUpO1xuICAgICAgICAgIHZhciBfYmFzZWRhdGUgPSBuZXcgRGF0ZShkb2N1bWVudC52YWx1ZXNbdGltZXN0YW1wRGltZW5zaW9uLmtleV0pO1xuXG4gICAgICAgICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgX2RhdGUuc2V0SG91cnMoX2RhdGUuZ2V0SG91cnMoKSAtIChfZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjApKTtcbiAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlZGF0ZS5nZXRUaW1lKCkgPT09IF9kYXRlLmdldFRpbWUoKTtcbiAgICAgICAgICAgIGNhc2UgJ21pbnV0ZSc6XG4gICAgICAgICAgICAgIF9iYXNlZGF0ZS5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgICAgICBfYmFzZWRhdGUuc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgICAgICByZXR1cm4gX2Jhc2VkYXRlLmdldFRpbWUoKSA9PT0gX2RhdGUuZ2V0VGltZSgpO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgX2Jhc2VkYXRlLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgcmV0dXJuIF9iYXNlZGF0ZS5nZXRUaW1lKCkgPT09IF9kYXRlLmdldFRpbWUoKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiBfYmFzZWRhdGUuZ2V0VGltZSgpID09PSBfZGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChleCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdleGNlcHRpb24gd2hpbGUgY2hlY2tFeGlzdHMnLCBleCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG4gICAgdmFyIGZpbGwgPSBmdW5jdGlvbiAocmVzdWx0Um93LCByb3csIHRpbWVzdGFtcERpbWVuc2lvbikge1xuICAgICAgT2JqZWN0LmtleXMocmVzdWx0Um93KS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKGtleSAhPT0gdGltZXN0YW1wRGltZW5zaW9uLmtleSkge1xuICAgICAgICAgIHJvdy52YWx1ZXNba2V5XSA9IDA7XG4gICAgICAgICAgcm93LmZ2YWx1ZXNba2V5XSA9IDA7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBtZXNzYWdlLmZvckVhY2goZnVuY3Rpb24gKHJlc3VsdCwgcmVzdWx0SW5kZXgpIHtcbiAgICAgIGlmIChyZXN1bHQuZG9jdW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXN1bHQuZG9jdW1lbnRzLnB1c2goe3ZhbHVlczoge30sIGZ2YWx1ZXM6IHt9fSk7XG4gICAgICAgIHJlc3VsdC5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICByZXN1bHQuZG9jdW1lbnRzWzBdLnZhbHVlc1tkLm5hbWVdID0gbnVsbDtcbiAgICAgICAgICByZXN1bHQuZG9jdW1lbnRzWzBdLmZ2YWx1ZXNbZC5uYW1lXSA9IG51bGw7XG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHQubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgcmVzdWx0LmRvY3VtZW50c1swXS52YWx1ZXNbbS5uYW1lXSA9IG51bGw7XG4gICAgICAgICAgcmVzdWx0LmRvY3VtZW50c1swXS5mdmFsdWVzW20ubmFtZV0gPSBudWxsO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRpbWVuc2lvbnMgPSByZXN1bHQuZGltZW5zaW9ucztcbiAgICAgIHZhciBtZXRyaWNzID0gcmVzdWx0Lm1ldHJpY3M7XG4gICAgICB2YXIgZG9jdW1lbnRzID0gY2UuY2xvbmUocmVzdWx0LmRvY3VtZW50cyk7XG4gICAgICAvL3Nob3VsZCB3ZSBmaWxsIHRoZSBkYXRlIHJhbmdlXG4gICAgICB2YXIgcXVlcnkgPSBjZS5jbG9uZShyZXN1bHQucXVlcnkpO1xuXG4gICAgICB2YXIgdGltZXN0YW1wRGltZW5zaW9uID0gXy5maW5kKHJlc3VsdC5kaW1lbnNpb25zLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICByZXR1cm4gaXRlbS5kYXRhdHlwZSA9PT0gJ2RhdGUnO1xuICAgICAgfSk7XG4gICAgICBpZiAodGltZXN0YW1wRGltZW5zaW9uKSB7XG4gICAgICAgIC8vdmFsaWRhdGUgYW5kIGZpbGwgdGhlIGRhdGUgcmFuZ2U7XG4gICAgICAgIGludGVydmFsID0gaW50ZXJ2YWwgPT09ICdkZGF0ZScgPyAnZGF5JyA6IChpbnRlcnZhbCB8fCAnZGF5Jyk7XG4gICAgICAgIGlmICghcXVlcnkudGltZWZyYW1lKSB7XG4gICAgICAgICAgcXVlcnkudGltZWZyYW1lID0ge307XG4gICAgICAgICAgcXVlcnkudGltZWZyYW1lLnN0YXJ0ID0gcmVzdWx0LmRvY3VtZW50c1tyZXN1bHQuZG9jdW1lbnRzLmxlbmd0aCAtIDFdLnZhbHVlcy50aW1lc3RhbXA7XG4gICAgICAgICAgcXVlcnkudGltZWZyYW1lLmVuZCA9IHJlc3VsdC5kb2N1bWVudHNbMF0udmFsdWVzLnRpbWVzdGFtcDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjb3VudGVyID0gMDtcbiAgICAgICAgdmFyIGZpeGVkID0gW107XG4gICAgICAgIHZhciBpdHIgPSBtb21lbnQudHdpeChxdWVyeS50aW1lZnJhbWUuc3RhcnQsIHF1ZXJ5LnRpbWVmcmFtZS5lbmQpLml0ZXJhdGUoaW50ZXJ2YWwpO1xuICAgICAgICB3aGlsZSAoaXRyLmhhc05leHQoKSAmJiBjb3VudGVyKysgPCAxMDAwKSB7XG4gICAgICAgICAgdmFyIF9kID0gbmV3IERhdGUoaXRyLm5leHQoKS5fZC5nZXRUaW1lKCkpO1xuICAgICAgICAgIHZhciBleGlzdHM7XG4gICAgICAgICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgX2Quc2V0SG91cnMoMCk7XG4gICAgICAgICAgICAgIF9kLnNldFNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIF9kLnNldE1pbGxpc2Vjb25kcygwKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgICBfZC5zZXRTZWNvbmRzKDApO1xuICAgICAgICAgICAgICBfZC5zZXRNaWxsaXNlY29uZHMoMCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgICAgX2Quc2V0TWlsbGlzZWNvbmRzKDApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YXIgb2Zmc2V0ID0gbmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpIC8gNjA7XG4gICAgICAgICAgZXhpc3RzID0gY2hlY2tFeGlzdHModGltZXN0YW1wRGltZW5zaW9uLCByZXN1bHQuZG9jdW1lbnRzLCBfZCk7XG4gICAgICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgICAgIC8vX2Quc2V0SG91cnMoX2QuZ2V0SG91cnMoKSArIChvZmZzZXQgKiAtMSkpO1xuICAgICAgICAgICAgZXhpc3RzID0ge3ZhbHVlczoge30sIGZ2YWx1ZXM6IHt9fTtcbiAgICAgICAgICAgIGV4aXN0cy52YWx1ZXNbdGltZXN0YW1wRGltZW5zaW9uLmtleV0gPSBfZC50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgZXhpc3RzLmZ2YWx1ZXNbdGltZXN0YW1wRGltZW5zaW9uLmtleV0gPSBfZC50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgZmlsbChyZXN1bHQuZG9jdW1lbnRzWzBdLnZhbHVlcywgZXhpc3RzLCB0aW1lc3RhbXBEaW1lbnNpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaXhlZC5wdXNoKGV4aXN0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZG9jdW1lbnRzID0gZml4ZWQ7XG4gICAgICB9XG5cbiAgICAgIGlmICghbWV0cmljcylcbiAgICAgICAgcmV0dXJuIHNlcmllcztcbiAgICAgIG1ldHJpY3MuZm9yRWFjaChmdW5jdGlvbiAobWV0cmljLCBpbmRleCkge1xuICAgICAgICB2YXIgX3lheGlzID0gMDtcbiAgICAgICAgeUF4aXNbaW5kZXggJSAyXSA9IHlBeGlzIFtpbmRleCAlIDJdIHx8IG1ldHJpYy5kZXBlbmRzT24gfHwgbWV0cmljLmtleTtcbiAgICAgICAgaWYgKHlBeGlzWzBdID09PSAoeUF4aXMgW2luZGV4ICUgMl0gfHwgbWV0cmljLmRlcGVuZHNPbiB8fCBtZXRyaWMua2V5KSlcbiAgICAgICAgICBfeWF4aXMgPSAwO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgX3lheGlzID0gMTtcbiAgICAgICAgdmFyIG1ldHJpY19uYW1lID0gbWV0cmljLm5hbWU7XG4gICAgICAgIGlmIChyZXN1bHQucXVlcnkuZmlsdGVyKSB7XG4gICAgICAgICAgcmVzdWx0LnF1ZXJ5LmZpbHRlci5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICBtZXRyaWNfbmFtZSA9IGZbMl0gKyAnOiAnICsgbWV0cmljX25hbWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc2VyaWVzWysrc2VyaWVzSW5kZXhdID0ge1xuICAgICAgICAgIG5hbWU6IG1ldHJpY19uYW1lLFxuICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICAgIHlBeGlzOiBfeWF4aXMsXG4gICAgICAgICAgY29sb3I6IGpvb2xhLmNvbG9yc1tzZXJpZXNJbmRleF1cbiAgICAgICAgfTtcbiAgICAgICAgZG9jdW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGRvY3VtZW50LCBkb2NJbmRleCkge1xuICAgICAgICAgIHZhciB4ID0gZG9jdW1lbnQuZnZhbHVlc1tkaW1lbnNpb25zWzBdLmtleV07XG4gICAgICAgICAgdmFyIG5hbWVCYXNlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKGRpbWVuc2lvbnNbMF0uZGF0YXR5cGUgPT09ICdkYXRlJykge1xuICAgICAgICAgICAgeCA9IG5ldyBEYXRlKGRvY3VtZW50LmZ2YWx1ZXNbZGltZW5zaW9uc1swXS5rZXldKTtcbiAgICAgICAgICAgIG5hbWVCYXNlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChuYW1lQmFzZWQpIHtcbiAgICAgICAgICAgIHNlcmllc1tzZXJpZXNJbmRleF0uZGF0YS5wdXNoKHtcbiAgICAgICAgICAgICAgbmFtZTogeCxcbiAgICAgICAgICAgICAgeTogZG9jdW1lbnQudmFsdWVzW21ldHJpY3NbaW5kZXhdLmtleV0gPyBkb2N1bWVudC52YWx1ZXNbbWV0cmljc1tpbmRleF0ua2V5XSA6IDBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChzZXJpZXNJbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgICBzZXJpZXNbc2VyaWVzSW5kZXhdLmRhdGEucHVzaCh7XG4gICAgICAgICAgICAgICAgeDogeCxcbiAgICAgICAgICAgICAgICB5OiBkb2N1bWVudC52YWx1ZXNbbWV0cmljc1tpbmRleF0ua2V5XSA/IGRvY3VtZW50LnZhbHVlc1ttZXRyaWNzW2luZGV4XS5rZXldIDogMFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICBzZXJpZXNbc2VyaWVzSW5kZXhdLmRhdGEucHVzaCh7XG4gICAgICAgICAgICAgICAgeDogc2VyaWVzWzBdLmRhdGFbZG9jSW5kZXhdLngsXG4gICAgICAgICAgICAgICAgeTogZG9jdW1lbnQudmFsdWVzW21ldHJpY3NbaW5kZXhdLmtleV0gPyBkb2N1bWVudC52YWx1ZXNbbWV0cmljc1tpbmRleF0ua2V5XSA6IDBcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBzZXJpZXM7XG5cbiAgfTtcblxuICB0aGlzLnBhaW50ID0gZnVuY3Rpb24gKHJlc2NhbGUpIHtcbiAgICBzZWxmLmNoYXJ0RGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChzKSB7XG4gICAgICBzZWxmLmNoYXJ0LmFkZFNlcmllcyhzKTtcbiAgICB9KTtcblxuICAgIC8vdmFyIGNvbFdpZHRoID0gKCQkKHNlbGYub3B0aW9ucy5jb250YWluZXIpLndpZHRoKCkgLyBzZWxmLmNoYXJ0RGF0YVswXS5kYXRhLmxlbmd0aCkgKyAxO1xuICAgIC8vY29uc29sZS5sb2coY29sV2lkdGgsIHNlbGYuY2hhcnQpO1xuICAgIC8vc2VsZi5jaGFydC5vcHRpb25zLnBsb3RPcHRpb25zLmNvbHVtbi5wb2ludFdpZHRoID0gY29sV2lkdGg7XG4gICAgc2VsZi5jaGFydC5yZWRyYXcoKTtcbiAgICAvL2lmICghc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLnJlYWx0aW1lIHx8IHJlc2NhbGUpIHtcbiAgICBleHRyZW1lc18wID0gc2VsZi5jaGFydC55QXhpc1swXS5nZXRFeHRyZW1lcygpO1xuICAgIGV4dHJlbWVzXzAubWluID0gMDtcbiAgICBleHRyZW1lc18wLm1heCA9IGV4dHJlbWVzXzAuZGF0YU1heCAqIDEuMTtcbiAgICBpZiAoZXh0cmVtZXNfMC5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzAuZGF0YU1heCA9PT0gMCkge1xuICAgICAgZXh0cmVtZXNfMC5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMC5tYXggPSAxO1xuICAgIH1cblxuICAgIGlmICghc2VsZi5sYXN0X2V4dHJlbWVzXzApXG4gICAgICBzZWxmLmxhc3RfZXh0cmVtZXNfMCA9IGV4dHJlbWVzXzA7XG4gICAgaWYgKHNlbGYubGFzdF9leHRyZW1lc18wLm1pbiAhPT0gZXh0cmVtZXNfMC5taW4gfHwgc2VsZi5sYXN0X2V4dHJlbWVzXzAubWF4ICE9PSBleHRyZW1lc18wLm1heClcbiAgICAgIHNlbGYuY2hhcnQueUF4aXNbMF0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMC5taW4sIGV4dHJlbWVzXzAubWF4KTtcbiAgICBpZiAoc2VsZi5jaGFydC55QXhpcy5sZW5ndGggPiAxKSB7XG4gICAgICBleHRyZW1lc18xID0gc2VsZi5jaGFydC55QXhpc1sxXS5nZXRFeHRyZW1lcygpO1xuICAgICAgZXh0cmVtZXNfMS5taW4gPSAwO1xuICAgICAgZXh0cmVtZXNfMS5tYXggPSBleHRyZW1lc18xLmRhdGFNYXggKiAxLjE7XG4gICAgICBpZiAoZXh0cmVtZXNfMS5kYXRhTWluID09PSAwICYmIGV4dHJlbWVzXzEuZGF0YU1heCA9PT0gMCkge1xuICAgICAgICBleHRyZW1lc18xLm1pbiA9IDA7XG4gICAgICAgIGV4dHJlbWVzXzEubWF4ID0gMTtcbiAgICAgIH1cbiAgICAgIGlmICghc2VsZi5sYXN0X2V4dHJlbWVzXzEpXG4gICAgICAgIHNlbGYubGFzdF9leHRyZW1lc18xID0gZXh0cmVtZXNfMTtcbiAgICAgIGlmIChzZWxmLmxhc3RfZXh0cmVtZXNfMS5taW4gIT09IGV4dHJlbWVzXzEubWluIHx8IHNlbGYubGFzdF9leHRyZW1lc18xLm1heCAhPT0gZXh0cmVtZXNfMS5tYXgpXG4gICAgICAgIHNlbGYuY2hhcnQueUF4aXNbMV0uc2V0RXh0cmVtZXMoZXh0cmVtZXNfMS5taW4sIGV4dHJlbWVzXzEubWF4KTtcbiAgICB9XG4gICAgLy99XG4gIH07XG5cbiAgdGhpcy5kcmF3ID0gZnVuY3Rpb24gKG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gICAgc2VsZi5jaGFydE9wdGlvbnMgPSBqb29sYS5jb21tb24uX21peGluKHt9LCBzZWxmLm9wdGlvbnMuY2hhcnQpO1xuICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmVtcHR5KCk7XG4gICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIuYXBwZW5kKHNlbGYub3B0aW9ucy50ZW1wbGF0ZSB8fCBzZWxmLnRlbXBsYXRlKCkpO1xuICAgIHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5jYXB0aW9uJykudGV4dChzZWxmLm9wdGlvbnMuY2FwdGlvbiB8fCAnJyk7XG5cbiAgICAvL3BpY2tlcnNcbiAgICBpZiAoc2VsZi5vcHRpb25zLnBpY2tlcnMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMubWFpbiAmJiBzZWxmLm9wdGlvbnMucGlja2Vycy5tYWluLmVuYWJsZWQpIHtcbiAgICAgIHZhciAkcHJpbWFyeV9tZXRyaWNfY29udGFpbmVyO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzLm1haW4uY29udGFpbmVyKVxuICAgICAgICAkcHJpbWFyeV9tZXRyaWNfY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLnBpY2tlcnMubWFpbi5jb250YWluZXIpO1xuICAgICAgZWxzZVxuICAgICAgICAkcHJpbWFyeV9tZXRyaWNfY29udGFpbmVyID0gJCQoc2VsZi5vcHRpb25zLiRjb250YWluZXIuZmluZCgnLnByaW1hcnktbWV0cmljLXBpY2tlcicpWzBdKTtcblxuICAgICAgaWYgKCRwcmltYXJ5X21ldHJpY19jb250YWluZXIpIHtcbiAgICAgICAgc2VsZi5wcmltYXJ5X21ldHJpY19jb250YWluZXIgPSBuZXcgam9vbGEudml6Lk1ldHJpY1BpY2tlcih7XG4gICAgICAgICAgY29udGFpbmVyOiAkcHJpbWFyeV9tZXRyaWNfY29udGFpbmVyLFxuICAgICAgICAgIGNhbnZhczogc2VsZi5vcHRpb25zLmNhbnZhcyxcbiAgICAgICAgICBzZWxlY3RlZDogc2VsZi5vcHRpb25zLnF1ZXJ5WzBdLm1ldHJpY3NbMF0sXG4gICAgICAgICAgYWxsb3dSZW1vdmU6IGZhbHNlXG4gICAgICAgIH0sIGZ1bmN0aW9uIChlcnIsIF9waWNrZXIpIHtcbiAgICAgICAgICBpZiAoZXJyKVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIF9waWNrZXIub24oJ2NoYW5nZScsIGZ1bmN0aW9uIChtZXRyaWMpIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGYub3B0aW9ucy5xdWVyeSkpIHtcbiAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5LmZvckVhY2goZnVuY3Rpb24gKHF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgcXVlcnkubWV0cmljc1swXSA9IG1ldHJpYztcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5tZXRyaWNzWzBdID0gbWV0cmljO1xuXG4gICAgICAgICAgICBpZiAoc2VsZi5zZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lcikge1xuICAgICAgICAgICAgICBzZWxmLnNlY29uZGFyeV9tZXRyaWNfY29udGFpbmVyLm9wdGlvbnMuZGlzYWJsZWQgPSBbbWV0cmljXTtcbiAgICAgICAgICAgICAgc2VsZi5zZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lci5tYXJrU2VsZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VsZi5kYXRhID0gW107XG4gICAgICAgICAgICBzZWxmLmNoYXJ0RGF0YSA9IFtdO1xuICAgICAgICAgICAgc2VsZi5pbml0aWFsQ2hhcnREcmF3biA9IGZhbHNlO1xuICAgICAgICAgICAgd2hpbGUgKHNlbGYuY2hhcnQuc2VyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgc2VsZi5jaGFydC5zZXJpZXNbMF0ucmVtb3ZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBzZWxmLm9wdGlvbnMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VsZi5vcHRpb25zLnBpY2tlcnMgJiYgc2VsZi5vcHRpb25zLnBpY2tlcnMuc2Vjb25kYXJ5ICYmIHNlbGYub3B0aW9ucy5waWNrZXJzLnNlY29uZGFyeS5lbmFibGVkKSB7XG4gICAgICB2YXIgJHNlY29uZGFyeV9tZXRyaWNfY29udGFpbmVyO1xuICAgICAgaWYgKHNlbGYub3B0aW9ucy5waWNrZXJzLnNlY29uZGFyeS5jb250YWluZXIpXG4gICAgICAgICRzZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lciA9ICQkKHNlbGYub3B0aW9ucy5waWNrZXJzLnNlY29uZGFyeS5jb250YWluZXIpO1xuICAgICAgZWxzZVxuICAgICAgICAkc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuc2Vjb25kYXJ5LW1ldHJpYy1waWNrZXInKVswXSk7XG5cbiAgICAgIGlmICgkc2Vjb25kYXJ5X21ldHJpY19jb250YWluZXIpIHtcbiAgICAgICAgc2VsZi5zZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lciA9IG5ldyBqb29sYS52aXouTWV0cmljUGlja2VyKHtcbiAgICAgICAgICBjb250YWluZXI6ICRzZWNvbmRhcnlfbWV0cmljX2NvbnRhaW5lcixcbiAgICAgICAgICBjYW52YXM6IHNlbGYub3B0aW9ucy5jYW52YXMsXG4gICAgICAgICAgc2VsZWN0ZWQ6IHNlbGYub3B0aW9ucy5xdWVyeVswXS5tZXRyaWNzWzFdLFxuICAgICAgICAgIGRpc2FibGVkOiBzZWxmLm9wdGlvbnMucXVlcnlbMF0ubWV0cmljc1swXSxcbiAgICAgICAgICBhbGxvd1JlbW92ZTogdHJ1ZVxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyLCBfcGlja2VyKSB7XG4gICAgICAgICAgaWYgKGVycilcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICBfcGlja2VyLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAobWV0cmljKSB7XG4gICAgICAgICAgICBpZiAoIW1ldHJpYykge1xuICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzZWxmLm9wdGlvbnMucXVlcnkpKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5LmZvckVhY2goZnVuY3Rpb24gKHF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgICBxdWVyeS5tZXRyaWNzLnNwbGljZSgxLCAxKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5Lm1ldHJpY3Muc3BsaWNlKDEsIDEpO1xuXG4gICAgICAgICAgICAgIHNlbGYucHJpbWFyeV9tZXRyaWNfY29udGFpbmVyLm9wdGlvbnMuZGlzYWJsZWQgPSBbXTtcbiAgICAgICAgICAgICAgc2VsZi5wcmltYXJ5X21ldHJpY19jb250YWluZXIubWFya1NlbGVjdGVkKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoc2VsZi5vcHRpb25zLnF1ZXJ5KSkge1xuICAgICAgICAgICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeS5mb3JFYWNoKGZ1bmN0aW9uIChxdWVyeSkge1xuICAgICAgICAgICAgICAgICAgcXVlcnkubWV0cmljc1sxXSA9IG1ldHJpYztcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgc2VsZi5vcHRpb25zLnF1ZXJ5Lm1ldHJpY3NbMV0gPSBtZXRyaWM7XG5cbiAgICAgICAgICAgICAgc2VsZi5wcmltYXJ5X21ldHJpY19jb250YWluZXIub3B0aW9ucy5kaXNhYmxlZCA9IFttZXRyaWNdO1xuICAgICAgICAgICAgICBzZWxmLnByaW1hcnlfbWV0cmljX2NvbnRhaW5lci5tYXJrU2VsZWN0ZWQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuZGF0YSA9IFtdO1xuICAgICAgICAgICAgc2VsZi5jaGFydERhdGEgPSBbXTtcbiAgICAgICAgICAgIHNlbGYuaW5pdGlhbENoYXJ0RHJhd24gPSBmYWxzZTtcbiAgICAgICAgICAgIHdoaWxlIChzZWxmLmNoYXJ0LnNlcmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHNlbGYuY2hhcnQuc2VyaWVzWzBdLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBzZWxmLm9wdGlvbnMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5maW5kKCcuc2VwJykpLmhpZGUoKTtcbiAgICAgICQkKHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy5zZWNvbmRhcnktbWV0cmljLXBpY2tlcicpKS5oaWRlKCk7XG4gICAgfVxuXG4gICAgc2VsZi5jaGFydE9wdGlvbnMgPSBqb29sYS5jb21tb24uX21peGluKHtcbiAgICAgIHRpdGxlOiB7XG4gICAgICAgIHRleHQ6IG51bGxcbiAgICAgIH0sXG4gICAgICBjaGFydDoge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgIC8qbWFyZ2luVG9wOiAwLFxuICAgICAgICAgbWFyZ2luQm90dG9tOiAwLFxuICAgICAgICAgbWFyZ2luTGVmdDogMCxcbiAgICAgICAgIG1hcmdpblJpZ2h0OiAwLFxuICAgICAgICAgc3BhY2luZ1RvcDogMCxcbiAgICAgICAgIHNwYWNpbmdCb3R0b206IDAsXG4gICAgICAgICBzcGFjaW5nTGVmdDogMCxcbiAgICAgICAgIHNwYWNpbmdSaWdodDogMCwqL1xuICAgICAgICBib3JkZXJXaWR0aDogMCxcbiAgICAgICAgcGxvdEJvcmRlcldpZHRoOiAwLFxuICAgICAgICB0eXBlOiAnbGluZScsXG4gICAgICAgIGhlaWdodDogc2VsZi5vcHRpb25zLmhlaWdodCB8fCBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci5oZWlnaHQoKSB8fCAyNTAsXG4gICAgICAgIC8vd2lkdGg6IHNlbGYub3B0aW9ucy53aWR0aCB8fCBzZWxmLm9wdGlvbnMuJGNvbnRhaW5lci53aWR0aCgpIHx8IG51bGxcbiAgICAgIH0sXG4gICAgICBsYW5nOiB7XG4gICAgICAgIG5vRGF0YTogJ05vIGRhdGEgdG8gZGlzcGxheSdcbiAgICAgIH0sXG4gICAgICBub0RhdGE6IHtcbiAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCcsXG4gICAgICAgICAgZm9udFNpemU6ICcxNXB4JyxcbiAgICAgICAgICBjb2xvcjogJyMzMDMwMzAnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzZXJpZXM6IFtdLFxuICAgICAgeEF4aXM6IHtcbiAgICAgICAgdHlwZTogJ2RhdGV0aW1lJyxcbiAgICAgICAgZW5kT25UaWNrOiBmYWxzZSxcblxuICAgICAgICB0aWNrV2lkdGg6IDAsXG4gICAgICAgIGRhdGVUaW1lTGFiZWxGb3JtYXRzOiB7XG4gICAgICAgICAgZGF5OiAnJUIgJWUnXG4gICAgICAgIH0sXG4gICAgICAgIGxhYmVsczoge1xuICAgICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgICAgc3RhZ2dlckxpbmVzOiAxLFxuICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICBjb2xvcjogJyNiM2IzYjEnXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgeUF4aXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGVuZE9uVGljazogZmFsc2UsXG4gICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIHRleHQ6IG51bGxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxhYmVsczoge1xuICAgICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgIGNvbG9yOiAnI2IzYjNiMSdcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIGdyaWRMaW5lRGFzaFN0eWxlOiAnRG90J1xuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgZW5kT25UaWNrOiBmYWxzZSxcbiAgICAgICAgICB0aXRsZToge1xuICAgICAgICAgICAgdGV4dDogbnVsbFxuICAgICAgICAgIH0sXG4gICAgICAgICAgbGFiZWxzOiB7XG4gICAgICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgY29sb3I6ICcjYjNiM2IxJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgZ3JpZExpbmVEYXNoU3R5bGU6ICdEb3QnLFxuICAgICAgICAgIGdyaWRMaW5lV2lkdGg6IDAsXG4gICAgICAgICAgb3Bwb3NpdGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgXSxcbiAgICAgIGxlZ2VuZDoge2VuYWJsZWQ6IGZhbHNlfSxcbiAgICAgIGNyZWRpdHM6IHtlbmFibGVkOiBmYWxzZX0sXG4gICAgICBleHBvcnRpbmc6IHtlbmFibGVkOiB0cnVlfSxcbiAgICAgIHBsb3RPcHRpb25zOiB7XG4gICAgICAgIGNvbHVtbjoge1xuICAgICAgICAgIGFsbG93UG9pbnRTZWxlY3Q6IHRydWUsXG4gICAgICAgICAgZ3JvdXBQYWRkaW5nOiAwLjA1LFxuICAgICAgICAgIHBvaW50UGFkZGluZzogMCxcbiAgICAgICAgICBib3JkZXJXaWR0aDogMFxuICAgICAgICB9LFxuICAgICAgICBsaW5lOiB7XG4gICAgICAgICAgLy90dXJib1RocmVzaG9sZDogbWVzc2FnZS5kb2N1bWVudHMgPyBtZXNzYWdlLmRvY3VtZW50cy5sZW5ndGggKyAxMDAwIDogMCxcbiAgICAgICAgICBjb2xvcjogJyMzMzMzMzMnLFxuICAgICAgICAgIGZpbGxPcGFjaXR5OiAwLjEsXG4gICAgICAgICAgbGluZVdpZHRoOiAzLFxuICAgICAgICAgIGNvbm5lY3ROdWxsczogdHJ1ZSxcbiAgICAgICAgICBtYXJrZXI6IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgc3ltYm9sOiAnY2lyY2xlJyxcbiAgICAgICAgICAgIHN0YXRlczoge1xuICAgICAgICAgICAgICBob3Zlcjoge1xuICAgICAgICAgICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIHNlbGYub3B0aW9ucy5jaGFydCk7XG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy4kY29udGFpbmVyKVxuICAgICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICBzZWxmLmNoYXJ0T3B0aW9ucy5jaGFydC5yZW5kZXJUbyA9IHNlbGYub3B0aW9ucy4kY29udGFpbmVyLmZpbmQoJy50aGVjaGFydCcpLmdldCgwKTtcbiAgICBzZWxmLmNoYXJ0ID0gbmV3IEhpZ2hjaGFydHMuQ2hhcnQoc2VsZi5jaGFydE9wdGlvbnMpO1xuICAgIC8vc2VsZi5jaGFydC5zZXRTaXplKCAkJChzZWxmLmNoYXJ0LmNvbnRhaW5lcikucGFyZW50KCkud2lkdGgoKSwgJCQoc2VsZi5jaGFydC5jb250YWluZXIpLnBhcmVudCgpLmhlaWdodCgpICk7XG4gICAgc2VsZi5jaGFydERyYXduID0gdHJ1ZTtcblxuICAgIGlmIChzZWxmLm9wdGlvbnMub25EcmF3KVxuICAgICAgd2luZG93W3NlbGYub3B0aW9ucy5vbkRyYXddKHNlbGYub3B0aW9ucy5jb250YWluZXIsIHNlbGYpO1xuXG4gICAgaWYgKHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgfTtcblxuICAvL2hlcmUgd2UgZ29cbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5xdWVyeSAmJiAhQXJyYXkuaXNBcnJheShvcHRpb25zLnF1ZXJ5KSlcbiAgICBvcHRpb25zLnF1ZXJ5ID0gW29wdGlvbnMucXVlcnldO1xuXG4gIC8vd2UgY2FsbCB0aGUgY29yZSBpbml0aWFsaXplIG9wdGlvblxuICBqb29sYS52aXouaW5pdGlhbGl6ZShzZWxmLCBvcHRpb25zIHx8IHt9KTtcblxuICBzZWxmLmRyYXcobnVsbCwgZnVuY3Rpb24gKGVyciwgcmVmKSB7XG4gICAgaWYgKGVycilcbiAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgIGpvb2xhLnZpei5vbnNjcmVlbi5wdXNoKHNlbGYpO1xuICAgIGlmICghc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgdmFyIGVsZW0gPSAkJChzZWxmLm9wdGlvbnMuJGNvbnRhaW5lcikucGFyZW50KCk7XG4gICAgICBpZiAoZWxlbS5hdHRyKCdqaW8tdHlwZScpID09ICdjYW52YXMnKSB7XG4gICAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMgPSAkJChlbGVtKS5DYW52YXMoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlbGYub3B0aW9ucy5jYW52YXMpIHtcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuYWRkVmlzdWFsaXphdGlvbihzZWxmKTtcbiAgICB9XG5cbiAgICAvL3dyYXAgdXBcbiAgICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrID09PSAnZnVuY3Rpb24nKVxuICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlZik7XG4gIH0pO1xuICByZXR1cm4gc2VsZjtcbn07XG5cbmpvb2xhLmV2ZW50cy5vbignY29yZS5pbml0LmZpbmlzaCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIGZvdW5kO1xuICBpZiAodHlwZW9mIChqUXVlcnkpICE9ICd1bmRlZmluZWQnKSB7XG4gICAgJC5mbi5UaW1lbGluZSA9IGZ1bmN0aW9uIChvcHRpb25zLCBjYWxsYmFjaykge1xuICAgICAgaWYgKCFvcHRpb25zKVxuICAgICAgICBvcHRpb25zID0ge2ZvcmNlOiBmYWxzZX07XG4gICAgICBlbHNlIGlmICghb3B0aW9ucy5oYXNPd25Qcm9wZXJ0eSgnZm9yY2UnKSlcbiAgICAgICAgb3B0aW9ucy5mb3JjZSA9IHRydWU7XG4gICAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICAgIHZhciB1dWlkID0gdGhpcy5hdHRyKCdqaW8tdXVpZCcpO1xuICAgICAgaWYgKCF1dWlkIHx8IG9wdGlvbnMuZm9yY2UpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZm9yY2UgJiYgdXVpZCkge1xuICAgICAgICAgIHZhciBleGlzdGluZyA9IG51bGw7XG4gICAgICAgICAgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgICBpZiAodml6LnV1aWQgPT0gdXVpZCAmJiAhZm91bmQpIHtcbiAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICBleGlzdGluZyA9IHZpejtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChmb3VuZCAmJiBleGlzdGluZykge1xuICAgICAgICAgICAgZXhpc3RpbmcuZGVzdHJveSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvL2NyZWF0ZSBuZXdcbiAgICAgICAgb3B0aW9ucy5jb250YWluZXIgPSB0aGlzLmdldCgwKTtcbiAgICAgICAgcmVzdWx0ID0gbmV3IGpvb2xhLnZpei5UaW1lbGluZShvcHRpb25zLCBmdW5jdGlvbiAoZXJyLCB0aW1lbGluZSkge1xuICAgICAgICAgIGlmIChlcnIpXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgLy90aW1lbGluZS5kcmF3KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICBpZiAoY2FsbGJhY2spXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdGltZWxpbmUpO1xuXG4gICAgICAgIH0pLm9wdGlvbnMuJGNvbnRhaW5lcjtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICAvL3JldHVybiBleGlzdGluZ1xuICAgICAgICBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBqb29sYS52aXoub25zY3JlZW4uZm9yRWFjaChmdW5jdGlvbiAodml6KSB7XG4gICAgICAgICAgaWYgKHZpei51dWlkID09IHV1aWQgJiYgIWZvdW5kKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICByZXN1bHQgPSB2aXo7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfTtcbiAgfVxufSk7XG5cbnV0aWwuaW5oZXJpdHMoVGltZWxpbmUsIGV2ZW50cy5FdmVudEVtaXR0ZXIpOyIsIi8qKlxuICogIEB0aXRsZSBqb29sYVxuICogIEBvdmVydmlldyB0aGUgb3Blbi1zb3VyY2UgZGF0YSBhbmFseXRpY3MgZnJhbWV3b3JrXG4gKiAgQGNvcHlyaWdodCBKb29sYSBTbWFydCBTb2x1dGlvbnMsIEx0ZC4gPGluZm9Aam9vLmxhPlxuICogIEBsaWNlbnNlIEdQTC0zLjArIDxodHRwOi8vc3BkeC5vcmcvbGljZW5zZXMvR1BMLTMuMCs+XG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIDMuMCBvciBsYXRlci5cbiAqICBTb21lIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExJQ0VOU0UsIEFVVEhPUlMuXG4gKiovXG5cbnZhclxuICBqb29sYSA9IHJlcXVpcmUoJy4uL2luZGV4JyksXG4gIGFzeW5jID0gcmVxdWlyZSgnYXN5bmMnKSxcbiAgY2UgPSByZXF1aXJlKCdjbG9uZWV4dGVuZCcpLFxuICBfID0gcmVxdWlyZSgndW5kZXJzY29yZScpLFxuICAkJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xuXG52YXIgdml6ID0gZXhwb3J0cztcbnZpei5faWQgPSAndml6JztcblxuLy9waWNrZXJzXG52aXouRGF0ZVBpY2tlciA9IHJlcXVpcmUoJy4vRGF0ZVBpY2tlcicpO1xudml6Lk1ldHJpY1BpY2tlciA9IHJlcXVpcmUoJy4vTWV0cmljUGlja2VyJyk7XG52aXouRGltZW5zaW9uUGlja2VyID0gcmVxdWlyZSgnLi9EaW1lbnNpb25QaWNrZXInKTtcbnZpei5GaWx0ZXJCb3ggPSByZXF1aXJlKCcuL0ZpbHRlckJveCcpO1xuLy9wYW5lbHNcbnZpei5DYW52YXMgPSByZXF1aXJlKCcuL0NhbnZhcycpO1xuXG4vL2NoYXJ0c1xudml6LlNwYXJrbGluZSA9IHJlcXVpcmUoJy4vU3BhcmtsaW5lJyk7XG52aXouTWV0cmljID0gcmVxdWlyZSgnLi9NZXRyaWMnKTtcbnZpei5HZW8gPSByZXF1aXJlKCcuL0dlbycpO1xudml6LlBpZSA9IHJlcXVpcmUoJy4vUGllJyk7XG52aXouTWluaVRhYmxlID0gcmVxdWlyZSgnLi9NaW5pVGFibGUnKTtcbnZpei5CYXJUYWJsZSA9IHJlcXVpcmUoJy4vQmFyVGFibGUnKTtcbnZpei5QdW5jaENhcmQgPSByZXF1aXJlKCcuL1B1bmNoQ2FyZCcpO1xudml6LlRhYmxlID0gcmVxdWlyZSgnLi9UYWJsZScpO1xudml6LlRpbWVsaW5lID0gcmVxdWlyZSgnLi9UaW1lbGluZScpO1xuXG4vL29uc2NyZWVuXG52aXoub25zY3JlZW4gPSBbXTtcblxudml6Lm1hcmtDb250YWluZXIgPSBmdW5jdGlvbiAoY29udGFpbmVyLCBhdHRyKSB7XG4gIGNvbnRhaW5lciA9ICQkKGNvbnRhaW5lcik7XG4gIGNvbnRhaW5lci5hdHRyKCdqaW8tZG9tYWluJywgJ2pvb2xhJyk7XG4gIGF0dHIgPSBhdHRyLmF0dHIgfHwgYXR0cjtcbiAgYXR0ci5mb3JFYWNoKGZ1bmN0aW9uIChhKSB7XG4gICAgT2JqZWN0LmtleXMoYSkuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnY3NzJyAmJiBhW2tleV0pIHtcbiAgICAgICAgdmFyIGN1cnJlbnRDbGFzc2VzID0gY29udGFpbmVyLmF0dHIoJ2NsYXNzJyk7XG4gICAgICAgIGNvbnRhaW5lci5hdHRyKCdjbGFzcycsIGN1cnJlbnRDbGFzc2VzICsgJyAnICsgYVtrZXldKTtcbiAgICAgIH1cbiAgICAgIGVsc2VcbiAgICAgICAgY29udGFpbmVyLmF0dHIoJ2ppby0nICsga2V5LCBhW2tleV0pO1xuICAgIH0pO1xuICB9KTtcbn07XG5cbnZpei5pbml0aWFsaXplID0gZnVuY3Rpb24gKHNlbGYsIG9wdGlvbnMsIGNhbGxiYWNrKSB7XG4gIGpvb2xhLmNvbW1vbi5taXhpbihzZWxmLm9wdGlvbnMsIG9wdGlvbnMsIHRydWUpO1xuICB2YXIgdmVyaWZpZWQgPSBzZWxmLnZlcmlmeS5hcHBseShzZWxmKTtcbiAgaWYgKHZlcmlmaWVkICE9PSBudWxsKVxuICAgIHRocm93IG5ldyBFcnJvcih2ZXJpZmllZCk7XG4gIGlmICghc2VsZi5pbml0aWFsaXplZCkge1xuICAgIHZpei5tYXJrQ29udGFpbmVyKHNlbGYub3B0aW9ucy5jb250YWluZXIsIFtcbiAgICAgIHt0eXBlOiBzZWxmLnR5cGV9LFxuICAgICAge3V1aWQ6IHNlbGYudXVpZH0sXG4gICAgICB7Y3NzOiBzZWxmLm9wdGlvbnMuY3NzIHx8IG51bGx9XG4gICAgXSk7XG4gICAgc2VsZi5vcHRpb25zLiRjb250YWluZXIgPSAkJChzZWxmLm9wdGlvbnMuY29udGFpbmVyKTtcbiAgICBpZiAoc2VsZi5vcHRpb25zLmNhbnZhcykge1xuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5hZGRWaXN1YWxpemF0aW9uKHNlbGYpO1xuICAgICAgLy9zdWJzY3JpYmUgdG8gZGVmYXVsdCBldmVudHNcbiAgICAgIHNlbGYub3B0aW9ucy5jYW52YXMuc2V0TWF4TGlzdGVuZXJzKDEwMCk7XG4gICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLm9uKCdkYXRlY2hhbmdlJywgZnVuY3Rpb24gKGRhdGVzKSB7XG4gICAgICAgIGlmICghc2VsZi5vcHRpb25zKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKCFzZWxmLm9wdGlvbnMucXVlcnkpXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvL2xldCdzIGNoYW5nZSBvdXIgcXVlcnkgYW5kIGZldGNoIGFnYWluXG4gICAgICAgIHNlbGYub3B0aW9ucy5xdWVyeSA9IGNlLmNsb25lKHNlbGYub3B0aW9ucy5jYW52YXMucHJlcGFyZVF1ZXJ5KHNlbGYub3B0aW9ucy5xdWVyeVswXSwgZGF0ZXMpKTtcbiAgICAgICAgdml6LmRlc3Ryb3koc2VsZiwge2xvYWRpbmc6IHRydWV9KTtcbiAgICAgICAgcmV0dXJuIHZpei5pbml0aWFsaXplKHNlbGYsIHNlbGYub3B0aW9ucyk7XG4gICAgICB9KTtcblxuICAgICAgc2VsZi5vcHRpb25zLmNhbnZhcy5vbignZmlsdGVyY2hhbmdlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXNlbGYub3B0aW9ucylcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICghc2VsZi5vcHRpb25zLnF1ZXJ5KVxuICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBzZWxmLm9wdGlvbnMucXVlcnkuZm9yRWFjaChmdW5jdGlvbiAocXVlcnkpIHtcbiAgICAgICAgICBpZiAoIXF1ZXJ5LmZpbHRlcnMpXG4gICAgICAgICAgICBxdWVyeS5maWx0ZXIgPSBbXTtcbiAgICAgICAgICBzZWxmLm9wdGlvbnMuY2FudmFzLm9wdGlvbnMuZmlsdGVycy5mb3JFYWNoKGZ1bmN0aW9uIChmKSB7XG4gICAgICAgICAgICBmLmZpbHRlcnMuZm9yRWFjaChmdW5jdGlvbiAoZjIpIHtcbiAgICAgICAgICAgICAgcXVlcnkuZmlsdGVyLnB1c2goZjIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICB2aXouZGVzdHJveShzZWxmLCB7bG9hZGluZzogdHJ1ZX0pO1xuICAgICAgICByZXR1cm4gdml6LmluaXRpYWxpemUoc2VsZiwgc2VsZi5vcHRpb25zKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBpZiAoc2VsZi5vcHRpb25zLnF1ZXJ5KSB7XG4gICAgY29uc29sZS5sb2coJ3FxcScsIHNlbGYub3B0aW9ucy5xdWVyeSk7XG4gICAgdml6LmZldGNoKHNlbGYsIHNlbGYub3B0aW9ucy5xdWVyeSwgZnVuY3Rpb24gKCkge1xuICAgICAgaWYgKGNhbGxiYWNrICYmIHR5cGVvZiBjYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHNlbGYpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHNlbGY7XG59O1xuXG52aXoubG9va3VwID0gZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICBpZiAoIWJhc2UpXG4gICAgcmV0dXJuIG51bGw7XG4gIHZhciByZXN1bHQgPSBfLmZpbHRlcihiYXNlLCBmdW5jdGlvbiAoaXRlbSkge1xuICAgIHJldHVybiBpdGVtLmtleSA9PT0ga2V5O1xuICB9KTtcbiAgaWYgKHJlc3VsdC5sZW5ndGggPT09IDApXG4gICAgcmV0dXJuIG51bGw7XG4gIHJldHVybiByZXN1bHRbMF07XG59O1xuXG52aXoubG9va3VwRGF0ZSA9IGZ1bmN0aW9uIChiYXNlLCBpbmRleCkge1xuICByZXR1cm4gYmFzZVtpbmRleF07XG59O1xuXG52aXouZmV0Y2ggPSBmdW5jdGlvbiAoY29udGV4dCwgcXVlcnksIGNhbGxiYWNrKSB7XG4gIGlmICghY29udGV4dC5yZWFsdGltZVF1ZXJpZXMpXG4gICAgY29udGV4dC5yZWFsdGltZVF1ZXJpZXMgPSBbXTtcbiAgaWYgKCFjYWxsYmFjayAmJiBjb250ZXh0ICYmIHF1ZXJ5KSB7XG4gICAgY2FsbGJhY2sgPSBxdWVyeTtcbiAgICBxdWVyeSA9IGNvbnRleHQ7XG4gIH1cbiAgdmFyIF9xdWVyeSA9IGNlLmNsb25lKHF1ZXJ5KTtcbiAgdml6LnN0b3AoY29udGV4dCwgZnVuY3Rpb24gKCkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShfcXVlcnkpKSB7XG4gICAgICBpZiAoY29udGV4dCAmJiBjb250ZXh0Lm9wdGlvbnMgJiYgY29udGV4dC5vcHRpb25zLmNhbnZhcykge1xuICAgICAgICBjb250ZXh0Lm9wdGlvbnMucXVlcnkuaW50ZXJ2YWwgPSBjb250ZXh0Lm9wdGlvbnMucXVlcnkuaW50ZXJ2YWwgfHwgY29udGV4dC5vcHRpb25zLmNhbnZhcy5vcHRpb25zLnF1ZXJ5LmludGVydmFsO1xuICAgICAgICBjb250ZXh0Lm9wdGlvbnMucXVlcnkudGltZWZyYW1lID0gY29udGV4dC5vcHRpb25zLnF1ZXJ5LnRpbWVmcmFtZSB8fCBjb250ZXh0Lm9wdGlvbnMuY2FudmFzLm9wdGlvbnMucXVlcnkudGltZWZyYW1lO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIGlmIChjb250ZXh0ICYmIGNvbnRleHQub3B0aW9ucyAmJiBjb250ZXh0Lm9wdGlvbnMuY2FudmFzKSB7XG4gICAgICAgIGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbCA9IGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS5pbnRlcnZhbCB8fCBjb250ZXh0Lm9wdGlvbnMuY2FudmFzLm9wdGlvbnMucXVlcnkuaW50ZXJ2YWw7XG4gICAgICAgIGNvbnRleHQub3B0aW9ucy5xdWVyeVswXS50aW1lZnJhbWUgPSBjb250ZXh0Lm9wdGlvbnMucXVlcnlbMF0udGltZWZyYW1lIHx8IGNvbnRleHQub3B0aW9ucy5jYW52YXMub3B0aW9ucy5xdWVyeS50aW1lZnJhbWU7XG4gICAgICB9XG4gICAgfVxuICAgIC8vYWRqdXN0IG9mZnNldFxuICAgIGlmIChfcXVlcnkudGltZWZyYW1lICYmIHR5cGVvZiBfcXVlcnkudGltZWZyYW1lID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKF9xdWVyeS50aW1lZnJhbWUuc3RhcnQpXG4gICAgICAgIF9xdWVyeS50aW1lZnJhbWUuc3RhcnQuc2V0SG91cnMoX3F1ZXJ5LnRpbWVmcmFtZS5zdGFydC5nZXRIb3VycygpICsgam9vbGEudGltZXpvbmUoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCkpO1xuICAgICAgaWYgKF9xdWVyeS50aW1lZnJhbWUuZW5kKVxuICAgICAgICBfcXVlcnkudGltZWZyYW1lLmVuZC5zZXRIb3VycyhfcXVlcnkudGltZWZyYW1lLmVuZC5nZXRIb3VycygpICsgam9vbGEudGltZXpvbmUoam9vbGEub3B0aW9ucy50aW1lem9uZU9mZnNldCkpO1xuICAgIH1cbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIGlmIChfcXVlcnkuYXV0aENvbnRleHQpXG4gICAgICBhcmdzLnB1c2goX3F1ZXJ5LmF1dGhDb250ZXh0KTtcbiAgICBhcmdzLnB1c2goX3F1ZXJ5KTtcbiAgICBhcmdzLnB1c2goZnVuY3Rpb24gKGVyciwgbWVzc2FnZXMpIHtcbiAgICAgIGlmIChlcnIpXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSlcbiAgICAgICAgbWVzc2FnZXMgPSBbbWVzc2FnZXNdO1xuXG4gICAgICBpZiAoY29udGV4dC5yZXBseSlcbiAgICAgICAgY29udGV4dC5yZXBseShtZXNzYWdlcywgY29udGV4dC5kYXRhKTtcblxuICAgICAgbWVzc2FnZXMuZm9yRWFjaChmdW5jdGlvbiAobWVzc2FnZSwgbWluZGV4KSB7XG4gICAgICAgIGlmICghY29udGV4dC5kYXRhKVxuICAgICAgICAgIGNvbnRleHQuZGF0YSA9IFtdO1xuICAgICAgICB2YXIgX2RhdGEgPSBbXTtcbiAgICAgICAgaWYgKGNvbnRleHQuZGF0YVttaW5kZXhdKSB7XG4gICAgICAgICAgX2RhdGEgPSBjb250ZXh0LmRhdGFbbWluZGV4XTtcbiAgICAgICAgICBfZGF0YS5mb3JFYWNoKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICBpdGVtLnN0YXRlID0gJ2V4aXQnO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlICYmIG1lc3NhZ2UucXVlcnkgJiYgbWVzc2FnZS5xdWVyeS50cyAmJiBtZXNzYWdlLnF1ZXJ5LnRzLmR1cmF0aW9uKVxuICAgICAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnZmV0Y2ggdG9vazogJyArIG1lc3NhZ2UucXVlcnkudHMuZHVyYXRpb24udG9TdHJpbmcoKSArICdtcywgcmVzdWx0czogJyArIChtZXNzYWdlICYmIG1lc3NhZ2UuZG9jdW1lbnRzID8gbWVzc2FnZS5kb2N1bWVudHMubGVuZ3RoLnRvU3RyaW5nKCkgOiAnbi9hJykpO1xuICAgICAgICBpZiAobWVzc2FnZS5xdWVyeS5yZWFsdGltZVVJRCAmJiBjb250ZXh0LnJlYWx0aW1lUXVlcmllcy5pbmRleE9mKG1lc3NhZ2UucXVlcnkucmVhbHRpbWVVSUQpID09IC0xKVxuICAgICAgICAgIGNvbnRleHQucmVhbHRpbWVRdWVyaWVzLnB1c2gobWVzc2FnZS5xdWVyeS5yZWFsdGltZVVJRCk7XG4gICAgICAgIG1lc3NhZ2UuZG9jdW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGRvYywgZG9jaW5kZXgpIHtcbiAgICAgICAgICBkb2MgPSB7XG4gICAgICAgICAgICBkaW1lbnNpb25zOiB7fSxcbiAgICAgICAgICAgIG1ldHJpY3M6IHt9LFxuICAgICAgICAgICAgbWV0YToge30sXG4gICAgICAgICAgICByYXc6IGNlLmNsb25lKGRvYyksXG4gICAgICAgICAgICBzdGF0ZTogJ2VudGVyJyxcbiAgICAgICAgICAgIHR5cGU6IG1lc3NhZ2UucXVlcnkudHlwZSxcbiAgICAgICAgICAgIHJlYWx0aW1lOiBtZXNzYWdlLnF1ZXJ5LnJlYWx0aW1lXG4gICAgICAgICAgfTtcbiAgICAgICAgICB2YXIga2V5ID0gJyc7XG4gICAgICAgICAgbWVzc2FnZS5kaW1lbnNpb25zLmZvckVhY2goZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIGtleSArPSBkb2MucmF3LnZhbHVlc1tkLmtleV07XG4gICAgICAgICAgICBkb2MuZGltZW5zaW9uc1tkLmtleV0gPSBkb2MucmF3LnZhbHVlc1tkLmtleV07XG4gICAgICAgICAgICBkb2MubWV0YVtkLmtleV0gPSBkO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIG1lc3NhZ2UubWV0cmljcy5mb3JFYWNoKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgICBkb2MubWV0cmljc1ttLmtleV0gPSBkb2MucmF3LnZhbHVlc1ttLmtleV07XG4gICAgICAgICAgICBkb2MubWV0YVttLmtleV0gPSBtO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGRvYy5rZXkgPSBqb29sYS5jb21tb24uaGFzaChrZXkpO1xuICAgICAgICAgIC8vbG9va3VwIGtleVxuICAgICAgICAgIHZhciBleGlzdCA9IHZpei5sb29rdXAoX2RhdGEsIGRvYy5rZXkpO1xuICAgICAgICAgIGlmIChleGlzdCkge1xuICAgICAgICAgICAgdmFyIGRpcnR5ID0gZmFsc2U7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhleGlzdC5tZXRyaWNzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICAgICAgaWYgKGV4aXN0Lm1ldHJpY3Nba2V5XSAhPT0gZG9jLm1ldHJpY3Nba2V5XSkge1xuICAgICAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBleGlzdC5tZXRyaWNzW2tleV0gPSBkb2MubWV0cmljc1trZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChkaXJ0eSlcbiAgICAgICAgICAgICAgZXhpc3Quc3RhdGUgPSAndXBkYXRlJztcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgZXhpc3Quc3RhdGUgPSAnc3RhdGljJztcbiAgICAgICAgICB9XG4gICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBfZGF0YS5wdXNoKGRvYyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29udGV4dC5kYXRhW21pbmRleF0gPSBfZGF0YTtcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgaGFuZGxlZCA9IFtdO1xuICAgICAgY29udGV4dC5kYXRhWzBdLmZvckVhY2goZnVuY3Rpb24gKGRhdGEsIHBvaW50SW5kZXgpIHtcbiAgICAgICAgaGFuZGxlZC5wdXNoKGRhdGEua2V5KTtcbiAgICAgICAgdmFyIHBvaW50ID0gW2RhdGFdO1xuICAgICAgICB2YXIgcGFpcmVkID0ge1xuICAgICAgICAgIG1pc3Npbmc6IHRydWUsXG4gICAgICAgICAgbWV0YTogcG9pbnQubWV0YVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY29udGV4dC5kYXRhLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgIC8vZmluZCB0aGUgcGFpclxuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhkYXRhLmRpbWVuc2lvbnMpLmxlbmd0aCA9PT0gMSAmJiBkYXRhLmRpbWVuc2lvbnMudGltZXN0YW1wKSB7XG4gICAgICAgICAgICBwYWlyZWQgPSBjb250ZXh0LmRhdGFbMV1bcG9pbnRJbmRleF0gfHwgcGFpcmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHBhaXJlZCA9IF8uZmluZChjb250ZXh0LmRhdGFbMV0sIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgICAgICAgIHJldHVybiBpdGVtLmtleSA9PT0gZGF0YS5rZXk7XG4gICAgICAgICAgICB9KSB8fCBwYWlyZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwYWlyZWQgfHwgY29udGV4dC5kYXRhLmxlbmd0aCA+IDEpXG4gICAgICAgICAgICBwb2ludCA9IFtkYXRhLCBwYWlyZWRdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhLnN0YXRlID09PSAnZW50ZXInIHx8IHBhaXJlZC5zdGF0ZSA9PT0gJ2VudGVyJykge1xuICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMuZW50ZXIpXG4gICAgICAgICAgICBjb250ZXh0Lm9wdGlvbnMuZW50ZXIuYXBwbHkoY29udGV4dCwgW3BvaW50LCBjb250ZXh0LmRhdGFdKTtcbiAgICAgICAgICBjb250ZXh0LmVudGVyKHBvaW50LCBjb250ZXh0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRhdGEuc3RhdGUgPT09ICd1cGRhdGUnIHx8IHBhaXJlZC5zdGF0ZSA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgICBpZiAoY29udGV4dC5vcHRpb25zLnVwZGF0ZSlcbiAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy51cGRhdGUuYXBwbHkoY29udGV4dCwgW3BvaW50LCBjb250ZXh0LmRhdGFdKTtcbiAgICAgICAgICBjb250ZXh0LnVwZGF0ZShwb2ludCwgY29udGV4dC5kYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkYXRhLnN0YXRlID09PSAnZXhpdCcgfHwgcGFpcmVkLnN0YXRlID09PSAnZXhpdCcpIHtcbiAgICAgICAgICBjb250ZXh0LmRhdGFbMF0uc3BsaWNlKHBvaW50SW5kZXgsIDEpO1xuICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMuZXhpdClcbiAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy5leGl0LmFwcGx5KGNvbnRleHQsIFtwb2ludCwgY29udGV4dC5kYXRhXSk7XG4gICAgICAgICAgY29udGV4dC5leGl0KHBvaW50LCBjb250ZXh0LmRhdGEpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChjb250ZXh0LmRhdGEubGVuZ3RoID4gMSkge1xuICAgICAgICBjb250ZXh0LmRhdGFbMV0uZm9yRWFjaChmdW5jdGlvbiAoZGF0YSwgcG9pbnRJbmRleCkge1xuICAgICAgICAgIGlmIChoYW5kbGVkLmluZGV4T2YoZGF0YS5rZXkpID09PSAtMSkge1xuICAgICAgICAgICAgdmFyIHBhaXJlZCA9IGRhdGE7XG4gICAgICAgICAgICB2YXIgcG9pbnQgPSBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBtaXNzaW5nOiB0cnVlLFxuICAgICAgICAgICAgICAgIG1ldGE6IHBhaXJlZC5tZXRhXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGRhdGFcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIGlmIChkYXRhLnN0YXRlID09PSAnZW50ZXInIHx8IHBhaXJlZC5zdGF0ZSA9PT0gJ2VudGVyJykge1xuICAgICAgICAgICAgICBpZiAoY29udGV4dC5vcHRpb25zLmVudGVyKVxuICAgICAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy5lbnRlci5hcHBseShjb250ZXh0LCBbcG9pbnQsIGNvbnRleHQuZGF0YV0pO1xuICAgICAgICAgICAgICBjb250ZXh0LmVudGVyKHBvaW50LCBjb250ZXh0LmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZGF0YS5zdGF0ZSA9PT0gJ3VwZGF0ZScgfHwgcGFpcmVkLnN0YXRlID09PSAndXBkYXRlJykge1xuICAgICAgICAgICAgICBpZiAoY29udGV4dC5vcHRpb25zLnVwZGF0ZSlcbiAgICAgICAgICAgICAgICBjb250ZXh0Lm9wdGlvbnMudXBkYXRlLmFwcGx5KGNvbnRleHQsIFtwb2ludCwgY29udGV4dC5kYXRhXSk7XG4gICAgICAgICAgICAgIGNvbnRleHQudXBkYXRlKHBvaW50LCBjb250ZXh0LmRhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZGF0YS5zdGF0ZSA9PT0gJ2V4aXQnIHx8IHBhaXJlZC5zdGF0ZSA9PT0gJ2V4aXQnKSB7XG4gICAgICAgICAgICAgIGNvbnRleHQuZGF0YVsxXS5zcGxpY2UocG9pbnRJbmRleCwgMSk7XG4gICAgICAgICAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMuZXhpdClcbiAgICAgICAgICAgICAgICBjb250ZXh0Lm9wdGlvbnMuZXhpdC5hcHBseShjb250ZXh0LCBbcG9pbnQsIGNvbnRleHQuZGF0YV0pO1xuICAgICAgICAgICAgICBjb250ZXh0LmV4aXQocG9pbnQsIGNvbnRleHQuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjb250ZXh0Lm9wdGlvbnMuZG9uZSlcbiAgICAgICAgY29udGV4dC5vcHRpb25zLmRvbmUuYXBwbHkoY29udGV4dCwgY29udGV4dC5kYXRhKTtcbiAgICAgIGlmIChjb250ZXh0LmRvbmUpXG4gICAgICAgIGNvbnRleHQuZG9uZShjb250ZXh0LmRhdGEsIG1lc3NhZ2VzKTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBjb250ZXh0LmRhdGEpO1xuICAgIH0pO1xuXG4gICAgLy9jb25zb2xlLmxvZygncScsIGFyZ3MpO1xuICAgIGpvb2xhLnF1ZXJ5LmZldGNoLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xuICB9KTtcbn07XG5cbnZpei5zdG9wID0gZnVuY3Rpb24gKHNlbGYsIGNhbGxiYWNrKSB7XG4gIGlmICghY2FsbGJhY2spXG4gICAgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgaWYgKHNlbGYucmVhbHRpbWVRdWVyaWVzKSB7XG4gICAgYXN5bmMubWFwKHNlbGYucmVhbHRpbWVRdWVyaWVzLCBmdW5jdGlvbiAocSwgY2FsbGJhY2spIHtcbiAgICAgIGpvb2xhLmxvZ2dlci5kZWJ1ZygnU3RvcHBpbmcgcmVhbHRpbWUgcXVlcnkgWycgKyBxICsgJ10uJyk7XG4gICAgICBqb29sYS5xdWVyeS5zdG9wKHEsIGNhbGxiYWNrKTtcbiAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICBpZiAoZXJyKVxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICB9KTtcbiAgfVxuICBlbHNlXG4gICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xufTtcblxudml6LmRlc3Ryb3kgPSBmdW5jdGlvbiAoc2VsZiwgdml6T3B0aW9ucykge1xuICBpZiAoc2VsZi5yZWFsdGltZVF1ZXJpZXMpIHtcbiAgICBzZWxmLnJlYWx0aW1lUXVlcmllcy5mb3JFYWNoKGZ1bmN0aW9uIChxKSB7XG4gICAgICBqb29sYS5sb2dnZXIuZGVidWcoJ1N0b3BwaW5nIHJlYWx0aW1lIHF1ZXJ5IFsnICsgcSArICddLicpO1xuICAgICAgam9vbGEucXVlcnkuc3RvcChxKTtcbiAgICB9KTtcbiAgfVxuICBzZWxmLmluaXRpYWxpemVkID0gZmFsc2U7XG4gIHNlbGYuZGF0YSA9IFtdO1xuICBzZWxmLmRlc3Ryb3koKTtcbiAgc2VsZi5kcmF3KHZpek9wdGlvbnMpO1xuICBzZWxmLmluaXRpYWxpemVkID0gdHJ1ZTtcbn07XG5cbi8vdGhpcyBpcyBhIG1hZ2ljIGZ1bmN0aW9uIGZvciBwaWNraW5nIHVwIG5hbWVzcGFjZSdkIGl0ZW1zXG4vKlxuIGpvb2xhLm9uKCdyZWFkeScsIGZ1bmN0aW9uIChlcnIpIHtcbiBpZiAoZXJyKVxuIHJldHVybjtcblxuIE9iamVjdC5rZXlzKGpvb2xhLnZpeikuZm9yRWFjaChmdW5jdGlvbiAoa2V5KSB7XG4gdmFyIHZpc3VhbGl6YXRpb24gPSBqb29sYS52aXpba2V5XTtcbiB2YXIgam9vbGFfZWxlbWVudHMgPSAkJCgnam9vbGFcXFxcOicgKyBrZXkudG9Mb3dlckNhc2UoKSk7XG4gaWYgKGpvb2xhX2VsZW1lbnRzLmxlbmd0aCA+IDApIHtcbiAkLmVhY2goam9vbGFfZWxlbWVudHMsIGZ1bmN0aW9uIChpbmRleCwgZWxlbWVudCkge1xuIHZhciAkZWxlbWVudCA9ICQkKGVsZW1lbnQpO1xuIC8vY2hlY2sgbm90IG5lc3RlZCB1bmRlciBhIGNhbnZhc1xuIGlmICgkZWxlbWVudC5wYXJlbnRzKCdqb29sYVxcXFw6Y2FudmFzJykubGVuZ3RoID09PSAwKSB7XG4gdmFyIGF0dHJpYnV0ZXMgPSAkZWxlbWVudC5nZXQoMCkuYXR0cmlidXRlcztcbiB2YXIgb3B0aW9ucyA9IHtcbiBjb250YWluZXI6ICRlbGVtZW50XG4gfTtcbiBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiB2YXIgYXR0cmlidXRlID0gYXR0cmlidXRlc1tpXTtcblxuIHZhciB2YWx1ZSA9IG51bGw7XG4gdHJ5IHtcbiB2YWx1ZSA9IEpTT04ucGFyc2UoYXR0cmlidXRlLnZhbHVlKTtcbiB9XG4gY2F0Y2ggKGV4KSB7XG4gdHJ5IHtcbiB2YWx1ZSA9IEpTT04ucGFyc2UoYXR0cmlidXRlLnZhbHVlLnJlcGxhY2UoL1xcJy9pZywgJ1wiJykpO1xuIH1cbiBjYXRjaCAoZXgyKSB7XG4gdmFsdWUgPSBhdHRyaWJ1dGUudmFsdWU7XG4gfVxuIH1cbiBqb29sYS5jb21tb24uZmxhdEdldFNldChvcHRpb25zLCBhdHRyaWJ1dGUubmFtZSwgdmFsdWUpO1xuIH1cbiBuZXcgdmlzdWFsaXphdGlvbihvcHRpb25zKTtcbiB9XG4gfSk7XG4gfVxuIH0pO1xuIH0pOyovIl19 +; \ No newline at end of file diff --git a/build/release/joola.min.css b/build/release/joola.min.css index 98e79b7..5ca64d1 100644 --- a/build/release/joola.min.css +++ b/build/release/joola.min.css @@ -1,2 +1,2 @@ -/*! joola.sdk - v0.8.1 - 2014-12-30 */ +/*! joola.sdk - v0.8.1 - 2015-01-07 */ [jio-domain=joola]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border-collapse:collapse;border-spacing:0}[jio-domain=joola]{font-family:Signika,helvetica,arial,sans-serif}[jio-domain=joola] .clearfix{clear:both}[jio-domain=joola] .btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}[jio-domain=joola] .btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.428571429;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;color:#333;background-color:#fff;border-color:#ccc}[jio-domain=joola] .btn:hover,.btn:focus{color:#333;text-decoration:none}[jio-domain=joola] .btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}[jio-domain=joola] .btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}[jio-domain=joola] .btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}[jio-domain=joola] .btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}[jio-domain=joola] .btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}[jio-domain=joola] .btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}[jio-domain=joola] .btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}[jio-domain=joola] .btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}[jio-domain=joola] .btn-group>.btn:first-child{margin-left:0}[jio-domain=joola] .btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}[jio-domain=joola] .unselectable{-moz-user-select:-moz-none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}[jio-domain=joola] .line-separator{height:1px}[jio-domain=joola] .chevron::before{border-style:solid;border-width:.25em .25em 0 0;content:'';display:inline-block;height:.45em;left:.15em;position:relative;transform:rotate(-45deg);width:.45em}[jio-domain=joola] .chevron.right:before{left:-.15em;transform:rotate(45deg)}[jio-domain=joola] .chevron.bottom:before{top:0;transform:rotate(135deg)}[jio-domain=joola] .chevron.left:before{transform:rotate(-135deg)}[jio-domain=joola] span.icon-help{position:relative;display:inline}[jio-domain=joola] span.icon-help span{position:absolute;width:150px;color:#FFF;background:#000;height:30px;line-height:30px;text-align:center;visibility:hidden;border-radius:6px;padding-left:5px;padding-right:5px;font-size:12px}[jio-domain=joola] span.icon-help span:after{content:'';position:absolute;bottom:100%;left:48%;margin-left:-8px;width:0;height:0;border-bottom:8px solid #000;border-right:8px solid transparent;border-left:8px solid transparent}[jio-domain=joola] span:hover.icon-help span{visibility:visible;opacity:.8;top:30px;left:48%;margin-left:-76px;z-index:999}[jio-type=bartable] .table{margin-bottom:10px;width:100%}[jio-type=bartable] .table tr{vertical-align:top}[jio-type=bartable] .table td{padding-top:8px;padding-bottom:5px}[jio-type=bartable] .table tr:first-of-type td{text-overflow:ellipsis;padding-top:5px;padding-bottom:5px;white-space:nowrap;overflow:hidden;min-width:100px}[jio-type=bartable] .table td .caption{text-overflow:ellipsis;line-height:17px;color:#666;font-weight:500;text-transform:uppercase;white-space:nowrap;overflow:hidden}[jio-type=bartable] .table td .subcaption{color:#999;font-size:12px;font-weight:400;line-height:1;text-transform:uppercase;margin-top:2px}[jio-type=bartable] .table.table-striped tbody>tr:nth-child(even)>td{background-color:#fff}[jio-type=bartable] .bartable-caption{line-height:1.2857142857em;margin:20px 0;padding:0;text-transform:uppercase;font-size:18px;font-weight:400;color:#333;text-align:center}[jio-type=bartable] .nodata,[jio-type=bartable] .loading{text-align:center}[jio-type=bartable] .barwrapper{float:left;width:95%}[jio-type=bartable] .barwrapper.compare .tablebar{height:15px}[jio-type=bartable] .barwrapper.compare .tablebar.compare_ratio{margin-top:1px}[jio-type=bartable] .tablebar{background-color:#058dc7;float:left;height:30px}[jio-type=bartable] tr[data-selectable=true] td{cursor:pointer}[jio-type=bartable] tr[data-selectable=true]:hover{background-color:#efefef}[jio-type=bartable] tr[data-selectable=true].active td{background-color:#efefef}[jio-type=datepicker]{float:right}[jio-type=datepicker] a{color:#428bca;text-decoration:none}[jio-type=datepicker] .jcontainer{background-color:#fff;border:1px solid #CCC;cursor:pointer;position:relative;z-index:19;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px}[jio-type=datepicker] .jcontainer:hover{border:1px solid #CCC}[jio-type=datepicker] .expanded{border:1px solid #CCC;border-bottom:1px solid #fff;border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;-webkit-border-top-left-radius:5px;-webkit-border-top-right-radius:5px;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:0}[jio-type=datepicker] .picker.compare{margin-top:17px}[jio-type=datepicker] .datetable{border-collapse:collapse}[jio-type=datepicker] .datetable .dates{padding:5px;text-align:left}[jio-type=datepicker] .datetable .dates .datelabel{color:#1C2E3D}[jio-type=datepicker] .datetable .dates .compare{color:#999;font-size:13px}[jio-type=datepicker] .datetable .dates .compare .datelabel.fromdate,[jio-type=datepicker] .datetable .dates .compare .datelabel.todate{font-size:13px;color:#333}[jio-type=datepicker] .datebox .dropdownmarker-wrapper{width:25px;background-color:#f5f5f5}[jio-type=datepicker] .datetable .dropdownmarker{position:absolute;top:12px;right:8px;display:block;width:0;height:0;content:"";border:5px solid;border-right-color:transparent;border-left-color:transparent;border-bottom-color:transparent;border-top-color:inherit}[jio-type=datepicker].compare .datetable .dropdownmarker{top:20px}[jio-type=datepicker] .datebox.expanded .datetable .dropdownmarker{top:5px;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;border-bottom-color:inherit}[jio-type=datepicker].compare .datebox.expanded .datetable .dropdownmarker{top:13px}[jio-type=datepicker] .picker{position:absolute;background-color:#F7F7F7;border:1px solid #CCC;margin-left:1px;margin-top:-1px;padding:10px;white-space:nowrap;z-index:1000;border-radius:5px 0 5px 5px;-moz-border-radius:5px 0 5px 5px;-webkit-border-bottom-left-radius:5px;-webkit-border-bottom-right-radius:5px}[jio-type=datepicker] .picker .wrapper .control{padding:0 10px;white-space:nowrap;vertical-align:top}[jio-type=datepicker] .picker .wrapper .control .optionscontainer{display:block;clear:both;padding:5px;font-size:16px;line-height:20px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .customdate{font-weight:700;margin-bottom:3px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .customdate select{border:#9A9A9A solid 1px;background-color:#fff;color:#000}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .customdate select.selector{width:auto;height:auto;padding:1px;margin-bottom:5px;margin-left:6px;width:120px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption span{top:-2px;position:relative}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .daterange .dateoption{border:#ccc solid 1px;cursor:pointer;width:6.5em;line-height:20px;padding:2px;padding-left:5px;margin-bottom:6px;margin-left:2px;margin-right:2px;margin-top:2px;font-size:16px;font-family:Signika,helvetica,arial,sans-serif}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .daterange .dateoption.active{border:#07C solid 3px;margin-top:0;margin-bottom:4px;margin-left:2px;margin-right:2px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .comparerange .dateoption.active{border:#86BE2B solid 3px;margin-bottom:4px;margin-left:2px;margin-right:2px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .daterange .dateoption.invalid{border:#B00 solid 3px;margin-bottom:4px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption{padding:3px;white-space:nowrap;padding-right:22px;display:none;margin-bottom:3px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption .checker{}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption.visible{display:block}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .divider{border-top:#666 dotted 1px;margin-top:3px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .buttons{padding-top:15px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .apply{margin-top:-15px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .cancel{text-decoration:underline;color:#24B;cursor:pointer;padding-left:10px}[jio-type=datepicker] .picker .wrapper .calendars{white-space:nowrap;margin:2px;width:405px}[jio-type=datepicker] .picker .wrapper .calendars table{border-collapse:collapse}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev,[jio-type=datepicker] .picker .wrapper .calendars .datetable-next{vertical-align:top}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div,[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div{border:#CCC solid 1px;background-color:#DDD;cursor:pointer}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div{border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;-webkit-border-top-left-radius:3px;-webkit-border-top-right-radius:0;-webkit-border-bottom-left-radius:3px;-webkit-border-bottom-right-radius:0}[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div{border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;-webkit-border-top-left-radius:0;-webkit-border-top-right-radius:3px;-webkit-border-bottom-left-radius:0;-webkit-border-bottom-right-radius:3px}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div div.inline-block,[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div div.inline-block{height:9px;padding:0;width:4px}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div div.inline-block{display:block;width:0;height:0;content:"";border:5px solid;border-left-color:transparent;border-top-color:transparent;border-bottom-color:transparent;margin-right:6px;margin-top:-5px}[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div div.inline-block{display:block;width:0;height:0;content:"";border:5px solid;border-right-color:transparent;border-top-color:transparent;border-bottom-color:transparent;margin-left:6px;margin-top:-5px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer input,[jio-type=datepicker] .picker .wrapper .control .optionscontainer textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:none;-moz-transition:border linear .1s,box-shadow linear .1s;-ms-transition:border linear .1s,box-shadow linear .1s;-o-transition:border linear .1s,box-shadow linear .1s;transition:border linear .1s,box-shadow linear .1s}[jio-type=datepicker] .picker .wrapper .calendars .ui-datepicker-prev,[jio-type=datepicker] .picker .wrapper .calendars .ui-datepicker-next{display:none}[jio-type=datepicker] .ui-datepicker-calendar td{border-bottom:#F7F7F7 solid 1px;border-right:#F7F7F7 solid 1px;background-color:#fff}[jio-type=datepicker] .ui-datepicker-title{text-align:center;background-color:#DDD;font-size:85%;color:#07C;cursor:default;border-bottom:#CCC solid 1px;height:18px}[jio-type=datepicker] .daycell{text-align:center;padding:2px 3px;vertical-align:middle;font-size:72%;cursor:pointer}[jio-type=datepicker] .daycell a{text-decoration:none}[jio-type=datepicker] .daycell:hover{background-color:#FC3}[jio-type=datepicker] .daycell.disabled,[jio-type=datepicker] .daycell.ui-state-disabled{cursor:default;color:#DDD;font-weight:400;background-color:#fff}[jio-type=datepicker] .daycell.inrange{background-color:#07C}[jio-type=datepicker] .daycell.inrange:hover{background-color:#FC3}[jio-type=datepicker] .daycell.inrange a{color:#fff}[jio-type=datepicker] .daycell.compare.disabled{cursor:default;color:#DDD;font-weight:400;background-color:#fff}[jio-type=datepicker] .daycell.compare.inrange{background-color:#86BE2B}[jio-type=datepicker] .daycell.basencompare.inrange{background-color:#00B1AB}[jio-type=datepicker] .daycell.compare.inrange:hover{background-color:#FC3}[jio-type=datepicker] .ui-datepicker-calendar th{text-align:center;padding:2px 3px;vertical-align:middle;font-size:80%;border-bottom:#F7F7F7 solid 1px;border-right:#F7F7F7 solid 1px;background-color:#fff;cursor:default;border-bottom:#CCC solid 1px}[jio-type=datepicker] .jcontainer{background:0}[jio-type=datepicker] select{display:inline-block;float:none;height:auto;margin-top:auto;width:auto}[jio-type=datepicker] .daterange{padding-left:0!important}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption .checker{top:4px;margin-left:0}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .compareoption{font-weight:300}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .customdate{font-weight:300}[jio-type=datepicker] .daycell{font-size:11px;font-weight:300;line-height:22px}[jio-type=datepicker] .daycell a{color:#08c;border-bottom:0}.ui-datepicker-calendar th{font-weight:600;line-height:22px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .apply{margin-top:-5px;font-family:Signika,helvetica,arial,sans-serif;background-color:#6d6d6d;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0%,#6d6d6d),color-stop(100%,#1a1a1a));background-image:-webkit-linear-gradient(top,#6d6d6d,#1a1a1a);background-image:-moz-linear-gradient(to bottom,#6d6d6d,#1a1a1a);background-image:-o-linear-gradient(top,#6d6d6d,#1a1a1a);background-image:linear-gradient(top,#6d6d6d,#1a1a1a);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, StartColorStr='#6d6d6d', EndColorStr='#1a1a1a');border:1px solid #4c4c4c;border-bottom:0;border-radius:5px;color:#fff;text-shadow:0 -1px 0 #272727;font-size:.875em;height:28px;line-height:26px;padding:1px 10px;text-transform:uppercase}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .apply:hover{background-color:#7f7f7f;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0%,#7f7f7f),color-stop(100%,#1a1a1a));background-image:-webkit-linear-gradient(top,#7f7f7f,#1a1a1a);background-image:-moz-linear-gradient(to bottom,#7f7f7f,#1a1a1a);background-image:-o-linear-gradient(top,#7f7f7f,#1a1a1a);background-image:linear-gradient(top,#7f7f7f,#1a1a1a);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, StartColorStr='#7f7f7f', EndColorStr='#1a1a1a')}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div,[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div{padding-top:14px;height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}[jio-type=datepicker] .picker .wrapper .calendars .datetable-prev div div.inline-block,[jio-type=datepicker] .picker .wrapper .calendars .datetable-next div div.inline-block{}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .customdate{display:none}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .divider{display:none}[jio-type=datepicker] ._buttons{bottom:15px;position:absolute;right:25px}[jio-type=datepicker] .picker .wrapper .control .optionscontainer input,[jio-type=datepicker] .picker .wrapper .control .optionscontainer textarea{-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none}[jio-type=datepicker] .picker .wrapper .control .optionscontainer .daterange .dateoption.active{margin-left:2px;margin-right:2px}[jio-type=datepicker] .picker .wrapper .calendars{padding-top:5px}[jio-type=datepicker] .ui-datepicker-title{height:28px;color:#666;padding-bottom:4px;padding-top:7px;font-weight:300;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}[jio-type=dimensionpicker]{float:left;position:relative}[jio-type=dimensionpicker] .picker-container{position:absolute;background-color:#fff;display:none;border:1px solid #ddd;padding:5px;z-index:1000}[jio-type=dimensionpicker] .picker-container.active{display:block}[jio-type=dimensionpicker] .name{font-weight:700}[jio-type=dimensionpicker] .dimensionOption{padding:5px;background-color:#dae2cb;border:1px solid #738d68;margin-top:2px;margin-bottom:2px;margin-left:7px;cursor:pointer;font-size:13px;font-weight:700;color:#738d68}[jio-type=dimensionpicker] .dimensionOption:hover,[jio-type=dimensionpicker] .dimensionOption.active{background-color:#9bb47a;color:#fff}[jio-type=dimensionpicker] .dimensionOption.disabled{opacity:.6;cursor:default}[jio-type=dimensionpicker] .dimensionOption.active{opacity:1;cursor:default}[jio-type=dimensionpicker] input.quicksearch{padding:5px;border:1px solid #DDD;font-family:Signika,helvetica,arial,sans-serif;font-size:14px;background-color:#FFF;margin-left:7px}[jio-type=dimensionpicker] input.quicksearch{margin-bottom:5px}[jio-type=filterbox]{}[jio-type=filterbox] .filterbox{padding:5px;margin:0;border-top:0;min-height:0;border-bottom:1px solid #ddd;margin-bottom:10px;display:none}[jio-type=filterbox] .filterbox:not(:empty){display:block}[jio-type=filterbox] .filter{display:inline-block;padding:5px;padding-left:8px;padding-right:8px;border:1px solid #ddd}[jio-type=filterbox] .filter:not(:first-of-type){margin-left:10px}[jio-type=filterbox] .close{padding-left:5px;cursor:pointer}.animate-spin{-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;display:inline-block}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-o-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@-ms-keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes spin{0%{-moz-transform:rotate(0deg);-o-transform:rotate(0deg);-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-moz-transform:rotate(359deg);-o-transform:rotate(359deg);-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.help:before{content:'\e800'}.icon-close:before{content:'\e803'}.sort-desc:before{content:'\e801'}.sort-asc:before{content:'\e802'}@font-face{font-family:fontello;src:url(../font/fontello.eot?52724408);src:url(../font/fontello.eot?52724408#iefix) format('embedded-opentype'),url(../font/fontello.svg?52724408#fontello) format('svg');font-weight:400;font-style:normal}@font-face{font-family:fontello;src:url(data:application/octet-stream;base64,d09GRgABAAAAAAu4AA4AAAAAFSQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABRAAAAEQAAABWPihJZWNtYXAAAAGIAAAAOgAAAUrQExm3Y3Z0IAAAAcQAAAAKAAAACgAAAABmcGdtAAAB0AAABZQAAAtwiJCQWWdhc3AAAAdkAAAACAAAAAgAAAAQZ2x5ZgAAB2wAAAGbAAAC2I5DYEBoZWFkAAAJCAAAADUAAAA2BIPN/2hoZWEAAAlAAAAAHgAAACQHlwNRaG10eAAACWAAAAAQAAAAEA9QAABsb2NhAAAJcAAAAAoAAAAKAdgA7G1heHAAAAl8AAAAIAAAACAAnQvabmFtZQAACZwAAAF3AAACzcydGhxwb3N0AAALFAAAADsAAABTwnpwrHByZXAAAAtQAAAAZQAAAHvdawOFeJxjYGS+wjiBgZWBg6mKaQ8DA0MPhGZ8wGDIyMTAwMTAysyAFQSkuaYwOLxgeMHEHPQ/iyGKOYhhGlCYESQHAAZ/DAt4nGNgYGBmgGAZBkYGEHAB8hjBfBYGDSDNBqQZGZgYGF4w/f8PUvCCAURLMELVAwEjG8OIBwBmAQawAAAAAAAAAAAAAAAAAAB4nK1WaXMTRxCd1WHLNj6CDxI2gVnGcox2VpjLCBDG7EoW4BzylexCjl1Ldu6LT/wG/ZpekVSRb/y0vB4d2GAnVVQoSv2m9+1M9+ueXpPQksReWI+k3HwpprY2aWTnSUg3bFqO4kPZ2QspU0z+LoiCaLXUvu04JCISgap1hSWC2PfI0iTjQ48yWrYlvWpSbulJd9kaD+qt+vbT0FGO3QklNZuhQ+uRLanCqBJFMu2RkjYtw9VfSVrh5yvMfNUMJYLoJJLGm2EMj+Rn44xWGa3GdhxFkU2WG0WKRDM8iCKPslpin1wxQUD5oBlSXvk0onyEH5EVe5TTCnHJdprf9yU/6R3OvyTieouyJQf+QHZkB3unK/ki0toK46adbEehivB0fSfEI5uT6p/sUV7TaOB2RaYnzQiWyleQWPkJZfYPyWrhfMqXPBrVkoOcCFovc2Jf8g60HkdMiWsmyILujk6IoO6XnKHYY/q4+OO9XSwXIQTIOJb1jkq4EEYpYbOaJG0EOYiSskWV1HpHTJzyOi3iLWG/Tu3oS2e0Sag7MZ6th46tnKjkeDSp00ymTu2k5tGUBlFKOhM85tcBlB/RJK+2sZrEyqNpbDNjJJFQoIVzaSqIZSeWNAXRPJrRm7thmmvXokWaPFDPPXpPb26Fmzs9p+3AP2v8Z3UqpoO9MJ2eDshKfJp2uUnRun56hn8m8UPWAiqRLTbDlMVDtn4H5eVjS47CawNs957zK+h99kTIpIH4G/AeL9UpBUyFmFVQC9201rUsy9RqVotUZOq7IU0rX9ZpAk05Dn1jX8Y4/q+ZGUtMCd/vxOnZEZeeufYlyDSH3GZdj+Z1arFdgM5sz+k0y/Z9nebYfqDTPNvzOh1ha+t0lO2HOi2w/UinY2wvaEGT7jsEchGBXMAGEoGwdRAI20sIhK1CIGwXEQjbIgJhu4RA2H6MQNguIxC2l7Wsmn4qaRw7E8sARYgDoznuyGVuKldTyaUSrotGpzbkKXKrpKJ4Vv0rA/3ikTesgbVAukTW/IpJrnxUleOPrmh508S5Ao5Vf3tzXJ8TD2W/WPhT8L/amqqkV6x5ZHIVeSPQk+NE1yYVj67p8rmqR9f/i4oOa4F+A6UQC0VZlg2+mZDwUafTUA1c5RAzGzMP1/W6Zc3P4fybGCEL6H78NxQaC9yDTllJWe1gr9XXj2W5twflsCdYkmK+zOtb4YuMzEr7RWYpez7yecAVMCqVYasNXK3gzXsS85DpTfJMELcVZYOkjceZILGBYx4wb76TICRMXbWB2imcsIG8YMwp2O+EQ1RvlOVwe6F9Ho2Uf2tX7MgZFU0Q+G32Rtjrs1DyW6yBhCe/1NdAVSFNxbipgEsj5YZq8GFcrdtGMk6gr6jYDcuyig8fR9x3So5lIPlIEatHRz+tvUKd1Ln9yihu3zv9CIJBaWL+9r6Z4qCUd7WSZVZtA1O3GpVT15rDxasO3c2j7nvH2Sdy1jTddE/c9L6mVbeDg7lZEO3bHJSlTC6o68MOG6jLzaXQ6mVckt52DzAsMKDfoRUb/1f3cfg8V6oKo+NIvZ2oH6PPYgzyDzh/R/UF6OcxTLmGlOd7lxOfbtzD2TJdxV2sn+LfwKy15mbpGnBD0w2Yh6xaHbrKDXynBjo90tyO9BDwse4K8QBgE8Bi8InuWsbzKYDxfMYcH+Bz5jBoMofBFnMYbDNnDWCHOQx2mcNgjzkMvmDOOsCXzGEQModBxBwGT5gTADxlDoOvmMPga+Yw+IY59wG+ZQ6DmDkMEuYw2Nd0ayhzixd0F6htUBXowPQTFvewONRUGbK/44Vhf28Qs38wiKk/aro9pP7EC0P92SCm/mIQU3/VdGdI/Y0Xhvq7QUz9wyCmPtMvxnKZwV9GvkuFA8ouNp/z98T7B8IaQLYAAQAB//8AD3icdZBPLwNBGMbfd2d3djpWu21nt9RmE1uWqH/pn21CpBISElTCwSeQiIqri6M7Zz4A5zq4iKMrH8PJSUSErVmNalqSd548zzMzh98LpPnRPCPnZBIY2FAFflMZisc0JFN5DCAFKiiQLgTlwM+jR3VhZ9JBueTnPJ3qVrFcqgSFjG0JnSYwmnZbxQDv79Ck4Wt4Ej5TNG5dX/FdxZHqXGX3txbHl9VD06wZpskMm3Orj8bVA5XazjSZUMK31jeOx5j6dH3H9UfkUXDVm6ytZyf2VDXrDAgxkLINltBZMsbEHFMNU5gpDwA0gOY+eSJbkIAxqMAK7EBi0dheW5ov5l3RR7SpvGYJKqn8BSwF81iwR4Uk8GbQlynZqqxkUfZd79Iy54ZbuTjcm5VLzk4Z/5bwhTa0uN5grL/OWZ1xOXjE2Xt0L0WW4UXkcbcVZr/DI+OD9chFUqV6Q9OuYxaBqPoE/tC+Q+vX2m3byZ/p5c8NxVXJ/x+v1sVD/sid++jOeNHLrGx0snVTd2zjZ3HTPdCbf5H+w/8FiWV1GgB4nGNgZGBgAOIlX9d/jee3+crAzfwCKMJw4UCUO4Q2EP//538W8wvmICCXg4EJJAoAohIOiwAAAHicY2BkYGAO+p/FEMX8goHh/y8gCRRBASwAkOIF7gAAA+gAAAOYAAAD6AAAA+gAAAAAAAAAbADsAWwAAAABAAAABABYAAUAAAAAAAIAAAAQAHMAAAAgC3AAAAAAeJx1kMtqwkAUhv/x0otCW1rotrMqSmm8YDeCIFh0026kuC0xxiQSMzIZBV+j79CH6Uv0WfqbjKUoTZjMd745c+ZkAFzjGwL588SRs8AZo5wLOEXPcpH+2XKJ/GK5jCreLJ/Qv1uu4AGB5Spu8MEKonTOaIFPywJX4tJyARfiznKR/tFyidyzXMateLV8Qu9ZrmAiUstV3IuvgVptdRSERtYGddlutjpyupWKKkrcWLprEyqdyr6cq8T4cawcTy33PPaDdezqfbifJ75OI5XIltPcq5Gf+No1/mxXPd0EbWPmcq7VUg5thlxptfA944TGrLqNxt/zMIDCCltoRLyqEAYSNdo65zaaaKFDmjJDMjPPipDARUzjYs0dYbaSMu5zzBkltD4zYrIDj9/lkR+TAu6PWUUfrR7GE9LujCjzkn057O4wa0RKskw3s7Pf3lNseFqb1nDXrkuddSUxPKgheR+7tQWNR+9kt2Jou2jw/ef/fgDdX4RLAHicY2BigAAuBuyAhYGBkYmRmZGFJyM1p0A3ObMoOSc1hbc4v6hENzGnRDclvzyPG84rLWBgAAA5yg5QAHicY/DewXAiKGIjI2Nf5AbGnRwMHAzJBRsZWJ02MjBoQWgOFHonAwMDJzKLmcFlowpjR2DEBoeOiI3MKS4b1UC8XRwNDIwsDh3JIREgJZFAsJGBR2sH4//WDSy9G5kYXAAH0yK4AAAA) format('woff'),url(data:application/octet-stream;base64,AAEAAAAOAIAAAwBgT1MvMj4oSWUAAADsAAAAVmNtYXDQExm3AAABRAAAAUpjdnQgAAAAAAAACSwAAAAKZnBnbYiQkFkAAAk4AAALcGdhc3AAAAAQAAAJJAAAAAhnbHlmjkNgQAAAApAAAALYaGVhZASDzf8AAAVoAAAANmhoZWEHlwNRAAAFoAAAACRobXR4D1AAAAAABcQAAAAQbG9jYQHYAOwAAAXUAAAACm1heHAAnQvaAAAF4AAAACBuYW1lzJ0aHAAABgAAAALNcG9zdMJ6cKwAAAjQAAAAU3ByZXDdawOFAAAUqAAAAHsAAQPUAZAABQAIAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA6ADoAgNS/2oAWgNSAJYAAAABAAAAAAAAAAAAAwAAAAMAAAAcAAEAAAAAAEQAAwABAAAAHAAEACgAAAAGAAQAAQACAADoAv//AAAAAOgA//8AABgBAAEAAAAAAAAAAAEGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8/5ADmgMsAAgAFgA/AAq3NxsOCQUBAy0rATYAEgAEAAIAEzI2NTYmKwEiBgcUFhcTNjU0JiMiBwYHFTM1NDc2MhcWFRQHBg8BBg8BBgcGBxUzNTQ3Nj8BNgHGvgEQBv72/oT+7gYBDLweJgImHgIcJgImHKgaalJAKEQEbhAQTgwQEAgMFgoKFQsGDgRsBAYWHC4DKgL++P6E/u4GAQoBfAES/R4mHB4mJBweJgIBSCIsTkwaKmgEBBocGBQUGBIWDAgPBwgRCQgUOggEDBAUEBIiAAAABQAA/2oD6ANSAA8AJwA3AEcAVwAPQAxTS0M7MyseFAsDBS0rBRUUBisBIiY9ATQ2OwEyFiUUDwEGIi8BJjY7ARE0NjsBMhYVETMyFiUVFAYrASImPQE0NjsBMhYTFRQGIyEiJj0BNDYzITIWExUUBiMhIiY9ATQ2MyEyFgKnCgiPCAoKCI8ICv70BrIFDgeyCAgNawoIawgKawgKAXcKCPoICgoI+ggKawoI/psICgoIAWUICmsKCP4wCAoKCAHQCAoZawgKCghrCAoKPwYHsgUFswkVAwAICgoI/QAKz2sICgoIawgKCgEVawgKCghrCAoKARZrCAoKCGsICgoAAAUAAP9qA+gDUgAXACcANwBHAFcAD0AMU0tDOzMrIxsOBAUtKyUUDwEGIi8BJjY7ARE0NjsBMhYVETMyFgUVFAYjISImPQE0NjMhMhYDFRQGIyEiJj0BNDYzITIWAxUUBisBIiY9ATQ2OwEyFgMVFAYrASImPQE0NjsBMhYBmwayBQ4HsggIDWsKCGsICmsICgJNCgj+MAgKCggB0AgKawoI/psICgoIAWUICmsKCPoICgoI+ggKawoIjwgKCgiPCAouBgeyBQWzCRUDAAgKCgj9AApPawgKCghrCAoKARZrCAoKCGsICgoBFWsICgoIawgKCgEWawgKCghrCAoKAAABAAAAAQAApPWv9V8PPPUACwPoAAAAANDAWkcAAAAA0MAwF//8/2oD6ANSAAAACAACAAAAAAAAAAEAAANS/2oAWgPoAAD/+gPoAAEAAAAAAAAAAAAAAAAAAAAEA+gAAAOYAAAD6AAAA+gAAAAAAAAAbADsAWwAAAABAAAABABYAAUAAAAAAAIAAAAQAHMAAAAgC3AAAAAAAAAAEgDeAAEAAAAAAAAANQAAAAEAAAAAAAEACAA1AAEAAAAAAAIABwA9AAEAAAAAAAMACABEAAEAAAAAAAQACABMAAEAAAAAAAUACwBUAAEAAAAAAAYACABfAAEAAAAAAAoAKwBnAAEAAAAAAAsAEwCSAAMAAQQJAAAAagClAAMAAQQJAAEAEAEPAAMAAQQJAAIADgEfAAMAAQQJAAMAEAEtAAMAAQQJAAQAEAE9AAMAAQQJAAUAFgFNAAMAAQQJAAYAEAFjAAMAAQQJAAoAVgFzAAMAAQQJAAsAJgHJQ29weXJpZ2h0IChDKSAyMDE0IGJ5IG9yaWdpbmFsIGF1dGhvcnMgQCBmb250ZWxsby5jb21mb250ZWxsb1JlZ3VsYXJmb250ZWxsb2ZvbnRlbGxvVmVyc2lvbiAxLjBmb250ZWxsb0dlbmVyYXRlZCBieSBzdmcydHRmIGZyb20gRm9udGVsbG8gcHJvamVjdC5odHRwOi8vZm9udGVsbG8uY29tAEMAbwBwAHkAcgBpAGcAaAB0ACAAKABDACkAIAAyADAAMQA0ACAAYgB5ACAAbwByAGkAZwBpAG4AYQBsACAAYQB1AHQAaABvAHIAcwAgAEAAIABmAG8AbgB0AGUAbABsAG8ALgBjAG8AbQBmAG8AbgB0AGUAbABsAG8AUgBlAGcAdQBsAGEAcgBmAG8AbgB0AGUAbABsAG8AZgBvAG4AdABlAGwAbABvAFYAZQByAHMAaQBvAG4AIAAxAC4AMABmAG8AbgB0AGUAbABsAG8ARwBlAG4AZQByAGEAdABlAGQAIABiAHkAIABzAHYAZwAyAHQAdABmACAAZgByAG8AbQAgAEYAbwBuAHQAZQBsAGwAbwAgAHAAcgBvAGoAZQBjAHQALgBoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAQIBAwEEDGhlbHAtY2lyY2xlZA1zb3J0LWFsdC1kb3duC3NvcnQtYWx0LXVwAAAAAAEAAf//AA8AAAAAAAAAAAAAAACwACwgsABVWEVZICBLuAAOUUuwBlNaWLA0G7AoWWBmIIpVWLACJWG5CAAIAGNjI2IbISGwAFmwAEMjRLIAAQBDYEItsAEssCBgZi2wAiwgZCCwwFCwBCZasigBCkNFY0VSW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCxAQpDRWNFYWSwKFBYIbEBCkNFY0UgsDBQWCGwMFkbILDAUFggZiCKimEgsApQWGAbILAgUFghsApgGyCwNlBYIbA2YBtgWVlZG7ABK1lZI7AAUFhlWVktsAMsIEUgsAQlYWQgsAVDUFiwBSNCsAYjQhshIVmwAWAtsAQsIyEjISBksQViQiCwBiNCsQEKQ0VjsQEKQ7AAYEVjsAMqISCwBkMgiiCKsAErsTAFJbAEJlFYYFAbYVJZWCNZISCwQFNYsAErGyGwQFkjsABQWGVZLbAFLLAHQyuyAAIAQ2BCLbAGLLAHI0IjILAAI0JhsAJiZrABY7ABYLAFKi2wBywgIEUgsAtDY7gEAGIgsABQWLBAYFlmsAFjYESwAWAtsAgssgcLAENFQiohsgABAENgQi2wCSywAEMjRLIAAQBDYEItsAosICBFILABKyOwAEOwBCVgIEWKI2EgZCCwIFBYIbAAG7AwUFiwIBuwQFlZI7AAUFhlWbADJSNhRESwAWAtsAssICBFILABKyOwAEOwBCVgIEWKI2EgZLAkUFiwABuwQFkjsABQWGVZsAMlI2FERLABYC2wDCwgsAAjQrILCgNFWCEbIyFZKiEtsA0ssQICRbBkYUQtsA4ssAFgICCwDENKsABQWCCwDCNCWbANQ0qwAFJYILANI0JZLbAPLCCwEGJmsAFjILgEAGOKI2GwDkNgIIpgILAOI0IjLbAQLEtUWLEEZERZJLANZSN4LbARLEtRWEtTWLEEZERZGyFZJLATZSN4LbASLLEAD0NVWLEPD0OwAWFCsA8rWbAAQ7ACJUKxDAIlQrENAiVCsAEWIyCwAyVQWLEBAENgsAQlQoqKIIojYbAOKiEjsAFhIIojYbAOKiEbsQEAQ2CwAiVCsAIlYbAOKiFZsAxDR7ANQ0dgsAJiILAAUFiwQGBZZrABYyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsQAAEyNEsAFDsAA+sgEBAUNgQi2wEywAsQACRVRYsA8jQiBFsAsjQrAKI7AAYEIgYLABYbUQEAEADgBCQopgsRIGK7ByKxsiWS2wFCyxABMrLbAVLLEBEystsBYssQITKy2wFyyxAxMrLbAYLLEEEystsBkssQUTKy2wGiyxBhMrLbAbLLEHEystsBwssQgTKy2wHSyxCRMrLbAeLACwDSuxAAJFVFiwDyNCIEWwCyNCsAojsABgQiBgsAFhtRAQAQAOAEJCimCxEgYrsHIrGyJZLbAfLLEAHistsCAssQEeKy2wISyxAh4rLbAiLLEDHistsCMssQQeKy2wJCyxBR4rLbAlLLEGHistsCYssQceKy2wJyyxCB4rLbAoLLEJHistsCksIDywAWAtsCosIGCwEGAgQyOwAWBDsAIlYbABYLApKiEtsCsssCorsCoqLbAsLCAgRyAgsAtDY7gEAGIgsABQWLBAYFlmsAFjYCNhOCMgilVYIEcgILALQ2O4BABiILAAUFiwQGBZZrABY2AjYTgbIVktsC0sALEAAkVUWLABFrAsKrABFTAbIlktsC4sALANK7EAAkVUWLABFrAsKrABFTAbIlktsC8sIDWwAWAtsDAsALABRWO4BABiILAAUFiwQGBZZrABY7ABK7ALQ2O4BABiILAAUFiwQGBZZrABY7ABK7AAFrQAAAAAAEQ+IzixLwEVKi2wMSwgPCBHILALQ2O4BABiILAAUFiwQGBZZrABY2CwAENhOC2wMiwuFzwtsDMsIDwgRyCwC0NjuAQAYiCwAFBYsEBgWWawAWNgsABDYbABQ2M4LbA0LLECABYlIC4gR7AAI0KwAiVJiopHI0cjYSBYYhshWbABI0KyMwEBFRQqLbA1LLAAFrAEJbAEJUcjRyNhsAlDK2WKLiMgIDyKOC2wNiywABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyCwCEMgiiNHI0cjYSNGYLAEQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwAmIgsABQWLBAYFlmsAFjYSMgILAEJiNGYTgbI7AIQ0awAiWwCENHI0cjYWAgsARDsAJiILAAUFiwQGBZZrABY2AjILABKyOwBENgsAErsAUlYbAFJbACYiCwAFBYsEBgWWawAWOwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbA3LLAAFiAgILAFJiAuRyNHI2EjPDgtsDgssAAWILAII0IgICBGI0ewASsjYTgtsDkssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbkIAAgAY2MjIFhiGyFZY7gEAGIgsABQWLBAYFlmsAFjYCMuIyAgPIo4IyFZLbA6LLAAFiCwCEMgLkcjRyNhIGCwIGBmsAJiILAAUFiwQGBZZrABYyMgIDyKOC2wOywjIC5GsAIlRlJYIDxZLrErARQrLbA8LCMgLkawAiVGUFggPFkusSsBFCstsD0sIyAuRrACJUZSWCA8WSMgLkawAiVGUFggPFkusSsBFCstsD4ssDUrIyAuRrACJUZSWCA8WS6xKwEUKy2wPyywNiuKICA8sAQjQoo4IyAuRrACJUZSWCA8WS6xKwEUK7AEQy6wKystsEAssAAWsAQlsAQmIC5HI0cjYbAJQysjIDwgLiM4sSsBFCstsEEssQgEJUKwABawBCWwBCUgLkcjRyNhILAEI0KwCUMrILBgUFggsEBRWLMCIAMgG7MCJgMaWUJCIyBHsARDsAJiILAAUFiwQGBZZrABY2AgsAErIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbACYiCwAFBYsEBgWWawAWNhsAIlRmE4IyA8IzgbISAgRiNHsAErI2E4IVmxKwEUKy2wQiywNSsusSsBFCstsEMssDYrISMgIDywBCNCIzixKwEUK7AEQy6wKystsEQssAAVIEewACNCsgABARUUEy6wMSotsEUssAAVIEewACNCsgABARUUEy6wMSotsEYssQABFBOwMiotsEcssDQqLbBILLAAFkUjIC4gRoojYTixKwEUKy2wSSywCCNCsEgrLbBKLLIAAEErLbBLLLIAAUErLbBMLLIBAEErLbBNLLIBAUErLbBOLLIAAEIrLbBPLLIAAUIrLbBQLLIBAEIrLbBRLLIBAUIrLbBSLLIAAD4rLbBTLLIAAT4rLbBULLIBAD4rLbBVLLIBAT4rLbBWLLIAAEArLbBXLLIAAUArLbBYLLIBAEArLbBZLLIBAUArLbBaLLIAAEMrLbBbLLIAAUMrLbBcLLIBAEMrLbBdLLIBAUMrLbBeLLIAAD8rLbBfLLIAAT8rLbBgLLIBAD8rLbBhLLIBAT8rLbBiLLA3Ky6xKwEUKy2wYyywNyuwOystsGQssDcrsDwrLbBlLLAAFrA3K7A9Ky2wZiywOCsusSsBFCstsGcssDgrsDsrLbBoLLA4K7A8Ky2waSywOCuwPSstsGossDkrLrErARQrLbBrLLA5K7A7Ky2wbCywOSuwPCstsG0ssDkrsD0rLbBuLLA6Ky6xKwEUKy2wbyywOiuwOystsHAssDorsDwrLbBxLLA6K7A9Ky2wciyzCQQCA0VYIRsjIVlCK7AIZbADJFB4sAEVMC0AS7gAyFJYsQEBjlmwAbkIAAgAY3CxAAVCsQAAKrEABUKxAAgqsQAFQrEACCqxAAVCuQAAAAkqsQAFQrkAAAAJKrEDAESxJAGIUViwQIhYsQNkRLEmAYhRWLoIgAABBECIY1RYsQMARFlZWVmxAAwquAH/hbAEjbECAEQA) format('truetype')}[class^=icon-]:before,[class*=" icon-"]:before{font-family:fontello;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.icon-help-circled:before{content:'\e800'}.icon-sort-alt-down:before{content:'\e801'}.icon-sort-alt-up:before{content:'\e802'}.icon-help-circled{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}.icon-sort-alt-down{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}.icon-sort-alt-up{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}[class^=icon-],[class*=" icon-"]{font-family:fontello;font-style:normal;font-weight:400;line-height:1em}.icon-help-circled{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}.icon-sort-alt-down{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}.icon-sort-alt-up{*zoom:expression(this.runtimeStyle[=zoom]='1',this.innerHTML=' ')}@font-face{font-family:fontello;src:url(../font/fontello.eot?68483856);src:url(../font/fontello.eot?68483856#iefix) format('embedded-opentype'),url(../font/fontello.woff?68483856) format('woff'),url(../font/fontello.ttf?68483856) format('truetype'),url(../font/fontello.svg?68483856#fontello) format('svg');font-weight:400;font-style:normal}[class^=icon-]:before,[class*=" icon-"]:before{font-family:fontello;font-style:normal;font-weight:400;speak:none;display:inline-block;text-decoration:inherit;width:1em;margin-right:.2em;text-align:center;font-variant:normal;text-transform:none;line-height:1em;margin-left:.2em}.icon-help:before{content:'\e800'}.icon-close:before{content:'\e803'}.icon-sort-desc:before{content:'\e801'}.icon-sort-asc:before{content:'\e802'}[jio-type=metric]{padding:5px;margin:0;float:none;border-top:0;min-height:0;text-align:center}[jio-type=metric] .caption{line-height:1.2857142857em;margin:0 0 10px;padding:0;text-transform:uppercase;padding-top:10px;color:#999;font-size:18px;font-weight:300;margin-bottom:0}[jio-type=metric] .value{color:#666;font-weight:300;font-size:32px;text-shadow:0 1px 5px rgba(0,0,0,.15)}[jio-type=metric] .summary{color:#999}[jio-type=metric] .base{padding-right:5px}[jio-type=metric] .compare{padding-left:5px}[jio-type=metricpicker]{float:left;position:relative}[jio-type=metricpicker] .picker-container{position:absolute;background-color:#fff;display:none;border:1px solid #ddd;padding:5px;z-index:1000}[jio-type=metricpicker] .picker-container.active{display:block}[jio-type=metricpicker] .name{font-weight:700}[jio-type=metricpicker] .metricOption{padding:5px;background-color:#c5dcfe;border:1px solid #2f67b4;margin-top:2px;margin-bottom:2px;margin-left:7px;cursor:pointer;font-size:13px;font-weight:700;color:#2f67b4}[jio-type=metricpicker] .metricOption:hover,[jio-type=metricpicker] .metricOption.active{background-color:#6faefd;color:#fff}[jio-type=metricpicker] .metricOption.disabled{opacity:.6;cursor:default}[jio-type=metricpicker] .metricOption.active{opacity:1;cursor:default}[jio-type=metricpicker] input.quicksearch{padding:5px;border:1px solid #DDD;font-family:Signika,helvetica,arial,sans-serif;font-size:14px;background-color:#FFF;margin-left:7px}[jio-type=metricpicker] input.quicksearch{margin-bottom:5px}[jio-type=table] .table-wrapper{overflow:auto}[jio-type=table] .table{border-top:1px solid #ddd;border-left:1px solid #ddd;margin-bottom:10px;width:100%;border-collapse:collapse;border-spacing:0}[jio-type=table] .table tr{vertical-align:top}[jio-type=table] .table td{padding-top:8px;padding-bottom:5px;padding-left:15px;padding-right:15px;border-right:1px solid #ddd;border-bottom:1px solid #ddd}[jio-type=table] .table th{text-overflow:ellipsis;padding-top:10px;padding-bottom:10px;padding-left:15px;text-align:left;background-color:#e9e9e9;font-weight:700;white-space:nowrap;min-width:100px;border-bottom:2px solid #ddd;border-right:1px solid #ddd;cursor:pointer;text-transform:uppercase}[jio-type=table] .table th .icon-help,[jio-type=table] .table th .icon-close{margin-left:5px}[jio-type=table] .table th .caret-sort{float:right;margin-right:15px}[jio-type=table] .table td.value.metric{text-align:right}[jio-type=table] .table td.caption.change{font-weight:700}[jio-type=table] .table td.value.change{text-align:right;font-weight:700}[jio-type=table] .table td.sorted{background-color:#F5F5F5}[jio-type=table] .table td.sorted{background-color:#F5F5F5}[jio-type=table] .table td.sorted.value{font-weight:700}[jio-type=table] .table td.value .summary{color:#999;font-size:13px;font-weight:400}[jio-type=table] .table.table-striped tbody>tr:nth-child(even)>td{background-color:#fff}[jio-type=table] .table-caption{line-height:1.2857142857em;margin:20px 0;padding:0;text-transform:uppercase;font-size:18px;font-weight:400;color:#333;text-align:center}[jio-type=table] .nodata,[jio-type=table] .loading{text-align:center}[jio-type=table] .controls{background-color:#f5f5f5;border-top:1px solid #ddd;border-left:1px solid #ddd;border-right:1px solid #ddd;padding:5px;padding-left:15px;padding-top:10px;padding-bottom:10px}[jio-type=table] .table-picker:not(:first-of-type){margin-left:10px}[jio-type=table] .search-wrapper{float:right;margin-right:30px;width:250px}[jio-type=table] .search-wrapper input.search{padding:5px;border:1px solid #DDD;font-family:Signika,helvetica,arial,sans-serif;font-size:16px;background-color:#FFF;margin-left:7px;width:100%}[jio-type=table] .paging{float:right;display:table;vertical-align:middle}[jio-type=table] .paging-wrapper{display:table-cell}[jio-type=table] .showing{display:inline-block;margin-left:20px;margin-right:20px}[jio-type=table] .navigation{display:table-cell}[jio-type=table] .prev,[jio-type=table] .next{padding:5px;padding-left:10px;padding-right:10px;border:1px solid #ddd;cursor:pointer;display:table-cell}[jio-type=table] .prev:hover,[jio-type=table] .next:hover{background-color:#e9e9e9}[jio-type=table] .prev.disabled,[jio-type=table] .next.disabled{opacity:.6}[jio-type=table] .prev.disabled:hover,[jio-type=table] .next.disabled:hover{background-color:inherit}[jio-type=table] .page-size select{padding:3px;border:1px solid #ddd;font-family:Signika,helvetica,arial,sans-serif;font-size:16px;background-color:#fff;margin-left:7px}[jio-type=timeline]{}[jio-type=timeline] .sep{float:left;padding-left:10px;padding-right:10px;padding-top:5px;font-weight:400} \ No newline at end of file diff --git a/build/release/joola.min.js b/build/release/joola.min.js index d3891df..9a5757e 100644 --- a/build/release/joola.min.js +++ b/build/release/joola.min.js @@ -1,4 +1,4 @@ -/*! joola.sdk 2014-12-30 */ +/*! joola.sdk 2015-01-07 */ !function(){function a(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function b(){var a,b,c=arguments,d={},e=function(a,b){var c,d;"object"!=typeof a&&(a={});for(d in b)b.hasOwnProperty(d)&&(c=b[d],a[d]=c&&"object"==typeof c&&"[object Array]"!==Object.prototype.toString.call(c)&&"renderTo"!==d&&"number"!=typeof c.nodeType?e(a[d]||{},c):b[d]);return a};for(c[0]===!0&&(d=c[1],c=Array.prototype.slice.call(c,2)),b=c.length,a=0;b>a;a++)d=e(d,c[a]);return d}function c(a,b){return parseInt(a,b||10)}function d(a){return"string"==typeof a}function e(a){return a&&"object"==typeof a}function f(a){return"[object Array]"===Object.prototype.toString.call(a)}function g(a){return"number"==typeof a}function h(a){return nb.log(a)/nb.LN10}function i(a){return nb.pow(10,a)}function j(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function k(a){return a!==N&&null!==a}function l(a,b,c){var f,g;if(d(b))k(c)?a.setAttribute(b,c):a&&a.getAttribute&&(g=a.getAttribute(b));else if(k(b)&&e(b))for(f in b)a.setAttribute(f,b[f]);return g}function m(a){return f(a)?a:[a]}function n(){var a,b,c=arguments,d=c.length;for(a=0;d>a;a++)if(b=c[a],b!==N&&null!==b)return b}function o(b,c){Ab&&!Gb&&c&&c.opacity!==N&&(c.filter="alpha(opacity="+100*c.opacity+")"),a(b.style,c)}function p(b,c,d,e,f){var g=lb.createElement(b);return c&&a(g,c),f&&o(g,{padding:0,border:Xb,margin:0}),d&&o(g,d),e&&e.appendChild(g),g}function q(b,c){var d=function(){return N};return d.prototype=new b,a(d.prototype,c),d}function r(a,b,d,e){var f=kb.numberFormat,g=R.lang,h=+a||0,i=-1===b?(h.toString().split(".")[1]||"").length:isNaN(b=tb(b))?2:b,j=void 0===d?g.decimalPoint:d,k=void 0===e?g.thousandsSep:e,l=0>h?"-":"",m=String(c(h=tb(h).toFixed(i))),n=m.length>3?m.length%3:0;return f!==r?f(a,b,d,e):l+(n?m.substr(0,n)+k:"")+m.substr(n).replace(/(\d{3})(?=\d)/g,"$1"+k)+(i?j+tb(h-m).toFixed(i).slice(2):"")}function s(a,b){return new Array((b||2)+1-String(a).length).join(0)+a}function t(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);return a.unshift(d),c.apply(this,a)}}function u(a,b){var c,d=/f$/,e=/\.([0-9])/,f=R.lang;return d.test(a)?(c=a.match(e),c=c?c[1]:-1,null!==b&&(b=r(b,c,f.decimalPoint,a.indexOf(",")>-1?f.thousandsSep:""))):b=S(a,b),b}function v(a,b){for(var c,d,e,f,g,h,i,j="{",k=!1,l=[];-1!==(i=a.indexOf(j));){if(c=a.slice(0,i),k){for(d=c.split(":"),e=d.shift().split("."),g=e.length,h=b,f=0;g>f;f++)h=h[e[f]];d.length&&(h=u(d.join(":"),h)),l.push(h)}else l.push(c);a=a.slice(i+1),k=!k,j=k?"}":"{"}return l.push(a),l.join("")}function w(a){return nb.pow(10,pb(nb.log(a)/nb.LN10))}function x(a,b,c,d){var e,f;for(c=n(c,1),e=a/c,b||(b=[1,2,2.5,5,10],d===!1&&(1===c?b=[1,2,5,10]:.1>=c&&(b=[1/c]))),f=0;fd;d++)a[d].ss_i=d;for(a.sort(function(a,d){return c=b(a,d),0===c?a.ss_i-d.ss_i:c}),d=0;e>d;d++)delete a[d].ss_i}function z(a){for(var b=a.length,c=a[0];b--;)a[b]c&&(c=a[b]);return c}function B(a,b){var c;for(c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function C(a){Q||(Q=p(Qb)),a&&Q.appendChild(a),Q.innerHTML=""}function D(a){return parseFloat(a.toPrecision(14))}function E(a,b){T=n(a,b.animation)}function F(){var a=R.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";Y=R.global.Date||window.Date,$=6e4*(a&&R.global.timezoneOffset||0),Z=a?Y.UTC:function(a,b,c,d,e,f){return new Y(a,b,n(c,1),n(d,0),n(e,0),n(f,0)).getTime()},_=b+"Minutes",ab=b+"Hours",bb=b+"Day",cb=b+"Date",db=b+"Month",eb=b+"FullYear",fb=c+"Minutes",gb=c+"Hours",hb=c+"Date",ib=c+"Month",jb=c+"FullYear"}function G(a){return R=b(!0,R,a),F(),R}function H(){return R}function I(){}function J(a,b,c,d){this.axis=a,this.pos=b,this.type=c||"",this.isNew=!0,c||d||this.addLabel()}function K(){this.init.apply(this,arguments)}function L(){this.init.apply(this,arguments)}function M(a,b,c,d,e){var f=a.chart.inverted;this.axis=a,this.isNegative=c,this.options=b,this.x=d,this.total=null,this.points={},this.stack=e,this.alignOptions={align:b.align||(f?c?"left":"right":"center"),verticalAlign:b.verticalAlign||(f?"middle":c?"bottom":"top"),y:n(b.y,f?4:c?14:-6),x:n(b.x,f?c?-6:6:0)},this.textAlign=b.textAlign||(f?c?"right":"left":"center")}var N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb=document,mb=window,nb=Math,ob=nb.round,pb=nb.floor,qb=nb.ceil,rb=nb.max,sb=nb.min,tb=nb.abs,ub=nb.cos,vb=nb.sin,wb=nb.PI,xb=2*wb/360,yb=navigator.userAgent,zb=mb.opera,Ab=/msie/i.test(yb)&&!zb,Bb=8===lb.documentMode,Cb=/AppleWebKit/.test(yb),Db=/Firefox/.test(yb),Eb=/(Mobile|Android|Windows Phone)/.test(yb),Fb="http://www.w3.org/2000/svg",Gb=!!lb.createElementNS&&!!lb.createElementNS(Fb,"svg").createSVGRect,Hb=Db&&parseInt(yb.split("Firefox/")[1],10)<4,Ib=!Gb&&!Ab&&!!lb.createElement("canvas").getContext,Jb={},Kb=0,Lb=function(){return N},Mb=[],Nb=0,Ob="Highcharts",Pb="4.0.4",Qb="div",Rb="absolute",Sb="relative",Tb="hidden",Ub="highcharts-",Vb="visible",Wb="px",Xb="none",Yb="M",Zb="L",$b=/^[0-9]+$/,_b="",ac="hover",bc="select",cc="stroke-width",dc={};mb.Highcharts?W(16,!0):kb=mb.Highcharts={},S=function(b,c,d){if(!k(c)||isNaN(c))return"Invalid date";b=n(b,"%Y-%m-%d %H:%M:%S");var e,f=new Y(c-$),g=f[ab](),h=f[bb](),i=f[cb](),j=f[db](),l=f[eb](),m=R.lang,o=m.weekdays,p=a({a:o[h].substr(0,3),A:o[h],d:s(i),e:i,b:m.shortMonths[j],B:m.months[j],m:s(j+1),y:l.toString().substr(2,2),Y:l,H:s(g),I:s(g%12||12),l:g%12||12,M:s(f[_]()),p:12>g?"AM":"PM",P:12>g?"am":"pm",S:s(f.getSeconds()),L:s(ob(c%1e3),3)},kb.dateFormats);for(e in p)for(;-1!==b.indexOf("%"+e);)b=b.replace("%"+e,"function"==typeof p[e]?p[e](c):p[e]);return d?b.substr(0,1).toUpperCase()+b.substr(1):b},W=function(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;mb.console&&console.log(c)},V={millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,week:6048e5,month:26784e5,year:31556952e3},U={init:function(a,b,c){b=b||"";var d,e,f,g,h,i=a.shift,j=b.indexOf("C")>-1,k=j?7:3,l=b.split(" "),m=[].concat(c),n=function(a){for(f=a.length;f--;)a[f]===Yb&&a.splice(f+1,0,a[f+1],a[f+2],a[f+1],a[f+2])};if(j&&(n(l),n(m)),a.isArea&&(g=l.splice(l.length-6,6),h=m.splice(m.length-6,6)),i<=m.length/k&&l.length===m.length)for(;i--;)m=[].concat(m).splice(0,k).concat(m);if(a.shift=0,l.length)for(d=m.length;l.lengthc)for(;g--;)e=parseFloat(a[g]),f[g]=isNaN(e)?a[g]:c*parseFloat(b[g]-e)+e;else f=b;return f}},function(b){mb.HighchartsAdapter=mb.HighchartsAdapter||b&&{init:function(a){var c=b.fx;b.extend(b.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}}),b.each(["cur","_default","width","height","opacity"],function(a,d){var e,f=c.step;"cur"===d?f=c.prototype:"_default"===d&&b.Tween&&(f=b.Tween.propHooks[d],d="set"),e=f[d],e&&(f[d]=function(b){var c;return b=a?b:this,"align"!==b.prop?(c=b.elem,c.attr?c.attr(b.prop,"cur"===d?N:b.now):e.apply(this,arguments)):void 0})}),t(b.cssHooks.opacity,"get",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)}),this.addAnimSetter("d",function(b){var c,d=b.elem;b.started||(c=a.init(d,d.d,d.toD),b.start=c[0],b.end=c[1],b.started=!0),d.attr("d",a.step(b.start,b.end,b.pos,d.toD))}),this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){var c,d=a.length;for(c=0;d>c;c++)if(b.call(a[c],a[c],c,a)===!1)return c},b.fn.highcharts=function(){var a,b,c,e="Chart",f=arguments;return this[0]&&(d(f[0])&&(e=f[0],f=Array.prototype.slice.call(f,1)),a=f[0],a!==N&&(a.chart=a.chart||{},a.chart.renderTo=this[0],c=new kb[e](a,f[1]),b=this),a===N&&(b=Mb[l(this[0],"data-highcharts-chart")])),b}},addAnimSetter:function(a,c){b.Tween?b.Tween.propHooks[a]={set:c}:b.fx.step[a]=c},getScript:b.getScript,inArray:b.inArray,adapterRun:function(a,c){return b(a)[c]()},grep:b.grep,map:function(a,b){for(var c=[],d=0,e=a.length;e>d;d++)c[d]=b.call(a[d],a[d],d,a);return c},offset:function(a){return b(a).offset()},addEvent:function(a,c,d){b(a).bind(c,d)},removeEvent:function(a,c,d){var e=lb.removeEventListener?"removeEventListener":"detachEvent";lb[e]&&a&&!a[e]&&(a[e]=function(){}),b(a).unbind(c,d)},fireEvent:function(c,d,e,f){var g,h=b.Event(d),i="detached"+d;!Ab&&e&&(delete e.layerX,delete e.layerY,delete e.returnValue),a(h,e),c[d]&&(c[i]=c[d],c[d]=null),b.each(["preventDefault","stopPropagation"],function(a,b){var c=h[b];h[b]=function(){try{c.call(h)}catch(a){"preventDefault"===b&&(g=!0)}}}),b(c).trigger(h),c[i]&&(c[d]=c[i],c[i]=null),!f||h.isDefaultPrevented()||g||f(h)},washMouseEvent:function(a){var b=a.originalEvent||a;return b.pageX===N&&(b.pageX=a.pageX,b.pageY=a.pageY),b},animate:function(a,c,d){var e=b(a);a.style||(a.style={}),c.d&&(a.toD=c.d,c.d=1),e.stop(),c.opacity!==N&&a.attr&&(c.opacity+="px"),a.hasAnim=1,e.animate(c,d)},stop:function(a){a.hasAnim&&b(a).stop()}}}(mb.jQuery);var ec=mb.HighchartsAdapter,fc=ec||{};ec&&ec.init.call(ec,U);var gc=fc.adapterRun,hc=fc.getScript,ic=fc.inArray,jc=fc.each,kc=fc.grep,lc=fc.offset,mc=fc.map,nc=fc.addEvent,oc=fc.removeEvent,pc=fc.fireEvent,qc=fc.washMouseEvent,rc=fc.animate,sc=fc.stop,tc={enabled:!0,x:0,y:15,style:{color:"#606060",cursor:"default",fontSize:"11px"}};R={colors:["#7cb5ec","#434348","#90ed7d","#f7a35c","#8085e9","#f15c80","#e4d354","#8085e8","#8d4653","#91e8e1"],symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],weekdays:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],decimalPoint:".",numericSymbols:["k","M","G","T","P","E"],resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/4.0.4/modules/canvas-tools.js",VMLRadialGradientURL:"http://code.highcharts.com/4.0.4/gfx/vml-radial-gradient.png"},chart:{borderColor:"#4572A7",borderRadius:0,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacing:[10,10,15,10],backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",margin:15,style:{color:"#333333",fontSize:"18px"}},subtitle:{text:"",align:"center",style:{color:"#555555"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1e3},events:{},lineWidth:2,marker:{lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{enabled:!0,lineWidthPlus:1,radiusPlus:2},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:b(tc,{align:"center",enabled:!1,formatter:function(){return null===this.y?"":r(this.y,-1)},verticalAlign:"bottom",y:0}),cropThreshold:300,pointRange:0,states:{hover:{lineWidthPlus:1,marker:{},halo:{size:10,opacity:.25}},select:{marker:{}}},stickyTracking:!0,turboThreshold:1e3}},labels:{style:{position:Rb,color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderColor:"#909090",borderRadius:0,navigation:{activeColor:"#274b6d",inactiveColor:"#CCC"},shadow:!1,itemStyle:{color:"#333333",fontSize:"12px",fontWeight:"bold"},itemHoverStyle:{color:"#000"},itemHiddenStyle:{color:"#CCC"},itemCheckboxStyle:{position:Rb,width:"13px",height:"13px"},symbolPadding:5,verticalAlign:"bottom",x:0,y:0,title:{style:{fontWeight:"bold"}}},loading:{labelStyle:{fontWeight:"bold",position:Sb,top:"45%"},style:{position:Rb,backgroundColor:"white",opacity:.5,textAlign:"center"}},tooltip:{enabled:!0,animation:Gb,backgroundColor:"rgba(249, 249, 249, .85)",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:"%A, %b %e, %H:%M:%S.%L",second:"%A, %b %e, %H:%M:%S",minute:"%A, %b %e, %H:%M",hour:"%A, %b %e, %H:%M",day:"%A, %b %e, %Y",week:"Week from %A, %b %e, %Y",month:"%B %Y",year:"%Y"},headerFormat:'{point.key}
',pointFormat:' {series.name}: {point.y}
',shadow:!0,snap:Eb?25:10,style:{color:"#333333",cursor:"default",fontSize:"12px",padding:"8px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"9px"}}};var uc=R.plotOptions,vc=uc.line;F();var wc=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/,xc=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,yc=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/,zc=function(a){function d(a){a&&a.stops?j=mc(a.stops,function(a){return zc(a[1])}):(i=wc.exec(a),i?k=[c(i[1]),c(i[2]),c(i[3]),parseFloat(i[4],10)]:(i=xc.exec(a),i?k=[c(i[1],16),c(i[2],16),c(i[3],16),1]:(i=yc.exec(a),i&&(k=[c(i[1]),c(i[2]),c(i[3]),1]))))}function e(c){var d;return j?(d=b(a),d.stops=[].concat(d.stops),jc(j,function(a,b){d.stops[b]=[d.stops[b][0],a.get(c)]})):d=k&&!isNaN(k[0])?"rgb"===c?"rgb("+k[0]+","+k[1]+","+k[2]+")":"a"===c?k[3]:"rgba("+k.join(",")+")":a,d}function f(a){if(j)jc(j,function(b){b.brighten(a)});else if(g(a)&&0!==a){var b;for(b=0;3>b;b++)k[b]+=c(255*a),k[b]<0&&(k[b]=0),k[b]>255&&(k[b]=255)}return this}function h(a){return k[3]=a,this}var i,j,k=[];return d(a),{get:e,brighten:f,rgba:k,setOpacity:h}};I.prototype={opacity:1,textProps:["fontSize","fontWeight","fontFamily","color","lineHeight","width","textDecoration","textShadow","HcTextStroke"],init:function(a,b){var c=this;c.element="span"===b?p(b):lb.createElementNS(Fb,b),c.renderer=a},animate:function(a,c,d){var e=n(c,T,!0);return sc(this),e?(e=b(e,{}),d&&(e.complete=d),rc(this,a,e)):(this.attr(a),d&&d()),this},colorGradient:function(a,c,d){var e,g,h,i,j,l,m,n,o,p,q,r=this.renderer,s=[];if(a.linearGradient?g="linearGradient":a.radialGradient&&(g="radialGradient"),g){h=a[g],i=r.gradients,l=a.stops,o=d.radialReference,f(h)&&(a[g]=h={x1:h[0],y1:h[1],x2:h[2],y2:h[3],gradientUnits:"userSpaceOnUse"}),"radialGradient"===g&&o&&!k(h.gradientUnits)&&(h=b(h,{cx:o[0]-o[2]/2+h.cx*o[2],cy:o[1]-o[2]/2+h.cy*o[2],r:h.r*o[2],gradientUnits:"userSpaceOnUse"}));for(p in h)"id"!==p&&s.push(p,h[p]);for(p in l)s.push(l[p]);s=s.join(","),i[s]?q=i[s].attr("id"):(h.id=q=Ub+Kb++,i[s]=j=r.createElement(g).attr(h).add(r.defs),j.stops=[],jc(l,function(a){var b;0===a[1].indexOf("rgba")?(e=zc(a[1]),m=e.get("rgb"),n=e.get("a")):(m=a[1],n=1),b=r.createElement("stop").attr({offset:a[0],"stop-color":m,"stop-opacity":n}).add(j),j.stops.push(b)})),d.setAttribute(c,"url("+r.url+"#"+q+")")}},attr:function(a,b){var c,d,e,f,g=this.element,h=this;if("string"==typeof a&&b!==N&&(c=a,a={},a[c]=b),"string"==typeof a)h=(this[a+"Getter"]||this._defaultGetter).call(this,a,g);else{for(c in a)d=a[c],f=!1,this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(e||(this.symbolAttr(a),e=!0),f=!0),!this.rotation||"x"!==c&&"y"!==c||(this.doTransform=!0),f||(this[c+"Setter"]||this._defaultSetter).call(this,d,c,g),this.shadows&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c)&&this.updateShadows(c,d);this.doTransform&&(this.updateTransform(),this.doTransform=!1)}return h},updateShadows:function(a,b){for(var c=this.shadows,d=c.length;d--;)c[d].setAttribute(a,"height"===a?rb(b-(c[d].cutHeight||0),0):"d"===a?this.d:b)},addClass:function(a){var b=this.element,c=l(b,"class")||"";return-1===c.indexOf(a)&&l(b,"class",c+" "+a),this},symbolAttr:function(a){var b=this;jc(["x","y","r","start","end","width","height","innerR","anchorX","anchorY"],function(c){b[c]=n(a[c],b[c])}),b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path",a?"url("+this.renderer.url+"#"+a.id+")":Xb)},crisp:function(a){var b,c,d=this,e={},f=a.strokeWidth||d.strokeWidth||0;c=ob(f)%2/2,a.x=pb(a.x||d.x||0)+c,a.y=pb(a.y||d.y||0)+c,a.width=pb((a.width||d.width||0)-2*c),a.height=pb((a.height||d.height||0)-2*c),a.strokeWidth=f;for(b in a)d[b]!==a[b]&&(d[b]=e[b]=a[b]);return e},css:function(b){var d,e,f,g=this,h=g.styles,i={},j=g.element,k="",m=!h;if(b&&b.color&&(b.fill=b.color),h)for(e in b)b[e]!==h[e]&&(i[e]=b[e],m=!0);if(m){if(d=g.textWidth=b&&b.width&&"text"===j.nodeName.toLowerCase()&&c(b.width),h&&(b=a(h,i)),g.styles=b,d&&(Ib||!Gb&&g.renderer.forExport)&&delete b.width,Ab&&!Gb)o(g.element,b);else{f=function(a,b){return"-"+b.toLowerCase()};for(e in b)k+=e.replace(/([A-Z])/g,f)+":"+b[e]+";";l(j,"style",k)}d&&g.added&&g.renderer.buildText(g)}return g},on:function(a,b){var c=this,d=c.element;return P&&"click"===a?(d.ontouchstart=function(a){c.touchEventFired=Y.now(),a.preventDefault(),b.call(d,a)},d.onclick=function(a){(-1===yb.indexOf("Android")||Y.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d["on"+a]=b,this},setRadialReference:function(a){return this.element.radialReference=a,this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){var a=this;return a.inverted=!0,a.updateTransform(),a},updateTransform:function(){var a,b=this,c=b.translateX||0,d=b.translateY||0,e=b.scaleX,f=b.scaleY,g=b.inverted,h=b.rotation,i=b.element;g&&(c+=b.attr("width"),d+=b.attr("height")),a=["translate("+c+","+d+")"],g?a.push("rotate(90) scale(-1,1)"):h&&a.push("rotate("+h+" "+(i.getAttribute("x")||0)+" "+(i.getAttribute("y")||0)+")"),(k(e)||k(f))&&a.push("scale("+n(e,1)+" "+n(f,1)+")"),a.length&&i.setAttribute("transform",a.join(" "))},toFront:function(){var a=this.element;return a.parentNode.appendChild(a),this},align:function(a,b,c){var e,f,g,h,i,k={},l=this.renderer,m=l.alignedObjects;return a?(this.alignOptions=a,this.alignByTranslate=b,(!c||d(c))&&(this.alignTo=i=c||"renderer",j(m,this),m.push(this),c=null)):(a=this.alignOptions,b=this.alignByTranslate,i=this.alignTo),c=n(c,l[i],l),e=a.align,f=a.verticalAlign,g=(c.x||0)+(a.x||0),h=(c.y||0)+(a.y||0),("right"===e||"center"===e)&&(g+=(c.width-(a.width||0))/{right:1,center:2}[e]),k[b?"translateX":"x"]=ob(g),("bottom"===f||"middle"===f)&&(h+=(c.height-(a.height||0))/({bottom:1,middle:2}[f]||1)),k[b?"translateY":"y"]=ob(h),this[this.placed?"animate":"attr"](k),this.placed=!0,this.alignAttr=k,this},getBBox:function(){var b,c,d,e=this,f=e.bBox,g=e.renderer,h=e.rotation,i=e.element,j=e.styles,k=h*xb,l=e.textStr;if((""===l||$b.test(l))&&(d="num."+l.toString().length+(j?"|"+j.fontSize+"|"+j.fontFamily:"")),d&&(f=g.cache[d]),!f){if(i.namespaceURI===Fb||g.forExport){try{f=i.getBBox?a({},i.getBBox()):{width:i.offsetWidth,height:i.offsetHeight}}catch(m){}(!f||f.width<0)&&(f={width:0,height:0})}else f=e.htmlGetBBox();g.isSVG&&(b=f.width,c=f.height,Ab&&j&&"11px"===j.fontSize&&"16.9"===c.toPrecision(3)&&(f.height=c=14),h&&(f.width=tb(c*vb(k))+tb(b*ub(k)),f.height=tb(c*ub(k))+tb(b*vb(k)))),e.bBox=f,d&&(g.cache[d]=f)}return f},show:function(a){return a&&this.element.namespaceURI===Fb?this.element.removeAttribute("visibility"):this.attr({visibility:a?"inherit":Vb}),this},hide:function(){return this.attr({visibility:Tb})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.attr({y:-9999})}})},add:function(a){var b,d,e,f,g,h=this.renderer,i=a||h,j=i.element||h.box,m=this.element,n=this.zIndex;if(a&&(this.parentGroup=a),this.parentInverted=a&&a.inverted,void 0!==this.textStr&&h.buildText(this),n&&(i.handleZ=!0,n=c(n)),i.handleZ)for(b=j.childNodes,f=0;fn||!k(n)&&k(e))){j.insertBefore(m,d),g=!0;break}return g||j.appendChild(m),this.added=!0,this.onAdd&&this.onAdd(),this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a,b,c,d=this,e=d.element||{},f=d.shadows,g=d.renderer.isSVG&&"SPAN"===e.nodeName&&d.parentGroup;if(e.onclick=e.onmouseout=e.onmouseover=e.onmousemove=e.point=null,sc(d),d.clipPath&&(d.clipPath=d.clipPath.destroy()),d.stops){for(c=0;c=d;d++)e=k.cloneNode(0),f=2*g+1-2*d,l(e,{isShadow:"true",stroke:a.color||"black","stroke-opacity":h*d,"stroke-width":f,transform:"translate"+i,fill:Xb}),c&&(l(e,"height",rb(l(e,"height")-f,0)),e.cutHeight=f),b?b.element.appendChild(e):k.parentNode.insertBefore(e,k),j.push(e);this.shadows=j}return this},xGetter:function(a){return"circle"===this.element.nodeName&&(a={x:"cx",y:"cy"}[a]||a),this._defaultGetter(a)},_defaultGetter:function(a){var b=n(this[a],this.element?this.element.getAttribute(a):null,0);return/^[\-0-9\.]+$/.test(b)&&(b=parseFloat(b)),b},dSetter:function(a,b,c){a&&a.join&&(a=a.join(" ")),/(NaN| {2}|^$)/.test(a)&&(a="M 0 0"),c.setAttribute(b,a),this[b]=a},dashstyleSetter:function(a){var b;if(a=a&&a.toLowerCase()){for(a=a.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(","),b=a.length;b--;)a[b]=c(a[b])*this["stroke-width"];a=a.join(",").replace("NaN","none"),this.element.setAttribute("stroke-dasharray",a)}},alignSetter:function(a){this.element.setAttribute("text-anchor",{left:"start",center:"middle",right:"end"}[a])},opacitySetter:function(a,b,c){this[b]=a,c.setAttribute(b,a)},titleSetter:function(a){var b=this.element.getElementsByTagName("title")[0];b||(b=lb.createElementNS(Fb,"title"),this.element.appendChild(b)),b.textContent=n(a,"").replace(/<[^>]*>/g,"")},textSetter:function(a){a!==this.textStr&&(delete this.bBox,this.textStr=a,this.added&&this.renderer.buildText(this))},fillSetter:function(a,b,c){"string"==typeof a?c.setAttribute(b,a):a&&this.colorGradient(a,b,c)},zIndexSetter:function(a,b,c){c.setAttribute(b,a),this[b]=a},_defaultSetter:function(a,b,c){c.setAttribute(b,a)}},I.prototype.yGetter=I.prototype.xGetter,I.prototype.translateXSetter=I.prototype.translateYSetter=I.prototype.rotationSetter=I.prototype.verticalAlignSetter=I.prototype.scaleXSetter=I.prototype.scaleYSetter=function(a,b){this[b]=a,this.doTransform=!0},I.prototype["stroke-widthSetter"]=I.prototype.strokeSetter=function(a,b,c){this[b]=a,this.stroke&&this["stroke-width"]?(this.strokeWidth=this["stroke-width"],I.prototype.fillSetter.call(this,this.stroke,"stroke",c),c.setAttribute("stroke-width",this["stroke-width"]),this.hasStroke=!0):"stroke-width"===b&&0===a&&this.hasStroke&&(c.removeAttribute("stroke"),this.hasStroke=!1)};var Ac=function(){this.init.apply(this,arguments)};Ac.prototype={Element:I,init:function(a,b,c,d,e){var f,g,h,i=this,j=location;f=i.createElement("svg").attr({version:"1.1"}).css(this.getStyle(d)),g=f.element,a.appendChild(g),-1===a.innerHTML.indexOf("xmlns")&&l(g,"xmlns",Fb),i.isSVG=!0,i.box=g,i.boxWrapper=f,i.alignedObjects=[],i.url=(Db||Cb)&&lb.getElementsByTagName("base").length?j.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"",h=this.createElement("desc").add(),h.element.appendChild(lb.createTextNode("Created with "+Ob+" "+Pb)),i.defs=this.createElement("defs").add(),i.forExport=e,i.gradients={},i.cache={},i.setSize(b,c,!1);var k,m;Db&&a.getBoundingClientRect&&(i.subPixelFix=k=function(){o(a,{left:0,top:0}),m=a.getBoundingClientRect(),o(a,{left:qb(m.left)-m.left+Wb,top:qb(m.top)-m.top+Wb})},k(),nc(mb,"resize",k))},getStyle:function(b){return this.style=a({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this,b=a.defs;return a.box=null,a.boxWrapper=a.boxWrapper.destroy(),B(a.gradients||{}),a.gradients=null,b&&(a.defs=b.destroy()),a.subPixelFix&&oc(mb,"resize",a.subPixelFix),a.alignedObjects=null,null},createElement:function(a){var b=new this.Element;return b.init(this,a),b},draw:function(){},buildText:function(a){for(var b,d,e,f=a.element,g=this,h=g.forExport,i=n(a.textStr,"").toString(),j=-1!==i.indexOf("<"),k=f.childNodes,m=l(f,"x"),p=a.styles,q=a.textWidth,r=p&&p.lineHeight,s=p&&p.HcTextStroke,t=k.length,u=function(a){return r?c(r):g.fontMetrics(/(px|em)$/.test(a&&a.style.fontSize)?a.style.fontSize:p&&p.fontSize||g.style.fontSize||12,a).h};t--;)f.removeChild(k[t]);return j||s||-1!==i.indexOf(" ")?(d=/<.*style="([^"]+)".*>/,e=/<.*href="(http[^"]+)".*>/,q&&!a.added&&this.box.appendChild(f),b=j?i.replace(/<(b|strong)>/g,'').replace(/<(i|em)>/g,'').replace(//g,"").split(//g):[i],""===b[b.length-1]&&b.pop(),jc(b,function(b,c){var i,j=0;b=b.replace(//g,"|||"),i=b.split("|||"),jc(i,function(b){if(""!==b||1===i.length){var k,n={},r=lb.createElementNS(Fb,"tspan");if(d.test(b)&&(k=b.match(d)[1].replace(/(;| |^)color([ :])/,"$1fill$2"),l(r,"style",k)),e.test(b)&&!h&&(l(r,"onclick",'location.href="'+b.match(e)[1]+'"'),o(r,{cursor:"pointer"})),b=(b.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">")," "!==b){if(r.appendChild(lb.createTextNode(b)),j?n.dx=0:c&&null!==m&&(n.x=m),l(r,n),f.appendChild(r),!j&&c&&(!Gb&&h&&o(r,{display:"block"}),l(r,"dy",u(r))),q)for(var s,t,v,w=b.replace(/([^\^])-/g,"$1- ").split(" "),x=i.length>1||w.length>1&&"nowrap"!==p.whiteSpace,y=p.HcHeight,z=[],A=u(r),B=1;x&&(w.length||z.length);)delete a.bBox,v=a.getBBox(),t=v.width,!Gb&&g.forExport&&(t=g.measureSpanWidth(r.firstChild.data,a.styles)),s=t>q,s&&1!==w.length?(r.removeChild(r.firstChild),z.unshift(w.pop())):(w=z,z=[],w.length&&(B++,y&&B*A>y?(w=["..."],a.attr("title",a.textStr)):(r=lb.createElementNS(Fb,"tspan"),l(r,{dy:A,x:m}),k&&l(r,"style",k),f.appendChild(r))),t>q&&(q=t)),w.length&&r.appendChild(lb.createTextNode(w.join(" ").replace(/- /g,"-")));j++}}})}),void 0):void f.appendChild(lb.createTextNode(i))},button:function(c,d,e,f,g,h,i,j,k){var l,m,n,o,p,q,r=this.label(c,d,e,k,null,null,null,null,"button"),s=0,t={x1:0,y1:0,x2:0,y2:1};return g=b({"stroke-width":1,stroke:"#CCCCCC",fill:{linearGradient:t,stops:[[0,"#FEFEFE"],[1,"#F6F6F6"]]},r:2,padding:5,style:{color:"black"}},g),n=g.style,delete g.style,h=b(g,{stroke:"#68A",fill:{linearGradient:t,stops:[[0,"#FFF"],[1,"#ACF"]]}},h),o=h.style,delete h.style,i=b(g,{stroke:"#68A",fill:{linearGradient:t,stops:[[0,"#9BD"],[1,"#CDF"]]}},i),p=i.style,delete i.style,j=b(g,{style:{color:"#CCC"}},j),q=j.style,delete j.style,nc(r.element,Ab?"mouseover":"mouseenter",function(){3!==s&&r.attr(h).css(o)}),nc(r.element,Ab?"mouseout":"mouseleave",function(){3!==s&&(l=[g,h,i][s],m=[n,o,p][s],r.attr(l).css(m))}),r.setState=function(a){r.state=s=a,a?2===a?r.attr(i).css(p):3===a&&r.attr(j).css(q):r.attr(g).css(n)},r.on("click",function(){3!==s&&f.call(r)}).attr(g).css(a({cursor:"default"},n))},crispLine:function(a,b){return a[1]===a[4]&&(a[1]=a[4]=ob(a[1])-b%2/2),a[2]===a[5]&&(a[2]=a[5]=ob(a[2])+b%2/2),a},path:function(b){var c={fill:Xb};return f(b)?c.d=b:e(b)&&a(c,b),this.createElement("path").attr(c)},circle:function(a,b,c){var d=e(a)?a:{x:a,y:b,r:c},f=this.createElement("circle");return f.xSetter=function(a){this.element.setAttribute("cx",a)},f.ySetter=function(a){this.element.setAttribute("cy",a)},f.attr(d)},arc:function(a,b,c,d,f,g){var h;return e(a)&&(b=a.y,c=a.r,d=a.innerR,f=a.start,g=a.end,a=a.x),h=this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:f||0,end:g||0}),h.r=c,h},rect:function(a,b,c,d,f,g){f=e(a)?a.r:f;var h=this.createElement("rect"),i=e(a)?a:a===N?{}:{x:a,y:b,width:rb(c,0),height:rb(d,0)};return g!==N&&(i.strokeWidth=g,i=h.crisp(i)),f&&(i.r=f),h.rSetter=function(a){l(this.element,{rx:a,ry:a})},h.attr(i)},setSize:function(a,b,c){var d=this,e=d.alignedObjects,f=e.length;for(d.width=a,d.height=b,d.boxWrapper[n(c,!0)?"animate":"attr"]({width:a,height:b});f--;)e[f].align()},g:function(a){var b=this.createElement("g");return k(a)?b.attr({"class":Ub+a}):b},image:function(b,c,d,e,f){var g,h={preserveAspectRatio:Xb};return arguments.length>1&&a(h,{x:c,y:d,width:e,height:f}),g=this.createElement("image").attr(h),g.element.setAttributeNS?g.element.setAttributeNS("http://www.w3.org/1999/xlink","href",b):g.element.setAttribute("hc-svg-href",b),g},symbol:function(b,c,d,e,f,g){var h,i,j,k,l,m=this.symbols[b],n=m&&m(ob(c),ob(d),e,f,g),o=/^url\((.*?)\)$/;return n?(h=this.path(n),a(h,{symbolName:b,x:c,y:d,width:e,height:f}),g&&a(h,g)):o.test(b)&&(l=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(ob((e-b[0])/2),ob((f-b[1])/2)))},j=b.match(o)[1],k=Jb[j]||g&&g.width&&g.height&&[g.width,g.height],h=this.image(j).attr({x:c,y:d}),h.isImg=!0,k?l(h,k):(h.attr({width:0,height:0}),i=p("img",{onload:function(){l(h,Jb[j]=[this.width,this.height])},src:j}))),h},symbols:{circle:function(a,b,c,d){var e=.166*c;return[Yb,a+c/2,b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return[Yb,a,b,Zb,a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return[Yb,a+c/2,b,Zb,a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return[Yb,a,b,Zb,a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return[Yb,a+c/2,b,Zb,a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,g=e.r||c||d,h=e.end-.001,i=e.innerR,j=e.open,k=ub(f),l=vb(f),m=ub(h),n=vb(h),o=e.end-fc&&l>b+j&&b+d-j>l?f.splice(13,3,"L",a+c,l-h,a+c+g,l,a+c,l+h,a+c,b+d-i):k&&0>k&&l>b+j&&b+d-j>l?f.splice(33,3,"L",a,l+h,a-g,l,a,l-h,a,b+i):l&&l>d&&k>a+j&&a+c-j>k?f.splice(23,3,"L",k+h,b+d,k,b+d+g,k-h,b+d,a+i,b+d):l&&0>l&&k>a+j&&a+c-j>k&&f.splice(3,3,"L",k-h,b,k,b-g,k+h,b,c-i,b),f}},clipRect:function(a,b,c,d){var e,f=Ub+Kb++,g=this.createElement("clipPath").attr({id:f}).add(this.defs);return e=this.rect(a,b,c,d,0).add(g),e.id=f,e.clipPath=g,e},text:function(a,b,c,d){var e,f=this,g=Ib||!Gb&&f.forExport,h={};return d&&!f.forExport?f.html(a,b,c):(h.x=Math.round(b||0),c&&(h.y=Math.round(c)),(a||0===a)&&(h.text=a),e=f.createElement("text").attr(h),g&&e.css({position:Rb}),d||(e.xSetter=function(a,b,c){var d,e,f=c.getElementsByTagName("tspan"),g=c.getAttribute(b);for(e=0;ea?a+4:ob(1.2*a),e=ob(.8*d);return{h:d,b:e,f:a}},label:function(c,d,e,f,g,h,i,j,l){function m(){var b,c,d=z.element.style;q=(void 0===r||void 0===s||y.styles.textAlign)&&z.textStr&&z.getBBox(),y.width=(r||q.width||0)+2*B+C,y.height=(s||q.height||0)+2*B,v=B+x.fontMetrics(d&&d.fontSize,z).b,w&&(p||(b=ob(-A*B),c=j?-v:0,y.box=p=f?x.symbol(f,b,c,y.width,y.height,E):x.rect(b,c,y.width,y.height,0,E[cc]),p.attr("fill",Xb).add(y)),p.isImg||p.attr(a({width:ob(y.width),height:ob(y.height)},E)),E=null)}function n(){var a,b=y.styles,c=b&&b.textAlign,d=C+B*(1-A);a=j?0:v,k(r)&&q&&("center"===c||"right"===c)&&(d+={center:.5,right:1}[c]*(r-q.width)),(d!==z.x||a!==z.y)&&(z.attr("x",d),a!==N&&z.attr("y",a)),z.x=d,z.y=a }function o(a,b){p?p.attr(a,b):E[a]=b}var p,q,r,s,t,u,v,w,x=this,y=x.g(l),z=x.text("",0,0,i).attr({zIndex:1}),A=0,B=3,C=0,D=0,E={};y.onAdd=function(){z.add(y),y.attr({text:c||0===c?c:"",x:d,y:e}),p&&k(g)&&y.attr({anchorX:g,anchorY:h})},y.widthSetter=function(a){r=a},y.heightSetter=function(a){s=a},y.paddingSetter=function(a){k(a)&&a!==B&&(B=a,n())},y.paddingLeftSetter=function(a){k(a)&&a!==C&&(C=a,n())},y.alignSetter=function(a){A={left:0,center:.5,right:1}[a]},y.textSetter=function(a){a!==N&&z.textSetter(a),m(),n()},y["stroke-widthSetter"]=function(a,b){a&&(w=!0),D=a%2/2,o(b,a)},y.strokeSetter=y.fillSetter=y.rSetter=function(a,b){"fill"===b&&a&&(w=!0),o(b,a)},y.anchorXSetter=function(a,b){g=a,o(b,a+D-t)},y.anchorYSetter=function(a,b){h=a,o(b,a-u)},y.xSetter=function(a){y.x=a,A&&(a-=A*((r||q.width)+B)),t=ob(a),y.attr("translateX",t)},y.ySetter=function(a){u=y.y=ob(a),y.attr("translateY",u)};var F=y.css;return a(y,{css:function(a){if(a){var c={};a=b(a),jc(y.textProps,function(b){a[b]!==N&&(c[b]=a[b],delete a[b])}),z.css(c)}return F.call(y,a)},getBBox:function(){return{width:q.width+2*B,height:q.height+2*B,x:q.x-B,y:q.y-B}},shadow:function(a){return p&&p.shadow(a),y},destroy:function(){oc(y.element,"mouseenter"),oc(y.element,"mouseleave"),z&&(z=z.destroy()),p&&(p=p.destroy()),I.prototype.destroy.call(y),y=x=m=n=o=null}})}},O=Ac,a(I.prototype,{htmlCss:function(b){var c=this,d=c.element,e=b&&"SPAN"===d.tagName&&b.width;return e&&(delete b.width,c.textWidth=e,c.updateTransform()),c.styles=a(c.styles,b),o(c.element,b),c},htmlGetBBox:function(){var a=this,b=a.element,c=a.bBox;return c||("text"===b.nodeName&&(b.style.position=Rb),c=a.bBox={x:b.offsetLeft,y:b.offsetTop,width:b.offsetWidth,height:b.offsetHeight}),c},htmlUpdateTransform:function(){if(!this.added)return void(this.alignOnAdd=!0);var a=this,b=a.renderer,d=a.element,e=a.translateX||0,f=a.translateY||0,g=a.x||0,h=a.y||0,i=a.textAlign||"left",j={left:0,center:.5,right:1}[i],l=a.shadows;if(o(d,{marginLeft:e,marginTop:f}),l&&jc(l,function(a){o(a,{marginLeft:e+1,marginTop:f+1})}),a.inverted&&jc(d.childNodes,function(a){b.invertChild(a,d)}),"SPAN"===d.tagName){var m,p,q=a.rotation,r=c(a.textWidth),s=[q,i,d.innerHTML,a.textWidth].join(",");s!==a.cTT&&(p=b.fontMetrics(d.style.fontSize).b,k(q)&&a.setSpanRotation(q,j,p),m=n(a.elemWidth,d.offsetWidth),m>r&&/[ \-]/.test(d.textContent||d.innerText)&&(o(d,{width:r+Wb,display:"block",whiteSpace:"normal"}),m=r),a.getSpanCorrection(m,p,j,q,i)),o(d,{left:g+(a.xCorr||0)+Wb,top:h+(a.yCorr||0)+Wb}),Cb&&(p=d.offsetHeight),a.cTT=s}},setSpanRotation:function(a,b,c){var d={},e=Ab?"-ms-transform":Cb?"-webkit-transform":Db?"MozTransform":zb?"-o-transform":"";d[e]=d.transform="rotate("+a+"deg)",d[e+(Db?"Origin":"-origin")]=d.transformOrigin=100*b+"% "+c+"px",o(this.element,d)},getSpanCorrection:function(a,b,c){this.xCorr=-a*c,this.yCorr=-b}}),a(Ac.prototype,{html:function(b,c,d){var e=this.createElement("span"),f=e.element,g=e.renderer;return e.textSetter=function(a){a!==f.innerHTML&&delete this.bBox,f.innerHTML=this.textStr=a},e.xSetter=e.ySetter=e.alignSetter=e.rotationSetter=function(a,b){"align"===b&&(b="textAlign"),e[b]=a,e.htmlUpdateTransform()},e.attr({text:b,x:ob(c),y:ob(d)}).css({position:Rb,whiteSpace:"nowrap",fontFamily:this.style.fontFamily,fontSize:this.style.fontSize}),e.css=e.htmlCss,g.isSVG&&(e.add=function(b){var c,d,h=g.box.parentNode,i=[];if(this.parentGroup=b,b){if(c=b.div,!c){for(d=b;d;)i.push(d),d=d.parentGroup;jc(i.reverse(),function(b){var d;c=b.div=b.div||p(Qb,{className:l(b.element,"class")},{position:Rb,left:(b.translateX||0)+Wb,top:(b.translateY||0)+Wb},c||h),d=c.style,a(b,{translateXSetter:function(a,c){d.left=a+Wb,b[c]=a,b.doTransform=!0},translateYSetter:function(a,c){d.top=a+Wb,b[c]=a,b.doTransform=!0},visibilitySetter:function(a,b){d[b]=a}})})}}else c=h;return c.appendChild(f),e.added=!0,e.alignOnAdd&&e.htmlUpdateTransform(),e}),e}});var Bc,Cc;if(!Gb&&!Ib){Cc={init:function(a,b){var c=this,d=["<",b,' filled="f" stroked="f"'],e=["position: ",Rb,";"],f=b===Qb;("shape"===b||f)&&e.push("left:0;top:0;width:1px;height:1px;"),e.push("visibility: ",f?Tb:Vb),d.push(' style="',e.join(""),'"/>'),b&&(d=f||"span"===b||"img"===b?d.join(""):a.prepVML(d),c.element=p(d)),c.renderer=a},add:function(a){var b=this,c=b.renderer,d=b.element,e=c.box,f=a&&a.inverted,g=a?a.element||a:e;return f&&c.invertChild(d,g),g.appendChild(d),b.added=!0,b.alignOnAdd&&!b.deferUpdateTransform&&b.updateTransform(),b.onAdd&&b.onAdd(),b},updateTransform:I.prototype.htmlUpdateTransform,setSpanRotation:function(){var a=this.rotation,b=ub(a*xb),c=vb(a*xb);o(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11=",b,", M12=",-c,", M21=",c,", M22=",b,", sizingMethod='auto expand')"].join(""):Xb})},getSpanCorrection:function(a,b,c,d,e){var f,g=d?ub(d*xb):1,h=d?vb(d*xb):0,i=n(this.elemHeight,this.element.offsetHeight),j=e&&"left"!==e;this.xCorr=0>g&&-a,this.yCorr=0>h&&-i,f=0>g*h,this.xCorr+=h*b*(f?1-c:c),this.yCorr-=g*b*(d?f?c:1-c:1),j&&(this.xCorr-=a*c*(0>g?-1:1),d&&(this.yCorr-=i*c*(0>h?-1:1)),o(this.element,{textAlign:e}))},pathToVML:function(a){for(var b=a.length,c=[];b--;)g(a[b])?c[b]=ob(10*a[b])-5:"Z"===a[b]?c[b]="x":(c[b]=a[b],!a.isArc||"wa"!==a[b]&&"at"!==a[b]||(c[b+5]===c[b+7]&&(c[b+7]+=a[b+7]>a[b+5]?1:-1),c[b+6]===c[b+8]&&(c[b+8]+=a[b+8]>a[b+6]?1:-1)));return c.join(" ")||"x"},clip:function(a){var b,c,d=this;return a?(b=a.members,j(b,d),b.push(d),d.destroyClip=function(){j(b,d)},c=a.getCSS(d)):(d.destroyClip&&d.destroyClip(),c={clip:Bb?"inherit":"rect(auto)"}),d.css(c)},css:I.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&C(a)},destroy:function(){return this.destroyClip&&this.destroyClip(),I.prototype.destroy.apply(this)},on:function(a,b){return this.element["on"+a]=function(){var a=mb.event;a.target=a.srcElement,b(a)},this},cutOffPath:function(a,b){var d;return a=a.split(/[ ,]/),d=a.length,(9===d||11===d)&&(a[d-4]=a[d-2]=c(a[d-2])-10*b),a.join(" ")},shadow:function(a,b,d){var e,f,g,h,i,j,k,l=[],m=this.element,o=this.renderer,q=m.style,r=m.path;if(r&&"string"!=typeof r.value&&(r="x"),i=r,a){for(j=n(a.width,3),k=(a.opacity||.15)/j,e=1;3>=e;e++)h=2*j+1-2*e,d&&(i=this.cutOffPath(r.value,h+.5)),g=[''],f=p(o.prepVML(g),null,{left:c(q.left)+n(a.offsetX,1),top:c(q.top)+n(a.offsetY,1)}),d&&(f.cutOff=h+1),g=[''],p(o.prepVML(g),null,null,f),b?b.element.appendChild(f):m.parentNode.insertBefore(f,m),l.push(f);this.shadows=l}return this},updateShadows:Lb,setAttr:function(a,b){Bb?this.element[a]=b:this.element.setAttribute(a,b)},classSetter:function(a){this.element.className=a},dashstyleSetter:function(a,b,c){var d=c.getElementsByTagName("stroke")[0]||p(this.renderer.prepVML([""]),null,null,c);d[b]=a||"solid",this[b]=a},dSetter:function(a,b,c){var d,e=this.shadows;if(a=a||[],this.d=a.join&&a.join(" "),c.path=a=this.pathToVML(a),e)for(d=e.length;d--;)e[d].path=e[d].cutOff?this.cutOffPath(a,e[d].cutOff):a;this.setAttr(b,a)},fillSetter:function(a,b,c){var d=c.nodeName;"SPAN"===d?c.style.color=a:"IMG"!==d&&(c.filled=a!==Xb,this.setAttr("fillcolor",this.renderer.color(a,c,b,this)))},opacitySetter:Lb,rotationSetter:function(a,b,c){var d=c.style;this[b]=d[b]=a,d.left=-ob(vb(a*xb)+1)+Wb,d.top=ob(ub(a*xb))+Wb},strokeSetter:function(a,b,c){this.setAttr("strokecolor",this.renderer.color(a,c,b))},"stroke-widthSetter":function(a,b,c){c.stroked=!!a,this[b]=a,g(a)&&(a+=Wb),this.setAttr("strokeweight",a)},titleSetter:function(a,b){this.setAttr(b,a)},visibilitySetter:function(a,b,c){"inherit"===a&&(a=Vb),this.shadows&&jc(this.shadows,function(c){c.style[b]=a}),"DIV"===c.nodeName&&(a=a===Tb?"-999em":0,Bb||(c.style[b]=a?Vb:Tb),b="top"),c.style[b]=a},xSetter:function(a,b,c){this[b]=a,"x"===b?b="left":"y"===b&&(b="top"),this.updateClipping?(this[b]=a,this.updateClipping()):c.style[b]=a},zIndexSetter:function(a,b,c){c.style[b]=a}},kb.VMLElement=Cc=q(I,Cc),Cc.prototype.ySetter=Cc.prototype.widthSetter=Cc.prototype.heightSetter=Cc.prototype.xSetter;var Dc={Element:Cc,isIE8:yb.indexOf("MSIE 8.0")>-1,init:function(b,c,d,e){var f,g,h,i=this;if(i.alignedObjects=[],f=i.createElement(Qb).css(a(this.getStyle(e),{position:Sb})),g=f.element,b.appendChild(f.element),i.isVML=!0,i.box=g,i.boxWrapper=f,i.cache={},i.setSize(c,d,!1),!lb.namespaces.hcv){lb.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),h="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } ";try{lb.createStyleSheet().cssText=h}catch(j){lb.styleSheets[0].cssText+=h}}},isHidden:function(){return!this.box.offsetWidth},clipRect:function(b,c,d,f){var g=this.createElement(),h=e(b);return a(g,{members:[],left:(h?b.x:b)+1,top:(h?b.y:c)+1,width:(h?b.width:d)-1,height:(h?b.height:f)-1,getCSS:function(b){var c=b.element,d=c.nodeName,e="shape"===d,f=b.inverted,g=this,h=g.top-(e?c.offsetTop:0),i=g.left,j=i+g.width,k=h+g.height,l={clip:"rect("+ob(f?i:h)+"px,"+ob(f?k:j)+"px,"+ob(f?j:k)+"px,"+ob(f?h:i)+"px)"};return!f&&Bb&&"DIV"===d&&a(l,{width:j+Wb,height:k+Wb}),l},updateClipping:function(){jc(g.members,function(a){a.element&&a.css(g.getCSS(a))})}})},color:function(a,b,c,d){var e,f,g,h=this,i=/^rgba/,j=Xb;if(a&&a.linearGradient?g="gradient":a&&a.radialGradient&&(g="pattern"),g){var k,l,m,n,o,q,r,s,t,u,v,w,x=a.linearGradient||a.radialGradient,y="",z=a.stops,A=[],B=function(){f=[''],p(h.prepVML(f),null,null,b)};if(v=z[0],w=z[z.length-1],v[0]>0&&z.unshift([0,v[1]]),w[0]<1&&z.push([1,w[1]]),jc(z,function(a,b){i.test(a[1])?(e=zc(a[1]),k=e.get("rgb"),l=e.get("a")):(k=a[1],l=1),A.push(100*a[0]+"% "+k),b?(s=l,t=k):(r=l,u=k)}),"fill"===c)if("gradient"===g)m=x.x1||x[0]||0,n=x.y1||x[1]||0,o=x.x2||x[2]||0,q=x.y2||x[3]||0,y='angle="'+(90-180*nb.atan((q-n)/(o-m))/wb)+'"',B();else{var C,D=x.r,E=2*D,F=2*D,G=x.cx,H=x.cy,I=b.radialReference,J=function(){I&&(C=d.getBBox(),G+=(I[0]-C.x)/C.width-.5,H+=(I[1]-C.y)/C.height-.5,E*=I[2]/C.width,F*=I[2]/C.height),y='src="'+R.global.VMLRadialGradientURL+'" size="'+E+","+F+'" origin="0.5,0.5" position="'+G+","+H+'" color2="'+u+'" ',B()};d.added?J():d.onAdd=J,j=t}else j=k}else if(i.test(a)&&"IMG"!==b.tagName)e=zc(a),f=["<",c,' opacity="',e.get("a"),'"/>'],p(this.prepVML(f),null,null,b),j=e.get("rgb");else{var K=b.getElementsByTagName(c);K.length&&(K[0].opacity=1,K[0].type="solid"),j=a}return j},prepVML:function(a){var b="display:inline-block;behavior:url(#default#VML);",c=this.isIE8;return a=a.join(""),c?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=-1===a.indexOf('style="')?a.replace("/>",' style="'+b+'" />'):a.replace('style="','style="'+b)):a=a.replace("<","1&&f.attr({x:b,y:c,width:d,height:e}),f},createElement:function(a){return"rect"===a?this.symbol(a):Ac.prototype.createElement.call(this,a)},invertChild:function(a,b){var d=this,e=b.style,f="IMG"===a.tagName&&a.style;o(a,{flip:"x",left:c(e.width)-(f?c(f.top):1),top:c(e.height)-(f?c(f.left):1),rotation:-90}),jc(a.childNodes,function(b){d.invertChild(b,a)})},symbols:{arc:function(a,b,c,d,e){var f,g=e.start,h=e.end,i=e.r||c||d,j=e.innerR,k=ub(g),l=vb(g),m=ub(h),n=vb(h);return h-g===0?["x"]:(f=["wa",a-i,b-i,a+i,b+i,a+i*k,b+i*l,a+i*m,b+i*n],e.open&&!j&&f.push("e",Yb,a,b),f.push("at",a-j,b-j,a+j,b+j,a+j*m,b+j*n,a+j*k,b+j*l,"x","e"),f.isArc=!0,f)},circle:function(a,b,c,d,e){return e&&(c=d=2*e.r),e&&e.isCircle&&(a-=c/2,b-=d/2),["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){return Ac.prototype.symbols[k(e)&&e.r?"callout":"square"].call(0,a,b,c,d,e)}}};kb.VMLRenderer=Bc=function(){this.init.apply(this,arguments)},Bc.prototype=b(Ac.prototype,Dc),O=Bc}Ac.prototype.measureSpanWidth=function(a,b){var c,d=lb.createElement("span"),e=lb.createTextNode(a);return d.appendChild(e),o(d,b),this.box.appendChild(d),c=d.offsetWidth,C(d),c};var Ec,Fc;Ib&&(kb.CanVGRenderer=Ec=function(){Fb="http://www.w3.org/1999/xhtml"},Ec.prototype.symbols={},Fc=function(){function a(){var a,c=b.length;for(a=0;c>a;a++)b[a]();b=[]}var b=[];return{push:function(c,d){0===b.length&&hc(d,a),b.push(c)}}}(),O=Ec),J.prototype={addLabel:function(){var b,c,d,e,f=this,h=f.axis,j=h.options,l=h.chart,m=h.horiz,o=h.categories,p=h.names,q=f.pos,r=j.labels,s=r.rotation,t=h.tickPositions,u=m&&o&&!r.step&&!r.staggerLines&&!r.rotation&&l.plotWidth/t.length||!m&&(l.margin[3]||.33*l.chartWidth),v=q===t[0],w=q===t[t.length-1],x=o?n(o[q],p[q],q):q,y=f.label,z=t.info;h.isDatetimeAxis&&z&&(e=j.dateTimeLabelFormats[z.higherRanks[q]||z.unitName]),f.isFirst=v,f.isLast=w,b=h.labelFormatter.call({axis:h,chart:l,isFirst:v,isLast:w,dateTimeLabelFormat:e,value:h.isLog?D(i(x)):x}),c=u&&{width:rb(1,ob(u-2*(r.padding||10)))+Wb},k(y)?y&&y.attr({text:b}).css(c):(d={align:h.labelAlign},g(s)&&(d.rotation=s),u&&r.ellipsis&&(c.HcHeight=h.len/t.length),f.label=y=k(b)&&r.enabled?l.renderer.text(b,0,0,r.useHTML).attr(d).css(a(c,r.style)).add(h.labelGroup):null,h.tickBaseline=l.renderer.fontMetrics(r.style.fontSize,y).b,s&&2===h.side&&(h.tickBaseline*=ub(s*xb))),f.yOffset=y?n(r.y,h.tickBaseline+(2===h.side?8:-(y.getBBox().height/2))):0},getLabelSize:function(){var a=this.label,b=this.axis;return a?a.getBBox()[b.horiz?"height":"width"]:0},getLabelSides:function(){var a=this.label.getBBox(),b=this.axis,c=b.horiz,d=b.options,e=d.labels,f=c?a.width:a.height,g=c?e.x-f*{left:0,center:.5,right:1}[b.labelAlign]:0,h=c?f+g:f;return[g,h]},handleOverflow:function(a,b){var c,d,e,f,g,h=!0,i=this.axis,j=this.isFirst,k=this.isLast,l=i.horiz,m=l?b.x:b.y,n=i.reversed,o=i.tickPositions,p=this.getLabelSides(),q=p[0],r=p[1],s=this.label.line,t=s||0,u=i.labelEdge,v=i.justifyLabels&&(j||k);if(u[t]===N||m+q>u[t]?u[t]=m+r:v||(h=!1),v){g=i.justifyToPlot,c=g?i.pos:0,d=g?c+i.len:i.chart.chartWidth;do a+=j?1:-1,e=i.ticks[o[a]];while(o[a]&&(!e||!e.label||e.label.line!==s));f=e&&e.label.xy&&e.label.xy.x+e.getLabelSides()[j?0:1],j&&!n||k&&n?c>m+q&&(m=c-q,e&&m+r>f&&(h=!1)):m+r>d&&(m=d-r,e&&f>m+q&&(h=!1)),b.x=m}return h},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?g-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines;return a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+this.yOffset-(f&&!d?f*j*(k?1:-1):0),l&&(c.line=g/(h||1)%l,b+=c.line*(i.labelOffset/l)),{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine([Yb,a,b,Zb,a+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d,e,f,g=this,h=g.axis,i=h.options,j=h.chart,k=j.renderer,l=h.horiz,m=g.type,o=g.label,p=g.pos,q=i.labels,r=g.gridLine,s=m?m+"Grid":"grid",t=m?m+"Tick":"tick",u=i[s+"LineWidth"],v=i[s+"LineColor"],w=i[s+"LineDashStyle"],x=i[t+"Length"],y=i[t+"Width"]||0,z=i[t+"Color"],A=i[t+"Position"],B=g.mark,C=q.step,D=!0,E=h.tickmarkOffset,F=g.getPosition(l,p,E,b),G=F.x,H=F.y,I=l&&G===h.pos+h.len||!l&&H===h.pos?-1:1;c=n(c,1),this.isActive=!0,u&&(d=h.getPlotLinePath(p+E,u*I,b,!0),r===N&&(f={stroke:v,"stroke-width":u},w&&(f.dashstyle=w),m||(f.zIndex=1),b&&(f.opacity=0),g.gridLine=r=u?k.path(d).attr(f).add(h.gridGroup):null),!b&&r&&d&&r[g.isNew?"attr":"animate"]({d:d,opacity:c})),y&&x&&("inside"===A&&(x=-x),h.opposite&&(x=-x),e=g.getMarkPath(G,H,x,y*I,l,k),B?B.animate({d:e,opacity:c}):g.mark=k.path(e).attr({stroke:z,"stroke-width":y,opacity:c}).add(h.axisGroup)),o&&!isNaN(G)&&(o.xy=F=g.getLabelPosition(G,H,o,l,q,E,a,C),g.isFirst&&!g.isLast&&!n(i.showFirstLabel,1)||g.isLast&&!g.isFirst&&!n(i.showLastLabel,1)?D=!1:h.isRadial||q.step||q.rotation||b||0===c||(D=g.handleOverflow(a,F)),C&&a%C&&(D=!1),D&&!isNaN(F.y)?(F.opacity=c,o[g.isNew?"attr":"animate"](F),g.isNew=!1):o.attr("y",-9999))},destroy:function(){B(this,this.axis)}},kb.PlotLineOrBand=function(a,b){this.axis=a,b&&(this.options=b,this.id=b.id)},kb.PlotLineOrBand.prototype={render:function(){var a,c,d,e,f,g,i=this,j=i.axis,l=j.horiz,m=(j.pointRange||0)/2,n=i.options,o=n.label,p=i.label,q=n.width,r=n.to,s=n.from,t=k(s)&&k(r),u=n.value,v=n.dashStyle,w=i.svgElem,x=[],y=n.color,B=n.zIndex,C=n.events,D={},E=j.chart.renderer;if(j.isLog&&(s=h(s),r=h(r),u=h(u)),q)x=j.getPlotLinePath(u,q),D={stroke:y,"stroke-width":q},v&&(D.dashstyle=v);else{if(!t)return;s=rb(s,j.min-m),r=sb(r,j.max+m),x=j.getPlotBandPath(s,r,n),y&&(D.fill=y),n.borderWidth&&(D.stroke=n.borderColor,D["stroke-width"]=n.borderWidth)}if(k(B)&&(D.zIndex=B),w)x?w.animate({d:x},null,w.onGetPath):(w.hide(),w.onGetPath=function(){w.show()},p&&(i.label=p=p.destroy()));else if(x&&x.length&&(i.svgElem=w=E.path(x).attr(D).add(),C)){a=function(a){w.on(a,function(b){C[a].apply(i,[b])})};for(c in C)a(c)}return o&&k(o.text)&&x&&x.length&&j.width>0&&j.height>0?(o=b({align:l&&t&&"center",x:l?!t&&4:10,verticalAlign:!l&&t&&"middle",y:l?t?16:10:t?6:-4,rotation:l&&!t&&90},o),p||(D={align:o.textAlign||o.align,rotation:o.rotation},k(B)&&(D.zIndex=B),i.label=p=E.text(o.text,0,0,o.useHTML).attr(D).css(o.style).add()),d=[x[1],x[4],t?x[6]:x[1]],e=[x[2],x[5],t?x[7]:x[2]],f=z(d),g=z(e),p.align(o,!1,{x:f,y:g,width:A(d)-f,height:A(e)-g}),p.show()):p&&p.hide(),i},destroy:function(){j(this.axis.plotLinesAndBands,this),delete this.axis,B(this)}},X={getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);return d&&c?d.push(c[4],c[5],c[1],c[2]):d=null,d},addPlotBand:function(a){return this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){return this.addPlotBandOrLine(a,"plotLines")},addPlotBandOrLine:function(a,b){var c=new kb.PlotLineOrBand(this,a).render(),d=this.userOptions;return c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c)),c},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();jc([c.plotLines||[],d.plotLines||[],c.plotBands||[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&j(b,b[e])})}},K.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S",minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,gridLineColor:"#C0C0C0",labels:tc,lineColor:"#C0D0E0",lineWidth:1,minPadding:.01,maxPadding:.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#707070"}},type:"linear"},defaultYAxisOptions:{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:.05,minPadding:.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return r(this.total,-1)},style:tc.style}},defaultLeftAxisOptions:{labels:{x:-15,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:15,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:null},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-15},title:{rotation:0}},init:function(a,b){var c=b.isX,d=this;d.horiz=a.inverted?!c:c,d.isXAxis=c,d.coll=c?"xAxis":"yAxis",d.opposite=b.opposite,d.side=b.side||(d.horiz?d.opposite?0:2:d.opposite?1:3),d.setOptions(b);var e=this.options,f=e.type,g="datetime"===f;d.labelFormatter=e.labels.formatter||d.defaultLabelFormatter,d.userOptions=b,d.minPixelPadding=0,d.chart=a,d.reversed=e.reversed,d.zoomEnabled=e.zoomEnabled!==!1,d.categories=e.categories||"category"===f,d.names=[],d.isLog="logarithmic"===f,d.isDatetimeAxis=g,d.isLinked=k(e.linkedTo),d.tickmarkOffset=d.categories&&"between"===e.tickmarkPlacement&&1===n(e.tickInterval,1)?.5:0,d.ticks={},d.labelEdge=[],d.minorTicks={},d.plotLinesAndBands=[],d.alternateBands={},d.len=0,d.minRange=d.userMinRange=e.minRange||e.maxZoom,d.range=e.range,d.offset=e.offset||0,d.stacks={},d.oldStacks={},d.max=null,d.min=null,d.crosshair=n(e.crosshair,m(a.options.tooltip.crosshairs)[c?0:1],!1);var j,l=d.options.events;-1===ic(d,a.axes)&&(c&&!this.isColorAxis?a.axes.splice(a.xAxis.length,0,d):a.axes.push(d),a[d.coll].push(d)),d.series=d.series||[],a.inverted&&c&&d.reversed===N&&(d.reversed=!0),d.removePlotBand=d.removePlotBandOrLine,d.removePlotLine=d.removePlotBandOrLine;for(j in l)nc(d,j,l[j]);d.isLog&&(d.val2lin=h,d.lin2val=i)},setOptions:function(a){this.options=b(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],b(R[this.coll],a))},defaultLabelFormatter:function(){var a,b,c=this.axis,d=this.value,e=c.categories,f=this.dateTimeLabelFormat,g=R.lang.numericSymbols,h=g&&g.length,i=c.options.labels.format,j=c.isLog?d:c.tickInterval;if(i)b=v(i,this);else if(e)b=d;else if(f)b=S(f,d);else if(h&&j>=1e3)for(;h--&&b===N;)a=Math.pow(1e3,h+1),j>=a&&null!==g[h]&&(b=r(d/a,-1)+g[h]);return b===N&&(b=tb(d)>=1e4?r(d,0):r(d,-1,N,"")),b},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1,a.dataMin=a.dataMax=a.ignoreMinPadding=a.ignoreMaxPadding=null,a.buildStacks&&a.buildStacks(),jc(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d,e,f,g=c.options,h=g.threshold;a.hasVisibleSeries=!0,a.isLog&&0>=h&&(h=null),a.isXAxis?(d=c.xData,d.length&&(a.dataMin=sb(n(a.dataMin,d[0]),z(d)),a.dataMax=rb(n(a.dataMax,d[0]),A(d)))):(c.getExtremes(),f=c.dataMax,e=c.dataMin,k(e)&&k(f)&&(a.dataMin=sb(n(a.dataMin,e),e),a.dataMax=rb(n(a.dataMax,f),f)),k(h)&&(a.dataMin>=h?(a.dataMin=h,a.ignoreMinPadding=!0):a.dataMaxf||f>m+k.width)&&(j=!0)):(f=m,h=q-k.right,(o>g||g>o+k.height)&&(j=!0)),j&&!d?null:l.renderer.crispLine([Yb,f,g,Zb,h,i],b||1)},getLinearTickPositions:function(a,b,c){var d,e,f=D(pb(b/a)*a),h=D(qb(c/a)*a),i=[];if(b===c&&g(b))return[b];for(d=f;h>=d&&(i.push(d),d=D(d+a),d!==e);)e=d;return i},getMinorTickPositions:function(){var a,b,c,d=this,e=d.options,f=d.tickPositions,g=d.minorTickInterval,h=[];if(d.isLog)for(c=f.length,b=1;c>b;b++)h=h.concat(d.getLogTickPositions(g,f[b-1],f[b],!0));else if(d.isDatetimeAxis&&"auto"===e.minorTickInterval)h=h.concat(d.getTimeTicks(d.normalizeTimeTickInterval(g),d.min,d.max,e.startOfWeek)),h[0]=i.minRange;if(i.isXAxis&&i.minRange===N&&!i.isLog&&(k(j.min)||k(j.max)?i.minRange=null:(jc(i.series,function(a){for(e=a.xData,f=a.xIncrement?1:e.length-1,c=f;c>0;c--)d=e[c]-e[c-1],(b===N||b>d)&&(b=d)}),i.minRange=sb(5*b,i.dataMax-i.dataMin))),m-lm-l&&(g[0]=m-p,g[1]=n(j.min,m-p),l=A(g))}i.min=l,i.max=m},setAxisTranslation:function(a){var b,c,e=this,f=e.max-e.min,g=e.axisPointRange||0,h=0,i=0,j=e.linkedParent,l=!!e.categories,m=e.transA;(e.isXAxis||l||g)&&(j?(h=j.minPointOffset,i=j.pointRangePadding):jc(e.series,function(a){var c=l?1:e.isXAxis?a.pointRange:e.axisPointRange||0,j=a.options.pointPlacement,m=a.closestPointRange;c>f&&(c=0),g=rb(g,c),h=rb(h,d(j)?0:c/2),i=rb(i,"on"===j?0:c),!a.noSharedTooltip&&k(m)&&(b=k(b)?sb(b,m):m)}),c=e.ordinalSlope&&b?e.ordinalSlope/b:1,e.minPointOffset=h*=c,e.pointRangePadding=i*=c,e.pointRange=sb(g,f),e.closestPointRange=b),a&&(e.oldTransA=m),e.translationSlope=e.transA=m=e.len/(f+i||1),e.transB=e.horiz?e.left:e.bottom,e.minPixelPadding=m*h},setTickPositions:function(a){var b,c,d,e,f=this,i=f.chart,j=f.options,l=j.startOnTick,m=j.endOnTick,o=f.isLog,p=f.isDatetimeAxis,q=f.isXAxis,r=f.isLinked,s=f.options.tickPositioner,t=j.maxPadding,u=j.minPadding,v=j.tickInterval,y=j.minTickInterval,z=j.tickPixelInterval,A=f.categories;if(r?(f.linkedParent=i[f.coll][j.linkedTo],c=f.linkedParent.getExtremes(),f.min=n(c.min,c.dataMin),f.max=n(c.max,c.dataMax),j.type!==f.linkedParent.options.type&&W(11,1)):(f.min=n(f.userMin,j.min,f.dataMin),f.max=n(f.userMax,j.max,f.dataMax)),o&&(!a&&sb(f.min,n(f.dataMin,f.min))<=0&&W(10,1),f.min=D(h(f.min)),f.max=D(h(f.max))),f.range&&k(f.max)&&(f.userMin=f.min=rb(f.min,f.max-f.range),f.userMax=f.max,f.range=null),f.beforePadding&&f.beforePadding(),f.adjustForMinRange(),A||f.axisPointRange||f.usePercentage||r||!k(f.min)||!k(f.max)||(b=f.max-f.min,b&&(k(j.min)||k(f.userMin)||!u||!(f.dataMin<0)&&f.ignoreMinPadding||(f.min-=b*u),k(j.max)||k(f.userMax)||!t||!(f.dataMax>0)&&f.ignoreMaxPadding||(f.max+=b*t))),g(j.floor)&&(f.min=rb(f.min,j.floor)),g(j.ceiling)&&(f.max=sb(f.max,j.ceiling)),f.min===f.max||void 0===f.min||void 0===f.max?f.tickInterval=1:r&&!v&&z===f.linkedParent.options.tickPixelInterval?f.tickInterval=f.linkedParent.tickInterval:(f.tickInterval=n(v,A?1:(f.max-f.min)*z/rb(f.len,z)),!k(v)&&f.len1&&f.tickInterval<5&&f.max>1e3&&f.max<9999)))),f.minorTickInterval="auto"===j.minorTickInterval&&f.tickInterval?f.tickInterval/5:j.minorTickInterval,f.tickPositions=d=j.tickPositions?[].concat(j.tickPositions):s&&s.apply(f,[f.min,f.max]),d||(!f.ordinalPositions&&(f.max-f.min)/f.tickInterval>rb(2*f.len,200)&&W(19,!0),d=p?f.getTimeTicks(f.normalizeTimeTickInterval(f.tickInterval,j.units),f.min,f.max,j.startOfWeek,f.ordinalPositions,f.closestPointRange,!0):o?f.getLogTickPositions(f.tickInterval,f.min,f.max):f.getLinearTickPositions(f.tickInterval,f.min,f.max),e&&d.splice(1,d.length-2),f.tickPositions=d),!r){var B,C=d[0],E=d[d.length-1],F=f.minPointOffset||0;l?f.min=C:f.min-F>C&&d.shift(),m?f.max=E:f.max+F1e13?1:.001,f.min-=B,f.max+=B)}},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.coll,this.pos,this.len].join("-");!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==!1&&(b[d]=c.length),a.maxTicks=b},adjustTickAmount:function(){var a=this,b=a.chart,c=a._maxTicksKey,d=a.tickPositions,e=b.maxTicks;if(e&&e[c]&&!a.isDatetimeAxis&&!a.categories&&!a.isLinked&&a.options.alignTicks!==!1&&this.min!==N){var f,g=a.tickAmount,h=d.length;if(a.tickAmount=f=e[c],f>h){for(;d.length=rb(d,n(e.max,d))&&(b=N)),this.displayBtn=a!==N||b!==N,this.setExtremes(a,b,!1,N,{trigger:"zoom"}),!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0,e=this.horiz,f=n(b.width,a.plotWidth-c+d),g=n(b.height,a.plotHeight),h=n(b.top,a.plotTop),i=n(b.left,a.plotLeft+c),j=/%$/;j.test(g)&&(g=parseInt(g,10)/100*a.plotHeight),j.test(h)&&(h=parseInt(h,10)/100*a.plotHeight+a.plotTop),this.left=i,this.top=h,this.width=f,this.height=g,this.bottom=a.chartHeight-g-h,this.right=a.chartWidth-f-i,this.len=rb(e?f:g,0),this.pos=e?i:h},getExtremes:function(){var a=this,b=a.isLog;return{min:b?D(i(a.min)):a.min,max:b?D(i(a.max)):a.max,dataMin:a.dataMin,dataMax:a.dataMax,userMin:a.userMin,userMax:a.userMax}},getThreshold:function(a){var b=this,c=b.isLog,d=c?i(b.min):b.min,e=c?i(b.max):b.max;return d>a||null===a?a=d:a>e&&(a=e),b.translate(a,0,1,0,1)},autoLabelAlign:function(a){var b,c=(n(a,0)-90*this.side+720)%360;return b=c>15&&165>c?"right":c>195&&345>c?"left":"center"},getOffset:function(){var a,b,c,d,e,f,g,h,i,j,l,m,o,p,q,r=this,s=r.chart,t=s.renderer,u=r.options,v=r.tickPositions,w=r.ticks,x=r.horiz,y=r.side,z=s.inverted?[1,0,3,2][y]:y,A=0,B=0,C=u.title,D=u.labels,E=0,F=s.axisOffset,G=s.clipOffset,H=[-1,1,1,-1][y],I=1,K=n(D.maxStaggerLines,5);if(r.hasData=a=r.hasVisibleSeries||k(r.min)&&k(r.max)&&!!v,r.showAxis=b=a||n(u.showEmpty,!0),r.staggerLines=r.horiz&&D.staggerLines,r.axisGroup||(r.gridGroup=t.g("grid").attr({zIndex:u.gridZIndex||1}).add(),r.axisGroup=t.g("axis").attr({zIndex:u.zIndex||2}).add(),r.labelGroup=t.g("axis-labels").attr({zIndex:D.zIndex||7}).addClass(Ub+r.coll.toLowerCase()+"-labels").add()),a||r.isLinked){if(r.labelAlign=n(D.align||r.autoLabelAlign(D.rotation)),jc(v,function(a){w[a]?w[a].addLabel():w[a]=new J(r,a)}),r.horiz&&!r.staggerLines&&K&&!D.rotation){for(g=r.reversed?[].concat(v).reverse():v;K>I;){for(h=[],i=!1,f=0;f1&&(r.staggerLines=I)}jc(v,function(a){(0===y||2===y||{1:"left",3:"right"}[y]===r.labelAlign)&&(E=rb(w[a].getLabelSize(),E))}),r.staggerLines&&(E*=r.staggerLines,r.labelOffset=E)}else for(e in w)w[e].destroy(),delete w[e];C&&C.text&&C.enabled!==!1&&(r.axisTitle||(r.axisTitle=t.text(C.text,0,0,C.useHTML).attr({zIndex:7,rotation:C.rotation||0,align:C.textAlign||{low:"left",middle:"center",high:"right"}[C.align]}).addClass(Ub+this.coll.toLowerCase()+"-title").css(C.style).add(r.axisGroup),r.axisTitle.isNew=!0),b&&(A=r.axisTitle.getBBox()[x?"height":"width"],c=C.offset,B=k(c)?0:n(C.margin,x?5:10)),r.axisTitle[b?"show":"hide"]()),r.offset=H*n(u.offset,F[y]),q=2===y?r.tickBaseline:0,d=E+B+(E&&H*(x?n(D.y,r.tickBaseline+8):D.x)-q),r.axisTitleMargin=n(c,d),F[y]=rb(F[y],r.axisTitleMargin+A+H*r.offset,d),G[z]=rb(G[z],2*pb(u.lineWidth/2)) @@ -9,15 +9,15 @@ var t=f(f(g(h,5),d(s,i,j,k)),f(f(l,c[s]),e(s)));l=k,k=j,j=g(i,30),i=h,h=t}h=f(h,n),i=f(i,o),j=f(j,p),k=f(k,q),l=f(l,r)}return Array(h,i,j,k,l)}function d(a,b,c,d){return 20>a?b&c|~b&d:40>a?b^c^d:60>a?b&c|b&d|c&d:b^c^d}function e(a){return 20>a?1518500249:40>a?1859775393:60>a?-1894007588:-899497514}function f(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function g(a,b){return a<>>32-b}var h=a("./helpers");b.exports=function(a){return h.hash(a,c,20,!0)}},{"./helpers":6}],11:[function(a,b){var c=a("./helpers"),d=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c},e=function(a,b){return a>>>b|a<<32-b},f=function(a,b){return a>>>b},g=function(a,b,c){return a&b^~a&c},h=function(a,b,c){return a&b^a&c^b&c},i=function(a){return e(a,2)^e(a,13)^e(a,22)},j=function(a){return e(a,6)^e(a,11)^e(a,25)},k=function(a){return e(a,7)^e(a,18)^f(a,3)},l=function(a){return e(a,17)^e(a,19)^f(a,10)},m=function(a,b){var c,e,f,m,n,o,p,q,r,s,t,u,v=new Array(1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298),w=new Array(1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225),x=new Array(64);a[b>>5]|=128<<24-b%32,a[(b+64>>9<<4)+15]=b;for(var r=0;rs;s++)x[s]=16>s?a[s+r]:d(d(d(l(x[s-2]),x[s-7]),k(x[s-15])),x[s-16]),t=d(d(d(d(q,j(n)),g(n,o,p)),v[s]),x[s]),u=d(i(c),h(c,e,f)),q=p,p=o,o=n,n=d(m,t),m=f,f=e,e=c,c=d(t,u);w[0]=d(c,w[0]),w[1]=d(e,w[1]),w[2]=d(f,w[2]),w[3]=d(m,w[3]),w[4]=d(n,w[4]),w[5]=d(o,w[5]),w[6]=d(p,w[6]),w[7]=d(q,w[7])}return w};b.exports=function(a){return c.hash(a,m,32,!0)}},{"./helpers":6}],12:[function(a,b){function c(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function d(a){return"function"==typeof a}function e(a){return"number"==typeof a}function f(a){return"object"==typeof a&&null!==a}function g(a){return void 0===a}b.exports=c,c.EventEmitter=c,c.prototype._events=void 0,c.prototype._maxListeners=void 0,c.defaultMaxListeners=10,c.prototype.setMaxListeners=function(a){if(!e(a)||0>a||isNaN(a))throw TypeError("n must be a positive number");return this._maxListeners=a,this},c.prototype.emit=function(a){var b,c,e,h,i,j;if(this._events||(this._events={}),"error"===a&&(!this._events.error||f(this._events.error)&&!this._events.error.length)){if(b=arguments[1],b instanceof Error)throw b;throw TypeError('Uncaught, unspecified "error" event.')}if(c=this._events[a],g(c))return!1;if(d(c))switch(arguments.length){case 1:c.call(this);break;case 2:c.call(this,arguments[1]);break;case 3:c.call(this,arguments[1],arguments[2]);break;default:for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];c.apply(this,h)}else if(f(c)){for(e=arguments.length,h=new Array(e-1),i=1;e>i;i++)h[i-1]=arguments[i];for(j=c.slice(),e=j.length,i=0;e>i;i++)j[i].apply(this,h)}return!0},c.prototype.addListener=function(a,b){var e;if(!d(b))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",a,d(b.listener)?b.listener:b),this._events[a]?f(this._events[a])?this._events[a].push(b):this._events[a]=[this._events[a],b]:this._events[a]=b,f(this._events[a])&&!this._events[a].warned){var e;e=g(this._maxListeners)?c.defaultMaxListeners:this._maxListeners,e&&e>0&&this._events[a].length>e&&(this._events[a].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[a].length),"function"==typeof console.trace&&console.trace())}return this},c.prototype.on=c.prototype.addListener,c.prototype.once=function(a,b){function c(){this.removeListener(a,c),e||(e=!0,b.apply(this,arguments))}if(!d(b))throw TypeError("listener must be a function");var e=!1;return c.listener=b,this.on(a,c),this},c.prototype.removeListener=function(a,b){var c,e,g,h;if(!d(b))throw TypeError("listener must be a function");if(!this._events||!this._events[a])return this;if(c=this._events[a],g=c.length,e=-1,c===b||d(c.listener)&&c.listener===b)delete this._events[a],this._events.removeListener&&this.emit("removeListener",a,b);else if(f(c)){for(h=g;h-->0;)if(c[h]===b||c[h].listener&&c[h].listener===b){e=h;break}if(0>e)return this;1===c.length?(c.length=0,delete this._events[a]):c.splice(e,1),this._events.removeListener&&this.emit("removeListener",a,b)}return this},c.prototype.removeAllListeners=function(a){var b,c;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[a]&&delete this._events[a],this;if(0===arguments.length){for(b in this._events)"removeListener"!==b&&this.removeAllListeners(b);return this.removeAllListeners("removeListener"),this._events={},this}if(c=this._events[a],d(c))this.removeListener(a,c);else for(;c.length;)this.removeListener(a,c[c.length-1]);return delete this._events[a],this},c.prototype.listeners=function(a){var b;return b=this._events&&this._events[a]?d(this._events[a])?[this._events[a]]:this._events[a].slice():[]},c.listenerCount=function(a,b){var c;return c=a._events&&a._events[b]?d(a._events[b])?1:a._events[b].length:0}},{}],13:[function(a,b){var c=b.exports,d=(a("events").EventEmitter,a("./lib/request")),e=a("url");c.request=function(a,b){"string"==typeof a&&(a=e.parse(a)),a||(a={}),a.host||a.port||(a.port=parseInt(window.location.port,10)),!a.host&&a.hostname&&(a.host=a.hostname),a.scheme||(a.scheme=window.location.protocol.split(":")[0]),a.host||(a.host=window.location.hostname||window.location.host),/:/.test(a.host)&&(a.port||(a.port=a.host.split(":")[1]),a.host=a.host.split(":")[0]),a.port||(a.port="https"==a.scheme?443:80);var c=new d(new f,a);return b&&c.on("response",b),c},c.get=function(a,b){a.method="GET";var d=c.request(a,b);return d.end(),d},c.Agent=function(){},c.Agent.defaultMaxSockets=4;var f=function(){if("undefined"==typeof window)throw new Error("no window object present");if(window.XMLHttpRequest)return window.XMLHttpRequest;if(window.ActiveXObject){for(var a=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Microsoft.XMLHTTP"],b=0;bthis.offset&&(this.emit("data",b.slice(this.offset)),this.offset=b.length))};var h=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}},{stream:25,util:34}],16:[function(a,b,c){!function(){function a(a){this.message=a}var b="undefined"!=typeof c?c:this,d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.prototype=new Error,a.prototype.name="InvalidCharacterError",b.btoa||(b.btoa=function(b){for(var c,e,f=0,g=d,h="";b.charAt(0|f)||(g="=",f%1);h+=g.charAt(63&c>>8-f%1*8)){if(e=b.charCodeAt(f+=.75),e>255)throw new a("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");c=c<<8|e}return h}),b.atob||(b.atob=function(b){if(b=b.replace(/=+$/,""),b.length%4==1)throw new a("'atob' failed: The string to be decoded is not correctly encoded.");for(var c,e,f=0,g=0,h="";e=b.charAt(g++);~e&&(c=f%4?64*c+e:e,f++%4)?h+=String.fromCharCode(255&c>>(-2*f&6)):0)e=d.indexOf(e);return h})}()},{}],17:[function(a,b){var c=a("http"),d=b.exports;for(var e in c)c.hasOwnProperty(e)&&(d[e]=c[e]);d.request=function(a,b){return a||(a={}),a.scheme="https",c.request.call(this,a,b)}},{http:13}],18:[function(a,b){b.exports="function"==typeof Object.create?function(a,b){a.super_=b,a.prototype=Object.create(b.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}})}:function(a,b){a.super_=b;var c=function(){};c.prototype=b.prototype,a.prototype=new c,a.prototype.constructor=a}},{}],19:[function(a,b){function c(){}var d=b.exports={};d.nextTick=function(){var a="undefined"!=typeof window&&window.setImmediate,b="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(a)return function(a){return window.setImmediate(a)};if(b){var c=[];return window.addEventListener("message",function(a){var b=a.source;if((b===window||null===b)&&"process-tick"===a.data&&(a.stopPropagation(),c.length>0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),d.title="browser",d.browser=!0,d.env={},d.argv=[],d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.binding=function(){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(){throw new Error("process.chdir is not supported")}},{}],20:[function(a,b,c){(function(a){!function(d){function e(a){throw RangeError(H[a])}function f(a,b){for(var c=a.length;c--;)a[c]=b(a[c]);return a}function g(a,b){return f(a.split(G),b).join(".")}function h(a){for(var b,c,d=[],e=0,f=a.length;f>e;)b=a.charCodeAt(e++),b>=55296&&56319>=b&&f>e?(c=a.charCodeAt(e++),56320==(64512&c)?d.push(((1023&b)<<10)+(1023&c)+65536):(d.push(b),e--)):d.push(b);return d}function i(a){return f(a,function(a){var b="";return a>65535&&(a-=65536,b+=K(a>>>10&1023|55296),a=56320|1023&a),b+=K(a)}).join("")}function j(a){return 10>a-48?a-22:26>a-65?a-65:26>a-97?a-97:w}function k(a,b){return a+22+75*(26>a)-((0!=b)<<5)}function l(a,b,c){var d=0;for(a=c?J(a/A):a>>1,a+=J(a/b);a>I*y>>1;d+=w)a=J(a/I);return J(d+(I+1)*a/(a+z))}function m(a){var b,c,d,f,g,h,k,m,n,o,p=[],q=a.length,r=0,s=C,t=B;for(c=a.lastIndexOf(D),0>c&&(c=0),d=0;c>d;++d)a.charCodeAt(d)>=128&&e("not-basic"),p.push(a.charCodeAt(d));for(f=c>0?c+1:0;q>f;){for(g=r,h=1,k=w;f>=q&&e("invalid-input"),m=j(a.charCodeAt(f++)),(m>=w||m>J((v-r)/h))&&e("overflow"),r+=m*h,n=t>=k?x:k>=t+y?y:k-t,!(n>m);k+=w)o=w-n,h>J(v/o)&&e("overflow"),h*=o;b=p.length+1,t=l(r-g,b,0==g),J(r/b)>v-s&&e("overflow"),s+=J(r/b),r%=b,p.splice(r++,0,s)}return i(p)}function n(a){var b,c,d,f,g,i,j,m,n,o,p,q,r,s,t,u=[];for(a=h(a),q=a.length,b=C,c=0,g=B,i=0;q>i;++i)p=a[i],128>p&&u.push(K(p));for(d=f=u.length,f&&u.push(D);q>d;){for(j=v,i=0;q>i;++i)p=a[i],p>=b&&j>p&&(j=p);for(r=d+1,j-b>J((v-c)/r)&&e("overflow"),c+=(j-b)*r,b=j,i=0;q>i;++i)if(p=a[i],b>p&&++c>v&&e("overflow"),p==b){for(m=c,n=w;o=g>=n?x:n>=g+y?y:n-g,!(o>m);n+=w)t=m-o,s=w-o,u.push(K(k(o+t%s,0))),m=J(t/s);u.push(K(k(m,0))),g=l(c,r,d==f),c=0,++d}++c,++b}return u.join("")}function o(a){return g(a,function(a){return E.test(a)?m(a.slice(4).toLowerCase()):a})}function p(a){return g(a,function(a){return F.test(a)?"xn--"+n(a):a})}var q="object"==typeof c&&c,r="object"==typeof b&&b&&b.exports==q&&b,s="object"==typeof a&&a;(s.global===s||s.window===s)&&(d=s);var t,u,v=2147483647,w=36,x=1,y=26,z=38,A=700,B=72,C=128,D="-",E=/^xn--/,F=/[^ -~]/,G=/\x2E|\u3002|\uFF0E|\uFF61/g,H={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},I=w-x,J=Math.floor,K=String.fromCharCode;if(t={version:"1.2.4",ucs2:{decode:h,encode:i},decode:m,encode:n,toASCII:p,toUnicode:o},"function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",function(){return t});else if(q&&!q.nodeType)if(r)r.exports=t;else for(u in t)t.hasOwnProperty(u)&&(q[u]=t[u]);else d.punycode=t}(this)}).call(this,"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],21:[function(a,b){"use strict";function c(a,b){return Object.prototype.hasOwnProperty.call(a,b)}b.exports=function(a,b,e,f){b=b||"&",e=e||"=";var g={};if("string"!=typeof a||0===a.length)return g;var h=/\+/g;a=a.split(b);var i=1e3;f&&"number"==typeof f.maxKeys&&(i=f.maxKeys);var j=a.length;i>0&&j>i&&(j=i);for(var k=0;j>k;++k){var l,m,n,o,p=a[k].replace(h,"%20"),q=p.indexOf(e);q>=0?(l=p.substr(0,q),m=p.substr(q+1)):(l=p,m=""),n=decodeURIComponent(l),o=decodeURIComponent(m),c(g,n)?d(g[n])?g[n].push(o):g[n]=[g[n],o]:g[n]=o}return g};var d=Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}},{}],22:[function(a,b){"use strict";function c(a,b){if(a.map)return a.map(b);for(var c=[],d=0;d0)){var d=c.shift();d()}},!0),function(a){c.push(a),window.postMessage("process-tick","*")}}return function(a){setTimeout(a,0)}}(),c.title="browser",c.browser=!0,c.env={},c.argv=[],c.binding=function(){throw new Error("process.binding is not supported")},c.cwd=function(){return"/"},c.chdir=function(){throw new Error("process.chdir is not supported")}},{}],27:[function(a,b){function c(a){return this instanceof c?void d.call(this,a):new c(a)}b.exports=c;var d=a("./transform.js"),e=a("inherits");e(c,d),c.prototype._transform=function(a,b,c){c(null,a)}},{"./transform.js":29,inherits:18}],28:[function(a,b){(function(c){function d(b){b=b||{};var c=b.highWaterMark;this.highWaterMark=c||0===c?c:16384,this.highWaterMark=~~this.highWaterMark,this.buffer=[],this.length=0,this.pipes=null,this.pipesCount=0,this.flowing=!1,this.ended=!1,this.endEmitted=!1,this.reading=!1,this.calledRead=!1,this.sync=!0,this.needReadable=!1,this.emittedReadable=!1,this.readableListening=!1,this.objectMode=!!b.objectMode,this.defaultEncoding=b.defaultEncoding||"utf8",this.ranOut=!1,this.awaitDrain=0,this.readingMore=!1,this.decoder=null,this.encoding=null,b.encoding&&(x||(x=a("string_decoder").StringDecoder),this.decoder=new x(b.encoding),this.encoding=b.encoding)}function e(a){return this instanceof e?(this._readableState=new d(a,this),this.readable=!0,void z.call(this)):new e(a)}function f(a,b,c,d,e){var f=j(b,c);if(f)a.emit("error",f);else if(null===c||void 0===c)b.reading=!1,b.ended||k(a,b);else if(b.objectMode||c&&c.length>0)if(b.ended&&!e){var h=new Error("stream.push() after EOF");a.emit("error",h)}else if(b.endEmitted&&e){var h=new Error("stream.unshift() after end event");a.emit("error",h)}else!b.decoder||e||d||(c=b.decoder.write(c)),b.length+=b.objectMode?1:c.length,e?b.buffer.unshift(c):(b.reading=!1,b.buffer.push(c)),b.needReadable&&l(a),n(a,b);else e||(b.reading=!1);return g(b)}function g(a){return!a.ended&&(a.needReadable||a.length=D)a=D;else{a--;for(var b=1;32>b;b<<=1)a|=a>>b;a++}return a}function i(a,b){return 0===b.length&&b.ended?0:b.objectMode?0===a?0:1:isNaN(a)||null===a?b.flowing&&b.buffer.length?b.buffer[0].length:b.length:0>=a?0:(a>b.highWaterMark&&(b.highWaterMark=h(a)),a>b.length?b.ended?b.length:(b.needReadable=!0,0):a)}function j(a,b){var c=null;return A.isBuffer(b)||"string"==typeof b||null===b||void 0===b||a.objectMode||c||(c=new TypeError("Invalid non-string/buffer chunk")),c}function k(a,b){if(b.decoder&&!b.ended){var c=b.decoder.end();c&&c.length&&(b.buffer.push(c),b.length+=b.objectMode?1:c.length)}b.ended=!0,b.length>0?l(a):u(a)}function l(a){var b=a._readableState;b.needReadable=!1,b.emittedReadable||(b.emittedReadable=!0,b.sync?B(function(){m(a)}):m(a))}function m(a){a.emit("readable")}function n(a,b){b.readingMore||(b.readingMore=!0,B(function(){o(a,b)}))}function o(a,b){for(var c=b.length;!b.reading&&!b.flowing&&!b.ended&&b.length0)return;return 0===d.pipesCount?(d.flowing=!1,void(y.listenerCount(a,"data")>0&&s(a))):void(d.ranOut=!0)}function r(){this._readableState.ranOut&&(this._readableState.ranOut=!1,q(this))}function s(a,b){var c=a._readableState;if(c.flowing)throw new Error("Cannot switch to old mode now.");var d=b||!1,e=!1;a.readable=!0,a.pipe=z.prototype.pipe,a.on=a.addListener=z.prototype.on,a.on("readable",function(){e=!0;for(var b;!d&&null!==(b=a.read());)a.emit("data",b);null===b&&(e=!1,a._readableState.needReadable=!0)}),a.pause=function(){d=!0,this.emit("pause")},a.resume=function(){d=!1,e?B(function(){a.emit("readable")}):this.read(0),this.emit("resume")},a.emit("readable")}function t(a,b){var c,d=b.buffer,e=b.length,f=!!b.decoder,g=!!b.objectMode;if(0===d.length)return null;if(0===e)c=null;else if(g)c=d.shift();else if(!a||a>=e)c=f?d.join(""):A.concat(d,e),d.length=0;else if(aj&&a>i;j++){var h=d[0],l=Math.min(a-i,h.length);f?c+=h.slice(0,l):h.copy(c,i,0,l),l0)throw new Error("endReadable called on non-empty stream");!b.endEmitted&&b.calledRead&&(b.ended=!0,B(function(){b.endEmitted||0!==b.length||(b.endEmitted=!0,a.readable=!1,a.emit("end"))}))}function v(a,b){for(var c=0,d=a.length;d>c;c++)b(a[c],c)}function w(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1}b.exports=e,e.ReadableState=d;var x,y=a("events").EventEmitter,z=a("./index.js"),A=a("buffer").Buffer,B=a("process/browser.js").nextTick,C=a("inherits");C(e,z),e.prototype.push=function(a,b){var c=this._readableState;return"string"!=typeof a||c.objectMode||(b=b||c.defaultEncoding,b!==c.encoding&&(a=new A(a,b),b="")),f(this,c,a,b,!1)},e.prototype.unshift=function(a){var b=this._readableState;return f(this,b,a,"",!0)},e.prototype.setEncoding=function(b){x||(x=a("string_decoder").StringDecoder),this._readableState.decoder=new x(b),this._readableState.encoding=b};var D=8388608;e.prototype.read=function(a){var b=this._readableState;b.calledRead=!0;var c=a;if(("number"!=typeof a||a>0)&&(b.emittedReadable=!1),0===a&&b.needReadable&&(b.length>=b.highWaterMark||b.ended))return l(this),null;if(a=i(a,b),0===a&&b.ended)return 0===b.length&&u(this),null;var d=b.needReadable;b.length-a<=b.highWaterMark&&(d=!0),(b.ended||b.reading)&&(d=!1),d&&(b.reading=!0,b.sync=!0,0===b.length&&(b.needReadable=!0),this._read(b.highWaterMark),b.sync=!1),d&&!b.reading&&(a=i(c,b));var e;return e=a>0?t(a,b):null,null===e&&(b.needReadable=!0,a=0),b.length-=a,0!==b.length||b.ended||(b.needReadable=!0),b.ended&&!b.endEmitted&&0===b.length&&u(this),e},e.prototype._read=function(){this.emit("error",new Error("not implemented"))},e.prototype.pipe=function(a,b){function d(a){a===k&&f()}function e(){a.end()}function f(){a.removeListener("close",h),a.removeListener("finish",i),a.removeListener("drain",o),a.removeListener("error",g),a.removeListener("unpipe",d),k.removeListener("end",e),k.removeListener("end",f),(!a._writableState||a._writableState.needDrain)&&o()}function g(b){j(),0===s&&0===y.listenerCount(a,"error")&&a.emit("error",b)}function h(){a.removeListener("finish",i),j()}function i(){a.removeListener("close",h),j()}function j(){k.unpipe(a)}var k=this,l=this._readableState;switch(l.pipesCount){case 0:l.pipes=a;break;case 1:l.pipes=[l.pipes,a];break;default:l.pipes.push(a)}l.pipesCount+=1;var m=(!b||b.end!==!1)&&a!==c.stdout&&a!==c.stderr,n=m?e:f;l.endEmitted?B(n):k.once("end",n),a.on("unpipe",d);var o=p(k);a.on("drain",o);var s=y.listenerCount(a,"error");return a.once("error",g),a.once("close",h),a.once("finish",i),a.emit("pipe",k),l.flowing||(this.on("readable",r),l.flowing=!0,B(function(){q(k)})),a},e.prototype.unpipe=function(a){var b=this._readableState;if(0===b.pipesCount)return this;if(1===b.pipesCount)return a&&a!==b.pipes?this:(a||(a=b.pipes),b.pipes=null,b.pipesCount=0,this.removeListener("readable",r),b.flowing=!1,a&&a.emit("unpipe",this),this);if(!a){var c=b.pipes,d=b.pipesCount;b.pipes=null,b.pipesCount=0,this.removeListener("readable",r),b.flowing=!1;for(var e=0;d>e;e++)c[e].emit("unpipe",this);return this}var e=w(b.pipes,a);return-1===e?this:(b.pipes.splice(e,1),b.pipesCount-=1,1===b.pipesCount&&(b.pipes=b.pipes[0]),a.emit("unpipe",this),this)},e.prototype.on=function(a,b){var c=z.prototype.on.call(this,a,b);if("data"!==a||this._readableState.flowing||s(this),"readable"===a&&this.readable){var d=this._readableState;d.readableListening||(d.readableListening=!0,d.emittedReadable=!1,d.needReadable=!0,d.reading?d.length&&l(this,d):this.read(0))}return c},e.prototype.addListener=e.prototype.on,e.prototype.resume=function(){s(this),this.read(0),this.emit("resume")},e.prototype.pause=function(){s(this,!0),this.emit("pause")},e.prototype.wrap=function(a){var b=this._readableState,c=!1,d=this;a.on("end",function(){if(b.decoder&&!b.ended){var a=b.decoder.end();a&&a.length&&d.push(a)}d.push(null)}),a.on("data",function(e){if(b.decoder&&(e=b.decoder.write(e)),e&&(b.objectMode||e.length)){var f=d.push(e);f||(c=!0,a.pause())}});for(var e in a)"function"==typeof a[e]&&"undefined"==typeof this[e]&&(this[e]=function(b){return function(){return a[b].apply(a,arguments)}}(e));var f=["error","close","destroy","pause","resume"];return v(f,function(b){a.on(b,function(a){return d.emit.apply(d,b,a)})}),d._read=function(){c&&(c=!1,a.resume())},d},e._fromList=t}).call(this,a("FWaASH"))},{"./index.js":25,FWaASH:19,buffer:3,events:12,inherits:18,"process/browser.js":26,string_decoder:31}],29:[function(a,b){function c(a,b){this.afterTransform=function(a,c){return d(b,a,c)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function d(a,b,c){var d=a._transformState;d.transforming=!1;var e=d.writecb;if(!e)return a.emit("error",new Error("no writecb in Transform class"));d.writechunk=null,d.writecb=null,null!==c&&void 0!==c&&a.push(c),e&&e(b);var f=a._readableState;f.reading=!1,(f.needReadable||f.length=this.charLength-this.charReceived?this.charLength-this.charReceived:a.length;if(a.copy(this.charBuffer,this.charReceived,c,d),this.charReceived+=d-c,c=d,this.charReceived=55296&&56319>=e)){if(this.charReceived=this.charLength=0,d==a.length)return b;a=a.slice(d,a.length);break}this.charLength+=this.surrogateSize,b=""}var f=this.detectIncompleteChar(a),g=a.length;this.charLength&&(a.copy(this.charBuffer,0,a.length-f,g),this.charReceived=f,g-=f),b+=a.toString(this.encoding,0,g);var g=b.length-1,e=b.charCodeAt(g);if(e>=55296&&56319>=e){var h=this.surrogateSize;return this.charLength+=h,this.charReceived+=h,this.charBuffer.copy(this.charBuffer,h,0,h),this.charBuffer.write(b.charAt(b.length-1),this.encoding),b.substring(0,g)}return b},i.prototype.detectIncompleteChar=function(a){for(var b=a.length>=3?3:a.length;b>0;b--){var c=a[a.length-b];if(1==b&&c>>5==6){this.charLength=2;break}if(2>=b&&c>>4==14){this.charLength=3;break}if(3>=b&&c>>3==30){this.charLength=4;break}}return b},i.prototype.end=function(a){var b="";if(a&&a.length&&(b=this.write(a)),this.charReceived){var c=this.charReceived,d=this.charBuffer,e=this.encoding;b+=d.slice(0,c).toString(e)}return b}},{buffer:3}],32:[function(a,b,c){function d(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function e(a,b,c){if(a&&j(a)&&a instanceof d)return a;var e=new d;return e.parse(a,b,c),e}function f(a){return i(a)&&(a=e(a)),a instanceof d?a.format():d.prototype.format.call(a)}function g(a,b){return e(a,!1,!0).resolve(b)}function h(a,b){return a?e(a,!1,!0).resolveObject(b):b}function i(a){return"string"==typeof a}function j(a){return"object"==typeof a&&null!==a}function k(a){return null===a}function l(a){return null==a}var m=a("punycode");c.parse=e,c.resolve=g,c.resolveObject=h,c.format=f,c.Url=d;var n=/^([a-z0-9.+-]+:)/i,o=/:[0-9]*$/,p=["<",">",'"',"`"," ","\r","\n"," "],q=["{","}","|","\\","^","`"].concat(p),r=["'"].concat(q),s=["%","/","?",";","#"].concat(r),t=["/","?","#"],u=255,v=/^[a-z0-9A-Z_-]{0,63}$/,w=/^([a-z0-9A-Z_-]{0,63})(.*)$/,x={javascript:!0,"javascript:":!0},y={javascript:!0,"javascript:":!0},z={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},A=a("querystring");d.prototype.parse=function(a,b,c){if(!i(a))throw new TypeError("Parameter 'url' must be a string, not "+typeof a);var d=a;d=d.trim();var e=n.exec(d);if(e){e=e[0];var f=e.toLowerCase();this.protocol=f,d=d.substr(e.length)}if(c||e||d.match(/^\/\/[^@\/]+@[^@\/]+/)){var g="//"===d.substr(0,2);!g||e&&y[e]||(d=d.substr(2),this.slashes=!0)}if(!y[e]&&(g||e&&!z[e])){for(var h=-1,j=0;jk)&&(h=k)}var l,o;o=-1===h?d.lastIndexOf("@"):d.lastIndexOf("@",h),-1!==o&&(l=d.slice(0,o),d=d.slice(o+1),this.auth=decodeURIComponent(l)),h=-1;for(var j=0;jk)&&(h=k)}-1===h&&(h=d.length),this.host=d.slice(0,h),d=d.slice(h),this.parseHost(),this.hostname=this.hostname||"";var p="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!p)for(var q=this.hostname.split(/\./),j=0,B=q.length;B>j;j++){var C=q[j];if(C&&!C.match(v)){for(var D="",E=0,F=C.length;F>E;E++)D+=C.charCodeAt(E)>127?"x":C[E];if(!D.match(v)){var G=q.slice(0,j),H=q.slice(j+1),I=C.match(w);I&&(G.push(I[1]),H.unshift(I[2])),H.length&&(d="/"+H.join(".")+d),this.hostname=G.join(".");break}}}if(this.hostname=this.hostname.length>u?"":this.hostname.toLowerCase(),!p){for(var J=this.hostname.split("."),K=[],j=0;jj;j++){var O=r[j],P=encodeURIComponent(O);P===O&&(P=escape(O)),d=d.split(O).join(P)}var Q=d.indexOf("#");-1!==Q&&(this.hash=d.substr(Q),d=d.slice(0,Q));var R=d.indexOf("?");if(-1!==R?(this.search=d.substr(R),this.query=d.substr(R+1),b&&(this.query=A.parse(this.query)),d=d.slice(0,R)):b&&(this.search="",this.query={}),d&&(this.pathname=d),z[f]&&this.hostname&&!this.pathname&&(this.pathname="/"),this.pathname||this.search){var M=this.pathname||"",L=this.search||"";this.path=M+L}return this.href=this.format(),this},d.prototype.format=function(){var a=this.auth||"";a&&(a=encodeURIComponent(a),a=a.replace(/%3A/i,":"),a+="@");var b=this.protocol||"",c=this.pathname||"",d=this.hash||"",e=!1,f="";this.host?e=a+this.host:this.hostname&&(e=a+(-1===this.hostname.indexOf(":")?this.hostname:"["+this.hostname+"]"),this.port&&(e+=":"+this.port)),this.query&&j(this.query)&&Object.keys(this.query).length&&(f=A.stringify(this.query));var g=this.search||f&&"?"+f||"";return b&&":"!==b.substr(-1)&&(b+=":"),this.slashes||(!b||z[b])&&e!==!1?(e="//"+(e||""),c&&"/"!==c.charAt(0)&&(c="/"+c)):e||(e=""),d&&"#"!==d.charAt(0)&&(d="#"+d),g&&"?"!==g.charAt(0)&&(g="?"+g),c=c.replace(/[?#]/g,function(a){return encodeURIComponent(a)}),g=g.replace("#","%23"),b+e+c+g+d},d.prototype.resolve=function(a){return this.resolveObject(e(a,!1,!0)).format()},d.prototype.resolveObject=function(a){if(i(a)){var b=new d;b.parse(a,!1,!0),a=b}var c=new d;if(Object.keys(this).forEach(function(a){c[a]=this[a]},this),c.hash=a.hash,""===a.href)return c.href=c.format(),c;if(a.slashes&&!a.protocol)return Object.keys(a).forEach(function(b){"protocol"!==b&&(c[b]=a[b])}),z[c.protocol]&&c.hostname&&!c.pathname&&(c.path=c.pathname="/"),c.href=c.format(),c;if(a.protocol&&a.protocol!==c.protocol){if(!z[a.protocol])return Object.keys(a).forEach(function(b){c[b]=a[b]}),c.href=c.format(),c;if(c.protocol=a.protocol,a.host||y[a.protocol])c.pathname=a.pathname;else{for(var e=(a.pathname||"").split("/");e.length&&!(a.host=e.shift()););a.host||(a.host=""),a.hostname||(a.hostname=""),""!==e[0]&&e.unshift(""),e.length<2&&e.unshift(""),c.pathname=e.join("/")}if(c.search=a.search,c.query=a.query,c.host=a.host||"",c.auth=a.auth,c.hostname=a.hostname||a.host,c.port=a.port,c.pathname||c.search){var f=c.pathname||"",g=c.search||"";c.path=f+g}return c.slashes=c.slashes||a.slashes,c.href=c.format(),c}var h=c.pathname&&"/"===c.pathname.charAt(0),j=a.host||a.pathname&&"/"===a.pathname.charAt(0),m=j||h||c.host&&a.pathname,n=m,o=c.pathname&&c.pathname.split("/")||[],e=a.pathname&&a.pathname.split("/")||[],p=c.protocol&&!z[c.protocol];if(p&&(c.hostname="",c.port=null,c.host&&(""===o[0]?o[0]=c.host:o.unshift(c.host)),c.host="",a.protocol&&(a.hostname=null,a.port=null,a.host&&(""===e[0]?e[0]=a.host:e.unshift(a.host)),a.host=null),m=m&&(""===e[0]||""===o[0])),j)c.host=a.host||""===a.host?a.host:c.host,c.hostname=a.hostname||""===a.hostname?a.hostname:c.hostname,c.search=a.search,c.query=a.query,o=e;else if(e.length)o||(o=[]),o.pop(),o=o.concat(e),c.search=a.search,c.query=a.query;else if(!l(a.search)){if(p){c.hostname=c.host=o.shift();var q=c.host&&c.host.indexOf("@")>0?c.host.split("@"):!1;q&&(c.auth=q.shift(),c.host=c.hostname=q.shift())}return c.search=a.search,c.query=a.query,k(c.pathname)&&k(c.search)||(c.path=(c.pathname?c.pathname:"")+(c.search?c.search:"")),c.href=c.format(),c}if(!o.length)return c.pathname=null,c.path=c.search?"/"+c.search:null,c.href=c.format(),c;for(var r=o.slice(-1)[0],s=(c.host||a.host)&&("."===r||".."===r)||""===r,t=0,u=o.length;u>=0;u--)r=o[u],"."==r?o.splice(u,1):".."===r?(o.splice(u,1),t++):t&&(o.splice(u,1),t--);if(!m&&!n)for(;t--;t)o.unshift("..");!m||""===o[0]||o[0]&&"/"===o[0].charAt(0)||o.unshift(""),s&&"/"!==o.join("/").substr(-1)&&o.push("");var v=""===o[0]||o[0]&&"/"===o[0].charAt(0);if(p){c.hostname=c.host=v?"":o.length?o.shift():"";var q=c.host&&c.host.indexOf("@")>0?c.host.split("@"):!1;q&&(c.auth=q.shift(),c.host=c.hostname=q.shift())}return m=m||c.host&&o.length,m&&!v&&o.unshift(""),o.length?c.pathname=o.join("/"):(c.pathname=null,c.path=null),k(c.pathname)&&k(c.search)||(c.path=(c.pathname?c.pathname:"")+(c.search?c.search:"")),c.auth=a.auth||c.auth,c.slashes=c.slashes||a.slashes,c.href=c.format(),c},d.prototype.parseHost=function(){var a=this.host,b=o.exec(a);b&&(b=b[0],":"!==b&&(this.port=b.substr(1)),a=a.substr(0,a.length-b.length)),a&&(this.hostname=a)}},{punycode:20,querystring:23}],33:[function(a,b){b.exports=function(a){return a&&"object"==typeof a&&"function"==typeof a.copy&&"function"==typeof a.fill&&"function"==typeof a.readUInt8}},{}],34:[function(a,b,c){(function(b,d){function e(a,b){var d={seen:[],stylize:g};return arguments.length>=3&&(d.depth=arguments[2]),arguments.length>=4&&(d.colors=arguments[3]),p(b)?d.showHidden=b:b&&c._extend(d,b),v(d.showHidden)&&(d.showHidden=!1),v(d.depth)&&(d.depth=2),v(d.colors)&&(d.colors=!1),v(d.customInspect)&&(d.customInspect=!0),d.colors&&(d.stylize=f),i(d,a,d.depth)}function f(a,b){var c=e.styles[b];return c?"["+e.colors[c][0]+"m"+a+"["+e.colors[c][1]+"m":a}function g(a){return a}function h(a){var b={};return a.forEach(function(a){b[a]=!0}),b}function i(a,b,d){if(a.customInspect&&b&&A(b.inspect)&&b.inspect!==c.inspect&&(!b.constructor||b.constructor.prototype!==b)){var e=b.inspect(d,a);return t(e)||(e=i(a,e,d)),e}var f=j(a,b);if(f)return f;var g=Object.keys(b),p=h(g);if(a.showHidden&&(g=Object.getOwnPropertyNames(b)),z(b)&&(g.indexOf("message")>=0||g.indexOf("description")>=0))return k(b);if(0===g.length){if(A(b)){var q=b.name?": "+b.name:"";return a.stylize("[Function"+q+"]","special")}if(w(b))return a.stylize(RegExp.prototype.toString.call(b),"regexp");if(y(b))return a.stylize(Date.prototype.toString.call(b),"date");if(z(b))return k(b)}var r="",s=!1,u=["{","}"];if(o(b)&&(s=!0,u=["[","]"]),A(b)){var v=b.name?": "+b.name:"";r=" [Function"+v+"]"}if(w(b)&&(r=" "+RegExp.prototype.toString.call(b)),y(b)&&(r=" "+Date.prototype.toUTCString.call(b)),z(b)&&(r=" "+k(b)),0===g.length&&(!s||0==b.length))return u[0]+r+u[1];if(0>d)return w(b)?a.stylize(RegExp.prototype.toString.call(b),"regexp"):a.stylize("[Object]","special");a.seen.push(b);var x;return x=s?l(a,b,d,p,g):g.map(function(c){return m(a,b,d,p,c,s)}),a.seen.pop(),n(x,r,u)}function j(a,b){if(v(b))return a.stylize("undefined","undefined");if(t(b)){var c="'"+JSON.stringify(b).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return a.stylize(c,"string")}return s(b)?a.stylize(""+b,"number"):p(b)?a.stylize(""+b,"boolean"):q(b)?a.stylize("null","null"):void 0}function k(a){return"["+Error.prototype.toString.call(a)+"]"}function l(a,b,c,d,e){for(var f=[],g=0,h=b.length;h>g;++g)f.push(F(b,String(g))?m(a,b,c,d,String(g),!0):"");return e.forEach(function(e){e.match(/^\d+$/)||f.push(m(a,b,c,d,e,!0))}),f}function m(a,b,c,d,e,f){var g,h,j;if(j=Object.getOwnPropertyDescriptor(b,e)||{value:b[e]},j.get?h=j.set?a.stylize("[Getter/Setter]","special"):a.stylize("[Getter]","special"):j.set&&(h=a.stylize("[Setter]","special")),F(d,e)||(g="["+e+"]"),h||(a.seen.indexOf(j.value)<0?(h=q(c)?i(a,j.value,null):i(a,j.value,c-1),h.indexOf("\n")>-1&&(h=f?h.split("\n").map(function(a){return" "+a}).join("\n").substr(2):"\n"+h.split("\n").map(function(a){return" "+a}).join("\n"))):h=a.stylize("[Circular]","special")),v(g)){if(f&&e.match(/^\d+$/))return h;g=JSON.stringify(""+e),g.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(g=g.substr(1,g.length-2),g=a.stylize(g,"name")):(g=g.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),g=a.stylize(g,"string"))}return g+": "+h}function n(a,b,c){var d=0,e=a.reduce(function(a,b){return d++,b.indexOf("\n")>=0&&d++,a+b.replace(/\u001b\[\d\d?m/g,"").length+1},0);return e>60?c[0]+(""===b?"":b+"\n ")+" "+a.join(",\n ")+" "+c[1]:c[0]+b+" "+a.join(", ")+" "+c[1]}function o(a){return Array.isArray(a)}function p(a){return"boolean"==typeof a}function q(a){return null===a}function r(a){return null==a}function s(a){return"number"==typeof a}function t(a){return"string"==typeof a}function u(a){return"symbol"==typeof a}function v(a){return void 0===a}function w(a){return x(a)&&"[object RegExp]"===C(a)}function x(a){return"object"==typeof a&&null!==a}function y(a){return x(a)&&"[object Date]"===C(a)}function z(a){return x(a)&&("[object Error]"===C(a)||a instanceof Error)}function A(a){return"function"==typeof a}function B(a){return null===a||"boolean"==typeof a||"number"==typeof a||"string"==typeof a||"symbol"==typeof a||"undefined"==typeof a}function C(a){return Object.prototype.toString.call(a)}function D(a){return 10>a?"0"+a.toString(10):a.toString(10)}function E(){var a=new Date,b=[D(a.getHours()),D(a.getMinutes()),D(a.getSeconds())].join(":");return[a.getDate(),J[a.getMonth()],b].join(" ")}function F(a,b){return Object.prototype.hasOwnProperty.call(a,b)}var G=/%[sdj%]/g;c.format=function(a){if(!t(a)){for(var b=[],c=0;c=f)return a;switch(a){case"%s":return String(d[c++]);case"%d":return Number(d[c++]);case"%j":try{return JSON.stringify(d[c++])}catch(b){return"[Circular]"}default:return a}}),h=d[c];f>c;h=d[++c])g+=q(h)||!x(h)?" "+h:" "+e(h);return g},c.deprecate=function(a,e){function f(){if(!g){if(b.throwDeprecation)throw new Error(e);b.traceDeprecation?console.trace(e):console.error(e),g=!0}return a.apply(this,arguments)}if(v(d.process))return function(){return c.deprecate(a,e).apply(this,arguments)};if(b.noDeprecation===!0)return a;var g=!1;return f};var H,I={};c.debuglog=function(a){if(v(H)&&(H=b.env.NODE_DEBUG||""),a=a.toUpperCase(),!I[a])if(new RegExp("\\b"+a+"\\b","i").test(H)){var d=b.pid;I[a]=function(){var b=c.format.apply(c,arguments);console.error("%s %d: %s",a,d,b)}}else I[a]=function(){};return I[a]},c.inspect=e,e.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},e.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},c.isArray=o,c.isBoolean=p,c.isNull=q,c.isNullOrUndefined=r,c.isNumber=s,c.isString=t,c.isSymbol=u,c.isUndefined=v,c.isRegExp=w,c.isObject=x,c.isDate=y,c.isError=z,c.isFunction=A,c.isPrimitive=B,c.isBuffer=a("./support/isBuffer");var J=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];c.log=function(){console.log("%s - %s",E(),c.format.apply(c,arguments))},c.inherits=a("inherits"),c._extend=function(a,b){if(!b||!x(b))return a;for(var c=Object.keys(b),d=c.length;d--;)a[c[d]]=b[c[d]];return a}}).call(this,a("FWaASH"),"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./support/isBuffer":33,FWaASH:19,inherits:18}],35:[function(a,b,c){function d(a,b){if(!b)return a;var c;for(c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function e(a,b){if(!b)return a;var c;for(c in b)b.hasOwnProperty(c)&&("undefined"==typeof a[c]||null===a[c])&&(a[c]=b[c]);return a}function f(a,b,c,d,e,g,h){if(a==b)return a;if(!b)return a;var i,j,k=!1;if(h||(e={a:a},g="a"),c||(k=!0,c=[],d=[]),j=c.indexOf(b),-1!=j)return d[j][0][d[j][1]];c.push(b),d.push([e,g]);for(i in b)b.hasOwnProperty(i)&&("undefined"==typeof a[i]?"object"==typeof b[i]?b[i]instanceof Array?a[i]=f([],b[i],c,d,a,i,!0):null===b[i]?a[i]=null:b[i]instanceof Date?(a[i]=new b[i].constructor,a[i].setTime(b[i].getTime())):a[i]=f({},b[i],c,d,a,i,!0):a[i]=b[i]:a[i]="object"==typeof a[i]&&null!==a[i]?f(a[i],b[i],c,d,a,i,!0):b[i]);return k&&(c=null,d=null),h?a:(e=null,a)}function g(a,b,c,d,e,f,h,i){if(a==b)return a;if(!b)return a;var j,k=!1;if(i||(f={a:a},h="a"),d||(k=!0,d=[],e=[]),b_pos=d.indexOf(b),-1!=b_pos)return e[b_pos][0][e[b_pos][1]];d.push(b),e.push([f,h]);for(j in b)b.hasOwnProperty(j)&&("undefined"==typeof a[j]?"object"==typeof b[j]&&c>0?b[j]instanceof Array?a[j]=g([],b[j],c-1,d,e,a,j,!0):null===b[j]?a[j]=null:b[j]instanceof Date?(a[j]=new b[j].constructor,a[j].setTime(b[j].getTime())):a[j]=g({},b[j],c-1,d,e,a,j,!0):a[j]=b[j]:a[j]="object"==typeof a[j]&&null!==a[j]&&c>0?g(a[j],b[j],c-1,d,e,a,j,!0):b[j]);return k&&(d=null,e=null),i?a:(f=null,a)}function h(a){if("object"==typeof a){if(null===a)return null;if(a instanceof Array)return f([],a);if(a instanceof Date){var b=new a.constructor;return b.setTime(a.getTime()),b}return f({},a)}return a}function i(a,b){return"object"==typeof a?null===a?null:f(h(a),b):a}function j(a,b){return"object"==typeof a?null===a?null:a instanceof Array?g([],a,b):g({},a,b):a}function k(a,b,c){if(a){if("object"==typeof a&&a instanceof Array)return a.forEach(a,b,c);if(a)for(var d in a)if(a.hasOwnProperty(d)&&b.call(c,a[d],d,a)===!1)break}}c.replace=d,c.add=e,c.extend=f,c.extenduptolevel=g,c.clone=h,c.cloneextend=i,c.cloneuptolevel=j,c.foreach=k},{}],36:[function(a,b){(function(a){var c=b.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var b,d,e,f,g,h=arguments[0],i=Array.prototype.slice.call(arguments,1);return i.forEach(function(i){if("object"==typeof i)for(b in i)b in i&&(e=h[b],d=i[b],d!==h&&("object"==typeof d&&null!==d?d instanceof a?(g=new a(d.length),d.copy(g),h[b]=g):d instanceof Date?h[b]=new Date(d.getTime()):"object"==typeof e&&null!==e?(f=Array.isArray(d)?Array.isArray(e)?e:[]:Array.isArray(e)?{}:e,h[b]=c(f,d)):(f=Array.isArray(d)?[]:{},h[b]=c(f,d)):h[b]=d))}),h}}).call(this,a("buffer").Buffer)},{buffer:3}],37:[function(a,b,c){!function(){function a(){this._events={},this._conf&&b.call(this,this._conf)}function b(a){a&&(this._conf=a,a.delimiter&&(this.delimiter=a.delimiter),a.maxListeners&&(this._events.maxListeners=a.maxListeners),a.wildcard&&(this.wildcard=a.wildcard),a.newListener&&(this.newListener=a.newListener),this.wildcard&&(this.listenerTree={}))}function d(a){this._events={},this.newListener=!1,b.call(this,a)}function e(a,b,c,d){if(!c)return[];var f,g,h,i,j,k,l,m=[],n=b.length,o=b[d],p=b[d+1];if(d===n&&c._listeners){if("function"==typeof c._listeners)return a&&a.push(c._listeners),[c];for(f=0,g=c._listeners.length;g>f;f++)a&&a.push(c._listeners[f]);return[c]}if("*"===o||"**"===o||c[o]){if("*"===o){for(h in c)"_listeners"!==h&&c.hasOwnProperty(h)&&(m=m.concat(e(a,b,c[h],d+1)));return m}if("**"===o){l=d+1===n||d+2===n&&"*"===p,l&&c._listeners&&(m=m.concat(e(a,b,c,n)));for(h in c)"_listeners"!==h&&c.hasOwnProperty(h)&&("*"===h||"**"===h?(c[h]._listeners&&!l&&(m=m.concat(e(a,b,c[h],n))),m=m.concat(e(a,b,c[h],d))):m=m.concat(h===p?e(a,b,c[h],d+2):e(a,b,c[h],d)));return m}m=m.concat(e(a,b,c[o],d+1))}if(i=c["*"],i&&e(a,b,i,d+1),j=c["**"])if(n>d){j._listeners&&e(a,b,j,n);for(h in j)"_listeners"!==h&&j.hasOwnProperty(h)&&(h===p?e(a,b,j[h],d+2):h===o?e(a,b,j[h],d+1):(k={},k[h]=j[h],e(a,b,{"**":k},d+1)))}else j._listeners?e(a,b,j,n):j["*"]&&j["*"]._listeners&&e(a,b,j["*"],n);return m}function f(a,b){a="string"==typeof a?a.split(this.delimiter):a.slice();for(var c=0,d=a.length;d>c+1;c++)if("**"===a[c]&&"**"===a[c+1])return;for(var e=this.listenerTree,f=a.shift();f;){if(e[f]||(e[f]={}),e=e[f],0===a.length){if(e._listeners){if("function"==typeof e._listeners)e._listeners=[e._listeners,b];else if(g(e._listeners)&&(e._listeners.push(b),!e._listeners.warned)){var i=h;"undefined"!=typeof this._events.maxListeners&&(i=this._events.maxListeners),i>0&&e._listeners.length>i&&(e._listeners.warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",e._listeners.length),console.trace())}}else e._listeners=b;return!0}f=a.shift()}return!0}var g=Array.isArray?Array.isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)},h=10;d.prototype.delimiter=".",d.prototype.setMaxListeners=function(b){this._events||a.call(this),this._events.maxListeners=b,this._conf||(this._conf={}),this._conf.maxListeners=b},d.prototype.event="",d.prototype.once=function(a,b){return this.many(a,1,b),this},d.prototype.many=function(a,b,c){function d(){0===--b&&e.off(a,d),c.apply(this,arguments)}var e=this;if("function"!=typeof c)throw new Error("many only accepts instances of Function");return d._origin=c,this.on(a,d),e},d.prototype.emit=function(){this._events||a.call(this);var b=arguments[0];if("newListener"===b&&!this.newListener&&!this._events.newListener)return!1;if(this._all){for(var c=arguments.length,d=new Array(c-1),f=1;c>f;f++)d[f-1]=arguments[f];for(f=0,c=this._all.length;c>f;f++)this.event=b,this._all[f].apply(this,d)}if("error"===b&&!(this._all||this._events.error||this.wildcard&&this.listenerTree.error))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");var g;if(this.wildcard){g=[];var h="string"==typeof b?b.split(this.delimiter):b.slice();e.call(this,g,h,this.listenerTree,0)}else g=this._events[b];if("function"==typeof g){if(this.event=b,1===arguments.length)g.call(this);else if(arguments.length>1)switch(arguments.length){case 2:g.call(this,arguments[1]);break;case 3:g.call(this,arguments[1],arguments[2]);break;default:for(var c=arguments.length,d=new Array(c-1),f=1;c>f;f++)d[f-1]=arguments[f];g.apply(this,d)}return!0}if(g){for(var c=arguments.length,d=new Array(c-1),f=1;c>f;f++)d[f-1]=arguments[f];for(var i=g.slice(),f=0,c=i.length;c>f;f++)this.event=b,i[f].apply(this,d);return i.length>0||!!this._all}return!!this._all},d.prototype.on=function(b,c){if("function"==typeof b)return this.onAny(b),this;if("function"!=typeof c)throw new Error("on only accepts instances of Function");if(this._events||a.call(this),this.emit("newListener",b,c),this.wildcard)return f.call(this,b,c),this;if(this._events[b]){if("function"==typeof this._events[b])this._events[b]=[this._events[b],c];else if(g(this._events[b])&&(this._events[b].push(c),!this._events[b].warned)){var d=h;"undefined"!=typeof this._events.maxListeners&&(d=this._events.maxListeners),d>0&&this._events[b].length>d&&(this._events[b].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[b].length),console.trace())}}else this._events[b]=c;return this},d.prototype.onAny=function(a){if("function"!=typeof a)throw new Error("onAny only accepts instances of Function");return this._all||(this._all=[]),this._all.push(a),this},d.prototype.addListener=d.prototype.on,d.prototype.off=function(a,b){if("function"!=typeof b)throw new Error("removeListener only takes instances of Function");var c,d=[];if(this.wildcard){var f="string"==typeof a?a.split(this.delimiter):a.slice();d=e.call(this,null,f,this.listenerTree,0)}else{if(!this._events[a])return this;c=this._events[a],d.push({_listeners:c})}for(var h=0;hk;k++)if(c[k]===b||c[k].listener&&c[k].listener===b||c[k]._origin&&c[k]._origin===b){j=k;break}if(0>j)continue;return this.wildcard?i._listeners.splice(j,1):this._events[a].splice(j,1),0===c.length&&(this.wildcard?delete i._listeners:delete this._events[a]),this}(c===b||c.listener&&c.listener===b||c._origin&&c._origin===b)&&(this.wildcard?delete i._listeners:delete this._events[a])}return this},d.prototype.offAny=function(a){var b,c=0,d=0;if(a&&this._all&&this._all.length>0){for(b=this._all,c=0,d=b.length;d>c;c++)if(a===b[c])return b.splice(c,1),this}else this._all=[];return this},d.prototype.removeListener=d.prototype.off,d.prototype.removeAllListeners=function(b){if(0===arguments.length)return!this._events||a.call(this),this;if(this.wildcard)for(var c="string"==typeof b?b.split(this.delimiter):b.slice(),d=e.call(this,null,c,this.listenerTree,0),f=0;f=0)&&c(b,!e)}}),a("").outerWidth(1).jquery||a.each(["Width","Height"],function(c,d){function e(b,c,d,e){return a.each(f,function(){c-=parseFloat(a.css(b,"padding"+this))||0,d&&(c-=parseFloat(a.css(b,"border"+this+"Width"))||0),e&&(c-=parseFloat(a.css(b,"margin"+this))||0)}),c}var f="Width"===d?["Left","Right"]:["Top","Bottom"],g=d.toLowerCase(),h={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?h["inner"+d].call(this):this.each(function(){a(this).css(g,e(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return"number"!=typeof b?h["outer"+d].call(this,b):this.each(function(){a(this).css(g,e(this,b,!0,c)+"px")})}}),a.fn.addBack||(a.fn.addBack=function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a)) }),a("").data("a-b","a").removeData("a-b").data("a-b")&&(a.fn.removeData=function(b){return function(c){return arguments.length?b.call(this,a.camelCase(c)):b.call(this)}}(a.fn.removeData)),a.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),a.support.selectstart="onselectstart"in document.createElement("div"),a.fn.extend({disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e,f=a.ui[b].prototype;for(e in d)f.plugins[e]=f.plugins[e]||[],f.plugins[e].push([c,d[e]])},call:function(a,b,c){var d,e=a.plugins[b];if(e&&a.element[0].parentNode&&11!==a.element[0].parentNode.nodeType)for(d=0;d0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)}})}(b)},{jquery:40}],39:[function(a){var b=a("jquery");a("./core"),function(a,b){function c(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},a.extend(this._defaults,this.regional[""]),this.dpDiv=d(a("
"))}function d(b){var c="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return b.delegate(c,"mouseout",function(){a(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&a(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&a(this).removeClass("ui-datepicker-next-hover")}).delegate(c,"mouseover",function(){a.datepicker._isDisabledDatepicker(f.inline?b.parent()[0]:f.input[0])||(a(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),a(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&a(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&a(this).addClass("ui-datepicker-next-hover"))})}function e(b,c){a.extend(b,c);for(var d in c)null==c[d]&&(b[d]=c[d]);return b}a.extend(a.ui,{datepicker:{version:"1.10.4"}});var f,g="datepicker";a.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){return e(this._defaults,a||{}),this},_attachDatepicker:function(b,c){var d,e,f;d=b.nodeName.toLowerCase(),e="div"===d||"span"===d,b.id||(this.uuid+=1,b.id="dp"+this.uuid),f=this._newInst(a(b),e),f.settings=a.extend({},c||{}),"input"===d?this._connectDatepicker(b,f):e&&this._inlineDatepicker(b,f)},_newInst:function(b,c){var e=b[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:e,input:b,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:c,dpDiv:c?d(a("
")):this.dpDiv}},_connectDatepicker:function(b,c){var d=a(b);c.append=a([]),c.trigger=a([]),d.hasClass(this.markerClassName)||(this._attachments(d,c),d.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(c),a.data(b,g,c),c.settings.disabled&&this._disableDatepicker(b))},_attachments:function(b,c){var d,e,f,g=this._get(c,"appendText"),h=this._get(c,"isRTL");c.append&&c.append.remove(),g&&(c.append=a(""+g+""),b[h?"before":"after"](c.append)),b.unbind("focus",this._showDatepicker),c.trigger&&c.trigger.remove(),d=this._get(c,"showOn"),("focus"===d||"both"===d)&&b.focus(this._showDatepicker),("button"===d||"both"===d)&&(e=this._get(c,"buttonText"),f=this._get(c,"buttonImage"),c.trigger=a(this._get(c,"buttonImageOnly")?a("").addClass(this._triggerClass).attr({src:f,alt:e,title:e}):a("").addClass(this._triggerClass).html(f?a("").attr({src:f,alt:e,title:e}):e)),b[h?"before":"after"](c.trigger),c.trigger.click(function(){return a.datepicker._datepickerShowing&&a.datepicker._lastInput===b[0]?a.datepicker._hideDatepicker():a.datepicker._datepickerShowing&&a.datepicker._lastInput!==b[0]?(a.datepicker._hideDatepicker(),a.datepicker._showDatepicker(b[0])):a.datepicker._showDatepicker(b[0]),!1}))},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b,c,d,e,f=new Date(2009,11,20),g=this._get(a,"dateFormat");g.match(/[DM]/)&&(b=function(a){for(c=0,d=0,e=0;ec&&(c=a[e].length,d=e);return d},f.setMonth(b(this._get(a,g.match(/MM/)?"monthNames":"monthNamesShort"))),f.setDate(b(this._get(a,g.match(/DD/)?"dayNames":"dayNamesShort"))+20-f.getDay())),a.input.attr("size",this._formatDate(a,f).length)}},_inlineDatepicker:function(b,c){var d=a(b);d.hasClass(this.markerClassName)||(d.addClass(this.markerClassName).append(c.dpDiv),a.data(b,g,c),this._setDate(c,this._getDefaultDate(c),!0),this._updateDatepicker(c),this._updateAlternate(c),c.settings.disabled&&this._disableDatepicker(b),c.dpDiv.css("display","block"))},_dialogDatepicker:function(b,c,d,f,h){var i,j,k,l,m,n=this._dialogInst;return n||(this.uuid+=1,i="dp"+this.uuid,this._dialogInput=a(""),this._dialogInput.keydown(this._doKeyDown),a("body").append(this._dialogInput),n=this._dialogInst=this._newInst(this._dialogInput,!1),n.settings={},a.data(this._dialogInput[0],g,n)),e(n.settings,f||{}),c=c&&c.constructor===Date?this._formatDate(n,c):c,this._dialogInput.val(c),this._pos=h?h.length?h:[h.pageX,h.pageY]:null,this._pos||(j=document.documentElement.clientWidth,k=document.documentElement.clientHeight,l=document.documentElement.scrollLeft||document.body.scrollLeft,m=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[j/2-100+l,k/2-150+m]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),n.settings.onSelect=d,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),a.blockUI&&a.blockUI(this.dpDiv),a.data(this._dialogInput[0],g,n),this},_destroyDatepicker:function(b){var c,d=a(b),e=a.data(b,g);d.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),a.removeData(b,g),"input"===c?(e.append.remove(),e.trigger.remove(),d.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===c||"span"===c)&&d.removeClass(this.markerClassName).empty())},_enableDatepicker:function(b){var c,d,e=a(b),f=a.data(b,g);e.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),"input"===c?(b.disabled=!1,f.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===c||"span"===c)&&(d=e.children("."+this._inlineClass),d.children().removeClass("ui-state-disabled"),d.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=a.map(this._disabledInputs,function(a){return a===b?null:a}))},_disableDatepicker:function(b){var c,d,e=a(b),f=a.data(b,g);e.hasClass(this.markerClassName)&&(c=b.nodeName.toLowerCase(),"input"===c?(b.disabled=!0,f.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===c||"span"===c)&&(d=e.children("."+this._inlineClass),d.children().addClass("ui-state-disabled"),d.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=a.map(this._disabledInputs,function(a){return a===b?null:a}),this._disabledInputs[this._disabledInputs.length]=b)},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;bd||!c||c.indexOf(d)>-1):void 0},_doKeyUp:function(b){var c,d=a.datepicker._getInst(b.target);if(d.input.val()!==d.lastVal)try{c=a.datepicker.parseDate(a.datepicker._get(d,"dateFormat"),d.input?d.input.val():null,a.datepicker._getFormatConfig(d)),c&&(a.datepicker._setDateFromField(d),a.datepicker._updateAlternate(d),a.datepicker._updateDatepicker(d))}catch(e){}return!0},_showDatepicker:function(b){if(b=b.target||b,"input"!==b.nodeName.toLowerCase()&&(b=a("input",b.parentNode)[0]),!a.datepicker._isDisabledDatepicker(b)&&a.datepicker._lastInput!==b){var c,d,f,g,h,i,j;c=a.datepicker._getInst(b),a.datepicker._curInst&&a.datepicker._curInst!==c&&(a.datepicker._curInst.dpDiv.stop(!0,!0),c&&a.datepicker._datepickerShowing&&a.datepicker._hideDatepicker(a.datepicker._curInst.input[0])),d=a.datepicker._get(c,"beforeShow"),f=d?d.apply(b,[b,c]):{},f!==!1&&(e(c.settings,f),c.lastVal=null,a.datepicker._lastInput=b,a.datepicker._setDateFromField(c),a.datepicker._inDialog&&(b.value=""),a.datepicker._pos||(a.datepicker._pos=a.datepicker._findPos(b),a.datepicker._pos[1]+=b.offsetHeight),g=!1,a(b).parents().each(function(){return g|="fixed"===a(this).css("position"),!g}),h={left:a.datepicker._pos[0],top:a.datepicker._pos[1]},a.datepicker._pos=null,c.dpDiv.empty(),c.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),a.datepicker._updateDatepicker(c),h=a.datepicker._checkOffset(c,h,g),c.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":g?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),c.inline||(i=a.datepicker._get(c,"showAnim"),j=a.datepicker._get(c,"duration"),c.dpDiv.zIndex(a(b).zIndex()+1),a.datepicker._datepickerShowing=!0,a.effects&&a.effects.effect[i]?c.dpDiv.show(i,a.datepicker._get(c,"showOptions"),j):c.dpDiv[i||"show"](i?j:null),a.datepicker._shouldFocusInput(c)&&c.input.focus(),a.datepicker._curInst=c))}},_updateDatepicker:function(b){this.maxRows=4,f=b,b.dpDiv.empty().append(this._generateHTML(b)),this._attachHandlers(b),b.dpDiv.find("."+this._dayOverClass+" a").mouseover();var c,d=this._getNumberOfMonths(b),e=d[1],g=17;b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),e>1&&b.dpDiv.addClass("ui-datepicker-multi-"+e).css("width",g*e+"em"),b.dpDiv[(1!==d[0]||1!==d[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),b===a.datepicker._curInst&&a.datepicker._datepickerShowing&&a.datepicker._shouldFocusInput(b)&&b.input.focus(),b.yearshtml&&(c=b.yearshtml,setTimeout(function(){c===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml),c=b.yearshtml=null},0))},_shouldFocusInput:function(a){return a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&!a.input.is(":focus")},_checkOffset:function(b,c,d){var e=b.dpDiv.outerWidth(),f=b.dpDiv.outerHeight(),g=b.input?b.input.outerWidth():0,h=b.input?b.input.outerHeight():0,i=document.documentElement.clientWidth+(d?0:a(document).scrollLeft()),j=document.documentElement.clientHeight+(d?0:a(document).scrollTop());return c.left-=this._get(b,"isRTL")?e-g:0,c.left-=d&&c.left===b.input.offset().left?a(document).scrollLeft():0,c.top-=d&&c.top===b.input.offset().top+h?a(document).scrollTop():0,c.left-=Math.min(c.left,c.left+e>i&&i>e?Math.abs(c.left+e-i):0),c.top-=Math.min(c.top,c.top+f>j&&j>f?Math.abs(f+h):0),c},_findPos:function(b){for(var c,d=this._getInst(b),e=this._get(d,"isRTL");b&&("hidden"===b.type||1!==b.nodeType||a.expr.filters.hidden(b));)b=b[e?"previousSibling":"nextSibling"];return c=a(b).offset(),[c.left,c.top]},_hideDatepicker:function(b){var c,d,e,f,h=this._curInst;!h||b&&h!==a.data(b,g)||this._datepickerShowing&&(c=this._get(h,"showAnim"),d=this._get(h,"duration"),e=function(){a.datepicker._tidyDialog(h)},a.effects&&(a.effects.effect[c]||a.effects[c])?h.dpDiv.hide(c,a.datepicker._get(h,"showOptions"),d,e):h.dpDiv["slideDown"===c?"slideUp":"fadeIn"===c?"fadeOut":"hide"](c?d:null,e),c||e(),this._datepickerShowing=!1,f=this._get(h,"onClose"),f&&f.apply(h.input?h.input[0]:null,[h.input?h.input.val():"",h]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),a.blockUI&&(a.unblockUI(),a("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(b){if(a.datepicker._curInst){var c=a(b.target),d=a.datepicker._getInst(c[0]);(c[0].id!==a.datepicker._mainDivId&&0===c.parents("#"+a.datepicker._mainDivId).length&&!c.hasClass(a.datepicker.markerClassName)&&!c.closest("."+a.datepicker._triggerClass).length&&a.datepicker._datepickerShowing&&(!a.datepicker._inDialog||!a.blockUI)||c.hasClass(a.datepicker.markerClassName)&&a.datepicker._curInst!==d)&&a.datepicker._hideDatepicker()}},_adjustDate:function(b,c,d){var e=a(b),f=this._getInst(e[0]);this._isDisabledDatepicker(e[0])||(this._adjustInstDate(f,c+("M"===d?this._get(f,"showCurrentAtPos"):0),d),this._updateDatepicker(f))},_gotoToday:function(b){var c,d=a(b),e=this._getInst(d[0]);this._get(e,"gotoCurrent")&&e.currentDay?(e.selectedDay=e.currentDay,e.drawMonth=e.selectedMonth=e.currentMonth,e.drawYear=e.selectedYear=e.currentYear):(c=new Date,e.selectedDay=c.getDate(),e.drawMonth=e.selectedMonth=c.getMonth(),e.drawYear=e.selectedYear=c.getFullYear()),this._notifyChange(e),this._adjustDate(d)},_selectMonthYear:function(b,c,d){var e=a(b),f=this._getInst(e[0]);f["selected"+("M"===d?"Month":"Year")]=f["draw"+("M"===d?"Month":"Year")]=parseInt(c.options[c.selectedIndex].value,10),this._notifyChange(f),this._adjustDate(e)},_selectDay:function(b,c,d,e){var f,g=a(b);a(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(g[0])||(f=this._getInst(g[0]),f.selectedDay=f.currentDay=a("a",e).html(),f.selectedMonth=f.currentMonth=c,f.selectedYear=f.currentYear=d,this._selectDate(b,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear)))},_clearDate:function(b){var c=a(b);this._selectDate(c,"")},_selectDate:function(b,c){var d,e=a(b),f=this._getInst(e[0]);c=null!=c?c:this._formatDate(f),f.input&&f.input.val(c),this._updateAlternate(f),d=this._get(f,"onSelect"),d?d.apply(f.input?f.input[0]:null,[c,f]):f.input&&f.input.trigger("change"),f.inline?this._updateDatepicker(f):(this._hideDatepicker(),this._lastInput=f.input[0],"object"!=typeof f.input[0]&&f.input.focus(),this._lastInput=null)},_updateAlternate:function(b){var c,d,e,f=this._get(b,"altField");f&&(c=this._get(b,"altFormat")||this._get(b,"dateFormat"),d=this._getDate(b),e=this.formatDate(c,d,this._getFormatConfig(b)),a(f).each(function(){a(this).val(e)}))},noWeekends:function(a){var b=a.getDay();return[b>0&&6>b,""]},iso8601Week:function(a){var b,c=new Date(a.getTime());return c.setDate(c.getDate()+4-(c.getDay()||7)),b=c.getTime(),c.setMonth(0),c.setDate(1),Math.floor(Math.round((b-c)/864e5)/7)+1},parseDate:function(b,c,d){if(null==b||null==c)throw"Invalid arguments";if(c="object"==typeof c?c.toString():c+"",""===c)return null;var e,f,g,h,i=0,j=(d?d.shortYearCutoff:null)||this._defaults.shortYearCutoff,k="string"!=typeof j?j:(new Date).getFullYear()%100+parseInt(j,10),l=(d?d.dayNamesShort:null)||this._defaults.dayNamesShort,m=(d?d.dayNames:null)||this._defaults.dayNames,n=(d?d.monthNamesShort:null)||this._defaults.monthNamesShort,o=(d?d.monthNames:null)||this._defaults.monthNames,p=-1,q=-1,r=-1,s=-1,t=!1,u=function(a){var c=e+1p&&(p+=(new Date).getFullYear()-(new Date).getFullYear()%100+(k>=p?0:-100)),s>-1)for(q=1,r=s;;){if(f=this._getDaysInMonth(p,q-1),f>=r)break;q++,r-=f}if(h=this._daylightSavingAdjust(new Date(p,q-1,r)),h.getFullYear()!==p||h.getMonth()+1!==q||h.getDate()!==r)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d,e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=function(b){var c=d+112?a.getHours()+2:0),a):null},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),e===a.selectedMonth&&f===a.selectedYear||c||this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&""===a.input.val()?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_attachHandlers:function(b){var c=this._get(b,"stepMonths"),d="#"+b.id.replace(/\\\\/g,"\\");b.dpDiv.find("[data-handler]").map(function(){var b={prev:function(){a.datepicker._adjustDate(d,-c,"M")},next:function(){a.datepicker._adjustDate(d,+c,"M")},hide:function(){a.datepicker._hideDatepicker()},today:function(){a.datepicker._gotoToday(d)},selectDay:function(){return a.datepicker._selectDay(d,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return a.datepicker._selectMonthYear(d,this,"M"),!1},selectYear:function(){return a.datepicker._selectMonthYear(d,this,"Y"),!1}};a(this).bind(this.getAttribute("data-event"),b[this.getAttribute("data-handler")])})},_generateHTML:function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O=new Date,P=this._daylightSavingAdjust(new Date(O.getFullYear(),O.getMonth(),O.getDate())),Q=this._get(a,"isRTL"),R=this._get(a,"showButtonPanel"),S=this._get(a,"hideIfNoPrevNext"),T=this._get(a,"navigationAsDateFormat"),U=this._getNumberOfMonths(a),V=this._get(a,"showCurrentAtPos"),W=this._get(a,"stepMonths"),X=1!==U[0]||1!==U[1],Y=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),Z=this._getMinMaxDate(a,"min"),$=this._getMinMaxDate(a,"max"),_=a.drawMonth-V,ab=a.drawYear;if(0>_&&(_+=12,ab--),$)for(b=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-U[0]*U[1]+1,$.getDate())),b=Z&&Z>b?Z:b;this._daylightSavingAdjust(new Date(ab,_,1))>b;)_--,0>_&&(_=11,ab--);for(a.drawMonth=_,a.drawYear=ab,c=this._get(a,"prevText"),c=T?this.formatDate(c,this._daylightSavingAdjust(new Date(ab,_-W,1)),this._getFormatConfig(a)):c,d=this._canAdjustMonth(a,-1,ab,_)?"
"+c+"":S?"":""+c+"",e=this._get(a,"nextText"),e=T?this.formatDate(e,this._daylightSavingAdjust(new Date(ab,_+W,1)),this._getFormatConfig(a)):e,f=this._canAdjustMonth(a,1,ab,_)?""+e+"":S?"":""+e+"",g=this._get(a,"currentText"),h=this._get(a,"gotoCurrent")&&a.currentDay?Y:P,g=T?this.formatDate(g,h,this._getFormatConfig(a)):g,i=a.inline?"":"",j=R?"
"+(Q?i:"")+(this._isInRange(a,h)?"":"")+(Q?"":i)+"
":"",k=parseInt(this._get(a,"firstDay"),10),k=isNaN(k)?0:k,l=this._get(a,"showWeek"),m=this._get(a,"dayNames"),n=this._get(a,"dayNamesMin"),o=this._get(a,"monthNames"),p=this._get(a,"monthNamesShort"),q=this._get(a,"beforeShowDay"),r=this._get(a,"showOtherMonths"),s=this._get(a,"selectOtherMonths"),t=this._getDefaultDate(a),u="",w=0;w1)switch(y){case 0:B+=" ui-datepicker-group-first",A=" ui-corner-"+(Q?"right":"left");break;case U[1]-1:B+=" ui-datepicker-group-last",A=" ui-corner-"+(Q?"left":"right");break;default:B+=" ui-datepicker-group-middle",A=""}B+="'>"}for(B+="
"+(/all|left/.test(A)&&0===w?Q?f:d:"")+(/all|right/.test(A)&&0===w?Q?d:f:"")+this._generateMonthYearHeader(a,_,ab,Z,$,w>0||y>0,o,p)+"
",C=l?"":"",v=0;7>v;v++)D=(v+k)%7,C+="=5?" class='ui-datepicker-week-end'":"")+">"+n[D]+"";for(B+=C+"",E=this._getDaysInMonth(ab,_),ab===a.selectedYear&&_===a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,E)),F=(this._getFirstDayOfMonth(ab,_)-k+7)%7,G=Math.ceil((F+E)/7),H=X&&this.maxRows>G?this.maxRows:G,this.maxRows=H,I=this._daylightSavingAdjust(new Date(ab,_,1-F)),J=0;H>J;J++){for(B+="",K=l?"":"",v=0;7>v;v++)L=q?q.apply(a.input?a.input[0]:null,[I]):[!0,""],M=I.getMonth()!==_,N=M&&!s||!L[0]||Z&&Z>I||$&&I>$,K+="",I.setDate(I.getDate()+1),I=this._daylightSavingAdjust(I); -B+=K+""}_++,_>11&&(_=0,ab++),B+="
"+this._get(a,"weekHeader")+"
"+this._get(a,"calculateWeek")(I)+""+(M&&!r?" ":N?""+I.getDate()+"":""+I.getDate()+"")+"
"+(X?""+(U[0]>0&&y===U[1]-1?"
":""):""),x+=B}u+=x}return u+=j,a._keyEvent=!1,u},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i,j,k,l,m,n,o,p,q=this._get(a,"changeMonth"),r=this._get(a,"changeYear"),s=this._get(a,"showMonthAfterYear"),t="
",u="";if(f||!q)u+=""+g[b]+"";else{for(i=d&&d.getFullYear()===c,j=e&&e.getFullYear()===c,u+=""}if(s||(t+=u+(!f&&q&&r?"":" ")),!a.yearshtml)if(a.yearshtml="",f||!r)t+=""+c+"";else{for(l=this._get(a,"yearRange").split(":"),m=(new Date).getFullYear(),n=function(a){var b=a.match(/c[+\-].*/)?c+parseInt(a.substring(1),10):a.match(/[+\-].*/)?m+parseInt(a,10):parseInt(a,10);return isNaN(b)?m:b},o=n(l[0]),p=Math.max(o,n(l[1]||"")),o=d?Math.max(o,d.getFullYear()):o,p=e?Math.min(p,e.getFullYear()):p,a.yearshtml+="",t+=a.yearshtml,a.yearshtml=null}return t+=this._get(a,"yearSuffix"),s&&(t+=(!f&&q&&r?"":" ")+u),t+="
"},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"===c?b:0),e=a.drawMonth+("M"===c?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"===c?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),("M"===c||"Y"===c)&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&c>b?c:b;return d&&e>d?d:e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return null==b?[1,1]:"number"==typeof b?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return new Date(a,b,1).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(0>b?b:e[0]*e[1]),1));return 0>b&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth())),this._isInRange(a,f)},_isInRange:function(a,b){var c,d,e=this._getMinMaxDate(a,"min"),f=this._getMinMaxDate(a,"max"),g=null,h=null,i=this._get(a,"yearRange");return i&&(c=i.split(":"),d=(new Date).getFullYear(),g=parseInt(c[0],10),h=parseInt(c[1],10),c[0].match(/[+\-].*/)&&(g+=d),c[1].match(/[+\-].*/)&&(h+=d)),(!e||b.getTime()>=e.getTime())&&(!f||b.getTime()<=f.getTime())&&(!g||b.getFullYear()>=g)&&(!h||b.getFullYear()<=h)},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");return b="string"!=typeof b?b:(new Date).getFullYear()%100+parseInt(b,10),{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?"object"==typeof b?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),a.fn.datepicker=function(b){if(!this.length)return this;a.datepicker.initialized||(a(document).mousedown(a.datepicker._checkExternalClick),a.datepicker.initialized=!0),0===a("#"+a.datepicker._mainDivId).length&&a("body").append(a.datepicker.dpDiv);var c=Array.prototype.slice.call(arguments,1);return"string"!=typeof b||"isDisabled"!==b&&"getDate"!==b&&"widget"!==b?"option"===b&&2===arguments.length&&"string"==typeof arguments[1]?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(c)):this.each(function(){"string"==typeof b?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(c)):a.datepicker._attachDatepicker(this,b)}):a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(c))},a.datepicker=new c,a.datepicker.initialized=!1,a.datepicker.uuid=(new Date).getTime(),a.datepicker.version="1.10.4"}(b)},{"./core":38,jquery:40}],40:[function(a,b){!function(a,c){"object"==typeof b&&"object"==typeof b.exports?b.exports=a.document?c(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return c(a)}:c(a)}("undefined"!=typeof window?window:this,function(a,b){function c(a){var b=a.length,c=_.type(a);return"function"===c||_.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}function d(a,b,c){if(_.isFunction(b))return _.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return _.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(hb.test(b))return _.filter(b,a,c);b=_.filter(b,a)}return _.grep(a,function(a){return U.call(b,a)>=0!==c})}function e(a,b){for(;(a=a[b])&&1!==a.nodeType;);return a}function f(a){var b=ob[a]={};return _.each(a.match(nb)||[],function(a,c){b[c]=!0}),b}function g(){Z.removeEventListener("DOMContentLoaded",g,!1),a.removeEventListener("load",g,!1),_.ready()}function h(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=_.expando+h.uid++}function i(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(ub,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:tb.test(c)?_.parseJSON(c):c}catch(e){}sb.set(a,b,c)}else c=void 0;return c}function j(){return!0}function k(){return!1}function l(){try{return Z.activeElement}catch(a){}}function m(a,b){return _.nodeName(a,"table")&&_.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function n(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function o(a){var b=Kb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function p(a,b){for(var c=0,d=a.length;d>c;c++)rb.set(a[c],"globalEval",!b||rb.get(b[c],"globalEval"))}function q(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(rb.hasData(a)&&(f=rb.access(a),g=rb.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)_.event.add(b,e,j[e][c])}sb.hasData(a)&&(h=sb.access(a),i=_.extend({},h),sb.set(b,i))}}function r(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&_.nodeName(a,b)?_.merge([a],c):c}function s(a,b){var c=b.nodeName.toLowerCase();"input"===c&&yb.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function t(b,c){var d,e=_(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:_.css(e[0],"display");return e.detach(),f}function u(a){var b=Z,c=Ob[a];return c||(c=t(a,b),"none"!==c&&c||(Nb=(Nb||_("