Created
January 5, 2015 22:26
-
-
Save EvanCarroll/073ff45151a397dabb57 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
/*! | |
* The buffer module from node.js, for the browser. | |
* | |
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> | |
* @license MIT | |
*/ | |
var base64 = require('base64-js') | |
var ieee754 = require('ieee754') | |
var isArray = require('is-array') | |
exports.Buffer = Buffer | |
exports.SlowBuffer = SlowBuffer | |
exports.INSPECT_MAX_BYTES = 50 | |
Buffer.poolSize = 8192 // not used by this implementation | |
var kMaxLength = 0x3fffffff | |
var rootParent = {} | |
/** | |
* If `Buffer.TYPED_ARRAY_SUPPORT`: | |
* === true Use Uint8Array implementation (fastest) | |
* === false Use Object implementation (most compatible, even IE6) | |
* | |
* Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, | |
* Opera 11.6+, iOS 4.2+. | |
* | |
* Note: | |
* | |
* - Implementation must support adding new properties to `Uint8Array` instances. | |
* Firefox 4-29 lacked support, fixed in Firefox 30+. | |
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. | |
* | |
* - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. | |
* | |
* - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of | |
* incorrect length in some situations. | |
* | |
* We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will | |
* get the Object implementation, which is slower but will work correctly. | |
*/ | |
Buffer.TYPED_ARRAY_SUPPORT = (function () { | |
try { | |
var buf = new ArrayBuffer(0) | |
var arr = new Uint8Array(buf) | |
arr.foo = function () { return 42 } | |
return 42 === arr.foo() && // typed array instances can be augmented | |
typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` | |
new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` | |
} catch (e) { | |
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) | |
var type = typeof subject | |
// Find the length | |
var length | |
if (type === 'number') | |
length = subject > 0 ? subject >>> 0 : 0 | |
else if (type === 'string') { | |
length = Buffer.byteLength(subject, encoding) | |
} else if (type === 'object' && subject !== null) { // assume object is array-like | |
if (subject.type === 'Buffer' && isArray(subject.data)) | |
subject = subject.data | |
length = +subject.length > 0 ? Math.floor(+subject.length) : 0 | |
} else | |
throw new TypeError('must start with number, buffer, array or string') | |
if (length > kMaxLength) | |
throw new RangeError('Attempt to allocate Buffer larger than maximum ' + | |
'size: 0x' + kMaxLength.toString(16) + ' bytes') | |
var buf | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
// 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.TYPED_ARRAY_SUPPORT && 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 | |
if (Buffer.isBuffer(subject)) { | |
for (i = 0; i < length; i++) | |
buf[i] = subject.readUInt8(i) | |
} else { | |
for (i = 0; i < length; i++) | |
buf[i] = ((subject[i] % 256) + 256) % 256 | |
} | |
} else if (type === 'string') { | |
buf.write(subject, 0, encoding) | |
} else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) { | |
for (i = 0; i < length; i++) { | |
buf[i] = 0 | |
} | |
} | |
if (length > 0 && length <= Buffer.poolSize) | |
buf.parent = rootParent | |
return buf | |
} | |
function SlowBuffer(subject, encoding, noZero) { | |
if (!(this instanceof SlowBuffer)) | |
return new SlowBuffer(subject, encoding, noZero) | |
var buf = new Buffer(subject, encoding, noZero) | |
delete buf.parent | |
return buf | |
} | |
Buffer.isBuffer = function (b) { | |
return !!(b != null && b._isBuffer) | |
} | |
Buffer.compare = function (a, b) { | |
if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) | |
throw new TypeError('Arguments must be Buffers') | |
var x = a.length | |
var y = b.length | |
for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} | |
if (i !== len) { | |
x = a[i] | |
y = b[i] | |
} | |
if (x < y) return -1 | |
if (y < x) return 1 | |
return 0 | |
} | |
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 | |
} | |
} | |
Buffer.concat = function (list, totalLength) { | |
if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])') | |
if (list.length === 0) { | |
return new Buffer(0) | |
} else if (list.length === 1) { | |
return list[0] | |
} | |
var i | |
if (totalLength === undefined) { | |
totalLength = 0 | |
for (i = 0; i < list.length; i++) { | |
totalLength += list[i].length | |
} | |
} | |
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 | |
} | |
Buffer.byteLength = function (str, encoding) { | |
var ret | |
str = str + '' | |
switch (encoding || 'utf8') { | |
case 'ascii': | |
case 'binary': | |
case 'raw': | |
ret = str.length | |
break | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
ret = str.length * 2 | |
break | |
case 'hex': | |
ret = str.length >>> 1 | |
break | |
case 'utf8': | |
case 'utf-8': | |
ret = utf8ToBytes(str).length | |
break | |
case 'base64': | |
ret = base64ToBytes(str).length | |
break | |
default: | |
ret = str.length | |
} | |
return ret | |
} | |
// pre-set for values that may exist in the future | |
Buffer.prototype.length = undefined | |
Buffer.prototype.parent = undefined | |
// toString(encoding, start=0, end=buffer.length) | |
Buffer.prototype.toString = function (encoding, start, end) { | |
var loweredCase = false | |
start = start >>> 0 | |
end = end === undefined || end === Infinity ? this.length : end >>> 0 | |
if (!encoding) encoding = 'utf8' | |
if (start < 0) start = 0 | |
if (end > this.length) end = this.length | |
if (end <= start) return '' | |
while (true) { | |
switch (encoding) { | |
case 'hex': | |
return hexSlice(this, start, end) | |
case 'utf8': | |
case 'utf-8': | |
return utf8Slice(this, start, end) | |
case 'ascii': | |
return asciiSlice(this, start, end) | |
case 'binary': | |
return binarySlice(this, start, end) | |
case 'base64': | |
return base64Slice(this, start, end) | |
case 'ucs2': | |
case 'ucs-2': | |
case 'utf16le': | |
case 'utf-16le': | |
return utf16leSlice(this, start, end) | |
default: | |
if (loweredCase) | |
throw new TypeError('Unknown encoding: ' + encoding) | |
encoding = (encoding + '').toLowerCase() | |
loweredCase = true | |
} | |
} | |
} | |
Buffer.prototype.equals = function (b) { | |
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') | |
return Buffer.compare(this, b) === 0 | |
} | |
Buffer.prototype.inspect = function () { | |
var str = '' | |
var max = exports.INSPECT_MAX_BYTES | |
if (this.length > 0) { | |
str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') | |
if (this.length > max) | |
str += ' ... ' | |
} | |
return '<Buffer ' + str + '>' | |
} | |
Buffer.prototype.compare = function (b) { | |
if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') | |
return Buffer.compare(this, b) | |
} | |
// `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) | |
} | |
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 | |
} | |
} | |
// must be an even number of digits | |
var strLen = string.length | |
if (strLen % 2 !== 0) 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') | |
buf[offset + i] = byte | |
} | |
return i | |
} | |
function utf8Write (buf, string, offset, length) { | |
var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) | |
return charsWritten | |
} | |
function asciiWrite (buf, string, offset, length) { | |
var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) | |
return charsWritten | |
} | |
function binaryWrite (buf, string, offset, length) { | |
return asciiWrite(buf, string, offset, length) | |
} | |
function base64Write (buf, string, offset, length) { | |
var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) | |
return charsWritten | |
} | |
function utf16leWrite (buf, string, offset, length) { | |
var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length, 2) | |
return charsWritten | |
} | |
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 | |
} | |
offset = Number(offset) || 0 | |
if (length < 0 || offset < 0 || offset > this.length) | |
throw new RangeError('attempt to write outside buffer bounds'); | |
var remaining = this.length - offset | |
if (!length) { | |
length = remaining | |
} else { | |
length = Number(length) | |
if (length > remaining) { | |
length = remaining | |
} | |
} | |
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 TypeError('Unknown encoding: ' + encoding) | |
} | |
return ret | |
} | |
Buffer.prototype.toJSON = function () { | |
return { | |
type: 'Buffer', | |
data: Array.prototype.slice.call(this._arr || this, 0) | |
} | |
} | |
function base64Slice (buf, start, end) { | |
if (start === 0 && end === buf.length) { | |
return base64.fromByteArray(buf) | |
} else { | |
return base64.fromByteArray(buf.slice(start, end)) | |
} | |
} | |
function utf8Slice (buf, start, end) { | |
var res = '' | |
var tmp = '' | |
end = Math.min(buf.length, end) | |
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) | |
} | |
} | |
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] & 0x7F) | |
} | |
return ret | |
} | |
function binarySlice (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 hexSlice (buf, start, end) { | |
var len = buf.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(buf[i]) | |
} | |
return out | |
} | |
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 | |
} | |
Buffer.prototype.slice = function (start, end) { | |
var len = this.length | |
start = ~~start | |
end = end === undefined ? len : ~~end | |
if (start < 0) { | |
start += len; | |
if (start < 0) | |
start = 0 | |
} else if (start > len) { | |
start = len | |
} | |
if (end < 0) { | |
end += len | |
if (end < 0) | |
end = 0 | |
} else if (end > len) { | |
end = len | |
} | |
if (end < start) | |
end = start | |
var newBuf | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
newBuf = Buffer._augment(this.subarray(start, end)) | |
} else { | |
var sliceLen = end - start | |
newBuf = new Buffer(sliceLen, undefined, true) | |
for (var i = 0; i < sliceLen; i++) { | |
newBuf[i] = this[i + start] | |
} | |
} | |
if (newBuf.length) | |
newBuf.parent = this.parent || this | |
return newBuf | |
} | |
/* | |
* Need to make sure that buffer isn't trying to write out of bounds. | |
*/ | |
function checkOffset (offset, ext, length) { | |
if ((offset % 1) !== 0 || offset < 0) | |
throw new RangeError('offset is not uint') | |
if (offset + ext > length) | |
throw new RangeError('Trying to access beyond buffer length') | |
} | |
Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) { | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkOffset(offset, byteLength, this.length) | |
var val = this[offset] | |
var mul = 1 | |
var i = 0 | |
while (++i < byteLength && (mul *= 0x100)) | |
val += this[offset + i] * mul | |
return val | |
} | |
Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) { | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkOffset(offset, byteLength, this.length) | |
var val = this[offset + --byteLength] | |
var mul = 1 | |
while (byteLength > 0 && (mul *= 0x100)) | |
val += this[offset + --byteLength] * mul; | |
return val | |
} | |
Buffer.prototype.readUInt8 = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 1, this.length) | |
return this[offset] | |
} | |
Buffer.prototype.readUInt16LE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 2, this.length) | |
return this[offset] | (this[offset + 1] << 8) | |
} | |
Buffer.prototype.readUInt16BE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 2, this.length) | |
return (this[offset] << 8) | this[offset + 1] | |
} | |
Buffer.prototype.readUInt32LE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return ((this[offset]) | | |
(this[offset + 1] << 8) | | |
(this[offset + 2] << 16)) + | |
(this[offset + 3] * 0x1000000) | |
} | |
Buffer.prototype.readUInt32BE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return (this[offset] * 0x1000000) + | |
((this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
this[offset + 3]) | |
} | |
Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) { | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkOffset(offset, byteLength, this.length) | |
var val = this[offset] | |
var mul = 1 | |
var i = 0 | |
while (++i < byteLength && (mul *= 0x100)) | |
val += this[offset + i] * mul | |
mul *= 0x80 | |
if (val >= mul) | |
val -= Math.pow(2, 8 * byteLength) | |
return val | |
} | |
Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) { | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkOffset(offset, byteLength, this.length) | |
var i = byteLength | |
var mul = 1 | |
var val = this[offset + --i] | |
while (i > 0 && (mul *= 0x100)) | |
val += this[offset + --i] * mul | |
mul *= 0x80 | |
if (val >= mul) | |
val -= Math.pow(2, 8 * byteLength) | |
return val | |
} | |
Buffer.prototype.readInt8 = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 1, this.length) | |
if (!(this[offset] & 0x80)) | |
return (this[offset]) | |
return ((0xff - this[offset] + 1) * -1) | |
} | |
Buffer.prototype.readInt16LE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 2, this.length) | |
var val = this[offset] | (this[offset + 1] << 8) | |
return (val & 0x8000) ? val | 0xFFFF0000 : val | |
} | |
Buffer.prototype.readInt16BE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 2, this.length) | |
var val = this[offset + 1] | (this[offset] << 8) | |
return (val & 0x8000) ? val | 0xFFFF0000 : val | |
} | |
Buffer.prototype.readInt32LE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return (this[offset]) | | |
(this[offset + 1] << 8) | | |
(this[offset + 2] << 16) | | |
(this[offset + 3] << 24) | |
} | |
Buffer.prototype.readInt32BE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return (this[offset] << 24) | | |
(this[offset + 1] << 16) | | |
(this[offset + 2] << 8) | | |
(this[offset + 3]) | |
} | |
Buffer.prototype.readFloatLE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, true, 23, 4) | |
} | |
Buffer.prototype.readFloatBE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 4, this.length) | |
return ieee754.read(this, offset, false, 23, 4) | |
} | |
Buffer.prototype.readDoubleLE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 8, this.length) | |
return ieee754.read(this, offset, true, 52, 8) | |
} | |
Buffer.prototype.readDoubleBE = function (offset, noAssert) { | |
if (!noAssert) | |
checkOffset(offset, 8, this.length) | |
return ieee754.read(this, offset, false, 52, 8) | |
} | |
function checkInt (buf, value, offset, ext, max, min) { | |
if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') | |
if (value > max || value < min) throw new RangeError('value is out of bounds') | |
if (offset + ext > buf.length) throw new RangeError('index out of range') | |
} | |
Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) | |
var mul = 1 | |
var i = 0 | |
this[offset] = value & 0xFF | |
while (++i < byteLength && (mul *= 0x100)) | |
this[offset + i] = (value / mul) >>> 0 & 0xFF | |
return offset + byteLength | |
} | |
Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
byteLength = byteLength >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) | |
var i = byteLength - 1 | |
var mul = 1 | |
this[offset + i] = value & 0xFF | |
while (--i >= 0 && (mul *= 0x100)) | |
this[offset + i] = (value / mul) >>> 0 & 0xFF | |
return offset + byteLength | |
} | |
Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 1, 0xff, 0) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
this[offset] = value | |
return offset + 1 | |
} | |
function objectWriteUInt16 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { | |
buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> | |
(littleEndian ? i : 1 - i) * 8 | |
} | |
} | |
Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = value | |
this[offset + 1] = (value >>> 8) | |
} else objectWriteUInt16(this, value, offset, true) | |
return offset + 2 | |
} | |
Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 2, 0xffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = value | |
} else objectWriteUInt16(this, value, offset, false) | |
return offset + 2 | |
} | |
function objectWriteUInt32 (buf, value, offset, littleEndian) { | |
if (value < 0) value = 0xffffffff + value + 1 | |
for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { | |
buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff | |
} | |
} | |
Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset + 3] = (value >>> 24) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 1] = (value >>> 8) | |
this[offset] = value | |
} else objectWriteUInt32(this, value, offset, true) | |
return offset + 4 | |
} | |
Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 4, 0xffffffff, 0) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = value | |
} else objectWriteUInt32(this, value, offset, false) | |
return offset + 4 | |
} | |
Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) { | |
checkInt(this, | |
value, | |
offset, | |
byteLength, | |
Math.pow(2, 8 * byteLength - 1) - 1, | |
-Math.pow(2, 8 * byteLength - 1)) | |
} | |
var i = 0 | |
var mul = 1 | |
var sub = value < 0 ? 1 : 0 | |
this[offset] = value & 0xFF | |
while (++i < byteLength && (mul *= 0x100)) | |
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF | |
return offset + byteLength | |
} | |
Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) { | |
checkInt(this, | |
value, | |
offset, | |
byteLength, | |
Math.pow(2, 8 * byteLength - 1) - 1, | |
-Math.pow(2, 8 * byteLength - 1)) | |
} | |
var i = byteLength - 1 | |
var mul = 1 | |
var sub = value < 0 ? 1 : 0 | |
this[offset + i] = value & 0xFF | |
while (--i >= 0 && (mul *= 0x100)) | |
this[offset + i] = ((value / mul) >> 0) - sub & 0xFF | |
return offset + byteLength | |
} | |
Buffer.prototype.writeInt8 = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 1, 0x7f, -0x80) | |
if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) | |
if (value < 0) value = 0xff + value + 1 | |
this[offset] = value | |
return offset + 1 | |
} | |
Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 2, 0x7fff, -0x8000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = value | |
this[offset + 1] = (value >>> 8) | |
} else objectWriteUInt16(this, value, offset, true) | |
return offset + 2 | |
} | |
Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 2, 0x7fff, -0x8000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 8) | |
this[offset + 1] = value | |
} else objectWriteUInt16(this, value, offset, false) | |
return offset + 2 | |
} | |
Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = value | |
this[offset + 1] = (value >>> 8) | |
this[offset + 2] = (value >>> 16) | |
this[offset + 3] = (value >>> 24) | |
} else objectWriteUInt32(this, value, offset, true) | |
return offset + 4 | |
} | |
Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { | |
value = +value | |
offset = offset >>> 0 | |
if (!noAssert) | |
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) | |
if (value < 0) value = 0xffffffff + value + 1 | |
if (Buffer.TYPED_ARRAY_SUPPORT) { | |
this[offset] = (value >>> 24) | |
this[offset + 1] = (value >>> 16) | |
this[offset + 2] = (value >>> 8) | |
this[offset + 3] = value | |
} else objectWriteUInt32(this, value, offset, false) | |
return offset + 4 | |
} | |
function checkIEEE754 (buf, value, offset, ext, max, min) { | |
if (value > max || value < min) throw new RangeError('value is out of bounds') | |
if (offset + ext > buf.length) throw new RangeError('index out of range') | |
if (offset < 0) throw new RangeError('index out of range') | |
} | |
function writeFloat (buf, value, offset, littleEndian, noAssert) { | |
if (!noAssert) | |
checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) | |
ieee754.write(buf, value, offset, littleEndian, 23, 4) | |
return offset + 4 | |
} | |
Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { | |
return writeFloat(this, value, offset, true, noAssert) | |
} | |
Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { | |
return writeFloat(this, value, offset, false, noAssert) | |
} | |
function writeDouble (buf, value, offset, littleEndian, noAssert) { | |
if (!noAssert) | |
checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) | |
ieee754.write(buf, value, offset, littleEndian, 52, 8) | |
return offset + 8 | |
} | |
Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { | |
return writeDouble(this, value, offset, true, noAssert) | |
} | |
Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { | |
return writeDouble(this, value, offset, false, noAssert) | |
} | |
// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) | |
Buffer.prototype.copy = function (target, target_start, start, end) { | |
var source = this | |
if (!start) start = 0 | |
if (!end && end !== 0) end = this.length | |
if (target_start >= target.length) target_start = target.length | |
if (!target_start) target_start = 0 | |
if (end > 0 && end < start) end = start | |
// Copy 0 bytes; we're done | |
if (end === start) return 0 | |
if (target.length === 0 || source.length === 0) return 0 | |
// Fatal error conditions | |
if (target_start < 0) | |
throw new RangeError('targetStart out of bounds') | |
if (start < 0 || start >= source.length) throw new RangeError('sourceStart out of bounds') | |
if (end < 0) throw new RangeError('sourceEnd out of bounds') | |
// Are we oob? | |
if (end > this.length) | |
end = this.length | |
if (target.length - target_start < end - start) | |
end = target.length - target_start + start | |
var len = end - start | |
if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { | |
for (var i = 0; i < len; i++) { | |
target[i + target_start] = this[i + start] | |
} | |
} else { | |
target._set(this.subarray(start, start + len), target_start) | |
} | |
return len | |
} | |
// 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 | |
if (end < start) throw new RangeError('end < start') | |
// Fill 0 bytes; we're done | |
if (end === start) return | |
if (this.length === 0) return | |
if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') | |
if (end < 0 || end > this.length) throw new RangeError('end out of bounds') | |
var i | |
if (typeof value === 'number') { | |
for (i = start; i < end; i++) { | |
this[i] = value | |
} | |
} else { | |
var bytes = utf8ToBytes(value.toString()) | |
var len = bytes.length | |
for (i = start; i < end; i++) { | |
this[i] = bytes[i % len] | |
} | |
} | |
return this | |
} | |
/** | |
* 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.TYPED_ARRAY_SUPPORT) { | |
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 TypeError('Buffer.toArrayBuffer not supported in this browser') | |
} | |
} | |
// HELPER FUNCTIONS | |
// ================ | |
var BP = Buffer.prototype | |
/** | |
* Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods | |
*/ | |
Buffer._augment = function (arr) { | |
arr.constructor = Buffer | |
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.equals = BP.equals | |
arr.compare = BP.compare | |
arr.copy = BP.copy | |
arr.slice = BP.slice | |
arr.readUIntLE = BP.readUIntLE | |
arr.readUIntBE = BP.readUIntBE | |
arr.readUInt8 = BP.readUInt8 | |
arr.readUInt16LE = BP.readUInt16LE | |
arr.readUInt16BE = BP.readUInt16BE | |
arr.readUInt32LE = BP.readUInt32LE | |
arr.readUInt32BE = BP.readUInt32BE | |
arr.readIntLE = BP.readIntLE | |
arr.readIntBE = BP.readIntBE | |
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.writeUIntLE = BP.writeUIntLE | |
arr.writeUIntBE = BP.writeUIntBE | |
arr.writeUInt16LE = BP.writeUInt16LE | |
arr.writeUInt16BE = BP.writeUInt16BE | |
arr.writeUInt32LE = BP.writeUInt32LE | |
arr.writeUInt32BE = BP.writeUInt32BE | |
arr.writeIntLE = BP.writeIntLE | |
arr.writeIntBE = BP.writeIntBE | |
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 | |
} | |
var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g | |
function base64clean (str) { | |
// Node strips out invalid characters like \n and \t from the string, base64-js does not | |
str = stringtrim(str).replace(INVALID_BASE64_RE, '') | |
// Node converts strings with length < 2 to '' | |
if (str.length < 2) return '' | |
// Node allows for non-padded base64 strings (missing trailing ===), base64-js does not | |
while (str.length % 4 !== 0) { | |
str = str + '=' | |
} | |
return str | |
} | |
function stringtrim (str) { | |
if (str.trim) return str.trim() | |
return str.replace(/^\s+|\s+$/g, '') | |
} | |
function isArrayish (subject) { | |
return isArray(subject) || Buffer.isBuffer(subject) || | |
subject && typeof subject === 'object' && | |
typeof subject.length === 'number' | |
} | |
function toHex (n) { | |
if (n < 16) return '0' + n.toString(16) | |
return n.toString(16) | |
} | |
function utf8ToBytes(string, units) { | |
var codePoint, length = string.length | |
var leadSurrogate = null | |
units = units || Infinity | |
var bytes = [] | |
var i = 0 | |
for (; i<length; i++) { | |
codePoint = string.charCodeAt(i) | |
// is surrogate component | |
if (codePoint > 0xD7FF && codePoint < 0xE000) { | |
// last char was a lead | |
if (leadSurrogate) { | |
// 2 leads in a row | |
if (codePoint < 0xDC00) { | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
leadSurrogate = codePoint | |
continue | |
} | |
// valid surrogate pair | |
else { | |
codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 | |
leadSurrogate = null | |
} | |
} | |
// no lead yet | |
else { | |
// unexpected trail | |
if (codePoint > 0xDBFF) { | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
continue | |
} | |
// unpaired lead | |
else if (i + 1 === length) { | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
continue | |
} | |
// valid lead | |
else { | |
leadSurrogate = codePoint | |
continue | |
} | |
} | |
} | |
// valid bmp char, but last char was a lead | |
else if (leadSurrogate) { | |
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) | |
leadSurrogate = null | |
} | |
// encode utf8 | |
if (codePoint < 0x80) { | |
if ((units -= 1) < 0) break | |
bytes.push(codePoint) | |
} | |
else if (codePoint < 0x800) { | |
if ((units -= 2) < 0) break | |
bytes.push( | |
codePoint >> 0x6 | 0xC0, | |
codePoint & 0x3F | 0x80 | |
); | |
} | |
else if (codePoint < 0x10000) { | |
if ((units -= 3) < 0) break | |
bytes.push( | |
codePoint >> 0xC | 0xE0, | |
codePoint >> 0x6 & 0x3F | 0x80, | |
codePoint & 0x3F | 0x80 | |
); | |
} | |
else if (codePoint < 0x200000) { | |
if ((units -= 4) < 0) break | |
bytes.push( | |
codePoint >> 0x12 | 0xF0, | |
codePoint >> 0xC & 0x3F | 0x80, | |
codePoint >> 0x6 & 0x3F | 0x80, | |
codePoint & 0x3F | 0x80 | |
); | |
} | |
else { | |
throw new Error('Invalid code point') | |
} | |
} | |
return bytes | |
} | |
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 utf16leToBytes (str, units) { | |
var c, hi, lo | |
var byteArray = [] | |
for (var i = 0; i < str.length; i++) { | |
if ((units -= 2) < 0) break | |
c = str.charCodeAt(i) | |
hi = c >> 8 | |
lo = c % 256 | |
byteArray.push(lo) | |
byteArray.push(hi) | |
} | |
return byteArray | |
} | |
function base64ToBytes (str) { | |
return base64.toByteArray(base64clean(str)) | |
} | |
function blitBuffer (src, dst, offset, length, unitSize) { | |
if (unitSize) length -= length % unitSize; | |
for (var i = 0; i < length; i++) { | |
if ((i + offset >= dst.length) || (i >= src.length)) | |
break | |
dst[i + offset] = src[i] | |
} | |
return i | |
} | |
function decodeUtf8Char (str) { | |
try { | |
return decodeURIComponent(str) | |
} catch (err) { | |
return String.fromCharCode(0xFFFD) // UTF 8 invalid char | |
} | |
} | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/browserify/node_modules/buffer/index.js","/node_modules/browserify/node_modules/buffer") | |
},{"_process":5,"base64-js":2,"buffer":1,"ieee754":3,"is-array":4}],2:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | |
;(function (exports) { | |
'use strict'; | |
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) | |
var PLUS_URL_SAFE = '-'.charCodeAt(0) | |
var SLASH_URL_SAFE = '_'.charCodeAt(0) | |
function decode (elt) { | |
var code = elt.charCodeAt(0) | |
if (code === PLUS || | |
code === PLUS_URL_SAFE) | |
return 62 // '+' | |
if (code === SLASH || | |
code === SLASH_URL_SAFE) | |
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 | |
if (b64.length % 4 > 0) { | |
throw new Error('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 | |
var len = b64.length | |
placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 | |
// base64 is 4/3 + up to two characters of the original data | |
arr = new Arr(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 | |
var L = 0 | |
function push (v) { | |
arr[L++] = v | |
} | |
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) | |
} | |
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) | |
} | |
return arr | |
} | |
function uint8ToBase64 (uint8) { | |
var i, | |
extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes | |
output = "", | |
temp, length | |
function encode (num) { | |
return lookup.charAt(num) | |
} | |
function tripletToBase64 (num) { | |
return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(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 += 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 | |
} | |
return output | |
} | |
exports.toByteArray = b64ToByteArray | |
exports.fromByteArray = uint8ToBase64 | |
}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/browserify/node_modules/buffer/node_modules/base64-js/lib/b64.js","/node_modules/browserify/node_modules/buffer/node_modules/base64-js/lib") | |
},{"_process":5,"buffer":1}],3:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
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]; | |
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); | |
}; | |
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; | |
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 { | |
value += rt * Math.pow(2, 1 - eBias); | |
} | |
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; | |
} | |
} | |
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); | |
buffer[offset + i - d] |= s * 128; | |
}; | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/browserify/node_modules/buffer/node_modules/ieee754/index.js","/node_modules/browserify/node_modules/buffer/node_modules/ieee754") | |
},{"_process":5,"buffer":1}],4:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
/** | |
* isArray | |
*/ | |
var isArray = Array.isArray; | |
/** | |
* toString | |
*/ | |
var str = Object.prototype.toString; | |
/** | |
* Whether or not the given `val` | |
* is an array. | |
* | |
* example: | |
* | |
* isArray([]); | |
* // > true | |
* isArray(arguments); | |
* // > false | |
* isArray(''); | |
* // > false | |
* | |
* @param {mixed} val | |
* @return {bool} | |
*/ | |
module.exports = isArray || function (val) { | |
return !! val && '[object Array]' == str.call(val); | |
}; | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/browserify/node_modules/buffer/node_modules/is-array/index.js","/node_modules/browserify/node_modules/buffer/node_modules/is-array") | |
},{"_process":5,"buffer":1}],5:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
// shim for using process in browser | |
var process = module.exports = {}; | |
process.nextTick = (function () { | |
var canSetImmediate = typeof window !== 'undefined' | |
&& window.setImmediate; | |
var canMutationObserver = typeof window !== 'undefined' | |
&& window.MutationObserver; | |
var canPost = typeof window !== 'undefined' | |
&& window.postMessage && window.addEventListener | |
; | |
if (canSetImmediate) { | |
return function (f) { return window.setImmediate(f) }; | |
} | |
var queue = []; | |
if (canMutationObserver) { | |
var hiddenDiv = document.createElement("div"); | |
var observer = new MutationObserver(function () { | |
var queueList = queue.slice(); | |
queue.length = 0; | |
queueList.forEach(function (fn) { | |
fn(); | |
}); | |
}); | |
observer.observe(hiddenDiv, { attributes: true }); | |
return function nextTick(fn) { | |
if (!queue.length) { | |
hiddenDiv.setAttribute('yes', 'no'); | |
} | |
queue.push(fn); | |
}; | |
} | |
if (canPost) { | |
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); | |
return function nextTick(fn) { | |
queue.push(fn); | |
window.postMessage('process-tick', '*'); | |
}; | |
} | |
return function nextTick(fn) { | |
setTimeout(fn, 0); | |
}; | |
})(); | |
process.title = 'browser'; | |
process.browser = true; | |
process.env = {}; | |
process.argv = []; | |
function noop() {} | |
process.on = noop; | |
process.addListener = noop; | |
process.once = noop; | |
process.off = noop; | |
process.removeListener = noop; | |
process.removeAllListeners = noop; | |
process.emit = noop; | |
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'); | |
}; | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/node_modules/browserify/node_modules/process/browser.js","/node_modules/browserify/node_modules/process") | |
},{"_process":5,"buffer":1}],6:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
/* Prototype JavaScript framework, version 1.7.2 | |
* (c) 2005-2010 Sam Stephenson | |
* | |
* Prototype is freely distributable under the terms of an MIT-style license. | |
* For details, see the Prototype web site: http://www.prototypejs.org/ | |
* | |
*--------------------------------------------------------------------------*/ | |
var Prototype = { | |
Version: '1.7.2', | |
Browser: (function(){ | |
var ua = navigator.userAgent; | |
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; | |
return { | |
IE: !!window.attachEvent && !isOpera, | |
Opera: isOpera, | |
WebKit: ua.indexOf('AppleWebKit/') > -1, | |
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, | |
MobileSafari: /Apple.*Mobile/.test(ua) | |
} | |
})(), | |
BrowserFeatures: { | |
XPath: !!document.evaluate, | |
SelectorsAPI: !!document.querySelector, | |
ElementExtensions: (function() { | |
var constructor = window.Element || window.HTMLElement; | |
return !!(constructor && constructor.prototype); | |
})(), | |
SpecificElementExtensions: (function() { | |
if (typeof window.HTMLDivElement !== 'undefined') | |
return true; | |
var div = document.createElement('div'), | |
form = document.createElement('form'), | |
isSupported = false; | |
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { | |
isSupported = true; | |
} | |
div = form = null; | |
return isSupported; | |
})() | |
}, | |
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script\\s*>', | |
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, | |
emptyFunction: function() { }, | |
K: function(x) { return x } | |
}; | |
if (Prototype.Browser.MobileSafari) | |
Prototype.BrowserFeatures.SpecificElementExtensions = false; | |
/* Based on Alex Arnell's inheritance implementation. */ | |
var Class = (function() { | |
var IS_DONTENUM_BUGGY = (function(){ | |
for (var p in { toString: 1 }) { | |
if (p === 'toString') return false; | |
} | |
return true; | |
})(); | |
function subclass() {}; | |
function create() { | |
var parent = null, properties = $A(arguments); | |
if (Object.isFunction(properties[0])) | |
parent = properties.shift(); | |
function klass() { | |
this.initialize.apply(this, arguments); | |
} | |
Object.extend(klass, Class.Methods); | |
klass.superclass = parent; | |
klass.subclasses = []; | |
if (parent) { | |
subclass.prototype = parent.prototype; | |
klass.prototype = new subclass; | |
parent.subclasses.push(klass); | |
} | |
for (var i = 0, length = properties.length; i < length; i++) | |
klass.addMethods(properties[i]); | |
if (!klass.prototype.initialize) | |
klass.prototype.initialize = Prototype.emptyFunction; | |
klass.prototype.constructor = klass; | |
return klass; | |
} | |
function addMethods(source) { | |
var ancestor = this.superclass && this.superclass.prototype, | |
properties = Object.keys(source); | |
if (IS_DONTENUM_BUGGY) { | |
if (source.toString != Object.prototype.toString) | |
properties.push("toString"); | |
if (source.valueOf != Object.prototype.valueOf) | |
properties.push("valueOf"); | |
} | |
for (var i = 0, length = properties.length; i < length; i++) { | |
var property = properties[i], value = source[property]; | |
if (ancestor && Object.isFunction(value) && | |
value.argumentNames()[0] == "$super") { | |
var method = value; | |
value = (function(m) { | |
return function() { return ancestor[m].apply(this, arguments); }; | |
})(property).wrap(method); | |
value.valueOf = (function(method) { | |
return function() { return method.valueOf.call(method); }; | |
})(method); | |
value.toString = (function(method) { | |
return function() { return method.toString.call(method); }; | |
})(method); | |
} | |
this.prototype[property] = value; | |
} | |
return this; | |
} | |
return { | |
create: create, | |
Methods: { | |
addMethods: addMethods | |
} | |
}; | |
})(); | |
(function() { | |
var _toString = Object.prototype.toString, | |
_hasOwnProperty = Object.prototype.hasOwnProperty, | |
NULL_TYPE = 'Null', | |
UNDEFINED_TYPE = 'Undefined', | |
BOOLEAN_TYPE = 'Boolean', | |
NUMBER_TYPE = 'Number', | |
STRING_TYPE = 'String', | |
OBJECT_TYPE = 'Object', | |
FUNCTION_CLASS = '[object Function]', | |
BOOLEAN_CLASS = '[object Boolean]', | |
NUMBER_CLASS = '[object Number]', | |
STRING_CLASS = '[object String]', | |
ARRAY_CLASS = '[object Array]', | |
DATE_CLASS = '[object Date]', | |
NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && | |
typeof JSON.stringify === 'function' && | |
JSON.stringify(0) === '0' && | |
typeof JSON.stringify(Prototype.K) === 'undefined'; | |
var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf', | |
'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor']; | |
var IS_DONTENUM_BUGGY = (function(){ | |
for (var p in { toString: 1 }) { | |
if (p === 'toString') return false; | |
} | |
return true; | |
})(); | |
function Type(o) { | |
switch(o) { | |
case null: return NULL_TYPE; | |
case (void 0): return UNDEFINED_TYPE; | |
} | |
var type = typeof o; | |
switch(type) { | |
case 'boolean': return BOOLEAN_TYPE; | |
case 'number': return NUMBER_TYPE; | |
case 'string': return STRING_TYPE; | |
} | |
return OBJECT_TYPE; | |
} | |
function extend(destination, source) { | |
for (var property in source) | |
destination[property] = source[property]; | |
return destination; | |
} | |
function inspect(object) { | |
try { | |
if (isUndefined(object)) return 'undefined'; | |
if (object === null) return 'null'; | |
return object.inspect ? object.inspect() : String(object); | |
} catch (e) { | |
if (e instanceof RangeError) return '...'; | |
throw e; | |
} | |
} | |
function toJSON(value) { | |
return Str('', { '': value }, []); | |
} | |
function Str(key, holder, stack) { | |
var value = holder[key]; | |
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { | |
value = value.toJSON(key); | |
} | |
var _class = _toString.call(value); | |
switch (_class) { | |
case NUMBER_CLASS: | |
case BOOLEAN_CLASS: | |
case STRING_CLASS: | |
value = value.valueOf(); | |
} | |
switch (value) { | |
case null: return 'null'; | |
case true: return 'true'; | |
case false: return 'false'; | |
} | |
var type = typeof value; | |
switch (type) { | |
case 'string': | |
return value.inspect(true); | |
case 'number': | |
return isFinite(value) ? String(value) : 'null'; | |
case 'object': | |
for (var i = 0, length = stack.length; i < length; i++) { | |
if (stack[i] === value) { | |
throw new TypeError("Cyclic reference to '" + value + "' in object"); | |
} | |
} | |
stack.push(value); | |
var partial = []; | |
if (_class === ARRAY_CLASS) { | |
for (var i = 0, length = value.length; i < length; i++) { | |
var str = Str(i, value, stack); | |
partial.push(typeof str === 'undefined' ? 'null' : str); | |
} | |
partial = '[' + partial.join(',') + ']'; | |
} else { | |
var keys = Object.keys(value); | |
for (var i = 0, length = keys.length; i < length; i++) { | |
var key = keys[i], str = Str(key, value, stack); | |
if (typeof str !== "undefined") { | |
partial.push(key.inspect(true)+ ':' + str); | |
} | |
} | |
partial = '{' + partial.join(',') + '}'; | |
} | |
stack.pop(); | |
return partial; | |
} | |
} | |
function stringify(object) { | |
return JSON.stringify(object); | |
} | |
function toQueryString(object) { | |
return $H(object).toQueryString(); | |
} | |
function toHTML(object) { | |
return object && object.toHTML ? object.toHTML() : String.interpret(object); | |
} | |
function keys(object) { | |
if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } | |
var results = []; | |
for (var property in object) { | |
if (_hasOwnProperty.call(object, property)) | |
results.push(property); | |
} | |
if (IS_DONTENUM_BUGGY) { | |
for (var i = 0; property = DONT_ENUMS[i]; i++) { | |
if (_hasOwnProperty.call(object, property)) | |
results.push(property); | |
} | |
} | |
return results; | |
} | |
function values(object) { | |
var results = []; | |
for (var property in object) | |
results.push(object[property]); | |
return results; | |
} | |
function clone(object) { | |
return extend({ }, object); | |
} | |
function isElement(object) { | |
return !!(object && object.nodeType == 1); | |
} | |
function isArray(object) { | |
return _toString.call(object) === ARRAY_CLASS; | |
} | |
var hasNativeIsArray = (typeof Array.isArray == 'function') | |
&& Array.isArray([]) && !Array.isArray({}); | |
if (hasNativeIsArray) { | |
isArray = Array.isArray; | |
} | |
function isHash(object) { | |
return object instanceof Hash; | |
} | |
function isFunction(object) { | |
return _toString.call(object) === FUNCTION_CLASS; | |
} | |
function isString(object) { | |
return _toString.call(object) === STRING_CLASS; | |
} | |
function isNumber(object) { | |
return _toString.call(object) === NUMBER_CLASS; | |
} | |
function isDate(object) { | |
return _toString.call(object) === DATE_CLASS; | |
} | |
function isUndefined(object) { | |
return typeof object === "undefined"; | |
} | |
extend(Object, { | |
extend: extend, | |
inspect: inspect, | |
toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, | |
toQueryString: toQueryString, | |
toHTML: toHTML, | |
keys: Object.keys || keys, | |
values: values, | |
clone: clone, | |
isElement: isElement, | |
isArray: isArray, | |
isHash: isHash, | |
isFunction: isFunction, | |
isString: isString, | |
isNumber: isNumber, | |
isDate: isDate, | |
isUndefined: isUndefined | |
}); | |
})(); | |
Object.extend(Function.prototype, (function() { | |
var slice = Array.prototype.slice; | |
function update(array, args) { | |
var arrayLength = array.length, length = args.length; | |
while (length--) array[arrayLength + length] = args[length]; | |
return array; | |
} | |
function merge(array, args) { | |
array = slice.call(array, 0); | |
return update(array, args); | |
} | |
function argumentNames() { | |
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] | |
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') | |
.replace(/\s+/g, '').split(','); | |
return names.length == 1 && !names[0] ? [] : names; | |
} | |
function bind(context) { | |
if (arguments.length < 2 && Object.isUndefined(arguments[0])) | |
return this; | |
if (!Object.isFunction(this)) | |
throw new TypeError("The object is not callable."); | |
var nop = function() {}; | |
var __method = this, args = slice.call(arguments, 1); | |
var bound = function() { | |
var a = merge(args, arguments); | |
var c = this instanceof bound ? this : context; | |
return __method.apply(c, a); | |
}; | |
nop.prototype = this.prototype; | |
bound.prototype = new nop(); | |
return bound; | |
} | |
function bindAsEventListener(context) { | |
var __method = this, args = slice.call(arguments, 1); | |
return function(event) { | |
var a = update([event || window.event], args); | |
return __method.apply(context, a); | |
} | |
} | |
function curry() { | |
if (!arguments.length) return this; | |
var __method = this, args = slice.call(arguments, 0); | |
return function() { | |
var a = merge(args, arguments); | |
return __method.apply(this, a); | |
} | |
} | |
function delay(timeout) { | |
var __method = this, args = slice.call(arguments, 1); | |
timeout = timeout * 1000; | |
return window.setTimeout(function() { | |
return __method.apply(__method, args); | |
}, timeout); | |
} | |
function defer() { | |
var args = update([0.01], arguments); | |
return this.delay.apply(this, args); | |
} | |
function wrap(wrapper) { | |
var __method = this; | |
return function() { | |
var a = update([__method.bind(this)], arguments); | |
return wrapper.apply(this, a); | |
} | |
} | |
function methodize() { | |
if (this._methodized) return this._methodized; | |
var __method = this; | |
return this._methodized = function() { | |
var a = update([this], arguments); | |
return __method.apply(null, a); | |
}; | |
} | |
var extensions = { | |
argumentNames: argumentNames, | |
bindAsEventListener: bindAsEventListener, | |
curry: curry, | |
delay: delay, | |
defer: defer, | |
wrap: wrap, | |
methodize: methodize | |
}; | |
if (!Function.prototype.bind) | |
extensions.bind = bind; | |
return extensions; | |
})()); | |
(function(proto) { | |
function toISOString() { | |
return this.getUTCFullYear() + '-' + | |
(this.getUTCMonth() + 1).toPaddedString(2) + '-' + | |
this.getUTCDate().toPaddedString(2) + 'T' + | |
this.getUTCHours().toPaddedString(2) + ':' + | |
this.getUTCMinutes().toPaddedString(2) + ':' + | |
this.getUTCSeconds().toPaddedString(2) + 'Z'; | |
} | |
function toJSON() { | |
return this.toISOString(); | |
} | |
if (!proto.toISOString) proto.toISOString = toISOString; | |
if (!proto.toJSON) proto.toJSON = toJSON; | |
})(Date.prototype); | |
RegExp.prototype.match = RegExp.prototype.test; | |
RegExp.escape = function(str) { | |
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | |
}; | |
var PeriodicalExecuter = Class.create({ | |
initialize: function(callback, frequency) { | |
this.callback = callback; | |
this.frequency = frequency; | |
this.currentlyExecuting = false; | |
this.registerCallback(); | |
}, | |
registerCallback: function() { | |
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); | |
}, | |
execute: function() { | |
this.callback(this); | |
}, | |
stop: function() { | |
if (!this.timer) return; | |
clearInterval(this.timer); | |
this.timer = null; | |
}, | |
onTimerEvent: function() { | |
if (!this.currentlyExecuting) { | |
try { | |
this.currentlyExecuting = true; | |
this.execute(); | |
this.currentlyExecuting = false; | |
} catch(e) { | |
this.currentlyExecuting = false; | |
throw e; | |
} | |
} | |
} | |
}); | |
Object.extend(String, { | |
interpret: function(value) { | |
return value == null ? '' : String(value); | |
}, | |
specialChar: { | |
'\b': '\\b', | |
'\t': '\\t', | |
'\n': '\\n', | |
'\f': '\\f', | |
'\r': '\\r', | |
'\\': '\\\\' | |
} | |
}); | |
Object.extend(String.prototype, (function() { | |
var NATIVE_JSON_PARSE_SUPPORT = window.JSON && | |
typeof JSON.parse === 'function' && | |
JSON.parse('{"test": true}').test; | |
function prepareReplacement(replacement) { | |
if (Object.isFunction(replacement)) return replacement; | |
var template = new Template(replacement); | |
return function(match) { return template.evaluate(match) }; | |
} | |
function isNonEmptyRegExp(regexp) { | |
return regexp.source && regexp.source !== '(?:)'; | |
} | |
function gsub(pattern, replacement) { | |
var result = '', source = this, match; | |
replacement = prepareReplacement(replacement); | |
if (Object.isString(pattern)) | |
pattern = RegExp.escape(pattern); | |
if (!(pattern.length || isNonEmptyRegExp(pattern))) { | |
replacement = replacement(''); | |
return replacement + source.split('').join(replacement) + replacement; | |
} | |
while (source.length > 0) { | |
match = source.match(pattern) | |
if (match && match[0].length > 0) { | |
result += source.slice(0, match.index); | |
result += String.interpret(replacement(match)); | |
source = source.slice(match.index + match[0].length); | |
} else { | |
result += source, source = ''; | |
} | |
} | |
return result; | |
} | |
function sub(pattern, replacement, count) { | |
replacement = prepareReplacement(replacement); | |
count = Object.isUndefined(count) ? 1 : count; | |
return this.gsub(pattern, function(match) { | |
if (--count < 0) return match[0]; | |
return replacement(match); | |
}); | |
} | |
function scan(pattern, iterator) { | |
this.gsub(pattern, iterator); | |
return String(this); | |
} | |
function truncate(length, truncation) { | |
length = length || 30; | |
truncation = Object.isUndefined(truncation) ? '...' : truncation; | |
return this.length > length ? | |
this.slice(0, length - truncation.length) + truncation : String(this); | |
} | |
function strip() { | |
return this.replace(/^\s+/, '').replace(/\s+$/, ''); | |
} | |
function stripTags() { | |
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); | |
} | |
function stripScripts() { | |
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); | |
} | |
function extractScripts() { | |
var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), | |
matchOne = new RegExp(Prototype.ScriptFragment, 'im'); | |
return (this.match(matchAll) || []).map(function(scriptTag) { | |
return (scriptTag.match(matchOne) || ['', ''])[1]; | |
}); | |
} | |
function evalScripts() { | |
return this.extractScripts().map(function(script) { return eval(script); }); | |
} | |
function escapeHTML() { | |
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | |
} | |
function unescapeHTML() { | |
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); | |
} | |
function toQueryParams(separator) { | |
var match = this.strip().match(/([^?#]*)(#.*)?$/); | |
if (!match) return { }; | |
return match[1].split(separator || '&').inject({ }, function(hash, pair) { | |
if ((pair = pair.split('='))[0]) { | |
var key = decodeURIComponent(pair.shift()), | |
value = pair.length > 1 ? pair.join('=') : pair[0]; | |
if (value != undefined) { | |
value = value.gsub('+', ' '); | |
value = decodeURIComponent(value); | |
} | |
if (key in hash) { | |
if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; | |
hash[key].push(value); | |
} | |
else hash[key] = value; | |
} | |
return hash; | |
}); | |
} | |
function toArray() { | |
return this.split(''); | |
} | |
function succ() { | |
return this.slice(0, this.length - 1) + | |
String.fromCharCode(this.charCodeAt(this.length - 1) + 1); | |
} | |
function times(count) { | |
return count < 1 ? '' : new Array(count + 1).join(this); | |
} | |
function camelize() { | |
return this.replace(/-+(.)?/g, function(match, chr) { | |
return chr ? chr.toUpperCase() : ''; | |
}); | |
} | |
function capitalize() { | |
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); | |
} | |
function underscore() { | |
return this.replace(/::/g, '/') | |
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') | |
.replace(/([a-z\d])([A-Z])/g, '$1_$2') | |
.replace(/-/g, '_') | |
.toLowerCase(); | |
} | |
function dasherize() { | |
return this.replace(/_/g, '-'); | |
} | |
function inspect(useDoubleQuotes) { | |
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { | |
if (character in String.specialChar) { | |
return String.specialChar[character]; | |
} | |
return '\\u00' + character.charCodeAt().toPaddedString(2, 16); | |
}); | |
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; | |
return "'" + escapedString.replace(/'/g, '\\\'') + "'"; | |
} | |
function unfilterJSON(filter) { | |
return this.replace(filter || Prototype.JSONFilter, '$1'); | |
} | |
function isJSON() { | |
var str = this; | |
if (str.blank()) return false; | |
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); | |
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); | |
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); | |
return (/^[\],:{}\s]*$/).test(str); | |
} | |
function evalJSON(sanitize) { | |
var json = this.unfilterJSON(), | |
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; | |
if (cx.test(json)) { | |
json = json.replace(cx, function (a) { | |
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | |
}); | |
} | |
try { | |
if (!sanitize || json.isJSON()) return eval('(' + json + ')'); | |
} catch (e) { } | |
throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); | |
} | |
function parseJSON() { | |
var json = this.unfilterJSON(); | |
return JSON.parse(json); | |
} | |
function include(pattern) { | |
return this.indexOf(pattern) > -1; | |
} | |
function startsWith(pattern, position) { | |
position = Object.isNumber(position) ? position : 0; | |
return this.lastIndexOf(pattern, position) === position; | |
} | |
function endsWith(pattern, position) { | |
pattern = String(pattern); | |
position = Object.isNumber(position) ? position : this.length; | |
if (position < 0) position = 0; | |
if (position > this.length) position = this.length; | |
var d = position - pattern.length; | |
return d >= 0 && this.indexOf(pattern, d) === d; | |
} | |
function empty() { | |
return this == ''; | |
} | |
function blank() { | |
return /^\s*$/.test(this); | |
} | |
function interpolate(object, pattern) { | |
return new Template(this, pattern).evaluate(object); | |
} | |
return { | |
gsub: gsub, | |
sub: sub, | |
scan: scan, | |
truncate: truncate, | |
strip: String.prototype.trim || strip, | |
stripTags: stripTags, | |
stripScripts: stripScripts, | |
extractScripts: extractScripts, | |
evalScripts: evalScripts, | |
escapeHTML: escapeHTML, | |
unescapeHTML: unescapeHTML, | |
toQueryParams: toQueryParams, | |
parseQuery: toQueryParams, | |
toArray: toArray, | |
succ: succ, | |
times: times, | |
camelize: camelize, | |
capitalize: capitalize, | |
underscore: underscore, | |
dasherize: dasherize, | |
inspect: inspect, | |
unfilterJSON: unfilterJSON, | |
isJSON: isJSON, | |
evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, | |
include: include, | |
startsWith: String.prototype.startsWith || startsWith, | |
endsWith: String.prototype.endsWith || endsWith, | |
empty: empty, | |
blank: blank, | |
interpolate: interpolate | |
}; | |
})()); | |
var Template = Class.create({ | |
initialize: function(template, pattern) { | |
this.template = template.toString(); | |
this.pattern = pattern || Template.Pattern; | |
}, | |
evaluate: function(object) { | |
if (object && Object.isFunction(object.toTemplateReplacements)) | |
object = object.toTemplateReplacements(); | |
return this.template.gsub(this.pattern, function(match) { | |
if (object == null) return (match[1] + ''); | |
var before = match[1] || ''; | |
if (before == '\\') return match[2]; | |
var ctx = object, expr = match[3], | |
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; | |
match = pattern.exec(expr); | |
if (match == null) return before; | |
while (match != null) { | |
var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; | |
ctx = ctx[comp]; | |
if (null == ctx || '' == match[3]) break; | |
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); | |
match = pattern.exec(expr); | |
} | |
return before + String.interpret(ctx); | |
}); | |
} | |
}); | |
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; | |
var $break = { }; | |
var Enumerable = (function() { | |
function each(iterator, context) { | |
try { | |
this._each(iterator, context); | |
} catch (e) { | |
if (e != $break) throw e; | |
} | |
return this; | |
} | |
function eachSlice(number, iterator, context) { | |
var index = -number, slices = [], array = this.toArray(); | |
if (number < 1) return array; | |
while ((index += number) < array.length) | |
slices.push(array.slice(index, index+number)); | |
return slices.collect(iterator, context); | |
} | |
function all(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result = true; | |
this.each(function(value, index) { | |
result = result && !!iterator.call(context, value, index, this); | |
if (!result) throw $break; | |
}, this); | |
return result; | |
} | |
function any(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result = false; | |
this.each(function(value, index) { | |
if (result = !!iterator.call(context, value, index, this)) | |
throw $break; | |
}, this); | |
return result; | |
} | |
function collect(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var results = []; | |
this.each(function(value, index) { | |
results.push(iterator.call(context, value, index, this)); | |
}, this); | |
return results; | |
} | |
function detect(iterator, context) { | |
var result; | |
this.each(function(value, index) { | |
if (iterator.call(context, value, index, this)) { | |
result = value; | |
throw $break; | |
} | |
}, this); | |
return result; | |
} | |
function findAll(iterator, context) { | |
var results = []; | |
this.each(function(value, index) { | |
if (iterator.call(context, value, index, this)) | |
results.push(value); | |
}, this); | |
return results; | |
} | |
function grep(filter, iterator, context) { | |
iterator = iterator || Prototype.K; | |
var results = []; | |
if (Object.isString(filter)) | |
filter = new RegExp(RegExp.escape(filter)); | |
this.each(function(value, index) { | |
if (filter.match(value)) | |
results.push(iterator.call(context, value, index, this)); | |
}, this); | |
return results; | |
} | |
function include(object) { | |
if (Object.isFunction(this.indexOf) && this.indexOf(object) != -1) | |
return true; | |
var found = false; | |
this.each(function(value) { | |
if (value == object) { | |
found = true; | |
throw $break; | |
} | |
}); | |
return found; | |
} | |
function inGroupsOf(number, fillWith) { | |
fillWith = Object.isUndefined(fillWith) ? null : fillWith; | |
return this.eachSlice(number, function(slice) { | |
while(slice.length < number) slice.push(fillWith); | |
return slice; | |
}); | |
} | |
function inject(memo, iterator, context) { | |
this.each(function(value, index) { | |
memo = iterator.call(context, memo, value, index, this); | |
}, this); | |
return memo; | |
} | |
function invoke(method) { | |
var args = $A(arguments).slice(1); | |
return this.map(function(value) { | |
return value[method].apply(value, args); | |
}); | |
} | |
function max(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result; | |
this.each(function(value, index) { | |
value = iterator.call(context, value, index, this); | |
if (result == null || value >= result) | |
result = value; | |
}, this); | |
return result; | |
} | |
function min(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var result; | |
this.each(function(value, index) { | |
value = iterator.call(context, value, index, this); | |
if (result == null || value < result) | |
result = value; | |
}, this); | |
return result; | |
} | |
function partition(iterator, context) { | |
iterator = iterator || Prototype.K; | |
var trues = [], falses = []; | |
this.each(function(value, index) { | |
(iterator.call(context, value, index, this) ? | |
trues : falses).push(value); | |
}, this); | |
return [trues, falses]; | |
} | |
function pluck(property) { | |
var results = []; | |
this.each(function(value) { | |
results.push(value[property]); | |
}); | |
return results; | |
} | |
function reject(iterator, context) { | |
var results = []; | |
this.each(function(value, index) { | |
if (!iterator.call(context, value, index, this)) | |
results.push(value); | |
}, this); | |
return results; | |
} | |
function sortBy(iterator, context) { | |
return this.map(function(value, index) { | |
return { | |
value: value, | |
criteria: iterator.call(context, value, index, this) | |
}; | |
}, this).sort(function(left, right) { | |
var a = left.criteria, b = right.criteria; | |
return a < b ? -1 : a > b ? 1 : 0; | |
}).pluck('value'); | |
} | |
function toArray() { | |
return this.map(); | |
} | |
function zip() { | |
var iterator = Prototype.K, args = $A(arguments); | |
if (Object.isFunction(args.last())) | |
iterator = args.pop(); | |
var collections = [this].concat(args).map($A); | |
return this.map(function(value, index) { | |
return iterator(collections.pluck(index)); | |
}); | |
} | |
function size() { | |
return this.toArray().length; | |
} | |
function inspect() { | |
return '#<Enumerable:' + this.toArray().inspect() + '>'; | |
} | |
return { | |
each: each, | |
eachSlice: eachSlice, | |
all: all, | |
every: all, | |
any: any, | |
some: any, | |
collect: collect, | |
map: collect, | |
detect: detect, | |
findAll: findAll, | |
select: findAll, | |
filter: findAll, | |
grep: grep, | |
include: include, | |
member: include, | |
inGroupsOf: inGroupsOf, | |
inject: inject, | |
invoke: invoke, | |
max: max, | |
min: min, | |
partition: partition, | |
pluck: pluck, | |
reject: reject, | |
sortBy: sortBy, | |
toArray: toArray, | |
entries: toArray, | |
zip: zip, | |
size: size, | |
inspect: inspect, | |
find: detect | |
}; | |
})(); | |
function $A(iterable) { | |
if (!iterable) return []; | |
if ('toArray' in Object(iterable)) return iterable.toArray(); | |
var length = iterable.length || 0, results = new Array(length); | |
while (length--) results[length] = iterable[length]; | |
return results; | |
} | |
function $w(string) { | |
if (!Object.isString(string)) return []; | |
string = string.strip(); | |
return string ? string.split(/\s+/) : []; | |
} | |
Array.from = $A; | |
(function() { | |
var arrayProto = Array.prototype, | |
slice = arrayProto.slice, | |
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available | |
function each(iterator, context) { | |
for (var i = 0, length = this.length >>> 0; i < length; i++) { | |
if (i in this) iterator.call(context, this[i], i, this); | |
} | |
} | |
if (!_each) _each = each; | |
function clear() { | |
this.length = 0; | |
return this; | |
} | |
function first() { | |
return this[0]; | |
} | |
function last() { | |
return this[this.length - 1]; | |
} | |
function compact() { | |
return this.select(function(value) { | |
return value != null; | |
}); | |
} | |
function flatten() { | |
return this.inject([], function(array, value) { | |
if (Object.isArray(value)) | |
return array.concat(value.flatten()); | |
array.push(value); | |
return array; | |
}); | |
} | |
function without() { | |
var values = slice.call(arguments, 0); | |
return this.select(function(value) { | |
return !values.include(value); | |
}); | |
} | |
function reverse(inline) { | |
return (inline === false ? this.toArray() : this)._reverse(); | |
} | |
function uniq(sorted) { | |
return this.inject([], function(array, value, index) { | |
if (0 == index || (sorted ? array.last() != value : !array.include(value))) | |
array.push(value); | |
return array; | |
}); | |
} | |
function intersect(array) { | |
return this.uniq().findAll(function(item) { | |
return array.indexOf(item) !== -1; | |
}); | |
} | |
function clone() { | |
return slice.call(this, 0); | |
} | |
function size() { | |
return this.length; | |
} | |
function inspect() { | |
return '[' + this.map(Object.inspect).join(', ') + ']'; | |
} | |
function indexOf(item, i) { | |
if (this == null) throw new TypeError(); | |
var array = Object(this), length = array.length >>> 0; | |
if (length === 0) return -1; | |
i = Number(i); | |
if (isNaN(i)) { | |
i = 0; | |
} else if (i !== 0 && isFinite(i)) { | |
i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); | |
} | |
if (i > length) return -1; | |
var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0); | |
for (; k < length; k++) | |
if (k in array && array[k] === item) return k; | |
return -1; | |
} | |
function lastIndexOf(item, i) { | |
if (this == null) throw new TypeError(); | |
var array = Object(this), length = array.length >>> 0; | |
if (length === 0) return -1; | |
if (!Object.isUndefined(i)) { | |
i = Number(i); | |
if (isNaN(i)) { | |
i = 0; | |
} else if (i !== 0 && isFinite(i)) { | |
i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i)); | |
} | |
} else { | |
i = length; | |
} | |
var k = i >= 0 ? Math.min(i, length - 1) : | |
length - Math.abs(i); | |
for (; k >= 0; k--) | |
if (k in array && array[k] === item) return k; | |
return -1; | |
} | |
function concat(_) { | |
var array = [], items = slice.call(arguments, 0), item, n = 0; | |
items.unshift(this); | |
for (var i = 0, length = items.length; i < length; i++) { | |
item = items[i]; | |
if (Object.isArray(item) && !('callee' in item)) { | |
for (var j = 0, arrayLength = item.length; j < arrayLength; j++) { | |
if (j in item) array[n] = item[j]; | |
n++; | |
} | |
} else { | |
array[n++] = item; | |
} | |
} | |
array.length = n; | |
return array; | |
} | |
function wrapNative(method) { | |
return function() { | |
if (arguments.length === 0) { | |
return method.call(this, Prototype.K); | |
} else if (arguments[0] === undefined) { | |
var args = slice.call(arguments, 1); | |
args.unshift(Prototype.K); | |
return method.apply(this, args); | |
} else { | |
return method.apply(this, arguments); | |
} | |
}; | |
} | |
function map(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var object = Object(this); | |
var results = [], context = arguments[1], n = 0; | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object) { | |
results[n] = iterator.call(context, object[i], i, object); | |
} | |
n++; | |
} | |
results.length = n; | |
return results; | |
} | |
if (arrayProto.map) { | |
map = wrapNative(Array.prototype.map); | |
} | |
function filter(iterator) { | |
if (this == null || !Object.isFunction(iterator)) | |
throw new TypeError(); | |
var object = Object(this); | |
var results = [], context = arguments[1], value; | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object) { | |
value = object[i]; | |
if (iterator.call(context, value, i, object)) { | |
results.push(value); | |
} | |
} | |
} | |
return results; | |
} | |
if (arrayProto.filter) { | |
filter = Array.prototype.filter; | |
} | |
function some(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var context = arguments[1]; | |
var object = Object(this); | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object && iterator.call(context, object[i], i, object)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
if (arrayProto.some) { | |
var some = wrapNative(Array.prototype.some); | |
} | |
function every(iterator) { | |
if (this == null) throw new TypeError(); | |
iterator = iterator || Prototype.K; | |
var context = arguments[1]; | |
var object = Object(this); | |
for (var i = 0, length = object.length >>> 0; i < length; i++) { | |
if (i in object && !iterator.call(context, object[i], i, object)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
if (arrayProto.every) { | |
var every = wrapNative(Array.prototype.every); | |
} | |
var _reduce = arrayProto.reduce; | |
function inject(memo, iterator) { | |
iterator = iterator || Prototype.K; | |
var context = arguments[2]; | |
return _reduce.call(this, iterator.bind(context), memo); | |
} | |
if (!arrayProto.reduce) { | |
var inject = Enumerable.inject; | |
} | |
Object.extend(arrayProto, Enumerable); | |
if (!arrayProto._reverse) | |
arrayProto._reverse = arrayProto.reverse; | |
Object.extend(arrayProto, { | |
_each: _each, | |
map: map, | |
collect: map, | |
select: filter, | |
filter: filter, | |
findAll: filter, | |
some: some, | |
any: some, | |
every: every, | |
all: every, | |
inject: inject, | |
clear: clear, | |
first: first, | |
last: last, | |
compact: compact, | |
flatten: flatten, | |
without: without, | |
reverse: reverse, | |
uniq: uniq, | |
intersect: intersect, | |
clone: clone, | |
toArray: clone, | |
size: size, | |
inspect: inspect | |
}); | |
var CONCAT_ARGUMENTS_BUGGY = (function() { | |
return [].concat(arguments)[0][0] !== 1; | |
})(1,2); | |
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; | |
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; | |
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; | |
})(); | |
function $H(object) { | |
return new Hash(object); | |
}; | |
var Hash = Class.create(Enumerable, (function() { | |
function initialize(object) { | |
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); | |
} | |
function _each(iterator, context) { | |
var i = 0; | |
for (var key in this._object) { | |
var value = this._object[key], pair = [key, value]; | |
pair.key = key; | |
pair.value = value; | |
iterator.call(context, pair, i); | |
i++; | |
} | |
} | |
function set(key, value) { | |
return this._object[key] = value; | |
} | |
function get(key) { | |
if (this._object[key] !== Object.prototype[key]) | |
return this._object[key]; | |
} | |
function unset(key) { | |
var value = this._object[key]; | |
delete this._object[key]; | |
return value; | |
} | |
function toObject() { | |
return Object.clone(this._object); | |
} | |
function keys() { | |
return this.pluck('key'); | |
} | |
function values() { | |
return this.pluck('value'); | |
} | |
function index(value) { | |
var match = this.detect(function(pair) { | |
return pair.value === value; | |
}); | |
return match && match.key; | |
} | |
function merge(object) { | |
return this.clone().update(object); | |
} | |
function update(object) { | |
return new Hash(object).inject(this, function(result, pair) { | |
result.set(pair.key, pair.value); | |
return result; | |
}); | |
} | |
function toQueryPair(key, value) { | |
if (Object.isUndefined(value)) return key; | |
value = String.interpret(value); | |
value = value.gsub(/(\r)?\n/, '\r\n'); | |
value = encodeURIComponent(value); | |
value = value.gsub(/%20/, '+'); | |
return key + '=' + value; | |
} | |
function toQueryString() { | |
return this.inject([], function(results, pair) { | |
var key = encodeURIComponent(pair.key), values = pair.value; | |
if (values && typeof values == 'object') { | |
if (Object.isArray(values)) { | |
var queryValues = []; | |
for (var i = 0, len = values.length, value; i < len; i++) { | |
value = values[i]; | |
queryValues.push(toQueryPair(key, value)); | |
} | |
return results.concat(queryValues); | |
} | |
} else results.push(toQueryPair(key, values)); | |
return results; | |
}).join('&'); | |
} | |
function inspect() { | |
return '#<Hash:{' + this.map(function(pair) { | |
return pair.map(Object.inspect).join(': '); | |
}).join(', ') + '}>'; | |
} | |
function clone() { | |
return new Hash(this); | |
} | |
return { | |
initialize: initialize, | |
_each: _each, | |
set: set, | |
get: get, | |
unset: unset, | |
toObject: toObject, | |
toTemplateReplacements: toObject, | |
keys: keys, | |
values: values, | |
index: index, | |
merge: merge, | |
update: update, | |
toQueryString: toQueryString, | |
inspect: inspect, | |
toJSON: toObject, | |
clone: clone | |
}; | |
})()); | |
Hash.from = $H; | |
Object.extend(Number.prototype, (function() { | |
function toColorPart() { | |
return this.toPaddedString(2, 16); | |
} | |
function succ() { | |
return this + 1; | |
} | |
function times(iterator, context) { | |
$R(0, this, true).each(iterator, context); | |
return this; | |
} | |
function toPaddedString(length, radix) { | |
var string = this.toString(radix || 10); | |
return '0'.times(length - string.length) + string; | |
} | |
function abs() { | |
return Math.abs(this); | |
} | |
function round() { | |
return Math.round(this); | |
} | |
function ceil() { | |
return Math.ceil(this); | |
} | |
function floor() { | |
return Math.floor(this); | |
} | |
return { | |
toColorPart: toColorPart, | |
succ: succ, | |
times: times, | |
toPaddedString: toPaddedString, | |
abs: abs, | |
round: round, | |
ceil: ceil, | |
floor: floor | |
}; | |
})()); | |
function $R(start, end, exclusive) { | |
return new ObjectRange(start, end, exclusive); | |
} | |
var ObjectRange = Class.create(Enumerable, (function() { | |
function initialize(start, end, exclusive) { | |
this.start = start; | |
this.end = end; | |
this.exclusive = exclusive; | |
} | |
function _each(iterator, context) { | |
var value = this.start, i; | |
for (i = 0; this.include(value); i++) { | |
iterator.call(context, value, i); | |
value = value.succ(); | |
} | |
} | |
function include(value) { | |
if (value < this.start) | |
return false; | |
if (this.exclusive) | |
return value < this.end; | |
return value <= this.end; | |
} | |
return { | |
initialize: initialize, | |
_each: _each, | |
include: include | |
}; | |
})()); | |
var Abstract = { }; | |
var Try = { | |
these: function() { | |
var returnValue; | |
for (var i = 0, length = arguments.length; i < length; i++) { | |
var lambda = arguments[i]; | |
try { | |
returnValue = lambda(); | |
break; | |
} catch (e) { } | |
} | |
return returnValue; | |
} | |
}; | |
var Ajax = { | |
getTransport: function() { | |
return Try.these( | |
function() {return new XMLHttpRequest()}, | |
function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | |
function() {return new ActiveXObject('Microsoft.XMLHTTP')} | |
) || false; | |
}, | |
activeRequestCount: 0 | |
}; | |
Ajax.Responders = { | |
responders: [], | |
_each: function(iterator, context) { | |
this.responders._each(iterator, context); | |
}, | |
register: function(responder) { | |
if (!this.include(responder)) | |
this.responders.push(responder); | |
}, | |
unregister: function(responder) { | |
this.responders = this.responders.without(responder); | |
}, | |
dispatch: function(callback, request, transport, json) { | |
this.each(function(responder) { | |
if (Object.isFunction(responder[callback])) { | |
try { | |
responder[callback].apply(responder, [request, transport, json]); | |
} catch (e) { } | |
} | |
}); | |
} | |
}; | |
Object.extend(Ajax.Responders, Enumerable); | |
Ajax.Responders.register({ | |
onCreate: function() { Ajax.activeRequestCount++ }, | |
onComplete: function() { Ajax.activeRequestCount-- } | |
}); | |
Ajax.Base = Class.create({ | |
initialize: function(options) { | |
this.options = { | |
method: 'post', | |
asynchronous: true, | |
contentType: 'application/x-www-form-urlencoded', | |
encoding: 'UTF-8', | |
parameters: '', | |
evalJSON: true, | |
evalJS: true | |
}; | |
Object.extend(this.options, options || { }); | |
this.options.method = this.options.method.toLowerCase(); | |
if (Object.isHash(this.options.parameters)) | |
this.options.parameters = this.options.parameters.toObject(); | |
} | |
}); | |
Ajax.Request = Class.create(Ajax.Base, { | |
_complete: false, | |
initialize: function($super, url, options) { | |
$super(options); | |
this.transport = Ajax.getTransport(); | |
this.request(url); | |
}, | |
request: function(url) { | |
this.url = url; | |
this.method = this.options.method; | |
var params = Object.isString(this.options.parameters) ? | |
this.options.parameters : | |
Object.toQueryString(this.options.parameters); | |
if (!['get', 'post'].include(this.method)) { | |
params += (params ? '&' : '') + "_method=" + this.method; | |
this.method = 'post'; | |
} | |
if (params && this.method === 'get') { | |
this.url += (this.url.include('?') ? '&' : '?') + params; | |
} | |
this.parameters = params.toQueryParams(); | |
try { | |
var response = new Ajax.Response(this); | |
if (this.options.onCreate) this.options.onCreate(response); | |
Ajax.Responders.dispatch('onCreate', this, response); | |
this.transport.open(this.method.toUpperCase(), this.url, | |
this.options.asynchronous); | |
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); | |
this.transport.onreadystatechange = this.onStateChange.bind(this); | |
this.setRequestHeaders(); | |
this.body = this.method == 'post' ? (this.options.postBody || params) : null; | |
this.transport.send(this.body); | |
/* Force Firefox to handle ready state 4 for synchronous requests */ | |
if (!this.options.asynchronous && this.transport.overrideMimeType) | |
this.onStateChange(); | |
} | |
catch (e) { | |
this.dispatchException(e); | |
} | |
}, | |
onStateChange: function() { | |
var readyState = this.transport.readyState; | |
if (readyState > 1 && !((readyState == 4) && this._complete)) | |
this.respondToReadyState(this.transport.readyState); | |
}, | |
setRequestHeaders: function() { | |
var headers = { | |
'X-Requested-With': 'XMLHttpRequest', | |
'X-Prototype-Version': Prototype.Version, | |
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' | |
}; | |
if (this.method == 'post') { | |
headers['Content-type'] = this.options.contentType + | |
(this.options.encoding ? '; charset=' + this.options.encoding : ''); | |
/* Force "Connection: close" for older Mozilla browsers to work | |
* around a bug where XMLHttpRequest sends an incorrect | |
* Content-length header. See Mozilla Bugzilla #246651. | |
*/ | |
if (this.transport.overrideMimeType && | |
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) | |
headers['Connection'] = 'close'; | |
} | |
if (typeof this.options.requestHeaders == 'object') { | |
var extras = this.options.requestHeaders; | |
if (Object.isFunction(extras.push)) | |
for (var i = 0, length = extras.length; i < length; i += 2) | |
headers[extras[i]] = extras[i+1]; | |
else | |
$H(extras).each(function(pair) { headers[pair.key] = pair.value }); | |
} | |
for (var name in headers) | |
if (headers[name] != null) | |
this.transport.setRequestHeader(name, headers[name]); | |
}, | |
success: function() { | |
var status = this.getStatus(); | |
return !status || (status >= 200 && status < 300) || status == 304; | |
}, | |
getStatus: function() { | |
try { | |
if (this.transport.status === 1223) return 204; | |
return this.transport.status || 0; | |
} catch (e) { return 0 } | |
}, | |
respondToReadyState: function(readyState) { | |
var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); | |
if (state == 'Complete') { | |
try { | |
this._complete = true; | |
(this.options['on' + response.status] | |
|| this.options['on' + (this.success() ? 'Success' : 'Failure')] | |
|| Prototype.emptyFunction)(response, response.headerJSON); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
var contentType = response.getHeader('Content-type'); | |
if (this.options.evalJS == 'force' | |
|| (this.options.evalJS && this.isSameOrigin() && contentType | |
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) | |
this.evalResponse(); | |
} | |
try { | |
(this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); | |
Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
if (state == 'Complete') { | |
this.transport.onreadystatechange = Prototype.emptyFunction; | |
} | |
}, | |
isSameOrigin: function() { | |
var m = this.url.match(/^\s*https?:\/\/[^\/]*/); | |
return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ | |
protocol: location.protocol, | |
domain: document.domain, | |
port: location.port ? ':' + location.port : '' | |
})); | |
}, | |
getHeader: function(name) { | |
try { | |
return this.transport.getResponseHeader(name) || null; | |
} catch (e) { return null; } | |
}, | |
evalResponse: function() { | |
try { | |
return eval((this.transport.responseText || '').unfilterJSON()); | |
} catch (e) { | |
this.dispatchException(e); | |
} | |
}, | |
dispatchException: function(exception) { | |
(this.options.onException || Prototype.emptyFunction)(this, exception); | |
Ajax.Responders.dispatch('onException', this, exception); | |
} | |
}); | |
Ajax.Request.Events = | |
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; | |
Ajax.Response = Class.create({ | |
initialize: function(request){ | |
this.request = request; | |
var transport = this.transport = request.transport, | |
readyState = this.readyState = transport.readyState; | |
if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { | |
this.status = this.getStatus(); | |
this.statusText = this.getStatusText(); | |
this.responseText = String.interpret(transport.responseText); | |
this.headerJSON = this._getHeaderJSON(); | |
} | |
if (readyState == 4) { | |
var xml = transport.responseXML; | |
this.responseXML = Object.isUndefined(xml) ? null : xml; | |
this.responseJSON = this._getResponseJSON(); | |
} | |
}, | |
status: 0, | |
statusText: '', | |
getStatus: Ajax.Request.prototype.getStatus, | |
getStatusText: function() { | |
try { | |
return this.transport.statusText || ''; | |
} catch (e) { return '' } | |
}, | |
getHeader: Ajax.Request.prototype.getHeader, | |
getAllHeaders: function() { | |
try { | |
return this.getAllResponseHeaders(); | |
} catch (e) { return null } | |
}, | |
getResponseHeader: function(name) { | |
return this.transport.getResponseHeader(name); | |
}, | |
getAllResponseHeaders: function() { | |
return this.transport.getAllResponseHeaders(); | |
}, | |
_getHeaderJSON: function() { | |
var json = this.getHeader('X-JSON'); | |
if (!json) return null; | |
try { | |
json = decodeURIComponent(escape(json)); | |
} catch(e) { | |
} | |
try { | |
return json.evalJSON(this.request.options.sanitizeJSON || | |
!this.request.isSameOrigin()); | |
} catch (e) { | |
this.request.dispatchException(e); | |
} | |
}, | |
_getResponseJSON: function() { | |
var options = this.request.options; | |
if (!options.evalJSON || (options.evalJSON != 'force' && | |
!(this.getHeader('Content-type') || '').include('application/json')) || | |
this.responseText.blank()) | |
return null; | |
try { | |
return this.responseText.evalJSON(options.sanitizeJSON || | |
!this.request.isSameOrigin()); | |
} catch (e) { | |
this.request.dispatchException(e); | |
} | |
} | |
}); | |
Ajax.Updater = Class.create(Ajax.Request, { | |
initialize: function($super, container, url, options) { | |
this.container = { | |
success: (container.success || container), | |
failure: (container.failure || (container.success ? null : container)) | |
}; | |
options = Object.clone(options); | |
var onComplete = options.onComplete; | |
options.onComplete = (function(response, json) { | |
this.updateContent(response.responseText); | |
if (Object.isFunction(onComplete)) onComplete(response, json); | |
}).bind(this); | |
$super(url, options); | |
}, | |
updateContent: function(responseText) { | |
var receiver = this.container[this.success() ? 'success' : 'failure'], | |
options = this.options; | |
if (!options.evalScripts) responseText = responseText.stripScripts(); | |
if (receiver = $(receiver)) { | |
if (options.insertion) { | |
if (Object.isString(options.insertion)) { | |
var insertion = { }; insertion[options.insertion] = responseText; | |
receiver.insert(insertion); | |
} | |
else options.insertion(receiver, responseText); | |
} | |
else receiver.update(responseText); | |
} | |
} | |
}); | |
Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { | |
initialize: function($super, container, url, options) { | |
$super(options); | |
this.onComplete = this.options.onComplete; | |
this.frequency = (this.options.frequency || 2); | |
this.decay = (this.options.decay || 1); | |
this.updater = { }; | |
this.container = container; | |
this.url = url; | |
this.start(); | |
}, | |
start: function() { | |
this.options.onComplete = this.updateComplete.bind(this); | |
this.onTimerEvent(); | |
}, | |
stop: function() { | |
this.updater.options.onComplete = undefined; | |
clearTimeout(this.timer); | |
(this.onComplete || Prototype.emptyFunction).apply(this, arguments); | |
}, | |
updateComplete: function(response) { | |
if (this.options.decay) { | |
this.decay = (response.responseText == this.lastText ? | |
this.decay * this.options.decay : 1); | |
this.lastText = response.responseText; | |
} | |
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); | |
}, | |
onTimerEvent: function() { | |
this.updater = new Ajax.Updater(this.container, this.url, this.options); | |
} | |
}); | |
(function(GLOBAL) { | |
var UNDEFINED; | |
var SLICE = Array.prototype.slice; | |
var DIV = document.createElement('div'); | |
function $(element) { | |
if (arguments.length > 1) { | |
for (var i = 0, elements = [], length = arguments.length; i < length; i++) | |
elements.push($(arguments[i])); | |
return elements; | |
} | |
if (Object.isString(element)) | |
element = document.getElementById(element); | |
return Element.extend(element); | |
} | |
GLOBAL.$ = $; | |
if (!GLOBAL.Node) GLOBAL.Node = {}; | |
if (!GLOBAL.Node.ELEMENT_NODE) { | |
Object.extend(GLOBAL.Node, { | |
ELEMENT_NODE: 1, | |
ATTRIBUTE_NODE: 2, | |
TEXT_NODE: 3, | |
CDATA_SECTION_NODE: 4, | |
ENTITY_REFERENCE_NODE: 5, | |
ENTITY_NODE: 6, | |
PROCESSING_INSTRUCTION_NODE: 7, | |
COMMENT_NODE: 8, | |
DOCUMENT_NODE: 9, | |
DOCUMENT_TYPE_NODE: 10, | |
DOCUMENT_FRAGMENT_NODE: 11, | |
NOTATION_NODE: 12 | |
}); | |
} | |
var ELEMENT_CACHE = {}; | |
function shouldUseCreationCache(tagName, attributes) { | |
if (tagName === 'select') return false; | |
if ('type' in attributes) return false; | |
return true; | |
} | |
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ | |
try { | |
var el = document.createElement('<input name="x">'); | |
return el.tagName.toLowerCase() === 'input' && el.name === 'x'; | |
} | |
catch(err) { | |
return false; | |
} | |
})(); | |
var oldElement = GLOBAL.Element; | |
function Element(tagName, attributes) { | |
attributes = attributes || {}; | |
tagName = tagName.toLowerCase(); | |
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { | |
tagName = '<' + tagName + ' name="' + attributes.name + '">'; | |
delete attributes.name; | |
return Element.writeAttribute(document.createElement(tagName), attributes); | |
} | |
if (!ELEMENT_CACHE[tagName]) | |
ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName)); | |
var node = shouldUseCreationCache(tagName, attributes) ? | |
ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName); | |
return Element.writeAttribute(node, attributes); | |
} | |
GLOBAL.Element = Element; | |
Object.extend(GLOBAL.Element, oldElement || {}); | |
if (oldElement) GLOBAL.Element.prototype = oldElement.prototype; | |
Element.Methods = { ByTag: {}, Simulated: {} }; | |
var methods = {}; | |
var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' }; | |
function inspect(element) { | |
element = $(element); | |
var result = '<' + element.tagName.toLowerCase(); | |
var attribute, value; | |
for (var property in INSPECT_ATTRIBUTES) { | |
attribute = INSPECT_ATTRIBUTES[property]; | |
value = (element[property] || '').toString(); | |
if (value) result += ' ' + attribute + '=' + value.inspect(true); | |
} | |
return result + '>'; | |
} | |
methods.inspect = inspect; | |
function visible(element) { | |
return $(element).style.display !== 'none'; | |
} | |
function toggle(element, bool) { | |
element = $(element); | |
if (Object.isUndefined(bool)) | |
bool = !Element.visible(element); | |
Element[bool ? 'show' : 'hide'](element); | |
return element; | |
} | |
function hide(element) { | |
element = $(element); | |
element.style.display = 'none'; | |
return element; | |
} | |
function show(element) { | |
element = $(element); | |
element.style.display = ''; | |
return element; | |
} | |
Object.extend(methods, { | |
visible: visible, | |
toggle: toggle, | |
hide: hide, | |
show: show | |
}); | |
function remove(element) { | |
element = $(element); | |
element.parentNode.removeChild(element); | |
return element; | |
} | |
var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ | |
var el = document.createElement("select"), | |
isBuggy = true; | |
el.innerHTML = "<option value=\"test\">test</option>"; | |
if (el.options && el.options[0]) { | |
isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; | |
} | |
el = null; | |
return isBuggy; | |
})(); | |
var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ | |
try { | |
var el = document.createElement("table"); | |
if (el && el.tBodies) { | |
el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; | |
var isBuggy = typeof el.tBodies[0] == "undefined"; | |
el = null; | |
return isBuggy; | |
} | |
} catch (e) { | |
return true; | |
} | |
})(); | |
var LINK_ELEMENT_INNERHTML_BUGGY = (function() { | |
try { | |
var el = document.createElement('div'); | |
el.innerHTML = "<link />"; | |
var isBuggy = (el.childNodes.length === 0); | |
el = null; | |
return isBuggy; | |
} catch(e) { | |
return true; | |
} | |
})(); | |
var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || | |
TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; | |
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { | |
var s = document.createElement("script"), | |
isBuggy = false; | |
try { | |
s.appendChild(document.createTextNode("")); | |
isBuggy = !s.firstChild || | |
s.firstChild && s.firstChild.nodeType !== 3; | |
} catch (e) { | |
isBuggy = true; | |
} | |
s = null; | |
return isBuggy; | |
})(); | |
function update(element, content) { | |
element = $(element); | |
var descendants = element.getElementsByTagName('*'), | |
i = descendants.length; | |
while (i--) purgeElement(descendants[i]); | |
if (content && content.toElement) | |
content = content.toElement(); | |
if (Object.isElement(content)) | |
return element.update().insert(content); | |
content = Object.toHTML(content); | |
var tagName = element.tagName.toUpperCase(); | |
if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { | |
element.text = content; | |
return element; | |
} | |
if (ANY_INNERHTML_BUGGY) { | |
if (tagName in INSERTION_TRANSLATIONS.tags) { | |
while (element.firstChild) | |
element.removeChild(element.firstChild); | |
var nodes = getContentFromAnonymousElement(tagName, content.stripScripts()); | |
for (var i = 0, node; node = nodes[i]; i++) | |
element.appendChild(node); | |
} else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) { | |
while (element.firstChild) | |
element.removeChild(element.firstChild); | |
var nodes = getContentFromAnonymousElement(tagName, | |
content.stripScripts(), true); | |
for (var i = 0, node; node = nodes[i]; i++) | |
element.appendChild(node); | |
} else { | |
element.innerHTML = content.stripScripts(); | |
} | |
} else { | |
element.innerHTML = content.stripScripts(); | |
} | |
content.evalScripts.bind(content).defer(); | |
return element; | |
} | |
function replace(element, content) { | |
element = $(element); | |
if (content && content.toElement) { | |
content = content.toElement(); | |
} else if (!Object.isElement(content)) { | |
content = Object.toHTML(content); | |
var range = element.ownerDocument.createRange(); | |
range.selectNode(element); | |
content.evalScripts.bind(content).defer(); | |
content = range.createContextualFragment(content.stripScripts()); | |
} | |
element.parentNode.replaceChild(content, element); | |
return element; | |
} | |
var INSERTION_TRANSLATIONS = { | |
before: function(element, node) { | |
element.parentNode.insertBefore(node, element); | |
}, | |
top: function(element, node) { | |
element.insertBefore(node, element.firstChild); | |
}, | |
bottom: function(element, node) { | |
element.appendChild(node); | |
}, | |
after: function(element, node) { | |
element.parentNode.insertBefore(node, element.nextSibling); | |
}, | |
tags: { | |
TABLE: ['<table>', '</table>', 1], | |
TBODY: ['<table><tbody>', '</tbody></table>', 2], | |
TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], | |
TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], | |
SELECT: ['<select>', '</select>', 1] | |
} | |
}; | |
var tags = INSERTION_TRANSLATIONS.tags; | |
Object.extend(tags, { | |
THEAD: tags.TBODY, | |
TFOOT: tags.TBODY, | |
TH: tags.TD | |
}); | |
function replace_IE(element, content) { | |
element = $(element); | |
if (content && content.toElement) | |
content = content.toElement(); | |
if (Object.isElement(content)) { | |
element.parentNode.replaceChild(content, element); | |
return element; | |
} | |
content = Object.toHTML(content); | |
var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); | |
if (tagName in INSERTION_TRANSLATIONS.tags) { | |
var nextSibling = Element.next(element); | |
var fragments = getContentFromAnonymousElement( | |
tagName, content.stripScripts()); | |
parent.removeChild(element); | |
var iterator; | |
if (nextSibling) | |
iterator = function(node) { parent.insertBefore(node, nextSibling) }; | |
else | |
iterator = function(node) { parent.appendChild(node); } | |
fragments.each(iterator); | |
} else { | |
element.outerHTML = content.stripScripts(); | |
} | |
content.evalScripts.bind(content).defer(); | |
return element; | |
} | |
if ('outerHTML' in document.documentElement) | |
replace = replace_IE; | |
function isContent(content) { | |
if (Object.isUndefined(content) || content === null) return false; | |
if (Object.isString(content) || Object.isNumber(content)) return true; | |
if (Object.isElement(content)) return true; | |
if (content.toElement || content.toHTML) return true; | |
return false; | |
} | |
function insertContentAt(element, content, position) { | |
position = position.toLowerCase(); | |
var method = INSERTION_TRANSLATIONS[position]; | |
if (content && content.toElement) content = content.toElement(); | |
if (Object.isElement(content)) { | |
method(element, content); | |
return element; | |
} | |
content = Object.toHTML(content); | |
var tagName = ((position === 'before' || position === 'after') ? | |
element.parentNode : element).tagName.toUpperCase(); | |
var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts()); | |
if (position === 'top' || position === 'after') childNodes.reverse(); | |
for (var i = 0, node; node = childNodes[i]; i++) | |
method(element, node); | |
content.evalScripts.bind(content).defer(); | |
} | |
function insert(element, insertions) { | |
element = $(element); | |
if (isContent(insertions)) | |
insertions = { bottom: insertions }; | |
for (var position in insertions) | |
insertContentAt(element, insertions[position], position); | |
return element; | |
} | |
function wrap(element, wrapper, attributes) { | |
element = $(element); | |
if (Object.isElement(wrapper)) { | |
$(wrapper).writeAttribute(attributes || {}); | |
} else if (Object.isString(wrapper)) { | |
wrapper = new Element(wrapper, attributes); | |
} else { | |
wrapper = new Element('div', wrapper); | |
} | |
if (element.parentNode) | |
element.parentNode.replaceChild(wrapper, element); | |
wrapper.appendChild(element); | |
return wrapper; | |
} | |
function cleanWhitespace(element) { | |
element = $(element); | |
var node = element.firstChild; | |
while (node) { | |
var nextNode = node.nextSibling; | |
if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue)) | |
element.removeChild(node); | |
node = nextNode; | |
} | |
return element; | |
} | |
function empty(element) { | |
return $(element).innerHTML.blank(); | |
} | |
function getContentFromAnonymousElement(tagName, html, force) { | |
var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV; | |
var workaround = !!t; | |
if (!workaround && force) { | |
workaround = true; | |
t = ['', '', 0]; | |
} | |
if (workaround) { | |
div.innerHTML = ' ' + t[0] + html + t[1]; | |
div.removeChild(div.firstChild); | |
for (var i = t[2]; i--; ) | |
div = div.firstChild; | |
} else { | |
div.innerHTML = html; | |
} | |
return $A(div.childNodes); | |
} | |
function clone(element, deep) { | |
if (!(element = $(element))) return; | |
var clone = element.cloneNode(deep); | |
if (!HAS_UNIQUE_ID_PROPERTY) { | |
clone._prototypeUID = UNDEFINED; | |
if (deep) { | |
var descendants = Element.select(clone, '*'), | |
i = descendants.length; | |
while (i--) | |
descendants[i]._prototypeUID = UNDEFINED; | |
} | |
} | |
return Element.extend(clone); | |
} | |
function purgeElement(element) { | |
var uid = getUniqueElementID(element); | |
if (uid) { | |
Element.stopObserving(element); | |
if (!HAS_UNIQUE_ID_PROPERTY) | |
element._prototypeUID = UNDEFINED; | |
delete Element.Storage[uid]; | |
} | |
} | |
function purgeCollection(elements) { | |
var i = elements.length; | |
while (i--) | |
purgeElement(elements[i]); | |
} | |
function purgeCollection_IE(elements) { | |
var i = elements.length, element, uid; | |
while (i--) { | |
element = elements[i]; | |
uid = getUniqueElementID(element); | |
delete Element.Storage[uid]; | |
delete Event.cache[uid]; | |
} | |
} | |
if (HAS_UNIQUE_ID_PROPERTY) { | |
purgeCollection = purgeCollection_IE; | |
} | |
function purge(element) { | |
if (!(element = $(element))) return; | |
purgeElement(element); | |
var descendants = element.getElementsByTagName('*'), | |
i = descendants.length; | |
while (i--) purgeElement(descendants[i]); | |
return null; | |
} | |
Object.extend(methods, { | |
remove: remove, | |
update: update, | |
replace: replace, | |
insert: insert, | |
wrap: wrap, | |
cleanWhitespace: cleanWhitespace, | |
empty: empty, | |
clone: clone, | |
purge: purge | |
}); | |
function recursivelyCollect(element, property, maximumLength) { | |
element = $(element); | |
maximumLength = maximumLength || -1; | |
var elements = []; | |
while (element = element[property]) { | |
if (element.nodeType === Node.ELEMENT_NODE) | |
elements.push(Element.extend(element)); | |
if (elements.length === maximumLength) break; | |
} | |
return elements; | |
} | |
function ancestors(element) { | |
return recursivelyCollect(element, 'parentNode'); | |
} | |
function descendants(element) { | |
return Element.select(element, '*'); | |
} | |
function firstDescendant(element) { | |
element = $(element).firstChild; | |
while (element && element.nodeType !== Node.ELEMENT_NODE) | |
element = element.nextSibling; | |
return $(element); | |
} | |
function immediateDescendants(element) { | |
var results = [], child = $(element).firstChild; | |
while (child) { | |
if (child.nodeType === Node.ELEMENT_NODE) | |
results.push(Element.extend(child)); | |
child = child.nextSibling; | |
} | |
return results; | |
} | |
function previousSiblings(element) { | |
return recursivelyCollect(element, 'previousSibling'); | |
} | |
function nextSiblings(element) { | |
return recursivelyCollect(element, 'nextSibling'); | |
} | |
function siblings(element) { | |
element = $(element); | |
var previous = previousSiblings(element), | |
next = nextSiblings(element); | |
return previous.reverse().concat(next); | |
} | |
function match(element, selector) { | |
element = $(element); | |
if (Object.isString(selector)) | |
return Prototype.Selector.match(element, selector); | |
return selector.match(element); | |
} | |
function _recursivelyFind(element, property, expression, index) { | |
element = $(element), expression = expression || 0, index = index || 0; | |
if (Object.isNumber(expression)) { | |
index = expression, expression = null; | |
} | |
while (element = element[property]) { | |
if (element.nodeType !== 1) continue; | |
if (expression && !Prototype.Selector.match(element, expression)) | |
continue; | |
if (--index >= 0) continue; | |
return Element.extend(element); | |
} | |
} | |
function up(element, expression, index) { | |
element = $(element); | |
if (arguments.length === 1) return $(element.parentNode); | |
return _recursivelyFind(element, 'parentNode', expression, index); | |
} | |
function down(element, expression, index) { | |
if (arguments.length === 1) return firstDescendant(element); | |
element = $(element), expression = expression || 0, index = index || 0; | |
if (Object.isNumber(expression)) | |
index = expression, expression = '*'; | |
var node = Prototype.Selector.select(expression, element)[index]; | |
return Element.extend(node); | |
} | |
function previous(element, expression, index) { | |
return _recursivelyFind(element, 'previousSibling', expression, index); | |
} | |
function next(element, expression, index) { | |
return _recursivelyFind(element, 'nextSibling', expression, index); | |
} | |
function select(element) { | |
element = $(element); | |
var expressions = SLICE.call(arguments, 1).join(', '); | |
return Prototype.Selector.select(expressions, element); | |
} | |
function adjacent(element) { | |
element = $(element); | |
var expressions = SLICE.call(arguments, 1).join(', '); | |
var siblings = Element.siblings(element), results = []; | |
for (var i = 0, sibling; sibling = siblings[i]; i++) { | |
if (Prototype.Selector.match(sibling, expressions)) | |
results.push(sibling); | |
} | |
return results; | |
} | |
function descendantOf_DOM(element, ancestor) { | |
element = $(element), ancestor = $(ancestor); | |
while (element = element.parentNode) | |
if (element === ancestor) return true; | |
return false; | |
} | |
function descendantOf_contains(element, ancestor) { | |
element = $(element), ancestor = $(ancestor); | |
if (!ancestor.contains) return descendantOf_DOM(element, ancestor); | |
return ancestor.contains(element) && ancestor !== element; | |
} | |
function descendantOf_compareDocumentPosition(element, ancestor) { | |
element = $(element), ancestor = $(ancestor); | |
return (element.compareDocumentPosition(ancestor) & 8) === 8; | |
} | |
var descendantOf; | |
if (DIV.compareDocumentPosition) { | |
descendantOf = descendantOf_compareDocumentPosition; | |
} else if (DIV.contains) { | |
descendantOf = descendantOf_contains; | |
} else { | |
descendantOf = descendantOf_DOM; | |
} | |
Object.extend(methods, { | |
recursivelyCollect: recursivelyCollect, | |
ancestors: ancestors, | |
descendants: descendants, | |
firstDescendant: firstDescendant, | |
immediateDescendants: immediateDescendants, | |
previousSiblings: previousSiblings, | |
nextSiblings: nextSiblings, | |
siblings: siblings, | |
match: match, | |
up: up, | |
down: down, | |
previous: previous, | |
next: next, | |
select: select, | |
adjacent: adjacent, | |
descendantOf: descendantOf, | |
getElementsBySelector: select, | |
childElements: immediateDescendants | |
}); | |
var idCounter = 1; | |
function identify(element) { | |
element = $(element); | |
var id = Element.readAttribute(element, 'id'); | |
if (id) return id; | |
do { id = 'anonymous_element_' + idCounter++ } while ($(id)); | |
Element.writeAttribute(element, 'id', id); | |
return id; | |
} | |
function readAttribute(element, name) { | |
return $(element).getAttribute(name); | |
} | |
function readAttribute_IE(element, name) { | |
element = $(element); | |
var table = ATTRIBUTE_TRANSLATIONS.read; | |
if (table.values[name]) | |
return table.values[name](element, name); | |
if (table.names[name]) name = table.names[name]; | |
if (name.include(':')) { | |
if (!element.attributes || !element.attributes[name]) return null; | |
return element.attributes[name].value; | |
} | |
return element.getAttribute(name); | |
} | |
function readAttribute_Opera(element, name) { | |
if (name === 'title') return element.title; | |
return element.getAttribute(name); | |
} | |
var PROBLEMATIC_ATTRIBUTE_READING = (function() { | |
DIV.setAttribute('onclick', []); | |
var value = DIV.getAttribute('onclick'); | |
var isFunction = Object.isArray(value); | |
DIV.removeAttribute('onclick'); | |
return isFunction; | |
})(); | |
if (PROBLEMATIC_ATTRIBUTE_READING) { | |
readAttribute = readAttribute_IE; | |
} else if (Prototype.Browser.Opera) { | |
readAttribute = readAttribute_Opera; | |
} | |
function writeAttribute(element, name, value) { | |
element = $(element); | |
var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write; | |
if (typeof name === 'object') { | |
attributes = name; | |
} else { | |
attributes[name] = Object.isUndefined(value) ? true : value; | |
} | |
for (var attr in attributes) { | |
name = table.names[attr] || attr; | |
value = attributes[attr]; | |
if (table.values[attr]) | |
name = table.values[attr](element, value) || name; | |
if (value === false || value === null) | |
element.removeAttribute(name); | |
else if (value === true) | |
element.setAttribute(name, name); | |
else element.setAttribute(name, value); | |
} | |
return element; | |
} | |
var PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES = (function () { | |
if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) { | |
return false; | |
} | |
var checkbox = document.createElement('<input type="checkbox">'); | |
checkbox.checked = true; | |
var node = checkbox.getAttributeNode('checked'); | |
return !node || !node.specified; | |
})(); | |
function hasAttribute(element, attribute) { | |
attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute; | |
var node = $(element).getAttributeNode(attribute); | |
return !!(node && node.specified); | |
} | |
function hasAttribute_IE(element, attribute) { | |
if (attribute === 'checked') { | |
return element.checked; | |
} | |
return hasAttribute(element, attribute); | |
} | |
GLOBAL.Element.Methods.Simulated.hasAttribute = | |
PROBLEMATIC_HAS_ATTRIBUTE_WITH_CHECKBOXES ? | |
hasAttribute_IE : hasAttribute; | |
function classNames(element) { | |
return new Element.ClassNames(element); | |
} | |
var regExpCache = {}; | |
function getRegExpForClassName(className) { | |
if (regExpCache[className]) return regExpCache[className]; | |
var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)"); | |
regExpCache[className] = re; | |
return re; | |
} | |
function hasClassName(element, className) { | |
if (!(element = $(element))) return; | |
var elementClassName = element.className; | |
if (elementClassName.length === 0) return false; | |
if (elementClassName === className) return true; | |
return getRegExpForClassName(className).test(elementClassName); | |
} | |
function addClassName(element, className) { | |
if (!(element = $(element))) return; | |
if (!hasClassName(element, className)) | |
element.className += (element.className ? ' ' : '') + className; | |
return element; | |
} | |
function removeClassName(element, className) { | |
if (!(element = $(element))) return; | |
element.className = element.className.replace( | |
getRegExpForClassName(className), ' ').strip(); | |
return element; | |
} | |
function toggleClassName(element, className, bool) { | |
if (!(element = $(element))) return; | |
if (Object.isUndefined(bool)) | |
bool = !hasClassName(element, className); | |
var method = Element[bool ? 'addClassName' : 'removeClassName']; | |
return method(element, className); | |
} | |
var ATTRIBUTE_TRANSLATIONS = {}; | |
var classProp = 'className', forProp = 'for'; | |
DIV.setAttribute(classProp, 'x'); | |
if (DIV.className !== 'x') { | |
DIV.setAttribute('class', 'x'); | |
if (DIV.className === 'x') | |
classProp = 'class'; | |
} | |
var LABEL = document.createElement('label'); | |
LABEL.setAttribute(forProp, 'x'); | |
if (LABEL.htmlFor !== 'x') { | |
LABEL.setAttribute('htmlFor', 'x'); | |
if (LABEL.htmlFor === 'x') | |
forProp = 'htmlFor'; | |
} | |
LABEL = null; | |
function _getAttr(element, attribute) { | |
return element.getAttribute(attribute); | |
} | |
function _getAttr2(element, attribute) { | |
return element.getAttribute(attribute, 2); | |
} | |
function _getAttrNode(element, attribute) { | |
var node = element.getAttributeNode(attribute); | |
return node ? node.value : ''; | |
} | |
function _getFlag(element, attribute) { | |
return $(element).hasAttribute(attribute) ? attribute : null; | |
} | |
DIV.onclick = Prototype.emptyFunction; | |
var onclickValue = DIV.getAttribute('onclick'); | |
var _getEv; | |
if (String(onclickValue).indexOf('{') > -1) { | |
_getEv = function(element, attribute) { | |
var value = element.getAttribute(attribute); | |
if (!value) return null; | |
value = value.toString(); | |
value = value.split('{')[1]; | |
value = value.split('}')[0]; | |
return value.strip(); | |
}; | |
} | |
else if (onclickValue === '') { | |
_getEv = function(element, attribute) { | |
var value = element.getAttribute(attribute); | |
if (!value) return null; | |
return value.strip(); | |
}; | |
} | |
ATTRIBUTE_TRANSLATIONS.read = { | |
names: { | |
'class': classProp, | |
'className': classProp, | |
'for': forProp, | |
'htmlFor': forProp | |
}, | |
values: { | |
style: function(element) { | |
return element.style.cssText.toLowerCase(); | |
}, | |
title: function(element) { | |
return element.title; | |
} | |
} | |
}; | |
ATTRIBUTE_TRANSLATIONS.write = { | |
names: { | |
className: 'class', | |
htmlFor: 'for', | |
cellpadding: 'cellPadding', | |
cellspacing: 'cellSpacing' | |
}, | |
values: { | |
checked: function(element, value) { | |
element.checked = !!value; | |
}, | |
style: function(element, value) { | |
element.style.cssText = value ? value : ''; | |
} | |
} | |
}; | |
ATTRIBUTE_TRANSLATIONS.has = { names: {} }; | |
Object.extend(ATTRIBUTE_TRANSLATIONS.write.names, | |
ATTRIBUTE_TRANSLATIONS.read.names); | |
var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' + | |
'accessKey tabIndex encType maxLength readOnly longDesc frameBorder'); | |
for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) { | |
ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr; | |
ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()] = attr; | |
} | |
Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, { | |
href: _getAttr2, | |
src: _getAttr2, | |
type: _getAttr, | |
action: _getAttrNode, | |
disabled: _getFlag, | |
checked: _getFlag, | |
readonly: _getFlag, | |
multiple: _getFlag, | |
onload: _getEv, | |
onunload: _getEv, | |
onclick: _getEv, | |
ondblclick: _getEv, | |
onmousedown: _getEv, | |
onmouseup: _getEv, | |
onmouseover: _getEv, | |
onmousemove: _getEv, | |
onmouseout: _getEv, | |
onfocus: _getEv, | |
onblur: _getEv, | |
onkeypress: _getEv, | |
onkeydown: _getEv, | |
onkeyup: _getEv, | |
onsubmit: _getEv, | |
onreset: _getEv, | |
onselect: _getEv, | |
onchange: _getEv | |
}); | |
Object.extend(methods, { | |
identify: identify, | |
readAttribute: readAttribute, | |
writeAttribute: writeAttribute, | |
classNames: classNames, | |
hasClassName: hasClassName, | |
addClassName: addClassName, | |
removeClassName: removeClassName, | |
toggleClassName: toggleClassName | |
}); | |
function normalizeStyleName(style) { | |
if (style === 'float' || style === 'styleFloat') | |
return 'cssFloat'; | |
return style.camelize(); | |
} | |
function normalizeStyleName_IE(style) { | |
if (style === 'float' || style === 'cssFloat') | |
return 'styleFloat'; | |
return style.camelize(); | |
} | |
function setStyle(element, styles) { | |
element = $(element); | |
var elementStyle = element.style, match; | |
if (Object.isString(styles)) { | |
elementStyle.cssText += ';' + styles; | |
if (styles.include('opacity')) { | |
var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1]; | |
Element.setOpacity(element, opacity); | |
} | |
return element; | |
} | |
for (var property in styles) { | |
if (property === 'opacity') { | |
Element.setOpacity(element, styles[property]); | |
} else { | |
var value = styles[property]; | |
if (property === 'float' || property === 'cssFloat') { | |
property = Object.isUndefined(elementStyle.styleFloat) ? | |
'cssFloat' : 'styleFloat'; | |
} | |
elementStyle[property] = value; | |
} | |
} | |
return element; | |
} | |
function getStyle(element, style) { | |
element = $(element); | |
style = normalizeStyleName(style); | |
var value = element.style[style]; | |
if (!value || value === 'auto') { | |
var css = document.defaultView.getComputedStyle(element, null); | |
value = css ? css[style] : null; | |
} | |
if (style === 'opacity') return value ? parseFloat(value) : 1.0; | |
return value === 'auto' ? null : value; | |
} | |
function getStyle_Opera(element, style) { | |
switch (style) { | |
case 'height': case 'width': | |
if (!Element.visible(element)) return null; | |
var dim = parseInt(getStyle(element, style), 10); | |
if (dim !== element['offset' + style.capitalize()]) | |
return dim + 'px'; | |
return Element.measure(element, style); | |
default: return getStyle(element, style); | |
} | |
} | |
function getStyle_IE(element, style) { | |
element = $(element); | |
style = normalizeStyleName_IE(style); | |
var value = element.style[style]; | |
if (!value && element.currentStyle) { | |
value = element.currentStyle[style]; | |
} | |
if (style === 'opacity' && !STANDARD_CSS_OPACITY_SUPPORTED) | |
return getOpacity_IE(element); | |
if (value === 'auto') { | |
if ((style === 'width' || style === 'height') && Element.visible(element)) | |
return Element.measure(element, style) + 'px'; | |
return null; | |
} | |
return value; | |
} | |
function stripAlphaFromFilter_IE(filter) { | |
return (filter || '').replace(/alpha\([^\)]*\)/gi, ''); | |
} | |
function hasLayout_IE(element) { | |
if (!element.currentStyle || !element.currentStyle.hasLayout) | |
element.style.zoom = 1; | |
return element; | |
} | |
var STANDARD_CSS_OPACITY_SUPPORTED = (function() { | |
DIV.style.cssText = "opacity:.55"; | |
return /^0.55/.test(DIV.style.opacity); | |
})(); | |
function setOpacity(element, value) { | |
element = $(element); | |
if (value == 1 || value === '') value = ''; | |
else if (value < 0.00001) value = 0; | |
element.style.opacity = value; | |
return element; | |
} | |
function setOpacity_IE(element, value) { | |
if (STANDARD_CSS_OPACITY_SUPPORTED) | |
return setOpacity(element, value); | |
element = hasLayout_IE($(element)); | |
var filter = Element.getStyle(element, 'filter'), | |
style = element.style; | |
if (value == 1 || value === '') { | |
filter = stripAlphaFromFilter_IE(filter); | |
if (filter) style.filter = filter; | |
else style.removeAttribute('filter'); | |
return element; | |
} | |
if (value < 0.00001) value = 0; | |
style.filter = stripAlphaFromFilter_IE(filter) + | |
'alpha(opacity=' + (value * 100) + ')'; | |
return element; | |
} | |
function getOpacity(element) { | |
return Element.getStyle(element, 'opacity'); | |
} | |
function getOpacity_IE(element) { | |
if (STANDARD_CSS_OPACITY_SUPPORTED) | |
return getOpacity(element); | |
var filter = Element.getStyle(element, 'filter'); | |
if (filter.length === 0) return 1.0; | |
var match = (filter || '').match(/alpha\(opacity=(.*)\)/); | |
if (match && match[1]) return parseFloat(match[1]) / 100; | |
return 1.0; | |
} | |
Object.extend(methods, { | |
setStyle: setStyle, | |
getStyle: getStyle, | |
setOpacity: setOpacity, | |
getOpacity: getOpacity | |
}); | |
if ('styleFloat' in DIV.style) { | |
methods.getStyle = getStyle_IE; | |
methods.setOpacity = setOpacity_IE; | |
methods.getOpacity = getOpacity_IE; | |
} | |
var UID = 0; | |
GLOBAL.Element.Storage = { UID: 1 }; | |
function getUniqueElementID(element) { | |
if (element === window) return 0; | |
if (typeof element._prototypeUID === 'undefined') | |
element._prototypeUID = Element.Storage.UID++; | |
return element._prototypeUID; | |
} | |
function getUniqueElementID_IE(element) { | |
if (element === window) return 0; | |
if (element == document) return 1; | |
return element.uniqueID; | |
} | |
var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV); | |
if (HAS_UNIQUE_ID_PROPERTY) | |
getUniqueElementID = getUniqueElementID_IE; | |
function getStorage(element) { | |
if (!(element = $(element))) return; | |
var uid = getUniqueElementID(element); | |
if (!Element.Storage[uid]) | |
Element.Storage[uid] = $H(); | |
return Element.Storage[uid]; | |
} | |
function store(element, key, value) { | |
if (!(element = $(element))) return; | |
var storage = getStorage(element); | |
if (arguments.length === 2) { | |
storage.update(key); | |
} else { | |
storage.set(key, value); | |
} | |
return element; | |
} | |
function retrieve(element, key, defaultValue) { | |
if (!(element = $(element))) return; | |
var storage = getStorage(element), value = storage.get(key); | |
if (Object.isUndefined(value)) { | |
storage.set(key, defaultValue); | |
value = defaultValue; | |
} | |
return value; | |
} | |
Object.extend(methods, { | |
getStorage: getStorage, | |
store: store, | |
retrieve: retrieve | |
}); | |
var Methods = {}, ByTag = Element.Methods.ByTag, | |
F = Prototype.BrowserFeatures; | |
if (!F.ElementExtensions && ('__proto__' in DIV)) { | |
GLOBAL.HTMLElement = {}; | |
GLOBAL.HTMLElement.prototype = DIV['__proto__']; | |
F.ElementExtensions = true; | |
} | |
function checkElementPrototypeDeficiency(tagName) { | |
if (typeof window.Element === 'undefined') return false; | |
if (!HAS_EXTENDED_CREATE_ELEMENT_SYNTAX) return false; | |
var proto = window.Element.prototype; | |
if (proto) { | |
var id = '_' + (Math.random() + '').slice(2), | |
el = document.createElement(tagName); | |
proto[id] = 'x'; | |
var isBuggy = (el[id] !== 'x'); | |
delete proto[id]; | |
el = null; | |
return isBuggy; | |
} | |
return false; | |
} | |
var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = | |
checkElementPrototypeDeficiency('object'); | |
function extendElementWith(element, methods) { | |
for (var property in methods) { | |
var value = methods[property]; | |
if (Object.isFunction(value) && !(property in element)) | |
element[property] = value.methodize(); | |
} | |
} | |
var EXTENDED = {}; | |
function elementIsExtended(element) { | |
var uid = getUniqueElementID(element); | |
return (uid in EXTENDED); | |
} | |
function extend(element) { | |
if (!element || elementIsExtended(element)) return element; | |
if (element.nodeType !== Node.ELEMENT_NODE || element == window) | |
return element; | |
var methods = Object.clone(Methods), | |
tagName = element.tagName.toUpperCase(); | |
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); | |
extendElementWith(element, methods); | |
EXTENDED[getUniqueElementID(element)] = true; | |
return element; | |
} | |
function extend_IE8(element) { | |
if (!element || elementIsExtended(element)) return element; | |
var t = element.tagName; | |
if (t && (/^(?:object|applet|embed)$/i.test(t))) { | |
extendElementWith(element, Element.Methods); | |
extendElementWith(element, Element.Methods.Simulated); | |
extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); | |
} | |
return element; | |
} | |
if (F.SpecificElementExtensions) { | |
extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K; | |
} | |
function addMethodsToTagName(tagName, methods) { | |
tagName = tagName.toUpperCase(); | |
if (!ByTag[tagName]) ByTag[tagName] = {}; | |
Object.extend(ByTag[tagName], methods); | |
} | |
function mergeMethods(destination, methods, onlyIfAbsent) { | |
if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false; | |
for (var property in methods) { | |
var value = methods[property]; | |
if (!Object.isFunction(value)) continue; | |
if (!onlyIfAbsent || !(property in destination)) | |
destination[property] = value.methodize(); | |
} | |
} | |
function findDOMClass(tagName) { | |
var klass; | |
var trans = { | |
"OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", | |
"FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", | |
"DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", | |
"H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", | |
"INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": | |
"TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": | |
"TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": | |
"TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": | |
"FrameSet", "IFRAME": "IFrame" | |
}; | |
if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; | |
if (window[klass]) return window[klass]; | |
klass = 'HTML' + tagName + 'Element'; | |
if (window[klass]) return window[klass]; | |
klass = 'HTML' + tagName.capitalize() + 'Element'; | |
if (window[klass]) return window[klass]; | |
var element = document.createElement(tagName), | |
proto = element['__proto__'] || element.constructor.prototype; | |
element = null; | |
return proto; | |
} | |
function addMethods(methods) { | |
if (arguments.length === 0) addFormMethods(); | |
if (arguments.length === 2) { | |
var tagName = methods; | |
methods = arguments[1]; | |
} | |
if (!tagName) { | |
Object.extend(Element.Methods, methods || {}); | |
} else { | |
if (Object.isArray(tagName)) { | |
for (var i = 0, tag; tag = tagName[i]; i++) | |
addMethodsToTagName(tag, methods); | |
} else { | |
addMethodsToTagName(tagName, methods); | |
} | |
} | |
var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype : | |
Element.prototype; | |
if (F.ElementExtensions) { | |
mergeMethods(ELEMENT_PROTOTYPE, Element.Methods); | |
mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true); | |
} | |
if (F.SpecificElementExtensions) { | |
for (var tag in Element.Methods.ByTag) { | |
var klass = findDOMClass(tag); | |
if (Object.isUndefined(klass)) continue; | |
mergeMethods(klass.prototype, ByTag[tag]); | |
} | |
} | |
Object.extend(Element, Element.Methods); | |
Object.extend(Element, Element.Methods.Simulated); | |
delete Element.ByTag; | |
delete Element.Simulated; | |
Element.extend.refresh(); | |
ELEMENT_CACHE = {}; | |
} | |
Object.extend(GLOBAL.Element, { | |
extend: extend, | |
addMethods: addMethods | |
}); | |
if (extend === Prototype.K) { | |
GLOBAL.Element.extend.refresh = Prototype.emptyFunction; | |
} else { | |
GLOBAL.Element.extend.refresh = function() { | |
if (Prototype.BrowserFeatures.ElementExtensions) return; | |
Object.extend(Methods, Element.Methods); | |
Object.extend(Methods, Element.Methods.Simulated); | |
EXTENDED = {}; | |
}; | |
} | |
function addFormMethods() { | |
Object.extend(Form, Form.Methods); | |
Object.extend(Form.Element, Form.Element.Methods); | |
Object.extend(Element.Methods.ByTag, { | |
"FORM": Object.clone(Form.Methods), | |
"INPUT": Object.clone(Form.Element.Methods), | |
"SELECT": Object.clone(Form.Element.Methods), | |
"TEXTAREA": Object.clone(Form.Element.Methods), | |
"BUTTON": Object.clone(Form.Element.Methods) | |
}); | |
} | |
Element.addMethods(methods); | |
function destroyCache_IE() { | |
DIV = null; | |
ELEMENT_CACHE = null; | |
} | |
if (window.attachEvent) | |
window.attachEvent('onunload', destroyCache_IE); | |
})(this); | |
(function() { | |
function toDecimal(pctString) { | |
var match = pctString.match(/^(\d+)%?$/i); | |
if (!match) return null; | |
return (Number(match[1]) / 100); | |
} | |
function getRawStyle(element, style) { | |
element = $(element); | |
var value = element.style[style]; | |
if (!value || value === 'auto') { | |
var css = document.defaultView.getComputedStyle(element, null); | |
value = css ? css[style] : null; | |
} | |
if (style === 'opacity') return value ? parseFloat(value) : 1.0; | |
return value === 'auto' ? null : value; | |
} | |
function getRawStyle_IE(element, style) { | |
var value = element.style[style]; | |
if (!value && element.currentStyle) { | |
value = element.currentStyle[style]; | |
} | |
return value; | |
} | |
function getContentWidth(element, context) { | |
var boxWidth = element.offsetWidth; | |
var bl = getPixelValue(element, 'borderLeftWidth', context) || 0; | |
var br = getPixelValue(element, 'borderRightWidth', context) || 0; | |
var pl = getPixelValue(element, 'paddingLeft', context) || 0; | |
var pr = getPixelValue(element, 'paddingRight', context) || 0; | |
return boxWidth - bl - br - pl - pr; | |
} | |
if ('currentStyle' in document.documentElement) { | |
getRawStyle = getRawStyle_IE; | |
} | |
function getPixelValue(value, property, context) { | |
var element = null; | |
if (Object.isElement(value)) { | |
element = value; | |
value = getRawStyle(element, property); | |
} | |
if (value === null || Object.isUndefined(value)) { | |
return null; | |
} | |
if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { | |
return window.parseFloat(value); | |
} | |
var isPercentage = value.include('%'), isViewport = (context === document.viewport); | |
if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) { | |
var style = element.style.left, rStyle = element.runtimeStyle.left; | |
element.runtimeStyle.left = element.currentStyle.left; | |
element.style.left = value || 0; | |
value = element.style.pixelLeft; | |
element.style.left = style; | |
element.runtimeStyle.left = rStyle; | |
return value; | |
} | |
if (element && isPercentage) { | |
context = context || element.parentNode; | |
var decimal = toDecimal(value), whole = null; | |
var isHorizontal = property.include('left') || property.include('right') || | |
property.include('width'); | |
var isVertical = property.include('top') || property.include('bottom') || | |
property.include('height'); | |
if (context === document.viewport) { | |
if (isHorizontal) { | |
whole = document.viewport.getWidth(); | |
} else if (isVertical) { | |
whole = document.viewport.getHeight(); | |
} | |
} else { | |
if (isHorizontal) { | |
whole = $(context).measure('width'); | |
} else if (isVertical) { | |
whole = $(context).measure('height'); | |
} | |
} | |
return (whole === null) ? 0 : whole * decimal; | |
} | |
return 0; | |
} | |
function toCSSPixels(number) { | |
if (Object.isString(number) && number.endsWith('px')) | |
return number; | |
return number + 'px'; | |
} | |
function isDisplayed(element) { | |
while (element && element.parentNode) { | |
var display = element.getStyle('display'); | |
if (display === 'none') { | |
return false; | |
} | |
element = $(element.parentNode); | |
} | |
return true; | |
} | |
var hasLayout = Prototype.K; | |
if ('currentStyle' in document.documentElement) { | |
hasLayout = function(element) { | |
if (!element.currentStyle.hasLayout) { | |
element.style.zoom = 1; | |
} | |
return element; | |
}; | |
} | |
function cssNameFor(key) { | |
if (key.include('border')) key = key + '-width'; | |
return key.camelize(); | |
} | |
Element.Layout = Class.create(Hash, { | |
initialize: function($super, element, preCompute) { | |
$super(); | |
this.element = $(element); | |
Element.Layout.PROPERTIES.each( function(property) { | |
this._set(property, null); | |
}, this); | |
if (preCompute) { | |
this._preComputing = true; | |
this._begin(); | |
Element.Layout.PROPERTIES.each( this._compute, this ); | |
this._end(); | |
this._preComputing = false; | |
} | |
}, | |
_set: function(property, value) { | |
return Hash.prototype.set.call(this, property, value); | |
}, | |
set: function(property, value) { | |
throw "Properties of Element.Layout are read-only."; | |
}, | |
get: function($super, property) { | |
var value = $super(property); | |
return value === null ? this._compute(property) : value; | |
}, | |
_begin: function() { | |
if (this._isPrepared()) return; | |
var element = this.element; | |
if (isDisplayed(element)) { | |
this._setPrepared(true); | |
return; | |
} | |
var originalStyles = { | |
position: element.style.position || '', | |
width: element.style.width || '', | |
visibility: element.style.visibility || '', | |
display: element.style.display || '' | |
}; | |
element.store('prototype_original_styles', originalStyles); | |
var position = getRawStyle(element, 'position'), width = element.offsetWidth; | |
if (width === 0 || width === null) { | |
element.style.display = 'block'; | |
width = element.offsetWidth; | |
} | |
var context = (position === 'fixed') ? document.viewport : | |
element.parentNode; | |
var tempStyles = { | |
visibility: 'hidden', | |
display: 'block' | |
}; | |
if (position !== 'fixed') tempStyles.position = 'absolute'; | |
element.setStyle(tempStyles); | |
var positionedWidth = element.offsetWidth, newWidth; | |
if (width && (positionedWidth === width)) { | |
newWidth = getContentWidth(element, context); | |
} else if (position === 'absolute' || position === 'fixed') { | |
newWidth = getContentWidth(element, context); | |
} else { | |
var parent = element.parentNode, pLayout = $(parent).getLayout(); | |
newWidth = pLayout.get('width') - | |
this.get('margin-left') - | |
this.get('border-left') - | |
this.get('padding-left') - | |
this.get('padding-right') - | |
this.get('border-right') - | |
this.get('margin-right'); | |
} | |
element.setStyle({ width: newWidth + 'px' }); | |
this._setPrepared(true); | |
}, | |
_end: function() { | |
var element = this.element; | |
var originalStyles = element.retrieve('prototype_original_styles'); | |
element.store('prototype_original_styles', null); | |
element.setStyle(originalStyles); | |
this._setPrepared(false); | |
}, | |
_compute: function(property) { | |
var COMPUTATIONS = Element.Layout.COMPUTATIONS; | |
if (!(property in COMPUTATIONS)) { | |
throw "Property not found."; | |
} | |
return this._set(property, COMPUTATIONS[property].call(this, this.element)); | |
}, | |
_isPrepared: function() { | |
return this.element.retrieve('prototype_element_layout_prepared', false); | |
}, | |
_setPrepared: function(bool) { | |
return this.element.store('prototype_element_layout_prepared', bool); | |
}, | |
toObject: function() { | |
var args = $A(arguments); | |
var keys = (args.length === 0) ? Element.Layout.PROPERTIES : | |
args.join(' ').split(' '); | |
var obj = {}; | |
keys.each( function(key) { | |
if (!Element.Layout.PROPERTIES.include(key)) return; | |
var value = this.get(key); | |
if (value != null) obj[key] = value; | |
}, this); | |
return obj; | |
}, | |
toHash: function() { | |
var obj = this.toObject.apply(this, arguments); | |
return new Hash(obj); | |
}, | |
toCSS: function() { | |
var args = $A(arguments); | |
var keys = (args.length === 0) ? Element.Layout.PROPERTIES : | |
args.join(' ').split(' '); | |
var css = {}; | |
keys.each( function(key) { | |
if (!Element.Layout.PROPERTIES.include(key)) return; | |
if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; | |
var value = this.get(key); | |
if (value != null) css[cssNameFor(key)] = value + 'px'; | |
}, this); | |
return css; | |
}, | |
inspect: function() { | |
return "#<Element.Layout>"; | |
} | |
}); | |
Object.extend(Element.Layout, { | |
PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'), | |
COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'), | |
COMPUTATIONS: { | |
'height': function(element) { | |
if (!this._preComputing) this._begin(); | |
var bHeight = this.get('border-box-height'); | |
if (bHeight <= 0) { | |
if (!this._preComputing) this._end(); | |
return 0; | |
} | |
var bTop = this.get('border-top'), | |
bBottom = this.get('border-bottom'); | |
var pTop = this.get('padding-top'), | |
pBottom = this.get('padding-bottom'); | |
if (!this._preComputing) this._end(); | |
return bHeight - bTop - bBottom - pTop - pBottom; | |
}, | |
'width': function(element) { | |
if (!this._preComputing) this._begin(); | |
var bWidth = this.get('border-box-width'); | |
if (bWidth <= 0) { | |
if (!this._preComputing) this._end(); | |
return 0; | |
} | |
var bLeft = this.get('border-left'), | |
bRight = this.get('border-right'); | |
var pLeft = this.get('padding-left'), | |
pRight = this.get('padding-right'); | |
if (!this._preComputing) this._end(); | |
return bWidth - bLeft - bRight - pLeft - pRight; | |
}, | |
'padding-box-height': function(element) { | |
var height = this.get('height'), | |
pTop = this.get('padding-top'), | |
pBottom = this.get('padding-bottom'); | |
return height + pTop + pBottom; | |
}, | |
'padding-box-width': function(element) { | |
var width = this.get('width'), | |
pLeft = this.get('padding-left'), | |
pRight = this.get('padding-right'); | |
return width + pLeft + pRight; | |
}, | |
'border-box-height': function(element) { | |
if (!this._preComputing) this._begin(); | |
var height = element.offsetHeight; | |
if (!this._preComputing) this._end(); | |
return height; | |
}, | |
'border-box-width': function(element) { | |
if (!this._preComputing) this._begin(); | |
var width = element.offsetWidth; | |
if (!this._preComputing) this._end(); | |
return width; | |
}, | |
'margin-box-height': function(element) { | |
var bHeight = this.get('border-box-height'), | |
mTop = this.get('margin-top'), | |
mBottom = this.get('margin-bottom'); | |
if (bHeight <= 0) return 0; | |
return bHeight + mTop + mBottom; | |
}, | |
'margin-box-width': function(element) { | |
var bWidth = this.get('border-box-width'), | |
mLeft = this.get('margin-left'), | |
mRight = this.get('margin-right'); | |
if (bWidth <= 0) return 0; | |
return bWidth + mLeft + mRight; | |
}, | |
'top': function(element) { | |
var offset = element.positionedOffset(); | |
return offset.top; | |
}, | |
'bottom': function(element) { | |
var offset = element.positionedOffset(), | |
parent = element.getOffsetParent(), | |
pHeight = parent.measure('height'); | |
var mHeight = this.get('border-box-height'); | |
return pHeight - mHeight - offset.top; | |
}, | |
'left': function(element) { | |
var offset = element.positionedOffset(); | |
return offset.left; | |
}, | |
'right': function(element) { | |
var offset = element.positionedOffset(), | |
parent = element.getOffsetParent(), | |
pWidth = parent.measure('width'); | |
var mWidth = this.get('border-box-width'); | |
return pWidth - mWidth - offset.left; | |
}, | |
'padding-top': function(element) { | |
return getPixelValue(element, 'paddingTop'); | |
}, | |
'padding-bottom': function(element) { | |
return getPixelValue(element, 'paddingBottom'); | |
}, | |
'padding-left': function(element) { | |
return getPixelValue(element, 'paddingLeft'); | |
}, | |
'padding-right': function(element) { | |
return getPixelValue(element, 'paddingRight'); | |
}, | |
'border-top': function(element) { | |
return getPixelValue(element, 'borderTopWidth'); | |
}, | |
'border-bottom': function(element) { | |
return getPixelValue(element, 'borderBottomWidth'); | |
}, | |
'border-left': function(element) { | |
return getPixelValue(element, 'borderLeftWidth'); | |
}, | |
'border-right': function(element) { | |
return getPixelValue(element, 'borderRightWidth'); | |
}, | |
'margin-top': function(element) { | |
return getPixelValue(element, 'marginTop'); | |
}, | |
'margin-bottom': function(element) { | |
return getPixelValue(element, 'marginBottom'); | |
}, | |
'margin-left': function(element) { | |
return getPixelValue(element, 'marginLeft'); | |
}, | |
'margin-right': function(element) { | |
return getPixelValue(element, 'marginRight'); | |
} | |
} | |
}); | |
if ('getBoundingClientRect' in document.documentElement) { | |
Object.extend(Element.Layout.COMPUTATIONS, { | |
'right': function(element) { | |
var parent = hasLayout(element.getOffsetParent()); | |
var rect = element.getBoundingClientRect(), | |
pRect = parent.getBoundingClientRect(); | |
return (pRect.right - rect.right).round(); | |
}, | |
'bottom': function(element) { | |
var parent = hasLayout(element.getOffsetParent()); | |
var rect = element.getBoundingClientRect(), | |
pRect = parent.getBoundingClientRect(); | |
return (pRect.bottom - rect.bottom).round(); | |
} | |
}); | |
} | |
Element.Offset = Class.create({ | |
initialize: function(left, top) { | |
this.left = left.round(); | |
this.top = top.round(); | |
this[0] = this.left; | |
this[1] = this.top; | |
}, | |
relativeTo: function(offset) { | |
return new Element.Offset( | |
this.left - offset.left, | |
this.top - offset.top | |
); | |
}, | |
inspect: function() { | |
return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this); | |
}, | |
toString: function() { | |
return "[#{left}, #{top}]".interpolate(this); | |
}, | |
toArray: function() { | |
return [this.left, this.top]; | |
} | |
}); | |
function getLayout(element, preCompute) { | |
return new Element.Layout(element, preCompute); | |
} | |
function measure(element, property) { | |
return $(element).getLayout().get(property); | |
} | |
function getHeight(element) { | |
return Element.getDimensions(element).height; | |
} | |
function getWidth(element) { | |
return Element.getDimensions(element).width; | |
} | |
function getDimensions(element) { | |
element = $(element); | |
var display = Element.getStyle(element, 'display'); | |
if (display && display !== 'none') { | |
return { width: element.offsetWidth, height: element.offsetHeight }; | |
} | |
var style = element.style; | |
var originalStyles = { | |
visibility: style.visibility, | |
position: style.position, | |
display: style.display | |
}; | |
var newStyles = { | |
visibility: 'hidden', | |
display: 'block' | |
}; | |
if (originalStyles.position !== 'fixed') | |
newStyles.position = 'absolute'; | |
Element.setStyle(element, newStyles); | |
var dimensions = { | |
width: element.offsetWidth, | |
height: element.offsetHeight | |
}; | |
Element.setStyle(element, originalStyles); | |
return dimensions; | |
} | |
function getOffsetParent(element) { | |
element = $(element); | |
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) | |
return $(document.body); | |
var isInline = (Element.getStyle(element, 'display') === 'inline'); | |
if (!isInline && element.offsetParent) return $(element.offsetParent); | |
while ((element = element.parentNode) && element !== document.body) { | |
if (Element.getStyle(element, 'position') !== 'static') { | |
return isHtml(element) ? $(document.body) : $(element); | |
} | |
} | |
return $(document.body); | |
} | |
function cumulativeOffset(element) { | |
element = $(element); | |
var valueT = 0, valueL = 0; | |
if (element.parentNode) { | |
do { | |
valueT += element.offsetTop || 0; | |
valueL += element.offsetLeft || 0; | |
element = element.offsetParent; | |
} while (element); | |
} | |
return new Element.Offset(valueL, valueT); | |
} | |
function positionedOffset(element) { | |
element = $(element); | |
var layout = element.getLayout(); | |
var valueT = 0, valueL = 0; | |
do { | |
valueT += element.offsetTop || 0; | |
valueL += element.offsetLeft || 0; | |
element = element.offsetParent; | |
if (element) { | |
if (isBody(element)) break; | |
var p = Element.getStyle(element, 'position'); | |
if (p !== 'static') break; | |
} | |
} while (element); | |
valueL -= layout.get('margin-top'); | |
valueT -= layout.get('margin-left'); | |
return new Element.Offset(valueL, valueT); | |
} | |
function cumulativeScrollOffset(element) { | |
var valueT = 0, valueL = 0; | |
do { | |
if (element === document.body) { | |
var bodyScrollNode = document.documentElement || document.body.parentNode || document.body; | |
valueT += !Object.isUndefined(window.pageYOffset) ? window.pageYOffset : bodyScrollNode.scrollTop || 0; | |
valueL += !Object.isUndefined(window.pageXOffset) ? window.pageXOffset : bodyScrollNode.scrollLeft || 0; | |
break; | |
} else { | |
valueT += element.scrollTop || 0; | |
valueL += element.scrollLeft || 0; | |
element = element.parentNode; | |
} | |
} while (element); | |
return new Element.Offset(valueL, valueT); | |
} | |
function viewportOffset(forElement) { | |
var valueT = 0, valueL = 0, docBody = document.body; | |
forElement = $(forElement); | |
var element = forElement; | |
do { | |
valueT += element.offsetTop || 0; | |
valueL += element.offsetLeft || 0; | |
if (element.offsetParent == docBody && | |
Element.getStyle(element, 'position') == 'absolute') break; | |
} while (element = element.offsetParent); | |
element = forElement; | |
do { | |
if (element != docBody) { | |
valueT -= element.scrollTop || 0; | |
valueL -= element.scrollLeft || 0; | |
} | |
} while (element = element.parentNode); | |
return new Element.Offset(valueL, valueT); | |
} | |
function absolutize(element) { | |
element = $(element); | |
if (Element.getStyle(element, 'position') === 'absolute') { | |
return element; | |
} | |
var offsetParent = getOffsetParent(element); | |
var eOffset = element.viewportOffset(), | |
pOffset = offsetParent.viewportOffset(); | |
var offset = eOffset.relativeTo(pOffset); | |
var layout = element.getLayout(); | |
element.store('prototype_absolutize_original_styles', { | |
position: element.getStyle('position'), | |
left: element.getStyle('left'), | |
top: element.getStyle('top'), | |
width: element.getStyle('width'), | |
height: element.getStyle('height') | |
}); | |
element.setStyle({ | |
position: 'absolute', | |
top: offset.top + 'px', | |
left: offset.left + 'px', | |
width: layout.get('width') + 'px', | |
height: layout.get('height') + 'px' | |
}); | |
return element; | |
} | |
function relativize(element) { | |
element = $(element); | |
if (Element.getStyle(element, 'position') === 'relative') { | |
return element; | |
} | |
var originalStyles = | |
element.retrieve('prototype_absolutize_original_styles'); | |
if (originalStyles) element.setStyle(originalStyles); | |
return element; | |
} | |
function scrollTo(element) { | |
element = $(element); | |
var pos = Element.cumulativeOffset(element); | |
window.scrollTo(pos.left, pos.top); | |
return element; | |
} | |
function makePositioned(element) { | |
element = $(element); | |
var position = Element.getStyle(element, 'position'), styles = {}; | |
if (position === 'static' || !position) { | |
styles.position = 'relative'; | |
if (Prototype.Browser.Opera) { | |
styles.top = 0; | |
styles.left = 0; | |
} | |
Element.setStyle(element, styles); | |
Element.store(element, 'prototype_made_positioned', true); | |
} | |
return element; | |
} | |
function undoPositioned(element) { | |
element = $(element); | |
var storage = Element.getStorage(element), | |
madePositioned = storage.get('prototype_made_positioned'); | |
if (madePositioned) { | |
storage.unset('prototype_made_positioned'); | |
Element.setStyle(element, { | |
position: '', | |
top: '', | |
bottom: '', | |
left: '', | |
right: '' | |
}); | |
} | |
return element; | |
} | |
function makeClipping(element) { | |
element = $(element); | |
var storage = Element.getStorage(element), | |
madeClipping = storage.get('prototype_made_clipping'); | |
if (Object.isUndefined(madeClipping)) { | |
var overflow = Element.getStyle(element, 'overflow'); | |
storage.set('prototype_made_clipping', overflow); | |
if (overflow !== 'hidden') | |
element.style.overflow = 'hidden'; | |
} | |
return element; | |
} | |
function undoClipping(element) { | |
element = $(element); | |
var storage = Element.getStorage(element), | |
overflow = storage.get('prototype_made_clipping'); | |
if (!Object.isUndefined(overflow)) { | |
storage.unset('prototype_made_clipping'); | |
element.style.overflow = overflow || ''; | |
} | |
return element; | |
} | |
function clonePosition(element, source, options) { | |
options = Object.extend({ | |
setLeft: true, | |
setTop: true, | |
setWidth: true, | |
setHeight: true, | |
offsetTop: 0, | |
offsetLeft: 0 | |
}, options || {}); | |
source = $(source); | |
element = $(element); | |
var p, delta, layout, styles = {}; | |
if (options.setLeft || options.setTop) { | |
p = Element.viewportOffset(source); | |
delta = [0, 0]; | |
if (Element.getStyle(element, 'position') === 'absolute') { | |
var parent = Element.getOffsetParent(element); | |
if (parent !== document.body) delta = Element.viewportOffset(parent); | |
} | |
} | |
if (options.setWidth || options.setHeight) { | |
layout = Element.getLayout(source); | |
} | |
if (options.setLeft) | |
styles.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; | |
if (options.setTop) | |
styles.top = (p[1] - delta[1] + options.offsetTop) + 'px'; | |
if (options.setWidth) | |
styles.width = layout.get('border-box-width') + 'px'; | |
if (options.setHeight) | |
styles.height = layout.get('border-box-height') + 'px'; | |
return Element.setStyle(element, styles); | |
} | |
if (Prototype.Browser.IE) { | |
getOffsetParent = getOffsetParent.wrap( | |
function(proceed, element) { | |
element = $(element); | |
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) | |
return $(document.body); | |
var position = element.getStyle('position'); | |
if (position !== 'static') return proceed(element); | |
element.setStyle({ position: 'relative' }); | |
var value = proceed(element); | |
element.setStyle({ position: position }); | |
return value; | |
} | |
); | |
positionedOffset = positionedOffset.wrap(function(proceed, element) { | |
element = $(element); | |
if (!element.parentNode) return new Element.Offset(0, 0); | |
var position = element.getStyle('position'); | |
if (position !== 'static') return proceed(element); | |
var offsetParent = element.getOffsetParent(); | |
if (offsetParent && offsetParent.getStyle('position') === 'fixed') | |
hasLayout(offsetParent); | |
element.setStyle({ position: 'relative' }); | |
var value = proceed(element); | |
element.setStyle({ position: position }); | |
return value; | |
}); | |
} else if (Prototype.Browser.Webkit) { | |
cumulativeOffset = function(element) { | |
element = $(element); | |
var valueT = 0, valueL = 0; | |
do { | |
valueT += element.offsetTop || 0; | |
valueL += element.offsetLeft || 0; | |
if (element.offsetParent == document.body) { | |
if (Element.getStyle(element, 'position') == 'absolute') break; | |
} | |
element = element.offsetParent; | |
} while (element); | |
return new Element.Offset(valueL, valueT); | |
}; | |
} | |
Element.addMethods({ | |
getLayout: getLayout, | |
measure: measure, | |
getWidth: getWidth, | |
getHeight: getHeight, | |
getDimensions: getDimensions, | |
getOffsetParent: getOffsetParent, | |
cumulativeOffset: cumulativeOffset, | |
positionedOffset: positionedOffset, | |
cumulativeScrollOffset: cumulativeScrollOffset, | |
viewportOffset: viewportOffset, | |
absolutize: absolutize, | |
relativize: relativize, | |
scrollTo: scrollTo, | |
makePositioned: makePositioned, | |
undoPositioned: undoPositioned, | |
makeClipping: makeClipping, | |
undoClipping: undoClipping, | |
clonePosition: clonePosition | |
}); | |
function isBody(element) { | |
return element.nodeName.toUpperCase() === 'BODY'; | |
} | |
function isHtml(element) { | |
return element.nodeName.toUpperCase() === 'HTML'; | |
} | |
function isDocument(element) { | |
return element.nodeType === Node.DOCUMENT_NODE; | |
} | |
function isDetached(element) { | |
return element !== document.body && | |
!Element.descendantOf(element, document.body); | |
} | |
if ('getBoundingClientRect' in document.documentElement) { | |
Element.addMethods({ | |
viewportOffset: function(element) { | |
element = $(element); | |
if (isDetached(element)) return new Element.Offset(0, 0); | |
var rect = element.getBoundingClientRect(), | |
docEl = document.documentElement; | |
return new Element.Offset(rect.left - docEl.clientLeft, | |
rect.top - docEl.clientTop); | |
} | |
}); | |
} | |
})(); | |
(function() { | |
var IS_OLD_OPERA = Prototype.Browser.Opera && | |
(window.parseFloat(window.opera.version()) < 9.5); | |
var ROOT = null; | |
function getRootElement() { | |
if (ROOT) return ROOT; | |
ROOT = IS_OLD_OPERA ? document.body : document.documentElement; | |
return ROOT; | |
} | |
function getDimensions() { | |
return { width: this.getWidth(), height: this.getHeight() }; | |
} | |
function getWidth() { | |
return getRootElement().clientWidth; | |
} | |
function getHeight() { | |
return getRootElement().clientHeight; | |
} | |
function getScrollOffsets() { | |
var x = window.pageXOffset || document.documentElement.scrollLeft || | |
document.body.scrollLeft; | |
var y = window.pageYOffset || document.documentElement.scrollTop || | |
document.body.scrollTop; | |
return new Element.Offset(x, y); | |
} | |
document.viewport = { | |
getDimensions: getDimensions, | |
getWidth: getWidth, | |
getHeight: getHeight, | |
getScrollOffsets: getScrollOffsets | |
}; | |
})(); | |
window.$$ = function() { | |
var expression = $A(arguments).join(', '); | |
return Prototype.Selector.select(expression, document); | |
}; | |
Prototype.Selector = (function() { | |
function select() { | |
throw new Error('Method "Prototype.Selector.select" must be defined.'); | |
} | |
function match() { | |
throw new Error('Method "Prototype.Selector.match" must be defined.'); | |
} | |
function find(elements, expression, index) { | |
index = index || 0; | |
var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i; | |
for (i = 0; i < length; i++) { | |
if (match(elements[i], expression) && index == matchIndex++) { | |
return Element.extend(elements[i]); | |
} | |
} | |
} | |
function extendElements(elements) { | |
for (var i = 0, length = elements.length; i < length; i++) { | |
Element.extend(elements[i]); | |
} | |
return elements; | |
} | |
var K = Prototype.K; | |
return { | |
select: select, | |
match: match, | |
find: find, | |
extendElements: (Element.extend === K) ? K : extendElements, | |
extendElement: Element.extend | |
}; | |
})(); | |
Prototype._original_property = window.Sizzle; | |
/*! | |
* Sizzle CSS Selector Engine v@VERSION | |
* http://sizzlejs.com/ | |
* | |
* Copyright 2013 jQuery Foundation, Inc. and other contributors | |
* Released under the MIT license | |
* http://jquery.org/license | |
* | |
* Date: @DATE | |
*/ | |
(function( window ) { | |
var i, | |
support, | |
Expr, | |
getText, | |
isXML, | |
compile, | |
select, | |
outermostContext, | |
sortInput, | |
hasDuplicate, | |
setDocument, | |
document, | |
docElem, | |
documentIsHTML, | |
rbuggyQSA, | |
rbuggyMatches, | |
matches, | |
contains, | |
expando = "sizzle" + -(new Date()), | |
preferredDoc = window.document, | |
dirruns = 0, | |
done = 0, | |
classCache = createCache(), | |
tokenCache = createCache(), | |
compilerCache = createCache(), | |
sortOrder = function( a, b ) { | |
if ( a === b ) { | |
hasDuplicate = true; | |
} | |
return 0; | |
}, | |
strundefined = typeof undefined, | |
MAX_NEGATIVE = 1 << 31, | |
hasOwn = ({}).hasOwnProperty, | |
arr = [], | |
pop = arr.pop, | |
push_native = arr.push, | |
push = arr.push, | |
slice = arr.slice, | |
indexOf = arr.indexOf || function( elem ) { | |
var i = 0, | |
len = this.length; | |
for ( ; i < len; i++ ) { | |
if ( this[i] === elem ) { | |
return i; | |
} | |
} | |
return -1; | |
}, | |
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", | |
whitespace = "[\\x20\\t\\r\\n\\f]", | |
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", | |
identifier = characterEncoding.replace( "w", "w#" ), | |
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + | |
"*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", | |
pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", | |
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), | |
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), | |
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), | |
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), | |
rpseudo = new RegExp( pseudos ), | |
ridentifier = new RegExp( "^" + identifier + "$" ), | |
matchExpr = { | |
"ID": new RegExp( "^#(" + characterEncoding + ")" ), | |
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), | |
"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), | |
"ATTR": new RegExp( "^" + attributes ), | |
"PSEUDO": new RegExp( "^" + pseudos ), | |
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + | |
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + | |
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ), | |
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ), | |
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + | |
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) | |
}, | |
rinputs = /^(?:input|select|textarea|button)$/i, | |
rheader = /^h\d$/i, | |
rnative = /^[^{]+\{\s*\[native \w/, | |
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, | |
rsibling = /[+~]/, | |
rescape = /'|\\/g, | |
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), | |
funescape = function( _, escaped, escapedWhitespace ) { | |
var high = "0x" + escaped - 0x10000; | |
return high !== high || escapedWhitespace ? | |
escaped : | |
high < 0 ? | |
String.fromCharCode( high + 0x10000 ) : | |
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); | |
}; | |
try { | |
push.apply( | |
(arr = slice.call( preferredDoc.childNodes )), | |
preferredDoc.childNodes | |
); | |
arr[ preferredDoc.childNodes.length ].nodeType; | |
} catch ( e ) { | |
push = { apply: arr.length ? | |
function( target, els ) { | |
push_native.apply( target, slice.call(els) ); | |
} : | |
function( target, els ) { | |
var j = target.length, | |
i = 0; | |
while ( (target[j++] = els[i++]) ) {} | |
target.length = j - 1; | |
} | |
}; | |
} | |
function Sizzle( selector, context, results, seed ) { | |
var match, elem, m, nodeType, | |
i, groups, old, nid, newContext, newSelector; | |
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { | |
setDocument( context ); | |
} | |
context = context || document; | |
results = results || []; | |
if ( !selector || typeof selector !== "string" ) { | |
return results; | |
} | |
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { | |
return []; | |
} | |
if ( documentIsHTML && !seed ) { | |
if ( (match = rquickExpr.exec( selector )) ) { | |
if ( (m = match[1]) ) { | |
if ( nodeType === 9 ) { | |
elem = context.getElementById( m ); | |
if ( elem && elem.parentNode ) { | |
if ( elem.id === m ) { | |
results.push( elem ); | |
return results; | |
} | |
} else { | |
return results; | |
} | |
} else { | |
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && | |
contains( context, elem ) && elem.id === m ) { | |
results.push( elem ); | |
return results; | |
} | |
} | |
} else if ( match[2] ) { | |
push.apply( results, context.getElementsByTagName( selector ) ); | |
return results; | |
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { | |
push.apply( results, context.getElementsByClassName( m ) ); | |
return results; | |
} | |
} | |
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { | |
nid = old = expando; | |
newContext = context; | |
newSelector = nodeType === 9 && selector; | |
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { | |
groups = tokenize( selector ); | |
if ( (old = context.getAttribute("id")) ) { | |
nid = old.replace( rescape, "\\$&" ); | |
} else { | |
context.setAttribute( "id", nid ); | |
} | |
nid = "[id='" + nid + "'] "; | |
i = groups.length; | |
while ( i-- ) { | |
groups[i] = nid + toSelector( groups[i] ); | |
} | |
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; | |
newSelector = groups.join(","); | |
} | |
if ( newSelector ) { | |
try { | |
push.apply( results, | |
newContext.querySelectorAll( newSelector ) | |
); | |
return results; | |
} catch(qsaError) { | |
} finally { | |
if ( !old ) { | |
context.removeAttribute("id"); | |
} | |
} | |
} | |
} | |
} | |
return select( selector.replace( rtrim, "$1" ), context, results, seed ); | |
} | |
/** | |
* Create key-value caches of limited size | |
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with | |
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) | |
* deleting the oldest entry | |
*/ | |
function createCache() { | |
var keys = []; | |
function cache( key, value ) { | |
if ( keys.push( key + " " ) > Expr.cacheLength ) { | |
delete cache[ keys.shift() ]; | |
} | |
return (cache[ key + " " ] = value); | |
} | |
return cache; | |
} | |
/** | |
* Mark a function for special use by Sizzle | |
* @param {Function} fn The function to mark | |
*/ | |
function markFunction( fn ) { | |
fn[ expando ] = true; | |
return fn; | |
} | |
/** | |
* Support testing using an element | |
* @param {Function} fn Passed the created div and expects a boolean result | |
*/ | |
function assert( fn ) { | |
var div = document.createElement("div"); | |
try { | |
return !!fn( div ); | |
} catch (e) { | |
return false; | |
} finally { | |
if ( div.parentNode ) { | |
div.parentNode.removeChild( div ); | |
} | |
div = null; | |
} | |
} | |
/** | |
* Adds the same handler for all of the specified attrs | |
* @param {String} attrs Pipe-separated list of attributes | |
* @param {Function} handler The method that will be applied | |
*/ | |
function addHandle( attrs, handler ) { | |
var arr = attrs.split("|"), | |
i = attrs.length; | |
while ( i-- ) { | |
Expr.attrHandle[ arr[i] ] = handler; | |
} | |
} | |
/** | |
* Checks document order of two siblings | |
* @param {Element} a | |
* @param {Element} b | |
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b | |
*/ | |
function siblingCheck( a, b ) { | |
var cur = b && a, | |
diff = cur && a.nodeType === 1 && b.nodeType === 1 && | |
( ~b.sourceIndex || MAX_NEGATIVE ) - | |
( ~a.sourceIndex || MAX_NEGATIVE ); | |
if ( diff ) { | |
return diff; | |
} | |
if ( cur ) { | |
while ( (cur = cur.nextSibling) ) { | |
if ( cur === b ) { | |
return -1; | |
} | |
} | |
} | |
return a ? 1 : -1; | |
} | |
/** | |
* Returns a function to use in pseudos for input types | |
* @param {String} type | |
*/ | |
function createInputPseudo( type ) { | |
return function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return name === "input" && elem.type === type; | |
}; | |
} | |
/** | |
* Returns a function to use in pseudos for buttons | |
* @param {String} type | |
*/ | |
function createButtonPseudo( type ) { | |
return function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return (name === "input" || name === "button") && elem.type === type; | |
}; | |
} | |
/** | |
* Returns a function to use in pseudos for positionals | |
* @param {Function} fn | |
*/ | |
function createPositionalPseudo( fn ) { | |
return markFunction(function( argument ) { | |
argument = +argument; | |
return markFunction(function( seed, matches ) { | |
var j, | |
matchIndexes = fn( [], seed.length, argument ), | |
i = matchIndexes.length; | |
while ( i-- ) { | |
if ( seed[ (j = matchIndexes[i]) ] ) { | |
seed[j] = !(matches[j] = seed[j]); | |
} | |
} | |
}); | |
}); | |
} | |
/** | |
* Checks a node for validity as a Sizzle context | |
* @param {Element|Object=} context | |
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value | |
*/ | |
function testContext( context ) { | |
return context && typeof context.getElementsByTagName !== strundefined && context; | |
} | |
support = Sizzle.support = {}; | |
/** | |
* Detects XML nodes | |
* @param {Element|Object} elem An element or a document | |
* @returns {Boolean} True iff elem is a non-HTML XML node | |
*/ | |
isXML = Sizzle.isXML = function( elem ) { | |
var documentElement = elem && (elem.ownerDocument || elem).documentElement; | |
return documentElement ? documentElement.nodeName !== "HTML" : false; | |
}; | |
/** | |
* Sets document-related variables once based on the current document | |
* @param {Element|Object} [doc] An element or document object to use to set the document | |
* @returns {Object} Returns the current document | |
*/ | |
setDocument = Sizzle.setDocument = function( node ) { | |
var hasCompare, | |
doc = node ? node.ownerDocument || node : preferredDoc, | |
parent = doc.defaultView; | |
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { | |
return document; | |
} | |
document = doc; | |
docElem = doc.documentElement; | |
documentIsHTML = !isXML( doc ); | |
if ( parent && parent !== parent.top ) { | |
if ( parent.addEventListener ) { | |
parent.addEventListener( "unload", function() { | |
setDocument(); | |
}, false ); | |
} else if ( parent.attachEvent ) { | |
parent.attachEvent( "onunload", function() { | |
setDocument(); | |
}); | |
} | |
} | |
/* Attributes | |
---------------------------------------------------------------------- */ | |
support.attributes = assert(function( div ) { | |
div.className = "i"; | |
return !div.getAttribute("className"); | |
}); | |
/* getElement(s)By* | |
---------------------------------------------------------------------- */ | |
support.getElementsByTagName = assert(function( div ) { | |
div.appendChild( doc.createComment("") ); | |
return !div.getElementsByTagName("*").length; | |
}); | |
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { | |
div.innerHTML = "<div class='a'></div><div class='a i'></div>"; | |
div.firstChild.className = "i"; | |
return div.getElementsByClassName("i").length === 2; | |
}); | |
support.getById = assert(function( div ) { | |
docElem.appendChild( div ).id = expando; | |
return !doc.getElementsByName || !doc.getElementsByName( expando ).length; | |
}); | |
if ( support.getById ) { | |
Expr.find["ID"] = function( id, context ) { | |
if ( typeof context.getElementById !== strundefined && documentIsHTML ) { | |
var m = context.getElementById( id ); | |
return m && m.parentNode ? [m] : []; | |
} | |
}; | |
Expr.filter["ID"] = function( id ) { | |
var attrId = id.replace( runescape, funescape ); | |
return function( elem ) { | |
return elem.getAttribute("id") === attrId; | |
}; | |
}; | |
} else { | |
delete Expr.find["ID"]; | |
Expr.filter["ID"] = function( id ) { | |
var attrId = id.replace( runescape, funescape ); | |
return function( elem ) { | |
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); | |
return node && node.value === attrId; | |
}; | |
}; | |
} | |
Expr.find["TAG"] = support.getElementsByTagName ? | |
function( tag, context ) { | |
if ( typeof context.getElementsByTagName !== strundefined ) { | |
return context.getElementsByTagName( tag ); | |
} | |
} : | |
function( tag, context ) { | |
var elem, | |
tmp = [], | |
i = 0, | |
results = context.getElementsByTagName( tag ); | |
if ( tag === "*" ) { | |
while ( (elem = results[i++]) ) { | |
if ( elem.nodeType === 1 ) { | |
tmp.push( elem ); | |
} | |
} | |
return tmp; | |
} | |
return results; | |
}; | |
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { | |
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { | |
return context.getElementsByClassName( className ); | |
} | |
}; | |
/* QSA/matchesSelector | |
---------------------------------------------------------------------- */ | |
rbuggyMatches = []; | |
rbuggyQSA = []; | |
if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { | |
assert(function( div ) { | |
div.innerHTML = "<select t=''><option selected=''></option></select>"; | |
if ( div.querySelectorAll("[t^='']").length ) { | |
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); | |
} | |
if ( !div.querySelectorAll("[selected]").length ) { | |
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); | |
} | |
if ( !div.querySelectorAll(":checked").length ) { | |
rbuggyQSA.push(":checked"); | |
} | |
}); | |
assert(function( div ) { | |
var input = doc.createElement("input"); | |
input.setAttribute( "type", "hidden" ); | |
div.appendChild( input ).setAttribute( "name", "D" ); | |
if ( div.querySelectorAll("[name=d]").length ) { | |
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); | |
} | |
if ( !div.querySelectorAll(":enabled").length ) { | |
rbuggyQSA.push( ":enabled", ":disabled" ); | |
} | |
div.querySelectorAll("*,:x"); | |
rbuggyQSA.push(",.*:"); | |
}); | |
} | |
if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || | |
docElem.mozMatchesSelector || | |
docElem.oMatchesSelector || | |
docElem.msMatchesSelector) )) ) { | |
assert(function( div ) { | |
support.disconnectedMatch = matches.call( div, "div" ); | |
matches.call( div, "[s!='']:x" ); | |
rbuggyMatches.push( "!=", pseudos ); | |
}); | |
} | |
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); | |
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); | |
/* Contains | |
---------------------------------------------------------------------- */ | |
hasCompare = rnative.test( docElem.compareDocumentPosition ); | |
contains = hasCompare || rnative.test( docElem.contains ) ? | |
function( a, b ) { | |
var adown = a.nodeType === 9 ? a.documentElement : a, | |
bup = b && b.parentNode; | |
return a === bup || !!( bup && bup.nodeType === 1 && ( | |
adown.contains ? | |
adown.contains( bup ) : | |
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 | |
)); | |
} : | |
function( a, b ) { | |
if ( b ) { | |
while ( (b = b.parentNode) ) { | |
if ( b === a ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
}; | |
/* Sorting | |
---------------------------------------------------------------------- */ | |
sortOrder = hasCompare ? | |
function( a, b ) { | |
if ( a === b ) { | |
hasDuplicate = true; | |
return 0; | |
} | |
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; | |
if ( compare ) { | |
return compare; | |
} | |
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? | |
a.compareDocumentPosition( b ) : | |
1; | |
if ( compare & 1 || | |
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { | |
if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { | |
return -1; | |
} | |
if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { | |
return 1; | |
} | |
return sortInput ? | |
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : | |
0; | |
} | |
return compare & 4 ? -1 : 1; | |
} : | |
function( a, b ) { | |
if ( a === b ) { | |
hasDuplicate = true; | |
return 0; | |
} | |
var cur, | |
i = 0, | |
aup = a.parentNode, | |
bup = b.parentNode, | |
ap = [ a ], | |
bp = [ b ]; | |
if ( !aup || !bup ) { | |
return a === doc ? -1 : | |
b === doc ? 1 : | |
aup ? -1 : | |
bup ? 1 : | |
sortInput ? | |
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : | |
0; | |
} else if ( aup === bup ) { | |
return siblingCheck( a, b ); | |
} | |
cur = a; | |
while ( (cur = cur.parentNode) ) { | |
ap.unshift( cur ); | |
} | |
cur = b; | |
while ( (cur = cur.parentNode) ) { | |
bp.unshift( cur ); | |
} | |
while ( ap[i] === bp[i] ) { | |
i++; | |
} | |
return i ? | |
siblingCheck( ap[i], bp[i] ) : | |
ap[i] === preferredDoc ? -1 : | |
bp[i] === preferredDoc ? 1 : | |
0; | |
}; | |
return doc; | |
}; | |
Sizzle.matches = function( expr, elements ) { | |
return Sizzle( expr, null, null, elements ); | |
}; | |
Sizzle.matchesSelector = function( elem, expr ) { | |
if ( ( elem.ownerDocument || elem ) !== document ) { | |
setDocument( elem ); | |
} | |
expr = expr.replace( rattributeQuotes, "='$1']" ); | |
if ( support.matchesSelector && documentIsHTML && | |
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && | |
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { | |
try { | |
var ret = matches.call( elem, expr ); | |
if ( ret || support.disconnectedMatch || | |
elem.document && elem.document.nodeType !== 11 ) { | |
return ret; | |
} | |
} catch(e) {} | |
} | |
return Sizzle( expr, document, null, [elem] ).length > 0; | |
}; | |
Sizzle.contains = function( context, elem ) { | |
if ( ( context.ownerDocument || context ) !== document ) { | |
setDocument( context ); | |
} | |
return contains( context, elem ); | |
}; | |
Sizzle.attr = function( elem, name ) { | |
if ( ( elem.ownerDocument || elem ) !== document ) { | |
setDocument( elem ); | |
} | |
var fn = Expr.attrHandle[ name.toLowerCase() ], | |
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? | |
fn( elem, name, !documentIsHTML ) : | |
undefined; | |
return val !== undefined ? | |
val : | |
support.attributes || !documentIsHTML ? | |
elem.getAttribute( name ) : | |
(val = elem.getAttributeNode(name)) && val.specified ? | |
val.value : | |
null; | |
}; | |
Sizzle.error = function( msg ) { | |
throw new Error( "Syntax error, unrecognized expression: " + msg ); | |
}; | |
/** | |
* Document sorting and removing duplicates | |
* @param {ArrayLike} results | |
*/ | |
Sizzle.uniqueSort = function( results ) { | |
var elem, | |
duplicates = [], | |
j = 0, | |
i = 0; | |
hasDuplicate = !support.detectDuplicates; | |
sortInput = !support.sortStable && results.slice( 0 ); | |
results.sort( sortOrder ); | |
if ( hasDuplicate ) { | |
while ( (elem = results[i++]) ) { | |
if ( elem === results[ i ] ) { | |
j = duplicates.push( i ); | |
} | |
} | |
while ( j-- ) { | |
results.splice( duplicates[ j ], 1 ); | |
} | |
} | |
sortInput = null; | |
return results; | |
}; | |
/** | |
* Utility function for retrieving the text value of an array of DOM nodes | |
* @param {Array|Element} elem | |
*/ | |
getText = Sizzle.getText = function( elem ) { | |
var node, | |
ret = "", | |
i = 0, | |
nodeType = elem.nodeType; | |
if ( !nodeType ) { | |
while ( (node = elem[i++]) ) { | |
ret += getText( node ); | |
} | |
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { | |
if ( typeof elem.textContent === "string" ) { | |
return elem.textContent; | |
} else { | |
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { | |
ret += getText( elem ); | |
} | |
} | |
} else if ( nodeType === 3 || nodeType === 4 ) { | |
return elem.nodeValue; | |
} | |
return ret; | |
}; | |
Expr = Sizzle.selectors = { | |
cacheLength: 50, | |
createPseudo: markFunction, | |
match: matchExpr, | |
attrHandle: {}, | |
find: {}, | |
relative: { | |
">": { dir: "parentNode", first: true }, | |
" ": { dir: "parentNode" }, | |
"+": { dir: "previousSibling", first: true }, | |
"~": { dir: "previousSibling" } | |
}, | |
preFilter: { | |
"ATTR": function( match ) { | |
match[1] = match[1].replace( runescape, funescape ); | |
match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); | |
if ( match[2] === "~=" ) { | |
match[3] = " " + match[3] + " "; | |
} | |
return match.slice( 0, 4 ); | |
}, | |
"CHILD": function( match ) { | |
/* matches from matchExpr["CHILD"] | |
1 type (only|nth|...) | |
2 what (child|of-type) | |
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) | |
4 xn-component of xn+y argument ([+-]?\d*n|) | |
5 sign of xn-component | |
6 x of xn-component | |
7 sign of y-component | |
8 y of y-component | |
*/ | |
match[1] = match[1].toLowerCase(); | |
if ( match[1].slice( 0, 3 ) === "nth" ) { | |
if ( !match[3] ) { | |
Sizzle.error( match[0] ); | |
} | |
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); | |
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); | |
} else if ( match[3] ) { | |
Sizzle.error( match[0] ); | |
} | |
return match; | |
}, | |
"PSEUDO": function( match ) { | |
var excess, | |
unquoted = !match[5] && match[2]; | |
if ( matchExpr["CHILD"].test( match[0] ) ) { | |
return null; | |
} | |
if ( match[3] && match[4] !== undefined ) { | |
match[2] = match[4]; | |
} else if ( unquoted && rpseudo.test( unquoted ) && | |
(excess = tokenize( unquoted, true )) && | |
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { | |
match[0] = match[0].slice( 0, excess ); | |
match[2] = unquoted.slice( 0, excess ); | |
} | |
return match.slice( 0, 3 ); | |
} | |
}, | |
filter: { | |
"TAG": function( nodeNameSelector ) { | |
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); | |
return nodeNameSelector === "*" ? | |
function() { return true; } : | |
function( elem ) { | |
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; | |
}; | |
}, | |
"CLASS": function( className ) { | |
var pattern = classCache[ className + " " ]; | |
return pattern || | |
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && | |
classCache( className, function( elem ) { | |
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); | |
}); | |
}, | |
"ATTR": function( name, operator, check ) { | |
return function( elem ) { | |
var result = Sizzle.attr( elem, name ); | |
if ( result == null ) { | |
return operator === "!="; | |
} | |
if ( !operator ) { | |
return true; | |
} | |
result += ""; | |
return operator === "=" ? result === check : | |
operator === "!=" ? result !== check : | |
operator === "^=" ? check && result.indexOf( check ) === 0 : | |
operator === "*=" ? check && result.indexOf( check ) > -1 : | |
operator === "$=" ? check && result.slice( -check.length ) === check : | |
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : | |
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : | |
false; | |
}; | |
}, | |
"CHILD": function( type, what, argument, first, last ) { | |
var simple = type.slice( 0, 3 ) !== "nth", | |
forward = type.slice( -4 ) !== "last", | |
ofType = what === "of-type"; | |
return first === 1 && last === 0 ? | |
function( elem ) { | |
return !!elem.parentNode; | |
} : | |
function( elem, context, xml ) { | |
var cache, outerCache, node, diff, nodeIndex, start, | |
dir = simple !== forward ? "nextSibling" : "previousSibling", | |
parent = elem.parentNode, | |
name = ofType && elem.nodeName.toLowerCase(), | |
useCache = !xml && !ofType; | |
if ( parent ) { | |
if ( simple ) { | |
while ( dir ) { | |
node = elem; | |
while ( (node = node[ dir ]) ) { | |
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { | |
return false; | |
} | |
} | |
start = dir = type === "only" && !start && "nextSibling"; | |
} | |
return true; | |
} | |
start = [ forward ? parent.firstChild : parent.lastChild ]; | |
if ( forward && useCache ) { | |
outerCache = parent[ expando ] || (parent[ expando ] = {}); | |
cache = outerCache[ type ] || []; | |
nodeIndex = cache[0] === dirruns && cache[1]; | |
diff = cache[0] === dirruns && cache[2]; | |
node = nodeIndex && parent.childNodes[ nodeIndex ]; | |
while ( (node = ++nodeIndex && node && node[ dir ] || | |
(diff = nodeIndex = 0) || start.pop()) ) { | |
if ( node.nodeType === 1 && ++diff && node === elem ) { | |
outerCache[ type ] = [ dirruns, nodeIndex, diff ]; | |
break; | |
} | |
} | |
} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { | |
diff = cache[1]; | |
} else { | |
while ( (node = ++nodeIndex && node && node[ dir ] || | |
(diff = nodeIndex = 0) || start.pop()) ) { | |
if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { | |
if ( useCache ) { | |
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; | |
} | |
if ( node === elem ) { | |
break; | |
} | |
} | |
} | |
} | |
diff -= last; | |
return diff === first || ( diff % first === 0 && diff / first >= 0 ); | |
} | |
}; | |
}, | |
"PSEUDO": function( pseudo, argument ) { | |
var args, | |
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || | |
Sizzle.error( "unsupported pseudo: " + pseudo ); | |
if ( fn[ expando ] ) { | |
return fn( argument ); | |
} | |
if ( fn.length > 1 ) { | |
args = [ pseudo, pseudo, "", argument ]; | |
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? | |
markFunction(function( seed, matches ) { | |
var idx, | |
matched = fn( seed, argument ), | |
i = matched.length; | |
while ( i-- ) { | |
idx = indexOf.call( seed, matched[i] ); | |
seed[ idx ] = !( matches[ idx ] = matched[i] ); | |
} | |
}) : | |
function( elem ) { | |
return fn( elem, 0, args ); | |
}; | |
} | |
return fn; | |
} | |
}, | |
pseudos: { | |
"not": markFunction(function( selector ) { | |
var input = [], | |
results = [], | |
matcher = compile( selector.replace( rtrim, "$1" ) ); | |
return matcher[ expando ] ? | |
markFunction(function( seed, matches, context, xml ) { | |
var elem, | |
unmatched = matcher( seed, null, xml, [] ), | |
i = seed.length; | |
while ( i-- ) { | |
if ( (elem = unmatched[i]) ) { | |
seed[i] = !(matches[i] = elem); | |
} | |
} | |
}) : | |
function( elem, context, xml ) { | |
input[0] = elem; | |
matcher( input, null, xml, results ); | |
return !results.pop(); | |
}; | |
}), | |
"has": markFunction(function( selector ) { | |
return function( elem ) { | |
return Sizzle( selector, elem ).length > 0; | |
}; | |
}), | |
"contains": markFunction(function( text ) { | |
return function( elem ) { | |
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; | |
}; | |
}), | |
"lang": markFunction( function( lang ) { | |
if ( !ridentifier.test(lang || "") ) { | |
Sizzle.error( "unsupported lang: " + lang ); | |
} | |
lang = lang.replace( runescape, funescape ).toLowerCase(); | |
return function( elem ) { | |
var elemLang; | |
do { | |
if ( (elemLang = documentIsHTML ? | |
elem.lang : | |
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { | |
elemLang = elemLang.toLowerCase(); | |
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; | |
} | |
} while ( (elem = elem.parentNode) && elem.nodeType === 1 ); | |
return false; | |
}; | |
}), | |
"target": function( elem ) { | |
var hash = window.location && window.location.hash; | |
return hash && hash.slice( 1 ) === elem.id; | |
}, | |
"root": function( elem ) { | |
return elem === docElem; | |
}, | |
"focus": function( elem ) { | |
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); | |
}, | |
"enabled": function( elem ) { | |
return elem.disabled === false; | |
}, | |
"disabled": function( elem ) { | |
return elem.disabled === true; | |
}, | |
"checked": function( elem ) { | |
var nodeName = elem.nodeName.toLowerCase(); | |
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); | |
}, | |
"selected": function( elem ) { | |
if ( elem.parentNode ) { | |
elem.parentNode.selectedIndex; | |
} | |
return elem.selected === true; | |
}, | |
"empty": function( elem ) { | |
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { | |
if ( elem.nodeType < 6 ) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
"parent": function( elem ) { | |
return !Expr.pseudos["empty"]( elem ); | |
}, | |
"header": function( elem ) { | |
return rheader.test( elem.nodeName ); | |
}, | |
"input": function( elem ) { | |
return rinputs.test( elem.nodeName ); | |
}, | |
"button": function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return name === "input" && elem.type === "button" || name === "button"; | |
}, | |
"text": function( elem ) { | |
var attr; | |
return elem.nodeName.toLowerCase() === "input" && | |
elem.type === "text" && | |
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); | |
}, | |
"first": createPositionalPseudo(function() { | |
return [ 0 ]; | |
}), | |
"last": createPositionalPseudo(function( matchIndexes, length ) { | |
return [ length - 1 ]; | |
}), | |
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
return [ argument < 0 ? argument + length : argument ]; | |
}), | |
"even": createPositionalPseudo(function( matchIndexes, length ) { | |
var i = 0; | |
for ( ; i < length; i += 2 ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"odd": createPositionalPseudo(function( matchIndexes, length ) { | |
var i = 1; | |
for ( ; i < length; i += 2 ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
var i = argument < 0 ? argument + length : argument; | |
for ( ; --i >= 0; ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
var i = argument < 0 ? argument + length : argument; | |
for ( ; ++i < length; ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}) | |
} | |
}; | |
Expr.pseudos["nth"] = Expr.pseudos["eq"]; | |
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { | |
Expr.pseudos[ i ] = createInputPseudo( i ); | |
} | |
for ( i in { submit: true, reset: true } ) { | |
Expr.pseudos[ i ] = createButtonPseudo( i ); | |
} | |
function setFilters() {} | |
setFilters.prototype = Expr.filters = Expr.pseudos; | |
Expr.setFilters = new setFilters(); | |
function tokenize( selector, parseOnly ) { | |
var matched, match, tokens, type, | |
soFar, groups, preFilters, | |
cached = tokenCache[ selector + " " ]; | |
if ( cached ) { | |
return parseOnly ? 0 : cached.slice( 0 ); | |
} | |
soFar = selector; | |
groups = []; | |
preFilters = Expr.preFilter; | |
while ( soFar ) { | |
if ( !matched || (match = rcomma.exec( soFar )) ) { | |
if ( match ) { | |
soFar = soFar.slice( match[0].length ) || soFar; | |
} | |
groups.push( (tokens = []) ); | |
} | |
matched = false; | |
if ( (match = rcombinators.exec( soFar )) ) { | |
matched = match.shift(); | |
tokens.push({ | |
value: matched, | |
type: match[0].replace( rtrim, " " ) | |
}); | |
soFar = soFar.slice( matched.length ); | |
} | |
for ( type in Expr.filter ) { | |
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || | |
(match = preFilters[ type ]( match ))) ) { | |
matched = match.shift(); | |
tokens.push({ | |
value: matched, | |
type: type, | |
matches: match | |
}); | |
soFar = soFar.slice( matched.length ); | |
} | |
} | |
if ( !matched ) { | |
break; | |
} | |
} | |
return parseOnly ? | |
soFar.length : | |
soFar ? | |
Sizzle.error( selector ) : | |
tokenCache( selector, groups ).slice( 0 ); | |
} | |
function toSelector( tokens ) { | |
var i = 0, | |
len = tokens.length, | |
selector = ""; | |
for ( ; i < len; i++ ) { | |
selector += tokens[i].value; | |
} | |
return selector; | |
} | |
function addCombinator( matcher, combinator, base ) { | |
var dir = combinator.dir, | |
checkNonElements = base && dir === "parentNode", | |
doneName = done++; | |
return combinator.first ? | |
function( elem, context, xml ) { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
return matcher( elem, context, xml ); | |
} | |
} | |
} : | |
function( elem, context, xml ) { | |
var oldCache, outerCache, | |
newCache = [ dirruns, doneName ]; | |
if ( xml ) { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
if ( matcher( elem, context, xml ) ) { | |
return true; | |
} | |
} | |
} | |
} else { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
outerCache = elem[ expando ] || (elem[ expando ] = {}); | |
if ( (oldCache = outerCache[ dir ]) && | |
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { | |
return (newCache[ 2 ] = oldCache[ 2 ]); | |
} else { | |
outerCache[ dir ] = newCache; | |
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { | |
return true; | |
} | |
} | |
} | |
} | |
} | |
}; | |
} | |
function elementMatcher( matchers ) { | |
return matchers.length > 1 ? | |
function( elem, context, xml ) { | |
var i = matchers.length; | |
while ( i-- ) { | |
if ( !matchers[i]( elem, context, xml ) ) { | |
return false; | |
} | |
} | |
return true; | |
} : | |
matchers[0]; | |
} | |
function multipleContexts( selector, contexts, results ) { | |
var i = 0, | |
len = contexts.length; | |
for ( ; i < len; i++ ) { | |
Sizzle( selector, contexts[i], results ); | |
} | |
return results; | |
} | |
function condense( unmatched, map, filter, context, xml ) { | |
var elem, | |
newUnmatched = [], | |
i = 0, | |
len = unmatched.length, | |
mapped = map != null; | |
for ( ; i < len; i++ ) { | |
if ( (elem = unmatched[i]) ) { | |
if ( !filter || filter( elem, context, xml ) ) { | |
newUnmatched.push( elem ); | |
if ( mapped ) { | |
map.push( i ); | |
} | |
} | |
} | |
} | |
return newUnmatched; | |
} | |
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { | |
if ( postFilter && !postFilter[ expando ] ) { | |
postFilter = setMatcher( postFilter ); | |
} | |
if ( postFinder && !postFinder[ expando ] ) { | |
postFinder = setMatcher( postFinder, postSelector ); | |
} | |
return markFunction(function( seed, results, context, xml ) { | |
var temp, i, elem, | |
preMap = [], | |
postMap = [], | |
preexisting = results.length, | |
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), | |
matcherIn = preFilter && ( seed || !selector ) ? | |
condense( elems, preMap, preFilter, context, xml ) : | |
elems, | |
matcherOut = matcher ? | |
postFinder || ( seed ? preFilter : preexisting || postFilter ) ? | |
[] : | |
results : | |
matcherIn; | |
if ( matcher ) { | |
matcher( matcherIn, matcherOut, context, xml ); | |
} | |
if ( postFilter ) { | |
temp = condense( matcherOut, postMap ); | |
postFilter( temp, [], context, xml ); | |
i = temp.length; | |
while ( i-- ) { | |
if ( (elem = temp[i]) ) { | |
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); | |
} | |
} | |
} | |
if ( seed ) { | |
if ( postFinder || preFilter ) { | |
if ( postFinder ) { | |
temp = []; | |
i = matcherOut.length; | |
while ( i-- ) { | |
if ( (elem = matcherOut[i]) ) { | |
temp.push( (matcherIn[i] = elem) ); | |
} | |
} | |
postFinder( null, (matcherOut = []), temp, xml ); | |
} | |
i = matcherOut.length; | |
while ( i-- ) { | |
if ( (elem = matcherOut[i]) && | |
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { | |
seed[temp] = !(results[temp] = elem); | |
} | |
} | |
} | |
} else { | |
matcherOut = condense( | |
matcherOut === results ? | |
matcherOut.splice( preexisting, matcherOut.length ) : | |
matcherOut | |
); | |
if ( postFinder ) { | |
postFinder( null, results, matcherOut, xml ); | |
} else { | |
push.apply( results, matcherOut ); | |
} | |
} | |
}); | |
} | |
function matcherFromTokens( tokens ) { | |
var checkContext, matcher, j, | |
len = tokens.length, | |
leadingRelative = Expr.relative[ tokens[0].type ], | |
implicitRelative = leadingRelative || Expr.relative[" "], | |
i = leadingRelative ? 1 : 0, | |
matchContext = addCombinator( function( elem ) { | |
return elem === checkContext; | |
}, implicitRelative, true ), | |
matchAnyContext = addCombinator( function( elem ) { | |
return indexOf.call( checkContext, elem ) > -1; | |
}, implicitRelative, true ), | |
matchers = [ function( elem, context, xml ) { | |
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( | |
(checkContext = context).nodeType ? | |
matchContext( elem, context, xml ) : | |
matchAnyContext( elem, context, xml ) ); | |
} ]; | |
for ( ; i < len; i++ ) { | |
if ( (matcher = Expr.relative[ tokens[i].type ]) ) { | |
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; | |
} else { | |
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); | |
if ( matcher[ expando ] ) { | |
j = ++i; | |
for ( ; j < len; j++ ) { | |
if ( Expr.relative[ tokens[j].type ] ) { | |
break; | |
} | |
} | |
return setMatcher( | |
i > 1 && elementMatcher( matchers ), | |
i > 1 && toSelector( | |
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) | |
).replace( rtrim, "$1" ), | |
matcher, | |
i < j && matcherFromTokens( tokens.slice( i, j ) ), | |
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), | |
j < len && toSelector( tokens ) | |
); | |
} | |
matchers.push( matcher ); | |
} | |
} | |
return elementMatcher( matchers ); | |
} | |
function matcherFromGroupMatchers( elementMatchers, setMatchers ) { | |
var bySet = setMatchers.length > 0, | |
byElement = elementMatchers.length > 0, | |
superMatcher = function( seed, context, xml, results, outermost ) { | |
var elem, j, matcher, | |
matchedCount = 0, | |
i = "0", | |
unmatched = seed && [], | |
setMatched = [], | |
contextBackup = outermostContext, | |
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), | |
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), | |
len = elems.length; | |
if ( outermost ) { | |
outermostContext = context !== document && context; | |
} | |
for ( ; i !== len && (elem = elems[i]) != null; i++ ) { | |
if ( byElement && elem ) { | |
j = 0; | |
while ( (matcher = elementMatchers[j++]) ) { | |
if ( matcher( elem, context, xml ) ) { | |
results.push( elem ); | |
break; | |
} | |
} | |
if ( outermost ) { | |
dirruns = dirrunsUnique; | |
} | |
} | |
if ( bySet ) { | |
if ( (elem = !matcher && elem) ) { | |
matchedCount--; | |
} | |
if ( seed ) { | |
unmatched.push( elem ); | |
} | |
} | |
} | |
matchedCount += i; | |
if ( bySet && i !== matchedCount ) { | |
j = 0; | |
while ( (matcher = setMatchers[j++]) ) { | |
matcher( unmatched, setMatched, context, xml ); | |
} | |
if ( seed ) { | |
if ( matchedCount > 0 ) { | |
while ( i-- ) { | |
if ( !(unmatched[i] || setMatched[i]) ) { | |
setMatched[i] = pop.call( results ); | |
} | |
} | |
} | |
setMatched = condense( setMatched ); | |
} | |
push.apply( results, setMatched ); | |
if ( outermost && !seed && setMatched.length > 0 && | |
( matchedCount + setMatchers.length ) > 1 ) { | |
Sizzle.uniqueSort( results ); | |
} | |
} | |
if ( outermost ) { | |
dirruns = dirrunsUnique; | |
outermostContext = contextBackup; | |
} | |
return unmatched; | |
}; | |
return bySet ? | |
markFunction( superMatcher ) : | |
superMatcher; | |
} | |
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { | |
var i, | |
setMatchers = [], | |
elementMatchers = [], | |
cached = compilerCache[ selector + " " ]; | |
if ( !cached ) { | |
if ( !match ) { | |
match = tokenize( selector ); | |
} | |
i = match.length; | |
while ( i-- ) { | |
cached = matcherFromTokens( match[i] ); | |
if ( cached[ expando ] ) { | |
setMatchers.push( cached ); | |
} else { | |
elementMatchers.push( cached ); | |
} | |
} | |
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); | |
cached.selector = selector; | |
} | |
return cached; | |
}; | |
/** | |
* A low-level selection function that works with Sizzle's compiled | |
* selector functions | |
* @param {String|Function} selector A selector or a pre-compiled | |
* selector function built with Sizzle.compile | |
* @param {Element} context | |
* @param {Array} [results] | |
* @param {Array} [seed] A set of elements to match against | |
*/ | |
select = Sizzle.select = function( selector, context, results, seed ) { | |
var i, tokens, token, type, find, | |
compiled = typeof selector === "function" && selector, | |
match = !seed && tokenize( (selector = compiled.selector || selector) ); | |
results = results || []; | |
if ( match.length === 1 ) { | |
tokens = match[0] = match[0].slice( 0 ); | |
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && | |
support.getById && context.nodeType === 9 && documentIsHTML && | |
Expr.relative[ tokens[1].type ] ) { | |
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; | |
if ( !context ) { | |
return results; | |
} else if ( compiled ) { | |
context = context.parentNode; | |
} | |
selector = selector.slice( tokens.shift().value.length ); | |
} | |
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; | |
while ( i-- ) { | |
token = tokens[i]; | |
if ( Expr.relative[ (type = token.type) ] ) { | |
break; | |
} | |
if ( (find = Expr.find[ type ]) ) { | |
if ( (seed = find( | |
token.matches[0].replace( runescape, funescape ), | |
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context | |
)) ) { | |
tokens.splice( i, 1 ); | |
selector = seed.length && toSelector( tokens ); | |
if ( !selector ) { | |
push.apply( results, seed ); | |
return results; | |
} | |
break; | |
} | |
} | |
} | |
} | |
( compiled || compile( selector, match ) )( | |
seed, | |
context, | |
!documentIsHTML, | |
results, | |
rsibling.test( selector ) && testContext( context.parentNode ) || context | |
); | |
return results; | |
}; | |
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; | |
support.detectDuplicates = !!hasDuplicate; | |
setDocument(); | |
support.sortDetached = assert(function( div1 ) { | |
return div1.compareDocumentPosition( document.createElement("div") ) & 1; | |
}); | |
if ( !assert(function( div ) { | |
div.innerHTML = "<a href='#'></a>"; | |
return div.firstChild.getAttribute("href") === "#" ; | |
}) ) { | |
addHandle( "type|href|height|width", function( elem, name, isXML ) { | |
if ( !isXML ) { | |
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); | |
} | |
}); | |
} | |
if ( !support.attributes || !assert(function( div ) { | |
div.innerHTML = "<input/>"; | |
div.firstChild.setAttribute( "value", "" ); | |
return div.firstChild.getAttribute( "value" ) === ""; | |
}) ) { | |
addHandle( "value", function( elem, name, isXML ) { | |
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { | |
return elem.defaultValue; | |
} | |
}); | |
} | |
if ( !assert(function( div ) { | |
return div.getAttribute("disabled") == null; | |
}) ) { | |
addHandle( booleans, function( elem, name, isXML ) { | |
var val; | |
if ( !isXML ) { | |
return elem[ name ] === true ? name.toLowerCase() : | |
(val = elem.getAttributeNode( name )) && val.specified ? | |
val.value : | |
null; | |
} | |
}); | |
} | |
if ( typeof define === "function" && define.amd ) { | |
define(function() { return Sizzle; }); | |
} else if ( typeof module !== "undefined" && module.exports ) { | |
module.exports = Sizzle; | |
} else { | |
window.Sizzle = Sizzle; | |
} | |
})( window ); | |
;(function(engine) { | |
var extendElements = Prototype.Selector.extendElements; | |
function select(selector, scope) { | |
return extendElements(engine(selector, scope || document)); | |
} | |
function match(element, selector) { | |
return engine.matches(selector, [element]).length == 1; | |
} | |
Prototype.Selector.engine = engine; | |
Prototype.Selector.select = select; | |
Prototype.Selector.match = match; | |
})(Sizzle); | |
window.Sizzle = Prototype._original_property; | |
delete Prototype._original_property; | |
var Form = { | |
reset: function(form) { | |
form = $(form); | |
form.reset(); | |
return form; | |
}, | |
serializeElements: function(elements, options) { | |
if (typeof options != 'object') options = { hash: !!options }; | |
else if (Object.isUndefined(options.hash)) options.hash = true; | |
var key, value, submitted = false, submit = options.submit, accumulator, initial; | |
if (options.hash) { | |
initial = {}; | |
accumulator = function(result, key, value) { | |
if (key in result) { | |
if (!Object.isArray(result[key])) result[key] = [result[key]]; | |
result[key] = result[key].concat(value); | |
} else result[key] = value; | |
return result; | |
}; | |
} else { | |
initial = ''; | |
accumulator = function(result, key, values) { | |
if (!Object.isArray(values)) {values = [values];} | |
if (!values.length) {return result;} | |
var encodedKey = encodeURIComponent(key).gsub(/%20/, '+'); | |
return result + (result ? "&" : "") + values.map(function (value) { | |
value = value.gsub(/(\r)?\n/, '\r\n'); | |
value = encodeURIComponent(value); | |
value = value.gsub(/%20/, '+'); | |
return encodedKey + "=" + value; | |
}).join("&"); | |
}; | |
} | |
return elements.inject(initial, function(result, element) { | |
if (!element.disabled && element.name) { | |
key = element.name; value = $(element).getValue(); | |
if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && | |
submit !== false && (!submit || key == submit) && (submitted = true)))) { | |
result = accumulator(result, key, value); | |
} | |
} | |
return result; | |
}); | |
} | |
}; | |
Form.Methods = { | |
serialize: function(form, options) { | |
return Form.serializeElements(Form.getElements(form), options); | |
}, | |
getElements: function(form) { | |
var elements = $(form).getElementsByTagName('*'); | |
var element, results = [], serializers = Form.Element.Serializers; | |
for (var i = 0; element = elements[i]; i++) { | |
if (serializers[element.tagName.toLowerCase()]) | |
results.push(Element.extend(element)); | |
} | |
return results; | |
}, | |
getInputs: function(form, typeName, name) { | |
form = $(form); | |
var inputs = form.getElementsByTagName('input'); | |
if (!typeName && !name) return $A(inputs).map(Element.extend); | |
for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { | |
var input = inputs[i]; | |
if ((typeName && input.type != typeName) || (name && input.name != name)) | |
continue; | |
matchingInputs.push(Element.extend(input)); | |
} | |
return matchingInputs; | |
}, | |
disable: function(form) { | |
form = $(form); | |
Form.getElements(form).invoke('disable'); | |
return form; | |
}, | |
enable: function(form) { | |
form = $(form); | |
Form.getElements(form).invoke('enable'); | |
return form; | |
}, | |
findFirstElement: function(form) { | |
var elements = $(form).getElements().findAll(function(element) { | |
return 'hidden' != element.type && !element.disabled; | |
}); | |
var firstByIndex = elements.findAll(function(element) { | |
return element.hasAttribute('tabIndex') && element.tabIndex >= 0; | |
}).sortBy(function(element) { return element.tabIndex }).first(); | |
return firstByIndex ? firstByIndex : elements.find(function(element) { | |
return /^(?:input|select|textarea)$/i.test(element.tagName); | |
}); | |
}, | |
focusFirstElement: function(form) { | |
form = $(form); | |
var element = form.findFirstElement(); | |
if (element) element.activate(); | |
return form; | |
}, | |
request: function(form, options) { | |
form = $(form), options = Object.clone(options || { }); | |
var params = options.parameters, action = form.readAttribute('action') || ''; | |
if (action.blank()) action = window.location.href; | |
options.parameters = form.serialize(true); | |
if (params) { | |
if (Object.isString(params)) params = params.toQueryParams(); | |
Object.extend(options.parameters, params); | |
} | |
if (form.hasAttribute('method') && !options.method) | |
options.method = form.method; | |
return new Ajax.Request(action, options); | |
} | |
}; | |
/*--------------------------------------------------------------------------*/ | |
Form.Element = { | |
focus: function(element) { | |
$(element).focus(); | |
return element; | |
}, | |
select: function(element) { | |
$(element).select(); | |
return element; | |
} | |
}; | |
Form.Element.Methods = { | |
serialize: function(element) { | |
element = $(element); | |
if (!element.disabled && element.name) { | |
var value = element.getValue(); | |
if (value != undefined) { | |
var pair = { }; | |
pair[element.name] = value; | |
return Object.toQueryString(pair); | |
} | |
} | |
return ''; | |
}, | |
getValue: function(element) { | |
element = $(element); | |
var method = element.tagName.toLowerCase(); | |
return Form.Element.Serializers[method](element); | |
}, | |
setValue: function(element, value) { | |
element = $(element); | |
var method = element.tagName.toLowerCase(); | |
Form.Element.Serializers[method](element, value); | |
return element; | |
}, | |
clear: function(element) { | |
$(element).value = ''; | |
return element; | |
}, | |
present: function(element) { | |
return $(element).value != ''; | |
}, | |
activate: function(element) { | |
element = $(element); | |
try { | |
element.focus(); | |
if (element.select && (element.tagName.toLowerCase() != 'input' || | |
!(/^(?:button|reset|submit)$/i.test(element.type)))) | |
element.select(); | |
} catch (e) { } | |
return element; | |
}, | |
disable: function(element) { | |
element = $(element); | |
element.disabled = true; | |
return element; | |
}, | |
enable: function(element) { | |
element = $(element); | |
element.disabled = false; | |
return element; | |
} | |
}; | |
/*--------------------------------------------------------------------------*/ | |
var Field = Form.Element; | |
var $F = Form.Element.Methods.getValue; | |
/*--------------------------------------------------------------------------*/ | |
Form.Element.Serializers = (function() { | |
function input(element, value) { | |
switch (element.type.toLowerCase()) { | |
case 'checkbox': | |
case 'radio': | |
return inputSelector(element, value); | |
default: | |
return valueSelector(element, value); | |
} | |
} | |
function inputSelector(element, value) { | |
if (Object.isUndefined(value)) | |
return element.checked ? element.value : null; | |
else element.checked = !!value; | |
} | |
function valueSelector(element, value) { | |
if (Object.isUndefined(value)) return element.value; | |
else element.value = value; | |
} | |
function select(element, value) { | |
if (Object.isUndefined(value)) | |
return (element.type === 'select-one' ? selectOne : selectMany)(element); | |
var opt, currentValue, single = !Object.isArray(value); | |
for (var i = 0, length = element.length; i < length; i++) { | |
opt = element.options[i]; | |
currentValue = this.optionValue(opt); | |
if (single) { | |
if (currentValue == value) { | |
opt.selected = true; | |
return; | |
} | |
} | |
else opt.selected = value.include(currentValue); | |
} | |
} | |
function selectOne(element) { | |
var index = element.selectedIndex; | |
return index >= 0 ? optionValue(element.options[index]) : null; | |
} | |
function selectMany(element) { | |
var values, length = element.length; | |
if (!length) return null; | |
for (var i = 0, values = []; i < length; i++) { | |
var opt = element.options[i]; | |
if (opt.selected) values.push(optionValue(opt)); | |
} | |
return values; | |
} | |
function optionValue(opt) { | |
return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; | |
} | |
return { | |
input: input, | |
inputSelector: inputSelector, | |
textarea: valueSelector, | |
select: select, | |
selectOne: selectOne, | |
selectMany: selectMany, | |
optionValue: optionValue, | |
button: valueSelector | |
}; | |
})(); | |
/*--------------------------------------------------------------------------*/ | |
Abstract.TimedObserver = Class.create(PeriodicalExecuter, { | |
initialize: function($super, element, frequency, callback) { | |
$super(callback, frequency); | |
this.element = $(element); | |
this.lastValue = this.getValue(); | |
}, | |
execute: function() { | |
var value = this.getValue(); | |
if (Object.isString(this.lastValue) && Object.isString(value) ? | |
this.lastValue != value : String(this.lastValue) != String(value)) { | |
this.callback(this.element, value); | |
this.lastValue = value; | |
} | |
} | |
}); | |
Form.Element.Observer = Class.create(Abstract.TimedObserver, { | |
getValue: function() { | |
return Form.Element.getValue(this.element); | |
} | |
}); | |
Form.Observer = Class.create(Abstract.TimedObserver, { | |
getValue: function() { | |
return Form.serialize(this.element); | |
} | |
}); | |
/*--------------------------------------------------------------------------*/ | |
Abstract.EventObserver = Class.create({ | |
initialize: function(element, callback) { | |
this.element = $(element); | |
this.callback = callback; | |
this.lastValue = this.getValue(); | |
if (this.element.tagName.toLowerCase() == 'form') | |
this.registerFormCallbacks(); | |
else | |
this.registerCallback(this.element); | |
}, | |
onElementEvent: function() { | |
var value = this.getValue(); | |
if (this.lastValue != value) { | |
this.callback(this.element, value); | |
this.lastValue = value; | |
} | |
}, | |
registerFormCallbacks: function() { | |
Form.getElements(this.element).each(this.registerCallback, this); | |
}, | |
registerCallback: function(element) { | |
if (element.type) { | |
switch (element.type.toLowerCase()) { | |
case 'checkbox': | |
case 'radio': | |
Event.observe(element, 'click', this.onElementEvent.bind(this)); | |
break; | |
default: | |
Event.observe(element, 'change', this.onElementEvent.bind(this)); | |
break; | |
} | |
} | |
} | |
}); | |
Form.Element.EventObserver = Class.create(Abstract.EventObserver, { | |
getValue: function() { | |
return Form.Element.getValue(this.element); | |
} | |
}); | |
Form.EventObserver = Class.create(Abstract.EventObserver, { | |
getValue: function() { | |
return Form.serialize(this.element); | |
} | |
}); | |
(function(GLOBAL) { | |
var DIV = document.createElement('div'); | |
var docEl = document.documentElement; | |
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl | |
&& 'onmouseleave' in docEl; | |
var Event = { | |
KEY_BACKSPACE: 8, | |
KEY_TAB: 9, | |
KEY_RETURN: 13, | |
KEY_ESC: 27, | |
KEY_LEFT: 37, | |
KEY_UP: 38, | |
KEY_RIGHT: 39, | |
KEY_DOWN: 40, | |
KEY_DELETE: 46, | |
KEY_HOME: 36, | |
KEY_END: 35, | |
KEY_PAGEUP: 33, | |
KEY_PAGEDOWN: 34, | |
KEY_INSERT: 45 | |
}; | |
var isIELegacyEvent = function(event) { return false; }; | |
if (window.attachEvent) { | |
if (window.addEventListener) { | |
isIELegacyEvent = function(event) { | |
return !(event instanceof window.Event); | |
}; | |
} else { | |
isIELegacyEvent = function(event) { return true; }; | |
} | |
} | |
var _isButton; | |
function _isButtonForDOMEvents(event, code) { | |
return event.which ? (event.which === code + 1) : (event.button === code); | |
} | |
var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; | |
function _isButtonForLegacyEvents(event, code) { | |
return event.button === legacyButtonMap[code]; | |
} | |
function _isButtonForWebKit(event, code) { | |
switch (code) { | |
case 0: return event.which == 1 && !event.metaKey; | |
case 1: return event.which == 2 || (event.which == 1 && event.metaKey); | |
case 2: return event.which == 3; | |
default: return false; | |
} | |
} | |
if (window.attachEvent) { | |
if (!window.addEventListener) { | |
_isButton = _isButtonForLegacyEvents; | |
} else { | |
_isButton = function(event, code) { | |
return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : | |
_isButtonForDOMEvents(event, code); | |
} | |
} | |
} else if (Prototype.Browser.WebKit) { | |
_isButton = _isButtonForWebKit; | |
} else { | |
_isButton = _isButtonForDOMEvents; | |
} | |
function isLeftClick(event) { return _isButton(event, 0) } | |
function isMiddleClick(event) { return _isButton(event, 1) } | |
function isRightClick(event) { return _isButton(event, 2) } | |
function element(event) { | |
return Element.extend(_element(event)); | |
} | |
function _element(event) { | |
event = Event.extend(event); | |
var node = event.target, type = event.type, | |
currentTarget = event.currentTarget; | |
if (currentTarget && currentTarget.tagName) { | |
if (type === 'load' || type === 'error' || | |
(type === 'click' && currentTarget.tagName.toLowerCase() === 'input' | |
&& currentTarget.type === 'radio')) | |
node = currentTarget; | |
} | |
return node.nodeType == Node.TEXT_NODE ? node.parentNode : node; | |
} | |
function findElement(event, expression) { | |
var element = _element(event), selector = Prototype.Selector; | |
if (!expression) return Element.extend(element); | |
while (element) { | |
if (Object.isElement(element) && selector.match(element, expression)) | |
return Element.extend(element); | |
element = element.parentNode; | |
} | |
} | |
function pointer(event) { | |
return { x: pointerX(event), y: pointerY(event) }; | |
} | |
function pointerX(event) { | |
var docElement = document.documentElement, | |
body = document.body || { scrollLeft: 0 }; | |
return event.pageX || (event.clientX + | |
(docElement.scrollLeft || body.scrollLeft) - | |
(docElement.clientLeft || 0)); | |
} | |
function pointerY(event) { | |
var docElement = document.documentElement, | |
body = document.body || { scrollTop: 0 }; | |
return event.pageY || (event.clientY + | |
(docElement.scrollTop || body.scrollTop) - | |
(docElement.clientTop || 0)); | |
} | |
function stop(event) { | |
Event.extend(event); | |
event.preventDefault(); | |
event.stopPropagation(); | |
event.stopped = true; | |
} | |
Event.Methods = { | |
isLeftClick: isLeftClick, | |
isMiddleClick: isMiddleClick, | |
isRightClick: isRightClick, | |
element: element, | |
findElement: findElement, | |
pointer: pointer, | |
pointerX: pointerX, | |
pointerY: pointerY, | |
stop: stop | |
}; | |
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { | |
m[name] = Event.Methods[name].methodize(); | |
return m; | |
}); | |
if (window.attachEvent) { | |
function _relatedTarget(event) { | |
var element; | |
switch (event.type) { | |
case 'mouseover': | |
case 'mouseenter': | |
element = event.fromElement; | |
break; | |
case 'mouseout': | |
case 'mouseleave': | |
element = event.toElement; | |
break; | |
default: | |
return null; | |
} | |
return Element.extend(element); | |
} | |
var additionalMethods = { | |
stopPropagation: function() { this.cancelBubble = true }, | |
preventDefault: function() { this.returnValue = false }, | |
inspect: function() { return '[object Event]' } | |
}; | |
Event.extend = function(event, element) { | |
if (!event) return false; | |
if (!isIELegacyEvent(event)) return event; | |
if (event._extendedByPrototype) return event; | |
event._extendedByPrototype = Prototype.emptyFunction; | |
var pointer = Event.pointer(event); | |
Object.extend(event, { | |
target: event.srcElement || element, | |
relatedTarget: _relatedTarget(event), | |
pageX: pointer.x, | |
pageY: pointer.y | |
}); | |
Object.extend(event, methods); | |
Object.extend(event, additionalMethods); | |
return event; | |
}; | |
} else { | |
Event.extend = Prototype.K; | |
} | |
if (window.addEventListener) { | |
Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; | |
Object.extend(Event.prototype, methods); | |
} | |
var EVENT_TRANSLATIONS = { | |
mouseenter: 'mouseover', | |
mouseleave: 'mouseout' | |
}; | |
function getDOMEventName(eventName) { | |
return EVENT_TRANSLATIONS[eventName] || eventName; | |
} | |
if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) | |
getDOMEventName = Prototype.K; | |
function getUniqueElementID(element) { | |
if (element === window) return 0; | |
if (typeof element._prototypeUID === 'undefined') | |
element._prototypeUID = Element.Storage.UID++; | |
return element._prototypeUID; | |
} | |
function getUniqueElementID_IE(element) { | |
if (element === window) return 0; | |
if (element == document) return 1; | |
return element.uniqueID; | |
} | |
if ('uniqueID' in DIV) | |
getUniqueElementID = getUniqueElementID_IE; | |
function isCustomEvent(eventName) { | |
return eventName.include(':'); | |
} | |
Event._isCustomEvent = isCustomEvent; | |
function getRegistryForElement(element, uid) { | |
var CACHE = GLOBAL.Event.cache; | |
if (Object.isUndefined(uid)) | |
uid = getUniqueElementID(element); | |
if (!CACHE[uid]) CACHE[uid] = { element: element }; | |
return CACHE[uid]; | |
} | |
function destroyRegistryForElement(element, uid) { | |
if (Object.isUndefined(uid)) | |
uid = getUniqueElementID(element); | |
delete GLOBAL.Event.cache[uid]; | |
} | |
function register(element, eventName, handler) { | |
var registry = getRegistryForElement(element); | |
if (!registry[eventName]) registry[eventName] = []; | |
var entries = registry[eventName]; | |
var i = entries.length; | |
while (i--) | |
if (entries[i].handler === handler) return null; | |
var uid = getUniqueElementID(element); | |
var responder = GLOBAL.Event._createResponder(uid, eventName, handler); | |
var entry = { | |
responder: responder, | |
handler: handler | |
}; | |
entries.push(entry); | |
return entry; | |
} | |
function unregister(element, eventName, handler) { | |
var registry = getRegistryForElement(element); | |
var entries = registry[eventName]; | |
if (!entries) return; | |
var i = entries.length, entry; | |
while (i--) { | |
if (entries[i].handler === handler) { | |
entry = entries[i]; | |
break; | |
} | |
} | |
if (!entry) return; | |
var index = entries.indexOf(entry); | |
entries.splice(index, 1); | |
return entry; | |
} | |
function observe(element, eventName, handler) { | |
element = $(element); | |
var entry = register(element, eventName, handler); | |
if (entry === null) return element; | |
var responder = entry.responder; | |
if (isCustomEvent(eventName)) | |
observeCustomEvent(element, eventName, responder); | |
else | |
observeStandardEvent(element, eventName, responder); | |
return element; | |
} | |
function observeStandardEvent(element, eventName, responder) { | |
var actualEventName = getDOMEventName(eventName); | |
if (element.addEventListener) { | |
element.addEventListener(actualEventName, responder, false); | |
} else { | |
element.attachEvent('on' + actualEventName, responder); | |
} | |
} | |
function observeCustomEvent(element, eventName, responder) { | |
if (element.addEventListener) { | |
element.addEventListener('dataavailable', responder, false); | |
} else { | |
element.attachEvent('ondataavailable', responder); | |
element.attachEvent('onlosecapture', responder); | |
} | |
} | |
function stopObserving(element, eventName, handler) { | |
element = $(element); | |
var handlerGiven = !Object.isUndefined(handler), | |
eventNameGiven = !Object.isUndefined(eventName); | |
if (!eventNameGiven && !handlerGiven) { | |
stopObservingElement(element); | |
return element; | |
} | |
if (!handlerGiven) { | |
stopObservingEventName(element, eventName); | |
return element; | |
} | |
var entry = unregister(element, eventName, handler); | |
if (!entry) return element; | |
removeEvent(element, eventName, entry.responder); | |
return element; | |
} | |
function stopObservingStandardEvent(element, eventName, responder) { | |
var actualEventName = getDOMEventName(eventName); | |
if (element.removeEventListener) { | |
element.removeEventListener(actualEventName, responder, false); | |
} else { | |
element.detachEvent('on' + actualEventName, responder); | |
} | |
} | |
function stopObservingCustomEvent(element, eventName, responder) { | |
if (element.removeEventListener) { | |
element.removeEventListener('dataavailable', responder, false); | |
} else { | |
element.detachEvent('ondataavailable', responder); | |
element.detachEvent('onlosecapture', responder); | |
} | |
} | |
function stopObservingElement(element) { | |
var uid = getUniqueElementID(element), registry = GLOBAL.Event.cache[uid]; | |
if (!registry) return; | |
destroyRegistryForElement(element, uid); | |
var entries, i; | |
for (var eventName in registry) { | |
if (eventName === 'element') continue; | |
entries = registry[eventName]; | |
i = entries.length; | |
while (i--) | |
removeEvent(element, eventName, entries[i].responder); | |
} | |
} | |
function stopObservingEventName(element, eventName) { | |
var registry = getRegistryForElement(element); | |
var entries = registry[eventName]; | |
if (!entries) return; | |
delete registry[eventName]; | |
var i = entries.length; | |
while (i--) | |
removeEvent(element, eventName, entries[i].responder); | |
} | |
function removeEvent(element, eventName, handler) { | |
if (isCustomEvent(eventName)) | |
stopObservingCustomEvent(element, eventName, handler); | |
else | |
stopObservingStandardEvent(element, eventName, handler); | |
} | |
function getFireTarget(element) { | |
if (element !== document) return element; | |
if (document.createEvent && !element.dispatchEvent) | |
return document.documentElement; | |
return element; | |
} | |
function fire(element, eventName, memo, bubble) { | |
element = getFireTarget($(element)); | |
if (Object.isUndefined(bubble)) bubble = true; | |
memo = memo || {}; | |
var event = fireEvent(element, eventName, memo, bubble); | |
return Event.extend(event); | |
} | |
function fireEvent_DOM(element, eventName, memo, bubble) { | |
var event = document.createEvent('HTMLEvents'); | |
event.initEvent('dataavailable', bubble, true); | |
event.eventName = eventName; | |
event.memo = memo; | |
element.dispatchEvent(event); | |
return event; | |
} | |
function fireEvent_IE(element, eventName, memo, bubble) { | |
var event = document.createEventObject(); | |
event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; | |
event.eventName = eventName; | |
event.memo = memo; | |
element.fireEvent(event.eventType, event); | |
return event; | |
} | |
var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE; | |
Event.Handler = Class.create({ | |
initialize: function(element, eventName, selector, callback) { | |
this.element = $(element); | |
this.eventName = eventName; | |
this.selector = selector; | |
this.callback = callback; | |
this.handler = this.handleEvent.bind(this); | |
}, | |
start: function() { | |
Event.observe(this.element, this.eventName, this.handler); | |
return this; | |
}, | |
stop: function() { | |
Event.stopObserving(this.element, this.eventName, this.handler); | |
return this; | |
}, | |
handleEvent: function(event) { | |
var element = Event.findElement(event, this.selector); | |
if (element) this.callback.call(this.element, event, element); | |
} | |
}); | |
function on(element, eventName, selector, callback) { | |
element = $(element); | |
if (Object.isFunction(selector) && Object.isUndefined(callback)) { | |
callback = selector, selector = null; | |
} | |
return new Event.Handler(element, eventName, selector, callback).start(); | |
} | |
Object.extend(Event, Event.Methods); | |
Object.extend(Event, { | |
fire: fire, | |
observe: observe, | |
stopObserving: stopObserving, | |
on: on | |
}); | |
Element.addMethods({ | |
fire: fire, | |
observe: observe, | |
stopObserving: stopObserving, | |
on: on | |
}); | |
Object.extend(document, { | |
fire: fire.methodize(), | |
observe: observe.methodize(), | |
stopObserving: stopObserving.methodize(), | |
on: on.methodize(), | |
loaded: false | |
}); | |
if (GLOBAL.Event) Object.extend(window.Event, Event); | |
else GLOBAL.Event = Event; | |
GLOBAL.Event.cache = {}; | |
function destroyCache_IE() { | |
GLOBAL.Event.cache = null; | |
} | |
if (window.attachEvent) | |
window.attachEvent('onunload', destroyCache_IE); | |
DIV = null; | |
docEl = null; | |
})(this); | |
(function(GLOBAL) { | |
/* Code for creating leak-free event responders is based on work by | |
John-David Dalton. */ | |
var docEl = document.documentElement; | |
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl | |
&& 'onmouseleave' in docEl; | |
function isSimulatedMouseEnterLeaveEvent(eventName) { | |
return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && | |
(eventName === 'mouseenter' || eventName === 'mouseleave'); | |
} | |
function createResponder(uid, eventName, handler) { | |
if (Event._isCustomEvent(eventName)) | |
return createResponderForCustomEvent(uid, eventName, handler); | |
if (isSimulatedMouseEnterLeaveEvent(eventName)) | |
return createMouseEnterLeaveResponder(uid, eventName, handler); | |
return function(event) { | |
if (!Event.cache) return; | |
var element = Event.cache[uid].element; | |
Event.extend(event, element); | |
handler.call(element, event); | |
}; | |
} | |
function createResponderForCustomEvent(uid, eventName, handler) { | |
return function(event) { | |
var element = Event.cache[uid].element; | |
if (Object.isUndefined(event.eventName)) | |
return false; | |
if (event.eventName !== eventName) | |
return false; | |
Event.extend(event, element); | |
handler.call(element, event); | |
}; | |
} | |
function createMouseEnterLeaveResponder(uid, eventName, handler) { | |
return function(event) { | |
var element = Event.cache[uid].element; | |
Event.extend(event, element); | |
var parent = event.relatedTarget; | |
while (parent && parent !== element) { | |
try { parent = parent.parentNode; } | |
catch(e) { parent = element; } | |
} | |
if (parent === element) return; | |
handler.call(element, event); | |
} | |
} | |
GLOBAL.Event._createResponder = createResponder; | |
docEl = null; | |
})(this); | |
(function(GLOBAL) { | |
/* Support for the DOMContentLoaded event is based on work by Dan Webb, | |
Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ | |
var TIMER; | |
function fireContentLoadedEvent() { | |
if (document.loaded) return; | |
if (TIMER) window.clearTimeout(TIMER); | |
document.loaded = true; | |
document.fire('dom:loaded'); | |
} | |
function checkReadyState() { | |
if (document.readyState === 'complete') { | |
document.detachEvent('onreadystatechange', checkReadyState); | |
fireContentLoadedEvent(); | |
} | |
} | |
function pollDoScroll() { | |
try { | |
document.documentElement.doScroll('left'); | |
} catch (e) { | |
TIMER = pollDoScroll.defer(); | |
return; | |
} | |
fireContentLoadedEvent(); | |
} | |
if (document.readyState === 'complete') { | |
fireContentLoadedEvent(); | |
return; | |
} | |
if (document.addEventListener) { | |
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); | |
} else { | |
document.attachEvent('onreadystatechange', checkReadyState); | |
if (window == top) TIMER = pollDoScroll.defer(); | |
} | |
Event.observe(window, 'load', fireContentLoadedEvent); | |
})(this); | |
Element.addMethods(); | |
/*------------------------------- DEPRECATED -------------------------------*/ | |
Hash.toQueryString = Object.toQueryString; | |
var Toggle = { display: Element.toggle }; | |
Element.Methods.childOf = Element.Methods.descendantOf; | |
var Insertion = { | |
Before: function(element, content) { | |
return Element.insert(element, {before:content}); | |
}, | |
Top: function(element, content) { | |
return Element.insert(element, {top:content}); | |
}, | |
Bottom: function(element, content) { | |
return Element.insert(element, {bottom:content}); | |
}, | |
After: function(element, content) { | |
return Element.insert(element, {after:content}); | |
} | |
}; | |
var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); | |
var Position = { | |
includeScrollOffsets: false, | |
prepare: function() { | |
this.deltaX = window.pageXOffset | |
|| document.documentElement.scrollLeft | |
|| document.body.scrollLeft | |
|| 0; | |
this.deltaY = window.pageYOffset | |
|| document.documentElement.scrollTop | |
|| document.body.scrollTop | |
|| 0; | |
}, | |
within: function(element, x, y) { | |
if (this.includeScrollOffsets) | |
return this.withinIncludingScrolloffsets(element, x, y); | |
this.xcomp = x; | |
this.ycomp = y; | |
this.offset = Element.cumulativeOffset(element); | |
return (y >= this.offset[1] && | |
y < this.offset[1] + element.offsetHeight && | |
x >= this.offset[0] && | |
x < this.offset[0] + element.offsetWidth); | |
}, | |
withinIncludingScrolloffsets: function(element, x, y) { | |
var offsetcache = Element.cumulativeScrollOffset(element); | |
this.xcomp = x + offsetcache[0] - this.deltaX; | |
this.ycomp = y + offsetcache[1] - this.deltaY; | |
this.offset = Element.cumulativeOffset(element); | |
return (this.ycomp >= this.offset[1] && | |
this.ycomp < this.offset[1] + element.offsetHeight && | |
this.xcomp >= this.offset[0] && | |
this.xcomp < this.offset[0] + element.offsetWidth); | |
}, | |
overlap: function(mode, element) { | |
if (!mode) return 0; | |
if (mode == 'vertical') | |
return ((this.offset[1] + element.offsetHeight) - this.ycomp) / | |
element.offsetHeight; | |
if (mode == 'horizontal') | |
return ((this.offset[0] + element.offsetWidth) - this.xcomp) / | |
element.offsetWidth; | |
}, | |
cumulativeOffset: Element.Methods.cumulativeOffset, | |
positionedOffset: Element.Methods.positionedOffset, | |
absolutize: function(element) { | |
Position.prepare(); | |
return Element.absolutize(element); | |
}, | |
relativize: function(element) { | |
Position.prepare(); | |
return Element.relativize(element); | |
}, | |
realOffset: Element.Methods.cumulativeScrollOffset, | |
offsetParent: Element.Methods.getOffsetParent, | |
page: Element.Methods.viewportOffset, | |
clone: function(source, target, options) { | |
options = options || { }; | |
return Element.clonePosition(target, source, options); | |
} | |
}; | |
/*--------------------------------------------------------------------------*/ | |
if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ | |
function iter(name) { | |
return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; | |
} | |
instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? | |
function(element, className) { | |
className = className.toString().strip(); | |
var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); | |
return cond ? document._getElementsByXPath('.//*' + cond, element) : []; | |
} : function(element, className) { | |
className = className.toString().strip(); | |
var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); | |
if (!classNames && !className) return elements; | |
var nodes = $(element).getElementsByTagName('*'); | |
className = ' ' + className + ' '; | |
for (var i = 0, child, cn; child = nodes[i]; i++) { | |
if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || | |
(classNames && classNames.all(function(name) { | |
return !name.toString().blank() && cn.include(' ' + name + ' '); | |
})))) | |
elements.push(Element.extend(child)); | |
} | |
return elements; | |
}; | |
return function(className, parentElement) { | |
return $(parentElement || document.body).getElementsByClassName(className); | |
}; | |
}(Element.Methods); | |
/*--------------------------------------------------------------------------*/ | |
Element.ClassNames = Class.create(); | |
Element.ClassNames.prototype = { | |
initialize: function(element) { | |
this.element = $(element); | |
}, | |
_each: function(iterator, context) { | |
this.element.className.split(/\s+/).select(function(name) { | |
return name.length > 0; | |
})._each(iterator, context); | |
}, | |
set: function(className) { | |
this.element.className = className; | |
}, | |
add: function(classNameToAdd) { | |
if (this.include(classNameToAdd)) return; | |
this.set($A(this).concat(classNameToAdd).join(' ')); | |
}, | |
remove: function(classNameToRemove) { | |
if (!this.include(classNameToRemove)) return; | |
this.set($A(this).without(classNameToRemove).join(' ')); | |
}, | |
toString: function() { | |
return $A(this).join(' '); | |
} | |
}; | |
Object.extend(Element.ClassNames.prototype, Enumerable); | |
/*--------------------------------------------------------------------------*/ | |
(function() { | |
window.Selector = Class.create({ | |
initialize: function(expression) { | |
this.expression = expression.strip(); | |
}, | |
findElements: function(rootElement) { | |
return Prototype.Selector.select(this.expression, rootElement); | |
}, | |
match: function(element) { | |
return Prototype.Selector.match(element, this.expression); | |
}, | |
toString: function() { | |
return this.expression; | |
}, | |
inspect: function() { | |
return "#<Selector: " + this.expression + ">"; | |
} | |
}); | |
Object.extend(Selector, { | |
matchElements: function(elements, expression) { | |
var match = Prototype.Selector.match, | |
results = []; | |
for (var i = 0, length = elements.length; i < length; i++) { | |
var element = elements[i]; | |
if (match(element, expression)) { | |
results.push(Element.extend(element)); | |
} | |
} | |
return results; | |
}, | |
findElement: function(elements, expression, index) { | |
index = index || 0; | |
var matchIndex = 0, element; | |
for (var i = 0, length = elements.length; i < length; i++) { | |
element = elements[i]; | |
if (Prototype.Selector.match(element, expression) && index === matchIndex++) { | |
return Element.extend(element); | |
} | |
} | |
}, | |
findChildElements: function(element, expressions) { | |
var selector = expressions.toArray().join(', '); | |
return Prototype.Selector.select(selector, element || document); | |
} | |
}); | |
})(); | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/public/dist/jsconcat.js","/public/dist") | |
},{"_process":5,"buffer":1}],7:[function(require,module,exports){ | |
(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ | |
require('jsconcat'); | |
alert(JSON.stringify); | |
}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/templates/js/foo.js","/templates/js") | |
},{"_process":5,"buffer":1,"jsconcat":6}]},{},[7]) | |
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnVmZmVyL25vZGVfbW9kdWxlcy9pZWVlNzU0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaXMtYXJyYXkvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvcHJvY2Vzcy9icm93c2VyLmpzIiwicHVibGljL2Rpc3QvanNjb25jYXQuanMiLCJ0ZW1wbGF0ZXMvanMvZm9vLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNweUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDNUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3RGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3QxT0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG52YXIgaXNBcnJheSA9IHJlcXVpcmUoJ2lzLWFycmF5JylcblxuZXhwb3J0cy5CdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuU2xvd0J1ZmZlciA9IFNsb3dCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuQnVmZmVyLnBvb2xTaXplID0gODE5MiAvLyBub3QgdXNlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uXG5cbnZhciBrTWF4TGVuZ3RoID0gMHgzZmZmZmZmZlxudmFyIHJvb3RQYXJlbnQgPSB7fVxuXG4vKipcbiAqIElmIGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGA6XG4gKiAgID09PSB0cnVlICAgIFVzZSBVaW50OEFycmF5IGltcGxlbWVudGF0aW9uIChmYXN0ZXN0KVxuICogICA9PT0gZmFsc2UgICBVc2UgT2JqZWN0IGltcGxlbWVudGF0aW9uIChtb3N0IGNvbXBhdGlibGUsIGV2ZW4gSUU2KVxuICpcbiAqIEJyb3dzZXJzIHRoYXQgc3VwcG9ydCB0eXBlZCBhcnJheXMgYXJlIElFIDEwKywgRmlyZWZveCA0KywgQ2hyb21lIDcrLCBTYWZhcmkgNS4xKyxcbiAqIE9wZXJhIDExLjYrLCBpT1MgNC4yKy5cbiAqXG4gKiBOb3RlOlxuICpcbiAqIC0gSW1wbGVtZW50YXRpb24gbXVzdCBzdXBwb3J0IGFkZGluZyBuZXcgcHJvcGVydGllcyB0byBgVWludDhBcnJheWAgaW5zdGFuY2VzLlxuICogICBGaXJlZm94IDQtMjkgbGFja2VkIHN1cHBvcnQsIGZpeGVkIGluIEZpcmVmb3ggMzArLlxuICogICBTZWU6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOC5cbiAqXG4gKiAgLSBDaHJvbWUgOS0xMCBpcyBtaXNzaW5nIHRoZSBgVHlwZWRBcnJheS5wcm90b3R5cGUuc3ViYXJyYXlgIGZ1bmN0aW9uLlxuICpcbiAqICAtIElFMTAgaGFzIGEgYnJva2VuIGBUeXBlZEFycmF5LnByb3RvdHlwZS5zdWJhcnJheWAgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhcnJheXMgb2ZcbiAqICAgIGluY29ycmVjdCBsZW5ndGggaW4gc29tZSBzaXR1YXRpb25zLlxuICpcbiAqIFdlIGRldGVjdCB0aGVzZSBidWdneSBicm93c2VycyBhbmQgc2V0IGBCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVGAgdG8gYGZhbHNlYCBzbyB0aGV5IHdpbGxcbiAqIGdldCB0aGUgT2JqZWN0IGltcGxlbWVudGF0aW9uLCB3aGljaCBpcyBzbG93ZXIgYnV0IHdpbGwgd29yayBjb3JyZWN0bHkuXG4gKi9cbkJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUID0gKGZ1bmN0aW9uICgpIHtcbiAgdHJ5IHtcbiAgICB2YXIgYnVmID0gbmV3IEFycmF5QnVmZmVyKDApXG4gICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGJ1ZilcbiAgICBhcnIuZm9vID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gNDIgfVxuICAgIHJldHVybiA0MiA9PT0gYXJyLmZvbygpICYmIC8vIHR5cGVkIGFycmF5IGluc3RhbmNlcyBjYW4gYmUgYXVnbWVudGVkXG4gICAgICAgIHR5cGVvZiBhcnIuc3ViYXJyYXkgPT09ICdmdW5jdGlvbicgJiYgLy8gY2hyb21lIDktMTAgbGFjayBgc3ViYXJyYXlgXG4gICAgICAgIG5ldyBVaW50OEFycmF5KDEpLnN1YmFycmF5KDEsIDEpLmJ5dGVMZW5ndGggPT09IDAgLy8gaWUxMCBoYXMgYnJva2VuIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59KSgpXG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybylcblxuICB2YXIgdHlwZSA9IHR5cGVvZiBzdWJqZWN0XG5cbiAgLy8gRmluZCB0aGUgbGVuZ3RoXG4gIHZhciBsZW5ndGhcbiAgaWYgKHR5cGUgPT09ICdudW1iZXInKVxuICAgIGxlbmd0aCA9IHN1YmplY3QgPiAwID8gc3ViamVjdCA+Pj4gMCA6IDBcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBsZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzdWJqZWN0LCBlbmNvZGluZylcbiAgfSBlbHNlIGlmICh0eXBlID09PSAnb2JqZWN0JyAmJiBzdWJqZWN0ICE9PSBudWxsKSB7IC8vIGFzc3VtZSBvYmplY3QgaXMgYXJyYXktbGlrZVxuICAgIGlmIChzdWJqZWN0LnR5cGUgPT09ICdCdWZmZXInICYmIGlzQXJyYXkoc3ViamVjdC5kYXRhKSlcbiAgICAgIHN1YmplY3QgPSBzdWJqZWN0LmRhdGFcbiAgICBsZW5ndGggPSArc3ViamVjdC5sZW5ndGggPiAwID8gTWF0aC5mbG9vcigrc3ViamVjdC5sZW5ndGgpIDogMFxuICB9IGVsc2VcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdtdXN0IHN0YXJ0IHdpdGggbnVtYmVyLCBidWZmZXIsIGFycmF5IG9yIHN0cmluZycpXG5cbiAgaWYgKGxlbmd0aCA+IGtNYXhMZW5ndGgpXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0F0dGVtcHQgdG8gYWxsb2NhdGUgQnVmZmVyIGxhcmdlciB0aGFuIG1heGltdW0gJyArXG4gICAgICAnc2l6ZTogMHgnICsga01heExlbmd0aC50b1N0cmluZygxNikgKyAnIGJ5dGVzJylcblxuICB2YXIgYnVmXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIC8vIFByZWZlcnJlZDogUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBidWYgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIFRISVMgaW5zdGFuY2Ugb2YgQnVmZmVyIChjcmVhdGVkIGJ5IGBuZXdgKVxuICAgIGJ1ZiA9IHRoaXNcbiAgICBidWYubGVuZ3RoID0gbGVuZ3RoXG4gICAgYnVmLl9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiB0eXBlb2Ygc3ViamVjdC5ieXRlTGVuZ3RoID09PSAnbnVtYmVyJykge1xuICAgIC8vIFNwZWVkIG9wdGltaXphdGlvbiAtLSB1c2Ugc2V0IGlmIHdlJ3JlIGNvcHlpbmcgZnJvbSBhIHR5cGVkIGFycmF5XG4gICAgYnVmLl9zZXQoc3ViamVjdClcbiAgfSBlbHNlIGlmIChpc0FycmF5aXNoKHN1YmplY3QpKSB7XG4gICAgLy8gVHJlYXQgYXJyYXktaXNoIG9iamVjdHMgYXMgYSBieXRlIGFycmF5XG4gICAgaWYgKEJ1ZmZlci5pc0J1ZmZlcihzdWJqZWN0KSkge1xuICAgICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKVxuICAgICAgICBidWZbaV0gPSBzdWJqZWN0LnJlYWRVSW50OChpKVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspXG4gICAgICAgIGJ1ZltpXSA9ICgoc3ViamVjdFtpXSAlIDI1NikgKyAyNTYpICUgMjU2XG4gICAgfVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgYnVmLndyaXRlKHN1YmplY3QsIDAsIGVuY29kaW5nKVxuICB9IGVsc2UgaWYgKHR5cGUgPT09ICdudW1iZXInICYmICFCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCAmJiAhbm9aZXJvKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBidWZbaV0gPSAwXG4gICAgfVxuICB9XG5cbiAgaWYgKGxlbmd0aCA+IDAgJiYgbGVuZ3RoIDw9IEJ1ZmZlci5wb29sU2l6ZSlcbiAgICBidWYucGFyZW50ID0gcm9vdFBhcmVudFxuXG4gIHJldHVybiBidWZcbn1cblxuZnVuY3Rpb24gU2xvd0J1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgbm9aZXJvKSB7XG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBTbG93QnVmZmVyKSlcbiAgICByZXR1cm4gbmV3IFNsb3dCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybylcblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcihzdWJqZWN0LCBlbmNvZGluZywgbm9aZXJvKVxuICBkZWxldGUgYnVmLnBhcmVudFxuICByZXR1cm4gYnVmXG59XG5cbkJ1ZmZlci5pc0J1ZmZlciA9IGZ1bmN0aW9uIChiKSB7XG4gIHJldHVybiAhIShiICE9IG51bGwgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5jb21wYXJlID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYSkgfHwgIUJ1ZmZlci5pc0J1ZmZlcihiKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBcmd1bWVudHMgbXVzdCBiZSBCdWZmZXJzJylcblxuICB2YXIgeCA9IGEubGVuZ3RoXG4gIHZhciB5ID0gYi5sZW5ndGhcbiAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IE1hdGgubWluKHgsIHkpOyBpIDwgbGVuICYmIGFbaV0gPT09IGJbaV07IGkrKykge31cbiAgaWYgKGkgIT09IGxlbikge1xuICAgIHggPSBhW2ldXG4gICAgeSA9IGJbaV1cbiAgfVxuICBpZiAoeCA8IHkpIHJldHVybiAtMVxuICBpZiAoeSA8IHgpIHJldHVybiAxXG4gIHJldHVybiAwXG59XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gKGxpc3QsIHRvdGFsTGVuZ3RoKSB7XG4gIGlmICghaXNBcnJheShsaXN0KSkgdGhyb3cgbmV3IFR5cGVFcnJvcignVXNhZ2U6IEJ1ZmZlci5jb25jYXQobGlzdFssIGxlbmd0aF0pJylcblxuICBpZiAobGlzdC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3IEJ1ZmZlcigwKVxuICB9IGVsc2UgaWYgKGxpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIGxpc3RbMF1cbiAgfVxuXG4gIHZhciBpXG4gIGlmICh0b3RhbExlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdG90YWxMZW5ndGggPSAwXG4gICAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRvdGFsTGVuZ3RoICs9IGxpc3RbaV0ubGVuZ3RoXG4gICAgfVxuICB9XG5cbiAgdmFyIGJ1ZiA9IG5ldyBCdWZmZXIodG90YWxMZW5ndGgpXG4gIHZhciBwb3MgPSAwXG4gIGZvciAoaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGl0ZW0gPSBsaXN0W2ldXG4gICAgaXRlbS5jb3B5KGJ1ZiwgcG9zKVxuICAgIHBvcyArPSBpdGVtLmxlbmd0aFxuICB9XG4gIHJldHVybiBidWZcbn1cblxuQnVmZmVyLmJ5dGVMZW5ndGggPSBmdW5jdGlvbiAoc3RyLCBlbmNvZGluZykge1xuICB2YXIgcmV0XG4gIHN0ciA9IHN0ciArICcnXG4gIHN3aXRjaCAoZW5jb2RpbmcgfHwgJ3V0ZjgnKSB7XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAncmF3JzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGhcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IHN0ci5sZW5ndGggKiAyXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoID4+PiAxXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IHV0ZjhUb0J5dGVzKHN0cikubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICByZXQgPSBiYXNlNjRUb0J5dGVzKHN0cikubGVuZ3RoXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG4vLyBwcmUtc2V0IGZvciB2YWx1ZXMgdGhhdCBtYXkgZXhpc3QgaW4gdGhlIGZ1dHVyZVxuQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSB1bmRlZmluZWRcbkJ1ZmZlci5wcm90b3R5cGUucGFyZW50ID0gdW5kZWZpbmVkXG5cbi8vIHRvU3RyaW5nKGVuY29kaW5nLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoZW5jb2RpbmcsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxvd2VyZWRDYXNlID0gZmFsc2VcblxuICBzdGFydCA9IHN0YXJ0ID4+PiAwXG4gIGVuZCA9IGVuZCA9PT0gdW5kZWZpbmVkIHx8IGVuZCA9PT0gSW5maW5pdHkgPyB0aGlzLmxlbmd0aCA6IGVuZCA+Pj4gMFxuXG4gIGlmICghZW5jb2RpbmcpIGVuY29kaW5nID0gJ3V0ZjgnXG4gIGlmIChzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoZW5kID4gdGhpcy5sZW5ndGgpIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmIChlbmQgPD0gc3RhcnQpIHJldHVybiAnJ1xuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgY2FzZSAnaGV4JzpcbiAgICAgICAgcmV0dXJuIGhleFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ3V0ZjgnOlxuICAgICAgY2FzZSAndXRmLTgnOlxuICAgICAgICByZXR1cm4gdXRmOFNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2FzY2lpJzpcbiAgICAgICAgcmV0dXJuIGFzY2lpU2xpY2UodGhpcywgc3RhcnQsIGVuZClcblxuICAgICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgICAgcmV0dXJuIGJpbmFyeVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGNhc2UgJ2Jhc2U2NCc6XG4gICAgICAgIHJldHVybiBiYXNlNjRTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuXG4gICAgICBjYXNlICd1Y3MyJzpcbiAgICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgICByZXR1cm4gdXRmMTZsZVNsaWNlKHRoaXMsIHN0YXJ0LCBlbmQpXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChsb3dlcmVkQ2FzZSlcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdVbmtub3duIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpXG4gICAgICAgIGVuY29kaW5nID0gKGVuY29kaW5nICsgJycpLnRvTG93ZXJDYXNlKClcbiAgICAgICAgbG93ZXJlZENhc2UgPSB0cnVlXG4gICAgfVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKGIpIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYikpIHRocm93IG5ldyBUeXBlRXJyb3IoJ0FyZ3VtZW50IG11c3QgYmUgYSBCdWZmZXInKVxuICByZXR1cm4gQnVmZmVyLmNvbXBhcmUodGhpcywgYikgPT09IDBcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5pbnNwZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgc3RyID0gJydcbiAgdmFyIG1heCA9IGV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVNcbiAgaWYgKHRoaXMubGVuZ3RoID4gMCkge1xuICAgIHN0ciA9IHRoaXMudG9TdHJpbmcoJ2hleCcsIDAsIG1heCkubWF0Y2goLy57Mn0vZykuam9pbignICcpXG4gICAgaWYgKHRoaXMubGVuZ3RoID4gbWF4KVxuICAgICAgc3RyICs9ICcgLi4uICdcbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIHN0ciArICc+J1xufVxuXG5CdWZmZXIucHJvdG90eXBlLmNvbXBhcmUgPSBmdW5jdGlvbiAoYikge1xuICBpZiAoIUJ1ZmZlci5pc0J1ZmZlcihiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignQXJndW1lbnQgbXVzdCBiZSBhIEJ1ZmZlcicpXG4gIHJldHVybiBCdWZmZXIuY29tcGFyZSh0aGlzLCBiKVxufVxuXG4vLyBgZ2V0YCB3aWxsIGJlIHJlbW92ZWQgaW4gTm9kZSAwLjEzK1xuQnVmZmVyLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAob2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuZ2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy5yZWFkVUludDgob2Zmc2V0KVxufVxuXG4vLyBgc2V0YCB3aWxsIGJlIHJlbW92ZWQgaW4gTm9kZSAwLjEzK1xuQnVmZmVyLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAodiwgb2Zmc2V0KSB7XG4gIGNvbnNvbGUubG9nKCcuc2V0KCkgaXMgZGVwcmVjYXRlZC4gQWNjZXNzIHVzaW5nIGFycmF5IGluZGV4ZXMgaW5zdGVhZC4nKVxuICByZXR1cm4gdGhpcy53cml0ZVVJbnQ4KHYsIG9mZnNldClcbn1cblxuZnVuY3Rpb24gaGV4V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICBvZmZzZXQgPSBOdW1iZXIob2Zmc2V0KSB8fCAwXG4gIHZhciByZW1haW5pbmcgPSBidWYubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cblxuICAvLyBtdXN0IGJlIGFuIGV2ZW4gbnVtYmVyIG9mIGRpZ2l0c1xuICB2YXIgc3RyTGVuID0gc3RyaW5nLmxlbmd0aFxuICBpZiAoc3RyTGVuICUgMiAhPT0gMCkgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnl0ZSA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBpZiAoaXNOYU4oYnl0ZSkpIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBieXRlXG4gIH1cbiAgcmV0dXJuIGlcbn1cblxuZnVuY3Rpb24gdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IGJsaXRCdWZmZXIodXRmOFRvQnl0ZXMoc3RyaW5nLCBidWYubGVuZ3RoIC0gb2Zmc2V0KSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBhc2NpaVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gYmluYXJ5V3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICByZXR1cm4gYXNjaWlXcml0ZShidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG59XG5cbmZ1bmN0aW9uIGJhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IGJsaXRCdWZmZXIoYmFzZTY0VG9CeXRlcyhzdHJpbmcpLCBidWYsIG9mZnNldCwgbGVuZ3RoKVxuICByZXR1cm4gY2hhcnNXcml0dGVuXG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVXcml0ZSAoYnVmLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKSB7XG4gIHZhciBjaGFyc1dyaXR0ZW4gPSBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZywgYnVmLmxlbmd0aCAtIG9mZnNldCksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgsIDIpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBTdXBwb3J0IGJvdGggKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKVxuICAvLyBhbmQgdGhlIGxlZ2FjeSAoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpXG4gIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2UgeyAgLy8gbGVnYWN5XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoXG4gICAgbGVuZ3RoID0gc3dhcFxuICB9XG5cbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuXG4gIGlmIChsZW5ndGggPCAwIHx8IG9mZnNldCA8IDAgfHwgb2Zmc2V0ID4gdGhpcy5sZW5ndGgpXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2F0dGVtcHQgdG8gd3JpdGUgb3V0c2lkZSBidWZmZXIgYm91bmRzJyk7XG5cbiAgdmFyIHJlbWFpbmluZyA9IHRoaXMubGVuZ3RoIC0gb2Zmc2V0XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gIH0gZWxzZSB7XG4gICAgbGVuZ3RoID0gTnVtYmVyKGxlbmd0aClcbiAgICBpZiAobGVuZ3RoID4gcmVtYWluaW5nKSB7XG4gICAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgICB9XG4gIH1cbiAgZW5jb2RpbmcgPSBTdHJpbmcoZW5jb2RpbmcgfHwgJ3V0ZjgnKS50b0xvd2VyQ2FzZSgpXG5cbiAgdmFyIHJldFxuICBzd2l0Y2ggKGVuY29kaW5nKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICAgIHJldCA9IGhleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IHV0ZjhXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgICByZXQgPSBhc2NpaVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgICByZXQgPSBiaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gYmFzZTY0V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAndWNzMic6XG4gICAgY2FzZSAndWNzLTInOlxuICAgIGNhc2UgJ3V0ZjE2bGUnOlxuICAgIGNhc2UgJ3V0Zi0xNmxlJzpcbiAgICAgIHJldCA9IHV0ZjE2bGVXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVW5rbm93biBlbmNvZGluZzogJyArIGVuY29kaW5nKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuZnVuY3Rpb24gYmFzZTY0U2xpY2UgKGJ1Ziwgc3RhcnQsIGVuZCkge1xuICBpZiAoc3RhcnQgPT09IDAgJiYgZW5kID09PSBidWYubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1ZilcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gYmFzZTY0LmZyb21CeXRlQXJyYXkoYnVmLnNsaWNlKHN0YXJ0LCBlbmQpKVxuICB9XG59XG5cbmZ1bmN0aW9uIHV0ZjhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXMgPSAnJ1xuICB2YXIgdG1wID0gJydcbiAgZW5kID0gTWF0aC5taW4oYnVmLmxlbmd0aCwgZW5kKVxuXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgaWYgKGJ1ZltpXSA8PSAweDdGKSB7XG4gICAgICByZXMgKz0gZGVjb2RlVXRmOENoYXIodG1wKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoYnVmW2ldKVxuICAgICAgdG1wID0gJydcbiAgICB9IGVsc2Uge1xuICAgICAgdG1wICs9ICclJyArIGJ1ZltpXS50b1N0cmluZygxNilcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzICsgZGVjb2RlVXRmOENoYXIodG1wKVxufVxuXG5mdW5jdGlvbiBhc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHJldCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ1ZltpXSAmIDB4N0YpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBiaW5hcnlTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciByZXQgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5mdW5jdGlvbiBoZXhTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG5cbiAgaWYgKCFzdGFydCB8fCBzdGFydCA8IDApIHN0YXJ0ID0gMFxuICBpZiAoIWVuZCB8fCBlbmQgPCAwIHx8IGVuZCA+IGxlbikgZW5kID0gbGVuXG5cbiAgdmFyIG91dCA9ICcnXG4gIGZvciAodmFyIGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgb3V0ICs9IHRvSGV4KGJ1ZltpXSlcbiAgfVxuICByZXR1cm4gb3V0XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSArIDFdICogMjU2KVxuICB9XG4gIHJldHVybiByZXNcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5zbGljZSA9IGZ1bmN0aW9uIChzdGFydCwgZW5kKSB7XG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBzdGFydCA9IH5+c3RhcnRcbiAgZW5kID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB+fmVuZFxuXG4gIGlmIChzdGFydCA8IDApIHtcbiAgICBzdGFydCArPSBsZW47XG4gICAgaWYgKHN0YXJ0IDwgMClcbiAgICAgIHN0YXJ0ID0gMFxuICB9IGVsc2UgaWYgKHN0YXJ0ID4gbGVuKSB7XG4gICAgc3RhcnQgPSBsZW5cbiAgfVxuXG4gIGlmIChlbmQgPCAwKSB7XG4gICAgZW5kICs9IGxlblxuICAgIGlmIChlbmQgPCAwKVxuICAgICAgZW5kID0gMFxuICB9IGVsc2UgaWYgKGVuZCA+IGxlbikge1xuICAgIGVuZCA9IGxlblxuICB9XG5cbiAgaWYgKGVuZCA8IHN0YXJ0KVxuICAgIGVuZCA9IHN0YXJ0XG5cbiAgdmFyIG5ld0J1ZlxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICBuZXdCdWYgPSBCdWZmZXIuX2F1Z21lbnQodGhpcy5zdWJhcnJheShzdGFydCwgZW5kKSlcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2xpY2VMZW4gPSBlbmQgLSBzdGFydFxuICAgIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgfVxuXG4gIGlmIChuZXdCdWYubGVuZ3RoKVxuICAgIG5ld0J1Zi5wYXJlbnQgPSB0aGlzLnBhcmVudCB8fCB0aGlzXG5cbiAgcmV0dXJuIG5ld0J1ZlxufVxuXG4vKlxuICogTmVlZCB0byBtYWtlIHN1cmUgdGhhdCBidWZmZXIgaXNuJ3QgdHJ5aW5nIHRvIHdyaXRlIG91dCBvZiBib3VuZHMuXG4gKi9cbmZ1bmN0aW9uIGNoZWNrT2Zmc2V0IChvZmZzZXQsIGV4dCwgbGVuZ3RoKSB7XG4gIGlmICgob2Zmc2V0ICUgMSkgIT09IDAgfHwgb2Zmc2V0IDwgMClcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignb2Zmc2V0IGlzIG5vdCB1aW50JylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGxlbmd0aClcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignVHJ5aW5nIHRvIGFjY2VzcyBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XVxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpXG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgaV0gKiBtdWxcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnRCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgYnl0ZUxlbmd0aCwgdGhpcy5sZW5ndGgpXG5cbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXVxuICB2YXIgbXVsID0gMVxuICB3aGlsZSAoYnl0ZUxlbmd0aCA+IDAgJiYgKG11bCAqPSAweDEwMCkpXG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1ieXRlTGVuZ3RoXSAqIG11bDtcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydClcbiAgICBjaGVja09mZnNldChvZmZzZXQsIDEsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydClcbiAgICBjaGVja09mZnNldChvZmZzZXQsIDIsIHRoaXMubGVuZ3RoKVxuICByZXR1cm4gdGhpc1tvZmZzZXRdIHwgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkVUludDE2QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgMiwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDgpIHwgdGhpc1tvZmZzZXQgKyAxXVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRVSW50MzJMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKCh0aGlzW29mZnNldF0pIHxcbiAgICAgICh0aGlzW29mZnNldCArIDFdIDw8IDgpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDE2KSkgK1xuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10gKiAweDEwMDAwMDApXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydClcbiAgICBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdICogMHgxMDAwMDAwKSArXG4gICAgICAoKHRoaXNbb2Zmc2V0ICsgMV0gPDwgMTYpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDJdIDw8IDgpIHxcbiAgICAgIHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludExFID0gZnVuY3Rpb24gKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgdmFsID0gdGhpc1tvZmZzZXRdXG4gIHZhciBtdWwgPSAxXG4gIHZhciBpID0gMFxuICB3aGlsZSAoKytpIDwgYnl0ZUxlbmd0aCAmJiAobXVsICo9IDB4MTAwKSlcbiAgICB2YWwgKz0gdGhpc1tvZmZzZXQgKyBpXSAqIG11bFxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKVxuICAgIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludEJFID0gZnVuY3Rpb24gKG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCBieXRlTGVuZ3RoLCB0aGlzLmxlbmd0aClcblxuICB2YXIgaSA9IGJ5dGVMZW5ndGhcbiAgdmFyIG11bCA9IDFcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgLS1pXVxuICB3aGlsZSAoaSA+IDAgJiYgKG11bCAqPSAweDEwMCkpXG4gICAgdmFsICs9IHRoaXNbb2Zmc2V0ICsgLS1pXSAqIG11bFxuICBtdWwgKj0gMHg4MFxuXG4gIGlmICh2YWwgPj0gbXVsKVxuICAgIHZhbCAtPSBNYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aClcblxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgMSwgdGhpcy5sZW5ndGgpXG4gIGlmICghKHRoaXNbb2Zmc2V0XSAmIDB4ODApKVxuICAgIHJldHVybiAodGhpc1tvZmZzZXRdKVxuICByZXR1cm4gKCgweGZmIC0gdGhpc1tvZmZzZXRdICsgMSkgKiAtMSlcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0XSB8ICh0aGlzW29mZnNldCArIDFdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MTZCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCAyLCB0aGlzLmxlbmd0aClcbiAgdmFyIHZhbCA9IHRoaXNbb2Zmc2V0ICsgMV0gfCAodGhpc1tvZmZzZXRdIDw8IDgpXG4gIHJldHVybiAodmFsICYgMHg4MDAwKSA/IHZhbCB8IDB4RkZGRjAwMDAgOiB2YWxcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkSW50MzJMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcblxuICByZXR1cm4gKHRoaXNbb2Zmc2V0XSkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMV0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgMTYpIHxcbiAgICAgICh0aGlzW29mZnNldCArIDNdIDw8IDI0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydClcbiAgICBjaGVja09mZnNldChvZmZzZXQsIDQsIHRoaXMubGVuZ3RoKVxuXG4gIHJldHVybiAodGhpc1tvZmZzZXRdIDw8IDI0KSB8XG4gICAgICAodGhpc1tvZmZzZXQgKyAxXSA8PCAxNikgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgMl0gPDwgOCkgfFxuICAgICAgKHRoaXNbb2Zmc2V0ICsgM10pXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgNCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRCRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tPZmZzZXQob2Zmc2V0LCA0LCB0aGlzLmxlbmd0aClcbiAgcmV0dXJuIGllZWU3NTQucmVhZCh0aGlzLCBvZmZzZXQsIGZhbHNlLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCB0cnVlLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrT2Zmc2V0KG9mZnNldCwgOCwgdGhpcy5sZW5ndGgpXG4gIHJldHVybiBpZWVlNzU0LnJlYWQodGhpcywgb2Zmc2V0LCBmYWxzZSwgNTIsIDgpXG59XG5cbmZ1bmN0aW9uIGNoZWNrSW50IChidWYsIHZhbHVlLCBvZmZzZXQsIGV4dCwgbWF4LCBtaW4pIHtcbiAgaWYgKCFCdWZmZXIuaXNCdWZmZXIoYnVmKSkgdGhyb3cgbmV3IFR5cGVFcnJvcignYnVmZmVyIG11c3QgYmUgYSBCdWZmZXIgaW5zdGFuY2UnKVxuICBpZiAodmFsdWUgPiBtYXggfHwgdmFsdWUgPCBtaW4pIHRocm93IG5ldyBSYW5nZUVycm9yKCd2YWx1ZSBpcyBvdXQgb2YgYm91bmRzJylcbiAgaWYgKG9mZnNldCArIGV4dCA+IGJ1Zi5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdpbmRleCBvdXQgb2YgcmFuZ2UnKVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludExFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGJ5dGVMZW5ndGgsIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoKSwgMClcblxuICB2YXIgbXVsID0gMVxuICB2YXIgaSA9IDBcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgrK2kgPCBieXRlTGVuZ3RoICYmIChtdWwgKj0gMHgxMDApKVxuICAgIHRoaXNbb2Zmc2V0ICsgaV0gPSAodmFsdWUgLyBtdWwpID4+PiAwICYgMHhGRlxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGgpLCAwKVxuXG4gIHZhciBpID0gYnl0ZUxlbmd0aCAtIDFcbiAgdmFyIG11bCA9IDFcbiAgdGhpc1tvZmZzZXQgKyBpXSA9IHZhbHVlICYgMHhGRlxuICB3aGlsZSAoLS1pID49IDAgJiYgKG11bCAqPSAweDEwMCkpXG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICh2YWx1ZSAvIG11bCkgPj4+IDAgJiAweEZGXG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQ4ID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDEsIDB4ZmYsIDApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgcmV0dXJuIG9mZnNldCArIDFcbn1cblxuZnVuY3Rpb24gb2JqZWN0V3JpdGVVSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gIGlmICh2YWx1ZSA8IDApIHZhbHVlID0gMHhmZmZmICsgdmFsdWUgKyAxXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4oYnVmLmxlbmd0aCAtIG9mZnNldCwgMik7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSAodmFsdWUgJiAoMHhmZiA8PCAoOCAqIChsaXR0bGVFbmRpYW4gPyBpIDogMSAtIGkpKSkpID4+PlxuICAgICAgKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkgKiA4XG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Ugb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQxNkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4ZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgMV0gPSB2YWx1ZVxuICB9IGVsc2Ugb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIHJldHVybiBvZmZzZXQgKyAyXG59XG5cbmZ1bmN0aW9uIG9iamVjdFdyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgZm9yICh2YXIgaSA9IDAsIGogPSBNYXRoLm1pbihidWYubGVuZ3RoIC0gb2Zmc2V0LCA0KTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9ICh2YWx1ZSA+Pj4gKGxpdHRsZUVuZGlhbiA/IGkgOiAzIC0gaSkgKiA4KSAmIDB4ZmZcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDMyTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHhmZmZmZmZmZiwgMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXQgKyAzXSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldF0gPSB2YWx1ZVxuICB9IGVsc2Ugb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgcmV0dXJuIG9mZnNldCArIDRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4ZmZmZmZmZmYsIDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9ICh2YWx1ZSA+Pj4gMjQpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gMTYpXG4gICAgdGhpc1tvZmZzZXQgKyAyXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDNdID0gdmFsdWVcbiAgfSBlbHNlIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlKVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgYnl0ZUxlbmd0aCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBjaGVja0ludCh0aGlzLFxuICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICAgICBieXRlTGVuZ3RoLFxuICAgICAgICAgICAgIE1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSkgLSAxLFxuICAgICAgICAgICAgIC1NYXRoLnBvdygyLCA4ICogYnl0ZUxlbmd0aCAtIDEpKVxuICB9XG5cbiAgdmFyIGkgPSAwXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldF0gPSB2YWx1ZSAmIDB4RkZcbiAgd2hpbGUgKCsraSA8IGJ5dGVMZW5ndGggJiYgKG11bCAqPSAweDEwMCkpXG4gICAgdGhpc1tvZmZzZXQgKyBpXSA9ICgodmFsdWUgLyBtdWwpID4+IDApIC0gc3ViICYgMHhGRlxuXG4gIHJldHVybiBvZmZzZXQgKyBieXRlTGVuZ3RoXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnRCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBieXRlTGVuZ3RoLCBub0Fzc2VydCkge1xuICB2YWx1ZSA9ICt2YWx1ZVxuICBvZmZzZXQgPSBvZmZzZXQgPj4+IDBcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGNoZWNrSW50KHRoaXMsXG4gICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgb2Zmc2V0LFxuICAgICAgICAgICAgIGJ5dGVMZW5ndGgsXG4gICAgICAgICAgICAgTWF0aC5wb3coMiwgOCAqIGJ5dGVMZW5ndGggLSAxKSAtIDEsXG4gICAgICAgICAgICAgLU1hdGgucG93KDIsIDggKiBieXRlTGVuZ3RoIC0gMSkpXG4gIH1cblxuICB2YXIgaSA9IGJ5dGVMZW5ndGggLSAxXG4gIHZhciBtdWwgPSAxXG4gIHZhciBzdWIgPSB2YWx1ZSA8IDAgPyAxIDogMFxuICB0aGlzW29mZnNldCArIGldID0gdmFsdWUgJiAweEZGXG4gIHdoaWxlICgtLWkgPj0gMCAmJiAobXVsICo9IDB4MTAwKSlcbiAgICB0aGlzW29mZnNldCArIGldID0gKCh2YWx1ZSAvIG11bCkgPj4gMCkgLSBzdWIgJiAweEZGXG5cbiAgcmV0dXJuIG9mZnNldCArIGJ5dGVMZW5ndGhcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDggPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMSwgMHg3ZiwgLTB4ODApXG4gIGlmICghQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHZhbHVlID0gTWF0aC5mbG9vcih2YWx1ZSlcbiAgaWYgKHZhbHVlIDwgMCkgdmFsdWUgPSAweGZmICsgdmFsdWUgKyAxXG4gIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gIHJldHVybiBvZmZzZXQgKyAxXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQxNkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDIsIDB4N2ZmZiwgLTB4ODAwMClcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiA4KVxuICB9IGVsc2Ugb2JqZWN0V3JpdGVVSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSlcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgMiwgMHg3ZmZmLCAtMHg4MDAwKVxuICBpZiAoQnVmZmVyLlRZUEVEX0FSUkFZX1NVUFBPUlQpIHtcbiAgICB0aGlzW29mZnNldF0gPSAodmFsdWUgPj4+IDgpXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9IHZhbHVlXG4gIH0gZWxzZSBvYmplY3RXcml0ZVVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSlcbiAgcmV0dXJuIG9mZnNldCArIDJcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDMyTEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgdmFsdWUgPSArdmFsdWVcbiAgb2Zmc2V0ID0gb2Zmc2V0ID4+PiAwXG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJbnQodGhpcywgdmFsdWUsIG9mZnNldCwgNCwgMHg3ZmZmZmZmZiwgLTB4ODAwMDAwMDApXG4gIGlmIChCdWZmZXIuVFlQRURfQVJSQVlfU1VQUE9SVCkge1xuICAgIHRoaXNbb2Zmc2V0XSA9IHZhbHVlXG4gICAgdGhpc1tvZmZzZXQgKyAxXSA9ICh2YWx1ZSA+Pj4gOClcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDNdID0gKHZhbHVlID4+PiAyNClcbiAgfSBlbHNlIG9iamVjdFdyaXRlVUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHZhbHVlID0gK3ZhbHVlXG4gIG9mZnNldCA9IG9mZnNldCA+Pj4gMFxuICBpZiAoIW5vQXNzZXJ0KVxuICAgIGNoZWNrSW50KHRoaXMsIHZhbHVlLCBvZmZzZXQsIDQsIDB4N2ZmZmZmZmYsIC0weDgwMDAwMDAwKVxuICBpZiAodmFsdWUgPCAwKSB2YWx1ZSA9IDB4ZmZmZmZmZmYgKyB2YWx1ZSArIDFcbiAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgdGhpc1tvZmZzZXRdID0gKHZhbHVlID4+PiAyNClcbiAgICB0aGlzW29mZnNldCArIDFdID0gKHZhbHVlID4+PiAxNilcbiAgICB0aGlzW29mZnNldCArIDJdID0gKHZhbHVlID4+PiA4KVxuICAgIHRoaXNbb2Zmc2V0ICsgM10gPSB2YWx1ZVxuICB9IGVsc2Ugb2JqZWN0V3JpdGVVSW50MzIodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UpXG4gIHJldHVybiBvZmZzZXQgKyA0XG59XG5cbmZ1bmN0aW9uIGNoZWNrSUVFRTc1NCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBleHQsIG1heCwgbWluKSB7XG4gIGlmICh2YWx1ZSA+IG1heCB8fCB2YWx1ZSA8IG1pbikgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3ZhbHVlIGlzIG91dCBvZiBib3VuZHMnKVxuICBpZiAob2Zmc2V0ICsgZXh0ID4gYnVmLmxlbmd0aCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2luZGV4IG91dCBvZiByYW5nZScpXG4gIGlmIChvZmZzZXQgPCAwKSB0aHJvdyBuZXcgUmFuZ2VFcnJvcignaW5kZXggb3V0IG9mIHJhbmdlJylcbn1cblxuZnVuY3Rpb24gd3JpdGVGbG9hdCAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgNCwgMy40MDI4MjM0NjYzODUyODg2ZSszOCwgLTMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgpXG4gIGllZWU3NTQud3JpdGUoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIDIzLCA0KVxuICByZXR1cm4gb2Zmc2V0ICsgNFxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUZsb2F0QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIHdyaXRlRmxvYXQodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiB3cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpXG4gICAgY2hlY2tJRUVFNzU0KGJ1ZiwgdmFsdWUsIG9mZnNldCwgOCwgMS43OTc2OTMxMzQ4NjIzMTU3RSszMDgsIC0xLjc5NzY5MzEzNDg2MjMxNTdFKzMwOClcbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG4gIHJldHVybiBvZmZzZXQgKyA4XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBjb3B5KHRhcmdldEJ1ZmZlciwgdGFyZ2V0U3RhcnQ9MCwgc291cmNlU3RhcnQ9MCwgc291cmNlRW5kPWJ1ZmZlci5sZW5ndGgpXG5CdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAodGFyZ2V0LCB0YXJnZXRfc3RhcnQsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHNvdXJjZSA9IHRoaXNcblxuICBpZiAoIXN0YXJ0KSBzdGFydCA9IDBcbiAgaWYgKCFlbmQgJiYgZW5kICE9PSAwKSBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0X3N0YXJ0ID49IHRhcmdldC5sZW5ndGgpIHRhcmdldF9zdGFydCA9IHRhcmdldC5sZW5ndGhcbiAgaWYgKCF0YXJnZXRfc3RhcnQpIHRhcmdldF9zdGFydCA9IDBcbiAgaWYgKGVuZCA+IDAgJiYgZW5kIDwgc3RhcnQpIGVuZCA9IHN0YXJ0XG5cbiAgLy8gQ29weSAwIGJ5dGVzOyB3ZSdyZSBkb25lXG4gIGlmIChlbmQgPT09IHN0YXJ0KSByZXR1cm4gMFxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCBzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm4gMFxuXG4gIC8vIEZhdGFsIGVycm9yIGNvbmRpdGlvbnNcbiAgaWYgKHRhcmdldF9zdGFydCA8IDApXG4gICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBpZiAoc3RhcnQgPCAwIHx8IHN0YXJ0ID49IHNvdXJjZS5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDApIHRocm93IG5ldyBSYW5nZUVycm9yKCdzb3VyY2VFbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgLy8gQXJlIHdlIG9vYj9cbiAgaWYgKGVuZCA+IHRoaXMubGVuZ3RoKVxuICAgIGVuZCA9IHRoaXMubGVuZ3RoXG4gIGlmICh0YXJnZXQubGVuZ3RoIC0gdGFyZ2V0X3N0YXJ0IDwgZW5kIC0gc3RhcnQpXG4gICAgZW5kID0gdGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCArIHN0YXJ0XG5cbiAgdmFyIGxlbiA9IGVuZCAtIHN0YXJ0XG5cbiAgaWYgKGxlbiA8IDEwMDAgfHwgIUJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRfc3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRhcmdldC5fc2V0KHRoaXMuc3ViYXJyYXkoc3RhcnQsIHN0YXJ0ICsgbGVuKSwgdGFyZ2V0X3N0YXJ0KVxuICB9XG5cbiAgcmV0dXJuIGxlblxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmIChlbmQgPCBzdGFydCkgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGlmIChzdGFydCA8IDAgfHwgc3RhcnQgPj0gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgaWYgKGVuZCA8IDAgfHwgZW5kID4gdGhpcy5sZW5ndGgpIHRocm93IG5ldyBSYW5nZUVycm9yKCdlbmQgb3V0IG9mIGJvdW5kcycpXG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKSB7XG4gICAgICB0aGlzW2ldID0gdmFsdWVcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFyIGJ5dGVzID0gdXRmOFRvQnl0ZXModmFsdWUudG9TdHJpbmcoKSlcbiAgICB2YXIgbGVuID0gYnl0ZXMubGVuZ3RoXG4gICAgZm9yIChpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgICAgdGhpc1tpXSA9IGJ5dGVzW2kgJSBsZW5dXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEJ1ZmZlci5UWVBFRF9BUlJBWV9TVVBQT1JUKSB7XG4gICAgICByZXR1cm4gKG5ldyBCdWZmZXIodGhpcykpLmJ1ZmZlclxuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYnVmID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5sZW5ndGgpXG4gICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gYnVmLmxlbmd0aDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIGJ1ZltpXSA9IHRoaXNbaV1cbiAgICAgIH1cbiAgICAgIHJldHVybiBidWYuYnVmZmVyXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0J1ZmZlci50b0FycmF5QnVmZmVyIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyJylcbiAgfVxufVxuXG4vLyBIRUxQRVIgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09XG5cbnZhciBCUCA9IEJ1ZmZlci5wcm90b3R5cGVcblxuLyoqXG4gKiBBdWdtZW50IGEgVWludDhBcnJheSAqaW5zdGFuY2UqIChub3QgdGhlIFVpbnQ4QXJyYXkgY2xhc3MhKSB3aXRoIEJ1ZmZlciBtZXRob2RzXG4gKi9cbkJ1ZmZlci5fYXVnbWVudCA9IGZ1bmN0aW9uIChhcnIpIHtcbiAgYXJyLmNvbnN0cnVjdG9yID0gQnVmZmVyXG4gIGFyci5faXNCdWZmZXIgPSB0cnVlXG5cbiAgLy8gc2F2ZSByZWZlcmVuY2UgdG8gb3JpZ2luYWwgVWludDhBcnJheSBnZXQvc2V0IG1ldGhvZHMgYmVmb3JlIG92ZXJ3cml0aW5nXG4gIGFyci5fZ2V0ID0gYXJyLmdldFxuICBhcnIuX3NldCA9IGFyci5zZXRcblxuICAvLyBkZXByZWNhdGVkLCB3aWxsIGJlIHJlbW92ZWQgaW4gbm9kZSAwLjEzK1xuICBhcnIuZ2V0ID0gQlAuZ2V0XG4gIGFyci5zZXQgPSBCUC5zZXRcblxuICBhcnIud3JpdGUgPSBCUC53cml0ZVxuICBhcnIudG9TdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9Mb2NhbGVTdHJpbmcgPSBCUC50b1N0cmluZ1xuICBhcnIudG9KU09OID0gQlAudG9KU09OXG4gIGFyci5lcXVhbHMgPSBCUC5lcXVhbHNcbiAgYXJyLmNvbXBhcmUgPSBCUC5jb21wYXJlXG4gIGFyci5jb3B5ID0gQlAuY29weVxuICBhcnIuc2xpY2UgPSBCUC5zbGljZVxuICBhcnIucmVhZFVJbnRMRSA9IEJQLnJlYWRVSW50TEVcbiAgYXJyLnJlYWRVSW50QkUgPSBCUC5yZWFkVUludEJFXG4gIGFyci5yZWFkVUludDggPSBCUC5yZWFkVUludDhcbiAgYXJyLnJlYWRVSW50MTZMRSA9IEJQLnJlYWRVSW50MTZMRVxuICBhcnIucmVhZFVJbnQxNkJFID0gQlAucmVhZFVJbnQxNkJFXG4gIGFyci5yZWFkVUludDMyTEUgPSBCUC5yZWFkVUludDMyTEVcbiAgYXJyLnJlYWRVSW50MzJCRSA9IEJQLnJlYWRVSW50MzJCRVxuICBhcnIucmVhZEludExFID0gQlAucmVhZEludExFXG4gIGFyci5yZWFkSW50QkUgPSBCUC5yZWFkSW50QkVcbiAgYXJyLnJlYWRJbnQ4ID0gQlAucmVhZEludDhcbiAgYXJyLnJlYWRJbnQxNkxFID0gQlAucmVhZEludDE2TEVcbiAgYXJyLnJlYWRJbnQxNkJFID0gQlAucmVhZEludDE2QkVcbiAgYXJyLnJlYWRJbnQzMkxFID0gQlAucmVhZEludDMyTEVcbiAgYXJyLnJlYWRJbnQzMkJFID0gQlAucmVhZEludDMyQkVcbiAgYXJyLnJlYWRGbG9hdExFID0gQlAucmVhZEZsb2F0TEVcbiAgYXJyLnJlYWRGbG9hdEJFID0gQlAucmVhZEZsb2F0QkVcbiAgYXJyLnJlYWREb3VibGVMRSA9IEJQLnJlYWREb3VibGVMRVxuICBhcnIucmVhZERvdWJsZUJFID0gQlAucmVhZERvdWJsZUJFXG4gIGFyci53cml0ZVVJbnQ4ID0gQlAud3JpdGVVSW50OFxuICBhcnIud3JpdGVVSW50TEUgPSBCUC53cml0ZVVJbnRMRVxuICBhcnIud3JpdGVVSW50QkUgPSBCUC53cml0ZVVJbnRCRVxuICBhcnIud3JpdGVVSW50MTZMRSA9IEJQLndyaXRlVUludDE2TEVcbiAgYXJyLndyaXRlVUludDE2QkUgPSBCUC53cml0ZVVJbnQxNkJFXG4gIGFyci53cml0ZVVJbnQzMkxFID0gQlAud3JpdGVVSW50MzJMRVxuICBhcnIud3JpdGVVSW50MzJCRSA9IEJQLndyaXRlVUludDMyQkVcbiAgYXJyLndyaXRlSW50TEUgPSBCUC53cml0ZUludExFXG4gIGFyci53cml0ZUludEJFID0gQlAud3JpdGVJbnRCRVxuICBhcnIud3JpdGVJbnQ4ID0gQlAud3JpdGVJbnQ4XG4gIGFyci53cml0ZUludDE2TEUgPSBCUC53cml0ZUludDE2TEVcbiAgYXJyLndyaXRlSW50MTZCRSA9IEJQLndyaXRlSW50MTZCRVxuICBhcnIud3JpdGVJbnQzMkxFID0gQlAud3JpdGVJbnQzMkxFXG4gIGFyci53cml0ZUludDMyQkUgPSBCUC53cml0ZUludDMyQkVcbiAgYXJyLndyaXRlRmxvYXRMRSA9IEJQLndyaXRlRmxvYXRMRVxuICBhcnIud3JpdGVGbG9hdEJFID0gQlAud3JpdGVGbG9hdEJFXG4gIGFyci53cml0ZURvdWJsZUxFID0gQlAud3JpdGVEb3VibGVMRVxuICBhcnIud3JpdGVEb3VibGVCRSA9IEJQLndyaXRlRG91YmxlQkVcbiAgYXJyLmZpbGwgPSBCUC5maWxsXG4gIGFyci5pbnNwZWN0ID0gQlAuaW5zcGVjdFxuICBhcnIudG9BcnJheUJ1ZmZlciA9IEJQLnRvQXJyYXlCdWZmZXJcblxuICByZXR1cm4gYXJyXG59XG5cbnZhciBJTlZBTElEX0JBU0U2NF9SRSA9IC9bXitcXC8wLTlBLXpcXC1dL2dcblxuZnVuY3Rpb24gYmFzZTY0Y2xlYW4gKHN0cikge1xuICAvLyBOb2RlIHN0cmlwcyBvdXQgaW52YWxpZCBjaGFyYWN0ZXJzIGxpa2UgXFxuIGFuZCBcXHQgZnJvbSB0aGUgc3RyaW5nLCBiYXNlNjQtanMgZG9lcyBub3RcbiAgc3RyID0gc3RyaW5ndHJpbShzdHIpLnJlcGxhY2UoSU5WQUxJRF9CQVNFNjRfUkUsICcnKVxuICAvLyBOb2RlIGNvbnZlcnRzIHN0cmluZ3Mgd2l0aCBsZW5ndGggPCAyIHRvICcnXG4gIGlmIChzdHIubGVuZ3RoIDwgMikgcmV0dXJuICcnXG4gIC8vIE5vZGUgYWxsb3dzIGZvciBub24tcGFkZGVkIGJhc2U2NCBzdHJpbmdzIChtaXNzaW5nIHRyYWlsaW5nID09PSksIGJhc2U2NC1qcyBkb2VzIG5vdFxuICB3aGlsZSAoc3RyLmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICBzdHIgPSBzdHIgKyAnPSdcbiAgfVxuICByZXR1cm4gc3RyXG59XG5cbmZ1bmN0aW9uIHN0cmluZ3RyaW0gKHN0cikge1xuICBpZiAoc3RyLnRyaW0pIHJldHVybiBzdHIudHJpbSgpXG4gIHJldHVybiBzdHIucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpXG59XG5cbmZ1bmN0aW9uIGlzQXJyYXlpc2ggKHN1YmplY3QpIHtcbiAgcmV0dXJuIGlzQXJyYXkoc3ViamVjdCkgfHwgQnVmZmVyLmlzQnVmZmVyKHN1YmplY3QpIHx8XG4gICAgICBzdWJqZWN0ICYmIHR5cGVvZiBzdWJqZWN0ID09PSAnb2JqZWN0JyAmJlxuICAgICAgdHlwZW9mIHN1YmplY3QubGVuZ3RoID09PSAnbnVtYmVyJ1xufVxuXG5mdW5jdGlvbiB0b0hleCAobikge1xuICBpZiAobiA8IDE2KSByZXR1cm4gJzAnICsgbi50b1N0cmluZygxNilcbiAgcmV0dXJuIG4udG9TdHJpbmcoMTYpXG59XG5cbmZ1bmN0aW9uIHV0ZjhUb0J5dGVzKHN0cmluZywgdW5pdHMpIHtcbiAgdmFyIGNvZGVQb2ludCwgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aFxuICB2YXIgbGVhZFN1cnJvZ2F0ZSA9IG51bGxcbiAgdW5pdHMgPSB1bml0cyB8fCBJbmZpbml0eVxuICB2YXIgYnl0ZXMgPSBbXVxuICB2YXIgaSA9IDBcblxuICBmb3IgKDsgaTxsZW5ndGg7IGkrKykge1xuICAgIGNvZGVQb2ludCA9IHN0cmluZy5jaGFyQ29kZUF0KGkpXG5cbiAgICAvLyBpcyBzdXJyb2dhdGUgY29tcG9uZW50XG4gICAgaWYgKGNvZGVQb2ludCA+IDB4RDdGRiAmJiBjb2RlUG9pbnQgPCAweEUwMDApIHtcblxuICAgICAgLy8gbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICAgIGlmIChsZWFkU3Vycm9nYXRlKSB7XG5cbiAgICAgICAgLy8gMiBsZWFkcyBpbiBhIHJvd1xuICAgICAgICBpZiAoY29kZVBvaW50IDwgMHhEQzAwKSB7XG4gICAgICAgICAgaWYgKCh1bml0cyAtPSAzKSA+IC0xKSBieXRlcy5wdXNoKDB4RUYsIDB4QkYsIDB4QkQpXG4gICAgICAgICAgbGVhZFN1cnJvZ2F0ZSA9IGNvZGVQb2ludFxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB2YWxpZCBzdXJyb2dhdGUgcGFpclxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBjb2RlUG9pbnQgPSBsZWFkU3Vycm9nYXRlIC0gMHhEODAwIDw8IDEwIHwgY29kZVBvaW50IC0gMHhEQzAwIHwgMHgxMDAwMFxuICAgICAgICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gbm8gbGVhZCB5ZXRcbiAgICAgIGVsc2Uge1xuXG4gICAgICAgIC8vIHVuZXhwZWN0ZWQgdHJhaWxcbiAgICAgICAgaWYgKGNvZGVQb2ludCA+IDB4REJGRikge1xuICAgICAgICAgIGlmICgodW5pdHMgLT0gMykgPiAtMSkgYnl0ZXMucHVzaCgweEVGLCAweEJGLCAweEJEKVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICAvLyB1bnBhaXJlZCBsZWFkXG4gICAgICAgIGVsc2UgaWYgKGkgKyAxID09PSBsZW5ndGgpIHtcbiAgICAgICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gdmFsaWQgbGVhZFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBsZWFkU3Vycm9nYXRlID0gY29kZVBvaW50XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHZhbGlkIGJtcCBjaGFyLCBidXQgbGFzdCBjaGFyIHdhcyBhIGxlYWRcbiAgICBlbHNlIGlmIChsZWFkU3Vycm9nYXRlKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpID4gLTEpIGJ5dGVzLnB1c2goMHhFRiwgMHhCRiwgMHhCRClcbiAgICAgIGxlYWRTdXJyb2dhdGUgPSBudWxsXG4gICAgfVxuXG4gICAgLy8gZW5jb2RlIHV0ZjhcbiAgICBpZiAoY29kZVBvaW50IDwgMHg4MCkge1xuICAgICAgaWYgKCh1bml0cyAtPSAxKSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKGNvZGVQb2ludClcbiAgICB9XG4gICAgZWxzZSBpZiAoY29kZVBvaW50IDwgMHg4MDApIHtcbiAgICAgIGlmICgodW5pdHMgLT0gMikgPCAwKSBicmVha1xuICAgICAgYnl0ZXMucHVzaChcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiB8IDB4QzAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDEwMDAwKSB7XG4gICAgICBpZiAoKHVuaXRzIC09IDMpIDwgMCkgYnJlYWtcbiAgICAgIGJ5dGVzLnB1c2goXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgfCAweEUwLFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHg2ICYgMHgzRiB8IDB4ODAsXG4gICAgICAgIGNvZGVQb2ludCAmIDB4M0YgfCAweDgwXG4gICAgICApO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlUG9pbnQgPCAweDIwMDAwMCkge1xuICAgICAgaWYgKCh1bml0cyAtPSA0KSA8IDApIGJyZWFrXG4gICAgICBieXRlcy5wdXNoKFxuICAgICAgICBjb2RlUG9pbnQgPj4gMHgxMiB8IDB4RjAsXG4gICAgICAgIGNvZGVQb2ludCA+PiAweEMgJiAweDNGIHwgMHg4MCxcbiAgICAgICAgY29kZVBvaW50ID4+IDB4NiAmIDB4M0YgfCAweDgwLFxuICAgICAgICBjb2RlUG9pbnQgJiAweDNGIHwgMHg4MFxuICAgICAgKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgY29kZSBwb2ludCcpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVzXG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIsIHVuaXRzKSB7XG4gIHZhciBjLCBoaSwgbG9cbiAgdmFyIGJ5dGVBcnJheSA9IFtdXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgaSsrKSB7XG5cbiAgICBpZiAoKHVuaXRzIC09IDIpIDwgMCkgYnJlYWtcblxuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKVxuICAgIGhpID0gYyA+PiA4XG4gICAgbG8gPSBjICUgMjU2XG4gICAgYnl0ZUFycmF5LnB1c2gobG8pXG4gICAgYnl0ZUFycmF5LnB1c2goaGkpXG4gIH1cblxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGJhc2U2NFRvQnl0ZXMgKHN0cikge1xuICByZXR1cm4gYmFzZTY0LnRvQnl0ZUFycmF5KGJhc2U2NGNsZWFuKHN0cikpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCwgdW5pdFNpemUpIHtcbiAgaWYgKHVuaXRTaXplKSBsZW5ndGggLT0gbGVuZ3RoICUgdW5pdFNpemU7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpXG4gICAgICBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGRlY29kZVV0ZjhDaGFyIChzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRkZEKSAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuIiwidmFyIGxvb2t1cCA9ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvJztcblxuOyhmdW5jdGlvbiAoZXhwb3J0cykge1xuXHQndXNlIHN0cmljdCc7XG5cbiAgdmFyIEFyciA9ICh0eXBlb2YgVWludDhBcnJheSAhPT0gJ3VuZGVmaW5lZCcpXG4gICAgPyBVaW50OEFycmF5XG4gICAgOiBBcnJheVxuXG5cdHZhciBQTFVTICAgPSAnKycuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0ggID0gJy8nLmNoYXJDb2RlQXQoMClcblx0dmFyIE5VTUJFUiA9ICcwJy5jaGFyQ29kZUF0KDApXG5cdHZhciBMT1dFUiAgPSAnYScuY2hhckNvZGVBdCgwKVxuXHR2YXIgVVBQRVIgID0gJ0EnLmNoYXJDb2RlQXQoMClcblx0dmFyIFBMVVNfVVJMX1NBRkUgPSAnLScuY2hhckNvZGVBdCgwKVxuXHR2YXIgU0xBU0hfVVJMX1NBRkUgPSAnXycuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTIHx8XG5cdFx0ICAgIGNvZGUgPT09IFBMVVNfVVJMX1NBRkUpXG5cdFx0XHRyZXR1cm4gNjIgLy8gJysnXG5cdFx0aWYgKGNvZGUgPT09IFNMQVNIIHx8XG5cdFx0ICAgIGNvZGUgPT09IFNMQVNIX1VSTF9TQUZFKVxuXHRcdFx0cmV0dXJuIDYzIC8vICcvJ1xuXHRcdGlmIChjb2RlIDwgTlVNQkVSKVxuXHRcdFx0cmV0dXJuIC0xIC8vbm8gbWF0Y2hcblx0XHRpZiAoY29kZSA8IE5VTUJFUiArIDEwKVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBOVU1CRVIgKyAyNiArIDI2XG5cdFx0aWYgKGNvZGUgPCBVUFBFUiArIDI2KVxuXHRcdFx0cmV0dXJuIGNvZGUgLSBVUFBFUlxuXHRcdGlmIChjb2RlIDwgTE9XRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gTE9XRVIgKyAyNlxuXHR9XG5cblx0ZnVuY3Rpb24gYjY0VG9CeXRlQXJyYXkgKGI2NCkge1xuXHRcdHZhciBpLCBqLCBsLCB0bXAsIHBsYWNlSG9sZGVycywgYXJyXG5cblx0XHRpZiAoYjY0Lmxlbmd0aCAlIDQgPiAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgc3RyaW5nLiBMZW5ndGggbXVzdCBiZSBhIG11bHRpcGxlIG9mIDQnKVxuXHRcdH1cblxuXHRcdC8vIHRoZSBudW1iZXIgb2YgZXF1YWwgc2lnbnMgKHBsYWNlIGhvbGRlcnMpXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHR3byBwbGFjZWhvbGRlcnMsIHRoYW4gdGhlIHR3byBjaGFyYWN0ZXJzIGJlZm9yZSBpdFxuXHRcdC8vIHJlcHJlc2VudCBvbmUgYnl0ZVxuXHRcdC8vIGlmIHRoZXJlIGlzIG9ubHkgb25lLCB0aGVuIHRoZSB0aHJlZSBjaGFyYWN0ZXJzIGJlZm9yZSBpdCByZXByZXNlbnQgMiBieXRlc1xuXHRcdC8vIHRoaXMgaXMganVzdCBhIGNoZWFwIGhhY2sgdG8gbm90IGRvIGluZGV4T2YgdHdpY2Vcblx0XHR2YXIgbGVuID0gYjY0Lmxlbmd0aFxuXHRcdHBsYWNlSG9sZGVycyA9ICc9JyA9PT0gYjY0LmNoYXJBdChsZW4gLSAyKSA/IDIgOiAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMSkgPyAxIDogMFxuXG5cdFx0Ly8gYmFzZTY0IGlzIDQvMyArIHVwIHRvIHR3byBjaGFyYWN0ZXJzIG9mIHRoZSBvcmlnaW5hbCBkYXRhXG5cdFx0YXJyID0gbmV3IEFycihiNjQubGVuZ3RoICogMyAvIDQgLSBwbGFjZUhvbGRlcnMpXG5cblx0XHQvLyBpZiB0aGVyZSBhcmUgcGxhY2Vob2xkZXJzLCBvbmx5IGdldCB1cCB0byB0aGUgbGFzdCBjb21wbGV0ZSA0IGNoYXJzXG5cdFx0bCA9IHBsYWNlSG9sZGVycyA+IDAgPyBiNjQubGVuZ3RoIC0gNCA6IGI2NC5sZW5ndGhcblxuXHRcdHZhciBMID0gMFxuXG5cdFx0ZnVuY3Rpb24gcHVzaCAodikge1xuXHRcdFx0YXJyW0wrK10gPSB2XG5cdFx0fVxuXG5cdFx0Zm9yIChpID0gMCwgaiA9IDA7IGkgPCBsOyBpICs9IDQsIGogKz0gMykge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxOCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCAxMikgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA8PCA2KSB8IGRlY29kZShiNjQuY2hhckF0KGkgKyAzKSlcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMDAwKSA+PiAxNilcblx0XHRcdHB1c2goKHRtcCAmIDB4RkYwMCkgPj4gOClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRpZiAocGxhY2VIb2xkZXJzID09PSAyKSB7XG5cdFx0XHR0bXAgPSAoZGVjb2RlKGI2NC5jaGFyQXQoaSkpIDw8IDIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPj4gNClcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9IGVsc2UgaWYgKHBsYWNlSG9sZGVycyA9PT0gMSkge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAxMCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDEpKSA8PCA0KSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMikpID4+IDIpXG5cdFx0XHRwdXNoKCh0bXAgPj4gOCkgJiAweEZGKVxuXHRcdFx0cHVzaCh0bXAgJiAweEZGKVxuXHRcdH1cblxuXHRcdHJldHVybiBhcnJcblx0fVxuXG5cdGZ1bmN0aW9uIHVpbnQ4VG9CYXNlNjQgKHVpbnQ4KSB7XG5cdFx0dmFyIGksXG5cdFx0XHRleHRyYUJ5dGVzID0gdWludDgubGVuZ3RoICUgMywgLy8gaWYgd2UgaGF2ZSAxIGJ5dGUgbGVmdCwgcGFkIDIgYnl0ZXNcblx0XHRcdG91dHB1dCA9IFwiXCIsXG5cdFx0XHR0ZW1wLCBsZW5ndGhcblxuXHRcdGZ1bmN0aW9uIGVuY29kZSAobnVtKSB7XG5cdFx0XHRyZXR1cm4gbG9va3VwLmNoYXJBdChudW0pXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gdHJpcGxldFRvQmFzZTY0IChudW0pIHtcblx0XHRcdHJldHVybiBlbmNvZGUobnVtID4+IDE4ICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDEyICYgMHgzRikgKyBlbmNvZGUobnVtID4+IDYgJiAweDNGKSArIGVuY29kZShudW0gJiAweDNGKVxuXHRcdH1cblxuXHRcdC8vIGdvIHRocm91Z2ggdGhlIGFycmF5IGV2ZXJ5IHRocmVlIGJ5dGVzLCB3ZSdsbCBkZWFsIHdpdGggdHJhaWxpbmcgc3R1ZmYgbGF0ZXJcblx0XHRmb3IgKGkgPSAwLCBsZW5ndGggPSB1aW50OC5sZW5ndGggLSBleHRyYUJ5dGVzOyBpIDwgbGVuZ3RoOyBpICs9IDMpIHtcblx0XHRcdHRlbXAgPSAodWludDhbaV0gPDwgMTYpICsgKHVpbnQ4W2kgKyAxXSA8PCA4KSArICh1aW50OFtpICsgMl0pXG5cdFx0XHRvdXRwdXQgKz0gdHJpcGxldFRvQmFzZTY0KHRlbXApXG5cdFx0fVxuXG5cdFx0Ly8gcGFkIHRoZSBlbmQgd2l0aCB6ZXJvcywgYnV0IG1ha2Ugc3VyZSB0byBub3QgZm9yZ2V0IHRoZSBleHRyYSBieXRlc1xuXHRcdHN3aXRjaCAoZXh0cmFCeXRlcykge1xuXHRcdFx0Y2FzZSAxOlxuXHRcdFx0XHR0ZW1wID0gdWludDhbdWludDgubGVuZ3RoIC0gMV1cblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDIpXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPDwgNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gJz09J1xuXHRcdFx0XHRicmVha1xuXHRcdFx0Y2FzZSAyOlxuXHRcdFx0XHR0ZW1wID0gKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDJdIDw8IDgpICsgKHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKHRlbXAgPj4gMTApXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUoKHRlbXAgPj4gNCkgJiAweDNGKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDIpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9J1xuXHRcdFx0XHRicmVha1xuXHRcdH1cblxuXHRcdHJldHVybiBvdXRwdXRcblx0fVxuXG5cdGV4cG9ydHMudG9CeXRlQXJyYXkgPSBiNjRUb0J5dGVBcnJheVxuXHRleHBvcnRzLmZyb21CeXRlQXJyYXkgPSB1aW50OFRvQmFzZTY0XG59KHR5cGVvZiBleHBvcnRzID09PSAndW5kZWZpbmVkJyA/ICh0aGlzLmJhc2U2NGpzID0ge30pIDogZXhwb3J0cykpXG4iLCJleHBvcnRzLnJlYWQgPSBmdW5jdGlvbihidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIG5CaXRzID0gLTcsXG4gICAgICBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDAsXG4gICAgICBkID0gaXNMRSA/IC0xIDogMSxcbiAgICAgIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV07XG5cbiAgaSArPSBkO1xuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBzID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gZUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIGUgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXM7XG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XG59O1xuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24oYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGMsXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxuICAgICAgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpLFxuICAgICAgZCA9IGlzTEUgPyAxIDogLTEsXG4gICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrO1xuICAgICAgYyAvPSAyO1xuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcblxuICBlID0gKGUgPDwgbUxlbikgfCBtO1xuICBlTGVuICs9IG1MZW47XG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xufTtcbiIsIlxuLyoqXG4gKiBpc0FycmF5XG4gKi9cblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuXG4vKipcbiAqIHRvU3RyaW5nXG4gKi9cblxudmFyIHN0ciA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV2hldGhlciBvciBub3QgdGhlIGdpdmVuIGB2YWxgXG4gKiBpcyBhbiBhcnJheS5cbiAqXG4gKiBleGFtcGxlOlxuICpcbiAqICAgICAgICBpc0FycmF5KFtdKTtcbiAqICAgICAgICAvLyA+IHRydWVcbiAqICAgICAgICBpc0FycmF5KGFyZ3VtZW50cyk7XG4gKiAgICAgICAgLy8gPiBmYWxzZVxuICogICAgICAgIGlzQXJyYXkoJycpO1xuICogICAgICAgIC8vID4gZmFsc2VcbiAqXG4gKiBAcGFyYW0ge21peGVkfSB2YWxcbiAqIEByZXR1cm4ge2Jvb2x9XG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5IHx8IGZ1bmN0aW9uICh2YWwpIHtcbiAgcmV0dXJuICEhIHZhbCAmJiAnW29iamVjdCBBcnJheV0nID09IHN0ci5jYWxsKHZhbCk7XG59O1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcblxucHJvY2Vzcy5uZXh0VGljayA9IChmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGNhblNldEltbWVkaWF0ZSA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93LnNldEltbWVkaWF0ZTtcbiAgICB2YXIgY2FuTXV0YXRpb25PYnNlcnZlciA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gICAgJiYgd2luZG93Lk11dGF0aW9uT2JzZXJ2ZXI7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgdmFyIHF1ZXVlID0gW107XG5cbiAgICBpZiAoY2FuTXV0YXRpb25PYnNlcnZlcikge1xuICAgICAgICB2YXIgaGlkZGVuRGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgdmFyIG9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHF1ZXVlTGlzdCA9IHF1ZXVlLnNsaWNlKCk7XG4gICAgICAgICAgICBxdWV1ZS5sZW5ndGggPSAwO1xuICAgICAgICAgICAgcXVldWVMaXN0LmZvckVhY2goZnVuY3Rpb24gKGZuKSB7XG4gICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBvYnNlcnZlci5vYnNlcnZlKGhpZGRlbkRpdiwgeyBhdHRyaWJ1dGVzOiB0cnVlIH0pO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgaWYgKCFxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBoaWRkZW5EaXYuc2V0QXR0cmlidXRlKCd5ZXMnLCAnbm8nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHF1ZXVlLnB1c2goZm4pO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmIChjYW5Qb3N0KSB7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbi8vIFRPRE8oc2h0eWxtYW4pXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbiIsIi8qICBQcm90b3R5cGUgSmF2YVNjcmlwdCBmcmFtZXdvcmssIHZlcnNpb24gMS43LjJcbiAqICAoYykgMjAwNS0yMDEwIFNhbSBTdGVwaGVuc29uXG4gKlxuICogIFByb3RvdHlwZSBpcyBmcmVlbHkgZGlzdHJpYnV0YWJsZSB1bmRlciB0aGUgdGVybXMgb2YgYW4gTUlULXN0eWxlIGxpY2Vuc2UuXG4gKiAgRm9yIGRldGFpbHMsIHNlZSB0aGUgUHJvdG90eXBlIHdlYiBzaXRlOiBodHRwOi8vd3d3LnByb3RvdHlwZWpzLm9yZy9cbiAqXG4gKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxudmFyIFByb3RvdHlwZSA9IHtcblxuICBWZXJzaW9uOiAnMS43LjInLFxuXG4gIEJyb3dzZXI6IChmdW5jdGlvbigpe1xuICAgIHZhciB1YSA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgdmFyIGlzT3BlcmEgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93Lm9wZXJhKSA9PSAnW29iamVjdCBPcGVyYV0nO1xuICAgIHJldHVybiB7XG4gICAgICBJRTogICAgICAgICAgICAgISF3aW5kb3cuYXR0YWNoRXZlbnQgJiYgIWlzT3BlcmEsXG4gICAgICBPcGVyYTogICAgICAgICAgaXNPcGVyYSxcbiAgICAgIFdlYktpdDogICAgICAgICB1YS5pbmRleE9mKCdBcHBsZVdlYktpdC8nKSA+IC0xLFxuICAgICAgR2Vja286ICAgICAgICAgIHVhLmluZGV4T2YoJ0dlY2tvJykgPiAtMSAmJiB1YS5pbmRleE9mKCdLSFRNTCcpID09PSAtMSxcbiAgICAgIE1vYmlsZVNhZmFyaTogICAvQXBwbGUuKk1vYmlsZS8udGVzdCh1YSlcbiAgICB9XG4gIH0pKCksXG5cbiAgQnJvd3NlckZlYXR1cmVzOiB7XG4gICAgWFBhdGg6ICEhZG9jdW1lbnQuZXZhbHVhdGUsXG5cbiAgICBTZWxlY3RvcnNBUEk6ICEhZG9jdW1lbnQucXVlcnlTZWxlY3RvcixcblxuICAgIEVsZW1lbnRFeHRlbnNpb25zOiAoZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3cuRWxlbWVudCB8fCB3aW5kb3cuSFRNTEVsZW1lbnQ7XG4gICAgICByZXR1cm4gISEoY29uc3RydWN0b3IgJiYgY29uc3RydWN0b3IucHJvdG90eXBlKTtcbiAgICB9KSgpLFxuICAgIFNwZWNpZmljRWxlbWVudEV4dGVuc2lvbnM6IChmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0eXBlb2Ygd2luZG93LkhUTUxEaXZFbGVtZW50ICE9PSAndW5kZWZpbmVkJylcbiAgICAgICAgcmV0dXJuIHRydWU7XG5cbiAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSxcbiAgICAgICAgICBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZm9ybScpLFxuICAgICAgICAgIGlzU3VwcG9ydGVkID0gZmFsc2U7XG5cbiAgICAgIGlmIChkaXZbJ19fcHJvdG9fXyddICYmIChkaXZbJ19fcHJvdG9fXyddICE9PSBmb3JtWydfX3Byb3RvX18nXSkpIHtcbiAgICAgICAgaXNTdXBwb3J0ZWQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBkaXYgPSBmb3JtID0gbnVsbDtcblxuICAgICAgcmV0dXJuIGlzU3VwcG9ydGVkO1xuICAgIH0pKClcbiAgfSxcblxuICBTY3JpcHRGcmFnbWVudDogJzxzY3JpcHRbXj5dKj4oW1xcXFxTXFxcXHNdKj8pPFxcL3NjcmlwdFxcXFxzKj4nLFxuICBKU09ORmlsdGVyOiAvXlxcL1xcKi1zZWN1cmUtKFtcXHNcXFNdKilcXCpcXC9cXHMqJC8sXG5cbiAgZW1wdHlGdW5jdGlvbjogZnVuY3Rpb24oKSB7IH0sXG5cbiAgSzogZnVuY3Rpb24oeCkgeyByZXR1cm4geCB9XG59O1xuXG5pZiAoUHJvdG90eXBlLkJyb3dzZXIuTW9iaWxlU2FmYXJpKVxuICBQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLlNwZWNpZmljRWxlbWVudEV4dGVuc2lvbnMgPSBmYWxzZTtcbi8qIEJhc2VkIG9uIEFsZXggQXJuZWxsJ3MgaW5oZXJpdGFuY2UgaW1wbGVtZW50YXRpb24uICovXG5cbnZhciBDbGFzcyA9IChmdW5jdGlvbigpIHtcblxuICB2YXIgSVNfRE9OVEVOVU1fQlVHR1kgPSAoZnVuY3Rpb24oKXtcbiAgICBmb3IgKHZhciBwIGluIHsgdG9TdHJpbmc6IDEgfSkge1xuICAgICAgaWYgKHAgPT09ICd0b1N0cmluZycpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0pKCk7XG5cbiAgZnVuY3Rpb24gc3ViY2xhc3MoKSB7fTtcbiAgZnVuY3Rpb24gY3JlYXRlKCkge1xuICAgIHZhciBwYXJlbnQgPSBudWxsLCBwcm9wZXJ0aWVzID0gJEEoYXJndW1lbnRzKTtcbiAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24ocHJvcGVydGllc1swXSkpXG4gICAgICBwYXJlbnQgPSBwcm9wZXJ0aWVzLnNoaWZ0KCk7XG5cbiAgICBmdW5jdGlvbiBrbGFzcygpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIE9iamVjdC5leHRlbmQoa2xhc3MsIENsYXNzLk1ldGhvZHMpO1xuICAgIGtsYXNzLnN1cGVyY2xhc3MgPSBwYXJlbnQ7XG4gICAga2xhc3Muc3ViY2xhc3NlcyA9IFtdO1xuXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgc3ViY2xhc3MucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTtcbiAgICAgIGtsYXNzLnByb3RvdHlwZSA9IG5ldyBzdWJjbGFzcztcbiAgICAgIHBhcmVudC5zdWJjbGFzc2VzLnB1c2goa2xhc3MpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBwcm9wZXJ0aWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKVxuICAgICAga2xhc3MuYWRkTWV0aG9kcyhwcm9wZXJ0aWVzW2ldKTtcblxuICAgIGlmICgha2xhc3MucHJvdG90eXBlLmluaXRpYWxpemUpXG4gICAgICBrbGFzcy5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uO1xuXG4gICAga2xhc3MucHJvdG90eXBlLmNvbnN0cnVjdG9yID0ga2xhc3M7XG4gICAgcmV0dXJuIGtsYXNzO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkTWV0aG9kcyhzb3VyY2UpIHtcbiAgICB2YXIgYW5jZXN0b3IgICA9IHRoaXMuc3VwZXJjbGFzcyAmJiB0aGlzLnN1cGVyY2xhc3MucHJvdG90eXBlLFxuICAgICAgICBwcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICAgIGlmIChJU19ET05URU5VTV9CVUdHWSkge1xuICAgICAgaWYgKHNvdXJjZS50b1N0cmluZyAhPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nKVxuICAgICAgICBwcm9wZXJ0aWVzLnB1c2goXCJ0b1N0cmluZ1wiKTtcbiAgICAgIGlmIChzb3VyY2UudmFsdWVPZiAhPSBPYmplY3QucHJvdG90eXBlLnZhbHVlT2YpXG4gICAgICAgIHByb3BlcnRpZXMucHVzaChcInZhbHVlT2ZcIik7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHByb3BlcnRpZXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaV0sIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XTtcbiAgICAgIGlmIChhbmNlc3RvciAmJiBPYmplY3QuaXNGdW5jdGlvbih2YWx1ZSkgJiZcbiAgICAgICAgICB2YWx1ZS5hcmd1bWVudE5hbWVzKClbMF0gPT0gXCIkc3VwZXJcIikge1xuICAgICAgICB2YXIgbWV0aG9kID0gdmFsdWU7XG4gICAgICAgIHZhbHVlID0gKGZ1bmN0aW9uKG0pIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBhbmNlc3RvclttXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpOyB9O1xuICAgICAgICB9KShwcm9wZXJ0eSkud3JhcChtZXRob2QpO1xuXG4gICAgICAgIHZhbHVlLnZhbHVlT2YgPSAoZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gbWV0aG9kLnZhbHVlT2YuY2FsbChtZXRob2QpOyB9O1xuICAgICAgICB9KShtZXRob2QpO1xuXG4gICAgICAgIHZhbHVlLnRvU3RyaW5nID0gKGZ1bmN0aW9uKG1ldGhvZCkge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ldGhvZC50b1N0cmluZy5jYWxsKG1ldGhvZCk7IH07XG4gICAgICAgIH0pKG1ldGhvZCk7XG4gICAgICB9XG4gICAgICB0aGlzLnByb3RvdHlwZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY3JlYXRlOiBjcmVhdGUsXG4gICAgTWV0aG9kczoge1xuICAgICAgYWRkTWV0aG9kczogYWRkTWV0aG9kc1xuICAgIH1cbiAgfTtcbn0pKCk7XG4oZnVuY3Rpb24oKSB7XG5cbiAgdmFyIF90b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsXG4gICAgICBfaGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LFxuICAgICAgTlVMTF9UWVBFID0gJ051bGwnLFxuICAgICAgVU5ERUZJTkVEX1RZUEUgPSAnVW5kZWZpbmVkJyxcbiAgICAgIEJPT0xFQU5fVFlQRSA9ICdCb29sZWFuJyxcbiAgICAgIE5VTUJFUl9UWVBFID0gJ051bWJlcicsXG4gICAgICBTVFJJTkdfVFlQRSA9ICdTdHJpbmcnLFxuICAgICAgT0JKRUNUX1RZUEUgPSAnT2JqZWN0JyxcbiAgICAgIEZVTkNUSU9OX0NMQVNTID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICAgIEJPT0xFQU5fQ0xBU1MgPSAnW29iamVjdCBCb29sZWFuXScsXG4gICAgICBOVU1CRVJfQ0xBU1MgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICAgIFNUUklOR19DTEFTUyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgICAgQVJSQVlfQ0xBU1MgPSAnW29iamVjdCBBcnJheV0nLFxuICAgICAgREFURV9DTEFTUyA9ICdbb2JqZWN0IERhdGVdJyxcbiAgICAgIE5BVElWRV9KU09OX1NUUklOR0lGWV9TVVBQT1JUID0gd2luZG93LkpTT04gJiZcbiAgICAgICAgdHlwZW9mIEpTT04uc3RyaW5naWZ5ID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KDApID09PSAnMCcgJiZcbiAgICAgICAgdHlwZW9mIEpTT04uc3RyaW5naWZ5KFByb3RvdHlwZS5LKSA9PT0gJ3VuZGVmaW5lZCc7XG5cblxuXG4gIHZhciBET05UX0VOVU1TID0gWyd0b1N0cmluZycsICd0b0xvY2FsZVN0cmluZycsICd2YWx1ZU9mJyxcbiAgICdoYXNPd25Qcm9wZXJ0eScsICdpc1Byb3RvdHlwZU9mJywgJ3Byb3BlcnR5SXNFbnVtZXJhYmxlJywgJ2NvbnN0cnVjdG9yJ107XG5cbiAgdmFyIElTX0RPTlRFTlVNX0JVR0dZID0gKGZ1bmN0aW9uKCl7XG4gICAgZm9yICh2YXIgcCBpbiB7IHRvU3RyaW5nOiAxIH0pIHtcbiAgICAgIGlmIChwID09PSAndG9TdHJpbmcnKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9KSgpO1xuXG4gIGZ1bmN0aW9uIFR5cGUobykge1xuICAgIHN3aXRjaChvKSB7XG4gICAgICBjYXNlIG51bGw6IHJldHVybiBOVUxMX1RZUEU7XG4gICAgICBjYXNlICh2b2lkIDApOiByZXR1cm4gVU5ERUZJTkVEX1RZUEU7XG4gICAgfVxuICAgIHZhciB0eXBlID0gdHlwZW9mIG87XG4gICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOiByZXR1cm4gQk9PTEVBTl9UWVBFO1xuICAgICAgY2FzZSAnbnVtYmVyJzogIHJldHVybiBOVU1CRVJfVFlQRTtcbiAgICAgIGNhc2UgJ3N0cmluZyc6ICByZXR1cm4gU1RSSU5HX1RZUEU7XG4gICAgfVxuICAgIHJldHVybiBPQkpFQ1RfVFlQRTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4dGVuZChkZXN0aW5hdGlvbiwgc291cmNlKSB7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gc291cmNlKVxuICAgICAgZGVzdGluYXRpb25bcHJvcGVydHldID0gc291cmNlW3Byb3BlcnR5XTtcbiAgICByZXR1cm4gZGVzdGluYXRpb247XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0KG9iamVjdCkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoaXNVbmRlZmluZWQob2JqZWN0KSkgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgICAgaWYgKG9iamVjdCA9PT0gbnVsbCkgcmV0dXJuICdudWxsJztcbiAgICAgIHJldHVybiBvYmplY3QuaW5zcGVjdCA/IG9iamVjdC5pbnNwZWN0KCkgOiBTdHJpbmcob2JqZWN0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpIHJldHVybiAnLi4uJztcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG9KU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIFN0cignJywgeyAnJzogdmFsdWUgfSwgW10pO1xuICB9XG5cbiAgZnVuY3Rpb24gU3RyKGtleSwgaG9sZGVyLCBzdGFjaykge1xuICAgIHZhciB2YWx1ZSA9IGhvbGRlcltrZXldO1xuICAgIGlmIChUeXBlKHZhbHVlKSA9PT0gT0JKRUNUX1RZUEUgJiYgdHlwZW9mIHZhbHVlLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdmFsdWUgPSB2YWx1ZS50b0pTT04oa2V5KTtcbiAgICB9XG5cbiAgICB2YXIgX2NsYXNzID0gX3RvU3RyaW5nLmNhbGwodmFsdWUpO1xuXG4gICAgc3dpdGNoIChfY2xhc3MpIHtcbiAgICAgIGNhc2UgTlVNQkVSX0NMQVNTOlxuICAgICAgY2FzZSBCT09MRUFOX0NMQVNTOlxuICAgICAgY2FzZSBTVFJJTkdfQ0xBU1M6XG4gICAgICAgIHZhbHVlID0gdmFsdWUudmFsdWVPZigpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodmFsdWUpIHtcbiAgICAgIGNhc2UgbnVsbDogcmV0dXJuICdudWxsJztcbiAgICAgIGNhc2UgdHJ1ZTogcmV0dXJuICd0cnVlJztcbiAgICAgIGNhc2UgZmFsc2U6IHJldHVybiAnZmFsc2UnO1xuICAgIH1cblxuICAgIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgcmV0dXJuIHZhbHVlLmluc3BlY3QodHJ1ZSk7XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICByZXR1cm4gaXNGaW5pdGUodmFsdWUpID8gU3RyaW5nKHZhbHVlKSA6ICdudWxsJztcbiAgICAgIGNhc2UgJ29iamVjdCc6XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IHN0YWNrLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgaWYgKHN0YWNrW2ldID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkN5Y2xpYyByZWZlcmVuY2UgdG8gJ1wiICsgdmFsdWUgKyBcIicgaW4gb2JqZWN0XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFjay5wdXNoKHZhbHVlKTtcblxuICAgICAgICB2YXIgcGFydGlhbCA9IFtdO1xuICAgICAgICBpZiAoX2NsYXNzID09PSBBUlJBWV9DTEFTUykge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHN0ciA9IFN0cihpLCB2YWx1ZSwgc3RhY2spO1xuICAgICAgICAgICAgcGFydGlhbC5wdXNoKHR5cGVvZiBzdHIgPT09ICd1bmRlZmluZWQnID8gJ251bGwnIDogc3RyKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFydGlhbCA9ICdbJyArIHBhcnRpYWwuam9pbignLCcpICsgJ10nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBrZXlzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXSwgc3RyID0gU3RyKGtleSwgdmFsdWUsIHN0YWNrKTtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3RyICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICBwYXJ0aWFsLnB1c2goa2V5Lmluc3BlY3QodHJ1ZSkrICc6JyArIHN0cik7XG4gICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBwYXJ0aWFsID0gJ3snICsgcGFydGlhbC5qb2luKCcsJykgKyAnfSc7XG4gICAgICAgIH1cbiAgICAgICAgc3RhY2sucG9wKCk7XG4gICAgICAgIHJldHVybiBwYXJ0aWFsO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0cmluZ2lmeShvYmplY3QpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkob2JqZWN0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvUXVlcnlTdHJpbmcob2JqZWN0KSB7XG4gICAgcmV0dXJuICRIKG9iamVjdCkudG9RdWVyeVN0cmluZygpO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9IVE1MKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgJiYgb2JqZWN0LnRvSFRNTCA/IG9iamVjdC50b0hUTUwoKSA6IFN0cmluZy5pbnRlcnByZXQob2JqZWN0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG4gICAgaWYgKFR5cGUob2JqZWN0KSAhPT0gT0JKRUNUX1RZUEUpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcigpOyB9XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChfaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSlcbiAgICAgICAgcmVzdWx0cy5wdXNoKHByb3BlcnR5KTtcbiAgICB9XG5cbiAgICBpZiAoSVNfRE9OVEVOVU1fQlVHR1kpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBwcm9wZXJ0eSA9IERPTlRfRU5VTVNbaV07IGkrKykge1xuICAgICAgICBpZiAoX2hhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSkpXG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHByb3BlcnR5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbHVlcyhvYmplY3QpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIG9iamVjdClcbiAgICAgIHJlc3VsdHMucHVzaChvYmplY3RbcHJvcGVydHldKTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsb25lKG9iamVjdCkge1xuICAgIHJldHVybiBleHRlbmQoeyB9LCBvYmplY3QpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNFbGVtZW50KG9iamVjdCkge1xuICAgIHJldHVybiAhIShvYmplY3QgJiYgb2JqZWN0Lm5vZGVUeXBlID09IDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNBcnJheShvYmplY3QpIHtcbiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gQVJSQVlfQ0xBU1M7XG4gIH1cblxuICB2YXIgaGFzTmF0aXZlSXNBcnJheSA9ICh0eXBlb2YgQXJyYXkuaXNBcnJheSA9PSAnZnVuY3Rpb24nKVxuICAgICYmIEFycmF5LmlzQXJyYXkoW10pICYmICFBcnJheS5pc0FycmF5KHt9KTtcblxuICBpZiAoaGFzTmF0aXZlSXNBcnJheSkge1xuICAgIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xuICB9XG5cbiAgZnVuY3Rpb24gaXNIYXNoKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBIYXNoO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNGdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gRlVOQ1RJT05fQ0xBU1M7XG4gIH1cblxuICBmdW5jdGlvbiBpc1N0cmluZyhvYmplY3QpIHtcbiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gU1RSSU5HX0NMQVNTO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNOdW1iZXIob2JqZWN0KSB7XG4gICAgcmV0dXJuIF90b1N0cmluZy5jYWxsKG9iamVjdCkgPT09IE5VTUJFUl9DTEFTUztcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRGF0ZShvYmplY3QpIHtcbiAgICByZXR1cm4gX3RvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gREFURV9DTEFTUztcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzVW5kZWZpbmVkKG9iamVjdCkge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqZWN0ID09PSBcInVuZGVmaW5lZFwiO1xuICB9XG5cbiAgZXh0ZW5kKE9iamVjdCwge1xuICAgIGV4dGVuZDogICAgICAgIGV4dGVuZCxcbiAgICBpbnNwZWN0OiAgICAgICBpbnNwZWN0LFxuICAgIHRvSlNPTjogICAgICAgIE5BVElWRV9KU09OX1NUUklOR0lGWV9TVVBQT1JUID8gc3RyaW5naWZ5IDogdG9KU09OLFxuICAgIHRvUXVlcnlTdHJpbmc6IHRvUXVlcnlTdHJpbmcsXG4gICAgdG9IVE1MOiAgICAgICAgdG9IVE1MLFxuICAgIGtleXM6ICAgICAgICAgIE9iamVjdC5rZXlzIHx8IGtleXMsXG4gICAgdmFsdWVzOiAgICAgICAgdmFsdWVzLFxuICAgIGNsb25lOiAgICAgICAgIGNsb25lLFxuICAgIGlzRWxlbWVudDogICAgIGlzRWxlbWVudCxcbiAgICBpc0FycmF5OiAgICAgICBpc0FycmF5LFxuICAgIGlzSGFzaDogICAgICAgIGlzSGFzaCxcbiAgICBpc0Z1bmN0aW9uOiAgICBpc0Z1bmN0aW9uLFxuICAgIGlzU3RyaW5nOiAgICAgIGlzU3RyaW5nLFxuICAgIGlzTnVtYmVyOiAgICAgIGlzTnVtYmVyLFxuICAgIGlzRGF0ZTogICAgICAgIGlzRGF0ZSxcbiAgICBpc1VuZGVmaW5lZDogICBpc1VuZGVmaW5lZFxuICB9KTtcbn0pKCk7XG5PYmplY3QuZXh0ZW5kKEZ1bmN0aW9uLnByb3RvdHlwZSwgKGZ1bmN0aW9uKCkge1xuICB2YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbiAgZnVuY3Rpb24gdXBkYXRlKGFycmF5LCBhcmdzKSB7XG4gICAgdmFyIGFycmF5TGVuZ3RoID0gYXJyYXkubGVuZ3RoLCBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICB3aGlsZSAobGVuZ3RoLS0pIGFycmF5W2FycmF5TGVuZ3RoICsgbGVuZ3RoXSA9IGFyZ3NbbGVuZ3RoXTtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZShhcnJheSwgYXJncykge1xuICAgIGFycmF5ID0gc2xpY2UuY2FsbChhcnJheSwgMCk7XG4gICAgcmV0dXJuIHVwZGF0ZShhcnJheSwgYXJncyk7XG4gIH1cblxuICBmdW5jdGlvbiBhcmd1bWVudE5hbWVzKCkge1xuICAgIHZhciBuYW1lcyA9IHRoaXMudG9TdHJpbmcoKS5tYXRjaCgvXltcXHNcXChdKmZ1bmN0aW9uW14oXSpcXCgoW14pXSopXFwpLylbMV1cbiAgICAgIC5yZXBsYWNlKC9cXC9cXC8uKj9bXFxyXFxuXXxcXC9cXCooPzoufFtcXHJcXG5dKSo/XFwqXFwvL2csICcnKVxuICAgICAgLnJlcGxhY2UoL1xccysvZywgJycpLnNwbGl0KCcsJyk7XG4gICAgcmV0dXJuIG5hbWVzLmxlbmd0aCA9PSAxICYmICFuYW1lc1swXSA/IFtdIDogbmFtZXM7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGJpbmQoY29udGV4dCkge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMiAmJiBPYmplY3QuaXNVbmRlZmluZWQoYXJndW1lbnRzWzBdKSlcbiAgICAgIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKCFPYmplY3QuaXNGdW5jdGlvbih0aGlzKSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJUaGUgb2JqZWN0IGlzIG5vdCBjYWxsYWJsZS5cIik7XG5cbiAgICB2YXIgbm9wID0gZnVuY3Rpb24oKSB7fTtcbiAgICB2YXIgX19tZXRob2QgPSB0aGlzLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXG4gICAgdmFyIGJvdW5kID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYSA9IG1lcmdlKGFyZ3MsIGFyZ3VtZW50cyk7XG4gICAgICB2YXIgYyA9IHRoaXMgaW5zdGFuY2VvZiBib3VuZCA/IHRoaXMgOiBjb250ZXh0O1xuICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KGMsIGEpO1xuICAgIH07XG5cbiAgICBub3AucHJvdG90eXBlICAgPSB0aGlzLnByb3RvdHlwZTtcbiAgICBib3VuZC5wcm90b3R5cGUgPSBuZXcgbm9wKCk7XG5cbiAgICByZXR1cm4gYm91bmQ7XG4gIH1cblxuICBmdW5jdGlvbiBiaW5kQXNFdmVudExpc3RlbmVyKGNvbnRleHQpIHtcbiAgICB2YXIgX19tZXRob2QgPSB0aGlzLCBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuICAgIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIGEgPSB1cGRhdGUoW2V2ZW50IHx8IHdpbmRvdy5ldmVudF0sIGFyZ3MpO1xuICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KGNvbnRleHQsIGEpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGN1cnJ5KCkge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXM7XG4gICAgdmFyIF9fbWV0aG9kID0gdGhpcywgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYSA9IG1lcmdlKGFyZ3MsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gX19tZXRob2QuYXBwbHkodGhpcywgYSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGVsYXkodGltZW91dCkge1xuICAgIHZhciBfX21ldGhvZCA9IHRoaXMsIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgdGltZW91dCA9IHRpbWVvdXQgKiAxMDAwO1xuICAgIHJldHVybiB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBfX21ldGhvZC5hcHBseShfX21ldGhvZCwgYXJncyk7XG4gICAgfSwgdGltZW91dCk7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZlcigpIHtcbiAgICB2YXIgYXJncyA9IHVwZGF0ZShbMC4wMV0sIGFyZ3VtZW50cyk7XG4gICAgcmV0dXJuIHRoaXMuZGVsYXkuYXBwbHkodGhpcywgYXJncyk7XG4gIH1cblxuICBmdW5jdGlvbiB3cmFwKHdyYXBwZXIpIHtcbiAgICB2YXIgX19tZXRob2QgPSB0aGlzO1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhID0gdXBkYXRlKFtfX21ldGhvZC5iaW5kKHRoaXMpXSwgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB3cmFwcGVyLmFwcGx5KHRoaXMsIGEpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1ldGhvZGl6ZSgpIHtcbiAgICBpZiAodGhpcy5fbWV0aG9kaXplZCkgcmV0dXJuIHRoaXMuX21ldGhvZGl6ZWQ7XG4gICAgdmFyIF9fbWV0aG9kID0gdGhpcztcbiAgICByZXR1cm4gdGhpcy5fbWV0aG9kaXplZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGEgPSB1cGRhdGUoW3RoaXNdLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIF9fbWV0aG9kLmFwcGx5KG51bGwsIGEpO1xuICAgIH07XG4gIH1cblxuICB2YXIgZXh0ZW5zaW9ucyA9IHtcbiAgICBhcmd1bWVudE5hbWVzOiAgICAgICBhcmd1bWVudE5hbWVzLFxuICAgIGJpbmRBc0V2ZW50TGlzdGVuZXI6IGJpbmRBc0V2ZW50TGlzdGVuZXIsXG4gICAgY3Vycnk6ICAgICAgICAgICAgICAgY3VycnksXG4gICAgZGVsYXk6ICAgICAgICAgICAgICAgZGVsYXksXG4gICAgZGVmZXI6ICAgICAgICAgICAgICAgZGVmZXIsXG4gICAgd3JhcDogICAgICAgICAgICAgICAgd3JhcCxcbiAgICBtZXRob2RpemU6ICAgICAgICAgICBtZXRob2RpemVcbiAgfTtcblxuICBpZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKVxuICAgIGV4dGVuc2lvbnMuYmluZCA9IGJpbmQ7XG5cbiAgcmV0dXJuIGV4dGVuc2lvbnM7XG59KSgpKTtcblxuXG5cbihmdW5jdGlvbihwcm90bykge1xuXG5cbiAgZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0VVRDRnVsbFllYXIoKSArICctJyArXG4gICAgICAodGhpcy5nZXRVVENNb250aCgpICsgMSkudG9QYWRkZWRTdHJpbmcoMikgKyAnLScgK1xuICAgICAgdGhpcy5nZXRVVENEYXRlKCkudG9QYWRkZWRTdHJpbmcoMikgKyAnVCcgK1xuICAgICAgdGhpcy5nZXRVVENIb3VycygpLnRvUGFkZGVkU3RyaW5nKDIpICsgJzonICtcbiAgICAgIHRoaXMuZ2V0VVRDTWludXRlcygpLnRvUGFkZGVkU3RyaW5nKDIpICsgJzonICtcbiAgICAgIHRoaXMuZ2V0VVRDU2Vjb25kcygpLnRvUGFkZGVkU3RyaW5nKDIpICsgJ1onO1xuICB9XG5cblxuICBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgcmV0dXJuIHRoaXMudG9JU09TdHJpbmcoKTtcbiAgfVxuXG4gIGlmICghcHJvdG8udG9JU09TdHJpbmcpIHByb3RvLnRvSVNPU3RyaW5nID0gdG9JU09TdHJpbmc7XG4gIGlmICghcHJvdG8udG9KU09OKSBwcm90by50b0pTT04gPSB0b0pTT047XG5cbn0pKERhdGUucHJvdG90eXBlKTtcblxuXG5SZWdFeHAucHJvdG90eXBlLm1hdGNoID0gUmVnRXhwLnByb3RvdHlwZS50ZXN0O1xuXG5SZWdFeHAuZXNjYXBlID0gZnVuY3Rpb24oc3RyKSB7XG4gIHJldHVybiBTdHJpbmcoc3RyKS5yZXBsYWNlKC8oWy4qKz9ePSE6JHt9KCl8W1xcXVxcL1xcXFxdKS9nLCAnXFxcXCQxJyk7XG59O1xudmFyIFBlcmlvZGljYWxFeGVjdXRlciA9IENsYXNzLmNyZWF0ZSh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNhbGxiYWNrLCBmcmVxdWVuY3kpIHtcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgdGhpcy5mcmVxdWVuY3kgPSBmcmVxdWVuY3k7XG4gICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSBmYWxzZTtcblxuICAgIHRoaXMucmVnaXN0ZXJDYWxsYmFjaygpO1xuICB9LFxuXG4gIHJlZ2lzdGVyQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudGltZXIgPSBzZXRJbnRlcnZhbCh0aGlzLm9uVGltZXJFdmVudC5iaW5kKHRoaXMpLCB0aGlzLmZyZXF1ZW5jeSAqIDEwMDApO1xuICB9LFxuXG4gIGV4ZWN1dGU6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuY2FsbGJhY2sodGhpcyk7XG4gIH0sXG5cbiAgc3RvcDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKCF0aGlzLnRpbWVyKSByZXR1cm47XG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLnRpbWVyKTtcbiAgICB0aGlzLnRpbWVyID0gbnVsbDtcbiAgfSxcblxuICBvblRpbWVyRXZlbnQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICghdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY3VycmVudGx5RXhlY3V0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5leGVjdXRlKCk7XG4gICAgICAgIHRoaXMuY3VycmVudGx5RXhlY3V0aW5nID0gZmFsc2U7XG4gICAgICB9IGNhdGNoKGUpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn0pO1xuT2JqZWN0LmV4dGVuZChTdHJpbmcsIHtcbiAgaW50ZXJwcmV0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBTdHJpbmcodmFsdWUpO1xuICB9LFxuICBzcGVjaWFsQ2hhcjoge1xuICAgICdcXGInOiAnXFxcXGInLFxuICAgICdcXHQnOiAnXFxcXHQnLFxuICAgICdcXG4nOiAnXFxcXG4nLFxuICAgICdcXGYnOiAnXFxcXGYnLFxuICAgICdcXHInOiAnXFxcXHInLFxuICAgICdcXFxcJzogJ1xcXFxcXFxcJ1xuICB9XG59KTtcblxuT2JqZWN0LmV4dGVuZChTdHJpbmcucHJvdG90eXBlLCAoZnVuY3Rpb24oKSB7XG4gIHZhciBOQVRJVkVfSlNPTl9QQVJTRV9TVVBQT1JUID0gd2luZG93LkpTT04gJiZcbiAgICB0eXBlb2YgSlNPTi5wYXJzZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgIEpTT04ucGFyc2UoJ3tcInRlc3RcIjogdHJ1ZX0nKS50ZXN0O1xuXG4gIGZ1bmN0aW9uIHByZXBhcmVSZXBsYWNlbWVudChyZXBsYWNlbWVudCkge1xuICAgIGlmIChPYmplY3QuaXNGdW5jdGlvbihyZXBsYWNlbWVudCkpIHJldHVybiByZXBsYWNlbWVudDtcbiAgICB2YXIgdGVtcGxhdGUgPSBuZXcgVGVtcGxhdGUocmVwbGFjZW1lbnQpO1xuICAgIHJldHVybiBmdW5jdGlvbihtYXRjaCkgeyByZXR1cm4gdGVtcGxhdGUuZXZhbHVhdGUobWF0Y2gpIH07XG4gIH1cblxuICBmdW5jdGlvbiBpc05vbkVtcHR5UmVnRXhwKHJlZ2V4cCkge1xuICAgIHJldHVybiByZWdleHAuc291cmNlICYmIHJlZ2V4cC5zb3VyY2UgIT09ICcoPzopJztcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZ3N1YihwYXR0ZXJuLCByZXBsYWNlbWVudCkge1xuICAgIHZhciByZXN1bHQgPSAnJywgc291cmNlID0gdGhpcywgbWF0Y2g7XG4gICAgcmVwbGFjZW1lbnQgPSBwcmVwYXJlUmVwbGFjZW1lbnQocmVwbGFjZW1lbnQpO1xuXG4gICAgaWYgKE9iamVjdC5pc1N0cmluZyhwYXR0ZXJuKSlcbiAgICAgIHBhdHRlcm4gPSBSZWdFeHAuZXNjYXBlKHBhdHRlcm4pO1xuXG4gICAgaWYgKCEocGF0dGVybi5sZW5ndGggfHwgaXNOb25FbXB0eVJlZ0V4cChwYXR0ZXJuKSkpIHtcbiAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQoJycpO1xuICAgICAgcmV0dXJuIHJlcGxhY2VtZW50ICsgc291cmNlLnNwbGl0KCcnKS5qb2luKHJlcGxhY2VtZW50KSArIHJlcGxhY2VtZW50O1xuICAgIH1cblxuICAgIHdoaWxlIChzb3VyY2UubGVuZ3RoID4gMCkge1xuICAgICAgbWF0Y2ggPSBzb3VyY2UubWF0Y2gocGF0dGVybilcbiAgICAgIGlmIChtYXRjaCAmJiBtYXRjaFswXS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJlc3VsdCArPSBzb3VyY2Uuc2xpY2UoMCwgbWF0Y2guaW5kZXgpO1xuICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmludGVycHJldChyZXBsYWNlbWVudChtYXRjaCkpO1xuICAgICAgICBzb3VyY2UgID0gc291cmNlLnNsaWNlKG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdCArPSBzb3VyY2UsIHNvdXJjZSA9ICcnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gc3ViKHBhdHRlcm4sIHJlcGxhY2VtZW50LCBjb3VudCkge1xuICAgIHJlcGxhY2VtZW50ID0gcHJlcGFyZVJlcGxhY2VtZW50KHJlcGxhY2VtZW50KTtcbiAgICBjb3VudCA9IE9iamVjdC5pc1VuZGVmaW5lZChjb3VudCkgPyAxIDogY291bnQ7XG5cbiAgICByZXR1cm4gdGhpcy5nc3ViKHBhdHRlcm4sIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICBpZiAoLS1jb3VudCA8IDApIHJldHVybiBtYXRjaFswXTtcbiAgICAgIHJldHVybiByZXBsYWNlbWVudChtYXRjaCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBzY2FuKHBhdHRlcm4sIGl0ZXJhdG9yKSB7XG4gICAgdGhpcy5nc3ViKHBhdHRlcm4sIGl0ZXJhdG9yKTtcbiAgICByZXR1cm4gU3RyaW5nKHRoaXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJ1bmNhdGUobGVuZ3RoLCB0cnVuY2F0aW9uKSB7XG4gICAgbGVuZ3RoID0gbGVuZ3RoIHx8IDMwO1xuICAgIHRydW5jYXRpb24gPSBPYmplY3QuaXNVbmRlZmluZWQodHJ1bmNhdGlvbikgPyAnLi4uJyA6IHRydW5jYXRpb247XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID4gbGVuZ3RoID9cbiAgICAgIHRoaXMuc2xpY2UoMCwgbGVuZ3RoIC0gdHJ1bmNhdGlvbi5sZW5ndGgpICsgdHJ1bmNhdGlvbiA6IFN0cmluZyh0aGlzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0cmlwKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15cXHMrLywgJycpLnJlcGxhY2UoL1xccyskLywgJycpO1xuICB9XG5cbiAgZnVuY3Rpb24gc3RyaXBUYWdzKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLzxcXHcrKFxccysoXCJbXlwiXSpcInwnW14nXSonfFtePl0pKyk/Pnw8XFwvXFx3Kz4vZ2ksICcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0cmlwU2NyaXB0cygpIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKG5ldyBSZWdFeHAoUHJvdG90eXBlLlNjcmlwdEZyYWdtZW50LCAnaW1nJyksICcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4dHJhY3RTY3JpcHRzKCkge1xuICAgIHZhciBtYXRjaEFsbCA9IG5ldyBSZWdFeHAoUHJvdG90eXBlLlNjcmlwdEZyYWdtZW50LCAnaW1nJyksXG4gICAgICAgIG1hdGNoT25lID0gbmV3IFJlZ0V4cChQcm90b3R5cGUuU2NyaXB0RnJhZ21lbnQsICdpbScpO1xuICAgIHJldHVybiAodGhpcy5tYXRjaChtYXRjaEFsbCkgfHwgW10pLm1hcChmdW5jdGlvbihzY3JpcHRUYWcpIHtcbiAgICAgIHJldHVybiAoc2NyaXB0VGFnLm1hdGNoKG1hdGNoT25lKSB8fCBbJycsICcnXSlbMV07XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBldmFsU2NyaXB0cygpIHtcbiAgICByZXR1cm4gdGhpcy5leHRyYWN0U2NyaXB0cygpLm1hcChmdW5jdGlvbihzY3JpcHQpIHsgcmV0dXJuIGV2YWwoc2NyaXB0KTsgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBlc2NhcGVIVE1MKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLyYvZywnJmFtcDsnKS5yZXBsYWNlKC88L2csJyZsdDsnKS5yZXBsYWNlKC8+L2csJyZndDsnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVuZXNjYXBlSFRNTCgpIHtcbiAgICByZXR1cm4gdGhpcy5zdHJpcFRhZ3MoKS5yZXBsYWNlKC8mbHQ7L2csJzwnKS5yZXBsYWNlKC8mZ3Q7L2csJz4nKS5yZXBsYWNlKC8mYW1wOy9nLCcmJyk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHRvUXVlcnlQYXJhbXMoc2VwYXJhdG9yKSB7XG4gICAgdmFyIG1hdGNoID0gdGhpcy5zdHJpcCgpLm1hdGNoKC8oW14/I10qKSgjLiopPyQvKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4geyB9O1xuXG4gICAgcmV0dXJuIG1hdGNoWzFdLnNwbGl0KHNlcGFyYXRvciB8fCAnJicpLmluamVjdCh7IH0sIGZ1bmN0aW9uKGhhc2gsIHBhaXIpIHtcbiAgICAgIGlmICgocGFpciA9IHBhaXIuc3BsaXQoJz0nKSlbMF0pIHtcbiAgICAgICAgdmFyIGtleSA9IGRlY29kZVVSSUNvbXBvbmVudChwYWlyLnNoaWZ0KCkpLFxuICAgICAgICAgICAgdmFsdWUgPSBwYWlyLmxlbmd0aCA+IDEgPyBwYWlyLmpvaW4oJz0nKSA6IHBhaXJbMF07XG5cbiAgICAgICAgaWYgKHZhbHVlICE9IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUuZ3N1YignKycsICcgJyk7XG4gICAgICAgICAgdmFsdWUgPSBkZWNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleSBpbiBoYXNoKSB7XG4gICAgICAgICAgaWYgKCFPYmplY3QuaXNBcnJheShoYXNoW2tleV0pKSBoYXNoW2tleV0gPSBbaGFzaFtrZXldXTtcbiAgICAgICAgICBoYXNoW2tleV0ucHVzaCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBoYXNoW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBoYXNoO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9BcnJheSgpIHtcbiAgICByZXR1cm4gdGhpcy5zcGxpdCgnJyk7XG4gIH1cblxuICBmdW5jdGlvbiBzdWNjKCkge1xuICAgIHJldHVybiB0aGlzLnNsaWNlKDAsIHRoaXMubGVuZ3RoIC0gMSkgK1xuICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSh0aGlzLmNoYXJDb2RlQXQodGhpcy5sZW5ndGggLSAxKSArIDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXMoY291bnQpIHtcbiAgICByZXR1cm4gY291bnQgPCAxID8gJycgOiBuZXcgQXJyYXkoY291bnQgKyAxKS5qb2luKHRoaXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FtZWxpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvLSsoLik/L2csIGZ1bmN0aW9uKG1hdGNoLCBjaHIpIHtcbiAgICAgIHJldHVybiBjaHIgPyBjaHIudG9VcHBlckNhc2UoKSA6ICcnO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY2FwaXRhbGl6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHRoaXMuc3Vic3RyaW5nKDEpLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICBmdW5jdGlvbiB1bmRlcnNjb3JlKCkge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoLzo6L2csICcvJylcbiAgICAgICAgICAgICAgIC5yZXBsYWNlKC8oW0EtWl0rKShbQS1aXVthLXpdKS9nLCAnJDFfJDInKVxuICAgICAgICAgICAgICAgLnJlcGxhY2UoLyhbYS16XFxkXSkoW0EtWl0pL2csICckMV8kMicpXG4gICAgICAgICAgICAgICAucmVwbGFjZSgvLS9nLCAnXycpXG4gICAgICAgICAgICAgICAudG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRhc2hlcml6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKC9fL2csICctJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0KHVzZURvdWJsZVF1b3Rlcykge1xuICAgIHZhciBlc2NhcGVkU3RyaW5nID0gdGhpcy5yZXBsYWNlKC9bXFx4MDAtXFx4MWZcXFxcXS9nLCBmdW5jdGlvbihjaGFyYWN0ZXIpIHtcbiAgICAgIGlmIChjaGFyYWN0ZXIgaW4gU3RyaW5nLnNwZWNpYWxDaGFyKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcuc3BlY2lhbENoYXJbY2hhcmFjdGVyXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAnXFxcXHUwMCcgKyBjaGFyYWN0ZXIuY2hhckNvZGVBdCgpLnRvUGFkZGVkU3RyaW5nKDIsIDE2KTtcbiAgICB9KTtcbiAgICBpZiAodXNlRG91YmxlUXVvdGVzKSByZXR1cm4gJ1wiJyArIGVzY2FwZWRTdHJpbmcucmVwbGFjZSgvXCIvZywgJ1xcXFxcIicpICsgJ1wiJztcbiAgICByZXR1cm4gXCInXCIgKyBlc2NhcGVkU3RyaW5nLnJlcGxhY2UoLycvZywgJ1xcXFxcXCcnKSArIFwiJ1wiO1xuICB9XG5cbiAgZnVuY3Rpb24gdW5maWx0ZXJKU09OKGZpbHRlcikge1xuICAgIHJldHVybiB0aGlzLnJlcGxhY2UoZmlsdGVyIHx8IFByb3RvdHlwZS5KU09ORmlsdGVyLCAnJDEnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSlNPTigpIHtcbiAgICB2YXIgc3RyID0gdGhpcztcbiAgICBpZiAoc3RyLmJsYW5rKCkpIHJldHVybiBmYWxzZTtcbiAgICBzdHIgPSBzdHIucmVwbGFjZSgvXFxcXCg/OltcIlxcXFxcXC9iZm5ydF18dVswLTlhLWZBLUZdezR9KS9nLCAnQCcpO1xuICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9cIlteXCJcXFxcXFxuXFxyXSpcInx0cnVlfGZhbHNlfG51bGx8LT9cXGQrKD86XFwuXFxkKik/KD86W2VFXVsrXFwtXT9cXGQrKT8vZywgJ10nKTtcbiAgICBzdHIgPSBzdHIucmVwbGFjZSgvKD86Xnw6fCwpKD86XFxzKlxcWykrL2csICcnKTtcbiAgICByZXR1cm4gKC9eW1xcXSw6e31cXHNdKiQvKS50ZXN0KHN0cik7XG4gIH1cblxuICBmdW5jdGlvbiBldmFsSlNPTihzYW5pdGl6ZSkge1xuICAgIHZhciBqc29uID0gdGhpcy51bmZpbHRlckpTT04oKSxcbiAgICAgICAgY3ggPSAvW1xcdTAwMDBcXHUwMGFkXFx1MDYwMC1cXHUwNjA0XFx1MDcwZlxcdTE3YjRcXHUxN2I1XFx1MjAwYy1cXHUyMDBmXFx1MjAyOC1cXHUyMDJmXFx1MjA2MC1cXHUyMDZmXFx1ZmVmZlxcdWZmZjAtXFx1ZmZmZl0vZztcbiAgICBpZiAoY3gudGVzdChqc29uKSkge1xuICAgICAganNvbiA9IGpzb24ucmVwbGFjZShjeCwgZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuICdcXFxcdScgKyAoJzAwMDAnICsgYS5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KSkuc2xpY2UoLTQpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBpZiAoIXNhbml0aXplIHx8IGpzb24uaXNKU09OKCkpIHJldHVybiBldmFsKCcoJyArIGpzb24gKyAnKScpO1xuICAgIH0gY2F0Y2ggKGUpIHsgfVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcignQmFkbHkgZm9ybWVkIEpTT04gc3RyaW5nOiAnICsgdGhpcy5pbnNwZWN0KCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VKU09OKCkge1xuICAgIHZhciBqc29uID0gdGhpcy51bmZpbHRlckpTT04oKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUocGF0dGVybikge1xuICAgIHJldHVybiB0aGlzLmluZGV4T2YocGF0dGVybikgPiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN0YXJ0c1dpdGgocGF0dGVybiwgcG9zaXRpb24pIHtcbiAgICBwb3NpdGlvbiA9IE9iamVjdC5pc051bWJlcihwb3NpdGlvbikgPyBwb3NpdGlvbiA6IDA7XG4gICAgcmV0dXJuIHRoaXMubGFzdEluZGV4T2YocGF0dGVybiwgcG9zaXRpb24pID09PSBwb3NpdGlvbjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZHNXaXRoKHBhdHRlcm4sIHBvc2l0aW9uKSB7XG4gICAgcGF0dGVybiA9IFN0cmluZyhwYXR0ZXJuKTtcbiAgICBwb3NpdGlvbiA9IE9iamVjdC5pc051bWJlcihwb3NpdGlvbikgPyBwb3NpdGlvbiA6IHRoaXMubGVuZ3RoO1xuICAgIGlmIChwb3NpdGlvbiA8IDApIHBvc2l0aW9uID0gMDtcbiAgICBpZiAocG9zaXRpb24gPiB0aGlzLmxlbmd0aCkgcG9zaXRpb24gPSB0aGlzLmxlbmd0aDtcbiAgICB2YXIgZCA9IHBvc2l0aW9uIC0gcGF0dGVybi5sZW5ndGg7XG4gICAgcmV0dXJuIGQgPj0gMCAmJiB0aGlzLmluZGV4T2YocGF0dGVybiwgZCkgPT09IGQ7XG4gIH1cblxuICBmdW5jdGlvbiBlbXB0eSgpIHtcbiAgICByZXR1cm4gdGhpcyA9PSAnJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGJsYW5rKCkge1xuICAgIHJldHVybiAvXlxccyokLy50ZXN0KHRoaXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gaW50ZXJwb2xhdGUob2JqZWN0LCBwYXR0ZXJuKSB7XG4gICAgcmV0dXJuIG5ldyBUZW1wbGF0ZSh0aGlzLCBwYXR0ZXJuKS5ldmFsdWF0ZShvYmplY3QpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBnc3ViOiAgICAgICAgICAgZ3N1YixcbiAgICBzdWI6ICAgICAgICAgICAgc3ViLFxuICAgIHNjYW46ICAgICAgICAgICBzY2FuLFxuICAgIHRydW5jYXRlOiAgICAgICB0cnVuY2F0ZSxcbiAgICBzdHJpcDogICAgICAgICAgU3RyaW5nLnByb3RvdHlwZS50cmltIHx8IHN0cmlwLFxuICAgIHN0cmlwVGFnczogICAgICBzdHJpcFRhZ3MsXG4gICAgc3RyaXBTY3JpcHRzOiAgIHN0cmlwU2NyaXB0cyxcbiAgICBleHRyYWN0U2NyaXB0czogZXh0cmFjdFNjcmlwdHMsXG4gICAgZXZhbFNjcmlwdHM6ICAgIGV2YWxTY3JpcHRzLFxuICAgIGVzY2FwZUhUTUw6ICAgICBlc2NhcGVIVE1MLFxuICAgIHVuZXNjYXBlSFRNTDogICB1bmVzY2FwZUhUTUwsXG4gICAgdG9RdWVyeVBhcmFtczogIHRvUXVlcnlQYXJhbXMsXG4gICAgcGFyc2VRdWVyeTogICAgIHRvUXVlcnlQYXJhbXMsXG4gICAgdG9BcnJheTogICAgICAgIHRvQXJyYXksXG4gICAgc3VjYzogICAgICAgICAgIHN1Y2MsXG4gICAgdGltZXM6ICAgICAgICAgIHRpbWVzLFxuICAgIGNhbWVsaXplOiAgICAgICBjYW1lbGl6ZSxcbiAgICBjYXBpdGFsaXplOiAgICAgY2FwaXRhbGl6ZSxcbiAgICB1bmRlcnNjb3JlOiAgICAgdW5kZXJzY29yZSxcbiAgICBkYXNoZXJpemU6ICAgICAgZGFzaGVyaXplLFxuICAgIGluc3BlY3Q6ICAgICAgICBpbnNwZWN0LFxuICAgIHVuZmlsdGVySlNPTjogICB1bmZpbHRlckpTT04sXG4gICAgaXNKU09OOiAgICAgICAgIGlzSlNPTixcbiAgICBldmFsSlNPTjogICAgICAgTkFUSVZFX0pTT05fUEFSU0VfU1VQUE9SVCA/IHBhcnNlSlNPTiA6IGV2YWxKU09OLFxuICAgIGluY2x1ZGU6ICAgICAgICBpbmNsdWRlLFxuICAgIHN0YXJ0c1dpdGg6ICAgICBTdHJpbmcucHJvdG90eXBlLnN0YXJ0c1dpdGggfHwgc3RhcnRzV2l0aCxcbiAgICBlbmRzV2l0aDogICAgICAgU3RyaW5nLnByb3RvdHlwZS5lbmRzV2l0aCB8fCBlbmRzV2l0aCxcbiAgICBlbXB0eTogICAgICAgICAgZW1wdHksXG4gICAgYmxhbms6ICAgICAgICAgIGJsYW5rLFxuICAgIGludGVycG9sYXRlOiAgICBpbnRlcnBvbGF0ZVxuICB9O1xufSkoKSk7XG5cbnZhciBUZW1wbGF0ZSA9IENsYXNzLmNyZWF0ZSh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKHRlbXBsYXRlLCBwYXR0ZXJuKSB7XG4gICAgdGhpcy50ZW1wbGF0ZSA9IHRlbXBsYXRlLnRvU3RyaW5nKCk7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybiB8fCBUZW1wbGF0ZS5QYXR0ZXJuO1xuICB9LFxuXG4gIGV2YWx1YXRlOiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBpZiAob2JqZWN0ICYmIE9iamVjdC5pc0Z1bmN0aW9uKG9iamVjdC50b1RlbXBsYXRlUmVwbGFjZW1lbnRzKSlcbiAgICAgIG9iamVjdCA9IG9iamVjdC50b1RlbXBsYXRlUmVwbGFjZW1lbnRzKCk7XG5cbiAgICByZXR1cm4gdGhpcy50ZW1wbGF0ZS5nc3ViKHRoaXMucGF0dGVybiwgZnVuY3Rpb24obWF0Y2gpIHtcbiAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkgcmV0dXJuIChtYXRjaFsxXSArICcnKTtcblxuICAgICAgdmFyIGJlZm9yZSA9IG1hdGNoWzFdIHx8ICcnO1xuICAgICAgaWYgKGJlZm9yZSA9PSAnXFxcXCcpIHJldHVybiBtYXRjaFsyXTtcblxuICAgICAgdmFyIGN0eCA9IG9iamVjdCwgZXhwciA9IG1hdGNoWzNdLFxuICAgICAgICAgIHBhdHRlcm4gPSAvXihbXi5bXSt8XFxbKCg/Oi4qP1teXFxcXF0pPylcXF0pKFxcLnxcXFt8JCkvO1xuXG4gICAgICBtYXRjaCA9IHBhdHRlcm4uZXhlYyhleHByKTtcbiAgICAgIGlmIChtYXRjaCA9PSBudWxsKSByZXR1cm4gYmVmb3JlO1xuXG4gICAgICB3aGlsZSAobWF0Y2ggIT0gbnVsbCkge1xuICAgICAgICB2YXIgY29tcCA9IG1hdGNoWzFdLnN0YXJ0c1dpdGgoJ1snKSA/IG1hdGNoWzJdLnJlcGxhY2UoL1xcXFxcXFxcXS9nLCAnXScpIDogbWF0Y2hbMV07XG4gICAgICAgIGN0eCA9IGN0eFtjb21wXTtcbiAgICAgICAgaWYgKG51bGwgPT0gY3R4IHx8ICcnID09IG1hdGNoWzNdKSBicmVhaztcbiAgICAgICAgZXhwciA9IGV4cHIuc3Vic3RyaW5nKCdbJyA9PSBtYXRjaFszXSA/IG1hdGNoWzFdLmxlbmd0aCA6IG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgIG1hdGNoID0gcGF0dGVybi5leGVjKGV4cHIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYmVmb3JlICsgU3RyaW5nLmludGVycHJldChjdHgpO1xuICAgIH0pO1xuICB9XG59KTtcblRlbXBsYXRlLlBhdHRlcm4gPSAvKF58LnxcXHJ8XFxuKSgjXFx7KC4qPylcXH0pLztcblxudmFyICRicmVhayA9IHsgfTtcblxudmFyIEVudW1lcmFibGUgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIGVhY2goaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5fZWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgIT0gJGJyZWFrKSB0aHJvdyBlO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGVhY2hTbGljZShudW1iZXIsIGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIGluZGV4ID0gLW51bWJlciwgc2xpY2VzID0gW10sIGFycmF5ID0gdGhpcy50b0FycmF5KCk7XG4gICAgaWYgKG51bWJlciA8IDEpIHJldHVybiBhcnJheTtcbiAgICB3aGlsZSAoKGluZGV4ICs9IG51bWJlcikgPCBhcnJheS5sZW5ndGgpXG4gICAgICBzbGljZXMucHVzaChhcnJheS5zbGljZShpbmRleCwgaW5kZXgrbnVtYmVyKSk7XG4gICAgcmV0dXJuIHNsaWNlcy5jb2xsZWN0KGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFsbChpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG4gICAgdmFyIHJlc3VsdCA9IHRydWU7XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0ICYmICEhaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIHRoaXMpO1xuICAgICAgaWYgKCFyZXN1bHQpIHRocm93ICRicmVhaztcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gYW55KGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgaXRlcmF0b3IgPSBpdGVyYXRvciB8fCBQcm90b3R5cGUuSztcbiAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKHJlc3VsdCA9ICEhaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIHRoaXMpKVxuICAgICAgICB0aHJvdyAkYnJlYWs7XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbGxlY3QoaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yIHx8IFByb3RvdHlwZS5LO1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgcmVzdWx0cy5wdXNoKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCB0aGlzKSk7XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBmdW5jdGlvbiBkZXRlY3QoaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgcmVzdWx0O1xuICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgdGhpcykpIHtcbiAgICAgICAgcmVzdWx0ID0gdmFsdWU7XG4gICAgICAgIHRocm93ICRicmVhaztcbiAgICAgIH1cbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZEFsbChpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCB0aGlzKSlcbiAgICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdyZXAoZmlsdGVyLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcblxuICAgIGlmIChPYmplY3QuaXNTdHJpbmcoZmlsdGVyKSlcbiAgICAgIGZpbHRlciA9IG5ldyBSZWdFeHAoUmVnRXhwLmVzY2FwZShmaWx0ZXIpKTtcblxuICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIGlmIChmaWx0ZXIubWF0Y2godmFsdWUpKVxuICAgICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIHRoaXMpKTtcbiAgICB9LCB0aGlzKTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGluY2x1ZGUob2JqZWN0KSB7XG4gICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKHRoaXMuaW5kZXhPZikgJiYgdGhpcy5pbmRleE9mKG9iamVjdCkgIT0gLTEpXG4gICAgICByZXR1cm4gdHJ1ZTtcblxuICAgIHZhciBmb3VuZCA9IGZhbHNlO1xuICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKHZhbHVlID09IG9iamVjdCkge1xuICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIHRocm93ICRicmVhaztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZm91bmQ7XG4gIH1cblxuICBmdW5jdGlvbiBpbkdyb3Vwc09mKG51bWJlciwgZmlsbFdpdGgpIHtcbiAgICBmaWxsV2l0aCA9IE9iamVjdC5pc1VuZGVmaW5lZChmaWxsV2l0aCkgPyBudWxsIDogZmlsbFdpdGg7XG4gICAgcmV0dXJuIHRoaXMuZWFjaFNsaWNlKG51bWJlciwgZnVuY3Rpb24oc2xpY2UpIHtcbiAgICAgIHdoaWxlKHNsaWNlLmxlbmd0aCA8IG51bWJlcikgc2xpY2UucHVzaChmaWxsV2l0aCk7XG4gICAgICByZXR1cm4gc2xpY2U7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBpbmplY3QobWVtbywgaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICBtZW1vID0gaXRlcmF0b3IuY2FsbChjb250ZXh0LCBtZW1vLCB2YWx1ZSwgaW5kZXgsIHRoaXMpO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBtZW1vO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCkge1xuICAgIHZhciBhcmdzID0gJEEoYXJndW1lbnRzKS5zbGljZSgxKTtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZVttZXRob2RdLmFwcGx5KHZhbHVlLCBhcmdzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1heChpdGVyYXRvciwgY29udGV4dCkge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG4gICAgdmFyIHJlc3VsdDtcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICB2YWx1ZSA9IGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGluZGV4LCB0aGlzKTtcbiAgICAgIGlmIChyZXN1bHQgPT0gbnVsbCB8fCB2YWx1ZSA+PSByZXN1bHQpXG4gICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBtaW4oaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yIHx8IFByb3RvdHlwZS5LO1xuICAgIHZhciByZXN1bHQ7XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgdmFsdWUgPSBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgdGhpcyk7XG4gICAgICBpZiAocmVzdWx0ID09IG51bGwgfHwgdmFsdWUgPCByZXN1bHQpXG4gICAgICAgIHJlc3VsdCA9IHZhbHVlO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJ0aXRpb24oaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBpdGVyYXRvciA9IGl0ZXJhdG9yIHx8IFByb3RvdHlwZS5LO1xuICAgIHZhciB0cnVlcyA9IFtdLCBmYWxzZXMgPSBbXTtcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICAoaXRlcmF0b3IuY2FsbChjb250ZXh0LCB2YWx1ZSwgaW5kZXgsIHRoaXMpID9cbiAgICAgICAgdHJ1ZXMgOiBmYWxzZXMpLnB1c2godmFsdWUpO1xuICAgIH0sIHRoaXMpO1xuICAgIHJldHVybiBbdHJ1ZXMsIGZhbHNlc107XG4gIH1cblxuICBmdW5jdGlvbiBwbHVjayhwcm9wZXJ0eSkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXN1bHRzLnB1c2godmFsdWVbcHJvcGVydHldKTtcbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlamVjdChpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgICAgaWYgKCFpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgdGhpcykpXG4gICAgICAgIHJlc3VsdHMucHVzaCh2YWx1ZSk7XG4gICAgfSwgdGhpcyk7XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBmdW5jdGlvbiBzb3J0QnkoaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICAgIGNyaXRlcmlhOiBpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpbmRleCwgdGhpcylcbiAgICAgIH07XG4gICAgfSwgdGhpcykuc29ydChmdW5jdGlvbihsZWZ0LCByaWdodCkge1xuICAgICAgdmFyIGEgPSBsZWZ0LmNyaXRlcmlhLCBiID0gcmlnaHQuY3JpdGVyaWE7XG4gICAgICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDA7XG4gICAgfSkucGx1Y2soJ3ZhbHVlJyk7XG4gIH1cblxuICBmdW5jdGlvbiB0b0FycmF5KCkge1xuICAgIHJldHVybiB0aGlzLm1hcCgpO1xuICB9XG5cbiAgZnVuY3Rpb24gemlwKCkge1xuICAgIHZhciBpdGVyYXRvciA9IFByb3RvdHlwZS5LLCBhcmdzID0gJEEoYXJndW1lbnRzKTtcbiAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24oYXJncy5sYXN0KCkpKVxuICAgICAgaXRlcmF0b3IgPSBhcmdzLnBvcCgpO1xuXG4gICAgdmFyIGNvbGxlY3Rpb25zID0gW3RoaXNdLmNvbmNhdChhcmdzKS5tYXAoJEEpO1xuICAgIHJldHVybiB0aGlzLm1hcChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIHJldHVybiBpdGVyYXRvcihjb2xsZWN0aW9ucy5wbHVjayhpbmRleCkpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gc2l6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy50b0FycmF5KCkubGVuZ3RoO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5zcGVjdCgpIHtcbiAgICByZXR1cm4gJyM8RW51bWVyYWJsZTonICsgdGhpcy50b0FycmF5KCkuaW5zcGVjdCgpICsgJz4nO1xuICB9XG5cblxuXG5cblxuXG5cblxuXG4gIHJldHVybiB7XG4gICAgZWFjaDogICAgICAgZWFjaCxcbiAgICBlYWNoU2xpY2U6ICBlYWNoU2xpY2UsXG4gICAgYWxsOiAgICAgICAgYWxsLFxuICAgIGV2ZXJ5OiAgICAgIGFsbCxcbiAgICBhbnk6ICAgICAgICBhbnksXG4gICAgc29tZTogICAgICAgYW55LFxuICAgIGNvbGxlY3Q6ICAgIGNvbGxlY3QsXG4gICAgbWFwOiAgICAgICAgY29sbGVjdCxcbiAgICBkZXRlY3Q6ICAgICBkZXRlY3QsXG4gICAgZmluZEFsbDogICAgZmluZEFsbCxcbiAgICBzZWxlY3Q6ICAgICBmaW5kQWxsLFxuICAgIGZpbHRlcjogICAgIGZpbmRBbGwsXG4gICAgZ3JlcDogICAgICAgZ3JlcCxcbiAgICBpbmNsdWRlOiAgICBpbmNsdWRlLFxuICAgIG1lbWJlcjogICAgIGluY2x1ZGUsXG4gICAgaW5Hcm91cHNPZjogaW5Hcm91cHNPZixcbiAgICBpbmplY3Q6ICAgICBpbmplY3QsXG4gICAgaW52b2tlOiAgICAgaW52b2tlLFxuICAgIG1heDogICAgICAgIG1heCxcbiAgICBtaW46ICAgICAgICBtaW4sXG4gICAgcGFydGl0aW9uOiAgcGFydGl0aW9uLFxuICAgIHBsdWNrOiAgICAgIHBsdWNrLFxuICAgIHJlamVjdDogICAgIHJlamVjdCxcbiAgICBzb3J0Qnk6ICAgICBzb3J0QnksXG4gICAgdG9BcnJheTogICAgdG9BcnJheSxcbiAgICBlbnRyaWVzOiAgICB0b0FycmF5LFxuICAgIHppcDogICAgICAgIHppcCxcbiAgICBzaXplOiAgICAgICBzaXplLFxuICAgIGluc3BlY3Q6ICAgIGluc3BlY3QsXG4gICAgZmluZDogICAgICAgZGV0ZWN0XG4gIH07XG59KSgpO1xuXG5mdW5jdGlvbiAkQShpdGVyYWJsZSkge1xuICBpZiAoIWl0ZXJhYmxlKSByZXR1cm4gW107XG4gIGlmICgndG9BcnJheScgaW4gT2JqZWN0KGl0ZXJhYmxlKSkgcmV0dXJuIGl0ZXJhYmxlLnRvQXJyYXkoKTtcbiAgdmFyIGxlbmd0aCA9IGl0ZXJhYmxlLmxlbmd0aCB8fCAwLCByZXN1bHRzID0gbmV3IEFycmF5KGxlbmd0aCk7XG4gIHdoaWxlIChsZW5ndGgtLSkgcmVzdWx0c1tsZW5ndGhdID0gaXRlcmFibGVbbGVuZ3RoXTtcbiAgcmV0dXJuIHJlc3VsdHM7XG59XG5cblxuZnVuY3Rpb24gJHcoc3RyaW5nKSB7XG4gIGlmICghT2JqZWN0LmlzU3RyaW5nKHN0cmluZykpIHJldHVybiBbXTtcbiAgc3RyaW5nID0gc3RyaW5nLnN0cmlwKCk7XG4gIHJldHVybiBzdHJpbmcgPyBzdHJpbmcuc3BsaXQoL1xccysvKSA6IFtdO1xufVxuXG5BcnJheS5mcm9tID0gJEE7XG5cblxuKGZ1bmN0aW9uKCkge1xuICB2YXIgYXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZSxcbiAgICAgIHNsaWNlID0gYXJyYXlQcm90by5zbGljZSxcbiAgICAgIF9lYWNoID0gYXJyYXlQcm90by5mb3JFYWNoOyAvLyB1c2UgbmF0aXZlIGJyb3dzZXIgSlMgMS42IGltcGxlbWVudGF0aW9uIGlmIGF2YWlsYWJsZVxuXG4gIGZ1bmN0aW9uIGVhY2goaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5sZW5ndGggPj4+IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgaW4gdGhpcykgaXRlcmF0b3IuY2FsbChjb250ZXh0LCB0aGlzW2ldLCBpLCB0aGlzKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFfZWFjaCkgX2VhY2ggPSBlYWNoO1xuXG4gIGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpcnN0KCkge1xuICAgIHJldHVybiB0aGlzWzBdO1xuICB9XG5cbiAgZnVuY3Rpb24gbGFzdCgpIHtcbiAgICByZXR1cm4gdGhpc1t0aGlzLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgZnVuY3Rpb24gY29tcGFjdCgpIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3QoZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiB2YWx1ZSAhPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZmxhdHRlbigpIHtcbiAgICByZXR1cm4gdGhpcy5pbmplY3QoW10sIGZ1bmN0aW9uKGFycmF5LCB2YWx1ZSkge1xuICAgICAgaWYgKE9iamVjdC5pc0FycmF5KHZhbHVlKSlcbiAgICAgICAgcmV0dXJuIGFycmF5LmNvbmNhdCh2YWx1ZS5mbGF0dGVuKCkpO1xuICAgICAgYXJyYXkucHVzaCh2YWx1ZSk7XG4gICAgICByZXR1cm4gYXJyYXk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB3aXRob3V0KCkge1xuICAgIHZhciB2YWx1ZXMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gIXZhbHVlcy5pbmNsdWRlKHZhbHVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJldmVyc2UoaW5saW5lKSB7XG4gICAgcmV0dXJuIChpbmxpbmUgPT09IGZhbHNlID8gdGhpcy50b0FycmF5KCkgOiB0aGlzKS5fcmV2ZXJzZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gdW5pcShzb3J0ZWQpIHtcbiAgICByZXR1cm4gdGhpcy5pbmplY3QoW10sIGZ1bmN0aW9uKGFycmF5LCB2YWx1ZSwgaW5kZXgpIHtcbiAgICAgIGlmICgwID09IGluZGV4IHx8IChzb3J0ZWQgPyBhcnJheS5sYXN0KCkgIT0gdmFsdWUgOiAhYXJyYXkuaW5jbHVkZSh2YWx1ZSkpKVxuICAgICAgICBhcnJheS5wdXNoKHZhbHVlKTtcbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGludGVyc2VjdChhcnJheSkge1xuICAgIHJldHVybiB0aGlzLnVuaXEoKS5maW5kQWxsKGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbiAgICB9KTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gY2xvbmUoKSB7XG4gICAgcmV0dXJuIHNsaWNlLmNhbGwodGhpcywgMCk7XG4gIH1cblxuICBmdW5jdGlvbiBzaXplKCkge1xuICAgIHJldHVybiB0aGlzLmxlbmd0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc3BlY3QoKSB7XG4gICAgcmV0dXJuICdbJyArIHRoaXMubWFwKE9iamVjdC5pbnNwZWN0KS5qb2luKCcsICcpICsgJ10nO1xuICB9XG5cbiAgZnVuY3Rpb24gaW5kZXhPZihpdGVtLCBpKSB7XG4gICAgaWYgKHRoaXMgPT0gbnVsbCkgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuXG4gICAgdmFyIGFycmF5ID0gT2JqZWN0KHRoaXMpLCBsZW5ndGggPSBhcnJheS5sZW5ndGggPj4+IDA7XG4gICAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xO1xuXG4gICAgaSA9IE51bWJlcihpKTtcbiAgICBpZiAoaXNOYU4oaSkpIHtcbiAgICAgIGkgPSAwO1xuICAgIH0gZWxzZSBpZiAoaSAhPT0gMCAmJiBpc0Zpbml0ZShpKSkge1xuICAgICAgaSA9IChpID4gMCA/IDEgOiAtMSkgKiBNYXRoLmZsb29yKE1hdGguYWJzKGkpKTtcbiAgICB9XG5cbiAgICBpZiAoaSA+IGxlbmd0aCkgcmV0dXJuIC0xO1xuXG4gICAgdmFyIGsgPSBpID49IDAgPyBpIDogTWF0aC5tYXgobGVuZ3RoIC0gTWF0aC5hYnMoaSksIDApO1xuICAgIGZvciAoOyBrIDwgbGVuZ3RoOyBrKyspXG4gICAgICBpZiAoayBpbiBhcnJheSAmJiBhcnJheVtrXSA9PT0gaXRlbSkgcmV0dXJuIGs7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cblxuICBmdW5jdGlvbiBsYXN0SW5kZXhPZihpdGVtLCBpKSB7XG4gICAgaWYgKHRoaXMgPT0gbnVsbCkgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuXG4gICAgdmFyIGFycmF5ID0gT2JqZWN0KHRoaXMpLCBsZW5ndGggPSBhcnJheS5sZW5ndGggPj4+IDA7XG4gICAgaWYgKGxlbmd0aCA9PT0gMCkgcmV0dXJuIC0xO1xuXG4gICAgaWYgKCFPYmplY3QuaXNVbmRlZmluZWQoaSkpIHtcbiAgICAgIGkgPSBOdW1iZXIoaSk7XG4gICAgICBpZiAoaXNOYU4oaSkpIHtcbiAgICAgICAgaSA9IDA7XG4gICAgICB9IGVsc2UgaWYgKGkgIT09IDAgJiYgaXNGaW5pdGUoaSkpIHtcbiAgICAgICAgaSA9IChpID4gMCA/IDEgOiAtMSkgKiBNYXRoLmZsb29yKE1hdGguYWJzKGkpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaSA9IGxlbmd0aDtcbiAgICB9XG5cbiAgICB2YXIgayA9IGkgPj0gMCA/IE1hdGgubWluKGksIGxlbmd0aCAtIDEpIDpcbiAgICAgbGVuZ3RoIC0gTWF0aC5hYnMoaSk7XG5cbiAgICBmb3IgKDsgayA+PSAwOyBrLS0pXG4gICAgICBpZiAoayBpbiBhcnJheSAmJiBhcnJheVtrXSA9PT0gaXRlbSkgcmV0dXJuIGs7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gY29uY2F0KF8pIHtcbiAgICB2YXIgYXJyYXkgPSBbXSwgaXRlbXMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMCksIGl0ZW0sIG4gPSAwO1xuICAgIGl0ZW1zLnVuc2hpZnQodGhpcyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGl0ZW1zLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpdGVtID0gaXRlbXNbaV07XG4gICAgICBpZiAoT2JqZWN0LmlzQXJyYXkoaXRlbSkgJiYgISgnY2FsbGVlJyBpbiBpdGVtKSkge1xuICAgICAgICBmb3IgKHZhciBqID0gMCwgYXJyYXlMZW5ndGggPSBpdGVtLmxlbmd0aDsgaiA8IGFycmF5TGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICBpZiAoaiBpbiBpdGVtKSBhcnJheVtuXSA9IGl0ZW1bal07XG4gICAgICAgICAgbisrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhcnJheVtuKytdID0gaXRlbTtcbiAgICAgIH1cbiAgICB9XG4gICAgYXJyYXkubGVuZ3RoID0gbjtcbiAgICByZXR1cm4gYXJyYXk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHdyYXBOYXRpdmUobWV0aG9kKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG1ldGhvZC5jYWxsKHRoaXMsIFByb3RvdHlwZS5LKTtcbiAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gICAgICAgIGFyZ3MudW5zaGlmdChQcm90b3R5cGUuSyk7XG4gICAgICAgIHJldHVybiBtZXRob2QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gbWFwKGl0ZXJhdG9yKSB7XG4gICAgaWYgKHRoaXMgPT0gbnVsbCkgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG5cbiAgICB2YXIgb2JqZWN0ID0gT2JqZWN0KHRoaXMpO1xuICAgIHZhciByZXN1bHRzID0gW10sIGNvbnRleHQgPSBhcmd1bWVudHNbMV0sIG4gPSAwO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGggPj4+IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgaW4gb2JqZWN0KSB7XG4gICAgICAgIHJlc3VsdHNbbl0gPSBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9iamVjdFtpXSwgaSwgb2JqZWN0KTtcbiAgICAgIH1cbiAgICAgIG4rKztcbiAgICB9XG4gICAgcmVzdWx0cy5sZW5ndGggPSBuO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgaWYgKGFycmF5UHJvdG8ubWFwKSB7XG4gICAgbWFwID0gd3JhcE5hdGl2ZShBcnJheS5wcm90b3R5cGUubWFwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbHRlcihpdGVyYXRvcikge1xuICAgIGlmICh0aGlzID09IG51bGwgfHwgIU9iamVjdC5pc0Z1bmN0aW9uKGl0ZXJhdG9yKSlcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcblxuICAgIHZhciBvYmplY3QgPSBPYmplY3QodGhpcyk7XG4gICAgdmFyIHJlc3VsdHMgPSBbXSwgY29udGV4dCA9IGFyZ3VtZW50c1sxXSwgdmFsdWU7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gb2JqZWN0Lmxlbmd0aCA+Pj4gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoaSBpbiBvYmplY3QpIHtcbiAgICAgICAgdmFsdWUgPSBvYmplY3RbaV07XG4gICAgICAgIGlmIChpdGVyYXRvci5jYWxsKGNvbnRleHQsIHZhbHVlLCBpLCBvYmplY3QpKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGlmIChhcnJheVByb3RvLmZpbHRlcikge1xuICAgIGZpbHRlciA9IEFycmF5LnByb3RvdHlwZS5maWx0ZXI7XG4gIH1cblxuICBmdW5jdGlvbiBzb21lKGl0ZXJhdG9yKSB7XG4gICAgaWYgKHRoaXMgPT0gbnVsbCkgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG4gICAgdmFyIGNvbnRleHQgPSBhcmd1bWVudHNbMV07XG5cbiAgICB2YXIgb2JqZWN0ID0gT2JqZWN0KHRoaXMpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBvYmplY3QubGVuZ3RoID4+PiAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChpIGluIG9iamVjdCAmJiBpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9iamVjdFtpXSwgaSwgb2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoYXJyYXlQcm90by5zb21lKSB7XG4gICAgdmFyIHNvbWUgPSB3cmFwTmF0aXZlKEFycmF5LnByb3RvdHlwZS5zb21lKTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZXZlcnkoaXRlcmF0b3IpIHtcbiAgICBpZiAodGhpcyA9PSBudWxsKSB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgaXRlcmF0b3IgPSBpdGVyYXRvciB8fCBQcm90b3R5cGUuSztcbiAgICB2YXIgY29udGV4dCA9IGFyZ3VtZW50c1sxXTtcblxuICAgIHZhciBvYmplY3QgPSBPYmplY3QodGhpcyk7XG4gICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGggPj4+IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGkgaW4gb2JqZWN0ICYmICFpdGVyYXRvci5jYWxsKGNvbnRleHQsIG9iamVjdFtpXSwgaSwgb2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpZiAoYXJyYXlQcm90by5ldmVyeSkge1xuICAgIHZhciBldmVyeSA9IHdyYXBOYXRpdmUoQXJyYXkucHJvdG90eXBlLmV2ZXJ5KTtcbiAgfVxuXG4gIHZhciBfcmVkdWNlID0gYXJyYXlQcm90by5yZWR1Y2U7XG4gIGZ1bmN0aW9uIGluamVjdChtZW1vLCBpdGVyYXRvcikge1xuICAgIGl0ZXJhdG9yID0gaXRlcmF0b3IgfHwgUHJvdG90eXBlLks7XG4gICAgdmFyIGNvbnRleHQgPSBhcmd1bWVudHNbMl07XG4gICAgcmV0dXJuIF9yZWR1Y2UuY2FsbCh0aGlzLCBpdGVyYXRvci5iaW5kKGNvbnRleHQpLCBtZW1vKTtcbiAgfVxuXG4gIGlmICghYXJyYXlQcm90by5yZWR1Y2UpIHtcbiAgICB2YXIgaW5qZWN0ID0gRW51bWVyYWJsZS5pbmplY3Q7XG4gIH1cblxuICBPYmplY3QuZXh0ZW5kKGFycmF5UHJvdG8sIEVudW1lcmFibGUpO1xuXG4gIGlmICghYXJyYXlQcm90by5fcmV2ZXJzZSlcbiAgICBhcnJheVByb3RvLl9yZXZlcnNlID0gYXJyYXlQcm90by5yZXZlcnNlO1xuXG4gIE9iamVjdC5leHRlbmQoYXJyYXlQcm90bywge1xuICAgIF9lYWNoOiAgICAgX2VhY2gsXG5cbiAgICBtYXA6ICAgICAgIG1hcCxcbiAgICBjb2xsZWN0OiAgIG1hcCxcbiAgICBzZWxlY3Q6ICAgIGZpbHRlcixcbiAgICBmaWx0ZXI6ICAgIGZpbHRlcixcbiAgICBmaW5kQWxsOiAgIGZpbHRlcixcbiAgICBzb21lOiAgICAgIHNvbWUsXG4gICAgYW55OiAgICAgICBzb21lLFxuICAgIGV2ZXJ5OiAgICAgZXZlcnksXG4gICAgYWxsOiAgICAgICBldmVyeSxcbiAgICBpbmplY3Q6ICAgIGluamVjdCxcblxuICAgIGNsZWFyOiAgICAgY2xlYXIsXG4gICAgZmlyc3Q6ICAgICBmaXJzdCxcbiAgICBsYXN0OiAgICAgIGxhc3QsXG4gICAgY29tcGFjdDogICBjb21wYWN0LFxuICAgIGZsYXR0ZW46ICAgZmxhdHRlbixcbiAgICB3aXRob3V0OiAgIHdpdGhvdXQsXG4gICAgcmV2ZXJzZTogICByZXZlcnNlLFxuICAgIHVuaXE6ICAgICAgdW5pcSxcbiAgICBpbnRlcnNlY3Q6IGludGVyc2VjdCxcbiAgICBjbG9uZTogICAgIGNsb25lLFxuICAgIHRvQXJyYXk6ICAgY2xvbmUsXG4gICAgc2l6ZTogICAgICBzaXplLFxuICAgIGluc3BlY3Q6ICAgaW5zcGVjdFxuICB9KTtcblxuICB2YXIgQ09OQ0FUX0FSR1VNRU5UU19CVUdHWSA9IChmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gW10uY29uY2F0KGFyZ3VtZW50cylbMF1bMF0gIT09IDE7XG4gIH0pKDEsMik7XG5cbiAgaWYgKENPTkNBVF9BUkdVTUVOVFNfQlVHR1kpIGFycmF5UHJvdG8uY29uY2F0ID0gY29uY2F0O1xuXG4gIGlmICghYXJyYXlQcm90by5pbmRleE9mKSBhcnJheVByb3RvLmluZGV4T2YgPSBpbmRleE9mO1xuICBpZiAoIWFycmF5UHJvdG8ubGFzdEluZGV4T2YpIGFycmF5UHJvdG8ubGFzdEluZGV4T2YgPSBsYXN0SW5kZXhPZjtcbn0pKCk7XG5mdW5jdGlvbiAkSChvYmplY3QpIHtcbiAgcmV0dXJuIG5ldyBIYXNoKG9iamVjdCk7XG59O1xuXG52YXIgSGFzaCA9IENsYXNzLmNyZWF0ZShFbnVtZXJhYmxlLCAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIGluaXRpYWxpemUob2JqZWN0KSB7XG4gICAgdGhpcy5fb2JqZWN0ID0gT2JqZWN0LmlzSGFzaChvYmplY3QpID8gb2JqZWN0LnRvT2JqZWN0KCkgOiBPYmplY3QuY2xvbmUob2JqZWN0KTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gX2VhY2goaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB2YXIgaSA9IDA7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuX29iamVjdCkge1xuICAgICAgdmFyIHZhbHVlID0gdGhpcy5fb2JqZWN0W2tleV0sIHBhaXIgPSBba2V5LCB2YWx1ZV07XG4gICAgICBwYWlyLmtleSA9IGtleTtcbiAgICAgIHBhaXIudmFsdWUgPSB2YWx1ZTtcbiAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgcGFpciwgaSk7XG4gICAgICBpKys7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5fb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldChrZXkpIHtcbiAgICBpZiAodGhpcy5fb2JqZWN0W2tleV0gIT09IE9iamVjdC5wcm90b3R5cGVba2V5XSlcbiAgICAgIHJldHVybiB0aGlzLl9vYmplY3Rba2V5XTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVuc2V0KGtleSkge1xuICAgIHZhciB2YWx1ZSA9IHRoaXMuX29iamVjdFtrZXldO1xuICAgIGRlbGV0ZSB0aGlzLl9vYmplY3Rba2V5XTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiB0b09iamVjdCgpIHtcbiAgICByZXR1cm4gT2JqZWN0LmNsb25lKHRoaXMuX29iamVjdCk7XG4gIH1cblxuXG5cbiAgZnVuY3Rpb24ga2V5cygpIHtcbiAgICByZXR1cm4gdGhpcy5wbHVjaygna2V5Jyk7XG4gIH1cblxuICBmdW5jdGlvbiB2YWx1ZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMucGx1Y2soJ3ZhbHVlJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbmRleCh2YWx1ZSkge1xuICAgIHZhciBtYXRjaCA9IHRoaXMuZGV0ZWN0KGZ1bmN0aW9uKHBhaXIpIHtcbiAgICAgIHJldHVybiBwYWlyLnZhbHVlID09PSB2YWx1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2gua2V5O1xuICB9XG5cbiAgZnVuY3Rpb24gbWVyZ2Uob2JqZWN0KSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoKS51cGRhdGUob2JqZWN0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZShvYmplY3QpIHtcbiAgICByZXR1cm4gbmV3IEhhc2gob2JqZWN0KS5pbmplY3QodGhpcywgZnVuY3Rpb24ocmVzdWx0LCBwYWlyKSB7XG4gICAgICByZXN1bHQuc2V0KHBhaXIua2V5LCBwYWlyLnZhbHVlKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB0b1F1ZXJ5UGFpcihrZXksIHZhbHVlKSB7XG4gICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZCh2YWx1ZSkpIHJldHVybiBrZXk7XG5cbiAgICB2YWx1ZSA9IFN0cmluZy5pbnRlcnByZXQodmFsdWUpO1xuXG4gICAgdmFsdWUgPSB2YWx1ZS5nc3ViKC8oXFxyKT9cXG4vLCAnXFxyXFxuJyk7XG4gICAgdmFsdWUgPSBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgIHZhbHVlID0gdmFsdWUuZ3N1YigvJTIwLywgJysnKTtcbiAgICByZXR1cm4ga2V5ICsgJz0nICsgdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiB0b1F1ZXJ5U3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmluamVjdChbXSwgZnVuY3Rpb24ocmVzdWx0cywgcGFpcikge1xuICAgICAgdmFyIGtleSA9IGVuY29kZVVSSUNvbXBvbmVudChwYWlyLmtleSksIHZhbHVlcyA9IHBhaXIudmFsdWU7XG5cbiAgICAgIGlmICh2YWx1ZXMgJiYgdHlwZW9mIHZhbHVlcyA9PSAnb2JqZWN0Jykge1xuICAgICAgICBpZiAoT2JqZWN0LmlzQXJyYXkodmFsdWVzKSkge1xuICAgICAgICAgIHZhciBxdWVyeVZhbHVlcyA9IFtdO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB2YWx1ZXMubGVuZ3RoLCB2YWx1ZTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlc1tpXTtcbiAgICAgICAgICAgIHF1ZXJ5VmFsdWVzLnB1c2godG9RdWVyeVBhaXIoa2V5LCB2YWx1ZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0cy5jb25jYXQocXVlcnlWYWx1ZXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgcmVzdWx0cy5wdXNoKHRvUXVlcnlQYWlyKGtleSwgdmFsdWVzKSk7XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9KS5qb2luKCcmJyk7XG4gIH1cblxuICBmdW5jdGlvbiBpbnNwZWN0KCkge1xuICAgIHJldHVybiAnIzxIYXNoOnsnICsgdGhpcy5tYXAoZnVuY3Rpb24ocGFpcikge1xuICAgICAgcmV0dXJuIHBhaXIubWFwKE9iamVjdC5pbnNwZWN0KS5qb2luKCc6ICcpO1xuICAgIH0pLmpvaW4oJywgJykgKyAnfT4nO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xvbmUoKSB7XG4gICAgcmV0dXJuIG5ldyBIYXNoKHRoaXMpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbml0aWFsaXplOiAgICAgICAgICAgICBpbml0aWFsaXplLFxuICAgIF9lYWNoOiAgICAgICAgICAgICAgICAgIF9lYWNoLFxuICAgIHNldDogICAgICAgICAgICAgICAgICAgIHNldCxcbiAgICBnZXQ6ICAgICAgICAgICAgICAgICAgICBnZXQsXG4gICAgdW5zZXQ6ICAgICAgICAgICAgICAgICAgdW5zZXQsXG4gICAgdG9PYmplY3Q6ICAgICAgICAgICAgICAgdG9PYmplY3QsXG4gICAgdG9UZW1wbGF0ZVJlcGxhY2VtZW50czogdG9PYmplY3QsXG4gICAga2V5czogICAgICAgICAgICAgICAgICAga2V5cyxcbiAgICB2YWx1ZXM6ICAgICAgICAgICAgICAgICB2YWx1ZXMsXG4gICAgaW5kZXg6ICAgICAgICAgICAgICAgICAgaW5kZXgsXG4gICAgbWVyZ2U6ICAgICAgICAgICAgICAgICAgbWVyZ2UsXG4gICAgdXBkYXRlOiAgICAgICAgICAgICAgICAgdXBkYXRlLFxuICAgIHRvUXVlcnlTdHJpbmc6ICAgICAgICAgIHRvUXVlcnlTdHJpbmcsXG4gICAgaW5zcGVjdDogICAgICAgICAgICAgICAgaW5zcGVjdCxcbiAgICB0b0pTT046ICAgICAgICAgICAgICAgICB0b09iamVjdCxcbiAgICBjbG9uZTogICAgICAgICAgICAgICAgICBjbG9uZVxuICB9O1xufSkoKSk7XG5cbkhhc2guZnJvbSA9ICRIO1xuT2JqZWN0LmV4dGVuZChOdW1iZXIucHJvdG90eXBlLCAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIHRvQ29sb3JQYXJ0KCkge1xuICAgIHJldHVybiB0aGlzLnRvUGFkZGVkU3RyaW5nKDIsIDE2KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHN1Y2MoKSB7XG4gICAgcmV0dXJuIHRoaXMgKyAxO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXMoaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICAkUigwLCB0aGlzLCB0cnVlKS5lYWNoKGl0ZXJhdG9yLCBjb250ZXh0KTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvUGFkZGVkU3RyaW5nKGxlbmd0aCwgcmFkaXgpIHtcbiAgICB2YXIgc3RyaW5nID0gdGhpcy50b1N0cmluZyhyYWRpeCB8fCAxMCk7XG4gICAgcmV0dXJuICcwJy50aW1lcyhsZW5ndGggLSBzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFicygpIHtcbiAgICByZXR1cm4gTWF0aC5hYnModGhpcyk7XG4gIH1cblxuICBmdW5jdGlvbiByb3VuZCgpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNlaWwoKSB7XG4gICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZsb29yKCkge1xuICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b0NvbG9yUGFydDogICAgdG9Db2xvclBhcnQsXG4gICAgc3VjYzogICAgICAgICAgIHN1Y2MsXG4gICAgdGltZXM6ICAgICAgICAgIHRpbWVzLFxuICAgIHRvUGFkZGVkU3RyaW5nOiB0b1BhZGRlZFN0cmluZyxcbiAgICBhYnM6ICAgICAgICAgICAgYWJzLFxuICAgIHJvdW5kOiAgICAgICAgICByb3VuZCxcbiAgICBjZWlsOiAgICAgICAgICAgY2VpbCxcbiAgICBmbG9vcjogICAgICAgICAgZmxvb3JcbiAgfTtcbn0pKCkpO1xuXG5mdW5jdGlvbiAkUihzdGFydCwgZW5kLCBleGNsdXNpdmUpIHtcbiAgcmV0dXJuIG5ldyBPYmplY3RSYW5nZShzdGFydCwgZW5kLCBleGNsdXNpdmUpO1xufVxuXG52YXIgT2JqZWN0UmFuZ2UgPSBDbGFzcy5jcmVhdGUoRW51bWVyYWJsZSwgKGZ1bmN0aW9uKCkge1xuICBmdW5jdGlvbiBpbml0aWFsaXplKHN0YXJ0LCBlbmQsIGV4Y2x1c2l2ZSkge1xuICAgIHRoaXMuc3RhcnQgPSBzdGFydDtcbiAgICB0aGlzLmVuZCA9IGVuZDtcbiAgICB0aGlzLmV4Y2x1c2l2ZSA9IGV4Y2x1c2l2ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9lYWNoKGl0ZXJhdG9yLCBjb250ZXh0KSB7XG4gICAgdmFyIHZhbHVlID0gdGhpcy5zdGFydCwgaTtcbiAgICBmb3IgKGkgPSAwOyB0aGlzLmluY2x1ZGUodmFsdWUpOyBpKyspIHtcbiAgICAgIGl0ZXJhdG9yLmNhbGwoY29udGV4dCwgdmFsdWUsIGkpO1xuICAgICAgdmFsdWUgPSB2YWx1ZS5zdWNjKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5jbHVkZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA8IHRoaXMuc3RhcnQpXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRoaXMuZXhjbHVzaXZlKVxuICAgICAgcmV0dXJuIHZhbHVlIDwgdGhpcy5lbmQ7XG4gICAgcmV0dXJuIHZhbHVlIDw9IHRoaXMuZW5kO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbml0aWFsaXplOiBpbml0aWFsaXplLFxuICAgIF9lYWNoOiAgICAgIF9lYWNoLFxuICAgIGluY2x1ZGU6ICAgIGluY2x1ZGVcbiAgfTtcbn0pKCkpO1xuXG5cblxudmFyIEFic3RyYWN0ID0geyB9O1xuXG5cbnZhciBUcnkgPSB7XG4gIHRoZXNlOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmV0dXJuVmFsdWU7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbGFtYmRhID0gYXJndW1lbnRzW2ldO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuVmFsdWUgPSBsYW1iZGEoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGNhdGNoIChlKSB7IH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cbn07XG5cbnZhciBBamF4ID0ge1xuICBnZXRUcmFuc3BvcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBUcnkudGhlc2UoXG4gICAgICBmdW5jdGlvbigpIHtyZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0KCl9LFxuICAgICAgZnVuY3Rpb24oKSB7cmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUCcpfSxcbiAgICAgIGZ1bmN0aW9uKCkge3JldHVybiBuZXcgQWN0aXZlWE9iamVjdCgnTWljcm9zb2Z0LlhNTEhUVFAnKX1cbiAgICApIHx8IGZhbHNlO1xuICB9LFxuXG4gIGFjdGl2ZVJlcXVlc3RDb3VudDogMFxufTtcblxuQWpheC5SZXNwb25kZXJzID0ge1xuICByZXNwb25kZXJzOiBbXSxcblxuICBfZWFjaDogZnVuY3Rpb24oaXRlcmF0b3IsIGNvbnRleHQpIHtcbiAgICB0aGlzLnJlc3BvbmRlcnMuX2VhY2goaXRlcmF0b3IsIGNvbnRleHQpO1xuICB9LFxuXG4gIHJlZ2lzdGVyOiBmdW5jdGlvbihyZXNwb25kZXIpIHtcbiAgICBpZiAoIXRoaXMuaW5jbHVkZShyZXNwb25kZXIpKVxuICAgICAgdGhpcy5yZXNwb25kZXJzLnB1c2gocmVzcG9uZGVyKTtcbiAgfSxcblxuICB1bnJlZ2lzdGVyOiBmdW5jdGlvbihyZXNwb25kZXIpIHtcbiAgICB0aGlzLnJlc3BvbmRlcnMgPSB0aGlzLnJlc3BvbmRlcnMud2l0aG91dChyZXNwb25kZXIpO1xuICB9LFxuXG4gIGRpc3BhdGNoOiBmdW5jdGlvbihjYWxsYmFjaywgcmVxdWVzdCwgdHJhbnNwb3J0LCBqc29uKSB7XG4gICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHJlc3BvbmRlcikge1xuICAgICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKHJlc3BvbmRlcltjYWxsYmFja10pKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVzcG9uZGVyW2NhbGxiYWNrXS5hcHBseShyZXNwb25kZXIsIFtyZXF1ZXN0LCB0cmFuc3BvcnQsIGpzb25dKTtcbiAgICAgICAgfSBjYXRjaCAoZSkgeyB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cbk9iamVjdC5leHRlbmQoQWpheC5SZXNwb25kZXJzLCBFbnVtZXJhYmxlKTtcblxuQWpheC5SZXNwb25kZXJzLnJlZ2lzdGVyKHtcbiAgb25DcmVhdGU6ICAgZnVuY3Rpb24oKSB7IEFqYXguYWN0aXZlUmVxdWVzdENvdW50KysgfSxcbiAgb25Db21wbGV0ZTogZnVuY3Rpb24oKSB7IEFqYXguYWN0aXZlUmVxdWVzdENvdW50LS0gfVxufSk7XG5BamF4LkJhc2UgPSBDbGFzcy5jcmVhdGUoe1xuICBpbml0aWFsaXplOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgbWV0aG9kOiAgICAgICAncG9zdCcsXG4gICAgICBhc3luY2hyb25vdXM6IHRydWUsXG4gICAgICBjb250ZW50VHlwZTogICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgZW5jb2Rpbmc6ICAgICAnVVRGLTgnLFxuICAgICAgcGFyYW1ldGVyczogICAnJyxcbiAgICAgIGV2YWxKU09OOiAgICAgdHJ1ZSxcbiAgICAgIGV2YWxKUzogICAgICAgdHJ1ZVxuICAgIH07XG4gICAgT2JqZWN0LmV4dGVuZCh0aGlzLm9wdGlvbnMsIG9wdGlvbnMgfHwgeyB9KTtcblxuICAgIHRoaXMub3B0aW9ucy5tZXRob2QgPSB0aGlzLm9wdGlvbnMubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAoT2JqZWN0LmlzSGFzaCh0aGlzLm9wdGlvbnMucGFyYW1ldGVycykpXG4gICAgICB0aGlzLm9wdGlvbnMucGFyYW1ldGVycyA9IHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzLnRvT2JqZWN0KCk7XG4gIH1cbn0pO1xuQWpheC5SZXF1ZXN0ID0gQ2xhc3MuY3JlYXRlKEFqYXguQmFzZSwge1xuICBfY29tcGxldGU6IGZhbHNlLFxuXG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKCRzdXBlciwgdXJsLCBvcHRpb25zKSB7XG4gICAgJHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMudHJhbnNwb3J0ID0gQWpheC5nZXRUcmFuc3BvcnQoKTtcbiAgICB0aGlzLnJlcXVlc3QodXJsKTtcbiAgfSxcblxuICByZXF1ZXN0OiBmdW5jdGlvbih1cmwpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICB0aGlzLm1ldGhvZCA9IHRoaXMub3B0aW9ucy5tZXRob2Q7XG4gICAgdmFyIHBhcmFtcyA9IE9iamVjdC5pc1N0cmluZyh0aGlzLm9wdGlvbnMucGFyYW1ldGVycykgP1xuICAgICAgICAgIHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzIDpcbiAgICAgICAgICBPYmplY3QudG9RdWVyeVN0cmluZyh0aGlzLm9wdGlvbnMucGFyYW1ldGVycyk7XG5cbiAgICBpZiAoIVsnZ2V0JywgJ3Bvc3QnXS5pbmNsdWRlKHRoaXMubWV0aG9kKSkge1xuICAgICAgcGFyYW1zICs9IChwYXJhbXMgPyAnJicgOiAnJykgKyBcIl9tZXRob2Q9XCIgKyB0aGlzLm1ldGhvZDtcbiAgICAgIHRoaXMubWV0aG9kID0gJ3Bvc3QnO1xuICAgIH1cblxuICAgIGlmIChwYXJhbXMgJiYgdGhpcy5tZXRob2QgPT09ICdnZXQnKSB7XG4gICAgICB0aGlzLnVybCArPSAodGhpcy51cmwuaW5jbHVkZSgnPycpID8gJyYnIDogJz8nKSArIHBhcmFtcztcbiAgICB9XG5cbiAgICB0aGlzLnBhcmFtZXRlcnMgPSBwYXJhbXMudG9RdWVyeVBhcmFtcygpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciByZXNwb25zZSA9IG5ldyBBamF4LlJlc3BvbnNlKHRoaXMpO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5vbkNyZWF0ZSkgdGhpcy5vcHRpb25zLm9uQ3JlYXRlKHJlc3BvbnNlKTtcbiAgICAgIEFqYXguUmVzcG9uZGVycy5kaXNwYXRjaCgnb25DcmVhdGUnLCB0aGlzLCByZXNwb25zZSk7XG5cbiAgICAgIHRoaXMudHJhbnNwb3J0Lm9wZW4odGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSwgdGhpcy51cmwsXG4gICAgICAgIHRoaXMub3B0aW9ucy5hc3luY2hyb25vdXMpO1xuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFzeW5jaHJvbm91cykgdGhpcy5yZXNwb25kVG9SZWFkeVN0YXRlLmJpbmQodGhpcykuZGVmZXIoMSk7XG5cbiAgICAgIHRoaXMudHJhbnNwb3J0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHRoaXMub25TdGF0ZUNoYW5nZS5iaW5kKHRoaXMpO1xuICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVycygpO1xuXG4gICAgICB0aGlzLmJvZHkgPSB0aGlzLm1ldGhvZCA9PSAncG9zdCcgPyAodGhpcy5vcHRpb25zLnBvc3RCb2R5IHx8IHBhcmFtcykgOiBudWxsO1xuICAgICAgdGhpcy50cmFuc3BvcnQuc2VuZCh0aGlzLmJvZHkpO1xuXG4gICAgICAvKiBGb3JjZSBGaXJlZm94IHRvIGhhbmRsZSByZWFkeSBzdGF0ZSA0IGZvciBzeW5jaHJvbm91cyByZXF1ZXN0cyAqL1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuYXN5bmNocm9ub3VzICYmIHRoaXMudHJhbnNwb3J0Lm92ZXJyaWRlTWltZVR5cGUpXG4gICAgICAgIHRoaXMub25TdGF0ZUNoYW5nZSgpO1xuXG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmRpc3BhdGNoRXhjZXB0aW9uKGUpO1xuICAgIH1cbiAgfSxcblxuICBvblN0YXRlQ2hhbmdlOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmVhZHlTdGF0ZSA9IHRoaXMudHJhbnNwb3J0LnJlYWR5U3RhdGU7XG4gICAgaWYgKHJlYWR5U3RhdGUgPiAxICYmICEoKHJlYWR5U3RhdGUgPT0gNCkgJiYgdGhpcy5fY29tcGxldGUpKVxuICAgICAgdGhpcy5yZXNwb25kVG9SZWFkeVN0YXRlKHRoaXMudHJhbnNwb3J0LnJlYWR5U3RhdGUpO1xuICB9LFxuXG4gIHNldFJlcXVlc3RIZWFkZXJzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgaGVhZGVycyA9IHtcbiAgICAgICdYLVJlcXVlc3RlZC1XaXRoJzogJ1hNTEh0dHBSZXF1ZXN0JyxcbiAgICAgICdYLVByb3RvdHlwZS1WZXJzaW9uJzogUHJvdG90eXBlLlZlcnNpb24sXG4gICAgICAnQWNjZXB0JzogJ3RleHQvamF2YXNjcmlwdCwgdGV4dC9odG1sLCBhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sLCAqLyonXG4gICAgfTtcblxuICAgIGlmICh0aGlzLm1ldGhvZCA9PSAncG9zdCcpIHtcbiAgICAgIGhlYWRlcnNbJ0NvbnRlbnQtdHlwZSddID0gdGhpcy5vcHRpb25zLmNvbnRlbnRUeXBlICtcbiAgICAgICAgKHRoaXMub3B0aW9ucy5lbmNvZGluZyA/ICc7IGNoYXJzZXQ9JyArIHRoaXMub3B0aW9ucy5lbmNvZGluZyA6ICcnKTtcblxuICAgICAgLyogRm9yY2UgXCJDb25uZWN0aW9uOiBjbG9zZVwiIGZvciBvbGRlciBNb3ppbGxhIGJyb3dzZXJzIHRvIHdvcmtcbiAgICAgICAqIGFyb3VuZCBhIGJ1ZyB3aGVyZSBYTUxIdHRwUmVxdWVzdCBzZW5kcyBhbiBpbmNvcnJlY3RcbiAgICAgICAqIENvbnRlbnQtbGVuZ3RoIGhlYWRlci4gU2VlIE1vemlsbGEgQnVnemlsbGEgIzI0NjY1MS5cbiAgICAgICAqL1xuICAgICAgaWYgKHRoaXMudHJhbnNwb3J0Lm92ZXJyaWRlTWltZVR5cGUgJiZcbiAgICAgICAgICAobmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvR2Vja29cXC8oXFxkezR9KS8pIHx8IFswLDIwMDVdKVsxXSA8IDIwMDUpXG4gICAgICAgICAgICBoZWFkZXJzWydDb25uZWN0aW9uJ10gPSAnY2xvc2UnO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLnJlcXVlc3RIZWFkZXJzID09ICdvYmplY3QnKSB7XG4gICAgICB2YXIgZXh0cmFzID0gdGhpcy5vcHRpb25zLnJlcXVlc3RIZWFkZXJzO1xuXG4gICAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24oZXh0cmFzLnB1c2gpKVxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZXh0cmFzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSArPSAyKVxuICAgICAgICAgIGhlYWRlcnNbZXh0cmFzW2ldXSA9IGV4dHJhc1tpKzFdO1xuICAgICAgZWxzZVxuICAgICAgICAkSChleHRyYXMpLmVhY2goZnVuY3Rpb24ocGFpcikgeyBoZWFkZXJzW3BhaXIua2V5XSA9IHBhaXIudmFsdWUgfSk7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgbmFtZSBpbiBoZWFkZXJzKVxuICAgICAgaWYgKGhlYWRlcnNbbmFtZV0gIT0gbnVsbClcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuc2V0UmVxdWVzdEhlYWRlcihuYW1lLCBoZWFkZXJzW25hbWVdKTtcbiAgfSxcblxuICBzdWNjZXNzOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgc3RhdHVzID0gdGhpcy5nZXRTdGF0dXMoKTtcbiAgICByZXR1cm4gIXN0YXR1cyB8fCAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDApIHx8IHN0YXR1cyA9PSAzMDQ7XG4gIH0sXG5cbiAgZ2V0U3RhdHVzOiBmdW5jdGlvbigpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMudHJhbnNwb3J0LnN0YXR1cyA9PT0gMTIyMykgcmV0dXJuIDIwNDtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5zdGF0dXMgfHwgMDtcbiAgICB9IGNhdGNoIChlKSB7IHJldHVybiAwIH1cbiAgfSxcblxuICByZXNwb25kVG9SZWFkeVN0YXRlOiBmdW5jdGlvbihyZWFkeVN0YXRlKSB7XG4gICAgdmFyIHN0YXRlID0gQWpheC5SZXF1ZXN0LkV2ZW50c1tyZWFkeVN0YXRlXSwgcmVzcG9uc2UgPSBuZXcgQWpheC5SZXNwb25zZSh0aGlzKTtcblxuICAgIGlmIChzdGF0ZSA9PSAnQ29tcGxldGUnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl9jb21wbGV0ZSA9IHRydWU7XG4gICAgICAgICh0aGlzLm9wdGlvbnNbJ29uJyArIHJlc3BvbnNlLnN0YXR1c11cbiAgICAgICAgIHx8IHRoaXMub3B0aW9uc1snb24nICsgKHRoaXMuc3VjY2VzcygpID8gJ1N1Y2Nlc3MnIDogJ0ZhaWx1cmUnKV1cbiAgICAgICAgIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKShyZXNwb25zZSwgcmVzcG9uc2UuaGVhZGVySlNPTik7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2hFeGNlcHRpb24oZSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBjb250ZW50VHlwZSA9IHJlc3BvbnNlLmdldEhlYWRlcignQ29udGVudC10eXBlJyk7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV2YWxKUyA9PSAnZm9yY2UnXG4gICAgICAgICAgfHwgKHRoaXMub3B0aW9ucy5ldmFsSlMgJiYgdGhpcy5pc1NhbWVPcmlnaW4oKSAmJiBjb250ZW50VHlwZVxuICAgICAgICAgICYmIGNvbnRlbnRUeXBlLm1hdGNoKC9eXFxzKih0ZXh0fGFwcGxpY2F0aW9uKVxcLyh4LSk/KGphdmF8ZWNtYSlzY3JpcHQoOy4qKT9cXHMqJC9pKSkpXG4gICAgICAgIHRoaXMuZXZhbFJlc3BvbnNlKCk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgICh0aGlzLm9wdGlvbnNbJ29uJyArIHN0YXRlXSB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbikocmVzcG9uc2UsIHJlc3BvbnNlLmhlYWRlckpTT04pO1xuICAgICAgQWpheC5SZXNwb25kZXJzLmRpc3BhdGNoKCdvbicgKyBzdGF0ZSwgdGhpcywgcmVzcG9uc2UsIHJlc3BvbnNlLmhlYWRlckpTT04pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuZGlzcGF0Y2hFeGNlcHRpb24oZSk7XG4gICAgfVxuXG4gICAgaWYgKHN0YXRlID09ICdDb21wbGV0ZScpIHtcbiAgICAgIHRoaXMudHJhbnNwb3J0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uO1xuICAgIH1cbiAgfSxcblxuICBpc1NhbWVPcmlnaW46IGZ1bmN0aW9uKCkge1xuICAgIHZhciBtID0gdGhpcy51cmwubWF0Y2goL15cXHMqaHR0cHM/OlxcL1xcL1teXFwvXSovKTtcbiAgICByZXR1cm4gIW0gfHwgKG1bMF0gPT0gJyN7cHJvdG9jb2x9Ly8je2RvbWFpbn0je3BvcnR9Jy5pbnRlcnBvbGF0ZSh7XG4gICAgICBwcm90b2NvbDogbG9jYXRpb24ucHJvdG9jb2wsXG4gICAgICBkb21haW46IGRvY3VtZW50LmRvbWFpbixcbiAgICAgIHBvcnQ6IGxvY2F0aW9uLnBvcnQgPyAnOicgKyBsb2NhdGlvbi5wb3J0IDogJydcbiAgICB9KSk7XG4gIH0sXG5cbiAgZ2V0SGVhZGVyOiBmdW5jdGlvbihuYW1lKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5nZXRSZXNwb25zZUhlYWRlcihuYW1lKSB8fCBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHsgcmV0dXJuIG51bGw7IH1cbiAgfSxcblxuICBldmFsUmVzcG9uc2U6IGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gZXZhbCgodGhpcy50cmFuc3BvcnQucmVzcG9uc2VUZXh0IHx8ICcnKS51bmZpbHRlckpTT04oKSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5kaXNwYXRjaEV4Y2VwdGlvbihlKTtcbiAgICB9XG4gIH0sXG5cbiAgZGlzcGF0Y2hFeGNlcHRpb246IGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xuICAgICh0aGlzLm9wdGlvbnMub25FeGNlcHRpb24gfHwgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb24pKHRoaXMsIGV4Y2VwdGlvbik7XG4gICAgQWpheC5SZXNwb25kZXJzLmRpc3BhdGNoKCdvbkV4Y2VwdGlvbicsIHRoaXMsIGV4Y2VwdGlvbik7XG4gIH1cbn0pO1xuXG5BamF4LlJlcXVlc3QuRXZlbnRzID1cbiAgWydVbmluaXRpYWxpemVkJywgJ0xvYWRpbmcnLCAnTG9hZGVkJywgJ0ludGVyYWN0aXZlJywgJ0NvbXBsZXRlJ107XG5cblxuXG5cblxuXG5cblxuQWpheC5SZXNwb25zZSA9IENsYXNzLmNyZWF0ZSh7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKHJlcXVlc3Qpe1xuICAgIHRoaXMucmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgdmFyIHRyYW5zcG9ydCAgPSB0aGlzLnRyYW5zcG9ydCAgPSByZXF1ZXN0LnRyYW5zcG9ydCxcbiAgICAgICAgcmVhZHlTdGF0ZSA9IHRoaXMucmVhZHlTdGF0ZSA9IHRyYW5zcG9ydC5yZWFkeVN0YXRlO1xuXG4gICAgaWYgKChyZWFkeVN0YXRlID4gMiAmJiAhUHJvdG90eXBlLkJyb3dzZXIuSUUpIHx8IHJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgdGhpcy5zdGF0dXMgICAgICAgPSB0aGlzLmdldFN0YXR1cygpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0ICAgPSB0aGlzLmdldFN0YXR1c1RleHQoKTtcbiAgICAgIHRoaXMucmVzcG9uc2VUZXh0ID0gU3RyaW5nLmludGVycHJldCh0cmFuc3BvcnQucmVzcG9uc2VUZXh0KTtcbiAgICAgIHRoaXMuaGVhZGVySlNPTiAgID0gdGhpcy5fZ2V0SGVhZGVySlNPTigpO1xuICAgIH1cblxuICAgIGlmIChyZWFkeVN0YXRlID09IDQpIHtcbiAgICAgIHZhciB4bWwgPSB0cmFuc3BvcnQucmVzcG9uc2VYTUw7XG4gICAgICB0aGlzLnJlc3BvbnNlWE1MICA9IE9iamVjdC5pc1VuZGVmaW5lZCh4bWwpID8gbnVsbCA6IHhtbDtcbiAgICAgIHRoaXMucmVzcG9uc2VKU09OID0gdGhpcy5fZ2V0UmVzcG9uc2VKU09OKCk7XG4gICAgfVxuICB9LFxuXG4gIHN0YXR1czogICAgICAwLFxuXG4gIHN0YXR1c1RleHQ6ICcnLFxuXG4gIGdldFN0YXR1czogQWpheC5SZXF1ZXN0LnByb3RvdHlwZS5nZXRTdGF0dXMsXG5cbiAgZ2V0U3RhdHVzVGV4dDogZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5zdGF0dXNUZXh0IHx8ICcnO1xuICAgIH0gY2F0Y2ggKGUpIHsgcmV0dXJuICcnIH1cbiAgfSxcblxuICBnZXRIZWFkZXI6IEFqYXguUmVxdWVzdC5wcm90b3R5cGUuZ2V0SGVhZGVyLFxuXG4gIGdldEFsbEhlYWRlcnM6IGZ1bmN0aW9uKCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKTtcbiAgICB9IGNhdGNoIChlKSB7IHJldHVybiBudWxsIH1cbiAgfSxcblxuICBnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5nZXRSZXNwb25zZUhlYWRlcihuYW1lKTtcbiAgfSxcblxuICBnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnRyYW5zcG9ydC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKTtcbiAgfSxcblxuICBfZ2V0SGVhZGVySlNPTjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGpzb24gPSB0aGlzLmdldEhlYWRlcignWC1KU09OJyk7XG4gICAgaWYgKCFqc29uKSByZXR1cm4gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBqc29uID0gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShqc29uKSk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBqc29uLmV2YWxKU09OKHRoaXMucmVxdWVzdC5vcHRpb25zLnNhbml0aXplSlNPTiB8fFxuICAgICAgICAhdGhpcy5yZXF1ZXN0LmlzU2FtZU9yaWdpbigpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnJlcXVlc3QuZGlzcGF0Y2hFeGNlcHRpb24oZSk7XG4gICAgfVxuICB9LFxuXG4gIF9nZXRSZXNwb25zZUpTT046IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvcHRpb25zID0gdGhpcy5yZXF1ZXN0Lm9wdGlvbnM7XG4gICAgaWYgKCFvcHRpb25zLmV2YWxKU09OIHx8IChvcHRpb25zLmV2YWxKU09OICE9ICdmb3JjZScgJiZcbiAgICAgICEodGhpcy5nZXRIZWFkZXIoJ0NvbnRlbnQtdHlwZScpIHx8ICcnKS5pbmNsdWRlKCdhcHBsaWNhdGlvbi9qc29uJykpIHx8XG4gICAgICAgIHRoaXMucmVzcG9uc2VUZXh0LmJsYW5rKCkpXG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnJlc3BvbnNlVGV4dC5ldmFsSlNPTihvcHRpb25zLnNhbml0aXplSlNPTiB8fFxuICAgICAgICAhdGhpcy5yZXF1ZXN0LmlzU2FtZU9yaWdpbigpKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnJlcXVlc3QuZGlzcGF0Y2hFeGNlcHRpb24oZSk7XG4gICAgfVxuICB9XG59KTtcblxuQWpheC5VcGRhdGVyID0gQ2xhc3MuY3JlYXRlKEFqYXguUmVxdWVzdCwge1xuICBpbml0aWFsaXplOiBmdW5jdGlvbigkc3VwZXIsIGNvbnRhaW5lciwgdXJsLCBvcHRpb25zKSB7XG4gICAgdGhpcy5jb250YWluZXIgPSB7XG4gICAgICBzdWNjZXNzOiAoY29udGFpbmVyLnN1Y2Nlc3MgfHwgY29udGFpbmVyKSxcbiAgICAgIGZhaWx1cmU6IChjb250YWluZXIuZmFpbHVyZSB8fCAoY29udGFpbmVyLnN1Y2Nlc3MgPyBudWxsIDogY29udGFpbmVyKSlcbiAgICB9O1xuXG4gICAgb3B0aW9ucyA9IE9iamVjdC5jbG9uZShvcHRpb25zKTtcbiAgICB2YXIgb25Db21wbGV0ZSA9IG9wdGlvbnMub25Db21wbGV0ZTtcbiAgICBvcHRpb25zLm9uQ29tcGxldGUgPSAoZnVuY3Rpb24ocmVzcG9uc2UsIGpzb24pIHtcbiAgICAgIHRoaXMudXBkYXRlQ29udGVudChyZXNwb25zZS5yZXNwb25zZVRleHQpO1xuICAgICAgaWYgKE9iamVjdC5pc0Z1bmN0aW9uKG9uQ29tcGxldGUpKSBvbkNvbXBsZXRlKHJlc3BvbnNlLCBqc29uKTtcbiAgICB9KS5iaW5kKHRoaXMpO1xuXG4gICAgJHN1cGVyKHVybCwgb3B0aW9ucyk7XG4gIH0sXG5cbiAgdXBkYXRlQ29udGVudDogZnVuY3Rpb24ocmVzcG9uc2VUZXh0KSB7XG4gICAgdmFyIHJlY2VpdmVyID0gdGhpcy5jb250YWluZXJbdGhpcy5zdWNjZXNzKCkgPyAnc3VjY2VzcycgOiAnZmFpbHVyZSddLFxuICAgICAgICBvcHRpb25zID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYgKCFvcHRpb25zLmV2YWxTY3JpcHRzKSByZXNwb25zZVRleHQgPSByZXNwb25zZVRleHQuc3RyaXBTY3JpcHRzKCk7XG5cbiAgICBpZiAocmVjZWl2ZXIgPSAkKHJlY2VpdmVyKSkge1xuICAgICAgaWYgKG9wdGlvbnMuaW5zZXJ0aW9uKSB7XG4gICAgICAgIGlmIChPYmplY3QuaXNTdHJpbmcob3B0aW9ucy5pbnNlcnRpb24pKSB7XG4gICAgICAgICAgdmFyIGluc2VydGlvbiA9IHsgfTsgaW5zZXJ0aW9uW29wdGlvbnMuaW5zZXJ0aW9uXSA9IHJlc3BvbnNlVGV4dDtcbiAgICAgICAgICByZWNlaXZlci5pbnNlcnQoaW5zZXJ0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIG9wdGlvbnMuaW5zZXJ0aW9uKHJlY2VpdmVyLCByZXNwb25zZVRleHQpO1xuICAgICAgfVxuICAgICAgZWxzZSByZWNlaXZlci51cGRhdGUocmVzcG9uc2VUZXh0KTtcbiAgICB9XG4gIH1cbn0pO1xuXG5BamF4LlBlcmlvZGljYWxVcGRhdGVyID0gQ2xhc3MuY3JlYXRlKEFqYXguQmFzZSwge1xuICBpbml0aWFsaXplOiBmdW5jdGlvbigkc3VwZXIsIGNvbnRhaW5lciwgdXJsLCBvcHRpb25zKSB7XG4gICAgJHN1cGVyKG9wdGlvbnMpO1xuICAgIHRoaXMub25Db21wbGV0ZSA9IHRoaXMub3B0aW9ucy5vbkNvbXBsZXRlO1xuXG4gICAgdGhpcy5mcmVxdWVuY3kgPSAodGhpcy5vcHRpb25zLmZyZXF1ZW5jeSB8fCAyKTtcbiAgICB0aGlzLmRlY2F5ID0gKHRoaXMub3B0aW9ucy5kZWNheSB8fCAxKTtcblxuICAgIHRoaXMudXBkYXRlciA9IHsgfTtcbiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjtcbiAgICB0aGlzLnVybCA9IHVybDtcblxuICAgIHRoaXMuc3RhcnQoKTtcbiAgfSxcblxuICBzdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5vcHRpb25zLm9uQ29tcGxldGUgPSB0aGlzLnVwZGF0ZUNvbXBsZXRlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5vblRpbWVyRXZlbnQoKTtcbiAgfSxcblxuICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnVwZGF0ZXIub3B0aW9ucy5vbkNvbXBsZXRlID0gdW5kZWZpbmVkO1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAodGhpcy5vbkNvbXBsZXRlIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9LFxuXG4gIHVwZGF0ZUNvbXBsZXRlOiBmdW5jdGlvbihyZXNwb25zZSkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVjYXkpIHtcbiAgICAgIHRoaXMuZGVjYXkgPSAocmVzcG9uc2UucmVzcG9uc2VUZXh0ID09IHRoaXMubGFzdFRleHQgP1xuICAgICAgICB0aGlzLmRlY2F5ICogdGhpcy5vcHRpb25zLmRlY2F5IDogMSk7XG5cbiAgICAgIHRoaXMubGFzdFRleHQgPSByZXNwb25zZS5yZXNwb25zZVRleHQ7XG4gICAgfVxuICAgIHRoaXMudGltZXIgPSB0aGlzLm9uVGltZXJFdmVudC5iaW5kKHRoaXMpLmRlbGF5KHRoaXMuZGVjYXkgKiB0aGlzLmZyZXF1ZW5jeSk7XG4gIH0sXG5cbiAgb25UaW1lckV2ZW50OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnVwZGF0ZXIgPSBuZXcgQWpheC5VcGRhdGVyKHRoaXMuY29udGFpbmVyLCB0aGlzLnVybCwgdGhpcy5vcHRpb25zKTtcbiAgfVxufSk7XG5cbihmdW5jdGlvbihHTE9CQUwpIHtcblxuICB2YXIgVU5ERUZJTkVEO1xuICB2YXIgU0xJQ0UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbiAgdmFyIERJViA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG5cbiAgZnVuY3Rpb24gJChlbGVtZW50KSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgZWxlbWVudHMgPSBbXSwgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKVxuICAgICAgICBlbGVtZW50cy5wdXNoKCQoYXJndW1lbnRzW2ldKSk7XG4gICAgICByZXR1cm4gZWxlbWVudHM7XG4gICAgfVxuXG4gICAgaWYgKE9iamVjdC5pc1N0cmluZyhlbGVtZW50KSlcbiAgICAgIGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChlbGVtZW50KTtcbiAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7XG4gIH1cblxuICBHTE9CQUwuJCA9ICQ7XG5cblxuICBpZiAoIUdMT0JBTC5Ob2RlKSBHTE9CQUwuTm9kZSA9IHt9O1xuXG4gIGlmICghR0xPQkFMLk5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgT2JqZWN0LmV4dGVuZChHTE9CQUwuTm9kZSwge1xuICAgICAgRUxFTUVOVF9OT0RFOiAgICAgICAgICAgICAgICAxLFxuICAgICAgQVRUUklCVVRFX05PREU6ICAgICAgICAgICAgICAyLFxuICAgICAgVEVYVF9OT0RFOiAgICAgICAgICAgICAgICAgICAzLFxuICAgICAgQ0RBVEFfU0VDVElPTl9OT0RFOiAgICAgICAgICA0LFxuICAgICAgRU5USVRZX1JFRkVSRU5DRV9OT0RFOiAgICAgICA1LFxuICAgICAgRU5USVRZX05PREU6ICAgICAgICAgICAgICAgICA2LFxuICAgICAgUFJPQ0VTU0lOR19JTlNUUlVDVElPTl9OT0RFOiA3LFxuICAgICAgQ09NTUVOVF9OT0RFOiAgICAgICAgICAgICAgICA4LFxuICAgICAgRE9DVU1FTlRfTk9ERTogICAgICAgICAgICAgICA5LFxuICAgICAgRE9DVU1FTlRfVFlQRV9OT0RFOiAgICAgICAgIDEwLFxuICAgICAgRE9DVU1FTlRfRlJBR01FTlRfTk9ERTogICAgIDExLFxuICAgICAgTk9UQVRJT05fTk9ERTogICAgICAgICAgICAgIDEyXG4gICAgfSk7XG4gIH1cblxuICB2YXIgRUxFTUVOVF9DQUNIRSA9IHt9O1xuXG4gIGZ1bmN0aW9uIHNob3VsZFVzZUNyZWF0aW9uQ2FjaGUodGFnTmFtZSwgYXR0cmlidXRlcykge1xuICAgIGlmICh0YWdOYW1lID09PSAnc2VsZWN0JykgcmV0dXJuIGZhbHNlO1xuICAgIGlmICgndHlwZScgaW4gYXR0cmlidXRlcykgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIEhBU19FWFRFTkRFRF9DUkVBVEVfRUxFTUVOVF9TWU5UQVggPSAoZnVuY3Rpb24oKXtcbiAgICB0cnkge1xuICAgICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnPGlucHV0IG5hbWU9XCJ4XCI+Jyk7XG4gICAgICByZXR1cm4gZWwudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09PSAnaW5wdXQnICYmIGVsLm5hbWUgPT09ICd4JztcbiAgICB9XG4gICAgY2F0Y2goZXJyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KSgpO1xuXG5cbiAgdmFyIG9sZEVsZW1lbnQgPSBHTE9CQUwuRWxlbWVudDtcbiAgZnVuY3Rpb24gRWxlbWVudCh0YWdOYW1lLCBhdHRyaWJ1dGVzKSB7XG4gICAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMgfHwge307XG4gICAgdGFnTmFtZSA9IHRhZ05hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChIQVNfRVhURU5ERURfQ1JFQVRFX0VMRU1FTlRfU1lOVEFYICYmIGF0dHJpYnV0ZXMubmFtZSkge1xuICAgICAgdGFnTmFtZSA9ICc8JyArIHRhZ05hbWUgKyAnIG5hbWU9XCInICsgYXR0cmlidXRlcy5uYW1lICsgJ1wiPic7XG4gICAgICBkZWxldGUgYXR0cmlidXRlcy5uYW1lO1xuICAgICAgcmV0dXJuIEVsZW1lbnQud3JpdGVBdHRyaWJ1dGUoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKSwgYXR0cmlidXRlcyk7XG4gICAgfVxuXG4gICAgaWYgKCFFTEVNRU5UX0NBQ0hFW3RhZ05hbWVdKVxuICAgICAgRUxFTUVOVF9DQUNIRVt0YWdOYW1lXSA9IEVsZW1lbnQuZXh0ZW5kKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSkpO1xuXG4gICAgdmFyIG5vZGUgPSBzaG91bGRVc2VDcmVhdGlvbkNhY2hlKHRhZ05hbWUsIGF0dHJpYnV0ZXMpID9cbiAgICAgRUxFTUVOVF9DQUNIRVt0YWdOYW1lXS5jbG9uZU5vZGUoZmFsc2UpIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcblxuICAgIHJldHVybiBFbGVtZW50LndyaXRlQXR0cmlidXRlKG5vZGUsIGF0dHJpYnV0ZXMpO1xuICB9XG5cbiAgR0xPQkFMLkVsZW1lbnQgPSBFbGVtZW50O1xuXG4gIE9iamVjdC5leHRlbmQoR0xPQkFMLkVsZW1lbnQsIG9sZEVsZW1lbnQgfHwge30pO1xuICBpZiAob2xkRWxlbWVudCkgR0xPQkFMLkVsZW1lbnQucHJvdG90eXBlID0gb2xkRWxlbWVudC5wcm90b3R5cGU7XG5cbiAgRWxlbWVudC5NZXRob2RzID0geyBCeVRhZzoge30sIFNpbXVsYXRlZDoge30gfTtcblxuICB2YXIgbWV0aG9kcyA9IHt9O1xuXG4gIHZhciBJTlNQRUNUX0FUVFJJQlVURVMgPSB7IGlkOiAnaWQnLCBjbGFzc05hbWU6ICdjbGFzcycgfTtcbiAgZnVuY3Rpb24gaW5zcGVjdChlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIHJlc3VsdCA9ICc8JyArIGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuXG4gICAgdmFyIGF0dHJpYnV0ZSwgdmFsdWU7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gSU5TUEVDVF9BVFRSSUJVVEVTKSB7XG4gICAgICBhdHRyaWJ1dGUgPSBJTlNQRUNUX0FUVFJJQlVURVNbcHJvcGVydHldO1xuICAgICAgdmFsdWUgPSAoZWxlbWVudFtwcm9wZXJ0eV0gfHwgJycpLnRvU3RyaW5nKCk7XG4gICAgICBpZiAodmFsdWUpIHJlc3VsdCArPSAnICcgKyBhdHRyaWJ1dGUgKyAnPScgKyB2YWx1ZS5pbnNwZWN0KHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQgKyAnPic7XG4gIH1cblxuICBtZXRob2RzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbiAgZnVuY3Rpb24gdmlzaWJsZShlbGVtZW50KSB7XG4gICAgcmV0dXJuICQoZWxlbWVudCkuc3R5bGUuZGlzcGxheSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlKGVsZW1lbnQsIGJvb2wpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKGJvb2wpKVxuICAgICAgYm9vbCA9ICFFbGVtZW50LnZpc2libGUoZWxlbWVudCk7XG4gICAgRWxlbWVudFtib29sID8gJ3Nob3cnIDogJ2hpZGUnXShlbGVtZW50KTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gaGlkZShlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvdyhlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuXG4gIE9iamVjdC5leHRlbmQobWV0aG9kcywge1xuICAgIHZpc2libGU6IHZpc2libGUsXG4gICAgdG9nZ2xlOiAgdG9nZ2xlLFxuICAgIGhpZGU6ICAgIGhpZGUsXG4gICAgc2hvdzogICAgc2hvd1xuICB9KTtcblxuXG4gIGZ1bmN0aW9uIHJlbW92ZShlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGVsZW1lbnQpO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgdmFyIFNFTEVDVF9FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSA9IChmdW5jdGlvbigpe1xuICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzZWxlY3RcIiksXG4gICAgICAgIGlzQnVnZ3kgPSB0cnVlO1xuICAgIGVsLmlubmVySFRNTCA9IFwiPG9wdGlvbiB2YWx1ZT1cXFwidGVzdFxcXCI+dGVzdDwvb3B0aW9uPlwiO1xuICAgIGlmIChlbC5vcHRpb25zICYmIGVsLm9wdGlvbnNbMF0pIHtcbiAgICAgIGlzQnVnZ3kgPSBlbC5vcHRpb25zWzBdLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgIT09IFwiT1BUSU9OXCI7XG4gICAgfVxuICAgIGVsID0gbnVsbDtcbiAgICByZXR1cm4gaXNCdWdneTtcbiAgfSkoKTtcblxuICB2YXIgVEFCTEVfRUxFTUVOVF9JTk5FUkhUTUxfQlVHR1kgPSAoZnVuY3Rpb24oKXtcbiAgICB0cnkge1xuICAgICAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRhYmxlXCIpO1xuICAgICAgaWYgKGVsICYmIGVsLnRCb2RpZXMpIHtcbiAgICAgICAgZWwuaW5uZXJIVE1MID0gXCI8dGJvZHk+PHRyPjx0ZD50ZXN0PC90ZD48L3RyPjwvdGJvZHk+XCI7XG4gICAgICAgIHZhciBpc0J1Z2d5ID0gdHlwZW9mIGVsLnRCb2RpZXNbMF0gPT0gXCJ1bmRlZmluZWRcIjtcbiAgICAgICAgZWwgPSBudWxsO1xuICAgICAgICByZXR1cm4gaXNCdWdneTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pKCk7XG5cbiAgdmFyIExJTktfRUxFTUVOVF9JTk5FUkhUTUxfQlVHR1kgPSAoZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHtcbiAgICAgIHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgZWwuaW5uZXJIVE1MID0gXCI8bGluayAvPlwiO1xuICAgICAgdmFyIGlzQnVnZ3kgPSAoZWwuY2hpbGROb2Rlcy5sZW5ndGggPT09IDApO1xuICAgICAgZWwgPSBudWxsO1xuICAgICAgcmV0dXJuIGlzQnVnZ3k7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pKCk7XG5cbiAgdmFyIEFOWV9JTk5FUkhUTUxfQlVHR1kgPSBTRUxFQ1RfRUxFTUVOVF9JTk5FUkhUTUxfQlVHR1kgfHxcbiAgIFRBQkxFX0VMRU1FTlRfSU5ORVJIVE1MX0JVR0dZIHx8IExJTktfRUxFTUVOVF9JTk5FUkhUTUxfQlVHR1k7XG5cbiAgdmFyIFNDUklQVF9FTEVNRU5UX1JFSkVDVFNfVEVYVE5PREVfQVBQRU5ESU5HID0gKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzY3JpcHRcIiksXG4gICAgICAgIGlzQnVnZ3kgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgcy5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlwiKSk7XG4gICAgICBpc0J1Z2d5ID0gIXMuZmlyc3RDaGlsZCB8fFxuICAgICAgICBzLmZpcnN0Q2hpbGQgJiYgcy5maXJzdENoaWxkLm5vZGVUeXBlICE9PSAzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlzQnVnZ3kgPSB0cnVlO1xuICAgIH1cbiAgICBzID0gbnVsbDtcbiAgICByZXR1cm4gaXNCdWdneTtcbiAgfSkoKTtcblxuICBmdW5jdGlvbiB1cGRhdGUoZWxlbWVudCwgY29udGVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuXG4gICAgdmFyIGRlc2NlbmRhbnRzID0gZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnKicpLFxuICAgICBpID0gZGVzY2VuZGFudHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHB1cmdlRWxlbWVudChkZXNjZW5kYW50c1tpXSk7XG5cbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LnRvRWxlbWVudClcbiAgICAgIGNvbnRlbnQgPSBjb250ZW50LnRvRWxlbWVudCgpO1xuXG4gICAgaWYgKE9iamVjdC5pc0VsZW1lbnQoY29udGVudCkpXG4gICAgICByZXR1cm4gZWxlbWVudC51cGRhdGUoKS5pbnNlcnQoY29udGVudCk7XG5cblxuICAgIGNvbnRlbnQgPSBPYmplY3QudG9IVE1MKGNvbnRlbnQpO1xuICAgIHZhciB0YWdOYW1lID0gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG5cbiAgICBpZiAodGFnTmFtZSA9PT0gJ1NDUklQVCcgJiYgU0NSSVBUX0VMRU1FTlRfUkVKRUNUU19URVhUTk9ERV9BUFBFTkRJTkcpIHtcbiAgICAgIGVsZW1lbnQudGV4dCA9IGNvbnRlbnQ7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBpZiAoQU5ZX0lOTkVSSFRNTF9CVUdHWSkge1xuICAgICAgaWYgKHRhZ05hbWUgaW4gSU5TRVJUSU9OX1RSQU5TTEFUSU9OUy50YWdzKSB7XG4gICAgICAgIHdoaWxlIChlbGVtZW50LmZpcnN0Q2hpbGQpXG4gICAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChlbGVtZW50LmZpcnN0Q2hpbGQpO1xuXG4gICAgICAgIHZhciBub2RlcyA9IGdldENvbnRlbnRGcm9tQW5vbnltb3VzRWxlbWVudCh0YWdOYW1lLCBjb250ZW50LnN0cmlwU2NyaXB0cygpKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIG5vZGU7IG5vZGUgPSBub2Rlc1tpXTsgaSsrKVxuICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQobm9kZSk7XG5cbiAgICAgIH0gZWxzZSBpZiAoTElOS19FTEVNRU5UX0lOTkVSSFRNTF9CVUdHWSAmJiBPYmplY3QuaXNTdHJpbmcoY29udGVudCkgJiYgY29udGVudC5pbmRleE9mKCc8bGluaycpID4gLTEpIHtcbiAgICAgICAgd2hpbGUgKGVsZW1lbnQuZmlyc3RDaGlsZClcbiAgICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGVsZW1lbnQuZmlyc3RDaGlsZCk7XG5cbiAgICAgICAgdmFyIG5vZGVzID0gZ2V0Q29udGVudEZyb21Bbm9ueW1vdXNFbGVtZW50KHRhZ05hbWUsXG4gICAgICAgICBjb250ZW50LnN0cmlwU2NyaXB0cygpLCB0cnVlKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMCwgbm9kZTsgbm9kZSA9IG5vZGVzW2ldOyBpKyspXG4gICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChub2RlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gY29udGVudC5zdHJpcFNjcmlwdHMoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5pbm5lckhUTUwgPSBjb250ZW50LnN0cmlwU2NyaXB0cygpO1xuICAgIH1cblxuICAgIGNvbnRlbnQuZXZhbFNjcmlwdHMuYmluZChjb250ZW50KS5kZWZlcigpO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVwbGFjZShlbGVtZW50LCBjb250ZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LnRvRWxlbWVudCkge1xuICAgICAgY29udGVudCA9IGNvbnRlbnQudG9FbGVtZW50KCk7XG4gICAgfSBlbHNlIGlmICghT2JqZWN0LmlzRWxlbWVudChjb250ZW50KSkge1xuICAgICAgY29udGVudCA9IE9iamVjdC50b0hUTUwoY29udGVudCk7XG4gICAgICB2YXIgcmFuZ2UgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgIHJhbmdlLnNlbGVjdE5vZGUoZWxlbWVudCk7XG4gICAgICBjb250ZW50LmV2YWxTY3JpcHRzLmJpbmQoY29udGVudCkuZGVmZXIoKTtcbiAgICAgIGNvbnRlbnQgPSByYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQoY29udGVudC5zdHJpcFNjcmlwdHMoKSk7XG4gICAgfVxuXG4gICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChjb250ZW50LCBlbGVtZW50KTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIHZhciBJTlNFUlRJT05fVFJBTlNMQVRJT05TID0ge1xuICAgIGJlZm9yZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xuICAgICAgZWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCBlbGVtZW50KTtcbiAgICB9LFxuICAgIHRvcDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xuICAgICAgZWxlbWVudC5pbnNlcnRCZWZvcmUobm9kZSwgZWxlbWVudC5maXJzdENoaWxkKTtcbiAgICB9LFxuICAgIGJvdHRvbTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xuICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChub2RlKTtcbiAgICB9LFxuICAgIGFmdGVyOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XG4gICAgICBlbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIGVsZW1lbnQubmV4dFNpYmxpbmcpO1xuICAgIH0sXG5cbiAgICB0YWdzOiB7XG4gICAgICBUQUJMRTogIFsnPHRhYmxlPicsICAgICAgICAgICAgICAgICc8L3RhYmxlPicsICAgICAgICAgICAgICAgICAgIDFdLFxuICAgICAgVEJPRFk6ICBbJzx0YWJsZT48dGJvZHk+JywgICAgICAgICAnPC90Ym9keT48L3RhYmxlPicsICAgICAgICAgICAyXSxcbiAgICAgIFRSOiAgICAgWyc8dGFibGU+PHRib2R5Pjx0cj4nLCAgICAgJzwvdHI+PC90Ym9keT48L3RhYmxlPicsICAgICAgM10sXG4gICAgICBURDogICAgIFsnPHRhYmxlPjx0Ym9keT48dHI+PHRkPicsICc8L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPicsIDRdLFxuICAgICAgU0VMRUNUOiBbJzxzZWxlY3Q+JywgICAgICAgICAgICAgICAnPC9zZWxlY3Q+JywgICAgICAgICAgICAgICAgICAxXVxuICAgIH1cbiAgfTtcblxuICB2YXIgdGFncyA9IElOU0VSVElPTl9UUkFOU0xBVElPTlMudGFncztcblxuICBPYmplY3QuZXh0ZW5kKHRhZ3MsIHtcbiAgICBUSEVBRDogdGFncy5UQk9EWSxcbiAgICBURk9PVDogdGFncy5UQk9EWSxcbiAgICBUSDogICAgdGFncy5URFxuICB9KTtcblxuICBmdW5jdGlvbiByZXBsYWNlX0lFKGVsZW1lbnQsIGNvbnRlbnQpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICBpZiAoY29udGVudCAmJiBjb250ZW50LnRvRWxlbWVudClcbiAgICAgIGNvbnRlbnQgPSBjb250ZW50LnRvRWxlbWVudCgpO1xuICAgIGlmIChPYmplY3QuaXNFbGVtZW50KGNvbnRlbnQpKSB7XG4gICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKGNvbnRlbnQsIGVsZW1lbnQpO1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29udGVudCA9IE9iamVjdC50b0hUTUwoY29udGVudCk7XG4gICAgdmFyIHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSwgdGFnTmFtZSA9IHBhcmVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG5cbiAgICBpZiAodGFnTmFtZSBpbiBJTlNFUlRJT05fVFJBTlNMQVRJT05TLnRhZ3MpIHtcbiAgICAgIHZhciBuZXh0U2libGluZyA9IEVsZW1lbnQubmV4dChlbGVtZW50KTtcbiAgICAgIHZhciBmcmFnbWVudHMgPSBnZXRDb250ZW50RnJvbUFub255bW91c0VsZW1lbnQoXG4gICAgICAgdGFnTmFtZSwgY29udGVudC5zdHJpcFNjcmlwdHMoKSk7XG5cbiAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbGVtZW50KTtcblxuICAgICAgdmFyIGl0ZXJhdG9yO1xuICAgICAgaWYgKG5leHRTaWJsaW5nKVxuICAgICAgICBpdGVyYXRvciA9IGZ1bmN0aW9uKG5vZGUpIHsgcGFyZW50Lmluc2VydEJlZm9yZShub2RlLCBuZXh0U2libGluZykgfTtcbiAgICAgIGVsc2VcbiAgICAgICAgaXRlcmF0b3IgPSBmdW5jdGlvbihub2RlKSB7IHBhcmVudC5hcHBlbmRDaGlsZChub2RlKTsgfVxuXG4gICAgICBmcmFnbWVudHMuZWFjaChpdGVyYXRvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQub3V0ZXJIVE1MID0gY29udGVudC5zdHJpcFNjcmlwdHMoKTtcbiAgICB9XG5cbiAgICBjb250ZW50LmV2YWxTY3JpcHRzLmJpbmQoY29udGVudCkuZGVmZXIoKTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGlmICgnb3V0ZXJIVE1MJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpXG4gICAgcmVwbGFjZSA9IHJlcGxhY2VfSUU7XG5cbiAgZnVuY3Rpb24gaXNDb250ZW50KGNvbnRlbnQpIHtcbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKGNvbnRlbnQpIHx8IGNvbnRlbnQgPT09IG51bGwpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChPYmplY3QuaXNTdHJpbmcoY29udGVudCkgfHwgT2JqZWN0LmlzTnVtYmVyKGNvbnRlbnQpKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoT2JqZWN0LmlzRWxlbWVudChjb250ZW50KSkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGNvbnRlbnQudG9FbGVtZW50IHx8IGNvbnRlbnQudG9IVE1MKSByZXR1cm4gdHJ1ZTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc2VydENvbnRlbnRBdChlbGVtZW50LCBjb250ZW50LCBwb3NpdGlvbikge1xuICAgIHBvc2l0aW9uICAgPSBwb3NpdGlvbi50b0xvd2VyQ2FzZSgpO1xuICAgIHZhciBtZXRob2QgPSBJTlNFUlRJT05fVFJBTlNMQVRJT05TW3Bvc2l0aW9uXTtcblxuICAgIGlmIChjb250ZW50ICYmIGNvbnRlbnQudG9FbGVtZW50KSBjb250ZW50ID0gY29udGVudC50b0VsZW1lbnQoKTtcbiAgICBpZiAoT2JqZWN0LmlzRWxlbWVudChjb250ZW50KSkge1xuICAgICAgbWV0aG9kKGVsZW1lbnQsIGNvbnRlbnQpO1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgY29udGVudCA9IE9iamVjdC50b0hUTUwoY29udGVudCk7XG4gICAgdmFyIHRhZ05hbWUgPSAoKHBvc2l0aW9uID09PSAnYmVmb3JlJyB8fCBwb3NpdGlvbiA9PT0gJ2FmdGVyJykgP1xuICAgICBlbGVtZW50LnBhcmVudE5vZGUgOiBlbGVtZW50KS50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG5cbiAgICB2YXIgY2hpbGROb2RlcyA9IGdldENvbnRlbnRGcm9tQW5vbnltb3VzRWxlbWVudCh0YWdOYW1lLCBjb250ZW50LnN0cmlwU2NyaXB0cygpKTtcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcgfHwgcG9zaXRpb24gPT09ICdhZnRlcicpIGNoaWxkTm9kZXMucmV2ZXJzZSgpO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG5vZGU7IG5vZGUgPSBjaGlsZE5vZGVzW2ldOyBpKyspXG4gICAgICBtZXRob2QoZWxlbWVudCwgbm9kZSk7XG5cbiAgICBjb250ZW50LmV2YWxTY3JpcHRzLmJpbmQoY29udGVudCkuZGVmZXIoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc2VydChlbGVtZW50LCBpbnNlcnRpb25zKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICBpZiAoaXNDb250ZW50KGluc2VydGlvbnMpKVxuICAgICAgaW5zZXJ0aW9ucyA9IHsgYm90dG9tOiBpbnNlcnRpb25zIH07XG5cbiAgICBmb3IgKHZhciBwb3NpdGlvbiBpbiBpbnNlcnRpb25zKVxuICAgICAgaW5zZXJ0Q29udGVudEF0KGVsZW1lbnQsIGluc2VydGlvbnNbcG9zaXRpb25dLCBwb3NpdGlvbik7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXAoZWxlbWVudCwgd3JhcHBlciwgYXR0cmlidXRlcykge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuXG4gICAgaWYgKE9iamVjdC5pc0VsZW1lbnQod3JhcHBlcikpIHtcbiAgICAgICQod3JhcHBlcikud3JpdGVBdHRyaWJ1dGUoYXR0cmlidXRlcyB8fCB7fSk7XG4gICAgfSBlbHNlIGlmIChPYmplY3QuaXNTdHJpbmcod3JhcHBlcikpIHtcbiAgICAgIHdyYXBwZXIgPSBuZXcgRWxlbWVudCh3cmFwcGVyLCBhdHRyaWJ1dGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd3JhcHBlciA9IG5ldyBFbGVtZW50KCdkaXYnLCB3cmFwcGVyKTtcbiAgICB9XG5cbiAgICBpZiAoZWxlbWVudC5wYXJlbnROb2RlKVxuICAgICAgZWxlbWVudC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZCh3cmFwcGVyLCBlbGVtZW50KTtcblxuICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cbiAgICByZXR1cm4gd3JhcHBlcjtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFuV2hpdGVzcGFjZShlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIG5vZGUgPSBlbGVtZW50LmZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAobm9kZSkge1xuICAgICAgdmFyIG5leHROb2RlID0gbm9kZS5uZXh0U2libGluZztcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSAmJiAhL1xcUy8udGVzdChub2RlLm5vZGVWYWx1ZSkpXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICBub2RlID0gbmV4dE5vZGU7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gZW1wdHkoZWxlbWVudCkge1xuICAgIHJldHVybiAkKGVsZW1lbnQpLmlubmVySFRNTC5ibGFuaygpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0Q29udGVudEZyb21Bbm9ueW1vdXNFbGVtZW50KHRhZ05hbWUsIGh0bWwsIGZvcmNlKSB7XG4gICAgdmFyIHQgPSBJTlNFUlRJT05fVFJBTlNMQVRJT05TLnRhZ3NbdGFnTmFtZV0sIGRpdiA9IERJVjtcblxuICAgIHZhciB3b3JrYXJvdW5kID0gISF0O1xuICAgIGlmICghd29ya2Fyb3VuZCAmJiBmb3JjZSkge1xuICAgICAgd29ya2Fyb3VuZCA9IHRydWU7XG4gICAgICB0ID0gWycnLCAnJywgMF07XG4gICAgfVxuXG4gICAgaWYgKHdvcmthcm91bmQpIHtcbiAgICAgIGRpdi5pbm5lckhUTUwgPSAnJiMxNjA7JyArIHRbMF0gKyBodG1sICsgdFsxXTtcbiAgICAgIGRpdi5yZW1vdmVDaGlsZChkaXYuZmlyc3RDaGlsZCk7XG4gICAgICBmb3IgKHZhciBpID0gdFsyXTsgaS0tOyApXG4gICAgICAgIGRpdiA9IGRpdi5maXJzdENoaWxkO1xuICAgIH0gZWxzZSB7XG4gICAgICBkaXYuaW5uZXJIVE1MID0gaHRtbDtcbiAgICB9XG5cbiAgICByZXR1cm4gJEEoZGl2LmNoaWxkTm9kZXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xvbmUoZWxlbWVudCwgZGVlcCkge1xuICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuO1xuICAgIHZhciBjbG9uZSA9IGVsZW1lbnQuY2xvbmVOb2RlKGRlZXApO1xuICAgIGlmICghSEFTX1VOSVFVRV9JRF9QUk9QRVJUWSkge1xuICAgICAgY2xvbmUuX3Byb3RvdHlwZVVJRCA9IFVOREVGSU5FRDtcbiAgICAgIGlmIChkZWVwKSB7XG4gICAgICAgIHZhciBkZXNjZW5kYW50cyA9IEVsZW1lbnQuc2VsZWN0KGNsb25lLCAnKicpLFxuICAgICAgICAgaSA9IGRlc2NlbmRhbnRzLmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGktLSlcbiAgICAgICAgICBkZXNjZW5kYW50c1tpXS5fcHJvdG90eXBlVUlEID0gVU5ERUZJTkVEO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoY2xvbmUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHVyZ2VFbGVtZW50KGVsZW1lbnQpIHtcbiAgICB2YXIgdWlkID0gZ2V0VW5pcXVlRWxlbWVudElEKGVsZW1lbnQpO1xuICAgIGlmICh1aWQpIHtcbiAgICAgIEVsZW1lbnQuc3RvcE9ic2VydmluZyhlbGVtZW50KTtcbiAgICAgIGlmICghSEFTX1VOSVFVRV9JRF9QUk9QRVJUWSlcbiAgICAgICAgZWxlbWVudC5fcHJvdG90eXBlVUlEID0gVU5ERUZJTkVEO1xuICAgICAgZGVsZXRlIEVsZW1lbnQuU3RvcmFnZVt1aWRdO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHB1cmdlQ29sbGVjdGlvbihlbGVtZW50cykge1xuICAgIHZhciBpID0gZWxlbWVudHMubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pXG4gICAgICBwdXJnZUVsZW1lbnQoZWxlbWVudHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gcHVyZ2VDb2xsZWN0aW9uX0lFKGVsZW1lbnRzKSB7XG4gICAgdmFyIGkgPSBlbGVtZW50cy5sZW5ndGgsIGVsZW1lbnQsIHVpZDtcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBlbGVtZW50ID0gZWxlbWVudHNbaV07XG4gICAgICB1aWQgPSBnZXRVbmlxdWVFbGVtZW50SUQoZWxlbWVudCk7XG4gICAgICBkZWxldGUgRWxlbWVudC5TdG9yYWdlW3VpZF07XG4gICAgICBkZWxldGUgRXZlbnQuY2FjaGVbdWlkXTtcbiAgICB9XG4gIH1cblxuICBpZiAoSEFTX1VOSVFVRV9JRF9QUk9QRVJUWSkge1xuICAgIHB1cmdlQ29sbGVjdGlvbiA9IHB1cmdlQ29sbGVjdGlvbl9JRTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gcHVyZ2UoZWxlbWVudCkge1xuICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuO1xuICAgIHB1cmdlRWxlbWVudChlbGVtZW50KTtcblxuICAgIHZhciBkZXNjZW5kYW50cyA9IGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKSxcbiAgICAgaSA9IGRlc2NlbmRhbnRzLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0pIHB1cmdlRWxlbWVudChkZXNjZW5kYW50c1tpXSk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIE9iamVjdC5leHRlbmQobWV0aG9kcywge1xuICAgIHJlbW92ZTogIHJlbW92ZSxcbiAgICB1cGRhdGU6ICB1cGRhdGUsXG4gICAgcmVwbGFjZTogcmVwbGFjZSxcbiAgICBpbnNlcnQ6ICBpbnNlcnQsXG4gICAgd3JhcDogICAgd3JhcCxcbiAgICBjbGVhbldoaXRlc3BhY2U6IGNsZWFuV2hpdGVzcGFjZSxcbiAgICBlbXB0eTogICBlbXB0eSxcbiAgICBjbG9uZTogICBjbG9uZSxcbiAgICBwdXJnZTogICBwdXJnZVxuICB9KTtcblxuXG5cbiAgZnVuY3Rpb24gcmVjdXJzaXZlbHlDb2xsZWN0KGVsZW1lbnQsIHByb3BlcnR5LCBtYXhpbXVtTGVuZ3RoKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgbWF4aW11bUxlbmd0aCA9IG1heGltdW1MZW5ndGggfHwgLTE7XG4gICAgdmFyIGVsZW1lbnRzID0gW107XG5cbiAgICB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnRbcHJvcGVydHldKSB7XG4gICAgICBpZiAoZWxlbWVudC5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREUpXG4gICAgICAgIGVsZW1lbnRzLnB1c2goRWxlbWVudC5leHRlbmQoZWxlbWVudCkpO1xuXG4gICAgICBpZiAoZWxlbWVudHMubGVuZ3RoID09PSBtYXhpbXVtTGVuZ3RoKSBicmVhaztcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudHM7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGFuY2VzdG9ycyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIHJlY3Vyc2l2ZWx5Q29sbGVjdChlbGVtZW50LCAncGFyZW50Tm9kZScpO1xuICB9XG5cbiAgZnVuY3Rpb24gZGVzY2VuZGFudHMoZWxlbWVudCkge1xuICAgIHJldHVybiBFbGVtZW50LnNlbGVjdChlbGVtZW50LCAnKicpO1xuICB9XG5cbiAgZnVuY3Rpb24gZmlyc3REZXNjZW5kYW50KGVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KS5maXJzdENoaWxkO1xuICAgIHdoaWxlIChlbGVtZW50ICYmIGVsZW1lbnQubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKVxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG5cbiAgICByZXR1cm4gJChlbGVtZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGltbWVkaWF0ZURlc2NlbmRhbnRzKGVsZW1lbnQpIHtcbiAgICB2YXIgcmVzdWx0cyA9IFtdLCBjaGlsZCA9ICQoZWxlbWVudCkuZmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChjaGlsZCkge1xuICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09PSBOb2RlLkVMRU1FTlRfTk9ERSlcbiAgICAgICAgcmVzdWx0cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGNoaWxkKSk7XG5cbiAgICAgIGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmc7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBmdW5jdGlvbiBwcmV2aW91c1NpYmxpbmdzKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gcmVjdXJzaXZlbHlDb2xsZWN0KGVsZW1lbnQsICdwcmV2aW91c1NpYmxpbmcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG5leHRTaWJsaW5ncyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIHJlY3Vyc2l2ZWx5Q29sbGVjdChlbGVtZW50LCAnbmV4dFNpYmxpbmcnKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpYmxpbmdzKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICB2YXIgcHJldmlvdXMgPSBwcmV2aW91c1NpYmxpbmdzKGVsZW1lbnQpLFxuICAgICBuZXh0ID0gbmV4dFNpYmxpbmdzKGVsZW1lbnQpO1xuICAgIHJldHVybiBwcmV2aW91cy5yZXZlcnNlKCkuY29uY2F0KG5leHQpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWF0Y2goZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcblxuICAgIGlmIChPYmplY3QuaXNTdHJpbmcoc2VsZWN0b3IpKVxuICAgICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaChlbGVtZW50LCBzZWxlY3Rvcik7XG5cbiAgICByZXR1cm4gc2VsZWN0b3IubWF0Y2goZWxlbWVudCk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIF9yZWN1cnNpdmVseUZpbmQoZWxlbWVudCwgcHJvcGVydHksIGV4cHJlc3Npb24sIGluZGV4KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCksIGV4cHJlc3Npb24gPSBleHByZXNzaW9uIHx8IDAsIGluZGV4ID0gaW5kZXggfHwgMDtcbiAgICBpZiAoT2JqZWN0LmlzTnVtYmVyKGV4cHJlc3Npb24pKSB7XG4gICAgICBpbmRleCA9IGV4cHJlc3Npb24sIGV4cHJlc3Npb24gPSBudWxsO1xuICAgIH1cblxuICAgIHdoaWxlIChlbGVtZW50ID0gZWxlbWVudFtwcm9wZXJ0eV0pIHtcbiAgICAgIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAxKSBjb250aW51ZTtcbiAgICAgIGlmIChleHByZXNzaW9uICYmICFQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2goZWxlbWVudCwgZXhwcmVzc2lvbikpXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgaWYgKC0taW5kZXggPj0gMCkgY29udGludWU7XG5cbiAgICAgIHJldHVybiBFbGVtZW50LmV4dGVuZChlbGVtZW50KTtcbiAgICB9XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHVwKGVsZW1lbnQsIGV4cHJlc3Npb24sIGluZGV4KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuICQoZWxlbWVudC5wYXJlbnROb2RlKTtcbiAgICByZXR1cm4gX3JlY3Vyc2l2ZWx5RmluZChlbGVtZW50LCAncGFyZW50Tm9kZScsIGV4cHJlc3Npb24sIGluZGV4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRvd24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIGZpcnN0RGVzY2VuZGFudChlbGVtZW50KTtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KSwgZXhwcmVzc2lvbiA9IGV4cHJlc3Npb24gfHwgMCwgaW5kZXggPSBpbmRleCB8fCAwO1xuXG4gICAgaWYgKE9iamVjdC5pc051bWJlcihleHByZXNzaW9uKSlcbiAgICAgIGluZGV4ID0gZXhwcmVzc2lvbiwgZXhwcmVzc2lvbiA9ICcqJztcblxuICAgIHZhciBub2RlID0gUHJvdG90eXBlLlNlbGVjdG9yLnNlbGVjdChleHByZXNzaW9uLCBlbGVtZW50KVtpbmRleF07XG4gICAgcmV0dXJuIEVsZW1lbnQuZXh0ZW5kKG5vZGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJldmlvdXMoZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHtcbiAgICByZXR1cm4gX3JlY3Vyc2l2ZWx5RmluZChlbGVtZW50LCAncHJldmlvdXNTaWJsaW5nJywgZXhwcmVzc2lvbiwgaW5kZXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gbmV4dChlbGVtZW50LCBleHByZXNzaW9uLCBpbmRleCkge1xuICAgIHJldHVybiBfcmVjdXJzaXZlbHlGaW5kKGVsZW1lbnQsICduZXh0U2libGluZycsIGV4cHJlc3Npb24sIGluZGV4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdChlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIGV4cHJlc3Npb25zID0gU0xJQ0UuY2FsbChhcmd1bWVudHMsIDEpLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QoZXhwcmVzc2lvbnMsIGVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRqYWNlbnQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBleHByZXNzaW9ucyA9IFNMSUNFLmNhbGwoYXJndW1lbnRzLCAxKS5qb2luKCcsICcpO1xuICAgIHZhciBzaWJsaW5ncyA9IEVsZW1lbnQuc2libGluZ3MoZWxlbWVudCksIHJlc3VsdHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMCwgc2libGluZzsgc2libGluZyA9IHNpYmxpbmdzW2ldOyBpKyspIHtcbiAgICAgIGlmIChQcm90b3R5cGUuU2VsZWN0b3IubWF0Y2goc2libGluZywgZXhwcmVzc2lvbnMpKVxuICAgICAgICByZXN1bHRzLnB1c2goc2libGluZyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICBmdW5jdGlvbiBkZXNjZW5kYW50T2ZfRE9NKGVsZW1lbnQsIGFuY2VzdG9yKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCksIGFuY2VzdG9yID0gJChhbmNlc3Rvcik7XG4gICAgd2hpbGUgKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGUpXG4gICAgICBpZiAoZWxlbWVudCA9PT0gYW5jZXN0b3IpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc2NlbmRhbnRPZl9jb250YWlucyhlbGVtZW50LCBhbmNlc3Rvcikge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpLCBhbmNlc3RvciA9ICQoYW5jZXN0b3IpO1xuICAgIGlmICghYW5jZXN0b3IuY29udGFpbnMpIHJldHVybiBkZXNjZW5kYW50T2ZfRE9NKGVsZW1lbnQsIGFuY2VzdG9yKTtcbiAgICByZXR1cm4gYW5jZXN0b3IuY29udGFpbnMoZWxlbWVudCkgJiYgYW5jZXN0b3IgIT09IGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBkZXNjZW5kYW50T2ZfY29tcGFyZURvY3VtZW50UG9zaXRpb24oZWxlbWVudCwgYW5jZXN0b3IpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KSwgYW5jZXN0b3IgPSAkKGFuY2VzdG9yKTtcbiAgICByZXR1cm4gKGVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYW5jZXN0b3IpICYgOCkgPT09IDg7XG4gIH1cblxuICB2YXIgZGVzY2VuZGFudE9mO1xuICBpZiAoRElWLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKSB7XG4gICAgZGVzY2VuZGFudE9mID0gZGVzY2VuZGFudE9mX2NvbXBhcmVEb2N1bWVudFBvc2l0aW9uO1xuICB9IGVsc2UgaWYgKERJVi5jb250YWlucykge1xuICAgIGRlc2NlbmRhbnRPZiA9IGRlc2NlbmRhbnRPZl9jb250YWlucztcbiAgfSBlbHNlIHtcbiAgICBkZXNjZW5kYW50T2YgPSBkZXNjZW5kYW50T2ZfRE9NO1xuICB9XG5cblxuICBPYmplY3QuZXh0ZW5kKG1ldGhvZHMsIHtcbiAgICByZWN1cnNpdmVseUNvbGxlY3Q6ICAgcmVjdXJzaXZlbHlDb2xsZWN0LFxuICAgIGFuY2VzdG9yczogICAgICAgICAgICBhbmNlc3RvcnMsXG4gICAgZGVzY2VuZGFudHM6ICAgICAgICAgIGRlc2NlbmRhbnRzLFxuICAgIGZpcnN0RGVzY2VuZGFudDogICAgICBmaXJzdERlc2NlbmRhbnQsXG4gICAgaW1tZWRpYXRlRGVzY2VuZGFudHM6IGltbWVkaWF0ZURlc2NlbmRhbnRzLFxuICAgIHByZXZpb3VzU2libGluZ3M6ICAgICBwcmV2aW91c1NpYmxpbmdzLFxuICAgIG5leHRTaWJsaW5nczogICAgICAgICBuZXh0U2libGluZ3MsXG4gICAgc2libGluZ3M6ICAgICAgICAgICAgIHNpYmxpbmdzLFxuICAgIG1hdGNoOiAgICAgICAgICAgICAgICBtYXRjaCxcbiAgICB1cDogICAgICAgICAgICAgICAgICAgdXAsXG4gICAgZG93bjogICAgICAgICAgICAgICAgIGRvd24sXG4gICAgcHJldmlvdXM6ICAgICAgICAgICAgIHByZXZpb3VzLFxuICAgIG5leHQ6ICAgICAgICAgICAgICAgICBuZXh0LFxuICAgIHNlbGVjdDogICAgICAgICAgICAgICBzZWxlY3QsXG4gICAgYWRqYWNlbnQ6ICAgICAgICAgICAgIGFkamFjZW50LFxuICAgIGRlc2NlbmRhbnRPZjogICAgICAgICBkZXNjZW5kYW50T2YsXG5cbiAgICBnZXRFbGVtZW50c0J5U2VsZWN0b3I6IHNlbGVjdCxcblxuICAgIGNoaWxkRWxlbWVudHM6ICAgICAgICAgaW1tZWRpYXRlRGVzY2VuZGFudHNcbiAgfSk7XG5cblxuICB2YXIgaWRDb3VudGVyID0gMTtcbiAgZnVuY3Rpb24gaWRlbnRpZnkoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBpZCA9IEVsZW1lbnQucmVhZEF0dHJpYnV0ZShlbGVtZW50LCAnaWQnKTtcbiAgICBpZiAoaWQpIHJldHVybiBpZDtcblxuICAgIGRvIHsgaWQgPSAnYW5vbnltb3VzX2VsZW1lbnRfJyArIGlkQ291bnRlcisrIH0gd2hpbGUgKCQoaWQpKTtcblxuICAgIEVsZW1lbnQud3JpdGVBdHRyaWJ1dGUoZWxlbWVudCwgJ2lkJywgaWQpO1xuICAgIHJldHVybiBpZDtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gcmVhZEF0dHJpYnV0ZShlbGVtZW50LCBuYW1lKSB7XG4gICAgcmV0dXJuICQoZWxlbWVudCkuZ2V0QXR0cmlidXRlKG5hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEF0dHJpYnV0ZV9JRShlbGVtZW50LCBuYW1lKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICB2YXIgdGFibGUgPSBBVFRSSUJVVEVfVFJBTlNMQVRJT05TLnJlYWQ7XG4gICAgaWYgKHRhYmxlLnZhbHVlc1tuYW1lXSlcbiAgICAgIHJldHVybiB0YWJsZS52YWx1ZXNbbmFtZV0oZWxlbWVudCwgbmFtZSk7XG5cbiAgICBpZiAodGFibGUubmFtZXNbbmFtZV0pIG5hbWUgPSB0YWJsZS5uYW1lc1tuYW1lXTtcblxuICAgIGlmIChuYW1lLmluY2x1ZGUoJzonKSkge1xuICAgICAgaWYgKCFlbGVtZW50LmF0dHJpYnV0ZXMgfHwgIWVsZW1lbnQuYXR0cmlidXRlc1tuYW1lXSkgcmV0dXJuIG51bGw7XG4gICAgICByZXR1cm4gZWxlbWVudC5hdHRyaWJ1dGVzW25hbWVdLnZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50LmdldEF0dHJpYnV0ZShuYW1lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRBdHRyaWJ1dGVfT3BlcmEoZWxlbWVudCwgbmFtZSkge1xuICAgIGlmIChuYW1lID09PSAndGl0bGUnKSByZXR1cm4gZWxlbWVudC50aXRsZTtcbiAgICByZXR1cm4gZWxlbWVudC5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gIH1cblxuICB2YXIgUFJPQkxFTUFUSUNfQVRUUklCVVRFX1JFQURJTkcgPSAoZnVuY3Rpb24oKSB7XG4gICAgRElWLnNldEF0dHJpYnV0ZSgnb25jbGljaycsIFtdKTtcbiAgICB2YXIgdmFsdWUgPSBESVYuZ2V0QXR0cmlidXRlKCdvbmNsaWNrJyk7XG4gICAgdmFyIGlzRnVuY3Rpb24gPSBPYmplY3QuaXNBcnJheSh2YWx1ZSk7XG4gICAgRElWLnJlbW92ZUF0dHJpYnV0ZSgnb25jbGljaycpO1xuICAgIHJldHVybiBpc0Z1bmN0aW9uO1xuICB9KSgpO1xuXG4gIGlmIChQUk9CTEVNQVRJQ19BVFRSSUJVVEVfUkVBRElORykge1xuICAgIHJlYWRBdHRyaWJ1dGUgPSByZWFkQXR0cmlidXRlX0lFO1xuICB9IGVsc2UgaWYgKFByb3RvdHlwZS5Ccm93c2VyLk9wZXJhKSB7XG4gICAgcmVhZEF0dHJpYnV0ZSA9IHJlYWRBdHRyaWJ1dGVfT3BlcmE7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHdyaXRlQXR0cmlidXRlKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSB7fSwgdGFibGUgPSBBVFRSSUJVVEVfVFJBTlNMQVRJT05TLndyaXRlO1xuXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSAnb2JqZWN0Jykge1xuICAgICAgYXR0cmlidXRlcyA9IG5hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF0dHJpYnV0ZXNbbmFtZV0gPSBPYmplY3QuaXNVbmRlZmluZWQodmFsdWUpID8gdHJ1ZSA6IHZhbHVlO1xuICAgIH1cblxuICAgIGZvciAodmFyIGF0dHIgaW4gYXR0cmlidXRlcykge1xuICAgICAgbmFtZSA9IHRhYmxlLm5hbWVzW2F0dHJdIHx8IGF0dHI7XG4gICAgICB2YWx1ZSA9IGF0dHJpYnV0ZXNbYXR0cl07XG4gICAgICBpZiAodGFibGUudmFsdWVzW2F0dHJdKVxuICAgICAgICBuYW1lID0gdGFibGUudmFsdWVzW2F0dHJdKGVsZW1lbnQsIHZhbHVlKSB8fCBuYW1lO1xuICAgICAgaWYgKHZhbHVlID09PSBmYWxzZSB8fCB2YWx1ZSA9PT0gbnVsbClcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICBlbHNlIGlmICh2YWx1ZSA9PT0gdHJ1ZSlcbiAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUobmFtZSwgbmFtZSk7XG4gICAgICBlbHNlIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIHZhciBQUk9CTEVNQVRJQ19IQVNfQVRUUklCVVRFX1dJVEhfQ0hFQ0tCT1hFUyA9IChmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFIQVNfRVhURU5ERURfQ1JFQVRFX0VMRU1FTlRfU1lOVEFYKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHZhciBjaGVja2JveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJzxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIj4nKTtcbiAgICBjaGVja2JveC5jaGVja2VkID0gdHJ1ZTtcbiAgICB2YXIgbm9kZSA9IGNoZWNrYm94LmdldEF0dHJpYnV0ZU5vZGUoJ2NoZWNrZWQnKTtcbiAgICByZXR1cm4gIW5vZGUgfHwgIW5vZGUuc3BlY2lmaWVkO1xuICB9KSgpO1xuXG4gIGZ1bmN0aW9uIGhhc0F0dHJpYnV0ZShlbGVtZW50LCBhdHRyaWJ1dGUpIHtcbiAgICBhdHRyaWJ1dGUgPSBBVFRSSUJVVEVfVFJBTlNMQVRJT05TLmhhc1thdHRyaWJ1dGVdIHx8IGF0dHJpYnV0ZTtcbiAgICB2YXIgbm9kZSA9ICQoZWxlbWVudCkuZ2V0QXR0cmlidXRlTm9kZShhdHRyaWJ1dGUpO1xuICAgIHJldHVybiAhIShub2RlICYmIG5vZGUuc3BlY2lmaWVkKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc0F0dHJpYnV0ZV9JRShlbGVtZW50LCBhdHRyaWJ1dGUpIHtcbiAgICBpZiAoYXR0cmlidXRlID09PSAnY2hlY2tlZCcpIHtcbiAgICAgIHJldHVybiBlbGVtZW50LmNoZWNrZWQ7XG4gICAgfVxuICAgIHJldHVybiBoYXNBdHRyaWJ1dGUoZWxlbWVudCwgYXR0cmlidXRlKTtcbiAgfVxuXG4gIEdMT0JBTC5FbGVtZW50Lk1ldGhvZHMuU2ltdWxhdGVkLmhhc0F0dHJpYnV0ZSA9XG4gICBQUk9CTEVNQVRJQ19IQVNfQVRUUklCVVRFX1dJVEhfQ0hFQ0tCT1hFUyA/XG4gICBoYXNBdHRyaWJ1dGVfSUUgOiBoYXNBdHRyaWJ1dGU7XG5cbiAgZnVuY3Rpb24gY2xhc3NOYW1lcyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIG5ldyBFbGVtZW50LkNsYXNzTmFtZXMoZWxlbWVudCk7XG4gIH1cblxuICB2YXIgcmVnRXhwQ2FjaGUgPSB7fTtcbiAgZnVuY3Rpb24gZ2V0UmVnRXhwRm9yQ2xhc3NOYW1lKGNsYXNzTmFtZSkge1xuICAgIGlmIChyZWdFeHBDYWNoZVtjbGFzc05hbWVdKSByZXR1cm4gcmVnRXhwQ2FjaGVbY2xhc3NOYW1lXTtcblxuICAgIHZhciByZSA9IG5ldyBSZWdFeHAoXCIoXnxcXFxccyspXCIgKyBjbGFzc05hbWUgKyBcIihcXFxccyt8JClcIik7XG4gICAgcmVnRXhwQ2FjaGVbY2xhc3NOYW1lXSA9IHJlO1xuICAgIHJldHVybiByZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc0NsYXNzTmFtZShlbGVtZW50LCBjbGFzc05hbWUpIHtcbiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjtcblxuICAgIHZhciBlbGVtZW50Q2xhc3NOYW1lID0gZWxlbWVudC5jbGFzc05hbWU7XG5cbiAgICBpZiAoZWxlbWVudENsYXNzTmFtZS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZWxlbWVudENsYXNzTmFtZSA9PT0gY2xhc3NOYW1lKSByZXR1cm4gdHJ1ZTtcblxuICAgIHJldHVybiBnZXRSZWdFeHBGb3JDbGFzc05hbWUoY2xhc3NOYW1lKS50ZXN0KGVsZW1lbnRDbGFzc05hbWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuO1xuXG4gICAgaWYgKCFoYXNDbGFzc05hbWUoZWxlbWVudCwgY2xhc3NOYW1lKSlcbiAgICAgIGVsZW1lbnQuY2xhc3NOYW1lICs9IChlbGVtZW50LmNsYXNzTmFtZSA/ICcgJyA6ICcnKSArIGNsYXNzTmFtZTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlQ2xhc3NOYW1lKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuO1xuXG4gICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKFxuICAgICBnZXRSZWdFeHBGb3JDbGFzc05hbWUoY2xhc3NOYW1lKSwgJyAnKS5zdHJpcCgpO1xuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiB0b2dnbGVDbGFzc05hbWUoZWxlbWVudCwgY2xhc3NOYW1lLCBib29sKSB7XG4gICAgaWYgKCEoZWxlbWVudCA9ICQoZWxlbWVudCkpKSByZXR1cm47XG5cbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKGJvb2wpKVxuICAgICAgYm9vbCA9ICFoYXNDbGFzc05hbWUoZWxlbWVudCwgY2xhc3NOYW1lKTtcblxuICAgIHZhciBtZXRob2QgPSBFbGVtZW50W2Jvb2wgPyAnYWRkQ2xhc3NOYW1lJyA6ICdyZW1vdmVDbGFzc05hbWUnXTtcbiAgICByZXR1cm4gbWV0aG9kKGVsZW1lbnQsIGNsYXNzTmFtZSk7XG4gIH1cblxuICB2YXIgQVRUUklCVVRFX1RSQU5TTEFUSU9OUyA9IHt9O1xuXG4gIHZhciBjbGFzc1Byb3AgPSAnY2xhc3NOYW1lJywgZm9yUHJvcCA9ICdmb3InO1xuXG4gIERJVi5zZXRBdHRyaWJ1dGUoY2xhc3NQcm9wLCAneCcpO1xuICBpZiAoRElWLmNsYXNzTmFtZSAhPT0gJ3gnKSB7XG4gICAgRElWLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAneCcpO1xuICAgIGlmIChESVYuY2xhc3NOYW1lID09PSAneCcpXG4gICAgICBjbGFzc1Byb3AgPSAnY2xhc3MnO1xuICB9XG5cbiAgdmFyIExBQkVMID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgTEFCRUwuc2V0QXR0cmlidXRlKGZvclByb3AsICd4Jyk7XG4gIGlmIChMQUJFTC5odG1sRm9yICE9PSAneCcpIHtcbiAgICBMQUJFTC5zZXRBdHRyaWJ1dGUoJ2h0bWxGb3InLCAneCcpO1xuICAgIGlmIChMQUJFTC5odG1sRm9yID09PSAneCcpXG4gICAgICBmb3JQcm9wID0gJ2h0bWxGb3InO1xuICB9XG4gIExBQkVMID0gbnVsbDtcblxuICBmdW5jdGlvbiBfZ2V0QXR0cihlbGVtZW50LCBhdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9nZXRBdHRyMihlbGVtZW50LCBhdHRyaWJ1dGUpIHtcbiAgICByZXR1cm4gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCAyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9nZXRBdHRyTm9kZShlbGVtZW50LCBhdHRyaWJ1dGUpIHtcbiAgICB2YXIgbm9kZSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlTm9kZShhdHRyaWJ1dGUpO1xuICAgIHJldHVybiBub2RlID8gbm9kZS52YWx1ZSA6ICcnO1xuICB9XG5cbiAgZnVuY3Rpb24gX2dldEZsYWcoZWxlbWVudCwgYXR0cmlidXRlKSB7XG4gICAgcmV0dXJuICQoZWxlbWVudCkuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZSkgPyBhdHRyaWJ1dGUgOiBudWxsO1xuICB9XG5cbiAgRElWLm9uY2xpY2sgPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjtcbiAgdmFyIG9uY2xpY2tWYWx1ZSA9IERJVi5nZXRBdHRyaWJ1dGUoJ29uY2xpY2snKTtcblxuICB2YXIgX2dldEV2O1xuXG4gIGlmIChTdHJpbmcob25jbGlja1ZhbHVlKS5pbmRleE9mKCd7JykgPiAtMSkge1xuICAgIF9nZXRFdiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZSkge1xuICAgICAgdmFyIHZhbHVlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcbiAgICAgIGlmICghdmFsdWUpIHJldHVybiBudWxsO1xuICAgICAgdmFsdWUgPSB2YWx1ZS50b1N0cmluZygpO1xuICAgICAgdmFsdWUgPSB2YWx1ZS5zcGxpdCgneycpWzFdO1xuICAgICAgdmFsdWUgPSB2YWx1ZS5zcGxpdCgnfScpWzBdO1xuICAgICAgcmV0dXJuIHZhbHVlLnN0cmlwKCk7XG4gICAgfTtcbiAgfVxuICBlbHNlIGlmIChvbmNsaWNrVmFsdWUgPT09ICcnKSB7XG4gICAgX2dldEV2ID0gZnVuY3Rpb24oZWxlbWVudCwgYXR0cmlidXRlKSB7XG4gICAgICB2YXIgdmFsdWUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZShhdHRyaWJ1dGUpO1xuICAgICAgaWYgKCF2YWx1ZSkgcmV0dXJuIG51bGw7XG4gICAgICByZXR1cm4gdmFsdWUuc3RyaXAoKTtcbiAgICB9O1xuICB9XG5cbiAgQVRUUklCVVRFX1RSQU5TTEFUSU9OUy5yZWFkID0ge1xuICAgIG5hbWVzOiB7XG4gICAgICAnY2xhc3MnOiAgICAgY2xhc3NQcm9wLFxuICAgICAgJ2NsYXNzTmFtZSc6IGNsYXNzUHJvcCxcbiAgICAgICdmb3InOiAgICAgICBmb3JQcm9wLFxuICAgICAgJ2h0bWxGb3InOiAgIGZvclByb3BcbiAgICB9LFxuXG4gICAgdmFsdWVzOiB7XG4gICAgICBzdHlsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudC5zdHlsZS5jc3NUZXh0LnRvTG93ZXJDYXNlKCk7XG4gICAgICB9LFxuICAgICAgdGl0bGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQudGl0bGU7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIEFUVFJJQlVURV9UUkFOU0xBVElPTlMud3JpdGUgPSB7XG4gICAgbmFtZXM6IHtcbiAgICAgIGNsYXNzTmFtZTogICAnY2xhc3MnLFxuICAgICAgaHRtbEZvcjogICAgICdmb3InLFxuICAgICAgY2VsbHBhZGRpbmc6ICdjZWxsUGFkZGluZycsXG4gICAgICBjZWxsc3BhY2luZzogJ2NlbGxTcGFjaW5nJ1xuICAgIH0sXG5cbiAgICB2YWx1ZXM6IHtcbiAgICAgIGNoZWNrZWQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlKSB7XG4gICAgICAgIGVsZW1lbnQuY2hlY2tlZCA9ICEhdmFsdWU7XG4gICAgICB9LFxuXG4gICAgICBzdHlsZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gdmFsdWUgPyB2YWx1ZSA6ICcnO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBBVFRSSUJVVEVfVFJBTlNMQVRJT05TLmhhcyA9IHsgbmFtZXM6IHt9IH07XG5cbiAgT2JqZWN0LmV4dGVuZChBVFRSSUJVVEVfVFJBTlNMQVRJT05TLndyaXRlLm5hbWVzLFxuICAgQVRUUklCVVRFX1RSQU5TTEFUSU9OUy5yZWFkLm5hbWVzKTtcblxuICB2YXIgQ0FNRUxfQ0FTRURfQVRUUklCVVRFX05BTUVTID0gJHcoJ2NvbFNwYW4gcm93U3BhbiB2QWxpZ24gZGF0ZVRpbWUgJyArXG4gICAnYWNjZXNzS2V5IHRhYkluZGV4IGVuY1R5cGUgbWF4TGVuZ3RoIHJlYWRPbmx5IGxvbmdEZXNjIGZyYW1lQm9yZGVyJyk7XG5cbiAgZm9yICh2YXIgaSA9IDAsIGF0dHI7IGF0dHIgPSBDQU1FTF9DQVNFRF9BVFRSSUJVVEVfTkFNRVNbaV07IGkrKykge1xuICAgIEFUVFJJQlVURV9UUkFOU0xBVElPTlMud3JpdGUubmFtZXNbYXR0ci50b0xvd2VyQ2FzZSgpXSA9IGF0dHI7XG4gICAgQVRUUklCVVRFX1RSQU5TTEFUSU9OUy5oYXMubmFtZXNbYXR0ci50b0xvd2VyQ2FzZSgpXSAgID0gYXR0cjtcbiAgfVxuXG4gIE9iamVjdC5leHRlbmQoQVRUUklCVVRFX1RSQU5TTEFUSU9OUy5yZWFkLnZhbHVlcywge1xuICAgIGhyZWY6ICAgICAgICBfZ2V0QXR0cjIsXG4gICAgc3JjOiAgICAgICAgIF9nZXRBdHRyMixcbiAgICB0eXBlOiAgICAgICAgX2dldEF0dHIsXG4gICAgYWN0aW9uOiAgICAgIF9nZXRBdHRyTm9kZSxcbiAgICBkaXNhYmxlZDogICAgX2dldEZsYWcsXG4gICAgY2hlY2tlZDogICAgIF9nZXRGbGFnLFxuICAgIHJlYWRvbmx5OiAgICBfZ2V0RmxhZyxcbiAgICBtdWx0aXBsZTogICAgX2dldEZsYWcsXG4gICAgb25sb2FkOiAgICAgIF9nZXRFdixcbiAgICBvbnVubG9hZDogICAgX2dldEV2LFxuICAgIG9uY2xpY2s6ICAgICBfZ2V0RXYsXG4gICAgb25kYmxjbGljazogIF9nZXRFdixcbiAgICBvbm1vdXNlZG93bjogX2dldEV2LFxuICAgIG9ubW91c2V1cDogICBfZ2V0RXYsXG4gICAgb25tb3VzZW92ZXI6IF9nZXRFdixcbiAgICBvbm1vdXNlbW92ZTogX2dldEV2LFxuICAgIG9ubW91c2VvdXQ6ICBfZ2V0RXYsXG4gICAgb25mb2N1czogICAgIF9nZXRFdixcbiAgICBvbmJsdXI6ICAgICAgX2dldEV2LFxuICAgIG9ua2V5cHJlc3M6ICBfZ2V0RXYsXG4gICAgb25rZXlkb3duOiAgIF9nZXRFdixcbiAgICBvbmtleXVwOiAgICAgX2dldEV2LFxuICAgIG9uc3VibWl0OiAgICBfZ2V0RXYsXG4gICAgb25yZXNldDogICAgIF9nZXRFdixcbiAgICBvbnNlbGVjdDogICAgX2dldEV2LFxuICAgIG9uY2hhbmdlOiAgICBfZ2V0RXZcbiAgfSk7XG5cblxuICBPYmplY3QuZXh0ZW5kKG1ldGhvZHMsIHtcbiAgICBpZGVudGlmeTogICAgICAgIGlkZW50aWZ5LFxuICAgIHJlYWRBdHRyaWJ1dGU6ICAgcmVhZEF0dHJpYnV0ZSxcbiAgICB3cml0ZUF0dHJpYnV0ZTogIHdyaXRlQXR0cmlidXRlLFxuICAgIGNsYXNzTmFtZXM6ICAgICAgY2xhc3NOYW1lcyxcbiAgICBoYXNDbGFzc05hbWU6ICAgIGhhc0NsYXNzTmFtZSxcbiAgICBhZGRDbGFzc05hbWU6ICAgIGFkZENsYXNzTmFtZSxcbiAgICByZW1vdmVDbGFzc05hbWU6IHJlbW92ZUNsYXNzTmFtZSxcbiAgICB0b2dnbGVDbGFzc05hbWU6IHRvZ2dsZUNsYXNzTmFtZVxuICB9KTtcblxuXG4gIGZ1bmN0aW9uIG5vcm1hbGl6ZVN0eWxlTmFtZShzdHlsZSkge1xuICAgIGlmIChzdHlsZSA9PT0gJ2Zsb2F0JyB8fCBzdHlsZSA9PT0gJ3N0eWxlRmxvYXQnKVxuICAgICAgcmV0dXJuICdjc3NGbG9hdCc7XG4gICAgcmV0dXJuIHN0eWxlLmNhbWVsaXplKCk7XG4gIH1cblxuICBmdW5jdGlvbiBub3JtYWxpemVTdHlsZU5hbWVfSUUoc3R5bGUpIHtcbiAgICBpZiAoc3R5bGUgPT09ICdmbG9hdCcgfHwgc3R5bGUgPT09ICdjc3NGbG9hdCcpXG4gICAgICByZXR1cm4gJ3N0eWxlRmxvYXQnO1xuICAgIHJldHVybiBzdHlsZS5jYW1lbGl6ZSgpO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0U3R5bGUoZWxlbWVudCwgc3R5bGVzKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIGVsZW1lbnRTdHlsZSA9IGVsZW1lbnQuc3R5bGUsIG1hdGNoO1xuXG4gICAgaWYgKE9iamVjdC5pc1N0cmluZyhzdHlsZXMpKSB7XG4gICAgICBlbGVtZW50U3R5bGUuY3NzVGV4dCArPSAnOycgKyBzdHlsZXM7XG4gICAgICBpZiAoc3R5bGVzLmluY2x1ZGUoJ29wYWNpdHknKSkge1xuICAgICAgICB2YXIgb3BhY2l0eSA9IHN0eWxlcy5tYXRjaCgvb3BhY2l0eTpcXHMqKFxcZD9cXC4/XFxkKikvKVsxXTtcbiAgICAgICAgRWxlbWVudC5zZXRPcGFjaXR5KGVsZW1lbnQsIG9wYWNpdHkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gc3R5bGVzKSB7XG4gICAgICBpZiAocHJvcGVydHkgPT09ICdvcGFjaXR5Jykge1xuICAgICAgICBFbGVtZW50LnNldE9wYWNpdHkoZWxlbWVudCwgc3R5bGVzW3Byb3BlcnR5XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdmFsdWUgPSBzdHlsZXNbcHJvcGVydHldO1xuICAgICAgICBpZiAocHJvcGVydHkgPT09ICdmbG9hdCcgfHwgcHJvcGVydHkgPT09ICdjc3NGbG9hdCcpIHtcbiAgICAgICAgICBwcm9wZXJ0eSA9IE9iamVjdC5pc1VuZGVmaW5lZChlbGVtZW50U3R5bGUuc3R5bGVGbG9hdCkgP1xuICAgICAgICAgICAnY3NzRmxvYXQnIDogJ3N0eWxlRmxvYXQnO1xuICAgICAgICB9XG4gICAgICAgIGVsZW1lbnRTdHlsZVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZ2V0U3R5bGUoZWxlbWVudCwgc3R5bGUpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICBzdHlsZSA9IG5vcm1hbGl6ZVN0eWxlTmFtZShzdHlsZSk7XG5cbiAgICB2YXIgdmFsdWUgPSBlbGVtZW50LnN0eWxlW3N0eWxlXTtcbiAgICBpZiAoIXZhbHVlIHx8IHZhbHVlID09PSAnYXV0bycpIHtcbiAgICAgIHZhciBjc3MgPSBkb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQsIG51bGwpO1xuICAgICAgdmFsdWUgPSBjc3MgPyBjc3Nbc3R5bGVdIDogbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoc3R5bGUgPT09ICdvcGFjaXR5JykgcmV0dXJuIHZhbHVlID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiAxLjA7XG4gICAgcmV0dXJuIHZhbHVlID09PSAnYXV0bycgPyBudWxsIDogdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTdHlsZV9PcGVyYShlbGVtZW50LCBzdHlsZSkge1xuICAgIHN3aXRjaCAoc3R5bGUpIHtcbiAgICAgIGNhc2UgJ2hlaWdodCc6IGNhc2UgJ3dpZHRoJzpcbiAgICAgICAgaWYgKCFFbGVtZW50LnZpc2libGUoZWxlbWVudCkpIHJldHVybiBudWxsO1xuXG4gICAgICAgIHZhciBkaW0gPSBwYXJzZUludChnZXRTdHlsZShlbGVtZW50LCBzdHlsZSksIDEwKTtcblxuICAgICAgICBpZiAoZGltICE9PSBlbGVtZW50WydvZmZzZXQnICsgc3R5bGUuY2FwaXRhbGl6ZSgpXSlcbiAgICAgICAgICByZXR1cm4gZGltICsgJ3B4JztcblxuICAgICAgICByZXR1cm4gRWxlbWVudC5tZWFzdXJlKGVsZW1lbnQsIHN0eWxlKTtcblxuICAgICAgZGVmYXVsdDogcmV0dXJuIGdldFN0eWxlKGVsZW1lbnQsIHN0eWxlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTdHlsZV9JRShlbGVtZW50LCBzdHlsZSkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHN0eWxlID0gbm9ybWFsaXplU3R5bGVOYW1lX0lFKHN0eWxlKTtcblxuICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQuc3R5bGVbc3R5bGVdO1xuICAgIGlmICghdmFsdWUgJiYgZWxlbWVudC5jdXJyZW50U3R5bGUpIHtcbiAgICAgIHZhbHVlID0gZWxlbWVudC5jdXJyZW50U3R5bGVbc3R5bGVdO1xuICAgIH1cblxuICAgIGlmIChzdHlsZSA9PT0gJ29wYWNpdHknICYmICFTVEFOREFSRF9DU1NfT1BBQ0lUWV9TVVBQT1JURUQpXG4gICAgICByZXR1cm4gZ2V0T3BhY2l0eV9JRShlbGVtZW50KTtcblxuICAgIGlmICh2YWx1ZSA9PT0gJ2F1dG8nKSB7XG4gICAgICBpZiAoKHN0eWxlID09PSAnd2lkdGgnIHx8IHN0eWxlID09PSAnaGVpZ2h0JykgJiYgRWxlbWVudC52aXNpYmxlKGVsZW1lbnQpKVxuICAgICAgICByZXR1cm4gRWxlbWVudC5tZWFzdXJlKGVsZW1lbnQsIHN0eWxlKSArICdweCc7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBzdHJpcEFscGhhRnJvbUZpbHRlcl9JRShmaWx0ZXIpIHtcbiAgICByZXR1cm4gKGZpbHRlciB8fCAnJykucmVwbGFjZSgvYWxwaGFcXChbXlxcKV0qXFwpL2dpLCAnJyk7XG4gIH1cblxuICBmdW5jdGlvbiBoYXNMYXlvdXRfSUUoZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5jdXJyZW50U3R5bGUgfHwgIWVsZW1lbnQuY3VycmVudFN0eWxlLmhhc0xheW91dClcbiAgICAgIGVsZW1lbnQuc3R5bGUuem9vbSA9IDE7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICB2YXIgU1RBTkRBUkRfQ1NTX09QQUNJVFlfU1VQUE9SVEVEID0gKGZ1bmN0aW9uKCkge1xuICAgIERJVi5zdHlsZS5jc3NUZXh0ID0gXCJvcGFjaXR5Oi41NVwiO1xuICAgIHJldHVybiAvXjAuNTUvLnRlc3QoRElWLnN0eWxlLm9wYWNpdHkpO1xuICB9KSgpO1xuXG4gIGZ1bmN0aW9uIHNldE9wYWNpdHkoZWxlbWVudCwgdmFsdWUpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICBpZiAodmFsdWUgPT0gMSB8fCB2YWx1ZSA9PT0gJycpIHZhbHVlID0gJyc7XG4gICAgZWxzZSBpZiAodmFsdWUgPCAwLjAwMDAxKSB2YWx1ZSA9IDA7XG4gICAgZWxlbWVudC5zdHlsZS5vcGFjaXR5ID0gdmFsdWU7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRPcGFjaXR5X0lFKGVsZW1lbnQsIHZhbHVlKSB7XG4gICAgaWYgKFNUQU5EQVJEX0NTU19PUEFDSVRZX1NVUFBPUlRFRClcbiAgICAgIHJldHVybiBzZXRPcGFjaXR5KGVsZW1lbnQsIHZhbHVlKTtcblxuICAgIGVsZW1lbnQgPSBoYXNMYXlvdXRfSUUoJChlbGVtZW50KSk7XG4gICAgdmFyIGZpbHRlciA9IEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ2ZpbHRlcicpLFxuICAgICBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7XG5cbiAgICBpZiAodmFsdWUgPT0gMSB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgIGZpbHRlciA9IHN0cmlwQWxwaGFGcm9tRmlsdGVyX0lFKGZpbHRlcik7XG4gICAgICBpZiAoZmlsdGVyKSBzdHlsZS5maWx0ZXIgPSBmaWx0ZXI7XG4gICAgICBlbHNlIHN0eWxlLnJlbW92ZUF0dHJpYnV0ZSgnZmlsdGVyJyk7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgPCAwLjAwMDAxKSB2YWx1ZSA9IDA7XG5cbiAgICBzdHlsZS5maWx0ZXIgPSBzdHJpcEFscGhhRnJvbUZpbHRlcl9JRShmaWx0ZXIpICtcbiAgICAgJ2FscGhhKG9wYWNpdHk9JyArICh2YWx1ZSAqIDEwMCkgKyAnKSc7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gZ2V0T3BhY2l0eShlbGVtZW50KSB7XG4gICAgcmV0dXJuIEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ29wYWNpdHknKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE9wYWNpdHlfSUUoZWxlbWVudCkge1xuICAgIGlmIChTVEFOREFSRF9DU1NfT1BBQ0lUWV9TVVBQT1JURUQpXG4gICAgICByZXR1cm4gZ2V0T3BhY2l0eShlbGVtZW50KTtcblxuICAgIHZhciBmaWx0ZXIgPSBFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdmaWx0ZXInKTtcbiAgICBpZiAoZmlsdGVyLmxlbmd0aCA9PT0gMCkgcmV0dXJuIDEuMDtcbiAgICB2YXIgbWF0Y2ggPSAoZmlsdGVyIHx8ICcnKS5tYXRjaCgvYWxwaGFcXChvcGFjaXR5PSguKilcXCkvKTtcbiAgICBpZiAobWF0Y2ggJiYgbWF0Y2hbMV0pIHJldHVybiBwYXJzZUZsb2F0KG1hdGNoWzFdKSAvIDEwMDtcbiAgICByZXR1cm4gMS4wO1xuICB9XG5cblxuICBPYmplY3QuZXh0ZW5kKG1ldGhvZHMsIHtcbiAgICBzZXRTdHlsZTogICBzZXRTdHlsZSxcbiAgICBnZXRTdHlsZTogICBnZXRTdHlsZSxcbiAgICBzZXRPcGFjaXR5OiBzZXRPcGFjaXR5LFxuICAgIGdldE9wYWNpdHk6IGdldE9wYWNpdHlcbiAgfSk7XG5cbiAgaWYgKCdzdHlsZUZsb2F0JyBpbiBESVYuc3R5bGUpIHtcbiAgICBtZXRob2RzLmdldFN0eWxlID0gZ2V0U3R5bGVfSUU7XG4gICAgbWV0aG9kcy5zZXRPcGFjaXR5ID0gc2V0T3BhY2l0eV9JRTtcbiAgICBtZXRob2RzLmdldE9wYWNpdHkgPSBnZXRPcGFjaXR5X0lFO1xuICB9XG5cbiAgdmFyIFVJRCA9IDA7XG5cbiAgR0xPQkFMLkVsZW1lbnQuU3RvcmFnZSA9IHsgVUlEOiAxIH07XG5cbiAgZnVuY3Rpb24gZ2V0VW5pcXVlRWxlbWVudElEKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudCA9PT0gd2luZG93KSByZXR1cm4gMDtcblxuICAgIGlmICh0eXBlb2YgZWxlbWVudC5fcHJvdG90eXBlVUlEID09PSAndW5kZWZpbmVkJylcbiAgICAgIGVsZW1lbnQuX3Byb3RvdHlwZVVJRCA9IEVsZW1lbnQuU3RvcmFnZS5VSUQrKztcbiAgICByZXR1cm4gZWxlbWVudC5fcHJvdG90eXBlVUlEO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0VW5pcXVlRWxlbWVudElEX0lFKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudCA9PT0gd2luZG93KSByZXR1cm4gMDtcbiAgICBpZiAoZWxlbWVudCA9PSBkb2N1bWVudCkgcmV0dXJuIDE7XG4gICAgcmV0dXJuIGVsZW1lbnQudW5pcXVlSUQ7XG4gIH1cblxuICB2YXIgSEFTX1VOSVFVRV9JRF9QUk9QRVJUWSA9ICgndW5pcXVlSUQnIGluIERJVik7XG4gIGlmIChIQVNfVU5JUVVFX0lEX1BST1BFUlRZKVxuICAgIGdldFVuaXF1ZUVsZW1lbnRJRCA9IGdldFVuaXF1ZUVsZW1lbnRJRF9JRTtcblxuICBmdW5jdGlvbiBnZXRTdG9yYWdlKGVsZW1lbnQpIHtcbiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjtcblxuICAgIHZhciB1aWQgPSBnZXRVbmlxdWVFbGVtZW50SUQoZWxlbWVudCk7XG5cbiAgICBpZiAoIUVsZW1lbnQuU3RvcmFnZVt1aWRdKVxuICAgICAgRWxlbWVudC5TdG9yYWdlW3VpZF0gPSAkSCgpO1xuXG4gICAgcmV0dXJuIEVsZW1lbnQuU3RvcmFnZVt1aWRdO1xuICB9XG5cbiAgZnVuY3Rpb24gc3RvcmUoZWxlbWVudCwga2V5LCB2YWx1ZSkge1xuICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuO1xuICAgIHZhciBzdG9yYWdlID0gZ2V0U3RvcmFnZShlbGVtZW50KTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgICAgc3RvcmFnZS51cGRhdGUoa2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RvcmFnZS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gcmV0cmlldmUoZWxlbWVudCwga2V5LCBkZWZhdWx0VmFsdWUpIHtcbiAgICBpZiAoIShlbGVtZW50ID0gJChlbGVtZW50KSkpIHJldHVybjtcbiAgICB2YXIgc3RvcmFnZSA9IGdldFN0b3JhZ2UoZWxlbWVudCksIHZhbHVlID0gc3RvcmFnZS5nZXQoa2V5KTtcblxuICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICBzdG9yYWdlLnNldChrZXksIGRlZmF1bHRWYWx1ZSk7XG4gICAgICB2YWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuXG4gIE9iamVjdC5leHRlbmQobWV0aG9kcywge1xuICAgIGdldFN0b3JhZ2U6IGdldFN0b3JhZ2UsXG4gICAgc3RvcmU6ICAgICAgc3RvcmUsXG4gICAgcmV0cmlldmU6ICAgcmV0cmlldmVcbiAgfSk7XG5cblxuICB2YXIgTWV0aG9kcyA9IHt9LCBCeVRhZyA9IEVsZW1lbnQuTWV0aG9kcy5CeVRhZyxcbiAgIEYgPSBQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzO1xuXG4gIGlmICghRi5FbGVtZW50RXh0ZW5zaW9ucyAmJiAoJ19fcHJvdG9fXycgaW4gRElWKSkge1xuICAgIEdMT0JBTC5IVE1MRWxlbWVudCA9IHt9O1xuICAgIEdMT0JBTC5IVE1MRWxlbWVudC5wcm90b3R5cGUgPSBESVZbJ19fcHJvdG9fXyddO1xuICAgIEYuRWxlbWVudEV4dGVuc2lvbnMgPSB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gY2hlY2tFbGVtZW50UHJvdG90eXBlRGVmaWNpZW5jeSh0YWdOYW1lKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cuRWxlbWVudCA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIUhBU19FWFRFTkRFRF9DUkVBVEVfRUxFTUVOVF9TWU5UQVgpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgcHJvdG8gPSB3aW5kb3cuRWxlbWVudC5wcm90b3R5cGU7XG4gICAgaWYgKHByb3RvKSB7XG4gICAgICB2YXIgaWQgPSAnXycgKyAoTWF0aC5yYW5kb20oKSArICcnKS5zbGljZSgyKSxcbiAgICAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XG4gICAgICBwcm90b1tpZF0gPSAneCc7XG4gICAgICB2YXIgaXNCdWdneSA9IChlbFtpZF0gIT09ICd4Jyk7XG4gICAgICBkZWxldGUgcHJvdG9baWRdO1xuICAgICAgZWwgPSBudWxsO1xuICAgICAgcmV0dXJuIGlzQnVnZ3k7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIEhUTUxPQkpFQ1RFTEVNRU5UX1BST1RPVFlQRV9CVUdHWSA9XG4gICBjaGVja0VsZW1lbnRQcm90b3R5cGVEZWZpY2llbmN5KCdvYmplY3QnKTtcblxuICBmdW5jdGlvbiBleHRlbmRFbGVtZW50V2l0aChlbGVtZW50LCBtZXRob2RzKSB7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gbWV0aG9kcykge1xuICAgICAgdmFyIHZhbHVlID0gbWV0aG9kc1twcm9wZXJ0eV07XG4gICAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24odmFsdWUpICYmICEocHJvcGVydHkgaW4gZWxlbWVudCkpXG4gICAgICAgIGVsZW1lbnRbcHJvcGVydHldID0gdmFsdWUubWV0aG9kaXplKCk7XG4gICAgfVxuICB9XG5cbiAgdmFyIEVYVEVOREVEID0ge307XG4gIGZ1bmN0aW9uIGVsZW1lbnRJc0V4dGVuZGVkKGVsZW1lbnQpIHtcbiAgICB2YXIgdWlkID0gZ2V0VW5pcXVlRWxlbWVudElEKGVsZW1lbnQpO1xuICAgIHJldHVybiAodWlkIGluIEVYVEVOREVEKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4dGVuZChlbGVtZW50KSB7XG4gICAgaWYgKCFlbGVtZW50IHx8IGVsZW1lbnRJc0V4dGVuZGVkKGVsZW1lbnQpKSByZXR1cm4gZWxlbWVudDtcbiAgICBpZiAoZWxlbWVudC5ub2RlVHlwZSAhPT0gTm9kZS5FTEVNRU5UX05PREUgfHwgZWxlbWVudCA9PSB3aW5kb3cpXG4gICAgICByZXR1cm4gZWxlbWVudDtcblxuICAgIHZhciBtZXRob2RzID0gT2JqZWN0LmNsb25lKE1ldGhvZHMpLFxuICAgICB0YWdOYW1lID0gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG5cbiAgICBpZiAoQnlUYWdbdGFnTmFtZV0pIE9iamVjdC5leHRlbmQobWV0aG9kcywgQnlUYWdbdGFnTmFtZV0pO1xuXG4gICAgZXh0ZW5kRWxlbWVudFdpdGgoZWxlbWVudCwgbWV0aG9kcyk7XG4gICAgRVhURU5ERURbZ2V0VW5pcXVlRWxlbWVudElEKGVsZW1lbnQpXSA9IHRydWU7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBleHRlbmRfSUU4KGVsZW1lbnQpIHtcbiAgICBpZiAoIWVsZW1lbnQgfHwgZWxlbWVudElzRXh0ZW5kZWQoZWxlbWVudCkpIHJldHVybiBlbGVtZW50O1xuXG4gICAgdmFyIHQgPSBlbGVtZW50LnRhZ05hbWU7XG4gICAgaWYgKHQgJiYgKC9eKD86b2JqZWN0fGFwcGxldHxlbWJlZCkkL2kudGVzdCh0KSkpIHtcbiAgICAgIGV4dGVuZEVsZW1lbnRXaXRoKGVsZW1lbnQsIEVsZW1lbnQuTWV0aG9kcyk7XG4gICAgICBleHRlbmRFbGVtZW50V2l0aChlbGVtZW50LCBFbGVtZW50Lk1ldGhvZHMuU2ltdWxhdGVkKTtcbiAgICAgIGV4dGVuZEVsZW1lbnRXaXRoKGVsZW1lbnQsIEVsZW1lbnQuTWV0aG9kcy5CeVRhZ1t0LnRvVXBwZXJDYXNlKCldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGlmIChGLlNwZWNpZmljRWxlbWVudEV4dGVuc2lvbnMpIHtcbiAgICBleHRlbmQgPSBIVE1MT0JKRUNURUxFTUVOVF9QUk9UT1RZUEVfQlVHR1kgPyBleHRlbmRfSUU4IDogUHJvdG90eXBlLks7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRNZXRob2RzVG9UYWdOYW1lKHRhZ05hbWUsIG1ldGhvZHMpIHtcbiAgICB0YWdOYW1lID0gdGFnTmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmICghQnlUYWdbdGFnTmFtZV0pIEJ5VGFnW3RhZ05hbWVdID0ge307XG4gICAgT2JqZWN0LmV4dGVuZChCeVRhZ1t0YWdOYW1lXSwgbWV0aG9kcyk7XG4gIH1cblxuICBmdW5jdGlvbiBtZXJnZU1ldGhvZHMoZGVzdGluYXRpb24sIG1ldGhvZHMsIG9ubHlJZkFic2VudCkge1xuICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQob25seUlmQWJzZW50KSkgb25seUlmQWJzZW50ID0gZmFsc2U7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gbWV0aG9kcykge1xuICAgICAgdmFyIHZhbHVlID0gbWV0aG9kc1twcm9wZXJ0eV07XG4gICAgICBpZiAoIU9iamVjdC5pc0Z1bmN0aW9uKHZhbHVlKSkgY29udGludWU7XG4gICAgICBpZiAoIW9ubHlJZkFic2VudCB8fCAhKHByb3BlcnR5IGluIGRlc3RpbmF0aW9uKSlcbiAgICAgICAgZGVzdGluYXRpb25bcHJvcGVydHldID0gdmFsdWUubWV0aG9kaXplKCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZmluZERPTUNsYXNzKHRhZ05hbWUpIHtcbiAgICB2YXIga2xhc3M7XG4gICAgdmFyIHRyYW5zID0ge1xuICAgICAgXCJPUFRHUk9VUFwiOiBcIk9wdEdyb3VwXCIsIFwiVEVYVEFSRUFcIjogXCJUZXh0QXJlYVwiLCBcIlBcIjogXCJQYXJhZ3JhcGhcIixcbiAgICAgIFwiRklFTERTRVRcIjogXCJGaWVsZFNldFwiLCBcIlVMXCI6IFwiVUxpc3RcIiwgXCJPTFwiOiBcIk9MaXN0XCIsIFwiRExcIjogXCJETGlzdFwiLFxuICAgICAgXCJESVJcIjogXCJEaXJlY3RvcnlcIiwgXCJIMVwiOiBcIkhlYWRpbmdcIiwgXCJIMlwiOiBcIkhlYWRpbmdcIiwgXCJIM1wiOiBcIkhlYWRpbmdcIixcbiAgICAgIFwiSDRcIjogXCJIZWFkaW5nXCIsIFwiSDVcIjogXCJIZWFkaW5nXCIsIFwiSDZcIjogXCJIZWFkaW5nXCIsIFwiUVwiOiBcIlF1b3RlXCIsXG4gICAgICBcIklOU1wiOiBcIk1vZFwiLCBcIkRFTFwiOiBcIk1vZFwiLCBcIkFcIjogXCJBbmNob3JcIiwgXCJJTUdcIjogXCJJbWFnZVwiLCBcIkNBUFRJT05cIjpcbiAgICAgIFwiVGFibGVDYXB0aW9uXCIsIFwiQ09MXCI6IFwiVGFibGVDb2xcIiwgXCJDT0xHUk9VUFwiOiBcIlRhYmxlQ29sXCIsIFwiVEhFQURcIjpcbiAgICAgIFwiVGFibGVTZWN0aW9uXCIsIFwiVEZPT1RcIjogXCJUYWJsZVNlY3Rpb25cIiwgXCJUQk9EWVwiOiBcIlRhYmxlU2VjdGlvblwiLCBcIlRSXCI6XG4gICAgICBcIlRhYmxlUm93XCIsIFwiVEhcIjogXCJUYWJsZUNlbGxcIiwgXCJURFwiOiBcIlRhYmxlQ2VsbFwiLCBcIkZSQU1FU0VUXCI6XG4gICAgICBcIkZyYW1lU2V0XCIsIFwiSUZSQU1FXCI6IFwiSUZyYW1lXCJcbiAgICB9O1xuICAgIGlmICh0cmFuc1t0YWdOYW1lXSkga2xhc3MgPSAnSFRNTCcgKyB0cmFuc1t0YWdOYW1lXSArICdFbGVtZW50JztcbiAgICBpZiAod2luZG93W2tsYXNzXSkgcmV0dXJuIHdpbmRvd1trbGFzc107XG4gICAga2xhc3MgPSAnSFRNTCcgKyB0YWdOYW1lICsgJ0VsZW1lbnQnO1xuICAgIGlmICh3aW5kb3dba2xhc3NdKSByZXR1cm4gd2luZG93W2tsYXNzXTtcbiAgICBrbGFzcyA9ICdIVE1MJyArIHRhZ05hbWUuY2FwaXRhbGl6ZSgpICsgJ0VsZW1lbnQnO1xuICAgIGlmICh3aW5kb3dba2xhc3NdKSByZXR1cm4gd2luZG93W2tsYXNzXTtcblxuICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKSxcbiAgICAgcHJvdG8gPSBlbGVtZW50WydfX3Byb3RvX18nXSB8fCBlbGVtZW50LmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblxuICAgIGVsZW1lbnQgPSBudWxsO1xuICAgIHJldHVybiBwcm90bztcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZE1ldGhvZHMobWV0aG9kcykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSBhZGRGb3JtTWV0aG9kcygpO1xuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgIHZhciB0YWdOYW1lID0gbWV0aG9kcztcbiAgICAgIG1ldGhvZHMgPSBhcmd1bWVudHNbMV07XG4gICAgfVxuXG4gICAgaWYgKCF0YWdOYW1lKSB7XG4gICAgICBPYmplY3QuZXh0ZW5kKEVsZW1lbnQuTWV0aG9kcywgbWV0aG9kcyB8fCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChPYmplY3QuaXNBcnJheSh0YWdOYW1lKSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgdGFnOyB0YWcgPSB0YWdOYW1lW2ldOyBpKyspXG4gICAgICAgICAgYWRkTWV0aG9kc1RvVGFnTmFtZSh0YWcsIG1ldGhvZHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWRkTWV0aG9kc1RvVGFnTmFtZSh0YWdOYW1lLCBtZXRob2RzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgRUxFTUVOVF9QUk9UT1RZUEUgPSB3aW5kb3cuSFRNTEVsZW1lbnQgPyBIVE1MRWxlbWVudC5wcm90b3R5cGUgOlxuICAgICBFbGVtZW50LnByb3RvdHlwZTtcblxuICAgIGlmIChGLkVsZW1lbnRFeHRlbnNpb25zKSB7XG4gICAgICBtZXJnZU1ldGhvZHMoRUxFTUVOVF9QUk9UT1RZUEUsIEVsZW1lbnQuTWV0aG9kcyk7XG4gICAgICBtZXJnZU1ldGhvZHMoRUxFTUVOVF9QUk9UT1RZUEUsIEVsZW1lbnQuTWV0aG9kcy5TaW11bGF0ZWQsIHRydWUpO1xuICAgIH1cblxuICAgIGlmIChGLlNwZWNpZmljRWxlbWVudEV4dGVuc2lvbnMpIHtcbiAgICAgIGZvciAodmFyIHRhZyBpbiBFbGVtZW50Lk1ldGhvZHMuQnlUYWcpIHtcbiAgICAgICAgdmFyIGtsYXNzID0gZmluZERPTUNsYXNzKHRhZyk7XG4gICAgICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQoa2xhc3MpKSBjb250aW51ZTtcbiAgICAgICAgbWVyZ2VNZXRob2RzKGtsYXNzLnByb3RvdHlwZSwgQnlUYWdbdGFnXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgT2JqZWN0LmV4dGVuZChFbGVtZW50LCBFbGVtZW50Lk1ldGhvZHMpO1xuICAgIE9iamVjdC5leHRlbmQoRWxlbWVudCwgRWxlbWVudC5NZXRob2RzLlNpbXVsYXRlZCk7XG4gICAgZGVsZXRlIEVsZW1lbnQuQnlUYWc7XG4gICAgZGVsZXRlIEVsZW1lbnQuU2ltdWxhdGVkO1xuXG4gICAgRWxlbWVudC5leHRlbmQucmVmcmVzaCgpO1xuXG4gICAgRUxFTUVOVF9DQUNIRSA9IHt9O1xuICB9XG5cbiAgT2JqZWN0LmV4dGVuZChHTE9CQUwuRWxlbWVudCwge1xuICAgIGV4dGVuZDogICAgIGV4dGVuZCxcbiAgICBhZGRNZXRob2RzOiBhZGRNZXRob2RzXG4gIH0pO1xuXG4gIGlmIChleHRlbmQgPT09IFByb3RvdHlwZS5LKSB7XG4gICAgR0xPQkFMLkVsZW1lbnQuZXh0ZW5kLnJlZnJlc2ggPSBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbjtcbiAgfSBlbHNlIHtcbiAgICBHTE9CQUwuRWxlbWVudC5leHRlbmQucmVmcmVzaCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKFByb3RvdHlwZS5Ccm93c2VyRmVhdHVyZXMuRWxlbWVudEV4dGVuc2lvbnMpIHJldHVybjtcbiAgICAgIE9iamVjdC5leHRlbmQoTWV0aG9kcywgRWxlbWVudC5NZXRob2RzKTtcbiAgICAgIE9iamVjdC5leHRlbmQoTWV0aG9kcywgRWxlbWVudC5NZXRob2RzLlNpbXVsYXRlZCk7XG5cbiAgICAgIEVYVEVOREVEID0ge307XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEZvcm1NZXRob2RzKCkge1xuICAgIE9iamVjdC5leHRlbmQoRm9ybSwgRm9ybS5NZXRob2RzKTtcbiAgICBPYmplY3QuZXh0ZW5kKEZvcm0uRWxlbWVudCwgRm9ybS5FbGVtZW50Lk1ldGhvZHMpO1xuICAgIE9iamVjdC5leHRlbmQoRWxlbWVudC5NZXRob2RzLkJ5VGFnLCB7XG4gICAgICBcIkZPUk1cIjogICAgIE9iamVjdC5jbG9uZShGb3JtLk1ldGhvZHMpLFxuICAgICAgXCJJTlBVVFwiOiAgICBPYmplY3QuY2xvbmUoRm9ybS5FbGVtZW50Lk1ldGhvZHMpLFxuICAgICAgXCJTRUxFQ1RcIjogICBPYmplY3QuY2xvbmUoRm9ybS5FbGVtZW50Lk1ldGhvZHMpLFxuICAgICAgXCJURVhUQVJFQVwiOiBPYmplY3QuY2xvbmUoRm9ybS5FbGVtZW50Lk1ldGhvZHMpLFxuICAgICAgXCJCVVRUT05cIjogICBPYmplY3QuY2xvbmUoRm9ybS5FbGVtZW50Lk1ldGhvZHMpXG4gICAgfSk7XG4gIH1cblxuICBFbGVtZW50LmFkZE1ldGhvZHMobWV0aG9kcyk7XG5cbiAgZnVuY3Rpb24gZGVzdHJveUNhY2hlX0lFKCkge1xuICAgIERJViA9IG51bGw7XG4gICAgRUxFTUVOVF9DQUNIRSA9IG51bGw7XG4gIH1cblxuICBpZiAod2luZG93LmF0dGFjaEV2ZW50KVxuICAgIHdpbmRvdy5hdHRhY2hFdmVudCgnb251bmxvYWQnLCBkZXN0cm95Q2FjaGVfSUUpO1xuXG59KSh0aGlzKTtcbihmdW5jdGlvbigpIHtcblxuICBmdW5jdGlvbiB0b0RlY2ltYWwocGN0U3RyaW5nKSB7XG4gICAgdmFyIG1hdGNoID0gcGN0U3RyaW5nLm1hdGNoKC9eKFxcZCspJT8kL2kpO1xuICAgIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuICAgIHJldHVybiAoTnVtYmVyKG1hdGNoWzFdKSAvIDEwMCk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRSYXdTdHlsZShlbGVtZW50LCBzdHlsZSkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuXG4gICAgdmFyIHZhbHVlID0gZWxlbWVudC5zdHlsZVtzdHlsZV07XG4gICAgaWYgKCF2YWx1ZSB8fCB2YWx1ZSA9PT0gJ2F1dG8nKSB7XG4gICAgICB2YXIgY3NzID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50LCBudWxsKTtcbiAgICAgIHZhbHVlID0gY3NzID8gY3NzW3N0eWxlXSA6IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHN0eWxlID09PSAnb3BhY2l0eScpIHJldHVybiB2YWx1ZSA/IHBhcnNlRmxvYXQodmFsdWUpIDogMS4wO1xuICAgIHJldHVybiB2YWx1ZSA9PT0gJ2F1dG8nID8gbnVsbCA6IHZhbHVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0UmF3U3R5bGVfSUUoZWxlbWVudCwgc3R5bGUpIHtcbiAgICB2YXIgdmFsdWUgPSBlbGVtZW50LnN0eWxlW3N0eWxlXTtcbiAgICBpZiAoIXZhbHVlICYmIGVsZW1lbnQuY3VycmVudFN0eWxlKSB7XG4gICAgICB2YWx1ZSA9IGVsZW1lbnQuY3VycmVudFN0eWxlW3N0eWxlXTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0Q29udGVudFdpZHRoKGVsZW1lbnQsIGNvbnRleHQpIHtcbiAgICB2YXIgYm94V2lkdGggPSBlbGVtZW50Lm9mZnNldFdpZHRoO1xuXG4gICAgdmFyIGJsID0gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnYm9yZGVyTGVmdFdpZHRoJywgIGNvbnRleHQpIHx8IDA7XG4gICAgdmFyIGJyID0gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnYm9yZGVyUmlnaHRXaWR0aCcsIGNvbnRleHQpIHx8IDA7XG4gICAgdmFyIHBsID0gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAncGFkZGluZ0xlZnQnLCAgICAgIGNvbnRleHQpIHx8IDA7XG4gICAgdmFyIHByID0gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAncGFkZGluZ1JpZ2h0JywgICAgIGNvbnRleHQpIHx8IDA7XG5cbiAgICByZXR1cm4gYm94V2lkdGggLSBibCAtIGJyIC0gcGwgLSBwcjtcbiAgfVxuXG4gIGlmICgnY3VycmVudFN0eWxlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICBnZXRSYXdTdHlsZSA9IGdldFJhd1N0eWxlX0lFO1xuICB9XG5cblxuICBmdW5jdGlvbiBnZXRQaXhlbFZhbHVlKHZhbHVlLCBwcm9wZXJ0eSwgY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gbnVsbDtcbiAgICBpZiAoT2JqZWN0LmlzRWxlbWVudCh2YWx1ZSkpIHtcbiAgICAgIGVsZW1lbnQgPSB2YWx1ZTtcbiAgICAgIHZhbHVlID0gZ2V0UmF3U3R5bGUoZWxlbWVudCwgcHJvcGVydHkpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCBPYmplY3QuaXNVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoKC9eKD86LSk/XFxkKyhcXC5cXGQrKT8ocHgpPyQvaSkudGVzdCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB3aW5kb3cucGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgdmFyIGlzUGVyY2VudGFnZSA9IHZhbHVlLmluY2x1ZGUoJyUnKSwgaXNWaWV3cG9ydCA9IChjb250ZXh0ID09PSBkb2N1bWVudC52aWV3cG9ydCk7XG5cbiAgICBpZiAoL1xcZC8udGVzdCh2YWx1ZSkgJiYgZWxlbWVudCAmJiBlbGVtZW50LnJ1bnRpbWVTdHlsZSAmJiAhKGlzUGVyY2VudGFnZSAmJiBpc1ZpZXdwb3J0KSkge1xuICAgICAgdmFyIHN0eWxlID0gZWxlbWVudC5zdHlsZS5sZWZ0LCByU3R5bGUgPSBlbGVtZW50LnJ1bnRpbWVTdHlsZS5sZWZ0O1xuICAgICAgZWxlbWVudC5ydW50aW1lU3R5bGUubGVmdCA9IGVsZW1lbnQuY3VycmVudFN0eWxlLmxlZnQ7XG4gICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSB2YWx1ZSB8fCAwO1xuICAgICAgdmFsdWUgPSBlbGVtZW50LnN0eWxlLnBpeGVsTGVmdDtcbiAgICAgIGVsZW1lbnQuc3R5bGUubGVmdCA9IHN0eWxlO1xuICAgICAgZWxlbWVudC5ydW50aW1lU3R5bGUubGVmdCA9IHJTdHlsZTtcblxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50ICYmIGlzUGVyY2VudGFnZSkge1xuICAgICAgY29udGV4dCA9IGNvbnRleHQgfHwgZWxlbWVudC5wYXJlbnROb2RlO1xuICAgICAgdmFyIGRlY2ltYWwgPSB0b0RlY2ltYWwodmFsdWUpLCB3aG9sZSA9IG51bGw7XG5cbiAgICAgIHZhciBpc0hvcml6b250YWwgPSBwcm9wZXJ0eS5pbmNsdWRlKCdsZWZ0JykgfHwgcHJvcGVydHkuaW5jbHVkZSgncmlnaHQnKSB8fFxuICAgICAgIHByb3BlcnR5LmluY2x1ZGUoJ3dpZHRoJyk7XG5cbiAgICAgIHZhciBpc1ZlcnRpY2FsICAgPSBwcm9wZXJ0eS5pbmNsdWRlKCd0b3AnKSB8fCBwcm9wZXJ0eS5pbmNsdWRlKCdib3R0b20nKSB8fFxuICAgICAgICBwcm9wZXJ0eS5pbmNsdWRlKCdoZWlnaHQnKTtcblxuICAgICAgaWYgKGNvbnRleHQgPT09IGRvY3VtZW50LnZpZXdwb3J0KSB7XG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICB3aG9sZSA9IGRvY3VtZW50LnZpZXdwb3J0LmdldFdpZHRoKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNWZXJ0aWNhbCkge1xuICAgICAgICAgIHdob2xlID0gZG9jdW1lbnQudmlld3BvcnQuZ2V0SGVpZ2h0KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICB3aG9sZSA9ICQoY29udGV4dCkubWVhc3VyZSgnd2lkdGgnKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc1ZlcnRpY2FsKSB7XG4gICAgICAgICAgd2hvbGUgPSAkKGNvbnRleHQpLm1lYXN1cmUoJ2hlaWdodCcpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiAod2hvbGUgPT09IG51bGwpID8gMCA6IHdob2xlICogZGVjaW1hbDtcbiAgICB9XG5cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRvQ1NTUGl4ZWxzKG51bWJlcikge1xuICAgIGlmIChPYmplY3QuaXNTdHJpbmcobnVtYmVyKSAmJiBudW1iZXIuZW5kc1dpdGgoJ3B4JykpXG4gICAgICByZXR1cm4gbnVtYmVyO1xuICAgIHJldHVybiBudW1iZXIgKyAncHgnO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNEaXNwbGF5ZWQoZWxlbWVudCkge1xuICAgIHdoaWxlIChlbGVtZW50ICYmIGVsZW1lbnQucGFyZW50Tm9kZSkge1xuICAgICAgdmFyIGRpc3BsYXkgPSBlbGVtZW50LmdldFN0eWxlKCdkaXNwbGF5Jyk7XG4gICAgICBpZiAoZGlzcGxheSA9PT0gJ25vbmUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQucGFyZW50Tm9kZSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgdmFyIGhhc0xheW91dCA9IFByb3RvdHlwZS5LO1xuICBpZiAoJ2N1cnJlbnRTdHlsZScgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgaGFzTGF5b3V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgaWYgKCFlbGVtZW50LmN1cnJlbnRTdHlsZS5oYXNMYXlvdXQpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS56b29tID0gMTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBjc3NOYW1lRm9yKGtleSkge1xuICAgIGlmIChrZXkuaW5jbHVkZSgnYm9yZGVyJykpIGtleSA9IGtleSArICctd2lkdGgnO1xuICAgIHJldHVybiBrZXkuY2FtZWxpemUoKTtcbiAgfVxuXG4gIEVsZW1lbnQuTGF5b3V0ID0gQ2xhc3MuY3JlYXRlKEhhc2gsIHtcbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbigkc3VwZXIsIGVsZW1lbnQsIHByZUNvbXB1dGUpIHtcbiAgICAgICRzdXBlcigpO1xuICAgICAgdGhpcy5lbGVtZW50ID0gJChlbGVtZW50KTtcblxuICAgICAgRWxlbWVudC5MYXlvdXQuUFJPUEVSVElFUy5lYWNoKCBmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgICAgICB0aGlzLl9zZXQocHJvcGVydHksIG51bGwpO1xuICAgICAgfSwgdGhpcyk7XG5cbiAgICAgIGlmIChwcmVDb21wdXRlKSB7XG4gICAgICAgIHRoaXMuX3ByZUNvbXB1dGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuX2JlZ2luKCk7XG4gICAgICAgIEVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuZWFjaCggdGhpcy5fY29tcHV0ZSwgdGhpcyApO1xuICAgICAgICB0aGlzLl9lbmQoKTtcbiAgICAgICAgdGhpcy5fcHJlQ29tcHV0aW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSxcblxuICAgIF9zZXQ6IGZ1bmN0aW9uKHByb3BlcnR5LCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIEhhc2gucHJvdG90eXBlLnNldC5jYWxsKHRoaXMsIHByb3BlcnR5LCB2YWx1ZSk7XG4gICAgfSxcblxuICAgIHNldDogZnVuY3Rpb24ocHJvcGVydHksIHZhbHVlKSB7XG4gICAgICB0aHJvdyBcIlByb3BlcnRpZXMgb2YgRWxlbWVudC5MYXlvdXQgYXJlIHJlYWQtb25seS5cIjtcbiAgICB9LFxuXG4gICAgZ2V0OiBmdW5jdGlvbigkc3VwZXIsIHByb3BlcnR5KSB7XG4gICAgICB2YXIgdmFsdWUgPSAkc3VwZXIocHJvcGVydHkpO1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsID8gdGhpcy5fY29tcHV0ZShwcm9wZXJ0eSkgOiB2YWx1ZTtcbiAgICB9LFxuXG4gICAgX2JlZ2luOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLl9pc1ByZXBhcmVkKCkpIHJldHVybjtcblxuICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICBpZiAoaXNEaXNwbGF5ZWQoZWxlbWVudCkpIHtcbiAgICAgICAgdGhpcy5fc2V0UHJlcGFyZWQodHJ1ZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuXG4gICAgICB2YXIgb3JpZ2luYWxTdHlsZXMgPSB7XG4gICAgICAgIHBvc2l0aW9uOiAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gICB8fCAnJyxcbiAgICAgICAgd2lkdGg6ICAgICAgZWxlbWVudC5zdHlsZS53aWR0aCAgICAgIHx8ICcnLFxuICAgICAgICB2aXNpYmlsaXR5OiBlbGVtZW50LnN0eWxlLnZpc2liaWxpdHkgfHwgJycsXG4gICAgICAgIGRpc3BsYXk6ICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSAgICB8fCAnJ1xuICAgICAgfTtcblxuICAgICAgZWxlbWVudC5zdG9yZSgncHJvdG90eXBlX29yaWdpbmFsX3N0eWxlcycsIG9yaWdpbmFsU3R5bGVzKTtcblxuICAgICAgdmFyIHBvc2l0aW9uID0gZ2V0UmF3U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJyksIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcblxuICAgICAgaWYgKHdpZHRoID09PSAwIHx8IHdpZHRoID09PSBudWxsKSB7XG4gICAgICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG4gICAgICAgIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSAocG9zaXRpb24gPT09ICdmaXhlZCcpID8gZG9jdW1lbnQudmlld3BvcnQgOlxuICAgICAgIGVsZW1lbnQucGFyZW50Tm9kZTtcblxuICAgICAgdmFyIHRlbXBTdHlsZXMgPSB7XG4gICAgICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICBkaXNwbGF5OiAgICAnYmxvY2snXG4gICAgICB9O1xuXG4gICAgICBpZiAocG9zaXRpb24gIT09ICdmaXhlZCcpIHRlbXBTdHlsZXMucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuXG4gICAgICBlbGVtZW50LnNldFN0eWxlKHRlbXBTdHlsZXMpO1xuXG4gICAgICB2YXIgcG9zaXRpb25lZFdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aCwgbmV3V2lkdGg7XG4gICAgICBpZiAod2lkdGggJiYgKHBvc2l0aW9uZWRXaWR0aCA9PT0gd2lkdGgpKSB7XG4gICAgICAgIG5ld1dpZHRoID0gZ2V0Q29udGVudFdpZHRoKGVsZW1lbnQsIGNvbnRleHQpO1xuICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2Fic29sdXRlJyB8fCBwb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xuICAgICAgICBuZXdXaWR0aCA9IGdldENvbnRlbnRXaWR0aChlbGVtZW50LCBjb250ZXh0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGUsIHBMYXlvdXQgPSAkKHBhcmVudCkuZ2V0TGF5b3V0KCk7XG5cbiAgICAgICAgbmV3V2lkdGggPSBwTGF5b3V0LmdldCgnd2lkdGgnKSAtXG4gICAgICAgICB0aGlzLmdldCgnbWFyZ2luLWxlZnQnKSAtXG4gICAgICAgICB0aGlzLmdldCgnYm9yZGVyLWxlZnQnKSAtXG4gICAgICAgICB0aGlzLmdldCgncGFkZGluZy1sZWZ0JykgLVxuICAgICAgICAgdGhpcy5nZXQoJ3BhZGRpbmctcmlnaHQnKSAtXG4gICAgICAgICB0aGlzLmdldCgnYm9yZGVyLXJpZ2h0JykgLVxuICAgICAgICAgdGhpcy5nZXQoJ21hcmdpbi1yaWdodCcpO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50LnNldFN0eWxlKHsgd2lkdGg6IG5ld1dpZHRoICsgJ3B4JyB9KTtcblxuICAgICAgdGhpcy5fc2V0UHJlcGFyZWQodHJ1ZSk7XG4gICAgfSxcblxuICAgIF9lbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG4gICAgICB2YXIgb3JpZ2luYWxTdHlsZXMgPSBlbGVtZW50LnJldHJpZXZlKCdwcm90b3R5cGVfb3JpZ2luYWxfc3R5bGVzJyk7XG4gICAgICBlbGVtZW50LnN0b3JlKCdwcm90b3R5cGVfb3JpZ2luYWxfc3R5bGVzJywgbnVsbCk7XG4gICAgICBlbGVtZW50LnNldFN0eWxlKG9yaWdpbmFsU3R5bGVzKTtcbiAgICAgIHRoaXMuX3NldFByZXBhcmVkKGZhbHNlKTtcbiAgICB9LFxuXG4gICAgX2NvbXB1dGU6IGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgICB2YXIgQ09NUFVUQVRJT05TID0gRWxlbWVudC5MYXlvdXQuQ09NUFVUQVRJT05TO1xuICAgICAgaWYgKCEocHJvcGVydHkgaW4gQ09NUFVUQVRJT05TKSkge1xuICAgICAgICB0aHJvdyBcIlByb3BlcnR5IG5vdCBmb3VuZC5cIjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX3NldChwcm9wZXJ0eSwgQ09NUFVUQVRJT05TW3Byb3BlcnR5XS5jYWxsKHRoaXMsIHRoaXMuZWxlbWVudCkpO1xuICAgIH0sXG5cbiAgICBfaXNQcmVwYXJlZDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5lbGVtZW50LnJldHJpZXZlKCdwcm90b3R5cGVfZWxlbWVudF9sYXlvdXRfcHJlcGFyZWQnLCBmYWxzZSk7XG4gICAgfSxcblxuICAgIF9zZXRQcmVwYXJlZDogZnVuY3Rpb24oYm9vbCkge1xuICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC5zdG9yZSgncHJvdG90eXBlX2VsZW1lbnRfbGF5b3V0X3ByZXBhcmVkJywgYm9vbCk7XG4gICAgfSxcblxuICAgIHRvT2JqZWN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhcmdzID0gJEEoYXJndW1lbnRzKTtcbiAgICAgIHZhciBrZXlzID0gKGFyZ3MubGVuZ3RoID09PSAwKSA/IEVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMgOlxuICAgICAgIGFyZ3Muam9pbignICcpLnNwbGl0KCcgJyk7XG4gICAgICB2YXIgb2JqID0ge307XG4gICAgICBrZXlzLmVhY2goIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoIUVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuaW5jbHVkZShrZXkpKSByZXR1cm47XG4gICAgICAgIHZhciB2YWx1ZSA9IHRoaXMuZ2V0KGtleSk7XG4gICAgICAgIGlmICh2YWx1ZSAhPSBudWxsKSBvYmpba2V5XSA9IHZhbHVlO1xuICAgICAgfSwgdGhpcyk7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH0sXG5cbiAgICB0b0hhc2g6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG9iaiA9IHRoaXMudG9PYmplY3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiBuZXcgSGFzaChvYmopO1xuICAgIH0sXG5cbiAgICB0b0NTUzogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cyk7XG4gICAgICB2YXIga2V5cyA9IChhcmdzLmxlbmd0aCA9PT0gMCkgPyBFbGVtZW50LkxheW91dC5QUk9QRVJUSUVTIDpcbiAgICAgICBhcmdzLmpvaW4oJyAnKS5zcGxpdCgnICcpO1xuICAgICAgdmFyIGNzcyA9IHt9O1xuXG4gICAgICBrZXlzLmVhY2goIGZ1bmN0aW9uKGtleSkge1xuICAgICAgICBpZiAoIUVsZW1lbnQuTGF5b3V0LlBST1BFUlRJRVMuaW5jbHVkZShrZXkpKSByZXR1cm47XG4gICAgICAgIGlmIChFbGVtZW50LkxheW91dC5DT01QT1NJVEVfUFJPUEVSVElFUy5pbmNsdWRlKGtleSkpIHJldHVybjtcblxuICAgICAgICB2YXIgdmFsdWUgPSB0aGlzLmdldChrZXkpO1xuICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCkgY3NzW2Nzc05hbWVGb3Ioa2V5KV0gPSB2YWx1ZSArICdweCc7XG4gICAgICB9LCB0aGlzKTtcbiAgICAgIHJldHVybiBjc3M7XG4gICAgfSxcblxuICAgIGluc3BlY3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiIzxFbGVtZW50LkxheW91dD5cIjtcbiAgICB9XG4gIH0pO1xuXG4gIE9iamVjdC5leHRlbmQoRWxlbWVudC5MYXlvdXQsIHtcbiAgICBQUk9QRVJUSUVTOiAkdygnaGVpZ2h0IHdpZHRoIHRvcCBsZWZ0IHJpZ2h0IGJvdHRvbSBib3JkZXItbGVmdCBib3JkZXItcmlnaHQgYm9yZGVyLXRvcCBib3JkZXItYm90dG9tIHBhZGRpbmctbGVmdCBwYWRkaW5nLXJpZ2h0IHBhZGRpbmctdG9wIHBhZGRpbmctYm90dG9tIG1hcmdpbi10b3AgbWFyZ2luLWJvdHRvbSBtYXJnaW4tbGVmdCBtYXJnaW4tcmlnaHQgcGFkZGluZy1ib3gtd2lkdGggcGFkZGluZy1ib3gtaGVpZ2h0IGJvcmRlci1ib3gtd2lkdGggYm9yZGVyLWJveC1oZWlnaHQgbWFyZ2luLWJveC13aWR0aCBtYXJnaW4tYm94LWhlaWdodCcpLFxuXG4gICAgQ09NUE9TSVRFX1BST1BFUlRJRVM6ICR3KCdwYWRkaW5nLWJveC13aWR0aCBwYWRkaW5nLWJveC1oZWlnaHQgbWFyZ2luLWJveC13aWR0aCBtYXJnaW4tYm94LWhlaWdodCBib3JkZXItYm94LXdpZHRoIGJvcmRlci1ib3gtaGVpZ2h0JyksXG5cbiAgICBDT01QVVRBVElPTlM6IHtcbiAgICAgICdoZWlnaHQnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9iZWdpbigpO1xuXG4gICAgICAgIHZhciBiSGVpZ2h0ID0gdGhpcy5nZXQoJ2JvcmRlci1ib3gtaGVpZ2h0Jyk7XG4gICAgICAgIGlmIChiSGVpZ2h0IDw9IDApIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fZW5kKCk7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYlRvcCA9IHRoaXMuZ2V0KCdib3JkZXItdG9wJyksXG4gICAgICAgICBiQm90dG9tID0gdGhpcy5nZXQoJ2JvcmRlci1ib3R0b20nKTtcblxuICAgICAgICB2YXIgcFRvcCA9IHRoaXMuZ2V0KCdwYWRkaW5nLXRvcCcpLFxuICAgICAgICAgcEJvdHRvbSA9IHRoaXMuZ2V0KCdwYWRkaW5nLWJvdHRvbScpO1xuXG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9lbmQoKTtcblxuICAgICAgICByZXR1cm4gYkhlaWdodCAtIGJUb3AgLSBiQm90dG9tIC0gcFRvcCAtIHBCb3R0b207XG4gICAgICB9LFxuXG4gICAgICAnd2lkdGgnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9iZWdpbigpO1xuXG4gICAgICAgIHZhciBiV2lkdGggPSB0aGlzLmdldCgnYm9yZGVyLWJveC13aWR0aCcpO1xuICAgICAgICBpZiAoYldpZHRoIDw9IDApIHtcbiAgICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fZW5kKCk7XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgYkxlZnQgPSB0aGlzLmdldCgnYm9yZGVyLWxlZnQnKSxcbiAgICAgICAgIGJSaWdodCA9IHRoaXMuZ2V0KCdib3JkZXItcmlnaHQnKTtcblxuICAgICAgICB2YXIgcExlZnQgPSB0aGlzLmdldCgncGFkZGluZy1sZWZ0JyksXG4gICAgICAgICBwUmlnaHQgPSB0aGlzLmdldCgncGFkZGluZy1yaWdodCcpO1xuXG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9lbmQoKTtcbiAgICAgICAgcmV0dXJuIGJXaWR0aCAtIGJMZWZ0IC0gYlJpZ2h0IC0gcExlZnQgLSBwUmlnaHQ7XG4gICAgICB9LFxuXG4gICAgICAncGFkZGluZy1ib3gtaGVpZ2h0JzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICB2YXIgaGVpZ2h0ID0gdGhpcy5nZXQoJ2hlaWdodCcpLFxuICAgICAgICAgcFRvcCA9IHRoaXMuZ2V0KCdwYWRkaW5nLXRvcCcpLFxuICAgICAgICAgcEJvdHRvbSA9IHRoaXMuZ2V0KCdwYWRkaW5nLWJvdHRvbScpO1xuXG4gICAgICAgIHJldHVybiBoZWlnaHQgKyBwVG9wICsgcEJvdHRvbTtcbiAgICAgIH0sXG5cbiAgICAgICdwYWRkaW5nLWJveC13aWR0aCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHdpZHRoID0gdGhpcy5nZXQoJ3dpZHRoJyksXG4gICAgICAgICBwTGVmdCA9IHRoaXMuZ2V0KCdwYWRkaW5nLWxlZnQnKSxcbiAgICAgICAgIHBSaWdodCA9IHRoaXMuZ2V0KCdwYWRkaW5nLXJpZ2h0Jyk7XG5cbiAgICAgICAgcmV0dXJuIHdpZHRoICsgcExlZnQgKyBwUmlnaHQ7XG4gICAgICB9LFxuXG4gICAgICAnYm9yZGVyLWJveC1oZWlnaHQnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9iZWdpbigpO1xuICAgICAgICB2YXIgaGVpZ2h0ID0gZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIGlmICghdGhpcy5fcHJlQ29tcHV0aW5nKSB0aGlzLl9lbmQoKTtcbiAgICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICAgIH0sXG5cbiAgICAgICdib3JkZXItYm94LXdpZHRoJzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICBpZiAoIXRoaXMuX3ByZUNvbXB1dGluZykgdGhpcy5fYmVnaW4oKTtcbiAgICAgICAgdmFyIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgICAgaWYgKCF0aGlzLl9wcmVDb21wdXRpbmcpIHRoaXMuX2VuZCgpO1xuICAgICAgICByZXR1cm4gd2lkdGg7XG4gICAgICB9LFxuXG4gICAgICAnbWFyZ2luLWJveC1oZWlnaHQnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIHZhciBiSGVpZ2h0ID0gdGhpcy5nZXQoJ2JvcmRlci1ib3gtaGVpZ2h0JyksXG4gICAgICAgICBtVG9wID0gdGhpcy5nZXQoJ21hcmdpbi10b3AnKSxcbiAgICAgICAgIG1Cb3R0b20gPSB0aGlzLmdldCgnbWFyZ2luLWJvdHRvbScpO1xuXG4gICAgICAgIGlmIChiSGVpZ2h0IDw9IDApIHJldHVybiAwO1xuXG4gICAgICAgIHJldHVybiBiSGVpZ2h0ICsgbVRvcCArIG1Cb3R0b207XG4gICAgICB9LFxuXG4gICAgICAnbWFyZ2luLWJveC13aWR0aCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIGJXaWR0aCA9IHRoaXMuZ2V0KCdib3JkZXItYm94LXdpZHRoJyksXG4gICAgICAgICBtTGVmdCA9IHRoaXMuZ2V0KCdtYXJnaW4tbGVmdCcpLFxuICAgICAgICAgbVJpZ2h0ID0gdGhpcy5nZXQoJ21hcmdpbi1yaWdodCcpO1xuXG4gICAgICAgIGlmIChiV2lkdGggPD0gMCkgcmV0dXJuIDA7XG5cbiAgICAgICAgcmV0dXJuIGJXaWR0aCArIG1MZWZ0ICsgbVJpZ2h0O1xuICAgICAgfSxcblxuICAgICAgJ3RvcCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IGVsZW1lbnQucG9zaXRpb25lZE9mZnNldCgpO1xuICAgICAgICByZXR1cm4gb2Zmc2V0LnRvcDtcbiAgICAgIH0sXG5cbiAgICAgICdib3R0b20nOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIHZhciBvZmZzZXQgPSBlbGVtZW50LnBvc2l0aW9uZWRPZmZzZXQoKSxcbiAgICAgICAgIHBhcmVudCA9IGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCksXG4gICAgICAgICBwSGVpZ2h0ID0gcGFyZW50Lm1lYXN1cmUoJ2hlaWdodCcpO1xuXG4gICAgICAgIHZhciBtSGVpZ2h0ID0gdGhpcy5nZXQoJ2JvcmRlci1ib3gtaGVpZ2h0Jyk7XG5cbiAgICAgICAgcmV0dXJuIHBIZWlnaHQgLSBtSGVpZ2h0IC0gb2Zmc2V0LnRvcDtcbiAgICAgIH0sXG5cbiAgICAgICdsZWZ0JzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICB2YXIgb2Zmc2V0ID0gZWxlbWVudC5wb3NpdGlvbmVkT2Zmc2V0KCk7XG4gICAgICAgIHJldHVybiBvZmZzZXQubGVmdDtcbiAgICAgIH0sXG5cbiAgICAgICdyaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIG9mZnNldCA9IGVsZW1lbnQucG9zaXRpb25lZE9mZnNldCgpLFxuICAgICAgICAgcGFyZW50ID0gZWxlbWVudC5nZXRPZmZzZXRQYXJlbnQoKSxcbiAgICAgICAgIHBXaWR0aCA9IHBhcmVudC5tZWFzdXJlKCd3aWR0aCcpO1xuXG4gICAgICAgIHZhciBtV2lkdGggPSB0aGlzLmdldCgnYm9yZGVyLWJveC13aWR0aCcpO1xuXG4gICAgICAgIHJldHVybiBwV2lkdGggLSBtV2lkdGggLSBvZmZzZXQubGVmdDtcbiAgICAgIH0sXG5cbiAgICAgICdwYWRkaW5nLXRvcCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ3BhZGRpbmdUb3AnKTtcbiAgICAgIH0sXG5cbiAgICAgICdwYWRkaW5nLWJvdHRvbSc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ3BhZGRpbmdCb3R0b20nKTtcbiAgICAgIH0sXG5cbiAgICAgICdwYWRkaW5nLWxlZnQnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdwYWRkaW5nTGVmdCcpO1xuICAgICAgfSxcblxuICAgICAgJ3BhZGRpbmctcmlnaHQnOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgIHJldHVybiBnZXRQaXhlbFZhbHVlKGVsZW1lbnQsICdwYWRkaW5nUmlnaHQnKTtcbiAgICAgIH0sXG5cbiAgICAgICdib3JkZXItdG9wJzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnYm9yZGVyVG9wV2lkdGgnKTtcbiAgICAgIH0sXG5cbiAgICAgICdib3JkZXItYm90dG9tJzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnYm9yZGVyQm90dG9tV2lkdGgnKTtcbiAgICAgIH0sXG5cbiAgICAgICdib3JkZXItbGVmdCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ2JvcmRlckxlZnRXaWR0aCcpO1xuICAgICAgfSxcblxuICAgICAgJ2JvcmRlci1yaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ2JvcmRlclJpZ2h0V2lkdGgnKTtcbiAgICAgIH0sXG5cbiAgICAgICdtYXJnaW4tdG9wJzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnbWFyZ2luVG9wJyk7XG4gICAgICB9LFxuXG4gICAgICAnbWFyZ2luLWJvdHRvbSc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ21hcmdpbkJvdHRvbScpO1xuICAgICAgfSxcblxuICAgICAgJ21hcmdpbi1sZWZ0JzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZ2V0UGl4ZWxWYWx1ZShlbGVtZW50LCAnbWFyZ2luTGVmdCcpO1xuICAgICAgfSxcblxuICAgICAgJ21hcmdpbi1yaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIGdldFBpeGVsVmFsdWUoZWxlbWVudCwgJ21hcmdpblJpZ2h0Jyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBpZiAoJ2dldEJvdW5kaW5nQ2xpZW50UmVjdCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgT2JqZWN0LmV4dGVuZChFbGVtZW50LkxheW91dC5DT01QVVRBVElPTlMsIHtcbiAgICAgICdyaWdodCc6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IGhhc0xheW91dChlbGVtZW50LmdldE9mZnNldFBhcmVudCgpKTtcbiAgICAgICAgdmFyIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICAgcFJlY3QgPSBwYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgICAgcmV0dXJuIChwUmVjdC5yaWdodCAtIHJlY3QucmlnaHQpLnJvdW5kKCk7XG4gICAgICB9LFxuXG4gICAgICAnYm90dG9tJzogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICB2YXIgcGFyZW50ID0gaGFzTGF5b3V0KGVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KCkpO1xuICAgICAgICB2YXIgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICAgICBwUmVjdCA9IHBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICByZXR1cm4gKHBSZWN0LmJvdHRvbSAtIHJlY3QuYm90dG9tKS5yb3VuZCgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgRWxlbWVudC5PZmZzZXQgPSBDbGFzcy5jcmVhdGUoe1xuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKGxlZnQsIHRvcCkge1xuICAgICAgdGhpcy5sZWZ0ID0gbGVmdC5yb3VuZCgpO1xuICAgICAgdGhpcy50b3AgID0gdG9wLnJvdW5kKCk7XG5cbiAgICAgIHRoaXNbMF0gPSB0aGlzLmxlZnQ7XG4gICAgICB0aGlzWzFdID0gdGhpcy50b3A7XG4gICAgfSxcblxuICAgIHJlbGF0aXZlVG86IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldChcbiAgICAgICAgdGhpcy5sZWZ0IC0gb2Zmc2V0LmxlZnQsXG4gICAgICAgIHRoaXMudG9wICAtIG9mZnNldC50b3BcbiAgICAgICk7XG4gICAgfSxcblxuICAgIGluc3BlY3Q6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIFwiIzxFbGVtZW50Lk9mZnNldCBsZWZ0OiAje2xlZnR9IHRvcDogI3t0b3B9PlwiLmludGVycG9sYXRlKHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gXCJbI3tsZWZ0fSwgI3t0b3B9XVwiLmludGVycG9sYXRlKHRoaXMpO1xuICAgIH0sXG5cbiAgICB0b0FycmF5OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBbdGhpcy5sZWZ0LCB0aGlzLnRvcF07XG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBnZXRMYXlvdXQoZWxlbWVudCwgcHJlQ29tcHV0ZSkge1xuICAgIHJldHVybiBuZXcgRWxlbWVudC5MYXlvdXQoZWxlbWVudCwgcHJlQ29tcHV0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiBtZWFzdXJlKGVsZW1lbnQsIHByb3BlcnR5KSB7XG4gICAgcmV0dXJuICQoZWxlbWVudCkuZ2V0TGF5b3V0KCkuZ2V0KHByb3BlcnR5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEhlaWdodChlbGVtZW50KSB7XG4gICAgcmV0dXJuIEVsZW1lbnQuZ2V0RGltZW5zaW9ucyhlbGVtZW50KS5oZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRXaWR0aChlbGVtZW50KSB7XG4gICAgcmV0dXJuIEVsZW1lbnQuZ2V0RGltZW5zaW9ucyhlbGVtZW50KS53aWR0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERpbWVuc2lvbnMoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBkaXNwbGF5ID0gRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAnZGlzcGxheScpO1xuXG4gICAgaWYgKGRpc3BsYXkgJiYgZGlzcGxheSAhPT0gJ25vbmUnKSB7XG4gICAgICByZXR1cm4geyB3aWR0aDogZWxlbWVudC5vZmZzZXRXaWR0aCwgaGVpZ2h0OiBlbGVtZW50Lm9mZnNldEhlaWdodCB9O1xuICAgIH1cblxuICAgIHZhciBzdHlsZSA9IGVsZW1lbnQuc3R5bGU7XG4gICAgdmFyIG9yaWdpbmFsU3R5bGVzID0ge1xuICAgICAgdmlzaWJpbGl0eTogc3R5bGUudmlzaWJpbGl0eSxcbiAgICAgIHBvc2l0aW9uOiAgIHN0eWxlLnBvc2l0aW9uLFxuICAgICAgZGlzcGxheTogICAgc3R5bGUuZGlzcGxheVxuICAgIH07XG5cbiAgICB2YXIgbmV3U3R5bGVzID0ge1xuICAgICAgdmlzaWJpbGl0eTogJ2hpZGRlbicsXG4gICAgICBkaXNwbGF5OiAgICAnYmxvY2snXG4gICAgfTtcblxuICAgIGlmIChvcmlnaW5hbFN0eWxlcy5wb3NpdGlvbiAhPT0gJ2ZpeGVkJylcbiAgICAgIG5ld1N0eWxlcy5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG5cbiAgICBFbGVtZW50LnNldFN0eWxlKGVsZW1lbnQsIG5ld1N0eWxlcyk7XG5cbiAgICB2YXIgZGltZW5zaW9ucyA9IHtcbiAgICAgIHdpZHRoOiAgZWxlbWVudC5vZmZzZXRXaWR0aCxcbiAgICAgIGhlaWdodDogZWxlbWVudC5vZmZzZXRIZWlnaHRcbiAgICB9O1xuXG4gICAgRWxlbWVudC5zZXRTdHlsZShlbGVtZW50LCBvcmlnaW5hbFN0eWxlcyk7XG5cbiAgICByZXR1cm4gZGltZW5zaW9ucztcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICBpZiAoaXNEb2N1bWVudChlbGVtZW50KSB8fCBpc0RldGFjaGVkKGVsZW1lbnQpIHx8IGlzQm9keShlbGVtZW50KSB8fCBpc0h0bWwoZWxlbWVudCkpXG4gICAgICByZXR1cm4gJChkb2N1bWVudC5ib2R5KTtcblxuICAgIHZhciBpc0lubGluZSA9IChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdkaXNwbGF5JykgPT09ICdpbmxpbmUnKTtcbiAgICBpZiAoIWlzSW5saW5lICYmIGVsZW1lbnQub2Zmc2V0UGFyZW50KSByZXR1cm4gJChlbGVtZW50Lm9mZnNldFBhcmVudCk7XG5cbiAgICB3aGlsZSAoKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGUpICYmIGVsZW1lbnQgIT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgIGlmIChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpICE9PSAnc3RhdGljJykge1xuICAgICAgICByZXR1cm4gaXNIdG1sKGVsZW1lbnQpID8gJChkb2N1bWVudC5ib2R5KSA6ICQoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuICQoZG9jdW1lbnQuYm9keSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIGN1bXVsYXRpdmVPZmZzZXQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciB2YWx1ZVQgPSAwLCB2YWx1ZUwgPSAwO1xuICAgIGlmIChlbGVtZW50LnBhcmVudE5vZGUpIHtcbiAgICAgIGRvIHtcbiAgICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwO1xuICAgICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDtcbiAgICAgIH0gd2hpbGUgKGVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHZhbHVlTCwgdmFsdWVUKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvc2l0aW9uZWRPZmZzZXQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuXG4gICAgdmFyIGxheW91dCA9IGVsZW1lbnQuZ2V0TGF5b3V0KCk7XG5cbiAgICB2YXIgdmFsdWVUID0gMCwgdmFsdWVMID0gMDtcbiAgICBkbyB7XG4gICAgICB2YWx1ZVQgKz0gZWxlbWVudC5vZmZzZXRUb3AgIHx8IDA7XG4gICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7XG4gICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBpZiAoaXNCb2R5KGVsZW1lbnQpKSBicmVhaztcbiAgICAgICAgdmFyIHAgPSBFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpO1xuICAgICAgICBpZiAocCAhPT0gJ3N0YXRpYycpIGJyZWFrO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKGVsZW1lbnQpO1xuXG4gICAgdmFsdWVMIC09IGxheW91dC5nZXQoJ21hcmdpbi10b3AnKTtcbiAgICB2YWx1ZVQgLT0gbGF5b3V0LmdldCgnbWFyZ2luLWxlZnQnKTtcblxuICAgIHJldHVybiBuZXcgRWxlbWVudC5PZmZzZXQodmFsdWVMLCB2YWx1ZVQpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3VtdWxhdGl2ZVNjcm9sbE9mZnNldChlbGVtZW50KSB7XG4gICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDA7XG4gICAgZG8ge1xuICAgICAgaWYgKGVsZW1lbnQgPT09IGRvY3VtZW50LmJvZHkpIHtcbiAgICAgICAgdmFyIGJvZHlTY3JvbGxOb2RlID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkucGFyZW50Tm9kZSB8fCBkb2N1bWVudC5ib2R5O1xuICAgICAgICB2YWx1ZVQgKz0gIU9iamVjdC5pc1VuZGVmaW5lZCh3aW5kb3cucGFnZVlPZmZzZXQpID8gd2luZG93LnBhZ2VZT2Zmc2V0IDogYm9keVNjcm9sbE5vZGUuc2Nyb2xsVG9wIHx8IDA7XG4gICAgICAgIHZhbHVlTCArPSAhT2JqZWN0LmlzVW5kZWZpbmVkKHdpbmRvdy5wYWdlWE9mZnNldCkgPyB3aW5kb3cucGFnZVhPZmZzZXQgOiBib2R5U2Nyb2xsTm9kZS5zY3JvbGxMZWZ0IHx8IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVUICs9IGVsZW1lbnQuc2Nyb2xsVG9wICB8fCAwO1xuICAgICAgICB2YWx1ZUwgKz0gZWxlbWVudC5zY3JvbGxMZWZ0IHx8IDA7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XG4gICAgICB9XG4gICAgfSB3aGlsZSAoZWxlbWVudCk7XG4gICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCh2YWx1ZUwsIHZhbHVlVCk7XG4gIH1cblxuICBmdW5jdGlvbiB2aWV3cG9ydE9mZnNldChmb3JFbGVtZW50KSB7XG4gICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDAsIGRvY0JvZHkgPSBkb2N1bWVudC5ib2R5O1xuXG4gICAgZm9yRWxlbWVudCA9ICQoZm9yRWxlbWVudCk7XG4gICAgdmFyIGVsZW1lbnQgPSBmb3JFbGVtZW50O1xuICAgIGRvIHtcbiAgICAgIHZhbHVlVCArPSBlbGVtZW50Lm9mZnNldFRvcCAgfHwgMDtcbiAgICAgIHZhbHVlTCArPSBlbGVtZW50Lm9mZnNldExlZnQgfHwgMDtcbiAgICAgIGlmIChlbGVtZW50Lm9mZnNldFBhcmVudCA9PSBkb2NCb2R5ICYmXG4gICAgICAgIEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJykgPT0gJ2Fic29sdXRlJykgYnJlYWs7XG4gICAgfSB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50KTtcblxuICAgIGVsZW1lbnQgPSBmb3JFbGVtZW50O1xuICAgIGRvIHtcbiAgICAgIGlmIChlbGVtZW50ICE9IGRvY0JvZHkpIHtcbiAgICAgICAgdmFsdWVUIC09IGVsZW1lbnQuc2Nyb2xsVG9wICB8fCAwO1xuICAgICAgICB2YWx1ZUwgLT0gZWxlbWVudC5zY3JvbGxMZWZ0IHx8IDA7XG4gICAgICB9XG4gICAgfSB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSk7XG4gICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCh2YWx1ZUwsIHZhbHVlVCk7XG4gIH1cblxuICBmdW5jdGlvbiBhYnNvbHV0aXplKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcblxuICAgIGlmIChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpID09PSAnYWJzb2x1dGUnKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICB2YXIgb2Zmc2V0UGFyZW50ID0gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpO1xuICAgIHZhciBlT2Zmc2V0ID0gZWxlbWVudC52aWV3cG9ydE9mZnNldCgpLFxuICAgICBwT2Zmc2V0ID0gb2Zmc2V0UGFyZW50LnZpZXdwb3J0T2Zmc2V0KCk7XG5cbiAgICB2YXIgb2Zmc2V0ID0gZU9mZnNldC5yZWxhdGl2ZVRvKHBPZmZzZXQpO1xuICAgIHZhciBsYXlvdXQgPSBlbGVtZW50LmdldExheW91dCgpO1xuXG4gICAgZWxlbWVudC5zdG9yZSgncHJvdG90eXBlX2Fic29sdXRpemVfb3JpZ2luYWxfc3R5bGVzJywge1xuICAgICAgcG9zaXRpb246IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyksXG4gICAgICBsZWZ0OiAgICAgZWxlbWVudC5nZXRTdHlsZSgnbGVmdCcpLFxuICAgICAgdG9wOiAgICAgIGVsZW1lbnQuZ2V0U3R5bGUoJ3RvcCcpLFxuICAgICAgd2lkdGg6ICAgIGVsZW1lbnQuZ2V0U3R5bGUoJ3dpZHRoJyksXG4gICAgICBoZWlnaHQ6ICAgZWxlbWVudC5nZXRTdHlsZSgnaGVpZ2h0JylcbiAgICB9KTtcblxuICAgIGVsZW1lbnQuc2V0U3R5bGUoe1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICB0b3A6ICAgIG9mZnNldC50b3AgKyAncHgnLFxuICAgICAgbGVmdDogICBvZmZzZXQubGVmdCArICdweCcsXG4gICAgICB3aWR0aDogIGxheW91dC5nZXQoJ3dpZHRoJykgKyAncHgnLFxuICAgICAgaGVpZ2h0OiBsYXlvdXQuZ2V0KCdoZWlnaHQnKSArICdweCdcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVsYXRpdml6ZShlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgaWYgKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJykgPT09ICdyZWxhdGl2ZScpIHtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIHZhciBvcmlnaW5hbFN0eWxlcyA9XG4gICAgIGVsZW1lbnQucmV0cmlldmUoJ3Byb3RvdHlwZV9hYnNvbHV0aXplX29yaWdpbmFsX3N0eWxlcycpO1xuXG4gICAgaWYgKG9yaWdpbmFsU3R5bGVzKSBlbGVtZW50LnNldFN0eWxlKG9yaWdpbmFsU3R5bGVzKTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gc2Nyb2xsVG8oZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBwb3MgPSBFbGVtZW50LmN1bXVsYXRpdmVPZmZzZXQoZWxlbWVudCk7XG4gICAgd2luZG93LnNjcm9sbFRvKHBvcy5sZWZ0LCBwb3MudG9wKTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gbWFrZVBvc2l0aW9uZWQoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBwb3NpdGlvbiA9IEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJyksIHN0eWxlcyA9IHt9O1xuICAgIGlmIChwb3NpdGlvbiA9PT0gJ3N0YXRpYycgfHwgIXBvc2l0aW9uKSB7XG4gICAgICBzdHlsZXMucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgaWYgKFByb3RvdHlwZS5Ccm93c2VyLk9wZXJhKSB7XG4gICAgICAgIHN0eWxlcy50b3AgID0gMDtcbiAgICAgICAgc3R5bGVzLmxlZnQgPSAwO1xuICAgICAgfVxuICAgICAgRWxlbWVudC5zZXRTdHlsZShlbGVtZW50LCBzdHlsZXMpO1xuICAgICAgRWxlbWVudC5zdG9yZShlbGVtZW50LCAncHJvdG90eXBlX21hZGVfcG9zaXRpb25lZCcsIHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVuZG9Qb3NpdGlvbmVkKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICB2YXIgc3RvcmFnZSA9IEVsZW1lbnQuZ2V0U3RvcmFnZShlbGVtZW50KSxcbiAgICAgbWFkZVBvc2l0aW9uZWQgPSBzdG9yYWdlLmdldCgncHJvdG90eXBlX21hZGVfcG9zaXRpb25lZCcpO1xuXG4gICAgaWYgKG1hZGVQb3NpdGlvbmVkKSB7XG4gICAgICBzdG9yYWdlLnVuc2V0KCdwcm90b3R5cGVfbWFkZV9wb3NpdGlvbmVkJyk7XG4gICAgICBFbGVtZW50LnNldFN0eWxlKGVsZW1lbnQsIHtcbiAgICAgICAgcG9zaXRpb246ICcnLFxuICAgICAgICB0b3A6ICAgICAgJycsXG4gICAgICAgIGJvdHRvbTogICAnJyxcbiAgICAgICAgbGVmdDogICAgICcnLFxuICAgICAgICByaWdodDogICAgJydcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1ha2VDbGlwcGluZyhlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICB2YXIgc3RvcmFnZSA9IEVsZW1lbnQuZ2V0U3RvcmFnZShlbGVtZW50KSxcbiAgICAgbWFkZUNsaXBwaW5nID0gc3RvcmFnZS5nZXQoJ3Byb3RvdHlwZV9tYWRlX2NsaXBwaW5nJyk7XG5cbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKG1hZGVDbGlwcGluZykpIHtcbiAgICAgIHZhciBvdmVyZmxvdyA9IEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ292ZXJmbG93Jyk7XG4gICAgICBzdG9yYWdlLnNldCgncHJvdG90eXBlX21hZGVfY2xpcHBpbmcnLCBvdmVyZmxvdyk7XG4gICAgICBpZiAob3ZlcmZsb3cgIT09ICdoaWRkZW4nKVxuICAgICAgICBlbGVtZW50LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbic7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiB1bmRvQ2xpcHBpbmcoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBzdG9yYWdlID0gRWxlbWVudC5nZXRTdG9yYWdlKGVsZW1lbnQpLFxuICAgICBvdmVyZmxvdyA9IHN0b3JhZ2UuZ2V0KCdwcm90b3R5cGVfbWFkZV9jbGlwcGluZycpO1xuXG4gICAgaWYgKCFPYmplY3QuaXNVbmRlZmluZWQob3ZlcmZsb3cpKSB7XG4gICAgICBzdG9yYWdlLnVuc2V0KCdwcm90b3R5cGVfbWFkZV9jbGlwcGluZycpO1xuICAgICAgZWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9IG92ZXJmbG93IHx8ICcnO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gY2xvbmVQb3NpdGlvbihlbGVtZW50LCBzb3VyY2UsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gT2JqZWN0LmV4dGVuZCh7XG4gICAgICBzZXRMZWZ0OiAgICB0cnVlLFxuICAgICAgc2V0VG9wOiAgICAgdHJ1ZSxcbiAgICAgIHNldFdpZHRoOiAgIHRydWUsXG4gICAgICBzZXRIZWlnaHQ6ICB0cnVlLFxuICAgICAgb2Zmc2V0VG9wOiAgMCxcbiAgICAgIG9mZnNldExlZnQ6IDBcbiAgICB9LCBvcHRpb25zIHx8IHt9KTtcblxuICAgIHNvdXJjZSAgPSAkKHNvdXJjZSk7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIHAsIGRlbHRhLCBsYXlvdXQsIHN0eWxlcyA9IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMuc2V0TGVmdCB8fCBvcHRpb25zLnNldFRvcCkge1xuICAgICAgcCA9IEVsZW1lbnQudmlld3BvcnRPZmZzZXQoc291cmNlKTtcbiAgICAgIGRlbHRhID0gWzAsIDBdO1xuICAgICAgaWYgKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJykgPT09ICdhYnNvbHV0ZScpIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IEVsZW1lbnQuZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpO1xuICAgICAgICBpZiAocGFyZW50ICE9PSBkb2N1bWVudC5ib2R5KSBkZWx0YSA9IEVsZW1lbnQudmlld3BvcnRPZmZzZXQocGFyZW50KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zZXRXaWR0aCB8fCBvcHRpb25zLnNldEhlaWdodCkge1xuICAgICAgbGF5b3V0ID0gRWxlbWVudC5nZXRMYXlvdXQoc291cmNlKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5zZXRMZWZ0KVxuICAgICAgc3R5bGVzLmxlZnQgPSAocFswXSAtIGRlbHRhWzBdICsgb3B0aW9ucy5vZmZzZXRMZWZ0KSArICdweCc7XG4gICAgaWYgKG9wdGlvbnMuc2V0VG9wKVxuICAgICAgc3R5bGVzLnRvcCAgPSAocFsxXSAtIGRlbHRhWzFdICsgb3B0aW9ucy5vZmZzZXRUb3ApICArICdweCc7XG5cbiAgICBpZiAob3B0aW9ucy5zZXRXaWR0aClcbiAgICAgIHN0eWxlcy53aWR0aCAgPSBsYXlvdXQuZ2V0KCdib3JkZXItYm94LXdpZHRoJykgICsgJ3B4JztcbiAgICBpZiAob3B0aW9ucy5zZXRIZWlnaHQpXG4gICAgICBzdHlsZXMuaGVpZ2h0ID0gbGF5b3V0LmdldCgnYm9yZGVyLWJveC1oZWlnaHQnKSArICdweCc7XG5cbiAgICByZXR1cm4gRWxlbWVudC5zZXRTdHlsZShlbGVtZW50LCBzdHlsZXMpO1xuICB9XG5cblxuICBpZiAoUHJvdG90eXBlLkJyb3dzZXIuSUUpIHtcbiAgICBnZXRPZmZzZXRQYXJlbnQgPSBnZXRPZmZzZXRQYXJlbnQud3JhcChcbiAgICAgIGZ1bmN0aW9uKHByb2NlZWQsIGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG5cbiAgICAgICAgaWYgKGlzRG9jdW1lbnQoZWxlbWVudCkgfHwgaXNEZXRhY2hlZChlbGVtZW50KSB8fCBpc0JvZHkoZWxlbWVudCkgfHwgaXNIdG1sKGVsZW1lbnQpKVxuICAgICAgICAgIHJldHVybiAkKGRvY3VtZW50LmJvZHkpO1xuXG4gICAgICAgIHZhciBwb3NpdGlvbiA9IGVsZW1lbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJyk7XG4gICAgICAgIGlmIChwb3NpdGlvbiAhPT0gJ3N0YXRpYycpIHJldHVybiBwcm9jZWVkKGVsZW1lbnQpO1xuXG4gICAgICAgIGVsZW1lbnQuc2V0U3R5bGUoeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9KTtcbiAgICAgICAgdmFyIHZhbHVlID0gcHJvY2VlZChlbGVtZW50KTtcbiAgICAgICAgZWxlbWVudC5zZXRTdHlsZSh7IHBvc2l0aW9uOiBwb3NpdGlvbiB9KTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBwb3NpdGlvbmVkT2Zmc2V0ID0gcG9zaXRpb25lZE9mZnNldC53cmFwKGZ1bmN0aW9uKHByb2NlZWQsIGVsZW1lbnQpIHtcbiAgICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgICAgaWYgKCFlbGVtZW50LnBhcmVudE5vZGUpIHJldHVybiBuZXcgRWxlbWVudC5PZmZzZXQoMCwgMCk7XG4gICAgICB2YXIgcG9zaXRpb24gPSBlbGVtZW50LmdldFN0eWxlKCdwb3NpdGlvbicpO1xuICAgICAgaWYgKHBvc2l0aW9uICE9PSAnc3RhdGljJykgcmV0dXJuIHByb2NlZWQoZWxlbWVudCk7XG5cbiAgICAgIHZhciBvZmZzZXRQYXJlbnQgPSBlbGVtZW50LmdldE9mZnNldFBhcmVudCgpO1xuICAgICAgaWYgKG9mZnNldFBhcmVudCAmJiBvZmZzZXRQYXJlbnQuZ2V0U3R5bGUoJ3Bvc2l0aW9uJykgPT09ICdmaXhlZCcpXG4gICAgICAgIGhhc0xheW91dChvZmZzZXRQYXJlbnQpO1xuXG4gICAgICBlbGVtZW50LnNldFN0eWxlKHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfSk7XG4gICAgICB2YXIgdmFsdWUgPSBwcm9jZWVkKGVsZW1lbnQpO1xuICAgICAgZWxlbWVudC5zZXRTdHlsZSh7IHBvc2l0aW9uOiBwb3NpdGlvbiB9KTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KTtcbiAgfSBlbHNlIGlmIChQcm90b3R5cGUuQnJvd3Nlci5XZWJraXQpIHtcbiAgICBjdW11bGF0aXZlT2Zmc2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgICB2YXIgdmFsdWVUID0gMCwgdmFsdWVMID0gMDtcbiAgICAgIGRvIHtcbiAgICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwO1xuICAgICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7XG4gICAgICAgIGlmIChlbGVtZW50Lm9mZnNldFBhcmVudCA9PSBkb2N1bWVudC5ib2R5KSB7XG4gICAgICAgICAgaWYgKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJykgPT0gJ2Fic29sdXRlJykgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG4gICAgICB9IHdoaWxlIChlbGVtZW50KTtcblxuICAgICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCh2YWx1ZUwsIHZhbHVlVCk7XG4gICAgfTtcbiAgfVxuXG5cbiAgRWxlbWVudC5hZGRNZXRob2RzKHtcbiAgICBnZXRMYXlvdXQ6ICAgICAgICAgICAgICBnZXRMYXlvdXQsXG4gICAgbWVhc3VyZTogICAgICAgICAgICAgICAgbWVhc3VyZSxcbiAgICBnZXRXaWR0aDogICAgICAgICAgICAgICBnZXRXaWR0aCxcbiAgICBnZXRIZWlnaHQ6ICAgICAgICAgICAgICBnZXRIZWlnaHQsXG4gICAgZ2V0RGltZW5zaW9uczogICAgICAgICAgZ2V0RGltZW5zaW9ucyxcbiAgICBnZXRPZmZzZXRQYXJlbnQ6ICAgICAgICBnZXRPZmZzZXRQYXJlbnQsXG4gICAgY3VtdWxhdGl2ZU9mZnNldDogICAgICAgY3VtdWxhdGl2ZU9mZnNldCxcbiAgICBwb3NpdGlvbmVkT2Zmc2V0OiAgICAgICBwb3NpdGlvbmVkT2Zmc2V0LFxuICAgIGN1bXVsYXRpdmVTY3JvbGxPZmZzZXQ6IGN1bXVsYXRpdmVTY3JvbGxPZmZzZXQsXG4gICAgdmlld3BvcnRPZmZzZXQ6ICAgICAgICAgdmlld3BvcnRPZmZzZXQsXG4gICAgYWJzb2x1dGl6ZTogICAgICAgICAgICAgYWJzb2x1dGl6ZSxcbiAgICByZWxhdGl2aXplOiAgICAgICAgICAgICByZWxhdGl2aXplLFxuICAgIHNjcm9sbFRvOiAgICAgICAgICAgICAgIHNjcm9sbFRvLFxuICAgIG1ha2VQb3NpdGlvbmVkOiAgICAgICAgIG1ha2VQb3NpdGlvbmVkLFxuICAgIHVuZG9Qb3NpdGlvbmVkOiAgICAgICAgIHVuZG9Qb3NpdGlvbmVkLFxuICAgIG1ha2VDbGlwcGluZzogICAgICAgICAgIG1ha2VDbGlwcGluZyxcbiAgICB1bmRvQ2xpcHBpbmc6ICAgICAgICAgICB1bmRvQ2xpcHBpbmcsXG4gICAgY2xvbmVQb3NpdGlvbjogICAgICAgICAgY2xvbmVQb3NpdGlvblxuICB9KTtcblxuICBmdW5jdGlvbiBpc0JvZHkoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09ICdCT0RZJztcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSHRtbChlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gJ0hUTUwnO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNEb2N1bWVudChlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQubm9kZVR5cGUgPT09IE5vZGUuRE9DVU1FTlRfTk9ERTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzRGV0YWNoZWQoZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50ICE9PSBkb2N1bWVudC5ib2R5ICYmXG4gICAgICFFbGVtZW50LmRlc2NlbmRhbnRPZihlbGVtZW50LCBkb2N1bWVudC5ib2R5KTtcbiAgfVxuXG4gIGlmICgnZ2V0Qm91bmRpbmdDbGllbnRSZWN0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICBFbGVtZW50LmFkZE1ldGhvZHMoe1xuICAgICAgdmlld3BvcnRPZmZzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgICAgIGlmIChpc0RldGFjaGVkKGVsZW1lbnQpKSByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KDAsIDApO1xuXG4gICAgICAgIHZhciByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxcbiAgICAgICAgIGRvY0VsID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgICByZXR1cm4gbmV3IEVsZW1lbnQuT2Zmc2V0KHJlY3QubGVmdCAtIGRvY0VsLmNsaWVudExlZnQsXG4gICAgICAgICByZWN0LnRvcCAtIGRvY0VsLmNsaWVudFRvcCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuXG59KSgpO1xuXG4oZnVuY3Rpb24oKSB7XG5cbiAgdmFyIElTX09MRF9PUEVSQSA9IFByb3RvdHlwZS5Ccm93c2VyLk9wZXJhICYmXG4gICAod2luZG93LnBhcnNlRmxvYXQod2luZG93Lm9wZXJhLnZlcnNpb24oKSkgPCA5LjUpO1xuICB2YXIgUk9PVCA9IG51bGw7XG4gIGZ1bmN0aW9uIGdldFJvb3RFbGVtZW50KCkge1xuICAgIGlmIChST09UKSByZXR1cm4gUk9PVDtcbiAgICBST09UID0gSVNfT0xEX09QRVJBID8gZG9jdW1lbnQuYm9keSA6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICByZXR1cm4gUk9PVDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldERpbWVuc2lvbnMoKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IHRoaXMuZ2V0V2lkdGgoKSwgaGVpZ2h0OiB0aGlzLmdldEhlaWdodCgpIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRXaWR0aCgpIHtcbiAgICByZXR1cm4gZ2V0Um9vdEVsZW1lbnQoKS5jbGllbnRXaWR0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEhlaWdodCgpIHtcbiAgICByZXR1cm4gZ2V0Um9vdEVsZW1lbnQoKS5jbGllbnRIZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTY3JvbGxPZmZzZXRzKCkge1xuICAgIHZhciB4ID0gd2luZG93LnBhZ2VYT2Zmc2V0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8XG4gICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdDtcbiAgICB2YXIgeSA9IHdpbmRvdy5wYWdlWU9mZnNldCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wIHx8XG4gICAgIGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wO1xuXG4gICAgcmV0dXJuIG5ldyBFbGVtZW50Lk9mZnNldCh4LCB5KTtcbiAgfVxuXG4gIGRvY3VtZW50LnZpZXdwb3J0ID0ge1xuICAgIGdldERpbWVuc2lvbnM6ICAgIGdldERpbWVuc2lvbnMsXG4gICAgZ2V0V2lkdGg6ICAgICAgICAgZ2V0V2lkdGgsXG4gICAgZ2V0SGVpZ2h0OiAgICAgICAgZ2V0SGVpZ2h0LFxuICAgIGdldFNjcm9sbE9mZnNldHM6IGdldFNjcm9sbE9mZnNldHNcbiAgfTtcblxufSkoKTtcbndpbmRvdy4kJCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZXhwcmVzc2lvbiA9ICRBKGFyZ3VtZW50cykuam9pbignLCAnKTtcbiAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QoZXhwcmVzc2lvbiwgZG9jdW1lbnQpO1xufTtcblxuUHJvdG90eXBlLlNlbGVjdG9yID0gKGZ1bmN0aW9uKCkge1xuXG4gIGZ1bmN0aW9uIHNlbGVjdCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIlByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3RcIiBtdXN0IGJlIGRlZmluZWQuJyk7XG4gIH1cblxuICBmdW5jdGlvbiBtYXRjaCgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01ldGhvZCBcIlByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaFwiIG11c3QgYmUgZGVmaW5lZC4nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpbmQoZWxlbWVudHMsIGV4cHJlc3Npb24sIGluZGV4KSB7XG4gICAgaW5kZXggPSBpbmRleCB8fCAwO1xuICAgIHZhciBtYXRjaCA9IFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaCwgbGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoLCBtYXRjaEluZGV4ID0gMCwgaTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoKGVsZW1lbnRzW2ldLCBleHByZXNzaW9uKSAmJiBpbmRleCA9PSBtYXRjaEluZGV4KyspIHtcbiAgICAgICAgcmV0dXJuIEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnRzW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBleHRlbmRFbGVtZW50cyhlbGVtZW50cykge1xuICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgRWxlbWVudC5leHRlbmQoZWxlbWVudHNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudHM7XG4gIH1cblxuXG4gIHZhciBLID0gUHJvdG90eXBlLks7XG5cbiAgcmV0dXJuIHtcbiAgICBzZWxlY3Q6IHNlbGVjdCxcbiAgICBtYXRjaDogbWF0Y2gsXG4gICAgZmluZDogZmluZCxcbiAgICBleHRlbmRFbGVtZW50czogKEVsZW1lbnQuZXh0ZW5kID09PSBLKSA/IEsgOiBleHRlbmRFbGVtZW50cyxcbiAgICBleHRlbmRFbGVtZW50OiBFbGVtZW50LmV4dGVuZFxuICB9O1xufSkoKTtcblByb3RvdHlwZS5fb3JpZ2luYWxfcHJvcGVydHkgPSB3aW5kb3cuU2l6emxlO1xuLyohXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2QFZFUlNJT05cbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMTMgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogQERBVEVcbiAqL1xuKGZ1bmN0aW9uKCB3aW5kb3cgKSB7XG5cbnZhciBpLFxuXHRzdXBwb3J0LFxuXHRFeHByLFxuXHRnZXRUZXh0LFxuXHRpc1hNTCxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHRzZXREb2N1bWVudCxcblx0ZG9jdW1lbnQsXG5cdGRvY0VsZW0sXG5cdGRvY3VtZW50SXNIVE1MLFxuXHRyYnVnZ3lRU0EsXG5cdHJidWdneU1hdGNoZXMsXG5cdG1hdGNoZXMsXG5cdGNvbnRhaW5zLFxuXG5cdGV4cGFuZG8gPSBcInNpenpsZVwiICsgLShuZXcgRGF0ZSgpKSxcblx0cHJlZmVycmVkRG9jID0gd2luZG93LmRvY3VtZW50LFxuXHRkaXJydW5zID0gMCxcblx0ZG9uZSA9IDAsXG5cdGNsYXNzQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHR0b2tlbkNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0Y29tcGlsZXJDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9LFxuXG5cdHN0cnVuZGVmaW5lZCA9IHR5cGVvZiB1bmRlZmluZWQsXG5cdE1BWF9ORUdBVElWRSA9IDEgPDwgMzEsXG5cblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcblx0YXJyID0gW10sXG5cdHBvcCA9IGFyci5wb3AsXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXG5cdHB1c2ggPSBhcnIucHVzaCxcblx0c2xpY2UgPSBhcnIuc2xpY2UsXG5cdGluZGV4T2YgPSBhcnIuaW5kZXhPZiB8fCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGlmICggdGhpc1tpXSA9PT0gZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAtMTtcblx0fSxcblxuXHRib29sZWFucyA9IFwiY2hlY2tlZHxzZWxlY3RlZHxhc3luY3xhdXRvZm9jdXN8YXV0b3BsYXl8Y29udHJvbHN8ZGVmZXJ8ZGlzYWJsZWR8aGlkZGVufGlzbWFwfGxvb3B8bXVsdGlwbGV8b3BlbnxyZWFkb25seXxyZXF1aXJlZHxzY29wZWRcIixcblxuXG5cdHdoaXRlc3BhY2UgPSBcIltcXFxceDIwXFxcXHRcXFxcclxcXFxuXFxcXGZdXCIsXG5cdGNoYXJhY3RlckVuY29kaW5nID0gXCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXFxceDAwLVxcXFx4YTBdKStcIixcblxuXHRpZGVudGlmaWVyID0gY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidyNcIiApLFxuXG5cdGF0dHJpYnV0ZXMgPSBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiKig/OihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbJ1xcXCJdKSgoPzpcXFxcXFxcXC58W15cXFxcXFxcXF0pKj8pXFxcXDN8KFwiICsgaWRlbnRpZmllciArIFwiKXwpfClcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLFxuXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKSg/OlxcXFwoKChbJ1xcXCJdKSgoPzpcXFxcXFxcXC58W15cXFxcXFxcXF0pKj8pXFxcXDN8KCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiICsgYXR0cmlidXRlcy5yZXBsYWNlKCAzLCA4ICkgKyBcIikqKXwuKilcXFxcKXwpXCIsXG5cblx0cnRyaW0gPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIit8KCg/Ol58W15cXFxcXFxcXF0pKD86XFxcXFxcXFwuKSopXCIgKyB3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblxuXHRyYXR0cmlidXRlUXVvdGVzID0gbmV3IFJlZ0V4cCggXCI9XCIgKyB3aGl0ZXNwYWNlICsgXCIqKFteXFxcXF0nXFxcIl0qPylcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLCBcImdcIiApLFxuXG5cdHJwc2V1ZG8gPSBuZXcgUmVnRXhwKCBwc2V1ZG9zICksXG5cdHJpZGVudGlmaWVyID0gbmV3IFJlZ0V4cCggXCJeXCIgKyBpZGVudGlmaWVyICsgXCIkXCIgKSxcblxuXHRtYXRjaEV4cHIgPSB7XG5cdFx0XCJJRFwiOiBuZXcgUmVnRXhwKCBcIl4jKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBjaGFyYWN0ZXJFbmNvZGluZyArIFwiKVwiICksXG5cdFx0XCJUQUdcIjogbmV3IFJlZ0V4cCggXCJeKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidypcIiApICsgXCIpXCIgKSxcblx0XHRcIkFUVFJcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBhdHRyaWJ1dGVzICksXG5cdFx0XCJQU0VVRE9cIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBwc2V1ZG9zICksXG5cdFx0XCJDSElMRFwiOiBuZXcgUmVnRXhwKCBcIl46KG9ubHl8Zmlyc3R8bGFzdHxudGh8bnRoLWxhc3QpLShjaGlsZHxvZi10eXBlKSg/OlxcXFwoXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86KFsrLV18KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooXFxcXGQrKXwpKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfClcIiwgXCJpXCIgKSxcblx0XHRcImJvb2xcIjogbmV3IFJlZ0V4cCggXCJeKD86XCIgKyBib29sZWFucyArIFwiKSRcIiwgXCJpXCIgKSxcblx0XHRcIm5lZWRzQ29udGV4dFwiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIipbPit+XXw6KGV2ZW58b2RkfGVxfGd0fGx0fG50aHxmaXJzdHxsYXN0KSg/OlxcXFwoXCIgK1xuXHRcdFx0d2hpdGVzcGFjZSArIFwiKigoPzotXFxcXGQpP1xcXFxkKilcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpKD89W14tXXwkKVwiLCBcImlcIiApXG5cdH0sXG5cblx0cmlucHV0cyA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXG5cblx0cm5hdGl2ZSA9IC9eW157XStcXHtcXHMqXFxbbmF0aXZlIFxcdy8sXG5cblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXHRyZXNjYXBlID0gLyd8XFxcXC9nLFxuXG5cdHJ1bmVzY2FwZSA9IG5ldyBSZWdFeHAoIFwiXFxcXFxcXFwoW1xcXFxkYS1mXXsxLDZ9XCIgKyB3aGl0ZXNwYWNlICsgXCI/fChcIiArIHdoaXRlc3BhY2UgKyBcIil8LilcIiwgXCJpZ1wiICksXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBfLCBlc2NhcGVkLCBlc2NhcGVkV2hpdGVzcGFjZSApIHtcblx0XHR2YXIgaGlnaCA9IFwiMHhcIiArIGVzY2FwZWQgLSAweDEwMDAwO1xuXHRcdHJldHVybiBoaWdoICE9PSBoaWdoIHx8IGVzY2FwZWRXaGl0ZXNwYWNlID9cblx0XHRcdGVzY2FwZWQgOlxuXHRcdFx0aGlnaCA8IDAgP1xuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoICsgMHgxMDAwMCApIDpcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCA+PiAxMCB8IDB4RDgwMCwgaGlnaCAmIDB4M0ZGIHwgMHhEQzAwICk7XG5cdH07XG5cbnRyeSB7XG5cdHB1c2guYXBwbHkoXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggP1xuXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xuXHRcdFx0cHVzaF9uYXRpdmUuYXBwbHkoIHRhcmdldCwgc2xpY2UuY2FsbChlbHMpICk7XG5cdFx0fSA6XG5cblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHR2YXIgaiA9IHRhcmdldC5sZW5ndGgsXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0d2hpbGUgKCAodGFyZ2V0W2orK10gPSBlbHNbaSsrXSkgKSB7fVxuXHRcdFx0dGFyZ2V0Lmxlbmd0aCA9IGogLSAxO1xuXHRcdH1cblx0fTtcbn1cblxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIG1hdGNoLCBlbGVtLCBtLCBub2RlVHlwZSxcblx0XHRpLCBncm91cHMsIG9sZCwgbmlkLCBuZXdDb250ZXh0LCBuZXdTZWxlY3RvcjtcblxuXHRpZiAoICggY29udGV4dCA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogcHJlZmVycmVkRG9jICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdH1cblxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0aWYgKCAhc2VsZWN0b3IgfHwgdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0aWYgKCAobm9kZVR5cGUgPSBjb250ZXh0Lm5vZGVUeXBlKSAhPT0gMSAmJiBub2RlVHlwZSAhPT0gOSApIHtcblx0XHRyZXR1cm4gW107XG5cdH1cblxuXHRpZiAoIGRvY3VtZW50SXNIVE1MICYmICFzZWVkICkge1xuXG5cdFx0aWYgKCAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0aWYgKCAobSA9IG1hdGNoWzFdKSApIHtcblx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggbSApO1xuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGlmICggY29udGV4dC5vd25lckRvY3VtZW50ICYmIChlbGVtID0gY29udGV4dC5vd25lckRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtICkpICYmXG5cdFx0XHRcdFx0XHRjb250YWlucyggY29udGV4dCwgZWxlbSApICYmIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFsyXSApIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0fSBlbHNlIGlmICggKG0gPSBtYXRjaFszXSkgJiYgc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBtICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBzdXBwb3J0LnFzYSAmJiAoIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0bmlkID0gb2xkID0gZXhwYW5kbztcblx0XHRcdG5ld0NvbnRleHQgPSBjb250ZXh0O1xuXHRcdFx0bmV3U2VsZWN0b3IgPSBub2RlVHlwZSA9PT0gOSAmJiBzZWxlY3RvcjtcblxuXHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gMSAmJiBjb250ZXh0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXG5cdFx0XHRcdGlmICggKG9sZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKFwiaWRcIikpICkge1xuXHRcdFx0XHRcdG5pZCA9IG9sZC5yZXBsYWNlKCByZXNjYXBlLCBcIlxcXFwkJlwiICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29udGV4dC5zZXRBdHRyaWJ1dGUoIFwiaWRcIiwgbmlkICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bmlkID0gXCJbaWQ9J1wiICsgbmlkICsgXCInXSBcIjtcblxuXHRcdFx0XHRpID0gZ3JvdXBzLmxlbmd0aDtcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0Z3JvdXBzW2ldID0gbmlkICsgdG9TZWxlY3RvciggZ3JvdXBzW2ldICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0bmV3Q29udGV4dCA9IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHQ7XG5cdFx0XHRcdG5ld1NlbGVjdG9yID0gZ3JvdXBzLmpvaW4oXCIsXCIpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIG5ld1NlbGVjdG9yICkge1xuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsXG5cdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHR9IGNhdGNoKHFzYUVycm9yKSB7XG5cdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0aWYgKCAhb2xkICkge1xuXHRcdFx0XHRcdFx0Y29udGV4dC5yZW1vdmVBdHRyaWJ1dGUoXCJpZFwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtGdW5jdGlvbihzdHJpbmcsIE9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cdFx0aWYgKCBrZXlzLnB1c2goIGtleSArIFwiIFwiICkgPiBFeHByLmNhY2hlTGVuZ3RoICkge1xuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcblx0XHR9XG5cdFx0cmV0dXJuIChjYWNoZVsga2V5ICsgXCIgXCIgXSA9IHZhbHVlKTtcblx0fVxuXHRyZXR1cm4gY2FjaGU7XG59XG5cbi8qKlxuICogTWFyayBhIGZ1bmN0aW9uIGZvciBzcGVjaWFsIHVzZSBieSBTaXp6bGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrXG4gKi9cbmZ1bmN0aW9uIG1hcmtGdW5jdGlvbiggZm4gKSB7XG5cdGZuWyBleHBhbmRvIF0gPSB0cnVlO1xuXHRyZXR1cm4gZm47XG59XG5cbi8qKlxuICogU3VwcG9ydCB0ZXN0aW5nIHVzaW5nIGFuIGVsZW1lbnRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFBhc3NlZCB0aGUgY3JlYXRlZCBkaXYgYW5kIGV4cGVjdHMgYSBib29sZWFuIHJlc3VsdFxuICovXG5mdW5jdGlvbiBhc3NlcnQoIGZuICkge1xuXHR2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcblxuXHR0cnkge1xuXHRcdHJldHVybiAhIWZuKCBkaXYgKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBmaW5hbGx5IHtcblx0XHRpZiAoIGRpdi5wYXJlbnROb2RlICkge1xuXHRcdFx0ZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGRpdiApO1xuXHRcdH1cblx0XHRkaXYgPSBudWxsO1xuXHR9XG59XG5cbi8qKlxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xuICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBUaGUgbWV0aG9kIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKi9cbmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7XG5cdHZhciBhcnIgPSBhdHRycy5zcGxpdChcInxcIiksXG5cdFx0aSA9IGF0dHJzLmxlbmd0aDtcblxuXHR3aGlsZSAoIGktLSApIHtcblx0XHRFeHByLmF0dHJIYW5kbGVbIGFycltpXSBdID0gaGFuZGxlcjtcblx0fVxufVxuXG4vKipcbiAqIENoZWNrcyBkb2N1bWVudCBvcmRlciBvZiB0d28gc2libGluZ3NcbiAqIEBwYXJhbSB7RWxlbWVudH0gYVxuICogQHBhcmFtIHtFbGVtZW50fSBiXG4gKiBAcmV0dXJucyB7TnVtYmVyfSBSZXR1cm5zIGxlc3MgdGhhbiAwIGlmIGEgcHJlY2VkZXMgYiwgZ3JlYXRlciB0aGFuIDAgaWYgYSBmb2xsb3dzIGJcbiAqL1xuZnVuY3Rpb24gc2libGluZ0NoZWNrKCBhLCBiICkge1xuXHR2YXIgY3VyID0gYiAmJiBhLFxuXHRcdGRpZmYgPSBjdXIgJiYgYS5ub2RlVHlwZSA9PT0gMSAmJiBiLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHQoIH5iLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApIC1cblx0XHRcdCggfmEuc291cmNlSW5kZXggfHwgTUFYX05FR0FUSVZFICk7XG5cblx0aWYgKCBkaWZmICkge1xuXHRcdHJldHVybiBkaWZmO1xuXHR9XG5cblx0aWYgKCBjdXIgKSB7XG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLm5leHRTaWJsaW5nKSApIHtcblx0XHRcdGlmICggY3VyID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGEgPyAxIDogLTE7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGJ1dHRvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJ1dHRvblBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiAobmFtZSA9PT0gXCJpbnB1dFwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCIpICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggYXJndW1lbnQgKSB7XG5cdFx0YXJndW1lbnQgPSArYXJndW1lbnQ7XG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggc2VlZFsgKGogPSBtYXRjaEluZGV4ZXNbaV0pIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFtqXSA9ICEobWF0Y2hlc1tqXSA9IHNlZWRbal0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0pO1xufVxuXG4vKipcbiAqIENoZWNrcyBhIG5vZGUgZm9yIHZhbGlkaXR5IGFzIGEgU2l6emxlIGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RWxlbWVudHxPYmplY3R8Qm9vbGVhbn0gVGhlIGlucHV0IG5vZGUgaWYgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGEgZmFsc3kgdmFsdWVcbiAqL1xuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XG5cdHJldHVybiBjb250ZXh0ICYmIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBzdHJ1bmRlZmluZWQgJiYgY29udGV4dDtcbn1cblxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBkb2N1bWVudEVsZW1lbnQgPSBlbGVtICYmIChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSkuZG9jdW1lbnRFbGVtZW50O1xuXHRyZXR1cm4gZG9jdW1lbnRFbGVtZW50ID8gZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSBcIkhUTUxcIiA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKi9cbnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7XG5cdHZhciBoYXNDb21wYXJlLFxuXHRcdGRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYyxcblx0XHRwYXJlbnQgPSBkb2MuZGVmYXVsdFZpZXc7XG5cblx0aWYgKCBkb2MgPT09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHRkb2N1bWVudCA9IGRvYztcblx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvYyApO1xuXG5cdGlmICggcGFyZW50ICYmIHBhcmVudCAhPT0gcGFyZW50LnRvcCApIHtcblx0XHRpZiAoIHBhcmVudC5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0cGFyZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwidW5sb2FkXCIsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRzZXREb2N1bWVudCgpO1xuXHRcdFx0fSwgZmFsc2UgKTtcblx0XHR9IGVsc2UgaWYgKCBwYXJlbnQuYXR0YWNoRXZlbnQgKSB7XG5cdFx0XHRwYXJlbnQuYXR0YWNoRXZlbnQoIFwib251bmxvYWRcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHNldERvY3VtZW50KCk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHQvKiBBdHRyaWJ1dGVzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHRzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0cmV0dXJuICFkaXYuZ2V0QXR0cmlidXRlKFwiY2xhc3NOYW1lXCIpO1xuXHR9KTtcblxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlQ29tbWVudChcIlwiKSApO1xuXHRcdHJldHVybiAhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKS5sZW5ndGg7XG5cdH0pO1xuXG5cdHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IHJuYXRpdmUudGVzdCggZG9jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSAmJiBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRkaXYuaW5uZXJIVE1MID0gXCI8ZGl2IGNsYXNzPSdhJz48L2Rpdj48ZGl2IGNsYXNzPSdhIGknPjwvZGl2PlwiO1xuXG5cdFx0ZGl2LmZpcnN0Q2hpbGQuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0cmV0dXJuIGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiaVwiKS5sZW5ndGggPT09IDI7XG5cdH0pO1xuXG5cdHN1cHBvcnQuZ2V0QnlJZCA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlkID0gZXhwYW5kbztcblx0XHRyZXR1cm4gIWRvYy5nZXRFbGVtZW50c0J5TmFtZSB8fCAhZG9jLmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xuXHR9KTtcblxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbmRbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IHN0cnVuZGVmaW5lZCAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHRcdFx0XHRyZXR1cm4gbSAmJiBtLnBhcmVudE5vZGUgPyBbbV0gOiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKFwiaWRcIikgPT09IGF0dHJJZDtcblx0XHRcdH07XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRkZWxldGUgRXhwci5maW5kW1wiSURcIl07XG5cblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gIGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09IHN0cnVuZGVmaW5lZCAmJiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9XG5cblx0RXhwci5maW5kW1wiVEFHXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA/XG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0dG1wID0gW10sXG5cdFx0XHRcdGkgPSAwLFxuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdG1wO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0fTtcblxuXHRFeHByLmZpbmRbXCJDTEFTU1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkge1xuXHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gc3RydW5kZWZpbmVkICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggY2xhc3NOYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3Jcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cblx0cmJ1Z2d5TWF0Y2hlcyA9IFtdO1xuXG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2MucXVlcnlTZWxlY3RvckFsbCApKSApIHtcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdGRpdi5pbm5lckhUTUwgPSBcIjxzZWxlY3QgdD0nJz48b3B0aW9uIHNlbGVjdGVkPScnPjwvb3B0aW9uPjwvc2VsZWN0PlwiO1xuXG5cdFx0XHRpZiAoIGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW3RePScnXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlsqXiRdPVwiICsgd2hpdGVzcGFjZSArIFwiKig/OicnfFxcXCJcXFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiW3NlbGVjdGVkXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86dmFsdWV8XCIgKyBib29sZWFucyArIFwiKVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiOmNoZWNrZWRcIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIjpjaGVja2VkXCIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHR2YXIgaW5wdXQgPSBkb2MuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XG5cblx0XHRcdGlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZT1kXVwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIm5hbWVcIiArIHdoaXRlc3BhY2UgKyBcIipbKl4kfCF+XT89XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6ZW5hYmxlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCIqLDp4XCIpO1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCIsLio6XCIpO1xuXHRcdH0pO1xuXHR9XG5cblx0aWYgKCAoc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgPSBybmF0aXZlLnRlc3QoIChtYXRjaGVzID0gZG9jRWxlbS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ub01hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubXNNYXRjaGVzU2VsZWN0b3IpICkpICkge1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHRzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoID0gbWF0Y2hlcy5jYWxsKCBkaXYsIFwiZGl2XCIgKTtcblxuXHRcdFx0bWF0Y2hlcy5jYWxsKCBkaXYsIFwiW3MhPScnXTp4XCIgKTtcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyYnVnZ3lRU0EgPSByYnVnZ3lRU0EubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneVFTQS5qb2luKFwifFwiKSApO1xuXHRyYnVnZ3lNYXRjaGVzID0gcmJ1Z2d5TWF0Y2hlcy5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5TWF0Y2hlcy5qb2luKFwifFwiKSApO1xuXG5cdC8qIENvbnRhaW5zXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xuXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHR2YXIgYWRvd24gPSBhLm5vZGVUeXBlID09PSA5ID8gYS5kb2N1bWVudEVsZW1lbnQgOiBhLFxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcblx0XHRcdHJldHVybiBhID09PSBidXAgfHwgISEoIGJ1cCAmJiBidXAubm9kZVR5cGUgPT09IDEgJiYgKFxuXHRcdFx0XHRhZG93bi5jb250YWlucyA/XG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcblx0XHRcdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICYmIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGJ1cCApICYgMTZcblx0XHRcdCkpO1xuXHRcdH0gOlxuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0aWYgKCBiICkge1xuXHRcdFx0XHR3aGlsZSAoIChiID0gYi5wYXJlbnROb2RlKSApIHtcblx0XHRcdFx0XHRpZiAoIGIgPT09IGEgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdC8qIFNvcnRpbmdcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdHNvcnRPcmRlciA9IGhhc0NvbXBhcmUgP1xuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XG5cdFx0aWYgKCBjb21wYXJlICkge1xuXHRcdFx0cmV0dXJuIGNvbXBhcmU7XG5cdFx0fVxuXG5cdFx0Y29tcGFyZSA9ICggYS5vd25lckRvY3VtZW50IHx8IGEgKSA9PT0gKCBiLm93bmVyRG9jdW1lbnQgfHwgYiApID9cblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGIgKSA6XG5cblx0XHRcdDE7XG5cblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoIXN1cHBvcnQuc29ydERldGFjaGVkICYmIGIuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGEgKSA9PT0gY29tcGFyZSkgKSB7XG5cblx0XHRcdGlmICggYSA9PT0gZG9jIHx8IGEub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYSkgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHRcdGlmICggYiA9PT0gZG9jIHx8IGIub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYikgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cblx0XHRcdFx0KCBpbmRleE9mLmNhbGwoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZi5jYWxsKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXVwID0gYS5wYXJlbnROb2RlLFxuXHRcdFx0YnVwID0gYi5wYXJlbnROb2RlLFxuXHRcdFx0YXAgPSBbIGEgXSxcblx0XHRcdGJwID0gWyBiIF07XG5cblx0XHRpZiAoICFhdXAgfHwgIWJ1cCApIHtcblx0XHRcdHJldHVybiBhID09PSBkb2MgPyAtMSA6XG5cdFx0XHRcdGIgPT09IGRvYyA/IDEgOlxuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YuY2FsbCggc29ydElucHV0LCBhICkgLSBpbmRleE9mLmNhbGwoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXG5cdFx0fSBlbHNlIGlmICggYXVwID09PSBidXAgKSB7XG5cdFx0XHRyZXR1cm4gc2libGluZ0NoZWNrKCBhLCBiICk7XG5cdFx0fVxuXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cdFx0Y3VyID0gYjtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRicC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cblx0XHR3aGlsZSAoIGFwW2ldID09PSBicFtpXSApIHtcblx0XHRcdGkrKztcblx0XHR9XG5cblx0XHRyZXR1cm4gaSA/XG5cdFx0XHRzaWJsaW5nQ2hlY2soIGFwW2ldLCBicFtpXSApIDpcblxuXHRcdFx0YXBbaV0gPT09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcblx0XHRcdDA7XG5cdH07XG5cblx0cmV0dXJuIGRvYztcbn07XG5cblNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xufTtcblxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xuXHRpZiAoICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKSAhPT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0fVxuXG5cdGV4cHIgPSBleHByLnJlcGxhY2UoIHJhdHRyaWJ1dGVRdW90ZXMsIFwiPSckMSddXCIgKTtcblxuXHRpZiAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxuXHRcdCggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHtcblxuXHRcdHRyeSB7XG5cdFx0XHR2YXIgcmV0ID0gbWF0Y2hlcy5jYWxsKCBlbGVtLCBleHByICk7XG5cblx0XHRcdGlmICggcmV0IHx8IHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggfHxcblx0XHRcdFx0XHRlbGVtLmRvY3VtZW50ICYmIGVsZW0uZG9jdW1lbnQubm9kZVR5cGUgIT09IDExICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2goZSkge31cblx0fVxuXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbZWxlbV0gKS5sZW5ndGggPiAwO1xufTtcblxuU2l6emxlLmNvbnRhaW5zID0gZnVuY3Rpb24oIGNvbnRleHQsIGVsZW0gKSB7XG5cdGlmICggKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHR2YXIgZm4gPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUudG9Mb3dlckNhc2UoKSBdLFxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cblx0XHRcdGZuKCBlbGVtLCBuYW1lLCAhZG9jdW1lbnRJc0hUTUwgKSA6XG5cdFx0XHR1bmRlZmluZWQ7XG5cblx0cmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID9cblx0XHR2YWwgOlxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xuXHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKSA6XG5cdFx0XHQodmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcbn07XG5cblNpenpsZS5lcnJvciA9IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdHRocm93IG5ldyBFcnJvciggXCJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiBcIiArIG1zZyApO1xufTtcblxuLyoqXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXG4gKiBAcGFyYW0ge0FycmF5TGlrZX0gcmVzdWx0c1xuICovXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xuXHR2YXIgZWxlbSxcblx0XHRkdXBsaWNhdGVzID0gW10sXG5cdFx0aiA9IDAsXG5cdFx0aSA9IDA7XG5cblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRpZiAoIGVsZW0gPT09IHJlc3VsdHNbIGkgXSApIHtcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdHJlc3VsdHMuc3BsaWNlKCBkdXBsaWNhdGVzWyBqIF0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRzb3J0SW5wdXQgPSBudWxsO1xuXG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xuICogQHBhcmFtIHtBcnJheXxFbGVtZW50fSBlbGVtXG4gKi9cbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHR2YXIgbm9kZSxcblx0XHRyZXQgPSBcIlwiLFxuXHRcdGkgPSAwLFxuXHRcdG5vZGVUeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRpZiAoICFub2RlVHlwZSApIHtcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcblx0XHRcdHJldCArPSBnZXRUZXh0KCBub2RlICk7XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLnRleHRDb250ZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVWYWx1ZTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5FeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHtcblxuXHRjYWNoZUxlbmd0aDogNTAsXG5cblx0Y3JlYXRlUHNldWRvOiBtYXJrRnVuY3Rpb24sXG5cblx0bWF0Y2g6IG1hdGNoRXhwcixcblxuXHRhdHRySGFuZGxlOiB7fSxcblxuXHRmaW5kOiB7fSxcblxuXHRyZWxhdGl2ZToge1xuXHRcdFwiPlwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCIgXCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiB9LFxuXHRcdFwiK1wiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIn5cIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIgfVxuXHR9LFxuXG5cdHByZUZpbHRlcjoge1xuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaFsxXSA9IG1hdGNoWzFdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsyXSA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0LyogbWF0Y2hlcyBmcm9tIG1hdGNoRXhwcltcIkNISUxEXCJdXG5cdFx0XHRcdDEgdHlwZSAob25seXxudGh8Li4uKVxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdDMgYXJndW1lbnQgKGV2ZW58b2RkfFxcZCp8XFxkKm4oWystXVxcZCspP3wuLi4pXG5cdFx0XHRcdDQgeG4tY29tcG9uZW50IG9mIHhuK3kgYXJndW1lbnQgKFsrLV0/XFxkKm58KVxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDYgeCBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NyBzaWduIG9mIHktY29tcG9uZW50XG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxuXHRcdFx0Ki9cblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsxXS5zbGljZSggMCwgMyApID09PSBcIm50aFwiICkge1xuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xuXHRcdFx0XHRtYXRjaFs1XSA9ICsoICggbWF0Y2hbN10gKyBtYXRjaFs4XSApIHx8IG1hdGNoWzNdID09PSBcIm9kZFwiICk7XG5cblx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWzNdICkge1xuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaDtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0dmFyIGV4Y2Vzcyxcblx0XHRcdFx0dW5xdW90ZWQgPSAhbWF0Y2hbNV0gJiYgbWF0Y2hbMl07XG5cblx0XHRcdGlmICggbWF0Y2hFeHByW1wiQ0hJTERcIl0udGVzdCggbWF0Y2hbMF0gKSApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggbWF0Y2hbM10gJiYgbWF0Y2hbNF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0bWF0Y2hbMl0gPSBtYXRjaFs0XTtcblxuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cdFx0XHRcdChleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSkgJiZcblx0XHRcdFx0KGV4Y2VzcyA9IHVucXVvdGVkLmluZGV4T2YoIFwiKVwiLCB1bnF1b3RlZC5sZW5ndGggLSBleGNlc3MgKSAtIHVucXVvdGVkLmxlbmd0aCkgKSB7XG5cblx0XHRcdFx0bWF0Y2hbMF0gPSBtYXRjaFswXS5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHRcdG1hdGNoWzJdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDMgKTtcblx0XHR9XG5cdH0sXG5cblx0ZmlsdGVyOiB7XG5cblx0XHRcIlRBR1wiOiBmdW5jdGlvbiggbm9kZU5hbWVTZWxlY3RvciApIHtcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09IFwiKlwiID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9IDpcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBub2RlTmFtZTtcblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDTEFTU1wiOiBmdW5jdGlvbiggY2xhc3NOYW1lICkge1xuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xuXG5cdFx0XHRyZXR1cm4gcGF0dGVybiB8fFxuXHRcdFx0XHQocGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkpICYmXG5cdFx0XHRcdGNsYXNzQ2FjaGUoIGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhdHRlcm4udGVzdCggdHlwZW9mIGVsZW0uY2xhc3NOYW1lID09PSBcInN0cmluZ1wiICYmIGVsZW0uY2xhc3NOYW1lIHx8IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSAhPT0gc3RydW5kZWZpbmVkICYmIGVsZW0uZ2V0QXR0cmlidXRlKFwiY2xhc3NcIikgfHwgXCJcIiApO1xuXHRcdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBuYW1lLCBvcGVyYXRvciwgY2hlY2sgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBTaXp6bGUuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiIT1cIiA/IHJlc3VsdCAhPT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIl49XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA9PT0gMCA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiQ9XCIgPyBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIn49XCIgPyAoIFwiIFwiICsgcmVzdWx0ICsgXCIgXCIgKS5pbmRleE9mKCBjaGVjayApID4gLTEgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcblx0XHRcdFx0XHRmYWxzZTtcblx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIHR5cGUsIHdoYXQsIGFyZ3VtZW50LCBmaXJzdCwgbGFzdCApIHtcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXG5cdFx0XHRcdGZvcndhcmQgPSB0eXBlLnNsaWNlKCAtNCApICE9PSBcImxhc3RcIixcblx0XHRcdFx0b2ZUeXBlID0gd2hhdCA9PT0gXCJvZi10eXBlXCI7XG5cblx0XHRcdHJldHVybiBmaXJzdCA9PT0gMSAmJiBsYXN0ID09PSAwID9cblxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRcdH0gOlxuXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBkaWZmLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSBub2RlWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6IG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0c3RhcnQgPSBkaXIgPSB0eXBlID09PSBcIm9ubHlcIiAmJiAhc3RhcnQgJiYgXCJuZXh0U2libGluZ1wiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdO1xuXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBwYXJlbnRbIGV4cGFuZG8gXSB8fCAocGFyZW50WyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRcdGNhY2hlID0gb3V0ZXJDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVswXSA9PT0gZGlycnVucyAmJiBjYWNoZVsxXTtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IGNhY2hlWzBdID09PSBkaXJydW5zICYmIGNhY2hlWzJdO1xuXHRcdFx0XHRcdFx0XHRub2RlID0gbm9kZUluZGV4ICYmIHBhcmVudC5jaGlsZE5vZGVzWyBub2RlSW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXG5cdFx0XHRcdFx0XHRcdFx0KGRpZmYgPSBub2RlSW5kZXggPSAwKSB8fCBzdGFydC5wb3AoKSkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHVzZUNhY2hlICYmIChjYWNoZSA9IChlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KSlbIHR5cGUgXSkgJiYgY2FjaGVbMF0gPT09IGRpcnJ1bnMgKSB7XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBjYWNoZVsxXTtcblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHxcblx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgPyBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOiBub2RlLm5vZGVUeXBlID09PSAxICkgJiYgKytkaWZmICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0KG5vZGVbIGV4cGFuZG8gXSB8fCAobm9kZVsgZXhwYW5kbyBdID0ge30pKVsgdHlwZSBdID0gWyBkaXJydW5zLCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGRpZmYgLT0gbGFzdDtcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIHBzZXVkbywgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdGlmICggZm5bIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0cmV0dXJuIGZuKCBhcmd1bWVudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mLmNhbGwoIHNlZWQsIG1hdGNoZWRbaV0gKTtcblx0XHRcdFx0XHRcdFx0c2VlZFsgaWR4IF0gPSAhKCBtYXRjaGVzWyBpZHggXSA9IG1hdGNoZWRbaV0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KSA6XG5cdFx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZm4oIGVsZW0sIDAsIGFyZ3MgKTtcblx0XHRcdFx0XHR9O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZm47XG5cdFx0fVxuXHR9LFxuXG5cdHBzZXVkb3M6IHtcblx0XHRcIm5vdFwiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0dmFyIGlucHV0ID0gW10sXG5cdFx0XHRcdHJlc3VsdHMgPSBbXSxcblx0XHRcdFx0bWF0Y2hlciA9IGNvbXBpbGUoIHNlbGVjdG9yLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSApO1xuXG5cdFx0XHRyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID9cblx0XHRcdFx0bWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXG5cdFx0XHRcdFx0XHRpID0gc2VlZC5sZW5ndGg7XG5cblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkW2ldID0gIShtYXRjaGVzW2ldID0gZWxlbSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lclRleHQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KGxhbmcgfHwgXCJcIikgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoXCJ4bWw6bGFuZ1wiKSB8fCBlbGVtLmdldEF0dHJpYnV0ZShcImxhbmdcIikpICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdFwidGFyZ2V0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0XHRyZXR1cm4gaGFzaCAmJiBoYXNoLnNsaWNlKCAxICkgPT09IGVsZW0uaWQ7XG5cdFx0fSxcblxuXHRcdFwicm9vdFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2NFbGVtO1xuXHRcdH0sXG5cblx0XHRcImZvY3VzXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKCFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpKSAmJiAhIShlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4KTtcblx0XHR9LFxuXG5cdFx0XCJlbmFibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlO1xuXHRcdH0sXG5cblx0XHRcImRpc2FibGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7XG5cdFx0fSxcblxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiAobm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiAhIWVsZW0uY2hlY2tlZCkgfHwgKG5vZGVOYW1lID09PSBcIm9wdGlvblwiICYmICEhZWxlbS5zZWxlY3RlZCk7XG5cdFx0fSxcblxuXHRcdFwic2VsZWN0ZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZWxlbS5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBlbGVtLnNlbGVjdGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA8IDYgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0XCJwYXJlbnRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gIUV4cHIucHNldWRvc1tcImVtcHR5XCJdKCBlbGVtICk7XG5cdFx0fSxcblxuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdCggKGF0dHIgPSBlbGVtLmdldEF0dHJpYnV0ZShcInR5cGVcIikpID09IG51bGwgfHwgYXR0ci50b0xvd2VyQ2FzZSgpID09PSBcInRleHRcIiApO1xuXHRcdH0sXG5cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9KSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSlcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zW1wibnRoXCJdID0gRXhwci5wc2V1ZG9zW1wiZXFcIl07XG5cbmZvciAoIGkgaW4geyByYWRpbzogdHJ1ZSwgY2hlY2tib3g6IHRydWUsIGZpbGU6IHRydWUsIHBhc3N3b3JkOiB0cnVlLCBpbWFnZTogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUlucHV0UHNldWRvKCBpICk7XG59XG5mb3IgKCBpIGluIHsgc3VibWl0OiB0cnVlLCByZXNldDogdHJ1ZSB9ICkge1xuXHRFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUJ1dHRvblBzZXVkbyggaSApO1xufVxuXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxuZnVuY3Rpb24gdG9rZW5pemUoIHNlbGVjdG9yLCBwYXJzZU9ubHkgKSB7XG5cdHZhciBtYXRjaGVkLCBtYXRjaCwgdG9rZW5zLCB0eXBlLFxuXHRcdHNvRmFyLCBncm91cHMsIHByZUZpbHRlcnMsXG5cdFx0Y2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xuXG5cdGlmICggY2FjaGVkICkge1xuXHRcdHJldHVybiBwYXJzZU9ubHkgPyAwIDogY2FjaGVkLnNsaWNlKCAwICk7XG5cdH1cblxuXHRzb0ZhciA9IHNlbGVjdG9yO1xuXHRncm91cHMgPSBbXTtcblx0cHJlRmlsdGVycyA9IEV4cHIucHJlRmlsdGVyO1xuXG5cdHdoaWxlICggc29GYXIgKSB7XG5cblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHRpZiAoIChtYXRjaCA9IHJjb21iaW5hdG9ycy5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0dG9rZW5zLnB1c2goe1xuXHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0dHlwZTogbWF0Y2hbMF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0pO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xuXHRcdFx0aWYgKCAobWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApKSAmJiAoIXByZUZpbHRlcnNbIHR5cGUgXSB8fFxuXHRcdFx0XHQobWF0Y2ggPSBwcmVGaWx0ZXJzWyB0eXBlIF0oIG1hdGNoICkpKSApIHtcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHRcdHRva2Vucy5wdXNoKHtcblx0XHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRcdG1hdGNoZXM6IG1hdGNoXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggIW1hdGNoZWQgKSB7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcGFyc2VPbmx5ID9cblx0XHRzb0Zhci5sZW5ndGggOlxuXHRcdHNvRmFyID9cblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XG5cdFx0XHR0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTtcbn1cblxuZnVuY3Rpb24gdG9TZWxlY3RvciggdG9rZW5zICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRzZWxlY3RvciA9IFwiXCI7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdHNlbGVjdG9yICs9IHRva2Vuc1tpXS52YWx1ZTtcblx0fVxuXHRyZXR1cm4gc2VsZWN0b3I7XG59XG5cbmZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoIG1hdGNoZXIsIGNvbWJpbmF0b3IsIGJhc2UgKSB7XG5cdHZhciBkaXIgPSBjb21iaW5hdG9yLmRpcixcblx0XHRjaGVja05vbkVsZW1lbnRzID0gYmFzZSAmJiBkaXIgPT09IFwicGFyZW50Tm9kZVwiLFxuXHRcdGRvbmVOYW1lID0gZG9uZSsrO1xuXG5cdHJldHVybiBjb21iaW5hdG9yLmZpcnN0ID9cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0d2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSA6XG5cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIG9sZENhY2hlLCBvdXRlckNhY2hlLFxuXHRcdFx0XHRuZXdDYWNoZSA9IFsgZGlycnVucywgZG9uZU5hbWUgXTtcblxuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8IChlbGVtWyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IG91dGVyQ2FjaGVbIGRpciBdKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZVsgZGlyIF0gPSBuZXdDYWNoZTtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIChuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcbn1cblxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xuXHRyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggIW1hdGNoZXJzW2ldKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWzBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRpZiAoICFmaWx0ZXIgfHwgZmlsdGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0aWYgKCBtYXBwZWQgKSB7XG5cdFx0XHRcdFx0bWFwLnB1c2goIGkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBuZXdVbm1hdGNoZWQ7XG59XG5cbmZ1bmN0aW9uIHNldE1hdGNoZXIoIHByZUZpbHRlciwgc2VsZWN0b3IsIG1hdGNoZXIsIHBvc3RGaWx0ZXIsIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApIHtcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTtcblx0fVxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmluZGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICk7XG5cdH1cblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksXG5cblx0XHRcdG1hdGNoZXJJbiA9IHByZUZpbHRlciAmJiAoIHNlZWQgfHwgIXNlbGVjdG9yICkgP1xuXHRcdFx0XHRjb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdGVsZW1zLFxuXG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlciA/XG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHRpZiAoIG1hdGNoZXIgKSB7XG5cdFx0XHRtYXRjaGVyKCBtYXRjaGVySW4sIG1hdGNoZXJPdXQsIGNvbnRleHQsIHhtbCApO1xuXHRcdH1cblxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoZWxlbSA9IHRlbXBbaV0pICkge1xuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggc2VlZCApIHtcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XG5cdFx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goIChtYXRjaGVySW5baV0gPSBlbGVtKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCAobWF0Y2hlck91dCA9IFtdKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSAmJlxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZi5jYWxsKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbaV0pID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbdGVtcF0gPSAhKHJlc3VsdHNbdGVtcF0gPSBlbGVtKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9KTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Ub2tlbnMoIHRva2VucyApIHtcblx0dmFyIGNoZWNrQ29udGV4dCwgbWF0Y2hlciwgaixcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdGxlYWRpbmdSZWxhdGl2ZSA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1swXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlW1wiIFwiXSxcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXG5cblx0XHRtYXRjaENvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBjaGVja0NvbnRleHQ7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoQW55Q29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGluZGV4T2YuY2FsbCggY2hlY2tDb250ZXh0LCBlbGVtICkgPiAtMTtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hlcnMgPSBbIGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRyZXR1cm4gKCAhbGVhZGluZ1JlbGF0aXZlICYmICggeG1sIHx8IGNvbnRleHQgIT09IG91dGVybW9zdENvbnRleHQgKSApIHx8IChcblx0XHRcdFx0KGNoZWNrQ29udGV4dCA9IGNvbnRleHQpLm5vZGVUeXBlID9cblx0XHRcdFx0XHRtYXRjaENvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0XHRtYXRjaEFueUNvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApICk7XG5cdFx0fSBdO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKG1hdGNoZXIgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbaV0udHlwZSBdKSApIHtcblx0XHRcdG1hdGNoZXJzID0gWyBhZGRDb21iaW5hdG9yKGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLCBtYXRjaGVyKSBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyID0gRXhwci5maWx0ZXJbIHRva2Vuc1tpXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1tpXS5tYXRjaGVzICk7XG5cblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1tqXS50eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHNldE1hdGNoZXIoXG5cdFx0XHRcdFx0aSA+IDEgJiYgZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3Rvcihcblx0XHRcdFx0XHRcdHRva2Vucy5zbGljZSggMCwgaSAtIDEgKS5jb25jYXQoeyB2YWx1ZTogdG9rZW5zWyBpIC0gMiBdLnR5cGUgPT09IFwiIFwiID8gXCIqXCIgOiBcIlwiIH0pXG5cdFx0XHRcdFx0KS5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksXG5cdFx0XHRcdFx0bWF0Y2hlcixcblx0XHRcdFx0XHRpIDwgaiAmJiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zLnNsaWNlKCBpLCBqICkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIG1hdGNoZXJGcm9tVG9rZW5zKCAodG9rZW5zID0gdG9rZW5zLnNsaWNlKCBqICkpICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkge1xuXHR2YXIgYnlTZXQgPSBzZXRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdHN1cGVyTWF0Y2hlciA9IGZ1bmN0aW9uKCBzZWVkLCBjb250ZXh0LCB4bWwsIHJlc3VsdHMsIG91dGVybW9zdCApIHtcblx0XHRcdHZhciBlbGVtLCBqLCBtYXRjaGVyLFxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxuXHRcdFx0XHRpID0gXCIwXCIsXG5cdFx0XHRcdHVubWF0Y2hlZCA9IHNlZWQgJiYgW10sXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcblx0XHRcdFx0Y29udGV4dEJhY2t1cCA9IG91dGVybW9zdENvbnRleHQsXG5cdFx0XHRcdGVsZW1zID0gc2VlZCB8fCBieUVsZW1lbnQgJiYgRXhwci5maW5kW1wiVEFHXCJdKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEpLFxuXHRcdFx0XHRsZW4gPSBlbGVtcy5sZW5ndGg7XG5cblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCAhPT0gZG9jdW1lbnQgJiYgY29udGV4dDtcblx0XHRcdH1cblxuXHRcdFx0Zm9yICggOyBpICE9PSBsZW4gJiYgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGJ5RWxlbWVudCAmJiBlbGVtICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBlbGVtZW50TWF0Y2hlcnNbaisrXSkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBieVNldCApIHtcblx0XHRcdFx0XHRpZiAoIChlbGVtID0gIW1hdGNoZXIgJiYgZWxlbSkgKSB7XG5cdFx0XHRcdFx0XHRtYXRjaGVkQ291bnQtLTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRtYXRjaGVkQ291bnQgKz0gaTtcblx0XHRcdGlmICggYnlTZXQgJiYgaSAhPT0gbWF0Y2hlZENvdW50ICkge1xuXHRcdFx0XHRqID0gMDtcblx0XHRcdFx0d2hpbGUgKCAobWF0Y2hlciA9IHNldE1hdGNoZXJzW2orK10pICkge1xuXHRcdFx0XHRcdG1hdGNoZXIoIHVubWF0Y2hlZCwgc2V0TWF0Y2hlZCwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFtpXSA9IHBvcC5jYWxsKCByZXN1bHRzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRzZXRNYXRjaGVkID0gY29uZGVuc2UoIHNldE1hdGNoZWQgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHRpZiAoIG91dGVybW9zdCAmJiAhc2VlZCAmJiBzZXRNYXRjaGVkLmxlbmd0aCA+IDAgJiZcblx0XHRcdFx0XHQoIG1hdGNoZWRDb3VudCArIHNldE1hdGNoZXJzLmxlbmd0aCApID4gMSApIHtcblxuXHRcdFx0XHRcdFNpenpsZS51bmlxdWVTb3J0KCByZXN1bHRzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoW2ldICk7XG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRzZXRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlKCBzZWxlY3RvciwgbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTtcblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59O1xuXG4vKipcbiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzZWxlY3RvciBBIHNlbGVjdG9yIG9yIGEgcHJlLWNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0c11cbiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0XG4gKi9cbnNlbGVjdCA9IFNpenpsZS5zZWxlY3QgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBpLCB0b2tlbnMsIHRva2VuLCB0eXBlLCBmaW5kLFxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXG5cdFx0bWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IpICk7XG5cblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XG5cblx0aWYgKCBtYXRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAodG9rZW4gPSB0b2tlbnNbMF0pLnR5cGUgPT09IFwiSURcIiAmJlxuXHRcdFx0XHRzdXBwb3J0LmdldEJ5SWQgJiYgY29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbXCJJRFwiXSggdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKHJ1bmVzY2FwZSwgZnVuZXNjYXBlKSwgY29udGV4dCApIHx8IFtdIClbMF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdGkgPSBtYXRjaEV4cHJbXCJuZWVkc0NvbnRleHRcIl0udGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbaV07XG5cblx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgKHR5cGUgPSB0b2tlbi50eXBlKSBdICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGlmICggKGZpbmQgPSBFeHByLmZpbmRbIHR5cGUgXSkgKSB7XG5cdFx0XHRcdGlmICggKHNlZWQgPSBmaW5kKFxuXHRcdFx0XHRcdHRva2VuLm1hdGNoZXNbMF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcblx0XHRcdFx0XHRyc2libGluZy50ZXN0KCB0b2tlbnNbMF0udHlwZSApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdFx0XHRcdCkpICkge1xuXG5cdFx0XHRcdFx0dG9rZW5zLnNwbGljZSggaSwgMSApO1xuXHRcdFx0XHRcdHNlbGVjdG9yID0gc2VlZC5sZW5ndGggJiYgdG9TZWxlY3RvciggdG9rZW5zICk7XG5cdFx0XHRcdFx0aWYgKCAhc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZWVkICk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdCggY29tcGlsZWQgfHwgY29tcGlsZSggc2VsZWN0b3IsIG1hdGNoICkgKShcblx0XHRzZWVkLFxuXHRcdGNvbnRleHQsXG5cdFx0IWRvY3VtZW50SXNIVE1MLFxuXHRcdHJlc3VsdHMsXG5cdFx0cnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dFxuXHQpO1xuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cblxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdChcIlwiKS5zb3J0KCBzb3J0T3JkZXIgKS5qb2luKFwiXCIpID09PSBleHBhbmRvO1xuXG5zdXBwb3J0LmRldGVjdER1cGxpY2F0ZXMgPSAhIWhhc0R1cGxpY2F0ZTtcblxuc2V0RG9jdW1lbnQoKTtcblxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdjEgKSB7XG5cdHJldHVybiBkaXYxLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpICkgJiAxO1xufSk7XG5cbmlmICggIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRkaXYuaW5uZXJIVE1MID0gXCI8YSBocmVmPScjJz48L2E+XCI7XG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIiA7XG59KSApIHtcblx0YWRkSGFuZGxlKCBcInR5cGV8aHJlZnxoZWlnaHR8d2lkdGhcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwidHlwZVwiID8gMSA6IDIgKTtcblx0XHR9XG5cdH0pO1xufVxuXG5pZiAoICFzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRkaXYuaW5uZXJIVE1MID0gXCI8aW5wdXQvPlwiO1xuXHRkaXYuZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiwgXCJcIiApO1xuXHRyZXR1cm4gZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gXCJcIjtcbn0pICkge1xuXHRhZGRIYW5kbGUoIFwidmFsdWVcIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdGlmICggIWlzWE1MICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xuXHRcdH1cblx0fSk7XG59XG5cbmlmICggIWFzc2VydChmdW5jdGlvbiggZGl2ICkge1xuXHRyZXR1cm4gZGl2LmdldEF0dHJpYnV0ZShcImRpc2FibGVkXCIpID09IG51bGw7XG59KSApIHtcblx0YWRkSGFuZGxlKCBib29sZWFucywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkge1xuXHRcdHZhciB2YWw7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbVsgbmFtZSBdID09PSB0cnVlID8gbmFtZS50b0xvd2VyQ2FzZSgpIDpcblx0XHRcdFx0XHQodmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkpICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG5cdFx0fVxuXHR9KTtcbn1cblxuaWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblx0ZGVmaW5lKGZ1bmN0aW9uKCkgeyByZXR1cm4gU2l6emxlOyB9KTtcbn0gZWxzZSBpZiAoIHR5cGVvZiBtb2R1bGUgIT09IFwidW5kZWZpbmVkXCIgJiYgbW9kdWxlLmV4cG9ydHMgKSB7XG5cdG1vZHVsZS5leHBvcnRzID0gU2l6emxlO1xufSBlbHNlIHtcblx0d2luZG93LlNpenpsZSA9IFNpenpsZTtcbn1cblxufSkoIHdpbmRvdyApO1xuXG47KGZ1bmN0aW9uKGVuZ2luZSkge1xuICB2YXIgZXh0ZW5kRWxlbWVudHMgPSBQcm90b3R5cGUuU2VsZWN0b3IuZXh0ZW5kRWxlbWVudHM7XG5cbiAgZnVuY3Rpb24gc2VsZWN0KHNlbGVjdG9yLCBzY29wZSkge1xuICAgIHJldHVybiBleHRlbmRFbGVtZW50cyhlbmdpbmUoc2VsZWN0b3IsIHNjb3BlIHx8IGRvY3VtZW50KSk7XG4gIH1cblxuICBmdW5jdGlvbiBtYXRjaChlbGVtZW50LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBlbmdpbmUubWF0Y2hlcyhzZWxlY3RvciwgW2VsZW1lbnRdKS5sZW5ndGggPT0gMTtcbiAgfVxuXG4gIFByb3RvdHlwZS5TZWxlY3Rvci5lbmdpbmUgPSBlbmdpbmU7XG4gIFByb3RvdHlwZS5TZWxlY3Rvci5zZWxlY3QgPSBzZWxlY3Q7XG4gIFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaCA9IG1hdGNoO1xufSkoU2l6emxlKTtcblxud2luZG93LlNpenpsZSA9IFByb3RvdHlwZS5fb3JpZ2luYWxfcHJvcGVydHk7XG5kZWxldGUgUHJvdG90eXBlLl9vcmlnaW5hbF9wcm9wZXJ0eTtcblxudmFyIEZvcm0gPSB7XG4gIHJlc2V0OiBmdW5jdGlvbihmb3JtKSB7XG4gICAgZm9ybSA9ICQoZm9ybSk7XG4gICAgZm9ybS5yZXNldCgpO1xuICAgIHJldHVybiBmb3JtO1xuICB9LFxuXG4gIHNlcmlhbGl6ZUVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50cywgb3B0aW9ucykge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPSAnb2JqZWN0Jykgb3B0aW9ucyA9IHsgaGFzaDogISFvcHRpb25zIH07XG4gICAgZWxzZSBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKG9wdGlvbnMuaGFzaCkpIG9wdGlvbnMuaGFzaCA9IHRydWU7XG4gICAgdmFyIGtleSwgdmFsdWUsIHN1Ym1pdHRlZCA9IGZhbHNlLCBzdWJtaXQgPSBvcHRpb25zLnN1Ym1pdCwgYWNjdW11bGF0b3IsIGluaXRpYWw7XG5cbiAgICBpZiAob3B0aW9ucy5oYXNoKSB7XG4gICAgICBpbml0aWFsID0ge307XG4gICAgICBhY2N1bXVsYXRvciA9IGZ1bmN0aW9uKHJlc3VsdCwga2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoa2V5IGluIHJlc3VsdCkge1xuICAgICAgICAgIGlmICghT2JqZWN0LmlzQXJyYXkocmVzdWx0W2tleV0pKSByZXN1bHRba2V5XSA9IFtyZXN1bHRba2V5XV07XG4gICAgICAgICAgcmVzdWx0W2tleV0gPSByZXN1bHRba2V5XS5jb25jYXQodmFsdWUpO1xuICAgICAgICB9IGVsc2UgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGluaXRpYWwgPSAnJztcbiAgICAgIGFjY3VtdWxhdG9yID0gZnVuY3Rpb24ocmVzdWx0LCBrZXksIHZhbHVlcykge1xuICAgICAgICBpZiAoIU9iamVjdC5pc0FycmF5KHZhbHVlcykpIHt2YWx1ZXMgPSBbdmFsdWVzXTt9XG4gICAgICAgIGlmICghdmFsdWVzLmxlbmd0aCkge3JldHVybiByZXN1bHQ7fVxuICAgICAgICB2YXIgZW5jb2RlZEtleSA9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpLmdzdWIoLyUyMC8sICcrJyk7XG4gICAgICAgIHJldHVybiByZXN1bHQgKyAocmVzdWx0ID8gXCImXCIgOiBcIlwiKSArIHZhbHVlcy5tYXAoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZS5nc3ViKC8oXFxyKT9cXG4vLCAnXFxyXFxuJyk7XG4gICAgICAgICAgdmFsdWUgPSBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpO1xuICAgICAgICAgIHZhbHVlID0gdmFsdWUuZ3N1YigvJTIwLywgJysnKTtcbiAgICAgICAgICByZXR1cm4gZW5jb2RlZEtleSArIFwiPVwiICsgdmFsdWU7XG4gICAgICAgIH0pLmpvaW4oXCImXCIpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudHMuaW5qZWN0KGluaXRpYWwsIGZ1bmN0aW9uKHJlc3VsdCwgZWxlbWVudCkge1xuICAgICAgaWYgKCFlbGVtZW50LmRpc2FibGVkICYmIGVsZW1lbnQubmFtZSkge1xuICAgICAgICBrZXkgPSBlbGVtZW50Lm5hbWU7IHZhbHVlID0gJChlbGVtZW50KS5nZXRWYWx1ZSgpO1xuICAgICAgICBpZiAodmFsdWUgIT0gbnVsbCAmJiBlbGVtZW50LnR5cGUgIT0gJ2ZpbGUnICYmIChlbGVtZW50LnR5cGUgIT0gJ3N1Ym1pdCcgfHwgKCFzdWJtaXR0ZWQgJiZcbiAgICAgICAgICAgIHN1Ym1pdCAhPT0gZmFsc2UgJiYgKCFzdWJtaXQgfHwga2V5ID09IHN1Ym1pdCkgJiYgKHN1Ym1pdHRlZCA9IHRydWUpKSkpIHtcbiAgICAgICAgICByZXN1bHQgPSBhY2N1bXVsYXRvcihyZXN1bHQsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG59O1xuXG5Gb3JtLk1ldGhvZHMgPSB7XG4gIHNlcmlhbGl6ZTogZnVuY3Rpb24oZm9ybSwgb3B0aW9ucykge1xuICAgIHJldHVybiBGb3JtLnNlcmlhbGl6ZUVsZW1lbnRzKEZvcm0uZ2V0RWxlbWVudHMoZm9ybSksIG9wdGlvbnMpO1xuICB9LFxuXG5cbiAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGZvcm0pIHtcbiAgICB2YXIgZWxlbWVudHMgPSAkKGZvcm0pLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gICAgdmFyIGVsZW1lbnQsIHJlc3VsdHMgPSBbXSwgc2VyaWFsaXplcnMgPSBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnM7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgZWxlbWVudCA9IGVsZW1lbnRzW2ldOyBpKyspIHtcbiAgICAgIGlmIChzZXJpYWxpemVyc1tlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKV0pXG4gICAgICAgIHJlc3VsdHMucHVzaChFbGVtZW50LmV4dGVuZChlbGVtZW50KSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9LFxuXG4gIGdldElucHV0czogZnVuY3Rpb24oZm9ybSwgdHlwZU5hbWUsIG5hbWUpIHtcbiAgICBmb3JtID0gJChmb3JtKTtcbiAgICB2YXIgaW5wdXRzID0gZm9ybS5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTtcblxuICAgIGlmICghdHlwZU5hbWUgJiYgIW5hbWUpIHJldHVybiAkQShpbnB1dHMpLm1hcChFbGVtZW50LmV4dGVuZCk7XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbWF0Y2hpbmdJbnB1dHMgPSBbXSwgbGVuZ3RoID0gaW5wdXRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaW5wdXQgPSBpbnB1dHNbaV07XG4gICAgICBpZiAoKHR5cGVOYW1lICYmIGlucHV0LnR5cGUgIT0gdHlwZU5hbWUpIHx8IChuYW1lICYmIGlucHV0Lm5hbWUgIT0gbmFtZSkpXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgbWF0Y2hpbmdJbnB1dHMucHVzaChFbGVtZW50LmV4dGVuZChpbnB1dCkpO1xuICAgIH1cblxuICAgIHJldHVybiBtYXRjaGluZ0lucHV0cztcbiAgfSxcblxuICBkaXNhYmxlOiBmdW5jdGlvbihmb3JtKSB7XG4gICAgZm9ybSA9ICQoZm9ybSk7XG4gICAgRm9ybS5nZXRFbGVtZW50cyhmb3JtKS5pbnZva2UoJ2Rpc2FibGUnKTtcbiAgICByZXR1cm4gZm9ybTtcbiAgfSxcblxuICBlbmFibGU6IGZ1bmN0aW9uKGZvcm0pIHtcbiAgICBmb3JtID0gJChmb3JtKTtcbiAgICBGb3JtLmdldEVsZW1lbnRzKGZvcm0pLmludm9rZSgnZW5hYmxlJyk7XG4gICAgcmV0dXJuIGZvcm07XG4gIH0sXG5cbiAgZmluZEZpcnN0RWxlbWVudDogZnVuY3Rpb24oZm9ybSkge1xuICAgIHZhciBlbGVtZW50cyA9ICQoZm9ybSkuZ2V0RWxlbWVudHMoKS5maW5kQWxsKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiAnaGlkZGVuJyAhPSBlbGVtZW50LnR5cGUgJiYgIWVsZW1lbnQuZGlzYWJsZWQ7XG4gICAgfSk7XG4gICAgdmFyIGZpcnN0QnlJbmRleCA9IGVsZW1lbnRzLmZpbmRBbGwoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQuaGFzQXR0cmlidXRlKCd0YWJJbmRleCcpICYmIGVsZW1lbnQudGFiSW5kZXggPj0gMDtcbiAgICB9KS5zb3J0QnkoZnVuY3Rpb24oZWxlbWVudCkgeyByZXR1cm4gZWxlbWVudC50YWJJbmRleCB9KS5maXJzdCgpO1xuXG4gICAgcmV0dXJuIGZpcnN0QnlJbmRleCA/IGZpcnN0QnlJbmRleCA6IGVsZW1lbnRzLmZpbmQoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhKSQvaS50ZXN0KGVsZW1lbnQudGFnTmFtZSk7XG4gICAgfSk7XG4gIH0sXG5cbiAgZm9jdXNGaXJzdEVsZW1lbnQ6IGZ1bmN0aW9uKGZvcm0pIHtcbiAgICBmb3JtID0gJChmb3JtKTtcbiAgICB2YXIgZWxlbWVudCA9IGZvcm0uZmluZEZpcnN0RWxlbWVudCgpO1xuICAgIGlmIChlbGVtZW50KSBlbGVtZW50LmFjdGl2YXRlKCk7XG4gICAgcmV0dXJuIGZvcm07XG4gIH0sXG5cbiAgcmVxdWVzdDogZnVuY3Rpb24oZm9ybSwgb3B0aW9ucykge1xuICAgIGZvcm0gPSAkKGZvcm0pLCBvcHRpb25zID0gT2JqZWN0LmNsb25lKG9wdGlvbnMgfHwgeyB9KTtcblxuICAgIHZhciBwYXJhbXMgPSBvcHRpb25zLnBhcmFtZXRlcnMsIGFjdGlvbiA9IGZvcm0ucmVhZEF0dHJpYnV0ZSgnYWN0aW9uJykgfHwgJyc7XG4gICAgaWYgKGFjdGlvbi5ibGFuaygpKSBhY3Rpb24gPSB3aW5kb3cubG9jYXRpb24uaHJlZjtcbiAgICBvcHRpb25zLnBhcmFtZXRlcnMgPSBmb3JtLnNlcmlhbGl6ZSh0cnVlKTtcblxuICAgIGlmIChwYXJhbXMpIHtcbiAgICAgIGlmIChPYmplY3QuaXNTdHJpbmcocGFyYW1zKSkgcGFyYW1zID0gcGFyYW1zLnRvUXVlcnlQYXJhbXMoKTtcbiAgICAgIE9iamVjdC5leHRlbmQob3B0aW9ucy5wYXJhbWV0ZXJzLCBwYXJhbXMpO1xuICAgIH1cblxuICAgIGlmIChmb3JtLmhhc0F0dHJpYnV0ZSgnbWV0aG9kJykgJiYgIW9wdGlvbnMubWV0aG9kKVxuICAgICAgb3B0aW9ucy5tZXRob2QgPSBmb3JtLm1ldGhvZDtcblxuICAgIHJldHVybiBuZXcgQWpheC5SZXF1ZXN0KGFjdGlvbiwgb3B0aW9ucyk7XG4gIH1cbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5cbkZvcm0uRWxlbWVudCA9IHtcbiAgZm9jdXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAkKGVsZW1lbnQpLmZvY3VzKCk7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH0sXG5cbiAgc2VsZWN0OiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgJChlbGVtZW50KS5zZWxlY3QoKTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxufTtcblxuRm9ybS5FbGVtZW50Lk1ldGhvZHMgPSB7XG5cbiAgc2VyaWFsaXplOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgaWYgKCFlbGVtZW50LmRpc2FibGVkICYmIGVsZW1lbnQubmFtZSkge1xuICAgICAgdmFyIHZhbHVlID0gZWxlbWVudC5nZXRWYWx1ZSgpO1xuICAgICAgaWYgKHZhbHVlICE9IHVuZGVmaW5lZCkge1xuICAgICAgICB2YXIgcGFpciA9IHsgfTtcbiAgICAgICAgcGFpcltlbGVtZW50Lm5hbWVdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiBPYmplY3QudG9RdWVyeVN0cmluZyhwYWlyKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9LFxuXG4gIGdldFZhbHVlOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIG1ldGhvZCA9IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnNbbWV0aG9kXShlbGVtZW50KTtcbiAgfSxcblxuICBzZXRWYWx1ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUpIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICB2YXIgbWV0aG9kID0gZWxlbWVudC50YWdOYW1lLnRvTG93ZXJDYXNlKCk7XG4gICAgRm9ybS5FbGVtZW50LlNlcmlhbGl6ZXJzW21ldGhvZF0oZWxlbWVudCwgdmFsdWUpO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9LFxuXG4gIGNsZWFyOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgJChlbGVtZW50KS52YWx1ZSA9ICcnO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9LFxuXG4gIHByZXNlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gJChlbGVtZW50KS52YWx1ZSAhPSAnJztcbiAgfSxcblxuICBhY3RpdmF0ZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHRyeSB7XG4gICAgICBlbGVtZW50LmZvY3VzKCk7XG4gICAgICBpZiAoZWxlbWVudC5zZWxlY3QgJiYgKGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9ICdpbnB1dCcgfHxcbiAgICAgICAgICAhKC9eKD86YnV0dG9ufHJlc2V0fHN1Ym1pdCkkL2kudGVzdChlbGVtZW50LnR5cGUpKSkpXG4gICAgICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgfSBjYXRjaCAoZSkgeyB9XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH0sXG5cbiAgZGlzYWJsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIGVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9LFxuXG4gIGVuYWJsZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIGVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbnZhciBGaWVsZCA9IEZvcm0uRWxlbWVudDtcblxudmFyICRGID0gRm9ybS5FbGVtZW50Lk1ldGhvZHMuZ2V0VmFsdWU7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5Gb3JtLkVsZW1lbnQuU2VyaWFsaXplcnMgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIGlucHV0KGVsZW1lbnQsIHZhbHVlKSB7XG4gICAgc3dpdGNoIChlbGVtZW50LnR5cGUudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAnY2hlY2tib3gnOlxuICAgICAgY2FzZSAncmFkaW8nOlxuICAgICAgICByZXR1cm4gaW5wdXRTZWxlY3RvcihlbGVtZW50LCB2YWx1ZSk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdmFsdWVTZWxlY3RvcihlbGVtZW50LCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5wdXRTZWxlY3RvcihlbGVtZW50LCB2YWx1ZSkge1xuICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQodmFsdWUpKVxuICAgICAgcmV0dXJuIGVsZW1lbnQuY2hlY2tlZCA/IGVsZW1lbnQudmFsdWUgOiBudWxsO1xuICAgIGVsc2UgZWxlbWVudC5jaGVja2VkID0gISF2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbHVlU2VsZWN0b3IoZWxlbWVudCwgdmFsdWUpIHtcbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKHZhbHVlKSkgcmV0dXJuIGVsZW1lbnQudmFsdWU7XG4gICAgZWxzZSBlbGVtZW50LnZhbHVlID0gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3QoZWxlbWVudCwgdmFsdWUpIHtcbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKHZhbHVlKSlcbiAgICAgIHJldHVybiAoZWxlbWVudC50eXBlID09PSAnc2VsZWN0LW9uZScgPyBzZWxlY3RPbmUgOiBzZWxlY3RNYW55KShlbGVtZW50KTtcblxuICAgIHZhciBvcHQsIGN1cnJlbnRWYWx1ZSwgc2luZ2xlID0gIU9iamVjdC5pc0FycmF5KHZhbHVlKTtcbiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gZWxlbWVudC5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgb3B0ID0gZWxlbWVudC5vcHRpb25zW2ldO1xuICAgICAgY3VycmVudFZhbHVlID0gdGhpcy5vcHRpb25WYWx1ZShvcHQpO1xuICAgICAgaWYgKHNpbmdsZSkge1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID09IHZhbHVlKSB7XG4gICAgICAgICAgb3B0LnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGVsc2Ugb3B0LnNlbGVjdGVkID0gdmFsdWUuaW5jbHVkZShjdXJyZW50VmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHNlbGVjdE9uZShlbGVtZW50KSB7XG4gICAgdmFyIGluZGV4ID0gZWxlbWVudC5zZWxlY3RlZEluZGV4O1xuICAgIHJldHVybiBpbmRleCA+PSAwID8gb3B0aW9uVmFsdWUoZWxlbWVudC5vcHRpb25zW2luZGV4XSkgOiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gc2VsZWN0TWFueShlbGVtZW50KSB7XG4gICAgdmFyIHZhbHVlcywgbGVuZ3RoID0gZWxlbWVudC5sZW5ndGg7XG4gICAgaWYgKCFsZW5ndGgpIHJldHVybiBudWxsO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIHZhbHVlcyA9IFtdOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBvcHQgPSBlbGVtZW50Lm9wdGlvbnNbaV07XG4gICAgICBpZiAob3B0LnNlbGVjdGVkKSB2YWx1ZXMucHVzaChvcHRpb25WYWx1ZShvcHQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIGZ1bmN0aW9uIG9wdGlvblZhbHVlKG9wdCkge1xuICAgIHJldHVybiBFbGVtZW50Lmhhc0F0dHJpYnV0ZShvcHQsICd2YWx1ZScpID8gb3B0LnZhbHVlIDogb3B0LnRleHQ7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGlucHV0OiAgICAgICAgIGlucHV0LFxuICAgIGlucHV0U2VsZWN0b3I6IGlucHV0U2VsZWN0b3IsXG4gICAgdGV4dGFyZWE6ICAgICAgdmFsdWVTZWxlY3RvcixcbiAgICBzZWxlY3Q6ICAgICAgICBzZWxlY3QsXG4gICAgc2VsZWN0T25lOiAgICAgc2VsZWN0T25lLFxuICAgIHNlbGVjdE1hbnk6ICAgIHNlbGVjdE1hbnksXG4gICAgb3B0aW9uVmFsdWU6ICAgb3B0aW9uVmFsdWUsXG4gICAgYnV0dG9uOiAgICAgICAgdmFsdWVTZWxlY3RvclxuICB9O1xufSkoKTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cblxuQWJzdHJhY3QuVGltZWRPYnNlcnZlciA9IENsYXNzLmNyZWF0ZShQZXJpb2RpY2FsRXhlY3V0ZXIsIHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oJHN1cGVyLCBlbGVtZW50LCBmcmVxdWVuY3ksIGNhbGxiYWNrKSB7XG4gICAgJHN1cGVyKGNhbGxiYWNrLCBmcmVxdWVuY3kpO1xuICAgIHRoaXMuZWxlbWVudCAgID0gJChlbGVtZW50KTtcbiAgICB0aGlzLmxhc3RWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcbiAgfSxcblxuICBleGVjdXRlOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG4gICAgaWYgKE9iamVjdC5pc1N0cmluZyh0aGlzLmxhc3RWYWx1ZSkgJiYgT2JqZWN0LmlzU3RyaW5nKHZhbHVlKSA/XG4gICAgICAgIHRoaXMubGFzdFZhbHVlICE9IHZhbHVlIDogU3RyaW5nKHRoaXMubGFzdFZhbHVlKSAhPSBTdHJpbmcodmFsdWUpKSB7XG4gICAgICB0aGlzLmNhbGxiYWNrKHRoaXMuZWxlbWVudCwgdmFsdWUpO1xuICAgICAgdGhpcy5sYXN0VmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cbn0pO1xuXG5Gb3JtLkVsZW1lbnQuT2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoQWJzdHJhY3QuVGltZWRPYnNlcnZlciwge1xuICBnZXRWYWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIEZvcm0uRWxlbWVudC5nZXRWYWx1ZSh0aGlzLmVsZW1lbnQpO1xuICB9XG59KTtcblxuRm9ybS5PYnNlcnZlciA9IENsYXNzLmNyZWF0ZShBYnN0cmFjdC5UaW1lZE9ic2VydmVyLCB7XG4gIGdldFZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gRm9ybS5zZXJpYWxpemUodGhpcy5lbGVtZW50KTtcbiAgfVxufSk7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5BYnN0cmFjdC5FdmVudE9ic2VydmVyID0gQ2xhc3MuY3JlYXRlKHtcbiAgaW5pdGlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCwgY2FsbGJhY2spIHtcbiAgICB0aGlzLmVsZW1lbnQgID0gJChlbGVtZW50KTtcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICB0aGlzLmxhc3RWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTtcbiAgICBpZiAodGhpcy5lbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PSAnZm9ybScpXG4gICAgICB0aGlzLnJlZ2lzdGVyRm9ybUNhbGxiYWNrcygpO1xuICAgIGVsc2VcbiAgICAgIHRoaXMucmVnaXN0ZXJDYWxsYmFjayh0aGlzLmVsZW1lbnQpO1xuICB9LFxuXG4gIG9uRWxlbWVudEV2ZW50OiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdmFsdWUgPSB0aGlzLmdldFZhbHVlKCk7XG4gICAgaWYgKHRoaXMubGFzdFZhbHVlICE9IHZhbHVlKSB7XG4gICAgICB0aGlzLmNhbGxiYWNrKHRoaXMuZWxlbWVudCwgdmFsdWUpO1xuICAgICAgdGhpcy5sYXN0VmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gIH0sXG5cbiAgcmVnaXN0ZXJGb3JtQ2FsbGJhY2tzOiBmdW5jdGlvbigpIHtcbiAgICBGb3JtLmdldEVsZW1lbnRzKHRoaXMuZWxlbWVudCkuZWFjaCh0aGlzLnJlZ2lzdGVyQ2FsbGJhY2ssIHRoaXMpO1xuICB9LFxuXG4gIHJlZ2lzdGVyQ2FsbGJhY2s6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC50eXBlKSB7XG4gICAgICBzd2l0Y2ggKGVsZW1lbnQudHlwZS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIGNhc2UgJ2NoZWNrYm94JzpcbiAgICAgICAgY2FzZSAncmFkaW8nOlxuICAgICAgICAgIEV2ZW50Lm9ic2VydmUoZWxlbWVudCwgJ2NsaWNrJywgdGhpcy5vbkVsZW1lbnRFdmVudC5iaW5kKHRoaXMpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBFdmVudC5vYnNlcnZlKGVsZW1lbnQsICdjaGFuZ2UnLCB0aGlzLm9uRWxlbWVudEV2ZW50LmJpbmQodGhpcykpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxufSk7XG5cbkZvcm0uRWxlbWVudC5FdmVudE9ic2VydmVyID0gQ2xhc3MuY3JlYXRlKEFic3RyYWN0LkV2ZW50T2JzZXJ2ZXIsIHtcbiAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBGb3JtLkVsZW1lbnQuZ2V0VmFsdWUodGhpcy5lbGVtZW50KTtcbiAgfVxufSk7XG5cbkZvcm0uRXZlbnRPYnNlcnZlciA9IENsYXNzLmNyZWF0ZShBYnN0cmFjdC5FdmVudE9ic2VydmVyLCB7XG4gIGdldFZhbHVlOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gRm9ybS5zZXJpYWxpemUodGhpcy5lbGVtZW50KTtcbiAgfVxufSk7XG4oZnVuY3Rpb24oR0xPQkFMKSB7XG4gIHZhciBESVYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgdmFyIGRvY0VsID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICB2YXIgTU9VU0VFTlRFUl9NT1VTRUxFQVZFX0VWRU5UU19TVVBQT1JURUQgPSAnb25tb3VzZWVudGVyJyBpbiBkb2NFbFxuICAgJiYgJ29ubW91c2VsZWF2ZScgaW4gZG9jRWw7XG5cbiAgdmFyIEV2ZW50ID0ge1xuICAgIEtFWV9CQUNLU1BBQ0U6IDgsXG4gICAgS0VZX1RBQjogICAgICAgOSxcbiAgICBLRVlfUkVUVVJOOiAgIDEzLFxuICAgIEtFWV9FU0M6ICAgICAgMjcsXG4gICAgS0VZX0xFRlQ6ICAgICAzNyxcbiAgICBLRVlfVVA6ICAgICAgIDM4LFxuICAgIEtFWV9SSUdIVDogICAgMzksXG4gICAgS0VZX0RPV046ICAgICA0MCxcbiAgICBLRVlfREVMRVRFOiAgIDQ2LFxuICAgIEtFWV9IT01FOiAgICAgMzYsXG4gICAgS0VZX0VORDogICAgICAzNSxcbiAgICBLRVlfUEFHRVVQOiAgIDMzLFxuICAgIEtFWV9QQUdFRE9XTjogMzQsXG4gICAgS0VZX0lOU0VSVDogICA0NVxuICB9O1xuXG5cbiAgdmFyIGlzSUVMZWdhY3lFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7IHJldHVybiBmYWxzZTsgfTtcblxuICBpZiAod2luZG93LmF0dGFjaEV2ZW50KSB7XG4gICAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICBpc0lFTGVnYWN5RXZlbnQgPSBmdW5jdGlvbihldmVudCkge1xuICAgICAgICByZXR1cm4gIShldmVudCBpbnN0YW5jZW9mIHdpbmRvdy5FdmVudCk7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpc0lFTGVnYWN5RXZlbnQgPSBmdW5jdGlvbihldmVudCkgeyByZXR1cm4gdHJ1ZTsgfTtcbiAgICB9XG4gIH1cblxuICB2YXIgX2lzQnV0dG9uO1xuXG4gIGZ1bmN0aW9uIF9pc0J1dHRvbkZvckRPTUV2ZW50cyhldmVudCwgY29kZSkge1xuICAgIHJldHVybiBldmVudC53aGljaCA/IChldmVudC53aGljaCA9PT0gY29kZSArIDEpIDogKGV2ZW50LmJ1dHRvbiA9PT0gY29kZSk7XG4gIH1cblxuICB2YXIgbGVnYWN5QnV0dG9uTWFwID0geyAwOiAxLCAxOiA0LCAyOiAyIH07XG4gIGZ1bmN0aW9uIF9pc0J1dHRvbkZvckxlZ2FjeUV2ZW50cyhldmVudCwgY29kZSkge1xuICAgIHJldHVybiBldmVudC5idXR0b24gPT09IGxlZ2FjeUJ1dHRvbk1hcFtjb2RlXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIF9pc0J1dHRvbkZvcldlYktpdChldmVudCwgY29kZSkge1xuICAgIHN3aXRjaCAoY29kZSkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZXZlbnQud2hpY2ggPT0gMSAmJiAhZXZlbnQubWV0YUtleTtcbiAgICAgIGNhc2UgMTogcmV0dXJuIGV2ZW50LndoaWNoID09IDIgfHwgKGV2ZW50LndoaWNoID09IDEgJiYgZXZlbnQubWV0YUtleSk7XG4gICAgICBjYXNlIDI6IHJldHVybiBldmVudC53aGljaCA9PSAzO1xuICAgICAgZGVmYXVsdDogcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGlmICh3aW5kb3cuYXR0YWNoRXZlbnQpIHtcbiAgICBpZiAoIXdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgICBfaXNCdXR0b24gPSBfaXNCdXR0b25Gb3JMZWdhY3lFdmVudHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIF9pc0J1dHRvbiA9IGZ1bmN0aW9uKGV2ZW50LCBjb2RlKSB7XG4gICAgICAgIHJldHVybiBpc0lFTGVnYWN5RXZlbnQoZXZlbnQpID8gX2lzQnV0dG9uRm9yTGVnYWN5RXZlbnRzKGV2ZW50LCBjb2RlKSA6XG4gICAgICAgICBfaXNCdXR0b25Gb3JET01FdmVudHMoZXZlbnQsIGNvZGUpO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChQcm90b3R5cGUuQnJvd3Nlci5XZWJLaXQpIHtcbiAgICBfaXNCdXR0b24gPSBfaXNCdXR0b25Gb3JXZWJLaXQ7XG4gIH0gZWxzZSB7XG4gICAgX2lzQnV0dG9uID0gX2lzQnV0dG9uRm9yRE9NRXZlbnRzO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNMZWZ0Q2xpY2soZXZlbnQpICAgeyByZXR1cm4gX2lzQnV0dG9uKGV2ZW50LCAwKSB9XG5cbiAgZnVuY3Rpb24gaXNNaWRkbGVDbGljayhldmVudCkgeyByZXR1cm4gX2lzQnV0dG9uKGV2ZW50LCAxKSB9XG5cbiAgZnVuY3Rpb24gaXNSaWdodENsaWNrKGV2ZW50KSAgeyByZXR1cm4gX2lzQnV0dG9uKGV2ZW50LCAyKSB9XG5cbiAgZnVuY3Rpb24gZWxlbWVudChldmVudCkge1xuICAgIHJldHVybiBFbGVtZW50LmV4dGVuZChfZWxlbWVudChldmVudCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gX2VsZW1lbnQoZXZlbnQpIHtcbiAgICBldmVudCA9IEV2ZW50LmV4dGVuZChldmVudCk7XG5cbiAgICB2YXIgbm9kZSA9IGV2ZW50LnRhcmdldCwgdHlwZSA9IGV2ZW50LnR5cGUsXG4gICAgIGN1cnJlbnRUYXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0O1xuXG4gICAgaWYgKGN1cnJlbnRUYXJnZXQgJiYgY3VycmVudFRhcmdldC50YWdOYW1lKSB7XG4gICAgICBpZiAodHlwZSA9PT0gJ2xvYWQnIHx8IHR5cGUgPT09ICdlcnJvcicgfHxcbiAgICAgICAgKHR5cGUgPT09ICdjbGljaycgJiYgY3VycmVudFRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdpbnB1dCdcbiAgICAgICAgICAmJiBjdXJyZW50VGFyZ2V0LnR5cGUgPT09ICdyYWRpbycpKVxuICAgICAgICAgICAgbm9kZSA9IGN1cnJlbnRUYXJnZXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGUubm9kZVR5cGUgPT0gTm9kZS5URVhUX05PREUgPyBub2RlLnBhcmVudE5vZGUgOiBub2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gZmluZEVsZW1lbnQoZXZlbnQsIGV4cHJlc3Npb24pIHtcbiAgICB2YXIgZWxlbWVudCA9IF9lbGVtZW50KGV2ZW50KSwgc2VsZWN0b3IgPSBQcm90b3R5cGUuU2VsZWN0b3I7XG4gICAgaWYgKCFleHByZXNzaW9uKSByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7XG4gICAgd2hpbGUgKGVsZW1lbnQpIHtcbiAgICAgIGlmIChPYmplY3QuaXNFbGVtZW50KGVsZW1lbnQpICYmIHNlbGVjdG9yLm1hdGNoKGVsZW1lbnQsIGV4cHJlc3Npb24pKVxuICAgICAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7XG4gICAgICBlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBvaW50ZXIoZXZlbnQpIHtcbiAgICByZXR1cm4geyB4OiBwb2ludGVyWChldmVudCksIHk6IHBvaW50ZXJZKGV2ZW50KSB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcG9pbnRlclgoZXZlbnQpIHtcbiAgICB2YXIgZG9jRWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICAgYm9keSA9IGRvY3VtZW50LmJvZHkgfHwgeyBzY3JvbGxMZWZ0OiAwIH07XG5cbiAgICByZXR1cm4gZXZlbnQucGFnZVggfHwgKGV2ZW50LmNsaWVudFggK1xuICAgICAgKGRvY0VsZW1lbnQuc2Nyb2xsTGVmdCB8fCBib2R5LnNjcm9sbExlZnQpIC1cbiAgICAgIChkb2NFbGVtZW50LmNsaWVudExlZnQgfHwgMCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9pbnRlclkoZXZlbnQpIHtcbiAgICB2YXIgZG9jRWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcbiAgICAgYm9keSA9IGRvY3VtZW50LmJvZHkgfHwgeyBzY3JvbGxUb3A6IDAgfTtcblxuICAgIHJldHVybiAgZXZlbnQucGFnZVkgfHwgKGV2ZW50LmNsaWVudFkgK1xuICAgICAgIChkb2NFbGVtZW50LnNjcm9sbFRvcCB8fCBib2R5LnNjcm9sbFRvcCkgLVxuICAgICAgIChkb2NFbGVtZW50LmNsaWVudFRvcCB8fCAwKSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHN0b3AoZXZlbnQpIHtcbiAgICBFdmVudC5leHRlbmQoZXZlbnQpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgICBldmVudC5zdG9wcGVkID0gdHJ1ZTtcbiAgfVxuXG5cbiAgRXZlbnQuTWV0aG9kcyA9IHtcbiAgICBpc0xlZnRDbGljazogICBpc0xlZnRDbGljayxcbiAgICBpc01pZGRsZUNsaWNrOiBpc01pZGRsZUNsaWNrLFxuICAgIGlzUmlnaHRDbGljazogIGlzUmlnaHRDbGljayxcblxuICAgIGVsZW1lbnQ6ICAgICBlbGVtZW50LFxuICAgIGZpbmRFbGVtZW50OiBmaW5kRWxlbWVudCxcblxuICAgIHBvaW50ZXI6ICBwb2ludGVyLFxuICAgIHBvaW50ZXJYOiBwb2ludGVyWCxcbiAgICBwb2ludGVyWTogcG9pbnRlclksXG5cbiAgICBzdG9wOiBzdG9wXG4gIH07XG5cbiAgdmFyIG1ldGhvZHMgPSBPYmplY3Qua2V5cyhFdmVudC5NZXRob2RzKS5pbmplY3QoeyB9LCBmdW5jdGlvbihtLCBuYW1lKSB7XG4gICAgbVtuYW1lXSA9IEV2ZW50Lk1ldGhvZHNbbmFtZV0ubWV0aG9kaXplKCk7XG4gICAgcmV0dXJuIG07XG4gIH0pO1xuXG4gIGlmICh3aW5kb3cuYXR0YWNoRXZlbnQpIHtcbiAgICBmdW5jdGlvbiBfcmVsYXRlZFRhcmdldChldmVudCkge1xuICAgICAgdmFyIGVsZW1lbnQ7XG4gICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgY2FzZSAnbW91c2VvdmVyJzpcbiAgICAgICAgY2FzZSAnbW91c2VlbnRlcic6XG4gICAgICAgICAgZWxlbWVudCA9IGV2ZW50LmZyb21FbGVtZW50O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdtb3VzZW91dCc6XG4gICAgICAgIGNhc2UgJ21vdXNlbGVhdmUnOlxuICAgICAgICAgIGVsZW1lbnQgPSBldmVudC50b0VsZW1lbnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gRWxlbWVudC5leHRlbmQoZWxlbWVudCk7XG4gICAgfVxuXG4gICAgdmFyIGFkZGl0aW9uYWxNZXRob2RzID0ge1xuICAgICAgc3RvcFByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHsgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlIH0sXG4gICAgICBwcmV2ZW50RGVmYXVsdDogIGZ1bmN0aW9uKCkgeyB0aGlzLnJldHVyblZhbHVlID0gZmFsc2UgfSxcbiAgICAgIGluc3BlY3Q6IGZ1bmN0aW9uKCkgeyByZXR1cm4gJ1tvYmplY3QgRXZlbnRdJyB9XG4gICAgfTtcblxuICAgIEV2ZW50LmV4dGVuZCA9IGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG4gICAgICBpZiAoIWV2ZW50KSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGlmICghaXNJRUxlZ2FjeUV2ZW50KGV2ZW50KSkgcmV0dXJuIGV2ZW50O1xuXG4gICAgICBpZiAoZXZlbnQuX2V4dGVuZGVkQnlQcm90b3R5cGUpIHJldHVybiBldmVudDtcbiAgICAgIGV2ZW50Ll9leHRlbmRlZEJ5UHJvdG90eXBlID0gUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247XG5cbiAgICAgIHZhciBwb2ludGVyID0gRXZlbnQucG9pbnRlcihldmVudCk7XG5cbiAgICAgIE9iamVjdC5leHRlbmQoZXZlbnQsIHtcbiAgICAgICAgdGFyZ2V0OiBldmVudC5zcmNFbGVtZW50IHx8IGVsZW1lbnQsXG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6IF9yZWxhdGVkVGFyZ2V0KGV2ZW50KSxcbiAgICAgICAgcGFnZVg6ICBwb2ludGVyLngsXG4gICAgICAgIHBhZ2VZOiAgcG9pbnRlci55XG4gICAgICB9KTtcblxuICAgICAgT2JqZWN0LmV4dGVuZChldmVudCwgbWV0aG9kcyk7XG4gICAgICBPYmplY3QuZXh0ZW5kKGV2ZW50LCBhZGRpdGlvbmFsTWV0aG9kcyk7XG5cbiAgICAgIHJldHVybiBldmVudDtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIEV2ZW50LmV4dGVuZCA9IFByb3RvdHlwZS5LO1xuICB9XG5cbiAgaWYgKHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgRXZlbnQucHJvdG90eXBlID0gd2luZG93LkV2ZW50LnByb3RvdHlwZSB8fCBkb2N1bWVudC5jcmVhdGVFdmVudCgnSFRNTEV2ZW50cycpLl9fcHJvdG9fXztcbiAgICBPYmplY3QuZXh0ZW5kKEV2ZW50LnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gIH1cblxuICB2YXIgRVZFTlRfVFJBTlNMQVRJT05TID0ge1xuICAgIG1vdXNlZW50ZXI6ICdtb3VzZW92ZXInLFxuICAgIG1vdXNlbGVhdmU6ICdtb3VzZW91dCdcbiAgfTtcblxuICBmdW5jdGlvbiBnZXRET01FdmVudE5hbWUoZXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIEVWRU5UX1RSQU5TTEFUSU9OU1tldmVudE5hbWVdIHx8IGV2ZW50TmFtZTtcbiAgfVxuXG4gIGlmIChNT1VTRUVOVEVSX01PVVNFTEVBVkVfRVZFTlRTX1NVUFBPUlRFRClcbiAgICBnZXRET01FdmVudE5hbWUgPSBQcm90b3R5cGUuSztcblxuICBmdW5jdGlvbiBnZXRVbmlxdWVFbGVtZW50SUQoZWxlbWVudCkge1xuICAgIGlmIChlbGVtZW50ID09PSB3aW5kb3cpIHJldHVybiAwO1xuXG4gICAgaWYgKHR5cGVvZiBlbGVtZW50Ll9wcm90b3R5cGVVSUQgPT09ICd1bmRlZmluZWQnKVxuICAgICAgZWxlbWVudC5fcHJvdG90eXBlVUlEID0gRWxlbWVudC5TdG9yYWdlLlVJRCsrO1xuICAgIHJldHVybiBlbGVtZW50Ll9wcm90b3R5cGVVSUQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRVbmlxdWVFbGVtZW50SURfSUUoZWxlbWVudCkge1xuICAgIGlmIChlbGVtZW50ID09PSB3aW5kb3cpIHJldHVybiAwO1xuICAgIGlmIChlbGVtZW50ID09IGRvY3VtZW50KSByZXR1cm4gMTtcbiAgICByZXR1cm4gZWxlbWVudC51bmlxdWVJRDtcbiAgfVxuXG4gIGlmICgndW5pcXVlSUQnIGluIERJVilcbiAgICBnZXRVbmlxdWVFbGVtZW50SUQgPSBnZXRVbmlxdWVFbGVtZW50SURfSUU7XG5cbiAgZnVuY3Rpb24gaXNDdXN0b21FdmVudChldmVudE5hbWUpIHtcbiAgICByZXR1cm4gZXZlbnROYW1lLmluY2x1ZGUoJzonKTtcbiAgfVxuXG4gIEV2ZW50Ll9pc0N1c3RvbUV2ZW50ID0gaXNDdXN0b21FdmVudDtcblxuICBmdW5jdGlvbiBnZXRSZWdpc3RyeUZvckVsZW1lbnQoZWxlbWVudCwgdWlkKSB7XG4gICAgdmFyIENBQ0hFID0gR0xPQkFMLkV2ZW50LmNhY2hlO1xuICAgIGlmIChPYmplY3QuaXNVbmRlZmluZWQodWlkKSlcbiAgICAgIHVpZCA9IGdldFVuaXF1ZUVsZW1lbnRJRChlbGVtZW50KTtcbiAgICBpZiAoIUNBQ0hFW3VpZF0pIENBQ0hFW3VpZF0gPSB7IGVsZW1lbnQ6IGVsZW1lbnQgfTtcbiAgICByZXR1cm4gQ0FDSEVbdWlkXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlc3Ryb3lSZWdpc3RyeUZvckVsZW1lbnQoZWxlbWVudCwgdWlkKSB7XG4gICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZCh1aWQpKVxuICAgICAgdWlkID0gZ2V0VW5pcXVlRWxlbWVudElEKGVsZW1lbnQpO1xuICAgIGRlbGV0ZSBHTE9CQUwuRXZlbnQuY2FjaGVbdWlkXTtcbiAgfVxuXG5cbiAgZnVuY3Rpb24gcmVnaXN0ZXIoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgdmFyIHJlZ2lzdHJ5ID0gZ2V0UmVnaXN0cnlGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgIGlmICghcmVnaXN0cnlbZXZlbnROYW1lXSkgcmVnaXN0cnlbZXZlbnROYW1lXSA9IFtdO1xuICAgIHZhciBlbnRyaWVzID0gcmVnaXN0cnlbZXZlbnROYW1lXTtcblxuICAgIHZhciBpID0gZW50cmllcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSlcbiAgICAgIGlmIChlbnRyaWVzW2ldLmhhbmRsZXIgPT09IGhhbmRsZXIpIHJldHVybiBudWxsO1xuXG4gICAgdmFyIHVpZCA9IGdldFVuaXF1ZUVsZW1lbnRJRChlbGVtZW50KTtcbiAgICB2YXIgcmVzcG9uZGVyID0gR0xPQkFMLkV2ZW50Ll9jcmVhdGVSZXNwb25kZXIodWlkLCBldmVudE5hbWUsIGhhbmRsZXIpO1xuICAgIHZhciBlbnRyeSA9IHtcbiAgICAgIHJlc3BvbmRlcjogcmVzcG9uZGVyLFxuICAgICAgaGFuZGxlcjogICBoYW5kbGVyXG4gICAgfTtcblxuICAgIGVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgZnVuY3Rpb24gdW5yZWdpc3RlcihlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICB2YXIgcmVnaXN0cnkgPSBnZXRSZWdpc3RyeUZvckVsZW1lbnQoZWxlbWVudCk7XG4gICAgdmFyIGVudHJpZXMgPSByZWdpc3RyeVtldmVudE5hbWVdO1xuICAgIGlmICghZW50cmllcykgcmV0dXJuO1xuXG4gICAgdmFyIGkgPSBlbnRyaWVzLmxlbmd0aCwgZW50cnk7XG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWYgKGVudHJpZXNbaV0uaGFuZGxlciA9PT0gaGFuZGxlcikge1xuICAgICAgICBlbnRyeSA9IGVudHJpZXNbaV07XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZW50cnkpIHJldHVybjtcblxuICAgIHZhciBpbmRleCA9IGVudHJpZXMuaW5kZXhPZihlbnRyeSk7XG4gICAgZW50cmllcy5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cblxuICBmdW5jdGlvbiBvYnNlcnZlKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcikge1xuICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICAgIHZhciBlbnRyeSA9IHJlZ2lzdGVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcik7XG5cbiAgICBpZiAoZW50cnkgPT09IG51bGwpIHJldHVybiBlbGVtZW50O1xuXG4gICAgdmFyIHJlc3BvbmRlciA9IGVudHJ5LnJlc3BvbmRlcjtcbiAgICBpZiAoaXNDdXN0b21FdmVudChldmVudE5hbWUpKVxuICAgICAgb2JzZXJ2ZUN1c3RvbUV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgcmVzcG9uZGVyKTtcbiAgICBlbHNlXG4gICAgICBvYnNlcnZlU3RhbmRhcmRFdmVudChlbGVtZW50LCBldmVudE5hbWUsIHJlc3BvbmRlcik7XG5cbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9ic2VydmVTdGFuZGFyZEV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgcmVzcG9uZGVyKSB7XG4gICAgdmFyIGFjdHVhbEV2ZW50TmFtZSA9IGdldERPTUV2ZW50TmFtZShldmVudE5hbWUpO1xuICAgIGlmIChlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihhY3R1YWxFdmVudE5hbWUsIHJlc3BvbmRlciwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50LmF0dGFjaEV2ZW50KCdvbicgKyBhY3R1YWxFdmVudE5hbWUsIHJlc3BvbmRlcik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb2JzZXJ2ZUN1c3RvbUV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgcmVzcG9uZGVyKSB7XG4gICAgaWYgKGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdkYXRhYXZhaWxhYmxlJywgcmVzcG9uZGVyLCBmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuYXR0YWNoRXZlbnQoJ29uZGF0YWF2YWlsYWJsZScsIHJlc3BvbmRlcik7XG4gICAgICBlbGVtZW50LmF0dGFjaEV2ZW50KCdvbmxvc2VjYXB0dXJlJywgICByZXNwb25kZXIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3BPYnNlcnZpbmcoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgZWxlbWVudCA9ICQoZWxlbWVudCk7XG4gICAgdmFyIGhhbmRsZXJHaXZlbiA9ICFPYmplY3QuaXNVbmRlZmluZWQoaGFuZGxlciksXG4gICAgIGV2ZW50TmFtZUdpdmVuID0gIU9iamVjdC5pc1VuZGVmaW5lZChldmVudE5hbWUpO1xuXG4gICAgaWYgKCFldmVudE5hbWVHaXZlbiAmJiAhaGFuZGxlckdpdmVuKSB7XG4gICAgICBzdG9wT2JzZXJ2aW5nRWxlbWVudChlbGVtZW50KTtcbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cblxuICAgIGlmICghaGFuZGxlckdpdmVuKSB7XG4gICAgICBzdG9wT2JzZXJ2aW5nRXZlbnROYW1lKGVsZW1lbnQsIGV2ZW50TmFtZSk7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG5cbiAgICB2YXIgZW50cnkgPSB1bnJlZ2lzdGVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcik7XG5cbiAgICBpZiAoIWVudHJ5KSByZXR1cm4gZWxlbWVudDtcbiAgICByZW1vdmVFdmVudChlbGVtZW50LCBldmVudE5hbWUsIGVudHJ5LnJlc3BvbmRlcik7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBzdG9wT2JzZXJ2aW5nU3RhbmRhcmRFdmVudChlbGVtZW50LCBldmVudE5hbWUsIHJlc3BvbmRlcikge1xuICAgIHZhciBhY3R1YWxFdmVudE5hbWUgPSBnZXRET01FdmVudE5hbWUoZXZlbnROYW1lKTtcbiAgICBpZiAoZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoYWN0dWFsRXZlbnROYW1lLCByZXNwb25kZXIsIGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgYWN0dWFsRXZlbnROYW1lLCByZXNwb25kZXIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3BPYnNlcnZpbmdDdXN0b21FdmVudChlbGVtZW50LCBldmVudE5hbWUsIHJlc3BvbmRlcikge1xuICAgIGlmIChlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIpIHtcbiAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGF0YWF2YWlsYWJsZScsIHJlc3BvbmRlciwgZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50LmRldGFjaEV2ZW50KCdvbmRhdGFhdmFpbGFibGUnLCByZXNwb25kZXIpO1xuICAgICAgZWxlbWVudC5kZXRhY2hFdmVudCgnb25sb3NlY2FwdHVyZScsICAgcmVzcG9uZGVyKTtcbiAgICB9XG4gIH1cblxuXG5cbiAgZnVuY3Rpb24gc3RvcE9ic2VydmluZ0VsZW1lbnQoZWxlbWVudCkge1xuICAgIHZhciB1aWQgPSBnZXRVbmlxdWVFbGVtZW50SUQoZWxlbWVudCksIHJlZ2lzdHJ5ID0gR0xPQkFMLkV2ZW50LmNhY2hlW3VpZF07XG4gICAgaWYgKCFyZWdpc3RyeSkgcmV0dXJuO1xuXG4gICAgZGVzdHJveVJlZ2lzdHJ5Rm9yRWxlbWVudChlbGVtZW50LCB1aWQpO1xuXG4gICAgdmFyIGVudHJpZXMsIGk7XG4gICAgZm9yICh2YXIgZXZlbnROYW1lIGluIHJlZ2lzdHJ5KSB7XG4gICAgICBpZiAoZXZlbnROYW1lID09PSAnZWxlbWVudCcpIGNvbnRpbnVlO1xuXG4gICAgICBlbnRyaWVzID0gcmVnaXN0cnlbZXZlbnROYW1lXTtcbiAgICAgIGkgPSBlbnRyaWVzLmxlbmd0aDtcbiAgICAgIHdoaWxlIChpLS0pXG4gICAgICAgIHJlbW92ZUV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgZW50cmllc1tpXS5yZXNwb25kZXIpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHN0b3BPYnNlcnZpbmdFdmVudE5hbWUoZWxlbWVudCwgZXZlbnROYW1lKSB7XG4gICAgdmFyIHJlZ2lzdHJ5ID0gZ2V0UmVnaXN0cnlGb3JFbGVtZW50KGVsZW1lbnQpO1xuICAgIHZhciBlbnRyaWVzID0gcmVnaXN0cnlbZXZlbnROYW1lXTtcbiAgICBpZiAoIWVudHJpZXMpIHJldHVybjtcbiAgICBkZWxldGUgcmVnaXN0cnlbZXZlbnROYW1lXTtcblxuICAgIHZhciBpID0gZW50cmllcy5sZW5ndGg7XG4gICAgd2hpbGUgKGktLSlcbiAgICAgIHJlbW92ZUV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgZW50cmllc1tpXS5yZXNwb25kZXIpO1xuICB9XG5cblxuICBmdW5jdGlvbiByZW1vdmVFdmVudChlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICBpZiAoaXNDdXN0b21FdmVudChldmVudE5hbWUpKVxuICAgICAgc3RvcE9ic2VydmluZ0N1c3RvbUV2ZW50KGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgZWxzZVxuICAgICAgc3RvcE9ic2VydmluZ1N0YW5kYXJkRXZlbnQoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKTtcbiAgfVxuXG5cblxuICBmdW5jdGlvbiBnZXRGaXJlVGFyZ2V0KGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudCAhPT0gZG9jdW1lbnQpIHJldHVybiBlbGVtZW50O1xuICAgIGlmIChkb2N1bWVudC5jcmVhdGVFdmVudCAmJiAhZWxlbWVudC5kaXNwYXRjaEV2ZW50KVxuICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpcmUoZWxlbWVudCwgZXZlbnROYW1lLCBtZW1vLCBidWJibGUpIHtcbiAgICBlbGVtZW50ID0gZ2V0RmlyZVRhcmdldCgkKGVsZW1lbnQpKTtcbiAgICBpZiAoT2JqZWN0LmlzVW5kZWZpbmVkKGJ1YmJsZSkpIGJ1YmJsZSA9IHRydWU7XG4gICAgbWVtbyA9IG1lbW8gfHwge307XG5cbiAgICB2YXIgZXZlbnQgPSBmaXJlRXZlbnQoZWxlbWVudCwgZXZlbnROYW1lLCBtZW1vLCBidWJibGUpO1xuICAgIHJldHVybiBFdmVudC5leHRlbmQoZXZlbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gZmlyZUV2ZW50X0RPTShlbGVtZW50LCBldmVudE5hbWUsIG1lbW8sIGJ1YmJsZSkge1xuICAgIHZhciBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdIVE1MRXZlbnRzJyk7XG4gICAgZXZlbnQuaW5pdEV2ZW50KCdkYXRhYXZhaWxhYmxlJywgYnViYmxlLCB0cnVlKTtcblxuICAgIGV2ZW50LmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICBldmVudC5tZW1vID0gbWVtbztcblxuICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgcmV0dXJuIGV2ZW50O1xuICB9XG5cbiAgZnVuY3Rpb24gZmlyZUV2ZW50X0lFKGVsZW1lbnQsIGV2ZW50TmFtZSwgbWVtbywgYnViYmxlKSB7XG4gICAgdmFyIGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnRPYmplY3QoKTtcbiAgICBldmVudC5ldmVudFR5cGUgPSBidWJibGUgPyAnb25kYXRhYXZhaWxhYmxlJyA6ICdvbmxvc2VjYXB0dXJlJztcblxuICAgIGV2ZW50LmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICBldmVudC5tZW1vID0gbWVtbztcblxuICAgIGVsZW1lbnQuZmlyZUV2ZW50KGV2ZW50LmV2ZW50VHlwZSwgZXZlbnQpO1xuICAgIHJldHVybiBldmVudDtcbiAgfVxuXG4gIHZhciBmaXJlRXZlbnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudCA/IGZpcmVFdmVudF9ET00gOiBmaXJlRXZlbnRfSUU7XG5cblxuXG4gIEV2ZW50LkhhbmRsZXIgPSBDbGFzcy5jcmVhdGUoe1xuICAgIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQsIGV2ZW50TmFtZSwgc2VsZWN0b3IsIGNhbGxiYWNrKSB7XG4gICAgICB0aGlzLmVsZW1lbnQgICA9ICQoZWxlbWVudCk7XG4gICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgIHRoaXMuc2VsZWN0b3IgID0gc2VsZWN0b3I7XG4gICAgICB0aGlzLmNhbGxiYWNrICA9IGNhbGxiYWNrO1xuICAgICAgdGhpcy5oYW5kbGVyICAgPSB0aGlzLmhhbmRsZUV2ZW50LmJpbmQodGhpcyk7XG4gICAgfSxcblxuXG4gICAgc3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgRXZlbnQub2JzZXJ2ZSh0aGlzLmVsZW1lbnQsIHRoaXMuZXZlbnROYW1lLCB0aGlzLmhhbmRsZXIpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgRXZlbnQuc3RvcE9ic2VydmluZyh0aGlzLmVsZW1lbnQsIHRoaXMuZXZlbnROYW1lLCB0aGlzLmhhbmRsZXIpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIGVsZW1lbnQgPSBFdmVudC5maW5kRWxlbWVudChldmVudCwgdGhpcy5zZWxlY3Rvcik7XG4gICAgICBpZiAoZWxlbWVudCkgdGhpcy5jYWxsYmFjay5jYWxsKHRoaXMuZWxlbWVudCwgZXZlbnQsIGVsZW1lbnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgZnVuY3Rpb24gb24oZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3RvciwgY2FsbGJhY2spIHtcbiAgICBlbGVtZW50ID0gJChlbGVtZW50KTtcbiAgICBpZiAoT2JqZWN0LmlzRnVuY3Rpb24oc2VsZWN0b3IpICYmIE9iamVjdC5pc1VuZGVmaW5lZChjYWxsYmFjaykpIHtcbiAgICAgIGNhbGxiYWNrID0gc2VsZWN0b3IsIHNlbGVjdG9yID0gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEV2ZW50LkhhbmRsZXIoZWxlbWVudCwgZXZlbnROYW1lLCBzZWxlY3RvciwgY2FsbGJhY2spLnN0YXJ0KCk7XG4gIH1cblxuICBPYmplY3QuZXh0ZW5kKEV2ZW50LCBFdmVudC5NZXRob2RzKTtcblxuICBPYmplY3QuZXh0ZW5kKEV2ZW50LCB7XG4gICAgZmlyZTogICAgICAgICAgZmlyZSxcbiAgICBvYnNlcnZlOiAgICAgICBvYnNlcnZlLFxuICAgIHN0b3BPYnNlcnZpbmc6IHN0b3BPYnNlcnZpbmcsXG4gICAgb246ICAgICAgICAgICAgb25cbiAgfSk7XG5cbiAgRWxlbWVudC5hZGRNZXRob2RzKHtcbiAgICBmaXJlOiAgICAgICAgICBmaXJlLFxuXG4gICAgb2JzZXJ2ZTogICAgICAgb2JzZXJ2ZSxcblxuICAgIHN0b3BPYnNlcnZpbmc6IHN0b3BPYnNlcnZpbmcsXG5cbiAgICBvbjogICAgICAgICAgICBvblxuICB9KTtcblxuICBPYmplY3QuZXh0ZW5kKGRvY3VtZW50LCB7XG4gICAgZmlyZTogICAgICAgICAgZmlyZS5tZXRob2RpemUoKSxcblxuICAgIG9ic2VydmU6ICAgICAgIG9ic2VydmUubWV0aG9kaXplKCksXG5cbiAgICBzdG9wT2JzZXJ2aW5nOiBzdG9wT2JzZXJ2aW5nLm1ldGhvZGl6ZSgpLFxuXG4gICAgb246ICAgICAgICAgICAgb24ubWV0aG9kaXplKCksXG5cbiAgICBsb2FkZWQ6ICAgICAgICBmYWxzZVxuICB9KTtcblxuICBpZiAoR0xPQkFMLkV2ZW50KSBPYmplY3QuZXh0ZW5kKHdpbmRvdy5FdmVudCwgRXZlbnQpO1xuICBlbHNlIEdMT0JBTC5FdmVudCA9IEV2ZW50O1xuXG4gIEdMT0JBTC5FdmVudC5jYWNoZSA9IHt9O1xuXG4gIGZ1bmN0aW9uIGRlc3Ryb3lDYWNoZV9JRSgpIHtcbiAgICBHTE9CQUwuRXZlbnQuY2FjaGUgPSBudWxsO1xuICB9XG5cbiAgaWYgKHdpbmRvdy5hdHRhY2hFdmVudClcbiAgICB3aW5kb3cuYXR0YWNoRXZlbnQoJ29udW5sb2FkJywgZGVzdHJveUNhY2hlX0lFKTtcblxuICBESVYgPSBudWxsO1xuICBkb2NFbCA9IG51bGw7XG59KSh0aGlzKTtcblxuKGZ1bmN0aW9uKEdMT0JBTCkge1xuICAvKiBDb2RlIGZvciBjcmVhdGluZyBsZWFrLWZyZWUgZXZlbnQgcmVzcG9uZGVycyBpcyBiYXNlZCBvbiB3b3JrIGJ5XG4gICBKb2huLURhdmlkIERhbHRvbi4gKi9cblxuICB2YXIgZG9jRWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIHZhciBNT1VTRUVOVEVSX01PVVNFTEVBVkVfRVZFTlRTX1NVUFBPUlRFRCA9ICdvbm1vdXNlZW50ZXInIGluIGRvY0VsXG4gICAgJiYgJ29ubW91c2VsZWF2ZScgaW4gZG9jRWw7XG5cbiAgZnVuY3Rpb24gaXNTaW11bGF0ZWRNb3VzZUVudGVyTGVhdmVFdmVudChldmVudE5hbWUpIHtcbiAgICByZXR1cm4gIU1PVVNFRU5URVJfTU9VU0VMRUFWRV9FVkVOVFNfU1VQUE9SVEVEICYmXG4gICAgIChldmVudE5hbWUgPT09ICdtb3VzZWVudGVyJyB8fCBldmVudE5hbWUgPT09ICdtb3VzZWxlYXZlJyk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVSZXNwb25kZXIodWlkLCBldmVudE5hbWUsIGhhbmRsZXIpIHtcbiAgICBpZiAoRXZlbnQuX2lzQ3VzdG9tRXZlbnQoZXZlbnROYW1lKSlcbiAgICAgIHJldHVybiBjcmVhdGVSZXNwb25kZXJGb3JDdXN0b21FdmVudCh1aWQsIGV2ZW50TmFtZSwgaGFuZGxlcik7XG4gICAgaWYgKGlzU2ltdWxhdGVkTW91c2VFbnRlckxlYXZlRXZlbnQoZXZlbnROYW1lKSlcbiAgICAgIHJldHVybiBjcmVhdGVNb3VzZUVudGVyTGVhdmVSZXNwb25kZXIodWlkLCBldmVudE5hbWUsIGhhbmRsZXIpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBpZiAoIUV2ZW50LmNhY2hlKSByZXR1cm47XG5cbiAgICAgIHZhciBlbGVtZW50ID0gRXZlbnQuY2FjaGVbdWlkXS5lbGVtZW50O1xuICAgICAgRXZlbnQuZXh0ZW5kKGV2ZW50LCBlbGVtZW50KTtcbiAgICAgIGhhbmRsZXIuY2FsbChlbGVtZW50LCBldmVudCk7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVJlc3BvbmRlckZvckN1c3RvbUV2ZW50KHVpZCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgZWxlbWVudCA9IEV2ZW50LmNhY2hlW3VpZF0uZWxlbWVudDtcblxuICAgICAgaWYgKE9iamVjdC5pc1VuZGVmaW5lZChldmVudC5ldmVudE5hbWUpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGlmIChldmVudC5ldmVudE5hbWUgIT09IGV2ZW50TmFtZSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuXG4gICAgICBFdmVudC5leHRlbmQoZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgaGFuZGxlci5jYWxsKGVsZW1lbnQsIGV2ZW50KTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlTW91c2VFbnRlckxlYXZlUmVzcG9uZGVyKHVpZCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgZWxlbWVudCA9IEV2ZW50LmNhY2hlW3VpZF0uZWxlbWVudDtcblxuICAgICAgRXZlbnQuZXh0ZW5kKGV2ZW50LCBlbGVtZW50KTtcbiAgICAgIHZhciBwYXJlbnQgPSBldmVudC5yZWxhdGVkVGFyZ2V0O1xuXG4gICAgICB3aGlsZSAocGFyZW50ICYmIHBhcmVudCAhPT0gZWxlbWVudCkge1xuICAgICAgICB0cnkgeyBwYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTsgfVxuICAgICAgICBjYXRjaChlKSB7IHBhcmVudCA9IGVsZW1lbnQ7IH1cbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudCA9PT0gZWxlbWVudCkgcmV0dXJuO1xuICAgICAgaGFuZGxlci5jYWxsKGVsZW1lbnQsIGV2ZW50KTtcbiAgICB9XG4gIH1cblxuICBHTE9CQUwuRXZlbnQuX2NyZWF0ZVJlc3BvbmRlciA9IGNyZWF0ZVJlc3BvbmRlcjtcbiAgZG9jRWwgPSBudWxsO1xufSkodGhpcyk7XG5cbihmdW5jdGlvbihHTE9CQUwpIHtcbiAgLyogU3VwcG9ydCBmb3IgdGhlIERPTUNvbnRlbnRMb2FkZWQgZXZlbnQgaXMgYmFzZWQgb24gd29yayBieSBEYW4gV2ViYixcbiAgICAgTWF0dGhpYXMgTWlsbGVyLCBEZWFuIEVkd2FyZHMsIEpvaG4gUmVzaWcsIGFuZCBEaWVnbyBQZXJpbmkuICovXG5cbiAgdmFyIFRJTUVSO1xuXG4gIGZ1bmN0aW9uIGZpcmVDb250ZW50TG9hZGVkRXZlbnQoKSB7XG4gICAgaWYgKGRvY3VtZW50LmxvYWRlZCkgcmV0dXJuO1xuICAgIGlmIChUSU1FUikgd2luZG93LmNsZWFyVGltZW91dChUSU1FUik7XG4gICAgZG9jdW1lbnQubG9hZGVkID0gdHJ1ZTtcbiAgICBkb2N1bWVudC5maXJlKCdkb206bG9hZGVkJyk7XG4gIH1cblxuICBmdW5jdGlvbiBjaGVja1JlYWR5U3RhdGUoKSB7XG4gICAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScpIHtcbiAgICAgIGRvY3VtZW50LmRldGFjaEV2ZW50KCdvbnJlYWR5c3RhdGVjaGFuZ2UnLCBjaGVja1JlYWR5U3RhdGUpO1xuICAgICAgZmlyZUNvbnRlbnRMb2FkZWRFdmVudCgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBvbGxEb1Njcm9sbCgpIHtcbiAgICB0cnkge1xuICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsKCdsZWZ0Jyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgVElNRVIgPSBwb2xsRG9TY3JvbGwuZGVmZXIoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmaXJlQ29udGVudExvYWRlZEV2ZW50KCk7XG4gIH1cblxuXG4gIGlmIChkb2N1bWVudC5yZWFkeVN0YXRlID09PSAnY29tcGxldGUnKSB7XG4gICAgZmlyZUNvbnRlbnRMb2FkZWRFdmVudCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKSB7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIGZpcmVDb250ZW50TG9hZGVkRXZlbnQsIGZhbHNlKTtcbiAgfSBlbHNlIHtcbiAgICBkb2N1bWVudC5hdHRhY2hFdmVudCgnb25yZWFkeXN0YXRlY2hhbmdlJywgY2hlY2tSZWFkeVN0YXRlKTtcbiAgICBpZiAod2luZG93ID09IHRvcCkgVElNRVIgPSBwb2xsRG9TY3JvbGwuZGVmZXIoKTtcbiAgfVxuXG4gIEV2ZW50Lm9ic2VydmUod2luZG93LCAnbG9hZCcsIGZpcmVDb250ZW50TG9hZGVkRXZlbnQpO1xufSkodGhpcyk7XG5cblxuRWxlbWVudC5hZGRNZXRob2RzKCk7XG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gREVQUkVDQVRFRCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuSGFzaC50b1F1ZXJ5U3RyaW5nID0gT2JqZWN0LnRvUXVlcnlTdHJpbmc7XG5cbnZhciBUb2dnbGUgPSB7IGRpc3BsYXk6IEVsZW1lbnQudG9nZ2xlIH07XG5cbkVsZW1lbnQuTWV0aG9kcy5jaGlsZE9mID0gRWxlbWVudC5NZXRob2RzLmRlc2NlbmRhbnRPZjtcblxudmFyIEluc2VydGlvbiA9IHtcbiAgQmVmb3JlOiBmdW5jdGlvbihlbGVtZW50LCBjb250ZW50KSB7XG4gICAgcmV0dXJuIEVsZW1lbnQuaW5zZXJ0KGVsZW1lbnQsIHtiZWZvcmU6Y29udGVudH0pO1xuICB9LFxuXG4gIFRvcDogZnVuY3Rpb24oZWxlbWVudCwgY29udGVudCkge1xuICAgIHJldHVybiBFbGVtZW50Lmluc2VydChlbGVtZW50LCB7dG9wOmNvbnRlbnR9KTtcbiAgfSxcblxuICBCb3R0b206IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHtcbiAgICByZXR1cm4gRWxlbWVudC5pbnNlcnQoZWxlbWVudCwge2JvdHRvbTpjb250ZW50fSk7XG4gIH0sXG5cbiAgQWZ0ZXI6IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHtcbiAgICByZXR1cm4gRWxlbWVudC5pbnNlcnQoZWxlbWVudCwge2FmdGVyOmNvbnRlbnR9KTtcbiAgfVxufTtcblxudmFyICRjb250aW51ZSA9IG5ldyBFcnJvcignXCJ0aHJvdyAkY29udGludWVcIiBpcyBkZXByZWNhdGVkLCB1c2UgXCJyZXR1cm5cIiBpbnN0ZWFkJyk7XG5cbnZhciBQb3NpdGlvbiA9IHtcbiAgaW5jbHVkZVNjcm9sbE9mZnNldHM6IGZhbHNlLFxuXG4gIHByZXBhcmU6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZGVsdGFYID0gIHdpbmRvdy5wYWdlWE9mZnNldFxuICAgICAgICAgICAgICAgIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0XG4gICAgICAgICAgICAgICAgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0XG4gICAgICAgICAgICAgICAgfHwgMDtcbiAgICB0aGlzLmRlbHRhWSA9ICB3aW5kb3cucGFnZVlPZmZzZXRcbiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wXG4gICAgICAgICAgICAgICAgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3BcbiAgICAgICAgICAgICAgICB8fCAwO1xuICB9LFxuXG4gIHdpdGhpbjogZnVuY3Rpb24oZWxlbWVudCwgeCwgeSkge1xuICAgIGlmICh0aGlzLmluY2x1ZGVTY3JvbGxPZmZzZXRzKVxuICAgICAgcmV0dXJuIHRoaXMud2l0aGluSW5jbHVkaW5nU2Nyb2xsb2Zmc2V0cyhlbGVtZW50LCB4LCB5KTtcbiAgICB0aGlzLnhjb21wID0geDtcbiAgICB0aGlzLnljb21wID0geTtcbiAgICB0aGlzLm9mZnNldCA9IEVsZW1lbnQuY3VtdWxhdGl2ZU9mZnNldChlbGVtZW50KTtcblxuICAgIHJldHVybiAoeSA+PSB0aGlzLm9mZnNldFsxXSAmJlxuICAgICAgICAgICAgeSA8ICB0aGlzLm9mZnNldFsxXSArIGVsZW1lbnQub2Zmc2V0SGVpZ2h0ICYmXG4gICAgICAgICAgICB4ID49IHRoaXMub2Zmc2V0WzBdICYmXG4gICAgICAgICAgICB4IDwgIHRoaXMub2Zmc2V0WzBdICsgZWxlbWVudC5vZmZzZXRXaWR0aCk7XG4gIH0sXG5cbiAgd2l0aGluSW5jbHVkaW5nU2Nyb2xsb2Zmc2V0czogZnVuY3Rpb24oZWxlbWVudCwgeCwgeSkge1xuICAgIHZhciBvZmZzZXRjYWNoZSA9IEVsZW1lbnQuY3VtdWxhdGl2ZVNjcm9sbE9mZnNldChlbGVtZW50KTtcblxuICAgIHRoaXMueGNvbXAgPSB4ICsgb2Zmc2V0Y2FjaGVbMF0gLSB0aGlzLmRlbHRhWDtcbiAgICB0aGlzLnljb21wID0geSArIG9mZnNldGNhY2hlWzFdIC0gdGhpcy5kZWx0YVk7XG4gICAgdGhpcy5vZmZzZXQgPSBFbGVtZW50LmN1bXVsYXRpdmVPZmZzZXQoZWxlbWVudCk7XG5cbiAgICByZXR1cm4gKHRoaXMueWNvbXAgPj0gdGhpcy5vZmZzZXRbMV0gJiZcbiAgICAgICAgICAgIHRoaXMueWNvbXAgPCAgdGhpcy5vZmZzZXRbMV0gKyBlbGVtZW50Lm9mZnNldEhlaWdodCAmJlxuICAgICAgICAgICAgdGhpcy54Y29tcCA+PSB0aGlzLm9mZnNldFswXSAmJlxuICAgICAgICAgICAgdGhpcy54Y29tcCA8ICB0aGlzLm9mZnNldFswXSArIGVsZW1lbnQub2Zmc2V0V2lkdGgpO1xuICB9LFxuXG4gIG92ZXJsYXA6IGZ1bmN0aW9uKG1vZGUsIGVsZW1lbnQpIHtcbiAgICBpZiAoIW1vZGUpIHJldHVybiAwO1xuICAgIGlmIChtb2RlID09ICd2ZXJ0aWNhbCcpXG4gICAgICByZXR1cm4gKCh0aGlzLm9mZnNldFsxXSArIGVsZW1lbnQub2Zmc2V0SGVpZ2h0KSAtIHRoaXMueWNvbXApIC9cbiAgICAgICAgZWxlbWVudC5vZmZzZXRIZWlnaHQ7XG4gICAgaWYgKG1vZGUgPT0gJ2hvcml6b250YWwnKVxuICAgICAgcmV0dXJuICgodGhpcy5vZmZzZXRbMF0gKyBlbGVtZW50Lm9mZnNldFdpZHRoKSAtIHRoaXMueGNvbXApIC9cbiAgICAgICAgZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgfSxcblxuXG4gIGN1bXVsYXRpdmVPZmZzZXQ6IEVsZW1lbnQuTWV0aG9kcy5jdW11bGF0aXZlT2Zmc2V0LFxuXG4gIHBvc2l0aW9uZWRPZmZzZXQ6IEVsZW1lbnQuTWV0aG9kcy5wb3NpdGlvbmVkT2Zmc2V0LFxuXG4gIGFic29sdXRpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBQb3NpdGlvbi5wcmVwYXJlKCk7XG4gICAgcmV0dXJuIEVsZW1lbnQuYWJzb2x1dGl6ZShlbGVtZW50KTtcbiAgfSxcblxuICByZWxhdGl2aXplOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgUG9zaXRpb24ucHJlcGFyZSgpO1xuICAgIHJldHVybiBFbGVtZW50LnJlbGF0aXZpemUoZWxlbWVudCk7XG4gIH0sXG5cbiAgcmVhbE9mZnNldDogRWxlbWVudC5NZXRob2RzLmN1bXVsYXRpdmVTY3JvbGxPZmZzZXQsXG5cbiAgb2Zmc2V0UGFyZW50OiBFbGVtZW50Lk1ldGhvZHMuZ2V0T2Zmc2V0UGFyZW50LFxuXG4gIHBhZ2U6IEVsZW1lbnQuTWV0aG9kcy52aWV3cG9ydE9mZnNldCxcblxuICBjbG9uZTogZnVuY3Rpb24oc291cmNlLCB0YXJnZXQsIG9wdGlvbnMpIHtcbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7IH07XG4gICAgcmV0dXJuIEVsZW1lbnQuY2xvbmVQb3NpdGlvbih0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucyk7XG4gIH1cbn07XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5pZiAoIWRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUpIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBmdW5jdGlvbihpbnN0YW5jZU1ldGhvZHMpe1xuICBmdW5jdGlvbiBpdGVyKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZS5ibGFuaygpID8gbnVsbCA6IFwiW2NvbnRhaW5zKGNvbmNhdCgnICcsIEBjbGFzcywgJyAnKSwgJyBcIiArIG5hbWUgKyBcIiAnKV1cIjtcbiAgfVxuXG4gIGluc3RhbmNlTWV0aG9kcy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gUHJvdG90eXBlLkJyb3dzZXJGZWF0dXJlcy5YUGF0aCA/XG4gIGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS50b1N0cmluZygpLnN0cmlwKCk7XG4gICAgdmFyIGNvbmQgPSAvXFxzLy50ZXN0KGNsYXNzTmFtZSkgPyAkdyhjbGFzc05hbWUpLm1hcChpdGVyKS5qb2luKCcnKSA6IGl0ZXIoY2xhc3NOYW1lKTtcbiAgICByZXR1cm4gY29uZCA/IGRvY3VtZW50Ll9nZXRFbGVtZW50c0J5WFBhdGgoJy4vLyonICsgY29uZCwgZWxlbWVudCkgOiBbXTtcbiAgfSA6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSkge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS50b1N0cmluZygpLnN0cmlwKCk7XG4gICAgdmFyIGVsZW1lbnRzID0gW10sIGNsYXNzTmFtZXMgPSAoL1xccy8udGVzdChjbGFzc05hbWUpID8gJHcoY2xhc3NOYW1lKSA6IG51bGwpO1xuICAgIGlmICghY2xhc3NOYW1lcyAmJiAhY2xhc3NOYW1lKSByZXR1cm4gZWxlbWVudHM7XG5cbiAgICB2YXIgbm9kZXMgPSAkKGVsZW1lbnQpLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7XG4gICAgY2xhc3NOYW1lID0gJyAnICsgY2xhc3NOYW1lICsgJyAnO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIGNoaWxkLCBjbjsgY2hpbGQgPSBub2Rlc1tpXTsgaSsrKSB7XG4gICAgICBpZiAoY2hpbGQuY2xhc3NOYW1lICYmIChjbiA9ICcgJyArIGNoaWxkLmNsYXNzTmFtZSArICcgJykgJiYgKGNuLmluY2x1ZGUoY2xhc3NOYW1lKSB8fFxuICAgICAgICAgIChjbGFzc05hbWVzICYmIGNsYXNzTmFtZXMuYWxsKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiAhbmFtZS50b1N0cmluZygpLmJsYW5rKCkgJiYgY24uaW5jbHVkZSgnICcgKyBuYW1lICsgJyAnKTtcbiAgICAgICAgICB9KSkpKVxuICAgICAgICBlbGVtZW50cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGNoaWxkKSk7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50cztcbiAgfTtcblxuICByZXR1cm4gZnVuY3Rpb24oY2xhc3NOYW1lLCBwYXJlbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuICQocGFyZW50RWxlbWVudCB8fCBkb2N1bWVudC5ib2R5KS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGNsYXNzTmFtZSk7XG4gIH07XG59KEVsZW1lbnQuTWV0aG9kcyk7XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG5FbGVtZW50LkNsYXNzTmFtZXMgPSBDbGFzcy5jcmVhdGUoKTtcbkVsZW1lbnQuQ2xhc3NOYW1lcy5wcm90b3R5cGUgPSB7XG4gIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICB0aGlzLmVsZW1lbnQgPSAkKGVsZW1lbnQpO1xuICB9LFxuXG4gIF9lYWNoOiBmdW5jdGlvbihpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHRoaXMuZWxlbWVudC5jbGFzc05hbWUuc3BsaXQoL1xccysvKS5zZWxlY3QoZnVuY3Rpb24obmFtZSkge1xuICAgICAgcmV0dXJuIG5hbWUubGVuZ3RoID4gMDtcbiAgICB9KS5fZWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gIH0sXG5cbiAgc2V0OiBmdW5jdGlvbihjbGFzc05hbWUpIHtcbiAgICB0aGlzLmVsZW1lbnQuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICB9LFxuXG4gIGFkZDogZnVuY3Rpb24oY2xhc3NOYW1lVG9BZGQpIHtcbiAgICBpZiAodGhpcy5pbmNsdWRlKGNsYXNzTmFtZVRvQWRkKSkgcmV0dXJuO1xuICAgIHRoaXMuc2V0KCRBKHRoaXMpLmNvbmNhdChjbGFzc05hbWVUb0FkZCkuam9pbignICcpKTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKGNsYXNzTmFtZVRvUmVtb3ZlKSB7XG4gICAgaWYgKCF0aGlzLmluY2x1ZGUoY2xhc3NOYW1lVG9SZW1vdmUpKSByZXR1cm47XG4gICAgdGhpcy5zZXQoJEEodGhpcykud2l0aG91dChjbGFzc05hbWVUb1JlbW92ZSkuam9pbignICcpKTtcbiAgfSxcblxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuICRBKHRoaXMpLmpvaW4oJyAnKTtcbiAgfVxufTtcblxuT2JqZWN0LmV4dGVuZChFbGVtZW50LkNsYXNzTmFtZXMucHJvdG90eXBlLCBFbnVtZXJhYmxlKTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbihmdW5jdGlvbigpIHtcbiAgd2luZG93LlNlbGVjdG9yID0gQ2xhc3MuY3JlYXRlKHtcbiAgICBpbml0aWFsaXplOiBmdW5jdGlvbihleHByZXNzaW9uKSB7XG4gICAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uLnN0cmlwKCk7XG4gICAgfSxcblxuICAgIGZpbmRFbGVtZW50czogZnVuY3Rpb24ocm9vdEVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBQcm90b3R5cGUuU2VsZWN0b3Iuc2VsZWN0KHRoaXMuZXhwcmVzc2lvbiwgcm9vdEVsZW1lbnQpO1xuICAgIH0sXG5cbiAgICBtYXRjaDogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaChlbGVtZW50LCB0aGlzLmV4cHJlc3Npb24pO1xuICAgIH0sXG5cbiAgICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uO1xuICAgIH0sXG5cbiAgICBpbnNwZWN0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBcIiM8U2VsZWN0b3I6IFwiICsgdGhpcy5leHByZXNzaW9uICsgXCI+XCI7XG4gICAgfVxuICB9KTtcblxuICBPYmplY3QuZXh0ZW5kKFNlbGVjdG9yLCB7XG4gICAgbWF0Y2hFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudHMsIGV4cHJlc3Npb24pIHtcbiAgICAgIHZhciBtYXRjaCA9IFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaCxcbiAgICAgICAgICByZXN1bHRzID0gW107XG5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRzW2ldO1xuICAgICAgICBpZiAobWF0Y2goZWxlbWVudCwgZXhwcmVzc2lvbikpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goRWxlbWVudC5leHRlbmQoZWxlbWVudCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9LFxuXG4gICAgZmluZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnRzLCBleHByZXNzaW9uLCBpbmRleCkge1xuICAgICAgaW5kZXggPSBpbmRleCB8fCAwO1xuICAgICAgdmFyIG1hdGNoSW5kZXggPSAwLCBlbGVtZW50O1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGVsZW1lbnRzLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcbiAgICAgICAgaWYgKFByb3RvdHlwZS5TZWxlY3Rvci5tYXRjaChlbGVtZW50LCBleHByZXNzaW9uKSAmJiBpbmRleCA9PT0gbWF0Y2hJbmRleCsrKSB7XG4gICAgICAgICAgcmV0dXJuIEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGZpbmRDaGlsZEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBleHByZXNzaW9ucykge1xuICAgICAgdmFyIHNlbGVjdG9yID0gZXhwcmVzc2lvbnMudG9BcnJheSgpLmpvaW4oJywgJyk7XG4gICAgICByZXR1cm4gUHJvdG90eXBlLlNlbGVjdG9yLnNlbGVjdChzZWxlY3RvciwgZWxlbWVudCB8fCBkb2N1bWVudCk7XG4gICAgfVxuICB9KTtcbn0pKCk7XG4iLCJyZXF1aXJlKCdqc2NvbmNhdCcpO1xuXG5hbGVydChKU09OLnN0cmluZ2lmeSk7XG4iXX0= |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment